mirror of
https://github.com/frappe/books.git
synced 2025-02-13 09:29:18 +00:00
Merge pull request #1116 from AbleKSaju/fix-invoice-creation
fix: allow invoice creation even when free items are out of stock
This commit is contained in:
commit
93512d7094
@ -24,7 +24,6 @@ import {
|
||||
getPricingRulesConflicts,
|
||||
removeLoyaltyPoint,
|
||||
roundFreeItemQty,
|
||||
getItemQtyMap,
|
||||
} from 'models/helpers';
|
||||
import { StockTransfer } from 'models/inventory/StockTransfer';
|
||||
import { validateBatch } from 'models/inventory/helpers';
|
||||
@ -1286,19 +1285,11 @@ export abstract class Invoice extends Transactional {
|
||||
continue;
|
||||
}
|
||||
|
||||
let freeItemQty: number | undefined;
|
||||
|
||||
if (pricingRuleDoc?.freeItem) {
|
||||
const itemQtyMap = await getItemQtyMap(this as SalesInvoice);
|
||||
freeItemQty = itemQtyMap[pricingRuleDoc.freeItem]?.availableQty;
|
||||
}
|
||||
|
||||
const canApplyPRLOnItem = canApplyPricingRule(
|
||||
pricingRuleDoc,
|
||||
this.date as Date,
|
||||
item.quantity as number,
|
||||
item.amount as Money,
|
||||
freeItemQty as number
|
||||
item.amount as Money
|
||||
);
|
||||
|
||||
if (!canApplyPRLOnItem) {
|
||||
@ -1313,7 +1304,7 @@ export abstract class Invoice extends Transactional {
|
||||
}
|
||||
|
||||
if (pricingRuleDoc.roundFreeItemQty) {
|
||||
freeItemQty = roundFreeItemQty(
|
||||
roundFreeItemQty(
|
||||
roundFreeItemQuantity,
|
||||
pricingRuleDoc.roundingMethod as 'round' | 'floor' | 'ceil'
|
||||
);
|
||||
@ -1467,7 +1458,7 @@ export abstract class Invoice extends Transactional {
|
||||
}
|
||||
}
|
||||
|
||||
const filtered = await filterPricingRules(
|
||||
const filtered = filterPricingRules(
|
||||
this as SalesInvoice,
|
||||
pricingRuleDocsForItem,
|
||||
item.quantity as number,
|
||||
|
@ -983,7 +983,7 @@ export async function getPricingRule(
|
||||
continue;
|
||||
}
|
||||
|
||||
const filtered = await filterPricingRules(
|
||||
const filtered = filterPricingRules(
|
||||
doc as SalesInvoice,
|
||||
pricingRuleDocsForItem,
|
||||
item.quantity as number,
|
||||
@ -1046,30 +1046,17 @@ export async function getItemRateFromPriceList(
|
||||
return plItem?.rate;
|
||||
}
|
||||
|
||||
export async function filterPricingRules(
|
||||
export function filterPricingRules(
|
||||
doc: SalesInvoice,
|
||||
pricingRuleDocsForItem: PricingRule[],
|
||||
quantity: number,
|
||||
amount: Money
|
||||
): Promise<PricingRule[] | []> {
|
||||
): PricingRule[] | [] {
|
||||
const filteredPricingRules: PricingRule[] = [];
|
||||
|
||||
for (const pricingRuleDoc of pricingRuleDocsForItem) {
|
||||
let freeItemQty: number | undefined;
|
||||
|
||||
if (pricingRuleDoc?.freeItem) {
|
||||
const itemQtyMap = await getItemQtyMap(doc);
|
||||
freeItemQty = itemQtyMap[pricingRuleDoc.freeItem]?.availableQty;
|
||||
}
|
||||
|
||||
if (
|
||||
canApplyPricingRule(
|
||||
pricingRuleDoc,
|
||||
doc.date as Date,
|
||||
quantity,
|
||||
amount,
|
||||
freeItemQty ?? 0
|
||||
)
|
||||
canApplyPricingRule(pricingRuleDoc, doc.date as Date, quantity, amount)
|
||||
) {
|
||||
filteredPricingRules.push(pricingRuleDoc);
|
||||
}
|
||||
@ -1081,22 +1068,8 @@ export function canApplyPricingRule(
|
||||
pricingRuleDoc: PricingRule,
|
||||
sinvDate: Date,
|
||||
quantity: number,
|
||||
amount: Money,
|
||||
freeItemQty: number
|
||||
amount: Money
|
||||
): boolean {
|
||||
const freeItemQuantity = pricingRuleDoc.freeItemQuantity;
|
||||
|
||||
if (pricingRuleDoc.isRecursive) {
|
||||
freeItemQty = quantity / (pricingRuleDoc.recurseEvery as number);
|
||||
}
|
||||
|
||||
// Filter by Quantity
|
||||
if (pricingRuleDoc.freeItem && 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)
|
||||
|
@ -803,6 +803,27 @@ export default defineComponent({
|
||||
|
||||
await this.sinvDoc.appendPricingRuleDetail(hasPricingRules);
|
||||
await this.sinvDoc.applyProductDiscount();
|
||||
|
||||
const outOfStockFreeItems: string[] = [];
|
||||
const itemQtyMap = await getItemQtyMap(this.sinvDoc as SalesInvoice);
|
||||
|
||||
hasPricingRules.map((pRule) => {
|
||||
const freeItemQty =
|
||||
itemQtyMap[pRule.pricingRule.freeItem as string]?.availableQty;
|
||||
|
||||
if (freeItemQty <= 0) {
|
||||
this.sinvDoc.items = this.sinvDoc.items?.filter(
|
||||
(val) => !(val.isFreeItem && val.item == pRule.pricingRule.freeItem)
|
||||
);
|
||||
|
||||
outOfStockFreeItems.push(pRule.pricingRule.freeItem as string);
|
||||
}
|
||||
});
|
||||
|
||||
showToast({
|
||||
type: 'error',
|
||||
message: t`Free items out of stock: ${outOfStockFreeItems.join(', ')}`,
|
||||
});
|
||||
},
|
||||
async routeToSinvList() {
|
||||
if (!this.sinvDoc.items?.length) {
|
||||
|
Loading…
x
Reference in New Issue
Block a user