Skip to content

Commit

Permalink
multiple delivery addresses (#1635)
Browse files Browse the repository at this point in the history
  • Loading branch information
TomasLudvik authored Feb 18, 2020
2 parents 3bc2484 + 83099f3 commit 2b6e375
Show file tree
Hide file tree
Showing 26 changed files with 519 additions and 170 deletions.
2 changes: 2 additions & 0 deletions assets/js/frontend.js
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,8 @@ import './frontend/validation/form';
// HP entry?
import './frontend/homepage/slickInit';

import './frontend/deliveryAddress';

// order entry?
import './frontend/order';

Expand Down
81 changes: 81 additions & 0 deletions assets/js/frontend/deliveryAddress/deliveryAddress.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,81 @@
import Register from 'framework/common/utils/register';
import Ajax from 'framework/common/utils/ajax';
import Window from '../utils/window';
import Translator from 'bazinga-translator';

export default class DeliveryAddress {
onRemove ($this, deliveryAddress) {
const $row = $this.closest('.js-delivery-address-row');
const $input = $row.find('.js-delivery-address-input');

// eslint-disable-next-line no-new
new Window({
content: Translator.trans('Do you really want to remove this delivery address?'),
buttonCancel: true,
buttonContinue: true,
eventContinue: () => {
const deliveryAddressId = $input.val();
if (deliveryAddressId > 0) {
Ajax.ajax({
overlayDelay: 0,
loaderElement: '#js-delivery-address-fields',
url: $this.data('href'),
type: 'get',
success: function () {
deliveryAddress.deleteSuccessMessage();
$this.closest('.js-delivery-address-row').remove();
},
error: function () {
deliveryAddress.deleteErrorMessage();
}
});
}
}
});
}

deleteSuccessMessage () {
return new Window({
content: Translator.trans('Delivery address has been removed.'),
buttonContinue: false,
textCancel: Translator.trans('Ok')
});
}

deleteErrorMessage () {
return new Window({
content: Translator.trans('Delivery address could not be removed.'),
buttonContinue: false,
textCancel: Translator.trans('Ok')
});
}

onChange ($input) {
const $orderDeliveryAddressFields = $('.js-order-delivery-address-fields');

if ($orderDeliveryAddressFields !== 'undefined') {
if ($input.val() == '') {
$orderDeliveryAddressFields.show();
} else {
$orderDeliveryAddressFields.hide();
}
}
}

static init ($container) {
const $deliveryAddressItem = $container.filterAllNodes('.js-delivery-address-row');
const $deliveryAddressRemove = $container.filterAllNodes('.js-delivery-address-remove-button');
const $deliveryAddressOrderInput = $container.filterAllNodes('.js-delivery-address-input');
const deliveryAddress = new DeliveryAddress();

$deliveryAddressRemove.click((event) => deliveryAddress.onRemove($(event.currentTarget), deliveryAddress));
$deliveryAddressOrderInput.change((event) => deliveryAddress.onChange($(event.currentTarget)));

$deliveryAddressItem.on('click', function (event) {
$deliveryAddressItem.removeClass('active');
$(event.currentTarget).addClass('active');
});
}
}

(new Register()).registerCallback(DeliveryAddress.init);
1 change: 1 addition & 0 deletions assets/js/frontend/deliveryAddress/index.js
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
import '../deliveryAddress/deliveryAddress';
5 changes: 3 additions & 2 deletions assets/js/frontend/validation/form/orderValidator.js
Original file line number Diff line number Diff line change
Expand Up @@ -15,9 +15,10 @@ export default function orderValidator ($container) {
const $orderPersonalInfoForm = window.$('form[name="order_personal_info_form"]');
$orderPersonalInfoForm.jsFormValidator({
'groups': function () {

const selectedDeliveryAddressValue = $orderPersonalInfoForm.find('.js-delivery-address-input:checked').val();
const groups = [constant('\\Shopsys\\FrameworkBundle\\Form\\ValidationGroup::VALIDATION_GROUP_DEFAULT')];
if ($orderPersonalInfoForm.find('#order_personal_info_form_deliveryAddressFilled').is(':checked')) {

if ($orderPersonalInfoForm.find('#order_personal_info_form_deliveryAddressFilled').is(':checked') && (selectedDeliveryAddressValue === '' || selectedDeliveryAddressValue === undefined)) {
groups.push(constant('\\App\\Form\\Front\\Customer\\DeliveryAddressFormType::VALIDATION_GROUP_DIFFERENT_DELIVERY_ADDRESS'));
}
if ($orderPersonalInfoForm.find('#order_personal_info_form_companyCustomer').is(':checked')) {
Expand Down
2 changes: 2 additions & 0 deletions config/packages/twig.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,8 @@ twig:
- '@ShopsysFramework/Admin/Form/localizedFullWidth.html.twig'
- '@ShopsysFramework/Admin/Form/productParameterValue.html.twig'
- '@ShopsysFramework/Admin/Form/productCalculatedPrices.html.twig'
- '@ShopsysFramework/Front/Form/deliveryAddressChoiceFields.html.twig'
- '@ShopsysFramework/Admin/Form/deliveryAddressListFields.html.twig'
strict_variables: true
globals:
globalMultipleFormSetting: '@Shopsys\FrameworkBundle\Component\Form\MultipleFormSetting'
9 changes: 9 additions & 0 deletions config/routes/shopsys_front.yml
Original file line number Diff line number Diff line change
Expand Up @@ -186,3 +186,12 @@ front_download_uploaded_file:
methods: [GET]
requirements:
uploadedFileId: \d+

front_customer_delivery_address_delete:
path: /customer/delete-delivery-address/{deliveryAddressId}
defaults:
_controller: App\Controller\Front\CustomerController:deleteDeliveryAddressAction
methods: [GET]
requirements:
deliveryAddressId: \d+

38 changes: 37 additions & 1 deletion src/Controller/Front/CustomerController.php
Original file line number Diff line number Diff line change
Expand Up @@ -6,13 +6,15 @@

use App\Form\Front\Customer\User\CustomerUserUpdateFormType;
use Shopsys\FrameworkBundle\Component\Domain\Domain;
use Shopsys\FrameworkBundle\Model\Customer\DeliveryAddressFacade;
use Shopsys\FrameworkBundle\Model\Customer\User\CustomerUserFacade;
use Shopsys\FrameworkBundle\Model\Customer\User\CustomerUserUpdateDataFactoryInterface;
use Shopsys\FrameworkBundle\Model\Order\Item\OrderItemPriceCalculation;
use Shopsys\FrameworkBundle\Model\Order\OrderFacade;
use Shopsys\FrameworkBundle\Model\Security\LoginAsUserFacade;
use Shopsys\FrameworkBundle\Model\Security\Roles;
use Symfony\Component\HttpFoundation\Request;
use Symfony\Component\HttpFoundation\Response;

class CustomerController extends FrontBaseController
{
Expand Down Expand Up @@ -46,28 +48,36 @@ class CustomerController extends FrontBaseController
*/
private $customerUserUpdateDataFactory;

/**
* @var \Shopsys\FrameworkBundle\Model\Customer\DeliveryAddressFacade
*/
private $deliveryAddressFacade;

/**
* @param \Shopsys\FrameworkBundle\Model\Customer\User\CustomerUserFacade $customerUserFacade
* @param \Shopsys\FrameworkBundle\Model\Order\OrderFacade $orderFacade
* @param \Shopsys\FrameworkBundle\Component\Domain\Domain $domain
* @param \Shopsys\FrameworkBundle\Model\Order\Item\OrderItemPriceCalculation $orderItemPriceCalculation
* @param \Shopsys\FrameworkBundle\Model\Security\LoginAsUserFacade $loginAsUserFacade
* @param \Shopsys\FrameworkBundle\Model\Customer\User\CustomerUserUpdateDataFactoryInterface $customerUserUpdateDataFactory
* @param \Shopsys\FrameworkBundle\Model\Customer\DeliveryAddressFacade $deliveryAddressFacade
*/
public function __construct(
CustomerUserFacade $customerUserFacade,
OrderFacade $orderFacade,
Domain $domain,
OrderItemPriceCalculation $orderItemPriceCalculation,
LoginAsUserFacade $loginAsUserFacade,
CustomerUserUpdateDataFactoryInterface $customerUserUpdateDataFactory
CustomerUserUpdateDataFactoryInterface $customerUserUpdateDataFactory,
DeliveryAddressFacade $deliveryAddressFacade
) {
$this->customerUserFacade = $customerUserFacade;
$this->orderFacade = $orderFacade;
$this->domain = $domain;
$this->orderItemPriceCalculation = $orderItemPriceCalculation;
$this->loginAsUserFacade = $loginAsUserFacade;
$this->customerUserUpdateDataFactory = $customerUserUpdateDataFactory;
$this->deliveryAddressFacade = $deliveryAddressFacade;
}

/**
Expand All @@ -82,10 +92,12 @@ public function editAction(Request $request)

$customerUser = $this->getUser();
$customerUserUpdateData = $this->customerUserUpdateDataFactory->createFromCustomerUser($customerUser);
$customerUserUpdateData->deliveryAddressData = null;

$form = $this->createForm(CustomerUserUpdateFormType::class, $customerUserUpdateData, [
'domain_id' => $this->domain->getId(),
]);

$form->handleRequest($request);

if ($form->isSubmitted() && $form->isValid()) {
Expand Down Expand Up @@ -191,4 +203,28 @@ public function loginAsRememberedUserAction(Request $request)

return $this->redirectToRoute('front_homepage');
}

/**
* @param int $deliveryAddressId
* @return \Symfony\Component\HttpFoundation\Response
*/
public function deleteDeliveryAddressAction(int $deliveryAddressId)
{
if (!$this->isGranted(Roles::ROLE_LOGGED_CUSTOMER)) {
throw $this->createAccessDeniedException('');
}

/** @var \App\Model\Customer\User\CustomerUser $customerUser */
$customerUser = $this->getUser();

$deliveryAddress = $this->deliveryAddressFacade->getById($deliveryAddressId);

if (in_array($deliveryAddress, $customerUser->getCustomer()->getDeliveryAddresses(), true)) {
$this->deliveryAddressFacade->delete($deliveryAddressId);

return Response::create('OK');
} else {
throw $this->createAccessDeniedException('');
}
}
}
4 changes: 3 additions & 1 deletion src/Controller/Front/OrderController.php
Original file line number Diff line number Diff line change
Expand Up @@ -184,6 +184,7 @@ public function indexAction()
if ($customerUser instanceof CustomerUser) {
$this->orderFacade->prefillFrontOrderData($frontOrderFormData, $customerUser);
}

$domainId = $this->domain->getId();
$frontOrderFormData->domainId = $domainId;
$currency = $this->currencyFacade->getDomainDefaultCurrencyByDomainId($domainId);
Expand Down Expand Up @@ -216,7 +217,8 @@ public function indexAction()
if ($orderFlow->nextStep()) {
$form = $orderFlow->createForm();
} elseif ($flashMessageBag->isEmpty()) {
$order = $this->orderFacade->createOrderFromFront($orderData);
$deliveryAddress = $orderData->deliveryAddressSameAsBillingAddress === false ? $frontOrderFormData->deliveryAddress : null;
$order = $this->orderFacade->createOrderFromFront($orderData, $deliveryAddress);
$this->orderFacade->sendHeurekaOrderInfo($order, $frontOrderFormData->disallowHeurekaVerifiedByCustomers);

if ($frontOrderFormData->newsletterSubscription) {
Expand Down
8 changes: 7 additions & 1 deletion src/Form/Front/Customer/DeliveryAddressFormType.php
Original file line number Diff line number Diff line change
Expand Up @@ -42,7 +42,13 @@ public function buildForm(FormBuilderInterface $builder, array $options)
$countries = $this->countryFacade->getAllEnabledOnDomain($options['domain_id']);

$builder
->add('addressFilled', CheckboxType::class, ['required' => false])
->add('addressFilled', CheckboxType::class, [
'required' => false,
'attr' => [
'class' => 'js-checkbox-toggle',
'data-checkbox-toggle-container-class' => 'js-delivery-address-fields',
],
])
->add('companyName', TextType::class, [
'required' => false,
'constraints' => [
Expand Down
4 changes: 3 additions & 1 deletion src/Form/Front/Customer/User/CustomerUserFormType.php
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,7 @@

use Shopsys\FrameworkBundle\Form\Constraints\FieldsAreNotIdentical;
use Shopsys\FrameworkBundle\Form\Constraints\NotIdenticalToEmailLocalPart;
use Shopsys\FrameworkBundle\Form\DeliveryAddressChoiceType;
use Shopsys\FrameworkBundle\Model\Customer\User\CustomerUserData;
use Symfony\Component\Form\AbstractType;
use Symfony\Component\Form\Extension\Core\Type\EmailType;
Expand Down Expand Up @@ -62,7 +63,8 @@ public function buildForm(FormBuilderInterface $builder, array $options)
],
],
'invalid_message' => 'Passwords do not match',
]);
])
->add('defaultDeliveryAddress', DeliveryAddressChoiceType::class);
}

/**
Expand Down
30 changes: 26 additions & 4 deletions src/Form/Front/Order/PersonalInfoFormType.php
Original file line number Diff line number Diff line change
Expand Up @@ -6,9 +6,11 @@

use Shopsys\FrameworkBundle\Component\Domain\Domain;
use Shopsys\FrameworkBundle\Form\Constraints\Email;
use Shopsys\FrameworkBundle\Form\DeliveryAddressChoiceType;
use Shopsys\FrameworkBundle\Form\Transformers\InverseTransformer;
use Shopsys\FrameworkBundle\Form\ValidationGroup;
use Shopsys\FrameworkBundle\Model\Country\CountryFacade;
use Shopsys\FrameworkBundle\Model\Customer\User\CurrentCustomerUser;
use Shopsys\FrameworkBundle\Model\Heureka\HeurekaFacade;
use Shopsys\FrameworkBundle\Model\Order\FrontOrderData;
use Symfony\Component\Form\AbstractType;
Expand Down Expand Up @@ -43,16 +45,27 @@ class PersonalInfoFormType extends AbstractType
*/
private $domain;

/**
* @var \Shopsys\FrameworkBundle\Model\Customer\User\CurrentCustomerUser
*/
private $currentCustomerUser;

/**
* @param \Shopsys\FrameworkBundle\Model\Country\CountryFacade $countryFacade
* @param \Shopsys\FrameworkBundle\Model\Heureka\HeurekaFacade $heurekaFacade
* @param \Shopsys\FrameworkBundle\Component\Domain\Domain $domain
* @param \Shopsys\FrameworkBundle\Model\Customer\User\CurrentCustomerUser $currentCustomerUser
*/
public function __construct(CountryFacade $countryFacade, HeurekaFacade $heurekaFacade, Domain $domain)
{
public function __construct(
CountryFacade $countryFacade,
HeurekaFacade $heurekaFacade,
Domain $domain,
CurrentCustomerUser $currentCustomerUser
) {
$this->countryFacade = $countryFacade;
$this->heurekaFacade = $heurekaFacade;
$this->domain = $domain;
$this->currentCustomerUser = $currentCustomerUser;
}

/**
Expand Down Expand Up @@ -158,7 +171,15 @@ public function buildForm(FormBuilderInterface $builder, array $options)
'required' => false,
'property_path' => 'deliveryAddressSameAsBillingAddress',
])
->addModelTransformer(new InverseTransformer()))
->addModelTransformer(new InverseTransformer()));

if ($this->currentCustomerUser->findCurrentCustomerUser() !== null) {
$builder->add('deliveryAddress', DeliveryAddressChoiceType::class, [
'required' => false,
]);
}

$builder
->add('deliveryFirstName', TextType::class, [
'required' => true,
'constraints' => [
Expand Down Expand Up @@ -311,7 +332,8 @@ public function configureOptions(OptionsResolver $resolver)
if ($orderData->companyCustomer) {
$validationGroups[] = self::VALIDATION_GROUP_COMPANY_CUSTOMER;
}
if (!$orderData->deliveryAddressSameAsBillingAddress) {

if (!$orderData->deliveryAddressSameAsBillingAddress && $orderData->deliveryAddress === null) {
$validationGroups[] = self::VALIDATION_GROUP_DIFFERENT_DELIVERY_ADDRESS;
}

Expand Down
7 changes: 2 additions & 5 deletions src/Model/Customer/User/CustomerUser.php
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,6 @@
namespace App\Model\Customer\User;

use Doctrine\ORM\Mapping as ORM;
use Shopsys\FrameworkBundle\Model\Customer\DeliveryAddress;
use Shopsys\FrameworkBundle\Model\Customer\User\CustomerUser as BaseUser;
use Shopsys\FrameworkBundle\Model\Customer\User\CustomerUserData as BaseUserData;

Expand All @@ -25,13 +24,11 @@ class CustomerUser extends BaseUser
{
/**
* @param \App\Model\Customer\User\CustomerUserData $customerUserData
* @param \Shopsys\FrameworkBundle\Model\Customer\DeliveryAddress|null $deliveryAddress
*/
public function __construct(
BaseUserData $customerUserData,
?DeliveryAddress $deliveryAddress
BaseUserData $customerUserData
) {
parent::__construct($customerUserData, $deliveryAddress);
parent::__construct($customerUserData);
}

/**
Expand Down
Loading

0 comments on commit 2b6e375

Please sign in to comment.