diff --git a/backends/database.js b/backends/database.js index d3d431fd..ca089b92 100644 --- a/backends/database.js +++ b/backends/database.js @@ -19,11 +19,12 @@ module.exports = class Database extends Observable { for (let doctype in frappe.models) { // check if controller module let meta = frappe.getMeta(doctype); + let baseDoctype = meta.getBaseDocType(); if (!meta.isSingle) { - if (await this.tableExists(doctype)) { - await this.alterTable(doctype); + if (await this.tableExists(baseDoctype)) { + await this.alterTable(baseDoctype); } else { - await this.createTable(doctype); + await this.createTable(baseDoctype); } } } @@ -197,20 +198,27 @@ module.exports = class Database extends Observable { triggerChange(doctype, name) { this.trigger(`change:${doctype}`, { name }, 500); this.trigger(`change`, { doctype, name }, 500); + // also trigger change for basedOn doctype + let meta = frappe.getMeta(doctype); + if (meta.basedOn) { + this.triggerChange(meta.basedOn, name); + } } async insert(doctype, doc) { let meta = frappe.getMeta(doctype); + let baseDoctype = meta.getBaseDocType(); + doc = this.applyBaseDocTypeFilters(doctype, doc); // insert parent if (meta.isSingle) { await this.updateSingle(meta, doc, doctype); } else { - await this.insertOne(doctype, doc); + await this.insertOne(baseDoctype, doc); } // insert children - await this.insertChildren(meta, doc, doctype); + await this.insertChildren(meta, doc, baseDoctype); this.triggerChange(doctype, doc.name); @@ -236,16 +244,18 @@ module.exports = class Database extends Observable { async update(doctype, doc) { let meta = frappe.getMeta(doctype); + let baseDoctype = meta.getBaseDocType(); + doc = this.applyBaseDocTypeFilters(doctype, doc); // update parent if (meta.isSingle) { await this.updateSingle(meta, doc, doctype); } else { - await this.updateOne(doctype, doc); + await this.updateOne(baseDoctype, doc); } // insert or update children - await this.updateChildren(meta, doc, doctype); + await this.updateChildren(meta, doc, baseDoctype); this.triggerChange(doctype, doc.name); @@ -343,6 +353,19 @@ module.exports = class Database extends Observable { } } + applyBaseDocTypeFilters(doctype, doc) { + let meta = frappe.getMeta(doctype); + if (meta.filters) { + for (let fieldname in meta.filters) { + let value = meta.filters[fieldname]; + if (typeof value !== 'object') { + doc[fieldname] = value; + } + } + } + return doc; + } + async deleteMany(doctype, names) { for (const name of names) { await this.delete(doctype, name); @@ -350,7 +373,9 @@ module.exports = class Database extends Observable { } async delete(doctype, name) { - await this.deleteOne(doctype, name); + let meta = frappe.getMeta(doctype); + let baseDoctype = meta.getBaseDocType(); + await this.deleteOne(baseDoctype, name); // delete children let tableFields = frappe.getMeta(doctype).getTableFields(); @@ -374,12 +399,17 @@ module.exports = class Database extends Observable { } async getValue(doctype, filters, fieldname = 'name') { + let meta = frappe.getMeta(doctype); + let baseDoctype = meta.getBaseDocType(); if (typeof filters === 'string') { filters = { name: filters }; } + if (meta.filters) { + Object.assign(filters, meta.filters); + } let row = await this.getAll({ - doctype: doctype, + doctype: baseDoctype, fields: [fieldname], filters: filters, start: 0, diff --git a/backends/sqlite.js b/backends/sqlite.js index b2e0e9ef..1c691712 100644 --- a/backends/sqlite.js +++ b/backends/sqlite.js @@ -103,9 +103,11 @@ module.exports = class sqliteDatabase extends Database { } getOne(doctype, name, fields = '*') { + let meta = frappe.getMeta(doctype); + let baseDoctype = meta.getBaseDocType(); fields = this.prepareFields(fields); return new Promise((resolve, reject) => { - this.conn.get(`select ${fields} from ${doctype} + this.conn.get(`select ${fields} from ${baseDoctype} where name = ?`, name, (err, row) => { resolve(row || {}); @@ -160,12 +162,15 @@ module.exports = class sqliteDatabase extends Database { } async rename(doctype, oldName, newName) { + let meta = frappe.getMeta(doctype); + let baseDoctype = meta.getBaseDocType(); await frappe.db.run(`update ${baseDoctype} set name = ? where name = ?`, [newName, oldName]); await frappe.db.commit(); } async setValues(doctype, name, fieldValuePair) { const meta = frappe.getMeta(doctype); + const baseDoctype = meta.getBaseDocType(); const validFields = this.getKeys(doctype); const validFieldnames = validFields.map(df => df.fieldname); const fieldsToUpdate = Object.keys(fieldValuePair) @@ -184,22 +189,27 @@ module.exports = class sqliteDatabase extends Database { // additional name for where clause values.push(name); - return await this.run(`update ${doctype} + return await this.run(`update ${baseDoctype} set ${assigns.join(', ')} where name=?`, values); } getAll({ doctype, fields, filters, start, limit, orderBy = 'modified', groupBy, order = 'desc' } = {}) { + let meta = frappe.getMeta(doctype); + let baseDoctype = meta.getBaseDocType(); if (!fields) { - fields = frappe.getMeta(doctype).getKeywordFields(); + fields = meta.getKeywordFields(); } if (typeof fields === 'string') { fields = [fields]; } + if (meta.filters) { + Object.assign(filters, meta.filters); + } return new Promise((resolve, reject) => { let conditions = this.getFilterConditions(filters); let query = `select ${fields.join(", ")} - from ${doctype} + from ${baseDoctype} ${conditions.conditions ? "where" : ""} ${conditions.conditions} ${groupBy ? ("group by " + groupBy.join(', ')) : ""} ${orderBy ? ("order by " + orderBy) : ""} ${orderBy ? (order || "asc") : ""} diff --git a/model/meta.js b/model/meta.js index 20aaba78..8e334881 100644 --- a/model/meta.js +++ b/model/meta.js @@ -5,6 +5,14 @@ const indicatorColor = require('frappejs/ui/constants/indicators'); module.exports = class BaseMeta extends BaseDocument { constructor(data) { + if (data.basedOn) { + let config = frappe.models[data.basedOn]; + Object.assign(data, config, { + name: data.name, + label: data.label, + filters: data.filters + }) + } super(data); this.setDefaultIndicators(); if (this.setupMeta) { @@ -86,6 +94,10 @@ module.exports = class BaseMeta extends BaseDocument { return this._hasFormula; } + getBaseDocType() { + return this.basedOn || this.name; + } + async set(fieldname, value) { this[fieldname] = value; await this.trigger(fieldname); @@ -196,6 +208,10 @@ module.exports = class BaseMeta extends BaseDocument { return this._keywordFields; } + getQuickEditFields() { + return this.quickEditFields || this.getKeywordFields(); + } + validateSelect(field, value) { let options = field.options; if (!options) return;