Orders
This section describes how the module maps orders to Shopware and what configuration options are available. It is possible to map orders to Shopware, but there are still some limitations. This section gives you an overview of what you can and cannot expect from mapping orders to Shopware.
Subsections
root
└───order
└───order-validate
└───order-upsert
└───order-build-cache
└───order-build-cache-order
└───order-build-cache-order-state
In difference to other mapping-subsections there are two -build-cache
subsections:
-
order-build-cache-order
is the "default" caching subsection that searches corresponding Shopware entities for documents -
order-build-cache-order-state
reads all state entities from Shopware that an order, order delivery or order transaction can have
Configuration
{
"order": {
"enabled": true,
"states": {}
}
}
The states
key allows you to define a custom mapping of state-names used in your data and state-names of Shopware. See "State
Handling" for details.
Limitations
Of all the types of documents transferred, orders are by far the most complex. This is caused by the interaction of several Shopware entities, synQup documents and incompatibilities between the synQup model and Shopware model. The following is an overview of the limitations that currently exist:
-
Orders
with multipleOrderSegments
are not supported (limitation by Shopware) -
Orders
with multiple deliveries (DeliveryPackage
) are not supported (limitation by Shopware) - Line items of type
PaymentSurchargeOrderItems
andVoucherOrderItems
are not supported (voucher handling is not yet possible) - The import of nested order line items is not supported yet
- Some entities are deleted and recreated on every import/update. This could affect external 3rd party plugins because data could get
lost (e.g. CustomFields and payloads filled by plugins):
- Order line items (table
order_line_item
) - Order deliveries (table
order_delivery
) and their positions (order_delivery_position
) - Order transactions / payments (table
order_transaction
)
- Order line items (table
- The status of deliveries and payments will be updated due to the deletion and recreation but there is no state history available
Work is in progress on many of these limitations (especially the deletion and recreation of entities on updates). But it is too early to give a release date for this.
State Handling
Quick Reference
- Order states are updated via action api
- This is not possible for
State Handling in Shopware
You need a basic understanding of how Shopware handles the states of orders, order-deliveries and order-transactions in order to configure how the output-module maps states from synQup to Shopware. However, this documentation is not intended to provide an in-depth explanation of the order state management in Shopware. You can find a lot of useful information on these pages of the documentation of Shopware:
Summary:
- Shopware uses
StateMachineEntities
that define all allowed states that an order, order delivery or order payment is allowed to have. - It is not possible to set those states on updates directly (for example, the field
OrderEntity::stateId
is write-protected on updates). You are forced to use the action API of Shopware. - In order to update states in Shopware you need to know the UUIDs of each Shopware state.
- Shopware only allows transitions between certain states. For example, you cannot update an order to "finished" while it is "open" - you have to set it to "in progress" before you can set it to "finished".
- You can find all allowed state transitions by the help of the
StateMachine
. There is oneStateMachine
available for orders, order-transactions and order-deliveries each.
State Handling in the Output-Module
The module is able to convert synQup states (= states from your transfer data) to the corresponding Shopware states. This is done by
the help of the states
key in the order configuration (see "Custom State Mapping" / next section).
By using state graphs the module is able to derive a valid set of action-requests that will eventually update the state of an order, order-transaction or order-delivery. Due to the aforementioned limitation of deleting and recreating deliveries and transactions on every update the action api is used for order states only (for now). So please be aware that there is no state history available right now in the frontend/backend if you import orders with this module.
The action api is used for order states only. There is no state history available for transactions and deliveries.
Depending on the amount of state updates this can slow down your import since those requests have to be sent individually.
Custom State Mapping
In most cases, the names of the states in Shopware do not match the states of your data source and vice versa. That's why the states
key in the configuration makes it possible to support different state names between your source data and Shopware. The configuration
follows this pattern:
{
"states": {
"{state_machine_key}": {
"{shopware_state_0}": null,
"{shopware_state_1}": "synqup_state_1",
"{shopware_state_2}": [
"synqup_state_2",
"synqup_state_3"
]
}
}
}
You can define zero to n source states that will be mapped to a dedicated Shopware state. You can find examples and a template below.
As soon as you define a single key in the states
configuration the default state mapping is turned off completely.
The following configuration is a template that contains all possible state keys that are available in Shopware by default:
{
"subsections": {
"order": {
"states": {
"order.state": {
"open": null,
"in_progress": null,
"completed": null,
"cancelled": null
},
"order_delivery.state": {
"open": null,
"shipped": null,
"shipped_partially": null,
"returned": null,
"returned_partially": null,
"cancelled": null,
"failed": null
},
"order_transaction.state": {
"open": null,
"paid": null,
"failed": null,
"in_progress": null,
"chargeback": null,
"cancelled": null,
"refunded": null,
"paid_partially": null,
"unconfirmed": null,
"refunded_partially": null,
"reminded": null,
"authorized": null
}
}
}
}
}
Default State Mapping
There is a default state mapping available (in case you do not provide a states
configuration). But it is highly recommended to
adjust the state mapping to your needs.
The default state mapping was implemented a long time ago based on the following state definition classes in the data model:
-
Elio\CommerceBundle\Definition\Order\OrderState
-
Elio\CommerceBundle\Definition\Order\DeliveryStates
-
Elio\CommerceBundle\Definition\Order\PaymentStates
Several states (especially of deliveries and payments) are not compatible between Shopware and synQup. So the default state mapping is outdated - the only reason it exists is backwards compatibility for all projects that do not use a custom state mapping yet.
Order States
Order states are updated with transition requests. You can set the state map with the following configuration:
{
"states": {
"order.state": {
"open": null,
"in_progress": null,
"completed": null,
"cancelled": null
}
}
}
The following states are mapped from synQup to Shopware by default (you should avoid using the default pattern):
Synqup State | Shopware State |
---|---|
OrderState::OPEN | OrderStates::STATE_OPEN |
OrderState::IN_PROGRESS | OrderStates::STATE_IN_PROGRESS |
OrderState::FINISHED | OrderStates::STATE_COMPLETED |
OrderState::FAILED | OrderStates::STATE_CANCELLED |
Order Delivery States
Order delivery states are not updated via action api. Order deliveries are deleted and recreated on every import which causes the state to "update", but it will not generate a state history.
You can set the state map with the following configuration:
{
"states": {
"order_delivery.state": {
"open": null,
"shipped": null,
"shipped_partially": null,
"returned": null,
"returned_partially": null,
"cancelled": null,
"failed": null
}
}
}
The following states are mapped from synQup to Shopware by default (you should avoid using the default pattern):
Synqup State | Shopware State |
---|---|
DeliveryStates::REGISTERED | OrderDeliveryStates::STATE_OPEN |
DeliveryStates::IN_DELIVERY | OrderDeliveryStates::STATE_SHIPPED |
DeliveryStates::DELIVERED | OrderDeliveryStates::STATE_SHIPPED |
DeliveryStates::CUSTOMS | OrderDeliveryStates::STATE_SHIPPED |
DeliveryStates::INTERVENTION | OrderDeliveryStates::STATE_SHIPPED |
DeliveryStates::EXCEPTION | OrderDeliveryStates::STATE_SHIPPED |
DeliveryStates::UNKNOWN | OrderDeliveryStates::STATE_SHIPPED |
Order Transaction States
Order transaction states are not updated via action api. Order transactions are deleted and recreated on every import which causes the state to "update", but it will not generate a state history.
You can set the state map with the following configuration:
{
"states": {
"order_transaction.state": {
"open": null,
"paid": null,
"failed": null,
"in_progress": null,
"chargeback": null,
"cancelled": null,
"refunded": null,
"paid_partially": null,
"unconfirmed": null,
"refunded_partially": null,
"reminded": null,
"authorized": null
}
}
}
The following states are mapped from synQup to Shopware by default (you should avoid using the default pattern):
Synqup State | Shopware State |
---|---|
PaymentStates::OPEN | OrderTransactionStates::STATE_OPEN |
PaymentStates::RESERVED | OrderTransactionStates::STATE_OPEN |
PaymentStates::PAID | OrderTransactionStates::STATE_PAID |
PaymentStates::FAILED | OrderTransactionStates::STATE_FAILED |
Mapping Orders
Order Mapping Table
Target: order
Source: Elio\CommerceBundle\Document\Order\Order
Target Field | Source Path |
---|---|
* orderNumber |
identifier |
* currencyId |
orderInformation.currency |
* currencyFactor |
orderInformation.currency.currencyFactor.factor |
* salesChannelId |
channels.[0] |
* orderDateTime |
orderDate |
* price |
orderInformation.totalAmountNet & orderInformation.totalAmountGross & orderInformation.taxStatus |
shippingCosts | orderSegments.[0].items.{{Elio\CommerceBundle\Document\Order\Items\ShippingCostsOrderItem}}.[0] |
* orderCustomer |
orderCustomer |
* languageId |
orderInformation.locale |
* addresses |
orderSegments.[0].shippingAddress & billingAddress |
* lineItems |
orderSegments.[0].items.{{!Elio\CommerceBundle\Document\Order\Items\ShippingCostsOrderItem}} |
deliveries | orderSegments.[0].deliveryPackages.[0] |
* transactions |
payments |
stateId | orderInformation.orderStatus.status |
* itemRounding |
automatically |
* totalRounding |
automatically |
Mapping Line Items
Mapping Table
Target: order_line_item
Embedded in: Synqup\Modules\Shopware6Bundle\Core\Shopware\Checkout\Order\OrderEntity
Source: Elio\CommerceBundle\Document\Order\Items\AbstractOrderItem
Target Field | Source Path |
---|---|
* orderId |
automatically |
* identifier |
identifier |
* referencedId |
Depends on the order line item type. Uuid of the product for product order items. |
productId | product.identifier, but only for Elio\CommerceBundle\Document\Order\Items\ProductOrderItem |
* quantity |
quantity |
* label |
label |
* position |
position |
* price |
netPrice, quantity, taxes |
payload | Automatically, depends on the item type. |
* type |
Depends on the item type. |
Line Item Types
There are four different types of order items in Shopware (field OrderLineItemEntity::type
) and several order items
available in synQup. Not all types of order items are mappable. The following table lists all supported order line items.
Shopware Type | Order Item Class | Comment |
---|---|---|
credit | DiscountOrderItem |
|
product | ProductOrderItem |
|
custom | GenericOrderItem |
|
promotion | - | not supported |
- | GenericVoucherOrderItem | not supported |
- | VoucherOrderItem | not supported |
- | PaymentSurchargeOrderItem | not supported |
- | ShippingCostsOrderItem | not mapped as order item |
Nested Line Items
Nested line items (AbstractOrderItem::childItems
) are not supported yet.
Limitations
As already mentioned line items are deleted and recreated on every update. This can be problematic if Shopware plugins add data to order line items, e.g. to the fields "payload" and "customFields". You must be aware that those fields are overwritten on every update.
The main reasons for this issue are:
- Missing compatibility between the input and output module: new items in the shop (of new orders) do not have synqup-identifiers and the input module is not able to update those on imports. On updates the output module is not able to identify those items. The only possibility to ensure updating all items is deleting and recreating.
- It is not guaranteed that
AbstractOrderItems
have unique identifiers so duplicate identifiers between orders can happen
Mapping Order Deliveries
The document OrderSegment
contains a collection of DeliveryPackages
.
The document DeliveryPackage
is mapped to the Shopware entity OrderDeliveryEntity
.
A DeliveryPackage
contains a collection of DeliveryPositions
.
Mapping Table
Target: order_delivery
Embedded in: Synqup\Modules\Shopware6Bundle\Core\Shopware\Checkout\Order\OrderEntity
Source: Elio\CommerceBundle\Document\Order\Delivery\DeliveryPackage
Target Field | Source Path |
---|---|
orderId | automatically |
* shippingOrderAddressId |
orderSegments.[0].shippingAddress |
* shippingMethodId |
%PARENT%.orderSegments.[0].dispatch.identifier |
trackingCodes | trackingCode |
* shippingDateEarliest |
deliveryDate |
* shippingDateLatest |
deliveryDate |
* shippingCosts |
orderSegments.[0].items.{{Elio\CommerceBundle\Document\Order\Items\ShippingCostsOrderItem}}.[0] |
* stateId |
%PARENT%.orderSegments.[0].deliveryPackages.[0].deliveryTransactions.[n].deliveryStatus.status |
* positions |
items |
Limitations
Partial Deliveries
Orders with multiple deliveries (= Order
that contains more than one DeliveryPackage
) are not supported and will not be mapped.
State Handling
As mentioned above order_deliveries
are deleted and recreated on every update. This prevents the module from using the action api to
update order delivery states, so no state history will be generated.
The main reasons for these limitations are:
- It is not guaranteed that
DeliveryPackages
have unique identifiers so duplicate identifiers between orders can happen -
DeliveryPositions
are not identifiable at all - Missing compatibility between the input and output module (see "Mapping Line Items", it is the same principle as with line items)
Mapping Order Transactions / Payments
Mapping Table
Target: order_transaction
Embedded in: Synqup\Modules\Shopware6Bundle\Core\Shopware\Checkout\Order\OrderEntity
Source: Elio\CommerceBundle\Document\Order\OrderPayment
Target Field | Source Path |
---|---|
* orderId |
automatically |
* paymentMethodId |
payment |
* amount |
%ROOT%.orderInformation.totalAmountNet & %ROOT%.orderInformation.totalAmountGross |
* stateId |
paymentStatus.status |
State Handling
State handling is not performed via action api yet. Order transactions are deleted and recreated on every import which causes the
state to "update", but there is a limitation with this approach. There is no oder delivery state history, because the deletion and
recreation does not create entries in state_machine_history
. So you can access the latest state only via backend/frontend.
Mapping Order Addresses
Target: order_address
Embedded in: Synqup\Modules\Shopware6Bundle\Core\Shopware\Checkout\Order\OrderEntity
Source: Elio\CommerceBundle\Document\Customer\Addresses\AbstractAddress
Target Field | Source Path |
---|---|
* countryId |
country |
* salutationId |
contact.personalInformation.salutation.salutation |
* firstName |
contact.personalInformation.firstName |
* lastName |
contact.personalInformation.lastName |
street | street |
* zipcode |
zipcode |
* city |
city |
company | contact.companyInformation.name |
department | contact.companyInformation.department |
title | contact.personalInformation.title |
vatId | contact.companyInformation.vatID |
phoneNumber | contact.personalInformation.phone |
* orderId |
automatically determined from its parent |
Mapping Order Customers
Target: order_customer
Embedded in: Synqup\Modules\Shopware6Bundle\Core\Shopware\Checkout\Order\OrderEntity
Source: Elio\CommerceBundle\Document\Order\OrderCustomer
Target Field | Source Path |
---|---|
* email |
customer.customerInformation.email |
* orderId |
automatically determined from its parent |
* salutationId |
customer.customerInformation.personalInformation.salutation.salutation |
* firstName |
customer.customerInformation.personalInformation.firstName |
* lastName |
customer.customerInformation.personalInformation.lastName |
title | customer.customerInformation.personalInformation.title |
vatIds | customer.customerInformation.companyInformation.vatID |
company | customer.customerInformation.companyInformation.name |
customerNumber | customer.identifier |
* customerId |
customer |