2
0
mirror of https://github.com/frappe/books.git synced 2024-12-22 19:09:01 +00:00

fix: item rate fetch logic

This commit is contained in:
18alantom 2023-06-07 10:15:26 +05:30 committed by Alan
parent 7d10951316
commit b97bbc293d
4 changed files with 76 additions and 135 deletions

View File

@ -12,7 +12,6 @@ import { DEFAULT_CURRENCY } from 'fyo/utils/consts';
import { ValidationError } from 'fyo/utils/errors'; import { ValidationError } from 'fyo/utils/errors';
import { Transactional } from 'models/Transactional/Transactional'; import { Transactional } from 'models/Transactional/Transactional';
import { addItem, getExchangeRate, getNumberSeries } from 'models/helpers'; import { addItem, getExchangeRate, getNumberSeries } from 'models/helpers';
import { InventorySettings } from 'models/inventory/InventorySettings';
import { StockTransfer } from 'models/inventory/StockTransfer'; import { StockTransfer } from 'models/inventory/StockTransfer';
import { validateBatch } from 'models/inventory/helpers'; import { validateBatch } from 'models/inventory/helpers';
import { ModelNameEnum } from 'models/types'; import { ModelNameEnum } from 'models/types';
@ -547,8 +546,8 @@ export abstract class Invoice extends Transactional {
}), }),
numberSeries: (doc: Doc) => ({ referenceType: doc.schemaName }), numberSeries: (doc: Doc) => ({ referenceType: doc.schemaName }),
priceList: (doc: Doc) => ({ priceList: (doc: Doc) => ({
enabled: true, isEnabled: true,
...(doc.isSales ? { selling: true } : { buying: true }), ...(doc.isSales ? { isSales: true } : { isPurchase: true }),
}), }),
}; };

View File

@ -17,7 +17,8 @@ import { safeParseFloat } from 'utils/index';
import { Invoice } from '../Invoice/Invoice'; import { Invoice } from '../Invoice/Invoice';
import { Item } from '../Item/Item'; import { Item } from '../Item/Item';
import { StockTransfer } from 'models/inventory/StockTransfer'; import { StockTransfer } from 'models/inventory/StockTransfer';
import { getPriceListRate } from 'models/helpers'; import { PriceList } from '../PriceList/PriceList';
import { isPesa } from 'fyo/utils';
export abstract class InvoiceItem extends Doc { export abstract class InvoiceItem extends Doc {
item?: string; item?: string;
@ -114,15 +115,7 @@ export abstract class InvoiceItem extends Doc {
}, },
rate: { rate: {
formula: async (fieldname) => { formula: async (fieldname) => {
const priceListRate = await getPriceListRate(this); const rate = await getItemRate(this);
const itemRate = (await this.fyo.getValue(
'Item',
this.item as string,
'rate'
)) as undefined | Money;
const rate = priceListRate instanceof Money ? priceListRate : itemRate;
if (!rate?.float && this.rate?.float) { if (!rate?.float && this.rate?.float) {
return this.rate; return this.rate;
} }
@ -529,6 +522,65 @@ export abstract class InvoiceItem extends Doc {
} }
} }
async function getItemRate(doc: InvoiceItem): Promise<Money | undefined> {
let priceListRate: Money | undefined;
if (doc.fyo.singles.AccountingSettings?.enablePriceList) {
priceListRate = await getItemRateFromPriceList(doc);
}
if (priceListRate) {
return priceListRate;
}
if (!doc.item) {
return;
}
const itemRate = await doc.fyo.getValue(ModelNameEnum.Item, doc.item, 'rate');
if (isPesa(itemRate)) {
return itemRate;
}
return;
}
async function getItemRateFromPriceList(
doc: InvoiceItem
): Promise<Money | undefined> {
const priceListName = doc.parentdoc?.priceList;
const item = doc.item;
if (!priceListName || !item) {
return;
}
const priceList = await doc.fyo.doc.getDoc(
ModelNameEnum.PriceList,
priceListName
);
if (!(priceList instanceof PriceList)) {
return;
}
const unit = doc.unit;
const transferUnit = doc.transferUnit;
const plItem = priceList.priceListItem?.find((pli) => {
if (pli.item !== item) {
return false;
}
if (transferUnit && pli.unit !== transferUnit) {
return false;
} else if (unit && pli.unit !== unit) {
return false;
}
return true;
});
return plItem?.rate;
}
function getDiscountedTotalBeforeTaxation( function getDiscountedTotalBeforeTaxation(
rate: Money, rate: Money,
quantity: number, quantity: number,

View File

@ -1,8 +1,8 @@
import { Doc } from 'fyo/model/doc'; import { Doc } from 'fyo/model/doc';
import { FormulaMap } from 'fyo/model/types'; import type { FormulaMap } from 'fyo/model/types';
import { Money } from 'pesa';
import type { PriceList } from './PriceList';
import { ModelNameEnum } from 'models/types'; import { ModelNameEnum } from 'models/types';
import type { Money } from 'pesa';
import type { PriceList } from './PriceList';
export class PriceListItem extends Doc { export class PriceListItem extends Doc {
item?: string; item?: string;
@ -10,18 +10,6 @@ export class PriceListItem extends Doc {
rate?: Money; rate?: Money;
parentdoc?: PriceList; parentdoc?: PriceList;
get isBuying() {
return !!this.parentdoc?.buying;
}
get isSelling() {
return !!this.parentdoc?.selling;
}
get priceList() {
return this.parentdoc?.name;
}
formulas: FormulaMap = { formulas: FormulaMap = {
unit: { unit: {
formula: async () => { formula: async () => {

View File

@ -17,8 +17,6 @@ import { Invoice } from './baseModels/Invoice/Invoice';
import { StockMovement } from './inventory/StockMovement'; import { StockMovement } from './inventory/StockMovement';
import { StockTransfer } from './inventory/StockTransfer'; import { StockTransfer } from './inventory/StockTransfer';
import { InvoiceStatus, ModelNameEnum } from './types'; import { InvoiceStatus, ModelNameEnum } from './types';
import { InvoiceItem } from './baseModels/InvoiceItem/InvoiceItem';
import { ItemPrice } from './baseModels/ItemPrice/ItemPrice';
export function getInvoiceActions( export function getInvoiceActions(
fyo: Fyo, fyo: Fyo,
@ -332,19 +330,15 @@ export function getPriceListStatusColumn(): ColumnConfig {
label: t`Enabled For`, label: t`Enabled For`,
fieldname: 'enabledFor', fieldname: 'enabledFor',
fieldtype: 'Select', fieldtype: 'Select',
render(doc) { render({ isSales, isPurchase }) {
let status = t`None`; let status = t`None`;
if (doc.buying && !doc.selling) { if (isSales && isPurchase) {
status = t`Buying`; status = t`Sales and Purchase`;
} } else if (isSales) {
status = t`Sales`;
if (doc.selling && !doc.buying) { } else if (isPurchase) {
status = t`Selling`; status = t`Purchase`;
}
if (doc.buying && doc.selling) {
status = t`Buying & Selling`;
} }
return { return {
@ -360,9 +354,9 @@ export function getPriceListEnabledColumn(): ColumnConfig {
fieldname: 'enabled', fieldname: 'enabled',
fieldtype: 'Data', fieldtype: 'Data',
render(doc) { render(doc) {
let status = t`Unenabled`; let status = t`Disabled`;
let color = 'orange'; let color = 'orange';
if (doc.enabled) { if (doc.isEnabled) {
status = t`Enabled`; status = t`Enabled`;
color = 'green'; color = 'green';
} }
@ -374,98 +368,6 @@ export function getPriceListEnabledColumn(): ColumnConfig {
}; };
} }
export async function getItemPrice(
doc: InvoiceItem | ItemPrice,
validFrom?: Date,
validUpto?: Date
): Promise<string | undefined> {
if (!doc.item || !doc.priceList) {
return;
}
const { isUomDependent, enabled, buying, selling } = await doc.fyo.doc.getDoc(
ModelNameEnum.PriceList,
doc.priceList,
);
if(!enabled || doc.isSales && !selling || !doc.isSales && !buying){
return
}
const itemPriceQuery = Object.values(
await doc.fyo.db.getAll(ModelNameEnum.ItemPrice, {
filters: {
enabled: true,
item: doc.item,
// ...(doc.isSales ? { selling: true } : { buying: true }),
...(doc.batch ? { batch: doc.batch as string } : { batch: null }),
},
fields: ['name', 'unit', 'party', 'batch', 'validFrom', 'validUpto'],
})
)[0];
if (!itemPriceQuery) {
return;
}
const { name, unit, party } = itemPriceQuery;
const validFromDate = validFrom ?? itemPriceQuery.validFrom;
const validUptoDate = validFrom ?? itemPriceQuery.validUpto;
let date;
if (doc.date) {
date = new Date((doc.date as Date).setHours(0, 0, 0));
}
if (isUomDependent && unit !== doc.unit) {
return;
}
if (party && doc.party !== party) {
return;
}
if (date instanceof Date) {
if (validFromDate && date < validFromDate) {
return;
}
if (validUptoDate && date > validUptoDate) {
return;
}
}
if (validFrom && validUpto) {
if (validFromDate && validFrom < validFromDate) {
return;
}
if (validUptoDate && validFrom > validUptoDate) {
return;
}
}
return name as string;
}
export async function getPriceListRate(
doc: InvoiceItem
): Promise<Money | undefined> {
const itemPrice = await getItemPrice(doc);
if (!itemPrice) {
return;
}
const itemPriceRate = (await doc.fyo.getValue(
ModelNameEnum.ItemPrice,
itemPrice,
'rate'
)) as Money;
return itemPriceRate;
}
export async function getExchangeRate({ export async function getExchangeRate({
fromCurrency, fromCurrency,
toCurrency, toCurrency,