feat(client): add financial reports and ledger management

- Add trial balance and general ledger pages to client resource with interactive tables
- Implement sales and expenses relation managers for client-specific transactions
- Enhance transaction handling with proper tax and withholding calculations
- Add date casting to Transaction model and define client relationships
- Configure super admin role bypass in AppServiceProvider
- Update Filament components and fix JavaScript formatting issues
This commit is contained in:
Jp
2026-02-09 16:20:55 +08:00
parent 91eb1fbe63
commit 207f4c1609
43 changed files with 3412 additions and 2967 deletions

View File

@@ -25,6 +25,7 @@ class CreateLedgerAction extends BaseAction
ledger_id: $ledger->id,
account_id: $ledger->account_id,
branch_id: $ledger->branch_id,
type: $payload->type ?? 'debit',
);
return $next($payload);

View File

@@ -30,6 +30,8 @@ class CreateTransactionAction extends BaseAction
public function transactionAccountLedger($payload): void
{
$branch = $payload->transaction->branch;
$isExpense = $payload->transactionable instanceof \App\Models\Expense;
$type = $isExpense ? 'debit' : 'credit';
if ($branch->isClientVatable) {
//create transaction account ledger
@@ -38,10 +40,11 @@ class CreateTransactionAction extends BaseAction
amount: $payload->transaction->net_amount ?? 0.00,
transaction: $payload->transaction,
account: $payload->transaction->account,
type: $type,
);
$this->ledgerPipe($ledgerPayload);
$this->inputTaxAccountLedger($payload);
$this->taxAccountLedger($payload, $isExpense);
} else {
//create transaction account ledger
$ledgerPayload = new CreateLedgerDTO(
@@ -49,6 +52,7 @@ class CreateTransactionAction extends BaseAction
amount: $payload->transaction->gross_amount ?? 0.00,
transaction: $payload->transaction,
account: $payload->transaction->account,
type: $type,
);
$this->ledgerPipe($ledgerPayload);
}
@@ -63,50 +67,69 @@ class CreateTransactionAction extends BaseAction
])->thenReturn();
}
public function inputTaxAccountLedger($payload): void
public function taxAccountLedger($payload, bool $isExpense): void
{
$inputTax = Account::query()->where('account', 'Input Tax')->whereHas('balances', function ($balance) use ($payload) {
$accountName = $isExpense ? 'Input Tax' : 'Output Tax';
$type = $isExpense ? 'debit' : 'credit';
$taxAccount = Account::query()->where('account', $accountName)->whereHas('balances', function ($balance) use ($payload) {
return $balance->where('branch_id', $payload->transactionable->branch_id);
})->first();
$ledgerPayload = new CreateLedgerDTO(
branch_id: $payload->transactionable->branch_id,
amount: $payload->transactionable->input_tax ?? 0.00,
transaction: $payload->transaction,
account: $inputTax,
);
$this->ledgerPipe($ledgerPayload);
if ($taxAccount) {
$ledgerPayload = new CreateLedgerDTO(
branch_id: $payload->transactionable->branch_id,
amount: $payload->transactionable->input_tax ?? 0.00, // Assuming input_tax holds the tax amount for both? Or output_tax?
transaction: $payload->transaction,
account: $taxAccount,
type: $type,
);
$this->ledgerPipe($ledgerPayload);
}
}
public function withHoldingAccountLedger($payload): void
{
$withholdingAccount = Account::query()->where('account', 'Payable Withholding Tax')->whereHas('balances', function ($balance) use ($payload) {
$isExpense = $payload->transactionable instanceof \App\Models\Expense;
$accountName = $isExpense ? 'Payable Withholding Tax' : 'Creditable Withholding Tax';
$type = $isExpense ? 'credit' : 'debit';
$withholdingAccount = Account::query()->where('account', $accountName)->whereHas('balances', function ($balance) use ($payload) {
return $balance->where('branch_id', $payload->transactionable->branch_id);
})->first();
$ledgerPayload = new CreateLedgerDTO(
branch_id: $payload->transactionable->branch_id,
amount: $payload->transaction->payable_withholding_tax ?? 0.00,
transaction: $payload->transaction,
account: $withholdingAccount,
);
$this->ledgerPipe($ledgerPayload);
if ($withholdingAccount) {
$ledgerPayload = new CreateLedgerDTO(
branch_id: $payload->transactionable->branch_id,
amount: $payload->transaction->payable_withholding_tax ?? 0.00,
transaction: $payload->transaction,
account: $withholdingAccount,
type: $type,
);
$this->ledgerPipe($ledgerPayload);
}
}
public function cashAccountLedger($payload): void
{
$isExpense = $payload->transactionable instanceof \App\Models\Expense;
$type = $isExpense ? 'credit' : 'debit';
$wht = $isExpense ? ($payload->transaction->payable_withholding_tax ?? 0) : ($payload->transaction->creditable_withholding_tax ?? 0);
$amount = ($payload->transaction->gross_amount ?? 0) - $wht;
$cashAccount = Account::query()->where('account', 'Cash')->whereHas('balances', function ($balance) use ($payload) {
return $balance->where('branch_id', $payload->transactionable->branch_id);
})->first();
$amount = $payload->transaction->gross_amount - $payload->transaction->creditable_withholding_tax;
$ledgerPayload = new CreateLedgerDTO(
branch_id: $payload->transactionable->branch_id,
amount: $amount ?? 0.00,
transaction: $payload->transaction,
account: $cashAccount,
);
$this->ledgerPipe($ledgerPayload);
if ($cashAccount) {
$ledgerPayload = new CreateLedgerDTO(
branch_id: $payload->transactionable->branch_id,
amount: $amount,
transaction: $payload->transaction,
account: $cashAccount,
type: $type,
);
$this->ledgerPipe($ledgerPayload);
}
}
}