Přenos dat z prima:Time do ABRA Flexi

Prima:Time je šikovná cloudová aplikace z rodiny produktů ABRA Software. Jedná se o nástroj na sledování času stráveného na týmových projektech (Timetracking) a jeho následné vyfakturování zákazníkovi (Billing). V prima:Time lze rovněž sledovat docházku pomocí modulu Attendance. Prima:Time stejně jako ABRA Flexi má propracované API rozhraní a není tedy problém tyto dva systémy propojit.

Rozhraní API v každé aplikaci funguje v jistých směrech odlišně. Pokud jste již zběhlí v používání API v ABRA Flexi, na odlišnosti API prime:Time si budete muset teprve zvyknout.

API klíč

Nejprve je potřeba získat API klíč, který umožní API využívat. Pro získání je nutné kontaktovat podporu pomocí dotazu přímo v chatu uvnitř aplikace nebo napsat e-mail na adresu support@primatime.com. Jakmile vám dorazí e-mail s vygenerovaným klíčem, můžete začít s nastavováním.

Autentizace a následné dotazy

API prima:Time se od Flexi odlišuje také postupem, jak získávat data. U Flexi je možné využít HTTP autentizaci a získat tak potřebná data hned prvním dotazem. V prima:Time API je nutné se nejprve přihlásit. Při přihlášení se vygeneruje token s omezenou platností, a ten se pak používá pro jednotlivé dotazy do API. Jakmile tokenu vyprší platnost, je nutné získat nový.

Tento princip lze použít i ve Flexi, ačkoliv je užitečný spíše jen pro uživatele webového rozhraní. Má ale jednu nespornou výhodu. Pokud je používán správně, tzn. token se získává až v okamžiku, kdy vyprší, zrychluje zpracování dotazů. Flexi totiž nemusí pro každý dotaz vytvářet nová sezení a načítat spousty dat do vyrovnávací paměti. Vytvoření sezení a načtení dat do cache se tak provede jen jednou. Popis, jak využívat tento způsob autentizace, je popsán v dokumentaci Flexi API v sekci Přihlašování.

Pro získání autentizačního tokenu je potřeba poslat GET požadavek na adresu

https://{tenant}.api.primaerp.com/v1/auth/login?apikey={apikey}

{tenant} nahradíme názvem účtu v prima:Time

{apikey} nahradíme API klíčem získaným od podpory prima:Time.

V hlavičce Authorization musí být ještě navíc jméno a heslo uživatele prima:Time.

Získání účtů z prima:Time

Pokud jste tedy přihlášeni a máte platný autentizační token, můžete z prima:Time začít načítat data. Pro tento scénář potřebujete získat seznam účtů, které pak přenesete do Flexi.

Seznam účtů se nachází na adrese /v1/billing/bills. Stejně jako u Flexi je možné data získat ve dvou formátech. Výběr formátu je stejný jako u Flexi. Data v XML získáte doplněním koncovky .xml, data ve formátu JSON doplněním koncovky .json. Do URL také musíte přidat parametr token.

Kompletní URL pro získání JSON dat o účtech z prima:Time je tedy

https://{tenant}.api.primaerp.com/v1/billing/bills.json?token={token}

Ukázka dat v JSON formátu:

[

    {
        "id": "1b5127a5-b8c3-4adf-a961-0cad42f718a3",
        "createdAt": "/Date(1495654409685)/",
        "updatedAt": null,
        "version": 0,
        "docNumber": "2017/001",
        "docDate": "/Date(1495576800000)/",
        "vatDate": "/Date(1495576800000)/",
        "dueDate": "/Date(1496786400000)/",
        "lastPaymentDate": null,
        "description": "FlexiBee System s.r.o. - 2017-05",
        "notes": null,
        "vatText": null,
        "header": null,
        "footer": null,
        "itemsPrice": 21300.0,
        "totalPrice": 25773.0,
        "client": {
            "id": "c46d9eca-585b-4d2a-ba2c-1c93da0ea08c",
            "createdAt": "/Date(1495654059779)/",
            "updatedAt": "/Date(1495732307124)/",
            "version": 4,
            "externalSystem": null,
            "externalResourceId": null,
            "externalBrowsableUrl": null,
            "externalSyncedAt": null,
            "externalSynced": null,
            "name": "FlexiBee System s.r.o.",
            "code": "FLEXIBEE",
            "email": "podpora@flexibee.eu",
            "active": true,
            "billsCount": null,
            "projectsCount": null,
            "streetAddress": "Lochotínská 18",
            "additionalAddressInfo": null,
            "zipCode": "30100",
            "city": "Plzeň",
            "state": "Plzeňský kraj",
            "countryCode": "CZE",
            "phone": "371 124 321",
            "vatId": "CZ28019920",
            "website": "www.flexibee.eu",
            "displayName": "FlexiBee System s.r.o."
        },
        "contactPerson": null,
        "approved": false,
        "items": [
            {
                "id": "636da95d-e19a-48cf-83e3-698a89a4108b",
                "createdAt": "/Date(1495654409685)/",
                "updatedAt": null,
                "version": 0,
                "attributes": "JSON{\"duration\":\"63900000\"}",
                "itemGroup": "trbi",
                "docIndex": null,
                "quantity": 17.75,
                "price": 21300.0,
                "unitPrice": 0.0,
                "unit": null,
                "displayName": "#null"
            }
        ],
        "author": {
            "id": "9e3c6b13-dc81-4630-9a21-3b9ab4023e60",
            "createdAt": "/Date(1495653967694)/",
            "updatedAt": "/Date(1495818089532)/",
            "version": 5,
            "firstName": "Kája",
            "lastName": "z Norska",
            "nickName": "z Norska, K.",
            "email": "kbel@flexibee.eu",
            "phone": null,
            "position": "A02200",
            "timeZone": "Europe/Berlin",
            "dateFormat": "dd.MM.yyyy",
            "timeFormat": "HH:mm",
            "weekStart": 1,
            "language": "cs_CZ",
            "password": null,
            "secretKey": null,
            "confirmed": true,
            "confirmedEmail": true,
            "active": true,
            "birthdayRemind": null,
            "workingTimeStart": null,
            "workingTimeEnd": null,
            "created": "/Date(1495653967694)/",
            "admin": false,
            "projectManager": false,
            "displayName": "z Norska Kája"
        },
        "groupAttributes": "JSON[[\"\"],null]",
        "draft": false,
        "vatMode": "DECLARE_VAT",
        "vats": [
            {
                "id": "d0a1fbe9-ee92-495d-940b-b89accd586e2",
                "createdAt": "/Date(1495654409685)/",
                "updatedAt": null,
                "version": 0,
                "vatRate": 21.0,
                "vatPrice": 4473.0,
                "displayName": "21.0"
            }
        ],
        "displayName": "2017/001"
    }

]

Převedení a zápis dat do ABRA Flexi

Načtená data z prima:Time je potřeba transformovat do podoby, kterou umí Flexi zpracovat a následně zapsat do patřičné evidence. Účty z Billingu je možné zapsat například do evidence vydané faktury, kde je pak můžeme zaúčtovat.

V prima:Time je u účtu evidováno vše potřebné pro vytvoření nové faktury vydané. Jen typ dokladu nastavíte napevno v můstku.

Zápis do ABRA Flexi je popsán v článku PHP JSON zápis dat do ABRA Flexi.

Ukázkový PHP script pro přenos účtů

function curl_get($url){
  $ch = curl_init(); // create curl resource 
  curl_setopt($ch, CURLOPT_RETURNTRANSFER, TRUE); // return content as a string from curl_exec
  curl_setopt($ch, CURLOPT_HTTPAUTH, TRUE); // HTTP authentication
  curl_setopt($ch, CURLOPT_USERPWD, "emailova@adresa.cz:heslo"); // set username and password
  curl_setopt($ch, CURLOPT_URL, $url); // set URL
  curl_setopt($ch, CURLOPT_CUSTOMREQUEST, "GET"); // set HTTP method
  $output = curl_exec($ch); 
  $info = curl_getinfo($ch);
  if (curl_getinfo($ch, CURLINFO_HTTP_CODE) != 200 && curl_getinfo($ch, CURLINFO_HTTP_CODE) != 201) {
    printf ("Při operaci nastala chyba (HTTP %d): %sn", curl_getinfo($ch, CURLINFO_HTTP_CODE), $output);
  }
  curl_close($ch);
  return $output;
}

function curl_put($url, $json_data){
  $ch = curl_init(); // create curl resource
  curl_setopt($ch, CURLOPT_RETURNTRANSFER, TRUE); // return content as a string from curl_exec
  curl_setopt($ch, CURLOPT_HTTPAUTH, TRUE); // HTTP authentication
  curl_setopt($ch, CURLOPT_USERPWD, "winstrom:winstrom"); // set username and password
  curl_setopt($ch, CURLOPT_URL, $url); // set URL
  curl_setopt($ch, CURLOPT_CUSTOMREQUEST, "PUT"); // set HTTP method
  curl_setopt($ch, CURLOPT_POSTFIELDS, $json_data); // set data
  $output = curl_exec($ch); // execute

  // Flexi return value
  header("Content-Type: application/json");
  print ($output);
  
  // close curl resource to free up system resources
  curl_close($ch);
}

function parse_date($primaerp_date, $to_format){
  $timestamp = preg_replace('/[^\d]/','', $primaerp_date)/1000;
  $datetime = new DateTime();
  $datetime->setTimestamp($timestamp);
  return $datetime->format($to_format);
}

// authentication
$url = "https://tenant.api.primaerp.com/v1/auth/login?apikey=abcdefgh-1234-5678-ijkl-mnopqrstuv";
$output = curl_get($url);
$json = json_decode($output, true);

// token for api requests
$apiToken = $json['token'];
echo $apiToken;

// request for billing data
$url = "https://tenant.api.primaerp.com/v1/billing/bills.json?token=".$apiToken;
$output = curl_get($url);

$billing_json = json_decode($output, true);

// transform data for Flexi
$faktury = array(
  "winstrom" => array (
    "faktura-vydana" => array()
  )
);

foreach($billing_json as $bill){
  $faktura = array();
  $faktura['id'] = array();
  array_push($faktura['id'], 'ext:primaerp:'.$bill['id']);
  array_push($faktura['id'], 'code:'.$bill['docNumber']);

  $faktura['typDokl'] = 'code:FAKTURA-PRIMAERP';
  $faktura['kod'] = $bill['docNumber'];
  $faktura['bezPolozek'] = 'true';
  $faktura['sumZklZakl'] = $bill['itemsPrice'];
  $faktura['sumCelkZakl'] = $bill['totalPrice'];
  $faktura['firma'] = 'code:'.$bill['client']['code'];
  $faktura['firma@if-not-found'] = "create";
  $faktura['nazFirmy'] = $bill['client']['name'];
  $faktura['ulice'] = $bill['client']['streetAddress'];
  $faktura['psc'] = $bill['client']['zipCode'];
  //$faktura['stat'] = 'code:'.$bill['client']['countryCode'];
  $faktura['stat'] = 'code:CZ';
  $faktura['dic'] = $bill['client']['vatId'];
  $faktura['datVyst'] = parse_date($bill['docDate'], 'Y-m-d');
  $faktura['duzpPpuv'] = parse_date($bill['vatDate'], 'Y-m-d');
  $faktura['datSplat'] = parse_date($bill['dueDate'], 'Y-m-d');

  array_push($faktury['winstrom']["faktura-vydana"], $faktura);
}

// write to Flexi
$url = "https://demo.flexibee.eu/c/demo/faktura-vydana.json";
$output = curl_put($url, json_encode($faktury));
?>

Ukázka přenosu z prima:Time na demo.flexibee.eu:

{"winstrom":{"@version":"1.0","success":"true","stats":{"created":"0","updated":"1","deleted":"0","skipped":"0","failed":"0"},"results":[{"id":"3468","request-id":"code:2017/001","request-id":"ext:primaerp:1b5127a5-b8c3-4adf-a961-0cad42f718a3","ref":"/c/demo/faktura-vydana/3468.json"}]}}

Prohlédněte si také ukázku vytvořené faktury.

Závěr a zhodnocení

V tomto příkladu jsou vytvářeny „bezpoložkové“ faktury. Není ale žádný problém začít vytvářet i položkové. Stačí jen podle kolekce items vytvořit patřičné položky faktury. Dalším možným vylepšením celého přenosu je využití filtrace, díky níž lze přenášet například jen schválené účty nebo účty, které se změnily od poslední synchronizace. Filtrace je popsána v dokumentaci prima:Time v sekci Filtering.

Přes API je možné přímo načítat také údaje z modulu Timetracking, zapisovat je do patřičných složek ve mzdách Flexi, a zaměstnancům pak podle odpracovaných hodin počítat výplaty.

Opačným směrem z Flexi do prima:Time je možné přenést celý adresář nebo seznam zaměstnanců, kteří si mají evidovat čas.

Hledáte-li k ABRA Flexi spolehlivý docházkový systém, je prima:Time jistě správnou volbou. Navíc nabízí možnost, jak automaticky přenášet data z jednoho systému do druhého.