Přeskočit na hlavní obsah

Synchronizace adresáře z e-shopu

Typická úloha: v e-shopu vznikají zákazníci a je potřeba je dostat do iÚčta tak, aby při opakovaném běhu nevznikaly duplicity.

Ukázková čísla

ID, čísla dokladů a částky jsou vymyšlené. Endpointy, názvy polí a tvar odpovědí odpovídají referenci.

Klíč pro párování: external_code

Zákazník má pole external_code (Externí ID), které iÚčto nijak nepoužívá — je určené přesně pro tohle. Ukládejte do něj ID z vašeho systému a párujte podle něj, ne podle jména. IČO (comid) se hodí na jednorázové dohledání konkrétní firmy, na opakovanou synchronizaci ne: firma může IČO změnit a bez IČO ho nemá vůbec.

curl -s "https://online.iucto.cz/api/1.3/customer?external_code=ESHOP-1042" \
-H "X-Auth-Key: $IUCTO_API_KEY"

Když filtr nic nenajde, klíč _embedded v odpovědi vůbec není (ne prázdné pole) — takový zákazník ještě neexistuje → POST /customer. Jinak PUT /customer/{id}.

upozornění

Filtr podle external_code vrací seznam, ne jeden záznam. Nic nebrání tomu, aby si dva zákazníci nesli stejný kód, pokud je tam takhle zapíšete — ošetřete to na své straně a při nálezu více než jednoho záznamu radši spadněte s chybou, než abyste přepsali špatný.

Plátce vs. neplátce DPH

Tělo požadavku se liší jen v těchhle dvou polích:

{ "vat_payer": true, "vatid": "CZ12345679" }
{ "vat_payer": false }

U plátce je vatid povinné — vat_payer: true bez DIČ skončí chybou 400. Opačně to hlídané není: neplátce s vyplněným DIČ projde.

Průchod celým adresářem

Adresář se vrací vždy po stránkách. Maximum je 200 záznamů na stránku, což je i nejrozumnější velikost pro dávkový běh:

$page = 1;

do {
$url = 'https://online.iucto.cz/api/1.3/customer?' . http_build_query([
'page' => $page,
'pageSize' => 200,
]);

$ch = curl_init($url);
curl_setopt_array($ch, [
CURLOPT_RETURNTRANSFER => true,
CURLOPT_HTTPHEADER => ['X-Auth-Key: ' . getenv('IUCTO_API_KEY')],
]);

$data = json_decode(curl_exec($ch), true);

foreach ($data['_embedded']['customer'] as $customer) {
// ... zpracování
}

$page++;
} while ($page <= $data['pageCount']);
Pozor na posun stránek

Adresář se řadí podle času vytvoření sestupně a parametr sort u něj nefunguje — řadit jde jen u dokladů a plateb, a to podle jediného pole modified. Když vám tedy během dávky někdo založí zákazníka, stránky se posunou a jeden záznam přeskočíte.

Buď si dávku pusťte v době, kdy nikdo nezakládá kontakty, nebo si výsledky z jednotlivých stránek slučte podle id a duplicity zahoďte.

Rozpočet dotazů

Denní kvóta je vázaná na tarif firmy — kolik dotazů má který, je v Limitech a kvótách. Naivní implementace („na každého zákazníka z e-shopu jeden GET a jeden PUT") vyčerpá kvótu zkušebního tarifu u 1 000 zákazníků. Levnější je stáhnout si adresář jednou celý (5 dotazů na 1 000 záznamů), porovnat v paměti a volat PUT jen tam, kde se něco změnilo.

PUT je úplná náhrada

Tělo se skládá z celého záznamu, ne z diffu, a před úpravou je potřeba načíst detail zákazníka — seznam vrací jen část polí. Podrobně to popisují Datové typy.

Co si připravit před prvním během

Tři věci si obstarejte dřív, než synchronizaci pustíte — API je samo nedoplní a bez nich PUT a POST buď zahodí hodnotu, nebo skončí chybou.

  • Skupiny zákazníkůcustomer_group_id musí existovat předem, API ho samo nezaloží.
  • Výchozí středisko a zakázkudefault_department_id, default_contract_id; opět je potřeba mít ID z odpovídajících číselníků.
  • Bankovní účty zákazníka — pole account_number1account_number4 se validují: projde jen IBAN, nebo tvar předčíslí-číslo/kód banky. Cokoli jiného skončí chybou 400.

Kam dál