Skip to content

Commit

Permalink
feat: price discount
Browse files Browse the repository at this point in the history
  • Loading branch information
akshayitzme committed Feb 1, 2024
1 parent 4fef5d2 commit d95c696
Show file tree
Hide file tree
Showing 2 changed files with 113 additions and 55 deletions.
167 changes: 112 additions & 55 deletions models/baseModels/InvoiceItem/InvoiceItem.ts
Original file line number Diff line number Diff line change
Expand Up @@ -19,9 +19,7 @@ import { Item } from '../Item/Item';
import { StockTransfer } from 'models/inventory/StockTransfer';
import { PriceList } from '../PriceList/PriceList';
import { isPesa } from 'fyo/utils';
import { canApplyPricingRule } from 'models/helpers';
import { PricingRule } from '../PricingRule/PricingRule';
import { SalesInvoiceItem } from '../SalesInvoiceItem/SalesInvoiceItem';

export abstract class InvoiceItem extends Doc {
item?: string;
Expand Down Expand Up @@ -49,6 +47,8 @@ export abstract class InvoiceItem extends Doc {
itemDiscountedTotal?: Money;
itemTaxedTotal?: Money;

isFreeItem?: boolean;

get isSales() {
return (
this.schemaName === 'SalesInvoiceItem' ||
Expand Down Expand Up @@ -96,6 +96,10 @@ export abstract class InvoiceItem extends Doc {
return !!this.parentdoc?.isReturn;
}

get pricingRuleDetail() {
return this.parentdoc?.pricingRuleDetail;
}

constructor(schema: Schema, data: DocValueMap, fyo: Fyo) {
super(schema, data, fyo);
this._setGetCurrencies();
Expand Down Expand Up @@ -172,6 +176,7 @@ export abstract class InvoiceItem extends Doc {
'itemTaxedTotal',
'itemDiscountedTotal',
'setItemDiscountAmount',
'pricingRuleDetail',
],
},
unit: {
Expand Down Expand Up @@ -407,41 +412,79 @@ export abstract class InvoiceItem extends Doc {
},
dependsOn: ['item', 'quantity'],
},
isPricingRuleAppliedItem: {
setItemDiscountAmount: {
formula: async () => {
if (!this.parentdoc?.pricingRuleDetail) {
return false;
if (
!this.fyo.singles.AccountingSettings?.enablePricingRule ||
!this.parentdoc?.pricingRuleDetail
) {
return this.setItemDiscountAmount;
}

for (const prleDoc of this.parentdoc.pricingRuleDetail) {
const pricingRuleDoc = (await this.fyo.doc.getDoc(
ModelNameEnum.PricingRule,
prleDoc.referenceName
)) as PricingRule;

if (
!canApplyPricingRule(
pricingRuleDoc,
this.parentdoc.date as Date,
this.quantity as number,
this.amount as Money
)
) {
continue;
}
const pricingRule = this.parentdoc?.pricingRuleDetail?.filter(
(prDetail) => prDetail.referenceItem === this.item
);

if (!pricingRule) {
return this.setItemDiscountAmount;
}

const pricingRuleDoc = (await this.fyo.doc.getDoc(
ModelNameEnum.PricingRule,
pricingRule[0].referenceName
)) as PricingRule;

if (pricingRuleDoc.discountType === 'Product Discount') {
return this.setItemDiscountAmount;
}

const appliedItems = pricingRuleDoc.appliedItems?.map(
(item) => item.item
if (pricingRuleDoc.priceDiscountType === 'amount') {
const discountAmount = pricingRuleDoc.discountAmount?.mul(
this.quantity as number
);
await this.set('itemDiscountAmount', discountAmount);
return true;
}

if (!appliedItems?.includes(this.item)) {
continue;
}
return this.setItemDiscountAmount;
},
dependsOn: ['pricingRuleDetail'],
},
itemDiscountPercent: {
formula: async () => {
if (
!this.fyo.singles.AccountingSettings?.enablePricingRule ||
!this.parentdoc?.pricingRuleDetail
) {
return this.itemDiscountPercent;
}

await applyPricingRuleOnItem(this, pricingRuleDoc);
const pricingRule = this.parentdoc?.pricingRuleDetail?.filter(
(prDetail) => prDetail.referenceItem === this.item
);

if (!pricingRule) {
return this.itemDiscountPercent;
}

const pricingRuleDoc = (await this.fyo.doc.getDoc(
ModelNameEnum.PricingRule,
pricingRule[0].referenceName
)) as PricingRule;

if (pricingRuleDoc.discountType === 'Product Discount') {
return this.itemDiscountPercent;
}

if (pricingRuleDoc.priceDiscountType === 'percentage') {
await this.set('setItemDiscountAmount', false);

return pricingRuleDoc.discountPercentage;
}

return this.setItemDiscountAmount;
},
dependsOn: ['item', 'quantity'],
dependsOn: ['pricingRuleDetail'],
},
};

Expand Down Expand Up @@ -570,7 +613,21 @@ export abstract class InvoiceItem extends Doc {
}

async function getItemRate(doc: InvoiceItem): Promise<Money | undefined> {
if (doc.isFreeItem) {
return doc.rate;
}

let pricingRuleRate: Money | undefined;
if (doc.fyo.singles.AccountingSettings?.enablePricingRule) {
pricingRuleRate = await getItemRateFromPricingRule(doc);
}

if (pricingRuleRate) {
return pricingRuleRate;
}

let priceListRate: Money | undefined;

if (doc.fyo.singles.AccountingSettings?.enablePriceList) {
priceListRate = await getItemRateFromPriceList(doc);
}
Expand All @@ -591,6 +648,33 @@ async function getItemRate(doc: InvoiceItem): Promise<Money | undefined> {
return;
}

async function getItemRateFromPricingRule(
doc: InvoiceItem
): Promise<Money | undefined> {
const pricingRule = doc.parentdoc?.pricingRuleDetail?.filter(
(prDetail) => prDetail.referenceItem === doc.item
);

if (!pricingRule) {
return;
}

const pricingRuleDoc = (await doc.fyo.doc.getDoc(
ModelNameEnum.PricingRule,
pricingRule[0].referenceName
)) as PricingRule;

if (pricingRuleDoc.discountType !== 'Price Discount') {
return;
}

if (pricingRuleDoc.priceDiscountType !== 'rate') {
return;
}

return pricingRuleDoc.discountRate;
}

async function getItemRateFromPriceList(
doc: InvoiceItem
): Promise<Money | undefined> {
Expand Down Expand Up @@ -773,30 +857,3 @@ function getRate(

return null;
}

async function applyPricingRuleOnItem(
sinvItemDoc: SalesInvoiceItem,
pricingRuleDoc: PricingRule
) {
switch (pricingRuleDoc.priceDiscountType) {
case 'rate':
await sinvItemDoc.set('rate', pricingRuleDoc.discountRate);
return;

case 'amount':
await sinvItemDoc.set('setItemDiscountAmount', true);
const discountAmount = pricingRuleDoc.discountAmount?.mul(
sinvItemDoc.quantity as number
);

await sinvItemDoc.set('itemDiscountAmount', discountAmount);
return;

case 'percentage':
await sinvItemDoc.set(
'itemDiscountPercent',
pricingRuleDoc.discountPercentage
);
return;
}
}
1 change: 1 addition & 0 deletions models/baseModels/PricingRuleDetail/PricingRuleDetail.ts
Original file line number Diff line number Diff line change
Expand Up @@ -2,4 +2,5 @@ import { Doc } from 'fyo/model/doc';

export class PricingRuleDetail extends Doc {
referenceName?: string;
referenceItem?: string;
}

0 comments on commit d95c696

Please sign in to comment.