REST API
Data z pokladen jsou pravidelně synchronizována do cloudu a zpřístupněna přes REST API.
API je v současné době poskytováno v omezeném režimu. Do budoucna plánujeme expiraci autorizačního tokenu. Pokud chcete získávat kontinuáně data a synchronizovat systémy doporučujeme používat Webhooky. Jedná se o efektivnější způsob.
Autorizace požadavku
Autorizace probíhá pomocí API Tokenu, který naleznete v Backoffice - Nastavení - Systém.
Autorizační klíč je v HTTP hlavičce Authorization: A|xxxxx
curl -XGET 'https://m6vadtaz1h.execute-api.eu-west-1.amazonaws.com/prod/data/products' \
-H 'Authorization: A|kLgT.........' \
-H 'Content-Type: application/json'
POST přííklad:
curl -XPOST 'https://m6vadtaz1h.execute-api.eu-west-1.amazonaws.com/prod/data/reports/generic/order_history' \
-H 'Authorization: A|kLgT.........' \
-H 'Content-Type: application/json' \
--data-raw '{"date_start":1639436400000,"date_end":1642028399999,"timezone":"Europe/Prague","id_cash_register":953221254382092,"id_shop":492696696397774}' \
Konvence
- Časy jsou reprezentovány v unix timestamp v millisekundách. Např. 1639436400000
- Monetární hodnoty (tržba, cena, atd) jsou vždy celé číslo, vynásobené 1000. Např. cena 23.50 je v JSON dokumentu jako 23500.
- Autorizační token nemá expiraci, ale do budoucna plánujeme že token bude muset být vyměněn za nový
- Do User Agent prosím vložte svoji identifikaci případně kontakt, abychom měli kontakt na vývojáře
- Pokud navrácený objekt obsahuje položku, která začíná na
__
tak se jedná o tzv. hydrataci - objekt je automaticky obohacen o child objekty, aby vývojář nemusel provádět další dotazy na API. - Převod id na čas lze provést pomocí funkce:
new Date((id / 32768) + 1440000000000);
Společné pole
id_c
- globální ID zákazníka_v
- verze objektu_d
- indikuje jestli byl záznam označen jako smazaný_t
- název tabulkypgx
- složený interní primární klíč - ignorujte, pokud se vyskytuje- pole s prefixem
date_
jsou Unix UTC čas v millisekundách - pole s prefixem
id_
jsou relace a odkaz na záznam v jiné tabulce. Napřid_shop
odkazuje na id obchodu v tabulce shops.
Funkce pro práci s id
Id je číslo složené z času, id tabulky a náhodného suffixu. Příklad výpočtu:
const EPOCH = 1440000000000;
// Vrati objekt s datem a id tabulky
function getDateFromId(id) {
return {
dt: new Date((id / 32768) + EPOCH),
tableId: (id / 512) & 0x3f
}
}
// Generuje id pro konkretni tabulku - pouzijte 0 pro referenci
function getRandomRowId(tableId) {
let ts = new Date().getTime() - EPOCH;
let randid = Math.floor(Math.random() * 512);
ts = (ts * 64);
ts = ts + tableId;
return (ts * 512) + (randid % 512);
}
Seznam endpointů
Následující endpointy podporují metody GET (získání seznamů dat json array) i POST (vytvoření nebo aktualizace jednoho objektu). Metoda POST podporuje i zaslání více objektů v JSON Array. Lze využít pro dávkové aktualizace více objektů.
Base URL: https://m6vadtaz1h.execute-api.eu-west-1.amazonaws.com/prod/data/
- products
- customers
- product_price_matrix
- shops
- cash_registers
- employees
- park_locations
- shifts
- stock_history
- stockup
- transactions
- warehouses
- order_details a orders - podporuje GET i POST - nedoporučujeme vytvářet nové objekty pomocí POST, proč?
GET products
Vrací JSON Array se seznamem produktů. Položky které jsou smazané, mají nastaveno _visible = false
CURL příklad
curl 'https://m6vadtaz1h.execute-api.eu-west-1.amazonaws.com/prod/data/products' \
-H 'Authorization: A|......'
Odpověď
[
{
"unit": 0,
"date_updated": 1641499263724,
"attributes_bitmask": 8208,
"__price_matrix_model": {
"date_starts": 1640070857424,
"unit_price_base_tax_incl": 550,
"unit_price_regular_tax_excl": 454546,
"unit_price_c_tax_excl": 0,
"credits_deduct": 0,
"hour_bitmask": 0,
"points_deduct": 0,
"reduction_amount_a_tax_excl": 0,
"id_exec_rule": 0,
"id_product": 6555921856010421,
"unit_price_b_tax_excl": 0,
"dow_bitmask": 0,
"price_bitmask": 0,
"unit_price_base_tax_excl": 454.5455,
"id_shop": 0,
"currency": "CZK",
"unit_price_a_tax_excl": 454546,
"id": 6555922259744395,
"id_warehouse": 953221254427235,
"_t": "product_price_matrix",
"_v": 1641499263728
},
"condition_type": 0,
"name": "Cesta",
"id_category": 5723345161520367,
"node_sort": -6680027574804497000,
"inventory_management": false,
"id": 6555921856010421,
"id_shop": 0,
"color": 0,
"visible": true,
"tax_pst_rate": 1.21,
"item_type": 0,
"icon_code": 0,
"quantity_minimal": 1,
"quantity_multiple": 1,
"id_c": 111111,
"_t": "products",
"_v": 1641499263746
}
]
GET product/{id}
Vrací jednotlivý produkt podle ID objektu. Pro ceny volejte get-price-by-product-id/
https://m6vadtaz1h.execute-api.eu-west-1.amazonaws.com/prod/data/products/{id}
Odpověď
{
"unit": 0,
"pgx": "111:products",
"description_short": "Vydařená kombinace rumu a griotky",
"date_updated": 1647012279153,
"attributes_bitmask": 8240,
"sale_group_type": 0,
"condition_type": 1,
"name": "Čert",
"id_tax_rules_group": 0,
"id_category": 6783340285035904,
"node_sort": 3752073357922477000,
"accounting_group": 600000,
"warranty_length": 0,
"inventory_management": true,
"inventory_type": 0,
"id": 6783372795320333,
"id_shop": 0,
"tax_eco": 1,
"color": 0,
"visible": true,
"_d": 0,
"tax_luxury": 1,
"tax_pst_rate": 1.21,
"item_type": 0,
"additional_shipping_cost": 0,
"icon_code": 0,
"warranty_type": 0,
"_t": "products",
"quantity_minimal": 1,
"_v": 1681918519463,
"quantity_multiple": 1,
"id_c": 111111,
"id_exec_rule": 0
}
POST product
Vytvoří nový produkt. Použijte id produktu 0
pro nový objekt, nebo id existujícího produktu pro aktualizaci objektu. Pro informace o formátu objektu se podívejte do definice zod, viz níže.
Poznámky:
- id_shop=0 indikuje ze položka není omezena na žádnou pobočku
- attributes_bitmask= je bitmaska s atributy. Používají se bitové operace, hodnota se ukládá jako int
curl 'https://m6vadtaz1h.execute-api.eu-west-1.amazonaws.com/prod/data/products' \
-H 'Accept: application/json' \
-H 'Authorization: A|....' \
-H 'Content-Type: application/json' \
-d '{
"deleted": 0,
"id": 0, // Zero or omit to create new record
"_t": "products",
"image_dimension": null,
"notes_quick": "Sample quick notes",
"quantity_multiple": 1,
"quantity_minimal": 1,
"additional_shipping_cost": 0,
"date_updated": 1678886400000, // Example timestamp (replace as needed)
"inventory_management": false,
"color": 0,
"item_type": 0,
"id_category": 0,
"tax_luxury": 1.000,
"ean13": "1234567890123",
"id_tax_rules_group": 0,
"name_alternative": "Alt Product Name",
"sku": "PROD-SKU-001",
"tax_eco": 1.000000,
"barcode": "9876543210987",
"height": 10.5,
"visible": true,
"image_url": "https://example.com/image.jpg",
"warranty_length": 12,
"condition_type": 0,
"tax_pst_rate": 1.000,
"upc": "012345678901",
"weight": 1.2,
"icon_code": 0,
"details_url": "https://example.com/details",
"warranty_type": 0,
"tags": "sample,product",
"description_short": "Short product description",
"unit": 0,
"id_exec_rule": 0,
"depth": 5.0,
"sale_group_type": 0,
"id_global_product_code": null,
"accounting_group": 600000,
"name": "Sample Product Name",
"width": 7.8,
"node_sort": 0,
"attributes_bitmask": 0,
"inventory_type": 0,
"internal_extra": "Internal notes",
"id_shop": 0
}'
GET get-price-by-product-id/{id_product}
Vrací ceny pro konkrétní produkt v ceníku podle id produktu.
https://m6vadtaz1h.execute-api.eu-west-1.amazonaws.com/prod/data/products/get-price-by-product-id/{id_product}
GET product_price_matrix
Ceny k produktům. Je nutné napárovat pomocí id_product
https://m6vadtaz1h.execute-api.eu-west-1.amazonaws.com/prod/data/product_price_matrix
Odpověď
[
{
"currency": "CZK",
"unit_price_base_tax_excl": 30,
"id_warehouse": 4438373662962620,
"_d": 1,
"dow_bitmask": 0,
"credits_deduct": 0,
"hour_bitmask": 0,
"unit_price_base_tax_incl": 30,
"id_product": 4438453021022482,
"unit_price_regular_tax_excl": 30000,
"points_deduct": 0,
"date_starts": 1575450836824,
"price_bitmask": 0,
"_t": "product_price_matrix",
"unit_price_a_tax_excl": 30000,
"_v": 1633950008092,
"id": 4438454091814580,
"reduction_amount_a_tax_excl": 0,
"id_shop": 0,
"id_c": 1141932
}
]
GET categories
Seznam kategorií v hiearchické struktuře
https://m6vadtaz1h.execute-api.eu-west-1.amazonaws.com/prod/data/categories
Odpověď
[
{
"visible": true,
"_d": 0,
"name": "Cakes >",
"category_bitmask": 0,
"icon_code": 5,
"node_sort": 5000000,
"id_category_sort_after": 0,
"_t": "categories",
"_v": 1672597351272,
"id_category_parent": 0,
"id": 1,
"id_shop": 0,
"color": 17,
"id_c": 111111,
"children": [
{
"visible": false,
"name": "test",
"category_bitmask": 0,
"margin_minimal_rate": null,
"icon_code": 4,
"node_sort": 5000000,
"id_category_sort_after": 0,
"_t": "categories",
"_v": 1640029337604,
"id_category_parent": 1,
"id": 1067887041152062,
"id_shop": 0,
"margin": null,
"color": 5,
"tags": null,
"id_c": 111111,
"children": []
}
]
}
]
GET shops
Seznam poboček (shops)
https://m6vadtaz1h.execute-api.eu-west-1.amazonaws.com/prod/data/shops
Odpověď
[
{
"visible": true,
"currency": "CZK",
"_d": 0,
"name": "Shop 83",
"location_name": "City 44",
"_t": "shops",
"_v": 1677240349376,
"id": 492696696391111,
"bitmask": 0,
"id_c": 111111
}
]
GET cash_registers
Seznam poboček. Více o struktuře a závislosti na obchodech v manuálu zde.
https://m6vadtaz1h.execute-api.eu-west-1.amazonaws.com/prod/data/cash_registers
Odpověď
[
{
"visible": true,
"name": "Point of Sale 233",
"location_name": "Brno",
"_t": "cash_registers",
"_v": 1640802641284,
"cash_register_type": 11,
"id": 49269669639111,
"id_shop": 492696696397774,
"bitmask": 0,
"id_c": 11111
}
]
GET customers
Seznam zákazníků
curl 'https://m6vadtaz1h.execute-api.eu-west-1.amazonaws.com/prod/data/customers' \
-H 'Authorization: A|ADq
Odpověď
[
{
"customer_type": 0,
"credit_account": null,
"internal_extra": null,
"price_group": "A",
"zip_code": "40801",
"date_updated": null,
"email": null,
"city": "RUMBURK",
"bank_account": null,
"date_birthday": null,
"company": "Test s.r.o.",
"geohash": null,
"firstname": null,
"company_ico": "3332650",
"id": 3665795354036044,
"color": 0,
"bitmask": 0,
"tags": "csv-import-91",
"barcode": null,
"visible": true,
"id_discount_group": null,
"lastname": null,
"company_dic": "CZ33333",
"internal_json": null,
"_t": "customers",
"_v": 1551875000154,
"date_expires": null,
"phone_number": null,
"note_internal": null,
"country_code": "CZ",
"note_external": null,
"id_c": "11111",
"street": "17.8"
}
]
GET customer/{id}
Jednotlivý záznam pro zákazníka podle ID.
https://m6vadtaz1h.execute-api.eu-west-1.amazonaws.com/prod/data/customers/{id}
curl 'https://m6vadtaz1h.execute-api.eu-west-1.amazonaws.com/prod/data/customers/12344566' \
-H 'Authorization: A|ADqsEX...
GET orders
Vrací seznam účtenek (JSON Array), seřazené od nejnovějších po nejstarší.
Poznámky:
- Pokud je doklad zrušený nebo stornovaný, pole
date_canceled
obsahuje čas zrušení (not-null) reduction_percent
indikuje slevu v procentech poskytnutou zakaznikovi vynasobene 1000, uvedené jako celé číslo (integer). Tzn. hodnota 500 znamená, že byla poskytnuta sleva 0.5%
Parametry
- id_start - id záznamu od kterého se má stránkovat. výchozí hodnota 0 stránkuje od nejnovejší účtenky
- version_start - unix epoch timestamp (ms) filtr. Hodnota 0 znamená že se hodnoty nebudou filtrovat.
- limit - omezit počet záznamů, výchozí 250, maximum 2000. Velková velikost navráceného JSON nemůže přesáhnout 6MB
https://m6vadtaz1h.execute-api.eu-west-1.amazonaws.com/prod/data/orders?version_start=0&id_start={id_order}
GET orders/latest/{id_cash_register}
Posledních 40 orders z konkrétní pokladny podle id_cash_register. Metoda nepodporuje stránkování. Doporučujeme na získávání aktuálních objednávek v pravidelných intervalech pro systémy, které chtějí získávat online přehled o uskutečnených pohybech.
Query string parametry:
- id_payment (optional) - ID forma platby. Např 221: hotovost, 222: kreditní parta, 238: sumup
https://m6vadtaz1h.execute-api.eu-west-1.amazonaws.com/prod/data/orders/latest/{id_cash_register}?id_payment={id_payment}
Odpověď
[
{
"total_discounts_tax_excl": 0,
"currency": "CZK",
"pgx": "1141932:orders:4438373662917304",
"total_points": 0,
"id_employee": 0,
"date_closed": 1642005467495,
"total_credits": 0,
"id_payment": 222,
"total_paid_tax_excl": 50000,
"total_shipping_tax_excl": 0,
"total_tax_service": 0,
"total_paid_real": 50000,
"conversion_rate": 1,
"_u_dyn": 1642005490213,
"total_discounts_tax_incl": 0,
"geohash": "u2ugrgc",
"date_collected": 1642005467495,
"total_tip": 0,
"id_cash_register": 4438373662917304,
"id": 6619285123010267,
"dine_in": true,
"id_shop": 4438373662924485,
"total_products": 1,
"total_tax_gst": 0,
"total_profit_tax_excl": 0,
"order_serial_number": 130,
"summary": "1x Pure bar",
"id_park_location": 0,
"total_wrapping_tax_incl": 0,
"_d": 0,
"total_tax_eco": 0,
"total_tax_pst": 0,
"total_shipping_tax_incl": 0,
"id_employee_served": 0,
"date_paid": 1642005467185,
"id_shift": 6618245790277082,
"total_profit_tax_incl": 0,
"date_tax_reported": 1642005467495,
"_t": "orders",
"total_paid_tax_incl": 50000,
"_v": 1642005467521,
"total_wrapping_tax_excl": 0,
"total_tax_luxury": 0,
"invoice_number": 202012274,
"id_c": 1141932
}
]
GET order/{id_cash_register}/{id_order}
Umožní získat účtenku/doklad včetně položek v poli __order_details
https://m6vadtaz1h.execute-api.eu-west-1.amazonaws.com/prod/data/orders_details/{id_cash_register}/{id_order}
{
"total_discounts_tax_excl": 0,
"currency": "CZK",
"pgx": "1173665:orders:7694791899251239",
"total_points": 0,
"id_employee": 1,
"date_closed": 1684414596504,
"total_credits": 0,
"id_payment": 222,
"total_paid_tax_excl": 56522,
"total_shipping_tax_excl": 0,
"total_tax_service": 0,
"date_fiscalized": 0,
"total_paid_real": 65000,
"conversion_rate": 1,
"total_discounts_tax_incl": 0,
"date_collected": 1684414596504,
"total_tip": 0,
"id_cash_register": 7694791899251000,
"id": 8008974168592088,
"dine_in": true,
"id_shop": 7694791899258554,
"total_products": 2,
"total_tax_gst": 0,
"total_profit_tax_excl": 0,
"order_serial_number": 320,
"id_park_location": 0,
"total_wrapping_tax_incl": 0,
"_d": 0,
"total_tax_eco": 0,
"total_tax_pst": 8478,
"total_shipping_tax_incl": 0,
"id_employee_served": 1,
"date_paid": 1684414596504,
"id_shift": 7962837799869694,
"total_profit_tax_incl": 0,
"date_tax_reported": 1684414596504,
"_t": "orders",
"total_paid_tax_incl": 65000,
"_v": 1684414596517,
"total_wrapping_tax_excl": 0,
"total_tax_luxury": 0,
"invoice_number": 202305288,
"id_c": 11111,
"date_canceled": null,
"__order_details": [
{
"product_item_type": 0,
"currency": "CZK",
"pgx": "1173665:order_details:7694791899251239",
"total_points": 0,
"id_warehouse": 0,
"id_employee": 1,
"date_updated": 1684414596517,
"total_credits": 0,
"id_payment": 222,
"id_product": 7833117185743150,
"_u_dyn": 1684414622686,
"reduction_amount_tax_incl": 0,
"id_category": 7694792007615808,
"id_order": 8008974168592088,
"product_name_alternative": ":;en:Cappuccino",
"product_price_billed_tax_incl": 35000,
"id_order_details_parent": 1,
"id_cash_register": 7694791899251000,
"id": 8008976796814560,
"id_shop": 7694791899258554,
"product_quantity": 1,
"product_bitmask": 0,
"product_name": "Cappuccino",
"_d": 0,
"total_tax_eco": 0,
"total_tax_pst": 4565,
"reduction_amount_tax_excl": 0,
"product_price_billed_tax_excl": 30435,
"product_unit": 0,
"product_price_original_tax_excl": 30435,
"tax_pst_rate": 1.15,
"date_paid": 1684414596517,
"id_shift": 7962837799869694,
"_t": "order_details",
"_v": 1684414596517,
"order_number": 320,
"total_tax_luxury": 0,
"reduction_percent": 0,
"id_c": 11111,
"date_voided": null,
"date_canceled": null
}
]
}
GET order_details
Vrací položky účtenek. Jedná se o child kolekci objektu orders.
https://m6vadtaz1h.execute-api.eu-west-1.amazonaws.com/prod/data/order_details?version_start=0&id_start={id_order_details}
POST warehouse_status
Aktuální stav skladu. Je nutné zaslat JSON request s id_warehouse který určuje ID skladu, pro který chcete report.
curl 'https://m6vadtaz1h.execute-api.eu-west-1.amazonaws.com/prod/data/reports/generic/warehouse_status' \
-H 'Accept: application/json' \
-H 'Authorization: A|....' \
-H 'Content-Type: application/json' \
--data-raw '{"id_warehouse":953221250000000}'
Odpověď
{
"data": [
{
"id_c": 111111,
"id_warehouse": 953221254427235,
"wname": "WAREHOUSE MAIN 21",
"id_product": 5128991459121170,
"pname": "Aperol",
"cname": null,
"id_category": 4933809643652539,
"barcode": null,
"ean13": null,
"unit": 0,
"qty_cnt": 1,
"qty_sum": 3,
"qty_avg": 3,
"date_updated": 1641489385000,
"pp_avg": 10000,
"pp_unit": 10000
},
{
"id_c": 111111,
"id_warehouse": 953221254427235,
"wname": "WAREHOUSE MAIN 21",
"id_product": 4305305643161675,
"pname": "01.Vstup 8225",
"cname": "ACesty",
"id_category": 5723345161520367,
"barcode": null,
"ean13": null,
"unit": 0,
"qty_cnt": 1,
"qty_sum": 6,
"qty_avg": 6,
"date_updated": 1642004221000,
"pp_avg": 100000,
"pp_unit": 100000
}
],
"source": "query"
}
POST customers
Slouží k vytvoření nebo aktualizaci objektu zákazníka podle primárního klíče - pokud vytváříte objekt. neposkytujte ID objektu, bude automaticky vytvořeno. Schéma entity je popsána v zod níže.
curl 'https://m6vadtaz1h.execute-api.eu-west-1.amazonaws.com/prod/data/customers' \
-H 'Accept: application/json' \
-H 'Authorization: A|....' \
-H 'Content-Type: application/json' \
--data-raw '{...}'
Zasílání objednávek do pokladny
Připravujeme propojení pro zasílání externích objednávek do pokladního systému přes API. Kontaktujre prosím podpora@kasafik.cz pro více informací.
Vazby - Mermaid
Schema vazeb ve formátu Mermaid
erDiagram
Customer {
bigint id PK
}
Orders {
bigint id PK
bigint id_customer FK
bigint id_address_invoice FK
bigint id_address_delivery FK
bigint id_cash_register FK
bigint id_shift FK
bigint id_employee FK
bigint id_employee_served FK
bigint id_shop FK
bigint id_park_location FK
bigint id_shipping FK
bigint id_superseded FK
}
OrderDetails {
bigint id PK
bigint id_order FK
bigint id_customer FK
bigint id_product FK
bigint id_shift FK
bigint id_employee FK
bigint id_shop FK
bigint id_warehouse FK
bigint id_cash_register FK
bigint id_category FK
}
Employees {
bigint id PK
}
StockHistory {
bigint id PK
bigint id_employee FK
bigint id_shop FK
bigint id_stockup FK
bigint id_warehouse FK
bigint id_cash_register FK
bigint id_order FK
bigint id_record FK
}
Transactions {
bigint id PK
bigint id_customer FK
bigint id_order FK
bigint id_shift FK
bigint id_employee FK
bigint id_shop FK
}
Stockup {
bigint id PK
bigint id_cash_register FK
bigint id_employee FK
bigint id_shop FK
bigint id_warehouse FK
}
Warehouses {
bigint id PK
}
Products {
bigint id PK
bigint id_category FK
bigint id_shop FK
bigint id_exec_rule FK
bigint id_tax_rules_group FK
bigint id_global_product_code FK
}
ProductPriceMatrix {
bigint id PK
bigint id_product FK
bigint id_exec_rule FK
bigint id_shop FK
bigint id_warehouse FK
}
Customer ||--o{ Orders : places
Orders ||--o{ OrderDetails : contains
Customer ||--o{ OrderDetails : "is associated with"
Employees ||--o{ Orders : "manages"
Employees ||--o{ OrderDetails : "fulfills"
Warehouses ||--o{ OrderDetails : "stores"
Products ||--o{ OrderDetails : "includes"
StockHistory ||--o{ Employees : "managed by"
StockHistory ||--o{ Warehouses : "stored in"
StockHistory ||--o{ Products : "deducts"
Transactions ||--o{ Customer : "initiated by"
Transactions ||--o{ Orders : "related to"
Transactions ||--o{ Employees : "processed by"
Stockup ||--o{ Employees : "performed by"
ProductPriceMatrix ||--o{ Products : "defines price for"
Orders ||--o{ Warehouses : "related to"
Products ||--o{ Warehouses : "related to"
Products ||--o{ ProductPriceMatrix : "related to"
Products ||--o{ Transactions : "bought with"
Orders ||--o{ Transactions : "related to"
StockHistory }o--|| Orders : "concerns"
Warehouses ||--o{ Stockup : "associated with"
Stockup ||--o{ StockHistory : "tracks"
Employees ||--o{ StockHistory : "managed by"
Orders ||--o{ StockHistory : "related to"
Warehouses ||--o{ StockHistory : "related to"
Employees ||--o{ Transactions : "related to"
Employees ||--o{ Orders : "related to"
Definice objektu - zod schema
const NOT_DELETED = 0;
const bigintOrNumber = z.union([
z.number().refine(value => !isNaN(value), {
message: 'Expected a valid number',
}),
z.bigint(),
]);
const BaseSchema = z.object({
id: z.number(),
_v: z.number().min(0).default(() => new Date().getTime()),
_d: z.number().min(0).default(NOT_DELETED),
date_created: z.number().default(() => new Date().getTime())
});
const CustomerSchema = BaseSchema.extend({
id: z.bigint().default(BigInt(dbhelpers.getRandomRowId(2))),
_t: z.literal("customers"),
firstname: z.string().nullable().optional(),
customer_type: z.number().int().min(0).default(0), // Assuming customerType should be non-negative integer
date_updated: z.number().default(() => new Date().getTime()), // Defaults to current date
color: z.number().int().min(0).default(0), // Assuming color should be non-negative integer
id_discount_group: bigintOrNumber.optional(),
zip_code: z.string().nullable().optional(),
date_birthday: z.number().nullable().optional(),
geohash: z.string().nullable().optional(),
company: z.string().nullable(), // Can be null
company_ico: z.string().nullable().optional(),
company_dic: z.string().nullable().optional(),
street: z.string().nullable().optional(),
city: z.string().nullable().optional(),
bank_account: z.string().nullable().optional(),
credit_account: z.string().nullable().optional(),
internal_json: z.string().nullable().optional(),
bitmask: z.number().int().min(0).default(0), // Assuming bitmask should be non-negative integer
barcode: z.string().nullable().optional(),
email: z.string().email().nullable().optional(), // Assuming email should be a valid email format
visible: z.boolean().default(true), // Assuming default visibility is true
lastname: z.string().nullable().optional(),
tags: z.string().nullable().optional(),
country_code: z.string().min(2).max(2).default('CZ'), // Assuming country code is always 2 characters
price_group: z.enum(['A', 'B', 'C']).default('A'),
note_external: z.string().nullable().optional(),
note_internal: z.string().nullable().optional(),
phone_number: z.string().nullable().optional(),
date_expires: z.number().nullable().optional(),
internal_extra: z.string().nullable().optional(),
price_discount: z.number().int().default(0) // Assuming price discount is an integer
});
const OrdersSchema = BaseSchema.extend({
id: z.bigint().default(BigInt(dbhelpers.getRandomRowId(7))),
_t: z.literal("orders"),
id_address_invoice: bigintOrNumber.optional(),
id_canceled_order: bigintOrNumber.optional(),
id_customer: bigintOrNumber.optional(),
total_points: z.number().default(0),
total_credits: z.number().default(0),
total_profit_tax_incl: z.number().default(0),
total_tax_gst: z.number().default(0),
dine_in: z.boolean().default(false), // boolean, default to false
id_tax_report: bigintOrNumber.optional(),
short_code: z.string().nullable().optional(), // string or null
date_closed: z.number().nullable().optional(), // number (Date) or null
date_paid: z.number().nullable().optional(), // number (Date) or null
total_shipping_tax_incl: z.number().default(0),
geohash: z.string().nullable().optional(), // string or null
id_shop: bigintOrNumber,
total_profit_tax_excl: z.number().default(0),
total_tax_service: z.number().default(0),
invoice_number: z.number().nullable().optional(),
total_discounts_tax_incl: z.number().default(0),
order_serial_number: z.number().nullable().optional(),
id_address_delivery: bigintOrNumber.optional(),
total_shipping_tax_excl: z.number().default(0),
total_tax_pst: z.number().default(0),
total_tax_luxury: z.number().default(0),
date_canceled: z.number().nullable().optional(), // number (Date) or null
id_cash_register: bigintOrNumber,
total_paid_real: z.number().default(0),
id_shift: bigintOrNumber,
total_paid_tax_incl: z.number().default(0),
total_people_seated: z.number().nullable().optional(), // short
total_tip: z.number().default(0),
total_discounts_tax_excl: z.number().default(0),
date_fiscalized: z.number().nullable().optional(), // number (Date) or null
note: z.string().nullable().optional(), // string or null
total_paid_tax_excl: z.number().default(0),
total_wrapping_tax_incl: z.number().default(0),
id_shipping: bigintOrNumber.optional(),
id_superseded: bigintOrNumber.optional(),
total_wrapping_tax_excl: z.number().default(0),
id_employee: bigintOrNumber,
currency: z.string().nullable(), // string or null
conversion_rate: z.number().default(1.0), // number, default to 1.0
coupon_code: z.string().nullable().optional(), // string or null
coupon_source: z.string().nullable().optional(), // string or null
id_payment: z.number().default(0),
date_tax_reported: z.number().nullable().optional(), // number (Date) or null
total_tax_eco: z.number().default(0),
shipping_number: z.string().nullable().optional(), // string or null
customer_zip: z.string().nullable().optional(), // string or null
date_loc_acq: z.number().nullable().optional(), // number (Date) or null
id_employee_served: bigintOrNumber,
total_products: z.number().default(0),
id_park_location: bigintOrNumber,
date_collected: z.number().nullable().optional(), // number (Date) or null
date_due_pay: z.number().nullable().optional(), // number (Date) or null
date_emailed: z.number().nullable().optional(), // number (Date) or null
summary: z.string().nullable().optional(), // string or null
tags: z.string().nullable().optional(), // string or null
});
// Create a Zod schema for OrderDetails
const OrderDetailsSchema = BaseSchema.extend({
id: z.bigint().default(BigInt(dbhelpers.getRandomRowId(6))),
_t: z.literal("order_details"),
id_payment: z.number().int().default(0), // Default value from TransactionsModel
id_customer: bigintOrNumber.optional(),
total_points: z.number().min(0).default(0), // Always whole number, no fractional
total_credits: z.number().default(0), // We have an issue, in Orders this is int and here double
id_order: bigintOrNumber,
date_paid: z.number().nullable().optional(),
id_shop: bigintOrNumber,
product_barcode: z.string().nullable().optional(),
total_tax_pst: z.number().int().default(0), // TODO pro prodej poukazu -100Kc je negativni dan
total_tax_luxury: z.number().int().min(0).default(0),
date_canceled: z.number().nullable().optional(),
id_cash_register: bigintOrNumber,
product_name: z.string().default("Unknown"),
product_unit: z.number().int().min(0).default(0),
tags: z.string().nullable().optional(),
id_shift: bigintOrNumber,
product_price_original_tax_excl: z.number().int().default(0),
id_product: bigintOrNumber,
product_purchase_price_tax_excl: z.number().nullable().optional(), // Integer or null
product_attribute_id: z.number().nullable().optional(),
date_timing_started: z.number().nullable().optional(),
note: z.string().nullable().optional(),
date_updated: z.number().nullable().optional(),
product_upc: z.string().nullable().optional(),
date_item_printed: z.number().nullable().optional(),
id_category: bigintOrNumber,
order_number: z.number().int().min(0).default(0),
reduction_amount_tax_incl: z.number().int().default(0),
product_quantity: z.number().default(0), // Assuming whole number as per the comment
total_weight: z.number().nullable().optional(), // Double or null
id_employee: bigintOrNumber,
reference_code: z.string().nullable().optional(),
currency: z.string().min(3).max(3), // Assuming currency is a 3-character code
product_price_billed_tax_excl: z.number().int().default(0),
product_name_alternative: z.string().default(""),
tax_pst_rate: z.number().default(1.000),
product_price_billed_tax_incl: z.number().int().default(0),
reduction_percent: z.number().int().min(0).default(0),
product_ean13: z.string().nullable().optional(),
total_tax_eco: z.number().int().default(0),
product_bitmask: z.number().int().min(0).default(0),
id_order_details_parent: bigintOrNumber.optional(),
id_warehouse: bigintOrNumber,
date_collected: z.number().nullable().optional(),
date_voided: z.number().nullable().optional(),
reduction_amount_tax_excl: z.number().int().default(0),
product_item_type: z.number().int().min(0).default(0),
});
const EmployeesSchema = BaseSchema.extend({
id: z.bigint().default(BigInt(dbhelpers.getRandomRowId(4))),
_t: z.literal("employees"),
salt: z.string().nullable().optional(),
visible: z.boolean().default(true),
pin_require: z.boolean().default(false),
perm_inventory_bitmask: z.number().int().default(0),
pin_hash: z.string().nullable().optional(),
pass_hash: z.string().nullable().optional(),
perm_cloud_bitmask: z.number().int().default(0),
tags: z.string().nullable().optional(),
perm_bitmask: z.number().int().default(0),
name: z.string(),
phone_number: z.string().nullable().optional(),
date_expires: z.number().nullable().optional(), // Stored as milliseconds since epoch (UNIX timestamp)
barcode: z.string().nullable().optional(),
visible_cash_register: z.boolean().default(true),
otp_hash: z.string().nullable().optional(),
email: z.string().nullable().optional(),
});
const StockHistorySchema = BaseSchema.extend({
id: z.bigint().default(BigInt(dbhelpers.getRandomRowId(16))),
_t: z.literal("stock_history"),
id_employee: bigintOrNumber,
id_shop: bigintOrNumber,
id_stockup: bigintOrNumber.optional().nullable(),
id_warehouse: bigintOrNumber,
note: z.string().nullable().optional(),
id_record: bigintOrNumber,
date_stocked: z.number().nullable().optional(), // Date as timestamp
quanity: z.number().default(0.0),
id_cash_register: bigintOrNumber,
id_supplier: bigintOrNumber.optional().nullable(),
stock_type: z.number().int(),
id_order: bigintOrNumber.optional().nullable(),
stock_history_type: z.number().int(),
supplier_sku: z.string().nullable().optional(),
product_purchase_unit_price_tax_excl: z.number().int().nullable().optional(),
});
const TransactionsSchema = BaseSchema.extend({
id: z.bigint().default(BigInt(dbhelpers.getRandomRowId(22))),
_t: z.literal("transactions"),
note: z.string().nullable().optional(),
transaction_code: z.string().nullable().optional(),
id_customer: bigintOrNumber.optional(),
transaction_type: z.number().int(),
id_cash_register: bigintOrNumber.default(BigInt(0)),
id_order: bigintOrNumber.optional(),
id_shift: bigintOrNumber.default(BigInt(0)),
payment_type: z.number().int().min(0),
total_amount: z.number().int().default(0),
id_employee: bigintOrNumber,
id_shop: bigintOrNumber,
reference_code: z.string().nullable().optional(),
});
const StockupSchema = BaseSchema.extend({
id: z.bigint().default(BigInt(dbhelpers.getRandomRowId(18))),
_t: z.literal("stockup"),
note: z.string().nullable().optional(),
total_product_purchase_unit_price_tax_excl: z.number().int().nullable().optional(),
date_stocked: z.number().nullable().optional(), // Assuming timestamp as milliseconds
id_cash_register: z.number().int(),
id_supplier: z.number().int().nullable().optional(),
stock_history_type: z.number().int(),
id_employee: z.number().int(),
id_shop: z.number().int(),
id_warehouse: z.number().int(),
invoice_number: z.string().nullable().optional(),
});
const WarehousesSchema = BaseSchema.extend({
id: z.bigint().default(BigInt(dbhelpers.getRandomRowId(25))),
_t: z.literal("warehouses"),
shared: z.boolean().default(false),
visible: z.boolean().default(true),
warehouse_bitmask: z.number().int().default(0),
name: z.string(),
});
const ProductsSchema = BaseSchema.extend({
id: z.bigint().default(BigInt(dbhelpers.getRandomRowId(12))),
_t: z.literal("products"),
image_dimension: z.number().int().nullable().optional(),
notes_quick: z.string().nullable().optional(),
quantity_multiple: z.number().default(1),
quantity_minimal: z.number().default(1),
additional_shipping_cost: z.number().default(0),
date_updated: z.number(), // Date as timestamp (milliseconds)
inventory_management: z.boolean().default(false),
color: z.number().int().default(0),
item_type: z.number().int().default(0),
id_category: bigintOrNumber.default(BigInt(0)),
tax_luxury: z.number().default(1.000),
ean13: z.string().nullable().optional(),
id_tax_rules_group: bigintOrNumber.nullable().default(BigInt(0)),
name_alternative: z.string().nullable().optional(),
sku: z.string().nullable().optional(),
tax_eco: z.number().default(1.000000),
barcode: z.string().nullable().optional(),
height: z.number().nullable().optional(),
visible: z.boolean().default(true),
image_url: z.string().nullable().optional(),
warranty_length: z.number().int().default(0),
condition_type: z.number().int().default(0),
tax_pst_rate: z.number().default(1.000),
upc: z.string().nullable().optional(),
weight: z.number().nullable().optional(), // Stored as alcoholTax in Java
icon_code: z.number().int().default(0),
details_url: z.string().nullable().optional(),
warranty_type: z.number().int().default(0),
tags: z.string().nullable().optional(),
description_short: z.string().nullable().optional(),
unit: z.number().int().default(0),
id_exec_rule: bigintOrNumber.default(BigInt(0)),
depth: z.number().nullable().optional(),
sale_group_type: z.number().int().default(0),
id_global_product_code: bigintOrNumber.nullable().optional(),
accounting_group: z.number().int().default(600000),
name: z.string(),
width: z.number().nullable().optional(),
node_sort: bigintOrNumber.default(BigInt(0)),
attributes_bitmask: z.number().int().default(0),
inventory_type: z.number().int().default(0),
internal_extra: z.string().nullable().optional(),
id_shop: bigintOrNumber.default(BigInt(0))
});
const ProductPriceMatrixSchema = BaseSchema.extend({
id: z.bigint().default(BigInt(dbhelpers.getRandomRowId(12))),
_t: z.literal("product_price_matrix"),
unit_price_base_tax_excl: z.number().nullable().optional(),
unit_price_base_tax_incl: z.number().nullable().optional(),
date_starts: z.number(), // Date as timestamp (milliseconds)
unit_price_regular_tax_excl: z.number().int().default(0),
unit_price_c_tax_excl: z.number().int().nullable().optional(),
points_deduct: z.number().default(0.0),
credits_deduct: z.number().default(0.0),
hour_bitmask: z.number().int().default(0),
reduction_amount_a_tax_excl: z.number().int().default(0),
id_product: bigintOrNumber,
id_exec_rule: bigintOrNumber.default(BigInt(0)),
unit_price_b_tax_excl: z.number().int().nullable().optional(),
price_bitmask: z.number().int().default(0),
dow_bitmask: z.number().int().default(0),
id_shop: bigintOrNumber.default(BigInt(0)),
currency: z.string(),
date_expires: z.number().nullable().optional(), // Date as timestamp (milliseconds)
unit_price_a_tax_excl: z.number().int().nullable().optional(),
id_warehouse: bigintOrNumber.default(BigInt(0)),
});