Variant Price Surcharge: Technical Details
Technical details of Variant Price Surcharge: storefront and cart flow, plugin structure, services and tags, logging, error code, plus notes on extensibility, permissions and snippets.
Technical Details
Flow
graph TD
A["Product loaded in sales channel"] --> B["ProductSubscriber"]
B --> C["SurchargeConfigReader"]
C --> D["ParentPriceResolver"]
D --> E["VariantPriceCalculator"]
E --> F["QuantityPriceCalculator"]
F --> G["calculatedPrice of the variant"]
H["Cart is calculated"] --> I["VariantPriceProcessor"]
I --> C
I --> D
I --> E
I --> F
F --> J["Price of the line item"]
Plugin structure
| Class | Purpose |
|---|---|
MmdVariantPriceSurcharge |
Plugin class. On uninstall without "keep user data" it deletes the custom field set and system configuration. |
Migration1705200000CreateCustomFields |
Creates the custom field set and the three fields |
Subscriber\ProductSubscriber |
Listens to sales_channel.product.loaded and replaces the calculated price of variants |
Core\Checkout\Cart\VariantPriceProcessor |
Cart processor, service tag shopware.cart.processor, priority 1000 |
Service\SurchargeConfigReader |
Reads and validates the custom fields, decides on inheritance |
Service\SurchargeConfig |
Immutable value object of percentage and surcharge |
Service\ParentPriceResolver |
Loads the parent product with its advanced prices, determines its price, caches per request |
Service\VariantPriceCalculator |
Calculation, value ranges, rounding settings from the system configuration |
Exception\ParentProductNotFoundException |
HTTP 404, error code MMD_VARIANT_PRICE_SURCHARGE__PARENT_NOT_FOUND |
Details
- The
ParentPriceResolvercarries thekernel.resettag and clears its cache between requests. - The rounding settings are read from the system configuration with the sales channel ID.
- The cart processor is registered as a public service so it is not removed during container compilation.
- The cart processor loads variants and parent products each in a single query for all line items and takes the tax rules from the existing price definition.
- Problems are written through the logger: warnings for invalid or non-numeric values and for missing parent products in the cart, errors for missing parent products in the product display.
Extensibility, permissions, snippets
- The plugin defines no events, extension points or configuration interfaces of its own. The services are regular Symfony services.
- It registers no admin role permissions (ACL), no admin modules and no storefront templates.
- It ships no snippet files. The custom field labels (de-DE and en-GB) are stored in the custom field set's configuration, the plugin settings' labels in
config.xml.