Last updated

Price integration

Prices are either handles in Norce and then sent to the ERP or the other way around.

Update prices in Norce

For some client some prices are calculated in the ERP, in those cases it is often one standard price for each product, but can also be many other different price lists, like contract prices for specific customers (companies) or temporary campaigns.

These are imported using Norce Commerce Connect. The endpoints that can be used are:

  • ImportProducts ImportProducts allows for one price list to be added to the large contract of updating almost everything else on the product. This could be any price list, but only one is allowed.
  • ImportSkuPriceList ImportSkuPriceList takes many pricelists and products at a time, use this if you have many prices that needs to be updated and more often than other product data.
  • ImportPriceList ImportPriceList updates metadata on the price list, not on the products. Use this to create or update new price lists. For example if you get new Contract price lists

Important information

FieldEntityDescriptionUsage
PartNoSkuPriceListRequired, identifies the product that should be updated
PriceListCode / CodeSkuPriceList / PriceListRequired, identifies the pricelist
IsActiveSkuPriceListDefault is true, if you send in PriceSale it will forcely set to true
PriceCatalogSkuPriceListA alternative amount, to keep track of
PriceRecommendedSkuPriceListAn alternative amount to keep track of
PriceSaleSkuPriceListIf sent in, the price rule will automatically be set to "fixed price" and isactive will be set to true
QuantityBreakSkuPriceListThreshold value, determines minimum number of items required for getting this price, you can have many prices therefore on same product and price list, if they have different quantitybreak
NamePriceListName of the price list
CurrencyCodePriceListthe currency of the price list (The data model allows for different currency on each price record, but this functionality is deprecated. All prices should be in same currency as is defined on its price list, if you find discrepances this is an error that should be reported)
StartDatePriceListOptional start date
EndDatePriceListOptiona end date
IsPublicPriceLista flag that decides if the pricelist is public on the application (the application specifified in the http header), which means that it will be automatically applied on the application.
(Warehouse)CodeWarehousePricelists should have at least one warehouse and location, decides which warehouses that should be part of the availability aggregations in Norce
(Location)CodeWarehouseLocationPricelists should have at least one warehouse and location, decides which warehouses that should be part of the availability aggregations in Norce
Example calling ImportSkuPriceList in Norce Commerce Connect

https://connect.lab.storm.io/4.0//api/Product/ImportSkuPriceLists

  1. Simple import with fixed prices only

{
    "AccountId": 0,
    "FullFile": false,
    "SerializationType": 0,
    "_SkuPriceListFieldsThatAreSet_Explanation": "PriceSale",
    "SkuPriceListFieldsThatAreSet": [3]
}


[
    {
        "_comment": "import fixed price ",
        "PartNo": "266639",
        "PriceListCode": "pl_campaign_mm",
        "PriceSale": 100,
        "QuantityBreak": 1
    },
    {
        "_comment": "import fixed price, w qty break",
        "PartNo": "266639",
        "PriceListCode": "pl_campaign_mm",
        "PriceSale": 90,
        "QuantityBreak": 10
    }
]

  1. Import with other price fields, except SalePrice The price record is not activated by the integration, require population rule and price rules on the price list. Some fields will be ignored if they are null, while some others will update the price record with null.

{
    "AccountId": 0,
    "FullFile": false,
    "_IgnoreSkuPriceListFieldsWhenEmpty_Explanation": "CostPurchase, PriceRecommended",
    "IgnoreSkuPriceListFieldsWhenEmpty": [4, 6],
    "SerializationType": 0,
    "_SkuPriceListFieldsThatAreSet_Explanation": "CostUnit, PriceRecommended, IsActive",
    "SkuPriceListFieldsThatAreSet": [5, 6, 10]
}


[
    {
        "_comment": "Price recommended and cost will be updated, overwrite values that already exist",
        "CostUnit": 2000,
        "CurrencyCode": "SEK",
        "IsActive": 1,
        "PartNo": "ERPPartNo0000004-1",
        "PriceListCode": "STD",
        "PriceRecommended": 4999,
        "QuantityBreak": 1
    },
    {
         "_comment": "Price recommended will be updated, costs will be ignored since they are null",
        "CostUnit": null,
        "CurrencyCode": "SEK",
        "IsActive": 1,
        "PartNo": "ERPPartNo0000004-2",
        "PriceListCode": "STD",
        "PriceRecommended": 5999,
        "QuantityBreak": 1
    }
]

Company price lists

To set company or customer price lists you need to do three things

  1. Create the price list
  2. Update the price list with SkuPriceList items
  3. Add the price list to the customer or company
Example calling ImportPriceList in Norce Commerce Connect
  1. Create a price list

https://connect.lab.storm.io/4.0//api/Product/ImportPriceLists


{
    "AccountId": 0,
    "FullFile": false,
    "_PriceListFieldsThatAreSet_Explanation": "Name, CurrencyCode, StartDate, EndDate, IsPublic, Warehouses, Description",
    "PriceListFieldsThatAreSet": [0, 1, 2, 3, 4, 7, 9],
    "SerializationType": 0,
    "_WarehouseFieldsThatAreSet_Explanation": "No values, only code is used.",
    "WarehouseFieldsThatAreSet": [],
    "_WarehouseLocationFieldsThatAreSet_Explanation": "No values, only code is used.",
    "WarehouseLocationFieldsThatAreSet": []
}



[
    {
    	"_comment": "Company price list, with fixed price rule Use recommended price Fixed price",
        "Code": "ContractYYY",
        "CurrencyCode": "SEK",
        "Description": "Price list from the ERP System with contract prices for Company XXX",
        "EndDate": "2025-10-01Z",
        "IsPublic": false,
        "Name": "Contract prices for customer XXX",
        "StartDate": "2023-04-01Z",
        "Warehouses": [
            {
            	"_comment": "A price list must have association to at least one warehouse.",
                "Code": "STD",
                "Locations": [
                    {
                        "Code": "STD"
                    }
                ]
            }
        ]
    }
]

  1. Update SkuPriceLists

Same as examples above

  1. Add the price list to the customer or company (showing Companies, since that is the most common scenario)

https://connect.lab.storm.io/4.0/api/Customer/ImportCompanies


{
    "AccountId": 0,
    "FullFile": false,
    "_AccountFieldsThatAreSet_Explanation": "n/a",
    "AccountFieldsThatAreSet": [],
    "_CompanyFieldsThatAreSet_Explanation": "Code, PriceLists",
    "CompanyFieldsThatAreSet": [2, 19],
    "_CustomerFieldsThatAreSet_Explanation": "None",
    "CustomerFieldsThatAreSet": []
}




[
    {
        "Id": null,
        "Code": "XXX",
        "Name": "Company XXX",
        "PriceLists": [
            {
                "Code": "ContractYYY",
                "IsExclusive": false
            }
        ]
    }
]

Update prices in ERP

For many scenarios, prices are handled in Norce, and later passed on to other systems, like the ERP. In this case, the ERP can handle other related information like cost that Norce need to set up its rules, see cost (coming) for more. But the primary responsibility for the ERP integration is to listen for changes to the prices in Norce and pass those on to the ERP. This is done by listening to events and calling Norce Commerce Query for the relevant information.

For Norce [Storm] clients:

Important information

The most important fields and their purpose:

FieldEntityDescription
PartNoProductSkuPricelistIdentifies the product
PriceListIdProductSkuPricelistIdentifies the price list (internal norce id, lookup id from code in separate lookup)
QtyBreakProductSkuPricelistThreshold value, determines minimum number of items required for getting this price, you can have many prices therefore on same product and price list, if they have different quantitybreak
CurrencyIdProductSkuPricelistthe currency of the price list (internal noce id, lookup id form code in separate lookup)
PriceSaleProductSkuPricelistcalculated sale price, either a fixed value or calculated based on price rules
CostPurchaseProductSkuPricelistthe cost of the item or service when purchased from supplier, see cost (coming) for more.
PriceStandardProductSkuPricelistold price, inherited from parent, is null if no parent price list exist
PriceRecommendedProductSkuPricelistrecommended price, MSRP. Can be inherited from parent or from supplier
ChosenSupplierIdProductSkuPricelistif exist, there is a preferred supplier that the pricing business rules uses, lookup the supplier code separatelt if you need.
ChosenSupplierPartNoProductSkuPricelistthe product identifier for the supplier, if you need to create a purchase request
ChosenSupplierPriceListIdProductSkuPricelistthe supplier's price list id, lookup separately if needed
ChosenSupplierQtyBreakProductSkuPricelistthreshold value from the supplier pricelist (rarely used)
IsActiveProductSkuPricelistif false, the price is disabled and the product is disabled on the pricelist, note that a disabled price record is no longer updated from business rules in Norce.
An example fetching price information from Norce Commerce Query

https://query.lab.storm.io/2.0//Products/ProductSkuPriceLists?$filter=in ('MyPartNo1', 'MyPartNo2') and PriceListId eq 1 and IsActive eq true&$select=PartNo,PriceListId,QtyBreak,CurrencyId,PriceSale,CostPurchase,PriceStandard,PriceRecommended,ChosenSupplierId,ChosenSupplierPartNo,ChosenSupplierPriceListId,ChosenSupplierQtyBreak


{
    "@odata.context": "https://query.lab.storm.io/Query/2.0/Products/$metadata#ProductSkuPriceLists(PartNo,PriceListId,QtyBreak,CurrencyId,PriceSale,CostPurchase,PriceStandard,PriceRecommended,ChosenSupplierId,ChosenSupplierPartNo,ChosenSupplierPriceListId,ChosenSupplierQtyBreak)",
    "value": [
        {
            "PartNo": "MyPartNo1",
            "PriceListId": 1,
            "QtyBreak": 1,
            "CurrencyId": 2,
            "PriceSale": 6375.2000,
            "CostPurchase": 5734.3440,
            "PriceStandard": 0.0000,
            "PriceRecommended": null,
            "ChosenSupplierId": 1545,
            "ChosenSupplierPartNo": "MySupplierPartNo1",
            "ChosenSupplierPriceListId": 16810,
            "ChosenSupplierQtyBreak": 1
        },
        {
            "PartNo": "MyPartNo2",
            "PriceListId": 1,
            "QtyBreak": 1,
            "CurrencyId": 2,
            "PriceSale": 583.0645,
            "CostPurchase": 1087.5480,
            "PriceStandard": 0.0000,
            "PriceRecommended": null,
            "ChosenSupplierId": 1545,
            "ChosenSupplierPartNo": "MySupplierPartNo2",
            "ChosenSupplierPriceListId": 16810,
            "ChosenSupplierQtyBreak": 1
        }
    ]
}

Event settings

Add events that should be used

You can either listen to SkuChangedNotification or SkuPriceChangedNotification.

SkuPriceChangedNotification is easier to set up, but will only trigger if SalePrice has changed, other changes, like PriceRecommended or a Cost will not trigger the event.

SkuPriceListChangedNotification will return several fields in the event message that you can use:

  • PartNo
  • PricelistId
  • PricelistCode
  • PriceSaleValue
  • QuantityBreak

SkuPriceChangedNotification has insted only PartNo and EntityChanged, and you must lookup in Norce Commerce Query more information. Here is an example on what you need to configure:

EntityOn InsertOn UpdateOn DeleteFilter
tClientProductSkuPriceListYesYes (see important fields above)NoFilter on relevant price lists that the ERP needs

Note that there is only one configured event per client and type, so if you already need SkuChangedNotification to other integrations, you need to add these settings to the same listener and merge your business logic.

Optional metadata

To get more information on entities referred only with an id in query, you need to to extra lookups. Make sure to lookup many at a time, instead of doing lookups for each product fetch. Put the response in your memory cache instead.

Price lists

If you need to access price list information there are two endpoint that is useful

  • ClientPriceList, has most information about the price list, start and end date, name, currency, etc.
  • ApplicationPricelist, has all the price lists that are specifically added to the application (ie all public price lists), an one important attrubute - IsPrimary, which is the most important price list on the application that has the holds the standard prices and assortments.
FieldEntityDescription
PriceListIdClientPriceListIdentifies the price list (internal norce id, lookup id from code in separate lookup)
NameClientPriceListName of the price list in the default language
AgreementClientPriceListIdentifier of the Price list (Note, renamed to Code in all contracts)
CurrencyIdClientPriceListthe currency of the price list (internal noce id, lookup id form code in separate lookup)
ParentPriceListIdClientPriceListpoint to the parent, if one exist
StartDateClientPriceListOptional start date
EndDateClientPriceListOptional end date
SalesAreaIdClientPriceListPrice lists can be tag:ed with a sales area, this lets Norce calculate and round prices correctly for prices inc vat

Note, the entity PriceList has some of the same fields as ClientPriceList, they are mostly deprecated, use ClientPriceList!

An example fetching price list information from Norce Commerce Query

Fetching all price lists https://query.lab.storm.io/2.0/Application/ClientPriceLists?$select=PriceListId,Name,Agreement,CurrencyId,ParentPriceListId,StartDate,EndDate,SalesAreaId

Fetching the primary price list for the current application: https://query.lab.storm.io/2.0/Application/ApplicationPriceLists?$filter=IsPrimary eq true

Lookup currency https://query.lab.storm.io/2.0/Core/Currencies

Sales area, see here

Supplier information

Sometimes you want additional supplier information about the price from Norce.

Note, you can read more about suppliers here (coming) .

An example lookup up more on chosen supplier from Norce Commerce Query

https://query.lab.storm.io/2.0/Products/SupplierProductSkus?$filter=PartNo eq 'chosensupplierpartno' and SupplierId eq supplierid&$expand=PriceLists($expand=PriceList($select=Id,DefaultName,Code);$select=SupplierId,SupplierPriceListId,QtyBreak,CurrencyId,CostPurchase,CostPurchaseLastChecked;$filter=SupplierPriceListId eq 16810),OnHands($select=WarehouseId,LocationId,OnHandValue,OnHandLastChecked)&$select=PartNo,SupplierId,Name


{
    "@odata.context": "https://query.lab.storm.io/Query/2.0/Products/$metadata#SupplierProductSkus(PartNo,SupplierId,Name,PriceLists(SupplierId,SupplierPriceListId,QtyBreak,CurrencyId,CostPurchase,CostPurchaseLastChecked,PriceList(Id,DefaultName,Code)),OnHands(WarehouseId,LocationId,OnHandValue,OnHandLastChecked))",
    "value": [
        {
            "PartNo": "chosensupplierpartno",
            "SupplierId": chosensupplierid,
            "Name": "",
            "PriceLists": [
                {
                    "SupplierId": chosensupplierid,
                    "SupplierPriceListId": chosensupplierpricelistid,
                    "QtyBreak": 1,
                    "CurrencyId": 1,
                    "CostPurchase": 580.0000,
                    "CostPurchaseLastChecked": "2017-02-14T09:40:44.96+01:00",
                    "PriceList": {
                        "Id": 16810,
                        "DefaultName": "Premium Supplies Standard Pricelist",
                        "Code": "STD1"
                    }
                }
            ],
            "OnHands": [
                {
                    "WarehouseId": 811,
                    "LocationId": 811,
                    "OnHandValue": 100.000,
                    "OnHandLastChecked": "2017-02-14T09:40:44.96+01:00"
                }
            ]
        }
    ]
}

Further reading