mirror of
https://github.com/frappe/books.git
synced 2024-12-23 03:19:01 +00:00
fix: transitive dependent field updates
This commit is contained in:
parent
537a8f7153
commit
d986471323
@ -186,7 +186,8 @@ export class Doc extends Observable<DocValue | Doc[]> {
|
|||||||
// set value and trigger change
|
// set value and trigger change
|
||||||
async set(
|
async set(
|
||||||
fieldname: string | DocValueMap,
|
fieldname: string | DocValueMap,
|
||||||
value?: DocValue | Doc[] | DocValueMap[]
|
value?: DocValue | Doc[] | DocValueMap[],
|
||||||
|
retriggerChildDocApplyChange: boolean = false
|
||||||
): Promise<boolean> {
|
): Promise<boolean> {
|
||||||
if (typeof fieldname === 'object') {
|
if (typeof fieldname === 'object') {
|
||||||
return await this.setMultiple(fieldname as DocValueMap);
|
return await this.setMultiple(fieldname as DocValueMap);
|
||||||
@ -216,7 +217,7 @@ export class Doc extends Observable<DocValue | Doc[]> {
|
|||||||
await this._applyChange(fieldname);
|
await this._applyChange(fieldname);
|
||||||
await this.parentdoc._applyChange(this.parentFieldname as string);
|
await this.parentdoc._applyChange(this.parentFieldname as string);
|
||||||
} else {
|
} else {
|
||||||
await this._applyChange(fieldname);
|
await this._applyChange(fieldname, retriggerChildDocApplyChange);
|
||||||
}
|
}
|
||||||
|
|
||||||
return true;
|
return true;
|
||||||
@ -259,8 +260,11 @@ export class Doc extends Observable<DocValue | Doc[]> {
|
|||||||
return !areDocValuesEqual(currentValue as DocValue, value as DocValue);
|
return !areDocValuesEqual(currentValue as DocValue, value as DocValue);
|
||||||
}
|
}
|
||||||
|
|
||||||
async _applyChange(fieldname: string): Promise<boolean> {
|
async _applyChange(
|
||||||
await this._applyFormula(fieldname);
|
fieldname: string,
|
||||||
|
retriggerChildDocApplyChange?: boolean
|
||||||
|
): Promise<boolean> {
|
||||||
|
await this._applyFormula(fieldname, retriggerChildDocApplyChange);
|
||||||
await this.trigger('change', {
|
await this.trigger('change', {
|
||||||
doc: this,
|
doc: this,
|
||||||
changed: fieldname,
|
changed: fieldname,
|
||||||
@ -616,37 +620,62 @@ export class Doc extends Observable<DocValue | Doc[]> {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
async _applyFormula(fieldname?: string): Promise<boolean> {
|
async _applyFormula(
|
||||||
|
fieldname?: string,
|
||||||
|
retriggerChildDocApplyChange?: boolean
|
||||||
|
): Promise<boolean> {
|
||||||
const doc = this;
|
const doc = this;
|
||||||
let changed = false;
|
let changed = await this._callAllTableFieldsApplyFormula(fieldname);
|
||||||
|
changed = (await this._applyFormulaForFields(doc, fieldname)) || changed;
|
||||||
|
|
||||||
const childDocs = this.tableFields
|
if (changed && retriggerChildDocApplyChange) {
|
||||||
.map((f) => (this.get(f.fieldname) as Doc[]) ?? [])
|
await this._callAllTableFieldsApplyFormula(fieldname);
|
||||||
.flat();
|
await this._applyFormulaForFields(doc, fieldname);
|
||||||
|
|
||||||
// children
|
|
||||||
for (const row of childDocs) {
|
|
||||||
changed ||= (await row?._applyFormula()) ?? false;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// parent or child row
|
return changed;
|
||||||
|
}
|
||||||
|
|
||||||
|
async _callAllTableFieldsApplyFormula(
|
||||||
|
changedFieldname?: string
|
||||||
|
): Promise<boolean> {
|
||||||
|
let changed = false;
|
||||||
|
|
||||||
|
for (const { fieldname } of this.tableFields) {
|
||||||
|
const childDocs = this.get(fieldname) as Doc[];
|
||||||
|
if (!childDocs) {
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
|
changed =
|
||||||
|
(await this._callChildDocApplyFormula(childDocs, changedFieldname)) ||
|
||||||
|
changed;
|
||||||
|
}
|
||||||
|
|
||||||
|
return changed;
|
||||||
|
}
|
||||||
|
|
||||||
|
async _callChildDocApplyFormula(
|
||||||
|
childDocs: Doc[],
|
||||||
|
fieldname?: string
|
||||||
|
): Promise<boolean> {
|
||||||
|
let changed: boolean = false;
|
||||||
|
for (const childDoc of childDocs) {
|
||||||
|
if (!childDoc._applyFormula) {
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
|
changed = (await childDoc._applyFormula(fieldname)) || changed;
|
||||||
|
}
|
||||||
|
|
||||||
|
return changed;
|
||||||
|
}
|
||||||
|
|
||||||
|
async _applyFormulaForFields(doc: Doc, fieldname?: string) {
|
||||||
const formulaFields = Object.keys(this.formulas).map(
|
const formulaFields = Object.keys(this.formulas).map(
|
||||||
(fn) => this.fieldMap[fn]
|
(fn) => this.fieldMap[fn]
|
||||||
);
|
);
|
||||||
|
|
||||||
changed ||= await this._applyFormulaForFields(
|
|
||||||
formulaFields,
|
|
||||||
doc,
|
|
||||||
fieldname
|
|
||||||
);
|
|
||||||
return changed;
|
|
||||||
}
|
|
||||||
|
|
||||||
async _applyFormulaForFields(
|
|
||||||
formulaFields: Field[],
|
|
||||||
doc: Doc,
|
|
||||||
fieldname?: string
|
|
||||||
) {
|
|
||||||
let changed = false;
|
let changed = false;
|
||||||
for (const field of formulaFields) {
|
for (const field of formulaFields) {
|
||||||
const shouldApply = shouldApplyFormula(field, doc, fieldname);
|
const shouldApply = shouldApplyFormula(field, doc, fieldname);
|
||||||
@ -662,7 +691,7 @@ export class Doc extends Observable<DocValue | Doc[]> {
|
|||||||
}
|
}
|
||||||
|
|
||||||
doc[field.fieldname] = newVal;
|
doc[field.fieldname] = newVal;
|
||||||
changed = true;
|
changed ||= true;
|
||||||
}
|
}
|
||||||
|
|
||||||
return changed;
|
return changed;
|
||||||
|
Loading…
Reference in New Issue
Block a user