Files
alrahma_sunday_school_api/app/Services/Finance/FinancialPaymentService.php
T
2026-03-09 02:52:13 -04:00

120 lines
4.2 KiB
PHP

<?php
namespace App\Services\Finance;
use Illuminate\Database\Query\Builder;
use Illuminate\Support\Facades\DB;
use Illuminate\Support\Facades\Schema;
class FinancialPaymentService
{
public function paymentsByInvoice(?string $schoolYear, ?string $dateFrom, ?string $dateTo): array
{
$query = $this->applyPaymentFilters($this->buildPaymentQuery($schoolYear, $dateFrom, $dateTo));
return $query
->selectRaw('invoice_id, SUM(paid_amount) AS paid_amount')
->whereNotNull('invoice_id')
->groupBy('invoice_id')
->get()
->map(fn ($row) => (array) $row)
->all();
}
public function paymentBreakdown(?string $schoolYear, ?string $dateFrom, ?string $dateTo): array
{
$query = $this->applyPaymentFilters($this->buildPaymentQuery($schoolYear, $dateFrom, $dateTo));
$rows = $query
->selectRaw("
invoice_id,
CASE
WHEN LOWER(TRIM(payment_method)) = 'cash' THEN 'cash'
WHEN LOWER(TRIM(payment_method)) IN ('check','cheque') THEN 'check'
WHEN LOWER(TRIM(payment_method)) IN ('credit','card','credit card','debit','debit card','visa','mastercard') THEN 'credit'
ELSE 'other'
END AS method,
SUM(paid_amount) AS amount
")
->whereNotNull('invoice_id')
->groupBy('invoice_id', 'method')
->get()
->map(fn ($row) => (array) $row)
->all();
$breakdown = [];
foreach ($rows as $row) {
$invoiceId = (int) ($row['invoice_id'] ?? 0);
if ($invoiceId <= 0) {
continue;
}
$method = (string) ($row['method'] ?? '');
$amount = (float) ($row['amount'] ?? 0);
if (!isset($breakdown[$invoiceId])) {
$breakdown[$invoiceId] = [];
}
$breakdown[$invoiceId][$method] = $amount;
}
return $breakdown;
}
public function paymentTotals(?string $schoolYear, ?string $dateFrom, ?string $dateTo): array
{
$query = $this->applyPaymentFilters($this->buildPaymentQuery($schoolYear, $dateFrom, $dateTo));
$row = (array) $query
->selectRaw("
SUM(paid_amount) AS total_all,
SUM(CASE WHEN LOWER(TRIM(payment_method)) = 'cash' THEN paid_amount ELSE 0 END) AS total_cash,
SUM(CASE WHEN LOWER(TRIM(payment_method)) IN ('check','cheque') THEN paid_amount ELSE 0 END) AS total_check,
SUM(CASE WHEN LOWER(TRIM(payment_method)) IN ('credit','card','credit card','debit','debit card','visa','mastercard') THEN paid_amount ELSE 0 END) AS total_credit
")
->whereNotNull('invoice_id')
->first();
return [
'total_all' => (float) ($row['total_all'] ?? 0),
'total_cash' => (float) ($row['total_cash'] ?? 0),
'total_check' => (float) ($row['total_check'] ?? 0),
'total_credit' => (float) ($row['total_credit'] ?? 0),
];
}
private function buildPaymentQuery(?string $schoolYear, ?string $dateFrom, ?string $dateTo): Builder
{
$query = DB::table('payments');
if (!empty($schoolYear)) {
$query->where('school_year', $schoolYear);
}
if (!empty($dateFrom)) {
$query->whereRaw('DATE(payment_date) >= ?', [$dateFrom]);
}
if (!empty($dateTo)) {
$query->whereRaw('DATE(payment_date) <= ?', [$dateTo]);
}
return $query;
}
private function applyPaymentFilters(Builder $query): Builder
{
$exclude = ['void', 'voided', 'refunded', 'failed', 'chargeback', 'declined', 'reversed', 'canceled', 'cancelled'];
if (Schema::hasColumn('payments', 'status')) {
$query->where(function ($q) use ($exclude) {
$q->whereNotIn('status', $exclude)->orWhereNull('status');
});
}
if (Schema::hasColumn('payments', 'is_void')) {
$query->where(function ($q) {
$q->where('is_void', 0)->orWhereNull('is_void');
});
}
return $query;
}
}