2
0
mirror of https://github.com/frappe/books.git synced 2024-11-08 23:00:56 +00:00

refactor: Setup wizard and company setup

- Move setup logic into setupCompany.js
- Set setupComplete field in AccountingSettings
- move connectToLocalDatabase in utils
This commit is contained in:
Faris Ansari 2020-01-01 13:41:57 +05:30
parent 69434d53eb
commit 67e9ce094d
9 changed files with 186 additions and 219 deletions

View File

@ -1,6 +1,4 @@
const countryList = Object.keys(
require('../../../fixtures/countryInfo.json')
).sort();
const countryList = Object.keys(require('~/fixtures/countryInfo.json')).sort();
module.exports = {
name: 'AccountingSettings',
@ -100,6 +98,13 @@ module.exports = {
required: 1
},
{
fieldname: 'setupComplete',
label: 'Setup Complete',
fieldtype: 'Check',
default: 0
},
{
fieldname: 'autoUpdate',
label: 'Auto Update',

View File

@ -1,5 +1,5 @@
const { DateTime } = require('luxon');
const countryList = require('../../../fixtures/countryInfo.json');
const countryList = require('~/fixtures/countryInfo.json');
module.exports = {
name: 'SetupWizard',

View File

@ -4,10 +4,16 @@
v-if="['Windows', 'Linux'].includes(platform)"
@close="reloadMainWindowOnSettingsClose"
/>
<Desk class="flex-1" v-if="showDesk" />
<database-selector v-if="showDatabaseSelector" @file="connectToDBFile" />
<setup-wizard v-if="showSetupWizard" />
<Settings v-if="showSettings" />
<Desk class="flex-1" v-if="activeScreen === 'Desk'" />
<DatabaseSelector
v-if="activeScreen === 'DatabaseSelector'"
@database-connect="showSetupWizardOrDesk"
/>
<SetupWizard
v-if="activeScreen === 'SetupWizard'"
@setup-complete="showSetupWizardOrDesk"
/>
<Settings v-if="activeScreen === 'Settings'" />
<portal-target name="popovers" multiple></portal-target>
</div>
</template>
@ -22,44 +28,30 @@ import DatabaseSelector from './pages/DatabaseSelector';
import Settings from '@/pages/Settings/Settings.vue';
import WindowsTitleBar from '@/components/WindowsTitleBar';
import { remote } from 'electron';
import { connectToLocalDatabase } from '@/utils';
export default {
name: 'App',
data() {
return {
showDatabaseSelector: false,
showDesk: false,
showSetupWizard: false,
showSettings: false
activeScreen: null
};
},
watch: {
showDatabaseSelector(newValue) {
if (newValue) {
let win = remote.getCurrentWindow();
win.setSize(600, 600);
win.setResizable(false);
}
},
showSetupWizard(newValue) {
if (newValue) {
let win = remote.getCurrentWindow();
win.setSize(600, 600);
win.setResizable(false);
}
},
showSettings(newValue) {
if (newValue) {
let win = remote.getCurrentWindow();
win.setSize(460, 577);
win.setResizable(false);
}
},
showDesk(newValue) {
if (newValue) {
let win = remote.getCurrentWindow();
win.setSize(1200, 907);
win.setResizable(true);
activeScreen(value) {
if (!value) return;
let size = {
Desk: [1200, 907],
DatabaseSelector: [600, 600],
SetupWizard: [600, 600],
Settings: [460, 577]
}[value];
let resizable = value === 'Desk';
let win = remote.getCurrentWindow();
if (size.length) {
win.setSize(...size);
win.setResizable(resizable);
}
}
},
@ -70,36 +62,29 @@ export default {
Settings,
WindowsTitleBar
},
mounted() {
if (!localStorage.dbPath) {
this.showDatabaseSelector = true;
async mounted() {
let dbPath = localStorage.dbPath;
if (!dbPath) {
this.activeScreen = 'DatabaseSelector';
} else {
frappe.events.trigger('connect-database', localStorage.dbPath);
await connectToLocalDatabase(dbPath);
this.showSetupWizardOrDesk();
}
frappe.events.on('show-setup-wizard', () => {
this.showSetupWizard = true;
this.showDesk = false;
this.showDatabaseSelector = false;
});
frappe.events.on('show-desk', () => {
if (this.$route.path.startsWith('/settings')) {
this.showSettings = true;
} else {
this.showDesk = true;
this.checkForUpdates();
}
this.showSetupWizard = false;
this.showDatabaseSelector = false;
});
},
methods: {
connectToDBFile(filePath) {
frappe.events.trigger('DatabaseSelector:file-selected', filePath);
showSetupWizardOrDesk() {
const { setupComplete } = frappe.AccountingSettings;
if (!setupComplete) {
this.activeScreen = 'SetupWizard';
} else if (this.$route.path.startsWith('/settings')) {
this.activeScreen = 'Settings';
} else {
this.activeScreen = 'Desk';
this.checkForUpdates();
}
},
reloadMainWindowOnSettingsClose() {
if (this.showSettings) {
if (this.activeScreen === 'Settings') {
frappe.events.trigger('reload-main-window');
}
},

View File

@ -1,12 +1,10 @@
// frappejs imports
import frappe from 'frappejs';
import SQLite from 'frappejs/backends/sqlite';
import common from 'frappejs/common';
import coreModels from 'frappejs/models';
import FeatherIcon from 'frappejs/ui/components/FeatherIcon';
import outsideClickDirective from 'frappejs/ui/plugins/outsideClickDirective';
import models from '../models';
import postStart from '../server/postStart';
import { ipcRenderer } from 'electron';
// vue imports
@ -23,39 +21,6 @@ import router from './router';
frappe.registerModels(coreModels);
frappe.registerModels(models);
frappe.fetch = window.fetch.bind();
frappe.events.on('connect-database', async filepath => {
await connectToLocalDatabase(filepath);
const { completed } = await frappe.getSingle('SetupWizard');
if (!completed) {
frappe.events.trigger('show-setup-wizard');
return;
}
const { country } = await frappe.getSingle('AccountingSettings');
if (country === 'India') {
frappe.models.Party = require('../models/doctype/Party/RegionalChanges.js');
} else {
frappe.models.Party = require('../models/doctype/Party/Party.js');
}
frappe.events.trigger('show-desk');
});
frappe.events.on('DatabaseSelector:file-selected', async filepath => {
await connectToLocalDatabase(filepath);
localStorage.dbPath = filepath;
const { companyName } = await frappe.getSingle('AccountingSettings');
if (!companyName) {
frappe.events.trigger('show-setup-wizard');
} else {
frappe.events.trigger('show-desk');
}
});
frappe.events.on('reload-main-window', () => {
ipcRenderer.send('reload-main-window');
@ -68,122 +33,6 @@ import router from './router';
}
});
frappe.events.on('SetupWizard:setup-complete', async setupWizardValues => {
const countryList = require('../fixtures/countryInfo.json');
const {
companyLogo,
companyName,
country,
name,
email,
bankName,
fiscalYearStart,
fiscalYearEnd
} = setupWizardValues;
const doc = await frappe.getSingle('AccountingSettings');
await doc.set({
companyName,
country,
fullname: name,
email,
bankName,
fiscalYearStart,
fiscalYearEnd,
currency: countryList[country]['currency']
});
await doc.update();
const printSettings = await frappe.getSingle('PrintSettings');
printSettings.set({
logo: companyLogo,
companyName,
email,
displayLogo: companyLogo ? 1 : 0
});
await printSettings.update();
await setupGlobalCurrencies(countryList);
await setupChartOfAccounts(bankName);
await setupRegionalChanges(country);
await setupWizardValues.set({ completed: 1 });
await setupWizardValues.update();
frappe.events.trigger('show-desk');
});
async function setupGlobalCurrencies(countries) {
const promises = [];
const queue = [];
for (let country of Object.values(countries)) {
const {
currency,
currency_fraction: fraction,
currency_fraction_units: fractionUnits,
smallest_currency_fraction_value: smallestValue,
currency_symbol: symbol,
number_format: numberFormat
} = country;
if (currency) {
const exists = queue.includes(currency);
if (!exists) {
const doc = await frappe.newDoc({
doctype: 'Currency',
name: currency,
fraction,
fractionUnits,
smallestValue,
symbol,
numberFormat: numberFormat || '#,###.##'
});
promises.push(doc.insert());
queue.push(currency);
}
}
}
return Promise.all(promises);
}
async function setupChartOfAccounts(bankName) {
await frappe.call({
method: 'import-coa'
});
const accountDoc = await frappe.newDoc({
doctype: 'Account'
});
Object.assign(accountDoc, {
name: bankName,
rootType: 'Asset',
parentAccount: 'Bank Accounts',
accountType: 'Bank',
isGroup: 0
});
accountDoc.insert();
}
async function setupRegionalChanges(country) {
const generateRegionalTaxes = require('../models/doctype/Tax/RegionalChanges');
await generateRegionalTaxes(country);
if (country === 'India') {
frappe.models.Party = require('../models/doctype/Party/RegionalChanges');
await frappe.db.migrate();
}
}
async function connectToLocalDatabase(filepath) {
frappe.login('Administrator');
frappe.db = new SQLite({
dbPath: filepath
});
await frappe.db.connect();
await frappe.db.migrate();
await postStart();
}
window.frappe = frappe;
Vue.config.productionTip = false;

View File

@ -44,18 +44,26 @@
</div>
</template>
<script>
import { createNewDatabase, loadExistingDatabase } from '@/utils';
import {
createNewDatabase,
loadExistingDatabase,
connectToLocalDatabase
} from '@/utils';
export default {
name: 'DatabaseSelector',
methods: {
async newDatabase() {
let filePath = await createNewDatabase();
this.$emit('file', filePath);
this.connectToDatabase(filePath);
},
async existingDatabase() {
let filePath = await loadExistingDatabase();
this.$emit('file', filePath);
this.connectToDatabase(filePath);
},
async connectToDatabase(filePath) {
await connectToLocalDatabase(filePath);
this.$emit('database-connect');
}
}
};

View File

@ -57,6 +57,7 @@ import frappe from 'frappejs';
import TwoColumnForm from '@/components/TwoColumnForm';
import FormControl from '@/components/Controls/FormControl';
import Button from '@/components/Button';
import setupCompany from './setupCompany';
import { handleErrorWithDialog, showMessageDialog } from '@/utils';
export default {
@ -104,10 +105,11 @@ export default {
}
try {
this.loading = true;
frappe.events.trigger('SetupWizard:setup-complete', this.doc);
await setupCompany(this.doc);
this.$emit('setup-complete');
} catch (e) {
this.loading = false;
console.error(e);
handleErrorWithDialog(e, this.doc);
}
}
},

View File

@ -0,0 +1,102 @@
import frappe from 'frappejs';
import countryList from '~/fixtures/countryInfo.json';
export default async function setupCompany(setupWizardValues) {
const {
companyLogo,
companyName,
country,
name,
email,
bankName,
fiscalYearStart,
fiscalYearEnd
} = setupWizardValues;
const accountingSettings = frappe.AccountingSettings;
await accountingSettings.update({
companyName,
country,
fullname: name,
email,
bankName,
fiscalYearStart,
fiscalYearEnd,
currency: countryList[country]['currency']
});
const printSettings = await frappe.getSingle('PrintSettings');
printSettings.update({
logo: companyLogo,
companyName,
email,
displayLogo: companyLogo ? 1 : 0
});
await setupGlobalCurrencies(countryList);
await setupChartOfAccounts(bankName);
await setupRegionalChanges(country);
await accountingSettings.update({ setupComplete: 1 });
frappe.AccountingSettings = accountingSettings;
}
async function setupGlobalCurrencies(countries) {
const promises = [];
const queue = [];
for (let country of Object.values(countries)) {
const {
currency,
currency_fraction: fraction,
currency_fraction_units: fractionUnits,
smallest_currency_fraction_value: smallestValue,
currency_symbol: symbol,
number_format: numberFormat
} = country;
if (currency) {
const exists = queue.includes(currency);
if (!exists) {
const doc = await frappe.newDoc({
doctype: 'Currency',
name: currency,
fraction,
fractionUnits,
smallestValue,
symbol,
numberFormat: numberFormat || '#,###.##'
});
promises.push(doc.insert());
queue.push(currency);
}
}
}
return Promise.all(promises);
}
async function setupChartOfAccounts(bankName) {
await frappe.call({
method: 'import-coa'
});
const accountDoc = await frappe.newDoc({
doctype: 'Account'
});
Object.assign(accountDoc, {
name: bankName,
rootType: 'Asset',
parentAccount: 'Bank Accounts',
accountType: 'Bank',
isGroup: 0
});
accountDoc.insert();
}
async function setupRegionalChanges(country) {
const generateRegionalTaxes = require('~/models/doctype/Tax/RegionalChanges');
await generateRegionalTaxes(country);
if (country === 'India') {
frappe.models.Party = require('~/models/doctype/Party/RegionalChanges');
await frappe.db.migrate();
}
}

View File

@ -2,6 +2,8 @@ import frappe from 'frappejs';
import fs from 'fs';
import { _ } from 'frappejs/utils';
import { remote, shell } from 'electron';
import SQLite from 'frappejs/backends/sqlite';
import postStart from '../server/postStart';
import router from '@/router';
import Avatar from '@/components/Avatar';
@ -60,6 +62,18 @@ export function loadExistingDatabase() {
});
}
export async function connectToLocalDatabase(filepath) {
frappe.login('Administrator');
frappe.db = new SQLite({
dbPath: filepath
});
await frappe.db.connect();
await frappe.db.migrate();
await postStart();
// cache dbpath in localstorage
localStorage.dbPath = filepath;
}
export function showMessageDialog({ message, description, buttons = [] }) {
let buttonLabels = buttons.map(a => a.label);
remote.dialog.showMessageBox(

View File

@ -1,3 +1,4 @@
const path = require('path');
const webpack = require('webpack');
module.exports = {
@ -16,7 +17,8 @@ module.exports = {
configureWebpack(config) {
Object.assign(config.resolve.alias, {
deepmerge$: 'deepmerge/dist/umd.js',
'frappe-charts$': 'frappe-charts/dist/frappe-charts.esm.js'
'frappe-charts$': 'frappe-charts/dist/frappe-charts.esm.js',
'~': path.resolve('.')
});
config.plugins.push(