Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

[API] Order confirmation email sending #11754

Merged
merged 7 commits into from
Nov 16, 2020
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
Expand Up @@ -11,15 +11,15 @@ Feature: Receiving confirmation email after finalizing checkout
And the store ships everywhere for free
And the store allows paying offline

@ui @email
@ui @email @api
Scenario: Receiving confirmation email after finalizing checkout
Given I have product "Sig Sauer P226" in the cart
And I have completed addressing step with email "john@example.com" and "United States" based billing address
And I have proceeded order with "Free" shipping method and "Offline" payment
When I confirm my order
Then an email with the summary of order placed by "john@example.com" should be sent to him

@ui @email
@ui @email @api
Scenario: Receiving confirmation email after finalizing checkout in different locale than the default one
Given I have product "Sig Sauer P226" in the cart
And I have proceeded through checkout process in the "Polish (Poland)" locale with email "john@example.com"
Expand Down
45 changes: 38 additions & 7 deletions src/Sylius/Behat/Context/Setup/CheckoutContext.php
Original file line number Diff line number Diff line change
Expand Up @@ -64,6 +64,26 @@ public function __construct(
$this->sharedStorage = $sharedStorage;
}

/**
* @Given I have proceeded through checkout process in the :localeCode locale with email :email
*/
public function iHaveProceededThroughCheckoutProcessInTheLocaleWithEmail(string $localeCode, string $email)
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Suggested change
public function iHaveProceededThroughCheckoutProcessInTheLocaleWithEmail(string $localeCode, string $email)
public function iHaveProceededThroughCheckoutProcessInTheLocaleWithEmail(string $localeCode, string $email): void

{
$cartToken = $this->sharedStorage->get('cart_token');

/** @var OrderInterface|null $cart */
$cart = $this->orderRepository->findCartByTokenValue($cartToken);
Assert::notNull($cart);

$cart->setLocaleCode($localeCode);

$command = new AddressOrder($email, $this->getDefaultAddress());
$command->setOrderTokenValue($cartToken);
$this->commandBus->dispatch($command);

$this->completeCheckout($cart);
}

/**
* @Given I have proceeded through checkout process
*/
Expand All @@ -75,33 +95,44 @@ public function iHaveProceededThroughCheckoutProcess(): void
$cart = $this->orderRepository->findCartByTokenValue($cartToken);
Assert::notNull($cart);

$command = new AddressOrder('rich@sylius.com', $this->getDefaultAddress());
$command->setOrderTokenValue($cartToken);
$this->commandBus->dispatch($command);

$this->completeCheckout($cart);
}

private function getDefaultAddress(): AddressInterface
{
/** @var AddressInterface $address */
$address = $this->addressFactory->createNew();

$address->setCity('New York');
$address->setStreet('Wall Street');
$address->setPostcode('00-001');
$address->setCountryCode('US');
$address->setFirstName('Richy');
$address->setLastName('Rich');

$command = new AddressOrder('rich@sylius.com', $address);
$command->setOrderTokenValue($cartToken);
$this->commandBus->dispatch($command);
return $address;
}

private function completeCheckout(OrderInterface $order): void
{
$command = new ChooseShippingMethod($this->shippingMethodRepository->findOneBy([])->getCode());
$command->setOrderTokenValue($cartToken);
$command->setOrderTokenValue($order->getTokenValue());

/** @var ShipmentInterface $shipment */
$shipment = $cart->getShipments()->first();
$shipment = $order->getShipments()->first();

$command->setSubresourceId((string) $shipment->getId());
$this->commandBus->dispatch($command);

$command = new ChoosePaymentMethod($this->paymentMethodRepository->findOneBy([])->getCode());
$command->setOrderTokenValue($cartToken);
$command->setOrderTokenValue($order->getTokenValue());

/** @var PaymentInterface $payment */
$payment = $cart->getPayments()->first();
$payment = $order->getPayments()->first();
$command->setSubresourceId((string) $payment->getId());

$this->commandBus->dispatch($command);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -29,6 +29,8 @@ default:
- sylius.behat.context.setup.admin_user
- sylius.behat.context.setup.cart
- sylius.behat.context.setup.channel
- sylius.behat.context.setup.checkout
- sylius.behat.context.setup.geographical
- sylius.behat.context.setup.customer
- sylius.behat.context.setup.geographical
- sylius.behat.context.setup.locale
Expand All @@ -49,5 +51,7 @@ default:
- sylius.behat.context.api.shop.login
- sylius.behat.context.api.shop.order

- sylius.behat.context.ui.email

filters:
tags: "@checkout && @api"
Original file line number Diff line number Diff line change
@@ -1,28 +1 @@
{% block body %}
{% autoescape false %}
{% set logo = channel.hostname is not null ? 'http://' ~ channel.hostname ~ asset('assets/admin/img/logo.png') : absolute_url(asset('assets/admin/img/logo.png')) %}

<div style="font-family: sans-serif; background: #eee; padding-top: 30px; padding-bottom: 30px; font-size: 16px; color: #333; line-height: 1.5">
<div style="max-width: 600px; margin: 20px auto;">
<div style="margin-bottom: 30px; text-align: center;">
{% if sylius_bundle_loaded_checker('SyliusShopBundle') %}
{% set url = channel.hostname is not null ? 'http://' ~ channel.hostname ~ path('sylius_shop_homepage', {'_locale': localeCode}) : url('sylius_shop_homepage', {'_locale': localeCode}) %}
<a href="{{ url|raw }}">
<img src="{{ logo }}" alt="Sylius" style="width: 170px">
</a>
{% else %}
<img src="{{ logo }}" alt="Sylius" style="width: 170px">
{% endif %}
</div>

<div style="background: #fff; padding: 40px 30px;">
{% block content %}{% endblock %}
</div>

<div style="text-align: center; padding: 20px 0;">
<a href="https://sylius.com" target="_blank" style="color: #1abb9c; text-decoration: none;">sylius.com</a>
</div>
</div>
</div>
{% endautoescape %}
{% endblock %}
{% extends '@SyliusCore/Email/layout.html.twig' %}
Original file line number Diff line number Diff line change
@@ -1,29 +1,10 @@
{% deprecated 'The "@SyliusAdmin/Email/orderConfirmation.html.twig" template is deprecated since Sylius 1.8 and will be removed in Sylius 2.0, use "@SyliusCore/Email/layout.html.twig" instead.' %}
{% extends '@SyliusAdmin/Email/layout.html.twig' %}

{% block subject %}
{{ 'sylius.email.order_confirmation.subject'|trans({}, null, localeCode) }}
{% include '@SyliusCore/Email/Blocks/OrderConfirmation/_subject.html.twig' %}
SirDomin marked this conversation as resolved.
Show resolved Hide resolved
{% endblock %}

{% block content %}
{% set url = channel.hostname is not null ? 'http://' ~ channel.hostname ~ path('sylius_shop_order_show', {'tokenValue': order.tokenValue, '_locale': localeCode}) : url('sylius_shop_order_show', {'tokenValue': order.tokenValue, '_locale': localeCode}) %}

<div style="text-align: center; margin-bottom: 30px;">
{{ 'sylius.email.order_confirmation.your_order_number'|trans({}, null, localeCode) }}
<div style="margin: 10px 0;">
<span style="border: 1px solid #eee; padding: 10px; color: #1abb9c; font-size: 28px;">
{{ order.number }}
</span>
</div>
{{ 'sylius.email.order_confirmation.has_been_successfully_placed'|trans({}, null, localeCode) }}
</div>

<div style="text-align: center; margin-bottom: 30px;">
<a href="{{ url|raw }}" style="display: inline-block; text-align: center; background: #1abb9c; padding: 18px 28px; color: #fff; text-decoration: none; border-radius: 3px;">
{{ 'sylius.email.order_confirmation.view_order_or_change_payment_method'|trans({}, null, localeCode) }}
</a>
</div>

<div style="text-align: center;">
{{ 'sylius.email.order_confirmation.thank_you'|trans({}, null, localeCode) }}
</div>
{% include '@SyliusCore/Email/Blocks/OrderConfirmation/_content.html.twig' %}
{% endblock %}
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,7 @@

use SM\Factory\FactoryInterface;
use Sylius\Bundle\ApiBundle\Command\Checkout\CompleteOrder;
use Sylius\Bundle\CoreBundle\Mailer\OrderEmailManagerInterface;
use Sylius\Component\Core\Model\OrderInterface;
use Sylius\Component\Core\OrderCheckoutTransitions;
use Sylius\Component\Core\Repository\OrderRepositoryInterface;
Expand All @@ -30,12 +31,17 @@ final class CompleteOrderHandler implements MessageHandlerInterface
/** @var FactoryInterface */
private $stateMachineFactory;

/** @var OrderEmailManagerInterface */
private $emailManager;

public function __construct(
OrderRepositoryInterface $orderRepository,
FactoryInterface $stateMachineFactory
FactoryInterface $stateMachineFactory,
OrderEmailManagerInterface $emailManager
) {
$this->orderRepository = $orderRepository;
$this->stateMachineFactory = $stateMachineFactory;
$this->emailManager = $emailManager;
}

public function __invoke(CompleteOrder $completeOrder): OrderInterface
Expand All @@ -60,6 +66,8 @@ public function __invoke(CompleteOrder $completeOrder): OrderInterface

$stateMachine->apply(OrderCheckoutTransitions::TRANSITION_COMPLETE);

$this->emailManager->sendConfirmationEmail($cart);

return $cart;
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -78,7 +78,8 @@
<service id="Sylius\Bundle\ApiBundle\CommandHandler\Checkout\CompleteOrderHandler">
<argument type="service" id="sylius.repository.order"/>
<argument type="service" id="sm.factory" />
<tag name="messenger.message_handler" bus="sylius_default.bus"/>
<argument type="service" id="sylius.mailer.order_email_manager" />
<tag name="messenger.message_handler" />
</service>

<service id="Sylius\Bundle\ApiBundle\CommandHandler\Cart\ChangeItemQuantityInCartHandler">
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -17,22 +17,27 @@
use SM\Factory\FactoryInterface;
use SM\StateMachine\StateMachineInterface;
use Sylius\Bundle\ApiBundle\Command\Checkout\CompleteOrder;
use Sylius\Bundle\CoreBundle\Mailer\OrderEmailManagerInterface;
use Sylius\Component\Core\Model\OrderInterface;
use Sylius\Component\Core\OrderCheckoutTransitions;
use Sylius\Component\Core\Repository\OrderRepositoryInterface;

final class CompleteOrderHandlerSpec extends ObjectBehavior
{
function let(OrderRepositoryInterface $orderRepository, FactoryInterface $stateMachineFactory): void
{
$this->beConstructedWith($orderRepository, $stateMachineFactory);
function let(
OrderRepositoryInterface $orderRepository,
FactoryInterface $stateMachineFactory,
OrderEmailManagerInterface $emailManager
): void {
$this->beConstructedWith($orderRepository, $stateMachineFactory, $emailManager);
}

function it_handles_order_completion_without_notes(
OrderRepositoryInterface $orderRepository,
StateMachineInterface $stateMachine,
OrderInterface $order,
FactoryInterface $stateMachineFactory
FactoryInterface $stateMachineFactory,
OrderEmailManagerInterface $emailManager
): void {
$completeOrder = new CompleteOrder();
$completeOrder->setOrderTokenValue('ORDERTOKEN');
Expand All @@ -47,14 +52,17 @@ function it_handles_order_completion_without_notes(

$stateMachine->apply('complete')->shouldBeCalled();

$emailManager->sendConfirmationEmail($order)->shouldBeCalled();

$this($completeOrder)->shouldReturn($order);
}

function it_handles_order_completion_with_notes(
OrderRepositoryInterface $orderRepository,
StateMachineInterface $stateMachine,
OrderInterface $order,
FactoryInterface $stateMachineFactory
FactoryInterface $stateMachineFactory,
OrderEmailManagerInterface $emailManager
): void {
$completeOrder = new CompleteOrder('ThankYou');
$completeOrder->setOrderTokenValue('ORDERTOKEN');
Expand All @@ -69,6 +77,8 @@ function it_handles_order_completion_with_notes(

$stateMachine->apply('complete')->shouldBeCalled();

$emailManager->sendConfirmationEmail($order)->shouldBeCalled();

$this($completeOrder)->shouldReturn($order);
}

Expand Down
45 changes: 45 additions & 0 deletions src/Sylius/Bundle/CoreBundle/Mailer/OrderEmailManager.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,45 @@
<?php

/*
* This file is part of the Sylius package.
*
* (c) Paweł Jędrzejewski
*
* For the full copyright and license information, please view the LICENSE
* file that was distributed with this source code.
*/

declare(strict_types=1);

namespace Sylius\Bundle\CoreBundle\Mailer;

use Sylius\Component\Core\Model\CustomerInterface;
use Sylius\Component\Core\Model\OrderInterface;
use Sylius\Component\Mailer\Sender\SenderInterface;

final class OrderEmailManager implements OrderEmailManagerInterface
{
/** @var SenderInterface */
private $emailSender;

public function __construct(SenderInterface $emailSender)
{
$this->emailSender = $emailSender;
}

public function sendConfirmationEmail(OrderInterface $order): void
{
/** @var CustomerInterface $customer */
$customer = $order->getCustomer();

$this->emailSender->send(
Emails::ORDER_CONFIRMATION,
[$customer->getEmail()],
[
'order' => $order,
'channel' => $order->getChannel(),
'localeCode' => $order->getLocaleCode(),
]
);
}
}
21 changes: 21 additions & 0 deletions src/Sylius/Bundle/CoreBundle/Mailer/OrderEmailManagerInterface.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,21 @@
<?php

/*
* This file is part of the Sylius package.
*
* (c) Paweł Jędrzejewski
*
* For the full copyright and license information, please view the LICENSE
* file that was distributed with this source code.
*/

declare(strict_types=1);

namespace Sylius\Bundle\CoreBundle\Mailer;

use Sylius\Component\Core\Model\OrderInterface;

interface OrderEmailManagerInterface
{
public function sendConfirmationEmail(OrderInterface $order): void;
}
Original file line number Diff line number Diff line change
Expand Up @@ -5,3 +5,7 @@ sylius_mailer:
sender:
name: Example.com
address: no-reply@example.com
emails:
order_confirmation:
subject: sylius.emails.order_confirmation.subject
template: "@SyliusCore/Email/orderConfirmation.html.twig"
4 changes: 4 additions & 0 deletions src/Sylius/Bundle/CoreBundle/Resources/config/services.xml
Original file line number Diff line number Diff line change
Expand Up @@ -233,5 +233,9 @@
<service id="sylius.grid_filter.entities" class="Sylius\Component\Core\Grid\Filter\EntitiesFilter">
<tag name="sylius.grid_filter" type="entities" form-type="Sylius\Bundle\CoreBundle\Form\Type\Grid\Filter\EntitiesFilterType" />
</service>

<service class="Sylius\Bundle\CoreBundle\Mailer\OrderEmailManager" id="sylius.mailer.order_email_manager">
<argument type="service" id="sylius.email_sender" />
</service>
</services>
</container>
Original file line number Diff line number Diff line change
@@ -0,0 +1,23 @@
<div style="text-align: center; margin-bottom: 30px;">
{{ 'sylius.email.order_confirmation.your_order_number'|trans({}, null, localeCode) }}
<div style="margin: 10px 0;">
<span style="border: 1px solid #eee; padding: 10px; color: #1abb9c; font-size: 28px;">
{{ order.number }}
</span>
</div>
{{ 'sylius.email.order_confirmation.has_been_successfully_placed'|trans({}, null, localeCode) }}
</div>

{% if sylius_bundle_loaded_checker('SyliusShopBundle') %}
{% set url = channel.hostname is not null ? 'http://' ~ channel.hostname ~ path('sylius_shop_order_show', {'tokenValue': order.tokenValue, '_locale': localeCode}) : url('sylius_shop_order_show', {'tokenValue': order.tokenValue, '_locale': localeCode}) %}

<div style="text-align: center; margin-bottom: 30px;">
<a href="{{ url|raw }}" style="display: inline-block; text-align: center; background: #1abb9c; padding: 18px 28px; color: #fff; text-decoration: none; border-radius: 3px;">
{{ 'sylius.email.order_confirmation.view_order_or_change_payment_method'|trans({}, null, localeCode) }}
</a>
</div>
{% endif %}

<div style="text-align: center;">
{{ 'sylius.email.order_confirmation.thank_you'|trans({}, null, localeCode) }}
</div>
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
{{ 'sylius.email.order_confirmation.subject'|trans({}, null, localeCode) }}
Loading