changes 0328092025
This commit is contained in:
@@ -0,0 +1,229 @@
|
||||
<?php
|
||||
|
||||
namespace App\Http\Controllers;
|
||||
|
||||
use App\Models\Activity;
|
||||
use App\Models\Contract;
|
||||
use App\Models\FieldJob;
|
||||
use App\Models\FieldJobSetting;
|
||||
use App\Models\User;
|
||||
use Illuminate\Http\Request;
|
||||
use Illuminate\Support\Facades\DB;
|
||||
use Inertia\Inertia;
|
||||
|
||||
class FieldJobController extends Controller
|
||||
{
|
||||
public function index(Request $request)
|
||||
{
|
||||
$setting = FieldJobSetting::query()->latest('id')->first();
|
||||
// Only fetch contracts that are currently in either the primary segment
|
||||
// or the optional queue segment defined on the latest FieldJobSetting.
|
||||
$segmentIds = collect([
|
||||
optional($setting)->queue_segment_id,
|
||||
optional($setting)->segment_id,
|
||||
])->filter()->unique()->values();
|
||||
|
||||
$contracts = Contract::query()
|
||||
->with(['clientCase.person', 'type', 'account'])
|
||||
->when($segmentIds->isNotEmpty(), function ($q) use ($segmentIds) {
|
||||
$q->whereHas('segments', function ($sq) use ($segmentIds) {
|
||||
// Relation already filters on active pivots
|
||||
$sq->whereIn('segments.id', $segmentIds);
|
||||
});
|
||||
}, function ($q) {
|
||||
// No segments configured on FieldJobSetting -> return none
|
||||
$q->whereRaw('1 = 0');
|
||||
})
|
||||
->latest('id')
|
||||
->limit(50)
|
||||
->get();
|
||||
|
||||
// Build active assignment map keyed by contract uuid for quicker UI checks
|
||||
$assignments = collect();
|
||||
if ($contracts->isNotEmpty()) {
|
||||
$activeJobs = FieldJob::query()
|
||||
->whereIn('contract_id', $contracts->pluck('id'))
|
||||
->whereNull('completed_at')
|
||||
->whereNull('cancelled_at')
|
||||
->with(['assignedUser:id,name', 'user:id,name', 'contract:id,uuid'])
|
||||
->get();
|
||||
|
||||
$assignments = $activeJobs->mapWithKeys(function (FieldJob $job) {
|
||||
return [
|
||||
optional($job->contract)->uuid => [
|
||||
'assigned_to' => $job->assignedUser ? ['id' => $job->assignedUser->id, 'name' => $job->assignedUser->name] : null,
|
||||
'assigned_by' => $job->user ? ['id' => $job->user->id, 'name' => $job->user->name] : null,
|
||||
'assigned_at' => $job->assigned_at,
|
||||
],
|
||||
];
|
||||
})->filter();
|
||||
}
|
||||
|
||||
$users = User::query()->orderBy('name')->get(['id', 'name']);
|
||||
|
||||
return Inertia::render('FieldJob/Index', [
|
||||
'setting' => $setting,
|
||||
'contracts' => $contracts,
|
||||
'users' => $users,
|
||||
'assignments' => $assignments,
|
||||
]);
|
||||
}
|
||||
|
||||
public function assign(Request $request)
|
||||
{
|
||||
$data = $request->validate([
|
||||
'contract_uuid' => 'required|string|exists:contracts,uuid',
|
||||
'assigned_user_id' => 'required|integer|exists:users,id',
|
||||
]);
|
||||
|
||||
$setting = FieldJobSetting::query()->latest('id')->first();
|
||||
if (! $setting) {
|
||||
return back()->withErrors(['setting' => 'No Field Job Setting found. Create one in Settings → Field Job Settings.']);
|
||||
}
|
||||
|
||||
$contract = Contract::query()->where('uuid', $data['contract_uuid'])->firstOrFail();
|
||||
|
||||
$job = FieldJob::create([
|
||||
'field_job_setting_id' => $setting->id,
|
||||
'assigned_user_id' => $data['assigned_user_id'],
|
||||
'contract_id' => $contract->id,
|
||||
'assigned_at' => now(),
|
||||
]);
|
||||
|
||||
// Create an activity for the assignment
|
||||
// Find the first action linked to the assign decision via pivot; also prefer actions within the same segment as the setting
|
||||
$decisionId = $setting->assign_decision_id;
|
||||
$actionId = null;
|
||||
if ($decisionId) {
|
||||
// Strictly use the action_decision pivot: take the first action mapped to this decision
|
||||
$actionId = DB::table('action_decision')
|
||||
->where('decision_id', $decisionId)
|
||||
->orderBy('id')
|
||||
->value('action_id');
|
||||
}
|
||||
|
||||
if ($actionId) {
|
||||
$assigneeName = User::query()->where('id', $data['assigned_user_id'])->value('name');
|
||||
// Localized note: "Terensko opravilo dodeljeno" + assignee when present
|
||||
$note = 'Terensko opravilo dodeljeno'.($assigneeName ? ' uporabniku '.$assigneeName : '');
|
||||
Activity::create([
|
||||
'due_date' => null,
|
||||
'amount' => null,
|
||||
'note' => $note,
|
||||
'action_id' => $actionId,
|
||||
'decision_id' => $decisionId,
|
||||
'client_case_id' => $contract->client_case_id,
|
||||
'contract_id' => $contract->id,
|
||||
]);
|
||||
}
|
||||
|
||||
return back()->with('success', 'Field job assigned.');
|
||||
}
|
||||
|
||||
public function cancel(Request $request)
|
||||
{
|
||||
$data = $request->validate([
|
||||
'contract_uuid' => 'required|string|exists:contracts,uuid',
|
||||
]);
|
||||
|
||||
$contract = Contract::query()->where('uuid', $data['contract_uuid'])->firstOrFail();
|
||||
|
||||
$job = FieldJob::query()
|
||||
->where('contract_id', $contract->id)
|
||||
->whereNull('completed_at')
|
||||
->whereNull('cancelled_at')
|
||||
->latest('id')
|
||||
->first();
|
||||
|
||||
if ($job) {
|
||||
$job->cancelled_at = now();
|
||||
$job->save();
|
||||
|
||||
// Create an activity for the cancellation, mirroring the assign flow
|
||||
// Prefer the job's setting for a consistent decision
|
||||
$job->loadMissing('setting');
|
||||
$decisionId = optional($job->setting)->cancel_decision_id;
|
||||
if ($decisionId) {
|
||||
$actionId = DB::table('action_decision')
|
||||
->where('decision_id', $decisionId)
|
||||
->orderBy('id')
|
||||
->value('action_id');
|
||||
|
||||
if ($actionId) {
|
||||
Activity::create([
|
||||
'due_date' => null,
|
||||
'amount' => null,
|
||||
'note' => 'Terensko opravilo preklicano',
|
||||
'action_id' => $actionId,
|
||||
'decision_id' => $decisionId,
|
||||
'client_case_id' => $contract->client_case_id,
|
||||
'contract_id' => $contract->id,
|
||||
]);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return back()->with('success', 'Field job cancelled.');
|
||||
}
|
||||
|
||||
public function complete(Request $request, \App\Models\ClientCase $clientCase)
|
||||
{
|
||||
// Complete all active field jobs for contracts of this case assigned to current user
|
||||
$userId = optional($request->user())->id;
|
||||
$setting = FieldJobSetting::query()->latest('id')->first();
|
||||
if (! $setting) {
|
||||
return back()->withErrors(['setting' => 'No Field Job Setting found.']);
|
||||
}
|
||||
|
||||
$decisionId = $setting->complete_decision_id;
|
||||
$actionId = null;
|
||||
if ($decisionId) {
|
||||
$actionId = DB::table('action_decision')
|
||||
->where('decision_id', $decisionId)
|
||||
->orderBy('id')
|
||||
->value('action_id');
|
||||
}
|
||||
|
||||
// Find all active jobs for this case for the current user
|
||||
$jobs = FieldJob::query()
|
||||
->whereHas('contract', function ($q) use ($clientCase) {
|
||||
$q->where('client_case_id', $clientCase->id);
|
||||
})
|
||||
->where(function ($q) use ($userId) {
|
||||
if ($userId) {
|
||||
$q->where('assigned_user_id', $userId);
|
||||
}
|
||||
})
|
||||
->whereNull('completed_at')
|
||||
->whereNull('cancelled_at')
|
||||
->with(['contract:id,client_case_id', 'setting'])
|
||||
->get();
|
||||
|
||||
DB::transaction(function () use ($jobs, $decisionId, $actionId) {
|
||||
foreach ($jobs as $job) {
|
||||
// Mark job complete
|
||||
$job->completed_at = now();
|
||||
$job->save();
|
||||
|
||||
// Log completion activity on the contract/case
|
||||
if ($actionId && $decisionId) {
|
||||
Activity::create([
|
||||
'due_date' => null,
|
||||
'amount' => null,
|
||||
'note' => 'Terensko opravilo zaključeno',
|
||||
'action_id' => $actionId,
|
||||
'decision_id' => $decisionId,
|
||||
'client_case_id' => $job->contract->client_case_id,
|
||||
'contract_id' => $job->contract_id,
|
||||
]);
|
||||
}
|
||||
|
||||
// Move contract to configured return segment
|
||||
$job->returnContractToConfiguredSegment();
|
||||
}
|
||||
});
|
||||
|
||||
// Redirect back to phone index
|
||||
return to_route('phone.index');
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user