Option to add installment to contract/account to increace balance amount same as payment and can be deleted which will reduce balance amount by new amount of the installment deleted, call later added badge to show active call laters
This commit is contained in:
@@ -0,0 +1,132 @@
|
||||
<?php
|
||||
|
||||
namespace App\Http\Controllers;
|
||||
|
||||
use App\Http\Requests\StoreInstallmentRequest;
|
||||
use App\Models\Account;
|
||||
use App\Models\Activity;
|
||||
use App\Models\Booking;
|
||||
use App\Models\Installment;
|
||||
use App\Models\InstallmentSetting;
|
||||
use Illuminate\Http\JsonResponse;
|
||||
use Illuminate\Http\RedirectResponse;
|
||||
|
||||
class AccountInstallmentController extends Controller
|
||||
{
|
||||
public function list(Account $account): JsonResponse
|
||||
{
|
||||
$installments = Installment::query()
|
||||
->where('account_id', $account->id)
|
||||
->orderByDesc('installment_at')
|
||||
->get(['id', 'amount', 'balance_before', 'currency', 'reference', 'installment_at', 'created_at'])
|
||||
->map(function (Installment $i) {
|
||||
return [
|
||||
'id' => $i->id,
|
||||
'amount' => (float) $i->amount,
|
||||
'balance_before' => (float) ($i->balance_before ?? 0),
|
||||
'currency' => $i->currency,
|
||||
'reference' => $i->reference,
|
||||
'installment_at' => optional($i->installment_at)?->toDateString(),
|
||||
'created_at' => optional($i->created_at)?->toDateTimeString(),
|
||||
];
|
||||
});
|
||||
|
||||
return response()->json([
|
||||
'account' => [
|
||||
'id' => $account->id,
|
||||
'balance_amount' => $account->balance_amount,
|
||||
],
|
||||
'installments' => $installments,
|
||||
]);
|
||||
}
|
||||
|
||||
public function store(StoreInstallmentRequest $request, Account $account): RedirectResponse
|
||||
{
|
||||
$validated = $request->validated();
|
||||
|
||||
$amountCents = (int) round(((float) $validated['amount']) * 100);
|
||||
|
||||
$settings = InstallmentSetting::query()->first();
|
||||
$defaultCurrency = strtoupper($settings->default_currency ?? 'EUR');
|
||||
|
||||
$installment = Installment::query()->create([
|
||||
'account_id' => $account->id,
|
||||
'balance_before' => (float) ($account->balance_amount ?? 0),
|
||||
'amount' => (float) $validated['amount'],
|
||||
'currency' => strtoupper($validated['currency'] ?? $defaultCurrency),
|
||||
'reference' => $validated['reference'] ?? null,
|
||||
'installment_at' => $validated['installment_at'] ?? now(),
|
||||
'meta' => $validated['meta'] ?? null,
|
||||
'created_by' => $request->user()?->id,
|
||||
]);
|
||||
|
||||
// Debit booking — increases the account balance
|
||||
Booking::query()->create([
|
||||
'account_id' => $account->id,
|
||||
'payment_id' => null,
|
||||
'amount_cents' => $amountCents,
|
||||
'type' => 'debit',
|
||||
'description' => $installment->reference ? ('Obremenitev '.$installment->reference) : 'Obremenitev',
|
||||
'booked_at' => $installment->installment_at ?? now(),
|
||||
]);
|
||||
|
||||
if ($settings && ($settings->create_activity_on_installment ?? false)) {
|
||||
$note = $settings->activity_note_template ?? 'Dodan obrok';
|
||||
$note = str_replace(['{amount}', '{currency}'], [number_format($amountCents / 100, 2, ',', '.'), $installment->currency], $note);
|
||||
|
||||
$account->refresh();
|
||||
$beforeStr = number_format((float) ($installment->balance_before ?? 0), 2, ',', '.').' '.$installment->currency;
|
||||
$afterStr = number_format((float) ($account->balance_amount ?? 0), 2, ',', '.').' '.$installment->currency;
|
||||
$note .= " (Stanje pred: {$beforeStr}, Stanje po: {$afterStr}; Izvor: obrok)";
|
||||
|
||||
$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,
|
||||
]);
|
||||
$installment->update(['activity_id' => $activity->id]);
|
||||
}
|
||||
}
|
||||
|
||||
return back()->with('success', 'Installment created.');
|
||||
}
|
||||
|
||||
public function destroy(Account $account, Installment $installment): RedirectResponse|JsonResponse
|
||||
{
|
||||
if ($installment->account_id !== $account->id) {
|
||||
abort(404);
|
||||
}
|
||||
|
||||
// Delete related debit booking(s) to revert balance via model events
|
||||
Booking::query()
|
||||
->where('account_id', $account->id)
|
||||
->where('type', 'debit')
|
||||
->whereDate('booked_at', optional($installment->installment_at)?->toDateString())
|
||||
->where('amount_cents', (int) round(((float) $installment->amount) * 100))
|
||||
->whereNull('payment_id')
|
||||
->get()
|
||||
->each->delete();
|
||||
|
||||
if ($installment->activity_id) {
|
||||
$activity = Activity::query()->find($installment->activity_id);
|
||||
if ($activity) {
|
||||
$activity->delete();
|
||||
}
|
||||
}
|
||||
|
||||
$installment->delete();
|
||||
|
||||
if (request()->wantsJson()) {
|
||||
return response()->json(['success' => true]);
|
||||
}
|
||||
|
||||
return back()->with('success', 'Installment deleted.');
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user