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(): string { $invoices = $this->relationLoaded('invoices') ? $this->invoices : $this->invoices()->with('payments.items.billingItemType')->get(); $invoices->loadMissing('payments.items.billingItemType'); $adjustments = $this->relationLoaded('invoiceAdjustments') ? $this->invoiceAdjustments : $this->invoiceAdjustments()->get(['client_id', 'entry_type', 'amount']); $invoiceItems = $invoices->flatMap(fn (ClientInvoice $invoice) => $invoice->payments ->flatMap(fn ($payment) => $payment->items ->map(fn (ClientInvoicePaymentItem $item) => [ 'invoice' => $invoice, 'item' => $item, ]))); $nettAmount = $invoiceItems ->filter(fn (array $row) => ! $row['item']->is_creditcard && ($row['item']->billingItemType?->nett_contribution ?? false)) ->sum(fn (array $row) => (float) ($row['item']->final_net_amount ?? $row['item']->net_amount ?? 0)); $billableSpending = $invoiceItems ->reject(fn (array $row) => $this->isCreditCardSpend($row['invoice'], $row['item'])) ->sum(fn (array $row) => (float) ($row['item']->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); } private function isCreditCardSpend(ClientInvoice $invoice, ClientInvoicePaymentItem $item): bool { if ($item->is_creditcard) { return true; } return $invoice->is_credit_card && $item->billingItemType?->name === ClientInvoicePaymentSyncService::MANAGEMENT_SEARCH_NAME && (float) ($item->spending ?? 0) > 0; } public function customers() { return $this->hasMany(ClientCustomer::class); } }