Files
Investidor-V2/app/Services/OpportunityWorkflowTasks.php
T
nala 287e991486
tests / ci (push) Waiting to run
oportunidades 7
2026-10-13 11:40:29 +02:00

62 lines
3.1 KiB
PHP

<?php
namespace App\Services;
use App\Models\Opportunity;
use App\Models\User;
use Illuminate\Support\Facades\DB;
use Illuminate\Support\Str;
/** Existing CRM tasks, explicit portal binding; no invented CRM opportunity or assignee. */
class OpportunityWorkflowTasks
{
public function ensure(Opportunity $record, string $kind, string $title): string
{
$key = 'portal-opportunity:'.$record->id.':'.$kind.':'.($record->workflow_context['content_revision'] ?? 1);
if (isset($record->workflow_context['review_cycle'])) {
$key .= ':cycle:'.$record->workflow_context['review_cycle'];
}
$existing = DB::table('tasks')->where('source_system', 'opportunity-workflow')->where('external_id', $key)->first();
if ($existing) {
return $existing->id;
}
$id = (string) Str::uuid();
DB::table('tasks')->insert(['id' => $id, 'source_system' => 'opportunity-workflow', 'external_id' => $key,
'correlation_id' => $record->management_creation_key, 'task_type' => $kind, 'title' => $title,
'status' => 'open', 'due_at' => null, 'assignee_user_id' => null, 'data_classification' => 'restricted']);
return $id;
}
public function assign(Opportunity $record, string $taskId, User $subject): void
{
abort_unless(DB::table('tasks')->where('id', $taskId)->where('source_system', 'opportunity-workflow')
->where('external_id', 'like', 'portal-opportunity:'.$record->id.':%')->whereIn('status', ['open', 'in_progress'])->exists(), 409, 'Tarefa não pertence à versão aberta.');
DB::table('tasks')->where('id', $taskId)->update(['assignee_user_id' => $subject->id, 'status' => 'in_progress', 'version_no' => DB::raw('version_no+1')]);
}
public function closedReviewBinding(Opportunity $record, ?string $id): bool
{
return $id !== null && DB::table('tasks')->where('id', $id)->where('source_system', 'opportunity-workflow')
->where('external_id', 'like', 'portal-opportunity:'.$record->id.':opportunity_review:%')->where('status', 'done')->exists();
}
public function complete(?string $taskId, string $outcome): void
{
if ($taskId) {
// Existing CRM outcome is a varchar(80) summary. The full reason is
// retained in the versioned workflow decision and its audit event.
$summary = mb_strlen($outcome) > 80 ? mb_substr($outcome, 0, 79).'…' : $outcome;
DB::table('tasks')->where('id', $taskId)->where('source_system', 'opportunity-workflow')->whereIn('status', ['open', 'in_progress'])
->update(['status' => 'done', 'outcome' => $summary, 'completed_at' => now(), 'version_no' => DB::raw('version_no+1')]);
}
}
/** @return list<\stdClass> */
public function listing(Opportunity $record): array
{
return array_values(DB::table('tasks')->where('source_system', 'opportunity-workflow')->where('external_id', 'like', 'portal-opportunity:'.$record->id.':%')
->get(['id', 'task_type', 'status', 'title', 'assignee_user_id', 'due_at', 'completed_at', 'outcome'])->all());
}
}