2
0
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:
Faris Ansari 2018-10-22 23:32:47 +05:30
parent 5f81654c7f
commit a00764e95e
10 changed files with 217 additions and 96 deletions

View File

@ -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 = {};
} }

View File

@ -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>
`
}

View File

@ -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
View 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();
}

View File

@ -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);
}
}
})
} }

View File

@ -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>

View File

@ -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;

View File

@ -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;

View File

@ -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);
} }

View File

@ -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'] }