flamingo.me/flamingo-commerce/v3@v3.11.0/CHANGELOG.md (about)

     1  # Changelog
     2  
     3  ## v3.12.0 [upcoming]
     4  
     5  ## v3.11.0
     6  
     7  **search**
     8  * The fake search service now interprets the passed sort options.
     9  
    10  **cart**
    11  * add possibility to get price in main currency for a payment method
    12  * during add to cart delivery method is now saved in context
    13  * **Fix:** error returned by `collectTotals(cart)` in DefaultCartBehaviour is now bubbled up
    14  
    15  **product**
    16  * **Fix:** price in loyalty points, during calculation of loyalty charge, is now rounded mathematically according to possible currency fractions 
    17  
    18  ## v3.10.0
    19  
    20  **sourcing**
    21  * **Breaking:** Drop deprecated sourcing service `SourcingServiceDetail` and all things related.
    22  
    23  **price**
    24  * **Breaking:** Introduce currency library http://github.com/Rhymond/go-money for more flexible rounding. All currency codes should comply to ISO4217 from now on.
    25  
    26  **product**
    27  * Introduced multiple loyalty prices for one product by adding AvailablePrices to ProductLoyalty.
    28  * Added ActiveLoyaltyPrice to Saleable and adapted charges generation to use it instead of array
    29  
    30  ## v3.9.0
    31  
    32  **search**
    33  * Introduce an Action to search result to advise the frontend to perform an action for that search different from displaying the result page.
    34    The action model is completely open to anything, but the most common use case is to redirect certain searches directly to product detail pages or special brand landing pages.
    35  
    36  **cart**
    37  * Fix: Cart merge of bundle products was broken, bundle configuration is now correctly added to the new customer cart
    38  * Fix: Add to cart of bundle products now only fails for missing required bundle choices. As prior passing all choices with qty of zero have been required. Now optional choices with qty of zero can be omitted.
    39  * Fix: Correctly evaluate min / max quantities of bundle choices. Previously it was possible to add bundle choices with qty 0 even if min qty was 1.
    40  * **Breaking**(In case you have implemented a custom cart service): Extend the cart service interface with `UpdateItemBundleConfig` to allow updating bundles that have already been placed inside the cart.
    41  * GraphQL:
    42    * Add new mutation `Commerce_Cart_UpdateItemBundleConfig` to update bundle configs for existing cart items
    43    * **Breaking** Make the qty in the `Commerce_Cart_ChoiceConfigurationInput` type mandatory, previously 1 was taken as a default
    44  
    45  **checkout**
    46  * initialize place order metrics with 0 on application start to follow prometheus best practices
    47  
    48  **product**
    49  * GraphQL:
    50    * Expose Active Option (product+qty) for bundle products
    51    * **Breaking** Make the qty in the `Commerce_Product_ChoiceConfigurationInput` type mandatory, previously it was 0 which lead to taking the minimum required qty of that choice
    52  
    53  ## v3.8.0
    54  
    55  **sourcing**
    56  * Introduce constant `MaxSourceQty` to indicate unlimited stock.
    57  
    58  **cart**
    59  * DefaultBehavior: consider discounts when updating cart item row prices
    60  * Make the cart merge strategy configurable, this strategy handles how a guest cart is transformed into a customer cart.
    61    The following strategies can be set via the config `commerce.cart.mergeStrategy`:
    62    * `merge` (default): Merge the content of the guest and customer cart
    63    * `replace`: Replace the customer cart with the guest cart content
    64    * `none`: Don't do anything, guest cart is lost during customer sign-in.
    65  * Telephone in Address is now deprecated. To distinguish phone number parts new fields were introduced: TelephoneCountryCode, 
    66    TelephoneAreaCode, TelephoneNumber. Changes are expected to be non-breaking.
    67  
    68  ## v3.7.0
    69  
    70  **cart**
    71  * Updated the `DefaultCartBehaviour` to be able to support other `CartStorage` implementations
    72      * Dropped the fake implementations of `GiftCardHandler` and `VoucherHandler` to not magically add some discounts
    73  
    74  **general**
    75  * Add .golangci.yml and github workflow
    76  * Add .mockery.yaml config
    77  
    78  **sourcing**
    79  * **Breaking**
    80      * SourcingService changed types for return values for bundle product support.
    81        Every sourcing value is now returned per product id.
    82  
    83  ## v3.6.0
    84  
    85  **cart**
    86  * **Breaking**: Move all calculations to cart behaviour implementation
    87    * By moving calculation responsibility, we enable different implementation possibilities for calculations like tax before or after discounts, tax on single item or sum and different tax rounding modes instead of having it hard-coded in the flamingo cart.
    88    * All calculation functions on cart item, shipping item, delivery and cart are now public fields for which the values must be set by the cart behaviour implementation
    89    * The `DefaultCartBehaviour` calculates all new fields accordingly
    90    * Removed `ItemBuilder`, `DeliveryBuilder` and `Builder` since they didn't provide any meaningful functionality after removing the calculations. Please create structs directly.
    91    * Changed the GraphQL cart model accordingly.
    92    * To help with the migration there are sed commands for the following fields in `cart/migration.sed`: run `find . -type f -iname '*.go' -exec gsed -i -f migration.sed "{}" +;`
    93    * Cart items
    94        * | Old Function                           | New Field                            |
    95          |----------------------------------------|--------------------------------------|
    96          | RowPriceGrossWithDiscount()            | RowPriceGrossWithDiscount            |
    97          | RowPriceGrossWithItemRelatedDiscount() | RowPriceGrossWithItemRelatedDiscount |
    98          | RowPriceNetWithDiscount()              | RowPriceNetWithDiscount              |
    99          | RowPriceNetWithItemRelatedDiscount()   | RowPriceNetWithItemRelatedDiscount   |
   100          | TotalDiscountAmount()                  | TotalDiscountAmount                  |
   101          | ItemRelatedDiscountAmount()            | ItemRelatedDiscountAmount            |
   102          | NonItemRelatedDiscountAmount()         | NonItemRelatedDiscountAmount         |
   103    * Shipping items
   104        * | Old Function               | New Field               |
   105          |----------------------------|-------------------------|
   106          | TotalWithDiscountInclTax() | PriceGrossWithDiscounts |
   107          | -                          | PriceNetWithDiscounts   |
   108    * Deliveries
   109        * | Old Function                      | New Field                       |
   110          |-----------------------------------|---------------------------------|
   111          | SubTotalGross()                   | SubTotalGross                   |
   112          | SubTotalNet()                     | SubTotalNet                     |
   113          | SumTotalDiscountAmount()          | TotalDiscountAmount             |
   114          | SumSubTotalDiscountAmount()       | SubTotalDiscountAmount          |
   115          | SumNonItemRelatedDiscountAmount() | NonItemRelatedDiscountAmount    |
   116          | SumItemRelatedDiscountAmount()    | ItemRelatedDiscountAmount       |
   117          | SubTotalGrossWithDiscounts()      | SubTotalGrossWithDiscounts      |
   118          | SubTotalNetWithDiscounts()        | SubTotalNetWithDiscounts        |
   119          | GrandTotal()                      | GrandTotal                      |
   120    * Cart
   121        * | Old Function                      | New Field                       |
   122          |-----------------------------------|---------------------------------|
   123          | GrandTotal()                      | GrandTotal                      |
   124          | -                                 | GrandTotalNet                   |
   125          | SumShippingNet()                  | ShippingNet                     |
   126          | SumShippingNetWithDiscounts()     | ShippingNetWithDiscounts        |
   127          | SumShippingGross()                | ShippingGross                   |
   128          | SumShippingGrossWithDiscounts()   | ShippingGrossWithDiscounts      |
   129          | SubTotalGross()                   | SubTotalGross                   |
   130          | SubTotalNet()                     | SubTotalNet                     |
   131          | SubTotalGrossWithDiscounts()      | SubTotalGrossWithDiscounts      |
   132          | SubTotalNetWithDiscounts()        | SubTotalNetWithDiscounts        |
   133          | SumTotalDiscountAmount()          | TotalDiscountAmount             |
   134          | SumNonItemRelatedDiscountAmount() | NonItemRelatedDiscountAmount    |
   135          | SumItemRelatedDiscountAmount()    | ItemRelatedDiscountAmount       |
   136          | SumAppliedGiftCards()             | TotalGiftCardAmount             |
   137          | SumGrandTotalWithGiftCards()      | GrandTotalWithGiftCards         |
   138          | -                                 | GrandTotalNetWithGiftCards      |
   139  * Dispatch a `PreCartMergeEvent` before and a `PostCartMergeEvent` after merging a guest and customer cart when logging in
   140  * Update payment selection on cart merge with the guest carts' payment selection after applying coupons and giftcards and only if customer cart has no items
   141  * Add possibility to have additional data in `AddToCartNotAllowed` error
   142  * Deprecate `BuildAddRequest` in cart service (build your own add request)
   143  * Provide `BaseCartReceiver` for fetching carts without `DecoratedCartFactory` dependency
   144  * Provide `Receiver` interface to be able to mock receiving a cart
   145  * GraphQL:
   146    * Aggregate many input values to `Commerce_Cart_AddToCart` mutation in `Commerce_Cart_AddToCartInput`
   147    * Add support for bundle and configurable products in `Commerce_Cart_AddToCart` mutation
   148  * Added support for AdditionalData on CartItem Level for the defaultCartBehaviour.
   149  
   150  **checkout**
   151  * Add possibility to have additional data in `PaymentFlowActionTriggerClientSDK`
   152  * Breaking: Disable auto canceling of orders during place order rollback, to restore old behaviour set `commerce.checkout.placeorder.states.placeorder.cancelOrdersDuringRollback: true`
   153  
   154  **product**
   155  * Introduce `Labels()` function on `Attribute` to handle translations for attributes with multiple values, will fallback to `Values()` function if not translated.
   156  * Introduce `Stock` slice in `BasicProductData` to store more accurate information about availability for each delivery code
   157  * Introduce new `BundleProduct` and `BundleProductWithActiveChoices` types
   158  * GraphQL:
   159    * Add `unitCode` to`Commerce_Product_VariationSelection_Option` and `Commerce_Product_ActiveVariationSelection`
   160    * Fix mapping of VariationSelections
   161    * Introduce `Labels` for attributes here as well
   162    * Extend `Commerce_Product` query with non-mandatory bundle configuration argument
   163    * Add type `Commerce_Product_BundleProduct` that implements `Commerce_Product` interface and is used as bundle product graphql representation.
   164    * Change `variantionSelections` field in configurable products with `variantSelection` that handles all possible combinations of multi axis configurable.
   165  * FakeService
   166    * Add configuration option `commerce.product.fakeservice.defaultProducts` which toggles the delivery of default test products. 
   167    * Add category facet functionality to the fake `SearchService` with default category facet items.
   168    * Add configuration option `commerce.product.fakeservice.jsonTestDataCategoryFacetItems` which can be used to provide your own category facet items. 
   169    * Add new `Stock` field to returned `SimpleProduct` from service
   170    * Add configuration option for delivery codes `commerce.product.fakeservice.deliveryCodes` which can be used to provide different delivery codes for stock.
   171  
   172  ## v3.5.0
   173  **general**
   174  * Switch to MIT License
   175  
   176  **cart**
   177  * Add convenience function to clone carts
   178  * DefaultCartBehaviour now returns real cart clones to prevent data races on cart fields 
   179  * API
   180    * **Breaking**: Update `DELETE /api/v1/cart` to actually clean the whole cart not only removing the cart items (introduces new route for the previous behaviour, see below)
   181    * Add new endpoint `DELETE /api/v1/cart/deliveries/items` to be able to remove all cart items from all deliveries but keeping delivery info and other cart data untouched
   182  * Add new method `SumShippingGrossWithDiscounts` to the cart domain which returns gross shipping costs for the cart 
   183  * When using the `ItemSplitter` to split items in items with single qty (`SplitInSingleQtyItems`) the split discounts are reversed to make splitting the row total stable.
   184  * **Breaking**: `SumTotalTaxAmount` now takes taxes on shipping costs into account
   185  * **Breaking**: Delivery discount sum calculations `SumTotalDiscountAmount`, `SumNonItemRelatedDiscountAmount`, `SumItemRelatedDiscountAmount` now take discount on shipping costs into account
   186    * Old calculation is now in `SumSubTotalDiscountAmount`.
   187  * `CartService`
   188    * Add `UpdateAdditionalData` to be able to set additional data to cart
   189    * Add `UpdateDeliveryAdditionalData` to be able to set additional data to the delivery info
   190    * Introduce new [interface](cart/application/service.go) to be able to easier mock the whole `CartService`
   191    * Add auto generated mockery mock for the `CartService`
   192    * Add new field `PriceGross` of `shippingItem` to directly get the shipping cost incl tax (must be filled by cart adapter)
   193  * GraphQL: 
   194    * Add new method `sumShippingGrossWithDiscounts` to the `Commerce_DecoratedCart` type
   195    * Add new field `sumShippingGross` to the `Commerce_DecoratedCart` type
   196    * Add new field `priceGross` to the `Commerce_Cart_ShippingItem` type
   197    * Add new mutation `Commerce_Cart_UpdateAdditionalData`
   198    * Add new mutation `Commerce_Cart_UpdateDeliveriesAdditionalData`
   199    * Add new field `customAttributes` to the `Commerce_CartAdditionalData` type
   200    * Add new field `additionalData` to the `Commerce_CartDeliveryInfo` type
   201    * Add new type `Commerce_Cart_CustomAttributes` with method for getting key/value pairs
   202    * **Breaking**: Make naming convention consistent in graphql schema `Commerce_Cart_*`
   203    * **Breaking**: Remove the fields `getAdditionalData, additionalDataKeys, additionalDeliveryInfoKeys` from the `Commerce_CartDeliveryInfo` type
   204    * **Breaking**: `Commerce_Cart_UpdateDeliveryShippingOptions` mutation responded with slice of `Commerce_Cart_DeliveryAddressForm` which was incorrect as we don't process any form data within the mutation. It responds now rightly only with `processed` state.
   205  * **Breaking**: Upgrade github.com/go-playground/form to v4, all types are fully compatible, but import paths have to be changed
   206  
   207  
   208  **checkout**
   209  * Introducing Flamingo events on final states of the place order process
   210  * Introduce a max ttl for the checkout state machine to avoid polluting the redis with stale checkout processes, defaults to 2h
   211  * Checkout controller: force new order id reservation if an early place happened and there was a payment issue
   212  * API
   213    * In case of an invalid cart during place order process we now expose the cart validation result, affected endpoints:
   214      ```
   215      GET /api/v1/checkout/placeorder
   216      POST /api/v1/checkout/placeorder/refresh
   217      POST /api/v1/checkout/placeorder/refresh-blocking
   218      ```
   219  * Add new Flow Action `PaymentFlowActionTriggerClientSDK` to the checkout
   220  * **Breaking**: Upgrade github.com/go-playground/form to v4, all types are fully compatible, but import paths have to be changed
   221  
   222  **customer**
   223  * Add mockery mocks for both `Customer` / `CustomerIdentityService` for easier testing
   224  * Add `State` field to customer address to be closer to cart address type, expose via GraphQL
   225  
   226  **price**
   227  * When marshalling `domain.Price` to JSON the amount is rounded.
   228  * Fix various rounding issues with negative prices, add all rounding modes and examples to moduel readme.
   229  
   230  **product**
   231  * Enhance the `PriceContext` to allow potential delivery specific pricing
   232  * GraphQL:
   233    * **Breaking**: Change `activeBase` of `Commerce_Product_PriceInfo` from `Float` to `Commerce_Price`
   234    * Add `availablePrices` to the `Commerce_Product` interface to display potential pricing options in the frontend
   235    * Add `context` to the `Commerce_Product_PriceInfo` model to be able to differ between prices
   236  
   237  ## v3.4.0
   238  **cart**
   239  * Added desired time to DeliveryForm
   240  * InMemoryCartStorage: initialize lock and storage already in Inject() to avoid potential race conditions
   241  * API
   242    * Add endpoints for deleting / updating a item in the cart (DELETE/PUT: /api/v1/cart/delivery/{deliveryCode}/item)
   243    * **Breaking**: Affects v1 prefixed routes, switched to a more RESTful naming and use of the correct HTTP verbs to mark idempotent operations
   244      * | old HTTP verb | old route                                          | new HTTP verb | new route                                  |
   245        |--------------:|----------------------------------------------------|---------------|--------------------------------------------|
   246        |          POST | /api/v1/cart/delivery/{deliveryCode}/additem       | POST          | /api/v1/cart/delivery/{deliveryCode}/item  |
   247        |      POST/PUT | /api/v1/cart/applyvoucher                          | POST          | /api/v1/cart/voucher                       |
   248        |   POST/DELETE | /api/v1/cart/removevoucher                         | DELETE        | /api/v1/cart/voucher                       |
   249        |      POST/PUT | /api/v1/cart/applygiftcard                         | POST          | /api/v1/cart/gift-card                     |
   250        |          POST | /api/v1/cart/applycombinedvouchergift              | POST          | /api/v1/cart/voucher-gift-card             |
   251        |          POST | /api/v1/cart/removegiftcard                        | DELETE        | /api/v1/cart/gift-card                     |
   252        |          POST | /api/v1/cart/billing                               | PUT           | /api/v1/cart/billing                       |
   253        |          POST | /api/v1/cart/delivery/{deliveryCode}/deliveryinfo  | PUT           | /api/v1/cart/delivery/{deliveryCode}       |
   254        |           PUT | /api/v1/cart/updatepaymentselection                | PUT           | /api/v1/cart/payment-selection             |
   255    
   256  * GraphQL
   257    * Update schema and resolver regarding desired time
   258  
   259  **category**
   260  * Added cue config to module
   261  * Update fake service documentation
   262  * FakeService
   263      * The category fake service was added which can return a project specific category tree and categories
   264      * Added configuration options are `fakeService.enabled` and `fakeService.testDataFolder` to enable the fake category service and to use json files as fake categories and tree. You can find examples in the documentation of the module
   265  
   266  **checkout**
   267  * Checkout Controller, update handling of aborted/canceled payments:
   268    * Cancel the order / restore the cart before generating the new idempotency key of the payment selection
   269  * Resolve goroutine leak in redis locker
   270  * **Breaking** Change StartPlaceOrder behaviour to always start a new one.
   271  * **Breaking** Change ClearPlaceOrderProcess behaviour to be always possible (no matter on which state)
   272  * API
   273    * **Breaking**: Affects v1 prefixed routes, switched to a more RESTful naming and use of the correct HTTP verbs to mark idempotent operations
   274      * | old HTTP verb | old route                                     | new HTTP verb | new route                                     |
   275        |--------------:|-----------------------------------------------|---------------|-----------------------------------------------|
   276        |          POST | /api/v1/checkout/placeorder/refreshblocking   | POST          | /api/v1/checkout/placeorder/refresh-blocking  |
   277  
   278  **customer**
   279  * GraphQL
   280    * Extend `Commerce_Customer_Address` with some useful fields
   281    * Extend `Commerce_Customer_Result` with a field for querying a specific address
   282    * **Breaking**:
   283      * `Commerce_Customer_Address`: rename field `StreetNr` to `StreetNumber`, `lastname` to `lastName` and `firstname` to `firstName` 
   284      * `Commerce_Customer_Result`: `defaultShippingAddress` and `defaultBillingAddress` now can return null if there is no default address
   285      * `Commerce_Customer_PersonData`: field `birthday` is now nullable and of type `Date`. 
   286  
   287  **payment**
   288  * Introduced wallet payment method 
   289  
   290  **product**
   291  * Add support for product badges
   292  * GraphQL
   293    * **Breaking** New schema for products:
   294      * `Commerce_Product` has been restructured and now has three subtypes: `Commerce_Product_SimpleProduct`, `Commerce_Product_ConfigurableProduct`, `Commerce_Product_ActiveVariantProduct`
   295      * Product variant data, that has previously been buried in `Commerce_ConfigurableProduct.variants`, has been mapped to the toplevel of each product and can be accessed directly.
   296      * Both `ActiveVariantProduct` and `ConfigurableProduct` provide a new property named `variationSelections` which exposes a list of possible attribute combinations for the configurable.
   297  * FakeService
   298      * The product fake search service is now able to return products with an active variant via `fake_configurable_with_active_variant`. Variation attributes have been changed to only include `color` and `size`.
   299      * Added configuration option `jsonTestDataFolder` to use json files as fake products. You can find an example product under: `test/integrationtest/projecttest/tests/graphql/testdata/products/json_simple.json`
   300      * Added fakservice documentation to the product module.
   301      * The product fake search service is now able to return a specific product if the given query matches the marketplace code / name of the json file of the product  
   302      * The product fake search service returns no products if it is queried with `no-results`
   303  * Expose `VariantVariationAttributesSorting` on `domain.ConfigurableProductWithActiveVariant`
   304  * **Breaking**: Update stock handling: Remove magic alwaysInStock product attribute. Just Rely BasicProductData.StockLevel field instead.
   305  
   306  **sourcing**
   307  * **Breaking**
   308    * Optional pointer `DeliveryInfo` added as parameter to `StockProvider.GetStock`
   309    
   310  **docs**
   311  * Embed swagger.json via go-bindata, so it can be used from the outside
   312  
   313  
   314  ## v3.3.0
   315  **product**
   316  * Switch module config to CUE
   317  * Extended product model with loyalty earnings
   318  * Added Rest API route to get products
   319  * GraphQL
   320    * Added values field of Attribute to schema
   321    * exposed loyalty earnings
   322    * Added facets to fake search service
   323  * Expose unit of product variant attributes
   324  * fake: add loyalty pricing for `fake_simple` product, introduced `fake_fixed_simple_without_discounts` product
   325  
   326  **cart**
   327  * **Breaking**: Moved to new flamingo auth module, breaks several interfaces which previously relied on the oauth module
   328  * **Breaking**
   329    * Cart item validation now requires the decorated cart to be passed to assure that validators don't rely on a cart from any other source (e.g. session)
   330    * Session added as parameter to interface method `MaxQuantityRestrictor.Restrict`
   331    * Session added as parameter to `RestrictionService.RestrictQty`
   332    * Changed no cache entry found error for cartCache `Invalidate`, `Delete` and `DeleteAll` to `ErrNoCacheEntry`
   333  * Switch module config to CUE
   334  * GraphQL
   335    * Add new mutation to set / update one or multiple delivery addresses `Commerce_Cart_UpdateDeliveryAddresses`
   336    * Add new mutation to update the shipping options (carrier / method) of an existing delivery `Commerce_Cart_UpdateDeliveryShippingOptions`
   337    * Add new mutation to clean current users cart `Commerce_Cart_Clean`
   338    * Add new query to check if a product is restricted in terms of the allowed quantity `Commerce_Cart_QtyRestriction`
   339    * Add new field `sumPaymentSelectionCartSplitValueAmountByMethods` to the `Commerce_Cart_Summary` which sums up cart split amounts of the payment selection by the provided methods.   
   340    * Expose PaymentSelection.CartSplit() via GraphQL, add new types `Commerce_Cart_PaymentSelection_Split` and `Commerce_Cart_PaymentSelection_SplitQualifier`
   341    * **Breaking**: renamed the following GraphQL types
   342      * type `Commerce_Cart_BillingAddressFormData` is now `Commerce_Cart_AddressForm`
   343      * input `Commerce_BillingAddressFormInput` is now `Commerce_Cart_AddressFormInput`
   344      * type `Commerce_Charge` is now `Commerce_Price_Charge`
   345      * type `Commerce_ChargeQualifier` is now `Commerce_Price_ChargeQualifier`
   346      * input `Commerce_ChargeQualifierInput` is now `Commerce_Price_ChargeQualifierInput`
   347  * Adjusted log level for cache entry not found error when trying to delete the cached cart   
   348  
   349  **customer**
   350  * **Breaking**: renamed `GetId` to `GetID` in `domain.Customer` interface
   351  * introduced new `CustomerIdentityService` to retrieve authenticated customers by `auth.Identity` 
   352  * **Breaking**: removed `CustomerService` please use `CustomerIdentityService`
   353  * GraphQL: Add new customer queries:
   354    * `Commerce_Customer_Status` returns the customer's login status
   355    * `Commerce_Customer` returns the logged-in customer
   356  
   357  **checkout**
   358  * Deprecate Sourcing service port in checkout (activate if required with setting `commerce.checkout.activateDeprecatedSourcing`)
   359  * Make cart validation before place order optional with configuration
   360  * State Machine
   361    * Add additional metrics to monitor place order flow
   362      * flamingo_commerce_checkout_placeorder_starts
   363      * flamingo_commerce_checkout_placeorder_state_run_count
   364      * flamingo_commerce_checkout_placeorder_state_failed_count
   365     * Add a step to validate the payment selection if needed. The step provides a port to be implemented if needed.
   366  * Expose placeorder endpoints also via rest
   367  * Checkout controller, update to the error handling:
   368    * In case of a payment error the checkout controller will now redirect to the checkout/review action instead of just rendering the matching template on the current route.
   369    * Same applies in case of an error during place order, the checkout controller will now redirect to the checkout step.
   370    * In both cases the error will be stored as a flash message in the session before redirecting, the target action will then receive it and pass it to the template view data. 
   371   
   372  **search**
   373  * Switch module config to CUE
   374  * Update `pagination` module configuration. Use `commerce.pagination` namespace for configuration now.
   375  * GraphQL
   376    * **Breaking** simplified Commerce_Search_SortOption type
   377    * **Breaking** use GraphQL specific search result type
   378    * Added facets resolver
   379    
   380  **category**
   381  * GraphQL
   382    * **Breaking** moved GraphQL `dto` package to `categorydto`
   383  
   384  **docs**
   385  * Add Swagger/OpenAPI 2.0 specification to project, using [swaggo/swag](https://github.com/swaggo/swag)
   386  **sourcing**
   387  * Add new "sourcing" module that can be used standalone. See sourcing/Readme.md for more details
   388  
   389  **w3cdatalayer**
   390  * **Breaking**: Switch from flamingo `oauth` module to the new `auth` module, to keep w3cdatalayer working please configure the new `auth` module accordingly
   391  
   392  **order**
   393  * **Breaking**: removed interface `CustomerOrderService` please use `CustomerIdentityOrderService`
   394  * Update config path: `order.useFakeAdapters` to `commerce.order.useFakeAdapter`
   395  
   396  ## v3.2.0
   397  **w3cdatalayer**
   398  * Fixed a bug that causes the datalayer to panic if it failed to build an absolute url
   399  * Introduced a configuration option to choose between base64url and hex encoding for the hashed values
   400  * Move config to commerce namespace, from `w3cDatalayer` to `commerce.w3cDatalayer`
   401  * Add legacy config mapping so old mappings can still be used
   402  * Add cue based config to have config validation in place
   403  
   404  **checkout**
   405  * Controller
   406    * Allow checkout for fully discounted carts without payment processing. Previously all checkouts needed a valid payment to continue.
   407      In case there is nothing to pay this can be skipped.
   408      * Order ID will be reserved as soon as the user hits the checkout previously it was done before starting the payment
   409  * GraphQL
   410    * Update place order process to also allow zero carts which don't need payment, this leads to a state flow that lacks the payment steps.
   411      See module readme for further details.
   412  * Update source service to support external location codes.
   413    * Adds `ExternalLocationCode` to the `Source` struct.
   414    * Update `SetSourcesForCartItems()` to use the new `SourcingServiceDetail` functionality if the bound service implements the interface
   415  * Update `OrderService` to expose more metrics regarding the place order process:
   416      ```
   417      flamingo-commerce/checkout/orders/cart_validation_failed
   418      flamingo-commerce/checkout/orders/no_payment_selection
   419      flamingo-commerce/checkout/orders/payment_gateway_not_found
   420      flamingo-commerce/checkout/orders/payment_flow_status_error
   421      flamingo-commerce/checkout/orders/order_payment_from_flow_error
   422      flamingo-commerce/checkout/orders/payment_flow_status_failed_canceled
   423      flamingo-commerce/checkout/orders/payment_flow_status_aborted
   424      flamingo-commerce/checkout/orders/place_order_failed
   425      flamingo-commerce/checkout/orders/place_order_successful
   426      ```
   427    
   428  **cart**
   429  * inMemoryBehaviour: Allow custom logic for GiftCard / Voucher handling
   430    * We introduced two new interfaces `GiftCardHandler` + `VoucherHandler`
   431    * This enables users of the in-memory cart to add project specific gift card and voucher handling 
   432  * Fix `CreateInitialDeliveryIfNotPresent` so that cache gets updated now when an initial delivery is created
   433  * GraphQL: Add new cart validation query `Commerce_Cart_Validator` to check if cart contains valid items
   434  
   435  **price**
   436  * IsZero() now uses LikelyEqual() instead of Equal() to avoid issues occurring due to floating-point arithmetic
   437  
   438  **product**
   439  * product attributes:
   440    * Added `AttributesByKey` domain method to filter attributes by key and exposed this method as `getAttributesByKey` in GraphQL
   441    * GraphQL: Exposing `codeLabel` property in the `Commerce_ProductAttribute` type
   442    
   443  **payment**
   444  * Introduced error message for already used idempotency key 
   445  
   446  ## v3.1.0
   447  **tests**
   448  * Added GraphQL integration tests for new Place Order Process, run manually with `make integrationtest`
   449  * To run the GraphQL Demo project use `make run-integrationtest-demo-project`
   450  * To regenerate the GraphQL files used by the integration tests / demo project use  `make generate-integrationtest-graphql`
   451  
   452  **cart**
   453  * Add `additionalData` to the `AddRequest` used during add to cart
   454      * Breaking: Update helper/builder function `BuildAddRequest`
   455  * Breaking: Change to `EventPublisher` interface, `PublishChangedQtyInCartEvent` and `PublishAddToCartEvent` now
   456  include a cart as a parameter
   457  * Breaking: Change to behaviour of `AddToCartEvent` and `ChangedQtyInCartEvent`, they are now thrown after
   458  the cart has been adjusted and written back to cache
   459  * Events deferred from `ModifyBehaviour` are dispatched before `AddToCartEvent` and `ChangedQtyInCartEvent`
   460  * The `AddToCartEvent` includes the current cart (with added product)
   461  * The `ChangedQtyInCartEvent` includes the current cart (with updated quantities)
   462  
   463  * Mark `CartReceiverService.RestoreCart()` as deprecated, use `CartService.RestoreCart()` instead,
   464    the cart adapter therefore needs to implement the `CompleteBehaviour` interface.
   465  * Add `CartReceiverService.ModifyBehaviour()` to easily receive the current behaviour (guest/customer)
   466  
   467  * Add `CompleteBehaviour` interface which ensures that the cart adapter offers Complete / Restore functionality
   468  * Add `CartService.CompleteCurrentCart()` and `CartService.RestoreCart()` which rely on the new `CompleteBehaviour` interface
   469  * **Breaking**: Update `CartService.CancelOrder()` to use `CartService.RestoreCart()` instead of `CartReceiverService.RestoreCart()`,
   470    if your cart supports completing/restoring please implement `CompleteBehaviour` interface
   471  * Add `CartService.CancelOrderWithoutRestore()` to allow order cancellation without restoring the cart
   472  
   473  * Mark `GuestCartService.RestoreCart` as deprecated, will be replaced by `CompleteBehaviour`
   474  * Mark `CustomerCartService.RestoreCart` as deprecated, will be replaced by `CompleteBehaviour`
   475  
   476  * Add mocks for all behaviours, you can use a specific one e.g. `&mocks.CompleteBehaviour{}` or the all in one `&mocks.AllBehaviour{}`
   477  
   478  * Update `InMemoryBehaviour` to fulfill the `CompleteBehaviour` interface (adds `Complete()`/`Restore()`)
   479  * Update `InMemoryCartStorage`, add Mutex to be thread safe
   480  
   481  * Update `SimplePaymentFormService` to allow gift cards in the `PaymentSelection`, please use the
   482    config `commerce.cart.simplePaymentForm.giftCardPaymentMethod`to specify the default payment method for gift cards
   483  
   484  * Add missing `product` module dependency to cart module
   485  
   486  **checkout**
   487  * Move config to commerce namespace, from `checkout` to `commerce.checkout`
   488  * Add legacy config mapping so old mappings can still be used
   489  * Add cue based config to have config validation in place
   490  
   491  * Add `OrderService.CancelOrderWithoutRestore()` which uses the new `CartService` function
   492  * Add `OrderService.CartPlaceOrder()` to place a provided cart instead of fetching it from the `CartService`
   493  
   494  * Add new GraphQL Place Order process which relies on a new state machine please referer to the module readme for more details
   495      * Transition all actions of the checkout controller to separate states
   496      * Add new `ContextStore` port to provide a storage for the place order process
   497          * Provide InMemory and Redis Adapter
   498      * Add new `TryLocker` port to provide an easy way to sync multiple order processes across different nodes
   499          * Provide InMemory and Redis Adapter
   500      * Breaking: Add new GraphQL mutations / queries to start / stop / refresh the place order process
   501      
   502  **payment**
   503  * Add `PaymentService` to easily work with bound PaymentGateway's
   504      * `PaymentService.AvailablePaymentGateways()` returns all bound gateways
   505      * `PaymentService.PaymentGateway()` gets the payment gateway by gateway code
   506      * `PaymentService.PaymentGatewayByCart()` gets the payment gateway of the cart payment selection
   507  
   508  * Extend the `FlowStatus` struct with more standardized `FlowActionData`
   509  * Add standardized Flow Actions `PaymentFlowActionShowIframe`, `PaymentFlowActionShowHTML`, `PaymentFlowActionRedirect`,
   510    `PaymentFlowActionPostRedirect` please use these in your payment adapter since the standard place order relies on them.
   511   
   512  **search**
   513  * Extend `Suggestion` struct with `Type` and `AdditionalAttributes` to be able to distinguish between product/category suggestions
   514  
   515  ## v3.0.1
   516  - Update dingo and form dependency to latest version
   517  
   518  ## v3.0.0
   519  - general cleanups and linting fixes - that includes several renames of packagenames and types.
   520  - price object introduced:
   521      - cart and product model don't use float64 anymore but a Price type
   522      - use commercePriceFormat templatefunc instead (core) priceFormat where you want to render a price object. This will automatically render a "Payable" price.
   523  - cart module:
   524      - Has a new secondary port: PlaceOrderService
   525      - The meaning of DeliveryInfo.Method has changed! The former meaning is now represented in the property DeliveryInfo.Workflow. See Readme of cart ackage for details
   526      - The complete pricefields are changed! Check readme for details on the new price fields and methods
   527  - checkout: 
   528      - removed depricated viewdata (CartTotals)
   529  - products:
   530      - product category breadcrumb is not filled in controller - if you want a breadcrum you can use category data functions
   531      - product category fields are changed to use a categoryTeaser
   532  - category:
   533      - Tree object uses a Tree Entity now which contains NOT all category properties. You have to fetch the category details separate on demand:
   534          - search for usages of the data funcs - they may need changes in rendering the data: `data('category´´..`