2
0
mirror of https://github.com/frappe/books.git synced 2025-01-03 07:12:21 +00:00

fix: prevent applying pricing rule for free items when stock is insufficient

This commit is contained in:
AbleKSaju 2024-12-02 12:08:11 +05:30
parent f830b109c1
commit ee348f967a
2 changed files with 46 additions and 19 deletions

View File

@ -1264,17 +1264,6 @@ export abstract class Invoice extends Transactional {
continue;
}
const canApplyPRLOnItem = canApplyPricingRule(
pricingRuleDoc,
this.date as Date,
item.quantity as number,
item.amount as Money
);
if (!canApplyPRLOnItem) {
continue;
}
let freeItemQty = pricingRuleDoc.freeItemQuantity as number;
if (pricingRuleDoc.isRecursive) {
@ -1282,6 +1271,18 @@ export abstract class Invoice extends Transactional {
(item.quantity as number) / (pricingRuleDoc.recurseEvery as number);
}
const canApplyPRLOnItem = canApplyPricingRule(
pricingRuleDoc,
this.date as Date,
item.quantity as number,
item.amount as Money,
freeItemQty
);
if (!canApplyPRLOnItem) {
continue;
}
if (pricingRuleDoc.roundFreeItemQty) {
freeItemQty = roundFreeItemQty(
freeItemQty,
@ -1437,14 +1438,14 @@ export abstract class Invoice extends Transactional {
}
}
const filtered = filterPricingRules(
const filtered = await filterPricingRules(
pricingRuleDocsForItem,
this.date as Date,
item.quantity as number,
item.amount as Money
);
if (!filtered.length) {
if (!filtered || !filtered.length) {
continue;
}

View File

@ -39,6 +39,7 @@ import { safeParseFloat } from 'utils/index';
import { PriceList } from './baseModels/PriceList/PriceList';
import { InvoiceItem } from './baseModels/InvoiceItem/InvoiceItem';
import { SalesInvoiceItem } from './baseModels/SalesInvoiceItem/SalesInvoiceItem';
import { getItemQtyMap } from 'src/utils/pos';
export function getQuoteActions(
fyo: Fyo,
@ -914,7 +915,7 @@ export async function getPricingRule(
continue;
}
const filtered = filterPricingRules(
const filtered = await filterPricingRules(
pricingRuleDocsForItem,
doc.date as Date,
item.quantity as number,
@ -977,16 +978,31 @@ export async function getItemRateFromPriceList(
return plItem?.rate;
}
export function filterPricingRules(
export async function filterPricingRules(
pricingRuleDocsForItem: PricingRule[],
sinvDate: Date,
quantity: number,
amount: Money
): PricingRule[] | [] {
const filteredPricingRules: PricingRule[] | undefined = [];
): Promise<PricingRule[] | []> {
const filteredPricingRules: PricingRule[] = [];
for (const pricingRuleDoc of pricingRuleDocsForItem) {
if (canApplyPricingRule(pricingRuleDoc, sinvDate, quantity, amount)) {
let freeItemQty: number | undefined;
if (pricingRuleDoc?.freeItem) {
const itemQtyMap = await getItemQtyMap();
freeItemQty = itemQtyMap[pricingRuleDoc.freeItem].availableQty;
}
if (
canApplyPricingRule(
pricingRuleDoc,
sinvDate,
quantity,
amount,
freeItemQty ?? 0
)
) {
filteredPricingRules.push(pricingRuleDoc);
}
}
@ -997,9 +1013,19 @@ export function canApplyPricingRule(
pricingRuleDoc: PricingRule,
sinvDate: Date,
quantity: number,
amount: Money
amount: Money,
freeItemQty: number
): boolean {
// Filter by Quantity
if (
pricingRuleDoc.freeItem &&
pricingRuleDoc.freeItemQuantity! >= freeItemQty
) {
throw new ValidationError(
t`Free item '${pricingRuleDoc.freeItem}' does not have a specified quantity`
);
}
if (
(pricingRuleDoc.minQuantity as number) > 0 &&
quantity < (pricingRuleDoc.minQuantity as number)