diff --git a/backend/database/core.ts b/backend/database/core.ts index 965d9904..ae52b816 100644 --- a/backend/database/core.ts +++ b/backend/database/core.ts @@ -201,7 +201,7 @@ export default class DatabaseCore extends DatabaseBase { } if (fields === undefined) { - fields = schema.fields.map((f) => f.fieldname); + fields = schema.fields.filter((f) => !f.computed).map((f) => f.fieldname); } /** @@ -756,9 +756,9 @@ export default class DatabaseCore extends DatabaseBase { fieldValueMap.name = getRandomString(); } - // Non Table Fields + // Column fields const fields = this.schemaMap[schemaName]!.fields.filter( - (f) => f.fieldtype !== FieldTypeEnum.Table + (f) => f.fieldtype !== FieldTypeEnum.Table && !f.computed ); const validMap: FieldValueMap = {}; @@ -773,8 +773,9 @@ export default class DatabaseCore extends DatabaseBase { singleSchemaName: string, fieldValueMap: FieldValueMap ) { - const fields = this.schemaMap[singleSchemaName]!.fields; - + const fields = this.schemaMap[singleSchemaName]!.fields.filter( + (f) => !f.computed + ); for (const field of fields) { const value = fieldValueMap[field.fieldname] as RawValue | undefined; if (value === undefined) { @@ -864,8 +865,8 @@ export default class DatabaseCore extends DatabaseBase { const updateMap = { ...fieldValueMap }; delete updateMap.name; const schema = this.schemaMap[schemaName] as Schema; - for (const { fieldname, fieldtype } of schema.fields) { - if (fieldtype !== FieldTypeEnum.Table) { + for (const { fieldname, fieldtype, computed } of schema.fields) { + if (fieldtype !== FieldTypeEnum.Table && !computed) { continue; } diff --git a/models/baseModels/Invoice/Invoice.ts b/models/baseModels/Invoice/Invoice.ts index 902222d9..e786d9e7 100644 --- a/models/baseModels/Invoice/Invoice.ts +++ b/models/baseModels/Invoice/Invoice.ts @@ -1,6 +1,7 @@ import { DocValue } from 'fyo/core/types'; import { Doc } from 'fyo/model/doc'; import { DefaultMap, FiltersMap, FormulaMap, HiddenMap } from 'fyo/model/types'; +import { ValidationError } from 'fyo/utils/errors'; import { getExchangeRate } from 'models/helpers'; import { Transactional } from 'models/Transactional/Transactional'; import { ModelNameEnum } from 'models/types'; @@ -41,6 +42,16 @@ export abstract class Invoice extends Transactional { return !!this.fyo.singles?.AccountingSettings?.enableDiscounting; } + async validate() { + await super.validate(); + if ( + this.enableDiscounting && + !this.fyo.singles?.AccountingSettings?.discountAccount + ) { + throw new ValidationError(this.fyo.t`Discount Account is not set.`); + } + } + async afterSubmit() { await super.afterSubmit(); @@ -176,11 +187,18 @@ export abstract class Invoice extends Transactional { return this._taxes[tax]; } - async getGrandTotal() { + async getTotalDiscount() { + if (!this.enableDiscounting) { + return this.fyo.pesa(0); + } + const itemDiscountAmount = this.getItemDiscountAmount(); const invoiceDiscountAmount = this.getInvoiceDiscountAmount(); - const totalDiscount = itemDiscountAmount.add(invoiceDiscountAmount); + return itemDiscountAmount.add(invoiceDiscountAmount); + } + async getGrandTotal() { + const totalDiscount = await this.getTotalDiscount(); return ((this.taxes ?? []) as Doc[]) .map((doc) => doc.amount as Money) .reduce((a, b) => a.add(b), this.netTotal!) @@ -188,6 +206,10 @@ export abstract class Invoice extends Transactional { } getInvoiceDiscountAmount() { + if (!this.enableDiscounting) { + return this.fyo.pesa(0); + } + if (this.setDiscountAmount) { return this.discountAmount ?? this.fyo.pesa(0); } @@ -205,6 +227,10 @@ export abstract class Invoice extends Transactional { } getItemDiscountAmount() { + if (!this.enableDiscounting) { + return this.fyo.pesa(0); + } + if (!this?.items?.length) { return this.fyo.pesa(0); } @@ -291,9 +317,11 @@ export abstract class Invoice extends Transactional { } hidden: HiddenMap = { - setDiscountAmount: () => !this.enableDiscounting, - discountAmount: () => !(this.enableDiscounting && !!this.setDiscountAmount), - discountPercent: () => !(this.enableDiscounting && !this.setDiscountAmount), + setDiscountAmount: () => true || !this.enableDiscounting, + discountAmount: () => + true || !(this.enableDiscounting && !!this.setDiscountAmount), + discountPercent: () => + true || !(this.enableDiscounting && !this.setDiscountAmount), discountAfterTax: () => !this.enableDiscounting, }; diff --git a/models/baseModels/PurchaseInvoice/PurchaseInvoice.ts b/models/baseModels/PurchaseInvoice/PurchaseInvoice.ts index df76ebd6..47caf0a8 100644 --- a/models/baseModels/PurchaseInvoice/PurchaseInvoice.ts +++ b/models/baseModels/PurchaseInvoice/PurchaseInvoice.ts @@ -11,7 +11,6 @@ export class PurchaseInvoice extends Invoice { async getPosting() { const posting: LedgerPosting = new LedgerPosting(this, this.fyo); - await posting.credit(this.account!, this.baseGrandTotal!); for (const item of this.items!) { @@ -24,6 +23,13 @@ export class PurchaseInvoice extends Invoice { } } + const discountAmount = await this.getTotalDiscount(); + const discountAccount = this.fyo.singles.AccountingSettings + ?.discountAccount as string | undefined; + if (discountAccount && discountAmount.isPositive()) { + await posting.credit(discountAccount, discountAmount); + } + await posting.makeRoundOffEntry(); return posting; } diff --git a/models/baseModels/SalesInvoice/SalesInvoice.ts b/models/baseModels/SalesInvoice/SalesInvoice.ts index c5b27317..d50a6345 100644 --- a/models/baseModels/SalesInvoice/SalesInvoice.ts +++ b/models/baseModels/SalesInvoice/SalesInvoice.ts @@ -23,6 +23,13 @@ export class SalesInvoice extends Invoice { } } + const discountAmount = await this.getTotalDiscount(); + const discountAccount = this.fyo.singles.AccountingSettings + ?.discountAccount as string | undefined; + if (discountAccount && discountAmount.isPositive()) { + await posting.debit(discountAccount, discountAmount); + } + await posting.makeRoundOffEntry(); return posting; } diff --git a/schemas/app/Item.json b/schemas/app/Item.json index f1af528c..4d5a76a0 100644 --- a/schemas/app/Item.json +++ b/schemas/app/Item.json @@ -28,6 +28,7 @@ "fieldtype": "Link", "target": "UOM", "create": true, + "default": "Unit", "placeholder": "Unit Type" }, { diff --git a/src/pages/InvoiceForm.vue b/src/pages/InvoiceForm.vue index 358be092..f9390717 100644 --- a/src/pages/InvoiceForm.vue +++ b/src/pages/InvoiceForm.vue @@ -94,6 +94,7 @@ @change="(value) => doc.set('account', value)" :read-only="doc?.submitted" /> +
@@ -187,7 +189,7 @@ class="flex justify-between" v-if="itemDiscountAmount.float > 0" > -
{{ t`Item Discount` }}
+
{{ t`Discount` }}
{{ `- ${fyo.format(itemDiscountAmount, 'Currency')}` }}
@@ -231,7 +233,7 @@ class="flex justify-between" v-if="itemDiscountAmount.float > 0" > -
{{ t`Item Discount` }}
+
{{ t`Discount` }}
{{ `- ${fyo.format(itemDiscountAmount, 'Currency')}` }}