2
0
mirror of https://github.com/frappe/books.git synced 2024-09-19 19:19:02 +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 path = require('path');
const fs = require('fs');
const { writeFile } = require('frappejs/server/utils');
const homedir = os.homedir();
@ -8,7 +9,7 @@ const configFilePath = path.join(homedir, '.config', 'frappe-accounting', 'setti
function getSettings() {
let settings;
try {
settings = require(configFilePath);
settings = JSON.parse(fs.readFileSync(configFilePath) || '{}');
} catch (e) {
settings = {};
}

View File

@ -1,6 +1,74 @@
module.exports = {
doctype: "PrintFormat",
name: "Standard Invoice Format",
for: "Invoice",
template: require('./invoice.html')
}
doctype: "PrintFormat",
name: "Standard Invoice Format",
for: "Invoice",
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 frappe = require('frappejs');
const naming = require('frappejs/model/naming');
const registerServerMethods = require('./registerServerMethods');
const postStart = require('./postStart');
async function start() {
await server.start({
@ -14,34 +12,8 @@ async function start() {
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();
module.exports = {
start,
postStart
start
}

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);
}
});
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>
<script>
import frappe from 'frappejs';
import Vue from 'vue';
import Observable from 'frappejs/utils/observable';
import Desk from 'frappejs/ui/components/Desk';
@ -18,7 +19,7 @@ export default {
name: 'App',
data() {
return {
showDesk: true,
showDesk: JSON.parse(localStorage.showDesk),
sidebarConfig
}
},
@ -27,14 +28,11 @@ export default {
SetupWizard
},
async created() {
const accountingSettings = await frappe.getSingle('AccountingSettings');
if (accountingSettings.companyName) {
this.showDesk = true;
} else {
frappe.events.on('show-setup-wizard', () => {
this.showDesk = false;
}
})
frappe.events.on('setup-complete', () => {
frappe.events.on('show-desk', () => {
this.showDesk = true;
this.$router.push('/tree/Account');
});
@ -43,11 +41,10 @@ export default {
</script>
<style lang="scss">
@import "~bootstrap/scss/bootstrap";
@import '~bootstrap/scss/bootstrap';
@import '~frappe-datatable/dist/frappe-datatable';
html {
font-size: 14px;
}
</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
import Vue from 'vue';
import App from './App';
import router from './router';
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 () => {
frappe.isServer = true;
frappe.isElectron = true;
frappe.init();
frappe.registerLibs(common);
frappe.registerModels(coreModels);
frappe.registerModels(models);
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');
registerServerMethods();
const electronSettings = getSettings();
if (!electronSettings.dbPath) {
localStorage.showDesk = false;
} else {
await connectToLocalDatabase();
localStorage.showDesk = true;
}
frappe.getSingle('AccountingSettings')
.then(accountingSettings => {
if (router.currentRoute.fullPath !== '/') return;
frappe.events.on('SetupWizard:setup-complete', async ({ setupWizardValues }) => {
const {
file,
companyName,
country,
name,
email,
bankName,
fiscalYearStart,
fiscalYearEnd
} = setupWizardValues;
if (accountingSettings.companyName) {
router.push('/tree/Account');
} else {
router.push('/setup-wizard');
}
// db init
const dbPath = path.join(file[0].path, 'frappe-accounting.db');
await saveSettings({ dbPath });
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;
Vue.config.productionTip = false;

View File

@ -31,12 +31,41 @@ frappe.getSingle('AccountingSettings')
if (router.currentRoute.fullPath !== '/') return;
if (accountingSettings.companyName) {
router.push('/tree/Account');
frappe.events.trigger('show-desk');
} 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;
Vue.config.productionTip = false;

View File

@ -55,31 +55,7 @@ export default {
methods: {
async submit() {
try {
const {
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');
frappe.events.trigger('SetupWizard:setup-complete', { setupWizardValues: this.doc });
} catch (e) {
console.error(e);
}

View File

@ -66,7 +66,7 @@ export default {
layout: {
paginated: true,
sections: [
frappe.isElectron ? {
process.env.ELECTRON === 'true' ? {
title: 'Select File location',
columns: [
{ fields: ['file'] }