Skip to content

Commit

Permalink
feat: pricing rule
Browse files Browse the repository at this point in the history
  • Loading branch information
akshayitzme committed Feb 1, 2024
1 parent d95c696 commit 5b1018a
Showing 1 changed file with 89 additions and 11 deletions.
100 changes: 89 additions & 11 deletions models/helpers.ts
Original file line number Diff line number Diff line change
Expand Up @@ -16,7 +16,8 @@ import { StockMovement } from './inventory/StockMovement';
import { StockTransfer } from './inventory/StockTransfer';
import { InvoiceStatus, ModelNameEnum } from './types';
import { PricingRule } from './baseModels/PricingRule/PricingRule';
import { showToast } from 'src/utils/interactive';
import { ValidationError } from 'fyo/utils/errors';
import { ApplicablePricingRules } from './baseModels/Invoice/types';

export function getQuoteActions(
fyo: Fyo,
Expand Down Expand Up @@ -565,6 +566,76 @@ export async function addItem<M extends ModelsWithItems>(name: string, doc: M) {
await item.set('item', name);
}

export async function getPricingRule(
doc: Invoice
): Promise<ApplicablePricingRules[] | undefined> {
if (
!doc.fyo.singles.AccountingSettings?.enablePricingRule ||
!doc.isSales ||
!doc.items
) {
return;
}

const pricingRules: ApplicablePricingRules[] = [];

for (const item of doc.items) {
if (item.isFreeItem) {
continue;
}

const pricingRuleDocNames = (
await doc.fyo.db.getAll(ModelNameEnum.PricingRuleItem, {
fields: ['parent'],
filters: {
item: item.item as string,
unit: item.unit as string,
},
})
).map((doc) => doc.parent) as string[];

const pricingRuleDocsForItem = (await doc.fyo.db.getAll(
ModelNameEnum.PricingRule,
{
fields: ['*'],
filters: {
name: ['in', pricingRuleDocNames],
isEnabled: true,
},
orderBy: 'priority',
order: 'desc',
}
)) as PricingRule[];

const filtered = filterPricingRules(
pricingRuleDocsForItem,
doc.date as Date,
item.quantity as number,
item.amount as Money
);

if (!filtered.length) {
continue;
}

const isPricingRuleHasConflicts = getPricingRulesConflicts(
filtered,
item.item as string
);

if (isPricingRuleHasConflicts) {
continue;
}

pricingRules.push({
applyOnItem: item.item as string,
pricingRule: filtered[0],
});
}

return pricingRules;
}

export function filterPricingRules(
pricingRuleDocsForItem: PricingRule[],
sinvDate: Date,
Expand Down Expand Up @@ -637,7 +708,7 @@ export function canApplyPricingRule(
export function getPricingRulesConflicts(
pricingRules: PricingRule[],
item: string
) {
): string[] | undefined {
const pricingRuleDocs = Array.from(pricingRules);

const firstPricingRule = pricingRuleDocs.shift();
Expand All @@ -647,22 +718,29 @@ export function getPricingRulesConflicts(

const conflictingPricingRuleNames: string[] = [];
for (const pricingRuleDoc of pricingRuleDocs.slice(0)) {
if (pricingRuleDoc.priority === firstPricingRule?.priority) {
conflictingPricingRuleNames.push(pricingRuleDoc.name as string);
if (pricingRuleDoc.priority !== firstPricingRule?.priority) {
continue;
}

conflictingPricingRuleNames.push(pricingRuleDoc.name as string);
}

if (!conflictingPricingRuleNames.length) {
return false;
return;
}

showToast({
type: 'error',
message: t`Pricing Rules ${
throw new ValidationError(
t`Pricing Rules ${
firstPricingRule.name as string
}, ${conflictingPricingRuleNames.join(
', '
)} has the same Priority for the Item ${item}.`,
});
return true;
)} has the same Priority for the Item ${item}.`
);
}

export function roundFreeItemQty(
quantity: number,
roundingMethod: 'round' | 'floor' | 'ceil'
): number {
return Math[roundingMethod](quantity);
}

0 comments on commit 5b1018a

Please sign in to comment.