Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
25 changes: 25 additions & 0 deletions .wordlist.txt
Original file line number Diff line number Diff line change
Expand Up @@ -72,6 +72,8 @@
AssociationField
AsyncPaymentTransactionStruct
AsynchronousPaymentHandlerInterface
AudienceContext
AudienceContextResolver
AuditLogValueEntity
AuthenticationIdentityLoader
AutoIncrementField
Expand Down Expand Up @@ -453,6 +455,15 @@
ImportTranslationsTrait
Inclusivity
IndexerService
IndividualPricingApplyExtension
IndividualPricingBuildCacheSingleRuleMessage
IndividualPricingCacheEntryUpdaterMessage
IndividualPricingComputedCacheEntity

Check warning on line 461 in .wordlist.txt

View workflow job for this annotation

GitHub Actions / LanguageTool

[LanguageTool] .wordlist.txt#L461

Possible typo: you repeated a word (ENGLISH_WORD_REPEAT_RULE) Suggestions: `IPV` Rule: https://community.languagetool.org/rule/show/ENGLISH_WORD_REPEAT_RULE?lang=en-US Category: MISC
Raw output
.wordlist.txt:461:5: Possible typo: you repeated a word (ENGLISH_WORD_REPEAT_RULE)
 Suggestions: `IPV`
 Rule: https://community.languagetool.org/rule/show/ENGLISH_WORD_REPEAT_RULE?lang=en-US
 Category: MISC
IndividualPricingIndexerEvent
IndividualPricingIndexingMessage
IndividualPricingLookupBatchCriteriaEvent
IndividualPricingLookupCriteriaEvent
IndividualPricingProductSubscriber
Init
Initialisms
IntField
Expand Down Expand Up @@ -738,6 +749,7 @@
ProductCountRouteResponse
ProductDataSelection
ProductDataSet
ProductEntity
ProductListRoute
ProductManufacturerDefinition
ProductMedia
Expand Down Expand Up @@ -1074,6 +1086,8 @@
ZSH
accel
acl
actionAmount
actionType
actionability
activateShopwareTheme
adr
Expand All @@ -1089,6 +1103,7 @@
apiKey
apk
appVersion
applyToAllProducts
args
arrayfacade
async
Expand Down Expand Up @@ -1238,6 +1253,7 @@
customerGroup
customerGroupAware
customerHasFeature
customerId
customerRecovery
customizability
customizable
Expand Down Expand Up @@ -1454,6 +1470,7 @@
incrementer
incrementing
indexActions
individualPricingId

Check warning on line 1473 in .wordlist.txt

View workflow job for this annotation

GitHub Actions / LanguageTool

[LanguageTool] .wordlist.txt#L1473

File types are normally capitalized. (FILE_EXTENSIONS_CASE[1]) Suggestions: `HTML` URL: https://languagetool.org/insights/post/spelling-capital-letters/ Rule: https://community.languagetool.org/rule/show/FILE_EXTENSIONS_CASE?lang=en-US&subId=1 Category: CASING
Raw output
.wordlist.txt:1473:8: File types are normally capitalized. (FILE_EXTENSIONS_CASE[1])
 Suggestions: `HTML`
 URL: https://languagetool.org/insights/post/spelling-capital-letters/ 
 Rule: https://community.languagetool.org/rule/show/FILE_EXTENSIONS_CASE?lang=en-US&subId=1
 Category: CASING
infoIt
ini
init
Expand Down Expand Up @@ -1616,6 +1633,7 @@
orderTransaction
orderTransactionCaptureRefund
org's
organizationUnitIds
otel
otlp
overrideComponentSetup
Expand Down Expand Up @@ -1682,6 +1700,7 @@
productCountRoute
productId
productNumber
productStreamId
productproxy
productsfacade
profiler
Expand All @@ -1696,6 +1715,8 @@
qa
qa@shopware.com
qty's
qtyFrom
qtyTo
quantityBefore
quantityDelta
quickstart
Expand Down Expand Up @@ -1801,6 +1822,7 @@
shopwarelabs
shopwarepartners
shorthands
showStrikeThrough
simples
simplexml
skipOnFeature
Expand Down Expand Up @@ -1929,11 +1951,14 @@
uri
url
urls
useValidityRange
userAware
userRecovery
userland
utils
uuid
validFrom
validUntil
validator
validators
varchar
Expand Down
8 changes: 5 additions & 3 deletions products/extensions/b2b-components/index.md
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,8 @@ In the world of digital B2B commerce, where businesses engage with other compani

* **Order Approval** allows for a more controlled buying process by introducing an approval workflow.

* **Individual Pricing** enables merchants to define catalog-wide discounts and special pricing based on flexible conditions for B2B scenarios, including volume pricing and company-specific pricing agreements.

* **Quick Order and Shopping List** takes care of distinctive B2B buying behaviors.

* **Organization Unit** allows for the configuration of more differentiated and specific access rights to meet the needs of businesses with complex structures.
Expand Down Expand Up @@ -84,7 +86,7 @@ We will place this check before every route, controller or API as follows:

```php
use Shopware\Commercial\B2B\QuickOrder\Domain\CustomerSpecificFeature\CustomerSpecificFeatureService;

class ApiController
{
public function __construct(private readonly CustomerSpecificFeatureService $customerSpecificFeatureService)
Expand Down Expand Up @@ -131,11 +133,11 @@ class CustomerSpecificFeatureTwigExtension extends AbstractExtension
if (\array_key_exists('context', $twigContext) && $twigContext['context'] instanceof SalesChannelContext) {
$customerId = $twigContext['context']->getCustomerId();
}

if (!$customerId) {
return false;
}

return $this->customerSpecificFeatureService->isAllowed($customerId, $feature);
}
}
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,200 @@
---
nav:
title: Entities and workflow
position: 10

---

# Entities and workflow

## Entities

### Individual Pricing

The Individual Pricing entity is the main configuration entity that defines a pricing rule. It contains all the settings needed to determine which products get special pricing, who receives it, and how the pricing is calculated.

**Key properties:**

- **name**: Human-readable name for the pricing rule
- **description**: Optional description of the pricing rule
- **active**: Boolean flag to enable/disable the rule
- **priority**: Integer value determining evaluation order (higher values = higher priority)
- **target**: Type of audience (companies, tags)
- **actionType**: Type of price modification (by_percent, by_fixed, to_fixed, volume_pricing)
- **actionAmount**: Amount for the pricing action (percentage or fixed value)
- **applyToAllProducts**: If true, applies to all products in the catalog
- **productStreamId**: Reference to a Shopware product stream for filtering specific products
- **useValidityRange**: Boolean indicating if time-based validity is used
- **validFrom**: Start date/time for the pricing rule
- **validUntil**: End date/time for the pricing rule
- **showStrikeThrough**: Whether to show original price with strike-through

**Action Types:**

- `by_percent`: Reduce price by a percentage (e.g., 10% off)
- `by_fixed`: Reduce price by a fixed amount (e.g., 5$ off)
- `to_fixed`: Set price to a specific amount (e.g., 99.99$)
- `volume_pricing`: Use tiered pricing based on quantity

### Individual Pricing Tier

The tier entity defines volume-based pricing tiers for quantity discounts. Multiple tiers can be associated with a single Individual Pricing rule when the action type is set to `volume_pricing`.

**Key properties:**

- **individualPricingId**: Reference to the parent pricing rule
- **qtyFrom**: Minimum quantity for this tier (inclusive)
- **qtyTo**: Maximum quantity for this tier (inclusive, null for unlimited)
- **price**: Price collection containing prices for different currencies

**Example tiers:**

- Tier 1: 1-9 units @ 10$ each

Check warning on line 52 in products/extensions/b2b-components/individual-pricing/concepts/01-entities-and-workflow.md

View workflow job for this annotation

GitHub Actions / LanguageTool

[LanguageTool] products/extensions/b2b-components/individual-pricing/concepts/01-entities-and-workflow.md#L52

If specifying a range, consider using an en dash instead of a hyphen. (HYPHEN_TO_EN[1]) Suggestions: `1–9` URL: https://languagetool.org/insights/post/dashes/#how-to-properly-use-an-en-dash Rule: https://community.languagetool.org/rule/show/HYPHEN_TO_EN?lang=en-US&subId=1 Category: PUNCTUATION
Raw output
products/extensions/b2b-components/individual-pricing/concepts/01-entities-and-workflow.md:52:10: If specifying a range, consider using an en dash instead of a hyphen. (HYPHEN_TO_EN[1])
 Suggestions: `1–9`
 URL: https://languagetool.org/insights/post/dashes/#how-to-properly-use-an-en-dash 
 Rule: https://community.languagetool.org/rule/show/HYPHEN_TO_EN?lang=en-US&subId=1
 Category: PUNCTUATION
- Tier 2: 10-49 units @ 9$ each

Check warning on line 53 in products/extensions/b2b-components/individual-pricing/concepts/01-entities-and-workflow.md

View workflow job for this annotation

GitHub Actions / LanguageTool

[LanguageTool] products/extensions/b2b-components/individual-pricing/concepts/01-entities-and-workflow.md#L53

If specifying a range, consider using an en dash instead of a hyphen. (HYPHEN_TO_EN[1]) Suggestions: `10–49` URL: https://languagetool.org/insights/post/dashes/#how-to-properly-use-an-en-dash Rule: https://community.languagetool.org/rule/show/HYPHEN_TO_EN?lang=en-US&subId=1 Category: PUNCTUATION
Raw output
products/extensions/b2b-components/individual-pricing/concepts/01-entities-and-workflow.md:53:10: If specifying a range, consider using an en dash instead of a hyphen. (HYPHEN_TO_EN[1])
 Suggestions: `10–49`
 URL: https://languagetool.org/insights/post/dashes/#how-to-properly-use-an-en-dash 
 Rule: https://community.languagetool.org/rule/show/HYPHEN_TO_EN?lang=en-US&subId=1
 Category: PUNCTUATION
- Tier 3: 50+ units @ 8$ each
Comment on lines +34 to +54
Copy link

Copilot AI Feb 25, 2026

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The examples use currency formatting like 5$, 99.99$, and 10$ each, which is atypical and can be misread. Consider switching to $5, $99.99, $10 (or using a currency-agnostic example) for clarity and consistency throughout the docs.

Copilot uses AI. Check for mistakes.

### Individual Pricing Company Assignment

This entity links pricing rules to specific business partner companies or organization units. It determines which companies or parts of companies receive the special pricing.

**Key properties:**

- **individualPricingId**: Reference to the pricing rule
- **customerId**: Reference to the business partner customer
- **scope**: Defines assignment scope (whole_company, all_org_units, specific_units)
- **organizationUnitIds**: JSON array of specific organization unit IDs (when scope is specific_units)

**Scopes:**

- `whole_company`: Applies to all employees of the business partner
- `all_org_units`: Applies to all organization units within the company
- `specific_units`: Applies only to specific organization units (requires organizationUnitIds)

### Individual Pricing Computed Cache

The computed cache entity pre-calculates which products are affected by which pricing rules. This significantly improves performance by avoiding repeated filter evaluations.

**Key properties:**

- **individualPricingId**: Reference to the pricing rule
- **productId**: Reference to the affected product (NULL if rule applies to all products)

This cache uses a hybrid approach: specific cache entries for targeted rules, and NULL entries for catalog-wide rules.

## Schema

```mermaid
erDiagram
b2b_components_individual_pricing {
uuid id PK

Check warning on line 89 in products/extensions/b2b-components/individual-pricing/concepts/01-entities-and-workflow.md

View workflow job for this annotation

GitHub Actions / LanguageTool

[LanguageTool] products/extensions/b2b-components/individual-pricing/concepts/01-entities-and-workflow.md#L89

This abbreviation for “identification” is spelled all-uppercase. (ID_CASING[2]) Suggestions: `ID` Rule: https://community.languagetool.org/rule/show/ID_CASING?lang=en-US&subId=2 Category: CASING
Raw output
products/extensions/b2b-components/individual-pricing/concepts/01-entities-and-workflow.md:89:13: This abbreviation for “identification” is spelled all-uppercase. (ID_CASING[2])
 Suggestions: `ID`
 Rule: https://community.languagetool.org/rule/show/ID_CASING?lang=en-US&subId=2
 Category: CASING
boolean active
boolean show_strike_through
string name
string target
int priority
boolean apply_to_all_products
uuid product_stream_id FK
boolean use_validity_range
datetime valid_from
datetime valid_until
string description
string action_type
float action_amount
uuid created_by_id FK
uuid updated_by_id FK
json custom_fields
}
b2b_components_individual_pricing_tier {
uuid id PK

Check warning on line 108 in products/extensions/b2b-components/individual-pricing/concepts/01-entities-and-workflow.md

View workflow job for this annotation

GitHub Actions / LanguageTool

[LanguageTool] products/extensions/b2b-components/individual-pricing/concepts/01-entities-and-workflow.md#L108

This abbreviation for “identification” is spelled all-uppercase. (ID_CASING[2]) Suggestions: `ID` Rule: https://community.languagetool.org/rule/show/ID_CASING?lang=en-US&subId=2 Category: CASING
Raw output
products/extensions/b2b-components/individual-pricing/concepts/01-entities-and-workflow.md:108:13: This abbreviation for “identification” is spelled all-uppercase. (ID_CASING[2])
 Suggestions: `ID`
 Rule: https://community.languagetool.org/rule/show/ID_CASING?lang=en-US&subId=2
 Category: CASING
uuid individual_pricing_id FK
int qty_from
int qty_to
json price
}
b2b_components_individual_pricing_company_assignment {
uuid id PK

Check warning on line 115 in products/extensions/b2b-components/individual-pricing/concepts/01-entities-and-workflow.md

View workflow job for this annotation

GitHub Actions / LanguageTool

[LanguageTool] products/extensions/b2b-components/individual-pricing/concepts/01-entities-and-workflow.md#L115

This abbreviation for “identification” is spelled all-uppercase. (ID_CASING[2]) Suggestions: `ID` Rule: https://community.languagetool.org/rule/show/ID_CASING?lang=en-US&subId=2 Category: CASING
Raw output
products/extensions/b2b-components/individual-pricing/concepts/01-entities-and-workflow.md:115:13: This abbreviation for “identification” is spelled all-uppercase. (ID_CASING[2])
 Suggestions: `ID`
 Rule: https://community.languagetool.org/rule/show/ID_CASING?lang=en-US&subId=2
 Category: CASING
uuid individual_pricing_id FK
uuid customer_id FK
string scope
json organization_unit_ids
}
b2b_components_individual_pricing_computed_cache {
uuid id PK

Check warning on line 122 in products/extensions/b2b-components/individual-pricing/concepts/01-entities-and-workflow.md

View workflow job for this annotation

GitHub Actions / LanguageTool

[LanguageTool] products/extensions/b2b-components/individual-pricing/concepts/01-entities-and-workflow.md#L122

This abbreviation for “identification” is spelled all-uppercase. (ID_CASING[2]) Suggestions: `ID` Rule: https://community.languagetool.org/rule/show/ID_CASING?lang=en-US&subId=2 Category: CASING
Raw output
products/extensions/b2b-components/individual-pricing/concepts/01-entities-and-workflow.md:122:13: This abbreviation for “identification” is spelled all-uppercase. (ID_CASING[2])
 Suggestions: `ID`
 Rule: https://community.languagetool.org/rule/show/ID_CASING?lang=en-US&subId=2
 Category: CASING
uuid individual_pricing_id FK
uuid product_id FK
}
b2b_components_individual_pricing_tag {
uuid individual_pricing_id FK
uuid tag_id FK
}
product_stream {
uuid id PK

Check warning on line 131 in products/extensions/b2b-components/individual-pricing/concepts/01-entities-and-workflow.md

View workflow job for this annotation

GitHub Actions / LanguageTool

[LanguageTool] products/extensions/b2b-components/individual-pricing/concepts/01-entities-and-workflow.md#L131

This abbreviation for “identification” is spelled all-uppercase. (ID_CASING[2]) Suggestions: `ID` Rule: https://community.languagetool.org/rule/show/ID_CASING?lang=en-US&subId=2 Category: CASING
Raw output
products/extensions/b2b-components/individual-pricing/concepts/01-entities-and-workflow.md:131:13: This abbreviation for “identification” is spelled all-uppercase. (ID_CASING[2])
 Suggestions: `ID`
 Rule: https://community.languagetool.org/rule/show/ID_CASING?lang=en-US&subId=2
 Category: CASING
string name
}

b2b_components_individual_pricing ||--o{ b2b_components_individual_pricing_tier : "has volume tiers"
b2b_components_individual_pricing ||--o{ b2b_components_individual_pricing_company_assignment : "assigned to companies"
b2b_components_individual_pricing ||--o{ b2b_components_individual_pricing_computed_cache : "cached for products"
b2b_components_individual_pricing ||--o{ b2b_components_individual_pricing_tag : "targets tags"
b2b_components_individual_pricing }o--|| product_stream : "uses"
b2b_components_individual_pricing_company_assignment }o--|| customer : "belongs to"
b2b_components_individual_pricing_computed_cache }o--|| product : "references"
b2b_components_individual_pricing_tag }o--|| tag : "references"
```

## Workflow

The following diagram shows how individual pricing is applied to a product:

```mermaid
flowchart TD
A[Customer views product] --> B{Is logged-in?}
B -->|No| C[Show standard catalog price]
B -->|Yes| D[Load customer context]
D --> E[Query active pricing rules]
E --> F{Any rules found?}
F -->|No| C
F -->|Yes| G[Get all rules at highest priority]
G --> H[Evaluate all rules at this priority]
H --> I{Any rules match product streams?}
I -->|No| C
I -->|Yes| J{Multiple rules match?}
J -->|No| K[Use single matching rule]
J -->|Yes| L[Calculate price for each rule]
L --> M[Select rule with lowest price]

Check warning on line 164 in products/extensions/b2b-components/individual-pricing/concepts/01-entities-and-workflow.md

View workflow job for this annotation

GitHub Actions / LanguageTool

[LanguageTool] products/extensions/b2b-components/individual-pricing/concepts/01-entities-and-workflow.md#L164

A determiner may be missing. (THE_SUPERLATIVE[2]) Suggestions: `the lowest` URL: https://languagetool.org/insights/post/grammar-comparatives-superlatives/#superlative-forms-of-adjectives Rule: https://community.languagetool.org/rule/show/THE_SUPERLATIVE?lang=en-US&subId=2 Category: GRAMMAR
Raw output
products/extensions/b2b-components/individual-pricing/concepts/01-entities-and-workflow.md:164:29: A determiner may be missing. (THE_SUPERLATIVE[2])
 Suggestions: `the lowest`
 URL: https://languagetool.org/insights/post/grammar-comparatives-superlatives/#superlative-forms-of-adjectives 
 Rule: https://community.languagetool.org/rule/show/THE_SUPERLATIVE?lang=en-US&subId=2
 Category: GRAMMAR
K --> N{Volume pricing?}
M --> N

Check warning on line 166 in products/extensions/b2b-components/individual-pricing/concepts/01-entities-and-workflow.md

View workflow job for this annotation

GitHub Actions / LanguageTool

[LanguageTool] products/extensions/b2b-components/individual-pricing/concepts/01-entities-and-workflow.md#L166

Possible typo: you repeated a word (ENGLISH_WORD_REPEAT_RULE) Suggestions: `N` Rule: https://community.languagetool.org/rule/show/ENGLISH_WORD_REPEAT_RULE?lang=en-US Category: MISC
Raw output
products/extensions/b2b-components/individual-pricing/concepts/01-entities-and-workflow.md:166:10: Possible typo: you repeated a word (ENGLISH_WORD_REPEAT_RULE)
 Suggestions: `N`
 Rule: https://community.languagetool.org/rule/show/ENGLISH_WORD_REPEAT_RULE?lang=en-US
 Category: MISC
N -->|Yes| O[Select appropriate tier]
N -->|No| P[Apply action type]
O --> Q[Calculate final price]
P --> Q

Check warning on line 170 in products/extensions/b2b-components/individual-pricing/concepts/01-entities-and-workflow.md

View workflow job for this annotation

GitHub Actions / LanguageTool

[LanguageTool] products/extensions/b2b-components/individual-pricing/concepts/01-entities-and-workflow.md#L170

Possible typo: you repeated a word (ENGLISH_WORD_REPEAT_RULE) Suggestions: `Q` Rule: https://community.languagetool.org/rule/show/ENGLISH_WORD_REPEAT_RULE?lang=en-US Category: MISC
Raw output
products/extensions/b2b-components/individual-pricing/concepts/01-entities-and-workflow.md:170:10: Possible typo: you repeated a word (ENGLISH_WORD_REPEAT_RULE)
 Suggestions: `Q`
 Rule: https://community.languagetool.org/rule/show/ENGLISH_WORD_REPEAT_RULE?lang=en-US
 Category: MISC
Q --> R{Show strike-through?}
R -->|Yes| S[Display with original price]
R -->|No| T[Display discounted price]
```

## Target type evaluation

Depending on the target type, different evaluation logic applies:

### Companies target

- Customer must be a business partner or employee
- Company assignment must exist linking the pricing rule to the customer's company
- Scope is checked (whole company, all units, or specific units)
- If specific units, customer must belong to one of the specified organization units

### Tags target

- Customer must have at least one of the tags specified in the pricing rule

## Priority and rule selection

When multiple pricing rules could apply to the same product:

1. Only rules at the highest priority level are considered
2. All rules at this priority level are evaluated
3. If multiple rules match, the one resulting in the lowest price is selected
4. If no rules match at the highest priority, standard catalog pricing is used

**Note:** Lower priority rules are never evaluated. This ensures the most important pricing takes precedence, and when multiple rules compete at the same level, customers always get the best price.
Loading