update
This commit is contained in:
@@ -534,12 +534,17 @@ final class AutomationController
|
||||
if ($type === 'send_email') {
|
||||
$templateId = (int) ($action['template_id'] ?? 0);
|
||||
$recipient = (string) ($action['recipient'] ?? '');
|
||||
$sendOncePerOrder = isset($action['send_once_per_order']) && (int) $action['send_once_per_order'] === 1 ? 1 : 0;
|
||||
|
||||
if ($templateId <= 0 || !in_array($recipient, self::ALLOWED_RECIPIENTS, true)) {
|
||||
return null;
|
||||
}
|
||||
|
||||
return ['template_id' => $templateId, 'recipient' => $recipient];
|
||||
return [
|
||||
'template_id' => $templateId,
|
||||
'recipient' => $recipient,
|
||||
'send_once_per_order' => $sendOncePerOrder,
|
||||
];
|
||||
}
|
||||
|
||||
if ($type === 'issue_receipt') {
|
||||
|
||||
54
src/Modules/Automation/AutomationEmailOnceRepository.php
Normal file
54
src/Modules/Automation/AutomationEmailOnceRepository.php
Normal file
@@ -0,0 +1,54 @@
|
||||
<?php
|
||||
declare(strict_types=1);
|
||||
|
||||
namespace App\Modules\Automation;
|
||||
|
||||
use PDO;
|
||||
|
||||
final class AutomationEmailOnceRepository
|
||||
{
|
||||
public function __construct(private readonly PDO $pdo)
|
||||
{
|
||||
}
|
||||
|
||||
public function wasSent(int $ruleId, int $actionId, int $orderId): bool
|
||||
{
|
||||
if ($ruleId <= 0 || $actionId <= 0 || $orderId <= 0) {
|
||||
return false;
|
||||
}
|
||||
|
||||
$statement = $this->pdo->prepare(
|
||||
'SELECT 1
|
||||
FROM automation_email_once_deliveries
|
||||
WHERE rule_id = :rule_id
|
||||
AND action_id = :action_id
|
||||
AND order_id = :order_id
|
||||
LIMIT 1'
|
||||
);
|
||||
$statement->execute([
|
||||
'rule_id' => $ruleId,
|
||||
'action_id' => $actionId,
|
||||
'order_id' => $orderId,
|
||||
]);
|
||||
|
||||
return $statement->fetchColumn() !== false;
|
||||
}
|
||||
|
||||
public function markSent(int $ruleId, int $actionId, int $orderId): void
|
||||
{
|
||||
if ($ruleId <= 0 || $actionId <= 0 || $orderId <= 0) {
|
||||
return;
|
||||
}
|
||||
|
||||
$statement = $this->pdo->prepare(
|
||||
'INSERT INTO automation_email_once_deliveries (rule_id, action_id, order_id, created_at)
|
||||
VALUES (:rule_id, :action_id, :order_id, NOW())
|
||||
ON DUPLICATE KEY UPDATE created_at = created_at'
|
||||
);
|
||||
$statement->execute([
|
||||
'rule_id' => $ruleId,
|
||||
'action_id' => $actionId,
|
||||
'order_id' => $orderId,
|
||||
]);
|
||||
}
|
||||
}
|
||||
@@ -34,6 +34,7 @@ final class AutomationService
|
||||
public function __construct(
|
||||
private readonly AutomationRepository $repository,
|
||||
private readonly AutomationExecutionLogRepository $executionLogs,
|
||||
private readonly AutomationEmailOnceRepository $emailOnceRepository,
|
||||
private readonly EmailSendingService $emailService,
|
||||
private readonly OrdersRepository $orders,
|
||||
private readonly CompanySettingsRepository $companySettings,
|
||||
@@ -78,11 +79,12 @@ final class AutomationService
|
||||
$conditions = is_array($rule['conditions'] ?? null) ? $rule['conditions'] : [];
|
||||
$actions = is_array($rule['actions'] ?? null) ? $rule['actions'] : [];
|
||||
$ruleName = (string) ($rule['name'] ?? '');
|
||||
$ruleId = (int) ($rule['id'] ?? 0);
|
||||
$ruleContext = $this->withExecution($context, $executionKey);
|
||||
$ruleMatched = $this->evaluateConditions($conditions, $order, $ruleContext);
|
||||
|
||||
if ($ruleMatched) {
|
||||
$this->executeActions($actions, $orderId, $ruleName, $ruleContext);
|
||||
$this->executeActions($actions, $orderId, $ruleId, $ruleName, $ruleContext);
|
||||
$this->logExecution($eventType, $ruleId, $ruleName, $orderId, 'success', 'Wykonano akcje automatyzacji', $ruleContext);
|
||||
}
|
||||
} catch (Throwable $exception) {
|
||||
@@ -282,8 +284,14 @@ final class AutomationService
|
||||
return false;
|
||||
}
|
||||
|
||||
$newStatus = strtolower(trim((string) ($context['new_status'] ?? '')));
|
||||
if ($newStatus === '') {
|
||||
$statusCandidate = (string) ($context['new_status'] ?? '');
|
||||
if ($statusCandidate === '') {
|
||||
// order.status_aged carries "current_status" instead of "new_status"
|
||||
$statusCandidate = (string) ($context['current_status'] ?? '');
|
||||
}
|
||||
|
||||
$normalizedStatus = strtolower(trim($statusCandidate));
|
||||
if ($normalizedStatus === '') {
|
||||
return false;
|
||||
}
|
||||
|
||||
@@ -292,7 +300,7 @@ final class AutomationService
|
||||
$orderStatusCodes
|
||||
);
|
||||
|
||||
return in_array($newStatus, $normalizedCodes, true);
|
||||
return in_array($normalizedStatus, $normalizedCodes, true);
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -315,14 +323,15 @@ final class AutomationService
|
||||
* @param list<array<string, mixed>> $actions
|
||||
* @param array<string, mixed> $context
|
||||
*/
|
||||
private function executeActions(array $actions, int $orderId, string $ruleName, array $context): void
|
||||
private function executeActions(array $actions, int $orderId, int $ruleId, string $ruleName, array $context): void
|
||||
{
|
||||
foreach ($actions as $action) {
|
||||
$type = (string) ($action['action_type'] ?? '');
|
||||
$config = is_array($action['action_config'] ?? null) ? $action['action_config'] : [];
|
||||
$actionId = (int) ($action['id'] ?? 0);
|
||||
|
||||
if ($type === 'send_email') {
|
||||
$this->handleSendEmail($config, $orderId, $ruleName);
|
||||
$this->handleSendEmail($config, $orderId, $ruleId, $actionId, $ruleName);
|
||||
continue;
|
||||
}
|
||||
|
||||
@@ -345,26 +354,43 @@ final class AutomationService
|
||||
/**
|
||||
* @param array<string, mixed> $config
|
||||
*/
|
||||
private function handleSendEmail(array $config, int $orderId, string $ruleName): void
|
||||
private function handleSendEmail(array $config, int $orderId, int $ruleId, int $actionId, string $ruleName): void
|
||||
{
|
||||
$templateId = (int) ($config['template_id'] ?? 0);
|
||||
if ($templateId <= 0) {
|
||||
return;
|
||||
}
|
||||
|
||||
$sendOncePerOrder = (int) ($config['send_once_per_order'] ?? 0) === 1;
|
||||
if (
|
||||
$sendOncePerOrder
|
||||
&& $ruleId > 0
|
||||
&& $actionId > 0
|
||||
&& $this->emailOnceRepository->wasSent($ruleId, $actionId, $orderId)
|
||||
) {
|
||||
return;
|
||||
}
|
||||
|
||||
$recipient = (string) ($config['recipient'] ?? 'client');
|
||||
$actorName = 'Automatyzacja: ' . $ruleName;
|
||||
|
||||
$wasSentSuccessfully = false;
|
||||
|
||||
if ($recipient === 'client' || $recipient === 'client_and_company') {
|
||||
$this->emailService->send($orderId, $templateId, null, $actorName);
|
||||
$result = $this->emailService->send($orderId, $templateId, null, $actorName);
|
||||
$wasSentSuccessfully = $wasSentSuccessfully || (bool) ($result['success'] ?? false);
|
||||
}
|
||||
|
||||
if ($recipient === 'company' || $recipient === 'client_and_company') {
|
||||
$this->sendToCompany($orderId, $templateId, $actorName);
|
||||
$wasSentSuccessfully = $this->sendToCompany($orderId, $templateId, $actorName) || $wasSentSuccessfully;
|
||||
}
|
||||
|
||||
if ($sendOncePerOrder && $ruleId > 0 && $actionId > 0 && $wasSentSuccessfully) {
|
||||
$this->emailOnceRepository->markSent($ruleId, $actionId, $orderId);
|
||||
}
|
||||
}
|
||||
|
||||
private function sendToCompany(int $orderId, int $templateId, string $actorName): void
|
||||
private function sendToCompany(int $orderId, int $templateId, string $actorName): bool
|
||||
{
|
||||
$settings = $this->companySettings->getSettings();
|
||||
$companyEmail = trim((string) ($settings['email'] ?? ''));
|
||||
@@ -378,12 +404,12 @@ final class AutomationService
|
||||
'system',
|
||||
$actorName
|
||||
);
|
||||
return;
|
||||
return false;
|
||||
}
|
||||
|
||||
$companyName = trim((string) ($settings['company_name'] ?? ''));
|
||||
|
||||
$this->emailService->send(
|
||||
$result = $this->emailService->send(
|
||||
$orderId,
|
||||
$templateId,
|
||||
null,
|
||||
@@ -391,6 +417,8 @@ final class AutomationService
|
||||
$companyEmail,
|
||||
$companyName
|
||||
);
|
||||
|
||||
return (bool) ($result['success'] ?? false);
|
||||
}
|
||||
|
||||
/**
|
||||
|
||||
@@ -11,6 +11,7 @@ use App\Modules\Accounting\ReceiptService;
|
||||
use App\Modules\Automation\AutomationRepository;
|
||||
use App\Modules\Automation\AutomationService;
|
||||
use App\Modules\Automation\AutomationExecutionLogRepository;
|
||||
use App\Modules\Automation\AutomationEmailOnceRepository;
|
||||
use App\Modules\Automation\OrderStatusAgedService;
|
||||
use App\Modules\Email\AttachmentGenerator;
|
||||
use App\Modules\Email\EmailSendingService;
|
||||
@@ -232,6 +233,7 @@ final class CronHandlerFactory
|
||||
return new AutomationService(
|
||||
$automationRepository,
|
||||
$executionLogRepository,
|
||||
new AutomationEmailOnceRepository($this->db),
|
||||
$emailService,
|
||||
$ordersRepository,
|
||||
$companySettingsRepository,
|
||||
|
||||
Reference in New Issue
Block a user