<?php
/*
* 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.
*/
declare(strict_types=1);
namespace App\Form\Type\Admin;
use Sylius\Bundle\ResourceBundle\Form\Type\AbstractResourceType;
use Sylius\Bundle\ResourceBundle\Form\Type\ResourceAutocompleteChoiceType;
use Sylius\Component\Core\Repository\ProductVariantRepositoryInterface;
use Sylius\Component\Inventory\Checker\AvailabilityCheckerInterface;
use Sylius\Component\Order\Repository\OrderItemRepositoryInterface;
use Symfony\Component\Form\DataMapperInterface;
use Symfony\Component\Form\Extension\Core\Type\IntegerType;
use Symfony\Component\Form\FormBuilderInterface;
use Symfony\Component\Form\FormError;
use Symfony\Component\Form\FormEvent;
use Symfony\Component\Form\FormEvents;
use Symfony\Component\Validator\Constraints\NotBlank;
final class OrderItemType extends AbstractResourceType
{
/** @var DataMapperInterface */
private $dataMapper;
private $orderItemRepository;
private AvailabilityCheckerInterface $availabilityChecker;
private ProductVariantRepositoryInterface $productVariantRepository;
public function __construct(
string $dataClass,
array $validationGroups = [],
DataMapperInterface $dataMapper,
OrderItemRepositoryInterface $orderItemRepository,
AvailabilityCheckerInterface $availabilityChecker,
ProductVariantRepositoryInterface $productVariantRepository
) {
parent::__construct($dataClass, $validationGroups);
$this->dataMapper = $dataMapper;
$this->orderItemRepository = $orderItemRepository;
$this->availabilityChecker = $availabilityChecker;
$this->productVariantRepository = $productVariantRepository;
}
public function buildForm(FormBuilderInterface $builder, array $options): void
{
$builder
->add('variant', ResourceAutocompleteChoiceType::class, [
'label' => 'sylius.ui.variant',
'choice_name' => 'descriptor',
'choice_value' => 'code',
'resource' => 'sylius.product_variant',
'constraints' => [
new NotBlank(['message' => 'Veuillez renseigner une variante', 'groups' => ['sylius']]),
],
])
->add('quantity', IntegerType::class, [
'attr' => ['min' => 1],
'label' => 'sylius.ui.quantity',
'constraints' => [
new NotBlank(['message' => 'Veuillez saisir une quantité', 'groups' => ['sylius']]),
],
])
->setDataMapper($this->dataMapper)
->addEventListener(FormEvents::PRE_SUBMIT, function (FormEvent $event) use ($options): void {
$orderItem = $event->getForm()->getNormData();
$order = $event->getForm()->getParent()->getParent()->getNormData();
$qte = (int) $event->getData()['quantity'];
if (null !== $orderItem) {
//Si on modifie un orderItem
$variant = $orderItem->getVariant();
$order = $orderItem->getOrder();
$delta = $qte - $orderItem->getQuantity();
if (0 !== $delta) {
if ($delta > 0 and !$this->availabilityChecker->isStockSufficient($orderItem->getVariant(), $delta)) {
$event->getForm()->addError(new FormError('STOCK ARTICLE ' . $variant->getCode() . ' INSUFFISANT'));
} else {
if (in_array($order->getPaymentState(), ['paid', 'refunded', 'partially_refunded'])) {
$variant->setOnHand($variant->getOnHand() - $delta);
} else {
$variant->setOnHold($variant->getOnHold() + $delta);
}
}
}
} else {
//Si on ajoute un orderItem
$variant = $this->productVariantRepository->findOneBy(['code' => $event->getData('variant')]);
if (!$this->availabilityChecker->isStockSufficient($variant, $qte)) {
$event->getForm()->addError(new FormError('STOCK ARTICLE ' . $variant->getCode() . ' INSUFFISANT'));
} else {
if (in_array($order->getPaymentState(), ['paid', 'refunded', 'partially_refunded'])) {
$variant->setOnHand($variant->getOnHand() - $qte);
} else {
$variant->setOnHold($variant->getOnHold() + $qte);
}
}
}
})
;
}
public function getBlockPrefix(): string
{
return 'app_order_update_item_block';
}
}