mirror of
https://github.com/frappe/books.git
synced 2024-11-15 01:44:04 +00:00
feat: add coupon code support in sales invoice
This commit is contained in:
parent
f200f775cf
commit
a6f6269ee7
@ -13,6 +13,7 @@ import { ValidationError } from 'fyo/utils/errors';
|
|||||||
import { Transactional } from 'models/Transactional/Transactional';
|
import { Transactional } from 'models/Transactional/Transactional';
|
||||||
import {
|
import {
|
||||||
addItem,
|
addItem,
|
||||||
|
canApplyCouponCode,
|
||||||
canApplyPricingRule,
|
canApplyPricingRule,
|
||||||
createLoyaltyPointEntry,
|
createLoyaltyPointEntry,
|
||||||
filterPricingRules,
|
filterPricingRules,
|
||||||
@ -42,6 +43,8 @@ import { PricingRule } from '../PricingRule/PricingRule';
|
|||||||
import { ApplicablePricingRules } from './types';
|
import { ApplicablePricingRules } from './types';
|
||||||
import { PricingRuleDetail } from '../PricingRuleDetail/PricingRuleDetail';
|
import { PricingRuleDetail } from '../PricingRuleDetail/PricingRuleDetail';
|
||||||
import { LoyaltyProgram } from '../LoyaltyProgram/LoyaltyProgram';
|
import { LoyaltyProgram } from '../LoyaltyProgram/LoyaltyProgram';
|
||||||
|
import { AppliedCouponCodes } from '../AppliedCouponCodes/AppliedCouponCodes';
|
||||||
|
import { CouponCode } from '../CouponCode/CouponCode';
|
||||||
|
|
||||||
export type TaxDetail = {
|
export type TaxDetail = {
|
||||||
account: string;
|
account: string;
|
||||||
@ -61,6 +64,7 @@ export abstract class Invoice extends Transactional {
|
|||||||
taxes?: TaxSummary[];
|
taxes?: TaxSummary[];
|
||||||
|
|
||||||
items?: InvoiceItem[];
|
items?: InvoiceItem[];
|
||||||
|
coupons?: AppliedCouponCodes[];
|
||||||
party?: string;
|
party?: string;
|
||||||
account?: string;
|
account?: string;
|
||||||
currency?: string;
|
currency?: string;
|
||||||
@ -727,7 +731,7 @@ export abstract class Invoice extends Transactional {
|
|||||||
await this.appendPricingRuleDetail(pricingRule);
|
await this.appendPricingRuleDetail(pricingRule);
|
||||||
return !!pricingRule;
|
return !!pricingRule;
|
||||||
},
|
},
|
||||||
dependsOn: ['items'],
|
dependsOn: ['items', 'coupons'],
|
||||||
},
|
},
|
||||||
};
|
};
|
||||||
|
|
||||||
@ -1298,6 +1302,41 @@ export abstract class Invoice extends Transactional {
|
|||||||
})
|
})
|
||||||
).map((doc) => doc.parent) as string[];
|
).map((doc) => doc.parent) as string[];
|
||||||
|
|
||||||
|
if (!pricingRuleDocNames.length) {
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (this.coupons?.length) {
|
||||||
|
for (const coupon of this.coupons) {
|
||||||
|
const couponCodeDatas = await this.fyo.db.getAll(
|
||||||
|
ModelNameEnum.CouponCode,
|
||||||
|
{
|
||||||
|
fields: ['*'],
|
||||||
|
filters: {
|
||||||
|
name: coupon?.coupons as string,
|
||||||
|
isEnabled: true,
|
||||||
|
},
|
||||||
|
}
|
||||||
|
);
|
||||||
|
|
||||||
|
const couponPricingRuleDocNames = couponCodeDatas
|
||||||
|
.map((doc) => doc.pricingRule)
|
||||||
|
.filter((val) =>
|
||||||
|
pricingRuleDocNames.includes(val as string)
|
||||||
|
) as string[];
|
||||||
|
|
||||||
|
const filtered = canApplyCouponCode(
|
||||||
|
couponCodeDatas[0] as CouponCode,
|
||||||
|
this.grandTotal as Money,
|
||||||
|
this.date as Date
|
||||||
|
);
|
||||||
|
|
||||||
|
if (filtered) {
|
||||||
|
pricingRuleDocNames.push(...couponPricingRuleDocNames);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
const pricingRuleDocsForItem = (await this.fyo.db.getAll(
|
const pricingRuleDocsForItem = (await this.fyo.db.getAll(
|
||||||
ModelNameEnum.PricingRule,
|
ModelNameEnum.PricingRule,
|
||||||
{
|
{
|
||||||
@ -1311,6 +1350,50 @@ export abstract class Invoice extends Transactional {
|
|||||||
}
|
}
|
||||||
)) as PricingRule[];
|
)) as PricingRule[];
|
||||||
|
|
||||||
|
if (pricingRuleDocsForItem[0].isCouponCodeBased) {
|
||||||
|
if (!this.coupons?.length) {
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
|
const data = await Promise.allSettled(
|
||||||
|
this.coupons?.map(async (val) => {
|
||||||
|
if (!val.coupons) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
const [pricingRule] = (
|
||||||
|
await this.fyo.db.getAll(ModelNameEnum.CouponCode, {
|
||||||
|
fields: ['pricingRule'],
|
||||||
|
filters: {
|
||||||
|
name: val?.coupons,
|
||||||
|
},
|
||||||
|
})
|
||||||
|
).map((doc) => doc.pricingRule);
|
||||||
|
|
||||||
|
if (!pricingRule) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (pricingRuleDocsForItem[0].name === pricingRule) {
|
||||||
|
return pricingRule;
|
||||||
|
}
|
||||||
|
|
||||||
|
return false;
|
||||||
|
})
|
||||||
|
);
|
||||||
|
|
||||||
|
const fulfilledData = data
|
||||||
|
.filter(
|
||||||
|
(result): result is PromiseFulfilledResult<string | false> =>
|
||||||
|
result.status === 'fulfilled'
|
||||||
|
)
|
||||||
|
.map((result) => result.value as string);
|
||||||
|
|
||||||
|
if (!fulfilledData[0] && !fulfilledData.filter((val) => val).length) {
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
const filtered = filterPricingRules(
|
const filtered = filterPricingRules(
|
||||||
pricingRuleDocsForItem,
|
pricingRuleDocsForItem,
|
||||||
this.date as Date,
|
this.date as Date,
|
||||||
|
@ -23,6 +23,8 @@ export class PricingRule extends Doc {
|
|||||||
discountPercentage?: number;
|
discountPercentage?: number;
|
||||||
discountAmount?: Money;
|
discountAmount?: Money;
|
||||||
|
|
||||||
|
isCouponCodeBased?: boolean;
|
||||||
|
|
||||||
forPriceList?: string;
|
forPriceList?: string;
|
||||||
|
|
||||||
freeItem?: string;
|
freeItem?: string;
|
||||||
|
Loading…
Reference in New Issue
Block a user