493 lines
17 KiB
PHP
493 lines
17 KiB
PHP
<?php
|
|
|
|
namespace KupShop\KupShopBundle\Email;
|
|
|
|
use KupShop\KupShopBundle\Context\ContextManager;
|
|
use KupShop\KupShopBundle\Context\LanguageContext;
|
|
use KupShop\KupShopBundle\Query\JsonOperator;
|
|
use KupShop\KupShopBundle\Util\Compat\ServiceContainer;
|
|
use KupShop\KupShopBundle\Util\Mail\Microdata;
|
|
use KupShop\OrderingBundle\Attachment\InvoicePDFAttachment;
|
|
use KupShop\OrderingBundle\Util\Attachment\AttachmentLocator;
|
|
use KupShop\OrderingBundle\Util\Order\OrderInfo;
|
|
use KupShop\SellerBundle\Utils\SellerOrderUtil;
|
|
use Query\Operator;
|
|
use Symfony\Component\Routing\Router;
|
|
use Symfony\Contracts\Service\Attribute\Required;
|
|
|
|
class OrderEmail extends BaseEmail
|
|
{
|
|
protected static $name = 'Komentář k objednávce';
|
|
protected static $type = 'ORDER_COMMENT';
|
|
protected static $group = EmailGroupTypeEnum::ORDER;
|
|
protected static $priority = 8;
|
|
|
|
protected $subject = 'Důležitá informace k objednávce {KOD}';
|
|
protected $template = 'email/email_order_comment.tpl';
|
|
protected $baseTemplate = 'email/order.tpl';
|
|
|
|
protected $logSentEmail = true;
|
|
protected bool $isAdminEmail = false;
|
|
protected ?bool $sendToInvoiceCopyEmail = null; // null: default, true: always, false: never
|
|
protected $order_message;
|
|
/** @var AttachmentLocator */
|
|
private $attachmentLocator;
|
|
|
|
/** @var ContextManager */
|
|
protected $contextManager;
|
|
|
|
public function __construct(
|
|
protected OrderInfo $orderInfo,
|
|
protected Microdata $microdataUtil,
|
|
LanguageContext $languageContext,
|
|
) {
|
|
parent::__construct($languageContext);
|
|
}
|
|
|
|
public static string $type_test_email = 'orders';
|
|
|
|
public static function attachmentsAllowed()
|
|
{
|
|
return true;
|
|
}
|
|
|
|
/**
|
|
* @required
|
|
*/
|
|
public function setAttachmentLocator(AttachmentLocator $attachmentLocator)
|
|
{
|
|
$this->attachmentLocator = $attachmentLocator;
|
|
}
|
|
|
|
/** @required */
|
|
public function setContextManager(ContextManager $contextManager)
|
|
{
|
|
$this->contextManager = $contextManager;
|
|
}
|
|
|
|
/** @var \Order */
|
|
protected $order;
|
|
|
|
public function setOrder(\Order $order)
|
|
{
|
|
$this->order = $order;
|
|
|
|
return $this;
|
|
}
|
|
|
|
public function getOrder()
|
|
{
|
|
return $this->order;
|
|
}
|
|
|
|
protected $comment;
|
|
|
|
public function setComment($comment)
|
|
{
|
|
$this->comment = $comment;
|
|
|
|
return $this;
|
|
}
|
|
|
|
public function setIsAdminEmail(bool $isAdminEmail): self
|
|
{
|
|
$this->isAdminEmail = $isAdminEmail;
|
|
|
|
return $this;
|
|
}
|
|
|
|
public function setSendToInvoiceCopyEmail(?bool $sendToInvoiceCopyEmail): self
|
|
{
|
|
$this->sendToInvoiceCopyEmail = $sendToInvoiceCopyEmail;
|
|
|
|
return $this;
|
|
}
|
|
|
|
public function getEmailTemplate($languageID = null): array
|
|
{
|
|
if (!$languageID && $this->order) {
|
|
$languageID = $this->order->id_language;
|
|
}
|
|
|
|
return parent::getEmailTemplate($languageID);
|
|
}
|
|
|
|
/**
|
|
* @return array
|
|
*/
|
|
public function getBasicTemplate($languageID = null)
|
|
{
|
|
if (!$languageID && $this->order) {
|
|
$languageID = $this->order->id_language;
|
|
}
|
|
|
|
return parent::getBasicTemplate($languageID);
|
|
}
|
|
|
|
public function renderEmail($template, $data = [], $base_template = 'order.tpl'): array
|
|
{
|
|
if ($this->comment) {
|
|
$template['body'] = str_replace('{KOMENTAR}', $this->comment, $template['body']);
|
|
}
|
|
|
|
if ($this->order) {
|
|
$data = array_merge($data, ['order' => $this->order]);
|
|
}
|
|
|
|
$message = parent::renderEmail($template, $data, $base_template);
|
|
if ($this->order) {
|
|
$message['to'] = $this->order->getUserEmail();
|
|
if ($this->shouldSendCopyEmail($template['attachments'])) {
|
|
if ($copyEmail = $this->order->getCopyEmail()) {
|
|
$message['cc'] = $copyEmail;
|
|
}
|
|
}
|
|
}
|
|
|
|
$message['template'] = $template;
|
|
|
|
return $message;
|
|
}
|
|
|
|
public function replacePlaceholdersItem($placeholder)
|
|
{
|
|
switch ($placeholder) {
|
|
case 'DATUM_DORUCENI':
|
|
$delivery_date = $this->orderInfo->getDeliveryDate($this->order);
|
|
if (!$delivery_date) {
|
|
// produkt neni skladem a nevime kdy bude => nemuzeme napsat datum doruceni
|
|
return translate_shop('unknownDeliveryDate', 'order');
|
|
}
|
|
|
|
return $delivery_date->format(\Settings::getDateFormat());
|
|
|
|
case 'POLOZKY_EXCEL':
|
|
return path('kupshop_orderingbundle_xlsinvoice', ['id_order' => $this->order->id, 'cf' => $this->order->getSecurityCode()], Router::ABSOLUTE_URL);
|
|
case 'ODKAZ_FAKTURA':
|
|
// spousta shopu ma tenhle placeholder pridany custom na shopu v class.Order.php, takze nejdriv to zkusim vytahnout
|
|
// pres order a pokud to existuje, tak vratim to kvuli backward compatibility
|
|
if ($result = $this->order->replacePlaceholdersItem($placeholder)) {
|
|
return $result;
|
|
}
|
|
|
|
return path(
|
|
'kupshop_orderingbundle_pdfinvoice',
|
|
[
|
|
'id_order' => $this->order->id,
|
|
'cf' => $this->order->getSecurityCode(),
|
|
],
|
|
Router::ABSOLUTE_URL
|
|
);
|
|
case 'BALIKY':
|
|
// could be more than one package
|
|
$packages = [];
|
|
foreach ($this->orderInfo->getPackages($this->order) as $package_id => $package) {
|
|
if ($link = $package['track_url'] ?? null) {
|
|
$packages[] = "<a href=\"{$link}\">{$package_id}</a>";
|
|
} else {
|
|
$packages[] = $package_id;
|
|
}
|
|
}
|
|
|
|
return implode(', ', $packages);
|
|
|
|
case 'TELEFON_FAKTURACNI':
|
|
return $this->order->invoice_phone;
|
|
|
|
case 'TELEFON_DODACI':
|
|
return $this->order->delivery_phone;
|
|
|
|
case 'MISTO_ODBERU':
|
|
$value = '';
|
|
$deliveryType = $this->order->getDeliveryType();
|
|
|
|
// vracim udaje jen kdy je typ doruceni POINT
|
|
if ($deliveryType->delivery_class->getType() == \DeliveryBase::TYPE_POINT) {
|
|
$value = $deliveryType->getDelivery()->name.': '.$deliveryType->getDelivery()->printDeliveryInfo();
|
|
}
|
|
|
|
return $value;
|
|
|
|
case 'URL_PRODEJCE':
|
|
$value = '';
|
|
$deliveryType = $this->order->getDeliveryType();
|
|
|
|
// vracim udaje jen kdyz je typ doruceni IN_PERSON
|
|
if ($deliveryType->delivery_class->getType() == \DeliveryBase::TYPE_IN_PERSON) {
|
|
if ($sellerId = SellerOrderUtil::getOrderSellerId($this->order->id)) {
|
|
$value = path('shop_seller_seller_detail', ['id_seller' => $sellerId]);
|
|
}
|
|
}
|
|
|
|
return $value;
|
|
|
|
case 'JMENO':
|
|
return $this->order->invoice_name;
|
|
case 'PRIJMENI':
|
|
return $this->order->invoice_surname;
|
|
}
|
|
|
|
$parent = parent::replacePlaceholdersItem($placeholder);
|
|
if ($parent === null) {
|
|
return $this->order->replacePlaceholdersItem($placeholder);
|
|
}
|
|
|
|
return $parent;
|
|
}
|
|
|
|
public function getAttachments($template): array
|
|
{
|
|
if (empty($template['attachments']) || !$this->order) {
|
|
return [];
|
|
}
|
|
|
|
return $this->renderAttachments(function () use ($template): iterable {
|
|
$types = json_decode($template['attachments'], true);
|
|
|
|
foreach ($types as $type) {
|
|
$attachment = $this->attachmentLocator->getServiceByType($type, $this->order);
|
|
yield $attachment;
|
|
}
|
|
});
|
|
}
|
|
|
|
public function testEmail(): array
|
|
{
|
|
if (!isset($this->order)) {
|
|
$this->setTestEntity();
|
|
}
|
|
$this->order->setPlaceholder('KOMENTAR', '<p>Testovací komentář od uživatele.</p>');
|
|
|
|
try {
|
|
return $this->contextManager->activateOrder(
|
|
$this->order,
|
|
function () {
|
|
return parent::testEmail();
|
|
}
|
|
);
|
|
} catch (\Throwable $e) {
|
|
throw new \InvalidArgumentException('E-mail nelze otestovat, protože neexistuje žádná objednávka', previous: $e);
|
|
}
|
|
}
|
|
|
|
public function setTestEntity(?int $id = null): void
|
|
{
|
|
$order = new \Order();
|
|
$order->createFromDB($id ?: sqlQueryBuilder()->select('MAX(id)')->from('orders')->execute()->fetchOne());
|
|
$this->setOrder($order);
|
|
}
|
|
|
|
public function sendEmail($message, $logComment = null)
|
|
{
|
|
// pokud je email vypnutej, tak nedava smysl logovat odeslani mailu
|
|
if ($this->isEnabled()) {
|
|
$this->logHistory($message, $logComment);
|
|
}
|
|
|
|
if (($bcc = (\Settings::getDefault()->archive_email ?? null)) && $bcc !== ($message['to'] ?? null)) {
|
|
$message['bcc'] = [$bcc];
|
|
}
|
|
|
|
$messageId = parent::sendEmail($message);
|
|
|
|
if ($messageId && !empty($message['id_history'])) {
|
|
// update orders_history with email ID
|
|
sqlQueryBuilder()->update('orders_history')
|
|
->set('custom_data', JsonOperator::set('custom_data', 'email_id', $messageId))
|
|
->where(Operator::equals(['id' => $message['id_history']]))
|
|
->execute();
|
|
}
|
|
|
|
return $messageId;
|
|
}
|
|
|
|
protected function logHistory(&$message, $comment = null)
|
|
{
|
|
$historyId = null;
|
|
$notifiedStatus = $this->isAdminEmail ? 0 : 4;
|
|
if ($this->logSentEmail && $this->order) {
|
|
$template = $message['template'];
|
|
$customData['email_type'] = self::getType();
|
|
if (self::getType() == 'ORDER_MESSAGE') {
|
|
$customData['email_type'] = 'Zprávy uživatelům: '.$this->order_message;
|
|
}
|
|
$customData['subject'] = $message['subject'];
|
|
$customData['isAdminEmail'] = $this->isAdminEmail;
|
|
|
|
if ($template['attachments']) {
|
|
// get attachments types because of saving them into history
|
|
$types = json_decode($template['attachments'], true);
|
|
$customData['attachments'] = empty($types) ? null : $types;
|
|
}
|
|
|
|
// Renders only body from email to $comment
|
|
if (is_null($comment)) {
|
|
$comment = $this->renderOnlyBody($message, ['order' => $this->order]);
|
|
}
|
|
|
|
// Write history
|
|
$comment = $this->replacePlaceholders($comment);
|
|
$historyId = $this->order->logHistory($comment, $notifiedStatus, $customData);
|
|
}
|
|
|
|
$message['isAdminEmail'] = $this->isAdminEmail;
|
|
$message['id_history'] = $historyId;
|
|
}
|
|
|
|
public static function getPlaceholders()
|
|
{
|
|
$placeholders = [
|
|
'KOD' => [
|
|
'text' => translate('OrderCode', 'emails'),
|
|
],
|
|
'STAV' => [
|
|
'text' => translate('NewOrderStatus', 'emails'),
|
|
],
|
|
'CENA' => [
|
|
'text' => translate('OrderPrice', 'emails'),
|
|
],
|
|
'ZAPLATIT' => [
|
|
'text' => translate('RemainsPaid', 'emails'),
|
|
],
|
|
'ODKAZ' => [
|
|
'text' => translate('ReferenceDetail', 'emails'),
|
|
],
|
|
'ODKAZ_PLATBA' => [
|
|
'text' => translate('ReferencePayment', 'emails'),
|
|
],
|
|
'DATUM_OBJEDNAVKY' => [
|
|
'text' => translate('OrderDate', 'emails'),
|
|
],
|
|
'CAS_OBJEDNAVKY' => [
|
|
'text' => translate('OrderTime', 'emails'),
|
|
],
|
|
'JMENO' => [
|
|
'text' => translate('UserName', 'emails'),
|
|
],
|
|
'PRIJMENI' => [
|
|
'text' => translate('UserSurname', 'emails'),
|
|
],
|
|
'OSLOVENI_JMENO' => [
|
|
'text' => translate('GreetingUserName', 'emails'),
|
|
],
|
|
'OSLOVENI_PRIJMENI' => [
|
|
'text' => translate('GreetingUserSurname', 'emails'),
|
|
],
|
|
'EMAIL_UZIVATELE' => [
|
|
'text' => translate('UsersEmail', 'emails'),
|
|
],
|
|
'KOMENTAR' => [
|
|
'text' => translate('CommentEntered', 'emails'),
|
|
],
|
|
'POLOZKY_OBJEDNAVKY' => [
|
|
'text' => translate('ListOfItems', 'emails'),
|
|
],
|
|
'QR_PLATBA' => [
|
|
'text' => translate('qrcodePayment', 'emails'),
|
|
],
|
|
'DATUM_SPLATNOSTI' => [
|
|
'text' => translate('dueDate', 'emails'),
|
|
],
|
|
'FAKTURACNI_ADRESA' => [
|
|
'text' => translate('invoiceAddress', 'emails'),
|
|
],
|
|
'DODACI_ADRESA' => [
|
|
'text' => translate('deliveryAddress', 'emails'),
|
|
],
|
|
'POZNAMKA_UZIVATELE' => [
|
|
'text' => translate('userNote', 'emails'),
|
|
],
|
|
'POLOZKY_EXCEL' => [
|
|
'text' => translate('invoice_xls', 'emails'),
|
|
],
|
|
'ODKAZ_FAKTURA' => [
|
|
'text' => translate('invoice_pdf', 'emails'),
|
|
],
|
|
'BALIKY' => [
|
|
'text' => translate('LinkToWebpage', 'emails'),
|
|
],
|
|
'CISLO_FAKTURY' => [
|
|
'text' => translate('invoice_no', 'emails'),
|
|
],
|
|
];
|
|
|
|
if (findModule(\Modules::DELIVERY_TYPES)) {
|
|
$placeholders['POPIS_ZPUSOBU_DORUCENI'] = [
|
|
'text' => translate('DescriptionOfSelected', 'emails').'
|
|
<a href="launch.php?s=main.php&l=s:menu.php|type:delivery&r=s:list.php|type:delivery"
|
|
target="_blank">'.translate('DescriptionOfSelectedLink', 'emails').'</a>',
|
|
];
|
|
$placeholders['POPIS_PLATBY'] = [
|
|
'text' => translate('DescriptionOfSelectedPay', 'emails').'
|
|
<a href="launch.php?s=main.php&l=s:menu.php|type:deliveryPayment&r=s:list.php|type:deliveryPayment"
|
|
target="_blank">'.translate('DescriptionOfSelectedPayLink', 'emails').'</a>',
|
|
];
|
|
$placeholders['POPIS_DOPRAVY'] = [
|
|
'text' => translate('DescriptionOfSelectedPay', 'emails').'
|
|
<a href="launch.php?s=main.php&l=s:menu.php|type:deliveryDelivery&r=s:list.php|type:deliveryDelivery"
|
|
target="_blank">'.translate('DescriptionOfSelectedTransport', 'emails').'</a>',
|
|
];
|
|
}
|
|
|
|
$placeholders['DATUM_DORUCENI'] = ['text' => translate('deliveryDate', 'emails')];
|
|
|
|
if (findModule(\Modules::BONUS_PROGRAM)) {
|
|
$placeholders['BONUS_PROGRAM_BODY'] = [
|
|
'text' => translate('bonusProgramPoints', 'emails'),
|
|
];
|
|
|
|
$placeholders['ZBYVAJICI_BONUS_PROGRAM_BODY'] = [
|
|
'text' => translate('bonusProgramPointsRemaining', 'emails'),
|
|
];
|
|
}
|
|
|
|
$placeholders['TELEFON_FAKTURACNI'] = ['text' => translate('invoicePhone', 'emails')];
|
|
|
|
$placeholders['TELEFON_DODACI'] = ['text' => translate('deliveryPhone', 'emails')];
|
|
|
|
$placeholders['MISTO_ODBERU'] = ['text' => translate('deliveryLocation', 'emails')];
|
|
|
|
$placeholders['URL_PRODEJCE'] = ['text' => translate('sellerUrl', 'emails')];
|
|
|
|
return [self::$type => $placeholders] + (parent::getPlaceholders() ?? []);
|
|
}
|
|
|
|
public function getMicrodata(): array
|
|
{
|
|
if ($order = $this->getOrder()) {
|
|
try {
|
|
return $this->microdataUtil->getOrderMicrodata($order);
|
|
} catch (\Throwable $exception) {
|
|
\Sentry\captureException($exception);
|
|
}
|
|
}
|
|
|
|
return [];
|
|
}
|
|
|
|
public function __wakeup()
|
|
{
|
|
parent::__wakeup();
|
|
|
|
$this->attachmentLocator = ServiceContainer::getService(AttachmentLocator::class);
|
|
$this->contextManager = ServiceContainer::getService(ContextManager::class);
|
|
$this->orderInfo = ServiceContainer::getService(OrderInfo::class);
|
|
$this->microdataUtil = ServiceContainer::getService(Microdata::class);
|
|
}
|
|
|
|
public function __sleep()
|
|
{
|
|
return array_diff(parent::__sleep(), ['attachmentLocator', 'contextManager', 'orderInfo', 'microdataUtil']);
|
|
}
|
|
|
|
public function getTestType(): ?string
|
|
{
|
|
return self::$type_test_email;
|
|
}
|
|
|
|
public function shouldSendCopyEmail($attachments): bool
|
|
{
|
|
return $this->sendToInvoiceCopyEmail ?? in_array(InvoicePDFAttachment::getType(), json_decode($attachments ?? '', true) ?? []);
|
|
}
|
|
}
|