Packaging Units feature integration
Edit on GitHubInstall Feature Core
Prerequisites
To start feature integration, overview and install the necessary features:
Name | Version |
---|---|
Inventory Management | 201903.0 |
Spryker Core | 201903.0 |
Order Management | 201903.0 |
Product | 201903.0 |
Measurement Units | 201903.0 |
1) Install the required modules using Composer
Run the following command(s) to install the required modules:
composer require spryker-feature/packaging-units:"^201903.0" --update-with-dependencies
Module | Expected Directory |
---|---|
ProductPackagingUnit |
vendor/spryker/product-packaging-unit |
ProductPackagingUnitDataImport |
vendor/spryker/product-packaging-unit-data-import |
ProductPackagingUnitStorage |
vendor/spryker/product-packaging-unit-storage |
2) Set up Configuration
Adjust synchronization queue pools in the configuration:
src/Pyz/Zed/ProductPackagingUnitStorage/ProductPackagingUnitStorageConfig.php
<?php
namespace Pyz\Zed\ProductPackagingUnitStorage;
use Pyz\Zed\Synchronization\SynchronizationConfig;
use Spryker\Zed\ProductPackagingUnitStorage\ProductPackagingUnitStorageConfig as SprykerProductPackagingUnitStorageConfig;
class ProductPackagingUnitStorageConfig extends SprykerProductPackagingUnitStorageConfig
{
/**
* @return string|null
*/
public function getProductPackagingUnitSynchronizationPoolName(): ?string
{
return SynchronizationConfig::DEFAULT_SYNCHRONIZATION_POOL_NAME; // "synchronizationPool"
}
}
3) Set up the Database Schema and Transfer Objects
Adjust the schema definition so that entity changes can trigger events.
- `Entity.spy_product_packaging_unit.create`
- `Entity.spy_product_packaging_unit.update`
- `Entity.spy_product_packaging_unit.delete`
- `Entity.spy_product_packaging_unit_type.creat`
- `Entity.spy_product_packaging_unit_type.update`
- `Entity.spy_product_packaging_unit_type.delete`
- `Entity.spy_product_packaging_unit_amount.create`
- `Entity.spy_product_packaging_unit_amount.update`
- `Entity.spy_product_packaging_unit_amount.delete`
- `Entity.spy_product_packaging_lead_product.create`
- `Entity.spy_product_packaging_lead_product.update`
- `Entity.spy_product_packaging_lead_product.delete`
src/Pyz/Zed/ProductPackagingUnit/Persistence/Propel/Schema/spy_product_packaging_unit.schema.xml
<?xml version="1.0"?>
<database xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" name="zed" xsi:noNamespaceSchemaLocation="http://static.spryker.com/schema-01.xsd" namespace="Orm\Zed\ProductPackagingUnit\Persistence" package="src.Orm.Zed.ProductPackagingUnit.Persistence">
<table name="spy_product_packaging_unit" phpName="SpyProductPackagingUnit">
<behavior name="event">
<parameter name="spy_product_packaging_unit_all" column="*"/>
</behavior>
</table>
<table name="spy_product_packaging_unit_type" phpName="SpyProductPackagingUnitType">
<behavior name="event">
<parameter name="spy_product_packaging_unit_type_all" column="*"/>
</behavior>
</table>
<table name="spy_product_packaging_unit_amount" phpName="SpyProductPackagingUnitAmount">
<behavior name="event">
<parameter name="spy_product_packaging_unit_amount_all" column="*"/>
</behavior>
</table>
<table name="spy_product_packaging_lead_product" phpName="SpyProductPackagingLeadProduct">
<behavior name="event">
<parameter name="spy_product_packaging_lead_product_all" column="*"/>
</behavior>
</table>
</database>
Set up synchronization queue pools so that non-multistore entities (not store-specific entities) can be synchronized among stores:
src/Pyz/Zed/ProductPackagingUnitStorage/Persistence/Propel/Schema/spy_product_abstract_packaging_storage.schema.xml
<?xml version="1.0"?>
<database xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
name="zed"
xsi:noNamespaceSchemaLocation="http://static.spryker.com/schema-01.xsd"
namespace="Orm\Zed\ProductPackagingUnitStorage\Persistence"
package="src.Orm.Zed.ProductPackagingUnitStorage.Persistence">
<table name="spy_product_abstract_packaging_storage">
<behavior name="synchronization">
<parameter name="queue_pool" value="synchronizationPool" />
</behavior>
</table>
</database>
Run the following commands to apply the database changes and generate entity and transfer changes:
console transfer:generate
console propel:install
console transfer:generate
Database Entity | Type | Event |
---|---|---|
spy_product_packaging_unit |
table | created |
spy_product_packaging_unit_type |
table | created |
spy_product_packaging_unit_amount |
table | created |
spy_product_packaging_lead_product |
table | created |
spy_product_abstract_packaging_storage |
table | created |
spy_sales_order_item.amount |
column | created |
spy_sales_order_item.amount_sku |
column | created |
Transfer | Type | Event | Path |
---|---|---|---|
ProductPackagingUnitType |
class | created | src/Generated/Shared/Transfer/ProductPackagingUnitTypeTransfer |
ProductPackagingUnitTypeTranslation |
class | created | src/Generated/Shared/Transfer/ProductPackagingUnitTypeTranslationTransfer |
ProductPackagingUnit |
class | created | src/Generated/Shared/Transfer/ProductPackagingUnitTransfer |
ProductPackagingUnitAmount |
class | created | src/Generated/Shared/Transfer/ProductPackagingUnitAmountTransfer |
ProductPackagingLeadProduct |
class | created | src/Generated/Shared/Transfer/ProductPackagingLeadProductTransfer |
Item |
class | created | src/Generated/Shared/Transfer/ItemTransfer |
ProductConcretePackagingStorage |
class | created | src/Generated/Shared/Transfer/ProductConcretePackagingStorageTransfer |
ProductAbstractPackagingStorage |
class | created | src/Generated/Shared/Transfer/ProductAbstractPackagingStorageTransfer |
SpyProductPackagingLeadProductEntity |
class | created | src/Generated/Shared/Transfer/SpyProductPackagingLeadProductEntityTransfer |
SpyProductPackagingUnitAmountEntity |
class | created | src/Generated/Shared/Transfer/SpyProductPackagingUnitAmountEntityTransfer |
SpyProductPackagingUnitEntity |
class | created | src/Generated/Shared/Transfer/SpyProductPackagingUnitEntityTransfer |
SpyProductPackagingUnitTypeEntity |
class | created | src/Generated/Shared/Transfer/SpyProductPackagingUnitTypeEntityTransfer |
SpyProductAbstractPackagingStorageEntity |
class | created | src/Generated/Shared/Transfer/SpyProductAbstractPackagingStorageEntityTransfer |
SpySalesOrderItemEntityTransfer.amount |
property | created | src/Generated/Shared/Transfer/SpySalesOrderItemEntityTransfer |
SpySalesOrderItemEntityTransfer.amountSku |
property | created | src/Generated/Shared/Transfer/SpySalesOrderItemEntityTransfer |
Make sure that the changes have been implemented successfully. For this purpose, trigger the following methods and make sure that the above events have been triggered:
Path | Method name |
---|---|
src/Orm/Zed/ProductPackagingUnit/Persistence/Base/SpyProductPackagingLeadProduct.php |
prepareSaveEventName() addSaveEventToMemory() addDeleteEventToMemory() |
src/Orm/Zed/ProductPackagingUnit/Persistence/Base/SpyProductPackagingUnit.php |
prepareSaveEventName() addSaveEventToMemory() addDeleteEventToMemory() |
src/Orm/Zed/ProductPackagingUnit/Persistence/Base/SpyProductPackagingUnitAmount.php |
prepareSaveEventName() addSaveEventToMemory() addDeleteEventToMemory() |
src/Orm/Zed/ProductPackagingUnit/Persistence/Base/SpyProductPackagingUnitType.php |
prepareSaveEventName() addSaveEventToMemory() addDeleteEventToMemory() |
src/Orm/Zed/ProductPackagingUnitStorage/Persistence/Base/SpyProductAbstractPackagingStorage.php |
sendToQueue() |
4) Add Translations
Append glossary according to your language configuration:
src/data/import/glossary.csv
cart.pre.check.availability.failed.lead.product,Products inside the item 'sku' are not available at the moment.,en_US
cart.pre.check.availability.failed.lead.product,Produkte im Artikel 'sku' sind momentan nicht verfügbar.,de_DE
product.unavailable,Product '%sku%' is not available at the moment,en_US
product.unavailable,Das Produkt '%sku%' ist momentan nicht verfügbar,de_DE
cart.pre.check.amount.min.failed,Die minimale Mengenanforderung für Produkt SKU '%sku%' ist nicht erreicht.,de_DE
cart.pre.check.amount.min.failed,Minimum amount requirements for product SKU '%sku%' are not fulfilled.,en_US
cart.pre.check.amount.max.failed,Die maximale Mengenanforderung für Produkt SKU '%sku%' ist überschritten.,de_DE
cart.pre.check.amount.max.failed,Maximum amount for product SKU '%sku%' is exceeded.,en_US
cart.pre.check.amount.interval.failed,Die Anzahl für Produkt SKU '%sku%' liegt nicht innerhalb des vorgegebenen Intervals.,de_DE
cart.pre.check.amount.interval.failed,Amount interval requirements for product SKU '%sku%' are not fulfilled.,en_US
cart.pre.check.amount.is_not_variable.failed,Standardbetrag für Produkt SKU '%sku%' ist überschritten.,de_DE
cart.pre.check.amount.is_not_variable.failed,Default amount requirements for product SKU '%sku%' are not fulfilled.,en_US
Infrastructural record’s glossary keys:
src/data/import/glossary.csv
packaging_unit_type.item.name,Item,en_US
packaging_unit_type.item.name,Stück,de_DE
Demo data glossary keys:
src/data/import/glossary.csv
packaging_unit_type.ring_500.name,"Ring (500m)",en_US
packaging_unit_type.ring_500.name,"Ring (500m)",de_DE
packaging_unit_type.box.name,Box,en_US
packaging_unit_type.box.name,Box,de_DE
packaging_unit_type.palette.name,Palette,en_US
packaging_unit_type.palette.name,Palette,de_DE
packaging_unit_type.giftbox.name,Giftbox,en_US
packaging_unit_type.giftbox.name,Geschenkbox,de_DE
packaging_unit_type.valentines_special.name,"Valentine's special",en_US
packaging_unit_type.valentines_special.name,Valentinstag Geschenkbox,de_DE
packaging_unit_type.pack_20.name,Pack 20,en_US
packaging_unit_type.pack_20.name,Pack 20,de_DE
packaging_unit_type.pack_500.name,Pack 500,en_US
packaging_unit_type.pack_500.name,Pack 500,de_DE
packaging_unit_type.pack_100.name,Pack 100,en_US
packaging_unit_type.pack_100.name,Pack 100,de_DE
packaging_unit_type.pack_mixed.name,Mixed Screws boxes,en_US
packaging_unit_type.pack_mixed.name,Gemischte Schraubenkästen,de_D
Run the following console command to import data:
console data:import glossary
5) Configure Export to Redis
This step will publish tables on change (create, edit, delete) to spy_product_abstract_packaging_storage
and synchronize the data to Storage.
Set up Event Listeners
Plugin | Specification | Prerequisites | Namespace |
---|---|---|---|
ProductPackagingUnitStorageEventSubscriber |
Registers listeners that are responsible for publishing product abstract packaging unit storage entity changes when a related entity change event occurs. | None | Spryker\Zed\ProductPackagingUnitStorage\Communication\Plugin\Event\Subscriber |
src/Pyz/Zed/Event/EventDependencyProvider.php
<?php
namespace Pyz\Zed\Event;
use Spryker\Zed\Event\EventDependencyProvider as SprykerEventDependencyProvider;
use Spryker\Zed\ProductPackagingUnitStorage\Communication\Plugin\Event\Subscriber\ProductPackagingUnitStorageEventSubscriber;
class EventDependencyProvider extends SprykerEventDependencyProvider
{
public function getEventSubscriberCollection()
{
$eventSubscriberCollection = parent::getEventSubscriberCollection();
$eventSubscriberCollection->add(new ProductPackagingUnitStorageEventSubscriber());
return $eventSubscriberCollection;
}
}
Set up Re-Generate and Re-Sync Features
Plugin | Specification | Prerequisites | Namespace |
---|---|---|---|
ProductPackagingUnitSynchronizationDataPlugin |
Allows synchronizing the whole storage table content into Storage. | None | Spryker\Zed\ProductPackagingUnitStorage\Communication\Plugin\Synchronization |
src/Pyz/Zed/Synchronization/SynchronizationDependencyProvider.php
<?php
namespace Pyz\Zed\Synchronization;
use Spryker\Zed\ProductPackagingUnitStorage\Communication\Plugin\Synchronization\ProductPackagingUnitSynchronizationDataPlugin;
use Spryker\Zed\Synchronization\SynchronizationDependencyProvider as SprykerSynchronizationDependencyProvider;
class SynchronizationDependencyProvider extends SprykerSynchronizationDependencyProvider
{
/**
* @return \Spryker\Zed\SynchronizationExtension\Dependency\Plugin\SynchronizationDataPluginInterface[]
*/
protected function getSynchronizationDataPlugins(): array
{
return [
new ProductPackagingUnitSynchronizationDataPlugin(),
];
}
}
6) Import Data
Add Infrastructural Data
Plugin | Specification | Prerequisites | Namespace |
---|---|---|---|
ProductPackagingUnitTypeInstallerPlugin |
Installs the configured infrastructural packaging unit types. | None | Spryker\Zed\ProductPackagingUnit\Communication\Plugin\Installer |
src/Pyz/Zed/Installer/InstallerDependencyProvider.php
<?php
namespace Pyz\Zed\Installer;
use Spryker\Zed\Installer\InstallerDependencyProvider as SprykerInstallerDependencyProvider;
use Spryker\Zed\ProductPackagingUnit\Communication\Plugin\Installer\ProductPackagingUnitTypeInstallerPlugin;
class InstallerDependencyProvider extends SprykerInstallerDependencyProvider
{
/**
* @return \Spryker\Zed\Installer\Dependency\Plugin\InstallerPluginInterface[]
*/
public function getInstallerPlugins()
{
/**
* @return \Spryker\Zed\Installer\Dependency\Plugin\InstallerPluginInterface[]
*/
public function getInstallerPlugins()
{
return [
new ProductPackagingUnitTypeInstallerPlugin(),
];
}
}
Run the following console command to execute registered installer plugins and install infrastructural data:
console setup:init-db
Import Product Packaging Unit Types
Prepare your data according to your requirements using our demo data:
vendor/spryker/spryker/Bundles/ProductPackagingUnitDataImport/data/import/product_packaging_unit_type.csv
name
packaging_unit_type.ring_500.name
packaging_unit_type.box.name
packaging_unit_type.palette.name
packaging_unit_type.giftbox.name
packaging_unit_type.valentines_special.name
packaging_unit_type.pack_mixed.name
packaging_unit_type.pack_20.name
packaging_unit_type.pack_100.name
packaging_unit_type.pack_500.name
Column | REQUIRED | Data Type | Data Example | Data Explanation |
---|---|---|---|---|
name |
mandatory | string | packaging_unit_type.ring_500.name |
Glossary key that will be used for display. Each name needs a glossary key definition for all configured locales. |
Register the following plugin to enable data import:
Plugin | Specification | Prerequisites | Namespace |
---|---|---|---|
ProductPackagingUnitTypeDataImportPlugin |
Imports packaging unit type data into the database. | None | Spryker\Zed\ProductPackagingUnitDataImport\Communication\Plugin\DataImport |
src/Pyz/Zed/DataImport/DataImportDependencyProvider.php
<?php
namespace Pyz\Zed\DataImport;
use Spryker\Zed\DataImport\DataImportDependencyProvider as SprykerDataImportDependencyProvider;
use Spryker\Zed\ProductPackagingUnitDataImport\Communication\Plugin\DataImport\ProductPackagingUnitTypeDataImportPlugin;
class DataImportDependencyProvider extends SprykerDataImportDependencyProvider
{
protected function getDataImporterPlugins(): array
{
return [
new ProductPackagingUnitTypeDataImportPlugin(),
];
}
}
Run the following console command to import data:
console data:import product-packaging-unit-type
Import Product Packaging Units
Prepare your data according to your requirements using our demo data:
vendor/spryker/spryker/Bundles/ProductPackagingUnitDataImport/data/import/product_packaging_unit.csv
concrete_sku,is_lead_product,has_lead_product,packaging_unit_type_name,default_amount,is_variable,amount_min,amount_max,amount_interval
218_123,1,,packaging_unit_type.item.name,,,,,
217_123,1,,packaging_unit_type.item.name,,,,,
218_1233,0,0,packaging_unit_type.pack_mixed.name,5,1,3,5,2
218_1234,0,1,packaging_unit_type.box.name,100,1,100,1000,10
218_1230,0,1,packaging_unit_type.pack_20.name,20,0,0,0,0
218_1231,0,1,packaging_unit_type.pack_100.name,100,0,0,0,0
218_1232,0,1,packaging_unit_type.pack_500.name,500,0,0,0,0
217_1231,0,0,packaging_unit_type.ring_500.name,1,0,,,
215_123,1,,packaging_unit_type.item.name,,,,,
215_124,0,0,packaging_unit_type.ring_500.name,1,0,,,
216_123,1,,packaging_unit_type.item.name,,,,,
- Relevant for non-lead product concretes only.
- Decides if the current product concrete has "amount" options. (The amount represents the lead product.)
- The default value is 0 when not provided.
- Defines how many lead products should be sold together with each quantity of the current product concrete.
- Effective only if the current concrete product `has_lead_product = 1`.
- The default value is 1 when not provided.
- Allows customers to override the `default_amount` and decide how many lead products will be ordered for each quantity of this product concrete.
- Effective only if current product concrete `has_lead_product = 1`.
- The default value is 0 when not provided.
- Restricts a customer to buy at least this amount of lead products.
- Effective only if `is_variable = 1`.
- the default value is 1 when not provided.
- Restricts a customer not to not buy more than this value.
- Effective only if `is_variable = 1`.
- The default value remains empty (unlimited) when not provided.
- Restricts customers to buy an amount that fits into the interval beginning with `amount_min`.
- Effective only if `is_variable = 1`.
- The default value is amount_min when not provided.
Choosable: 3, 5, 7, 9|
Register the following plugin to enable data import:
- Requires related product concretes and product abstract to be present in the database already.
- Requires related packaging unit types to be present in the database already.
src/Pyz/Zed/DataImport/DataImportDependencyProvider.php
<?php
namespace Pyz\Zed\DataImport;
use Spryker\Zed\DataImport\DataImportDependencyProvider as SprykerDataImportDependencyProvider;
use Spryker\Zed\ProductPackagingUnitDataImport\Communication\Plugin\DataImport\ProductPackagingUnitDataImportPlugin;
class DataImportDependencyProvider extends SprykerDataImportDependencyProvider
{
protected function getDataImporterPlugins(): array
{
return [
new ProductPackagingUnitDataImportPlugin(),
];
}
}
Run the following console command to import data:
console data:import product-packaging-unit
7) Set up Behavior
Set up Checkout Workflow
Enable the following behaviors by registering the plugins:
Plugin | Specification | Prerequisites | Namespace |
---|---|---|---|
AmountAvailabilityCartPreCheckPlugin |
Validates if the given amount is available according to stock configuration during the cart change. | Expects the amount field to be set in ItemTransfers with packaging units. |
Spryker\Zed\ProductPackagingUnit\Communication\Plugin\Cart |
AmountGroupKeyItemExpanderPlugin |
Expands a group key with the amount and its sales unit to granulate the item grouping in the cart for packaging unit items. | Expects the amount and amountSalesUnit fields to be set in ItemTransfers with packaging units. |
Spryker\Zed\ProductPackagingUnit\Communication\Plugin\Cart |
AmountRestrictionCartPreCheckPlugin |
Validates the amount restrictions when Item has restrictions. | Expects the amount and amountSalesUnit fields to be set in ItemTransfer with packaging units. |
Spryker\Zed\ProductPackagingUnit\Communication\Plugin\Cart |
AmountSalesUnitItemExpanderPlugin |
Sets the amountSalesUnit field for ItemTransfers with packaging units. |
Expects the amount and amountSalesUnit.IdProductMeasurementSalesUnit to be set in ItemTransfers with packaging units. |
Spryker\Zed\ProductPackagingUnit\Communication\Plugin\Cart |
AmountSalesUnitValuePostSavePlugin |
Sets normalized amount sales unit value field. | Expects the amount and amountSalesUnit fields to be set in ItemTransfer with packaging units. |
Spryker\Zed\ProductPackagingUnit\Communication\Plugin\Cart |
CustomAmountPriceItemExpanderPlugin |
Updates unit prices for variable amounted packaging units. | Expects the amount and productPackagingUnit fields to be set in ItemTransfers with packaging units. |
Spryker\Zed\ProductPackagingUnit\Communication\Plugin\Cart |
ProductPackagingUnitCartAddItemStrategyPlugin |
Merges quantity and amount field changes into the cart for ItemTransfers with packaging units on the cart add action. |
Expects the amount field to be set in ItemTransfers with packaging units. |
Spryker\Zed\ProductPackagingUnit\Communication\Plugin\Cart |
ProductPackagingUnitCartRemoveItemStrategyPlugin |
Merges the quantity and amount field changes into the cart for ItemTransfers with packaging units on the cart removal action. |
Expects the amount field to be set in ItemTransfers with packaging units. |
Spryker\Zed\ProductPackagingUnit\Communication\Plugin\Cart |
ProductPackagingUnitItemExpanderPlugin |
Sets the amountLeadProduct and productPackagingUnit fields in ItemTransfer. |
Expects the amount field to be set in ItemTransfers with packaging units. |
Spryker\Zed\ProductPackagingUnit\Communication\Plugin\Cart |
AmountAvailabilityCheckoutPreConditionPlugin |
Validates if the given amount is available according to stock configuration during checkout. | Expects the amount and amountLeadProduct fields to be set in ItemTransfers with packaging units. |
Spryker\Zed\ProductPackagingUnit\Communication\Plugin\Checkout |
ProductPackagingUnitCartAddItemStrategyPlugin |
Merges the quantity and amount field changes into the cart for ItemTransfers with packaging units on the persistent cart add action. |
Expects the amount field to be set in ItemTransfers with packaging units. |
Spryker\Zed\ProductPackagingUnit\Communication\Plugin\PersistentCart |
LeadProductReservationHandlerPlugin |
Updates availability and reservation of lead product for a given product packaging unit for reservation handler. | None | Spryker\Zed\ProductPackagingUnit\Communication\Plugin\Reservation |
AmountLeadProductHydrateOrderPlugin |
Hydrates the leadProduct field for Order read. |
Expects the items, amount and amountSku fields to be set in Order. |
Spryker\Zed\ProductPackagingUnit\Communication\Plugin\Sales |
AmountSalesUnitHydrateOrderPlugin |
Hydrates the amountSalesUnit field for Order read. |
Expects the items field to be set in Order. | Spryker\Zed\ProductPackagingUnit\Communication\Plugin\Sales |
AmountSalesUnitOrderItemExpanderPreSavePlugin |
Sets the amount measurement related fields in the Order item for saving. | Expects the amountSalesUnit field to be set in ItemTransfers with packaging units. |
Spryker\Zed\ProductPackagingUnit\Communication\Plugin\SalesExtension |
ProductPackagingUnitOrderItemExpanderPreSavePlugin |
Sets the amount and amountSku fields in the Order item for saving. |
Expects amountLeadProduct to be set in mTransfers with packaging units. |
Spryker\Zed\ProductPackagingUnit\Communication\Plugin\SalesExtension |
LeadProductStockUpdateHandlerPlugin |
Updates availability and reservation of lead product for a given product packaging unit for stock update handler. | None | Spryker\Zed\ProductPackagingUnit\Communication\Plugin\Stock |
ProductPackagingUnitAmountCartChangeRequestExpanderPlugin |
Sets the amount and amountSalesUnit.IdProductMeasurementSalesUnit fields in ItemTransfers with packaging units for cart change. |
Expects a request to contain the to-be-used information. | Spryker\Client\ProductPackagingUnit\Plugin\CartExtension |
ProductPackagingUnitAmountPersistentCartChangeExpanderPlugin |
Sets the amount and amountSalesUnit.IdProductMeasurementSalesUnit fields in ItemTransfers with packaging units for persistent cart change. |
Expects a request to contain the to-be-used information. | Spryker\Client\ProductPackagingUnit\Plugin\PersistentCartExtension |
src/Pyz/Client/Cart/CartDependencyProvider.php
<?php
namespace Pyz\Zed\Cart;
use Spryker\Zed\Cart\CartDependencyProvider as SprykerCartDependencyProvider;
use Spryker\Zed\ProductPackagingUnit\Communication\Plugin\Cart\AmountAvailabilityCartPreCheckPlugin;
use Spryker\Zed\ProductPackagingUnit\Communication\Plugin\Cart\AmountGroupKeyItemExpanderPlugin;
use Spryker\Zed\ProductPackagingUnit\Communication\Plugin\Cart\AmountRestrictionCartPreCheckPlugin;
use Spryker\Zed\ProductPackagingUnit\Communication\Plugin\Cart\AmountSalesUnitItemExpanderPlugin;
use Spryker\Zed\ProductPackagingUnit\Communication\Plugin\Cart\AmountSalesUnitValuePostSavePlugin;
use Spryker\Zed\ProductPackagingUnit\Communication\Plugin\Cart\CustomAmountPriceItemExpanderPlugin;
use Spryker\Zed\ProductPackagingUnit\Communication\Plugin\Cart\ProductPackagingUnitCartAddItemStrategyPlugin;
use Spryker\Zed\ProductPackagingUnit\Communication\Plugin\Cart\ProductPackagingUnitCartRemoveItemStrategyPlugin;
use Spryker\Zed\ProductPackagingUnit\Communication\Plugin\Cart\ProductPackagingUnitItemExpanderPlugin;
use Spryker\Zed\Kernel\Container;
class CartDependencyProvider extends SprykerCartDependencyProvider
{
/**
* @param \Spryker\Zed\Kernel\Container $container
*
* @return \Spryker\Zed\Cart\Dependency\ItemExpanderPluginInterface[]
*/
protected function getExpanderPlugins(Container $container)
{
return [
new AmountGroupKeyItemExpanderPlugin(),
new AmountSalesUnitItemExpanderPlugin(),
new ProductPackagingUnitItemExpanderPlugin(),
new CustomAmountPriceItemExpanderPlugin(),
];
}
/**
* @param \Spryker\Zed\Kernel\Container $container
*
* @return \Spryker\Zed\CartExtension\Dependency\Plugin\CartOperationStrategyPluginInterface[]
*/
protected function getCartRemoveItemStrategyPlugins(Container $container): array
{
return [
new ProductPackagingUnitCartRemoveItemStrategyPlugin(),
];
}
/**
* @param \Spryker\Zed\Kernel\Container $container
*
* @return \Spryker\Zed\CartExtension\Dependency\Plugin\CartPreCheckPluginInterface[]
*/
protected function getCartPreCheckPlugins(Container $container)
{
return [
new AmountAvailabilityCartPreCheckPlugin(),
new AmountRestrictionCartPreCheckPlugin(),
];
}
/**
* @param \Spryker\Zed\Kernel\Container $container
*
* @return \Spryker\Zed\Cart\Dependency\PostSavePluginInterface[]
*/
protected function getPostSavePlugins(Container $container)
{
return [
new AmountSalesUnitValuePostSavePlugin(),
];
}
/**
* @param \Spryker\Zed\Kernel\Container $container
*
* @return \Spryker\Zed\CartExtension\Dependency\Plugin\CartOperationStrategyPluginInterface[]
*/
protected function getCartAddItemStrategyPlugins(Container $container): array
{
return [
new ProductPackagingUnitCartAddItemStrategyPlugin(),
];
}
}
src/Pyz/Zed/Checkout/CheckoutDependencyProvider.php
<?php
namespace Pyz\Zed\Checkout;
use Spryker\Zed\Checkout\CheckoutDependencyProvider as SprykerCheckoutDependencyProvider;
use Spryker\Zed\ProductPackagingUnit\Communication\Plugin\Checkout\AmountAvailabilityCheckoutPreConditionPlugin;
use Spryker\Zed\Kernel\Container;
class CheckoutDependencyProvider extends SprykerCheckoutDependencyProvider
{
/**
* @param \Spryker\Zed\Kernel\Container $container ’
*
* @return \Spryker\Zed\Checkout\Dependency\Plugin\CheckoutPreConditionInterface[]
*/
protected function getCheckoutPreConditions(Container $container)
{
return [
new AmountAvailabilityCheckoutPreConditionPlugin(),
];
}
}
src/Pyz/Zed/PersistentCart/PersistentCartDependencyProvider.php
<?php
namespace Pyz\Zed\PersistentCart;
use Spryker\Zed\Kernel\Container;
use Spryker\Zed\PersistentCart\PersistentCartDependencyProvider as SprykerPersistentCartDependencyProvider;
use Spryker\Zed\ProductPackagingUnit\Communication\Plugin\PersistentCart\ProductPackagingUnitCartAddItemStrategyPlugin;
class PersistentCartDependencyProvider extends SprykerPersistentCartDependencyProvider
{
/**
* @param \Spryker\Zed\Kernel\Container $container
*
* @return \Spryker\Zed\CartExtension\Dependency\Plugin\CartOperationStrategyPluginInterface[]
*/
protected function getCartAddItemStrategyPlugins(Container $container): array
{
return [
new ProductPackagingUnitCartAddItemStrategyPlugin(),
];
}
}
src/Pyz/Zed/Oms/OmsDependencyProvider.php
<?php
namespace Pyz\Zed\Oms;
use Spryker\Zed\Kernel\Container;
use Spryker\Zed\Oms\OmsDependencyProvider as SprykerOmsDependencyProvider;
use Spryker\Zed\ProductPackagingUnit\Communication\Plugin\Reservation\LeadProductReservationHandlerPlugin;
class OmsDependencyProvider extends SprykerOmsDependencyProvider
{
/**
* @param \Spryker\Zed\Kernel\Container $container
*
* @return \Spryker\Zed\Oms\Dependency\Plugin\ReservationHandlerPluginInterface[]
*/
protected function getReservationHandlerPlugins(Container $container)
{
return [
new LeadProductReservationHandlerPlugin(),
];
}
}
src/Pyz/Zed/Sales/SalesDependencyProvider.php
<?php
namespace Pyz\Zed\Sales;
use Spryker\Zed\Sales\SalesDependencyProvider as SprykerSalesDependencyProvider;
use Spryker\Zed\ProductPackagingUnit\Communication\Plugin\Sales\AmountLeadProductHydrateOrderPlugin;
use Spryker\Zed\ProductPackagingUnit\Communication\Plugin\Sales\AmountSalesUnitHydrateOrderPlugin;
use Spryker\Zed\ProductPackagingUnit\Communication\Plugin\SalesExtension\AmountSalesUnitOrderItemExpanderPreSavePlugin;
use Spryker\Zed\ProductPackagingUnit\Communication\Plugin\SalesExtension\ProductPackagingUnitOrderItemExpanderPreSavePlugin;
class SalesDependencyProvider extends SprykerSalesDependencyProvider
{
/**
* @return \Spryker\Zed\Sales\Dependency\Plugin\HydrateOrderPluginInterface[]
*/
protected function getOrderHydrationPlugins()
{
return [
new AmountLeadProductHydrateOrderPlugin(),
new AmountSalesUnitHydrateOrderPlugin(),
];
}
/**
* @return \Spryker\Zed\SalesExtension\Dependency\Plugin\OrderItemExpanderPreSavePluginInterface[]
*/
protected function getOrderItemExpanderPreSavePlugins()
{
return [
new ProductPackagingUnitOrderItemExpanderPreSavePlugin(),
new AmountSalesUnitOrderItemExpanderPreSavePlugin(),
];
}
}
src/Pyz/Zed/Stock/StockDependencyProvider.php
<?php
namespace Pyz\Zed\Stock;
use Spryker\Zed\Kernel\Container;
use Spryker\Zed\ProductPackagingUnit\Communication\Plugin\Stock\LeadProductStockUpdateHandlerPlugin;
use Spryker\Zed\Stock\StockDependencyProvider as SprykerStockDependencyProvider;
class StockDependencyProvider extends SprykerStockDependencyProvider
{
/**
* @param \Spryker\Zed\Kernel\Container $container
*
* @return \Spryker\Zed\Stock\Dependency\Plugin\StockUpdateHandlerPluginInterface[]
*/
protected function getStockUpdateHandlerPlugins(Container $container)
{
return [
new LeadProductStockUpdateHandlerPlugin(),
];
}
}
src/Pyz/Client/Cart/CartDependencyProvider.php
<?php
namespace Pyz\Client\Cart;
use Spryker\Client\Cart\CartDependencyProvider as SprykerCartDependencyProvider;
use Spryker\Client\ProductPackagingUnit\Plugin\CartExtension\ProductPackagingUnitAmountCartChangeRequestExpanderPlugin;
class CartDependencyProvider extends SprykerCartDependencyProvider
{
/**
* @return \Spryker\Client\CartExtension\Dependency\Plugin\CartChangeRequestExpanderPluginInterface[]
*/
protected function getAddItemsRequestExpanderPlugins()
{
return [
new ProductPackagingUnitAmountCartChangeRequestExpanderPlugin(),
];
}
}
src/Pyz/Client/PersistentCart/PersistentCartDependencyProvider.php
<?php
namespace Pyz\Client\PersistentCart;
use Spryker\Client\PersistentCart\PersistentCartDependencyProvider as SprykerPersistentCartDependencyProvider;
use Spryker\Client\ProductPackagingUnit\Plugin\PersistentCartExtension\ProductPackagingUnitAmountPersistentCartChangeExpanderPlugin;
class PersistentCartDependencyProvider extends SprykerPersistentCartDependencyProvider
{
/**
* @return \Spryker\Client\PersistentCartExtension\Dependency\Plugin\PersistentCartChangeExpanderPluginInterface[]
*/
protected function getChangeRequestExtendPlugins(): array
{
return [
new ProductPackagingUnitAmountPersistentCartChangeExpanderPlugin(), #ProductPackagingUnit
];
}
}
- Check if the
amount
,amountSalesUnit
,amountLeadProduct
andproductPackagingUnit
fields inItemTransfer
get fully populated. - Check if amount restriction works as expected.
- Check if availability is validated respectfully according to your lead product’s and packaging unit’s configuration.
- Check if item grouping in the cart works as expected.
- Check if variable amount changes affect unit prices in
ItemTransfer
. - Check if quantity and amount are merged correctly when a group key matches.
- Check if the stock is modified respectfully according to your lead product’s and packaging unit’s configuration.
- Check if the following fields in the
spy_sales_order_item
table are saved:amount
amount_sku
amount_measurement_unit_name
amount_measurement_unit_code
amount_measurement_unit_precision
amount_measurement_unit_conversion
amount_base_measurement_unit_name
Install feature frontend
Prerequisites
To start feature integration, overview and install the necessary features:
Name | Version |
---|---|
Spryker Core E-commerce | 201903.0 |
Measurement Units | 201903.0 |
Non-splittable Products | 201903.0 |
1) Install the required modules using Composer
Run the following command(s) to install the required modules:
composer require spryker-feature/packaging-units: "^2018.11.0" --update-with-dependencies
2) Add Translations
Append glossary according to your configuration:
src/data/import/glossary.csv
packaging-units.recommendation.amount-min-violation,Minimum amount requirements for product are not fulfilled,en_US
packaging-units.recommendation.amount-min-violation,Mindestmengenanforderungen für das Produkt sind nicht erfüllt,de_DE
packaging-units.recommendation.amount-max-violation,Maximum amount requirements for product are not fulfilled,en_US
packaging-units.recommendation.amount-max-violation,Maximale Mengenanforderungen für das Produkt sind nicht erfüllt,de_DE
packaging-units.recommendation.amount-interval-violation,Amount interval requirements for product are not fulfilled,en_US
packaging-units.recommendation.amount-interval-violation,Mengenintervallanforderungen für das Produkt sind nicht erfüllt,de_DE
packaging_units.recommendation.suggestion,Would you like to add:,en_US
packaging_units.recommendation.suggestion,Möchten Sie hinzufügen:,de_DE
packaging_units.recommendation.between-units-info,The amount you have chosen is in between 2 base units,en_US
packaging_units.recommendation.between-units-info,Ihre gewählte Anzahl liegt zwischen 2 basis Einheiten,de_DE
packaging_units.cart.quantity,Quantity,en_US
packaging_units.cart.quantity,Anzahl,de_DE
packaging_units.cart.amount,Amount,en_US
packaging_units.cart.amount,Betrag,de_DE
packaging_units.cart.item,Items,en_US
packaging_units.cart.item,Artikel,de_DE
page.detail.add-to-cart,In den Warenkorb,de_DE
page.detail.add-to-cart,Add to Cart,en_US
product.measurement.sales_unit,Sales Unit,en_US
product.measurement.sales_unit,Maßeinheit,de_DE
cart.item_quantity,Anzahl,de_DE
cart.item_quantity,Quantity,en_US
measurement_units.new-price,New price,en_US
measurement_units.new-price,Neuer Preis,de_DE
measurement_units.recommendation.between-units-info,The quantity you have chosen is in between 2 base units,en_US
measurement_units.recommendation.between-units-info,Ihre gewählte Anzahl liegt zwischen 2 basis Einheiten,de_DE
measurement_units.recommendation.min-violation,Minimum quantity requirements for product are not fulfilled,en_US
measurement_units.recommendation.min-violation,Minimale Mengenanforderungen für das Produkt sind nicht erfüllt,de_DE
measurement_units.recommendation.max-violation,Maximum quantity requirements for product are not fulfilled,en_US
measurement_units.recommendation.max-violation,Maximale Mengenanforderungen für das Produkt sind nicht erfüllt,de_DE
measurement_units.recommendation.suggestion,Would you like to add,en_US
measurement_units.recommendation.suggestion,Was würden Sie gerne hinzufügen? ,de_DE
Run the following console command to import data:
console data:import glossary
3) Set up Widgets
Enable the following global widget(s):
Widget | Description | Namespace |
---|---|---|
ProductPackagingUnitWidget |
Displays product packaging options for quantity and amount. | SprykerShop\Yves\ProductPackagingUnitWidget\Widget |
src/Pyz/Yves/ShopApplication/ShopApplicationDependencyProvider.php
<?php
namespace Pyz\Yves\ShopApplication;
use SprykerShop\Yves\ProductPackagingUnitWidget\Widget\ProductPackagingUnitWidget;
use SprykerShop\Yves\ShopApplication\ShopApplicationDependencyProvider as SprykerShopApplicationDependencyProvider;
class ShopApplicationDependencyProvider extends SprykerShopApplicationDependencyProvider
{
/**
* @return string[]
*/
protected function getGlobalWidgets(): array
{
return [
ProductPackagingUnitWidget::class,
];
}
}
Run the following command to enable Javascript and CSS changes:
console frontend:yves:build
- Check if the amount field appears on the Product Detail page for items with packaging units.
- Check if the amount field appears correctly with measurement unit information on the Cart page.
- Check if the amount field appears correctly with measurement unit information on the Checkout Summary page.
- Check if the amount field appears correctly with measurement unit information on the previous Orders page.
Thank you!
For submitting the form