2
0
mirror of https://github.com/frappe/books.git synced 2024-11-10 07:40:55 +00:00

Merge pull request #239 from 18alantom/fix-db-creation

fix: db creation flow, don't show annoying messages when not required
This commit is contained in:
Alan 2021-11-09 16:21:38 +05:30 committed by GitHub
commit 65570d4210
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
8 changed files with 173 additions and 107 deletions

View File

@ -64,7 +64,6 @@ export default {
return ['fullName'];
},
getRowHTML(list, data) {
console.log(list, data);
return `<div class="col-11">${list.getNameHTML(data)}</div>`;
}
},

View File

@ -1,41 +1,49 @@
import frappe from 'frappejs';
export default async function generateTaxes(country) {
if (country === 'India') {
const GSTs = {
GST: [28, 18, 12, 6, 5, 3, 0.25, 0],
IGST: [28, 18, 12, 6, 5, 3, 0.25, 0],
'Exempt-GST': [0],
'Exempt-IGST': [0]
'Exempt-IGST': [0],
};
let newTax = await frappe.getNewDoc('Tax');
for (const type of Object.keys(GSTs)) {
for (const percent of GSTs[type]) {
if (type === 'GST') {
await newTax.set({
name: `${type}-${percent}`,
details: [
{
account: 'CGST',
rate: percent / 2
},
{
account: 'SGST',
rate: percent / 2
}
]
});
} else {
await newTax.set({
name: `${type}-${percent}`,
details: [
{
account: type.toString().split('-')[0],
rate: percent
}
]
});
}
const name = `${type}-${percent}`;
// Not cross checking cause hardcoded values.
await frappe.db.knex('Tax').where({ name }).del();
await frappe.db.knex('TaxDetail').where({ parent: name }).del();
const details = getTaxDetails(type, percent);
await newTax.set({ name, details });
await newTax.insert();
}
}
}
};
}
function getTaxDetails(type, percent) {
if (type === 'GST') {
return [
{
account: 'CGST',
rate: percent / 2,
},
{
account: 'SGST',
rate: percent / 2,
},
];
} else {
return [
{
account: type.toString().split('-')[0],
rate: percent,
},
];
}
}

View File

@ -31,8 +31,6 @@ async function getReceivablePayable({ reportType = 'Receivable', date }) {
for (let entry of validEntries) {
const { outStandingAmount, creditNoteAmount } = getOutstandingAmount(entry);
console.log(outStandingAmount);
if (outStandingAmount > 0.1 / 10) {
const row = {
date: entry.date,

View File

@ -1,11 +1,28 @@
import frappe from 'frappejs';
import migrate from 'frappejs/model/migrate';
import runPatches from 'frappejs/model/runPatches';
import patchesTxt from '../patches/patches.txt';
const requirePatch = require.context('../patches', true, /\w+\.(js)$/);
export default async function runMigrate() {
let patchOrder = patchesTxt.split('\n');
let allPatches = {};
if (await canRunPatches()) {
const patchOrder = patchesTxt.split('\n');
const allPatches = getAllPatches();
await runPatches(allPatches, patchOrder);
}
await frappe.db.migrate();
}
async function canRunPatches() {
return (
(await frappe.db
.knex('sqlite_master')
.where({ type: 'table', name: 'PatchRun' })
.select('name').length) > 0
);
}
async function getAllPatches() {
const allPatches = {};
requirePatch.keys().forEach((fileName) => {
if (fileName === './index.js') return;
let method;
@ -20,6 +37,5 @@ export default async function runMigrate() {
allPatches[fileName] = method;
}
});
await migrate(allPatches, patchOrder);
await frappe.db.migrate();
};
return allPatches;
}

View File

@ -139,7 +139,7 @@ export default {
};
},
mounted() {
this.files = config.get('files', []).filter(({filepath}) => fs.existsSync(filepath));
this.files = config.get('files', []).filter(({filePath}) => fs.existsSync(filePath));
this.showFiles = this.files.length > 0;
},
methods: {
@ -158,6 +158,10 @@ export default {
await this.connectToDatabase(file.filePath);
},
async connectToDatabase(filePath) {
if (!filePath) {
return;
}
this.loadingDatabase = true;
const connectionSuccess = await connectToLocalDatabase(filePath);
this.loadingDatabase = false;

View File

@ -65,6 +65,10 @@ import FormControl from '@/components/Controls/FormControl';
import Button from '@/components/Button';
import setupCompany from './setupCompany';
import Popover from '@/components/Popover';
import config from '@/config';
import path from 'path';
import fs from 'fs';
import { connectToLocalDatabase } from '@/utils';
import {
getErrorMessage,
@ -121,24 +125,31 @@ export default {
showMessageDialog({ message: this._('Please fill all values') });
return;
}
try {
this.loading = true;
await setupCompany(this.doc);
this.$emit('setup-complete');
} catch (e) {
this.loading = false;
console.log(e, this.doc);
if (e.type === frappe.errors.DuplicateEntryError) {
// TODO: Add option to overwrite file from here.
const message = this._(
'Records already exist in the db. Please create a new database file and try again.'
);
showMessageDialog({ message });
await this.renameDbFileAndRerunSetup();
} else {
handleErrorWithDialog(e, this.doc);
}
}
},
async renameDbFileAndRerunSetup() {
const filePath = config.get('lastSelectedFilePath');
renameDbFile(filePath);
frappe.removeFromCache('AccountingSettings', 'AccountingSettings');
delete frappe.AccountingSettings;
const connectionSuccess = await connectToLocalDatabase(filePath);
if (connectionSuccess) {
await setupCompany(this.doc);
this.$emit('setup-complete');
}
},
},
computed: {
meta() {
@ -152,4 +163,14 @@ export default {
},
},
};
function renameDbFile(filePath) {
const dirname = path.dirname(filePath);
const basename = path.basename(filePath);
const backupPath = path.join(dirname, `_${basename}`);
if (fs.existsSync(backupPath)) {
fs.unlinkSync(backupPath);
}
fs.renameSync(filePath, backupPath);
}
</script>

View File

@ -12,7 +12,7 @@ export default async function setupCompany(setupWizardValues) {
email,
bankName,
fiscalYearStart,
fiscalYearEnd
fiscalYearEnd,
} = setupWizardValues;
const accountingSettings = frappe.AccountingSettings;
@ -24,7 +24,7 @@ export default async function setupCompany(setupWizardValues) {
bankName,
fiscalYearStart,
fiscalYearEnd,
currency: countryList[country]['currency']
currency: countryList[country]['currency'],
});
const printSettings = await frappe.getSingle('PrintSettings');
@ -32,7 +32,7 @@ export default async function setupCompany(setupWizardValues) {
logo: companyLogo,
companyName,
email,
displayLogo: companyLogo ? 1 : 0
displayLogo: companyLogo ? 1 : 0,
});
await setupGlobalCurrencies(countryList);
@ -55,24 +55,28 @@ async function setupGlobalCurrencies(countries) {
currency_fraction_units: fractionUnits,
smallest_currency_fraction_value: smallestValue,
currency_symbol: symbol,
number_format: numberFormat
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);
}
if (!currency || queue.includes(currency)) {
continue;
}
const docObject = {
doctype: 'Currency',
name: currency,
fraction,
fractionUnits,
smallestValue,
symbol,
numberFormat: numberFormat || '#,###.##',
};
const canCreate = await checkIfExactRecordAbsent(docObject);
if (canCreate) {
const doc = await frappe.newDoc(docObject);
promises.push(doc.insert());
queue.push(currency);
}
}
return Promise.all(promises);
@ -80,26 +84,30 @@ async function setupGlobalCurrencies(countries) {
async function setupChartOfAccounts(bankName) {
await frappe.call({
method: 'import-coa'
method: 'import-coa',
});
const accountDoc = await frappe.newDoc({
doctype: 'Account'
});
Object.assign(accountDoc, {
const docObject = {
doctype: 'Account',
name: bankName,
rootType: 'Asset',
parentAccount: 'Bank Accounts',
accountType: 'Bank',
isGroup: 0
});
accountDoc.insert();
isGroup: 0,
};
if (await checkIfExactRecordAbsent(docObject)) {
const accountDoc = await frappe.newDoc(docObject);
accountDoc.insert();
}
}
async function setupRegionalChanges(country) {
await generateTaxes(country);
if (country === 'India') {
frappe.models.Party = await import('../../../models/doctype/Party/RegionalChanges');
frappe.models.Party = await import(
'../../../models/doctype/Party/RegionalChanges'
);
await frappe.db.migrate();
}
}
@ -107,10 +115,35 @@ async function setupRegionalChanges(country) {
function updateCompanyNameInConfig() {
let filePath = frappe.db.dbPath;
let files = config.get('files', []);
files.forEach(file => {
files.forEach((file) => {
if (file.filePath === filePath) {
file.companyName = frappe.AccountingSettings.companyName;
}
});
config.set('files', files);
}
export async function checkIfExactRecordAbsent(docObject) {
const { doctype, name } = docObject;
const newDocObject = Object.assign({}, docObject);
delete newDocObject.doctype;
const rows = await frappe.db.knex(doctype).where({ name });
if (rows.length === 0) {
return true;
}
const storedDocObject = rows[0];
const matchList = Object.keys(newDocObject).map((key) => {
const newValue = newDocObject[key];
const storedValue = storedDocObject[key];
return newValue == storedValue; // Should not be type sensitive.
});
if (!matchList.every(Boolean)) {
await frappe.db.knex(doctype).where({ name }).del();
return true;
}
return false;
}

View File

@ -16,38 +16,24 @@ export async function createNewDatabase() {
defaultPath: 'frappe-books.db',
};
let { filePath } = await ipcRenderer.invoke(
let { canceled, filePath } = await ipcRenderer.invoke(
IPC_ACTIONS.GET_SAVE_FILEPATH,
options
);
if (filePath) {
if (!filePath.endsWith('.db')) {
filePath = filePath + '.db';
}
if (fs.existsSync(filePath)) {
showMessageDialog({
// prettier-ignore
message: _('A file exists with the same name and it will be overwritten. Are you sure you want to continue?'),
buttons: [
{
label: _('Overwrite'),
action() {
fs.unlinkSync(filePath);
return filePath;
},
},
{
label: _('Cancel'),
action() {
return '';
},
},
],
});
} else {
return filePath;
}
if (canceled || filePath.length === 0) {
return '';
}
if (!filePath.endsWith('.db')) {
filePath = filePath + '.db';
}
if (fs.existsSync(filePath)) {
fs.unlinkSync(filePath);
}
return filePath;
}
export async function loadExistingDatabase() {
@ -67,30 +53,31 @@ export async function loadExistingDatabase() {
}
}
export async function connectToLocalDatabase(filepath) {
if (!filepath) {
export async function connectToLocalDatabase(filePath) {
if (!filePath) {
return false;
}
frappe.login('Administrator');
try {
frappe.db = new SQLite({
dbPath: filepath,
dbPath: filePath,
});
await frappe.db.connect();
} catch (error) {
return false;
}
await migrate();
await postStart();
// set file info in config
let files = config.get('files') || [];
if (!files.find((file) => file.filePath === filepath)) {
if (!files.find((file) => file.filePath === filePath)) {
files = [
{
companyName: frappe.AccountingSettings.companyName,
filePath: filepath,
filePath: filePath,
},
...files,
];
@ -98,7 +85,7 @@ export async function connectToLocalDatabase(filepath) {
}
// set last selected file
config.set('lastSelectedFilePath', filepath);
config.set('lastSelectedFilePath', filePath);
return true;
}
@ -274,4 +261,4 @@ export async function runWindowAction(name) {
break;
}
return name;
}
}