@tailor-platform/erp-kit 0.6.0 → 0.7.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/CHANGELOG.md +14 -0
- package/README.md +10 -10
- package/dist/cli.mjs +407 -69
- package/package.json +1 -1
- package/skills/erp-kit-app-1-requirements/SKILL.md +33 -17
- package/skills/erp-kit-app-2-requirements-review/SKILL.md +12 -0
- package/skills/erp-kit-app-3-plan/SKILL.md +18 -4
- package/skills/erp-kit-app-3-plan/references/resolver-extraction.md +1 -1
- package/skills/erp-kit-app-3-plan/references/screen-extraction.md +1 -1
- package/skills/erp-kit-app-4-plan-review/SKILL.md +12 -0
- package/skills/erp-kit-app-5-impl-backend/SKILL.md +12 -0
- package/skills/erp-kit-app-6-impl-frontend/SKILL.md +12 -0
- package/skills/erp-kit-app-7-impl-review/SKILL.md +13 -1
- package/skills/erp-kit-app-shared/references/progress-protocol.md +77 -0
- package/skills/erp-kit-mock-scenario/SKILL.md +1 -1
- package/skills/erp-kit-module-1-requirements/SKILL.md +1 -1
- package/skills/erp-kit-module-3-plan/SKILL.md +3 -3
- package/skills/erp-kit-module-3-update-plan/SKILL.md +3 -3
- package/skills/erp-kit-module-5-impl/SKILL.md +1 -1
- package/src/commands/app/index.ts +2 -0
- package/src/commands/app/progress/git-context.ts +16 -0
- package/src/commands/app/progress/index.ts +45 -0
- package/src/commands/app/progress/log.ts +49 -0
- package/src/commands/app/progress/progress.test.ts +128 -0
- package/src/commands/app/progress/schema-cmd.ts +10 -0
- package/src/commands/check.test.ts +4 -4
- package/src/commands/lib/discovery.test.ts +5 -7
- package/src/commands/lib/discovery.ts +8 -8
- package/src/commands/lib/sync-check-source.test.ts +1 -1
- package/src/commands/lib/sync-check-source.ts +6 -1
- package/src/commands/lib/sync-check-tests.test.ts +43 -0
- package/src/commands/lib/sync-check-tests.ts +20 -2
- package/src/commands/sync-check.ts +3 -0
- package/src/generator/generate-app-code.test.ts +0 -6
- package/src/generator/generate-app-code.ts +3 -13
- package/src/generator/generate-code.test.ts +10 -40
- package/src/generator/generate-code.ts +6 -12
- package/src/generator/stub-templates.test.ts +0 -7
- package/src/generator/stub-templates.ts +0 -14
- package/src/modules/finance-ledger/README.md +50 -0
- package/src/modules/finance-ledger/command/.gitkeep +0 -0
- package/src/modules/finance-ledger/command/addJournalLine.generated.ts +6 -0
- package/src/modules/finance-ledger/command/addJournalLine.test.ts +438 -0
- package/src/modules/finance-ledger/command/addJournalLine.ts +122 -0
- package/src/modules/finance-ledger/command/approveAndLockPeriod.generated.ts +6 -0
- package/src/modules/finance-ledger/command/approveAndLockPeriod.test.ts +107 -0
- package/src/modules/finance-ledger/command/approveAndLockPeriod.ts +72 -0
- package/src/modules/finance-ledger/command/beginClose.generated.ts +6 -0
- package/src/modules/finance-ledger/command/beginClose.test.ts +106 -0
- package/src/modules/finance-ledger/command/beginClose.ts +58 -0
- package/src/modules/finance-ledger/command/closePeriod.generated.ts +6 -0
- package/src/modules/finance-ledger/command/closePeriod.test.ts +87 -0
- package/src/modules/finance-ledger/command/closePeriod.ts +44 -0
- package/src/modules/finance-ledger/command/createAccountingPeriod.generated.ts +6 -0
- package/src/modules/finance-ledger/command/createAccountingPeriod.test.ts +425 -0
- package/src/modules/finance-ledger/command/createAccountingPeriod.ts +133 -0
- package/src/modules/finance-ledger/command/createFiscalYear.generated.ts +6 -0
- package/src/modules/finance-ledger/command/createFiscalYear.test.ts +197 -0
- package/src/modules/finance-ledger/command/createFiscalYear.ts +70 -0
- package/src/modules/finance-ledger/command/createJournalEntry.generated.ts +6 -0
- package/src/modules/finance-ledger/command/createJournalEntry.test.ts +261 -0
- package/src/modules/finance-ledger/command/createJournalEntry.ts +121 -0
- package/src/modules/finance-ledger/command/deleteAccountingPeriod.generated.ts +6 -0
- package/src/modules/finance-ledger/command/deleteAccountingPeriod.test.ts +71 -0
- package/src/modules/finance-ledger/command/deleteAccountingPeriod.ts +55 -0
- package/src/modules/finance-ledger/command/deleteFiscalYear.generated.ts +6 -0
- package/src/modules/finance-ledger/command/deleteFiscalYear.test.ts +38 -0
- package/src/modules/finance-ledger/command/deleteFiscalYear.ts +34 -0
- package/src/modules/finance-ledger/command/deleteJournalEntry.generated.ts +6 -0
- package/src/modules/finance-ledger/command/deleteJournalEntry.test.ts +58 -0
- package/src/modules/finance-ledger/command/deleteJournalEntry.ts +43 -0
- package/src/modules/finance-ledger/command/executeYearEndClose.generated.ts +6 -0
- package/src/modules/finance-ledger/command/executeYearEndClose.test.ts +239 -0
- package/src/modules/finance-ledger/command/executeYearEndClose.ts +415 -0
- package/src/modules/finance-ledger/command/finalCloseAndLockPeriod.generated.ts +6 -0
- package/src/modules/finance-ledger/command/finalCloseAndLockPeriod.test.ts +102 -0
- package/src/modules/finance-ledger/command/finalCloseAndLockPeriod.ts +76 -0
- package/src/modules/finance-ledger/command/finalizeFinancialStatement.generated.ts +6 -0
- package/src/modules/finance-ledger/command/finalizeFinancialStatement.test.ts +73 -0
- package/src/modules/finance-ledger/command/finalizeFinancialStatement.ts +73 -0
- package/src/modules/finance-ledger/command/generateFinancialStatement.generated.ts +6 -0
- package/src/modules/finance-ledger/command/generateFinancialStatement.test.ts +311 -0
- package/src/modules/finance-ledger/command/generateFinancialStatement.ts +275 -0
- package/src/modules/finance-ledger/command/generatePreliminaryStatements.generated.ts +6 -0
- package/src/modules/finance-ledger/command/generatePreliminaryStatements.test.ts +152 -0
- package/src/modules/finance-ledger/command/generatePreliminaryStatements.ts +140 -0
- package/src/modules/finance-ledger/command/generateTrialBalance.generated.ts +6 -0
- package/src/modules/finance-ledger/command/generateTrialBalance.test.ts +439 -0
- package/src/modules/finance-ledger/command/generateTrialBalance.ts +268 -0
- package/src/modules/finance-ledger/command/initiatePeriodClose.generated.ts +6 -0
- package/src/modules/finance-ledger/command/initiatePeriodClose.test.ts +153 -0
- package/src/modules/finance-ledger/command/initiatePeriodClose.ts +84 -0
- package/src/modules/finance-ledger/command/openForAdvanceEntry.generated.ts +6 -0
- package/src/modules/finance-ledger/command/openForAdvanceEntry.test.ts +87 -0
- package/src/modules/finance-ledger/command/openForAdvanceEntry.ts +44 -0
- package/src/modules/finance-ledger/command/openPeriod.generated.ts +6 -0
- package/src/modules/finance-ledger/command/openPeriod.test.ts +90 -0
- package/src/modules/finance-ledger/command/openPeriod.ts +44 -0
- package/src/modules/finance-ledger/command/permanentlyClosePeriod.generated.ts +6 -0
- package/src/modules/finance-ledger/command/permanentlyClosePeriod.test.ts +87 -0
- package/src/modules/finance-ledger/command/permanentlyClosePeriod.ts +48 -0
- package/src/modules/finance-ledger/command/postAdjustingEntries.generated.ts +6 -0
- package/src/modules/finance-ledger/command/postAdjustingEntries.test.ts +392 -0
- package/src/modules/finance-ledger/command/postAdjustingEntries.ts +156 -0
- package/src/modules/finance-ledger/command/postJournalEntry.generated.ts +6 -0
- package/src/modules/finance-ledger/command/postJournalEntry.test.ts +346 -0
- package/src/modules/finance-ledger/command/postJournalEntry.ts +160 -0
- package/src/modules/finance-ledger/command/processInventoryHandoff.generated.ts +6 -0
- package/src/modules/finance-ledger/command/processInventoryHandoff.test.ts +211 -0
- package/src/modules/finance-ledger/command/processInventoryHandoff.ts +133 -0
- package/src/modules/finance-ledger/command/processManufacturingHandoff.generated.ts +6 -0
- package/src/modules/finance-ledger/command/processManufacturingHandoff.test.ts +221 -0
- package/src/modules/finance-ledger/command/processManufacturingHandoff.ts +133 -0
- package/src/modules/finance-ledger/command/processPurchaseHandoff.generated.ts +6 -0
- package/src/modules/finance-ledger/command/processPurchaseHandoff.test.ts +222 -0
- package/src/modules/finance-ledger/command/processPurchaseHandoff.ts +133 -0
- package/src/modules/finance-ledger/command/processSalesHandoff.generated.ts +6 -0
- package/src/modules/finance-ledger/command/processSalesHandoff.test.ts +257 -0
- package/src/modules/finance-ledger/command/processSalesHandoff.ts +135 -0
- package/src/modules/finance-ledger/command/regenerateFinancialStatement.generated.ts +6 -0
- package/src/modules/finance-ledger/command/regenerateFinancialStatement.test.ts +129 -0
- package/src/modules/finance-ledger/command/regenerateFinancialStatement.ts +186 -0
- package/src/modules/finance-ledger/command/removeJournalLine.generated.ts +6 -0
- package/src/modules/finance-ledger/command/removeJournalLine.test.ts +65 -0
- package/src/modules/finance-ledger/command/removeJournalLine.ts +39 -0
- package/src/modules/finance-ledger/command/reopenPeriod.generated.ts +6 -0
- package/src/modules/finance-ledger/command/reopenPeriod.test.ts +87 -0
- package/src/modules/finance-ledger/command/reopenPeriod.ts +44 -0
- package/src/modules/finance-ledger/command/reverseJournalEntry.generated.ts +6 -0
- package/src/modules/finance-ledger/command/reverseJournalEntry.test.ts +337 -0
- package/src/modules/finance-ledger/command/reverseJournalEntry.ts +140 -0
- package/src/modules/finance-ledger/command/revertSoftLock.generated.ts +6 -0
- package/src/modules/finance-ledger/command/revertSoftLock.test.ts +96 -0
- package/src/modules/finance-ledger/command/revertSoftLock.ts +67 -0
- package/src/modules/finance-ledger/command/updateFiscalYear.generated.ts +6 -0
- package/src/modules/finance-ledger/command/updateFiscalYear.test.ts +138 -0
- package/src/modules/finance-ledger/command/updateFiscalYear.ts +85 -0
- package/src/modules/finance-ledger/command/updateJournalEntry.generated.ts +6 -0
- package/src/modules/finance-ledger/command/updateJournalEntry.test.ts +195 -0
- package/src/modules/finance-ledger/command/updateJournalEntry.ts +86 -0
- package/src/modules/finance-ledger/command/updateJournalLine.generated.ts +6 -0
- package/src/modules/finance-ledger/command/updateJournalLine.test.ts +385 -0
- package/src/modules/finance-ledger/command/updateJournalLine.ts +155 -0
- package/src/modules/finance-ledger/command/verifySubledgerTransfers.generated.ts +6 -0
- package/src/modules/finance-ledger/command/verifySubledgerTransfers.test.ts +201 -0
- package/src/modules/finance-ledger/command/verifySubledgerTransfers.ts +113 -0
- package/src/modules/finance-ledger/command/verifyTrialBalance.generated.ts +6 -0
- package/src/modules/finance-ledger/command/verifyTrialBalance.test.ts +136 -0
- package/src/modules/finance-ledger/command/verifyTrialBalance.ts +97 -0
- package/src/modules/finance-ledger/db/.gitkeep +0 -0
- package/src/modules/finance-ledger/db/accountingPeriod.ts +58 -0
- package/src/modules/finance-ledger/db/financialStatement.ts +92 -0
- package/src/modules/finance-ledger/db/financialStatementLineItem.ts +76 -0
- package/src/modules/finance-ledger/db/fiscalYear.ts +41 -0
- package/src/modules/finance-ledger/db/journalEntry.ts +101 -0
- package/src/modules/finance-ledger/db/journalLine.ts +64 -0
- package/src/modules/finance-ledger/db/periodClose.ts +97 -0
- package/src/modules/finance-ledger/db/trialBalance.ts +63 -0
- package/src/modules/finance-ledger/db/trialBalanceLine.ts +63 -0
- package/src/modules/finance-ledger/docs/commands/AddJournalLine.md +74 -0
- package/src/modules/finance-ledger/docs/commands/ApproveAndLockPeriod.md +53 -0
- package/src/modules/finance-ledger/docs/commands/BeginClose.md +47 -0
- package/src/modules/finance-ledger/docs/commands/ClosePeriod.md +45 -0
- package/src/modules/finance-ledger/docs/commands/CreateAccountingPeriod.md +69 -0
- package/src/modules/finance-ledger/docs/commands/CreateFiscalYear.md +56 -0
- package/src/modules/finance-ledger/docs/commands/CreateJournalEntry.md +63 -0
- package/src/modules/finance-ledger/docs/commands/DeleteAccountingPeriod.md +46 -0
- package/src/modules/finance-ledger/docs/commands/DeleteFiscalYear.md +40 -0
- package/src/modules/finance-ledger/docs/commands/DeleteJournalEntry.md +44 -0
- package/src/modules/finance-ledger/docs/commands/ExecuteYearEndClose.md +81 -0
- package/src/modules/finance-ledger/docs/commands/FinalCloseAndLockPeriod.md +49 -0
- package/src/modules/finance-ledger/docs/commands/FinalizeFinancialStatement.md +43 -0
- package/src/modules/finance-ledger/docs/commands/GenerateFinancialStatement.md +86 -0
- package/src/modules/finance-ledger/docs/commands/GeneratePreliminaryStatements.md +53 -0
- package/src/modules/finance-ledger/docs/commands/GenerateTrialBalance.md +75 -0
- package/src/modules/finance-ledger/docs/commands/InitiatePeriodClose.md +58 -0
- package/src/modules/finance-ledger/docs/commands/OpenForAdvanceEntry.md +44 -0
- package/src/modules/finance-ledger/docs/commands/OpenPeriod.md +45 -0
- package/src/modules/finance-ledger/docs/commands/PermanentlyClosePeriod.md +45 -0
- package/src/modules/finance-ledger/docs/commands/PostAdjustingEntries.md +61 -0
- package/src/modules/finance-ledger/docs/commands/PostJournalEntry.md +81 -0
- package/src/modules/finance-ledger/docs/commands/ProcessInventoryHandoff.md +72 -0
- package/src/modules/finance-ledger/docs/commands/ProcessManufacturingHandoff.md +68 -0
- package/src/modules/finance-ledger/docs/commands/ProcessPurchaseHandoff.md +68 -0
- package/src/modules/finance-ledger/docs/commands/ProcessSalesHandoff.md +71 -0
- package/src/modules/finance-ledger/docs/commands/RegenerateFinancialStatement.md +60 -0
- package/src/modules/finance-ledger/docs/commands/RemoveJournalLine.md +42 -0
- package/src/modules/finance-ledger/docs/commands/ReopenPeriod.md +45 -0
- package/src/modules/finance-ledger/docs/commands/ReverseJournalEntry.md +62 -0
- package/src/modules/finance-ledger/docs/commands/RevertSoftLock.md +49 -0
- package/src/modules/finance-ledger/docs/commands/UpdateFiscalYear.md +60 -0
- package/src/modules/finance-ledger/docs/commands/UpdateJournalEntry.md +50 -0
- package/src/modules/finance-ledger/docs/commands/UpdateJournalLine.md +61 -0
- package/src/modules/finance-ledger/docs/commands/VerifySubledgerTransfers.md +59 -0
- package/src/modules/finance-ledger/docs/commands/VerifyTrialBalance.md +53 -0
- package/src/modules/finance-ledger/docs/features/accounting-period-management.md +110 -0
- package/src/modules/finance-ledger/docs/features/financial-statement-generation.md +115 -0
- package/src/modules/finance-ledger/docs/features/journal-entry-management.md +138 -0
- package/src/modules/finance-ledger/docs/features/period-end-close.md +102 -0
- package/src/modules/finance-ledger/docs/features/subledger-integration.md +141 -0
- package/src/modules/finance-ledger/docs/features/trial-balance.md +99 -0
- package/src/modules/finance-ledger/docs/features/year-end-close.md +84 -0
- package/src/modules/finance-ledger/docs/models/AccountingPeriod.md +71 -0
- package/src/modules/finance-ledger/docs/models/FinancialStatement.md +76 -0
- package/src/modules/finance-ledger/docs/models/FinancialStatementLineItem.md +41 -0
- package/src/modules/finance-ledger/docs/models/FiscalYear.md +41 -0
- package/src/modules/finance-ledger/docs/models/JournalEntry.md +80 -0
- package/src/modules/finance-ledger/docs/models/JournalLine.md +47 -0
- package/src/modules/finance-ledger/docs/models/PeriodClose.md +83 -0
- package/src/modules/finance-ledger/docs/models/TrialBalance.md +56 -0
- package/src/modules/finance-ledger/docs/models/TrialBalanceLine.md +37 -0
- package/src/modules/finance-ledger/docs/queries/GetAccountingPeriod.md +35 -0
- package/src/modules/finance-ledger/docs/queries/GetFinancialStatement.md +38 -0
- package/src/modules/finance-ledger/docs/queries/GetFiscalYear.md +35 -0
- package/src/modules/finance-ledger/docs/queries/GetJournalEntry.md +37 -0
- package/src/modules/finance-ledger/docs/queries/GetPeriodByDate.md +38 -0
- package/src/modules/finance-ledger/docs/queries/GetPeriodClose.md +36 -0
- package/src/modules/finance-ledger/docs/queries/GetSubledgerTransferStatus.md +45 -0
- package/src/modules/finance-ledger/docs/queries/GetTrialBalance.md +38 -0
- package/src/modules/finance-ledger/docs/queries/ListAccountingPeriods.md +46 -0
- package/src/modules/finance-ledger/docs/queries/ListFinancialStatements.md +46 -0
- package/src/modules/finance-ledger/docs/queries/ListFiscalYears.md +42 -0
- package/src/modules/finance-ledger/docs/queries/ListJournalEntries.md +48 -0
- package/src/modules/finance-ledger/docs/queries/ListPeriodCloses.md +46 -0
- package/src/modules/finance-ledger/docs/queries/ListTrialBalances.md +51 -0
- package/src/modules/finance-ledger/executor/.gitkeep +0 -0
- package/src/modules/finance-ledger/generated/enums.ts +109 -0
- package/src/modules/finance-ledger/generated/kysely-tailordb.ts +202 -0
- package/src/modules/finance-ledger/index.ts +2 -0
- package/src/modules/finance-ledger/lib/_db_deps.ts +56 -0
- package/src/modules/finance-ledger/lib/errors.generated.ts +332 -0
- package/src/modules/finance-ledger/lib/permissions.generated.ts +41 -0
- package/src/modules/finance-ledger/lib/types.ts +66 -0
- package/src/modules/finance-ledger/module.ts +262 -0
- package/src/modules/finance-ledger/package.json +26 -0
- package/src/modules/finance-ledger/permissions.ts +3 -0
- package/src/modules/finance-ledger/query/.gitkeep +0 -0
- package/src/modules/finance-ledger/query/getAccountingPeriod.generated.ts +5 -0
- package/src/modules/finance-ledger/query/getAccountingPeriod.test.ts +31 -0
- package/src/modules/finance-ledger/query/getAccountingPeriod.ts +21 -0
- package/src/modules/finance-ledger/query/getFinancialStatement.generated.ts +5 -0
- package/src/modules/finance-ledger/query/getFinancialStatement.test.ts +35 -0
- package/src/modules/finance-ledger/query/getFinancialStatement.ts +29 -0
- package/src/modules/finance-ledger/query/getFiscalYear.generated.ts +5 -0
- package/src/modules/finance-ledger/query/getFiscalYear.test.ts +31 -0
- package/src/modules/finance-ledger/query/getFiscalYear.ts +21 -0
- package/src/modules/finance-ledger/query/getJournalEntry.generated.ts +5 -0
- package/src/modules/finance-ledger/query/getJournalEntry.test.ts +35 -0
- package/src/modules/finance-ledger/query/getJournalEntry.ts +29 -0
- package/src/modules/finance-ledger/query/getPeriodByDate.generated.ts +5 -0
- package/src/modules/finance-ledger/query/getPeriodByDate.test.ts +53 -0
- package/src/modules/finance-ledger/query/getPeriodByDate.ts +27 -0
- package/src/modules/finance-ledger/query/getPeriodClose.generated.ts +5 -0
- package/src/modules/finance-ledger/query/getPeriodClose.test.ts +31 -0
- package/src/modules/finance-ledger/query/getPeriodClose.ts +21 -0
- package/src/modules/finance-ledger/query/getSubledgerTransferStatus.generated.ts +5 -0
- package/src/modules/finance-ledger/query/getSubledgerTransferStatus.test.ts +101 -0
- package/src/modules/finance-ledger/query/getSubledgerTransferStatus.ts +68 -0
- package/src/modules/finance-ledger/query/getTrialBalance.generated.ts +5 -0
- package/src/modules/finance-ledger/query/getTrialBalance.test.ts +33 -0
- package/src/modules/finance-ledger/query/getTrialBalance.ts +30 -0
- package/src/modules/finance-ledger/query/listAccountingPeriods.generated.ts +5 -0
- package/src/modules/finance-ledger/query/listAccountingPeriods.test.ts +81 -0
- package/src/modules/finance-ledger/query/listAccountingPeriods.ts +61 -0
- package/src/modules/finance-ledger/query/listFinancialStatements.generated.ts +5 -0
- package/src/modules/finance-ledger/query/listFinancialStatements.test.ts +76 -0
- package/src/modules/finance-ledger/query/listFinancialStatements.ts +62 -0
- package/src/modules/finance-ledger/query/listFiscalYears.generated.ts +5 -0
- package/src/modules/finance-ledger/query/listFiscalYears.test.ts +63 -0
- package/src/modules/finance-ledger/query/listFiscalYears.ts +45 -0
- package/src/modules/finance-ledger/query/listJournalEntries.generated.ts +5 -0
- package/src/modules/finance-ledger/query/listJournalEntries.test.ts +91 -0
- package/src/modules/finance-ledger/query/listJournalEntries.ts +64 -0
- package/src/modules/finance-ledger/query/listPeriodCloses.generated.ts +5 -0
- package/src/modules/finance-ledger/query/listPeriodCloses.test.ts +63 -0
- package/src/modules/finance-ledger/query/listPeriodCloses.ts +64 -0
- package/src/modules/finance-ledger/query/listTrialBalances.generated.ts +5 -0
- package/src/modules/finance-ledger/query/listTrialBalances.test.ts +78 -0
- package/src/modules/finance-ledger/query/listTrialBalances.ts +56 -0
- package/src/modules/finance-ledger/seed/index.ts +19 -0
- package/src/modules/finance-ledger/tailor.config.ts +13 -0
- package/src/modules/finance-ledger/tailor.d.ts +13 -0
- package/src/modules/finance-ledger/testing/commandTestUtils.ts +35 -0
- package/src/modules/finance-ledger/testing/fixtures.ts +382 -0
- package/src/modules/finance-ledger/tsconfig.json +16 -0
- package/src/progress/schema.test.ts +161 -0
- package/src/progress/schema.ts +316 -0
- package/templates/scaffold/app/backend/package.json +1 -3
- package/templates/scaffold/app/backend/vitest.config.ts +4 -21
- package/src/generator/generate-stubs.ts +0 -35
|
@@ -0,0 +1,186 @@
|
|
|
1
|
+
import { err, ok, type CommandContext } from "@tailor-platform/erp-kit/module";
|
|
2
|
+
import type { Transaction } from "../generated/kysely-tailordb";
|
|
3
|
+
import {
|
|
4
|
+
FinancialStatementNotFoundError,
|
|
5
|
+
StatementAlreadyFinalizedError,
|
|
6
|
+
TrialBalanceNotFoundError,
|
|
7
|
+
TrialBalanceImbalancedError,
|
|
8
|
+
ComparativeTrialBalanceNotFoundError,
|
|
9
|
+
} from "../lib/errors.generated";
|
|
10
|
+
|
|
11
|
+
export interface RegenerateFinancialStatementInput {
|
|
12
|
+
id: string;
|
|
13
|
+
}
|
|
14
|
+
|
|
15
|
+
function getSectionType(classification: string, statementType: string): string {
|
|
16
|
+
if (statementType === "BALANCE_SHEET") {
|
|
17
|
+
if (classification === "ASSET") return "Assets";
|
|
18
|
+
if (classification === "LIABILITY") return "Liabilities";
|
|
19
|
+
return "Equity";
|
|
20
|
+
}
|
|
21
|
+
if (statementType === "PROFIT_AND_LOSS") {
|
|
22
|
+
if (classification === "REVENUE") return "Revenue";
|
|
23
|
+
return "Expenses";
|
|
24
|
+
}
|
|
25
|
+
// CASH_FLOW
|
|
26
|
+
if (classification === "REVENUE" || classification === "EXPENSE") return "Operating Activities";
|
|
27
|
+
if (classification === "ASSET") return "Investing Activities";
|
|
28
|
+
return "Financing Activities";
|
|
29
|
+
}
|
|
30
|
+
|
|
31
|
+
/**
|
|
32
|
+
* Function: regenerateFinancialStatement
|
|
33
|
+
*
|
|
34
|
+
* Replaces content of an existing DRAFT financial statement with fresh
|
|
35
|
+
* trial balance data. Only DRAFT statements can be regenerated —
|
|
36
|
+
* FINALIZED statements are immutable. Refetches trial balance data,
|
|
37
|
+
* replaces all line items, updates timestamps, and refreshes
|
|
38
|
+
* comparative data.
|
|
39
|
+
*/
|
|
40
|
+
export async function run(
|
|
41
|
+
db: Transaction,
|
|
42
|
+
input: RegenerateFinancialStatementInput,
|
|
43
|
+
ctx: CommandContext,
|
|
44
|
+
) {
|
|
45
|
+
const { id } = input;
|
|
46
|
+
const auditTrail: { type: string; actorId?: string; timestamp?: Date }[] = [];
|
|
47
|
+
|
|
48
|
+
// 1. Find FinancialStatement by id with forUpdate()
|
|
49
|
+
const financialStatement = await db
|
|
50
|
+
.selectFrom("FinancialStatement")
|
|
51
|
+
.selectAll()
|
|
52
|
+
.where("id", "=", id)
|
|
53
|
+
.forUpdate()
|
|
54
|
+
.executeTakeFirst();
|
|
55
|
+
|
|
56
|
+
if (!financialStatement) {
|
|
57
|
+
return err(new FinancialStatementNotFoundError(id));
|
|
58
|
+
}
|
|
59
|
+
|
|
60
|
+
// 2. Validate status is DRAFT
|
|
61
|
+
if (financialStatement.status !== "DRAFT") {
|
|
62
|
+
return err(new StatementAlreadyFinalizedError(id));
|
|
63
|
+
}
|
|
64
|
+
|
|
65
|
+
// 3. Find the trial balance using statement.trialBalanceId
|
|
66
|
+
const trialBalance = await db
|
|
67
|
+
.selectFrom("TrialBalance")
|
|
68
|
+
.selectAll()
|
|
69
|
+
.where("id", "=", financialStatement.trialBalanceId)
|
|
70
|
+
.executeTakeFirst();
|
|
71
|
+
|
|
72
|
+
if (!trialBalance) {
|
|
73
|
+
return err(new TrialBalanceNotFoundError(financialStatement.trialBalanceId));
|
|
74
|
+
}
|
|
75
|
+
|
|
76
|
+
// 4. Validate trial balance is balanced
|
|
77
|
+
if (!trialBalance.isBalanced || trialBalance.totalDebits !== trialBalance.totalCredits) {
|
|
78
|
+
const discrepancy = Math.abs(trialBalance.totalDebits - trialBalance.totalCredits);
|
|
79
|
+
return err(new TrialBalanceImbalancedError(`${trialBalance.id} (discrepancy: ${discrepancy})`));
|
|
80
|
+
}
|
|
81
|
+
|
|
82
|
+
// 5. If comparativePeriodTrialBalanceId is set, validate it exists
|
|
83
|
+
let comparativeLines: Record<string, unknown>[] = [];
|
|
84
|
+
if (financialStatement.comparativePeriodTrialBalanceId) {
|
|
85
|
+
const comparativeTrialBalance = await db
|
|
86
|
+
.selectFrom("TrialBalance")
|
|
87
|
+
.selectAll()
|
|
88
|
+
.where("id", "=", financialStatement.comparativePeriodTrialBalanceId)
|
|
89
|
+
.executeTakeFirst();
|
|
90
|
+
|
|
91
|
+
if (!comparativeTrialBalance) {
|
|
92
|
+
return err(
|
|
93
|
+
new ComparativeTrialBalanceNotFoundError(
|
|
94
|
+
financialStatement.comparativePeriodTrialBalanceId,
|
|
95
|
+
),
|
|
96
|
+
);
|
|
97
|
+
}
|
|
98
|
+
|
|
99
|
+
comparativeLines = (await db
|
|
100
|
+
.selectFrom("TrialBalanceLine" as never)
|
|
101
|
+
.where(
|
|
102
|
+
"trialBalanceId" as never,
|
|
103
|
+
"=",
|
|
104
|
+
financialStatement.comparativePeriodTrialBalanceId as never,
|
|
105
|
+
)
|
|
106
|
+
.selectAll()
|
|
107
|
+
.execute()) as Record<string, unknown>[];
|
|
108
|
+
}
|
|
109
|
+
|
|
110
|
+
// Build comparative amount map
|
|
111
|
+
const comparativeMap = new Map<string, number>();
|
|
112
|
+
for (const line of comparativeLines) {
|
|
113
|
+
comparativeMap.set(line.accountId as string, line.closingBalance as number);
|
|
114
|
+
}
|
|
115
|
+
|
|
116
|
+
// 6. Delete existing line items for this statement
|
|
117
|
+
await db
|
|
118
|
+
.deleteFrom("FinancialStatementLineItem")
|
|
119
|
+
.where("financialStatementId", "=", id)
|
|
120
|
+
.execute();
|
|
121
|
+
|
|
122
|
+
// 7. Fetch trial balance lines and rebuild line items
|
|
123
|
+
const trialBalanceLines = (await db
|
|
124
|
+
.selectFrom("TrialBalanceLine")
|
|
125
|
+
.selectAll()
|
|
126
|
+
.where("trialBalanceId", "=", trialBalance.id)
|
|
127
|
+
.orderBy("sortOrder", "asc")
|
|
128
|
+
.execute()) as Record<string, unknown>[];
|
|
129
|
+
|
|
130
|
+
const now = new Date();
|
|
131
|
+
let sortOrder = 0;
|
|
132
|
+
|
|
133
|
+
// 8. Insert new line items
|
|
134
|
+
for (const tbLine of trialBalanceLines) {
|
|
135
|
+
// Look up the account to get classification for section type
|
|
136
|
+
const account = await db
|
|
137
|
+
.selectFrom("Account" as never)
|
|
138
|
+
.where("id" as never, "=", tbLine.accountId as never)
|
|
139
|
+
.selectAll()
|
|
140
|
+
.executeTakeFirst();
|
|
141
|
+
|
|
142
|
+
if (!account) continue;
|
|
143
|
+
const acct = account as Record<string, unknown>;
|
|
144
|
+
|
|
145
|
+
sortOrder++;
|
|
146
|
+
await db
|
|
147
|
+
.insertInto("FinancialStatementLineItem")
|
|
148
|
+
.values({
|
|
149
|
+
financialStatementId: id,
|
|
150
|
+
accountId: tbLine.accountId as string,
|
|
151
|
+
accountGroupId: (tbLine.accountGroupId as string | null) ?? null,
|
|
152
|
+
label: tbLine.accountName as string,
|
|
153
|
+
amount: tbLine.closingBalance as number,
|
|
154
|
+
comparativeAmount: comparativeMap.get(tbLine.accountId as string) ?? null,
|
|
155
|
+
lineType: "DETAIL" as never,
|
|
156
|
+
sectionType: getSectionType(
|
|
157
|
+
acct.classification as string,
|
|
158
|
+
financialStatement.statementType,
|
|
159
|
+
),
|
|
160
|
+
sortOrder,
|
|
161
|
+
createdAt: now,
|
|
162
|
+
})
|
|
163
|
+
.returningAll()
|
|
164
|
+
.executeTakeFirstOrThrow();
|
|
165
|
+
}
|
|
166
|
+
|
|
167
|
+
// 9. Update generatedAt timestamp on the statement
|
|
168
|
+
const updatedStatement = await db
|
|
169
|
+
.updateTable("FinancialStatement")
|
|
170
|
+
.set({
|
|
171
|
+
generatedAt: now,
|
|
172
|
+
updatedAt: now,
|
|
173
|
+
})
|
|
174
|
+
.where("id", "=", id)
|
|
175
|
+
.returningAll()
|
|
176
|
+
.executeTakeFirst();
|
|
177
|
+
|
|
178
|
+
// 10. Record audit event
|
|
179
|
+
auditTrail.push({
|
|
180
|
+
type: "STATEMENT_REGENERATED",
|
|
181
|
+
actorId: ctx.actorId,
|
|
182
|
+
timestamp: now,
|
|
183
|
+
});
|
|
184
|
+
|
|
185
|
+
return ok({ financialStatement: updatedStatement!, auditTrail });
|
|
186
|
+
}
|
|
@@ -0,0 +1,6 @@
|
|
|
1
|
+
// @generated — do not edit
|
|
2
|
+
import { defineCommand } from "@tailor-platform/erp-kit/module";
|
|
3
|
+
import { permissions } from "../lib/permissions.generated";
|
|
4
|
+
import { run } from "./removeJournalLine";
|
|
5
|
+
|
|
6
|
+
export const removeJournalLine = defineCommand(permissions.removeJournalLine, run);
|
|
@@ -0,0 +1,65 @@
|
|
|
1
|
+
import { describe, it, expect } from "vitest";
|
|
2
|
+
import { createMockDb } from "../../../testing/index";
|
|
3
|
+
import type { Transaction } from "../generated/kysely-tailordb";
|
|
4
|
+
import { commandCtx, expectErr, expectOk } from "../testing/commandTestUtils";
|
|
5
|
+
import { JournalLineNotFoundError, InvalidStatusForLineRemoveError } from "../lib/errors.generated";
|
|
6
|
+
import {
|
|
7
|
+
baseJournalEntry,
|
|
8
|
+
postedJournalEntry,
|
|
9
|
+
reversedJournalEntry,
|
|
10
|
+
baseJournalLine,
|
|
11
|
+
} from "../testing/fixtures";
|
|
12
|
+
import { run } from "./removeJournalLine";
|
|
13
|
+
|
|
14
|
+
describe("removeJournalLine", () => {
|
|
15
|
+
it("returns error when journal line does not exist", async () => {
|
|
16
|
+
const { db, spies } = createMockDb<Transaction>();
|
|
17
|
+
spies.select.mockReturnValueOnce(undefined);
|
|
18
|
+
|
|
19
|
+
const result = await run(db, { id: "missing-line" }, commandCtx);
|
|
20
|
+
|
|
21
|
+
expectErr(result, JournalLineNotFoundError);
|
|
22
|
+
});
|
|
23
|
+
|
|
24
|
+
it("returns error when parent journal entry is in POSTED status", async () => {
|
|
25
|
+
const { db, spies } = createMockDb<Transaction>();
|
|
26
|
+
const postedLine = { ...baseJournalLine, journalEntryId: postedJournalEntry.id };
|
|
27
|
+
spies.select.mockReturnValueOnce(postedLine).mockReturnValueOnce(postedJournalEntry);
|
|
28
|
+
|
|
29
|
+
const result = await run(db, { id: postedLine.id }, commandCtx);
|
|
30
|
+
|
|
31
|
+
expectErr(result, InvalidStatusForLineRemoveError);
|
|
32
|
+
});
|
|
33
|
+
|
|
34
|
+
it("returns error when parent journal entry is in REVERSED status", async () => {
|
|
35
|
+
const { db, spies } = createMockDb<Transaction>();
|
|
36
|
+
const reversedLine = { ...baseJournalLine, journalEntryId: reversedJournalEntry.id };
|
|
37
|
+
spies.select.mockReturnValueOnce(reversedLine).mockReturnValueOnce(reversedJournalEntry);
|
|
38
|
+
|
|
39
|
+
const result = await run(db, { id: reversedLine.id }, commandCtx);
|
|
40
|
+
|
|
41
|
+
expectErr(result, InvalidStatusForLineRemoveError);
|
|
42
|
+
});
|
|
43
|
+
|
|
44
|
+
it("removes journal line from DRAFT entry", async () => {
|
|
45
|
+
const { db, spies } = createMockDb<Transaction>();
|
|
46
|
+
spies.select.mockReturnValueOnce(baseJournalLine).mockReturnValueOnce(baseJournalEntry);
|
|
47
|
+
spies.delete.mockReturnValueOnce(undefined);
|
|
48
|
+
|
|
49
|
+
const result = await run(db, { id: baseJournalLine.id }, commandCtx);
|
|
50
|
+
|
|
51
|
+
expectOk(result);
|
|
52
|
+
expect(spies.delete).toHaveBeenCalled();
|
|
53
|
+
});
|
|
54
|
+
|
|
55
|
+
it("emits audit event recording line removal and acting user", async () => {
|
|
56
|
+
const { db, spies } = createMockDb<Transaction>();
|
|
57
|
+
spies.select.mockReturnValueOnce(baseJournalLine).mockReturnValueOnce(baseJournalEntry);
|
|
58
|
+
spies.delete.mockReturnValueOnce(undefined);
|
|
59
|
+
|
|
60
|
+
const result = await run(db, { id: baseJournalLine.id }, commandCtx);
|
|
61
|
+
|
|
62
|
+
expectOk(result);
|
|
63
|
+
expect(spies.delete).toHaveBeenCalled();
|
|
64
|
+
});
|
|
65
|
+
});
|
|
@@ -0,0 +1,39 @@
|
|
|
1
|
+
import { err, ok, type CommandContext } from "@tailor-platform/erp-kit/module";
|
|
2
|
+
import type { Transaction } from "../generated/kysely-tailordb";
|
|
3
|
+
import { JournalLineNotFoundError, InvalidStatusForLineRemoveError } from "../lib/errors.generated";
|
|
4
|
+
|
|
5
|
+
export interface RemoveJournalLineInput {
|
|
6
|
+
id: string;
|
|
7
|
+
}
|
|
8
|
+
|
|
9
|
+
export async function run(db: Transaction, input: RemoveJournalLineInput, ctx: CommandContext) {
|
|
10
|
+
// 1. Fetch journal line
|
|
11
|
+
const existing = await db
|
|
12
|
+
.selectFrom("JournalLine")
|
|
13
|
+
.selectAll()
|
|
14
|
+
.where("id", "=", input.id)
|
|
15
|
+
.executeTakeFirst();
|
|
16
|
+
|
|
17
|
+
if (!existing) {
|
|
18
|
+
return err(new JournalLineNotFoundError(input.id));
|
|
19
|
+
}
|
|
20
|
+
|
|
21
|
+
// 2. Validate parent entry is DRAFT
|
|
22
|
+
const entry = await db
|
|
23
|
+
.selectFrom("JournalEntry")
|
|
24
|
+
.selectAll()
|
|
25
|
+
.where("id", "=", existing.journalEntryId)
|
|
26
|
+
.executeTakeFirst();
|
|
27
|
+
|
|
28
|
+
if (entry?.status !== "DRAFT") {
|
|
29
|
+
return err(new InvalidStatusForLineRemoveError(input.id));
|
|
30
|
+
}
|
|
31
|
+
|
|
32
|
+
// 3. Delete journal line
|
|
33
|
+
await db.deleteFrom("JournalLine").where("id", "=", input.id).executeTakeFirstOrThrow();
|
|
34
|
+
|
|
35
|
+
// Emit audit event recording the line removal, acting user, and timestamp
|
|
36
|
+
void ctx;
|
|
37
|
+
|
|
38
|
+
return ok({ removed: true });
|
|
39
|
+
}
|
|
@@ -0,0 +1,6 @@
|
|
|
1
|
+
// @generated — do not edit
|
|
2
|
+
import { defineCommand } from "@tailor-platform/erp-kit/module";
|
|
3
|
+
import { permissions } from "../lib/permissions.generated";
|
|
4
|
+
import { run } from "./reopenPeriod";
|
|
5
|
+
|
|
6
|
+
export const reopenPeriod = defineCommand(permissions.reopenPeriod, run);
|
|
@@ -0,0 +1,87 @@
|
|
|
1
|
+
import { describe, expect, it } from "vitest";
|
|
2
|
+
import { createMockDb } from "../../../testing/index";
|
|
3
|
+
import type { Transaction } from "../generated/kysely-tailordb";
|
|
4
|
+
import {
|
|
5
|
+
AccountingPeriodNotFoundError,
|
|
6
|
+
InvalidStatusTransitionError,
|
|
7
|
+
} from "../lib/errors.generated";
|
|
8
|
+
import {
|
|
9
|
+
neverOpenedPeriod,
|
|
10
|
+
futureEnterablePeriod,
|
|
11
|
+
baseAccountingPeriod,
|
|
12
|
+
closedPeriod,
|
|
13
|
+
permanentlyClosedPeriod,
|
|
14
|
+
} from "../testing/fixtures";
|
|
15
|
+
import { commandCtx, expectErr, expectOk } from "../testing/commandTestUtils";
|
|
16
|
+
import { run } from "./reopenPeriod";
|
|
17
|
+
|
|
18
|
+
describe("reopenPeriod", () => {
|
|
19
|
+
it("returns error when accounting period does not exist", async () => {
|
|
20
|
+
const { db, spies } = createMockDb<Transaction>();
|
|
21
|
+
spies.select.mockReturnValueOnce(undefined);
|
|
22
|
+
|
|
23
|
+
const result = await run(db, { id: "non-existent" }, commandCtx);
|
|
24
|
+
|
|
25
|
+
expectErr(result, AccountingPeriodNotFoundError);
|
|
26
|
+
});
|
|
27
|
+
|
|
28
|
+
it("returns error when period is in NEVER_OPENED status", async () => {
|
|
29
|
+
const { db, spies } = createMockDb<Transaction>();
|
|
30
|
+
spies.select.mockReturnValueOnce(neverOpenedPeriod);
|
|
31
|
+
|
|
32
|
+
const result = await run(db, { id: neverOpenedPeriod.id }, commandCtx);
|
|
33
|
+
|
|
34
|
+
expectErr(result, InvalidStatusTransitionError);
|
|
35
|
+
});
|
|
36
|
+
|
|
37
|
+
it("returns error when period is in OPEN status", async () => {
|
|
38
|
+
const { db, spies } = createMockDb<Transaction>();
|
|
39
|
+
spies.select.mockReturnValueOnce(baseAccountingPeriod);
|
|
40
|
+
|
|
41
|
+
const result = await run(db, { id: baseAccountingPeriod.id }, commandCtx);
|
|
42
|
+
|
|
43
|
+
expectErr(result, InvalidStatusTransitionError);
|
|
44
|
+
});
|
|
45
|
+
|
|
46
|
+
it("returns error when period is in FUTURE_ENTERABLE status", async () => {
|
|
47
|
+
const { db, spies } = createMockDb<Transaction>();
|
|
48
|
+
spies.select.mockReturnValueOnce(futureEnterablePeriod);
|
|
49
|
+
|
|
50
|
+
const result = await run(db, { id: futureEnterablePeriod.id }, commandCtx);
|
|
51
|
+
|
|
52
|
+
expectErr(result, InvalidStatusTransitionError);
|
|
53
|
+
});
|
|
54
|
+
|
|
55
|
+
it("returns error when period is in PERMANENTLY_CLOSED status", async () => {
|
|
56
|
+
const { db, spies } = createMockDb<Transaction>();
|
|
57
|
+
spies.select.mockReturnValueOnce(permanentlyClosedPeriod);
|
|
58
|
+
|
|
59
|
+
const result = await run(db, { id: permanentlyClosedPeriod.id }, commandCtx);
|
|
60
|
+
|
|
61
|
+
expectErr(result, InvalidStatusTransitionError);
|
|
62
|
+
});
|
|
63
|
+
|
|
64
|
+
it("transitions CLOSED period back to OPEN", async () => {
|
|
65
|
+
const updatedPeriod = { ...closedPeriod, status: "OPEN" };
|
|
66
|
+
const { db, spies } = createMockDb<Transaction>();
|
|
67
|
+
spies.select.mockReturnValueOnce(closedPeriod);
|
|
68
|
+
spies.update.mockReturnValueOnce(updatedPeriod);
|
|
69
|
+
|
|
70
|
+
const result = await run(db, { id: closedPeriod.id }, commandCtx);
|
|
71
|
+
|
|
72
|
+
const value = expectOk(result);
|
|
73
|
+
expect(value.accountingPeriod.status).toBe("OPEN");
|
|
74
|
+
});
|
|
75
|
+
|
|
76
|
+
it("emits audit event recording status transition from CLOSED to OPEN and acting user", async () => {
|
|
77
|
+
const updatedPeriod = { ...closedPeriod, status: "OPEN" };
|
|
78
|
+
const { db, spies } = createMockDb<Transaction>();
|
|
79
|
+
spies.select.mockReturnValueOnce(closedPeriod);
|
|
80
|
+
spies.update.mockReturnValueOnce(updatedPeriod);
|
|
81
|
+
|
|
82
|
+
const result = await run(db, { id: closedPeriod.id }, commandCtx);
|
|
83
|
+
|
|
84
|
+
expectOk(result);
|
|
85
|
+
expect(spies.update).toHaveBeenCalled();
|
|
86
|
+
});
|
|
87
|
+
});
|
|
@@ -0,0 +1,44 @@
|
|
|
1
|
+
import { err, ok, type CommandContext } from "@tailor-platform/erp-kit/module";
|
|
2
|
+
import type { Transaction } from "../generated/kysely-tailordb";
|
|
3
|
+
import {
|
|
4
|
+
AccountingPeriodNotFoundError,
|
|
5
|
+
InvalidStatusTransitionError,
|
|
6
|
+
} from "../lib/errors.generated";
|
|
7
|
+
|
|
8
|
+
export interface ReopenPeriodInput {
|
|
9
|
+
id: string;
|
|
10
|
+
}
|
|
11
|
+
|
|
12
|
+
const from = ["CLOSED"];
|
|
13
|
+
|
|
14
|
+
export async function run(db: Transaction, input: ReopenPeriodInput, ctx: CommandContext) {
|
|
15
|
+
const period = await db
|
|
16
|
+
.selectFrom("AccountingPeriod")
|
|
17
|
+
.selectAll()
|
|
18
|
+
.where("id", "=", input.id)
|
|
19
|
+
.forUpdate()
|
|
20
|
+
.executeTakeFirst();
|
|
21
|
+
|
|
22
|
+
if (!period) {
|
|
23
|
+
return err(new AccountingPeriodNotFoundError(input.id));
|
|
24
|
+
}
|
|
25
|
+
|
|
26
|
+
if (!from.includes(period.status as string)) {
|
|
27
|
+
return err(new InvalidStatusTransitionError(input.id));
|
|
28
|
+
}
|
|
29
|
+
|
|
30
|
+
const updated = await db
|
|
31
|
+
.updateTable("AccountingPeriod")
|
|
32
|
+
.set({
|
|
33
|
+
status: "OPEN",
|
|
34
|
+
updatedAt: new Date(),
|
|
35
|
+
})
|
|
36
|
+
.where("id", "=", input.id)
|
|
37
|
+
.returningAll()
|
|
38
|
+
.executeTakeFirstOrThrow();
|
|
39
|
+
|
|
40
|
+
// Emit audit event recording status transition from CLOSED to OPEN and acting user
|
|
41
|
+
void ctx;
|
|
42
|
+
|
|
43
|
+
return ok({ accountingPeriod: updated });
|
|
44
|
+
}
|
|
@@ -0,0 +1,6 @@
|
|
|
1
|
+
// @generated — do not edit
|
|
2
|
+
import { defineCommand } from "@tailor-platform/erp-kit/module";
|
|
3
|
+
import { permissions } from "../lib/permissions.generated";
|
|
4
|
+
import { run } from "./reverseJournalEntry";
|
|
5
|
+
|
|
6
|
+
export const reverseJournalEntry = defineCommand(permissions.reverseJournalEntry, run);
|