2
0
mirror of https://github.com/frappe/books.git synced 2024-12-23 11:29:03 +00:00
books/models/baseModels/Item/Item.ts

149 lines
4.1 KiB
TypeScript
Raw Normal View History

import { Fyo } from 'fyo';
import { DocValue } from 'fyo/core/types';
import { Doc } from 'fyo/model/doc';
import {
Action,
FiltersMap,
FormulaMap,
HiddenMap,
ListViewSettings,
ReadOnlyMap,
ValidationMap,
} from 'fyo/model/types';
import { ValidationError } from 'fyo/utils/errors';
2022-05-23 05:30:54 +00:00
import { Money } from 'pesa';
import { AccountRootTypeEnum, AccountTypeEnum } from '../Account/types';
export class Item extends Doc {
trackItem?: boolean;
itemType?: 'Product' | 'Service';
for?: 'Purchases' | 'Sales' | 'Both';
2023-02-28 06:01:04 +00:00
hasBatch?: boolean;
2023-05-04 10:45:12 +00:00
hasSerialNumber?: boolean;
formulas: FormulaMap = {
incomeAccount: {
formula: async () => {
let accountName = 'Service';
if (this.itemType === 'Product') {
accountName = 'Sales';
}
const accountExists = await this.fyo.db.exists('Account', accountName);
return accountExists ? accountName : '';
},
dependsOn: ['itemType'],
},
expenseAccount: {
formula: async () => {
if (this.trackItem) {
return this.fyo.singles.InventorySettings
?.stockReceivedButNotBilled as string;
}
const cogs = await this.fyo.db.getAllRaw('Account', {
filters: {
accountType: AccountTypeEnum['Cost of Goods Sold'],
},
});
if (cogs.length === 0) {
return '';
} else {
return cogs[0].name as string;
}
},
dependsOn: ['itemType', 'trackItem'],
},
};
static filters: FiltersMap = {
incomeAccount: () => ({
isGroup: false,
rootType: AccountRootTypeEnum.Income,
}),
expenseAccount: (doc) => ({
isGroup: false,
rootType: doc.trackItem
? AccountRootTypeEnum.Liability
: AccountRootTypeEnum.Expense,
}),
};
validations: ValidationMap = {
rate: (value: DocValue) => {
if ((value as Money).isNegative()) {
throw new ValidationError(this.fyo.t`Rate can't be negative.`);
}
},
2024-11-04 07:19:07 +00:00
hsnCode: (value: DocValue) => {
if (value && !(value as string).match(/^\d{4,8}$/)) {
throw new ValidationError(this.fyo.t`Invalid HSN Code.`);
}
},
};
static getActions(fyo: Fyo): Action[] {
return [
{
group: fyo.t`Create`,
label: fyo.t`Sales Invoice`,
condition: (doc) => !doc.notInserted && doc.for !== 'Purchases',
action: async (doc, router) => {
const invoice = fyo.doc.getNewDoc('SalesInvoice');
await invoice.append('items', {
item: doc.name as string,
rate: doc.rate as Money,
tax: doc.tax as string,
});
await router.push(`/edit/SalesInvoice/${invoice.name!}`);
},
},
{
group: fyo.t`Create`,
label: fyo.t`Purchase Invoice`,
condition: (doc) => !doc.notInserted && doc.for !== 'Sales',
action: async (doc, router) => {
const invoice = fyo.doc.getNewDoc('PurchaseInvoice');
await invoice.append('items', {
item: doc.name as string,
rate: doc.rate as Money,
tax: doc.tax as string,
});
await router.push(`/edit/PurchaseInvoice/${invoice.name!}`);
},
},
];
}
static getListViewSettings(): ListViewSettings {
return {
columns: ['name', 'unit', 'tax', 'rate'],
};
}
hidden: HiddenMap = {
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-28 06:01:04 +00:00
hasBatch: () =>
!(this.fyo.singles.InventorySettings?.enableBatches && this.trackItem),
2023-05-04 10:45:12 +00:00
hasSerialNumber: () =>
!(
this.fyo.singles.InventorySettings?.enableSerialNumber && this.trackItem
),
uomConversions: () =>
!this.fyo.singles.InventorySettings?.enableUomConversions,
};
readOnly: ReadOnlyMap = {
unit: () => this.inserted,
itemType: () => this.inserted,
trackItem: () => this.inserted,
2023-02-28 06:01:04 +00:00
hasBatch: () => this.inserted,
2023-05-04 10:45:12 +00:00
hasSerialNumber: () => this.inserted,
};
}