2022-04-19 05:59:36 +00:00
|
|
|
import { Fyo } from 'fyo';
|
|
|
|
import { DocValue } from 'fyo/core/types';
|
2022-04-24 06:48:44 +00:00
|
|
|
import { Doc } from 'fyo/model/doc';
|
2022-04-11 12:44:36 +00:00
|
|
|
import {
|
|
|
|
Action,
|
|
|
|
FiltersMap,
|
|
|
|
FormulaMap,
|
2022-10-05 14:37:17 +00:00
|
|
|
HiddenMap,
|
2022-04-11 12:44:36 +00:00
|
|
|
ListViewSettings,
|
2022-10-06 08:50:13 +00:00
|
|
|
ReadOnlyMap,
|
2022-11-21 09:57:59 +00:00
|
|
|
ValidationMap,
|
2022-04-19 05:59:36 +00:00
|
|
|
} from 'fyo/model/types';
|
|
|
|
import { ValidationError } from 'fyo/utils/errors';
|
2023-02-17 09:26:42 +00:00
|
|
|
import { ModelNameEnum } from 'models/types';
|
2022-05-23 05:30:54 +00:00
|
|
|
import { Money } from 'pesa';
|
2022-04-29 13:00:24 +00:00
|
|
|
import { AccountRootTypeEnum, AccountTypeEnum } from '../Account/types';
|
2022-04-11 12:44:36 +00:00
|
|
|
|
|
|
|
export class Item extends Doc {
|
2022-11-21 09:57:59 +00:00
|
|
|
trackItem?: boolean;
|
2022-10-05 14:37:17 +00:00
|
|
|
itemType?: 'Product' | 'Service';
|
2023-01-09 07:03:26 +00:00
|
|
|
for?: 'Purchases' | 'Sales' | 'Both';
|
2023-01-13 13:16:52 +00:00
|
|
|
hasBatchNumber?: boolean;
|
2022-10-05 14:37:17 +00:00
|
|
|
|
2022-04-11 12:44:36 +00:00
|
|
|
formulas: FormulaMap = {
|
2022-04-29 13:00:24 +00:00
|
|
|
incomeAccount: {
|
|
|
|
formula: async () => {
|
|
|
|
let accountName = 'Service';
|
|
|
|
if (this.itemType === 'Product') {
|
|
|
|
accountName = 'Sales';
|
|
|
|
}
|
2022-04-11 12:44:36 +00:00
|
|
|
|
2022-04-29 13:00:24 +00:00
|
|
|
const accountExists = await this.fyo.db.exists('Account', accountName);
|
|
|
|
return accountExists ? accountName : '';
|
|
|
|
},
|
|
|
|
dependsOn: ['itemType'],
|
2022-04-11 12:44:36 +00:00
|
|
|
},
|
2022-04-29 13:00:24 +00:00
|
|
|
expenseAccount: {
|
|
|
|
formula: async () => {
|
2022-11-21 09:57:59 +00:00
|
|
|
if (this.trackItem) {
|
|
|
|
return this.fyo.singles.InventorySettings
|
|
|
|
?.stockReceivedButNotBilled as string;
|
|
|
|
}
|
|
|
|
|
2022-04-29 13:00:24 +00:00
|
|
|
const cogs = await this.fyo.db.getAllRaw('Account', {
|
|
|
|
filters: {
|
|
|
|
accountType: AccountTypeEnum['Cost of Goods Sold'],
|
|
|
|
},
|
|
|
|
});
|
2022-04-11 12:44:36 +00:00
|
|
|
|
2022-04-29 13:00:24 +00:00
|
|
|
if (cogs.length === 0) {
|
|
|
|
return '';
|
|
|
|
} else {
|
|
|
|
return cogs[0].name as string;
|
|
|
|
}
|
|
|
|
},
|
2022-11-21 09:57:59 +00:00
|
|
|
dependsOn: ['itemType', 'trackItem'],
|
2022-04-11 12:44:36 +00:00
|
|
|
},
|
|
|
|
};
|
|
|
|
|
|
|
|
static filters: FiltersMap = {
|
|
|
|
incomeAccount: () => ({
|
|
|
|
isGroup: false,
|
2022-04-29 13:00:24 +00:00
|
|
|
rootType: AccountRootTypeEnum.Income,
|
2022-04-11 12:44:36 +00:00
|
|
|
}),
|
2022-11-21 09:57:59 +00:00
|
|
|
expenseAccount: (doc) => ({
|
2022-04-11 12:44:36 +00:00
|
|
|
isGroup: false,
|
2022-11-21 09:57:59 +00:00
|
|
|
rootType: doc.trackItem
|
|
|
|
? AccountRootTypeEnum.Liability
|
|
|
|
: AccountRootTypeEnum.Expense,
|
2022-04-11 12:44:36 +00:00
|
|
|
}),
|
|
|
|
};
|
|
|
|
|
|
|
|
validations: ValidationMap = {
|
|
|
|
rate: async (value: DocValue) => {
|
|
|
|
if ((value as Money).isNegative()) {
|
2022-04-19 05:59:36 +00:00
|
|
|
throw new ValidationError(this.fyo.t`Rate can't be negative.`);
|
2022-04-11 12:44:36 +00:00
|
|
|
}
|
|
|
|
},
|
|
|
|
};
|
|
|
|
|
2022-04-19 05:59:36 +00:00
|
|
|
static getActions(fyo: Fyo): Action[] {
|
2022-04-18 11:29:20 +00:00
|
|
|
return [
|
|
|
|
{
|
2022-12-14 08:39:45 +00:00
|
|
|
group: fyo.t`Create`,
|
|
|
|
label: fyo.t`Sales Invoice`,
|
2022-05-05 10:44:26 +00:00
|
|
|
condition: (doc) => !doc.notInserted && doc.for !== 'Purchases',
|
2022-04-18 11:29:20 +00:00
|
|
|
action: async (doc, router) => {
|
2022-04-24 06:48:44 +00:00
|
|
|
const invoice = await fyo.doc.getNewDoc('SalesInvoice');
|
|
|
|
await invoice.append('items', {
|
2022-04-18 11:29:20 +00:00
|
|
|
item: doc.name as string,
|
|
|
|
rate: doc.rate as Money,
|
|
|
|
tax: doc.tax as string,
|
|
|
|
});
|
|
|
|
router.push(`/edit/SalesInvoice/${invoice.name}`);
|
|
|
|
},
|
2022-04-11 12:44:36 +00:00
|
|
|
},
|
2022-04-18 11:29:20 +00:00
|
|
|
{
|
2022-12-14 08:39:45 +00:00
|
|
|
group: fyo.t`Create`,
|
|
|
|
label: fyo.t`Purchase Invoice`,
|
2022-05-05 10:44:26 +00:00
|
|
|
condition: (doc) => !doc.notInserted && doc.for !== 'Sales',
|
2022-04-18 11:29:20 +00:00
|
|
|
action: async (doc, router) => {
|
2022-04-24 06:48:44 +00:00
|
|
|
const invoice = await fyo.doc.getNewDoc('PurchaseInvoice');
|
|
|
|
await invoice.append('items', {
|
2022-04-18 11:29:20 +00:00
|
|
|
item: doc.name as string,
|
|
|
|
rate: doc.rate as Money,
|
|
|
|
tax: doc.tax as string,
|
|
|
|
});
|
|
|
|
router.push(`/edit/PurchaseInvoice/${invoice.name}`);
|
|
|
|
},
|
2022-04-11 12:44:36 +00:00
|
|
|
},
|
2022-04-18 11:29:20 +00:00
|
|
|
];
|
|
|
|
}
|
2022-04-11 12:44:36 +00:00
|
|
|
|
2022-04-18 11:29:20 +00:00
|
|
|
static getListViewSettings(): ListViewSettings {
|
|
|
|
return {
|
2023-02-21 05:34:35 +00:00
|
|
|
formRoute: ({ name }) => `/edit/Item/${name}`,
|
2022-04-18 11:29:20 +00:00
|
|
|
columns: ['name', 'unit', 'tax', 'rate'],
|
|
|
|
};
|
|
|
|
}
|
2022-10-05 14:37:17 +00:00
|
|
|
|
|
|
|
hidden: HiddenMap = {
|
2022-10-06 08:50:13 +00:00
|
|
|
trackItem: () =>
|
2022-11-30 05:54:05 +00:00
|
|
|
!this.fyo.singles.AccountingSettings?.enableInventory ||
|
|
|
|
this.itemType !== 'Product' ||
|
|
|
|
(this.inserted && !this.trackItem),
|
2023-01-16 05:31:12 +00:00
|
|
|
barcode: () => !this.fyo.singles.InventorySettings?.enableBarcodes,
|
2023-02-27 12:41:35 +00:00
|
|
|
hasBatchNumber: () =>
|
|
|
|
!(this.fyo.singles.InventorySettings?.enableBatches && this.trackItem),
|
|
|
|
uomConversions: () =>
|
|
|
|
!this.fyo.singles.InventorySettings?.enableUomConversions,
|
2022-10-06 08:50:13 +00:00
|
|
|
};
|
|
|
|
|
|
|
|
readOnly: ReadOnlyMap = {
|
|
|
|
unit: () => this.inserted,
|
|
|
|
itemType: () => this.inserted,
|
|
|
|
trackItem: () => this.inserted,
|
2023-02-17 09:39:57 +00:00
|
|
|
hasBatchNumber: () => this.inserted,
|
2022-10-05 14:37:17 +00:00
|
|
|
};
|
2022-04-11 12:44:36 +00:00
|
|
|
}
|