Code Coverage
 
Lines
Functions and Methods
Classes and Traits
Total
0.00% covered (danger)
0.00%
0 / 50
0.00% covered (danger)
0.00%
0 / 1
CRAP
0.00% covered (danger)
0.00%
0 / 1
UpdateWorkflowAction
0.00% covered (danger)
0.00%
0 / 50
0.00% covered (danger)
0.00%
0 / 1
110
0.00% covered (danger)
0.00%
0 / 1
 execute
0.00% covered (danger)
0.00%
0 / 50
0.00% covered (danger)
0.00%
0 / 1
110
1<?php
2
3declare(strict_types=1);
4
5namespace ImovelZapAi\Automation\Application\Actions;
6
7use Illuminate\Support\Facades\DB;
8use ImovelZapAi\Automation\Application\Services\TriggerCatalog;
9use ImovelZapAi\Automation\Domain\Enums\WorkflowStatus;
10use ImovelZapAi\Automation\Domain\Exceptions\AutomationException;
11use ImovelZapAi\Automation\Infrastructure\Persistence\Eloquent\AutomationActionModel;
12use ImovelZapAi\Automation\Infrastructure\Persistence\Eloquent\AutomationConditionModel;
13use ImovelZapAi\Automation\Infrastructure\Persistence\Eloquent\AutomationTriggerModel;
14use ImovelZapAi\Automation\Infrastructure\Persistence\Eloquent\AutomationWorkflowModel;
15
16final class UpdateWorkflowAction
17{
18    /**
19     * @param  array{
20     *     name?: string,
21     *     description?: string|null,
22     *     status?: string,
23     *     trigger?: array{event_key: string, config?: array|null},
24     *     conditions?: list<array{field: string, operator: string, value?: string|null, sort_order?: int}>,
25     *     actions?: list<array{action_key: string, config?: array|null, delay_seconds?: int, sort_order?: int}>,
26     * }  $data
27     */
28    public function execute(string $tenantId, string $workflowId, array $data): AutomationWorkflowModel
29    {
30        $workflow = AutomationWorkflowModel::query()
31            ->where('tenant_id', $tenantId)
32            ->where('id', $workflowId)
33            ->first();
34
35        if ($workflow === null) {
36            throw AutomationException::notFound('Automação');
37        }
38
39        return DB::transaction(function () use ($workflow, $tenantId, $data): AutomationWorkflowModel {
40            $workflow->forceFill(array_filter([
41                'name' => $data['name'] ?? $workflow->name,
42                'description' => array_key_exists('description', $data) ? $data['description'] : $workflow->description,
43                'status' => isset($data['status'])
44                    ? (WorkflowStatus::tryFrom($data['status']) ?? $workflow->status)
45                    : $workflow->status,
46            ], static fn ($v) => $v !== null))->save();
47
48            if (isset($data['trigger'])) {
49                $eventClass = TriggerCatalog::classForKey($data['trigger']['event_key']);
50
51                if ($eventClass === null) {
52                    throw AutomationException::invalidTrigger($data['trigger']['event_key']);
53                }
54
55                AutomationTriggerModel::query()->where('workflow_id', $workflow->id)->delete();
56                AutomationTriggerModel::query()->create([
57                    'tenant_id' => $tenantId,
58                    'workflow_id' => $workflow->id,
59                    'event_key' => $data['trigger']['event_key'],
60                    'event_class' => $eventClass,
61                    'config' => $data['trigger']['config'] ?? null,
62                ]);
63            }
64
65            if (array_key_exists('conditions', $data)) {
66                AutomationConditionModel::query()->where('workflow_id', $workflow->id)->delete();
67
68                foreach ($data['conditions'] ?? [] as $index => $condition) {
69                    AutomationConditionModel::query()->create([
70                        'tenant_id' => $tenantId,
71                        'workflow_id' => $workflow->id,
72                        'field' => $condition['field'],
73                        'operator' => $condition['operator'],
74                        'value' => $condition['value'] ?? null,
75                        'sort_order' => $condition['sort_order'] ?? $index,
76                    ]);
77                }
78            }
79
80            if (array_key_exists('actions', $data)) {
81                AutomationActionModel::query()->where('workflow_id', $workflow->id)->delete();
82
83                foreach ($data['actions'] ?? [] as $index => $action) {
84                    AutomationActionModel::query()->create([
85                        'tenant_id' => $tenantId,
86                        'workflow_id' => $workflow->id,
87                        'action_key' => $action['action_key'],
88                        'config' => $action['config'] ?? null,
89                        'delay_seconds' => (int) ($action['delay_seconds'] ?? 0),
90                        'sort_order' => $action['sort_order'] ?? $index,
91                    ]);
92                }
93            }
94
95            return $workflow->fresh(['triggers', 'conditions', 'actions']);
96        });
97    }
98}