changes
This commit is contained in:
@@ -172,34 +172,76 @@ public function updateContract(ClientCase $clientCase, string $uuid, UpdateContr
|
||||
]);
|
||||
|
||||
$initial = $request->input('initial_amount');
|
||||
$balance = $request->input('balance_amount');
|
||||
$shouldUpsertAccount = (! is_null($initial)) || (! is_null($balance)) || $request->has('account_type_id');
|
||||
// Use has() to distinguish between an omitted field and an explicit 0 / null intent
|
||||
$balanceFieldPresent = $request->has('balance_amount');
|
||||
$balance = $balanceFieldPresent ? $request->input('balance_amount') : null;
|
||||
// Always allow updating existing account even if only balance set to 0 (or unchanged) so user can correct it.
|
||||
$hasType = $request->has('account_type_id');
|
||||
$shouldUpsertAccount = ($contract->account()->exists()) || (! is_null($initial)) || $balanceFieldPresent || $hasType;
|
||||
if ($shouldUpsertAccount) {
|
||||
$accountData = [];
|
||||
// Track old balance before applying changes
|
||||
$oldBalance = (float) optional($contract->account)->balance_amount;
|
||||
$currentAccount = $contract->account; // newest (latestOfMany)
|
||||
$oldBalance = (float) optional($currentAccount)->balance_amount;
|
||||
if (! is_null($initial)) {
|
||||
$accountData['initial_amount'] = $initial;
|
||||
}
|
||||
if (! is_null($balance)) {
|
||||
$accountData['balance_amount'] = $balance;
|
||||
// If the balance field was present in the request payload we always apply it (allow setting to 0)
|
||||
if ($balanceFieldPresent) {
|
||||
// Allow explicitly setting to 0, fallback to 0 if null provided
|
||||
$accountData['balance_amount'] = $balance ?? 0;
|
||||
}
|
||||
if ($request->has('account_type_id')) {
|
||||
$accountData['type_id'] = $request->input('account_type_id');
|
||||
}
|
||||
|
||||
if ($contract->account) {
|
||||
$contract->account->update($accountData);
|
||||
if ($currentAccount) {
|
||||
$currentAccount->update($accountData);
|
||||
if (array_key_exists('balance_amount', $accountData)) {
|
||||
$currentAccount->forceFill(['balance_amount' => $accountData['balance_amount']])->save();
|
||||
$freshBal = (float) optional($currentAccount->fresh())->balance_amount;
|
||||
if ((float) $freshBal !== (float) $accountData['balance_amount']) {
|
||||
\DB::table('accounts')
|
||||
->where('id', $currentAccount->id)
|
||||
->update(['balance_amount' => $accountData['balance_amount'], 'updated_at' => now()]);
|
||||
$freshBal = (float) optional($currentAccount->fresh())->balance_amount;
|
||||
}
|
||||
} else {
|
||||
$freshBal = (float) optional($currentAccount->fresh())->balance_amount;
|
||||
}
|
||||
} else {
|
||||
// For create, ensure defaults exist if not provided
|
||||
$accountData = array_merge(['initial_amount' => 0, 'balance_amount' => 0], $accountData);
|
||||
$contract->account()->create($accountData);
|
||||
$created = $contract->account()->create($accountData);
|
||||
$freshBal = (float) optional($created->fresh())->balance_amount;
|
||||
}
|
||||
// If multiple historical accounts exist, log them and optionally propagate update to all to keep consistent
|
||||
$allAccounts = \DB::table('accounts')->where('contract_id', $contract->id)->orderBy('id')->get(['id','balance_amount','initial_amount']);
|
||||
if ($allAccounts->count() > 1 && array_key_exists('balance_amount', $accountData)) {
|
||||
// Propagate balance to all for consistency (comment out if not desired)
|
||||
\DB::table('accounts')->where('contract_id', $contract->id)->update(['balance_amount' => $accountData['balance_amount'], 'updated_at' => now()]);
|
||||
$freshBal = (float) \DB::table('accounts')->where('contract_id', $contract->id)->latest('id')->value('balance_amount');
|
||||
}
|
||||
try {
|
||||
$accountCount = $allAccounts->count();
|
||||
logger()->info('Contract account upsert', [
|
||||
'contract_id' => $contract->id,
|
||||
'request_initial' => $initial,
|
||||
'request_balance_present' => $balanceFieldPresent,
|
||||
'request_balance' => $balance,
|
||||
'request_account_type_id' => $request->input('account_type_id'),
|
||||
'account_data_applied' => $accountData,
|
||||
'old_balance' => $oldBalance,
|
||||
'new_balance_after_update' => $freshBal,
|
||||
'accounts_for_contract' => $accountCount,
|
||||
'accounts_snapshot' => $allAccounts,
|
||||
]);
|
||||
} catch (\Throwable $e) {
|
||||
// ignore logging errors
|
||||
}
|
||||
|
||||
// After update/create, if balance_amount changed (and not through a payment), log an activity with before/after
|
||||
if (array_key_exists('balance_amount', $accountData)) {
|
||||
// Guard against null account (e.g., if creation failed silently earlier)
|
||||
$newAccount = $contract->account; // single relationship access
|
||||
$newAccount = $contract->account; // refreshed latest
|
||||
$newBalance = $newAccount ? (float) optional($newAccount->fresh())->balance_amount : $oldBalance;
|
||||
if ($newAccount && $newBalance !== $oldBalance) {
|
||||
try {
|
||||
@@ -231,6 +273,24 @@ public function updateContract(ClientCase $clientCase, string $uuid, UpdateContr
|
||||
return to_route('clientCase.show', ['client_case' => $clientCase, 'segment' => $segment]);
|
||||
}
|
||||
|
||||
/**
|
||||
* Debug endpoint: list all account rows for a contract (only in debug mode).
|
||||
*/
|
||||
public function debugContractAccounts(ClientCase $clientCase, string $uuid, Request $request)
|
||||
{
|
||||
abort_unless(config('app.debug'), 404);
|
||||
$contract = $clientCase->contracts()->where('uuid', $uuid)->firstOrFail(['id','uuid','reference']);
|
||||
$accounts = \DB::table('accounts')
|
||||
->where('contract_id', $contract->id)
|
||||
->orderBy('id')
|
||||
->get(['id','contract_id','initial_amount','balance_amount','type_id','created_at','updated_at']);
|
||||
return response()->json([
|
||||
'contract' => $contract,
|
||||
'accounts' => $accounts,
|
||||
'count' => $accounts->count(),
|
||||
]);
|
||||
}
|
||||
|
||||
public function storeActivity(ClientCase $clientCase, Request $request)
|
||||
{
|
||||
try {
|
||||
@@ -1048,8 +1108,8 @@ public function show(ClientCase $clientCase)
|
||||
// Prepare contracts and a reference map.
|
||||
// Only apply active/inactive filtering IF a segment filter is provided.
|
||||
$contractsQuery = $case->contracts()
|
||||
// Only select lean columns to avoid oversize JSON / headers
|
||||
->select(['id', 'uuid', 'reference', 'start_date', 'end_date', 'active', 'type_id', 'client_case_id', 'created_at'])
|
||||
// Only select lean columns to avoid oversize JSON / headers (include description for UI display)
|
||||
->select(['id', 'uuid', 'reference', 'start_date', 'end_date', 'description', 'active', 'type_id', 'client_case_id', 'created_at'])
|
||||
->with([
|
||||
'type:id,name',
|
||||
// Use closure for account to avoid ambiguous column names with latestOfMany join
|
||||
@@ -1060,9 +1120,14 @@ public function show(ClientCase $clientCase)
|
||||
'accounts.type_id',
|
||||
'accounts.initial_amount',
|
||||
'accounts.balance_amount',
|
||||
]);
|
||||
'accounts.promise_date',
|
||||
'accounts.created_at',
|
||||
'accounts.updated_at', // include updated_at so FE can detect changes & for debugging
|
||||
])->orderByDesc('accounts.id');
|
||||
},
|
||||
'segments:id,name',
|
||||
// Eager load objects so newly created objects appear without full reload logic issues
|
||||
'objects:id,contract_id,reference,name,description,type,created_at',
|
||||
]);
|
||||
|
||||
$contractsQuery->orderByDesc('created_at');
|
||||
@@ -1089,6 +1154,25 @@ public function show(ClientCase $clientCase)
|
||||
// pathological memory / header growth. Frontend can request more via future endpoint.
|
||||
$contracts = $contractsQuery->limit(500)->get();
|
||||
|
||||
// TEMP DEBUG: log what balances are being sent to Inertia (remove once issue resolved)
|
||||
try {
|
||||
logger()->info('Show contracts balances', [
|
||||
'case_id' => $case->id,
|
||||
'contract_count' => $contracts->count(),
|
||||
'contracts' => $contracts->map(fn($c) => [
|
||||
'id' => $c->id,
|
||||
'uuid' => $c->uuid,
|
||||
'reference' => $c->reference,
|
||||
'account_id' => optional($c->account)->id,
|
||||
'initial_amount' => optional($c->account)->initial_amount,
|
||||
'balance_amount' => optional($c->account)->balance_amount,
|
||||
'account_updated_at' => optional($c->account)->updated_at,
|
||||
])->toArray(),
|
||||
]);
|
||||
} catch (\Throwable $e) {
|
||||
// swallow
|
||||
}
|
||||
|
||||
$contractRefMap = [];
|
||||
foreach ($contracts as $c) {
|
||||
$contractRefMap[$c->id] = $c->reference;
|
||||
|
||||
Reference in New Issue
Block a user