2
0
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:
akshayitzme 2023-02-15 14:39:56 +05:30 committed by 18alantom
parent da7cd2af55
commit a132705545
5 changed files with 158 additions and 13 deletions

View File

@ -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 = {

View File

@ -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 = {

View File

@ -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';

View File

@ -11,6 +11,7 @@ export enum ModelNameEnum {
Defaults = 'Defaults',
Item = 'Item',
UOM = 'UOM',
UOMConversionFactor = 'UOMConversionFactor',
JournalEntry = 'JournalEntry',
JournalEntryAccount = 'JournalEntryAccount',
Misc = 'Misc',

View File

@ -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,7 +82,8 @@ export const appSchemas: Schema[] | SchemaStub[] = [
Address as Schema,
Item as Schema,
UOM as Schema,
UOMConversionFactor as Schema,
Payment as Schema,
PaymentFor as Schema,