where('account_id', $account->id) ->orderByDesc('paid_at') ->get(['id', 'amount_cents', 'currency', 'reference', 'paid_at', 'created_at']) ->map(function (Payment $p) { return [ 'id' => $p->id, 'amount' => $p->amount, // accessor divides cents 'currency' => $p->currency, 'reference' => $p->reference, 'paid_at' => $p->paid_at, 'created_at' => $p->created_at, ]; }); return Inertia::render('Accounts/Payments/Index', [ 'account' => $account->only(['id', 'reference', 'description']), 'payments' => $payments, ]); } public function list(Account $account): JsonResponse { $payments = Payment::query() ->where('account_id', $account->id) ->orderByDesc('paid_at') ->get(['id', 'amount_cents', 'currency', 'reference', 'paid_at', 'created_at']) ->map(function (Payment $p) { return [ 'id' => $p->id, 'amount' => $p->amount, 'currency' => $p->currency, 'reference' => $p->reference, 'paid_at' => optional($p->paid_at)?->toDateString(), 'created_at' => optional($p->created_at)?->toDateTimeString(), ]; }); return response()->json([ 'account' => [ 'id' => $account->id, 'balance_amount' => $account->balance_amount, ], 'payments' => $payments, ]); } public function store(StorePaymentRequest $request, Account $account): RedirectResponse { $validated = $request->validated(); $amountCents = (int) round(((float) $validated['amount']) * 100); // Load defaults from settings $settings = PaymentSetting::query()->first(); $defaultCurrency = strtoupper($settings->default_currency ?? 'EUR'); $payment = Payment::query()->create([ 'account_id' => $account->id, 'amount_cents' => $amountCents, 'currency' => strtoupper($validated['currency'] ?? $defaultCurrency), 'reference' => $validated['reference'] ?? null, 'paid_at' => $validated['paid_at'] ?? now(), 'meta' => $validated['meta'] ?? null, 'created_by' => $request->user()?->id, ]); // Auto-create a credit booking for this payment to reduce account balance Booking::query()->create([ 'account_id' => $account->id, 'payment_id' => $payment->id, 'amount_cents' => $amountCents, 'type' => 'credit', 'description' => $payment->reference ? ('Plačilo '.$payment->reference) : 'Plačilo', 'booked_at' => $payment->paid_at ?? now(), ]); // Optionally create an activity entry with default decision/action if ($settings && ($settings->create_activity_on_payment ?? false)) { $note = $settings->activity_note_template ?? 'Prejeto plačilo'; $note = str_replace(['{amount}', '{currency}'], [number_format($amountCents / 100, 2, ',', '.'), $payment->currency], $note); $account->loadMissing('contract'); $clientCaseId = $account->contract?->client_case_id; if ($clientCaseId) { $activity = Activity::query()->create([ 'due_date' => null, 'amount' => $amountCents / 100, 'note' => $note, 'action_id' => $settings->default_action_id, 'decision_id' => $settings->default_decision_id, 'client_case_id' => $clientCaseId, 'contract_id' => $account->contract_id, ]); // Link the payment to the activity $payment->update(['activity_id' => $activity->id]); } } return back()->with('success', 'Payment created.'); } public function destroy(Account $account, Payment $payment): RedirectResponse|JsonResponse { if ($payment->account_id !== $account->id) { abort(404); } // Delete related booking(s) to revert balance via model events Booking::query()->where('payment_id', $payment->id)->get()->each->delete(); // Optionally delete related activity if ($payment->activity_id ?? null) { $activity = Activity::query()->find($payment->activity_id); if ($activity) { $activity->delete(); } } $payment->delete(); if (request()->wantsJson()) { $account->refresh(); return response()->json([ 'ok' => true, 'balance_amount' => $account->balance_amount, ]); } return back()->with('success', 'Payment deleted.'); } }