update
This commit is contained in:
@@ -178,7 +178,7 @@ final class ReceiptController
|
||||
'created_by' => is_array($user) ? ($user['id'] ?? null) : null,
|
||||
]);
|
||||
|
||||
$userName = is_array($user) ? (string) ($user['username'] ?? $user['email'] ?? '') : '';
|
||||
$userName = is_array($user) ? trim((string) ($user['name'] ?? $user['email'] ?? '')) : '';
|
||||
$this->orders->recordActivity(
|
||||
$orderId,
|
||||
'receipt_issued',
|
||||
|
||||
106
src/Modules/Email/AttachmentGenerator.php
Normal file
106
src/Modules/Email/AttachmentGenerator.php
Normal file
@@ -0,0 +1,106 @@
|
||||
<?php
|
||||
|
||||
declare(strict_types=1);
|
||||
|
||||
namespace App\Modules\Email;
|
||||
|
||||
use App\Core\View\Template;
|
||||
use App\Modules\Accounting\ReceiptRepository;
|
||||
use App\Modules\Settings\ReceiptConfigRepository;
|
||||
use Dompdf\Dompdf;
|
||||
|
||||
final class AttachmentGenerator
|
||||
{
|
||||
public function __construct(
|
||||
private readonly ReceiptRepository $receipts,
|
||||
private readonly ReceiptConfigRepository $receiptConfigs,
|
||||
private readonly Template $template
|
||||
) {
|
||||
}
|
||||
|
||||
/**
|
||||
* @param array<string, mixed> $order
|
||||
* @return array{filename: string, content: string, mime: string}|null
|
||||
*/
|
||||
public function generate(string $type, array $order): ?array
|
||||
{
|
||||
return match ($type) {
|
||||
'receipt' => $this->generateReceiptPdf($order),
|
||||
default => null,
|
||||
};
|
||||
}
|
||||
|
||||
/**
|
||||
* @param array<string, mixed> $order
|
||||
* @return array{filename: string, content: string, mime: string}|null
|
||||
*/
|
||||
private function generateReceiptPdf(array $order): ?array
|
||||
{
|
||||
$orderId = (int) ($order['id'] ?? 0);
|
||||
if ($orderId <= 0) {
|
||||
return null;
|
||||
}
|
||||
|
||||
$receipts = $this->receipts->findByOrderId($orderId);
|
||||
if ($receipts === []) {
|
||||
return null;
|
||||
}
|
||||
|
||||
$receipt = $receipts[0];
|
||||
$receiptId = (int) ($receipt['id'] ?? 0);
|
||||
|
||||
$fullReceipt = $this->receipts->findById($receiptId);
|
||||
if ($fullReceipt === null) {
|
||||
return null;
|
||||
}
|
||||
|
||||
$data = $this->buildReceiptViewData($fullReceipt);
|
||||
|
||||
$html = $this->template->render('receipts/print', $data);
|
||||
|
||||
$dompdf = new Dompdf();
|
||||
$dompdf->loadHtml($html);
|
||||
$dompdf->setPaper('A4');
|
||||
$dompdf->render();
|
||||
|
||||
$pdfContent = $dompdf->output();
|
||||
if ($pdfContent === null || $pdfContent === '') {
|
||||
return null;
|
||||
}
|
||||
|
||||
$filename = str_replace(['/', '\\'], '_', (string) ($fullReceipt['receipt_number'] ?? 'paragon')) . '.pdf';
|
||||
|
||||
return [
|
||||
'filename' => $filename,
|
||||
'content' => $pdfContent,
|
||||
'mime' => 'application/pdf',
|
||||
];
|
||||
}
|
||||
|
||||
/**
|
||||
* @param array<string, mixed> $receipt
|
||||
* @return array<string, mixed>
|
||||
*/
|
||||
private function buildReceiptViewData(array $receipt): array
|
||||
{
|
||||
$seller = json_decode((string) ($receipt['seller_data_json'] ?? '{}'), true);
|
||||
$buyer = ($receipt['buyer_data_json'] ?? null) !== null
|
||||
? json_decode((string) $receipt['buyer_data_json'], true)
|
||||
: null;
|
||||
$items = json_decode((string) ($receipt['items_json'] ?? '[]'), true);
|
||||
|
||||
$configName = '';
|
||||
$config = $this->receiptConfigs->findById((int) ($receipt['config_id'] ?? 0));
|
||||
if ($config !== null) {
|
||||
$configName = (string) ($config['name'] ?? '');
|
||||
}
|
||||
|
||||
return [
|
||||
'receipt' => $receipt,
|
||||
'seller' => is_array($seller) ? $seller : [],
|
||||
'buyer' => is_array($buyer) ? $buyer : null,
|
||||
'items' => is_array($items) ? $items : [],
|
||||
'configName' => $configName,
|
||||
];
|
||||
}
|
||||
}
|
||||
336
src/Modules/Email/EmailSendingService.php
Normal file
336
src/Modules/Email/EmailSendingService.php
Normal file
@@ -0,0 +1,336 @@
|
||||
<?php
|
||||
|
||||
declare(strict_types=1);
|
||||
|
||||
namespace App\Modules\Email;
|
||||
|
||||
use App\Modules\Orders\OrdersRepository;
|
||||
use App\Modules\Settings\EmailMailboxRepository;
|
||||
use App\Modules\Settings\EmailTemplateRepository;
|
||||
use PDO;
|
||||
use PHPMailer\PHPMailer\PHPMailer;
|
||||
use PHPMailer\PHPMailer\Exception as PHPMailerException;
|
||||
use RuntimeException;
|
||||
use Throwable;
|
||||
|
||||
final class EmailSendingService
|
||||
{
|
||||
public function __construct(
|
||||
private readonly PDO $pdo,
|
||||
private readonly OrdersRepository $orders,
|
||||
private readonly EmailTemplateRepository $templates,
|
||||
private readonly EmailMailboxRepository $mailboxes,
|
||||
private readonly VariableResolver $variableResolver,
|
||||
private readonly AttachmentGenerator $attachmentGenerator
|
||||
) {
|
||||
}
|
||||
|
||||
/**
|
||||
* @return array{success: bool, error: ?string, log_id: int}
|
||||
*/
|
||||
public function send(int $orderId, int $templateId, ?int $mailboxId = null, ?string $actorName = null): array
|
||||
{
|
||||
$details = $this->orders->findDetails($orderId);
|
||||
if ($details === null) {
|
||||
return ['success' => false, 'error' => 'Zamowienie nie znalezione', 'log_id' => 0];
|
||||
}
|
||||
|
||||
$order = is_array($details['order'] ?? null) ? $details['order'] : [];
|
||||
$addresses = is_array($details['addresses'] ?? null) ? $details['addresses'] : [];
|
||||
|
||||
$template = $this->templates->findById($templateId);
|
||||
if ($template === null) {
|
||||
return ['success' => false, 'error' => 'Szablon nie znaleziony', 'log_id' => 0];
|
||||
}
|
||||
|
||||
$mailbox = $this->resolveMailbox($mailboxId, $template);
|
||||
if ($mailbox === null) {
|
||||
return ['success' => false, 'error' => 'Brak skonfigurowanej skrzynki SMTP', 'log_id' => 0];
|
||||
}
|
||||
|
||||
$recipientEmail = $this->findRecipientEmail($addresses);
|
||||
if ($recipientEmail === '') {
|
||||
return ['success' => false, 'error' => 'Brak adresu e-mail kupujacego', 'log_id' => 0];
|
||||
}
|
||||
|
||||
$recipientName = $this->findRecipientName($addresses);
|
||||
$companySettings = $this->loadCompanySettings();
|
||||
|
||||
$variableMap = $this->variableResolver->buildVariableMap($order, $addresses, $companySettings);
|
||||
$resolvedSubject = $this->variableResolver->resolve((string) ($template['subject'] ?? ''), $variableMap);
|
||||
$resolvedBody = $this->variableResolver->resolve((string) ($template['body_html'] ?? ''), $variableMap);
|
||||
|
||||
$attachments = [];
|
||||
$attachmentType = (string) ($template['attachment_1'] ?? '');
|
||||
if ($attachmentType !== '') {
|
||||
$attachment = $this->attachmentGenerator->generate($attachmentType, $order);
|
||||
if ($attachment !== null) {
|
||||
$attachments[] = $attachment;
|
||||
}
|
||||
}
|
||||
|
||||
$status = 'sent';
|
||||
$errorMessage = null;
|
||||
$sentAt = null;
|
||||
|
||||
try {
|
||||
$this->sendViaSMTP($mailbox, $recipientEmail, $recipientName, $resolvedSubject, $resolvedBody, $attachments);
|
||||
$sentAt = date('Y-m-d H:i:s');
|
||||
} catch (Throwable $e) {
|
||||
$status = 'failed';
|
||||
$errorMessage = $e->getMessage();
|
||||
}
|
||||
|
||||
$logId = $this->logEmail(
|
||||
$templateId,
|
||||
(int) ($mailbox['id'] ?? 0),
|
||||
$orderId,
|
||||
$recipientEmail,
|
||||
$recipientName,
|
||||
$resolvedSubject,
|
||||
$resolvedBody,
|
||||
$attachments,
|
||||
$status,
|
||||
$errorMessage,
|
||||
$sentAt
|
||||
);
|
||||
|
||||
$templateName = (string) ($template['name'] ?? '');
|
||||
$activitySummary = $status === 'sent'
|
||||
? 'Wyslano e-mail "' . $resolvedSubject . '" do ' . $recipientEmail
|
||||
: 'Blad wysylki e-mail "' . $resolvedSubject . '" do ' . $recipientEmail . ': ' . ($errorMessage ?? '');
|
||||
$this->orders->recordActivity(
|
||||
$orderId,
|
||||
'email_' . $status,
|
||||
$activitySummary,
|
||||
['template' => $templateName, 'recipient' => $recipientEmail, 'log_id' => $logId],
|
||||
'user',
|
||||
$actorName
|
||||
);
|
||||
|
||||
return [
|
||||
'success' => $status === 'sent',
|
||||
'error' => $errorMessage,
|
||||
'log_id' => $logId,
|
||||
];
|
||||
}
|
||||
|
||||
/**
|
||||
* @return array{subject: string, body_html: string, attachments: list<string>}
|
||||
*/
|
||||
public function preview(int $orderId, int $templateId): array
|
||||
{
|
||||
$details = $this->orders->findDetails($orderId);
|
||||
if ($details === null) {
|
||||
return ['subject' => '', 'body_html' => '<p>Zamowienie nie znalezione</p>', 'attachments' => []];
|
||||
}
|
||||
|
||||
$order = is_array($details['order'] ?? null) ? $details['order'] : [];
|
||||
$addresses = is_array($details['addresses'] ?? null) ? $details['addresses'] : [];
|
||||
|
||||
$template = $this->templates->findById($templateId);
|
||||
if ($template === null) {
|
||||
return ['subject' => '', 'body_html' => '<p>Szablon nie znaleziony</p>', 'attachments' => []];
|
||||
}
|
||||
|
||||
$companySettings = $this->loadCompanySettings();
|
||||
$variableMap = $this->variableResolver->buildVariableMap($order, $addresses, $companySettings);
|
||||
$resolvedSubject = $this->variableResolver->resolve((string) ($template['subject'] ?? ''), $variableMap);
|
||||
$resolvedBody = $this->variableResolver->resolve((string) ($template['body_html'] ?? ''), $variableMap);
|
||||
|
||||
$attachmentNames = [];
|
||||
$attachmentType = (string) ($template['attachment_1'] ?? '');
|
||||
if ($attachmentType !== '') {
|
||||
$attachment = $this->attachmentGenerator->generate($attachmentType, $order);
|
||||
if ($attachment !== null) {
|
||||
$attachmentNames[] = $attachment['filename'];
|
||||
}
|
||||
}
|
||||
|
||||
return [
|
||||
'subject' => $resolvedSubject,
|
||||
'body_html' => $resolvedBody,
|
||||
'attachments' => $attachmentNames,
|
||||
];
|
||||
}
|
||||
|
||||
/**
|
||||
* @param array<string, mixed>|null $template
|
||||
* @return array<string, mixed>|null
|
||||
*/
|
||||
private function resolveMailbox(?int $mailboxId, ?array $template): ?array
|
||||
{
|
||||
if ($mailboxId !== null && $mailboxId > 0) {
|
||||
$mailbox = $this->mailboxes->findById($mailboxId);
|
||||
if ($mailbox !== null && (int) ($mailbox['is_active'] ?? 0) === 1) {
|
||||
return $mailbox;
|
||||
}
|
||||
}
|
||||
|
||||
$templateMailboxId = (int) ($template['mailbox_id'] ?? 0);
|
||||
if ($templateMailboxId > 0) {
|
||||
$mailbox = $this->mailboxes->findById($templateMailboxId);
|
||||
if ($mailbox !== null && (int) ($mailbox['is_active'] ?? 0) === 1) {
|
||||
return $mailbox;
|
||||
}
|
||||
}
|
||||
|
||||
$active = $this->mailboxes->listActive();
|
||||
foreach ($active as $m) {
|
||||
if ((int) ($m['is_default'] ?? 0) === 1) {
|
||||
return $this->mailboxes->findById((int) $m['id']);
|
||||
}
|
||||
}
|
||||
|
||||
return $active !== [] ? $this->mailboxes->findById((int) $active[0]['id']) : null;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param array<int, array<string, mixed>> $addresses
|
||||
*/
|
||||
private function findRecipientEmail(array $addresses): string
|
||||
{
|
||||
foreach (['customer', 'delivery', 'invoice'] as $type) {
|
||||
foreach ($addresses as $addr) {
|
||||
if (($addr['address_type'] ?? '') === $type) {
|
||||
$email = trim((string) ($addr['email'] ?? ''));
|
||||
if ($email !== '' && filter_var($email, FILTER_VALIDATE_EMAIL) !== false) {
|
||||
return $email;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return '';
|
||||
}
|
||||
|
||||
/**
|
||||
* @param array<int, array<string, mixed>> $addresses
|
||||
*/
|
||||
private function findRecipientName(array $addresses): string
|
||||
{
|
||||
foreach (['customer', 'delivery'] as $type) {
|
||||
foreach ($addresses as $addr) {
|
||||
if (($addr['address_type'] ?? '') === $type) {
|
||||
$name = trim((string) ($addr['name'] ?? ''));
|
||||
if ($name !== '') {
|
||||
return $name;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return '';
|
||||
}
|
||||
|
||||
/**
|
||||
* @return array<string, mixed>
|
||||
*/
|
||||
private function loadCompanySettings(): array
|
||||
{
|
||||
$stmt = $this->pdo->prepare('SELECT * FROM company_settings LIMIT 1');
|
||||
$stmt->execute();
|
||||
$row = $stmt->fetch(PDO::FETCH_ASSOC);
|
||||
|
||||
return is_array($row) ? $row : [];
|
||||
}
|
||||
|
||||
/**
|
||||
* @param array<string, mixed> $mailbox
|
||||
* @param list<array{filename: string, content: string, mime: string}> $attachments
|
||||
*/
|
||||
private function sendViaSMTP(
|
||||
array $mailbox,
|
||||
string $recipientEmail,
|
||||
string $recipientName,
|
||||
string $subject,
|
||||
string $body,
|
||||
array $attachments
|
||||
): void {
|
||||
$mail = new PHPMailer(true);
|
||||
|
||||
$mail->isSMTP();
|
||||
$mail->Host = (string) ($mailbox['smtp_host'] ?? '');
|
||||
$mail->Port = (int) ($mailbox['smtp_port'] ?? 587);
|
||||
$mail->SMTPAuth = true;
|
||||
$mail->Username = (string) ($mailbox['smtp_username'] ?? '');
|
||||
$mail->Password = (string) ($mailbox['smtp_password_decrypted'] ?? '');
|
||||
$mail->CharSet = PHPMailer::CHARSET_UTF8;
|
||||
|
||||
$encryption = (string) ($mailbox['smtp_encryption'] ?? 'tls');
|
||||
if ($encryption === 'tls') {
|
||||
$mail->SMTPSecure = PHPMailer::ENCRYPTION_STARTTLS;
|
||||
} elseif ($encryption === 'ssl') {
|
||||
$mail->SMTPSecure = PHPMailer::ENCRYPTION_SMTPS;
|
||||
} else {
|
||||
$mail->SMTPSecure = '';
|
||||
$mail->SMTPAutoTLS = false;
|
||||
}
|
||||
|
||||
$senderEmail = (string) ($mailbox['sender_email'] ?? $mailbox['smtp_username'] ?? '');
|
||||
$senderName = (string) ($mailbox['sender_name'] ?? '');
|
||||
$mail->setFrom($senderEmail, $senderName);
|
||||
$mail->addAddress($recipientEmail, $recipientName);
|
||||
|
||||
$mail->isHTML(true);
|
||||
$mail->Subject = $subject;
|
||||
$mail->Body = $body;
|
||||
|
||||
foreach ($attachments as $att) {
|
||||
$mail->addStringAttachment($att['content'], $att['filename'], PHPMailer::ENCODING_BASE64, $att['mime']);
|
||||
}
|
||||
|
||||
$mail->send();
|
||||
}
|
||||
|
||||
/**
|
||||
* @param list<array{filename: string, content: string, mime: string}> $attachments
|
||||
*/
|
||||
private function logEmail(
|
||||
int $templateId,
|
||||
int $mailboxId,
|
||||
int $orderId,
|
||||
string $recipientEmail,
|
||||
string $recipientName,
|
||||
string $subject,
|
||||
string $bodyHtml,
|
||||
array $attachments,
|
||||
string $status,
|
||||
?string $errorMessage,
|
||||
?string $sentAt
|
||||
): int {
|
||||
$attachmentsJson = [];
|
||||
foreach ($attachments as $att) {
|
||||
$attachmentsJson[] = [
|
||||
'name' => $att['filename'],
|
||||
'type' => $att['mime'],
|
||||
];
|
||||
}
|
||||
|
||||
$stmt = $this->pdo->prepare(
|
||||
'INSERT INTO email_logs (
|
||||
template_id, mailbox_id, order_id, recipient_email, recipient_name,
|
||||
subject, body_html, attachments_json, status, error_message, sent_at, created_at
|
||||
) VALUES (
|
||||
:template_id, :mailbox_id, :order_id, :recipient_email, :recipient_name,
|
||||
:subject, :body_html, :attachments_json, :status, :error_message, :sent_at, NOW()
|
||||
)'
|
||||
);
|
||||
|
||||
$stmt->execute([
|
||||
'template_id' => $templateId,
|
||||
'mailbox_id' => $mailboxId,
|
||||
'order_id' => $orderId,
|
||||
'recipient_email' => $recipientEmail,
|
||||
'recipient_name' => $recipientName,
|
||||
'subject' => $subject,
|
||||
'body_html' => $bodyHtml,
|
||||
'attachments_json' => json_encode($attachmentsJson, JSON_UNESCAPED_UNICODE),
|
||||
'status' => $status,
|
||||
'error_message' => $errorMessage,
|
||||
'sent_at' => $sentAt,
|
||||
]);
|
||||
|
||||
return (int) $this->pdo->lastInsertId();
|
||||
}
|
||||
}
|
||||
73
src/Modules/Email/VariableResolver.php
Normal file
73
src/Modules/Email/VariableResolver.php
Normal file
@@ -0,0 +1,73 @@
|
||||
<?php
|
||||
|
||||
declare(strict_types=1);
|
||||
|
||||
namespace App\Modules\Email;
|
||||
|
||||
final class VariableResolver
|
||||
{
|
||||
/**
|
||||
* @param array<string, mixed> $order
|
||||
* @param array<int, array<string, mixed>> $addresses
|
||||
* @param array<string, mixed> $companySettings
|
||||
* @return array<string, string>
|
||||
*/
|
||||
public function buildVariableMap(array $order, array $addresses, array $companySettings): array
|
||||
{
|
||||
$customerAddress = $this->findAddress($addresses, 'customer');
|
||||
$deliveryAddress = $this->findAddress($addresses, 'delivery') ?? $customerAddress;
|
||||
|
||||
$buyerName = (string) ($customerAddress['name'] ?? '');
|
||||
$buyerEmail = (string) ($customerAddress['email'] ?? '');
|
||||
$buyerPhone = (string) ($customerAddress['phone'] ?? '');
|
||||
|
||||
$totalFormatted = number_format((float) ($order['total_with_tax'] ?? 0), 2, ',', ' ');
|
||||
$orderedAt = (string) ($order['ordered_at'] ?? '');
|
||||
if ($orderedAt !== '' && ($ts = strtotime($orderedAt)) !== false) {
|
||||
$orderedAt = date('Y-m-d', $ts);
|
||||
}
|
||||
|
||||
return [
|
||||
'zamowienie.numer' => (string) ($order['internal_order_number'] ?? $order['id'] ?? ''),
|
||||
'zamowienie.numer_zewnetrzny' => (string) ($order['external_order_id'] ?? $order['source_order_id'] ?? ''),
|
||||
'zamowienie.zrodlo' => ucfirst((string) ($order['source'] ?? '')),
|
||||
'zamowienie.kwota' => $totalFormatted,
|
||||
'zamowienie.waluta' => (string) ($order['currency'] ?? 'PLN'),
|
||||
'zamowienie.data' => $orderedAt,
|
||||
'kupujacy.imie_nazwisko' => $buyerName,
|
||||
'kupujacy.email' => $buyerEmail,
|
||||
'kupujacy.telefon' => $buyerPhone,
|
||||
'kupujacy.login' => (string) ($order['customer_login'] ?? ''),
|
||||
'adres.ulica' => trim(($deliveryAddress['street_name'] ?? '') . ' ' . ($deliveryAddress['street_number'] ?? '')),
|
||||
'adres.miasto' => (string) ($deliveryAddress['city'] ?? ''),
|
||||
'adres.kod_pocztowy' => (string) ($deliveryAddress['zip_code'] ?? ''),
|
||||
'adres.kraj' => (string) ($deliveryAddress['country'] ?? ''),
|
||||
'firma.nazwa' => (string) ($companySettings['company_name'] ?? ''),
|
||||
'firma.nip' => (string) ($companySettings['tax_number'] ?? ''),
|
||||
];
|
||||
}
|
||||
|
||||
public function resolve(string $template, array $variableMap): string
|
||||
{
|
||||
return preg_replace_callback(
|
||||
'/\{\{([a-z_]+\.[a-z_]+)\}\}/',
|
||||
static fn(array $m): string => $variableMap[$m[1]] ?? '',
|
||||
$template
|
||||
) ?? $template;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param array<int, array<string, mixed>> $addresses
|
||||
* @return array<string, mixed>|null
|
||||
*/
|
||||
private function findAddress(array $addresses, string $type): ?array
|
||||
{
|
||||
foreach ($addresses as $addr) {
|
||||
if (($addr['address_type'] ?? '') === $type) {
|
||||
return $addr;
|
||||
}
|
||||
}
|
||||
|
||||
return null;
|
||||
}
|
||||
}
|
||||
@@ -12,6 +12,9 @@ use App\Core\Support\Flash;
|
||||
use App\Core\Support\StringHelper;
|
||||
use App\Modules\Accounting\ReceiptRepository;
|
||||
use App\Modules\Auth\AuthService;
|
||||
use App\Modules\Email\EmailSendingService;
|
||||
use App\Modules\Settings\EmailMailboxRepository;
|
||||
use App\Modules\Settings\EmailTemplateRepository;
|
||||
use App\Modules\Settings\ReceiptConfigRepository;
|
||||
use App\Modules\Shipments\ShipmentPackageRepository;
|
||||
|
||||
@@ -24,7 +27,10 @@ final class OrdersController
|
||||
private readonly OrdersRepository $orders,
|
||||
private readonly ?ShipmentPackageRepository $shipmentPackages = null,
|
||||
private readonly ?ReceiptRepository $receiptRepo = null,
|
||||
private readonly ?ReceiptConfigRepository $receiptConfigRepo = null
|
||||
private readonly ?ReceiptConfigRepository $receiptConfigRepo = null,
|
||||
private readonly ?EmailSendingService $emailService = null,
|
||||
private readonly ?EmailTemplateRepository $emailTemplateRepo = null,
|
||||
private readonly ?EmailMailboxRepository $emailMailboxRepo = null
|
||||
) {
|
||||
}
|
||||
|
||||
@@ -178,6 +184,9 @@ final class OrdersController
|
||||
);
|
||||
}
|
||||
|
||||
$emailTemplates = $this->emailTemplateRepo !== null ? $this->emailTemplateRepo->listActive() : [];
|
||||
$emailMailboxes = $this->emailMailboxRepo !== null ? $this->emailMailboxRepo->listActive() : [];
|
||||
|
||||
$flashSuccess = (string) Flash::get('order.success', '');
|
||||
$flashError = (string) Flash::get('order.error', '');
|
||||
|
||||
@@ -206,6 +215,8 @@ final class OrdersController
|
||||
'flashError' => $flashError,
|
||||
'receipts' => $receipts,
|
||||
'receiptConfigs' => $activeReceiptConfigs,
|
||||
'emailTemplates' => $emailTemplates,
|
||||
'emailMailboxes' => $emailMailboxes,
|
||||
], 'layouts/app');
|
||||
|
||||
return Response::html($html);
|
||||
@@ -676,4 +687,51 @@ final class OrdersController
|
||||
return $entry;
|
||||
}, $history);
|
||||
}
|
||||
|
||||
public function sendEmail(Request $request): Response
|
||||
{
|
||||
$orderId = max(0, (int) $request->input('id', 0));
|
||||
if ($orderId <= 0) {
|
||||
return Response::json(['success' => false, 'message' => 'Nieprawidlowe zamowienie'], 400);
|
||||
}
|
||||
|
||||
$csrfToken = (string) $request->input('_token', '');
|
||||
if (!Csrf::validate($csrfToken)) {
|
||||
return Response::json(['success' => false, 'message' => 'Sesja wygasla, odswiez strone'], 403);
|
||||
}
|
||||
|
||||
if ($this->emailService === null) {
|
||||
return Response::json(['success' => false, 'message' => 'Modul e-mail nie jest skonfigurowany'], 500);
|
||||
}
|
||||
|
||||
$templateId = max(0, (int) $request->input('template_id', 0));
|
||||
if ($templateId <= 0) {
|
||||
return Response::json(['success' => false, 'message' => 'Wybierz szablon'], 400);
|
||||
}
|
||||
|
||||
$mailboxId = (int) $request->input('mailbox_id', 0);
|
||||
$user = $this->auth->user();
|
||||
$userName = is_array($user) ? trim((string) ($user['name'] ?? $user['email'] ?? '')) : '';
|
||||
$result = $this->emailService->send($orderId, $templateId, $mailboxId > 0 ? $mailboxId : null, $userName !== '' ? $userName : null);
|
||||
|
||||
return Response::json([
|
||||
'success' => $result['success'],
|
||||
'message' => $result['success'] ? 'E-mail wyslany pomyslnie' : ('Blad wysylki: ' . ($result['error'] ?? 'nieznany')),
|
||||
]);
|
||||
}
|
||||
|
||||
public function emailPreview(Request $request): Response
|
||||
{
|
||||
$orderId = max(0, (int) $request->input('id', 0));
|
||||
$templateId = max(0, (int) $request->input('template_id', 0));
|
||||
|
||||
if ($orderId <= 0 || $templateId <= 0 || $this->emailService === null) {
|
||||
return Response::json(['subject' => '', 'body_html' => '', 'attachments' => []], 400);
|
||||
}
|
||||
|
||||
$preview = $this->emailService->preview($orderId, $templateId);
|
||||
|
||||
return Response::json($preview);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@@ -95,8 +95,13 @@ final class OrdersRepository
|
||||
|
||||
$search = trim((string) ($filters['search'] ?? ''));
|
||||
if ($search !== '') {
|
||||
$where[] = '(o.source_order_id LIKE :search OR o.external_order_id LIKE :search OR o.customer_login LIKE :search OR a.name LIKE :search OR a.email LIKE :search)';
|
||||
$params['search'] = '%' . $search . '%';
|
||||
$where[] = '(o.source_order_id LIKE :s1 OR o.external_order_id LIKE :s2 OR o.customer_login LIKE :s3 OR a.name LIKE :s4 OR a.email LIKE :s5)';
|
||||
$searchVal = '%' . $search . '%';
|
||||
$params['s1'] = $searchVal;
|
||||
$params['s2'] = $searchVal;
|
||||
$params['s3'] = $searchVal;
|
||||
$params['s4'] = $searchVal;
|
||||
$params['s5'] = $searchVal;
|
||||
}
|
||||
|
||||
$source = trim((string) ($filters['source'] ?? ''));
|
||||
|
||||
Reference in New Issue
Block a user