mirror of
https://github.com/frappe/books.git
synced 2024-11-10 07:40:55 +00:00
feat: init pesa and set on the frappe object
This commit is contained in:
parent
b746200050
commit
7698af67e6
@ -13,9 +13,10 @@ module.exports = class Database extends Observable {
|
|||||||
|
|
||||||
connect() {
|
connect() {
|
||||||
this.knex = Knex(this.connectionParams);
|
this.knex = Knex(this.connectionParams);
|
||||||
this.knex.on('query-error', error => {
|
this.knex.on('query-error', (error) => {
|
||||||
error.type = this.getError(error);
|
error.type = this.getError(error);
|
||||||
});
|
});
|
||||||
|
this.executePostDbConnect();
|
||||||
}
|
}
|
||||||
|
|
||||||
close() {
|
close() {
|
||||||
@ -41,15 +42,25 @@ module.exports = class Database extends Observable {
|
|||||||
|
|
||||||
async initializeSingles() {
|
async initializeSingles() {
|
||||||
let singleDoctypes = frappe
|
let singleDoctypes = frappe
|
||||||
.getModels(model => model.isSingle)
|
.getModels((model) => model.isSingle)
|
||||||
.map(model => model.name);
|
.map((model) => model.name);
|
||||||
|
|
||||||
for (let doctype of singleDoctypes) {
|
for (let doctype of singleDoctypes) {
|
||||||
if (await this.singleExists(doctype)) {
|
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;
|
continue;
|
||||||
}
|
}
|
||||||
let meta = frappe.getMeta(doctype);
|
let meta = frappe.getMeta(doctype);
|
||||||
if (meta.fields.every(df => df.default == null)) {
|
if (meta.fields.every((df) => df.default == null)) {
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
let defaultValues = meta.fields.reduce((doc, df) => {
|
let defaultValues = meta.fields.reduce((doc, df) => {
|
||||||
@ -70,6 +81,26 @@ module.exports = class Database extends Observable {
|
|||||||
return res.count > 0;
|
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) {
|
tableExists(table) {
|
||||||
return this.knex.schema.hasTable(table);
|
return this.knex.schema.hasTable(table);
|
||||||
}
|
}
|
||||||
@ -80,7 +111,7 @@ module.exports = class Database extends Observable {
|
|||||||
}
|
}
|
||||||
|
|
||||||
runCreateTableQuery(doctype, fields) {
|
runCreateTableQuery(doctype, fields) {
|
||||||
return this.knex.schema.createTable(doctype, table => {
|
return this.knex.schema.createTable(doctype, (table) => {
|
||||||
for (let field of fields) {
|
for (let field of fields) {
|
||||||
this.buildColumnForTable(table, field);
|
this.buildColumnForTable(table, field);
|
||||||
}
|
}
|
||||||
@ -93,7 +124,7 @@ module.exports = class Database extends Observable {
|
|||||||
let newForeignKeys = await this.getNewForeignKeys(doctype);
|
let newForeignKeys = await this.getNewForeignKeys(doctype);
|
||||||
|
|
||||||
return this.knex.schema
|
return this.knex.schema
|
||||||
.table(doctype, table => {
|
.table(doctype, (table) => {
|
||||||
if (diff.added.length) {
|
if (diff.added.length) {
|
||||||
for (let field of diff.added) {
|
for (let field of diff.added) {
|
||||||
this.buildColumnForTable(table, field);
|
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) {
|
for (let column of tableColumns) {
|
||||||
if (!validFieldNames.includes(column)) {
|
if (!validFieldNames.includes(column)) {
|
||||||
diff.removed.push(column);
|
diff.removed.push(column);
|
||||||
@ -235,7 +266,7 @@ module.exports = class Database extends Observable {
|
|||||||
fields: ['*'],
|
fields: ['*'],
|
||||||
filters: { parent: doc.name },
|
filters: { parent: doc.name },
|
||||||
orderBy: 'idx',
|
orderBy: 'idx',
|
||||||
order: 'asc'
|
order: 'asc',
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -246,7 +277,7 @@ module.exports = class Database extends Observable {
|
|||||||
fields: ['fieldname', 'value'],
|
fields: ['fieldname', 'value'],
|
||||||
filters: { parent: doctype },
|
filters: { parent: doctype },
|
||||||
orderBy: 'fieldname',
|
orderBy: 'fieldname',
|
||||||
order: 'asc'
|
order: 'asc',
|
||||||
});
|
});
|
||||||
let doc = {};
|
let doc = {};
|
||||||
for (let row of values) {
|
for (let row of values) {
|
||||||
@ -255,6 +286,38 @@ module.exports = class Database extends Observable {
|
|||||||
return doc;
|
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 = '*') {
|
getOne(doctype, name, fields = '*') {
|
||||||
let meta = frappe.getMeta(doctype);
|
let meta = frappe.getMeta(doctype);
|
||||||
let baseDoctype = meta.getBaseDocType();
|
let baseDoctype = meta.getBaseDocType();
|
||||||
@ -358,8 +421,8 @@ module.exports = class Database extends Observable {
|
|||||||
|
|
||||||
updateOne(doctype, doc) {
|
updateOne(doctype, doc) {
|
||||||
let validFields = this.getValidFields(doctype);
|
let validFields = this.getValidFields(doctype);
|
||||||
let fieldsToUpdate = Object.keys(doc).filter(f => f !== 'name');
|
let fieldsToUpdate = Object.keys(doc).filter((f) => f !== 'name');
|
||||||
let fields = validFields.filter(df =>
|
let fields = validFields.filter((df) =>
|
||||||
fieldsToUpdate.includes(df.fieldname)
|
fieldsToUpdate.includes(df.fieldname)
|
||||||
);
|
);
|
||||||
let formattedDoc = this.getFormattedDoc(fields, doc);
|
let formattedDoc = this.getFormattedDoc(fields, doc);
|
||||||
@ -396,7 +459,7 @@ module.exports = class Database extends Observable {
|
|||||||
doctype: 'SingleValue',
|
doctype: 'SingleValue',
|
||||||
parent: doctype,
|
parent: doctype,
|
||||||
fieldname: field.fieldname,
|
fieldname: field.fieldname,
|
||||||
value: value
|
value: value,
|
||||||
});
|
});
|
||||||
await singleValue.insert();
|
await singleValue.insert();
|
||||||
}
|
}
|
||||||
@ -404,9 +467,7 @@ module.exports = class Database extends Observable {
|
|||||||
}
|
}
|
||||||
|
|
||||||
deleteSingleValues(name) {
|
deleteSingleValues(name) {
|
||||||
return this.knex('SingleValue')
|
return this.knex('SingleValue').where('parent', name).delete();
|
||||||
.where('parent', name)
|
|
||||||
.delete();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
async rename(doctype, oldName, newName) {
|
async rename(doctype, oldName, newName) {
|
||||||
@ -439,7 +500,7 @@ module.exports = class Database extends Observable {
|
|||||||
|
|
||||||
getFormattedDoc(fields, doc) {
|
getFormattedDoc(fields, doc) {
|
||||||
let formattedDoc = {};
|
let formattedDoc = {};
|
||||||
fields.map(field => {
|
fields.map((field) => {
|
||||||
let value = doc[field.fieldname];
|
let value = doc[field.fieldname];
|
||||||
formattedDoc[field.fieldname] = this.getFormattedValue(field, value);
|
formattedDoc[field.fieldname] = this.getFormattedValue(field, value);
|
||||||
});
|
});
|
||||||
@ -507,9 +568,7 @@ module.exports = class Database extends Observable {
|
|||||||
}
|
}
|
||||||
|
|
||||||
deleteChildren(parenttype, parent) {
|
deleteChildren(parenttype, parent) {
|
||||||
return this.knex(parenttype)
|
return this.knex(parenttype).where('parent', parent).delete();
|
||||||
.where('parent', parent)
|
|
||||||
.delete();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
async exists(doctype, name) {
|
async exists(doctype, name) {
|
||||||
@ -533,14 +592,14 @@ module.exports = class Database extends Observable {
|
|||||||
start: 0,
|
start: 0,
|
||||||
limit: 1,
|
limit: 1,
|
||||||
orderBy: 'name',
|
orderBy: 'name',
|
||||||
order: 'asc'
|
order: 'asc',
|
||||||
});
|
});
|
||||||
return row.length ? row[0][fieldname] : null;
|
return row.length ? row[0][fieldname] : null;
|
||||||
}
|
}
|
||||||
|
|
||||||
async setValue(doctype, name, fieldname, value) {
|
async setValue(doctype, name, fieldname, value) {
|
||||||
return await this.setValues(doctype, name, {
|
return await this.setValues(doctype, name, {
|
||||||
[fieldname]: value
|
[fieldname]: value,
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -565,7 +624,7 @@ module.exports = class Database extends Observable {
|
|||||||
limit,
|
limit,
|
||||||
groupBy,
|
groupBy,
|
||||||
orderBy = 'creation',
|
orderBy = 'creation',
|
||||||
order = 'desc'
|
order = 'desc',
|
||||||
} = {}) {
|
} = {}) {
|
||||||
let meta = frappe.getMeta(doctype);
|
let meta = frappe.getMeta(doctype);
|
||||||
let baseDoctype = meta.getBaseDocType();
|
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;
|
const [field, operator, comparisonValue] = filter;
|
||||||
if (operator === '=') {
|
if (operator === '=') {
|
||||||
builder.where(field, comparisonValue);
|
builder.where(field, comparisonValue);
|
||||||
@ -689,4 +748,8 @@ module.exports = class Database extends Observable {
|
|||||||
initTypeMap() {
|
initTypeMap() {
|
||||||
this.typeMap = {};
|
this.typeMap = {};
|
||||||
}
|
}
|
||||||
|
|
||||||
|
executePostDbConnect() {
|
||||||
|
frappe.initializeMoneyMaker();
|
||||||
|
}
|
||||||
};
|
};
|
||||||
|
32
index.js
32
index.js
@ -1,5 +1,6 @@
|
|||||||
const Observable = require('./utils/observable');
|
const Observable = require('./utils/observable');
|
||||||
const utils = require('./utils');
|
const utils = require('./utils');
|
||||||
|
const { getMoneyMaker } = require('pesa');
|
||||||
|
|
||||||
module.exports = {
|
module.exports = {
|
||||||
initializeAndRegister(customModels = {}, force = false) {
|
initializeAndRegister(customModels = {}, force = false) {
|
||||||
@ -11,6 +12,37 @@ module.exports = {
|
|||||||
this.registerModels(customModels);
|
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) {
|
init(force) {
|
||||||
if (this._initialized && !force) return;
|
if (this._initialized && !force) return;
|
||||||
this.initConfig();
|
this.initConfig();
|
||||||
|
@ -32,7 +32,7 @@
|
|||||||
"multer": "^1.4.3",
|
"multer": "^1.4.3",
|
||||||
"node-fetch": "^3.0.0",
|
"node-fetch": "^3.0.0",
|
||||||
"nunjucks": "^3.2.3",
|
"nunjucks": "^3.2.3",
|
||||||
"pesa": "latest",
|
"pesa": "^1.0.3",
|
||||||
"postcss": "^8.3.11",
|
"postcss": "^8.3.11",
|
||||||
"postcss-loader": "^6.2.0",
|
"postcss-loader": "^6.2.0",
|
||||||
"sass-loader": "^12.3.0",
|
"sass-loader": "^12.3.0",
|
||||||
|
@ -3417,10 +3417,10 @@ performance-now@^2.1.0:
|
|||||||
resolved "https://registry.yarnpkg.com/performance-now/-/performance-now-2.1.0.tgz#6309f4e0e5fa913ec1c69307ae364b4b377c9e7b"
|
resolved "https://registry.yarnpkg.com/performance-now/-/performance-now-2.1.0.tgz#6309f4e0e5fa913ec1c69307ae364b4b377c9e7b"
|
||||||
integrity sha1-Ywn04OX6kT7BxpMHrjZLSzd8nns=
|
integrity sha1-Ywn04OX6kT7BxpMHrjZLSzd8nns=
|
||||||
|
|
||||||
pesa@latest:
|
pesa@^1.0.3:
|
||||||
version "1.0.2"
|
version "1.0.3"
|
||||||
resolved "https://registry.yarnpkg.com/pesa/-/pesa-1.0.2.tgz#78410dbbebb92382cb5c4285aa0a781de2dfc769"
|
resolved "https://registry.yarnpkg.com/pesa/-/pesa-1.0.3.tgz#e0eab7a13a6a8d0cfd1cbc0214aece6befd63a74"
|
||||||
integrity sha512-ITR9V8bRe1GDbBQq8/SyMBtzXJlDs8ludO2ZBMtCZen6D7oqlJXVBeZQSJQs4FfoHBLKJtdsk/JvsleE5Qqu4g==
|
integrity sha512-UGw3TPnQKAcM0EhPzQO17cXtibBcJCCqlB/hjfYtVPFAgDOIJ2kv6az9Fwq5Gflp2R7hODZlJy1cG+eL70od/g==
|
||||||
|
|
||||||
pg-connection-string@2.5.0:
|
pg-connection-string@2.5.0:
|
||||||
version "2.5.0"
|
version "2.5.0"
|
||||||
|
Loading…
Reference in New Issue
Block a user