This commit is contained in:
Simon Pocrnjič
2026-01-10 20:11:20 +01:00
parent 711438d79f
commit c4d2f6e473
21 changed files with 1744 additions and 1889 deletions
+96 -46
View File
@@ -311,6 +311,9 @@ public function storeActivity(ClientCase $clientCase, Request $request)
'action_id' => 'exists:\App\Models\Action,id',
'decision_id' => 'exists:\App\Models\Decision,id',
'contract_uuid' => 'nullable|uuid',
'contract_uuids' => 'nullable|array',
'contract_uuids.*' => 'uuid',
'create_for_all_contracts' => 'nullable|boolean',
'phone_view' => 'nullable|boolean',
'send_auto_mail' => 'sometimes|boolean',
'attachment_document_ids' => 'sometimes|array',
@@ -318,61 +321,102 @@ public function storeActivity(ClientCase $clientCase, Request $request)
]);
$isPhoneView = $attributes['phone_view'] ?? false;
$createForAll = $attributes['create_for_all_contracts'] ?? false;
$contractUuids = $attributes['contract_uuids'] ?? [];
// Map contract_uuid to contract_id within the same client case, if provided
$contractId = null;
if (! empty($attributes['contract_uuid'])) {
// Determine which contracts to process
$contractIds = [];
if ($createForAll && !empty($contractUuids)) {
// Get all contract IDs from the provided UUIDs
$contracts = Contract::withTrashed()
->whereIn('uuid', $contractUuids)
->where('client_case_id', $clientCase->id)
->get();
$contractIds = $contracts->pluck('id')->toArray();
} elseif (!empty($contractUuids) && isset($contractUuids[0])) {
// Single contract mode
$contract = Contract::withTrashed()
->where('uuid', $contractUuids[0])
->where('client_case_id', $clientCase->id)
->first();
if ($contract) {
$contractIds = [$contract->id];
}
} elseif (!empty($attributes['contract_uuid'])) {
// Legacy single contract_uuid support
$contract = Contract::withTrashed()
->where('uuid', $attributes['contract_uuid'])
->where('client_case_id', $clientCase->id)
->first();
if ($contract) {
// Archived contracts are allowed: link activity regardless of active flag
$contractId = $contract->id;
$contractIds = [$contract->id];
}
}
// Create activity
$row = $clientCase->activities()->create([
'due_date' => $attributes['due_date'] ?? null,
'amount' => $attributes['amount'] ?? null,
'note' => $attributes['note'] ?? null,
'action_id' => $attributes['action_id'],
'decision_id' => $attributes['decision_id'],
'contract_id' => $contractId,
]);
if ($isPhoneView && $contractId) {
$fieldJob = $contract->fieldJobs()
->whereNull('completed_at')
->whereNull('cancelled_at')
->where('assigned_user_id', \Auth::id())
->orderByDesc('id')
->first();
if ($fieldJob) {
$fieldJob->update([
'added_activity' => true,
'last_activity' => $row->created_at,
]);
}
// If no contracts specified, create a single activity without contract
if (empty($contractIds)) {
$contractIds = [null];
}
logger()->info('Activity successfully inserted', $attributes);
$createdActivities = [];
$sendFlag = (bool) ($attributes['send_auto_mail'] ?? true);
// Disable auto mail if creating activities for multiple contracts
if ($sendFlag && count($contractIds) > 1) {
$sendFlag = false;
logger()->info('Auto mail disabled: multiple contracts selected', ['contract_count' => count($contractIds)]);
}
// Auto mail dispatch (best-effort)
try {
$sendFlag = (bool) ($attributes['send_auto_mail'] ?? true);
$row->load(['decision', 'clientCase.client.person', 'clientCase.person', 'contract']);
// Filter attachments to those belonging to the selected contract
$attachmentIds = collect($attributes['attachment_document_ids'] ?? [])
->filter()
->map(fn ($v) => (int) $v)
->values();
$validAttachmentIds = collect();
if ($attachmentIds->isNotEmpty() && $contractId) {
$validAttachmentIds = Document::query()
foreach ($contractIds as $contractId) {
// Create activity
$row = $clientCase->activities()->create([
'due_date' => $attributes['due_date'] ?? null,
'amount' => $attributes['amount'] ?? null,
'note' => $attributes['note'] ?? null,
'action_id' => $attributes['action_id'],
'decision_id' => $attributes['decision_id'],
'contract_id' => $contractId,
]);
$createdActivities[] = $row;
if ($isPhoneView && $contractId) {
$contract = Contract::find($contractId);
if ($contract) {
$fieldJob = $contract->fieldJobs()
->whereNull('completed_at')
->whereNull('cancelled_at')
->where('assigned_user_id', \Auth::id())
->orderByDesc('id')
->first();
if ($fieldJob) {
$fieldJob->update([
'added_activity' => true,
'last_activity' => $row->created_at,
]);
}
}
}
logger()->info('Activity successfully inserted', array_merge($attributes, ['contract_id' => $contractId]));
// Auto mail dispatch (best-effort)
try {
$row->load(['decision', 'clientCase.client.person', 'clientCase.person', 'contract']);
// Filter attachments to those belonging to the selected contract
$attachmentIds = collect($attributes['attachment_document_ids'] ?? [])
->filter()
->map(fn ($v) => (int) $v)
->values();
$validAttachmentIds = collect();
if ($attachmentIds->isNotEmpty() && $contractId) {
$validAttachmentIds = Document::query()
->where('documentable_type', Contract::class)
->where('documentable_id', $contractId)
->whereIn('id', $attachmentIds)
->pluck('id');
$validAttachmentIds = Document::query()
->where('documentable_type', Contract::class)
->where('documentable_id', $contractId)
->whereIn('id', $attachmentIds)
@@ -383,19 +427,25 @@ public function storeActivity(ClientCase $clientCase, Request $request)
]);
if (($result['skipped'] ?? null) === 'missing-contract' && $sendFlag) {
// If template requires contract and user attempted to send, surface a validation message
return back()->with('warning', 'Email not queued: required contract is missing for the selected template.');
logger()->warning('Email not queued: required contract is missing for the selected template.');
}
if (($result['skipped'] ?? null) === 'no-recipients' && $sendFlag) {
return back()->with('warning', 'Email not queued: no eligible client emails to receive auto mails.');
logger()->warning('Email not queued: no eligible client emails to receive auto mails.');
}
} catch (\Throwable $e) {
// Do not fail activity creation due to mailing issues
logger()->warning('Auto mail dispatch failed: '.$e->getMessage());
}
}
$activityCount = count($createdActivities);
$successMessage = $activityCount > 1
? "Successfully created {$activityCount} activities!"
: 'Successfully created activity!';
// Stay on the current page (desktop or phone) instead of forcing a redirect to the desktop route.
// Use 303 to align with Inertia's recommended POST/Redirect/GET behavior.
return back(303)->with('success', 'Successful created!')->with('flash_method', 'POST');
return back(303)->with('success', $successMessage)->with('flash_method', 'POST');
} catch (QueryException $e) {
logger()->error('Database error occurred:', ['error' => $e->getMessage()]);