diff --git a/models/baseModels/InvoiceItem/InvoiceItem.ts b/models/baseModels/InvoiceItem/InvoiceItem.ts index 44d915ba..e38e1350 100644 --- a/models/baseModels/InvoiceItem/InvoiceItem.ts +++ b/models/baseModels/InvoiceItem/InvoiceItem.ts @@ -23,11 +23,13 @@ export abstract class InvoiceItem extends Doc { amount?: Money; parentdoc?: Invoice; rate?: Money; + + unit?: string; + transferUnit?: string; quantity?: number; - transferQty?: number; - stockUOM?: string; - uom?: string; - UOMConversionFactor?: number; + transferQuantity?: number; + unitConversionFactor?: number; + tax?: string; stockNotTransferred?: number; @@ -49,6 +51,10 @@ export abstract class InvoiceItem extends Doc { return !!this.fyo.singles?.AccountingSettings?.enableDiscounting; } + get enableInventory() { + return !!this.fyo.singles?.AccountingSettings?.enableInventory; + } + get currency() { return this.parentdoc?.currency ?? DEFAULT_CURRENCY; } @@ -141,6 +147,34 @@ export abstract class InvoiceItem extends Doc { 'setItemDiscountAmount', ], }, + unit: { + formula: async () => + (await this.fyo.getValue( + 'Item', + this.item as string, + 'unit' + )) as string, + dependsOn: ['item'], + }, + transferUnit: { + formula: async () => + (await this.fyo.getValue( + 'Item', + this.item as string, + 'unit' + )) as string, + dependsOn: ['item'], + }, + transferQuantity: { + formula: async () => { + if (this.unit === this.transferUnit) { + return this.quantity; + } + + return this.transferQuantity; + }, + dependsOn: ['item'], + }, quantity: { formula: async () => { if (!this.item) { @@ -153,36 +187,34 @@ export abstract class InvoiceItem extends Doc { ); const unitDoc = itemDoc.getLink('uom'); if (unitDoc?.isWhole) { - return Math.round(this.transferQty! * this.UOMConversionFactor!); + return Math.round( + this.transferQuantity! * this.unitConversionFactor! + ); } - return safeParseFloat(this.transferQty! * this.UOMConversionFactor!); - }, - dependsOn: ['quantity', 'transferQty', 'UOMConversionFactor'], - }, - stockUOM: { - formula: async () => { - const { unit } = await this.fyo.db.get( - ModelNameEnum.Item, - this.item!, - 'unit' + return safeParseFloat( + this.transferQuantity! * this.unitConversionFactor! ); - return unit; }, - dependsOn: ['item'], + dependsOn: ['quantity', 'transferQuantity', 'unitConversionFactor'], }, - UOMConversionFactor: { + unitConversionFactor: { formula: async () => { + if (this.unit === this.transferUnit) { + return 1; + } + const conversionFactor = await this.fyo.db.getAll( - ModelNameEnum.UOMConversionFactor, + ModelNameEnum.UOMConversionItem, { - fields: ['value'], + fields: ['conversionFactor'], filters: { parent: this.item! }, } ); - return safeParseFloat(conversionFactor[0].value); + + return safeParseFloat(conversionFactor[0]?.conversionFactor ?? 1); }, - dependsOn: ['uom'], + dependsOn: ['transferUnit'], }, account: { formula: () => { @@ -347,14 +379,20 @@ export abstract class InvoiceItem extends Doc { }) cannot be greater than 100.` ); }, - uom: async (value: DocValue) => { - const item = await this.fyo.db.getAll(ModelNameEnum.UOMConversionFactor, { + transferUnit: async (value: DocValue) => { + if (!this.item) { + return; + } + + const item = await this.fyo.db.getAll(ModelNameEnum.UOMConversionItem, { 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!}` + t`Transfer Unit ${value as string} is not applicable for Item ${this + .item!}` ); }, }; @@ -380,6 +418,8 @@ export abstract class InvoiceItem extends Doc { !(this.enableDiscounting && !!this.setItemDiscountAmount), itemDiscountPercent: () => !(this.enableDiscounting && !this.setItemDiscountAmount), + transferUnit: () => !this.enableInventory, + transferQuantity: () => !this.enableInventory, }; static filters: FiltersMap = { diff --git a/models/inventory/StockMovementItem.ts b/models/inventory/StockMovementItem.ts index ff87c769..35842b77 100644 --- a/models/inventory/StockMovementItem.ts +++ b/models/inventory/StockMovementItem.ts @@ -20,11 +20,13 @@ export class StockMovementItem extends Doc { item?: string; fromLocation?: string; toLocation?: string; + + unit?: string; + transferUnit?: string; quantity?: number; - transferQty?: number; - stockUOM?: string; - uom?: string; - UOMConversionFactor?: number; + transferQuantity?: number; + unitConversionFactor?: number; + rate?: Money; amount?: Money; parentdoc?: StockMovement; @@ -96,29 +98,33 @@ export class StockMovementItem extends Doc { }, dependsOn: ['movementType'], }, - stockUOM: { - formula: async () => { - const { unit } = await this.fyo.db.get( - ModelNameEnum.Item, - this.item!, + unit: { + formula: async () => + (await this.fyo.getValue( + 'Item', + this.item as string, 'unit' - ); - return unit; - }, + )) as string, dependsOn: ['item'], }, - UOMConversionFactor: { + transferUnit: { + formula: async () => + (await this.fyo.getValue( + 'Item', + this.item as string, + 'unit' + )) as string, + dependsOn: ['item'], + }, + transferQuantity: { formula: async () => { - const conversionFactor = await this.fyo.db.getAll( - ModelNameEnum.UOMConversionFactor, - { - fields: ['value'], - filters: { parent: this.item! }, - } - ); - return safeParseFloat(conversionFactor[0].value); + if (this.unit === this.transferUnit) { + return this.quantity; + } + + return this.transferQuantity; }, - dependsOn: ['uom'], + dependsOn: ['item'], }, quantity: { formula: async () => { @@ -132,12 +138,34 @@ export class StockMovementItem extends Doc { ); const unitDoc = itemDoc.getLink('uom'); if (unitDoc?.isWhole) { - return Math.round(this.transferQty! * this.UOMConversionFactor!); + return Math.round( + this.transferQuantity! * this.unitConversionFactor! + ); } - return safeParseFloat(this.transferQty! * this.UOMConversionFactor!); + return safeParseFloat( + this.transferQuantity! * this.unitConversionFactor! + ); }, - dependsOn: ['quantity', 'transferQty', 'UOMConversionFactor'], + dependsOn: ['quantity', 'transferQuantity', 'unitConversionFactor'], + }, + unitConversionFactor: { + formula: async () => { + if (this.unit === this.transferUnit) { + return 1; + } + + const conversionFactor = await this.fyo.db.getAll( + ModelNameEnum.UOMConversionItem, + { + fields: ['conversionFactor'], + filters: { parent: this.item! }, + } + ); + + return safeParseFloat(conversionFactor[0]?.conversionFactor ?? 1); + }, + dependsOn: ['transferUnit'], }, }; @@ -164,14 +192,20 @@ export class StockMovementItem extends Doc { ); } }, - uom: async (value: DocValue) => { - const item = await this.fyo.db.getAll(ModelNameEnum.UOMConversionFactor, { + transferUnit: async (value: DocValue) => { + if (!this.item) { + return; + } + + const item = await this.fyo.db.getAll(ModelNameEnum.UOMConversionItem, { 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!}` + t`Transfer Unit ${value as string} is not applicable for Item ${this + .item!}` ); }, }; diff --git a/models/inventory/StockTransferItem.ts b/models/inventory/StockTransferItem.ts index 97b9e48c..cb58e4f2 100644 --- a/models/inventory/StockTransferItem.ts +++ b/models/inventory/StockTransferItem.ts @@ -10,14 +10,15 @@ import { safeParseFloat } from 'utils/index'; export class StockTransferItem extends Doc { item?: string; location?: string; + + unit?: string; + transferUnit?: string; quantity?: number; - transferQty?: number; - stockUOM?: string; - uom?: string; - UOMConversionFactor?: number; + transferQuantity?: number; + unitConversionFactor?: number; + rate?: Money; amount?: Money; - unit?: string; description?: string; hsnCode?: number; @@ -40,6 +41,66 @@ export class StockTransferItem extends Doc { )) as string, dependsOn: ['item'], }, + transferUnit: { + formula: async () => + (await this.fyo.getValue( + 'Item', + this.item as string, + 'unit' + )) as string, + dependsOn: ['item'], + }, + transferQuantity: { + formula: async () => { + if (this.unit === this.transferUnit) { + return this.quantity; + } + + return this.transferQuantity; + }, + dependsOn: ['item'], + }, + 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.transferQuantity! * this.unitConversionFactor! + ); + } + + return safeParseFloat( + this.transferQuantity! * this.unitConversionFactor! + ); + }, + dependsOn: ['quantity', 'transferQuantity', 'unitConversionFactor'], + }, + unitConversionFactor: { + formula: async () => { + if (this.unit === this.transferUnit) { + return 1; + } + + const conversionFactor = await this.fyo.db.getAll( + ModelNameEnum.UOMConversionItem, + { + fields: ['conversionFactor'], + filters: { parent: this.item! }, + } + ); + + return safeParseFloat(conversionFactor[0]?.conversionFactor ?? 1); + }, + dependsOn: ['transferUnit'], + }, hsnCode: { formula: async () => (await this.fyo.getValue( @@ -71,49 +132,6 @@ 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) { - 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'], - }, account: { formula: () => { let accountType = 'expenseAccount'; @@ -141,14 +159,20 @@ export class StockTransferItem extends Doc { }; validations: ValidationMap = { - uom: async (value: DocValue) => { - const item = await this.fyo.db.getAll(ModelNameEnum.UOMConversionFactor, { + transferUnit: async (value: DocValue) => { + if (!this.item) { + return; + } + + const item = await this.fyo.db.getAll(ModelNameEnum.UOMConversionItem, { 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!}` + t`Transfer Unit ${value as string} is not applicable for Item ${this + .item!}` ); }, }; diff --git a/schemas/app/InvoiceItem.json b/schemas/app/InvoiceItem.json index 9833d07f..0d75772b 100644 --- a/schemas/app/InvoiceItem.json +++ b/schemas/app/InvoiceItem.json @@ -34,6 +34,7 @@ "fieldname": "transferQuantity", "label": "Qty. in Transfer Unit", "fieldtype": "Float", + "default": 1, "required": true }, { @@ -56,7 +57,8 @@ "fieldname": "unitConversionFactor", "label": "Conversion Factor", "fieldtype": "Float", - "required": true + "required": true, + "default": 1 }, { "fieldname": "account", diff --git a/schemas/app/inventory/StockMovementItem.json b/schemas/app/inventory/StockMovementItem.json index 74b00c78..ed2ca679 100644 --- a/schemas/app/inventory/StockMovementItem.json +++ b/schemas/app/inventory/StockMovementItem.json @@ -37,6 +37,7 @@ "fieldname": "transferQuantity", "label": "Qty. in Transfer Unit", "fieldtype": "Float", + "default": 1, "required": true }, { @@ -59,7 +60,8 @@ "fieldname": "unitConversionFactor", "label": "Conversion Factor", "fieldtype": "Float", - "required": true + "required": true, + "default": 1 }, { "fieldname": "rate", diff --git a/schemas/app/inventory/StockTransferItem.json b/schemas/app/inventory/StockTransferItem.json index 55b6460c..1ef8548e 100644 --- a/schemas/app/inventory/StockTransferItem.json +++ b/schemas/app/inventory/StockTransferItem.json @@ -28,6 +28,7 @@ "fieldname": "transferQuantity", "label": "Qty. in Transfer Unit", "fieldtype": "Float", + "default": 1, "required": true }, { @@ -50,7 +51,8 @@ "fieldname": "unitConversionFactor", "label": "Conversion Factor", "fieldtype": "Float", - "required": true + "required": true, + "default": 1 }, { "fieldname": "rate",