Checklist before updating eComlogic from 5.0 to 6.0

Triggers

In triggers, by analogy with templates, it is not necessary to check that the variable is not equal to null. The code order.getStatus().getCode() no longer generates an exception if order.getStatus() or order are equal to null, and returns null.

That is why you should pay attention to the code of triggers, where the reverse-check takes place (for example, not in, != and etc.). Perhaps, they will need to be changed so that to take new behaviour into account.

For example, if previously, expression order.getPaymentStatus().getCode() not in ['paid', 'not-paid'] generated an exception when payment status was not specified in order and trigger was not executed, then, in new logic, the left-hand side of the expression returns null, which will successfully pass the specified test.

Before updating to 6.0, find out triggers in Action Log, which lead to an error and correct them accordingly.

Multiple payments

А possibility of adding multiple payments within one and the same order has been added to 6.0 version. It leads to changes in data model because now the order has not a payment but a collection of payments with all that it implies.

Previous direct methods of access to payment data order.getPaymentType(), order.getPaymentStatus(), order.getPaymentDetail() are kept for compatibility but work only in case of one payment in the order.

Now there is the collection of payments order.getPayments(), as well as order.fullPayedAt field and order.getFullPayedAt() method, which return complete payment date of the order.

Operating peculiarities

For maintaining compatibility, methods of objects, available in templates and triggers, as well as the methods of API v4 and lower, work according to the logic of "working payment":

Thus, in case of working with prepayment and old versions of API, manager should add it directly in the paid status.

Triggers

1. [Can be corrected before updating] In triggers, condition of complete payment for the order needs to be checked by means of order.fullPaidAt and react to the change of full_paid_at.

I.e. expressions, triggered on the fact of complete payment of the order

changeSet.hasChangedField("payment_status") and changeSet.getNewValue("payment_status").getCode() == "paid"

should be replaced by expressions

changeSet.hasChangedField("full_paid_at") and changeSet.getNewValue("full_paid_at")

And verification expressions that the order is paid

order.getPaymentStatus() && order.getPaymentStatus().getCode() == 'paid'

should be replaced by expressions

order.fullPaidAt

2. [Should be corrected AFTER updating] Verification of payment data in the order needs to be corrected taking into account that payments are a collection now

Expressions

order.getPaymentType() and
order.getPaymentType().getCode() in [ "cash", "bank-card-courier", "bank-card-office", "axiomus", "posthub" ]

should be replaced by expressions:

a) if at least one payment in the order is of the specified type:

order.payments | contains( item => item.type.code in [ "cash", "bank-card-courier", "bank-card-office", "axiomus", "posthub" ] )

b) if all payments of the order are of the specified type:

order.payments | every( item => item.type.code in [ "cash", "bank-card-courier", "bank-card-office", "axiomus", "posthub" ] )

API

In old versions of API we tried to maintain the maximum compatibility which is executed till you begin to add the second or more payments to the order. As soon as you decide to work with multiple payments in eComlogic, you will need to turn to API v5 in advance.

1. Collection of payments order[payments][] returns to /api/v5/orders and /api/v5/orders/get.

2. New API method /api/v5/orders/payments/create has appeared for adding payment to the order, /api/v5/orders/payments/{id}/edit is for editing and /api/v5/orders/payments/{id}/delete is for deleting.

3. In API v4 and lower versions, data structure has not been changed, but data on order payment returns only if the order contains one payment or several payments and where only one is not paid, otherwise empty fields will appear. Payment editing is also possible but only in case of none or one payment in the order.

4. Changes of a field order.prepaySum do not return in order history /api/v*/orders/history, since now it is only the adder of paid payments sums.

Discounts and rounding

Changes in work with discounts

Since 6.0 version, work with discounts is built in another way. The key change is that discount for the order is included now not in the orders total sum but is distributed between goods and included in the sum of each separate item of a good in the order. At the same time, the distributed discount for the order doesn't touch discounts for goods, which can be specified separately as previously.

Look at the example. Let us assume we have the following order:

|  Name        |  Price   |  Discount           | Quantity |   Total    |
|              |          |                     |          |            |
|  Shorts      |  60 EUR  |  5 EUR (for a good) |      2   |  110 EUR   |
|              |          |                     |          |            |
|  Flip-flops  |  30 EUR  |  0 EUR (for a good) |      3   |  90  EUR   |
|                                                          |            |
|  Total                                                   |  200 EUR   |

We gave the discount for the order of 30 euros.

In system version of 5.0 and lower, this discount will be included in the order total sum:

|  Name        |  Price    |  Discount             |  Quantity  |   Total   |
|              |                                   |            |           |
|  Shorts      |  60 EUR   |  5 EUR (for a good)   |      2     |  110 EUR  |
|              |           |                       |            |           |
|  Flip-flops  |  30 EUR   |  0 EUR (for a good)   |      3     |  90  EUR  |
|                                                  |            |           |
|  Discount for the order                                       |  30  EUR  |
|                                                               |           |
|  Total                                                        |  170 EUR  |

In 6.0 version and higher the discount for the order will be distributed between goods and included in their cost:

|  Name       |    Price  |  Discount               | Quantity |  Total  |
|             |           |                         |          |         |
|  Shorts     |  60  EUR  |  5 EUR  (for a good)    |     2    | 98 EUR  |
|             |           |  6 EUR  (for an order)  |          |         |
|             |           |                         |          |         |
|  Flip-flops |  30  EUR  |  0 EUR  (for a good)    |     3    | 72 EUR  |
|             |           |  6 EUR  (for an order)  |          |         |
|                                                              |         |
|  Total                                                       | 170 EUR |

In this case, order cost is calculated in the following way: (60 – 5 – 6) x 2 + (30 – 6) x 3 = 170

API

Discount fields in API v4 order[discount], order[discountPercent], order[items][][discount], order[items][][discountPercent] remain unchanged in the order and are available both for POST method and GET method.

On the order`s example above, values should be transferred in the following form when creating the order:

order = {
    // ...
    "discount": 300,
    "items": [
        {
            "offer": { "externalId": "1" },
            "initialPrice": 600,
            "discount": 50,
            "quantity": 2
        },
        {
            "offer": { "externalId": "2" },
            "initialPrice": 300,
            "quantity": 3
        }
    ],
    // ...
}

In API methods for getting orders, fields content and values will be similar:

{
    // ...
    "discount": 300,
    "items": [
        {
            "offer": { "externalId": "1" },
            "initialPrice": 600,
            "discount": 50,
            "quantity": 2
        },
        {
            "offer": { "externalId": "2" },
            "initialPrice": 300,
            "quantity": 3
        }
    ],
    // ...
}

API v5

It is possible to transfer discounts for the order and goods in fields order[discountManualAmount], order[discountManualPercent], order[items][][discountManualAmount], order[items][][discountManualPercent] in methods of order creation and editing /api/v5/orders/create, /api/v5/orders/{externalId}/edit, /api/v5/orders/upload. Discounts for the order will be distributed among goods.

On the order`s example above, values should be transferred in the following form when creating the order:

order = {
    // ...
    "discountManualAmount": 300,
    "items": [
        {
            "offer": { "externalId": "1" },
            "initialPrice": 600,
            "discountManualAmount": 50,
            "quantity": 2
        },
        {
            "offer": { "externalId": "2" },
            "initialPrice": 300,
            "quantity": 3
        }
    ],
    // ...
}

Total monetary discount for a product unit for each order item in the field order[items][][discountTotal] has been returned in methods for getting orders /api/v5/orders, /api/v5/orders/{externalId}. It also includes discounts for a current good and discounts for an order, distributed between goods.

{
    // ...
    "items": [
        {
            "offer": { "externalId": "1" },
            "initialPrice": 600,
            "discountTotal": 110,
            "quantity": 2
        },
        {
            "offer": { "externalId": "2" },
            "initialPrice": 300,
            "discountTotal": 60,
            "quantity": 3
        }
    ],
    // ...
}

Triggers and templates

In OrderProduct object, fields OrderProduct.discount and OrderProduct. discountPercent are considered as deprecated. One should use the field OrderProduct. discountTotal which returns total monetary discount for a product unit, including all discounts for a good and an order. When addressing to the field OrderProduct.discount, the field value OrderProduct.discountTotal will be returned; when addressing to the field OrderProduct.discountPercent, 0 will always return.

Extreme cases in discount distribution for an order between goods

In some cases, the system can not distribute discount for an order between goods. Look at the example.

Let us assume we have the following order:

|  Name     |  Price   | Discount          | Quantity |  Total   |
|           |          |                   |          |          |
|  Shorts   |  60 EUR  | –                 |   3      | 180 EUR  |
|                                                     |          |
|  Total                                              | 180 EUR  |

We add discount for the order of 10 euros. The system needs to distribute the discount between all three product units of the order.

If you try to specify such discount for the order, the system will show an error by default. What is important, if you create such order in the system or via API, the error will be shown regardless of API version.

If "Correct discount for order" is enabled in Settings > Orders section, the system will correct discount for order to the closest dividend (in this case, the discount for the order will be changed from 10 euros to 9, 99 euros).

Rounding

To 6.0 version has been added a rounding function, which can be enabled in Settings > Orders section. If you enable rounding, it is applied to items in the order. That cost, which is subtracted from the goods sum as a result of rounding, goes to the discount for a good.

Also, there is rounding of the cost of each good, including the cost of the order, which is set by default with the rounding enabled. With this function, rounding of the goods value is made in such a way that the resulting cost of the order is as close to the cost of the order without rounding as possible.


PrintEditHistory
Page last modified on August 29, 2018, at 09:30 AM