resource; $allocations = $payment->relationLoaded('allocations') ? $payment->allocations : $payment->allocations()->with('invoice')->get(); $allocated = (int) $allocations->sum('amount'); $baseAllocated = (int) $allocations->sum('base_amount'); $baseAmount = $this->baseAmount(); return [ 'id' => $payment->id, 'payment_number' => $payment->payment_number, 'payment_date' => $payment->payment_date, 'notes' => $payment->getNotes(), 'amount' => $payment->amount, 'unique_hash' => $payment->unique_hash, 'company_id' => $payment->company_id, 'payment_method_id' => $payment->payment_method_id, 'creator_id' => $payment->creator_id, 'customer_id' => $payment->customer_id, 'exchange_rate' => $payment->exchange_rate, 'base_amount' => $baseAmount, 'allocations' => $this->allocationRows($allocations), 'allocated_amount' => $allocated, 'unallocated_amount' => (int) $payment->amount - $allocated, 'base_allocated_amount' => $baseAllocated, 'base_unallocated_amount' => $baseAmount - $baseAllocated, 'currency_id' => $payment->currency_id, 'transaction_id' => $payment->transaction_id, 'sequence_number' => $payment->sequence_number, 'formatted_created_at' => $payment->formattedCreatedAt, 'formatted_payment_date' => $payment->formattedPaymentDate, 'payment_pdf_url' => $payment->paymentPdfUrl, 'customer' => $this->when( $payment->customer()->exists(), fn () => new CustomerResource($payment->customer) ), 'payment_method' => $this->when( $payment->paymentMethod()->exists(), fn () => new PaymentMethodResource($payment->paymentMethod) ), 'fields' => $this->when( $payment->fields()->exists(), fn () => CustomFieldValueResource::collection($payment->fields) ), 'company' => $this->when( $payment->company()->exists(), fn () => new CompanyResource($payment->company) ), 'currency' => $this->when( $payment->currency()->exists(), fn () => new CurrencyResource($payment->currency) ), 'transaction' => $this->when( $payment->transaction()->exists(), fn () => new TransactionResource($payment->transaction) ), ]; } /** * The payment's value in the company's currency. * * Older rows predate the stored column, so when it is absent the figure is * recomputed from the amount and the rate. A rate of zero -- or any other * falsy value -- stands in as one, which keeps such a payment at its face * value instead of reporting it as worth nothing. */ private function baseAmount(): int { $payment = $this->resource; if ($payment->base_amount === null) { return (int) round($payment->amount * ($payment->exchange_rate ?: 1)); } return (int) $payment->base_amount; } /** * One row per invoice this payment has been allocated against. * * The invoice is nested in full where there is one; an allocation whose * invoice cannot be resolved still reports its amounts. */ private function allocationRows(Collection $allocations): Collection { return $allocations->map(fn ($allocation) => [ 'id' => $allocation->id, 'invoice_id' => $allocation->invoice_id, 'amount' => $allocation->amount, 'base_amount' => $allocation->base_amount, 'invoice' => $allocation->invoice ? new InvoiceResource($allocation->invoice) : null, ]); } }