Skip to content

Commit

Permalink
[shopsys] transport restrictions (#3397)
Browse files Browse the repository at this point in the history
  • Loading branch information
vitek-rostislav authored Sep 30, 2024
2 parents bfb0ee6 + 8dd3c0a commit 3c4863e
Show file tree
Hide file tree
Showing 47 changed files with 1,067 additions and 261 deletions.
Original file line number Diff line number Diff line change
@@ -0,0 +1,45 @@
import Register from '../../common/utils/Register';
import { addNewItemToCollection, removeItemFromCollection } from '../validation/customization/customizeCollectionBundle';

export default class TransportPriceWithWeightLimitCollection {
static init () {
const $transportPriceItemAdd = $('.js-transport-prices-item-add');
const $transportPricesCollection = $('.js-transport-prices');

$transportPriceItemAdd.off('click');
$transportPricesCollection.off('click', '.js-transport-prices-item-remove');

$transportPricesCollection.on('click', '.js-transport-prices-item-remove', function (event) {
const $item = $(this).closest('.js-transport-prices-item');
const index = $item.data('index');
removeItemFromCollection('.js-transport-prices', index);
$item.remove();

event.preventDefault();
});

$transportPriceItemAdd.on('click', function () {
const $collection = $(this).closest('.js-transport-prices-form-group').find('.js-transport-prices');
const index = $collection.data('index');

const prototype = $collection.data('prototype');
const item = prototype
.replace(/__name__label__/g, index)
.replace(/__name__/g, index);
const $item = $($.parseHTML(item));
$item.data('index', index);

$collection.data('index', index + 1);

$collection.append($item);
(new Register()).registerNewContent($item);

addNewItemToCollection('.js-transport-prices', index);

event.preventDefault();
return false;
});
}
}

(new Register()).registerCallback(TransportPriceWithWeightLimitCollection.init, 'TransportPriceWithWeightLimitCollection.init');
1 change: 1 addition & 0 deletions assets/js/admin/components/index.js
Original file line number Diff line number Diff line change
Expand Up @@ -59,3 +59,4 @@ import './StaticConfirmWindow';
import './Statistics';
import './SymfonyToolbarSupport';
import './ToggleMenu';
import './TransportPriceWithWeightLimitCollection';
1 change: 1 addition & 0 deletions assets/js/admin/validation/form/index.js
Original file line number Diff line number Diff line change
Expand Up @@ -10,3 +10,4 @@ import './validationPayment';
import './validationPromoCode';
import './validationHreflangSetting';
import './validationStore';
import './validationTransportPrices';
13 changes: 13 additions & 0 deletions assets/js/admin/validation/form/validationTransportPrices.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,13 @@
import Register from '../../../common/utils/Register';

function validationTransportPrices ($container) {
window.$('form[name="transport_form"]').jsFormValidator({
callbacks: {
validateTransportPricesOnDomain: function () {
// JS validation is not necessary
}
}
});
}

(new Register()).registerCallback(validationTransportPrices);
11 changes: 11 additions & 0 deletions src/Form/Admin/Product/ProductFormType.php
Original file line number Diff line number Diff line change
Expand Up @@ -37,6 +37,7 @@
use Shopsys\FrameworkBundle\Model\Product\ProductFacade;
use Shopsys\FrameworkBundle\Model\Product\Unit\UnitFacade;
use Shopsys\FrameworkBundle\Model\Seo\SeoSettingFacade;
use Shopsys\FrameworkBundle\Model\Transport\TransportFacade;
use Symfony\Component\Form\AbstractType;
use Symfony\Component\Form\Extension\Core\Type\ChoiceType;
use Symfony\Component\Form\Extension\Core\Type\CollectionType;
Expand Down Expand Up @@ -64,6 +65,7 @@ class ProductFormType extends AbstractType
* @param \Shopsys\FrameworkBundle\Component\Plugin\PluginCrudExtensionFacade $pluginDataFormExtensionFacade
* @param \Shopsys\FrameworkBundle\Form\Transformers\ProductParameterValueToProductParameterValuesLocalizedTransformer $productParameterValueToProductParameterValuesLocalizedTransformer
* @param \Shopsys\FrameworkBundle\Model\Product\ProductFacade $productFacade
* @param \Shopsys\FrameworkBundle\Model\Transport\TransportFacade $transportFacade
*/
public function __construct(
private readonly BrandFacade $brandFacade,
Expand All @@ -76,6 +78,7 @@ public function __construct(
private readonly PluginCrudExtensionFacade $pluginDataFormExtensionFacade,
private readonly ProductParameterValueToProductParameterValuesLocalizedTransformer $productParameterValueToProductParameterValuesLocalizedTransformer,
private readonly ProductFacade $productFacade,
private readonly TransportFacade $transportFacade,
) {
}

Expand Down Expand Up @@ -229,6 +232,14 @@ private function createBasicInformationGroup(
->add('weight', IntegerType::class, [
'label' => t('Weight (g)'),
'required' => false,
])
->add('excludedTransports', ChoiceType::class, [
'required' => false,
'choices' => $this->transportFacade->getAll(),
'choice_label' => 'name',
'multiple' => true,
'expanded' => false,
'label' => t('Excluded transports'),
]);

return $builderBasicInformationGroup;
Expand Down
85 changes: 85 additions & 0 deletions src/Form/Admin/Transport/Price/PriceWithLimitType.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,85 @@
<?php

declare(strict_types=1);

namespace Shopsys\FrameworkBundle\Form\Admin\Transport\Price;

use Override;
use Shopsys\FrameworkBundle\Model\Transport\PriceWithLimitData;
use Shopsys\FrameworkBundle\Twig\InputPriceLabelExtension;
use Symfony\Component\Form\AbstractType;
use Symfony\Component\Form\Extension\Core\Type\FormType;
use Symfony\Component\Form\Extension\Core\Type\HiddenType;
use Symfony\Component\Form\Extension\Core\Type\IntegerType;
use Symfony\Component\Form\Extension\Core\Type\MoneyType;
use Symfony\Component\Form\FormBuilderInterface;
use Symfony\Component\Form\FormInterface;
use Symfony\Component\Form\FormView;
use Symfony\Component\OptionsResolver\OptionsResolver;
use Symfony\Component\Validator\Constraints\NotBlank;

class PriceWithLimitType extends AbstractType
{
/**
* @param \Shopsys\FrameworkBundle\Twig\InputPriceLabelExtension $inputPriceLabelExtension
*/
public function __construct(
protected readonly InputPriceLabelExtension $inputPriceLabelExtension,
) {
}

/**
* @param \Symfony\Component\Form\FormBuilderInterface $builder
* @param array $options
*/
#[Override]
public function buildForm(FormBuilderInterface $builder, array $options): void
{
$builder
->add('price', MoneyType::class, [
'scale' => 6,
'constraints' => [
new NotBlank(['message' => 'Please enter price']),
],
'label' => $this->inputPriceLabelExtension->getInputPriceLabel(),
])
->add('maxWeight', IntegerType::class)
->add('transportPriceId', HiddenType::class);
}

/**
* @param \Symfony\Component\OptionsResolver\OptionsResolver $resolver
*/
#[Override]
public function configureOptions(OptionsResolver $resolver)
{
$resolver
->setDefaults([
'data_class' => PriceWithLimitData::class,
'attr' => ['novalidate' => 'novalidate'],
])
->setRequired(['domain_id', 'current_transport_prices_indexed_by_id'])
->setAllowedTypes('domain_id', 'int')
->setAllowedTypes('current_transport_prices_indexed_by_id', 'array');
}

/**
* @return string
*/
#[Override]
public function getParent(): string
{
return FormType::class;
}

/**
* {@inheritdoc}
*/
#[Override]
public function buildView(FormView $view, FormInterface $form, array $options): void
{
$transportPriceId = (int)$form->get('transportPriceId')->getData();
$view->vars['domain_id'] = $options['domain_id'];
$view->vars['transport_calculated_price'] = $options['current_transport_prices_indexed_by_id'][$transportPriceId] ?? null;
}
}
71 changes: 60 additions & 11 deletions src/Form/Admin/Transport/TransportFormType.php
Original file line number Diff line number Diff line change
Expand Up @@ -5,15 +5,18 @@
namespace Shopsys\FrameworkBundle\Form\Admin\Transport;

use FOS\CKEditorBundle\Form\Type\CKEditorType;
use Shopsys\FormTypesBundle\MultidomainType;
use Shopsys\FormTypesBundle\YesNoType;
use Shopsys\FrameworkBundle\Component\Domain\Domain;
use Shopsys\FrameworkBundle\Component\Translation\Translator;
use Shopsys\FrameworkBundle\Form\DisplayOnlyType;
use Shopsys\FrameworkBundle\Form\DisplayVariablesType;
use Shopsys\FrameworkBundle\Form\DomainsType;
use Shopsys\FrameworkBundle\Form\FormRenderingConfigurationExtension;
use Shopsys\FrameworkBundle\Form\GroupType;
use Shopsys\FrameworkBundle\Form\ImageUploadType;
use Shopsys\FrameworkBundle\Form\Locale\LocalizedType;
use Shopsys\FrameworkBundle\Form\PriceAndVatTableByDomainsType;
use Shopsys\FrameworkBundle\Form\TransportInputPricesType;
use Shopsys\FrameworkBundle\Model\Order\Mail\OrderMail;
use Shopsys\FrameworkBundle\Model\Payment\PaymentFacade;
use Shopsys\FrameworkBundle\Model\Transport\Transport;
Expand All @@ -22,7 +25,6 @@
use Shopsys\FrameworkBundle\Model\Transport\TransportTypeEnum;
use Symfony\Component\Form\AbstractType;
use Symfony\Component\Form\Extension\Core\Type\ChoiceType;
use Symfony\Component\Form\Extension\Core\Type\IntegerType;
use Symfony\Component\Form\Extension\Core\Type\SubmitType;
use Symfony\Component\Form\Extension\Core\Type\TextareaType;
use Symfony\Component\Form\Extension\Core\Type\TextType;
Expand All @@ -31,18 +33,21 @@
use Symfony\Component\Validator\Constraints;
use Symfony\Component\Validator\Constraints\Length;
use Symfony\Component\Validator\Constraints\NotBlank;
use Symfony\Component\Validator\Context\ExecutionContextInterface;

class TransportFormType extends AbstractType
{
/**
* @param \Shopsys\FrameworkBundle\Model\Payment\PaymentFacade $paymentFacade
* @param \Shopsys\FrameworkBundle\Model\Transport\TransportFacade $transportFacade
* @param \Shopsys\FrameworkBundle\Model\Transport\TransportTypeEnum $transportTypeEnum
* @param \Shopsys\FrameworkBundle\Component\Domain\Domain $domain
*/
public function __construct(
private readonly PaymentFacade $paymentFacade,
private readonly TransportFacade $transportFacade,
protected readonly TransportTypeEnum $transportTypeEnum,
private readonly TransportTypeEnum $transportTypeEnum,
private readonly Domain $domain,
) {
}

Expand Down Expand Up @@ -117,20 +122,27 @@ public function buildForm(FormBuilderInterface $builder, array $options)
]),
],
'label' => t('Days until delivery'),
])
->add('maxWeight', IntegerType::class, [
'label' => t('Maximum weight (g)'),
'required' => false,
]);

$builderPricesGroup = $builder->create('prices', GroupType::class, [
'label' => t('Prices'),
]);

$builderPricesGroup->add('pricesByDomains', PriceAndVatTableByDomainsType::class, [
'pricesIndexedByDomainId' => $this->transportFacade->getPricesIndexedByDomainId($transport),
'inherit_data' => true,
'render_form_row' => false,
$optionsByDomainId = [];

$pricesIndexedByTransportPriceId = $transport instanceof Transport ? $this->transportFacade->getPricesIndexedByTransportPriceId($transport) : [];

foreach ($this->domain->getAllIds() as $domainId) {
$optionsByDomainId[$domainId] = [
'domain_id' => $domainId,
'current_transport_prices_indexed_by_id' => $pricesIndexedByTransportPriceId,
];
}

$builderPricesGroup->add('inputPricesByDomain', MultidomainType::class, [
'label' => false,
'entry_type' => TransportInputPricesType::class,
'options_by_domain_id' => $optionsByDomainId,
]);

$builderAdditionalInformationGroup = $builder->create('additionalInformation', GroupType::class, [
Expand Down Expand Up @@ -235,6 +247,43 @@ public function configureOptions(OptionsResolver $resolver)
->setDefaults([
'data_class' => TransportData::class,
'attr' => ['novalidate' => 'novalidate'],
'constraints' => [
new Constraints\Callback([$this, 'validateTransportPricesOnDomain']),
],
]);
}

/**
* @param \Shopsys\FrameworkBundle\Model\Transport\TransportData $transportData
* @param \Symfony\Component\Validator\Context\ExecutionContextInterface $context
*/
public function validateTransportPricesOnDomain(
TransportData $transportData,
ExecutionContextInterface $context,
): void {
foreach ($transportData->inputPricesByDomain as $domainId => $pricesData) {
$weightLimits = [];

if ($pricesData->pricesWithLimits === []) {
$context
->buildViolation(t('Please enter at least one price', [], Translator::VALIDATOR_TRANSLATION_DOMAIN))
->atPath(sprintf('inputPricesByDomain[%d].pricesWithLimits', $domainId))
->addViolation();
}

foreach ($pricesData->pricesWithLimits as $priceData) {
if ($priceData === null) {
continue;
}

if (in_array($priceData->maxWeight, $weightLimits, true)) {
$context
->buildViolation(t('Please use each limit only once', [], Translator::VALIDATOR_TRANSLATION_DOMAIN))
->atPath(sprintf('inputPricesByDomain[%d].pricesWithLimits', $domainId))
->addViolation();
}
$weightLimits[] = $priceData->maxWeight;
}
}
}
}
1 change: 0 additions & 1 deletion src/Form/OrderItemsType.php
Original file line number Diff line number Diff line change
Expand Up @@ -76,7 +76,6 @@ public function buildView(FormView $view, FormInterface $form, array $options)

$view->vars['order'] = $order;
$view->vars['transportPricesWithVatByTransportId'] = $this->transportFacade->getTransportPricesWithVatByCurrencyAndDomainIdIndexedByTransportId(
$order->getCurrency(),
$order->getDomainId(),
);
$view->vars['transportVatPercentsByTransportId'] = $this->transportFacade->getTransportVatPercentsByDomainIdIndexedByTransportId(
Expand Down
Loading

0 comments on commit 3c4863e

Please sign in to comment.