Files
nnterp-react-admin/docs/PLAN-doubleentry-compat.md
admin 015ddea46c feat(asset-management): complete module with standardized UI + demo data seeder
- Fix Vendor column bug (name → company_name) across all controllers
- Create 6 missing pages (Assets/Edit, Categories/Create+Edit, Maintenance/Show+Edit, Disposal/Show)
- Standardize all 7 Index pages with DataTable, SearchInput, PerPageSelector, Pagination
- Add AssetManagementDemoSeeder with 5 categories, 22 assets, 8 maintenance, 4 assignments, 3 transfers, 2 disposals
- All 19 controller-referenced pages now have matching .tsx files
2026-05-02 10:49:55 +08:00

12 KiB
Raw Permalink Blame History

Merge DoubleEntry into Account Package

Background

The DoubleEntry module is a child module of Account (parent_module: ["Account"]). It provides:

  1. Journal Entries — CRUD (but Account already has JournalEntry + JournalEntryItem models)
  2. Financial Reports — Ledger, Balance Sheet, Profit & Loss, Trial Balance (Account does NOT have these)
  3. Sidebar menu — "Double Entry" with 5 items

Since DoubleEntry IS accounting, we'll absorb its unique functionality into Account and retire the DoubleEntry package.


What Each Package Already Has

Account Package (keep)

Feature Controller React Pages Models
Dashboard DashboardController 4 dashboards
Chart of Accounts ChartOfAccountController CRUD (4 pages) ChartOfAccount
Bank Accounts BankAccountController CRUD (4 pages) BankAccount
Bank Transactions BankTransactionController Index BankTransaction
Bank Transfers BankTransferController CRUD (4 pages) BankTransfer
Customers CustomerController CRUD (4 pages) Customer
Vendors VendorController CRUD (4 pages) Vendor
Customer Payments CustomerPaymentController Create/Index/View CustomerPayment
Vendor Payments VendorPaymentController Create/Index/View VendorPayment
Revenue RevenueController CRUD Revenue
Expense ExpenseController CRUD Expense
Debit Notes DebitNoteController Create/Index/View DebitNote
Credit Notes CreditNoteController Create/Index/View CreditNote
Reports ReportsController Invoice/Bill Aging, Tax, Customer/Vendor Balance via ReportService
System Setup AccountTypeController Account Types, Expense/Revenue Categories AccountType, AccountCategory
Journal Entries — (model only) — (no pages) JournalEntry, JournalEntryItem

DoubleEntry Package 🔴 (retire)

Feature Controller React Pages Status
Journal Entries JournalEntryController Index, Create, Edit, View ⚠️ Uses old schema
Ledger Report ReportController::ledgerReport Ledger.tsx 🆕 Account doesn't have
Balance Sheet ReportController::balanceSheet BalanceSheet.tsx 🆕 Account doesn't have
Profit & Loss ReportController::profitLoss ProfitLoss.tsx 🆕 Account doesn't have
Trial Balance ReportController::trialBalance TrialBalance.tsx 🆕 Account doesn't have

What Needs to Move

Already duplicated (skip)

  • JournalEntry model → Account already has Workdo\Account\Models\JournalEntry
  • JournalItem model → Account already has Workdo\Account\Models\JournalEntryItem

🆕 Unique to DoubleEntry (must migrate)

Asset Source Location Target Location
Journal CRUD Controller DoubleEntry/JournalEntryController.php Rewrite in Account package using Account models
Journal CRUD Pages (4) DoubleEntry/Pages/JournalEntries/*.tsx Move to Account/Pages/JournalEntries/*.tsx
Financial Reports Controller DoubleEntry/ReportController.php Rewrite as Account/FinancialReportController.php using Account models
Financial Reports Pages (4) DoubleEntry/Pages/Reports/*.tsx Move to Account/Pages/Reports/*.tsx
Sidebar Menu Items DoubleEntry/menus/company-menu.ts Merge into Account/menus/company-menu.ts
Permissions journalentry manage/create/edit/delete/show, report ledger/balance sheet/profit loss/trial balance Add to Account permission seeder

Proposed Changes

Phase 1 — New JournalEntry Controller in Account

[NEW] Account/src/Http/Controllers/JournalEntryController.php

Rewrite DoubleEntry's JournalEntryController to use Account's own models:

  • Replace Workdo\DoubleEntry\Entities\JournalEntryWorkdo\Account\Models\JournalEntry
  • Replace Workdo\DoubleEntry\Entities\JournalItemWorkdo\Account\Models\JournalEntryItem
  • Replace Workdo\Account\Entities\ChartOfAccountWorkdo\Account\Models\ChartOfAccount
  • Remove AccountUtility::addTransactionLines() (deprecated flow)
  • Remove BankAccount::where('chart_account_id', ...) → use gl_account_id
  • Remove chart_of_account_parents join → use parent_account_id self-join
  • Map column names: codeaccount_code, nameaccount_name, parentparent_account_id
  • Render to Account/JournalEntries/* instead of DoubleEntry/JournalEntries/*

Methods: index, create, store, show, edit, update, destroy, journalDestroy, accountDestroy, setting


Phase 2 — New Financial Reports Controller in Account

[NEW] Account/src/Http/Controllers/FinancialReportController.php

Completely rewrite the 4 report methods against the modern schema:

Method Query Pattern (new schema)
ledgerReport() JournalEntryItem joined with ChartOfAccount, grouped by account, filtered by date
balanceSheet() JournalEntryItem aggregated by AccountCategory (Assets, Liabilities, Equity) via AccountType
profitLoss() JournalEntryItem aggregated by AccountCategory (Revenue, Expenses) via AccountType
trialBalance() JournalEntryItem totals per ChartOfAccount, all categories

Key simplification: The old ReportController was 2183 lines because it navigated a 4-layer hierarchy (Type → SubType → Parent → Account). The new schema is cleaner: AccountCategory → AccountType → ChartOfAccount, so reports become ~300-400 lines.

Renders to Account/Reports/Ledger, Account/Reports/BalanceSheet, Account/Reports/ProfitLoss, Account/Reports/TrialBalance.


Phase 3 — Move & Adapt React Pages

[MOVE] Journal Entry Pages (4 files)

DoubleEntry/Pages/JournalEntries/Index.tsx   → Account/Pages/JournalEntries/Index.tsx
DoubleEntry/Pages/JournalEntries/Create.tsx  → Account/Pages/JournalEntries/Create.tsx
DoubleEntry/Pages/JournalEntries/Edit.tsx    → Account/Pages/JournalEntries/Edit.tsx
DoubleEntry/Pages/JournalEntries/View.tsx    → Account/Pages/JournalEntries/View.tsx

Update Inertia page references from DoubleEntry/JournalEntries/*Account/JournalEntries/*

[MOVE] Financial Report Pages (4 files)

DoubleEntry/Pages/Reports/Ledger.tsx         → Account/Pages/Reports/Ledger.tsx
DoubleEntry/Pages/Reports/BalanceSheet.tsx   → Account/Pages/Reports/BalanceSheet.tsx
DoubleEntry/Pages/Reports/ProfitLoss.tsx     → Account/Pages/Reports/ProfitLoss.tsx
DoubleEntry/Pages/Reports/TrialBalance.tsx   → Account/Pages/Reports/TrialBalance.tsx

Important

These React pages may need prop adjustments since the new controller will pass data in a different structure than the old one. Review each page's expected props.


Phase 4 — Update Account Routes

[MODIFY] Account/src/Routes/web.php

Add journal entry and financial report routes:

// Journal Entries
Route::prefix('account/journal-entries')->name('account.journal-entries.')->group(function () {
    Route::resource('/', JournalEntryController::class);
    Route::post('/account/destroy', [JournalEntryController::class, 'accountDestroy'])->name('account.destroy');
    Route::delete('/journal/destroy/{item_id}', [JournalEntryController::class, 'journalDestroy'])->name('journal.destroy');
    Route::post('/setting/store', [JournalEntryController::class, 'setting'])->name('setting.store');
});

// Financial Reports
Route::prefix('account/financial-reports')->name('account.financial-reports.')->group(function () {
    Route::get('/ledger/{account?}', [FinancialReportController::class, 'ledgerReport'])->name('ledger');
    Route::get('/balance-sheet', [FinancialReportController::class, 'balanceSheet'])->name('balance-sheet');
    Route::get('/profit-loss', [FinancialReportController::class, 'profitLoss'])->name('profit-loss');
    Route::get('/trial-balance', [FinancialReportController::class, 'trialBalance'])->name('trial-balance');
});

Phase 5 — Update Account Sidebar Menu

[MODIFY] Account/src/Resources/js/menus/company-menu.ts

Add to the existing Accounting menu children:

{
    title: t('Journal Entries'),
    href: route('account.journal-entries.index'),
    permission: 'journalentry manage',
},
{
    title: t('Financial Reports'),
    permission: 'report ledger',
    children: [
        { title: t('Ledger'), href: route('account.financial-reports.ledger'), permission: 'report ledger' },
        { title: t('Balance Sheet'), href: route('account.financial-reports.balance-sheet'), permission: 'report balance sheet' },
        { title: t('Profit & Loss'), href: route('account.financial-reports.profit-loss'), permission: 'report profit loss' },
        { title: t('Trial Balance'), href: route('account.financial-reports.trial-balance'), permission: 'report trial balance' },
    ],
},

Phase 6 — Seed Permissions

[MODIFY] Account permission seeder

Add the DoubleEntry permissions to Account's seeder:

  • journalentry manage, journalentry create, journalentry edit, journalentry delete, journalentry show
  • report ledger, report balance sheet, report profit loss, report trial balance
  • doubleentry manage

Phase 7 — Disable DoubleEntry Module

[MODIFY] packages/workdo/DoubleEntry/module.json

Set "is_enable": 0 or remove the module from modules_statuses.json to prevent it loading. We keep the package directory intact as a backup but stop it from registering routes/menus.

Warning

Do NOT delete the DoubleEntry package yet. Disable it first, verify everything works, then delete in a future cleanup pass.


File Summary

Action File Phase
🆕 NEW Account/Http/Controllers/JournalEntryController.php 1
🆕 NEW Account/Http/Controllers/FinancialReportController.php 2
📋 MOVE 4 JournalEntry React pages → Account 3
📋 MOVE 4 Financial Report React pages → Account 3
✏️ MODIFY Account/Routes/web.php 4
✏️ MODIFY Account/menus/company-menu.ts 5
✏️ MODIFY Account permission seeder 6
✏️ MODIFY DoubleEntry/module.json (disable) 7
Total ~12 files

Verification Plan

Phase-by-Phase Testing

  1. After Phase 14: Navigate to /account/journal-entries → Index page loads
  2. After Phase 14: Create a journal entry → saves to journal_entries + journal_entry_items
  3. After Phase 24: Navigate to /account/financial-reports/trial-balance → report loads
  4. After Phase 24: Navigate to Balance Sheet, P&L, Ledger → all render
  5. After Phase 5: Sidebar shows Journal Entries + Financial Reports under "Accounting"
  6. After Phase 7: Disable DoubleEntry → /doubleentry/* routes return 404
  7. Build test: npm run build → no TS errors

Data Integrity

  • Existing journal_entries and journal_entry_items data is preserved (same tables)
  • No migration needed (using existing Account tables)

Estimated Complexity

Phase Effort Notes
Phase 1 Medium Rewrite JournalEntryController (~300 lines)
Phase 2 High Rewrite FinancialReportController from scratch (~400 lines)
Phase 3 Low Copy + adjust Inertia page references
Phase 4 Low Add routes
Phase 5 Low Add menu items
Phase 6 Low Seed permissions
Phase 7 Low Flip module off