From 9b88c82c0b2ad9846633dae68b835340f8e7aa88 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Marek=20Noco=C5=84?= Date: Tue, 10 Jun 2025 22:03:11 +0200 Subject: [PATCH 1/3] [Discounts] Described Discounts API --- .../src/Command/ManageDiscountsCommand.php | 88 ++++++++++++ .../data_migration/importing_data.md | 2 + docs/discounts/discounts.md | 5 +- docs/discounts/discounts_api.md | 126 ++++++++++++++++++ docs/discounts/discounts_guide.md | 4 +- mkdocs.yml | 1 + 6 files changed, 223 insertions(+), 3 deletions(-) create mode 100644 code_samples/discounts/src/Command/ManageDiscountsCommand.php create mode 100644 docs/discounts/discounts_api.md diff --git a/code_samples/discounts/src/Command/ManageDiscountsCommand.php b/code_samples/discounts/src/Command/ManageDiscountsCommand.php new file mode 100644 index 0000000000..5444a95e75 --- /dev/null +++ b/code_samples/discounts/src/Command/ManageDiscountsCommand.php @@ -0,0 +1,88 @@ +userService = $userSerice; + $this->discountService = $discountService; + $this->discountCodeService = $discountCodeService; + $this->permissionResolver = $permissionResolver; + + parent::__construct(); + } + + protected function execute(InputInterface $input, OutputInterface $output): int + { + $this->permissionResolver->setCurrentUserReference($this->userService->loadUserByLogin('admin')); + + $now = new \DateTimeImmutable(); + + $discountCodeCreateStruct = new DiscountCodeCreateStruct( + 'summer10', + null, // Unlimited usage + $this->permissionResolver->getCurrentUserReference()->getUserId(), + $now + ); + $discountCode = $this->discountCodeService->createDiscountCode($discountCodeCreateStruct); + + $discountCreateStruct = new DiscountCreateStruct(); + $discountCreateStruct->setIdentifier('discount_identifier') + ->setType(DiscountType::CART) + ->setPriority(10) + ->setEnabled(true) + ->setUser($this->userService->loadUserByLogin('admin')) + ->setRule(new FixedAmount(10)) + ->setStartDate($now) + ->setConditions([ + new IsInRegions(['germany', 'france']), + new IsProductInArray(['product-1', 'product-2']), + new IsInCurrency('EUR'), + new IsValidDiscountCode($discountCode->getCode(), $discountCode->getUsedLimit()), + ]) + ->setTranslations([ + new DiscountTranslationStruct('eng-GB', 'Discount name', 'This is a discount description', 'Promotion Label', 'Promotion Description'), + new DiscountTranslationStruct('ger-DE', 'Discount name (German)', 'Description (German)', 'Promotion Label (German)', 'Promotion Description (German)'), + ]) + ->setEndDate(null) // Permanent discount + ->setCreatedAt($now) + ->setUpdatedAt($now) + ->setContext(new ArrayMap(['custom_context' => 'custom_value'])); + + $this->discountService->createDiscount($discountCreateStruct); + + return Command::SUCCESS; + } +} diff --git a/docs/content_management/data_migration/importing_data.md b/docs/content_management/data_migration/importing_data.md index 36c9e67dd1..f73dbdb368 100644 --- a/docs/content_management/data_migration/importing_data.md +++ b/docs/content_management/data_migration/importing_data.md @@ -522,6 +522,8 @@ The provided conditions overwrite any already existing ones. [[= include_file('code_samples/data_migration/examples/discounts/discount_update.yaml') =]] ``` +For a list of available conditions, see [Discounts API](discounts_api.md). + ## Criteria When using `update` or `delete` modes, you can use criteria to identify the objects to operate on. diff --git a/docs/discounts/discounts.md b/docs/discounts/discounts.md index 78d4070de2..322335a76c 100644 --- a/docs/discounts/discounts.md +++ b/docs/discounts/discounts.md @@ -16,5 +16,6 @@ You can also extend the feature, for example, by creating custom pricing rules, [[= cards([ "discounts/discounts_guide", -"discounts/install_discounts" -], columns=4) =]] +"discounts/install_discounts", +"discounts/discounts_api" +], columns=3) =]] diff --git a/docs/discounts/discounts_api.md b/docs/discounts/discounts_api.md new file mode 100644 index 0000000000..27ad501a43 --- /dev/null +++ b/docs/discounts/discounts_api.md @@ -0,0 +1,126 @@ +--- +description: Discounts LTS Update enables reducing prices on products or product categories based on a detailed logic resolution. +month_change: true +editions: + - lts-update + - commerce +--- + +# Discounts API + +## Manage discounts and discount codes + +By integrating with the [Discount feature](discounts_guide.md) you can automate the process of managing discounts, streamlining the whole process and automating business rules. + +For example, you can automatically create a discount when a customer places their 3rd order, encouraging them to make another purchase and increase their chances of becoming a local customer. + +You can manage discounts using [data migrations](importing_data.md#discounts), [REST API](/api/rest_api/rest_api_reference/rest_api_reference.html#discounts), or the PHP API by using the [Ibexa\Contracts\Discounts\DiscountServiceInterface](/api/php_api/php_api_reference/classes/Ibexa-Contracts-Discounts-DiscountServiceInterface.html) service. + +The core concepts when working with discounts through the APIs are listed below. + +### Types + +When using the PHP API, the discount type defines where the discount can be applied. + +Discounts are applied in two places, listed in the [DiscountType](/api/php_api/php_api_reference/classes/Ibexa-Contracts-Discounts-Value-DiscountType.html) class: + +- **Product catalog** - `catalog` discounts are activated when browsing the product catalog and do not require any action from the customer to be activated +- **Cart** - `cart` discounts can activate when entering the [cart](cart.md), if the right conditions are met. They may also require entering a discount code to be activated + +Regardless of activation place, discounts always apply to products and reduce their base price. + +To define when a discount activates and how the price is reduced, use rules and conditions. +They make use of the [Symfony Expression language]([[= symfony_doc=]]//components/expression_language.html). +Use the expression values provided below when using data migrations or the REST API to pass the right values. + +### Rules + +Discount rules define how the calculate the price reduction. +The following discount rule types are available: + +| Rule type | Identifier | Description | Expression value | +|---|---|---|---| +| `Ibexa\Discounts\Value\DiscountRule\FixedAmount` | `fixed_amount` | Deducts the specified amount, for example 10 EUR, from the base price | `discount_amount` | +| `Ibexa\Discounts\Value\DiscountRule\Percentage` | `percentage` | Deducts the specified percentage, for example -10%, from the base price | `discount_percentage` | + +Only a single discount can be applied to a given product, and a discount can only have a single rule. + +You can create your own rules by creating a class implementing the [DiscountRuleInterface](/api/php_api/php_api_reference/classes/Ibexa-Contracts-Discounts-Value-DiscountRuleInterface.html) interface. + +### Conditions + +With conditions you can narrow down the scenarios in which the discount applies. The following conditions are available: + +| Condition | Applies to | Identifier | Description | Expression values | +|---|---|---|---|---| +| `Ibexa\Discounts\Value\DiscountCondition\IsInCategory` | Cart, Catalog | `is_in_category` | Checks if the product belongs to specified [product categories]([[= user_doc =]]/pim/work_with_product_categories) | `categories` | +| `Ibexa\Discounts\Value\DiscountCondition\IsInCurrency` | Cart, Catalog |`is_in_currency` | Checks if the product has price in the specified currency | `currency_code` | +| `Ibexa\Discounts\Value\DiscountCondition\IsInRegions` | Cart, Catalog | `is_in_regions` | Checks if the customer is making the purchase in one of the specified regions | `regions` | +| `Ibexa\Discounts\Value\DiscountCondition\IsProductInArray` | Cart, Catalog| `is_product_in_array` | Checks if the product belongs to the group of selected products | `product_codes` | +| `Ibexa\Discounts\Value\DiscountCondition\IsUserInCustomerGroup` | Cart, Catalog| `is_user_in_customer_group` | Check if the customer belongs to specified [customer groups](customer_groups.md) | `customer_groups` | +| `Ibexa\Discounts\Value\DiscountCondition\IsProductInQuantityInCart` | Cart | `is_product_in_quantity_in_cart` | Checks if the required minimum quantity of a given product is present in the cart | `quantity` | +| `Ibexa\Discounts\Value\DiscountCondition\MinimumPurchaseAmount` | Cart | `minimum_purchase_amount` | Checks if purchase amount in the cart exceeds the specified minimum | `minimum_purchase_amount` | +| `Ibexa\DiscountsCodes\Value\DiscountCondition\IsValidDiscountCode` | Cart | `is_valid_discount_code` | Checks if the correct discount code has been provided and how many times it was used by the customer | `discount_code`, `usage_count` | + +When multiple conditions are specified, all of them must be met. + +You can create your own conditions by creating a class implementing the [DiscountConditionInterface](/api/php_api/php_api_reference/classes/Ibexa-Contracts-Discounts-Value-DiscountConditionInterface.html) interface. + +### Priority + +You can set discount priority as a number between 1 and 10 to indicate which discount should have [higher priority](discounts_guide.md#discounts-priority) when choosing the one to apply. + +### Start and end date + +Discounts can be permanent, or valid only in specified time frame. + +Every discount has a start date, which defaults to the date when the discount was created. +The end date can be set to `null` to make the discount permanent. + +### Discount translations + +The discount has four properties that can be translated: + +| Property | Usage | +|---|---| +| Name | Internal information for store managers | +| Description | Internal information for store managers | +| Promotion label | Information displayed to customers | +| Promotion description | Information displayed to customers | + +Use the [DiscountTranslationStruct](/api/php_api/php_api_reference/classes/Ibexa-Contracts-Discounts-Value-Struct-DiscountTranslationStruct.html) to provide translations for discounts. + +### Discount codes + +To activate a cart discount only after a proper discount code is provided, you need to: + +1. Create a discount code using the [DiscountCodeServiceInterface::createDiscountCode()](/api/php_api/php_api_reference/classes/Ibexa-Contracts-DiscountsCodes-DiscountCodeServiceInterface.html#method_createDiscountCode) method +1. Attach it to a discount by using the `IsValidDiscountCode` condition + +Set the [`usedLimit`](/api/php_api/php_api_reference/classes/Ibexa-Contracts-DiscountsCodes-Value-Struct-DiscountCodeCreateStruct.html#method___construct) property to the number of times a single customer can use this code, or to `null` to make the usage unlimited. + +The [`DiscountCodeServiceInterface::registerUsage()`](/api/php_api/php_api_reference/classes/Ibexa-Contracts-DiscountsCodes-DiscountCodeServiceInterface.html#method_registerUsage) method is used to track the number of times a discount code has been used. + +### Example API usage + +The example below contains a Command creating a cart discount. The discount: + +- has the highest possible priority value +- deducts 10 EUR from the base price of the product +- is permanent +- is valid in Germany and France +- applies to 2 products +- requires a `summer10` discount code to be activated. The code can be used unlimited number of times + +``` php hl_lines="53-59 61-84" +[[= include_file('code_samples/discounts/src/Command/ManageDiscountsCommand.php') =]] +``` + +Similarly, use the `deleteDiscount`, `deleteTranslation`, `disableDiscount`, `enableDiscount`, and `updateDiscount` methods from the [DiscountServiceInterface](/api/php_api/php_api_reference/classes/Ibexa-Contracts-Discounts-DiscountServiceInterface.html) to manage the discounts. You can always attach additional logic to the Discounts API by listening to the available events. + +## Search + +You can search for Discounts using the [`DiscountServiceInterface::findDiscounts()](/api/php_api/php_api_reference/classes/Ibexa-Contracts-Discounts-DiscountServiceInterface.html#method_findDiscounts) method. +To learn more about the available search options, see Discounts' Search Criteria and Sort Clauses. + +For discount codes, you can query the database for discount code usage using [`DiscountCodeServiceInterface::findCodeUsages()`](/api/php_api/php_api_reference/classes/Ibexa-Contracts-DiscountsCodes-DiscountCodeServiceInterface.html#method_findCodeUsages) and [`DiscountCodeUsageQuery`](/api/php_api/php_api_reference/classes/Ibexa-Contracts-DiscountsCodes-Value-Query-DiscountCodeUsageQuery.html). diff --git a/docs/discounts/discounts_guide.md b/docs/discounts/discounts_guide.md index 615d02c737..7c0364bb2f 100644 --- a/docs/discounts/discounts_guide.md +++ b/docs/discounts/discounts_guide.md @@ -1,6 +1,6 @@ --- description: Discounts LTS Update enables reducing prices on products or product categories based on a detailed logic resolution. -month_change: false +month_change: true editions: - lts-update - commerce @@ -55,6 +55,8 @@ Discounts are applied in two places: A shopping cart can have multiple active discounts, but a specific product can only have a single discount applied to it at a time. +#### Discounts priority + When two or more discounts can be applied to a single product, the system evaluates the following properties to choose the right one: - discount activation place (cart discounts rank higher over catalog discounts) diff --git a/mkdocs.yml b/mkdocs.yml index 20be1066a9..6cabd93a4c 100644 --- a/mkdocs.yml +++ b/mkdocs.yml @@ -406,6 +406,7 @@ nav: - Discounts: discounts/discounts.md - Discounts guide: discounts/discounts_guide.md - Install Discounts: discounts/install_discounts.md + - Discounts API: discounts/discounts_api.md - Customer management: - Customer Portal: customer_management/customer_portal.md - Customer Portal guide: customer_management/customer_portal_guide.md From 0cd5ae42483ffc35a1b65377ffb563483e4a5378 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Marek=20Noco=C5=84?= Date: Wed, 11 Jun 2025 10:13:07 +0200 Subject: [PATCH 2/3] Review fixes --- .../src/Command/ManageDiscountsCommand.php | 18 ++++++++++++----- docs/discounts/discounts_api.md | 20 ++++++++++--------- 2 files changed, 24 insertions(+), 14 deletions(-) diff --git a/code_samples/discounts/src/Command/ManageDiscountsCommand.php b/code_samples/discounts/src/Command/ManageDiscountsCommand.php index 5444a95e75..6243da8ca6 100644 --- a/code_samples/discounts/src/Command/ManageDiscountsCommand.php +++ b/code_samples/discounts/src/Command/ManageDiscountsCommand.php @@ -4,6 +4,7 @@ namespace App\Command; +use DateTimeImmutable; use Ibexa\Contracts\Core\Collection\ArrayMap; use Ibexa\Contracts\Core\Repository\PermissionResolver; use Ibexa\Contracts\Core\Repository\UserService; @@ -34,8 +35,12 @@ final class ManageDiscountsCommand extends Command private UserService $userService; - public function __construct(UserService $userSerice, PermissionResolver $permissionResolver, DiscountServiceInterface $discountService, DiscountCodeServiceInterface $discountCodeService) - { + public function __construct( + UserService $userSerice, + PermissionResolver $permissionResolver, + DiscountServiceInterface $discountService, + DiscountCodeServiceInterface $discountCodeService + ) { $this->userService = $userSerice; $this->discountService = $discountService; $this->discountCodeService = $discountCodeService; @@ -46,9 +51,11 @@ public function __construct(UserService $userSerice, PermissionResolver $permiss protected function execute(InputInterface $input, OutputInterface $output): int { - $this->permissionResolver->setCurrentUserReference($this->userService->loadUserByLogin('admin')); + $this->permissionResolver->setCurrentUserReference( + $this->userService->loadUserByLogin('admin') + ); - $now = new \DateTimeImmutable(); + $now = new DateTimeImmutable(); $discountCodeCreateStruct = new DiscountCodeCreateStruct( 'summer10', @@ -59,7 +66,8 @@ protected function execute(InputInterface $input, OutputInterface $output): int $discountCode = $this->discountCodeService->createDiscountCode($discountCodeCreateStruct); $discountCreateStruct = new DiscountCreateStruct(); - $discountCreateStruct->setIdentifier('discount_identifier') + $discountCreateStruct + ->setIdentifier('discount_identifier') ->setType(DiscountType::CART) ->setPriority(10) ->setEnabled(true) diff --git a/docs/discounts/discounts_api.md b/docs/discounts/discounts_api.md index 27ad501a43..78ab62aa66 100644 --- a/docs/discounts/discounts_api.md +++ b/docs/discounts/discounts_api.md @@ -45,8 +45,6 @@ The following discount rule types are available: Only a single discount can be applied to a given product, and a discount can only have a single rule. -You can create your own rules by creating a class implementing the [DiscountRuleInterface](/api/php_api/php_api_reference/classes/Ibexa-Contracts-Discounts-Value-DiscountRuleInterface.html) interface. - ### Conditions With conditions you can narrow down the scenarios in which the discount applies. The following conditions are available: @@ -64,19 +62,23 @@ With conditions you can narrow down the scenarios in which the discount applies. When multiple conditions are specified, all of them must be met. -You can create your own conditions by creating a class implementing the [DiscountConditionInterface](/api/php_api/php_api_reference/classes/Ibexa-Contracts-Discounts-Value-DiscountConditionInterface.html) interface. - ### Priority You can set discount priority as a number between 1 and 10 to indicate which discount should have [higher priority](discounts_guide.md#discounts-priority) when choosing the one to apply. ### Start and end date -Discounts can be permanent, or valid only in specified time frame. +Discounts can be permanent, or valid only in a specified time frame. Every discount has a start date, which defaults to the date when the discount was created. The end date can be set to `null` to make the discount permanent. +### Status + +You can disable a discount anytime to stop it from being active, even if the conditions enforced by start and end date are met. + +Only disabled discounts can be deleted. + ### Discount translations The discount has four properties that can be translated: @@ -112,15 +114,15 @@ The example below contains a Command creating a cart discount. The discount: - applies to 2 products - requires a `summer10` discount code to be activated. The code can be used unlimited number of times -``` php hl_lines="53-59 61-84" +``` php hl_lines="60-66 68-92" [[= include_file('code_samples/discounts/src/Command/ManageDiscountsCommand.php') =]] ``` -Similarly, use the `deleteDiscount`, `deleteTranslation`, `disableDiscount`, `enableDiscount`, and `updateDiscount` methods from the [DiscountServiceInterface](/api/php_api/php_api_reference/classes/Ibexa-Contracts-Discounts-DiscountServiceInterface.html) to manage the discounts. You can always attach additional logic to the Discounts API by listening to the available events. +Similarly, use the `deleteDiscount`, `deleteTranslation`, `disableDiscount`, `enableDiscount`, and `updateDiscount` methods from the [DiscountServiceInterface](/api/php_api/php_api_reference/classes/Ibexa-Contracts-Discounts-DiscountServiceInterface.html) to manage the discounts. You can always attach additional logic to the Discounts API by listening to the [available events](discounts_events.md). ## Search -You can search for Discounts using the [`DiscountServiceInterface::findDiscounts()](/api/php_api/php_api_reference/classes/Ibexa-Contracts-Discounts-DiscountServiceInterface.html#method_findDiscounts) method. -To learn more about the available search options, see Discounts' Search Criteria and Sort Clauses. +You can search for Discounts using the [`DiscountServiceInterface::findDiscounts()](/api/php_api/php_api_reference/classes/Ibexa-Contracts-Discounts-DiscountServiceInterface.html#method_findDiscounts) method. +To learn more about the available search options, see Discounts' [Search Criteria](discounts_criteria.md) and [Sort Clauses](discounts_sort_clauses.md). For discount codes, you can query the database for discount code usage using [`DiscountCodeServiceInterface::findCodeUsages()`](/api/php_api/php_api_reference/classes/Ibexa-Contracts-DiscountsCodes-DiscountCodeServiceInterface.html#method_findCodeUsages) and [`DiscountCodeUsageQuery`](/api/php_api/php_api_reference/classes/Ibexa-Contracts-DiscountsCodes-Value-Query-DiscountCodeUsageQuery.html). From 792252b42cae4349a3667a6749d7009542f33ce0 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Marek=20Noco=C5=84?= Date: Sun, 15 Jun 2025 22:49:02 +0200 Subject: [PATCH 3/3] Apply suggestions from code review Co-authored-by: Adrien Dupuis <61695653+adriendupuis@users.noreply.github.com> --- .../data_migration/importing_data.md | 2 +- docs/discounts/discounts_api.md | 29 ++++++++++--------- 2 files changed, 16 insertions(+), 15 deletions(-) diff --git a/docs/content_management/data_migration/importing_data.md b/docs/content_management/data_migration/importing_data.md index f73dbdb368..e1da81407a 100644 --- a/docs/content_management/data_migration/importing_data.md +++ b/docs/content_management/data_migration/importing_data.md @@ -522,7 +522,7 @@ The provided conditions overwrite any already existing ones. [[= include_file('code_samples/data_migration/examples/discounts/discount_update.yaml') =]] ``` -For a list of available conditions, see [Discounts API](discounts_api.md). +For a list of available conditions, see [Discounts API](discounts_api.md#conditions). ## Criteria diff --git a/docs/discounts/discounts_api.md b/docs/discounts/discounts_api.md index 78ab62aa66..c6ef554b98 100644 --- a/docs/discounts/discounts_api.md +++ b/docs/discounts/discounts_api.md @@ -14,7 +14,7 @@ By integrating with the [Discount feature](discounts_guide.md) you can automate For example, you can automatically create a discount when a customer places their 3rd order, encouraging them to make another purchase and increase their chances of becoming a local customer. -You can manage discounts using [data migrations](importing_data.md#discounts), [REST API](/api/rest_api/rest_api_reference/rest_api_reference.html#discounts), or the PHP API by using the [Ibexa\Contracts\Discounts\DiscountServiceInterface](/api/php_api/php_api_reference/classes/Ibexa-Contracts-Discounts-DiscountServiceInterface.html) service. +You can manage discounts using [data migrations](importing_data.md#discounts), [REST API](/api/rest_api/rest_api_reference/rest_api_reference.html#discounts), or the PHP API by using the [`Ibexa\Contracts\Discounts\DiscountServiceInterface`](/api/php_api/php_api_reference/classes/Ibexa-Contracts-Discounts-DiscountServiceInterface.html) service. The core concepts when working with discounts through the APIs are listed below. @@ -22,7 +22,7 @@ The core concepts when working with discounts through the APIs are listed below. When using the PHP API, the discount type defines where the discount can be applied. -Discounts are applied in two places, listed in the [DiscountType](/api/php_api/php_api_reference/classes/Ibexa-Contracts-Discounts-Value-DiscountType.html) class: +Discounts are applied in two places, listed in the [`DiscountType`](/api/php_api/php_api_reference/classes/Ibexa-Contracts-Discounts-Value-DiscountType.html) class: - **Product catalog** - `catalog` discounts are activated when browsing the product catalog and do not require any action from the customer to be activated - **Cart** - `cart` discounts can activate when entering the [cart](cart.md), if the right conditions are met. They may also require entering a discount code to be activated @@ -31,7 +31,7 @@ Regardless of activation place, discounts always apply to products and reduce th To define when a discount activates and how the price is reduced, use rules and conditions. They make use of the [Symfony Expression language]([[= symfony_doc=]]//components/expression_language.html). -Use the expression values provided below when using data migrations or the REST API to pass the right values. +Use the expression values provided below when using data migrations or when parsing REST API responses. ### Rules @@ -40,8 +40,8 @@ The following discount rule types are available: | Rule type | Identifier | Description | Expression value | |---|---|---|---| -| `Ibexa\Discounts\Value\DiscountRule\FixedAmount` | `fixed_amount` | Deducts the specified amount, for example 10 EUR, from the base price | `discount_amount` | -| `Ibexa\Discounts\Value\DiscountRule\Percentage` | `percentage` | Deducts the specified percentage, for example -10%, from the base price | `discount_percentage` | +| `Ibexa\Discounts\Value\DiscountRule\FixedAmount` | `fixed_amount` | Deducts the specified amount, for example 10 EUR, from the base price | `discount_amount` | +| `Ibexa\Discounts\Value\DiscountRule\Percentage` | `percentage` | Deducts the specified percentage, for example -10%, from the base price | `discount_percentage` | Only a single discount can be applied to a given product, and a discount can only have a single rule. @@ -90,13 +90,13 @@ The discount has four properties that can be translated: | Promotion label | Information displayed to customers | | Promotion description | Information displayed to customers | -Use the [DiscountTranslationStruct](/api/php_api/php_api_reference/classes/Ibexa-Contracts-Discounts-Value-Struct-DiscountTranslationStruct.html) to provide translations for discounts. +Use the [`DiscountTranslationStruct`](/api/php_api/php_api_reference/classes/Ibexa-Contracts-Discounts-Value-Struct-DiscountTranslationStruct.html) to provide translations for discounts. ### Discount codes To activate a cart discount only after a proper discount code is provided, you need to: -1. Create a discount code using the [DiscountCodeServiceInterface::createDiscountCode()](/api/php_api/php_api_reference/classes/Ibexa-Contracts-DiscountsCodes-DiscountCodeServiceInterface.html#method_createDiscountCode) method +1. Create a discount code using the [`DiscountCodeServiceInterface::createDiscountCode()`](/api/php_api/php_api_reference/classes/Ibexa-Contracts-DiscountsCodes-DiscountCodeServiceInterface.html#method_createDiscountCode) method 1. Attach it to a discount by using the `IsValidDiscountCode` condition Set the [`usedLimit`](/api/php_api/php_api_reference/classes/Ibexa-Contracts-DiscountsCodes-Value-Struct-DiscountCodeCreateStruct.html#method___construct) property to the number of times a single customer can use this code, or to `null` to make the usage unlimited. @@ -107,12 +107,13 @@ The [`DiscountCodeServiceInterface::registerUsage()`](/api/php_api/php_api_refer The example below contains a Command creating a cart discount. The discount: -- has the highest possible priority value -- deducts 10 EUR from the base price of the product -- is permanent -- is valid in Germany and France -- applies to 2 products -- requires a `summer10` discount code to be activated. The code can be used unlimited number of times +- has the highest possible [priority](#priority) value +- [rule](#rules) deducts 10 EUR from the base price of the product +- is [permanent](#start-and-end-date) +- [depends](#conditions) on + - being bought from Germany or France + - 2 products + - a `summer10` [discount code](#discount-codes) which can be used unlimited number of times ``` php hl_lines="60-66 68-92" [[= include_file('code_samples/discounts/src/Command/ManageDiscountsCommand.php') =]] @@ -122,7 +123,7 @@ Similarly, use the `deleteDiscount`, `deleteTranslation`, `disableDiscount`, `en ## Search -You can search for Discounts using the [`DiscountServiceInterface::findDiscounts()](/api/php_api/php_api_reference/classes/Ibexa-Contracts-Discounts-DiscountServiceInterface.html#method_findDiscounts) method. +You can search for Discounts using the [`DiscountServiceInterface::findDiscounts()`](/api/php_api/php_api_reference/classes/Ibexa-Contracts-Discounts-DiscountServiceInterface.html#method_findDiscounts) method. To learn more about the available search options, see Discounts' [Search Criteria](discounts_criteria.md) and [Sort Clauses](discounts_sort_clauses.md). For discount codes, you can query the database for discount code usage using [`DiscountCodeServiceInterface::findCodeUsages()`](/api/php_api/php_api_reference/classes/Ibexa-Contracts-DiscountsCodes-DiscountCodeServiceInterface.html#method_findCodeUsages) and [`DiscountCodeUsageQuery`](/api/php_api/php_api_reference/classes/Ibexa-Contracts-DiscountsCodes-Value-Query-DiscountCodeUsageQuery.html).