mirror of
https://github.com/frappe/books.git
synced 2026-08-24 10:04:45 -05:00
Merge pull request #1242 from frappe/feat-sync-pricing-rule
feat: sync pricing rule from ERPNext
This commit is contained in:
@@ -337,7 +337,17 @@ export abstract class Invoice extends Transactional {
|
||||
|
||||
const tax = await this.getTax(item.tax);
|
||||
for (const details of (tax.details ?? []) as TaxDetail[]) {
|
||||
const amount = item.amount!;
|
||||
let amount = item.amount!;
|
||||
|
||||
if (!this.discountAfterTax) {
|
||||
const itemDiscountAmount = this.getItemDiscountAmount();
|
||||
|
||||
if (this.isReturn) {
|
||||
amount = amount.add(itemDiscountAmount);
|
||||
} else {
|
||||
amount = amount.sub(itemDiscountAmount);
|
||||
}
|
||||
}
|
||||
|
||||
const taxItem: InvoiceTaxItem = {
|
||||
details,
|
||||
@@ -416,6 +426,11 @@ export abstract class Invoice extends Transactional {
|
||||
|
||||
const itemDiscountAmount = this.getItemDiscountAmount();
|
||||
const invoiceDiscountAmount = this.getInvoiceDiscountAmount();
|
||||
|
||||
if (this.isReturn) {
|
||||
return itemDiscountAmount.add(invoiceDiscountAmount).neg();
|
||||
}
|
||||
|
||||
return itemDiscountAmount.add(invoiceDiscountAmount);
|
||||
}
|
||||
|
||||
@@ -430,7 +445,7 @@ export abstract class Invoice extends Transactional {
|
||||
.map((doc) => doc.amount as Money)
|
||||
.reduce((a, b) => {
|
||||
if (this.isReturn) {
|
||||
return a.add(b.abs()).neg();
|
||||
return a.abs().add(b.abs()).neg();
|
||||
}
|
||||
|
||||
return a.add(b.abs());
|
||||
@@ -473,7 +488,9 @@ export abstract class Invoice extends Transactional {
|
||||
for (const item of this.items) {
|
||||
if (item.setItemDiscountAmount) {
|
||||
discountAmount = discountAmount.add(
|
||||
item.itemDiscountAmount ?? this.fyo.pesa(0)
|
||||
(item.itemDiscountAmount ?? this.fyo.pesa(0)).mul(
|
||||
item.quantity as number
|
||||
)
|
||||
);
|
||||
} else if (!this.discountAfterTax) {
|
||||
if (this.isReturn) {
|
||||
@@ -566,6 +583,7 @@ export abstract class Invoice extends Transactional {
|
||||
}
|
||||
|
||||
const docData = this.getValidDict(true, true);
|
||||
docData.pricingRuleDetail = [];
|
||||
const docItems = docData.items as DocValueMap[];
|
||||
|
||||
if (!docItems) {
|
||||
|
||||
@@ -10,6 +10,8 @@ import { StockMovementItem } from 'models/inventory/StockMovementItem';
|
||||
import { getRandomString } from '../../utils';
|
||||
import { ErrorLogEnum } from 'fyo/telemetry/types';
|
||||
import { ValidationError } from 'fyo/utils/errors';
|
||||
import { PricingRule } from 'models/baseModels/PricingRule/PricingRule';
|
||||
import { PricingRuleItem } from 'models/baseModels/PricingRuleItem/PricingRuleItem';
|
||||
|
||||
export async function registerInstanceToERPNext(fyo: Fyo) {
|
||||
if (!navigator.onLine) {
|
||||
@@ -153,10 +155,12 @@ export async function syncDocumentsFromERPNext(fyo: Fyo) {
|
||||
(doc.fbooksDocName as string) || (doc.name as string)
|
||||
);
|
||||
|
||||
doc.name = doc.fbooksDocName ?? doc.name;
|
||||
doc = checkDocDataTypes(fyo, doc) as DocValueMap;
|
||||
|
||||
await existingDoc.setMultiple(doc);
|
||||
await performPreSync(fyo, doc);
|
||||
await appendDocValues(existingDoc as DocValueMap, doc);
|
||||
existingDoc._addDocToSyncQueue = false;
|
||||
|
||||
await existingDoc.sync();
|
||||
@@ -175,7 +179,7 @@ export async function syncDocumentsFromERPNext(fyo: Fyo) {
|
||||
token,
|
||||
deviceID,
|
||||
doc,
|
||||
doc.name as string,
|
||||
(doc.erpnextDocName as string) || (doc.name as string),
|
||||
doc.name as string
|
||||
);
|
||||
continue;
|
||||
@@ -213,7 +217,7 @@ export async function syncDocumentsFromERPNext(fyo: Fyo) {
|
||||
token,
|
||||
deviceID,
|
||||
doc,
|
||||
doc.name as string,
|
||||
(doc.erpnextDocName as string) || (doc.name as string),
|
||||
newDoc.name as string
|
||||
);
|
||||
} catch (error) {
|
||||
@@ -231,6 +235,36 @@ async function appendDocValues(newDoc: DocValueMap, doc: DocValueMap) {
|
||||
conversionFactor: uomDoc.conversionFactor,
|
||||
});
|
||||
}
|
||||
|
||||
case ModelNameEnum.PricingRule:
|
||||
const itemSet = new Set<string>();
|
||||
|
||||
(newDoc as Doc).appliedItems = (
|
||||
newDoc as PricingRule
|
||||
).appliedItems?.filter((row: PricingRuleItem) => {
|
||||
const key = `${row.item as string}::${row.unit as string}`;
|
||||
|
||||
if (itemSet.has(key)) {
|
||||
return false;
|
||||
}
|
||||
|
||||
itemSet.add(key);
|
||||
return true;
|
||||
});
|
||||
|
||||
const docItemSet = new Set<string>(
|
||||
(doc as PricingRule).appliedItems?.map(
|
||||
(row: PricingRuleItem) =>
|
||||
`${row.item as string}::${row.unit as string}`
|
||||
) || []
|
||||
);
|
||||
|
||||
(newDoc as PricingRule).appliedItems = (
|
||||
newDoc as PricingRule
|
||||
).appliedItems?.filter((row: PricingRuleItem) =>
|
||||
docItemSet.has(`${row.item as string}::${row.unit as string}`)
|
||||
);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -573,8 +607,28 @@ function checkDocDataTypes(
|
||||
doc: DocValueMap | Doc
|
||||
): DocValueMap | Doc {
|
||||
switch (doc.doctype) {
|
||||
case ModelNameEnum.Item:
|
||||
case ModelNameEnum.Item: {
|
||||
const fields = ['rate'];
|
||||
|
||||
const updatedDoc = changeDocDataType(
|
||||
fyo,
|
||||
doc,
|
||||
fields,
|
||||
ModelNameEnum.Currency
|
||||
);
|
||||
|
||||
return updatedDoc;
|
||||
}
|
||||
|
||||
case ModelNameEnum.PricingRule: {
|
||||
const fields = [
|
||||
'minAmount',
|
||||
'maxAmount',
|
||||
'discountAmount',
|
||||
'discountRate',
|
||||
'freeItemRate',
|
||||
];
|
||||
|
||||
const updatedDoc = changeDocDataType(
|
||||
fyo,
|
||||
doc,
|
||||
@@ -582,6 +636,8 @@ function checkDocDataTypes(
|
||||
ModelNameEnum.Currency
|
||||
);
|
||||
return updatedDoc;
|
||||
}
|
||||
|
||||
default:
|
||||
return doc;
|
||||
}
|
||||
@@ -591,6 +647,7 @@ function isValidSyncableDocName(doctype: string): boolean {
|
||||
const syncableDocNames = [
|
||||
ModelNameEnum.Item,
|
||||
ModelNameEnum.Batch,
|
||||
ModelNameEnum.PricingRule,
|
||||
] as string[];
|
||||
|
||||
if (syncableDocNames.includes(doctype)) {
|
||||
|
||||
+3
-1
@@ -56,7 +56,9 @@ export function getItemDiscounts(items: SalesInvoiceItem[]): Money {
|
||||
for (const item of items) {
|
||||
if (item.setItemDiscountAmount) {
|
||||
if (!item.itemDiscountAmount?.isZero()) {
|
||||
itemDiscounts = itemDiscounts.add(item.itemDiscountAmount as Money);
|
||||
itemDiscounts = itemDiscounts.add(
|
||||
(item.itemDiscountAmount as Money).mul(item.quantity as number)
|
||||
);
|
||||
}
|
||||
} else {
|
||||
if (item.amount && (item.itemDiscountPercent as number) > 1) {
|
||||
|
||||
Reference in New Issue
Block a user