mirror of
https://github.com/frappe/books.git
synced 2025-02-02 12:08:27 +00:00
feat: uom conversion factor
This commit is contained in:
parent
da7cd2af55
commit
a132705545
@ -1,4 +1,4 @@
|
||||
import { Fyo } from 'fyo';
|
||||
import { Fyo, t } from 'fyo';
|
||||
import { DocValue, DocValueMap } from 'fyo/core/types';
|
||||
import { Doc } from 'fyo/model/doc';
|
||||
import {
|
||||
@ -13,6 +13,7 @@ import { ValidationError } from 'fyo/utils/errors';
|
||||
import { ModelNameEnum } from 'models/types';
|
||||
import { Money } from 'pesa';
|
||||
import { FieldTypeEnum, Schema } from 'schemas/types';
|
||||
import { safeParseFloat } from 'utils/index';
|
||||
import { Invoice } from '../Invoice/Invoice';
|
||||
import { Item } from '../Item/Item';
|
||||
|
||||
@ -23,6 +24,10 @@ export abstract class InvoiceItem extends Doc {
|
||||
parentdoc?: Invoice;
|
||||
rate?: Money;
|
||||
quantity?: number;
|
||||
transferQty?: number;
|
||||
stockUOM?: string;
|
||||
uom?: string;
|
||||
UOMConversionFactor?: number;
|
||||
tax?: string;
|
||||
stockNotTransferred?: number;
|
||||
|
||||
@ -146,15 +151,38 @@ export abstract class InvoiceItem extends Doc {
|
||||
ModelNameEnum.Item,
|
||||
this.item as string
|
||||
);
|
||||
|
||||
const unitDoc = itemDoc.getLink('unit');
|
||||
const unitDoc = itemDoc.getLink('uom');
|
||||
if (unitDoc?.isWhole) {
|
||||
return Math.round(this.quantity as number);
|
||||
return Math.round(this.transferQty! * this.UOMConversionFactor!);
|
||||
}
|
||||
|
||||
return this.quantity as number;
|
||||
return safeParseFloat(this.transferQty! * this.UOMConversionFactor!);
|
||||
},
|
||||
dependsOn: ['quantity'],
|
||||
dependsOn: ['quantity', 'transferQty', 'UOMConversionFactor'],
|
||||
},
|
||||
stockUOM: {
|
||||
formula: async () => {
|
||||
const { unit } = await this.fyo.db.get(
|
||||
ModelNameEnum.Item,
|
||||
this.item!,
|
||||
'unit'
|
||||
);
|
||||
return unit;
|
||||
},
|
||||
dependsOn: ['item'],
|
||||
},
|
||||
UOMConversionFactor: {
|
||||
formula: async () => {
|
||||
const conversionFactor = await this.fyo.db.getAll(
|
||||
ModelNameEnum.UOMConversionFactor,
|
||||
{
|
||||
fields: ['value'],
|
||||
filters: { parent: this.item! },
|
||||
}
|
||||
);
|
||||
return safeParseFloat(conversionFactor[0].value);
|
||||
},
|
||||
dependsOn: ['uom'],
|
||||
},
|
||||
account: {
|
||||
formula: () => {
|
||||
@ -319,6 +347,16 @@ export abstract class InvoiceItem extends Doc {
|
||||
}) cannot be greater than 100.`
|
||||
);
|
||||
},
|
||||
uom: async (value: DocValue) => {
|
||||
const item = await this.fyo.db.getAll(ModelNameEnum.UOMConversionFactor, {
|
||||
fields: ['parent'],
|
||||
filters: { uom: value as string, parent: this.item! },
|
||||
});
|
||||
if (item.length < 1)
|
||||
throw new ValidationError(
|
||||
t`UOM ${value as string} is not applicable for item ${this.item!}`
|
||||
);
|
||||
},
|
||||
};
|
||||
|
||||
hidden: HiddenMap = {
|
||||
|
@ -1,3 +1,5 @@
|
||||
import { t } from 'fyo';
|
||||
import { DocValue } from 'fyo/core/types';
|
||||
import { Doc } from 'fyo/model/doc';
|
||||
import {
|
||||
FiltersMap,
|
||||
@ -9,6 +11,7 @@ import {
|
||||
import { ValidationError } from 'fyo/utils/errors';
|
||||
import { ModelNameEnum } from 'models/types';
|
||||
import { Money } from 'pesa';
|
||||
import { safeParseFloat } from 'utils/index';
|
||||
import { StockMovement } from './StockMovement';
|
||||
import { MovementType } from './types';
|
||||
|
||||
@ -18,6 +21,10 @@ export class StockMovementItem extends Doc {
|
||||
fromLocation?: string;
|
||||
toLocation?: string;
|
||||
quantity?: number;
|
||||
transferQty?: number;
|
||||
stockUOM?: string;
|
||||
uom?: string;
|
||||
UOMConversionFactor?: number;
|
||||
rate?: Money;
|
||||
amount?: Money;
|
||||
parentdoc?: StockMovement;
|
||||
@ -89,6 +96,49 @@ export class StockMovementItem extends Doc {
|
||||
},
|
||||
dependsOn: ['movementType'],
|
||||
},
|
||||
stockUOM: {
|
||||
formula: async () => {
|
||||
const { unit } = await this.fyo.db.get(
|
||||
ModelNameEnum.Item,
|
||||
this.item!,
|
||||
'unit'
|
||||
);
|
||||
return unit;
|
||||
},
|
||||
dependsOn: ['item'],
|
||||
},
|
||||
UOMConversionFactor: {
|
||||
formula: async () => {
|
||||
const conversionFactor = await this.fyo.db.getAll(
|
||||
ModelNameEnum.UOMConversionFactor,
|
||||
{
|
||||
fields: ['value'],
|
||||
filters: { parent: this.item! },
|
||||
}
|
||||
);
|
||||
return safeParseFloat(conversionFactor[0].value);
|
||||
},
|
||||
dependsOn: ['uom'],
|
||||
},
|
||||
quantity: {
|
||||
formula: async () => {
|
||||
if (!this.item) {
|
||||
return this.quantity as number;
|
||||
}
|
||||
|
||||
const itemDoc = await this.fyo.doc.getDoc(
|
||||
ModelNameEnum.Item,
|
||||
this.item as string
|
||||
);
|
||||
const unitDoc = itemDoc.getLink('uom');
|
||||
if (unitDoc?.isWhole) {
|
||||
return Math.round(this.transferQty! * this.UOMConversionFactor!);
|
||||
}
|
||||
|
||||
return safeParseFloat(this.transferQty! * this.UOMConversionFactor!);
|
||||
},
|
||||
dependsOn: ['quantity', 'transferQty', 'UOMConversionFactor'],
|
||||
},
|
||||
};
|
||||
|
||||
validations: ValidationMap = {
|
||||
@ -114,6 +164,16 @@ export class StockMovementItem extends Doc {
|
||||
);
|
||||
}
|
||||
},
|
||||
uom: async (value: DocValue) => {
|
||||
const item = await this.fyo.db.getAll(ModelNameEnum.UOMConversionFactor, {
|
||||
fields: ['parent'],
|
||||
filters: { uom: value as string, parent: this.item! },
|
||||
});
|
||||
if (item.length < 1)
|
||||
throw new ValidationError(
|
||||
t`UOM ${value as string} is not applicable for item ${this.item!}`
|
||||
);
|
||||
},
|
||||
};
|
||||
|
||||
required: RequiredMap = {
|
||||
|
@ -1,12 +1,20 @@
|
||||
import { t } from 'fyo';
|
||||
import { DocValue } from 'fyo/core/types';
|
||||
import { Doc } from 'fyo/model/doc';
|
||||
import { FiltersMap, FormulaMap } from 'fyo/model/types';
|
||||
import { FiltersMap, FormulaMap, ValidationMap } from 'fyo/model/types';
|
||||
import { ValidationError } from 'fyo/utils/errors';
|
||||
import { ModelNameEnum } from 'models/types';
|
||||
import { Money } from 'pesa';
|
||||
import { safeParseFloat } from 'utils/index';
|
||||
|
||||
export class StockTransferItem extends Doc {
|
||||
item?: string;
|
||||
location?: string;
|
||||
quantity?: number;
|
||||
transferQty?: number;
|
||||
stockUOM?: string;
|
||||
uom?: string;
|
||||
UOMConversionFactor?: number;
|
||||
rate?: Money;
|
||||
amount?: Money;
|
||||
unit?: string;
|
||||
@ -63,6 +71,30 @@ export class StockTransferItem extends Doc {
|
||||
},
|
||||
dependsOn: ['item'],
|
||||
},
|
||||
stockUOM: {
|
||||
formula: async () => {
|
||||
const { unit } = await this.fyo.db.get(
|
||||
ModelNameEnum.Item,
|
||||
this.item!,
|
||||
'unit'
|
||||
);
|
||||
return unit;
|
||||
},
|
||||
dependsOn: ['item'],
|
||||
},
|
||||
UOMConversionFactor: {
|
||||
formula: async () => {
|
||||
const conversionFactor = await this.fyo.db.getAll(
|
||||
ModelNameEnum.UOMConversionFactor,
|
||||
{
|
||||
fields: ['value'],
|
||||
filters: { parent: this.item! },
|
||||
}
|
||||
);
|
||||
return safeParseFloat(conversionFactor[0].value);
|
||||
},
|
||||
dependsOn: ['uom'],
|
||||
},
|
||||
quantity: {
|
||||
formula: async () => {
|
||||
if (!this.item) {
|
||||
@ -73,15 +105,14 @@ export class StockTransferItem extends Doc {
|
||||
ModelNameEnum.Item,
|
||||
this.item as string
|
||||
);
|
||||
|
||||
const unitDoc = itemDoc.getLink('unit');
|
||||
const unitDoc = itemDoc.getLink('uom');
|
||||
if (unitDoc?.isWhole) {
|
||||
return Math.round(this.quantity as number);
|
||||
return Math.round(this.transferQty! * this.UOMConversionFactor!);
|
||||
}
|
||||
|
||||
return this.quantity as number;
|
||||
return safeParseFloat(this.transferQty! * this.UOMConversionFactor!);
|
||||
},
|
||||
dependsOn: ['quantity'],
|
||||
dependsOn: ['quantity', 'transferQty', 'UOMConversionFactor'],
|
||||
},
|
||||
account: {
|
||||
formula: () => {
|
||||
@ -109,6 +140,19 @@ export class StockTransferItem extends Doc {
|
||||
},
|
||||
};
|
||||
|
||||
validations: ValidationMap = {
|
||||
uom: async (value: DocValue) => {
|
||||
const item = await this.fyo.db.getAll(ModelNameEnum.UOMConversionFactor, {
|
||||
fields: ['parent'],
|
||||
filters: { uom: value as string, parent: this.item! },
|
||||
});
|
||||
if (item.length < 1)
|
||||
throw new ValidationError(
|
||||
t`UOM ${value as string} is not applicable for item ${this.item!}`
|
||||
);
|
||||
},
|
||||
};
|
||||
|
||||
static filters: FiltersMap = {
|
||||
item: (doc: Doc) => {
|
||||
let itemNotFor = 'Sales';
|
||||
|
@ -11,6 +11,7 @@ export enum ModelNameEnum {
|
||||
Defaults = 'Defaults',
|
||||
Item = 'Item',
|
||||
UOM = 'UOM',
|
||||
UOMConversionFactor = 'UOMConversionFactor',
|
||||
JournalEntry = 'JournalEntry',
|
||||
JournalEntryAccount = 'JournalEntryAccount',
|
||||
Misc = 'Misc',
|
||||
|
@ -37,6 +37,7 @@ import Tax from './app/Tax.json';
|
||||
import TaxDetail from './app/TaxDetail.json';
|
||||
import TaxSummary from './app/TaxSummary.json';
|
||||
import UOM from './app/UOM.json';
|
||||
import UOMConversionFactor from './app/UOMConversionFactor.json'
|
||||
import PatchRun from './core/PatchRun.json';
|
||||
import SingleValue from './core/SingleValue.json';
|
||||
import SystemSettings from './core/SystemSettings.json';
|
||||
@ -81,6 +82,7 @@ export const appSchemas: Schema[] | SchemaStub[] = [
|
||||
Address as Schema,
|
||||
Item as Schema,
|
||||
UOM as Schema,
|
||||
UOMConversionFactor as Schema,
|
||||
|
||||
Payment as Schema,
|
||||
PaymentFor as Schema,
|
||||
|
Loading…
x
Reference in New Issue
Block a user