From c4a6e8fe28409f89fc6df0d5613be68c4a72cc86 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Tomasz=20D=C4=85browski?= <64841871+dabrt@users.noreply.github.com> Date: Wed, 16 Apr 2025 18:29:40 +0200 Subject: [PATCH 1/4] IBX-9683: Document Discounts --- docs/discounts/discounts.md | 18 +++++ docs/discounts/discounts_guide.md | 102 ++++++++++++++++++++++++++++ docs/discounts/extend_discounts.md | 8 +++ docs/discounts/install_discounts.md | 44 ++++++++++++ 4 files changed, 172 insertions(+) create mode 100644 docs/discounts/discounts.md create mode 100644 docs/discounts/discounts_guide.md create mode 100644 docs/discounts/extend_discounts.md create mode 100644 docs/discounts/install_discounts.md diff --git a/docs/discounts/discounts.md b/docs/discounts/discounts.md new file mode 100644 index 0000000000..8d1195c5ab --- /dev/null +++ b/docs/discounts/discounts.md @@ -0,0 +1,18 @@ +--- +description: Discounts help store managers reduce prices on products or product categories. +page_type: landing_page +month_change: true +--- + +# Discounts + +With the Discounts feature, store managers can reduce prices on specific products or categories for all or selected customers. +After you install it, temporary or permanent discounts can be applied against items from the product catalog or cart. + +You can also extend the feature by creating custom pricing rules, application conditions, changing discount priorities,and so on. + +[[= cards([ +"discounts/discounts_guide", +"discounts/install_discounts", +"discounts/extend_discounts", +], columns=4) =]] diff --git a/docs/discounts/discounts_guide.md b/docs/discounts/discounts_guide.md new file mode 100644 index 0000000000..13658e7a4d --- /dev/null +++ b/docs/discounts/discounts_guide.md @@ -0,0 +1,102 @@ +--- +description: Discounts LTS Update enables reducing prices on products or product categories based on a detailed logic resolution. +month_change: false +--- + +# Discounts product guide + +## What are Discounts + +Just like brick-and-mortar shops, online stores use clever strategies to attract new customers, keep loyal ones, boost sales, highlight special products, and clear out inventory. + +One powerful technique that helps achieve these goals is offering discounts. +Discounts allow online stores to temporarily or permanently reduce prices on specific products or categories, making deals more attractive to potential buyers. +They can be used to encourage first-time purchases, reward loyal customers, promote new or slow-moving items, or drive sales during seasonal events. +By displaying discounted prices clearly in the catalog or cart, businesses can create a sense of urgency, increase customer satisfaction, and ultimately boost revenue. + +[[= product_name =]] can be equipped with the Discounts [LTS update](ibexa_dxp_v4.6.md#lts-updates), that introduces a highly extensible solution for building discounts. + +Store managers can apply general discounts for products from the product catalogue or specific discounts for products in the customer's shopping cart. +Once the target is selected, they can set the type of discount by choosing a discount calculation rule. +Then they can use an extended set of conditions to decide when their discounts are applied. + +Out of the box, the Discounts module delivers three types of discounts: + +- "Fixed amount" - where a specified amount of money, for example, 5 Euro, is deducted from the base price +- "Percentage" - where a specified percentage, for example, 10%, is used to calculate the deducted amount +- "Buy X, get Y" - where customers purchase a specified number of items (X) and receive additional items (Y) for free or at a discounted price + +A selection of conditions used to limit the applicability of a discount is broader, and includes, for example, rules that check whether: + +- the product belongs to a specific category +- the customer belongs to a specific customer group +- the purchase is made within a defined timeframe +- a minimum purchase amount is met + +!!! note "Difference between discounts and price rules" + + Unlike flexible and highly configurable discounts, [prices applied to customer groups](prices.md#custom-pricing) cannot have time limits, only apply to specific customer groups, and do not offer flexibility to adjust prices at cart level. + +You can extend the solution's capabilities beyond the default setup by ... + +## Availability + +Discounts are an opt-in capability available as an [LTS update](editions.md#lts-updates) starting with the v4.6.XX version of [[= product_name =]], regardless of its edition. +To begin using Discounts, you must first [install the required packages and perform initial configuration](install_discounts.md). + +## How it works + +Discounts LTS update relies on an extensible AI framework, which is responsible for gathering information from various sources, such as Discount types, Discount configurations, and contextual details like SiteAccess, user details, locale settings, and more. +This data can then be combined with user input. +It's then passed to a service for final processing on [[= product_name =]] side. +... + +### Core concepts + +#### Promotion + +Promotions are a marketing tool used to increase sales of certain products or product lines. +They enable sellers to apply various discounts to their stock, generate personalized discount coupons, and can follow strategic promotion schedules. + +#### Discount + +A a reduction in the usual price, a deduction applied to an online purchase, typically implemented as part of a marketing campaign. +Discounts can apply to specific items, shipping costs, total order amount and so on. + +- Automatic discounts + +... + +- Discount codes (aka. coupons) + +... + +### + +## Capabilities + +### Management + +Users with the appropriate permissions, governed by role-based [policies](policies.md#ai-actions), can control the lifecycle of Discounts by creating, editing, executing, and deleting them. +Additionally, Discount configurations can be enabled or disabled depending on the organization's needs. + +![Discount management screen](img/discount_list.png) + +An intuitive Discounts interface displays a list of all available Discounts. +Here, you can search for specific discounts and filter them by type or status. +By accessing the detailed view of individual Discounts, you can quickly review all their parameters. + +### Extensibility + +Built-in Discount types offer a good starting point, but the real power of the Discounts lies in extensibility. +Extending Discounts opens up new possibilities for building promotional campaigns that help move stock and attach customers. +... + +For example, [[= product_name =]] could apply a special discount when a customer places their 1st, 10th, or 100th order in the storefront. +This would encourages first-time purchases, repeat business, and long-term customer loyalty. + +## Use cases + +Out of the box, the [[= product_name_base =]] Discounts LTS update comes with multiple discount types that can be applied in the following use cases. + +### ... diff --git a/docs/discounts/extend_discounts.md b/docs/discounts/extend_discounts.md new file mode 100644 index 0000000000..83d2d80bd9 --- /dev/null +++ b/docs/discounts/extend_discounts.md @@ -0,0 +1,8 @@ +--- +description: Extend Discounts by adding new capabilities. +month_change: false +--- + +# Extend Discounts + +By extending [Discounts](discounts_guide.md), you can ... diff --git a/docs/discounts/install_discounts.md b/docs/discounts/install_discounts.md new file mode 100644 index 0000000000..489c71c419 --- /dev/null +++ b/docs/discounts/install_discounts.md @@ -0,0 +1,44 @@ +--- +description: Install the Discounts LTS update. +month_change: false +--- + +# Install Discounts + +Discounts are available as an LTS update to [[= product_name =]] Commerce, starting with version v4.6.18 or higher. +To use this feature you must first install the packages and configure them. + +## Install packages + +Run the following commands to install the packages: + +``` bash +composer require ibexa/discounts +composer require ibexa/discount-codes +``` + +These commands add the framework code, service handlers, helper Twig templates, and configurations required for using Discounts. +It also modifies the permission system to account for the new functionality. + +## Configure Discounts + +Once the packages are installed, before you can start using Discounts, you must enable them by following these instructions. + +### Modify the database schema + +Run the following command, where `` is the same name that you defined when you [installed [[= product_name =]]](../getting_started/install_ibexa_dxp.md#change-installation-parameters). + +=== "MySQL" + + ```bash + + ``` + +=== "PostgreSQL" + + ```bash + ``` + +This command modifies the existing database schema by adding database configuration required for using Discounts. + +You can now restart you application and start [working with the Discounts feature]([[= user_doc =]]/discounts/work_with_discounts/). From 2607a6727180aefb024c24c7b7025196abcb70c0 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Tomasz=20D=C4=85browski?= <64841871+dabrt@users.noreply.github.com> Date: Wed, 16 Apr 2025 18:30:29 +0200 Subject: [PATCH 2/4] Document permissions --- docs/permissions/limitation_reference.md | 14 ++++++++++++-- docs/permissions/permission_use_cases.md | 14 ++++++++++++++ docs/permissions/policies.md | 11 +++++++++++ 3 files changed, 37 insertions(+), 2 deletions(-) diff --git a/docs/permissions/limitation_reference.md b/docs/permissions/limitation_reference.md index 40bcc538fa..008e0d4097 100644 --- a/docs/permissions/limitation_reference.md +++ b/docs/permissions/limitation_reference.md @@ -41,9 +41,9 @@ The `ActivityLogOwner` limitation specifies if a user can see only their own [re |-------|-----------------|--------------------------------------------------------------| | `1` | "Only own logs" | Current user can only access their own activity log entries. | -## CartOwner limitation +## Cart Owner limitation -The `CartOwner` limitation specifies whether the user can modify a cart. +The Cart Owner `CartOwner` limitation specifies whether the user can modify a cart. ### Possible values @@ -62,6 +62,16 @@ The Change Owner (`ChangeOwner`) limitation specifies whether the user can chang |------|------|------| |`1`|"Forbid"|The user cannot change owner of a content item| +## Discount Owner limitation + +The Discount Owner `DiscountOwner` limitation specifies whether the user can interact with a discount. + +### Possible values + +|Value|UI value|Description| +|------|------|------| +|"self"|"self"|Only the user who is the owner of the discount gets access.| + ## Content type Group limitation The Content Type Group (`UserGroup`) limitation specifies that only users with at least one common *direct* user group with the owner of content get the selected access right. diff --git a/docs/permissions/permission_use_cases.md b/docs/permissions/permission_use_cases.md index cd043357de..ec4f0a8b3a 100644 --- a/docs/permissions/permission_use_cases.md +++ b/docs/permissions/permission_use_cases.md @@ -269,6 +269,20 @@ Set the following permissions to decide what actions are available when users in - `checkout/update` - to allow users to modify existing information, for example item quantity - `checkout/delete` - to delete checkout +### Discount management + +Set the following permissions to decide what actions are available when users interact with discounts: + +- `discount/create` - to allow the user to create a new discount +- `discount/update` - to allow the user to change the parameters of an existing discount +- `discount/view` - to allow the user to view discounts +- `discount/delete` - to delete an existing discount +- `discount/enable` - to allow the user to enable an existing discount +- `discount/disable` - to allow the user to disable an existing discount + +To further control access to a discount, you can use the `DiscountOwner` limitation and set its value to `self`. +This way users can only interact with their own discounts. + ### Order management Set the following permissions to decide what actions are available when users interact with orders: diff --git a/docs/permissions/policies.md b/docs/permissions/policies.md index d7ab811549..6108c4fe3a 100644 --- a/docs/permissions/policies.md +++ b/docs/permissions/policies.md @@ -124,6 +124,17 @@ Each role you assign to user or user group consists of policies which define, wh | `commerce` | `currency` | manage currencies | | | `region` | manage regions | +#### Discounts [[% include 'snippets/commerce_badge.md' %]] + +| Module | Function | Effect | Possible limitations | +|----------------------|--------------------------|-----------------------------|----------------------------------------------------| +| `discount` | `create` | create a discount | [DiscountOwner](limitation_reference.md#discount-owner-limitation) | +| | `delete` | delete a discount | [DiscountOwner](limitation_reference.md#discount-owner-limitation) | +| | `enable` | enable a discount | [DiscountOwner](limitation_reference.md#discount-owner-limitation) | +| | `disable` | disable a discount | [DiscountOwner](limitation_reference.md#discount-owner-limitation) | +| | `update` | modify discount parameters | [DiscountOwner](limitation_reference.md#discount-owner-limitation) | +| | `view` | view discounts | [DiscountOwner](limitation_reference.md#discount-owner-limitation) | + #### Orders [[% include 'snippets/commerce_badge.md' %]] | Module | Function | Effect | Possible limitations | From 3958c12a5ef4baea7583605dbcf3b51fa4193d19 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Tomasz=20D=C4=85browski?= <64841871+dabrt@users.noreply.github.com> Date: Wed, 16 Apr 2025 18:30:44 +0200 Subject: [PATCH 3/4] Document search --- .../discount_created_criterion.md | 25 +++++++++++++ .../discount_creator_criterion.md | 24 +++++++++++++ .../discount_enddate_criterion.md | 30 ++++++++++++++++ .../discount_identifier_criterion.md | 22 ++++++++++++ .../discount_isenabled_criterion.md | 22 ++++++++++++ .../discount_logicaland_criterion.md | 29 +++++++++++++++ .../discount_logicalor_criterion.md | 25 +++++++++++++ .../discount_name_criterion.md | 22 ++++++++++++ .../discount_priority_criterion.md | 22 ++++++++++++ .../discount_search_criteria.md | 26 ++++++++++++++ .../discount_startdate_criterion.md | 30 ++++++++++++++++ .../discount_type_criterion.md | 22 ++++++++++++ .../discount_createdat_sort_clause.md | 36 +++++++++++++++++++ .../discount_id_sort_clause.md | 30 ++++++++++++++++ .../discount_identifier_sort_clause.md | 30 ++++++++++++++++ .../discount_priority_sort_clause.md | 30 ++++++++++++++++ .../discount_type_sort_clause.md | 30 ++++++++++++++++ .../discount_updatedat_sort_clause.md | 36 +++++++++++++++++++ .../discounts_enddate_sort_clause.md | 36 +++++++++++++++++++ .../discounts_startdate_sort_clause.md | 36 +++++++++++++++++++ 20 files changed, 563 insertions(+) create mode 100644 docs/search/criteria_reference/discount_created_criterion.md create mode 100644 docs/search/criteria_reference/discount_creator_criterion.md create mode 100644 docs/search/criteria_reference/discount_enddate_criterion.md create mode 100644 docs/search/criteria_reference/discount_identifier_criterion.md create mode 100644 docs/search/criteria_reference/discount_isenabled_criterion.md create mode 100644 docs/search/criteria_reference/discount_logicaland_criterion.md create mode 100644 docs/search/criteria_reference/discount_logicalor_criterion.md create mode 100644 docs/search/criteria_reference/discount_name_criterion.md create mode 100644 docs/search/criteria_reference/discount_priority_criterion.md create mode 100644 docs/search/criteria_reference/discount_search_criteria.md create mode 100644 docs/search/criteria_reference/discount_startdate_criterion.md create mode 100644 docs/search/criteria_reference/discount_type_criterion.md create mode 100644 docs/search/sort_clause_reference/discount_createdat_sort_clause.md create mode 100644 docs/search/sort_clause_reference/discount_id_sort_clause.md create mode 100644 docs/search/sort_clause_reference/discount_identifier_sort_clause.md create mode 100644 docs/search/sort_clause_reference/discount_priority_sort_clause.md create mode 100644 docs/search/sort_clause_reference/discount_type_sort_clause.md create mode 100644 docs/search/sort_clause_reference/discount_updatedat_sort_clause.md create mode 100644 docs/search/sort_clause_reference/discounts_enddate_sort_clause.md create mode 100644 docs/search/sort_clause_reference/discounts_startdate_sort_clause.md diff --git a/docs/search/criteria_reference/discount_created_criterion.md b/docs/search/criteria_reference/discount_created_criterion.md new file mode 100644 index 0000000000..1f54de3bd7 --- /dev/null +++ b/docs/search/criteria_reference/discount_created_criterion.md @@ -0,0 +1,25 @@ +--- +description: Discount CreatedAt Search Criterion +edition: commerce +--- + +# Discount CreatedAt Criterion + +The `CreatedAtCriterion` Search Criterion searches for discounts based on the date when they were created. + +## Arguments + +- `createdAt` - date to be matched, provided as a `DateTimeInterface` object +- `operator` - optional operator string (EQ, GT, GTE, LT, LTE) + +## Example + +### PHP + +``` php +$criteria = new \Ibexa\Contracts\Discounts\Value\Query\Criterion\CreatedAtCriterion( + new DateTime('2025-04-11 14:07:02'), Operator::GTE +); + +$discountQuery = new DiscountQuery($criteria); +``` diff --git a/docs/search/criteria_reference/discount_creator_criterion.md b/docs/search/criteria_reference/discount_creator_criterion.md new file mode 100644 index 0000000000..5de245df8c --- /dev/null +++ b/docs/search/criteria_reference/discount_creator_criterion.md @@ -0,0 +1,24 @@ +--- +description: Discount CreatorCriterion Search Criterion +edition: commerce +--- + +# Creator Criterion + +The `CreatorCriterion` Criterion searches for discounts based on the user reference. + +## Arguments + +- `UserReference` object - \Ibexa\Contracts\Core\Repository\Values\User\UserReference(int $userId) + +## Example + +### PHP + +``` php +$query = new DiscountQuery( + new \Ibexa\Contracts\Discounts\Value\Query\Criterion\CreatorCriterion( + \Ibexa\Core\Repository\Values\User\UserReference(14) + ) +); +``` diff --git a/docs/search/criteria_reference/discount_enddate_criterion.md b/docs/search/criteria_reference/discount_enddate_criterion.md new file mode 100644 index 0000000000..ee093f0beb --- /dev/null +++ b/docs/search/criteria_reference/discount_enddate_criterion.md @@ -0,0 +1,30 @@ +--- +description: Discount EndDate Search Criterion +edition: commerce +--- + +# Discount EndDate Criterion + +The `EndDateCriterion` Search Criterion searches for discounts based on the date and time when they expire. + +## Arguments + +- `value` - searched value provided as the [DateTimeImmutable](https://www.php.net/manual/en/class.datetimeimmutable.php) object +- `operator` - optional operator string (EQ, GT, GTE, LT, LTE) + +## Example + +### PHP + +``` php +$criteria = new \Ibexa\Contracts\Discounts\Value\Query\Criterion\LogicalAnd( + new \Ibexa\Contracts\Discounts\Value\Query\Criterion\StartDateCriterion( + new DateTimeImmutable('2025-04-11 14:07:03'), Operator::GTE + ), + new \Ibexa\Contracts\Discounts\Value\Query\Criterion\EndDateCriterion( + new DateTimeImmutable('2027-04-11 14:07:02'), Operator::LTE + ), +); + +$discountQuery = new DiscountQuery($criteria); +``` diff --git a/docs/search/criteria_reference/discount_identifier_criterion.md b/docs/search/criteria_reference/discount_identifier_criterion.md new file mode 100644 index 0000000000..abf0bb91ed --- /dev/null +++ b/docs/search/criteria_reference/discount_identifier_criterion.md @@ -0,0 +1,22 @@ +--- +description: Discount Identifier Search Criterion +edition: commerce +--- + +# Discount Identifier Criterion + +The `Identifier` Search Criterion searches for discounts based on the discount identifier. + +## Arguments + +- `identifier` - string that represents the discount identifier + +## Example + +### PHP + +``` php +$criteria = new \Ibexa\Contracts\Discounts\Value\Query\Criterion\IdentifierCriterion('summer-sale'); + +$discountQuery = new DiscountQuery($criteria); +``` diff --git a/docs/search/criteria_reference/discount_isenabled_criterion.md b/docs/search/criteria_reference/discount_isenabled_criterion.md new file mode 100644 index 0000000000..2a01a049b9 --- /dev/null +++ b/docs/search/criteria_reference/discount_isenabled_criterion.md @@ -0,0 +1,22 @@ +--- +description: Discount IsEnabled Search Criterion +edition: commerce +--- + +# Discount IsEnabled Criterion + +The `IsEnabledCriterion` Search Criterion searches for discounts based on whether the discount is enabled or not. + +## Arguments + +- `value` - Boolean value stating whether the discount is enabled or not + +## Example + +### PHP + +``` php +$criteria = new \Ibexa\Contracts\Discounts\Value\Query\Criterion\IsEnabledCriterion(true); + +$discountQuery = new DiscountQuery($criteria); +``` diff --git a/docs/search/criteria_reference/discount_logicaland_criterion.md b/docs/search/criteria_reference/discount_logicaland_criterion.md new file mode 100644 index 0000000000..392675a75b --- /dev/null +++ b/docs/search/criteria_reference/discount_logicaland_criterion.md @@ -0,0 +1,29 @@ +--- +description: Discount LogicalAnd Search Criterion +edition: commerce +--- + +# Discount LogicalAnd Criterion + +The `LogicalAnd` Search Criterion matches discounts if all provided Criteria match. + +## Arguments + +- `criterion` - a set of Criteria combined by the logical operator + +## Example + +### PHP + +``` php +$criteria = new \Ibexa\Contracts\Discounts\Value\Query\Criterion\LogicalAnd( + new \Ibexa\Contracts\Discounts\Value\Query\Criterion\StartDateCriterion( + new DateTimeImmutable('2025-04-11 14:07:03'), Operator::GTE + ), + new \Ibexa\Contracts\Discounts\Value\Query\Criterion\EndDateCriterion( + new DateTimeImmutable('2027-04-11 14:07:02'), Operator::LTE + ), +); + +$discountQuery = new DiscountQuery($criteria); +``` diff --git a/docs/search/criteria_reference/discount_logicalor_criterion.md b/docs/search/criteria_reference/discount_logicalor_criterion.md new file mode 100644 index 0000000000..daff1e41db --- /dev/null +++ b/docs/search/criteria_reference/discount_logicalor_criterion.md @@ -0,0 +1,25 @@ +--- +description: Discount LogicalOr Search Criterion +edition: commerce +--- + +# Discount LogicalOr Criterion + +The `LogicalOr` Search Criterion matches discounts if at least one of the provided Criteria matches. + +## Arguments + +- `criterion` - a set of Criteria combined by the logical operator + +## Example + +### PHP + +``` php +$criteria = new LogicalOr( + new StartDateCriterion(new DateTimeImmutable('2025-04-11 14:07:03'), Operator::GTE), + new CreatedAtCriterion(new DateTime('2025-04-11 14:07:02'), Operator::GTE), +); + +$discountQuery = new DiscountQuery($criteria); +``` diff --git a/docs/search/criteria_reference/discount_name_criterion.md b/docs/search/criteria_reference/discount_name_criterion.md new file mode 100644 index 0000000000..a2e23f0fdb --- /dev/null +++ b/docs/search/criteria_reference/discount_name_criterion.md @@ -0,0 +1,22 @@ +--- +description: Discount NameCriterion Search Criterion +edition: commerce +--- + +# Discount Name Criterion + +The `NameCriterion` Search Criterion searches for discounts based on the discount name. + +## Arguments + +- `value` - string that represents the discount name + +## Example + +### PHP + +``` php +$criteria = new \Ibexa\Contracts\Discounts\Value\Query\Criterion\NameCriterion('Summer sale'); + +$discountQuery = new DiscountQuery($criteria); +``` diff --git a/docs/search/criteria_reference/discount_priority_criterion.md b/docs/search/criteria_reference/discount_priority_criterion.md new file mode 100644 index 0000000000..19741a977a --- /dev/null +++ b/docs/search/criteria_reference/discount_priority_criterion.md @@ -0,0 +1,22 @@ +--- +description: Discount PriorityCriterion Search Criterion +edition: commerce +--- + +# Priority Criterion + +The `PriorityCriterion` Criterion searches for discounts based on their priority. + +## Arguments + +- `value` - numerical value representing the discount's priority + +## Example + +### PHP + +``` php +$criteria = new \Ibexa\Contracts\Discounts\Value\Query\Criterion\PriorityCriterion(5); + +$discountQuery = new DiscountQuery($criteria); +``` diff --git a/docs/search/criteria_reference/discount_search_criteria.md b/docs/search/criteria_reference/discount_search_criteria.md new file mode 100644 index 0000000000..ea40d84ca8 --- /dev/null +++ b/docs/search/criteria_reference/discount_search_criteria.md @@ -0,0 +1,26 @@ +--- +description: Discount Search Criteria +edition: commerce +--- + +# Discount Search Criteria reference + +Discount Search Criteria are only supported by [Discount Search (`DiscountService::findDiscounts`)](discounts_api.md#get-multiple-discounts). + +With these Criteria you can filter discounts, for example, by their discount identifier, name, creation date, discount status, priority, or type. + +## Discount Search Criteria + +|Search Criterion|Search based on| +|-----|-----| +|[CreatedAtCriterion](discount_created_criterion.md)|Date and time when the discount was created| +|[CreatorCriterion](discount_creator_criterion.md)|User who created the discount| +|[EndDateCriterion](discount_end_date_criterion.md)|Date and time when the discount expires| +|[IdentifierCriterion](discount_identifier_criterion.md)|Discount identifier| +|[IsEnabledCriterion](discount_is_enabled_criterion.md)|Whether the discount is enabled or not| +|[LogicalAndCriterion](discount_logicaland_criterion.md)|Owner based on the user reference| +|[LogicalOrCriterion](discount_logicalor_criterion.md)|Owner based on the user reference| +|[NameCriterion](discount_name_criterion.md)|The name of the discount| +|[PriorityCriterion](discount_priority_criterion.md)|Priority value of the discount| +|[StartDateCriterion](discount_start_date_criterion.md)|Date and time when the discount begins| +|[TypeCriterion](discount_type_criterion.md)|Type value of the criterion| diff --git a/docs/search/criteria_reference/discount_startdate_criterion.md b/docs/search/criteria_reference/discount_startdate_criterion.md new file mode 100644 index 0000000000..77946cff92 --- /dev/null +++ b/docs/search/criteria_reference/discount_startdate_criterion.md @@ -0,0 +1,30 @@ +--- +description: Discount StartDate Search Criterion +edition: commerce +--- + +# Discount StartDate Criterion + +The `StartDateCriterion` Search Criterion searches for discounts based on the date and time when they begin. + +## Arguments + +- `value` - searched value provided as the [DateTimeImmutable](https://www.php.net/manual/en/class.datetimeimmutable.php) object +- `operator` - optional operator string (EQ, GT, GTE, LT, LTE) + +## Example + +### PHP + +``` php +$criteria = new \Ibexa\Contracts\Discounts\Value\Query\Criterion\LogicalAnd( + new \Ibexa\Contracts\Discounts\Value\Query\Criterion\StartDateCriterion( + new DateTimeImmutable('2025-04-11 14:07:03'), Operator::GTE + ), + new \Ibexa\Contracts\Discounts\Value\Query\Criterion\EndDateCriterion( + new DateTimeImmutable('2027-04-11 14:07:02'), Operator::LTE + ), +); + +$discountQuery = new DiscountQuery($criteria); +``` diff --git a/docs/search/criteria_reference/discount_type_criterion.md b/docs/search/criteria_reference/discount_type_criterion.md new file mode 100644 index 0000000000..a7f94b2175 --- /dev/null +++ b/docs/search/criteria_reference/discount_type_criterion.md @@ -0,0 +1,22 @@ +--- +description: Discount TypeCriterion Search Criterion +edition: commerce +--- + +# Discount Type Criterion + +The `TypeCriterion` Search Criterion searches for discounts based on the discount type. + +## Arguments + +- `value` - string that represents the discount type + +## Example + +### PHP + +``` php +$criteria = new \Ibexa\Contracts\Discounts\Value\Query\Criterion\TypeCriterion('catalog'); + +$discountQuery = new DiscountQuery($criteria); +``` diff --git a/docs/search/sort_clause_reference/discount_createdat_sort_clause.md b/docs/search/sort_clause_reference/discount_createdat_sort_clause.md new file mode 100644 index 0000000000..5d96feec36 --- /dev/null +++ b/docs/search/sort_clause_reference/discount_createdat_sort_clause.md @@ -0,0 +1,36 @@ +--- +description: Discount CreatedAt Sort Clause +edition: commerce +--- + +# Discount CreatedAt Sort Clause + +The `CreatedAt` Sort Clause sorts search results by the date and time when the discount was created. + +## Arguments + +- (optional) `sortDirection` - `CreatedAt` constant, either `CreatedAt::SORT_ASC` or `CreatedAt::SORT_DESC` + +## Example + +``` php +new \Ibexa\Contracts\Discounts\Value\Query\DiscountQuery( + null, + [new \Ibexa\Contracts\Discounts\Value\Query\SortClause\CreatedAt(\Ibexa\Contracts\CoreSearch\Values\Query\AbstractSortClause::SORT_ASC)], +), +10, +static function (\Ibexa\Contracts\Discounts\Value\DiscountListInterface $discountList): void { + $timestamps = array_map( + static fn (\Ibexa\Contracts\Discounts\Value\DiscountInterface $discount): DateTimeInterface => $discount->getCreatedAt(), + $discountList->getDiscounts() + ); + + self::assertEquals( + [ + new DateTimeImmutable('2024-11-20 14:07:04'), + new DateTimeImmutable('2024-11-20 14:07:04'), + ], + $timestamps + ); +} +``` diff --git a/docs/search/sort_clause_reference/discount_id_sort_clause.md b/docs/search/sort_clause_reference/discount_id_sort_clause.md new file mode 100644 index 0000000000..dbae63049f --- /dev/null +++ b/docs/search/sort_clause_reference/discount_id_sort_clause.md @@ -0,0 +1,30 @@ +--- +description: Discount Id Sort Clause +edition: commerce +--- + +# Discount Id Sort Clause + +The `Id` Sort Clause sorts search results by discount ID. + +## Arguments + +- (optional) `sortDirection` - `Id` constant, either `Id::SORT_ASC` or `Id::SORT_DESC` + +## Example + +``` php +new \Ibexa\Contracts\Discounts\Value\Query\DiscountQuery( + null, + [new \Ibexa\Contracts\Discounts\Value\Query\SortClause\Id(AbstractSortClause::SORT_DESC)], + ), + 10, + static function (\Ibexa\Contracts\Discounts\Value\DiscountListInterface $discountList): void { + $ids = array_map( + static fn (\Ibexa\Contracts\Discounts\Value\DiscountInterface $discount): int => $discount->getId(), + $discountList->getDiscounts() + ); + + self::assertSame([10, 7, 3, 1], $ids); + } +``` diff --git a/docs/search/sort_clause_reference/discount_identifier_sort_clause.md b/docs/search/sort_clause_reference/discount_identifier_sort_clause.md new file mode 100644 index 0000000000..dc3facdc85 --- /dev/null +++ b/docs/search/sort_clause_reference/discount_identifier_sort_clause.md @@ -0,0 +1,30 @@ +--- +description: Discount Identifier Sort Clause +edition: commerce +--- + +# Discount Identifier Sort Clause + +The `Identifier` Sort Clause sorts search results by discount identifier. + +## Arguments + +- (optional) `sortDirection` - `Identifier` constant, either `Identifier::SORT_ASC` or `Identifier::SORT_DESC` + +## Example + +``` php +new \Ibexa\Contracts\Discounts\Value\Query\DiscountQuery( + null, + [new \Ibexa\Contracts\Discounts\Value\Query\SortClause\Identifier(AbstractSortClause::SORT_DESC)], + ), + 10, + static function (\Ibexa\Contracts\Discounts\Value\DiscountListInterface $discountList): void { + $identifiers = array_map( + static fn (\Ibexa\Contracts\Discounts\Value\DiscountInterface $discount): string => $discount->getIdentifier(), + $discountList->getDiscounts() + ); + + self::assertSame([foo, bar, tic, tac], $identifiers); + } +``` diff --git a/docs/search/sort_clause_reference/discount_priority_sort_clause.md b/docs/search/sort_clause_reference/discount_priority_sort_clause.md new file mode 100644 index 0000000000..c7053a61b1 --- /dev/null +++ b/docs/search/sort_clause_reference/discount_priority_sort_clause.md @@ -0,0 +1,30 @@ +--- +description: Discount Priority Sort Clause +edition: commerce +--- + +# Discount Priority Sort Clause + +The `Priority` Sort Clause sorts search results by discount priority. + +## Arguments + +- (optional) `sortDirection` - `Priority` constant, either `Priority::SORT_ASC` or `Priority::SORT_DESC` + +## Example + +``` php +new \Ibexa\Contracts\Discounts\Value\Query\DiscountQuery( + null, + [new \Ibexa\Contracts\Discounts\Value\Query\SortClause\Priority(AbstractSortClause::SORT_DESC)], + ), + 10, + static function (\Ibexa\Contracts\Discounts\Value\DiscountListInterface $discountList): void { + $priorities = array_map( + static fn (\Ibexa\Contracts\Discounts\Value\DiscountInterface $discount): int => $discount->getPriority(), + $discountList->getDiscounts() + ); + + self::assertSame([10, 7, 3, 1], $priorities); + } +``` diff --git a/docs/search/sort_clause_reference/discount_type_sort_clause.md b/docs/search/sort_clause_reference/discount_type_sort_clause.md new file mode 100644 index 0000000000..7b2d220f50 --- /dev/null +++ b/docs/search/sort_clause_reference/discount_type_sort_clause.md @@ -0,0 +1,30 @@ +--- +description: Discount Type Sort Clause +edition: commerce +--- + +# Discount Type Sort Clause + +The `Type` Sort Clause sorts search results by discount type. + +## Arguments + +- (optional) `sortDirection` - `Type` constant, either `Type::SORT_ASC` or `Type::SORT_DESC` + +## Example + +``` php +new \Ibexa\Contracts\Discounts\Value\Query\DiscountQuery( + null, + [new \Ibexa\Contracts\Discounts\Value\Query\SortClause\Type(AbstractSortClause::SORT_DESC)], + ), + 10, + static function (\Ibexa\Contracts\Discounts\Value\DiscountListInterface $discountList): void { + $types = array_map( + static fn (\Ibexa\Contracts\Discounts\Value\DiscountInterface $discount): string => $discount->getType(), + $discountList->getDiscounts() + ); + + self::assertSame([catalog, cart], $types); + } +``` diff --git a/docs/search/sort_clause_reference/discount_updatedat_sort_clause.md b/docs/search/sort_clause_reference/discount_updatedat_sort_clause.md new file mode 100644 index 0000000000..03186c7abc --- /dev/null +++ b/docs/search/sort_clause_reference/discount_updatedat_sort_clause.md @@ -0,0 +1,36 @@ +--- +description: Discount UpdatedAt Sort Clause +edition: commerce +--- + +# Discount UpdatedAt Sort Clause + +The `UpdatedAt` Sort Clause sorts search results by the date and time when the discount's parameters were updated. + +## Arguments + +- (optional) `sortDirection` - `UpdatedAt` constant, either `UpdatedAt::SORT_ASC` or `UpdatedAt::SORT_DESC` + +## Example + +``` php +new \Ibexa\Contracts\Discounts\Value\Query\DiscountQuery( + null, + [new \Ibexa\Contracts\Discounts\Value\Query\SortClause\UpdatedAt(\Ibexa\Contracts\CoreSearch\Values\Query\AbstractSortClause::SORT_ASC)], +), +10, +static function (\Ibexa\Contracts\Discounts\Value\DiscountListInterface $discountList): void { + $timestamps = array_map( + static fn (\Ibexa\Contracts\Discounts\Value\DiscountInterface $discount): DateTimeInterface => $discount->getUpdatedAt(), + $discountList->getDiscounts() + ); + + self::assertEquals( + [ + new DateTimeImmutable('2024-11-20 14:07:04'), + new DateTimeImmutable('2024-11-20 14:07:04'), + ], + $timestamps + ); +} +``` diff --git a/docs/search/sort_clause_reference/discounts_enddate_sort_clause.md b/docs/search/sort_clause_reference/discounts_enddate_sort_clause.md new file mode 100644 index 0000000000..5d215d09d0 --- /dev/null +++ b/docs/search/sort_clause_reference/discounts_enddate_sort_clause.md @@ -0,0 +1,36 @@ +--- +description: Discount EndDate Sort Clause +edition: commerce +--- + +# Discount EndDate Sort Clause + +The `EndDate` Sort Clause sorts search results by the discount's end date and time. + +## Arguments + +- (optional) `sortDirection` - `EndDate` constant, either `EndDate::SORT_ASC` or `EndDate::SORT_DESC` + +## Example + +``` php +new \Ibexa\Contracts\Discounts\Value\Query\DiscountQuery( + null, + [new \Ibexa\Contracts\Discounts\Value\Query\SortClause\EndDate(AbstractSortClause::SORT_DESC)], +), +10, +static function (\Ibexa\Contracts\Discounts\Value\DiscountListInterface $discountList): void { + $timestamps = array_map( + static fn (\Ibexa\Contracts\Discounts\Value\DiscountInterface $discount): DateTimeInterface => $discount->getEndDate(), + $discountList->getDiscounts() + ); + + self::assertEquals( + [ + new DateTimeImmutable('2024-11-20 14:07:04'), + new DateTimeImmutable('2024-11-20 14:07:04'), + ], + $timestamps + ); +} +``` diff --git a/docs/search/sort_clause_reference/discounts_startdate_sort_clause.md b/docs/search/sort_clause_reference/discounts_startdate_sort_clause.md new file mode 100644 index 0000000000..7c5410fab6 --- /dev/null +++ b/docs/search/sort_clause_reference/discounts_startdate_sort_clause.md @@ -0,0 +1,36 @@ +--- +description: Discount StartDate Sort Clause +edition: commerce +--- + +# Discount StartDate Sort Clause + +The `StartDate` Sort Clause sorts search results by the discount's start date and time. + +## Arguments + +- (optional) `sortDirection` - `StartDate` constant, either `StartDate::SORT_ASC` or `StartDate::SORT_DESC` + +## Example + +``` php +new \Ibexa\Contracts\Discounts\Value\Query\DiscountQuery( + null, + [new \Ibexa\Contracts\Discounts\Value\Query\SortClause\StartDate(AbstractSortClause::SORT_DESC)], +), +10, +static function (\Ibexa\Contracts\Discounts\Value\DiscountListInterface $discountList): void { + $timestamps = array_map( + static fn (\Ibexa\Contracts\Discounts\Value\DiscountInterface $discount): DateTimeInterface => $discount->getStartDate(), + $discountList->getDiscounts() + ); + + self::assertEquals( + [ + new DateTimeImmutable('2024-11-20 14:07:04'), + new DateTimeImmutable('2024-11-20 14:07:04'), + ], + $timestamps + ); +} +``` From 1f172a277961ae5ea6d9e1b0fbb63f321d7a7cb0 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Tomasz=20D=C4=85browski?= <64841871+dabrt@users.noreply.github.com> Date: Wed, 16 Apr 2025 18:34:20 +0200 Subject: [PATCH 4/4] Update TOC --- docs/discounts/discounts.md | 3 +-- docs/discounts/discounts_guide.md | 2 +- docs/discounts/install_discounts.md | 2 +- mkdocs.yml | 26 ++++++++++++++++++++++++++ 4 files changed, 29 insertions(+), 4 deletions(-) diff --git a/docs/discounts/discounts.md b/docs/discounts/discounts.md index 8d1195c5ab..9626bc3ba7 100644 --- a/docs/discounts/discounts.md +++ b/docs/discounts/discounts.md @@ -13,6 +13,5 @@ You can also extend the feature by creating custom pricing rules, application co [[= cards([ "discounts/discounts_guide", -"discounts/install_discounts", -"discounts/extend_discounts", +"discounts/install_discounts" ], columns=4) =]] diff --git a/docs/discounts/discounts_guide.md b/docs/discounts/discounts_guide.md index 13658e7a4d..9132422ca3 100644 --- a/docs/discounts/discounts_guide.md +++ b/docs/discounts/discounts_guide.md @@ -77,7 +77,7 @@ Discounts can apply to specific items, shipping costs, total order amount and so ### Management -Users with the appropriate permissions, governed by role-based [policies](policies.md#ai-actions), can control the lifecycle of Discounts by creating, editing, executing, and deleting them. +Users with the appropriate permissions, governed by role-based [policies](policies.md#disc ounts), can control the lifecycle of Discounts by creating, editing, executing, and deleting them. Additionally, Discount configurations can be enabled or disabled depending on the organization's needs. ![Discount management screen](img/discount_list.png) diff --git a/docs/discounts/install_discounts.md b/docs/discounts/install_discounts.md index 489c71c419..8b9e7e8f9a 100644 --- a/docs/discounts/install_discounts.md +++ b/docs/discounts/install_discounts.md @@ -17,7 +17,7 @@ composer require ibexa/discounts composer require ibexa/discount-codes ``` -These commands add the framework code, service handlers, helper Twig templates, and configurations required for using Discounts. +These commands add the feature code, service handlers, helper Twig templates, and configurations required for using Discounts. It also modifies the permission system to account for the new functionality. ## Configure Discounts diff --git a/mkdocs.yml b/mkdocs.yml index 264c8307ed..f4844e41b4 100644 --- a/mkdocs.yml +++ b/mkdocs.yml @@ -392,6 +392,11 @@ nav: - Transactional emails: commerce/transactional_emails/transactional_emails.md - Transactional email variables reference: commerce/transactional_emails/transactional_emails_parameters.md - Customize transactional emails: commerce/transactional_emails/extend_transactional_emails.md + - Discounts: + - Discounts: discounts/discounts.md + - Discounts guide: discounts/discounts_guide.md + - Install Discounts: discounts/install_discounts.md +# - Extend Discounts: discounts/extend_discounts.md - Customer management: - Customer Portal: customer_management/customer_portal.md - Customer Portal guide: customer_management/customer_portal_guide.md @@ -576,6 +581,18 @@ nav: - RangeMeasurementAttributeMaximum: search/criteria_reference/rangemeasurementattributemaximum_criterion.md - SimpleMeasurementAttribute: search/criteria_reference/simplemeasurementattribute_criterion.md - SelectionAttribute: search/criteria_reference/selectionattribute_criterion.md + - Discount Search Criteria: + - Discount Search Criteria: search/criteria_reference/discount_search_criteria.md + - CompanyName: search/criteria_reference/order_company_name_criterion.md + - CreatedAt: search/criteria_reference/order_created_criterion.md + - CurrencyCode: search/criteria_reference/order_currency_code_criterion.md + - CustomerName: search/criteria_reference/order_customer_name_criterion.md + - Identifier: search/criteria_reference/order_identifier_criterion.md + - IsCompanyAssociated: search/criteria_reference/order_company_associated_criterion.md + - Owner: search/criteria_reference/order_owner_criterion.md + - Price: search/criteria_reference/order_price_criterion.md + - Source: search/criteria_reference/order_source_criterion.md + - Status: search/criteria_reference/order_status_criterion.md - Order Search Criteria: - Order Search Criteria: search/criteria_reference/order_search_criteria.md - CompanyName: search/criteria_reference/order_company_name_criterion.md @@ -686,6 +703,15 @@ nav: - ProductStockRange: search/criteria_reference/productstockrange_criterion.md - ProductCode: search/sort_clause_reference/productcode_sort_clause.md - ProductName: search/sort_clause_reference/productname_sort_clause.md + - Discount Sort Clauses: + - Discount Sort Clauses: search/sort_clause_reference/discount_sort_clauses.md + - CreatedAt: search/sort_clause_reference/discount_enddate_sort_clause.md + - EndDate: search/sort_clause_reference/discount_createdat_sort_clause.md + - Identifier: search/sort_clause_reference/discount_identifier_sort_clause.md + - Priority: search/sort_clause_reference/discount_priority_sort_clause.md + - StartDate: search/sort_clause_reference/discount_sstartdate_sort_clause.md + - Type: search/sort_clause_reference/discount_type_sort_clause.md + - UpdatedAt: search/sort_clause_reference/discount_updatedat_sort_clause.md - Order Sort Clauses: - Order Sort Clauses: search/sort_clause_reference/order_sort_clauses.md - Id: search/sort_clause_reference/order_id_sort_clause.md