2
0
mirror of https://github.com/frappe/books.git synced 2024-09-20 03:29:00 +00:00

feat: init pesa and set on the frappe object

This commit is contained in:
18alantom 2021-11-30 14:50:54 +05:30
parent b746200050
commit 7698af67e6
4 changed files with 123 additions and 28 deletions

View File

@ -13,9 +13,10 @@ module.exports = class Database extends Observable {
connect() {
this.knex = Knex(this.connectionParams);
this.knex.on('query-error', error => {
this.knex.on('query-error', (error) => {
error.type = this.getError(error);
});
this.executePostDbConnect();
}
close() {
@ -41,15 +42,25 @@ module.exports = class Database extends Observable {
async initializeSingles() {
let singleDoctypes = frappe
.getModels(model => model.isSingle)
.map(model => model.name);
.getModels((model) => model.isSingle)
.map((model) => model.name);
for (let doctype of singleDoctypes) {
if (await this.singleExists(doctype)) {
const singleValues = await this.getSingleFieldsToInsert(doctype);
singleValues.forEach(({ fieldname, value }) => {
let singleValue = frappe.newDoc({
doctype: 'SingleValue',
parent: doctype,
fieldname,
value,
});
singleValue.insert();
});
continue;
}
let meta = frappe.getMeta(doctype);
if (meta.fields.every(df => df.default == null)) {
if (meta.fields.every((df) => df.default == null)) {
continue;
}
let defaultValues = meta.fields.reduce((doc, df) => {
@ -70,6 +81,26 @@ module.exports = class Database extends Observable {
return res.count > 0;
}
async getSingleFieldsToInsert(doctype) {
const existingFields = (
await frappe.db
.knex('SingleValue')
.where({ parent: doctype })
.select('fieldname')
).map(({ fieldname }) => fieldname);
return frappe
.getMeta(doctype)
.fields.map(({ fieldname, default: value }) => ({
fieldname,
value,
}))
.filter(
({ fieldname, value }) =>
!existingFields.includes(fieldname) && value !== undefined
);
}
tableExists(table) {
return this.knex.schema.hasTable(table);
}
@ -80,7 +111,7 @@ module.exports = class Database extends Observable {
}
runCreateTableQuery(doctype, fields) {
return this.knex.schema.createTable(doctype, table => {
return this.knex.schema.createTable(doctype, (table) => {
for (let field of fields) {
this.buildColumnForTable(table, field);
}
@ -93,7 +124,7 @@ module.exports = class Database extends Observable {
let newForeignKeys = await this.getNewForeignKeys(doctype);
return this.knex.schema
.table(doctype, table => {
.table(doctype, (table) => {
if (diff.added.length) {
for (let field of diff.added) {
this.buildColumnForTable(table, field);
@ -162,7 +193,7 @@ module.exports = class Database extends Observable {
}
}
const validFieldNames = validFields.map(field => field.fieldname);
const validFieldNames = validFields.map((field) => field.fieldname);
for (let column of tableColumns) {
if (!validFieldNames.includes(column)) {
diff.removed.push(column);
@ -235,7 +266,7 @@ module.exports = class Database extends Observable {
fields: ['*'],
filters: { parent: doc.name },
orderBy: 'idx',
order: 'asc'
order: 'asc',
});
}
}
@ -246,7 +277,7 @@ module.exports = class Database extends Observable {
fields: ['fieldname', 'value'],
filters: { parent: doctype },
orderBy: 'fieldname',
order: 'asc'
order: 'asc',
});
let doc = {};
for (let row of values) {
@ -255,6 +286,38 @@ module.exports = class Database extends Observable {
return doc;
}
/**
* Get list of values from the singles table.
* @param {...string | Object} fieldnames list of fieldnames to get the values of
* @returns {Array<Object>} array of {parent, value, fieldname}.
* @example
* Database.getSingleValues('internalPrecision');
* // returns [{ fieldname: 'internalPrecision', parent: 'SystemSettings', value: '12' }]
* @example
* Database.getSingleValues({fieldname:'internalPrecision', parent: 'SystemSettings'});
* // returns [{ fieldname: 'internalPrecision', parent: 'SystemSettings', value: '12' }]
*/
async getSingleValues(...fieldnames) {
fieldnames = fieldnames.map((fieldname) => {
if (typeof fieldname === 'string') {
return { fieldname };
}
return fieldname;
});
let builder = frappe.db.knex('SingleValue');
builder = builder.where(fieldnames[0]);
fieldnames.slice(1).forEach(({ fieldname, parent }) => {
if (typeof parent === 'undefined') {
builder = builder.orWhere({ fieldname });
} else {
builder = builder.orWhere({ fieldname, parent });
}
});
return await builder.select('fieldname', 'value', 'parent');
}
getOne(doctype, name, fields = '*') {
let meta = frappe.getMeta(doctype);
let baseDoctype = meta.getBaseDocType();
@ -358,8 +421,8 @@ module.exports = class Database extends Observable {
updateOne(doctype, doc) {
let validFields = this.getValidFields(doctype);
let fieldsToUpdate = Object.keys(doc).filter(f => f !== 'name');
let fields = validFields.filter(df =>
let fieldsToUpdate = Object.keys(doc).filter((f) => f !== 'name');
let fields = validFields.filter((df) =>
fieldsToUpdate.includes(df.fieldname)
);
let formattedDoc = this.getFormattedDoc(fields, doc);
@ -396,7 +459,7 @@ module.exports = class Database extends Observable {
doctype: 'SingleValue',
parent: doctype,
fieldname: field.fieldname,
value: value
value: value,
});
await singleValue.insert();
}
@ -404,9 +467,7 @@ module.exports = class Database extends Observable {
}
deleteSingleValues(name) {
return this.knex('SingleValue')
.where('parent', name)
.delete();
return this.knex('SingleValue').where('parent', name).delete();
}
async rename(doctype, oldName, newName) {
@ -439,7 +500,7 @@ module.exports = class Database extends Observable {
getFormattedDoc(fields, doc) {
let formattedDoc = {};
fields.map(field => {
fields.map((field) => {
let value = doc[field.fieldname];
formattedDoc[field.fieldname] = this.getFormattedValue(field, value);
});
@ -507,9 +568,7 @@ module.exports = class Database extends Observable {
}
deleteChildren(parenttype, parent) {
return this.knex(parenttype)
.where('parent', parent)
.delete();
return this.knex(parenttype).where('parent', parent).delete();
}
async exists(doctype, name) {
@ -533,14 +592,14 @@ module.exports = class Database extends Observable {
start: 0,
limit: 1,
orderBy: 'name',
order: 'asc'
order: 'asc',
});
return row.length ? row[0][fieldname] : null;
}
async setValue(doctype, name, fieldname, value) {
return await this.setValues(doctype, name, {
[fieldname]: value
[fieldname]: value,
});
}
@ -565,7 +624,7 @@ module.exports = class Database extends Observable {
limit,
groupBy,
orderBy = 'creation',
order = 'desc'
order = 'desc',
} = {}) {
let meta = frappe.getMeta(doctype);
let baseDoctype = meta.getBaseDocType();
@ -643,7 +702,7 @@ module.exports = class Database extends Observable {
}
}
filtersArray.map(filter => {
filtersArray.map((filter) => {
const [field, operator, comparisonValue] = filter;
if (operator === '=') {
builder.where(field, comparisonValue);
@ -689,4 +748,8 @@ module.exports = class Database extends Observable {
initTypeMap() {
this.typeMap = {};
}
executePostDbConnect() {
frappe.initializeMoneyMaker();
}
};

View File

@ -1,5 +1,6 @@
const Observable = require('./utils/observable');
const utils = require('./utils');
const { getMoneyMaker } = require('pesa');
module.exports = {
initializeAndRegister(customModels = {}, force = false) {
@ -11,6 +12,37 @@ module.exports = {
this.registerModels(customModels);
},
async initializeMoneyMaker() {
// to be called after db initialization
const { currency, internalPrecision: precision } = (
await frappe.db.getSingleValues(
{ fieldname: 'currency', parent: 'AccountingSettings' },
{ fieldname: 'internalPrecision', parent: 'SystemSettings' }
)
).reduce((acc, { fieldname, value }) => {
acc[fieldname] = value;
return acc;
}, {});
if (typeof precision === 'undefined') {
precision = this.getMeta('SystemSettings').fields.find(
(f) => f.fieldname === 'internalPrecision'
)?.default;
}
if (typeof precision === 'undefined') {
throw new frappe.errors.NotFoundError(
'SystemSettings internalPrecision value is undefined'
);
}
if (typeof precision.value === 'string') {
precision = parseInt(precision);
}
this.pesa = getMoneyMaker({ currency, precision });
},
init(force) {
if (this._initialized && !force) return;
this.initConfig();

View File

@ -32,7 +32,7 @@
"multer": "^1.4.3",
"node-fetch": "^3.0.0",
"nunjucks": "^3.2.3",
"pesa": "latest",
"pesa": "^1.0.3",
"postcss": "^8.3.11",
"postcss-loader": "^6.2.0",
"sass-loader": "^12.3.0",

View File

@ -3417,10 +3417,10 @@ performance-now@^2.1.0:
resolved "https://registry.yarnpkg.com/performance-now/-/performance-now-2.1.0.tgz#6309f4e0e5fa913ec1c69307ae364b4b377c9e7b"
integrity sha1-Ywn04OX6kT7BxpMHrjZLSzd8nns=
pesa@latest:
version "1.0.2"
resolved "https://registry.yarnpkg.com/pesa/-/pesa-1.0.2.tgz#78410dbbebb92382cb5c4285aa0a781de2dfc769"
integrity sha512-ITR9V8bRe1GDbBQq8/SyMBtzXJlDs8ludO2ZBMtCZen6D7oqlJXVBeZQSJQs4FfoHBLKJtdsk/JvsleE5Qqu4g==
pesa@^1.0.3:
version "1.0.3"
resolved "https://registry.yarnpkg.com/pesa/-/pesa-1.0.3.tgz#e0eab7a13a6a8d0cfd1cbc0214aece6befd63a74"
integrity sha512-UGw3TPnQKAcM0EhPzQO17cXtibBcJCCqlB/hjfYtVPFAgDOIJ2kv6az9Fwq5Gflp2R7hODZlJy1cG+eL70od/g==
pg-connection-string@2.5.0:
version "2.5.0"