2
0
mirror of https://github.com/frappe/books.git synced 2024-11-09 23:30:56 +00:00

incr: ledger posting for discount

- remove invoice wide discount
This commit is contained in:
18alantom 2022-07-15 13:05:07 +05:30
parent f157ed4240
commit f05f77e191
6 changed files with 60 additions and 15 deletions

View File

@ -201,7 +201,7 @@ export default class DatabaseCore extends DatabaseBase {
} }
if (fields === undefined) { 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(); fieldValueMap.name = getRandomString();
} }
// Non Table Fields // Column fields
const fields = this.schemaMap[schemaName]!.fields.filter( const fields = this.schemaMap[schemaName]!.fields.filter(
(f) => f.fieldtype !== FieldTypeEnum.Table (f) => f.fieldtype !== FieldTypeEnum.Table && !f.computed
); );
const validMap: FieldValueMap = {}; const validMap: FieldValueMap = {};
@ -773,8 +773,9 @@ export default class DatabaseCore extends DatabaseBase {
singleSchemaName: string, singleSchemaName: string,
fieldValueMap: FieldValueMap fieldValueMap: FieldValueMap
) { ) {
const fields = this.schemaMap[singleSchemaName]!.fields; const fields = this.schemaMap[singleSchemaName]!.fields.filter(
(f) => !f.computed
);
for (const field of fields) { for (const field of fields) {
const value = fieldValueMap[field.fieldname] as RawValue | undefined; const value = fieldValueMap[field.fieldname] as RawValue | undefined;
if (value === undefined) { if (value === undefined) {
@ -864,8 +865,8 @@ export default class DatabaseCore extends DatabaseBase {
const updateMap = { ...fieldValueMap }; const updateMap = { ...fieldValueMap };
delete updateMap.name; delete updateMap.name;
const schema = this.schemaMap[schemaName] as Schema; const schema = this.schemaMap[schemaName] as Schema;
for (const { fieldname, fieldtype } of schema.fields) { for (const { fieldname, fieldtype, computed } of schema.fields) {
if (fieldtype !== FieldTypeEnum.Table) { if (fieldtype !== FieldTypeEnum.Table && !computed) {
continue; continue;
} }

View File

@ -1,6 +1,7 @@
import { DocValue } from 'fyo/core/types'; import { DocValue } from 'fyo/core/types';
import { Doc } from 'fyo/model/doc'; import { Doc } from 'fyo/model/doc';
import { DefaultMap, FiltersMap, FormulaMap, HiddenMap } from 'fyo/model/types'; import { DefaultMap, FiltersMap, FormulaMap, HiddenMap } from 'fyo/model/types';
import { ValidationError } from 'fyo/utils/errors';
import { getExchangeRate } from 'models/helpers'; import { getExchangeRate } from 'models/helpers';
import { Transactional } from 'models/Transactional/Transactional'; import { Transactional } from 'models/Transactional/Transactional';
import { ModelNameEnum } from 'models/types'; import { ModelNameEnum } from 'models/types';
@ -41,6 +42,16 @@ export abstract class Invoice extends Transactional {
return !!this.fyo.singles?.AccountingSettings?.enableDiscounting; 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() { async afterSubmit() {
await super.afterSubmit(); await super.afterSubmit();
@ -176,11 +187,18 @@ export abstract class Invoice extends Transactional {
return this._taxes[tax]; return this._taxes[tax];
} }
async getGrandTotal() { async getTotalDiscount() {
if (!this.enableDiscounting) {
return this.fyo.pesa(0);
}
const itemDiscountAmount = this.getItemDiscountAmount(); const itemDiscountAmount = this.getItemDiscountAmount();
const invoiceDiscountAmount = this.getInvoiceDiscountAmount(); 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[]) return ((this.taxes ?? []) as Doc[])
.map((doc) => doc.amount as Money) .map((doc) => doc.amount as Money)
.reduce((a, b) => a.add(b), this.netTotal!) .reduce((a, b) => a.add(b), this.netTotal!)
@ -188,6 +206,10 @@ export abstract class Invoice extends Transactional {
} }
getInvoiceDiscountAmount() { getInvoiceDiscountAmount() {
if (!this.enableDiscounting) {
return this.fyo.pesa(0);
}
if (this.setDiscountAmount) { if (this.setDiscountAmount) {
return this.discountAmount ?? this.fyo.pesa(0); return this.discountAmount ?? this.fyo.pesa(0);
} }
@ -205,6 +227,10 @@ export abstract class Invoice extends Transactional {
} }
getItemDiscountAmount() { getItemDiscountAmount() {
if (!this.enableDiscounting) {
return this.fyo.pesa(0);
}
if (!this?.items?.length) { if (!this?.items?.length) {
return this.fyo.pesa(0); return this.fyo.pesa(0);
} }
@ -291,9 +317,11 @@ export abstract class Invoice extends Transactional {
} }
hidden: HiddenMap = { hidden: HiddenMap = {
setDiscountAmount: () => !this.enableDiscounting, setDiscountAmount: () => true || !this.enableDiscounting,
discountAmount: () => !(this.enableDiscounting && !!this.setDiscountAmount), discountAmount: () =>
discountPercent: () => !(this.enableDiscounting && !this.setDiscountAmount), true || !(this.enableDiscounting && !!this.setDiscountAmount),
discountPercent: () =>
true || !(this.enableDiscounting && !this.setDiscountAmount),
discountAfterTax: () => !this.enableDiscounting, discountAfterTax: () => !this.enableDiscounting,
}; };

View File

@ -11,7 +11,6 @@ export class PurchaseInvoice extends Invoice {
async getPosting() { async getPosting() {
const posting: LedgerPosting = new LedgerPosting(this, this.fyo); const posting: LedgerPosting = new LedgerPosting(this, this.fyo);
await posting.credit(this.account!, this.baseGrandTotal!); await posting.credit(this.account!, this.baseGrandTotal!);
for (const item of this.items!) { 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(); await posting.makeRoundOffEntry();
return posting; return posting;
} }

View File

@ -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(); await posting.makeRoundOffEntry();
return posting; return posting;
} }

View File

@ -28,6 +28,7 @@
"fieldtype": "Link", "fieldtype": "Link",
"target": "UOM", "target": "UOM",
"create": true, "create": true,
"default": "Unit",
"placeholder": "Unit Type" "placeholder": "Unit Type"
}, },
{ {

View File

@ -94,6 +94,7 @@
@change="(value) => doc.set('account', value)" @change="(value) => doc.set('account', value)"
:read-only="doc?.submitted" :read-only="doc?.submitted"
/> />
<!--
<FormControl <FormControl
v-if="doc.enableDiscounting" v-if="doc.enableDiscounting"
:show-label="true" :show-label="true"
@ -131,6 +132,7 @@
@change="(value) => doc.set('discountAmount', value)" @change="(value) => doc.set('discountAmount', value)"
:read-only="doc?.submitted" :read-only="doc?.submitted"
/> />
-->
</div> </div>
<hr /> <hr />
@ -187,7 +189,7 @@
class="flex justify-between" class="flex justify-between"
v-if="itemDiscountAmount.float > 0" v-if="itemDiscountAmount.float > 0"
> >
<div>{{ t`Item Discount` }}</div> <div>{{ t`Discount` }}</div>
<div> <div>
{{ `- ${fyo.format(itemDiscountAmount, 'Currency')}` }} {{ `- ${fyo.format(itemDiscountAmount, 'Currency')}` }}
</div> </div>
@ -231,7 +233,7 @@
class="flex justify-between" class="flex justify-between"
v-if="itemDiscountAmount.float > 0" v-if="itemDiscountAmount.float > 0"
> >
<div>{{ t`Item Discount` }}</div> <div>{{ t`Discount` }}</div>
<div> <div>
{{ `- ${fyo.format(itemDiscountAmount, 'Currency')}` }} {{ `- ${fyo.format(itemDiscountAmount, 'Currency')}` }}
</div> </div>