mirror of
https://github.com/frappe/books.git
synced 2024-11-08 23:00:56 +00:00
fix: item rate fetch logic
This commit is contained in:
parent
7d10951316
commit
b97bbc293d
@ -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 }),
|
||||||
}),
|
}),
|
||||||
};
|
};
|
||||||
|
|
||||||
|
@ -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,
|
||||||
|
@ -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 () => {
|
||||||
|
@ -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,
|
||||||
|
Loading…
Reference in New Issue
Block a user