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

Allow preventing sending the notification email on GC creation #219

Merged
merged 9 commits into from
May 9, 2022
Original file line number Diff line number Diff line change
Expand Up @@ -42,6 +42,10 @@ public function postCreate(ResourceControllerEvent $event): void
return;
}

if (!$giftCard->getSendNotificationEmail()) {
return;
}

$this->giftCardEmailManager->sendEmailToCustomerWithGiftCard($customer, $giftCard);
}
}
109 changes: 61 additions & 48 deletions src/Form/Type/GiftCardType.php
Original file line number Diff line number Diff line change
Expand Up @@ -41,55 +41,68 @@ public function __construct(

public function buildForm(FormBuilderInterface $builder, array $options): void
{
$builder
->addEventSubscriber(new AddCodeFormSubscriber())
->add('customer', CustomerAutocompleteChoiceType::class, [
'label' => 'sylius.ui.customer',
])
->add('amount', NumberType::class, [
'label' => 'sylius.ui.amount',
])
->add('enabled', CheckboxType::class, [
'label' => 'sylius.ui.enabled',
'required' => false,
])
->add('customMessage', TextareaType::class, [
'label' => 'setono_sylius_gift_card.form.gift_card.custom_message',
$builder->addEventSubscriber(new AddCodeFormSubscriber());
$builder->add('customer', CustomerAutocompleteChoiceType::class, [
'label' => 'sylius.ui.customer',
]);
$builder->addEventListener(FormEvents::PRE_SET_DATA, function (FormEvent $event): void {
/** @var GiftCardInterface $giftCard */
$giftCard = $event->getData();

// We only add the notification input if the gift card is new
if (null !== $giftCard->getId()) {
return;
}

$form = $event->getForm();
$form->add('sendNotificationEmail', CheckboxType::class, [
'required' => false,
'attr' => [
'placeholder' => 'setono_sylius_gift_card.form.gift_card.custom_message_placeholder',
],
])
->add('expiresAt', DateTimeType::class, [
'label' => 'setono_sylius_gift_card.form.gift_card.expires_at',
'widget' => 'single_text',
'html5' => true,
])
->addEventListener(FormEvents::PRE_SET_DATA, function (FormEvent $event): void {
/** @var GiftCardInterface $giftCard */
$giftCard = $event->getData();

if ($giftCard->getCode() === null) {
$giftCard->setCode($this->giftCardCodeGenerator->generate());
}

/** @var ChannelInterface $channel */
$channel = $giftCard->getChannel();

/** @var CurrencyInterface $currency */
$currency = $channel->getBaseCurrency();

$form = $event->getForm();
$form
->add('currencyCode', ChoiceType::class, [
'label' => 'sylius.ui.currency',
'choices' => $this->currencyRepository->findAll(),
'choice_label' => 'code',
'choice_value' => 'code',
'preferred_choices' => [$currency->getCode()],
]);
})
;
'label' => 'setono_sylius_gift_card.form.gift_card.send_notification_email',
]);
});
$builder->add('amount', NumberType::class, [
'label' => 'sylius.ui.amount',
]);
$builder->add('enabled', CheckboxType::class, [
'label' => 'sylius.ui.enabled',
'required' => false,
]);
$builder->add('customMessage', TextareaType::class, [
'label' => 'setono_sylius_gift_card.form.gift_card.custom_message',
'required' => false,
'attr' => [
'placeholder' => 'setono_sylius_gift_card.form.gift_card.custom_message_placeholder',
],
]);
$builder->add('expiresAt', DateTimeType::class, [
'label' => 'setono_sylius_gift_card.form.gift_card.expires_at',
'widget' => 'single_text',
'html5' => true,
]);
$builder->addEventListener(FormEvents::PRE_SET_DATA, function (FormEvent $event): void {
/** @var GiftCardInterface $giftCard */
$giftCard = $event->getData();

if ($giftCard->getCode() === null) {
$giftCard->setCode($this->giftCardCodeGenerator->generate());
}

/** @var ChannelInterface $channel */
$channel = $giftCard->getChannel();

/** @var CurrencyInterface $currency */
$currency = $channel->getBaseCurrency();

$form = $event->getForm();
$form
->add('currencyCode', ChoiceType::class, [
'label' => 'sylius.ui.currency',
'choices' => $this->currencyRepository->findAll(),
'choice_label' => 'code',
'choice_value' => 'code',
'preferred_choices' => [$currency->getCode()],
]);
});

$builder->get('amount')->addModelTransformer(new CallbackTransformer(static function (?int $amount): ?float {
if (null === $amount) {
Expand Down
12 changes: 12 additions & 0 deletions src/Model/GiftCard.php
Original file line number Diff line number Diff line change
Expand Up @@ -49,6 +49,8 @@ class GiftCard implements GiftCardInterface

protected ?DateTimeInterface $expiresAt = null;

protected bool $sendNotificationEmail = true;
Roshyo marked this conversation as resolved.
Show resolved Hide resolved

public function __construct()
{
$this->appliedOrders = new ArrayCollection();
Expand Down Expand Up @@ -296,4 +298,14 @@ public function isExpired(DateTimeInterface $date = null): bool

return $date > $giftCardValidUntil;
}

public function getSendNotificationEmail(): bool
{
return $this->sendNotificationEmail;
}

public function setSendNotificationEmail(bool $sendNotificationEmail = true): void
{
$this->sendNotificationEmail = $sendNotificationEmail;
}
}
4 changes: 4 additions & 0 deletions src/Model/GiftCardInterface.php
Original file line number Diff line number Diff line change
Expand Up @@ -127,4 +127,8 @@ public function getExpiresAt(): ?\DateTimeInterface;
public function setExpiresAt(?\DateTimeInterface $expiresAt): void;

public function isExpired(\DateTimeInterface $date = null): bool;

public function getSendNotificationEmail(): bool;

public function setSendNotificationEmail(bool $sendNotificationEmail = true): void;
}
4 changes: 4 additions & 0 deletions src/Resources/config/app/config.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -33,3 +33,7 @@ sylius_ui:
setono_sylius_gift_card.admin.gift_card_configuration.update.javascripts:
blocks:
live_pdf_rendering_js: '@SetonoSyliusGiftCardPlugin/Admin/GiftCardConfiguration/Update/_javascripts.html.twig'

setono_sylius_gift_card.admin.gift_card.create.javascripts:
blocks:
send_customer_email_js: '@SetonoSyliusGiftCardPlugin/Admin/GiftCard/Create/_javascripts.html.twig'
7 changes: 7 additions & 0 deletions src/Resources/config/validation/GiftCard.xml
Original file line number Diff line number Diff line change
Expand Up @@ -37,5 +37,12 @@
<option name="groups">setono_sylius_gift_card</option>
</constraint>
</property>
<property name="sendNotificationEmail">
<constraint name="Type">
<option name="type">bool</option>
<option name="message">setono_sylius_gift_card.gift_card.send_notification_email.boolean</option>
<option name="groups">setono_sylius_gift_card</option>
</constraint>
</property>
</class>
</constraint-mapping>
Original file line number Diff line number Diff line change
@@ -0,0 +1,32 @@
(function ($) {
'use strict';

$.fn.extend({
sendNotificationEmailInput: function () {
const $customerInput = $(this);
const $sendCustomerNotificationEmail = $($customerInput.data('target'));

if ($customerInput.val() !== '') {
$sendCustomerNotificationEmail.show();
} else {
$sendCustomerNotificationEmail.hide();
}

$('label[for="setono_sylius_gift_card_gift_card_customer"]').prepend('<i class="delete icon js-ssgc-clear-input" style="float: right;cursor: pointer"></i>');

$customerInput.on('change', () => {
if ($customerInput.val() !== '') {
$sendCustomerNotificationEmail.show();
} else {
$sendCustomerNotificationEmail.hide();
}
});

$('.js-ssgc-clear-input').on('click', () => {
$customerInput.parent().children('div.text').html('');
$customerInput.val('');
$customerInput.trigger('change');
});
}
});
})(jQuery);
1 change: 1 addition & 0 deletions src/Resources/translations/messages.da.yml
Original file line number Diff line number Diff line change
Expand Up @@ -21,6 +21,7 @@ setono_sylius_gift_card:
custom_message: Personlig besked
custom_message_placeholder: This message is printed on the gift card PDF...
expires_at: Udløber
send_notification_email: Send email med gavekort til kunde
gift_card_configuration:
background_image: Baggrundsbillede
channel_configurations: Kanalkonfigurationer
Expand Down
1 change: 1 addition & 0 deletions src/Resources/translations/messages.en.yml
Original file line number Diff line number Diff line change
Expand Up @@ -21,6 +21,7 @@ setono_sylius_gift_card:
custom_message: Custom message
custom_message_placeholder: This message is printed on the gift card PDF...
expires_at: Expires at
send_notification_email: Send notification email
gift_card_configuration:
background_image: Background image
channel_configurations: Channel configurations
Expand Down
3 changes: 2 additions & 1 deletion src/Resources/translations/messages.fr.yml
Original file line number Diff line number Diff line change
Expand Up @@ -21,6 +21,7 @@ setono_sylius_gift_card:
custom_message: Message personnalisé
custom_message_placeholder: Ce message sera affiché sur le PDF du chèque-cadeau...
expires_at: Expire le
send_notification_email: Envoyer un email de notification
gift_card_configuration:
background_image: Image de fond
channel_configurations: Configurations des canaux
Expand Down Expand Up @@ -49,7 +50,7 @@ setono_sylius_gift_card:
covered_by_gift_cards: Montant pris en charge
count: Nombre
create_for_channel: Créer pour %channel%
customer_help_text: When you associate a customer with a gift card, Sylius will automatically notify this customer via email
customer_help_text: Quand vous attribuez un chèque-cadeau à un client, Sylius enverra un email à ce client.
customer_email: Customer email
download_pdf: PDF
edit_gift_card: Edit gift card
Expand Down
2 changes: 2 additions & 0 deletions src/Resources/translations/validators.da.yml
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,8 @@ setono_sylius_gift_card:
integer: Beløb skal være heltal
min: Beløbet kan ikke være mindre en 1
greater_than_or_equal: Beløbet skal være større eller lig med 1
send_notification_email:
boolean: Send notification email must be a boolean
gift_card_configuration:
background_image_required: Baggrundsbillede er påkrævet
gift_card_search_command:
Expand Down
2 changes: 2 additions & 0 deletions src/Resources/translations/validators.en.yml
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,8 @@ setono_sylius_gift_card:
integer: Amount must be an integer
min: Amount cannot be lower than 1
greater_than_or_equal: The amount must be greater than or equal to 1
send_notification_email:
boolean: Send notification email must be a boolean
gift_card_configuration:
background_image_required: The background image is required
gift_card_search_command:
Expand Down
2 changes: 2 additions & 0 deletions src/Resources/translations/validators.fr.yml
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,8 @@ setono_sylius_gift_card:
not_blank: Veuillez renseigner un montant
integer: Le montant doit être un entier
min: Le montant ne dois pas être en-dessous de 1
send_notification_email:
boolean: L'envoi de l'email de notification doit être un booléen
gift_card_configuration:
background_image_required: L'image de fond est requise
gift_card_search_command:
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
<script src="{{ asset('bundles/setonosyliusgiftcardplugin/setono-sylius-gift-card-send-notification-email.js') }}"></script>
<script>
$(() => {
Roshyo marked this conversation as resolved.
Show resolved Hide resolved
$('#setono_sylius_gift_card_gift_card_customer').sendNotificationEmailInput();
});
</script>
9 changes: 7 additions & 2 deletions src/Resources/views/Admin/GiftCard/_form.html.twig
Original file line number Diff line number Diff line change
Expand Up @@ -6,8 +6,13 @@
{{ form_row(form.code) }}
{{ form_row(form.enabled) }}
{{ form_row(form.expiresAt) }}
<div class="ui info message">{{ 'setono_sylius_gift_card.ui.customer_help_text'|trans }}</div>
{{ form_row(form.customer) }}
{{ form_row(form.customer, {'attr': {'data-target': '.js-ssgc-send-customer-email'}}) }}
{% if form.sendNotificationEmail is defined %}
<div class="js-ssgc-send-customer-email" style="display: none;">
<div class="ui info message">{{ 'setono_sylius_gift_card.ui.customer_help_text'|trans }}</div>
{{ form_row(form.sendNotificationEmail) }}
</div>
{% endif %}
</div>
</div>

Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,88 @@
<?php

declare(strict_types=1);

namespace Tests\Setono\SyliusGiftCardPlugin\Unit\EventListener;

use PHPUnit\Framework\TestCase;
use Prophecy\Argument;
use Prophecy\PhpUnit\ProphecyTrait;
use Setono\SyliusGiftCardPlugin\EmailManager\GiftCardEmailManagerInterface;
use Setono\SyliusGiftCardPlugin\EventListener\SendEmailWithGiftCardToCustomerSubscriber;
use Setono\SyliusGiftCardPlugin\Model\GiftCardInterface;
use Sylius\Bundle\ResourceBundle\Event\ResourceControllerEvent;
use Sylius\Component\Core\Model\CustomerInterface;
use Sylius\Component\Resource\Exception\UnexpectedTypeException;

final class SendEmailWithGiftCardToCustomerSubscriberTest extends TestCase
{
use ProphecyTrait;

/**
* @test
*/
public function it_throws_an_error_if_the_subject_is_not_gift_card(): void
{
$giftCardEmailManager = $this->prophesize(GiftCardEmailManagerInterface::class);
$event = $this->prophesize(ResourceControllerEvent::class);
$event->getSubject()->willReturn(new \stdClass());

$this->expectException(UnexpectedTypeException::class);
$subscriber = new SendEmailWithGiftCardToCustomerSubscriber($giftCardEmailManager->reveal());
$subscriber->postCreate($event->reveal());
}

/**
* @test
*/
public function it_does_not_send_email_if_no_customer(): void
{
$giftCardEmailManager = $this->prophesize(GiftCardEmailManagerInterface::class);
$giftCard = $this->prophesize(GiftCardInterface::class);
$event = $this->prophesize(ResourceControllerEvent::class);
$event->getSubject()->willReturn($giftCard);

$subscriber = new SendEmailWithGiftCardToCustomerSubscriber($giftCardEmailManager->reveal());
$subscriber->postCreate($event->reveal());

$giftCardEmailManager->sendEmailToCustomerWithGiftCard(Argument::any(), Argument::any())->shouldNotHaveBeenCalled();
}

/**
* @test
*/
public function it_does_not_send_email_if_it_was_not_asked(): void
{
$giftCardEmailManager = $this->prophesize(GiftCardEmailManagerInterface::class);
$customer = $this->prophesize(CustomerInterface::class);
$giftCard = $this->prophesize(GiftCardInterface::class);
$giftCard->getCustomer()->willReturn($customer);
$giftCard->getSendNotificationEmail()->willReturn(false);
$event = $this->prophesize(ResourceControllerEvent::class);
$event->getSubject()->willReturn($giftCard);

$subscriber = new SendEmailWithGiftCardToCustomerSubscriber($giftCardEmailManager->reveal());
$subscriber->postCreate($event->reveal());

$giftCardEmailManager->sendEmailToCustomerWithGiftCard(Argument::any(), Argument::any())->shouldNotHaveBeenCalled();
}

/**
* @test
*/
public function it_sends_email_if_it_was_asked(): void
{
$giftCardEmailManager = $this->prophesize(GiftCardEmailManagerInterface::class);
$customer = $this->prophesize(CustomerInterface::class);
$giftCard = $this->prophesize(GiftCardInterface::class);
$giftCard->getCustomer()->willReturn($customer);
$giftCard->getSendNotificationEmail()->willReturn(true);
$event = $this->prophesize(ResourceControllerEvent::class);
$event->getSubject()->willReturn($giftCard);

$subscriber = new SendEmailWithGiftCardToCustomerSubscriber($giftCardEmailManager->reveal());
$subscriber->postCreate($event->reveal());

$giftCardEmailManager->sendEmailToCustomerWithGiftCard(Argument::any(), Argument::any())->shouldHaveBeenCalled();
}
}
3 changes: 3 additions & 0 deletions tests/Unit/Model/GiftCardTest.php
Original file line number Diff line number Diff line change
Expand Up @@ -61,6 +61,9 @@ public function it_has_properties(): void
$expiresAt = new \DateTime();
$giftCard->setExpiresAt($expiresAt);
$this->assertSame($expiresAt, $giftCard->getExpiresAt());

$giftCard->setSendNotificationEmail(false);
$this->assertFalse($giftCard->getSendNotificationEmail());
}

/**
Expand Down