Changes
This commit is contained in:
@@ -26,6 +26,14 @@ public function index(Request $request): Response
|
||||
$packages = Package::query()
|
||||
->latest('id')
|
||||
->paginate(25);
|
||||
|
||||
return Inertia::render('Admin/Packages/Index', [
|
||||
'packages' => $packages,
|
||||
]);
|
||||
}
|
||||
|
||||
public function create(Request $request): Response
|
||||
{
|
||||
// Minimal lookups for create form (active only)
|
||||
$profiles = \App\Models\SmsProfile::query()
|
||||
->where('active', true)
|
||||
@@ -58,8 +66,7 @@ public function index(Request $request): Response
|
||||
})
|
||||
->values();
|
||||
|
||||
return Inertia::render('Admin/Packages/Index', [
|
||||
'packages' => $packages,
|
||||
return Inertia::render('Admin/Packages/Create', [
|
||||
'profiles' => $profiles,
|
||||
'senders' => $senders,
|
||||
'templates' => $templates,
|
||||
@@ -312,7 +319,7 @@ public function contracts(Request $request, PhoneSelector $selector): \Illuminat
|
||||
$request->validate([
|
||||
'segment_id' => ['nullable', 'integer', 'exists:segments,id'],
|
||||
'q' => ['nullable', 'string'],
|
||||
'per_page' => ['nullable', 'integer', 'min:1', 'max:100'],
|
||||
|
||||
'client_id' => ['nullable', 'integer', 'exists:clients,id'],
|
||||
'only_mobile' => ['nullable', 'boolean'],
|
||||
'only_validated' => ['nullable', 'boolean'],
|
||||
@@ -323,7 +330,7 @@ public function contracts(Request $request, PhoneSelector $selector): \Illuminat
|
||||
]);
|
||||
|
||||
$segmentId = $request->input('segment_id') ? (int) $request->input('segment_id') : null;
|
||||
$perPage = (int) ($request->input('per_page') ?? 25);
|
||||
|
||||
|
||||
$query = Contract::query()
|
||||
->with([
|
||||
@@ -390,9 +397,9 @@ public function contracts(Request $request, PhoneSelector $selector): \Illuminat
|
||||
});
|
||||
}
|
||||
|
||||
$contracts = $query->paginate($perPage);
|
||||
$contracts = $query->get();
|
||||
|
||||
$data = collect($contracts->items())->map(function (Contract $contract) use ($selector) {
|
||||
$data = collect($contracts)->map(function (Contract $contract) use ($selector) {
|
||||
$person = $contract->clientCase?->person;
|
||||
$selected = $person ? $selector->selectForPerson($person) : ['phone' => null, 'reason' => 'no_person'];
|
||||
$phone = $selected['phone'];
|
||||
@@ -431,13 +438,7 @@ public function contracts(Request $request, PhoneSelector $selector): \Illuminat
|
||||
});
|
||||
|
||||
return response()->json([
|
||||
'data' => $data,
|
||||
'meta' => [
|
||||
'current_page' => $contracts->currentPage(),
|
||||
'last_page' => $contracts->lastPage(),
|
||||
'per_page' => $contracts->perPage(),
|
||||
'total' => $contracts->total(),
|
||||
],
|
||||
'data' => $data
|
||||
]);
|
||||
}
|
||||
|
||||
|
||||
@@ -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()]);
|
||||
|
||||
|
||||
Reference in New Issue
Block a user