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 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 = {};
|
||||
}
|
||||
|
@ -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>
|
||||
`
|
||||
}
|
@ -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
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);
|
||||
}
|
||||
});
|
||||
|
||||
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>
|
||||
|
||||
<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>
|
||||
|
@ -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;
|
||||
|
33
src/main.js
33
src/main.js
@ -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;
|
||||
|
@ -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);
|
||||
}
|
||||
|
@ -66,7 +66,7 @@ export default {
|
||||
layout: {
|
||||
paginated: true,
|
||||
sections: [
|
||||
frappe.isElectron ? {
|
||||
process.env.ELECTRON === 'true' ? {
|
||||
title: 'Select File location',
|
||||
columns: [
|
||||
{ fields: ['file'] }
|
||||
|
Loading…
Reference in New Issue
Block a user