Files
InvoiceShelf/app/Domains/Sales/Application/InvoiceBalanceService.php
T
Darko Gjorgjijoski 5ef7804e60 refactor: adopt modular domain architecture (#747)
* refactor: stabilize model identities for domain migration

* refactor: extract module platform context

* refactor: assign models to domain contexts

* refactor: extract ai platform context

* refactor: extract storage platform context

* refactor: extract mail platform context

* refactor: extract pdf platform context

* refactor: extract operations platform context

* refactor: move installation into operations platform

* refactor: extract money domain context

* refactor: extract taxation domain context

* refactor: extract catalog domain context

* refactor: extract metadata domain context

* refactor: extract reporting domain context

* refactor: extract purchases domain context

* refactor: extract receivables domain context

* refactor: extract accounts domain context

* refactor: complete reporting statement boundary

* refactor: extract contacts domain context

* refactor: extract sales domain context

* refactor: remove legacy application layers

* fix: migrate legacy bouncer role identities
2026-08-05 17:40:03 +02:00

46 lines
1.3 KiB
PHP

<?php
namespace App\Domains\Sales\Application;
use App\Domains\Sales\Models\Invoice;
class InvoiceBalanceService
{
public function allocatedTotal(Invoice $invoice): int
{
return (int) $invoice->allocations()->sum('amount');
}
public function creditedTotal(Invoice $invoice): int
{
return -(int) $invoice->creditNotes()->sum('total');
}
/**
* Recalculate an invoice exclusively from durable credits and payment
* allocations. Callers that change allocations must hold the invoice lock.
*/
public function recalculate(Invoice $invoice): void
{
$allocated = $this->allocatedTotal($invoice);
$credited = $this->creditedTotal($invoice);
$due = max(0, (int) $invoice->total - $allocated - $credited);
$invoice->due_amount = $due;
$invoice->base_due_amount = (int) round($due * $invoice->exchange_rate);
if ($due === 0) {
$invoice->status = Invoice::STATUS_COMPLETED;
$invoice->paid_status = Invoice::STATUS_PAID;
$invoice->overdue = false;
} else {
$invoice->status = $invoice->getPreviousStatus();
$invoice->paid_status = $allocated > 0
? Invoice::STATUS_PARTIALLY_PAID
: Invoice::STATUS_UNPAID;
}
$invoice->save();
}
}