mirror of
https://github.com/frappe/books.git
synced 2024-11-09 23:30:56 +00:00
Reorganize boot logic for Electron
This commit is contained in:
parent
5f81654c7f
commit
a00764e95e
@ -1,5 +1,6 @@
|
|||||||
const os = require('os');
|
const os = require('os');
|
||||||
const path = require('path');
|
const path = require('path');
|
||||||
|
const fs = require('fs');
|
||||||
const { writeFile } = require('frappejs/server/utils');
|
const { writeFile } = require('frappejs/server/utils');
|
||||||
|
|
||||||
const homedir = os.homedir();
|
const homedir = os.homedir();
|
||||||
@ -8,7 +9,7 @@ const configFilePath = path.join(homedir, '.config', 'frappe-accounting', 'setti
|
|||||||
function getSettings() {
|
function getSettings() {
|
||||||
let settings;
|
let settings;
|
||||||
try {
|
try {
|
||||||
settings = require(configFilePath);
|
settings = JSON.parse(fs.readFileSync(configFilePath) || '{}');
|
||||||
} catch (e) {
|
} catch (e) {
|
||||||
settings = {};
|
settings = {};
|
||||||
}
|
}
|
||||||
|
@ -1,6 +1,74 @@
|
|||||||
module.exports = {
|
module.exports = {
|
||||||
doctype: "PrintFormat",
|
doctype: "PrintFormat",
|
||||||
name: "Standard Invoice Format",
|
name: "Standard Invoice Format",
|
||||||
for: "Invoice",
|
for: "Invoice",
|
||||||
template: require('./invoice.html')
|
template: `
|
||||||
}
|
<h1>{{ doc.name }}</h1>
|
||||||
|
<div class="row py-4">
|
||||||
|
<div class="col-6">
|
||||||
|
<div><b>{{ frappe._("Customer") }}</b></div>
|
||||||
|
<div>{{ doc.customer }}</div>
|
||||||
|
</div>
|
||||||
|
<div class="col-6">
|
||||||
|
<div><b>{{ frappe._("Date") }}</b></div>
|
||||||
|
<div>{{ frappe.format(doc.date, 'Date') }}</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
<table class="table table-bordered">
|
||||||
|
<thead>
|
||||||
|
<tr>
|
||||||
|
<th style='width: 30px'></th>
|
||||||
|
<th>{{ frappe._("Item") }}</th>
|
||||||
|
<th class='text-right'>{{ frappe._("Qty") }}</th>
|
||||||
|
<th class='text-right'>{{ frappe._("Rate") }}</th>
|
||||||
|
<th class='text-right'>{{ frappe._("Amount") }}</th>
|
||||||
|
</tr>
|
||||||
|
</thead>
|
||||||
|
<tbody>
|
||||||
|
{% for row in doc.items %}
|
||||||
|
<tr>
|
||||||
|
<td class='text-right'>{{ row.idx + 1 }}</td>
|
||||||
|
<td>{{ row.item }}<br>{{ frappe.format(row.description, 'Text') }}</td>
|
||||||
|
<td class='text-right'>{{ row.quantity }}</td>
|
||||||
|
<td class='text-right'>{{ frappe.format(row.rate, 'Currency') }}</td>
|
||||||
|
<td class='text-right'>{{ frappe.format(row.amount, 'Currency') }}</td>
|
||||||
|
</tr>
|
||||||
|
{% endfor %}
|
||||||
|
</tbody>
|
||||||
|
</table>
|
||||||
|
<div class='row'>
|
||||||
|
<div class='col-6'></div>
|
||||||
|
<div class='col-6'>
|
||||||
|
<div class='row'>
|
||||||
|
<div class='col-6'>
|
||||||
|
{{ frappe._("Total") }}
|
||||||
|
</div>
|
||||||
|
<div class='col-6 text-right'>
|
||||||
|
{{ frappe.format(doc.netTotal, 'Currency')}}
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
{% for tax in doc.taxes %}
|
||||||
|
<div class='row'>
|
||||||
|
<div class='col-6'>
|
||||||
|
{{ tax.account }} ({{ tax.rate }}%)
|
||||||
|
</div>
|
||||||
|
<div class='col-6 text-right'>
|
||||||
|
{{ frappe.format(tax.amount, 'Currency')}}
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
{% endfor %}
|
||||||
|
<div class='row py-3'>
|
||||||
|
<div class='col-6'>
|
||||||
|
<h5>{{ frappe._("Grand Total") }}</h5>
|
||||||
|
</div>
|
||||||
|
<div class='col-6 text-right'>
|
||||||
|
<h5>{{ frappe.format(doc.grandTotal, 'Currency')}}</h5>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
<div class='py-3'>
|
||||||
|
{{ frappe.format(doc.terms, 'Text') }}
|
||||||
|
</div>
|
||||||
|
`
|
||||||
|
}
|
||||||
|
@ -1,8 +1,6 @@
|
|||||||
const path = require('path');
|
|
||||||
const server = require('frappejs/server');
|
const server = require('frappejs/server');
|
||||||
const frappe = require('frappejs');
|
const postStart = require('./postStart');
|
||||||
const naming = require('frappejs/model/naming');
|
|
||||||
const registerServerMethods = require('./registerServerMethods');
|
|
||||||
|
|
||||||
async function start() {
|
async function start() {
|
||||||
await server.start({
|
await server.start({
|
||||||
@ -14,34 +12,8 @@ async function start() {
|
|||||||
await postStart();
|
await postStart();
|
||||||
}
|
}
|
||||||
|
|
||||||
async function postStart() {
|
|
||||||
// set server-side modules
|
|
||||||
frappe.models.Invoice.documentClass = require('../models/doctype/Invoice/InvoiceServer.js');
|
|
||||||
frappe.models.Payment.documentClass = require('../models/doctype/Payment/PaymentServer.js');
|
|
||||||
frappe.models.Bill.documentClass = require('../models/doctype/Bill/BillServer.js');
|
|
||||||
frappe.models.JournalEntry.documentClass = require('../models/doctype/JournalEntry/JournalEntryServer.js');
|
|
||||||
|
|
||||||
frappe.metaCache = {};
|
|
||||||
|
|
||||||
frappe.syncDoc(require('../fixtures/invoicePrint'));
|
|
||||||
|
|
||||||
// init naming series if missing
|
|
||||||
await naming.createNumberSeries('INV-', 'InvoiceSettings');
|
|
||||||
await naming.createNumberSeries('BILL-', 'BillSettings');
|
|
||||||
await naming.createNumberSeries('PAY-', 'PaymentSettings');
|
|
||||||
await naming.createNumberSeries('JV-', 'JournalEntrySettings');
|
|
||||||
await naming.createNumberSeries('QTN-', 'QuotationSettings');
|
|
||||||
await naming.createNumberSeries('SO-', 'SalesOrderSettings');
|
|
||||||
await naming.createNumberSeries('OF-', 'FulfillmentSettings');
|
|
||||||
await naming.createNumberSeries('PO-', 'PurchaseOrderSettings');
|
|
||||||
await naming.createNumberSeries('PREC-', 'PurchaseReceiptSettings');
|
|
||||||
|
|
||||||
registerServerMethods();
|
|
||||||
}
|
|
||||||
|
|
||||||
start();
|
start();
|
||||||
|
|
||||||
module.exports = {
|
module.exports = {
|
||||||
start,
|
start
|
||||||
postStart
|
|
||||||
}
|
}
|
28
server/postStart.js
Normal file
28
server/postStart.js
Normal file
@ -0,0 +1,28 @@
|
|||||||
|
const frappe = require('frappejs');
|
||||||
|
const naming = require('frappejs/model/naming');
|
||||||
|
const registerServerMethods = require('./registerServerMethods');
|
||||||
|
|
||||||
|
module.exports = async function postStart() {
|
||||||
|
// set server-side modules
|
||||||
|
frappe.models.Invoice.documentClass = require('../models/doctype/Invoice/InvoiceServer.js');
|
||||||
|
frappe.models.Payment.documentClass = require('../models/doctype/Payment/PaymentServer.js');
|
||||||
|
frappe.models.Bill.documentClass = require('../models/doctype/Bill/BillServer.js');
|
||||||
|
frappe.models.JournalEntry.documentClass = require('../models/doctype/JournalEntry/JournalEntryServer.js');
|
||||||
|
|
||||||
|
frappe.metaCache = {};
|
||||||
|
|
||||||
|
frappe.syncDoc(require('../fixtures/invoicePrint'));
|
||||||
|
|
||||||
|
// init naming series if missing
|
||||||
|
await naming.createNumberSeries('INV-', 'InvoiceSettings');
|
||||||
|
await naming.createNumberSeries('BILL-', 'BillSettings');
|
||||||
|
await naming.createNumberSeries('PAY-', 'PaymentSettings');
|
||||||
|
await naming.createNumberSeries('JV-', 'JournalEntrySettings');
|
||||||
|
await naming.createNumberSeries('QTN-', 'QuotationSettings');
|
||||||
|
await naming.createNumberSeries('SO-', 'SalesOrderSettings');
|
||||||
|
await naming.createNumberSeries('OF-', 'FulfillmentSettings');
|
||||||
|
await naming.createNumberSeries('PO-', 'PurchaseOrderSettings');
|
||||||
|
await naming.createNumberSeries('PREC-', 'PurchaseReceiptSettings');
|
||||||
|
|
||||||
|
registerServerMethods();
|
||||||
|
}
|
@ -12,4 +12,17 @@ module.exports = function registerServerMethods() {
|
|||||||
await importCOA(standardCOA);
|
await importCOA(standardCOA);
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
|
||||||
|
frappe.registerMethod({
|
||||||
|
method: 'print-pdf',
|
||||||
|
handler({doctype, name}) {
|
||||||
|
if (frappe.isElectron) {
|
||||||
|
const path = require('path');
|
||||||
|
const { getPDFForElectron } = require('frappejs/server/pdf');
|
||||||
|
const { getSettings } = require('../electron/settings');
|
||||||
|
const destination = path.resolve(getSettings().dbPath, '..')
|
||||||
|
getPDFForElectron(doctype, name, destination);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
})
|
||||||
}
|
}
|
15
src/App.vue
15
src/App.vue
@ -8,6 +8,7 @@
|
|||||||
</template>
|
</template>
|
||||||
|
|
||||||
<script>
|
<script>
|
||||||
|
import frappe from 'frappejs';
|
||||||
import Vue from 'vue';
|
import Vue from 'vue';
|
||||||
import Observable from 'frappejs/utils/observable';
|
import Observable from 'frappejs/utils/observable';
|
||||||
import Desk from 'frappejs/ui/components/Desk';
|
import Desk from 'frappejs/ui/components/Desk';
|
||||||
@ -18,7 +19,7 @@ export default {
|
|||||||
name: 'App',
|
name: 'App',
|
||||||
data() {
|
data() {
|
||||||
return {
|
return {
|
||||||
showDesk: true,
|
showDesk: JSON.parse(localStorage.showDesk),
|
||||||
sidebarConfig
|
sidebarConfig
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
@ -27,14 +28,11 @@ export default {
|
|||||||
SetupWizard
|
SetupWizard
|
||||||
},
|
},
|
||||||
async created() {
|
async created() {
|
||||||
const accountingSettings = await frappe.getSingle('AccountingSettings');
|
frappe.events.on('show-setup-wizard', () => {
|
||||||
if (accountingSettings.companyName) {
|
|
||||||
this.showDesk = true;
|
|
||||||
} else {
|
|
||||||
this.showDesk = false;
|
this.showDesk = false;
|
||||||
}
|
})
|
||||||
|
|
||||||
frappe.events.on('setup-complete', () => {
|
frappe.events.on('show-desk', () => {
|
||||||
this.showDesk = true;
|
this.showDesk = true;
|
||||||
this.$router.push('/tree/Account');
|
this.$router.push('/tree/Account');
|
||||||
});
|
});
|
||||||
@ -43,11 +41,10 @@ export default {
|
|||||||
</script>
|
</script>
|
||||||
|
|
||||||
<style lang="scss">
|
<style lang="scss">
|
||||||
@import "~bootstrap/scss/bootstrap";
|
@import '~bootstrap/scss/bootstrap';
|
||||||
@import '~frappe-datatable/dist/frappe-datatable';
|
@import '~frappe-datatable/dist/frappe-datatable';
|
||||||
|
|
||||||
html {
|
html {
|
||||||
font-size: 14px;
|
font-size: 14px;
|
||||||
}
|
}
|
||||||
|
|
||||||
</style>
|
</style>
|
||||||
|
@ -1,43 +1,80 @@
|
|||||||
|
// frappejs imports
|
||||||
|
import frappe from 'frappejs';
|
||||||
|
import path from 'path';
|
||||||
|
import SQLite from 'frappejs/backends/sqlite';
|
||||||
|
import common from 'frappejs/common';
|
||||||
|
import coreModels from 'frappejs/models';
|
||||||
|
import models from '../models';
|
||||||
|
import postStart from '../server/postStart';
|
||||||
|
import { getSettings, saveSettings } from '../electron/settings';
|
||||||
|
|
||||||
// vue imports
|
// vue imports
|
||||||
import Vue from 'vue';
|
import Vue from 'vue';
|
||||||
import App from './App';
|
import App from './App';
|
||||||
import router from './router';
|
import router from './router';
|
||||||
import frappeVue from 'frappejs/ui/plugins/frappeVue';
|
import frappeVue from 'frappejs/ui/plugins/frappeVue';
|
||||||
|
|
||||||
// frappejs imports
|
|
||||||
import frappe from 'frappejs';
|
|
||||||
import SQLite from 'frappejs/backends/sqlite';
|
|
||||||
import common from 'frappejs/common';
|
|
||||||
import coreModels from 'frappejs/models';
|
|
||||||
import models from '../models';
|
|
||||||
import registerServerMethods from '../server/registerServerMethods';
|
|
||||||
|
|
||||||
(async () => {
|
(async () => {
|
||||||
frappe.isServer = true;
|
frappe.isServer = true;
|
||||||
|
frappe.isElectron = true;
|
||||||
frappe.init();
|
frappe.init();
|
||||||
frappe.registerLibs(common);
|
frappe.registerLibs(common);
|
||||||
frappe.registerModels(coreModels);
|
frappe.registerModels(coreModels);
|
||||||
frappe.registerModels(models);
|
frappe.registerModels(models);
|
||||||
frappe.fetch = window.fetch.bind();
|
frappe.fetch = window.fetch.bind();
|
||||||
frappe.login('Administrator');
|
|
||||||
frappe.db = new SQLite({ dbPath: 'test.db' });
|
|
||||||
await frappe.db.connect();
|
|
||||||
await frappe.db.migrate();
|
|
||||||
|
|
||||||
frappe.getSingle('SystemSettings');
|
const electronSettings = getSettings();
|
||||||
registerServerMethods();
|
if (!electronSettings.dbPath) {
|
||||||
|
localStorage.showDesk = false;
|
||||||
|
} else {
|
||||||
|
await connectToLocalDatabase();
|
||||||
|
localStorage.showDesk = true;
|
||||||
|
}
|
||||||
|
|
||||||
frappe.getSingle('AccountingSettings')
|
frappe.events.on('SetupWizard:setup-complete', async ({ setupWizardValues }) => {
|
||||||
.then(accountingSettings => {
|
const {
|
||||||
if (router.currentRoute.fullPath !== '/') return;
|
file,
|
||||||
|
companyName,
|
||||||
|
country,
|
||||||
|
name,
|
||||||
|
email,
|
||||||
|
bankName,
|
||||||
|
fiscalYearStart,
|
||||||
|
fiscalYearEnd
|
||||||
|
} = setupWizardValues;
|
||||||
|
|
||||||
if (accountingSettings.companyName) {
|
// db init
|
||||||
router.push('/tree/Account');
|
const dbPath = path.join(file[0].path, 'frappe-accounting.db');
|
||||||
} else {
|
await saveSettings({ dbPath });
|
||||||
router.push('/setup-wizard');
|
await connectToLocalDatabase();
|
||||||
}
|
|
||||||
|
const doc = await frappe.getSingle('AccountingSettings');
|
||||||
|
await doc.set({
|
||||||
|
companyName,
|
||||||
|
country,
|
||||||
|
fullname: name,
|
||||||
|
email,
|
||||||
|
bankName,
|
||||||
|
fiscalYearStart,
|
||||||
|
fiscalYearEnd
|
||||||
});
|
});
|
||||||
|
|
||||||
|
await doc.update();
|
||||||
|
await frappe.call({ method: 'import-coa' });
|
||||||
|
|
||||||
|
frappe.events.trigger('show-desk');
|
||||||
|
});
|
||||||
|
|
||||||
|
async function connectToLocalDatabase() {
|
||||||
|
const electronSettings = getSettings();
|
||||||
|
frappe.login('Administrator');
|
||||||
|
frappe.db = new SQLite({ dbPath: electronSettings.dbPath });
|
||||||
|
await frappe.db.connect();
|
||||||
|
await frappe.db.migrate();
|
||||||
|
frappe.getSingle('SystemSettings');
|
||||||
|
await postStart();
|
||||||
|
}
|
||||||
|
|
||||||
window.frappe = frappe;
|
window.frappe = frappe;
|
||||||
|
|
||||||
Vue.config.productionTip = false;
|
Vue.config.productionTip = false;
|
||||||
|
33
src/main.js
33
src/main.js
@ -31,12 +31,41 @@ frappe.getSingle('AccountingSettings')
|
|||||||
if (router.currentRoute.fullPath !== '/') return;
|
if (router.currentRoute.fullPath !== '/') return;
|
||||||
|
|
||||||
if (accountingSettings.companyName) {
|
if (accountingSettings.companyName) {
|
||||||
router.push('/tree/Account');
|
frappe.events.trigger('show-desk');
|
||||||
} else {
|
} else {
|
||||||
router.push('/setup-wizard');
|
frappe.events.trigger('show-setup-wizard');
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
|
||||||
|
frappe.events.on('SetupWizard:setup-complete', async ({ setupWizardValues }) => {
|
||||||
|
const {
|
||||||
|
companyName,
|
||||||
|
country,
|
||||||
|
name,
|
||||||
|
email,
|
||||||
|
abbreviation,
|
||||||
|
bankName,
|
||||||
|
fiscalYearStart,
|
||||||
|
fiscalYearEnd
|
||||||
|
} = setupWizardValues;
|
||||||
|
|
||||||
|
const doc = await frappe.getSingle('AccountingSettings');
|
||||||
|
await doc.set({
|
||||||
|
companyName,
|
||||||
|
country,
|
||||||
|
fullname: name,
|
||||||
|
email,
|
||||||
|
bankName,
|
||||||
|
fiscalYearStart,
|
||||||
|
fiscalYearEnd
|
||||||
|
});
|
||||||
|
|
||||||
|
await doc.update();
|
||||||
|
await frappe.call({ method: 'import-coa' });
|
||||||
|
|
||||||
|
frappe.events.trigger('show-desk');
|
||||||
|
});
|
||||||
|
|
||||||
window.frappe = frappe;
|
window.frappe = frappe;
|
||||||
|
|
||||||
Vue.config.productionTip = false;
|
Vue.config.productionTip = false;
|
||||||
|
@ -55,31 +55,7 @@ export default {
|
|||||||
methods: {
|
methods: {
|
||||||
async submit() {
|
async submit() {
|
||||||
try {
|
try {
|
||||||
const {
|
frappe.events.trigger('SetupWizard:setup-complete', { setupWizardValues: this.doc });
|
||||||
companyName,
|
|
||||||
country,
|
|
||||||
name,
|
|
||||||
email,
|
|
||||||
abbreviation,
|
|
||||||
bankName,
|
|
||||||
fiscalYearStart,
|
|
||||||
fiscalYearEnd
|
|
||||||
} = this.doc;
|
|
||||||
|
|
||||||
const doc = await frappe.getSingle('AccountingSettings');
|
|
||||||
await doc.set({
|
|
||||||
companyName,
|
|
||||||
country,
|
|
||||||
fullname: name,
|
|
||||||
email,
|
|
||||||
bankName,
|
|
||||||
fiscalYearStart,
|
|
||||||
fiscalYearEnd
|
|
||||||
});
|
|
||||||
|
|
||||||
await doc.update();
|
|
||||||
await frappe.call({ method: 'import-coa'});
|
|
||||||
frappe.events.trigger('setup-complete');
|
|
||||||
} catch (e) {
|
} catch (e) {
|
||||||
console.error(e);
|
console.error(e);
|
||||||
}
|
}
|
||||||
|
@ -66,7 +66,7 @@ export default {
|
|||||||
layout: {
|
layout: {
|
||||||
paginated: true,
|
paginated: true,
|
||||||
sections: [
|
sections: [
|
||||||
frappe.isElectron ? {
|
process.env.ELECTRON === 'true' ? {
|
||||||
title: 'Select File location',
|
title: 'Select File location',
|
||||||
columns: [
|
columns: [
|
||||||
{ fields: ['file'] }
|
{ fields: ['file'] }
|
||||||
|
Loading…
Reference in New Issue
Block a user