Big changes added events for decisions

This commit is contained in:
Simon Pocrnjič
2025-10-22 23:20:04 +02:00
parent 872b76b012
commit 67ebe4b225
36 changed files with 2240 additions and 189 deletions
@@ -0,0 +1,58 @@
<?php
namespace App\Services\DecisionEvents\Handlers;
use App\Services\DecisionEvents\Contracts\DecisionEventHandler;
use App\Services\DecisionEvents\DecisionEventContext;
use Illuminate\Support\Facades\DB;
use InvalidArgumentException;
class AddSegmentHandler implements DecisionEventHandler
{
public function handle(DecisionEventContext $context, array $config = []): void
{
$contract = $context->contract;
if (! $contract) {
// If no contract on activity, nothing to apply
return;
}
$segmentId = (int) ($config['segment_id'] ?? 0);
if ($segmentId <= 0) {
throw new InvalidArgumentException('add_segment requires a valid segment_id');
}
$deactivatePrevious = array_key_exists('deactivate_previous', $config)
? (bool) $config['deactivate_previous']
: true;
DB::transaction(function () use ($contract, $segmentId, $deactivatePrevious) {
if ($deactivatePrevious) {
DB::table('contract_segment')
->where('contract_id', $contract->id)
->where('active', 1)
->update(['active' => 0, 'updated_at' => now()]);
}
// Ensure pivot exists and mark active=1
$existing = DB::table('contract_segment')
->where('contract_id', $contract->id)
->where('segment_id', $segmentId)
->first();
if ($existing) {
DB::table('contract_segment')
->where('id', $existing->id)
->update(['active' => 1, 'updated_at' => now()]);
} else {
DB::table('contract_segment')->insert([
'contract_id' => $contract->id,
'segment_id' => $segmentId,
'active' => 1,
'created_at' => now(),
'updated_at' => now(),
]);
}
});
}
}
@@ -0,0 +1,110 @@
<?php
namespace App\Services\DecisionEvents\Handlers;
use App\Models\ArchiveSetting;
use App\Services\Archiving\ArchiveExecutor;
use App\Services\DecisionEvents\Contracts\DecisionEventHandler;
use App\Services\DecisionEvents\DecisionEventContext;
class ArchiveContractHandler implements DecisionEventHandler
{
/**
* Config contract:
* - archive_setting_id: int (required) which ArchiveSetting to execute
* - reactivate: bool (optional) override ArchiveSetting->reactivate per run
*/
public function handle(DecisionEventContext $context, array $config = []): void
{
$activity = $context->activity;
// Require a contract_id from the activity per request requirements
$contractId = (int) ($activity->contract_id ?? 0);
if ($contractId <= 0) {
throw new \InvalidArgumentException('ArchiveContractHandler requires activity.contract_id');
}
$settingId = (int) ($config['archive_setting_id'] ?? 0);
if ($settingId <= 0) {
throw new \InvalidArgumentException('ArchiveContractHandler requires config.archive_setting_id');
}
$setting = ArchiveSetting::query()->findOrFail($settingId);
// Optionally override reactivate flag for this run
if (array_key_exists('reactivate', $config)) {
$setting->reactivate = (bool) $config['reactivate'];
}
$results = app(ArchiveExecutor::class)->executeSetting(
$setting,
['contract_id' => $contractId],
$activity->user_id ?? null,
null,
);
// If the ArchiveSetting specifies a segment, move the contract to that segment (mirror controller logic)
if (! empty($setting->segment_id)) {
try {
$segmentId = (int) $setting->segment_id;
$clientCase = $context->clientCase; // expected per context contract
$contract = $context->contract; // already loaded on context
if ($clientCase && $contract) {
\DB::transaction(function () use ($clientCase, $contract, $segmentId) {
// Ensure the segment is attached to the client case (activate if previously inactive)
$casePivot = \DB::table('client_case_segment')
->where('client_case_id', $clientCase->id)
->where('segment_id', $segmentId)
->first();
if (! $casePivot) {
\DB::table('client_case_segment')->insert([
'client_case_id' => $clientCase->id,
'segment_id' => $segmentId,
'active' => true,
'created_at' => now(),
'updated_at' => now(),
]);
} elseif (! $casePivot->active) {
\DB::table('client_case_segment')
->where('id', $casePivot->id)
->update(['active' => true, 'updated_at' => now()]);
}
// Deactivate all current active contract segments
\DB::table('contract_segment')
->where('contract_id', $contract->id)
->where('active', true)
->update(['active' => false, 'updated_at' => now()]);
// Attach or activate the target segment for this contract
$existing = \DB::table('contract_segment')
->where('contract_id', $contract->id)
->where('segment_id', $segmentId)
->first();
if ($existing) {
\DB::table('contract_segment')
->where('id', $existing->id)
->update(['active' => true, 'updated_at' => now()]);
} else {
\DB::table('contract_segment')->insert([
'contract_id' => $contract->id,
'segment_id' => $segmentId,
'active' => true,
'created_at' => now(),
'updated_at' => now(),
]);
}
});
}
} catch (\Throwable $e) {
// Do not fail the event; log warning for diagnostics
logger()->warning('ArchiveContractHandler: failed to move contract to segment', [
'error' => $e->getMessage(),
'setting_id' => $setting->id,
'segment_id' => $setting->segment_id,
'contract_id' => $contractId,
]);
}
}
}
}
@@ -0,0 +1,36 @@
<?php
namespace App\Services\DecisionEvents\Handlers;
use App\Jobs\EndFieldJob;
use App\Services\DecisionEvents\Contracts\DecisionEventHandler;
use App\Services\DecisionEvents\DecisionEventContext;
use Illuminate\Support\Facades\Bus;
class EndFieldJobHandler implements DecisionEventHandler
{
/**
* Config contract:
* - any pass-through keys needed by the EndFieldJob implementation
*/
public function handle(DecisionEventContext $context, array $config = []): void
{
$activity = $context->activity;
$job = new EndFieldJob(
activityId: (int) $activity->id,
contractId: $activity->contract_id ? (int) $activity->contract_id : null,
config: $config,
);
// Run synchronously in local/dev/testing or when debug is on or queue driver is sync; otherwise queue it.
$shouldRunSync = app()->environment(['local', 'development', 'dev', 'testing'])
|| (bool) config('app.debug')
|| config('queue.default') === 'sync';
if ($shouldRunSync) {
Bus::dispatchSync($job);
} else {
dispatch($job);
}
}
}