91 lines
3.4 KiB
PHP
91 lines
3.4 KiB
PHP
<?php
|
|
|
|
namespace App\Services\Refunds;
|
|
|
|
use App\Models\AdditionalCharge;
|
|
use App\Models\Invoice;
|
|
use App\Services\Discounts\DiscountInvoiceService;
|
|
|
|
class RefundInvoiceAdjustmentService
|
|
{
|
|
public function __construct(private DiscountInvoiceService $invoiceService) {}
|
|
|
|
public function applyBookChargeAndUpdateInvoice(
|
|
Invoice $invoice,
|
|
int $parentId,
|
|
array $refundDetails,
|
|
string $semester,
|
|
?int $actorId
|
|
): array {
|
|
$bookChargeTitle = 'Book Fee (Non-Refundable)';
|
|
$bookChargeDesc = 'Book fee retained for withdrawals before the refund deadline.';
|
|
|
|
$bookPrice = (float) ($refundDetails['book_price'] ?? 0.0);
|
|
$eligible = ! empty($refundDetails['eligible']);
|
|
|
|
$bookChargeDelta = 0.0;
|
|
$bookChargeAction = 'none';
|
|
$bookChargeId = null;
|
|
|
|
$existingCharge = AdditionalCharge::query()
|
|
->where('invoice_id', (int) $invoice->id)
|
|
->where('parent_id', (int) $parentId)
|
|
->where('school_year', (string) $invoice->school_year)
|
|
->where('title', $bookChargeTitle)
|
|
->orderByDesc('id')
|
|
->first();
|
|
|
|
if ($eligible && $bookPrice > 0) {
|
|
if ($existingCharge) {
|
|
$oldAmount = (float) ($existingCharge->amount ?? 0.0);
|
|
$bookChargeId = (int) $existingCharge->id;
|
|
if (abs($oldAmount - $bookPrice) > 0.00001 || ($existingCharge->status ?? '') !== 'applied') {
|
|
$existingCharge->update([
|
|
'charge_type' => 'add',
|
|
'title' => $bookChargeTitle,
|
|
'description' => $bookChargeDesc,
|
|
'amount' => $bookPrice,
|
|
'status' => 'applied',
|
|
]);
|
|
$bookChargeDelta = round($bookPrice - $oldAmount, 2);
|
|
$bookChargeAction = 'updated';
|
|
}
|
|
} else {
|
|
$bookChargeId = AdditionalCharge::query()->insertGetId([
|
|
'parent_id' => (int) $parentId,
|
|
'invoice_id' => (int) $invoice->id,
|
|
'school_year' => (string) $invoice->school_year,
|
|
'semester' => $semester,
|
|
'charge_type' => 'add',
|
|
'title' => $bookChargeTitle,
|
|
'description' => $bookChargeDesc,
|
|
'amount' => $bookPrice,
|
|
'status' => 'applied',
|
|
'created_by' => $actorId,
|
|
'created_at' => utc_now(),
|
|
'updated_at' => utc_now(),
|
|
]);
|
|
|
|
if ($bookChargeId) {
|
|
$bookChargeDelta = round($bookPrice, 2);
|
|
$bookChargeAction = 'inserted';
|
|
}
|
|
}
|
|
} elseif ($existingCharge) {
|
|
$oldAmount = (float) ($existingCharge->amount ?? 0.0);
|
|
$bookChargeId = (int) $existingCharge->id;
|
|
$existingCharge->delete();
|
|
$bookChargeDelta = round(-$oldAmount, 2);
|
|
$bookChargeAction = 'deleted';
|
|
}
|
|
|
|
$this->invoiceService->recalculateInvoice((int) $invoice->id, (string) $invoice->school_year);
|
|
|
|
return [
|
|
'book_charge_action' => $bookChargeAction,
|
|
'book_charge_delta' => $bookChargeDelta,
|
|
'book_charge_id' => $bookChargeId,
|
|
];
|
|
}
|
|
}
|