Skip to main content

Shipping cost calculations

Kalkulačka dopravy v BC

Vytvořili jsme externí službu "Kalkulačky dopravy" běžící na našem webovém serveru, která skrze REST API předá na výstupu informace o tom, kolik bude stát doprava pro danou zásilku.

V tuto chvíli je Kalkulačka volána eshopem, který tak získává cenu dopravy a tu posílá jako součást objednávky do BC.

Eshop ale tvoří jen cca 20% všech našich objednávek a my potřebujeme mít možnost Kalkulačku zavolat přímo z BC, abychom napočítali cenu dopravy pro zbývajících 80% vznikajících objednávek.

 

Od Aricomy potřebujeme zajistit propojení této služby s kartou Prodejní objednávky tak, aby po spuštění této funkce "tlačítkem" zaměstnancem SOLSOLu přibyl do prodejní objednávky řádek s napočítanou cenou dopravy, která bude nejvýhodnější pro dané zboží a danou dodací adresu, anebo s poznámkou, že dopravu nelze spočítat.

Tedy, v případě úspěšného zavolání kalkulačky

  • přidat řádek "P-Přeprava" s cenou dopravy SOLSOL
  • Kódy lokace pro zboží upravit na lokaci, kterou vrátí kalkulačka

V případě neúspěšného zavolání:

  • přidat řádek "poznámka" s informací s chybovým hlášením, které kalkulačka posílá na výstup. Někdy je důvodem neúspěchu nedostatek zboží na skladě, někdy termín dodávky či chyba v dodací adrese (validace na PSČ neproběhne úspěšně - protože je třeba v PSČ překlep). Zaměstnanec Backoffice by pak sjednal nápravu a kalkulačku zavolal znovu s opravenými hodnotami.

 

POSTMAN kolekci s ukázkou volání přikládám k tomuto ticketu.

 

API klíč:

babb6901505a4d93023b157022665aa9e4a359852f800d7d2719ff8b11e33097

 

Programátorský kontakt na kalkulačku je: Michal Gottstein <michal.gottstein@insolutions.io>

 

 

Pro lepší pochopení jak kalkulačka funguje. Logika a možnosti jsou v tuto chvíli takovéto:

  • počítá cenu dopravy z některého z pickovacích skladů SOLSOL (nyní Olomouc a Ústí nad Labem). Jiné sklady nebere v potaz.
  • Data o skladové dostupnosti si Kalkulačka bere z BC ve chvíli zavolání.
  • Pokud je všechno zboží z objednávky na alespoň jednom z pickovacích skladů a jsou splněny další omezující podmínky související s dopravci, tak vrátí "success" s detaily přepravy (včetně dopravce a konkrétní dopravní služby, rozdělení zboží na palety, hmotnosti, kilometráže, ceny dopravy bez DPH, atp.). Na pozadí proběhne napočítání všech různých relevantních způsobů přepravy a buď je vybrána ta s nejlepší cenou, nebo se vypisuje seznam všech proveditelných přeprav.
  • Pokud nelze objednávku uspokojit, vrátí chybové hlášení s důvodem proč nedošlo k uspokojení objednávky.

 

Kalkulačka má mnoho parametrů, se kterými ji lze volat. Většina z nich jsou volitelné. Omezují ale možnosti toho, zda je možné dopravu uspokojit.

 

Zde je ukázkové volání a komentáře k němu:

 

 

{

  "delivery": {

    "country": "SK",

    "city": "Bardejov",

    "street": "Bardejovská Nová Ves 3092",

    "zip": "08501"

  },

  "Items": [

    {"plu": "104552", "amount": 15},

    {"plu": "417012", "amount": 2}

  ],

  "order_id": "TEST_ORDER",

  "pricing_list": "VIP",

  "off_stock_included": false,

  "best_price": true,

  "desired_delivery_date": "2025-03-30",

  "dispatch_datetime": "2024-11-10T10:00:00",

  "carrier_code": "toptrans",

  "multi_warehouse": true,

  "sort_by": "price",

  "sort_order": "ASC"

  }

 

 

"delivery" - v BC jde o dodací adresu

"Items" - jednotlivé řádky Prodejní objednávky s PLU a počtem kusů

"order_id": "TEST_ORDER" - volitelný parametr pro identifikaci objednávky. Z BC bychom sem měli ideálně zapisovat ID objednávky (číslo objednávky z číselné řady)

"pricing_list": "VIP" - cenová skupina zákazníka dle BC

"off_stock_included": false - ponechat vždy FALSE. Hodnota TRUE je pro účely nezávazného nacenění ceny dopravy nezávisle na tom, zda zboží máme nebo nemáme skladem. To ale v tomto use-case není relevantní.

"best_price": true - vrací pouze jedno konkrétní dopravu s nejlepší cenou. Pokud bychom dali FALSE, tak na výstupu bude více cen, které budou dle třídícího pravidla seřazeny na výstupu. Hodnota TRUE slouží spíše pro testování kalkulačky, než pro co jiného.

"desired_delivery_date": "2025-03-30", - předpokládané datum dodání, pokud zákazník požaduje doručení do určitého data (brzká data mohou znamenat, že to není možné doručit a doprava není možná)

"dispatch_datetime": "2024-11-10T10:00:00", - časová značka kdy je doprava volaná (pro simulaci dopravy v minulosti nebo v budoucnosti). Volitelný parametr. Pokud se nepoužije, kalkulačka bere jako čas volání daný okamžik.

  "carrier_code": "toptrans" - v BC jako kód dopravce, potřebujeme být pro BC case sensitive? Toto pole se použije, pokud je z nějakého důvodu v BC již vyplněno (preferovaný dopravce, nebo Vlastní doprava). Pokud není vyplněno, kalkulačka zvolí nejlepšího dopravce pro dané zboží, čas, lokalitu, a další omezující podmínky, které máme ve správě dopravců nastaveny.

  "multi_warehouse": false, - základní hodnota je "false", tedy na výstup se vypíše cena jen pro jeden sklad. Hodnota TRUE slouží pro testování výstupů, že jsou zvažovány všechny možnosti.

  "sort_by": "price", - volitelný parametr pro řazení výstupů v případě, že best_price je FALSE.

  "sort_order": "ASC", - volitelný parametr pro řazení výstupů v případě, že best_price je FALSE

 

 

 

Příklad výstupu

 

{

    "status": "success",

    "normal_weight": 435.02,

    "volume": 0.14,

    "paletts_count": 2,

    "paletts": [

        {

            "dimensions": {

                "length": 120,

                "width": 80,

                "height": 15

            },

            "weight": 434,

            "volume": 0.144,

            "items": [

                {

                    "plu": "104552",

                    "quantity": 15

                }

            ]

        },

        {

            "dimensions": {

                "length": 0,

                "width": 0,

                "height": 0

            },

            "weight": 1.02,

            "volume": 0,

            "items": [

                {

                    "plu": "417012",

                    "quantity": 2

                }

            ]

        }

    ],

    "warehouses": [

        {

            "warehouse_code": "OLOMOUC",

            "warehouse_name": "Sklad Olomouc",

            "address": "Hybešova 1291/14, Olomouc, 779 00, CZ",

            "distance": "392.60",

            "couriers": [

                {

                    "carrier_code": "TOPTRANS",

                    "volumetric_weight": 35,

                    "unloading": "carrier",

                    "price": {

                        "CZK": "5171.00",

                        "EUR": "205.97"

                    },

                    "price_solsol": {

                        "CZK": "5429.55",

                        "EUR": "216.27"

                    },

                    "surcharge": {

                        "CZK": "0.00",

                        "EUR": "0.00"

                    },

                    "delivery_date_estimate": "2024-11-13"

                }

            ]

        }

    ]

reservations: [

{

plu: xyz,

quantity: 1,

warehouse_code: Olomouc

},

{

plu: xyz2,

quantity: 3,

warehouse_code: Usti

},

]

}

 

 

Pozornost je třeba věnovat zejména atributům:

"warehouse_code": "OLOMOUC", - kód lokace dle BC pro danou objednávku. Typicky je vše zboží rezervováno jen vůči jednomu z pickovacích skladů. Je to lokalita, vůči které se následně objednává odvoz zboží dopravcem k zákazníkovi.

"unloading": "carrier", - zde jsou možnosti buď "carrier" nebo "customer". Pokud je na výstupu "Customer", pak je třeba na kartě objednávky zaškrtnout na TRUE pole "VZV" (vysokozdvižný vozík)

"price_solsol" - cena dopravy, kterou SOLSOL zákazníkovi naúčtuje. Tato cena je cenou BEZ DPH.

"delivery_date_estimate": "2024-11-13" - předpokládané datum dodávky. Aktuálně s ním v BC nepracujeme a nebude třeba jej nikam zatím zapisovat. Časem to ale bude pravděpodobně v Přislíbeném datu příjmu.

reservations: - pole s výčtem jednotlivých položek a vůči jakému skladu mají být rezervovány. Máme speciální případ fungování skladu USTI a USTINEPANEL, které jsou reálně dvě fyzické lokality, ale z pohledu expedice se chovají jako jeden sklad, protože nám firma zajišťující služby skladu sváží na své náklady zboží z těchto dvou lokalit na jednu, ze které se shipuje ven. Rezervace je ale třeba provést vůči konkrétním skladům. BC by tedy mělo řádky prodejní objednávky aktualizovat na lokaci dle Reservations. Skladba zboží na těchto dvou skladech v Usti nad Labem je disjunktní, tak by nemělo nastat to, že by pár kusů například panelů bylo rezervováno na jednom skladu a další kusy na druhém (to by jinak mělo za následek nutnost rozdělit řádky objednávky).

 

 

Příklad neúspěšného volání:

 

{

    "status": "error",

    "message": "The given data was invalid.",

    "errors": {

        "desired_delivery_date": [

            "The desired delivery date field must be a date after today."

        ]

    }

}

 

V takovém případě chceme vytvořit u objednávky řádek Poznámka se obsahem řádku jako zřetězením "message"+"error message". V tomto případě tedy:

"The given data was invalid. The desired delivery date field must be a date after today."