From bb6a56e1efc9ecfdb2e1330ed9bf81a5931709b0 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Tomasz=20Kali=C5=84ski?= Date: Tue, 6 Aug 2024 08:28:34 +0200 Subject: [PATCH 01/16] OP-319 - Extended shipping export by a parameter parcel_template --- src/Entity/ShippingExportInterface.php | 12 +++++++++++ .../Application/src/Entity/ShippingExport.php | 21 +++++++++++++++++++ .../config/doctrine/ShippingExport.orm.xml | 9 ++++++++ 3 files changed, 42 insertions(+) create mode 100644 src/Entity/ShippingExportInterface.php create mode 100644 tests/Application/src/Entity/ShippingExport.php create mode 100644 tests/Application/src/Resources/config/doctrine/ShippingExport.orm.xml diff --git a/src/Entity/ShippingExportInterface.php b/src/Entity/ShippingExportInterface.php new file mode 100644 index 0000000..da85e82 --- /dev/null +++ b/src/Entity/ShippingExportInterface.php @@ -0,0 +1,12 @@ +parcel_template; + } + + public function setParcelTemplate(?string $parcel_template): void + { + $this->parcel_template = $parcel_template; + } +} diff --git a/tests/Application/src/Resources/config/doctrine/ShippingExport.orm.xml b/tests/Application/src/Resources/config/doctrine/ShippingExport.orm.xml new file mode 100644 index 0000000..041d614 --- /dev/null +++ b/tests/Application/src/Resources/config/doctrine/ShippingExport.orm.xml @@ -0,0 +1,9 @@ + + + + + From c74bc5fcbfe19fff462eeaf657e7e72f99a37a14 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Tomasz=20Kali=C5=84ski?= Date: Tue, 6 Aug 2024 13:46:31 +0200 Subject: [PATCH 02/16] OP-319 - Added select parcel template column --- src/Api/WebClient.php | 22 +++- src/Api/WebClientInterface.php | 6 +- src/Controller/ShippingExportController.php | 98 +++++++++++++++ .../SelectParcelTemplateEventListener.php | 28 +++++ .../SelectParcelTemplateAction.php | 28 +++++ .../SelectParcelTemplateActionInterface.php | 10 ++ .../ShippingExportEventListener.php | 4 +- src/Resources/config/grid/order.yml | 112 +++++++++++++----- src/Resources/config/routes.yml | 6 + src/Resources/config/services.xml | 7 ++ .../select_parcel_template_action.xml | 20 ++++ src/Resources/translations/messages.en.yml | 7 ++ .../Grid/Field/parcel_template.html.twig | 26 ++++ .../bitbag_sylius_shipping_export_plugin.yaml | 9 +- 14 files changed, 344 insertions(+), 39 deletions(-) create mode 100644 src/Controller/ShippingExportController.php create mode 100644 src/EventListener/SelectParcelTemplateEventListener.php create mode 100644 src/EventListener/SelectParcelTemplateEventListener/SelectParcelTemplateAction.php create mode 100644 src/EventListener/SelectParcelTemplateEventListener/SelectParcelTemplateActionInterface.php create mode 100644 src/Resources/config/services/select_parcel_template_action.xml create mode 100644 src/Resources/views/ShippingExport/Grid/Field/parcel_template.html.twig diff --git a/src/Api/WebClient.php b/src/Api/WebClient.php index 5450e43..56278f3 100644 --- a/src/Api/WebClient.php +++ b/src/Api/WebClient.php @@ -11,6 +11,7 @@ namespace BitBag\SyliusInPostPlugin\Api; use BitBag\SyliusInPostPlugin\Entity\InPostPoint; +use BitBag\SyliusInPostPlugin\Entity\ShippingExportInterface; use BitBag\SyliusInPostPlugin\Model\InPostPointsAwareInterface; use BitBag\SyliusShippingExportPlugin\Entity\ShippingGatewayInterface; use GuzzleHttp\Client; @@ -35,6 +36,8 @@ final class WebClient implements WebClientInterface private ShippingGatewayInterface $shippingGateway; + private ?ShippingExportInterface $shippingExport = null; + private string $labelType = 'normal'; public function __construct(Client $client, string $labelType) @@ -137,8 +140,12 @@ public function getShipments(): ?array return $this->request('GET', $url); } - public function createShipment(ShipmentInterface $shipment): array - { + public function createShipment( + ShipmentInterface $shipment, + ?ShippingExportInterface $shippingExport = null + ): array { + $this->shippingExport = $shippingExport; + /** @var OrderInterface $order */ $order = $shipment->getOrder(); @@ -296,9 +303,14 @@ private function isCashOnDelivery(OrderInterface $order): bool return false; } - private function createParcel(ShipmentInterface $shipment): array - { + private function createParcel( + ShipmentInterface $shipment + ): array{ $weight = $shipment->getShippingWeight(); + $template = 'large'; + if (null !== $this->shippingExport) { + $template = $this->shippingExport->getParcelTemplate(); + } return [ 'id' => $shipment->getId(), @@ -307,7 +319,7 @@ private function createParcel(ShipmentInterface $shipment): array 'unit' => 'kg', ], 'dimensions' => [], - 'template' => 'large', + 'template' => $template, 'tracking_number' => null, 'is_non_standard' => false, ]; diff --git a/src/Api/WebClientInterface.php b/src/Api/WebClientInterface.php index 9e9c06d..22128c9 100644 --- a/src/Api/WebClientInterface.php +++ b/src/Api/WebClientInterface.php @@ -10,6 +10,7 @@ namespace BitBag\SyliusInPostPlugin\Api; +use BitBag\SyliusInPostPlugin\Entity\ShippingExportInterface; use BitBag\SyliusShippingExportPlugin\Entity\ShippingGatewayInterface; use GuzzleHttp\Exception\GuzzleException; use Sylius\Component\Core\Model\ShipmentInterface; @@ -54,6 +55,9 @@ interface WebClientInterface public const ROD_ADDITIONAL_SERVICE = 'rod'; + public const TEMPLATE_SELECT_EVENT = 'export_shipping_select_parcel_template'; + + public function setShippingGateway(ShippingGatewayInterface $shippingGateway): self; public function getApiEndpoint(): string; @@ -78,7 +82,7 @@ public function getLabels(array $shipmentIds): ?string; public function getAuthorizedHeaderWithContentType(): array; - public function createShipment(ShipmentInterface $shipment): array; + public function createShipment(ShipmentInterface $shipment, ?ShippingExportInterface $shippingExport = null): array; /** * @return mixed|string diff --git a/src/Controller/ShippingExportController.php b/src/Controller/ShippingExportController.php new file mode 100644 index 0000000..6fae616 --- /dev/null +++ b/src/Controller/ShippingExportController.php @@ -0,0 +1,98 @@ +requestConfigurationFactory->create($this->metadata, $request); + + Assert::implementsInterface($this->repository, ShippingExportRepositoryInterface::class); + $shippingExports = $this->repository->findAllWithNewOrPendingState(); + + if (0 === count($shippingExports)) { + /** @var FlashBagInterface $flashBag */ + $flashBag = $request->getSession()->getBag('flashes'); + $flashBag->add('error', 'bitbag.ui.no_new_shipments_to_export'); + + return $this->redirectToReferer($request); + } + + foreach ($shippingExports as $shippingExport) { + $this->eventDispatcher->dispatch( + ExportShipmentEvent::SHORT_NAME, + $configuration, + $shippingExport + ); + } + + return $this->redirectToReferer($request); + } + + public function exportSingleShipmentAction(Request $request): RedirectResponse + { + $configuration = $this->requestConfigurationFactory->create($this->metadata, $request); + + /** @var ResourceInterface|null $shippingExport */ + $shippingExport = $this->repository->find($request->get('id')); + Assert::notNull($shippingExport); + + $this->eventDispatcher->dispatch( + ExportShipmentEvent::SHORT_NAME, + $configuration, + $shippingExport + ); + + return $this->redirectToReferer($request); + } + + public function selectParcelTemplate(Request $request): RedirectResponse + { + $configuration = $this->requestConfigurationFactory->create($this->metadata, $request); + + /** @var ResourceInterface|null $shippingExport */ + $shippingExport = $this->repository->find($request->get('id')); + Assert::notNull($shippingExport); + + /** @var ShippingExportInterface $shippingExport */ + $shippingExport?->setParcelTemplate($request->get('template')); + + $this->eventDispatcher->dispatch( + WebClientInterface::TEMPLATE_SELECT_EVENT, + $configuration, + $shippingExport + ); + + return $this->redirectToReferer($request); + } + + private function redirectToReferer(Request $request): RedirectResponse + { + $referer = $request->headers->get('referer'); + if (null !== $referer) { + return new RedirectResponse($referer); + } + + return $this->redirectToRoute($request->attributes->get('_route')); + } +} diff --git a/src/EventListener/SelectParcelTemplateEventListener.php b/src/EventListener/SelectParcelTemplateEventListener.php new file mode 100644 index 0000000..b6f6237 --- /dev/null +++ b/src/EventListener/SelectParcelTemplateEventListener.php @@ -0,0 +1,28 @@ +action = $action; + } + + public function setParcelTemplate(ResourceControllerEvent $exportShipmentEvent): void + { + /** @var ?ShippingExportInterface $shippingExport */ + $shippingExport = $exportShipmentEvent->getSubject(); + Assert::isInstanceOf($shippingExport, ShippingExportInterface::class); + + $this->action->execute($shippingExport); + } +} diff --git a/src/EventListener/SelectParcelTemplateEventListener/SelectParcelTemplateAction.php b/src/EventListener/SelectParcelTemplateEventListener/SelectParcelTemplateAction.php new file mode 100644 index 0000000..2d0ea5f --- /dev/null +++ b/src/EventListener/SelectParcelTemplateEventListener/SelectParcelTemplateAction.php @@ -0,0 +1,28 @@ +shippingExportRepository = $shippingExportRepository; + $this->requestStack = $requestStack; + } + + public function execute(ShippingExportInterface $shippingExport): void + { + $this->shippingExportRepository->add($shippingExport); + $this->requestStack->getSession()->getBag('flashes')->add(self::INFO, self::TRANSLATION_KEY); + } +} diff --git a/src/EventListener/SelectParcelTemplateEventListener/SelectParcelTemplateActionInterface.php b/src/EventListener/SelectParcelTemplateEventListener/SelectParcelTemplateActionInterface.php new file mode 100644 index 0000000..91a5f42 --- /dev/null +++ b/src/EventListener/SelectParcelTemplateEventListener/SelectParcelTemplateActionInterface.php @@ -0,0 +1,10 @@ +getExternalId()) { try { - $createShipmentResponse = $this->webClient->createShipment($shipment); + $createShipmentResponse = $this->webClient->createShipment($shipment, $shippingExport); } catch (ClientException $exception) { $this->requestStack->getSession()->getBag('flashes')->add('error', 'bitbag.ui.shipping_export_error'); $this->logError($exception, $shipment); diff --git a/src/Resources/config/grid/order.yml b/src/Resources/config/grid/order.yml index b0aa5c2..a15ae67 100644 --- a/src/Resources/config/grid/order.yml +++ b/src/Resources/config/grid/order.yml @@ -2,33 +2,85 @@ # (c) Paweł Jędrzejewski sylius_grid: - templates: - action: - shop_quick_return: "@SyliusShop/Grid/Action/quickReturn.html.twig" - grids: - sylius_shop_account_order: - actions: - item: - quick_return: - type: shop_quick_return - label: bitbag_sylius_inpost_plugin.ui.quick_return - options: - link: - route: sylius_shop_account_order_return - - show: - type: shop_show - label: sylius.ui.show - options: - link: - route: sylius_shop_account_order_show - parameters: - number: resource.number - pay: - type: shop_pay - label: sylius.ui.pay - options: - link: - route: sylius_shop_order_show - parameters: - tokenValue: resource.tokenValue + templates: + action: + shop_quick_return: "@SyliusShop/Grid/Action/quickReturn.html.twig" + grids: + sylius_shop_account_order: + actions: + item: + quick_return: + type: shop_quick_return + label: bitbag_sylius_inpost_plugin.ui.quick_return + options: + link: + route: sylius_shop_account_order_return + + show: + type: shop_show + label: sylius.ui.show + options: + link: + route: sylius_shop_account_order_show + parameters: + number: resource.number + pay: + type: shop_pay + label: sylius.ui.pay + options: + link: + route: sylius_shop_order_show + parameters: + tokenValue: resource.tokenValue + + bitbag_admin_shipping_export: + fields: + order: + type: twig + label: sylius.ui.order + path: . + sortable: shipment.order + options: + template: "@BitBagSyliusShippingExportPlugin/ShippingExport/Grid/Field/orderNumber.html.twig" + shipment: + type: datetime + label: sylius.ui.created_at + path: shipment.createdAt + sortable: shipment.createdAt + options: + format: 'd-m-Y H:i:s' + exportedAt: + type: twig + label: bitbag.ui.exported_at + path: . + sortable: ~ + options: + template: "@BitBagSyliusShippingExportPlugin/ShippingExport/Grid/Field/exportedAt.html.twig" + shippingMethod: + type: twig + label: sylius.ui.shipping_method + path: . + sortable: shipment.method + options: + template: "@BitBagSyliusShippingExportPlugin/ShippingExport/Grid/Field/shippingMethod.html.twig" + labelPath: + type: twig + label: bitbag.ui.shipping_export_label + path: . + sortable: ~ + options: + template: "@BitBagSyliusShippingExportPlugin/ShippingExport/Grid/Field/shippingExportLabel.html.twig" + parcel_template: + type: twig + label: bitbag_sylius_inpost_plugin.ui.parcel_template.label + path: . + sortable: ~ + options: + template: "@BitBagSyliusInPostPlugin/ShippingExport/Grid/Field/parcel_template.html.twig" + state: + type: twig + label: sylius.ui.state + path: . + sortable: ~ + options: + template: "@BitBagSyliusShippingExportPlugin/ShippingExport/Grid/Field/state.html.twig" diff --git a/src/Resources/config/routes.yml b/src/Resources/config/routes.yml index 9947e5e..97b1517 100644 --- a/src/Resources/config/routes.yml +++ b/src/Resources/config/routes.yml @@ -8,3 +8,9 @@ bitbag_sylius_inpost_plugin_admin_add_point_to_order: methods: [POST] defaults: _controller: bitbag.sylius_inpost_plugin.controller.add_point_to_order::addPointToOrderAction + +bitbag_admin_shipping_export_select_parcel_template: + path: /admin/shipping_export/select_parcel_template/{id}/{template} + methods: [POST, PUT] + defaults: + _controller: bitbag.controller.shipping_export::selectParcelTemplate diff --git a/src/Resources/config/services.xml b/src/Resources/config/services.xml index cfbd832..e054e32 100644 --- a/src/Resources/config/services.xml +++ b/src/Resources/config/services.xml @@ -24,6 +24,13 @@ + + + + + + + + + + + + + + + diff --git a/src/Resources/translations/messages.en.yml b/src/Resources/translations/messages.en.yml index 30f1d0c..9c21f56 100644 --- a/src/Resources/translations/messages.en.yml +++ b/src/Resources/translations/messages.en.yml @@ -17,6 +17,13 @@ bitbag_sylius_inpost_plugin: not_blank: This field cannot be blank is_quick_return: Quick Return quick_return: Quick Return + parcel_template: + label: Parcel template + select_template: Select template + template_a: Template A (8 x 38 x 64 cm) + template_b: Template B (19 x 38 x 64 cm) + template_c: Template C (41 x 38 x 64 cm) + select_action_performed: Parcel template has been changed main_service: inpost_locker_standard: Inpost Locker Standard inpost_locker_pass_thru: Inpost Locker Pass Thru diff --git a/src/Resources/views/ShippingExport/Grid/Field/parcel_template.html.twig b/src/Resources/views/ShippingExport/Grid/Field/parcel_template.html.twig new file mode 100644 index 0000000..e3abb71 --- /dev/null +++ b/src/Resources/views/ShippingExport/Grid/Field/parcel_template.html.twig @@ -0,0 +1,26 @@ +{% set template = data.getParcelTemplate %} +{% if template is null %} + + {{ 'bitbag_sylius_inpost_plugin.ui.parcel_template.select_template'|trans }} + +
+{% endif %} + +
+ {% set templates = {'small': 'A', 'medium': 'B', 'large': 'C'} %} + {% for key, label in templates %} + {% if template == key %} + + {% else %} + {% if data.getExportedAt != null %} + + {% else %} +
+ + +
+ {% endif %} + {% endif %} + {% endfor %} +
diff --git a/tests/Application/config/packages/bitbag_sylius_shipping_export_plugin.yaml b/tests/Application/config/packages/bitbag_sylius_shipping_export_plugin.yaml index 15c0929..18afff6 100644 --- a/tests/Application/config/packages/bitbag_sylius_shipping_export_plugin.yaml +++ b/tests/Application/config/packages/bitbag_sylius_shipping_export_plugin.yaml @@ -1,2 +1,9 @@ imports: - - { resource: "@BitBagSyliusShippingExportPlugin/Resources/config/config.yml" } \ No newline at end of file + - { resource: "@BitBagSyliusShippingExportPlugin/Resources/config/config.yml" } + +sylius_resource: + resources: + bitbag.shipping_export: + classes: + model: Tests\BitBag\SyliusInPostPlugin\Application\src\Entity\ShippingExport + controller: BitBag\SyliusInPostPlugin\Controller\ShippingExportController From fa04c2ec5ce6b8df8b7f0e8e5d796f84c03888a7 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Tomasz=20Kali=C5=84ski?= Date: Tue, 6 Aug 2024 14:31:01 +0200 Subject: [PATCH 03/16] OP-319 - ECS fixes --- src/Api/WebClient.php | 17 +++++++++-------- src/Api/WebClientInterface.php | 1 - src/Controller/ShippingExportController.php | 15 ++++++++------- src/Entity/ShippingExportInterface.php | 9 +++++++++ .../SelectParcelTemplateEventListener.php | 9 +++++++++ .../SelectParcelTemplateActionInterface.php | 9 +++++++++ .../ShippingExportEventListener.php | 2 +- tests/Application/src/Entity/ShippingExport.php | 9 +++++++++ 8 files changed, 54 insertions(+), 17 deletions(-) diff --git a/src/Api/WebClient.php b/src/Api/WebClient.php index a7e207b..fc518cd 100644 --- a/src/Api/WebClient.php +++ b/src/Api/WebClient.php @@ -1,18 +1,19 @@ shippingExport = $shippingExport; @@ -324,8 +325,8 @@ private function isCashOnDelivery(OrderInterface $order): bool } private function createParcel( - ShipmentInterface $shipment - ): array{ + ShipmentInterface $shipment, + ): array { $weight = $shipment->getShippingWeight(); $template = 'large'; if (null !== $this->shippingExport) { diff --git a/src/Api/WebClientInterface.php b/src/Api/WebClientInterface.php index 9b3ecb0..f079ed7 100644 --- a/src/Api/WebClientInterface.php +++ b/src/Api/WebClientInterface.php @@ -57,7 +57,6 @@ interface WebClientInterface public const TEMPLATE_SELECT_EVENT = 'export_shipping_select_parcel_template'; - public function setShippingGateway(ShippingGatewayInterface $shippingGateway): self; public function getApiEndpoint(): string; diff --git a/src/Controller/ShippingExportController.php b/src/Controller/ShippingExportController.php index 6fae616..52917f3 100644 --- a/src/Controller/ShippingExportController.php +++ b/src/Controller/ShippingExportController.php @@ -1,10 +1,11 @@ eventDispatcher->dispatch( ExportShipmentEvent::SHORT_NAME, $configuration, - $shippingExport + $shippingExport, ); } @@ -60,7 +61,7 @@ public function exportSingleShipmentAction(Request $request): RedirectResponse $this->eventDispatcher->dispatch( ExportShipmentEvent::SHORT_NAME, $configuration, - $shippingExport + $shippingExport, ); return $this->redirectToReferer($request); @@ -80,7 +81,7 @@ public function selectParcelTemplate(Request $request): RedirectResponse $this->eventDispatcher->dispatch( WebClientInterface::TEMPLATE_SELECT_EVENT, $configuration, - $shippingExport + $shippingExport, ); return $this->redirectToReferer($request); diff --git a/src/Entity/ShippingExportInterface.php b/src/Entity/ShippingExportInterface.php index da85e82..0c8a032 100644 --- a/src/Entity/ShippingExportInterface.php +++ b/src/Entity/ShippingExportInterface.php @@ -1,5 +1,14 @@ Date: Tue, 6 Aug 2024 15:54:06 +0200 Subject: [PATCH 04/16] OP-319 - Select parcel template fixes --- src/Api/WebClientInterface.php | 2 -- src/Controller/ShippingExportController.php | 10 +++----- .../SelectParcelTemplateAction.php | 25 ++++++++++++++++--- .../select_parcel_template_action.xml | 1 + tests/Spec/Builder/ShippingExportBuilder.php | 4 +-- 5 files changed, 29 insertions(+), 13 deletions(-) diff --git a/src/Api/WebClientInterface.php b/src/Api/WebClientInterface.php index f079ed7..4530fc6 100644 --- a/src/Api/WebClientInterface.php +++ b/src/Api/WebClientInterface.php @@ -55,8 +55,6 @@ interface WebClientInterface public const ROD_ADDITIONAL_SERVICE = 'rod'; - public const TEMPLATE_SELECT_EVENT = 'export_shipping_select_parcel_template'; - public function setShippingGateway(ShippingGatewayInterface $shippingGateway): self; public function getApiEndpoint(): string; diff --git a/src/Controller/ShippingExportController.php b/src/Controller/ShippingExportController.php index 52917f3..5949e65 100644 --- a/src/Controller/ShippingExportController.php +++ b/src/Controller/ShippingExportController.php @@ -11,8 +11,6 @@ namespace BitBag\SyliusInPostPlugin\Controller; -use BitBag\SyliusInPostPlugin\Api\WebClientInterface; -use BitBag\SyliusInPostPlugin\Entity\ShippingExportInterface; use BitBag\SyliusShippingExportPlugin\Event\ExportShipmentEvent; use BitBag\SyliusShippingExportPlugin\Repository\ShippingExportRepositoryInterface; use Sylius\Bundle\ResourceBundle\Controller\ResourceController; @@ -24,6 +22,8 @@ final class ShippingExportController extends ResourceController { + public const SELECT_PARCEL_TEMPLATE_EVENT = 'export_shipping_select_parcel_template'; + public function exportAllNewShipmentsAction(Request $request): RedirectResponse { $configuration = $this->requestConfigurationFactory->create($this->metadata, $request); @@ -74,12 +74,10 @@ public function selectParcelTemplate(Request $request): RedirectResponse /** @var ResourceInterface|null $shippingExport */ $shippingExport = $this->repository->find($request->get('id')); Assert::notNull($shippingExport); - - /** @var ShippingExportInterface $shippingExport */ - $shippingExport?->setParcelTemplate($request->get('template')); + $shippingExport->setParcelTemplate($request->get('template')); $this->eventDispatcher->dispatch( - WebClientInterface::TEMPLATE_SELECT_EVENT, + self::SELECT_PARCEL_TEMPLATE_EVENT, $configuration, $shippingExport, ); diff --git a/src/EventListener/SelectParcelTemplateEventListener/SelectParcelTemplateAction.php b/src/EventListener/SelectParcelTemplateEventListener/SelectParcelTemplateAction.php index 2d0ea5f..bd903dc 100644 --- a/src/EventListener/SelectParcelTemplateEventListener/SelectParcelTemplateAction.php +++ b/src/EventListener/SelectParcelTemplateEventListener/SelectParcelTemplateAction.php @@ -1,28 +1,47 @@ shippingExportRepository = $shippingExportRepository; $this->requestStack = $requestStack; + $this->translator = $translator; } public function execute(ShippingExportInterface $shippingExport): void { + $message = $this->translator->trans(self::TRANSLATION_KEY); $this->shippingExportRepository->add($shippingExport); - $this->requestStack->getSession()->getBag('flashes')->add(self::INFO, self::TRANSLATION_KEY); + $this->requestStack->getSession()->getBag('flashes')->add(self::INFO, $message); } } diff --git a/src/Resources/config/services/select_parcel_template_action.xml b/src/Resources/config/services/select_parcel_template_action.xml index 846e40e..19e8375 100644 --- a/src/Resources/config/services/select_parcel_template_action.xml +++ b/src/Resources/config/services/select_parcel_template_action.xml @@ -15,6 +15,7 @@ > +
diff --git a/tests/Spec/Builder/ShippingExportBuilder.php b/tests/Spec/Builder/ShippingExportBuilder.php index cf88bd8..0159707 100644 --- a/tests/Spec/Builder/ShippingExportBuilder.php +++ b/tests/Spec/Builder/ShippingExportBuilder.php @@ -11,10 +11,10 @@ namespace Tests\BitBag\SyliusInPostPlugin\Spec\Builder; -use BitBag\SyliusShippingExportPlugin\Entity\ShippingExport; -use BitBag\SyliusShippingExportPlugin\Entity\ShippingExportInterface; +use BitBag\SyliusInPostPlugin\Entity\ShippingExportInterface; use BitBag\SyliusShippingExportPlugin\Entity\ShippingGatewayInterface; use Sylius\Component\Core\Model\ShipmentInterface; +use Tests\BitBag\SyliusInPostPlugin\Application\src\Entity\ShippingExport; class ShippingExportBuilder { From 3cab4af008ca0906fb20ddcf2d24f5d68640500c Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Tomasz=20Kali=C5=84ski?= Date: Wed, 7 Aug 2024 14:02:06 +0200 Subject: [PATCH 05/16] OP-319 - Added PHPSpec tests --- .../SelectParcelTemplateActionSpec.php | 46 +++++++++++ .../SelectParcelTemplateEventListenerSpec.php | 82 +++++++++++++++++++ .../SelectParcelTemplateEventListener.php | 8 ++ tests/Spec/Builder/ShippingExportBuilder.php | 7 ++ 4 files changed, 143 insertions(+) create mode 100644 spec/EventListener/SelectParcelTemplateEventListener/SelectParcelTemplateActionSpec.php create mode 100644 spec/EventListener/SelectParcelTemplateEventListenerSpec.php diff --git a/spec/EventListener/SelectParcelTemplateEventListener/SelectParcelTemplateActionSpec.php b/spec/EventListener/SelectParcelTemplateEventListener/SelectParcelTemplateActionSpec.php new file mode 100644 index 0000000..0744837 --- /dev/null +++ b/spec/EventListener/SelectParcelTemplateEventListener/SelectParcelTemplateActionSpec.php @@ -0,0 +1,46 @@ +beConstructedWith($shippingExportRepository, $requestStack, $translator); + } + + public function it_is_initializable() + { + $this->shouldHaveType(SelectParcelTemplateAction::class); + $this->shouldBeAnInstanceOf(SelectParcelTemplateActionInterface::class); + } + + public function it_should_save_shipping_export_changes( + ShippingExportInterface $shippingExport, + ShippingExportRepositoryInterface $shippingExportRepository, + RequestStack $requestStack, + SessionInterface $session, + FlashBagInterface $flashBag + ): void { + $shippingExportRepository->add($shippingExport)->shouldBeCalled(); + + $requestStack->getSession()->willReturn($session); + $session->getBag('flashes')->willReturn($flashBag); + + $this->execute($shippingExport); + } + +} diff --git a/spec/EventListener/SelectParcelTemplateEventListenerSpec.php b/spec/EventListener/SelectParcelTemplateEventListenerSpec.php new file mode 100644 index 0000000..13b5220 --- /dev/null +++ b/spec/EventListener/SelectParcelTemplateEventListenerSpec.php @@ -0,0 +1,82 @@ +beConstructedWith($action); + } + + public function it_is_initializable(): void + { + $this->shouldHaveType(SelectParcelTemplateEventListener::class); + } + + public function it_should_throw_exception_if_subject_is_not_shipping_export_instance(ResourceControllerEvent $event): void + { + $event->getSubject()->willReturn(new \stdClass()); + + $this + ->shouldThrow(\InvalidArgumentException::class) + ->during('setParcelTemplate', [$event]) + ; + } + + public function it_should_throw_exception_if_incorrect_parcel_template_is_passed(ResourceControllerEvent $event): void + { + $shippingGateway = ShippingGatewayBuilder::create()->withCode(self::INPOST)->build(); + $shipment = ShipmentBuilder::create()->build(); + $shippingExport = ShippingExportBuilder::create() + ->withShippingGateway($shippingGateway) + ->withShipment($shipment) + ->withParcelTemplate(self::INCORRECT_PARCEL_TEMPLATE) + ->build(); + $event->getSubject()->willReturn($shippingExport); + + $this + ->shouldThrow(\Exception::class) + ->during('setParcelTemplate', [$event]) + ; + } + + /** + * @throws \Exception + */ + public function it_should_perform_set_parcel_template_action(ResourceControllerEvent $event): void + { + $shippingGateway = ShippingGatewayBuilder::create()->withCode(self::INPOST)->build(); + $shipment = ShipmentBuilder::create()->build(); + $shippingExport = ShippingExportBuilder::create() + ->withShippingGateway($shippingGateway) + ->withShipment($shipment) + ->withParcelTemplate(self::EXPECTED_PARCEL_TEMPLATE) + ->build(); + $event->getSubject()->willReturn($shippingExport); + $this->setParcelTemplate($event); + } +} diff --git a/src/EventListener/SelectParcelTemplateEventListener.php b/src/EventListener/SelectParcelTemplateEventListener.php index 26d3527..c2397ba 100644 --- a/src/EventListener/SelectParcelTemplateEventListener.php +++ b/src/EventListener/SelectParcelTemplateEventListener.php @@ -20,6 +20,10 @@ class SelectParcelTemplateEventListener { private SelectParcelTemplateActionInterface $action; + private const PARCEL_TEMPLATE_VALUES = [ + 'small', 'medium', 'large', + ]; + public function __construct( SelectParcelTemplateActionInterface $action, ) { @@ -32,6 +36,10 @@ public function setParcelTemplate(ResourceControllerEvent $exportShipmentEvent): $shippingExport = $exportShipmentEvent->getSubject(); Assert::isInstanceOf($shippingExport, ShippingExportInterface::class); + if (!in_array($shippingExport->getParcelTemplate(), self::PARCEL_TEMPLATE_VALUES)) { + throw new \Exception(sprintf('"%s" is invalid parcel template!', $shippingExport->getParcelTemplate())); + } + $this->action->execute($shippingExport); } } diff --git a/tests/Spec/Builder/ShippingExportBuilder.php b/tests/Spec/Builder/ShippingExportBuilder.php index 0159707..aa2697d 100644 --- a/tests/Spec/Builder/ShippingExportBuilder.php +++ b/tests/Spec/Builder/ShippingExportBuilder.php @@ -51,6 +51,13 @@ public function withShippingGateway(ShippingGatewayInterface $shippingGateway): return $this; } + public function withParcelTemplate(string $template): self + { + $this->shippingExport->setParcelTemplate($template); + + return $this; + } + public function build(): ShippingExportInterface { return $this->shippingExport; From dabaaca958bd15f89f0e9e69ec43141d98c649c0 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Tomasz=20Kali=C5=84ski?= Date: Wed, 7 Aug 2024 16:26:30 +0200 Subject: [PATCH 06/16] OP-319 - Extension of parcel template with courier services --- .../SelectParcelTemplateEventListenerSpec.php | 1 + .../SelectParcelTemplateEventListener.php | 25 +++++++++++-- .../ParcelTemplate/_inpost_template.html.twig | 37 +++++++++++++++++++ .../Grid/Field/parcel_template.html.twig | 29 ++------------- 4 files changed, 64 insertions(+), 28 deletions(-) create mode 100644 src/Resources/views/ShippingExport/Grid/Field/ParcelTemplate/_inpost_template.html.twig diff --git a/spec/EventListener/SelectParcelTemplateEventListenerSpec.php b/spec/EventListener/SelectParcelTemplateEventListenerSpec.php index 13b5220..4a5feca 100644 --- a/spec/EventListener/SelectParcelTemplateEventListenerSpec.php +++ b/spec/EventListener/SelectParcelTemplateEventListenerSpec.php @@ -70,6 +70,7 @@ public function it_should_throw_exception_if_incorrect_parcel_template_is_passed public function it_should_perform_set_parcel_template_action(ResourceControllerEvent $event): void { $shippingGateway = ShippingGatewayBuilder::create()->withCode(self::INPOST)->build(); + $shippingGateway->setConfig(['service' => 'inpost_locker_standard']); $shipment = ShipmentBuilder::create()->build(); $shippingExport = ShippingExportBuilder::create() ->withShippingGateway($shippingGateway) diff --git a/src/EventListener/SelectParcelTemplateEventListener.php b/src/EventListener/SelectParcelTemplateEventListener.php index c2397ba..151b70d 100644 --- a/src/EventListener/SelectParcelTemplateEventListener.php +++ b/src/EventListener/SelectParcelTemplateEventListener.php @@ -20,10 +20,20 @@ class SelectParcelTemplateEventListener { private SelectParcelTemplateActionInterface $action; - private const PARCEL_TEMPLATE_VALUES = [ + private const INPOST_LOCKER_PARCEL_TEMPLATES = [ 'small', 'medium', 'large', ]; + private const INPOST_COURIER_PARCEL_TEMPLATES = [ + 'small', 'medium', 'large', 'xlarge', + ]; + + private const INPOST_LOCKER_STANDARD = 'inpost_locker_standard'; + + private const INPOST_LOCKER_PASS_THRU = 'inpost_locker_pass_thru'; + + private const ERROR_INVALID_PARCEL_TEMPLATE = '"%s" is an invalid parcel template!'; + public function __construct( SelectParcelTemplateActionInterface $action, ) { @@ -36,8 +46,17 @@ public function setParcelTemplate(ResourceControllerEvent $exportShipmentEvent): $shippingExport = $exportShipmentEvent->getSubject(); Assert::isInstanceOf($shippingExport, ShippingExportInterface::class); - if (!in_array($shippingExport->getParcelTemplate(), self::PARCEL_TEMPLATE_VALUES)) { - throw new \Exception(sprintf('"%s" is invalid parcel template!', $shippingExport->getParcelTemplate())); + $service = $shippingExport->getShippingGateway()->getConfig()['service']; + $parcelTemplate = $shippingExport->getParcelTemplate(); + + if (in_array($service, [self::INPOST_LOCKER_STANDARD, self::INPOST_LOCKER_PASS_THRU])) { + $validTemplates = self::INPOST_LOCKER_PARCEL_TEMPLATES; + } else { + $validTemplates = self::INPOST_COURIER_PARCEL_TEMPLATES; + } + + if (!in_array($parcelTemplate, $validTemplates, true)) { + throw new \Exception(sprintf(self::ERROR_INVALID_PARCEL_TEMPLATE, $parcelTemplate)); } $this->action->execute($shippingExport); diff --git a/src/Resources/views/ShippingExport/Grid/Field/ParcelTemplate/_inpost_template.html.twig b/src/Resources/views/ShippingExport/Grid/Field/ParcelTemplate/_inpost_template.html.twig new file mode 100644 index 0000000..126857b --- /dev/null +++ b/src/Resources/views/ShippingExport/Grid/Field/ParcelTemplate/_inpost_template.html.twig @@ -0,0 +1,37 @@ +{% set parcelTemplate = data.getParcelTemplate %} + +{% if parcelTemplate is null %} + + {{ 'bitbag_sylius_inpost_plugin.ui.parcel_template.select_template'|trans }} + +
+{% endif %} + +{% set templates = {} %} +{% if data.getShippingGateway.getConfig.service == 'inpost_locker_standard' %} + {% set templates = {'small': 'A', 'medium': 'B', 'large': 'C'} %} +{% else %} + {% set templates = {'small': 'A', 'medium': 'B', 'large': 'C', 'xlarge': 'D'} %} +{% endif %} + +
+ {% for key, label in templates %} + {% if parcelTemplate == key %} + + {% else %} + {% if data.getExportedAt != null %} + + {% else %} +
+ + +
+ {% endif %} + {% endif %} + {% endfor %} +
diff --git a/src/Resources/views/ShippingExport/Grid/Field/parcel_template.html.twig b/src/Resources/views/ShippingExport/Grid/Field/parcel_template.html.twig index e3abb71..56bb6a0 100644 --- a/src/Resources/views/ShippingExport/Grid/Field/parcel_template.html.twig +++ b/src/Resources/views/ShippingExport/Grid/Field/parcel_template.html.twig @@ -1,26 +1,5 @@ -{% set template = data.getParcelTemplate %} -{% if template is null %} - - {{ 'bitbag_sylius_inpost_plugin.ui.parcel_template.select_template'|trans }} - -
+{% if data.getShippingGateway.getName == 'INPOST_PL' %} + {% include '@BitBagSyliusInPostPlugin/ShippingExport/Grid/Field/ParcelTemplate/_inpost_template.html.twig' %} +{% else %} + {% endif %} - -
- {% set templates = {'small': 'A', 'medium': 'B', 'large': 'C'} %} - {% for key, label in templates %} - {% if template == key %} - - {% else %} - {% if data.getExportedAt != null %} - - {% else %} -
- - -
- {% endif %} - {% endif %} - {% endfor %} -
From 2ec47d1d1a65ddfa7b9ac542487c6b73aa6e6bc2 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Tomasz=20Kali=C5=84ski?= Date: Thu, 8 Aug 2024 10:54:31 +0200 Subject: [PATCH 07/16] OP-319 - Added select parcel Behat test --- .../adding_image_to_shipping_method.feature | 2 +- ...ng_shipping_method_parcel_template.feature | 28 ++++++++++ .../ParcelTemplate/_inpost_template.html.twig | 6 +- .../Ui/Admin/ShippingExportContext.php | 18 +++++- .../Page/Admin/ShippingExport/IndexPage.php | 56 +++++++++++++++++++ .../ShippingExport/IndexPageInterface.php | 19 +++++++ tests/Behat/Resources/services/contexts.yml | 4 +- tests/Behat/Resources/services/pages.yml | 8 +++ tests/Behat/Resources/suites.yml | 33 +++++++++++ 9 files changed, 166 insertions(+), 8 deletions(-) create mode 100644 features/changing_shipping_method_parcel_template.feature create mode 100644 tests/Behat/Page/Admin/ShippingExport/IndexPage.php create mode 100644 tests/Behat/Page/Admin/ShippingExport/IndexPageInterface.php diff --git a/features/adding_image_to_shipping_method.feature b/features/adding_image_to_shipping_method.feature index 1ea5b4e..b97fd28 100644 --- a/features/adding_image_to_shipping_method.feature +++ b/features/adding_image_to_shipping_method.feature @@ -14,4 +14,4 @@ Feature: Adding shipping method image When I want to modify a shipping method "InPost" And I upload the "image/shipping_logo.jpg" image as shipping method logo And I save my changes - Then I should be notified that it has been successfully edited \ No newline at end of file + Then I should be notified that it has been successfully edited diff --git a/features/changing_shipping_method_parcel_template.feature b/features/changing_shipping_method_parcel_template.feature new file mode 100644 index 0000000..71fb854 --- /dev/null +++ b/features/changing_shipping_method_parcel_template.feature @@ -0,0 +1,28 @@ +@managing_shipping_export_parcel_template_inpost +Feature: Changing shipping export parcel template + To send a query to the Inpost API with a different shipment template + As an Administrator + I need to be able to choose a parcel template + + Background: + Given the store operates on a single channel in the "United States" named "Web-US" + And I am logged in as an administrator + And the store has "Inpost" shipping method with "$10.00" fee + And there is a registered "inpost" shipping gateway for this shipping method named "INPOST_PL" + And it has "Access token" field set to "123" + And it has "Organization ID" field set to "123" + And it has "Environment" field set to "sandbox" + And it has "service" field set to "inpost_locker_standard" + And the store has a product "Chicken" priced at "$2.00" in "Web-US" channel + And customer "user@bitbag.pl" has placed 1 orders on the "Web-US" channel in each buying 5 "Chicken" products + And the customer set the shipping address "Mike Ross" addressed it to "350 5th Ave", "10118" "New York" in the "United States" to orders + And those orders were placed with "Inpost" shipping method + And set product weight to "10" + And set units to the shipment + + @ui + Scenario: Seeing shipments to export + When I go to the shipping export page + Then I should see 1 shipments with "New" state + When I select parcel template + Then I should see that shipping export parcel template is set diff --git a/src/Resources/views/ShippingExport/Grid/Field/ParcelTemplate/_inpost_template.html.twig b/src/Resources/views/ShippingExport/Grid/Field/ParcelTemplate/_inpost_template.html.twig index 126857b..e921a34 100644 --- a/src/Resources/views/ShippingExport/Grid/Field/ParcelTemplate/_inpost_template.html.twig +++ b/src/Resources/views/ShippingExport/Grid/Field/ParcelTemplate/_inpost_template.html.twig @@ -17,7 +17,7 @@
{% for key, label in templates %} {% if parcelTemplate == key %} - + {% else %} {% if data.getExportedAt != null %} @@ -25,9 +25,7 @@
-
diff --git a/tests/Behat/Context/Ui/Admin/ShippingExportContext.php b/tests/Behat/Context/Ui/Admin/ShippingExportContext.php index 0b0e852..a20f6f1 100644 --- a/tests/Behat/Context/Ui/Admin/ShippingExportContext.php +++ b/tests/Behat/Context/Ui/Admin/ShippingExportContext.php @@ -13,7 +13,7 @@ use Behat\Behat\Context\Context; use Tests\BitBag\SyliusInPostPlugin\Behat\Mocker\InPostApiMocker; -use Tests\BitBag\SyliusShippingExportPlugin\Behat\Page\Admin\ShippingExport\IndexPageInterface; +use Tests\BitBag\SyliusInPostPlugin\Behat\Page\Admin\ShippingExport\IndexPageInterface; final class ShippingExportContext implements Context { @@ -48,4 +48,20 @@ public function iExportFirsShipments(): void $this->indexPage->exportFirsShipment(); }); } + + /** + * @When I select parcel template + */ + public function iSelectParcelTemplate(): void + { + $this->indexPage->selectParcelTemplate(); + } + + /** + * @Then I should see that shipping export parcel template is set + */ + public function iCheckParcelTemplate(): void + { + $this->indexPage->checkParcelTemplate(); + } } diff --git a/tests/Behat/Page/Admin/ShippingExport/IndexPage.php b/tests/Behat/Page/Admin/ShippingExport/IndexPage.php new file mode 100644 index 0000000..59a0e72 --- /dev/null +++ b/tests/Behat/Page/Admin/ShippingExport/IndexPage.php @@ -0,0 +1,56 @@ +getDocument()->findAll('css', '.shipping-export-state'); + $result = []; + + /** @var ElementInterface $item */ + foreach ($items as $item) { + if ($item->getText() === $state) { + $result[] = $item; + } + } + + return $result; + } + + public function exportAllShipments(): void + { + $this->getDocument()->pressButton('Export all new shipments'); + } + + public function exportFirsShipment(): void + { + $this->getDocument()->find('css', '.shipping-export-state')->click(); + } + + public function selectParcelTemplate(): void + { + $this->getDocument()->find('css', '.shipping-export-select-template')->click(); + } + + public function checkParcelTemplate(): void + { + $button = $this->getDocument()->find('xpath', '//button[@data-shipping-export-selected-template]'); + if (null === $button) { + throw new \Exception('Parcel template is not selected.'); + } + } +} diff --git a/tests/Behat/Page/Admin/ShippingExport/IndexPageInterface.php b/tests/Behat/Page/Admin/ShippingExport/IndexPageInterface.php new file mode 100644 index 0000000..0273f59 --- /dev/null +++ b/tests/Behat/Page/Admin/ShippingExport/IndexPageInterface.php @@ -0,0 +1,19 @@ + Date: Thu, 8 Aug 2024 12:34:33 +0200 Subject: [PATCH 08/16] OP-319 - Shipping-export fixes --- src/Model/ParcelTemplateTrait.php | 27 +++++++++++++++++++ .../Application/src/Entity/ShippingExport.php | 13 ++------- 2 files changed, 29 insertions(+), 11 deletions(-) create mode 100644 src/Model/ParcelTemplateTrait.php diff --git a/src/Model/ParcelTemplateTrait.php b/src/Model/ParcelTemplateTrait.php new file mode 100644 index 0000000..dd4b900 --- /dev/null +++ b/src/Model/ParcelTemplateTrait.php @@ -0,0 +1,27 @@ +parcel_template; + } + + public function setParcelTemplate(?string $parcel_template): void + { + $this->parcel_template = $parcel_template; + } +} diff --git a/tests/Application/src/Entity/ShippingExport.php b/tests/Application/src/Entity/ShippingExport.php index bb24ed2..d039367 100644 --- a/tests/Application/src/Entity/ShippingExport.php +++ b/tests/Application/src/Entity/ShippingExport.php @@ -12,19 +12,10 @@ namespace Tests\BitBag\SyliusInPostPlugin\Application\src\Entity; use BitBag\SyliusInPostPlugin\Entity\ShippingExportInterface; +use BitBag\SyliusInPostPlugin\Model\ParcelTemplateTrait; use BitBag\SyliusShippingExportPlugin\Entity\ShippingExport as BaseShippingExport; class ShippingExport extends BaseShippingExport implements ShippingExportInterface { - protected $parcel_template; - - public function getParcelTemplate(): ?string - { - return $this->parcel_template; - } - - public function setParcelTemplate(?string $parcel_template): void - { - $this->parcel_template = $parcel_template; - } + use ParcelTemplateTrait; } From 160a5a56dea1cb1954928860e52a70376c9b36f4 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Tomasz=20Kali=C5=84ski?= Date: Thu, 8 Aug 2024 12:34:42 +0200 Subject: [PATCH 09/16] OP-319 - installation.md --- doc/installation.md | 91 ++++++++++++++++++- .../Resources/config/doctrine/Order.orm.xml | 10 +- 2 files changed, 91 insertions(+), 10 deletions(-) diff --git a/doc/installation.md b/doc/installation.md index 3ed4773..291b335 100644 --- a/doc/installation.md +++ b/doc/installation.md @@ -43,6 +43,26 @@ bitbag_shipping_export_plugin.yaml to the config/packages and config/routes dire It also adding the appropriate entry to config/bundles.php. If it doesn't, so please remember to do the same as above for SyliusShippingExportPlugin configuration. +Add after @BitBagSyliusShippingExportPlugin import: +```yaml +# config/packages/bitbag_shipping_export_plugin.yaml +imports: + - { resource: "@BitBagSyliusShippingExportPlugin/Resources/config/config.yml" } + +sylius_resource: + resources: + bitbag.shipping_export: + classes: + model: App\Entity\Shipping\ShippingExport + controller: BitBag\SyliusInPostPlugin\Controller\ShippingExportController + +``` +Remember that in case of different mapping, the model path may be different. +Default: +```yaml + model: App\Entity\ShippingExport +``` + ### Extend entities with parameters You can implement this using xml-mapping or attributes. Instructions for both settings are described below. @@ -101,6 +121,22 @@ class ShippingMethod extends BaseShippingMethod implements ImageAwareInterface use ShippingMethodImageTrait; } ``` +```php + - @@ -156,6 +191,19 @@ Define new Entity mapping inside your src/Resources/config/doctrine directory. ``` +```xml + + + + + + + + +``` #### You can do it with attributes if you prefer. Remember to mark it appropriately in the config/doctrine.yaml configuration file. ``` doctrine: @@ -239,8 +287,43 @@ class ShippingMethod extends BaseShippingMethod implements ImageAwareInterface { $this->image = $image; } + + // other methods } +``` +```php +parcel_template; + } + + public function setParcelTemplate(?string $parcel_template): void + { + $this->parcel_template = $parcel_template; + } +} ``` Finish the installation by updating the database schema (check in advance: [Known Issues](known_issues.md)): diff --git a/tests/Application/src/Resources/config/doctrine/Order.orm.xml b/tests/Application/src/Resources/config/doctrine/Order.orm.xml index 92b4292..c887cac 100644 --- a/tests/Application/src/Resources/config/doctrine/Order.orm.xml +++ b/tests/Application/src/Resources/config/doctrine/Order.orm.xml @@ -1,11 +1,9 @@ - + From 297dc75698f7af8243abdd85fc03751df6fc260e Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Tomasz=20Kali=C5=84ski?= Date: Thu, 8 Aug 2024 13:22:15 +0200 Subject: [PATCH 10/16] OP-319 - ShippingExportEventListener fix --- spec/EventListener/ShippingExportEventListenerSpec.php | 8 ++++---- src/EventListener/ShippingExportEventListener.php | 2 +- 2 files changed, 5 insertions(+), 5 deletions(-) diff --git a/spec/EventListener/ShippingExportEventListenerSpec.php b/spec/EventListener/ShippingExportEventListenerSpec.php index 6476d99..97648ef 100644 --- a/spec/EventListener/ShippingExportEventListenerSpec.php +++ b/spec/EventListener/ShippingExportEventListenerSpec.php @@ -128,7 +128,7 @@ public function it_should_handle_when_create_shipment_throws_exception( $event->getSubject()->willReturn($shippingExport); $webClient->setShippingGateway($shippingGateway); - $webClient->createShipment($shipment)->willThrow(InvalidInPostResponseException::class); + $webClient->createShipment($shipment, $shippingExport)->willThrow(InvalidInPostResponseException::class); $requestStack->getSession()->willReturn($session); $session->getBag('flashes')->willReturn($flashBag); $flashBag->add(self::ERROR, self::SHIPPING_EXPORT_ERROR_MESSAGE)->shouldBeCalled(); @@ -155,7 +155,7 @@ public function it_should_handle_when_get_shipment_by_id_throws_exception( $event->getSubject()->willReturn($shippingExport); $webClient->setShippingGateway($shippingGateway); - $webClient->createShipment($shipment)->willReturn(self::EXPECTED_CREATE_SHIPMENT_RESPONSE); + $webClient->createShipment($shipment, $shippingExport)->willReturn(self::EXPECTED_CREATE_SHIPMENT_RESPONSE); $webClient->getShipmentById(self::SHIPMENT_ID)->willThrow(InvalidInPostResponseException::class); $requestStack->getSession()->willReturn($session); $session->getBag('flashes')->willReturn($flashBag); @@ -184,7 +184,7 @@ public function it_should_handle_when_provide_shipment_action_throws_exception( $event->getSubject()->willReturn($shippingExport); $webClient->setShippingGateway($shippingGateway); - $webClient->createShipment($shipment)->willReturn(self::EXPECTED_CREATE_SHIPMENT_RESPONSE); + $webClient->createShipment($shipment, $shippingExport)->willReturn(self::EXPECTED_CREATE_SHIPMENT_RESPONSE); $webClient->getShipmentById(self::SHIPMENT_ID)->willReturn(self::EXPECTED_GET_SHIPMENT_RESPONSE); $shippingExportActionProvider->provide(Argument::type('string'))->willThrow(\Exception::class); $requestStack->getSession()->willReturn($session); @@ -210,7 +210,7 @@ public function it_should_execute_shipping_export_action( $event->getSubject()->willReturn($shippingExport); $webClient->setShippingGateway($shippingGateway); - $webClient->createShipment($shipment)->willReturn(self::EXPECTED_CREATE_SHIPMENT_RESPONSE); + $webClient->createShipment($shipment, $shippingExport)->willReturn(self::EXPECTED_CREATE_SHIPMENT_RESPONSE); $webClient->getShipmentById(self::SHIPMENT_ID)->willReturn(self::EXPECTED_GET_SHIPMENT_RESPONSE); $shippingExportActionProvider->provide(Argument::type('string'))->willReturn($shippingExportAction); $shippingExportAction->execute($shippingExport)->shouldBeCalled(); diff --git a/src/EventListener/ShippingExportEventListener.php b/src/EventListener/ShippingExportEventListener.php index a88718d..aed375f 100644 --- a/src/EventListener/ShippingExportEventListener.php +++ b/src/EventListener/ShippingExportEventListener.php @@ -73,7 +73,7 @@ public function exportShipment(ResourceControllerEvent $exportShipmentEvent): vo if (null === $shippingExport->getExternalId()) { try { - $createShipmentResponse = $this->webClient->createShipment($shipment); + $createShipmentResponse = $this->webClient->createShipment($shipment, $shippingExport); } catch (InPostException $exception) { $this->requestStack->getSession()->getBag('flashes')->add('error', 'bitbag.ui.shipping_export_error'); $this->logError($exception, $shipment); From e161c2e774a91f7748ebeb82ffe6c411a84f695a Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Tomasz=20Kali=C5=84ski?= Date: Tue, 13 Aug 2024 11:13:49 +0200 Subject: [PATCH 11/16] OP-319 - PHPSpec: PHPDoc annotation has been removed --- spec/EventListener/SelectParcelTemplateEventListenerSpec.php | 3 --- 1 file changed, 3 deletions(-) diff --git a/spec/EventListener/SelectParcelTemplateEventListenerSpec.php b/spec/EventListener/SelectParcelTemplateEventListenerSpec.php index 4a5feca..0de6466 100644 --- a/spec/EventListener/SelectParcelTemplateEventListenerSpec.php +++ b/spec/EventListener/SelectParcelTemplateEventListenerSpec.php @@ -64,9 +64,6 @@ public function it_should_throw_exception_if_incorrect_parcel_template_is_passed ; } - /** - * @throws \Exception - */ public function it_should_perform_set_parcel_template_action(ResourceControllerEvent $event): void { $shippingGateway = ShippingGatewayBuilder::create()->withCode(self::INPOST)->build(); From 7c1d315e9b64d02e63f2ce92324488484419ee37 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Tomasz=20Kali=C5=84ski?= Date: Tue, 13 Aug 2024 12:50:33 +0200 Subject: [PATCH 12/16] OP-319 - Default parcel template and label type configuration --- doc/installation.md | 18 +++++++++++++++++ spec/Api/WebClientSpec.php | 5 ++++- .../ShippingExportEventListenerSpec.php | 3 ++- src/Api/WebClient.php | 20 +++++++++---------- src/Api/WebClientInterface.php | 2 +- src/Resources/config/config.yml | 9 ++++++++- src/Resources/config/services.xml | 1 + .../ParcelTemplate/_inpost_template.html.twig | 6 +----- tests/Application/.env | 3 +++ 9 files changed, 47 insertions(+), 20 deletions(-) diff --git a/doc/installation.md b/doc/installation.md index 291b335..6b8513a 100644 --- a/doc/installation.md +++ b/doc/installation.md @@ -423,6 +423,24 @@ By a standard, the `webpack.config.js` file should be available in your reposito ``` +## Default parameters configuration +In the .env file, the default parcel size and label type can be specified by adding: + +```` +BITBAG_INPOST_DEFAULT_PARCEL_TEMPLATE='medium' +BITBAG_INPOST_DEFAULT_LABEL_TYPE='normal' +```` + +Three types of parcel templates are allowed: +- 'small' +- 'medium' +- 'large' + +Two types of labels are allowed: +- 'normal' +- 'A6' + + ## Testing & running the plugin ```bash diff --git a/spec/Api/WebClientSpec.php b/spec/Api/WebClientSpec.php index e93737a..0269780 100644 --- a/spec/Api/WebClientSpec.php +++ b/spec/Api/WebClientSpec.php @@ -28,13 +28,16 @@ final class WebClientSpec extends ObjectBehavior public const LABEL_TYPE = "normal"; + public const PARCEL_TEMPLATE = "medium"; + + public function let( ClientInterface $client, RequestFactoryInterface $requestFactory, StreamFactoryInterface $streamFactory, ): void { - $this->beConstructedWith($client, $requestFactory, $streamFactory, self::LABEL_TYPE); + $this->beConstructedWith($client, $requestFactory, $streamFactory, self::LABEL_TYPE, self::PARCEL_TEMPLATE); } public function it_is_initializable(): void diff --git a/spec/EventListener/ShippingExportEventListenerSpec.php b/spec/EventListener/ShippingExportEventListenerSpec.php index 97648ef..bfa7964 100644 --- a/spec/EventListener/ShippingExportEventListenerSpec.php +++ b/spec/EventListener/ShippingExportEventListenerSpec.php @@ -52,7 +52,8 @@ public function let( WebClientInterface $webClient, InPostShippingExportActionProviderInterface $shippingExportActionProvider, RequestStack $requestStack, - LoggerInterface $logger + LoggerInterface $logger, + ): void { $this->beConstructedWith($webClient, $shippingExportActionProvider, $requestStack, $logger); } diff --git a/src/Api/WebClient.php b/src/Api/WebClient.php index fc518cd..e6e887b 100644 --- a/src/Api/WebClient.php +++ b/src/Api/WebClient.php @@ -42,20 +42,22 @@ final class WebClient implements WebClientInterface private ShippingGatewayInterface $shippingGateway; - private ?ShippingExportInterface $shippingExport = null; + private string $labelType; - private string $labelType = 'normal'; + private string $parcelTemplate; public function __construct( ClientInterface $client, RequestFactoryInterface $requestFactory, StreamFactoryInterface $streamFactory, string $labelType, + string $parcelTemplate, ) { $this->apiClient = $client; $this->requestFactory = $requestFactory; $this->streamFactory = $streamFactory; $this->labelType = $labelType; + $this->parcelTemplate = $parcelTemplate; } public function setShippingGateway(ShippingGatewayInterface $shippingGateway): WebClientInterface @@ -154,10 +156,8 @@ public function getShipments(): ?array public function createShipment( ShipmentInterface $shipment, - ?ShippingExportInterface $shippingExport = null, + ShippingExportInterface $shippingExport, ): array { - $this->shippingExport = $shippingExport; - /** @var OrderInterface $order */ $order = $shipment->getOrder(); @@ -168,7 +168,7 @@ public function createShipment( 'external_customer_id' => $customer->getId(), 'receiver' => $this->createReceiverDetails($order), 'custom_attributes' => $this->createCustomAttributes($shipment), - 'parcels' => [$this->createParcel($shipment)], + 'parcels' => [$this->createParcel($shipment, $shippingExport)], 'service' => $this->getShippingGatewayConfig('service'), 'additional_services' => $this->getAdditionalServices(), 'reference' => 'Order: ' . $order->getNumber(), @@ -326,12 +326,10 @@ private function isCashOnDelivery(OrderInterface $order): bool private function createParcel( ShipmentInterface $shipment, + ShippingExportInterface $shippingExport, ): array { $weight = $shipment->getShippingWeight(); - $template = 'large'; - if (null !== $this->shippingExport) { - $template = $this->shippingExport->getParcelTemplate(); - } + $template = $shippingExport->getParcelTemplate(); return [ 'id' => $shipment->getId(), @@ -340,7 +338,7 @@ private function createParcel( 'unit' => 'kg', ], 'dimensions' => [], - 'template' => $template, + 'template' => $template ?? $this->parcelTemplate, 'tracking_number' => null, 'is_non_standard' => false, ]; diff --git a/src/Api/WebClientInterface.php b/src/Api/WebClientInterface.php index 4530fc6..69b89b8 100644 --- a/src/Api/WebClientInterface.php +++ b/src/Api/WebClientInterface.php @@ -79,7 +79,7 @@ public function getLabels(array $shipmentIds): ?string; public function getAuthorizedHeaderWithContentType(): array; - public function createShipment(ShipmentInterface $shipment, ?ShippingExportInterface $shippingExport = null): array; + public function createShipment(ShipmentInterface $shipment, ShippingExportInterface $shippingExport): array; public function request( string $method, diff --git a/src/Resources/config/config.yml b/src/Resources/config/config.yml index 141e502..b02e731 100644 --- a/src/Resources/config/config.yml +++ b/src/Resources/config/config.yml @@ -1,10 +1,17 @@ parameters: - bitbag.inpost.label_type: 'normal' + bitbag.inpost.label_type: '%env(BITBAG_INPOST_DEFAULT_LABEL_TYPE)%' + bitbag.inpost.parcel_template: '%env(BITBAG_INPOST_DEFAULT_PARCEL_TEMPLATE)%' + env(BITBAG_INPOST_DEFAULT_LABEL_TYPE): 'normal' + env(BITBAG_INPOST_DEFAULT_PARCEL_TEMPLATE): 'large' + imports: - { resource: "@BitBagSyliusInPostPlugin/Resources/config/services.xml" } - { resource: "@BitBagSyliusInPostPlugin/Resources/config/resource/bitbag_inpost.yml" } - { resource: "@BitBagSyliusInPostPlugin/Resources/config/sylius_ui.yml" } - { resource: "@BitBagSyliusInPostPlugin/Resources/config/grid/*" } + twig: globals: inpost_client: '@bitbag.sylius_inpost_plugin.api.web_client' + bitbag_inpost_parcel_template: '%env(BITBAG_INPOST_DEFAULT_PARCEL_TEMPLATE)%' + diff --git a/src/Resources/config/services.xml b/src/Resources/config/services.xml index 30bffe5..ea6b889 100644 --- a/src/Resources/config/services.xml +++ b/src/Resources/config/services.xml @@ -52,6 +52,7 @@ %bitbag.inpost.label_type% + %bitbag.inpost.parcel_template% - {{ 'bitbag_sylius_inpost_plugin.ui.parcel_template.select_template'|trans }} - -
+ {% set parcelTemplate = bitbag_inpost_parcel_template %} {% endif %} {% set templates = {} %} diff --git a/tests/Application/.env b/tests/Application/.env index f4d17a6..83583c2 100644 --- a/tests/Application/.env +++ b/tests/Application/.env @@ -15,6 +15,9 @@ APP_SECRET=EDITME DATABASE_URL=mysql://root@127.0.0.1/bitbag_sylius_inpost_plugin_%kernel.environment% ###< doctrine/doctrine-bundle ### +BITBAG_INPOST_DEFAULT_LABEL_TYPE='normal' +BITBAG_INPOST_DEFAULT_PARCEL_TEMPLATE='medium' + ###> lexik/jwt-authentication-bundle ### JWT_SECRET_KEY=%kernel.project_dir%/config/jwt/private.pem JWT_PUBLIC_KEY=%kernel.project_dir%/config/jwt/public.pem From 80cdcfbb6188794f3c46fe1cb3e8b8458ef163b9 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Tomasz=20Kali=C5=84ski?= Date: Tue, 13 Aug 2024 13:07:11 +0200 Subject: [PATCH 13/16] OP-319 - Behat feature fixed --- features/changing_shipping_method_parcel_template.feature | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/features/changing_shipping_method_parcel_template.feature b/features/changing_shipping_method_parcel_template.feature index 71fb854..c7341f4 100644 --- a/features/changing_shipping_method_parcel_template.feature +++ b/features/changing_shipping_method_parcel_template.feature @@ -24,5 +24,5 @@ Feature: Changing shipping export parcel template Scenario: Seeing shipments to export When I go to the shipping export page Then I should see 1 shipments with "New" state - When I select parcel template + Then I select parcel template Then I should see that shipping export parcel template is set From ebf8ae9cbf0ac8b30037af78a2a15532526519cd Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Tomasz=20Kali=C5=84ski?= Date: Tue, 13 Aug 2024 15:57:24 +0200 Subject: [PATCH 14/16] OP-319 - The way the controller is overwritten has been changed --- doc/installation.md | 89 ++++++++++++++++++- src/Controller/SelectParcelTemplateTrait.php | 38 ++++++++ .../bitbag_sylius_shipping_export_plugin.yaml | 2 +- .../Controller/ShippingExportController.php | 23 +---- 4 files changed, 130 insertions(+), 22 deletions(-) create mode 100644 src/Controller/SelectParcelTemplateTrait.php rename {src => tests/Application/src}/Controller/ShippingExportController.php (80%) diff --git a/doc/installation.md b/doc/installation.md index 6b8513a..be8da21 100644 --- a/doc/installation.md +++ b/doc/installation.md @@ -43,9 +43,93 @@ bitbag_shipping_export_plugin.yaml to the config/packages and config/routes dire It also adding the appropriate entry to config/bundles.php. If it doesn't, so please remember to do the same as above for SyliusShippingExportPlugin configuration. -Add after @BitBagSyliusShippingExportPlugin import: +### Create a new controller: +```php +// src/Controller/ShippingExportController + +requestConfigurationFactory->create($this->metadata, $request); + + Assert::implementsInterface($this->repository, ShippingExportRepositoryInterface::class); + $shippingExports = $this->repository->findAllWithNewOrPendingState(); + + if (0 === count($shippingExports)) { + /** @var FlashBagInterface $flashBag */ + $flashBag = $request->getSession()->getBag('flashes'); + $flashBag->add('error', 'bitbag.ui.no_new_shipments_to_export'); + + return $this->redirectToReferer($request); + } + + foreach ($shippingExports as $shippingExport) { + $this->eventDispatcher->dispatch( + ExportShipmentEvent::SHORT_NAME, + $configuration, + $shippingExport, + ); + } + + return $this->redirectToReferer($request); + } + + public function exportSingleShipmentAction(Request $request): RedirectResponse + { + $configuration = $this->requestConfigurationFactory->create($this->metadata, $request); + + /** @var ResourceInterface|null $shippingExport */ + $shippingExport = $this->repository->find($request->get('id')); + Assert::notNull($shippingExport); + + $this->eventDispatcher->dispatch( + ExportShipmentEvent::SHORT_NAME, + $configuration, + $shippingExport, + ); + + return $this->redirectToReferer($request); + } + + private function redirectToReferer(Request $request): RedirectResponse + { + $referer = $request->headers->get('referer'); + if (null !== $referer) { + return new RedirectResponse($referer); + } + + return $this->redirectToRoute($request->attributes->get('_route')); + } +} + +``` + +Complete the **config/packages/bitbag_shipping_export_plugin.yaml** file with the following data: + ```yaml # config/packages/bitbag_shipping_export_plugin.yaml + imports: - { resource: "@BitBagSyliusShippingExportPlugin/Resources/config/config.yml" } @@ -54,7 +138,7 @@ sylius_resource: bitbag.shipping_export: classes: model: App\Entity\Shipping\ShippingExport - controller: BitBag\SyliusInPostPlugin\Controller\ShippingExportController + controller: App\Controller\ShippingExportController ``` Remember that in case of different mapping, the model path may be different. @@ -325,6 +409,7 @@ class ShippingExport extends BaseShippingExport implements ShippingExportInterfa } } ``` + Finish the installation by updating the database schema (check in advance: [Known Issues](known_issues.md)): ``` diff --git a/src/Controller/SelectParcelTemplateTrait.php b/src/Controller/SelectParcelTemplateTrait.php new file mode 100644 index 0000000..7e6d385 --- /dev/null +++ b/src/Controller/SelectParcelTemplateTrait.php @@ -0,0 +1,38 @@ +requestConfigurationFactory->create($this->metadata, $request); + + /** @var ResourceInterface|null $shippingExport */ + $shippingExport = $this->repository->find($request->get('id')); + Assert::notNull($shippingExport); + $shippingExport->setParcelTemplate($request->get('template')); + + $this->eventDispatcher->dispatch( + self::SELECT_PARCEL_TEMPLATE_EVENT, + $configuration, + $shippingExport, + ); + + return $this->redirectToReferer($request); + } +} diff --git a/tests/Application/config/packages/bitbag_sylius_shipping_export_plugin.yaml b/tests/Application/config/packages/bitbag_sylius_shipping_export_plugin.yaml index 18afff6..5944ca5 100644 --- a/tests/Application/config/packages/bitbag_sylius_shipping_export_plugin.yaml +++ b/tests/Application/config/packages/bitbag_sylius_shipping_export_plugin.yaml @@ -6,4 +6,4 @@ sylius_resource: bitbag.shipping_export: classes: model: Tests\BitBag\SyliusInPostPlugin\Application\src\Entity\ShippingExport - controller: BitBag\SyliusInPostPlugin\Controller\ShippingExportController + controller: Tests\BitBag\SyliusInPostPlugin\Application\src\Controller\ShippingExportController diff --git a/src/Controller/ShippingExportController.php b/tests/Application/src/Controller/ShippingExportController.php similarity index 80% rename from src/Controller/ShippingExportController.php rename to tests/Application/src/Controller/ShippingExportController.php index 5949e65..cfbf6c0 100644 --- a/src/Controller/ShippingExportController.php +++ b/tests/Application/src/Controller/ShippingExportController.php @@ -9,8 +9,9 @@ declare(strict_types=1); -namespace BitBag\SyliusInPostPlugin\Controller; +namespace Tests\BitBag\SyliusInPostPlugin\Application\src\Controller; +use BitBag\SyliusInPostPlugin\Controller\SelectParcelTemplateTrait; use BitBag\SyliusShippingExportPlugin\Event\ExportShipmentEvent; use BitBag\SyliusShippingExportPlugin\Repository\ShippingExportRepositoryInterface; use Sylius\Bundle\ResourceBundle\Controller\ResourceController; @@ -24,6 +25,8 @@ final class ShippingExportController extends ResourceController { public const SELECT_PARCEL_TEMPLATE_EVENT = 'export_shipping_select_parcel_template'; + use SelectParcelTemplateTrait; + public function exportAllNewShipmentsAction(Request $request): RedirectResponse { $configuration = $this->requestConfigurationFactory->create($this->metadata, $request); @@ -67,24 +70,6 @@ public function exportSingleShipmentAction(Request $request): RedirectResponse return $this->redirectToReferer($request); } - public function selectParcelTemplate(Request $request): RedirectResponse - { - $configuration = $this->requestConfigurationFactory->create($this->metadata, $request); - - /** @var ResourceInterface|null $shippingExport */ - $shippingExport = $this->repository->find($request->get('id')); - Assert::notNull($shippingExport); - $shippingExport->setParcelTemplate($request->get('template')); - - $this->eventDispatcher->dispatch( - self::SELECT_PARCEL_TEMPLATE_EVENT, - $configuration, - $shippingExport, - ); - - return $this->redirectToReferer($request); - } - private function redirectToReferer(Request $request): RedirectResponse { $referer = $request->headers->get('referer'); From 0198a0e61f6593de40eb3fcfef6809a13470d362 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Tomasz=20Kali=C5=84ski?= Date: Tue, 20 Aug 2024 12:54:17 +0200 Subject: [PATCH 15/16] OP-319 - Lexical error has been fixed --- doc/installation.md | 2 +- src/Resources/config/services.xml | 2 +- tests/Application/src/Controller/ShippingExportController.php | 2 +- 3 files changed, 3 insertions(+), 3 deletions(-) diff --git a/doc/installation.md b/doc/installation.md index be8da21..0dda2bc 100644 --- a/doc/installation.md +++ b/doc/installation.md @@ -65,7 +65,7 @@ use Webmozart\Assert\Assert; final class ShippingExportController extends ResourceController { - public const SELECT_PARCEL_TEMPLATE_EVENT = 'export_shipping_select_parcel_template'; + public const SELECT_PARCEL_TEMPLATE_EVENT = 'select_parcel_template'; use SelectParcelTemplateTrait; diff --git a/src/Resources/config/services.xml b/src/Resources/config/services.xml index ea6b889..b06d055 100644 --- a/src/Resources/config/services.xml +++ b/src/Resources/config/services.xml @@ -32,7 +32,7 @@ id="bitbag.sylius_inpost_plugin.event_listener.inpost_select_parcel_template" > - +
Date: Tue, 27 Aug 2024 10:15:21 +0200 Subject: [PATCH 16/16] OP-319 - installation.md and code review fixes --- doc/installation.md | 22 +++------------------- spec/Api/WebClientSpec.php | 1 - 2 files changed, 3 insertions(+), 20 deletions(-) diff --git a/doc/installation.md b/doc/installation.md index 0dda2bc..b250deb 100644 --- a/doc/installation.md +++ b/doc/installation.md @@ -122,7 +122,6 @@ final class ShippingExportController extends ResourceController return $this->redirectToRoute($request->attributes->get('_route')); } } - ``` Complete the **config/packages/bitbag_shipping_export_plugin.yaml** file with the following data: @@ -139,7 +138,6 @@ sylius_resource: classes: model: App\Entity\Shipping\ShippingExport controller: App\Controller\ShippingExportController - ``` Remember that in case of different mapping, the model path may be different. Default: @@ -167,7 +165,6 @@ sylius_shipping: shipping_method: classes: model: App\Entity\ShippingMethod - ``` Add trait and interface to your Order and ShippingMethod entity classes: @@ -298,7 +295,6 @@ doctrine: App: ... type: attribute - ``` ```php point = $point; } } - ``` ```php @@ -371,10 +366,9 @@ class ShippingMethod extends BaseShippingMethod implements ImageAwareInterface { $this->image = $image; } - + // other methods } - ``` ```php