120 lines
4.2 KiB
PHP
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;
|
|
}
|
|
}
|