feat(16-automated-tasks): moduł zadań automatycznych — CRUD + watcher/executor

Reguły automatyzacji oparte na zdarzeniach (receipt.created) z warunkami
(integracja/kanał sprzedaży, AND logic) i akcjami (wyślij e-mail z 3 trybami
odbiorcy: klient / firma / klient+firma). Trigger w ReceiptController po
utworzeniu paragonu — błąd automatyzacji nie blokuje sukcesu paragonu.

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
This commit is contained in:
2026-03-18 00:39:47 +01:00
parent a6512cbfa4
commit b9f639e037
24 changed files with 4997 additions and 32 deletions

View File

@@ -47,6 +47,9 @@ use App\Modules\Email\VariableResolver;
use App\Modules\Accounting\AccountingController;
use App\Modules\Accounting\ReceiptController;
use App\Modules\Accounting\ReceiptRepository;
use App\Modules\Automation\AutomationController;
use App\Modules\Automation\AutomationRepository;
use App\Modules\Automation\AutomationService;
use App\Modules\Settings\CronSettingsController;
use App\Modules\Settings\SettingsController;
use App\Modules\Shipments\ApaczkaShipmentService;
@@ -209,6 +212,13 @@ return static function (Application $app): void {
$emailTemplateRepository,
$emailMailboxRepository
);
$automationRepository = new AutomationRepository($app->db());
$automationController = new AutomationController(
$template,
$translator,
$auth,
$automationRepository
);
$variableResolver = new VariableResolver();
$attachmentGenerator = new AttachmentGenerator($receiptRepository, $receiptConfigRepository, $template);
$emailSendingService = new EmailSendingService(
@@ -219,6 +229,12 @@ return static function (Application $app): void {
$variableResolver,
$attachmentGenerator
);
$automationService = new AutomationService(
$automationRepository,
$emailSendingService,
new OrdersRepository($app->db()),
$companySettingsRepository
);
$ordersController = new OrdersController($template, $translator, $auth, $app->orders(), $shipmentPackageRepositoryForOrders, $receiptRepository, $receiptConfigRepository, $emailSendingService, $emailTemplateRepository, $emailMailboxRepository);
$receiptController = new ReceiptController(
$template,
@@ -227,7 +243,8 @@ return static function (Application $app): void {
$receiptRepository,
$receiptConfigRepository,
$companySettingsRepository,
new OrdersRepository($app->db())
new OrdersRepository($app->db()),
$automationService
);
$accountingController = new AccountingController(
$template,
@@ -356,6 +373,13 @@ return static function (Application $app): void {
$router->post('/settings/email-templates/toggle', [$emailTemplateController, 'toggleStatus'], [$authMiddleware]);
$router->post('/settings/email-templates/preview', [$emailTemplateController, 'preview'], [$authMiddleware]);
$router->get('/settings/email-templates/variables', [$emailTemplateController, 'getVariables'], [$authMiddleware]);
$router->get('/settings/automation', [$automationController, 'index'], [$authMiddleware]);
$router->get('/settings/automation/create', [$automationController, 'create'], [$authMiddleware]);
$router->post('/settings/automation/store', [$automationController, 'store'], [$authMiddleware]);
$router->get('/settings/automation/edit', [$automationController, 'edit'], [$authMiddleware]);
$router->post('/settings/automation/update', [$automationController, 'update'], [$authMiddleware]);
$router->post('/settings/automation/delete', [$automationController, 'destroy'], [$authMiddleware]);
$router->post('/settings/automation/toggle', [$automationController, 'toggleStatus'], [$authMiddleware]);
$router->get('/accounting', [$accountingController, 'index'], [$authMiddleware]);
$router->post('/accounting/export', [$accountingController, 'export'], [$authMiddleware]);
$router->get('/orders/{id}/receipt/create', [$receiptController, 'create'], [$authMiddleware]);