mirror of
https://github.com/frappe/books.git
synced 2024-11-09 23:30:56 +00:00
fix: pricing rule not applied in pos
This commit is contained in:
parent
427b8260e0
commit
d4a08d8331
@ -646,11 +646,12 @@ export abstract class Invoice extends Transactional {
|
||||
}
|
||||
|
||||
const pricingRule = await this.getPricingRule();
|
||||
if (pricingRule) {
|
||||
await this.appendPricingRuleDetail(pricingRule);
|
||||
if (!pricingRule) {
|
||||
return false;
|
||||
}
|
||||
|
||||
return !!pricingRule?.length;
|
||||
await this.appendPricingRuleDetail(pricingRule);
|
||||
return !!pricingRule;
|
||||
},
|
||||
dependsOn: ['items'],
|
||||
},
|
||||
@ -954,6 +955,8 @@ export abstract class Invoice extends Transactional {
|
||||
|
||||
if (this.pricingRuleDetail?.length) {
|
||||
await this.applyProductDiscount();
|
||||
} else {
|
||||
this.clearFreeItems();
|
||||
}
|
||||
}
|
||||
|
||||
@ -1099,22 +1102,40 @@ export abstract class Invoice extends Transactional {
|
||||
}
|
||||
}
|
||||
|
||||
clearFreeItems() {
|
||||
if (this.pricingRuleDetail?.length || !this.items) {
|
||||
return;
|
||||
}
|
||||
|
||||
for (const item of this.items) {
|
||||
if (item.isFreeItem) {
|
||||
this.items = this.items?.filter(
|
||||
(invoiceItem) => invoiceItem.name !== item.name
|
||||
);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
async applyProductDiscount() {
|
||||
if (!this.pricingRuleDetail || !this.items) {
|
||||
if (!this.items) {
|
||||
return;
|
||||
}
|
||||
|
||||
if (!this.pricingRuleDetail?.length || !this.pricingRuleDetail.length) {
|
||||
return;
|
||||
}
|
||||
|
||||
this.items = this.items.filter((item) => !item.isFreeItem);
|
||||
|
||||
for (const item of this.items) {
|
||||
if (item.isFreeItem) {
|
||||
continue;
|
||||
}
|
||||
|
||||
const pricingRuleDetailForItem = this.pricingRuleDetail.filter(
|
||||
(doc) => doc.referenceItem === item.item
|
||||
);
|
||||
|
||||
if (!pricingRuleDetailForItem.length) {
|
||||
return;
|
||||
}
|
||||
|
||||
const pricingRuleDoc = (await this.fyo.doc.getDoc(
|
||||
ModelNameEnum.PricingRule,
|
||||
pricingRuleDetailForItem[0].referenceName
|
||||
|
@ -141,7 +141,7 @@ test('pricing rule is applied when filtered by min and max qty', async (t) => {
|
||||
);
|
||||
});
|
||||
|
||||
test('pricing rule is not applied when item qty is < min qty ', async (t) => {
|
||||
test('pricing rule is not applied when item qty is < min qty', async (t) => {
|
||||
const sinv = fyo.doc.getNewDoc(ModelNameEnum.SalesInvoice, {
|
||||
date: new Date(),
|
||||
party: partyMap.partyOne.name,
|
||||
@ -548,7 +548,6 @@ test('create a product discount, recurse 2', async (t) => {
|
||||
await sinv.runFormulas();
|
||||
await sinv.sync();
|
||||
|
||||
console.log('freeQty', sinv.items![1].quantity);
|
||||
t.equal(!!sinv.items![1].isFreeItem, true);
|
||||
t.equal(sinv.items![1].rate!.float, pricingRuleMap[1].freeItemRate);
|
||||
t.equal(sinv.items![1].quantity, pricingRuleMap[1].freeItemQuantity);
|
||||
|
@ -663,13 +663,13 @@ export async function addItem<M extends ModelsWithItems>(name: string, doc: M) {
|
||||
|
||||
export async function getPricingRule(
|
||||
doc: Invoice
|
||||
): Promise<ApplicablePricingRules[] | undefined> {
|
||||
): Promise<ApplicablePricingRules[] | null> {
|
||||
if (
|
||||
!doc.fyo.singles.AccountingSettings?.enablePricingRule ||
|
||||
!doc.isSales ||
|
||||
!doc.items
|
||||
) {
|
||||
return;
|
||||
return null;
|
||||
}
|
||||
|
||||
const pricingRules: ApplicablePricingRules[] = [];
|
||||
@ -786,13 +786,15 @@ export function canApplyPricingRule(
|
||||
// Filter by Validity
|
||||
if (
|
||||
pricingRuleDoc.validFrom &&
|
||||
sinvDate.toISOString() < pricingRuleDoc.validFrom.toISOString()
|
||||
new Date(sinvDate.setHours(0, 0, 0, 0)).toISOString() <
|
||||
pricingRuleDoc.validFrom.toISOString()
|
||||
) {
|
||||
return false;
|
||||
}
|
||||
if (
|
||||
pricingRuleDoc.validTo &&
|
||||
sinvDate.toISOString() > pricingRuleDoc.validTo.toISOString()
|
||||
new Date(sinvDate.setHours(0, 0, 0, 0)).toISOString() >
|
||||
pricingRuleDoc.validTo.toISOString()
|
||||
) {
|
||||
return false;
|
||||
}
|
||||
|
@ -362,6 +362,23 @@ export default defineComponent({
|
||||
setTransferRefNo(ref: string) {
|
||||
this.transferRefNo = ref;
|
||||
},
|
||||
removeFreeItems() {
|
||||
if (!this.sinvDoc || !this.sinvDoc.items) {
|
||||
return;
|
||||
}
|
||||
|
||||
if (!!this.sinvDoc.isPricingRuleApplied) {
|
||||
return;
|
||||
}
|
||||
|
||||
for (const item of this.sinvDoc.items) {
|
||||
if (item.isFreeItem) {
|
||||
this.sinvDoc.items = this.sinvDoc.items?.filter(
|
||||
(invoiceItem) => invoiceItem.name !== item.name
|
||||
);
|
||||
}
|
||||
}
|
||||
},
|
||||
|
||||
async addItem(item: POSItem | Item | undefined) {
|
||||
// eslint-disable-next-line @typescript-eslint/no-floating-promises
|
||||
@ -385,17 +402,21 @@ export default defineComponent({
|
||||
|
||||
const existingItems =
|
||||
this.sinvDoc.items?.filter(
|
||||
(invoiceItem) => invoiceItem.item === item.name
|
||||
(invoiceItem) =>
|
||||
invoiceItem.item === item.name && !invoiceItem.isFreeItem
|
||||
) ?? [];
|
||||
|
||||
if (item.hasBatch) {
|
||||
for (const item of existingItems) {
|
||||
const itemQty = item.quantity ?? 0;
|
||||
for (const invItem of existingItems) {
|
||||
const itemQty = invItem.quantity ?? 0;
|
||||
const qtyInBatch =
|
||||
this.itemQtyMap[item.item as string][item.batch as string] ?? 0;
|
||||
this.itemQtyMap[invItem.item as string][invItem.batch as string] ??
|
||||
0;
|
||||
|
||||
if (itemQty < qtyInBatch) {
|
||||
item.quantity = (item.quantity as number) + 1;
|
||||
invItem.quantity = (invItem.quantity as number) + 1;
|
||||
invItem.rate = item.rate as Money;
|
||||
|
||||
return;
|
||||
}
|
||||
}
|
||||
@ -415,8 +436,10 @@ export default defineComponent({
|
||||
}
|
||||
|
||||
if (existingItems.length) {
|
||||
existingItems[0].rate = item.rate as Money;
|
||||
existingItems[0].quantity = (existingItems[0].quantity as number) + 1;
|
||||
await this.applyPricingRule();
|
||||
await this.sinvDoc.runFormulas();
|
||||
return;
|
||||
}
|
||||
|
||||
@ -568,7 +591,11 @@ export default defineComponent({
|
||||
const hasPricingRules = await getPricingRule(
|
||||
this.sinvDoc as SalesInvoice
|
||||
);
|
||||
if (!hasPricingRules) {
|
||||
|
||||
if (!hasPricingRules || !hasPricingRules.length) {
|
||||
this.sinvDoc.pricingRuleDetail = undefined;
|
||||
this.sinvDoc.isPricingRuleApplied = false;
|
||||
this.removeFreeItems();
|
||||
return;
|
||||
}
|
||||
|
||||
|
@ -21,7 +21,8 @@ import { showToast } from './interactive';
|
||||
export async function getItemQtyMap(): Promise<ItemQtyMap> {
|
||||
const itemQtyMap: ItemQtyMap = {};
|
||||
const valuationMethod =
|
||||
fyo.singles.InventorySettings?.valuationMethod ?? ValuationMethod.FIFO;
|
||||
(fyo.singles.InventorySettings?.valuationMethod as ValuationMethod) ??
|
||||
ValuationMethod.FIFO;
|
||||
|
||||
const rawSLEs = await getRawStockLedgerEntries(fyo);
|
||||
const rawData = getStockLedgerEntries(rawSLEs, valuationMethod);
|
||||
|
Loading…
Reference in New Issue
Block a user