diff --git a/app/Providers/BalanceServiceProvider.php b/app/Providers/BalanceServiceProvider.php new file mode 100644 index 0000000..cadbde5 --- /dev/null +++ b/app/Providers/BalanceServiceProvider.php @@ -0,0 +1,31 @@ +app->singleton(AccountBalanceService::class, function ($app) { + return new AccountBalanceService(); + }); + } + + /** + * Get the services provided by the provider. + * + * @return array + */ + public function provides(): array + { + return [AccountBalanceService::class]; + } +} diff --git a/app/Providers/WebstatementServiceProvider.php b/app/Providers/WebstatementServiceProvider.php index 83b0bf1..55a7579 100644 --- a/app/Providers/WebstatementServiceProvider.php +++ b/app/Providers/WebstatementServiceProvider.php @@ -57,6 +57,7 @@ class WebstatementServiceProvider extends ServiceProvider { $this->app->register(EventServiceProvider::class); $this->app->register(RouteServiceProvider::class); + $this->app->register(BalanceServiceProvider::class); $this->app->bind(UpdateAtmCardBranchCurrencyJob::class); } diff --git a/app/Services/AccountBalanceService.php b/app/Services/AccountBalanceService.php new file mode 100644 index 0000000..fef6deb --- /dev/null +++ b/app/Services/AccountBalanceService.php @@ -0,0 +1,130 @@ + $accountNumber, + 'start_date' => $startDate, + 'end_date' => $endDate + ]); + + // Convert dates to Carbon instances + $startDateCarbon = Carbon::parse($startDate); + $endDateCarbon = Carbon::parse($endDate); + + // Get opening balance (balance from previous day) + $openingBalanceDate = $startDateCarbon->copy()->subDay(); + $openingBalance = $this->getAccountBalance($accountNumber, $openingBalanceDate); + + // Get closing balance date (previous day from end date) + $closingBalanceDate = $endDateCarbon->copy()->subDay(); + $closingBalanceBase = $this->getAccountBalance($accountNumber, $closingBalanceDate); + + // Get transactions on end date + $transactionsOnEndDate = $this->getTransactionsOnDate($accountNumber, $endDate); + + // Calculate closing balance + $closingBalance = $closingBalanceBase + $transactionsOnEndDate; + + $result = [ + 'account_number' => $accountNumber, + 'period' => [ + 'start_date' => $startDate, + 'end_date' => $endDate + ], + 'opening_balance' => [ + 'date' => $openingBalanceDate->format('Y-m-d'), + 'balance' => $openingBalance, + 'formatted_balance' => number_format($openingBalance, 2) + ], + 'closing_balance' => [ + 'date' => $endDate, + 'balance' => $closingBalance, + 'formatted_balance' => number_format($closingBalance, 2), + 'base_balance' => [ + 'date' => $closingBalanceDate->format('Y-m-d'), + 'balance' => $closingBalanceBase, + 'formatted_balance' => number_format($closingBalanceBase, 2) + ], + 'transactions_on_end_date' => $transactionsOnEndDate, + 'formatted_transactions_on_end_date' => number_format($transactionsOnEndDate, 2) + ] + ]; + + Log::info('Balance summary calculated successfully', $result); + + return $result; + }); + } + + /** + * Get account balance for specific date + * + * @param string $accountNumber + * @param Carbon $date + * @return float + */ + private function getAccountBalance(string $accountNumber, Carbon $date): float + { + $balance = AccountBalance::where('account_number', $accountNumber) + ->where('period', $date->format('Ymd')) + ->value('actual_balance'); + + if ($balance === null) { + Log::warning('Account balance not found', [ + 'account_number' => $accountNumber, + 'date' => $date->format('Y-m-d'), + 'period' => $date->format('Ymd') + ]); + return 0.00; + } + + return (float) $balance; + } + + /** + * Get transactions on specific date + * + * @param string $accountNumber + * @param string $date + * @return float + */ + private function getTransactionsOnDate(string $accountNumber, string $date): float + { + $total = StmtEntry::where('account_number', $accountNumber) + ->whereDate('value_date', $date) + ->sum(DB::raw('CAST(amount_lcy AS DECIMAL(15,2))')); + + return (float) $total; + } + + /** + * Validate if account exists + * + * @param string $accountNumber + * @return bool + */ + public function validateAccount(string $accountNumber): bool + { + return AccountBalance::where('account_number', $accountNumber)->exists(); + } +}