Merge pull request #7651 from NeverResponse/autocomplete-promotions

[Admin] Reduced query size while creating/editing promotions
This commit is contained in:
Paweł Jędrzejewski 2017-03-14 15:55:36 +01:00 committed by GitHub
commit 720068906b
32 changed files with 275 additions and 59 deletions

View file

@ -156,7 +156,7 @@ final class ManagingPromotionsContext implements Context
$this->createPage->addRule('Has at least one from taxons');
foreach ($taxons as $taxon) {
$this->createPage->selectRuleOption('Taxons', $taxon, true);
$this->createPage->selectAutocompleteRuleOption('Taxons', $taxon, true);
}
}
@ -166,7 +166,7 @@ final class ManagingPromotionsContext implements Context
public function iAddTheRuleConfiguredWith($taxonName, $amount, $channelName)
{
$this->createPage->addRule('Total price of items from taxon');
$this->createPage->selectRuleOption('Taxon', $taxonName);
$this->createPage->selectAutocompleteRuleOption('Taxon', $taxonName);
$this->createPage->fillRuleOptionForChannel($channelName, 'Amount', $amount);
}
@ -231,7 +231,7 @@ final class ManagingPromotionsContext implements Context
*/
public function iSpecifyThatThisActionShouldBeAppliedToItemsFromCategory($taxonName)
{
$this->createPage->selectFilterOption('Taxons filter', $taxonName);
$this->createPage->selectAutoCompleteFilterOption('Taxons', $taxonName);
}
/**
@ -556,7 +556,7 @@ final class ManagingPromotionsContext implements Context
public function iAddTheRuleConfiguredWithTheProduct($productName)
{
$this->createPage->addRule('Contains product');
$this->createPage->selectRuleOption('Product', $productName);
$this->createPage->selectAutocompleteRuleOption('Product code', $productName);
}
/**
@ -564,7 +564,7 @@ final class ManagingPromotionsContext implements Context
*/
public function iSpecifyThatThisActionShouldBeAppliedToTheProduct($productName)
{
$this->createPage->selectFilterOption('Products filter', $productName);
$this->createPage->selectAutoCompleteFilterOption('Products', $productName);
}
/**

View file

@ -11,6 +11,7 @@
namespace Sylius\Behat\Page\Admin\Promotion;
use Behat\Mink\Driver\Selenium2Driver;
use Behat\Mink\Element\NodeElement;
use Behat\Mink\Exception\ElementNotFoundException;
use Sylius\Behat\Behaviour\NamesIt;
@ -51,6 +52,22 @@ class CreatePage extends BaseCreatePage implements CreatePageInterface
$this->getLastCollectionItem('rules')->find('named', array('select', $option))->selectOption($value, $multiple);
}
/**
* {@inheritdoc}
*/
public function selectAutocompleteRuleOption($option, $value, $multiple = false)
{
$option = strtolower(str_replace(' ', '_', $option));
$ruleAutoComplete = $this
->getLastCollectionItem('rules')
->find('css', sprintf('input[type="hidden"][name*="[%s]"]', $option))
->getParent()
;
$this->selectAutocompleteValue($ruleAutoComplete, $value);
}
/**
* {@inheritdoc}
*/
@ -172,9 +189,17 @@ class CreatePage extends BaseCreatePage implements CreatePageInterface
/**
* {@inheritdoc}
*/
public function selectFilterOption($option, $value, $multiple = false)
public function selectAutoCompleteFilterOption($option, $value, $multiple = false)
{
$this->getLastCollectionItem('actions')->find('named', array('select', $option))->selectOption($value, $multiple);
$option = strtolower(str_replace(' ', '_', $option));
$filterAutoComplete = $this
->getLastCollectionItem('actions')
->find('css', sprintf('input[type="hidden"][name*="[%s_filter]"]', $option))
->getParent()
;
$this->selectAutocompleteValue($filterAutoComplete, $value);
}
/**
@ -217,7 +242,7 @@ class CreatePage extends BaseCreatePage implements CreatePageInterface
return $this
->getLastCollectionItem('rules')
->find('css', sprintf('[id*="sylius_promotion_rules"] .configuration .field:contains("%s")', $channelName))
;
;
}
/**
@ -247,4 +272,41 @@ class CreatePage extends BaseCreatePage implements CreatePageInterface
return $items;
}
/**
* @param NodeElement $autocomplete
* @param string $value
*/
private function selectAutocompleteValue(NodeElement $autocomplete, $value)
{
Assert::isInstanceOf($this->getDriver(), Selenium2Driver::class);
$isAnyAsyncActionInProgressScript = 'jQuery.active';
$isVisibleScript = sprintf(
'$(document.evaluate("%s", document, null, XPathResult.FIRST_ORDERED_NODE_TYPE, null).singleNodeValue).dropdown("is visible")',
$autocomplete->getXpath()
);
$this->getDocument()->waitFor(5, function () use ($isAnyAsyncActionInProgressScript) {
return !(bool) $this->getDriver()->evaluateScript($isAnyAsyncActionInProgressScript);
});
$autocomplete->click();
$this->getDocument()->waitFor(5, function () use ($isAnyAsyncActionInProgressScript) {
return !(bool) $this->getDriver()->evaluateScript($isAnyAsyncActionInProgressScript);
});
$this->getDocument()->waitFor(5, function () use ($isVisibleScript) {
return $this->getDriver()->evaluateScript($isVisibleScript);
});
$autocompleteItem = $autocomplete->find('css', sprintf('div.item:contains("%s")', $value));
$autocompleteItem->click();
$this->getDocument()->waitFor(5, function () use ($isVisibleScript) {
return !$this->getDriver()->evaluateScript($isVisibleScript);
});
}
}

View file

@ -42,6 +42,13 @@ interface CreatePageInterface extends BaseCreatePageInterface
*/
public function selectRuleOption($option, $value, $multiple = false);
/**
* @param string $option
* @param string $value
* @param bool $multiple
*/
public function selectAutocompleteRuleOption($option, $value, $multiple = false);
/**
* @param string $option
* @param string $value
@ -116,5 +123,5 @@ interface CreatePageInterface extends BaseCreatePageInterface
* @param string $value
* @param bool $multiple
*/
public function selectFilterOption($option, $value, $multiple = false);
public function selectAutoCompleteFilterOption($option, $value, $multiple = false);
}

View file

@ -4,6 +4,30 @@ sylius_admin_ajax_generate_product_slug:
defaults:
_controller: sylius.controller.product_slug:generateAction
sylius_admin_ajax_product_by_name_phrase:
path: /search
methods: [GET]
defaults:
_controller: sylius.controller.product:indexAction
_sylius:
serialization_groups: [Autocomplete]
repository:
method: findByNamePart
arguments:
phrase: $phrase
locale: expr:service('sylius.context.locale').getLocaleCode()
sylius_admin_ajax_product_by_code:
path: /code
methods: [GET]
defaults:
_controller: sylius.controller.product:indexAction
_sylius:
serialization_groups: [Autocomplete]
repository:
method: findBy
arguments: [code: $code]
sylius_admin_ajax_product_index:
path: /
methods: [GET]

View file

@ -8,13 +8,13 @@
*/
(function($) {
$(document).ready(function() {
$(document).ready(function () {
$('#sylius_product_variant_pricingCalculator').handlePrototypes({
'prototypePrefix': 'sylius_product_variant_pricingCalculator',
'containerSelector': '#sylius_calculator_container'
});
$('#sylius_customer_createUser').change(function(){
$('#sylius_customer_createUser').change(function () {
$('#user-form').toggle();
});
@ -37,18 +37,25 @@
'containerSelector': '.configuration'
});
$('#actions a[data-form-collection="add"]').on('click', function(){
$('#actions a[data-form-collection="add"]').on('click', function () {
setTimeout(function(){
$('select[name^="sylius_promotion[actions]"][name$="[type]"]').last().change();
}, 50);
});
$('#rules a[data-form-collection="add"]').on('click', function(){
$('#rules a[data-form-collection="add"]').on('click', function () {
setTimeout(function(){
$('select[name^="sylius_promotion[rules]"][name$="[type]"]').last().change();
}, 50);
});
$(document).on('collection-form-update', function () {
$.each($('.sylius-autocomplete'), function (index, element) {
if ($._data($(element).get(0), 'events') == undefined) {
$(element).autoComplete();
}
});
});
$('.sylius-tabular-form').addTabErrors();
$('.ui.accordion').addAccordionErrors();
$('#sylius-product-taxonomy-tree').choiceTree('productTaxon', true, 1);

View file

@ -6,7 +6,7 @@
{% block title %}{{ parent() }} {{ header|trans }}{% endblock %}
{% form_theme form 'SyliusUiBundle:Form:theme.html.twig' %}
{% form_theme form '@SyliusAdmin/Form/theme.html.twig' %}
{% block content %}
{% include '@SyliusAdmin/Crud/Create/_header.html.twig' %}

View file

@ -7,7 +7,7 @@
{% block title %}{{ parent() }} {{ header|trans }}{% endblock %}
{% form_theme form 'SyliusUiBundle:Form:theme.html.twig' %}
{% form_theme form '@SyliusAdmin/Form/theme.html.twig' %}
{% block content %}
{% include '@SyliusAdmin/Crud/Update/_header.html.twig' %}

View file

@ -0,0 +1,21 @@
{% extends '@SyliusUi/Form/theme.html.twig' %}
{% block _sylius_promotion_rules_entry_configuration_entry_taxon_row %}
{{ form_row(form, {'remote_url': path('sylius_admin_ajax_taxon_by_name_phrase'), 'remote_criteria_type': 'contains', 'remote_criteria_name': 'phrase', 'load_edit_url': path('sylius_admin_ajax_taxon_by_code')}) }}
{% endblock %}
{% block _sylius_promotion_rules_entry_configuration_taxons_row %}
{{ form_row(form, {'remote_url': path('sylius_admin_ajax_taxon_by_name_phrase'), 'remote_criteria_type': 'contains', 'remote_criteria_name': 'phrase', 'load_edit_url': path('sylius_admin_ajax_taxon_by_code')}) }}
{% endblock %}
{% block _sylius_promotion_actions_entry_configuration_entry_filters_taxons_filter_taxons_row %}
{{ form_row(form, {'remote_url': path('sylius_admin_ajax_taxon_by_name_phrase'), 'remote_criteria_type': 'contains', 'remote_criteria_name': 'phrase', 'load_edit_url': path('sylius_admin_ajax_taxon_by_code')}) }}
{% endblock %}
{% block _sylius_promotion_rules_entry_configuration_product_code_row %}
{{ form_row(form, {'remote_url': path('sylius_admin_ajax_product_by_name_phrase'), 'remote_criteria_type': 'contains', 'remote_criteria_name': 'phrase', 'load_edit_url': path('sylius_admin_ajax_product_by_code')}) }}
{% endblock %}
{% block _sylius_promotion_actions_entry_configuration_entry_filters_products_filter_products_row %}
{{ form_row(form, {'remote_url': path('sylius_admin_ajax_product_by_name_phrase'), 'remote_criteria_type': 'contains', 'remote_criteria_name': 'phrase', 'load_edit_url': path('sylius_admin_ajax_product_by_code')}) }}
{% endblock %}

View file

@ -3,7 +3,7 @@
{% for associationForm in form.associations %}
<div class="field">
{{ form_label(associationForm) }}
{{- form_label(associationForm) -}}
<div class="product-select ui fluid multiple search selection dropdown" data-url="{{ path('sylius_admin_ajax_product_index') }}">
{{ form_widget(associationForm, {'attr': {'class' : 'autocomplete'}}) }}
<i class="dropdown icon"></i>
@ -18,6 +18,7 @@
{% endfor %}
</div>
</div>
{{ form_errors(associationForm) }}
</div>
{% endfor %}
</div>

View file

@ -67,6 +67,7 @@ final class BuildChannelBasedPromotionActionFormSubscriber extends AbstractConfi
$configurationCollection = $this->factory->createNamed('configuration', PromotionConfigurationType::class, [], [
'compound' => true,
'auto_initialize' => false,
'error_bubbling' => false,
]);
/** @var ChannelInterface $channel */
@ -107,6 +108,9 @@ final class BuildChannelBasedPromotionActionFormSubscriber extends AbstractConfi
'auto_initialize' => false,
'label' => $channel->getName(),
'currency' => $channel->getBaseCurrency()->getCode(),
'property_path' => '[' . $channel->getCode() . ']',
'block_name' => 'entry',
'error_bubbling' => false,
];
$data = array_key_exists($channel->getCode(), $data) ? $data[$channel->getCode()] : [];

View file

@ -18,7 +18,6 @@ use Sylius\Component\Core\Model\ChannelInterface;
use Sylius\Component\Core\Promotion\Checker\Rule\ChannelBasedRuleCheckerInterface;
use Sylius\Component\Promotion\Model\PromotionRuleInterface;
use Sylius\Component\Registry\ServiceRegistryInterface;
use Symfony\Component\Form\FormFactoryIntegrface;
use Symfony\Component\Form\FormFactoryInterface;
use Symfony\Component\Form\FormInterface;
@ -68,6 +67,7 @@ final class BuildChannelBasedPromotionRuleFormSubscriber extends AbstractConfigu
$configurationCollection = $this->factory->createNamed('configuration', PromotionConfigurationType::class, [], [
'compound' => true,
'auto_initialize' => false,
'error_bubbling' => false,
]);
/** @var ChannelInterface $channel */
@ -108,6 +108,9 @@ final class BuildChannelBasedPromotionRuleFormSubscriber extends AbstractConfigu
'auto_initialize' => false,
'label' => $channel->getName(),
'currency' => $channel->getBaseCurrency()->getCode(),
'property_path' => '[' . $channel->getCode() . ']',
'block_name' => 'entry',
'error_bubbling' => false,
];
$data = array_key_exists($channel->getCode(), $data) ? $data[$channel->getCode()] : [];

View file

@ -12,7 +12,6 @@
namespace Sylius\Bundle\CoreBundle\Form\Extension;
use Sylius\Bundle\CoreBundle\Form\EventSubscriber\BuildChannelBasedPromotionRuleFormSubscriber;
use Sylius\Bundle\PromotionBundle\Form\Type\Core\AbstractConfigurationType;
use Sylius\Bundle\PromotionBundle\Form\Type\PromotionRuleChoiceType;
use Sylius\Bundle\PromotionBundle\Form\Type\PromotionRuleType;
use Sylius\Component\Channel\Repository\ChannelRepositoryInterface;

View file

@ -11,8 +11,7 @@
namespace Sylius\Bundle\CoreBundle\Form\Type\Promotion\Filter;
use Sylius\Bundle\ProductBundle\Form\Type\ProductChoiceType;
use Sylius\Component\Core\Repository\ProductRepositoryInterface;
use Sylius\Bundle\ResourceBundle\Form\Type\ResourceAutocompleteChoiceType;
use Symfony\Component\Form\AbstractType;
use Symfony\Component\Form\DataTransformerInterface;
use Symfony\Component\Form\FormBuilderInterface;
@ -41,10 +40,12 @@ final class ProductFilterConfigurationType extends AbstractType
public function buildForm(FormBuilderInterface $builder, array $options)
{
$builder
->add('products', ProductChoiceType::class, [
->add('products', ResourceAutocompleteChoiceType::class, [
'label' => 'sylius.form.promotion_filter.products',
'resource' => 'sylius.product',
'choice_name' => 'name',
'choice_value' => 'code',
'multiple' => true,
'required' => false,
])
;

View file

@ -11,7 +11,7 @@
namespace Sylius\Bundle\CoreBundle\Form\Type\Promotion\Filter;
use Sylius\Bundle\TaxonomyBundle\Form\Type\TaxonChoiceType;
use Sylius\Bundle\ResourceBundle\Form\Type\ResourceAutocompleteChoiceType;
use Symfony\Component\Form\AbstractType;
use Symfony\Component\Form\DataTransformerInterface;
use Symfony\Component\Form\FormBuilderInterface;
@ -41,10 +41,13 @@ final class TaxonFilterConfigurationType extends AbstractType
public function buildForm(FormBuilderInterface $builder, array $options)
{
$builder
->add('taxons', TaxonChoiceType::class, [
->add('taxons', ResourceAutocompleteChoiceType::class, [
'label' => 'sylius.form.promotion_filter.taxons',
'multiple' => true,
'required' => false,
'resource' => 'sylius.taxon',
'choice_name' => 'name',
'choice_value' => 'code',
])
;

View file

@ -11,9 +11,12 @@
namespace Sylius\Bundle\CoreBundle\Form\Type\Promotion\Rule;
use Sylius\Bundle\ProductBundle\Form\Type\ProductCodeChoiceType;
use Sylius\Bundle\ResourceBundle\Form\DataTransformer\ResourceToIdentifierTransformer;
use Sylius\Bundle\ResourceBundle\Form\Type\ResourceAutocompleteChoiceType;
use Sylius\Component\Resource\Repository\RepositoryInterface;
use Symfony\Component\Form\AbstractType;
use Symfony\Component\Form\FormBuilderInterface;
use Symfony\Component\Form\ReversedTransformer;
use Symfony\Component\Validator\Constraints\NotBlank;
use Symfony\Component\Validator\Constraints\Type;
@ -23,20 +26,38 @@ use Symfony\Component\Validator\Constraints\Type;
*/
final class ContainsProductConfigurationType extends AbstractType
{
/**
* @var RepositoryInterface
*/
private $productRepository;
/**
* @param RepositoryInterface $productRepository
*/
public function __construct(RepositoryInterface $productRepository)
{
$this->productRepository = $productRepository;
}
/**
* {@inheritdoc}
*/
public function buildForm(FormBuilderInterface $builder, array $options)
{
$builder
->add('product_code', ProductCodeChoiceType::class, [
->add('product_code', ResourceAutocompleteChoiceType::class, [
'label' => 'sylius.form.promotion_action.add_product_configuration.product',
'resource' => 'sylius.product',
'choice_name' => 'name',
'choice_value' => 'code',
'constraints' => [
new NotBlank(['groups' => ['sylius']]),
new Type(['type' => 'string', 'groups' => ['sylius']]),
],
])
;
$builder->get('product_code')->addModelTransformer(new ReversedTransformer(new ResourceToIdentifierTransformer($this->productRepository, 'code')));
}
/**

View file

@ -11,7 +11,7 @@
namespace Sylius\Bundle\CoreBundle\Form\Type\Promotion\Rule;
use Sylius\Bundle\TaxonomyBundle\Form\Type\TaxonChoiceType;
use Sylius\Bundle\ResourceBundle\Form\Type\ResourceAutocompleteChoiceType;
use Symfony\Component\Form\AbstractType;
use Symfony\Component\Form\DataTransformerInterface;
use Symfony\Component\Form\FormBuilderInterface;
@ -40,9 +40,12 @@ final class HasTaxonConfigurationType extends AbstractType
public function buildForm(FormBuilderInterface $builder, array $options)
{
$builder
->add('taxons', TaxonChoiceType::class, [
->add('taxons', ResourceAutocompleteChoiceType::class, [
'label' => 'sylius.form.promotion_rule.has_taxon.taxons',
'resource' => 'sylius.taxon',
'multiple' => true,
'choice_name' => 'name',
'choice_value' => 'code',
])
;

View file

@ -12,9 +12,12 @@
namespace Sylius\Bundle\CoreBundle\Form\Type\Promotion\Rule;
use Sylius\Bundle\MoneyBundle\Form\Type\MoneyType;
use Sylius\Bundle\TaxonomyBundle\Form\Type\TaxonCodeChoiceType;
use Sylius\Bundle\ResourceBundle\Form\DataTransformer\ResourceToIdentifierTransformer;
use Sylius\Bundle\ResourceBundle\Form\Type\ResourceAutocompleteChoiceType;
use Sylius\Component\Resource\Repository\RepositoryInterface;
use Symfony\Component\Form\AbstractType;
use Symfony\Component\Form\FormBuilderInterface;
use Symfony\Component\Form\ReversedTransformer;
use Symfony\Component\OptionsResolver\OptionsResolver;
/**
@ -22,20 +25,39 @@ use Symfony\Component\OptionsResolver\OptionsResolver;
*/
final class TotalOfItemsFromTaxonConfigurationType extends AbstractType
{
/**
* @var RepositoryInterface
*/
private $taxonRepository;
/**
* @param RepositoryInterface $taxonRepository
*/
public function __construct(RepositoryInterface $taxonRepository)
{
$this->taxonRepository = $taxonRepository;
}
/**
* {@inheritdoc}
*/
public function buildForm(FormBuilderInterface $builder, array $options)
{
$builder
->add('taxon', TaxonCodeChoiceType::class, [
->add('taxon', ResourceAutocompleteChoiceType::class, [
'label' => 'sylius.form.promotion_rule.total_of_items_from_taxon.taxon',
'resource' => 'sylius.taxon',
'multiple' => false,
'choice_name' => 'name',
'choice_value' => 'code',
])
->add('amount', MoneyType::class, [
'label' => 'sylius.form.promotion_rule.total_of_items_from_taxon.amount',
'currency' => $options['currency'],
])
;
$builder->get('taxon')->addModelTransformer(new ReversedTransformer(new ResourceToIdentifierTransformer($this->taxonRepository, 'code')));
}
/**

View file

@ -156,9 +156,11 @@
<tag name="form.type" />
</service>
<service id="sylius.form.type.promotion_rule.total_of_items_from_taxon_configuration" class="Sylius\Bundle\CoreBundle\Form\Type\Promotion\Rule\TotalOfItemsFromTaxonConfigurationType">
<argument type="service" id="sylius.repository.taxon" />
<tag name="form.type" />
</service>
<service id="sylius.form.type.promotion_rule.contains_product_configuration" class="Sylius\Bundle\CoreBundle\Form\Type\Promotion\Rule\ContainsProductConfigurationType">
<argument type="service" id="sylius.repository.product" />
<tag name="form.type" />
</service>
<service id="sylius.form.type.promotion.configuration" class="Sylius\Bundle\CoreBundle\Form\Type\Promotion\PromotionConfigurationType" />

View file

@ -26,13 +26,27 @@ class ProductRepository extends EntityRepository implements ProductRepositoryInt
public function findByName($name, $locale)
{
return $this->createQueryBuilder('o')
->innerJoin('o.translations', 'translation')
->innerJoin('o.translations', 'translation', 'WITH', 'translation.locale = :locale')
->andWhere('translation.name = :name')
->andWhere('translation.locale = :locale')
->setParameter('name', $name)
->setParameter('locale', $locale)
->getQuery()
->getResult()
;
}
/**
* {@inheritdoc}
*/
public function findByNamePart($phrase, $locale)
{
return $this->createQueryBuilder('o')
->innerJoin('o.translations', 'translation', 'WITH', 'translation.locale = :locale')
->andWhere('translation.name LIKE :name')
->setParameter('name', '%'.$phrase.'%')
->setParameter('locale', $locale)
->getQuery()
->getResult()
;
}
}

View file

@ -6,11 +6,11 @@ Sylius\Component\Product\Model\Product:
expose: true
type: integer
xml_attribute: true
groups: [Default, Detailed]
groups: [Default, Detailed, Autocomplete]
code:
expose: true
type: string
groups: [Default, Detailed]
groups: [Default, Detailed, Autocomplete]
options:
expose: true
type: array
@ -30,6 +30,7 @@ Sylius\Component\Product\Model\Product:
virtual_properties:
getName:
serialized_name: name
groups: [Default, Detailed, Autocomplete]
relations:
- rel: self
href:

View file

@ -129,7 +129,7 @@ abstract class AbstractConfigurationSubscriber implements EventSubscriberInterfa
}
/**
* @param PromotionDynamicTypeInterface|null $type
* @param PromotionDynamicTypeInterface|null $modelType
* @param FormInterface $form
*
* @return null|string

View file

@ -80,6 +80,7 @@ abstract class AbstractConfigurationCollectionType extends AbstractType
'allow_add' => true,
'allow_delete' => true,
'by_reference' => false,
'error_bubbling' => false,
]);
}

View file

@ -11,10 +11,7 @@
namespace Sylius\Bundle\PromotionBundle\Form\Type;
use Sylius\Bundle\PromotionBundle\Form\EventListener\BuildPromotionActionFormSubscriber;
use Sylius\Bundle\PromotionBundle\Form\Type\Core\AbstractConfigurationType;
use Sylius\Bundle\ResourceBundle\Form\Type\AbstractResourceType;
use Sylius\Component\Registry\ServiceRegistryInterface;
use Symfony\Component\EventDispatcher\EventSubscriberInterface;
use Symfony\Component\Form\FormBuilderInterface;
use Symfony\Component\OptionsResolver\OptionsResolver;

View file

@ -11,11 +11,8 @@
namespace Sylius\Bundle\PromotionBundle\Form\Type;
use Sylius\Bundle\PromotionBundle\Form\EventListener\BuildPromotionRuleFormSubscriber;
use Sylius\Bundle\PromotionBundle\Form\Type\Core\AbstractConfigurationType;
use Sylius\Bundle\ResourceBundle\Form\Type\AbstractResourceType;
use Sylius\Component\Promotion\Checker\Rule\ItemTotalRuleChecker;
use Sylius\Component\Registry\ServiceRegistryInterface;
use Symfony\Component\EventDispatcher\EventSubscriberInterface;
use Symfony\Component\Form\FormBuilderInterface;
use Symfony\Component\OptionsResolver\OptionsResolver;
@ -39,7 +36,6 @@ final class PromotionRuleType extends AbstractResourceType
public function __construct(
$dataClass,
array $validationGroups,
ServiceRegistryInterface $registry,
EventSubscriberInterface $buildRuleSubscriber
) {
parent::__construct($dataClass, $validationGroups);

View file

@ -44,7 +44,6 @@
<service id="sylius.form.type.promotion_rule" class="Sylius\Bundle\PromotionBundle\Form\Type\PromotionRuleType">
<argument>%sylius.model.promotion_rule.class%</argument>
<argument>%sylius.form.type.promotion_rule.validation_groups%</argument>
<argument type="service" id="sylius.registry_promotion_rule_checker" />
<argument type="service" id="sylius.form.event_subscriber.build_promotion_rule" />
<tag name="form.type" />
</service>

View file

@ -58,5 +58,8 @@
<property name="actions">
<constraint name="Valid" />
</property>
<property name="rules">
<constraint name="Valid" />
</property>
</class>
</constraint-mapping>

View file

@ -0,0 +1,20 @@
<?xml version="1.0" encoding="UTF-8"?>
<!--
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.
-->
<constraint-mapping xmlns="http://symfony.com/schema/dic/constraint-mapping" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://symfony.com/schema/dic/constraint-mapping http://symfony.com/schema/dic/services/constraint-mapping-1.0.xsd">
<class name="Sylius\Component\Promotion\Model\PromotionRule">
<property name="configuration">
<constraint name="Valid" />
</property>
</class>
</constraint-mapping>

View file

@ -94,6 +94,7 @@ class ResourceAutocompleteChoiceType extends AbstractType
])
->setDefaults([
'multiple' => false,
'error_bubbling' => false,
'placeholder' => '',
'repository' => function (Options $options) {
return $this->resourceRepositoryRegistry->get($options['resource']);

View file

@ -203,9 +203,10 @@
data-criteria-name="{{ remote_criteria_name }}"
data-load-edit-url="{{ load_edit_url }}"
>
{{ form_row(form, {'attr': {'class' : 'autocomplete'}}) }}
{{ form_widget(form, {'attr': {'class' : 'autocomplete'}}) }}
<i class="dropdown icon"></i>
<div class="default text">{% if placeholder is defined %} {{ placeholder|trans }} {% endif %}</div>
<div class="menu"></div>
</div>
{{ form_errors(form) }}
{% endblock %}

View file

@ -26,4 +26,12 @@ interface ProductRepositoryInterface extends RepositoryInterface
* @return ProductInterface[]
*/
public function findByName($name, $locale);
/**
* @param string $phrase
* @param string $locale
*
* @return ProductInterface[]
*/
public function findByNamePart($phrase, $locale);
}

View file

@ -357,15 +357,10 @@ EOT;
"max": 12000
},
"taxons_filter": {
"taxons": [
"mugs"
]
"taxons": "mugs"
},
"products_filter": {
"products": [
"MUG_SW",
"MUG_LOTR"
]
"products": "MUG_SW,MUG_LOTR"
}
}
},
@ -373,9 +368,7 @@ EOT;
"percentage": 20,
"filters": {
"products_filter": {
"products": [
"MUG_SW"
]
"products": "MUG_SW"
}
}
}
@ -395,13 +388,13 @@ EOT;
]
}
EOT;
$this->client->request('POST', '/api/v1/promotions/', [], [], static::$authorizedHeaderWithContentType, $data);
$response = $this->client->getResponse();
$this->assertResponse($response, 'promotion/create_response_with_actions', Response::HTTP_CREATED);
}
/**
* @test
*/
@ -457,7 +450,8 @@ EOT;
$data =
<<<EOT
{
"name": "Monday promotion"
"name": "Monday promotion",
"priority": 0
}
EOT;
$this->client->request('PUT', $this->getPromotionUrl($promotion), [], [], static::$authorizedHeaderWithContentType, $data);
@ -483,8 +477,7 @@ EOT;
$data =
<<<EOT
{
"exclusive": true,
"priority": 0
"exclusive": true
}
EOT;
$this->client->request('PATCH', $this->getPromotionUrl($promotion), [], [], static::$authorizedHeaderWithContentType, $data);

View file

@ -6,6 +6,7 @@ Sylius\Component\Core\Model\Channel:
description: "Lorem ipsum"
baseCurrency: "@currency1"
defaultLocale: "@locale"
locales: ["@locale"]
color: "black"
enabled: true
taxCalculationStrategy: "order_items_based"
@ -16,6 +17,7 @@ Sylius\Component\Core\Model\Channel:
description: "Lorem ipsum psore"
baseCurrency: "@currency2"
defaultLocale: "@locale"
locales: ["@locale"]
color: "yellow"
enabled: true
taxCalculationStrategy: "order_items_based"