hasMany(GoogleCampaign::class); } public function assignations() { return $this->hasMany(ClientUserAssignation::class); } public function invoices(): HasMany { return $this->hasMany(ClientInvoice::class); } public function invoiceAdjustments(): HasMany { return $this->hasMany(ClientInvoiceAdjustment::class); } public function getLatestRemainingAmountAttribute(): string { return $this->latestRemainingAmount(); } public function latestRemainingAmount(?callable $invoiceSpendingResolver = null): string { $invoices = $this->relationLoaded('invoices') ? $this->invoices : $this->invoices()->get(['client_id', 'is_credit_card', 'nett_amount', 'total_spending']); $adjustments = $this->relationLoaded('invoiceAdjustments') ? $this->invoiceAdjustments : $this->invoiceAdjustments()->get(['client_id', 'entry_type', 'amount']); $nettAmount = $invoices ->sum(fn (ClientInvoice $invoice) => (float) ($invoice->nett_amount ?? 0)); $billableSpending = $invoices ->reject(fn (ClientInvoice $invoice) => $invoice->is_credit_card) ->sum(function (ClientInvoice $invoice) use ($invoiceSpendingResolver) { if ($invoiceSpendingResolver !== null) { return (float) $invoiceSpendingResolver($invoice); } return (float) ($invoice->total_spending ?? 0); }); $adjustmentNet = $adjustments->sum(function (ClientInvoiceAdjustment $adjustment) { $amount = (float) ($adjustment->amount ?? 0); return $adjustment->entry_type === ClientInvoiceAdjustment::TYPE_CREDIT ? $amount : -$amount; }); return number_format(max(0, $nettAmount + $adjustmentNet - $billableSpending), 2, '.', ''); } public function activitiesList(): HasMany { return $this->hasMany(ClientProjectActivities::class); } public function customers() { return $this->hasMany(ClientCustomer::class); } }