1<?php
2/**
3 * Copyright since 2007 PrestaShop SA and Contributors
4 * PrestaShop is an International Registered Trademark & Property of PrestaShop SA
5 *
6 * NOTICE OF LICENSE
7 *
8 * This source file is subject to the Open Software License (OSL 3.0)
9 * that is bundled with this package in the file LICENSE.md.
10 * It is also available through the world-wide-web at this URL:
11 * https://opensource.org/licenses/OSL-3.0
12 * If you did not receive a copy of the license and are unable to
13 * obtain it through the world-wide-web, please send an email
14 * to license@prestashop.com so we can send you a copy immediately.
15 *
16 * DISCLAIMER
17 *
18 * Do not edit or add to this file if you wish to upgrade PrestaShop to newer
19 * versions in the future. If you wish to customize PrestaShop for your
20 * needs please refer to https://devdocs.prestashop.com/ for more information.
21 *
22 * @author    PrestaShop SA and Contributors <contact@prestashop.com>
23 * @copyright Since 2007 PrestaShop SA and Contributors
24 * @license   https://opensource.org/licenses/OSL-3.0 Open Software License (OSL 3.0)
25 */
26
27namespace PrestaShopBundle\Form\Admin\Sell\CatalogPriceRule;
28
29use PrestaShop\PrestaShop\Core\ConstraintValidator\Constraints\CleanHtml;
30use PrestaShop\PrestaShop\Core\ConstraintValidator\Constraints\DateRange;
31use PrestaShop\PrestaShop\Core\ConstraintValidator\Constraints\Reduction;
32use PrestaShop\PrestaShop\Core\Domain\ValueObject\Reduction as ReductionVO;
33use PrestaShopBundle\Form\Admin\Type\DateRangeType;
34use PrestaShopBundle\Form\Admin\Type\ReductionType;
35use Symfony\Component\Form\AbstractType;
36use Symfony\Component\Form\Extension\Core\Type\CheckboxType;
37use Symfony\Component\Form\Extension\Core\Type\ChoiceType;
38use Symfony\Component\Form\Extension\Core\Type\NumberType;
39use Symfony\Component\Form\Extension\Core\Type\TextType;
40use Symfony\Component\Form\FormBuilderInterface;
41use Symfony\Component\Translation\TranslatorInterface;
42use Symfony\Component\Validator\Constraints\GreaterThanOrEqual;
43
44/**
45 * Defines catalog price rule form for create/edit actions
46 */
47class CatalogPriceRuleType extends AbstractType
48{
49    /**
50     * @var TranslatorInterface
51     */
52    private $translator;
53
54    /**
55     * @var bool
56     */
57    private $isMultishopEnabled;
58
59    /**
60     * @var array
61     */
62    private $currencyByIdChoices;
63
64    /**
65     * @var array
66     */
67    private $countryByIdChoices;
68
69    /**
70     * @var array
71     */
72    private $groupByIdChoices;
73
74    /**
75     * @var array
76     */
77    private $shopByIdChoices;
78
79    /**
80     * @var array
81     */
82    private $taxInclusionChoices;
83
84    /**
85     * @param TranslatorInterface $translator
86     * @param bool $isMultishopEnabled
87     * @param array $currencyByIdChoices
88     * @param array $countryByIdChoices
89     * @param array $groupByIdChoices
90     * @param array $shopByIdChoices
91     * @param array $taxInclusionChoices
92     */
93    public function __construct(
94        TranslatorInterface $translator,
95        bool $isMultishopEnabled,
96        array $currencyByIdChoices,
97        array $countryByIdChoices,
98        array $groupByIdChoices,
99        array $shopByIdChoices,
100        array $taxInclusionChoices
101    ) {
102        $this->translator = $translator;
103        $this->isMultishopEnabled = $isMultishopEnabled;
104        $this->currencyByIdChoices = $currencyByIdChoices;
105        $this->countryByIdChoices = $countryByIdChoices;
106        $this->groupByIdChoices = $groupByIdChoices;
107        $this->shopByIdChoices = $shopByIdChoices;
108        $this->taxInclusionChoices = $taxInclusionChoices;
109    }
110
111    /**
112     * {@inheritdoc}
113     */
114    public function buildForm(FormBuilderInterface $builder, array $options)
115    {
116        $builder
117            ->add('name', TextType::class, [
118                'constraints' => [
119                    new CleanHtml(),
120                ],
121            ])
122            ->add('id_currency', ChoiceType::class, [
123                'required' => false,
124                'placeholder' => false,
125                'choices' => $this->getModifiedCurrencyChoices(),
126            ])
127            ->add('id_country', ChoiceType::class, [
128                'required' => false,
129                'placeholder' => false,
130                'choices' => $this->getModifiedCountryChoices(),
131            ])
132            ->add('id_group', ChoiceType::class, [
133                'required' => false,
134                'placeholder' => false,
135                'choices' => $this->getModifiedGroupChoices(),
136            ])
137            ->add('from_quantity', NumberType::class, [
138                'scale' => 0,
139                'constraints' => [
140                    new GreaterThanOrEqual([
141                        'value' => 0,
142                        'message' => $this->translator->trans(
143                            '%s is invalid.',
144                            [],
145                            'Admin.Notifications.Error'
146                        ),
147                    ]),
148                ],
149            ])
150            ->add('price', NumberType::class, [
151                'required' => false,
152                'scale' => 6,
153                'constraints' => [
154                    new GreaterThanOrEqual([
155                        'value' => 0,
156                        'message' => $this->translator->trans(
157                            '%s is invalid.',
158                            [],
159                            'Admin.Notifications.Error'
160                        ),
161                    ]),
162                ],
163            ])
164            ->add('leave_initial_price', CheckboxType::class, [
165                'required' => false,
166            ])
167            ->add('date_range', DateRangeType::class, [
168                'date_format' => 'YYYY-MM-DD HH:mm:ss',
169                'constraints' => [
170                    new DateRange([
171                        'message' => $this->translator->trans(
172                            'The selected date range is not valid.',
173                            [],
174                            'Admin.Notifications.Error'
175                        ),
176                    ]),
177                ],
178            ])
179            ->add('include_tax', ChoiceType::class, [
180                'placeholder' => false,
181                'required' => false,
182                'choices' => $this->taxInclusionChoices,
183            ])
184            ->add('reduction', ReductionType::class, [
185                'constraints' => [
186                    new Reduction([
187                        'invalidPercentageValueMessage' => $this->translator->trans(
188                            'Reduction value "%value%" is invalid. Allowed values from 0 to %max%',
189                            ['%max%' => ReductionVO::MAX_ALLOWED_PERCENTAGE . '%'],
190                            'Admin.Notifications.Error'
191                        ),
192                        'invalidAmountValueMessage' => $this->translator->trans(
193                            'Reduction value "%value%" is invalid. Value cannot be negative',
194                            [],
195                            'Admin.Notifications.Error'
196                        ),
197                    ]),
198                ],
199            ])
200        ;
201
202        if ($this->isMultishopEnabled) {
203            $builder->add('id_shop', ChoiceType::class, [
204                'required' => false,
205                'placeholder' => false,
206                'choices' => $this->shopByIdChoices,
207            ]);
208        }
209    }
210
211    /**
212     * Prepends 'All currencies' option with id of 0 to currency choices
213     *
214     * @return array
215     */
216    private function getModifiedCurrencyChoices(): array
217    {
218        return array_merge(
219            [$this->translator->trans('All currencies', [], 'Admin.Global') => 0],
220            $this->currencyByIdChoices
221        );
222    }
223
224    /**
225     * Prepends 'All countries' option with id of 0 to country choices
226     *
227     * @return array
228     */
229    private function getModifiedCountryChoices(): array
230    {
231        return array_merge(
232            [$this->translator->trans('All countries', [], 'Admin.Global') => 0],
233            $this->countryByIdChoices
234        );
235    }
236
237    /**
238     * Prepends 'All groups' option with id of 0 to group choices
239     *
240     * @return array
241     */
242    private function getModifiedGroupChoices(): array
243    {
244        return array_merge(
245            [$this->translator->trans('All groups', [], 'Admin.Global') => 0],
246            $this->groupByIdChoices
247        );
248    }
249}
250