diff --git a/src/DependencyInjection/SetonoSyliusOrderEditExtension.php b/src/DependencyInjection/SetonoSyliusOrderEditExtension.php index dceb25a..79e293a 100644 --- a/src/DependencyInjection/SetonoSyliusOrderEditExtension.php +++ b/src/DependencyInjection/SetonoSyliusOrderEditExtension.php @@ -51,6 +51,13 @@ public function prepend(ContainerBuilder $container): void ], ], ], + 'sylius.admin.order.show.summary' => [ + 'blocks' => [ + 'store_notes' => [ + 'template' => '@SetonoSyliusOrderEditPlugin/admin/order/show/_store_notes.html.twig', + ], + ], + ], ], ]); diff --git a/src/Entity/EditableOrderInterface.php b/src/Entity/EditableOrderInterface.php index 3fc0df0..da1f97f 100644 --- a/src/Entity/EditableOrderInterface.php +++ b/src/Entity/EditableOrderInterface.php @@ -13,4 +13,8 @@ public function isAlreadyPaid(): bool; public function getInitialTotal(): int; public function setInitialTotal(int $initialTotal): void; + + public function getStoreNotes(): ?string; + + public function setStoreNotes(?string $storeNotes): void; } diff --git a/src/Entity/EditableOrderTrait.php b/src/Entity/EditableOrderTrait.php index 8338ad8..45ec84c 100644 --- a/src/Entity/EditableOrderTrait.php +++ b/src/Entity/EditableOrderTrait.php @@ -15,6 +15,10 @@ trait EditableOrderTrait #[ORM\Column(type: 'integer')] private int $initialTotal = 0; + /** @ORM\Column(type="text", nullable=true) */ + #[ORM\Column(type: 'text', nullable: true)] + private ?string $storeNotes = null; + public function isAlreadyPaid(): bool { return $this->getPaymentState() === OrderPaymentStates::STATE_PAID; @@ -29,4 +33,14 @@ public function setInitialTotal(int $initialTotal): void { $this->initialTotal = $initialTotal; } + + public function getStoreNotes(): ?string + { + return $this->storeNotes; + } + + public function setStoreNotes(?string $storeNotes): void + { + $this->storeNotes = $storeNotes; + } } diff --git a/src/Form/Extension/OrderTypeExtension.php b/src/Form/Extension/OrderTypeExtension.php index f43dbcb..97dd49f 100644 --- a/src/Form/Extension/OrderTypeExtension.php +++ b/src/Form/Extension/OrderTypeExtension.php @@ -9,6 +9,7 @@ use Sylius\Bundle\OrderBundle\Form\Type\OrderType; use Sylius\Component\Core\Model\OrderInterface; use Symfony\Component\Form\AbstractTypeExtension; +use Symfony\Component\Form\Extension\Core\Type\TextareaType; use Symfony\Component\Form\FormBuilderInterface; use Symfony\Component\Form\FormEvent; use Symfony\Component\Form\FormEvents; @@ -17,6 +18,14 @@ final class OrderTypeExtension extends AbstractTypeExtension { public function buildForm(FormBuilderInterface $builder, array $options): void { + $builder->add('storeNotes', TextareaType::class, [ + 'required' => false, + 'label' => 'setono_sylius_order_edit.ui.store_notes', + 'attr' => [ + 'placeholder' => 'setono_sylius_order_edit.ui.store_notes_placeholder', + ], + ]); + $builder->addEventListener(FormEvents::PRE_SET_DATA, function (FormEvent $event): void { $form = $event->getForm(); /** @var OrderInterface $order */ @@ -26,15 +35,14 @@ public function buildForm(FormBuilderInterface $builder, array $options): void ->add('items', OrderItemCollectionType::class, [ 'entry_options' => ['currency_code' => $order->getCurrencyCode()], ]) + ->add('discounts', OrderDiscountCollectionType::class, [ + 'property_path' => 'adjustments', + 'entry_options' => [ + 'currency' => $order->getCurrencyCode(), + ], + 'button_add_label' => 'setono_sylius_order_edit.ui.add_discount', + ]) ; - - $form->add('discounts', OrderDiscountCollectionType::class, [ - 'property_path' => 'adjustments', - 'entry_options' => [ - 'currency' => $order->getCurrencyCode(), - ], - 'button_add_label' => 'setono_sylius_order_edit.ui.add_discount', - ]); }); $builder->addEventListener(FormEvents::PRE_SUBMIT, function (FormEvent $event): void { diff --git a/src/Resources/translations/messages.en.yaml b/src/Resources/translations/messages.en.yaml index a113870..6923488 100644 --- a/src/Resources/translations/messages.en.yaml +++ b/src/Resources/translations/messages.en.yaml @@ -5,3 +5,5 @@ setono_sylius_order_edit: discounts: Discounts order_discounts: Order discounts order_items: Order items + store_notes: Store notes + store_notes_placeholder: If you want to add a note regarding your changes, you can do it here. The customer will not be able to see this note... diff --git a/src/Resources/views/admin/order/show/_store_notes.html.twig b/src/Resources/views/admin/order/show/_store_notes.html.twig new file mode 100644 index 0000000..cef43ae --- /dev/null +++ b/src/Resources/views/admin/order/show/_store_notes.html.twig @@ -0,0 +1,10 @@ +{% if order.storeNotes is not null %} +
+

+ {{ 'setono_sylius_order_edit.ui.store_notes'|trans }} +

+
+ {{ order.storeNotes }} +
+
+{% endif %} diff --git a/src/Resources/views/admin/order/update/_store_notes.html.twig b/src/Resources/views/admin/order/update/_store_notes.html.twig new file mode 100644 index 0000000..9906c43 --- /dev/null +++ b/src/Resources/views/admin/order/update/_store_notes.html.twig @@ -0,0 +1,3 @@ +
+ {{ form_row(form.storeNotes) }} +
diff --git a/tests/Application/templates/bundles/SyliusAdminBundle/Order/Update/_content.html.twig b/tests/Application/templates/bundles/SyliusAdminBundle/Order/Update/_content.html.twig index 63e27dc..40b725a 100644 --- a/tests/Application/templates/bundles/SyliusAdminBundle/Order/Update/_content.html.twig +++ b/tests/Application/templates/bundles/SyliusAdminBundle/Order/Update/_content.html.twig @@ -5,6 +5,7 @@ {{ include('@SetonoSyliusOrderEditPlugin/admin/order/update/_order_items.html.twig') }} + {{ include('@SetonoSyliusOrderEditPlugin/admin/order/update/_store_notes.html.twig') }}
diff --git a/tests/Functional/OrderUpdateTest.php b/tests/Functional/OrderUpdateTest.php index 74d4097..d7fe5d2 100644 --- a/tests/Functional/OrderUpdateTest.php +++ b/tests/Functional/OrderUpdateTest.php @@ -7,6 +7,7 @@ use Doctrine\ORM\EntityManagerInterface; use Setono\SyliusOrderEditPlugin\Entity\EditableOrderInterface; use Setono\SyliusOrderEditPlugin\Model\AdjustmentTypes; +use Setono\SyliusOrderEditPlugin\Tests\Application\Entity\Order; use Sylius\Bundle\ApiBundle\Command\Cart\AddItemToCart; use Sylius\Bundle\ApiBundle\Command\Cart\PickupCart; use Sylius\Bundle\ApiBundle\Command\Checkout\ChoosePaymentMethod; @@ -15,7 +16,6 @@ use Sylius\Bundle\ApiBundle\Command\Checkout\UpdateCart; use Sylius\Component\Core\Model\Address; use Sylius\Component\Core\Model\AdjustmentInterface; -use Sylius\Component\Core\Model\Order; use Sylius\Component\Core\Model\OrderInterface; use Sylius\Component\Core\Model\ProductVariantInterface; use Sylius\Component\Core\Repository\OrderRepositoryInterface; @@ -190,6 +190,24 @@ public function testItAllowsToAddAndRemoveDiscountsForTheOrderItemMultipleTimes( ); } + public function testItAllowsToAddStoreNotes(): void + { + $this->makeVariantTrackedWithStockAndPrice('000F_office_grey_jeans-variant-0', 100); + + $order = $this->placeOrderProgramatically(quantity: 5); + + $this->loginAsAdmin(); + $this->addStoreNotes($order->getId(), 'store notes'); + + self::assertResponseStatusCodeSame(302); + + $this->getEntityManager()->clear(); + + /** @var EditableOrderInterface $order */ + $order = $this->getOrderRepository()->findOneBy(['tokenValue' => 'TOKEN']); + self::assertSame('store notes', $order->getStoreNotes()); + } + private function placeOrderProgramatically( string $variantCode = '000F_office_grey_jeans-variant-0', int $quantity = 1, @@ -346,6 +364,22 @@ private function addDiscountsToOrderItem(int $orderId, array $discounts): void ); } + private function addStoreNotes(int $orderId, ?string $storeNotes): void + { + static::$client->request( + 'PATCH', + sprintf('/admin/orders/%d/update-and-process', $orderId), + [], + [], + ['CONTENT_TYPE' => 'application/json'], + json_encode([ + 'sylius_order' => [ + 'storeNotes' => $storeNotes, + ], + ]), + ); + } + private function getOrderRepository(): OrderRepositoryInterface { return self::getContainer()->get('sylius.repository.order'); @@ -361,12 +395,12 @@ private function getEntityManager(): EntityManagerInterface return self::getContainer()->get('doctrine.orm.entity_manager'); } - private function getInitialTotal(Order|InitialTotalAwareOrderInterface $order) + private function getInitialTotal(Order $order): int { return $order->getInitialTotal() - $order->getAdjustmentsTotalRecursively(AdjustmentInterface::TAX_ADJUSTMENT); } - private function getResultTotal(Order|InitialTotalAwareOrderInterface $order) + private function getResultTotal(Order $order): int { return $order->getTotal() - $order->getAdjustmentsTotalRecursively(AdjustmentInterface::TAX_ADJUSTMENT); } diff --git a/tests/Unit/Entity/EditableOrderTraitTest.php b/tests/Unit/Entity/EditableOrderTraitTest.php new file mode 100644 index 0000000..3c4967b --- /dev/null +++ b/tests/Unit/Entity/EditableOrderTraitTest.php @@ -0,0 +1,30 @@ +setInitialTotal(1000); + + self::assertSame(1000, $order->getInitialTotal()); + } + + public function testItAllowsSettingStoreNotesAndNullingThem(): void + { + $order = new Order(); + $order->setStoreNotes('Store notes'); + + self::assertSame('Store notes', $order->getStoreNotes()); + + $order->setStoreNotes(null); + self::assertNull($order->getStoreNotes()); + } +}