From d19182b583de5d45c49386e33a91d942b5244358 Mon Sep 17 00:00:00 2001 From: Faris Ansari Date: Wed, 18 Dec 2019 23:52:47 +0530 Subject: [PATCH] fix: Singles - Initialize defaults for SIngles - Cast values when loading a Single document --- backends/database.js | 41 +++++++++++++++++++++++++++++++++++++---- model/document.js | 42 +++++++++++++++++++++++++++++------------- model/meta.js | 4 +++- 3 files changed, 69 insertions(+), 18 deletions(-) diff --git a/backends/database.js b/backends/database.js index b3724098..f85c6268 100644 --- a/backends/database.js +++ b/backends/database.js @@ -36,6 +36,38 @@ module.exports = class Database extends Observable { } } await this.commit(); + await this.initializeSingles(); + } + + async initializeSingles() { + let singleDoctypes = frappe + .getModels(model => model.isSingle) + .map(model => model.name); + + for (let doctype of singleDoctypes) { + if (await this.singleExists(doctype)) { + continue; + } + let meta = frappe.getMeta(doctype); + if (meta.fields.every(df => df.default == null)) { + continue; + } + let defaultValues = meta.fields.reduce((doc, df) => { + if (df.default != null) { + doc[df.fieldname] = df.default; + } + return doc; + }, {}); + await this.updateSingle(doctype, defaultValues); + } + } + + async singleExists(doctype) { + let res = await this.knex('SingleValue') + .count('parent as count') + .where('parent', doctype) + .first(); + return res.count > 0; } tableExists(table) { @@ -245,7 +277,7 @@ module.exports = class Database extends Observable { // insert parent if (meta.isSingle) { - await this.updateSingle(meta, doc, doctype); + await this.updateSingle(doctype, doc); } else { await this.insertOne(baseDoctype, doc); } @@ -288,7 +320,7 @@ module.exports = class Database extends Observable { // update parent if (meta.isSingle) { - await this.updateSingle(meta, doc, doctype); + await this.updateSingle(doctype, doc); } else { await this.updateOne(baseDoctype, doc); } @@ -348,11 +380,12 @@ module.exports = class Database extends Observable { .delete(); } - async updateSingle(meta, doc, doctype) { + async updateSingle(doctype, doc) { + let meta = frappe.getMeta(doctype); await this.deleteSingleValues(doctype); for (let field of meta.getValidFields({ withChildren: false })) { let value = doc[field.fieldname]; - if (value) { + if (value != null) { let singleValue = frappe.newDoc({ doctype: 'SingleValue', parent: doctype, diff --git a/model/document.js b/model/document.js index 8378d0b4..5f30091f 100644 --- a/model/document.js +++ b/model/document.js @@ -86,19 +86,19 @@ module.exports = class BaseDocument extends Observable { if (this.meta.isChild && this.parentdoc) { await this.parentdoc.applyChange(this.parentfield); } else { - await this.applyChange(fieldname); + await this.applyChange(fieldname); + } } } - } async applyChange(fieldname) { await this.applyFormula(fieldname); this.roundFloats(); - await this.trigger('change', { - doc: this, - changed: fieldname - }); - } + await this.trigger('change', { + doc: this, + changed: fieldname + }); + } setDefaults() { for (let field of this.meta.fields) { @@ -121,6 +121,21 @@ module.exports = class BaseDocument extends Observable { } } + castValues() { + for (let field of this.meta.fields) { + let value = this[field.fieldname]; + if (value == null) { + continue; + } + if (['Int', 'Check'].includes(field.fieldtype)) { + value = parseInt(value, 10); + } else if (['Float', 'Currency'].includes(field.fieldtype)) { + value = parseFloat(value); + } + this[field.fieldname] = value; + } + } + setKeywords() { let keywords = []; for (let fieldname of this.meta.getKeywordFields()) { @@ -229,6 +244,7 @@ module.exports = class BaseDocument extends Observable { this.syncValues(data); if (this.meta.isSingle) { this.setDefaults(); + this.castValues(); } await this.loadLinks(); } else { @@ -249,13 +265,13 @@ module.exports = class BaseDocument extends Observable { async loadLink(fieldname) { this._links = this._links || {}; let df = this.meta.getField(fieldname); - if (this[df.fieldname]) { - this._links[df.fieldname] = await frappe.getDoc( - df.target, - this[df.fieldname] - ); - } + if (this[df.fieldname]) { + this._links[df.fieldname] = await frappe.getDoc( + df.target, + this[df.fieldname] + ); } + } getLink(fieldname) { return this._links ? this._links[fieldname] : null; diff --git a/model/meta.js b/model/meta.js index 65edf0d8..9696ab3c 100644 --- a/model/meta.js +++ b/model/meta.js @@ -50,7 +50,9 @@ module.exports = class BaseMeta extends BaseDocument { // attach default precision to Float and Currency if (['Float', 'Currency'].includes(df.fieldtype)) { - let defaultPrecision = frappe.SystemSettings ? frappe.SystemSettings.floatPrecision : 2; + let defaultPrecision = frappe.SystemSettings + ? frappe.SystemSettings.floatPrecision + : 2; df.precision = df.precision || defaultPrecision; } return df;