mirror of
https://github.com/frappe/books.git
synced 2024-12-26 04:17:36 +00:00
feat: Create DocTypes based on another DocType
This commit is contained in:
parent
700ee9c55c
commit
216e70a132
@ -19,11 +19,12 @@ module.exports = class Database extends Observable {
|
|||||||
for (let doctype in frappe.models) {
|
for (let doctype in frappe.models) {
|
||||||
// check if controller module
|
// check if controller module
|
||||||
let meta = frappe.getMeta(doctype);
|
let meta = frappe.getMeta(doctype);
|
||||||
|
let baseDoctype = meta.getBaseDocType();
|
||||||
if (!meta.isSingle) {
|
if (!meta.isSingle) {
|
||||||
if (await this.tableExists(doctype)) {
|
if (await this.tableExists(baseDoctype)) {
|
||||||
await this.alterTable(doctype);
|
await this.alterTable(baseDoctype);
|
||||||
} else {
|
} else {
|
||||||
await this.createTable(doctype);
|
await this.createTable(baseDoctype);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -197,20 +198,27 @@ module.exports = class Database extends Observable {
|
|||||||
triggerChange(doctype, name) {
|
triggerChange(doctype, name) {
|
||||||
this.trigger(`change:${doctype}`, { name }, 500);
|
this.trigger(`change:${doctype}`, { name }, 500);
|
||||||
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) {
|
async insert(doctype, doc) {
|
||||||
let meta = frappe.getMeta(doctype);
|
let meta = frappe.getMeta(doctype);
|
||||||
|
let baseDoctype = meta.getBaseDocType();
|
||||||
|
doc = this.applyBaseDocTypeFilters(doctype, doc);
|
||||||
|
|
||||||
// insert parent
|
// insert parent
|
||||||
if (meta.isSingle) {
|
if (meta.isSingle) {
|
||||||
await this.updateSingle(meta, doc, doctype);
|
await this.updateSingle(meta, doc, doctype);
|
||||||
} else {
|
} else {
|
||||||
await this.insertOne(doctype, doc);
|
await this.insertOne(baseDoctype, doc);
|
||||||
}
|
}
|
||||||
|
|
||||||
// insert children
|
// insert children
|
||||||
await this.insertChildren(meta, doc, doctype);
|
await this.insertChildren(meta, doc, baseDoctype);
|
||||||
|
|
||||||
this.triggerChange(doctype, doc.name);
|
this.triggerChange(doctype, doc.name);
|
||||||
|
|
||||||
@ -236,16 +244,18 @@ module.exports = class Database extends Observable {
|
|||||||
|
|
||||||
async update(doctype, doc) {
|
async update(doctype, doc) {
|
||||||
let meta = frappe.getMeta(doctype);
|
let meta = frappe.getMeta(doctype);
|
||||||
|
let baseDoctype = meta.getBaseDocType();
|
||||||
|
doc = this.applyBaseDocTypeFilters(doctype, doc);
|
||||||
|
|
||||||
// update parent
|
// update parent
|
||||||
if (meta.isSingle) {
|
if (meta.isSingle) {
|
||||||
await this.updateSingle(meta, doc, doctype);
|
await this.updateSingle(meta, doc, doctype);
|
||||||
} else {
|
} else {
|
||||||
await this.updateOne(doctype, doc);
|
await this.updateOne(baseDoctype, doc);
|
||||||
}
|
}
|
||||||
|
|
||||||
// insert or update children
|
// insert or update children
|
||||||
await this.updateChildren(meta, doc, doctype);
|
await this.updateChildren(meta, doc, baseDoctype);
|
||||||
|
|
||||||
this.triggerChange(doctype, doc.name);
|
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) {
|
async deleteMany(doctype, names) {
|
||||||
for (const name of names) {
|
for (const name of names) {
|
||||||
await this.delete(doctype, name);
|
await this.delete(doctype, name);
|
||||||
@ -350,7 +373,9 @@ module.exports = class Database extends Observable {
|
|||||||
}
|
}
|
||||||
|
|
||||||
async delete(doctype, name) {
|
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
|
// delete children
|
||||||
let tableFields = frappe.getMeta(doctype).getTableFields();
|
let tableFields = frappe.getMeta(doctype).getTableFields();
|
||||||
@ -374,12 +399,17 @@ module.exports = class Database extends Observable {
|
|||||||
}
|
}
|
||||||
|
|
||||||
async getValue(doctype, filters, fieldname = 'name') {
|
async getValue(doctype, filters, fieldname = 'name') {
|
||||||
|
let meta = frappe.getMeta(doctype);
|
||||||
|
let baseDoctype = meta.getBaseDocType();
|
||||||
if (typeof filters === 'string') {
|
if (typeof filters === 'string') {
|
||||||
filters = { name: filters };
|
filters = { name: filters };
|
||||||
}
|
}
|
||||||
|
if (meta.filters) {
|
||||||
|
Object.assign(filters, meta.filters);
|
||||||
|
}
|
||||||
|
|
||||||
let row = await this.getAll({
|
let row = await this.getAll({
|
||||||
doctype: doctype,
|
doctype: baseDoctype,
|
||||||
fields: [fieldname],
|
fields: [fieldname],
|
||||||
filters: filters,
|
filters: filters,
|
||||||
start: 0,
|
start: 0,
|
||||||
|
@ -103,9 +103,11 @@ module.exports = class sqliteDatabase extends Database {
|
|||||||
}
|
}
|
||||||
|
|
||||||
getOne(doctype, name, fields = '*') {
|
getOne(doctype, name, fields = '*') {
|
||||||
|
let meta = frappe.getMeta(doctype);
|
||||||
|
let baseDoctype = meta.getBaseDocType();
|
||||||
fields = this.prepareFields(fields);
|
fields = this.prepareFields(fields);
|
||||||
return new Promise((resolve, reject) => {
|
return new Promise((resolve, reject) => {
|
||||||
this.conn.get(`select ${fields} from ${doctype}
|
this.conn.get(`select ${fields} from ${baseDoctype}
|
||||||
where name = ?`, name,
|
where name = ?`, name,
|
||||||
(err, row) => {
|
(err, row) => {
|
||||||
resolve(row || {});
|
resolve(row || {});
|
||||||
@ -160,12 +162,15 @@ module.exports = class sqliteDatabase extends Database {
|
|||||||
}
|
}
|
||||||
|
|
||||||
async rename(doctype, oldName, newName) {
|
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.run(`update ${baseDoctype} set name = ? where name = ?`, [newName, oldName]);
|
||||||
await frappe.db.commit();
|
await frappe.db.commit();
|
||||||
}
|
}
|
||||||
|
|
||||||
async setValues(doctype, name, fieldValuePair) {
|
async setValues(doctype, name, fieldValuePair) {
|
||||||
const meta = frappe.getMeta(doctype);
|
const meta = frappe.getMeta(doctype);
|
||||||
|
const baseDoctype = meta.getBaseDocType();
|
||||||
const validFields = this.getKeys(doctype);
|
const validFields = this.getKeys(doctype);
|
||||||
const validFieldnames = validFields.map(df => df.fieldname);
|
const validFieldnames = validFields.map(df => df.fieldname);
|
||||||
const fieldsToUpdate = Object.keys(fieldValuePair)
|
const fieldsToUpdate = Object.keys(fieldValuePair)
|
||||||
@ -184,22 +189,27 @@ module.exports = class sqliteDatabase extends Database {
|
|||||||
// additional name for where clause
|
// additional name for where clause
|
||||||
values.push(name);
|
values.push(name);
|
||||||
|
|
||||||
return await this.run(`update ${doctype}
|
return await this.run(`update ${baseDoctype}
|
||||||
set ${assigns.join(', ')} where name=?`, values);
|
set ${assigns.join(', ')} where name=?`, values);
|
||||||
}
|
}
|
||||||
|
|
||||||
getAll({ doctype, fields, filters, start, limit, orderBy = 'modified', groupBy, order = 'desc' } = {}) {
|
getAll({ doctype, fields, filters, start, limit, orderBy = 'modified', groupBy, order = 'desc' } = {}) {
|
||||||
|
let meta = frappe.getMeta(doctype);
|
||||||
|
let baseDoctype = meta.getBaseDocType();
|
||||||
if (!fields) {
|
if (!fields) {
|
||||||
fields = frappe.getMeta(doctype).getKeywordFields();
|
fields = meta.getKeywordFields();
|
||||||
}
|
}
|
||||||
if (typeof fields === 'string') {
|
if (typeof fields === 'string') {
|
||||||
fields = [fields];
|
fields = [fields];
|
||||||
}
|
}
|
||||||
|
if (meta.filters) {
|
||||||
|
Object.assign(filters, meta.filters);
|
||||||
|
}
|
||||||
|
|
||||||
return new Promise((resolve, reject) => {
|
return new Promise((resolve, reject) => {
|
||||||
let conditions = this.getFilterConditions(filters);
|
let conditions = this.getFilterConditions(filters);
|
||||||
let query = `select ${fields.join(", ")}
|
let query = `select ${fields.join(", ")}
|
||||||
from ${doctype}
|
from ${baseDoctype}
|
||||||
${conditions.conditions ? "where" : ""} ${conditions.conditions}
|
${conditions.conditions ? "where" : ""} ${conditions.conditions}
|
||||||
${groupBy ? ("group by " + groupBy.join(', ')) : ""}
|
${groupBy ? ("group by " + groupBy.join(', ')) : ""}
|
||||||
${orderBy ? ("order by " + orderBy) : ""} ${orderBy ? (order || "asc") : ""}
|
${orderBy ? ("order by " + orderBy) : ""} ${orderBy ? (order || "asc") : ""}
|
||||||
|
@ -5,6 +5,14 @@ const indicatorColor = require('frappejs/ui/constants/indicators');
|
|||||||
|
|
||||||
module.exports = class BaseMeta extends BaseDocument {
|
module.exports = class BaseMeta extends BaseDocument {
|
||||||
constructor(data) {
|
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);
|
super(data);
|
||||||
this.setDefaultIndicators();
|
this.setDefaultIndicators();
|
||||||
if (this.setupMeta) {
|
if (this.setupMeta) {
|
||||||
@ -86,6 +94,10 @@ module.exports = class BaseMeta extends BaseDocument {
|
|||||||
return this._hasFormula;
|
return this._hasFormula;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
getBaseDocType() {
|
||||||
|
return this.basedOn || this.name;
|
||||||
|
}
|
||||||
|
|
||||||
async set(fieldname, value) {
|
async set(fieldname, value) {
|
||||||
this[fieldname] = value;
|
this[fieldname] = value;
|
||||||
await this.trigger(fieldname);
|
await this.trigger(fieldname);
|
||||||
@ -196,6 +208,10 @@ module.exports = class BaseMeta extends BaseDocument {
|
|||||||
return this._keywordFields;
|
return this._keywordFields;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
getQuickEditFields() {
|
||||||
|
return this.quickEditFields || this.getKeywordFields();
|
||||||
|
}
|
||||||
|
|
||||||
validateSelect(field, value) {
|
validateSelect(field, value) {
|
||||||
let options = field.options;
|
let options = field.options;
|
||||||
if (!options) return;
|
if (!options) return;
|
||||||
|
Loading…
Reference in New Issue
Block a user