services:
    oro_promotion.security.acl.voter.promotion_matched_product_segment:
        class: Oro\Bundle\PromotionBundle\Acl\Voter\PromotionMatchedProductSegmentVoter
        public: false
        arguments:
            - '@oro_entity.doctrine_helper'
        calls:
            - [setClassName, ['Oro\Bundle\SegmentBundle\Entity\Segment']]
        tags:
            - { name: security.voter, priority: 500 }

    oro_promotion.rule_filtration.service:
        class: Oro\Bundle\RuleBundle\RuleFiltration\BasicRuleFiltrationService
        parent: oro_rule.rule_filtration.service

    oro_promotion.rule_filtration.duplicate_decorator:
        class: Oro\Bundle\PromotionBundle\RuleFiltration\DuplicateFiltrationService
        public: false
        decorates: oro_promotion.rule_filtration.service
        decoration_priority: 20
        arguments:
            - '@.inner'

    oro_promotion.rule_filtration.expression_language_decorator:
        class: Oro\Bundle\RuleBundle\RuleFiltration\ExpressionLanguageRuleFiltrationServiceDecorator
        public: false
        decorates: oro_promotion.rule_filtration.service
        decoration_priority: 100
        arguments:
            - '@oro_rule.expression_language'
            - '@.inner'
            - '@logger'

    oro_promotion.rule_filtration.coupon_decorator:
        class: Oro\Bundle\PromotionBundle\RuleFiltration\CouponFiltrationService
        decorates: oro_promotion.rule_filtration.service
        decoration_priority: 250
        public: false
        arguments:
            - '@.inner'
            - '@doctrine'

    oro_promotion.rule_filtration.matching_items:
        class: Oro\Bundle\PromotionBundle\RuleFiltration\MatchingItemsFiltrationService
        public: false
        decorates: oro_promotion.rule_filtration.service
        decoration_priority: 300
        arguments:
            - '@.inner'
            - '@oro_promotion.provider.matching_products_provider'

    oro_promotion.rule_filtration.shipping_decorator:
        class: Oro\Bundle\PromotionBundle\RuleFiltration\ShippingFiltrationService
        decorates: oro_promotion.rule_filtration.service
        decoration_priority: 350
        public: false
        arguments:
            - '@.inner'

    oro_promotion.rule_filtration.stop_processing_decorator:
        class: Oro\Bundle\RuleBundle\RuleFiltration\StopProcessingRuleFiltrationServiceDecorator
        public: false
        decorates: oro_promotion.rule_filtration.service
        decoration_priority: 400
        arguments:
            - '@.inner'

    oro_promotion.rule_filtration.sub_entities_promotions_decorator:
        class: Oro\Bundle\PromotionBundle\RuleFiltration\SubOrdersPromotionsFiltrationService
        decorates: oro_promotion.rule_filtration.service
        decoration_priority: 5
        public: false
        arguments:
            - '@.inner'
            - '@oro_promotion.promotion.context_data_converter_registry'

    oro_promotion.rule_filtration.multi_shipping_promotions_decorator:
        class: Oro\Bundle\PromotionBundle\RuleFiltration\MultiShippingFiltrationService
        decorates: oro_promotion.rule_filtration.service
        decoration_priority: 5
        arguments:
            - '@.inner'

    oro_promotion.promotion_provider:
        class: Oro\Bundle\PromotionBundle\Provider\PromotionProvider
        public: false
        arguments:
            - '@doctrine'
            - '@oro_promotion.rule_filtration.service'
            - '@oro_promotion.promotion.context_data_converter_registry'
            - '@oro_promotion.mapper.applied_promotion'
            - '@oro_security.token_accessor'
            - '@oro_promotion.promotion_provider.memory_cache'
            - '@oro_promotion.entity_promotion_aware_helper'
        calls:
            - ['setAvailablePromotionProvider', ['@oro_promotion.available_promotion_provider']]

    oro_promotion.shipping_promotion_provider:
        class: Oro\Bundle\PromotionBundle\Provider\PromotionProvider
        arguments:
            - '@doctrine'
            - '@oro_promotion.rule_filtration.service'
            - '@oro_promotion.shipping_promotion.context_data_converter_registry'
            - '@oro_promotion.mapper.applied_promotion'
            - '@oro_security.token_accessor'
            - '@oro_promotion.promotion_provider.memory_cache'
            - '@oro_promotion.entity_promotion_aware_helper'
        calls:
            - ['setAvailablePromotionProvider', ['@oro_promotion.available_promotion_provider']]

    oro_promotion.available_promotion_provider:
        class: Oro\Bundle\PromotionBundle\Provider\AvailablePromotionProvider
        arguments:
            - '@doctrine'
            - '@oro_security.token_accessor'

    oro_promotion.promotion_provider.memory_cache:
        parent: oro.cache.provider.memory_cache

    oro_promotion.discount_factory:
        class: Oro\Bundle\PromotionBundle\Discount\DiscountFactory
        public: false
        arguments:
            - '@service_container'
        calls:
            - ['addType', ['order', 'oro_promotion.discount.order_discount']]
            - ['addType', ['line_item', 'oro_promotion.discount.line_item_discount']]
            - ['addType', ['buy_x_get_y', 'oro_promotion.discount.buy_x_get_y_discount']]
            - ['addType', ['shipping', 'oro_promotion.discount.shipping_discount']]

    oro_promotion.discount.context_converter.registry:
        class: Oro\Bundle\PromotionBundle\Discount\Converter\DiscountContextConverterRegistry
        arguments:
            - !tagged_iterator oro_promotion.discount_context_converter

    oro_promotion.shipping_discount.context_converter.registry:
        class: Oro\Bundle\PromotionBundle\Discount\Converter\DiscountContextConverterRegistry
        arguments:
            - !tagged_iterator oro_promotion.shipping_discount_context_converter

    oro_promotion.discount.shopping_list_context_converter:
        class: Oro\Bundle\PromotionBundle\Discount\Converter\ShoppingListDiscountContextConverter
        arguments:
           - '@oro_promotion.discount.line_items_to_discount_line_items_converter'
           - '@oro_pricing.user_currency_manager'
           - '@oro_shopping_list.manager.shopping_list_total'
        tags:
            - { name: 'oro_promotion.discount_context_converter' }

    oro_promotion.discount.order_context_converter:
        class: Oro\Bundle\PromotionBundle\Discount\Converter\OrderDiscountContextConverter
        arguments:
            - '@oro_promotion.discount.order_line_items_to_discount_line_items_converter'
            - '@oro_pricing.subtotal_processor.provider.subtotal_line_item'
        tags:
            - { name: 'oro_promotion.discount_context_converter' }

    oro_promotion.discount.checkout_context_converter:
        class: Oro\Bundle\PromotionBundle\Discount\Converter\CheckoutDiscountContextConverter
        arguments:
            - '@oro_checkout.data_provider.converter.checkout_to_order'
            - '@oro_promotion.discount.order_context_converter'
        tags:
            - { name: 'oro_promotion.discount_context_converter' }

    oro_promotion.shipping_discount.checkout_context_converter:
        class: Oro\Bundle\PromotionBundle\Discount\Converter\CheckoutShippingDiscountContextConverter
        tags:
            - { name: 'oro_promotion.shipping_discount_context_converter' }

    oro_promotion.discount.line_items_to_discount_line_items_converter:
        class: Oro\Bundle\PromotionBundle\Discount\Converter\LineItemsToDiscountLineItemsConverter
        arguments:
            - '@oro_pricing.provider.frontend_product_prices'
        calls:
            - ['setProductLineItemsPriceProvider', ['@oro_pricing.provider.product_line_item_price']]

    oro_promotion.discount.order_line_items_to_discount_line_items_converter:
        class: Oro\Bundle\PromotionBundle\Discount\Converter\OrderLineItemsToDiscountLineItemsConverter

    oro_promotion.promotion.context_data_converter_registry:
        class: Oro\Bundle\PromotionBundle\Context\ContextDataConverterRegistry
        arguments:
            - !tagged_iterator oro_promotion.promotion_context_converter

    oro_promotion.shipping_promotion.context_data_converter_registry:
        class: Oro\Bundle\PromotionBundle\Context\ContextDataConverterRegistry
        arguments:
            - !tagged_iterator oro_promotion.shipping_promotion_context_converter

    oro_promotion.promotion.shopping_list_context_data_converter:
        class: Oro\Bundle\PromotionBundle\Context\ShoppingListContextDataConverter
        arguments:
            - '@oro_promotion.context.criteria_data_provider'
            - '@oro_promotion.discount.line_items_to_discount_line_items_converter'
            - '@oro_pricing.user_currency_manager'
            - '@oro_scope.scope_manager'
            - '@oro_shopping_list.manager.shopping_list_total'
        tags:
            - { name: 'oro_promotion.promotion_context_converter' }

    oro_promotion.promotion.order_context_data_converter:
        class: Oro\Bundle\PromotionBundle\Context\OrderContextDataConverter
        public: false
        arguments:
            - '@oro_promotion.context.criteria_data_provider'
            - '@oro_promotion.discount.order_line_items_to_discount_line_items_converter'
            - '@oro_scope.scope_manager'
            - '@oro_pricing.subtotal_processor.provider.subtotal_line_item'
            - '@oro_promotion.validation_service.coupon_validation'
            - '@oro_promotion.provider.entity_coupons_provider'
            - '@oro_checkout.payment_methods_provider'
        tags:
            - { name: 'oro_promotion.promotion_context_converter' }

    oro_promotion.context.criteria_data_provider:
        class: Oro\Bundle\PromotionBundle\Context\CriteriaDataProvider
        public: false
        arguments:
            - '@oro_customer.provider.customer_user_relations_provider'
            - '@oro_website.manager'

    oro_promotion.promotion.checkout_context_data_converter:
        class: Oro\Bundle\PromotionBundle\Context\CheckoutContextDataConverter
        public: false
        arguments:
            - '@oro_checkout.data_provider.converter.checkout_to_order'
            - '@oro_promotion.promotion.order_context_data_converter'
        tags:
            - { name: 'oro_promotion.promotion_context_converter' }

    oro_promotion.promotion.checkout_shipping_context_data_converter:
        class: Oro\Bundle\PromotionBundle\Context\CheckoutShippingContextDataConverter
        arguments:
            - '@oro_promotion.promotion.checkout_context_data_converter'
        tags:
            - { name: 'oro_promotion.shipping_promotion_context_converter' }

    oro_promotion.discount.strategy_registry:
        class: Oro\Bundle\PromotionBundle\Discount\Strategy\StrategyRegistry
        arguments:
            - [] # strategy aliases
            - ~ # service locator for strategies

    oro_promotion.discount.strategy_provider:
        class: Oro\Bundle\PromotionBundle\Discount\Strategy\StrategyProvider
        arguments:
            - '@oro_promotion.discount.strategy_registry'
            - '@oro_config.manager'

    oro_promotion.discount.strategy.apply_all_strategy:
        class: Oro\Bundle\PromotionBundle\Discount\Strategy\ApplyAllStrategy
        public: false
        tags:
            - { name: oro_promotion.discount_strategy, alias: apply_all }

    oro_promotion.discount.strategy.profitable_strategy:
        class: Oro\Bundle\PromotionBundle\Discount\Strategy\ProfitableStrategy
        public: false
        tags:
            - { name: oro_promotion.discount_strategy, alias: profitable }

    oro_promotion.form.type.promotion_select:
        class: Oro\Bundle\PromotionBundle\Form\Type\PromotionSelectType
        tags:
            - { name: form.type, alias: oro_promotion_select }

    oro_promotion.form.type.order_discount:
        class: Oro\Bundle\PromotionBundle\Form\Type\OrderDiscountOptionsType
        tags:
            - { name: form.type, alias: oro_promotion_order_discount_options }

    oro_promotion.form.type.line_item_discount:
        class: Oro\Bundle\PromotionBundle\Form\Type\LineItemDiscountOptionsType
        tags:
            - { name: form.type, alias: oro_promotion_line_item_discount_options }

    oro_promotion.form.type.buy_x_get_y_discount:
        class: Oro\Bundle\PromotionBundle\Form\Type\BuyXGetYDiscountOptionsType
        tags:
            - { name: form.type, alias: oro_promotion_buy_x_get_y_discount_options }

    oro_promotion.form.type.discount_strategy_select:
        class: Oro\Bundle\PromotionBundle\Form\Type\DiscountStrategySelectType
        arguments:
            - '@oro_promotion.discount.strategy_registry'
        tags:
            - { name: form.type, alias: oro_discount_strategy_select }

    oro_promotion.form.type.shipping_discount:
        class: Oro\Bundle\PromotionBundle\Form\Type\ShippingDiscountOptionsType
        tags:
            - { name: form.type, alias: oro_promotion_shipping_discount_options }

    oro_promotion.form.autocomplete.promotion.search_handler:
        parent: oro_form.autocomplete.search_handler
        arguments:
            - 'Oro\Bundle\PromotionBundle\Entity\Promotion'
            - ['rule.name']
        tags:
            - { name: oro_form.autocomplete.search_handler, alias: Oro\Bundle\PromotionBundle\Form\Type\PromotionType, acl_resource: oro_promotion_view }

    oro_promotion.form.autocomplete.promotion_use_coupons.search_handler:
        class: Oro\Bundle\PromotionBundle\Form\Autocomplete\PromotionsUseCouponsSearchHandler
        parent: oro_form.autocomplete.search_handler
        arguments:
            - 'Oro\Bundle\PromotionBundle\Entity\Promotion'
            - ['rule.name']
        tags:
            - { name: oro_form.autocomplete.search_handler, alias: oro_promotion_use_coupons, acl_resource: oro_promotion_view }

    oro_promotion.discount.shipping_discount:
        class: Oro\Bundle\PromotionBundle\Discount\ShippingDiscount
        shared: false

    oro_promotion.discount.order_discount:
        class: Oro\Bundle\PromotionBundle\Discount\OrderDiscount
        shared: false

    oro_promotion.discount.line_item_discount:
        class: Oro\Bundle\PromotionBundle\Discount\LineItemsDiscount
        shared: false

    oro_promotion.discount.buy_x_get_y_discount:
        class: Oro\Bundle\PromotionBundle\Discount\BuyXGetYDiscount
        shared: false

    oro_promotion.discount_type_to_form_type_provider:
        class: Oro\Bundle\PromotionBundle\Provider\DiscountFormTypeProvider
        calls:
            - ['setDefaultFormType', [Oro\Bundle\PromotionBundle\Form\Type\OrderDiscountOptionsType]]
            - ['addFormType', ['order', Oro\Bundle\PromotionBundle\Form\Type\OrderDiscountOptionsType]]
            - ['addFormType', ['line_item', Oro\Bundle\PromotionBundle\Form\Type\LineItemDiscountOptionsType]]
            - ['addFormType', ['buy_x_get_y', Oro\Bundle\PromotionBundle\Form\Type\BuyXGetYDiscountOptionsType]]
            - ['addFormType', ['shipping', Oro\Bundle\PromotionBundle\Form\Type\ShippingDiscountOptionsType]]

    oro_promotion.layout.discount_information_data_provider:
        class: Oro\Bundle\PromotionBundle\Layout\DataProvider\DiscountsInformationDataProvider
        arguments:
            - '@oro_promotion.promotion_executor'
            - '@oro_pricing.user_currency_manager'
        tags:
            - { name: layout.data_provider, alias: oro_promotion_discounts_information }

    oro_promotion.layout.oro_promotion_applied_coupons:
        class: Oro\Bundle\PromotionBundle\Layout\DataProvider\AppliedCouponsDataProvider
        arguments:
            - '@doctrine'
        calls:
            - ['setPromotionProvider', ['@oro_promotion.promotion_provider']]
        tags:
            - { name: layout.data_provider, alias: oro_promotion_applied_coupons }

    oro_promotion.layout.extension.applied_coupons_aware_context_configurator:
        class: Oro\Bundle\PromotionBundle\Layout\Extension\AppliedCouponsAwareContextConfigurator
        arguments:
            - '@oro_promotion.entity_promotion_aware_helper'
        tags:
            - { name: layout.context_configurator }

    oro_promotion.promotion_executor:
        class: Oro\Bundle\PromotionBundle\Executor\PromotionExecutor
        arguments:
            - '@oro_promotion.discount.context_converter.registry'
            - '@oro_promotion.discount.strategy_provider'
            - '@oro_promotion.provider.promotion_discounts_provider'
        calls:
            - [setCache, ['@oro_promotion.promotion_executor.cache']]
            - [setObjectCacheKeyGenerator, ['@oro.cache.generator.object_cache_key']]

    oro_promotion.shipping_promotion_executor:
        class: Oro\Bundle\PromotionBundle\Executor\PromotionExecutor
        arguments:
            - '@oro_promotion.shipping_discount.context_converter.registry'
            - '@oro_promotion.discount.strategy_provider'
            - '@oro_promotion.provider.shipping_promotion_discounts_provider'

    oro_promotion.promotion_executor.cache:
        parent: oro.cache.adapter.array
        tags:
            - { name: 'cache.pool', namespace: 'oro_promotion_executor' }

    oro_promotion.matching_products.cache:
        parent: oro.cache.adapter.array
        tags:
            - { name: 'cache.pool', namespace: 'oro_promotion_matching_products' }

    oro_promotion.provider.matching_products_provider:
        class: Oro\Bundle\PromotionBundle\Provider\MatchingProductsProvider
        public: false
        arguments:
            - '@oro_segment.segment_manager'
            - '@oro_promotion.matching_products.cache'

    oro_promotion.provider.applied_discounts_provider:
        class: Oro\Bundle\PromotionBundle\Provider\AppliedDiscountsProvider
        public: false

    oro_promotion.promotion_entity_name_provider:
        class: Oro\Bundle\PromotionBundle\Provider\PromotionEntityNameProvider
        tags:
            - { name: oro_entity.name_provider, priority: 100 }

    Oro\Bundle\PromotionBundle\Mapper\AppliedPromotionMapper:
        alias: oro_promotion.mapper.applied_promotion

    oro_promotion.mapper.applied_promotion:
        class: Oro\Bundle\PromotionBundle\Mapper\AppliedPromotionMapper
        public: true
        arguments:
            - '@doctrine'
            - '@oro_promotion.applied_promotion_normalizer'

    oro_promotion.provider.entity_coupons_provider:
        class: Oro\Bundle\PromotionBundle\Provider\EntityCouponsProvider
        public: true
        arguments:
            - '@oro_entity.doctrine_helper'
            - '@oro_promotion.entity_promotion_aware_helper'

    oro_promotion.provider.subtotal_provider:
        class: Oro\Bundle\PromotionBundle\Provider\SubtotalProvider
        public: false
        arguments:
            - '@oro_pricing.subtotal_processor.provider.arguments'
            - '@oro_promotion.promotion_executor'
            - '@oro_promotion.provider.applied_discounts_provider'
            - '@oro_currency.rounding.price_rounding_service'
            - '@translator'
        tags:
            - { name: oro_pricing.subtotal_provider, alias: oro_promotion.subtotal_discount }

    oro_promotion.event_listener.payment_discount_surcharge:
        class: Oro\Bundle\PaymentBundle\EventListener\PaymentDiscountSurchargeListener
        arguments:
            - '@oro_promotion.provider.subtotal_provider'
        tags:
            - { name: kernel.event_listener, event: oro_payment.event.collect_surcharge, method: onCollectSurcharge }

    oro_promotion.form.type.promotion:
        class: Oro\Bundle\PromotionBundle\Form\Type\PromotionType
        tags:
            - { name: form.type, alias: oro_promotion }

    oro_promotion.customer_scope_criteria_provider:
        parent: oro_customer.customer_scope_criteria_provider
        tags:
            - { name: oro_scope.provider, scopeType: promotion, priority: 20 }

    oro_promotion.customer_group_scope_criteria_provider:
        parent: oro_customer.customer_group_scope_criteria_provider
        tags:
            - { name: oro_scope.provider, scopeType: promotion, priority: 30 }

    oro_promotion.form.type.discount_options:
        class: Oro\Bundle\PromotionBundle\Form\Type\DiscountOptionsType
        arguments:
            - '@oro_promotion.discount_type_to_form_type_provider'
        tags:
            - { name: form.type, alias: oro_promotion_discount_options }

    oro_promotion.form.type.discounts:
        class: Oro\Bundle\PromotionBundle\Form\Type\DiscountConfigurationType
        arguments:
            - '@oro_promotion.discount_type_to_form_type_provider'
        tags:
            - { name: form.type, alias: oro_promotion_discount_configuration }

    oro_promotion.repository.promotion:
        alias: Oro\Bundle\PromotionBundle\Entity\Repository\PromotionRepository
        public: true

    Oro\Bundle\PromotionBundle\Entity\Repository\PromotionRepository:
        parent: oro_entity.abstract_repository
        public: true
        arguments:
            - 'Oro\Bundle\PromotionBundle\Entity\Promotion'
        tags:
            - { name: doctrine.repository_service }

    oro_promotion.placeholder.discount_information_placeholder_filter:
        class: Oro\Bundle\PromotionBundle\Placeholder\DiscountInformationPlaceholderFilter
        public: true

    oro_promotion.event_listener.order:
        class: Oro\Bundle\PromotionBundle\EventListener\OrderEntityListener
        public: false
        arguments:
             - '@oro_promotion.applied_promotion_manager'
        tags:
            - { name: doctrine.orm.entity_listener, entity: 'Oro\Bundle\OrderBundle\Entity\Order', event: prePersist }

    oro_promotion.event_listener.order_form_listener:
        class: Oro\Bundle\PromotionBundle\EventListener\OrderFormListener
        arguments:
             - '@oro_promotion.applied_promotion_manager'
        tags:
            - { name: kernel.event_listener, event: oro.form.update_handler.before_entity_flush.oro_order_type, method: onBeforeFlush }

    oro_promotion.promotion_executor.link:
        tags:
            - { name: oro_service_link,  service: oro_promotion.promotion_executor }

    oro_promotion.applied_promotion_manager:
        class: Oro\Bundle\PromotionBundle\Manager\AppliedPromotionManager
        public: true
        arguments:
            - '@oro_promotion.promotion_executor.link'
            - '@oro_entity.doctrine_helper'
            - '@oro_promotion.mapper.applied_promotion'

    oro_promotion.coupon_usage_manager:
        class: Oro\Bundle\PromotionBundle\Manager\CouponUsageManager
        arguments:
            - '@doctrine'

    oro_promotion.event_listener.order_view_listener:
        class: Oro\Bundle\PromotionBundle\EventListener\OrderViewListener
        arguments:
            - '@translator'
        tags:
            - { name: kernel.event_listener, event: oro_ui.scroll_data.before.order-view, method: onView }
            - { name: kernel.event_listener, event: oro_ui.scroll_data.before.order-edit, method: onEdit }

    oro_promotion.event_listener.shipping_methods_listener:
        class: Oro\Bundle\PromotionBundle\EventListener\ShippingMethodsListener
        arguments:
            - '@oro_promotion.shipping_promotion_executor'
        tags:
            - { name: kernel.event_listener, event: oro_shipping.applicable_methods, method: modifyPrices }

    oro_promotion.event_listener.grid.order_line_item:
        class: 'Oro\Bundle\PromotionBundle\EventListener\OrderLineItemGridListener'
        arguments:
            - '@oro_tax.provider.taxation_settings_provider'
        tags:
            - { name: kernel.event_listener, event: oro_datagrid.datagrid.build.before.order-line-items-grid, method: onBuildBefore }
            - { name: kernel.event_listener, event: oro_datagrid.datagrid.build.before.order-line-items-grid-frontend, method: onBuildBefore }

    oro_promotion.form.extension.order_line_item:
        class: 'Oro\Bundle\PromotionBundle\Form\Extension\OrderLineItemTypeExtension'
        arguments:
            - '@oro_tax.provider.taxation_settings_provider'
            - '@oro_tax.provider.tax_provider_registry'
            - '@oro_promotion.provider.applied_discounts_provider'
            - '@oro_order.form.section.provider'
            - '@oro_pricing.subtotal_processor.provider.subtotal_line_item'
        tags:
            - { name: form.type_extension, extended_type: 'Oro\Bundle\OrderBundle\Form\Type\OrderLineItemType' }

    oro_promotion.form.extension.order:
        class: Oro\Bundle\PromotionBundle\Form\Extension\OrderTypeExtension
        tags:
            - { name: form.type_extension, extended_type: 'Oro\Bundle\OrderBundle\Form\Type\OrderType' }

    oro_promotion.event_listener.order_line_item_applied_discounts_listener:
        class: Oro\Bundle\PromotionBundle\EventListener\OrderLineItemAppliedDiscountsListener
        arguments:
            - '@oro_tax.provider.tax_provider_registry'
            - '@oro_tax.provider.taxation_settings_provider'
            - '@oro_pricing.subtotal_processor.provider.subtotal_line_item'
            - '@oro_promotion.provider.applied_discounts_provider'
        tags:
            - { name: kernel.event_listener, event: oro_order.order, method: onOrderEvent, priority: -128 }

    oro_promotion.mass_action.coupon_mass_action_handler:
        class: Oro\Bundle\PromotionBundle\Datagrid\Extension\MassAction\AbstractCouponMassActionHandler
        abstract: true
        arguments:
            - '@oro_entity.doctrine_helper'
            - '@oro_security.acl_helper'

    oro_promotion.mass_action.coupon_edit_mass_action_handler:
        parent: oro_promotion.mass_action.coupon_mass_action_handler
        public: true
        class: Oro\Bundle\PromotionBundle\Datagrid\Extension\MassAction\CouponEditMassActionHandler
        calls:
            - ['setTranslator', ['@translator']]
            - ['setFormFactory', ['@form.factory']]

    oro_promotion.mass_action.assigned_coupon_unassign_mass_action_handler:
        parent: oro_promotion.mass_action.coupon_mass_action_handler
        public: true
        class: Oro\Bundle\PromotionBundle\Datagrid\Extension\MassAction\CouponUnassignActionHandler
        calls:
            - ['setTranslator', ['@translator']]

    oro_promotion.form.type.shipping_method_types_choice:
        class: 'Oro\Bundle\PromotionBundle\Form\Type\ShippingMethodTypesChoiceType'
        arguments:
            - '@oro_shipping.shipping_method_provider'
            - '@oro_shipping.provider.shipping_method_icon'
            - '@assets.packages'
        tags:
            - { name: form.type, alias: oro_promotion_shipping_methods }
        calls:
            - [ 'setProvider', [ '@oro_shipping.provider.shipping_methods_choices' ] ]

    oro_promotion.coupon_generation.handler:
        class: 'Oro\Bundle\PromotionBundle\CouponGeneration\CouponGenerationHandler'
        public: true
        arguments:
            - '@oro_promotion.coupon_generation.coupon'

    Oro\Bundle\PromotionBundle\CouponGeneration\Code\CodeGenerator:
        alias: oro_promotion.coupon_generation.code_generator

    oro_promotion.coupon_generation.code_generator:
        class: Oro\Bundle\PromotionBundle\CouponGeneration\Code\CodeGenerator
        public: true

    oro_promotion.coupon_generation.coupon:
        class: Oro\Bundle\PromotionBundle\CouponGeneration\Coupon\CouponGenerator
        arguments:
            - '@oro_promotion.coupon_generation.code_generator'
            - '@oro_entity.doctrine_helper'
            - '@logger'
        tags:
            - { name: monolog.logger, channel: oro_promotion }

    oro_promotion.validator.coupon_code_length:
        class: 'Oro\Bundle\PromotionBundle\Validator\Constraints\CouponCodeLengthValidator'
        tags:
            - { name: validator.constraint_validator, alias: oro_promotion_coupon_code_length }

    oro_promotion.model.coupon_applicability_query_builder_modifier:
        public: false
        class: Oro\Bundle\PromotionBundle\Model\CouponApplicabilityQueryBuilderModifier

    oro_promotion.autocomplete.coupon_search_handler:
        parent: oro_form.autocomplete.search_handler
        class: Oro\Bundle\PromotionBundle\Autocomplete\CouponSearchHandler
        arguments:
            - 'Oro\Bundle\PromotionBundle\Entity\Coupon'
            - ['code', 'promotion.rule.name']
        calls:
            - [setCouponApplicabilityQueryBuilderModifier, ['@oro_promotion.model.coupon_applicability_query_builder_modifier']]
        tags:
            - { name: oro_form.autocomplete.search_handler, alias: oro_coupon, acl_resource: oro_promotion_coupon_view }

    oro_promotion.event_listener.select_coupon_grid_listener:
        class: Oro\Bundle\PromotionBundle\EventListener\SelectCouponGridListener
        arguments:
            - '@oro_promotion.model.coupon_applicability_query_builder_modifier'
        tags:
            - { name: kernel.event_listener, event: oro_datagrid.datagrid.build.after.promotion-coupons-select-grid, method: onBuildAfter }

    oro_promotion.validation_service.coupon_validation:
        class: Oro\Bundle\PromotionBundle\ValidationService\CouponValidationService
        arguments:
            - '@oro_promotion.coupon_usage_manager'

    oro_promotion.form.type.coupon_autocomplete_type:
        class: Oro\Bundle\PromotionBundle\Form\Type\CouponAutocompleteType
        tags:
            - { name: form.type, alias: oro_promotion_coupon_autocomplete }

    oro_promotion.form.type.coupon_add_type:
        class: Oro\Bundle\PromotionBundle\Form\Type\CouponAddType
        arguments:
            - '@oro_entity.doctrine_helper'
        tags:
            - { name: form.type, alias: oro_promotion_coupon_add }

    oro_promotion.validation_service.coupon_applicability_validation:
        class: Oro\Bundle\PromotionBundle\ValidationService\CouponApplicabilityValidationService
        arguments:
            - '@oro_promotion.validation_service.coupon_validation'
            - '@oro_promotion.promotion_provider'
            - '@oro_promotion.provider.entity_coupons_provider'
            - '@oro_promotion.entity_promotion_aware_helper'
        calls:
            - [setCouponValidators, [!tagged_iterator oro_promotion.coupon_validator]]

    oro_promotion.coupon_validator.organization_validator:
        class: Oro\Bundle\PromotionBundle\ValidationService\OrganizationCouponValidator
        tags:
            - {name: oro_promotion.coupon_validator}

    oro_promotion.rule_normalizer:
        public: false
        class: Oro\Bundle\PromotionBundle\Normalizer\RuleNormalizer

    oro_promotion.scope_normalizer:
        public: false
        class: Oro\Bundle\PromotionBundle\Normalizer\ScopeNormalizer
        arguments:
            - '@doctrine'

    oro_promotion.segment_normalizer:
        public: false
        class: Oro\Bundle\PromotionBundle\Normalizer\SegmentNormalizer

    oro_promotion.applied_promotion_normalizer:
        public: false
        class: Oro\Bundle\PromotionBundle\Normalizer\AppliedPromotionNormalizer
        arguments:
            - '@oro_promotion.rule_normalizer'
            - '@oro_promotion.scope_normalizer'
            - '@oro_promotion.segment_normalizer'

    oro_promotion.handler.abstract_coupon_handler:
        class: Oro\Bundle\PromotionBundle\Handler\AbstractCouponHandler
        abstract: true
        arguments:
            - '@oro_entity.routing_helper'
            - '@doctrine'
            - '@event_dispatcher'
            - '@security.authorization_checker'
            - '@oro_promotion.entity_promotion_aware_helper'

    Oro\Bundle\PromotionBundle\Handler\CouponValidationHandler:
        alias: oro_promotion.handler.coupon_validation_handler

    oro_promotion.handler.coupon_validation_handler:
        class: Oro\Bundle\PromotionBundle\Handler\CouponValidationHandler
        public: true
        parent: oro_promotion.handler.abstract_coupon_handler
        calls:
            - [setCouponApplicabilityValidationService, ['@oro_promotion.validation_service.coupon_applicability_validation']]

    Oro\Bundle\PromotionBundle\Handler\FrontendCouponHandler:
        alias: oro_promotion.handler.frontend_coupon_handler

    oro_promotion.handler.frontend_coupon_handler:
        class: Oro\Bundle\PromotionBundle\Handler\FrontendCouponHandler
        public: true
        parent: oro_promotion.handler.abstract_coupon_handler
        calls:
            - [setCouponApplicabilityValidationService, ['@oro_promotion.validation_service.coupon_applicability_validation']]
            - [setEntityCouponsProviderService, ['@oro_promotion.provider.entity_coupons_provider']]
            - [setConfigManager, ['@oro_config.manager']]
            - [disableFilter, ['Oro\Bundle\PromotionBundle\RuleFiltration\ShippingFiltrationService']]

    Oro\Bundle\PromotionBundle\Handler\FrontendCouponRemoveHandler:
        alias: oro_promotion.handler.frontend_coupon_remove_handler

    oro_promotion.handler.frontend_coupon_remove_handler:
        class: Oro\Bundle\PromotionBundle\Handler\FrontendCouponRemoveHandler
        public: true
        arguments:
            - '@security.authorization_checker'
            - '@doctrine'
            - '@oro_promotion.entity_promotion_aware_helper'

    oro_promotion.event_listener.actualize_coupons_state_listener:
        class: Oro\Bundle\PromotionBundle\EventListener\ActualizeCouponsStateListener
        arguments:
            - '@doctrine'
            - '@oro_promotion.provider.entity_coupons_provider'
            - '@oro_promotion.entity_promotion_aware_helper'
        tags:
            - { name: kernel.event_listener, event: oro_pricing.total_calculate_before_event, method: onBeforeTotalCalculate }

    oro_promotion.provider.promotion_discounts_provider:
        class: Oro\Bundle\PromotionBundle\Provider\PromotionDiscountsProvider
        public: false
        arguments:
            - '@oro_promotion.promotion_provider'
            - '@oro_promotion.discount_factory'
            - '@oro_promotion.provider.matching_products_provider'

    oro_promotion.provider.shipping_promotion_discounts_provider:
        class: Oro\Bundle\PromotionBundle\Provider\PromotionDiscountsProvider
        arguments:
            - '@oro_promotion.shipping_promotion_provider'
            - '@oro_promotion.discount_factory'
            - '@oro_promotion.provider.matching_products_provider'

    oro_promotion.provider.disabled_promotion_discounts_provider_decorator:
        class: Oro\Bundle\PromotionBundle\Provider\DisabledPromotionDiscountProviderDecorator
        public: false
        decorates: oro_promotion.provider.promotion_discounts_provider
        arguments:
            - '@.inner'
            - '@oro_promotion.entity_promotion_aware_helper'

    oro_promotion.provider.order_promotion_discounts_provider_decorator:
        class: Oro\Bundle\PromotionBundle\Provider\OrderPromotionDiscountsProviderDecorator
        public: false
        decorates: oro_promotion.provider.promotion_discounts_provider
        arguments:
            - '@.inner'
            - '@oro_promotion.entity_promotion_aware_helper'

    oro_promotion.event_listener.order_applied_promotion_event_listener:
        class: Oro\Bundle\PromotionBundle\EventListener\OrderAppliedPromotionEventListener
        arguments:
            - '@twig'
            - '@form.factory'
            - '@oro_promotion.applied_promotion_manager'
        tags:
            - { name: kernel.event_listener, event: oro_order.order, method: onOrderEvent }

    oro_promotion.event_listener.applied_coupon:
        class: Oro\Bundle\PromotionBundle\EventListener\AppliedCouponEntityListener
        public: false
        arguments:
            - '@oro_promotion.coupon_usage_manager'
            - '@doctrine'
        tags:
            - { name: doctrine.orm.entity_listener, entity: 'Oro\Bundle\PromotionBundle\Entity\AppliedCoupon', event: postPersist }

    oro_promotion.factory.multishipping.checkout_factory_decorator:
        class: Oro\Bundle\PromotionBundle\Factory\MultiShipping\CheckoutFactoryDecorator
        decorates: oro_checkout.factory.multi_shipping.checkout_factory
        arguments:
            - '@.inner'
            - '@oro_promotion.entity_promotion_aware_helper'

    oro_promotion.mapper.order_mapper_decorator:
        class: Oro\Bundle\PromotionBundle\Mapper\OrderMapperDecorator
        public: false
        decorates: oro_checkout.mapper.order_mapper
        arguments:
            - '@.inner'
            - '@oro_promotion.entity_promotion_aware_helper'

    oro_promotion.datagrid.extension.frontend_segment_datagrid:
        class: Oro\Bundle\PromotionBundle\Datagrid\Extension\FrontendSegmentDatagridExtension
        arguments:
            - '@security.token_storage'
            - '@oro_frontend.request.frontend_helper'
            - '@oro_entity.doctrine_helper'
        tags:
            - { name: oro_datagrid.extension }

    oro_promotion.twig.promotion_extension:
        class: Oro\Bundle\PromotionBundle\Twig\PromotionExtension
        arguments:
            - '@oro_platform.twig.service_locator'
        tags:
            - { name: twig.extension }

    oro_promotion.event_listener.datagrid_line_items_data.promotions:
        class: Oro\Bundle\PromotionBundle\EventListener\DatagridLineItemsDataPromotionsListener
        arguments:
            - '@oro_promotion.promotion_executor'
            - '@oro_locale.formatter.number'
            - '@oro_checkout.provider.multi_shipping.split_entities_provider'
        calls:
            - ['setRoundingService', ['@oro_currency.rounding.price_rounding_service']]
        tags:
            # Priority should be less than "oro_pricing.event_listener.datagrid_line_items_data.pricing" and "oro_pricing.event_listener.datagrid_kit_line_items_data.pricing" have.
            - { name: kernel.event_listener, event: oro_product.datagrid_line_items_data.frontend-customer-user-shopping-list-grid, method: onLineItemData, priority: 80 }
            - { name: kernel.event_listener, event: oro_product.datagrid_line_items_data.frontend-customer-user-shopping-list-edit-grid, method: onLineItemData, priority: 80 }
            - { name: kernel.event_listener, event: oro_product.datagrid_line_items_data.frontend-checkout-line-items-grid, method: onLineItemData, priority: 80 }
            - { name: kernel.event_listener, event: oro_product.datagrid_line_items_data.frontend-single-page-checkout-line-items-grid, method: onLineItemData, priority: 80 }

    oro_promotion.order_tax.mapper.order_after_discounts_mapper:
        class: Oro\Bundle\PromotionBundle\OrderTax\Mapper\OrderAfterDiscountsMapper
        decorates: oro_tax.order_tax.mapper.order_mapper
        arguments:
            - '@.inner'
            - '@oro_tax.provider.taxation_settings_provider'
            - '@oro_promotion.promotion_executor'

    oro_promotion.order_tax.mapper.order_line_item_after_discounts_mapper:
        class: Oro\Bundle\PromotionBundle\OrderTax\Mapper\OrderLineItemAfterDiscountsMapper
        decorates: oro_tax.order_tax.mapper.order_line_item_mapper
        arguments:
            - '@.inner'
            - '@oro_tax.provider.taxation_settings_provider'
            - '@oro_promotion.promotion_executor'

    oro_promotion.event_listener.order_tax.order_taxable_listener:
        class: Oro\Bundle\PromotionBundle\EventListener\OrderTax\OrderTaxableListener
        parent: oro_tax.event_listener.order_tax.abstract_taxable_listener
        arguments:
            - '@oro_tax.provider.taxation_settings_provider'
        tags:
            - { name: kernel.event_listener, event: Oro\Bundle\TaxBundle\Event\SkipOrderTaxRecalculationEvent, method: onSkipOrderTaxRecalculation, priority: -250 }

    oro_promotion.entity_promotion_aware_helper:
        class: Oro\Bundle\PromotionBundle\Model\PromotionAwareEntityHelper
        public: true
        arguments:
            - "@oro_entity_config.config_manager"

    Oro\Bundle\PromotionBundle\Model\PromotionAwareEntityHelper:
        alias: oro_promotion.entity_promotion_aware_helper

    oro_promotion.aware_entity_configuration:
        class: Oro\Bundle\PromotionBundle\EntityConfig\PromotionAwareEntityConfiguration
        tags:
            - oro_entity_config.validation.entity_config

    oro_promotion.event_listener.order_subtotal_with_discounts_listener:
        class: Oro\Bundle\PromotionBundle\EventListener\OrderSubtotalWithDiscountsListener
        arguments:
            - '@oro_promotion.provider.subtotal_provider'
        tags:
            - { name: doctrine.orm.entity_listener, entity: 'Oro\Bundle\OrderBundle\Entity\Order', event: prePersist }
            - { name: doctrine.orm.entity_listener, entity: 'Oro\Bundle\OrderBundle\Entity\Order', event: preUpdate }

    oro_promotion.event_listener.promotion_products_collection_grid_listener:
        class: Oro\Bundle\PromotionBundle\EventListener\PromotionProductsCollectionGridListener
        tags:
            - { name: kernel.event_listener, event: oro_datagrid.datagrid.build.after.promotion-products-collection-grid, method: onBuildAfter }
