{"id":19817873,"url":"https://github.com/unimapper/flexibee","last_synced_at":"2025-08-23T10:33:01.073Z","repository":{"id":14069024,"uuid":"16772441","full_name":"unimapper/flexibee","owner":"unimapper","description":"Flexibee integration with Unimapper","archived":false,"fork":false,"pushed_at":"2016-01-12T15:48:29.000Z","size":129,"stargazers_count":9,"open_issues_count":1,"forks_count":5,"subscribers_count":6,"default_branch":"master","last_synced_at":"2025-05-31T03:41:41.367Z","etag":null,"topics":["adapter","api","flexibee","orm","unimapper"],"latest_commit_sha":null,"homepage":"","language":"PHP","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":"mit","status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/unimapper.png","metadata":{"files":{"readme":"README.md","changelog":null,"contributing":null,"funding":null,"license":"LICENSE","code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null}},"created_at":"2014-02-12T15:53:31.000Z","updated_at":"2025-01-07T09:22:46.000Z","dependencies_parsed_at":"2022-08-21T08:20:58.241Z","dependency_job_id":null,"html_url":"https://github.com/unimapper/flexibee","commit_stats":null,"previous_names":[],"tags_count":26,"template":false,"template_full_name":null,"purl":"pkg:github/unimapper/flexibee","repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/unimapper%2Fflexibee","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/unimapper%2Fflexibee/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/unimapper%2Fflexibee/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/unimapper%2Fflexibee/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/unimapper","download_url":"https://codeload.github.com/unimapper/flexibee/tar.gz/refs/heads/master","sbom_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/unimapper%2Fflexibee/sbom","scorecard":null,"host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":271745808,"owners_count":24813529,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2022-07-04T15:15:14.044Z","status":"online","status_checked_at":"2025-08-23T02:00:09.327Z","response_time":69,"last_error":null,"robots_txt_status":"success","robots_txt_updated_at":"2025-07-24T06:49:26.215Z","robots_txt_url":"https://github.com/robots.txt","online":true,"can_crawl_api":true,"host_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub","repositories_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories","repository_names_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repository_names","owners_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners"}},"keywords":["adapter","api","flexibee","orm","unimapper"],"created_at":"2024-11-12T10:13:58.981Z","updated_at":"2025-08-23T10:33:01.047Z","avatar_url":"https://github.com/unimapper.png","language":"PHP","funding_links":[],"categories":[],"sub_categories":[],"readme":"UniMapper Flexibee extension\n============================\n\nFlexibee API integration with [UniMapper](http://unimapper.github.io).\n\n[![Build Status](https://secure.travis-ci.org/unimapper/flexibee.png?branch=master)](http://travis-ci.org/unimapper/flexibee)\n\n# Usage\n\n```php\n$config = [\n    // Required\n    \"host\" =\u003e \"http://localhost:5434\"\n    \"company\" =\u003e \"name\"\n\n    // Optional authentization\n    \"user\" =\u003e ,\n    \"password\" =\u003e ,\n\n    // Optional SSL version\n    \"ssl_version\" =\u003e 3\n];\n$adapter = new UniMapper\\Flexibee\\Adapter($config);\n\n// Create new contacts\n$response = $adapter-\u003eput(\"adresar.json\", [\"adresar\" =\u003e [\"sumCelkem\" =\u003e ....]);\n\n// Read every created contact detail\nforeach ($response-\u003eresults as $result) {\n    $adapter-\u003eget(\"adresar/\" . $result-\u003eid . \".json\");\n}\n```\n\nFor more inromation see the docs on official [Flexibee](http://www.flexibee.eu) site.\n\n# Příklady z praxe\n\nTakhle může být zadefinovaná evidence *objednavka-prijata* v plné kráse. Seznam všech lze najít například na https://demo.flexibee.eu/c/demo/evidence-list\n\n## Entity\n```\n\u003c?php\n\nnamespace ProjectName\\Entity;\n\n/**\n * @adapter Flexibee(objednavka-prijata)\n *\n * @property string             $id                 m:primary m:map-by(id)\n * @property string             $code               m:map-by(kod)\n * @property string             $status             m:map-by(stavUzivK) m:enum(self::STATE_*)\n * @property string             $staff              m:map-by(zodpOsoba)\n * @property-read string        $staffFullName      m:map-by(zodpOsoba@showAs)\n * @property Date               $dateCreated        m:map-by(datVyst)\n * @property-read double        $basePrice          m:map-by(sumZklCelkem)\n * @property boolean            $cancel             m:map-by(storno)\n * @property Attachment[]       $attachments        m:map-by(prilohy)\n * @property boolean            $itemsRemoveAll     m:map-by(polozkyObchDokladu@removeAll)\n * @property EvidenceItem[]     $evidenceItems      m:map-by(polozkyObchDokladu)\n * @property boolean            $tagsRemoveAll      m:map-by(stitky@removeAll)\n * @property array              $tags               m:map-by(stitky) m:map-filter(mapStitky|unmapStitky)\n * @property string             $addressBookId      m:map-by(firma)\n * @property string             $city               m:map-by(mesto)\n * @property string             $email              m:map-by(kontaktEmail)\n * @property string             $companyName        m:map-by(nazFirmy)\n * @property string             $phone              m:map-by(kontaktTel)\n * @property string             $postCity           m:map-by(faMesto)\n * @property string             $postCompanyName    m:map-by(faNazev)\n * @property string             $postStreet         m:map-by(faUlice)\n * @property string             $postZipCode        m:map-by(faPsc)\n * @property string             $street             m:map-by(ulice)\n * @property string             $zipCode            m:map-by(psc)\n * @property string             $companyId          m:map-by(ic)\n * @property string             $vatId              m:map-by(dic)\n * @property boolean            $mainAddress        m:map-by(postovniShodna)\n * @property array              $externalIds        m:map-by(external-ids)\n * @property Offer[]            $offers             m:assoc(M:N) m:assoc-by(vazby|typVazbyDokl.obchod_obchod_hla|a)\n * @property Invoice[]          $advanceInvoices    m:assoc(M:N) m:assoc-by(vazby|typVazbyDokl.obchod_zaloha_hla|b)\n * @property Invoice[]          $cashInvoices       m:assoc(M:N) m:assoc-by(vazby|typVazbyDokl.obchod_faktura_hla|b)\n * @property-read Invoice[]     $invoices           m:computed\n * @property-read Attachment[]  $attachments        m:assoc(1:N) m:assoc-by(prilohy)\n */\nclass Order extends \\UniMapper\\Flexibee\\Entity\n{\n\n    const STATE_NEW = null,\n          STATE_UNSPECIFIED = \"stavDoklObch.nespec\",\n          STATE_FORAPPROVAL = \"stavDoklObch.pripraveno\",\n          STATE_APPROVED = \"stavDoklObch.schvaleno\",\n          STATE_ACCEPTED_PARTIALLY = \"stavDoklObch.castVydano\",\n          STATE_ACCEPTED = \"stavDoklObch.vydano\",\n          STATE_FINISHED_PARTIALLY = \"stavDoklObch.castHotovo\",\n          STATE_FINISHED = \"stavDoklObch.hotovo\",\n          STATE_CANCELED = \"stavDoklObch.storno\",\n\n    /**\n     * Compute invoice\n     *\n     * @return \\UniMapper\\EntityCollection\n     */\n    public function computeInvoices()\n    {\n        $invoices = new \\UniMapper\\EntityCollection(\"Invoice\");\n\n        foreach ($this-\u003ecashInvoices as $invoice) {\n            $invoices[] = $invoice;\n        }\n        foreach ($this-\u003eadvanceInvoices as $invoice) {\n            $invoices[] = $invoice;\n        }\n        return $invoices;\n    }\n```\n\n#### Doporučení\n- **Identifikátory (zde například ID objednávky, addressBookId, ...) definujte VŽDY typu string.** Unimapper preferuje textový identifikátor z Flexibee před číselným. Tj. pokud si necháme vylistovat objednávky z Flexibee, jako ID dorazí něco ve stylu *code:OBP0001/2015*. Pokud Flexibee u dané evidence nedrží textový identifikátor, vrátí se číselný (avšak typově jako string).\n- Proměnné, které si Flexibee vypočítává samo (například suma za celou objednávku) a nebo je zakázáno je do Flexibee posílat (viz. dokumentace Flexibee) je vhodné označit jako *@property-read*. Unimapper pak nebude tyto property do Flexibee zapisovat, pouze je z Flexibee načte.\n- Pokud je v dokumentaci Flexibee proměnná definovaná jako *date*, nastavte typ i zde na *Date*. Nepoužívejte *DateTime*, vyvarujete se problémů při filtraci záznamů dle datumu (např. vypiš všechny včerejší objednávky).\n\n#### Tipy\n- Díky *m:enum* lze hlídat hodnoty ve výčtových typech. Unimapper vyhodí výjimku, pokud se hodnota nenachází v datech, která se vrací z Flexibee / posílají do Flexibee.\n- Štítky (zde tags) si lze jednoduše převést do array pomocí *m:map-filter(mapStitky|unmapStitky)* a pak s nimi jednodušeji pracovat. Naopak při zápisu se z array vhodně přetransformují do podoby, kterou Flexibee akceptuje.\n- Pokud chcete načítat i externí identifikátory, lze ala příklad použít *$externalIds*.\n- Pomocí *m:assoc(M:N)* dokážete skoro kouzla. Například v *$advanceInvoices* budete mít rovnou kolekci navázaných zálohovek k této objednávce a v *$cashInvoices* kolekci navázaných faktur. Pokud byste to rovnou chtěli pohromadě v jedné kolekci (proformy i faktury), můžete využít další vychytávku Unimapperu a to je \"computed\" property.\n- Pomocí *m:computed* můžete zařídit, že jakmile k takové property přistoupíte, bude obsahovat přesně ten obsah, který potřebujete. V příkladu s tím souvisí metoda *computeInvoices()*.\n- Pokud upravujeme existující objednávku, je vhodné nastavit *$itemsRemoveAll* na *TRUE* a zároveň poslat všechny položky objednávky znovu (*$evidenceItems*). V opačném případě se nám budou s každou úpravou množit na objednávce položky (viz. dokumentace Flexibee).\n\n## Repository\nPokud pak máme repository zadefinovanou takto:\n\n```\nnamespace ProjectName\\Repository;\n\nclass OrderRepository extends \\UniMapper\\Repository\n{\n\n```\n\nmůžeme tam vytvořit třeba tyhle metody:\n\n- Přepíše \"vlastníka\" objednávky za předpokladu, že aktuálně patří adminovi a je v určitém stavu.\n\n```\npublic function assignStaffToOrder($orderId, $staff)\n{\n    $this-\u003equery()\n        -\u003eupdate(array(\"staff\" =\u003e $staff))\n        -\u003ewhere(\"id\", \"=\", $orderId)\n        -\u003ewhere(\"status\", \"=\", Order::STATE_FORAPPROVAL)\n        -\u003ewhere(\"staff\", \"=\", \"code:admin\")\n        -\u003erun($this-\u003econnection);\n}\n```\n\n- Pokud si chcete formou štítků poznamenávat důvod storna, může přijít vhod následující metoda, která vrátí seznam štítků. Vynikající je v tomto ohledu možnost zapnout kešování Unimapperu! Proč se ptát na neměnný číselník stále dokola? Každý dotaz do Flexibee má nějako tu režii.\n\n```\npublic function getCancelReasons()\n{\n    return \\Fik\\Entity\\Tag::query()\n        -\u003eselect()\n        -\u003ewhere(\"tagGroup\", \"=\", \"code:STORNO\")\n        -\u003ecached(\n            true,\n            [\\UniMapper\\Cache\\ICache::TAGS =\u003e [self::CACHE_TAG_CODEBOOK]]\n        )\n        -\u003erun($this-\u003econnection);\n}\n```\n\n- Nevyhovuje standardní *save()*? Můžeme ji přetížit a udělat nějakou tu věc navíc. Tady třeba nastavit dnešní datum vzniku objednávky, pokud jde o novou objednávku (*ID === null*).\n\n```\npublic function save(\\UniMapper\\Entity $order)\n{\n    if ($order-\u003eid === null) {\n        $order-\u003edateCreated = new \\DateTime();\n    }\n\n    parent::save($order);\n}\n```\n\n- Některá workflow Flexibee vyžadují trochu více snahy. Pokud chceme z objednávky udělat fakturu, budeme potřebovat určitě tuto pasáž kódu (dokumence Flexibee napoví):\n\n```\n$structure = array(\n    \"objednavka-prijata\" =\u003e array(\n        \"@id\" =\u003e \"{$orderId}\",\n        \"realizaceObj\" =\u003e\n        array(\"@type\" =\u003e \"faktura-vydana\",\n            \"polozkyObchDokladu\" =\u003e $polozkyDokladu\n        )\n    )\n);\n\n$invoiceCreated = $this-\u003egetAdapter(\"Flexibee\")-\u003eput(\n    \"objednavka-prijata.json\",\n    $structure\n);\n```\n\n- Počty objednávek ke schválení? Žádný problém :-)\n\n```\npublic function getTotalCountForApprove()\n{\n    $result = $this-\u003equery()\n        -\u003ecount()\n        -\u003ewhere(\"status\", \"=\", Order::STATE_FORAPPROVAL)\n        -\u003ewhere(\"staff\", \"=\", \"code:admin\")\n        -\u003erun($this-\u003econnection);\n\n    return $result + $this-\u003equery()\n        -\u003ecount()\n        -\u003ewhere(\"documentType\", \"=\", Order::DOCTYPE_CARD)\n        -\u003ewhere(\"staff\", \"=\", \"code:admin\")\n        -\u003erun($this-\u003econnection);\n}\n```\n\n- Vytvoření jednoduché objednávky:\n\n```\n    public function createTestOrder()\n    {\n        $order = new Order;\n        $order-\u003edocumentType = Order::DOCTYPE_CONSIGNMENT;\n        $order-\u003eaddressBookId = \"code:FIRMA\";\n\n        $items = [];\n        \n        $item = new EvidenceItem; // entita vázaná na evidenci \"objednavka-prijata-polozka\"\n        $item-\u003eitemPriceList = \"code:KRABICE_DROG\"; // property objednavka-prijata-polozka.cenik\n        $item-\u003eitemAmount = 2.0; // property objednavka-prijata-polozka.mnozMj\n        $items[] = $item;\n        \n        $item = new EvidenceItem;\n        $item-\u003eitemPriceList = \"code:KRABICE_ALKOHOLU\";\n        $item-\u003eitemAmount = 1.0;\n        $items[] = $item;\n\n        $order-\u003eevidenceItems = new \\UniMapper\\EntityCollection(\n            \"EvidenceItem\", $items\n        );\n\n        $this-\u003esave($order);\n        \n        // v $order-\u003eid budu mít v tento moment identifikátor objednávky z Flexibee, tj. třeba \"code:OBP0001/2015\"\n    }\n```\n\n- Vrácení PDF definované objednávky:\n\n```\npublic function getOrderPdf($orderId)\n{\n    return $this-\u003egetAdapter(\"Flexibee\")-\u003eget(\n        \"objednavka-vydana/\" . rawurlencode($orderId) . \".pdf\",\n        \"application/pdf\"\n    );\n}\n```\n\n- Vytažení objednávky včetně asociací:\n\n```\npublic function getOrder($orderId)\n{\n    $query = $this-\u003equery()-\u003eselectOne($orderId)-\u003eassociate([\"advanceInvoices\", \"cashInvoices\"]);\n    $order = $query-\u003erun($this-\u003econnection);\n\n    return $order;\n}\n```\n\n- Hledání textu v poznámce určitých objednávek:\n\n```\nuse UniMapper\\Entity\\Filter;\n\n$invoices = $this-\u003equery()\n    -\u003ewhere(\n        [\n            \"note\" =\u003e [Filter::CONTAIN =\u003e $tentoTextHledame]\n            \"documentType\" =\u003e [Filter::EQUAL =\u003e [\"code:PRIMA\", \"code:NEPRIMA\"]]\n        ]\n    -\u003eorderBy(\"id\", \"desc\")\n    -\u003elimit(10)\n    -\u003erun($this-\u003econnection);\n```\n\n## Práce nad repository\n\nI tady se toho nabízí spousta. Například tohle může být základ pro skript, který má odesílat nezaplacené proformy:\n\n```\n// vyber vsechny, co nejsou uhrazene a stornovane\n$filter = [\n    \"canceled\" =\u003e [\"=\" =\u003e false], // = faktura-vydana.storno\n    \"paymentStatus\" =\u003e [ // = faktura-vydana.stavUhrK\n        \"!\" =\u003e [\n            Entity\\Invoice::PAYMENT_STATUS_PAIDMANUALLY, // = faktura-vydana.stavUhr.uhrazenoRucne\n            Entity\\Invoice::PAYMENT_STATUS_PAID // = faktura-vydana.stavUhr.uhrazeno\n        ]\n    ]\n];\n\n// prvni upominka dva dny po splatnosti\nforeach ($this-\u003einvoiceRepository-\u003efind(\n    $filter + [\n        \"documentType\" =\u003e [\"=\" =\u003e Entity\\Invoice::DOCTYPE_PROFORMA], // = faktura-vydana.typDokl = \"code:ZÁLOHA\"\n        \"firstReminder\" =\u003e [\"=\" =\u003e null], // faktura-vydana.datUp1\n        \"dueDate\" =\u003e [\n            \"\u003c\" =\u003e new \\DateTime(\"-1 day\") // faktura-vydana.datSplat\n        ]\n    ]\n) as $invoice) {\n```\n\n#### Doporučení pro úpravu stavů v entitě\n\nObčas se nám může naskytnout situace, kdy máme například celou entitu objednávka načtenou a po nějakých těch operacích dospějeme k tomu, že je potřeba upravit pouze stav objednávky:\n\n```\n$order = $this-\u003eorderRepository-\u003efindOne(\"code:OBP0001/2015);\n...\nnějaké ty operace\n...\n$order-\u003estatus = \"stavDoklObch.hotovo\";\n$this-\u003eorderRepository-\u003esave($order);\n```\n\n**Výše uvedený postup je však nevhodný!**\n\nNaopak to doporučujeme řešit takto:\n\n```\n$order = $this-\u003eorderRepository-\u003efindOne(\"code:OBP0001/2015);\n...\nnějaké ty operace\n...\n$this-\u003eorderRepository-\u003esave(\n    new ProjectName\\Entity\\Order(\n        [\"id\" =\u003e $order-\u003eid, \"status\" =\u003e \"stavDoklObch.hotovo\"]\n    )\n);\n```\n\nTakhle zajistíme, že Flexibee nebude celou objednávku přepočítávat (neboť v *$order-\u003eevidenceItems* budou i její položky! a že opravdu pouze změní status u definované objednávky (*id*).\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Funimapper%2Fflexibee","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Funimapper%2Fflexibee","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Funimapper%2Fflexibee/lists"}