From e1123ecc3a5d0504f03110cc2425b4f3d231b23c Mon Sep 17 00:00:00 2001 From: 18alantom <2.alan.tom@gmail.com> Date: Thu, 3 Nov 2022 20:25:08 +0530 Subject: [PATCH] incr: add basic stock ledger (w.i.p) --- reports/index.ts | 2 + reports/inventory/StockLedger.ts | 75 ++++++++++++++++++++++++++++++++ schemas/index.ts | 2 +- src/pages/Report.vue | 5 ++- src/utils/sidebarConfig.ts | 70 +++++++++++++++++------------ 5 files changed, 124 insertions(+), 30 deletions(-) create mode 100644 reports/inventory/StockLedger.ts diff --git a/reports/index.ts b/reports/index.ts index 562fcd90..9a7ae5a3 100644 --- a/reports/index.ts +++ b/reports/index.ts @@ -2,6 +2,7 @@ import { BalanceSheet } from './BalanceSheet/BalanceSheet'; import { GeneralLedger } from './GeneralLedger/GeneralLedger'; import { GSTR1 } from './GoodsAndServiceTax/GSTR1'; import { GSTR2 } from './GoodsAndServiceTax/GSTR2'; +import { StockLedger } from './inventory/StockLedger'; import { ProfitAndLoss } from './ProfitAndLoss/ProfitAndLoss'; import { Report } from './Report'; import { TrialBalance } from './TrialBalance/TrialBalance'; @@ -13,4 +14,5 @@ export const reports = { TrialBalance, GSTR1, GSTR2, + StockLedger, } as Record; diff --git a/reports/inventory/StockLedger.ts b/reports/inventory/StockLedger.ts new file mode 100644 index 00000000..afa0d945 --- /dev/null +++ b/reports/inventory/StockLedger.ts @@ -0,0 +1,75 @@ +import { t } from 'fyo'; +import { RawValueMap } from 'fyo/core/types'; +import { Action } from 'fyo/model/types'; +import { ModelNameEnum } from 'models/types'; +import getCommonExportActions from 'reports/commonExporter'; +import { Report } from 'reports/Report'; +import { ColumnField, ReportCell, ReportData, ReportRow } from 'reports/types'; +import { Field, RawValue } from 'schemas/types'; +import { isNumeric } from 'src/utils'; + +export class StockLedger extends Report { + static title = t`Stock Ledger`; + static reportName = 'stock-ledger'; + + loading: boolean = false; + async setReportData( + filter?: string | undefined, + force?: boolean | undefined + ): Promise { + this.loading = true; + this.reportData = await this._getReportData(); + this.loading = false; + } + + async _getReportData(): Promise { + const columns = this.getColumns(); + const fieldnames = columns.map(({ fieldname }) => fieldname); + const rawData = await this.fyo.db.getAllRaw( + ModelNameEnum.StockLedgerEntry, + { + fields: fieldnames, + } + ); + + return this.convertRawDataToReportData(rawData, columns); + } + + convertRawDataToReportData( + rawData: RawValueMap[], + fields: Field[] + ): ReportData { + const reportData: ReportData = []; + for (const row of rawData) { + reportData.push(this.convertRawDataRowToReportRow(row, fields)); + } + return reportData; + } + + convertRawDataRowToReportRow(row: RawValueMap, fields: Field[]): ReportRow { + const cells: ReportCell[] = []; + for (const { fieldname, fieldtype } of fields) { + const rawValue = row[fieldname] as RawValue; + const value = this.fyo.format(rawValue, fieldtype); + const align = isNumeric(fieldtype) ? 'right' : 'left'; + + cells.push({ rawValue, value, align }); + } + + return { cells }; + } + + getColumns(): ColumnField[] { + return ( + this.fyo.schemaMap[ModelNameEnum.StockLedgerEntry]?.fields ?? [] + ).filter((f) => !f.meta); + } + + getFilters(): Field[] | Promise { + return []; + } + + getActions(): Action[] { + return getCommonExportActions(this); + } +} diff --git a/schemas/index.ts b/schemas/index.ts index 4cb50ec2..46c8bb6a 100644 --- a/schemas/index.ts +++ b/schemas/index.ts @@ -127,7 +127,7 @@ function addNameField(schemaMap: SchemaMap) { continue; } - schema.fields.push(NAME_FIELD as Field); + schema.fields.unshift(NAME_FIELD as Field); } } diff --git a/src/pages/Report.vue b/src/pages/Report.vue index e7ef4002..18e871a6 100644 --- a/src/pages/Report.vue +++ b/src/pages/Report.vue @@ -14,7 +14,10 @@ -
+
{ ]; } +async function getReportSidebar() { + const reports = { + label: t`Reports`, + name: 'reports', + icon: 'reports', + route: '/report/GeneralLedger', + items: [ + { + label: t`General Ledger`, + name: 'general-ledger', + route: '/report/GeneralLedger', + }, + { + label: t`Profit And Loss`, + name: 'profit-and-loss', + route: '/report/ProfitAndLoss', + }, + { + label: t`Balance Sheet`, + name: 'balance-sheet', + route: '/report/BalanceSheet', + }, + { + label: t`Trial Balance`, + name: 'trial-balance', + route: '/report/TrialBalance', + }, + ], + }; + + if (await getIsInventoryEnabled(fyo)) { + reports.items.push({ + label: t`Stock Ledger`, + name: 'stock-ledger', + route: '/report/StockLedger', + }); + } + + return reports; +} + async function getCompleteSidebar(): Promise { return [ { @@ -194,34 +235,7 @@ async function getCompleteSidebar(): Promise { }, ], }, - { - label: t`Reports`, - name: 'reports', - icon: 'reports', - route: '/report/GeneralLedger', - items: [ - { - label: t`General Ledger`, - name: 'general-ledger', - route: '/report/GeneralLedger', - }, - { - label: t`Profit And Loss`, - name: 'profit-and-loss', - route: '/report/ProfitAndLoss', - }, - { - label: t`Balance Sheet`, - name: 'balance-sheet', - route: '/report/BalanceSheet', - }, - { - label: t`Trial Balance`, - name: 'trial-balance', - route: '/report/TrialBalance', - }, - ], - }, + await getReportSidebar(), await getInventorySidebar(), await getRegionalSidebar(), {