Invoice Ninja 5 - fakturační systém
Hledal jsem jednoduchý fakturační systém, který bych si mohl nainstalovat jako webovou službu. V minulosti mě zaujal InvoiceNinja a používal jsem verzi 4. Musel jsem si ji trošku přizpůsobit pro české prostředí, ale bylo to funkční.
Nicméně vývojáři InvoiceNinja vytvořili novější verzi a protože struktura systému je jiná, nebylo možné systém jednoduše aktualizovat. Musel jsem vytvořit novou instanci s verzí 5 a poté udělat migraci. Naštěstí na to vývojáři mysleli a migrace je funkční. A zdá se, že verze 5 je opravdu slušně vylepšená a přechod měl smysl. A dokonce se mi podařilo vyřešit i několik problémů z verze 4, které bránily k dokonalému použití.
Migrace
Postupoval jsem podle dokumentace k migraci. Vytvořil jsem novou instalaci na jiné subdoméně.
Popis instalace zahrnuje:
- doporučenou verzi PHP
- potřebné balíčky
- nastavení práv
- nastavení cronu a další
V rámci migrace jsem pak ve verzi 4 šel podle návodu, nastavil jsem doménu na kterou budu migrovat a bylo to. Starý systém mohu nyní vypnout nebo přesměrovat.
Po migraci jsem se začal věnovat nastavení nového fakturačního systému. Fakt je, že se přeneslo i nastavení z původní verze. Nicméně stejně jsem si to nastavení musel vylepšit v menu Nastaveni/Settings.
Lokalizace
Lokalizace se provádí skrze menu Uživatelské detaily, kde zapnu jazyk a dále pak přes menu Lokalizace, kde se zapíná desetinná tečku a čárka na České prostředí.
Warning
I přesto, že jsem měl desetinnou tečku a čárku správně nastavenou, tak jsem zjistil, že na vystavených fakturách je anglický formát. Později jsem si všimnul, že se to týká pouze některých faktur. Původně jsem si myslel, že je to chyba v programu. Ale když jsem si zkusil přidat novou firmu (čistou) firmu, tak vystavení faktur bylo v pořádku v českém formátu.
Pak mě napadlo, kde by mohl být problém. Podíval jsem se, komu faktury vystavuji a měl jsem v kontaktu napsáno, že kontakt pochází z United States. Nevím jestli to vzniknul problém při migraci nebo jsem v původní systému špatně zadával údaje. Každopádně změnil jsem u kontaktu zemi a v tu chvíli se změnila desetinná tečka na faktuře na destinnou čárku. Problém byl vyřešen.
Další možnost je přejmenovat některé popisky na faktuře. Například jsem se snažil původně přejmenovat pole Číslo faktury na variabilní symbol. To jsem dělal v menu Lokalizace→ Custom Lables.
Vycházel jsem z existujících labelů z dokumentace. Použil jsem při vytváření label a pak bylo možné mu nastavit nový název.
Každopádně jsem z tohoto postupu upustil, vyřešil jsem variabilní symbol k platbě editací šablony.
QR kód
Protože byl přepracován vzhled šablon, tak se otevřely nové možnosti vložení QR kódu do šablony. Nejprve vypadala nadějně oficiální dokumentace ke QR kódům.
V dokumentaci jsou 3 typy QR kódů. Pochopil jsem, že první se týká Švýcarska - takže pro mě nepoužitelné. Další variantou jsou SEPA ERC QR kódy. Aktivace spočívá v přidání v custom fields pro Company. Pozor, musí být přesně dané pořadí, jinak to nebude fungovat. Nicméně měna byla v Eurech a týkala se podle mě plateb v zahraničí.
Řešením měla být poslední možnost - Generic Payment link QR Codes. Použití bylo jednoduché, stačilo do šablony vložit proměnnou payment_qrcode a mělo to fungovat. Bohužel mělo a nefungovalo.
Pak jsem se ale inspiroval ve fóru, kde vložili do šablony tag, který načítá URL, která vygeneruje QR kód. Velmi jednoduché řešení.
Jako služba pro generování QR kódu jsem použil službu https://developers.google.com/chart/infographics/docs/qr_codes.
V bankovnictví jsem si vygeneroval QR kód, přečetl jsem si obsah a nahradil v řětezci proměnné pro měnu a variabilní symbol. Výsledek byl, že jsem do šablony pak vložil tento tag, který generuje QR platby:
<img src="https://chart.googleapis.com/chart?cht=qr&chl=SPD*1.0*ACC:CZ8520100000002801581174*AM:$amount_raw*CC:CZK*X-VS:$number&chs=200x200&chld=L|0" class="qr-code img-thumbnail img-responsive" />
Ještě doplním, že jsem musel použít proměnnou $amount_raw, aby byla v kódu částka bez měny.
O proměnné je psáno zde a zde.
Jenom jsem nasadil QR platby, tak u druhé faktury dostal Google výpadek a nejde generovat QR obrázky. To mě dovedlo k alternativní službě, která je jistým způsobem ještě jednodušší, protože parametry účtu předávám v rámci parametrů.
Dokumentaci jsem našel na serveru qr-platba.cz a tady je příklad kódu:
<img src="http://api.paylibo.com/paylibo/generator/czech/image?accountNumber=222885&bankCode=5500&amount=250.00¤cy=CZK&vs=333&message=FOND%20HUMANITY%20CCK" />
Vkládání podpisu (obrázku) do šablony
Zakódoval jsem obrázek do base64 a vložil pomocí tagu IMG s nastavenou src. Obrázek lze zakódovat jednoduše například přes službu base64image. Výsledek kódu a vložení vypadá takto:
<img src="data:image/png;base64,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jBQWsQQRAmTUUUEVFuK0a6SYyNB50sM/5PhFcsnkqoCRYwE1qJAcP/gf/J6tWUxMuknhJBB8se2PESC0C7Qatv19bNutEyDwDFxpHX+tCcx8kt7oaLEjoH8buLjuaPIecLkDDD7pkiE5UoCWv1gE3s/om/LAwC3Qt+bOrX2O0wcgS7NK3wAHh8BoibLXPd7d2z23f3va8/sBlZ9ytbVp6sEAAA39aVRYdFhNTDpjb20uYWRvYmUueG1wAAAAAAA8P3hwYWNrZXQgYmVnaW49Iu+7vyIgaWQ9Ilc1TTBNcENlaGlIenJlU3pOVGN6a2M5ZCI/Pgo8eDp4bXBtZXRhIHhtbG5zOng9ImFkb2JlOm5zOm1ldGEvIiB4OnhtcHRrPSJYTVAgQ29yZSA0LjQuMC1FeGl2MiI+CiA8cmRmOlJERiB4bWxuczpyZGY9Imh0dHA6Ly93d3cudzMub3JnLzE5OTkvMDIvMjItcmRmLXN5bnRheC1ucyMiPgogIDxyZGY6RGVzY3JpcHRpb24gcmRmOmFib3V0PSIiCiAgICB4bWxuczp4bXBNTT0iaHR0cDovL25zLmFkb2JlLmNvbS94YXAvMS4wL21tLyIKICAgIHhtbG5zOnN0RXZ0PSJodHRwOi8vbnMuYWRvYmUuY29tL3hhcC8xLjAvc1R5cGUvUmVzb3VyY2VFdmVudCMiCiAgICB4bWxuczpkYz0iaHR0cDovL3B1cmwub3JnL2RjL2VsZW1lbnRzLzEuMS8iCiAgICB4bWxuczpHSU1QPSJodHRwOi8vd3d3LmdpbXAub3JnL3htcC8iCiAgICB4bWxuczp0aWZmPSJodHRwOi8vbnMuYWRvYmUuY29tL3RpZmYvMS4wLyIKICAgIHhtbG5zOnhtcD0iaHR0cDovL25zLmFkb2JlLmNvbS94YXAvMS4wLyIKICAgeG1wTU06RG9jdW1lbnRJRD0iZ2ltcDpkb2NpZDpnaW1wOjcwN2JkNDQ0LWRkMzUtNDk4YS05YzI0LTY2YzcwMzc5NzBjNCIKICAgeG1wTU06SW5zdGFuY2VJRD0ieG1wLmlpZDowODkyNTNhOC01NzQ4LTRkMTEtYjRhMy04MzQ5NDQ0OGQwZjUiCiAgIHhtcE1NOk9yaWdpbmFsRG9jdW1lbnRJRD0ieG1wLmRpZDpmMGZhNjU3ZC03ODE5LTQzMTYtODdlZi1hYjc4ODc4NmFlNTgiCiAgIGRjOkZvcm1hdD0iaW1hZ2UvcG5nIgogICBHSU1QOkFQST0iMi4wIgogICBHSU1QOlBsYXRmb3JtPSJMaW51eCIKICAgR0lNUDpUaW1lU3RhbXA9IjE3MDQ0NjI3MTkzMjMxNjEiCiAgIEdJTVA6VmVyc2lvbj0iMi4xMC4zMCIKICAgdGlmZjpPcmllbnRhdGlvbj0iMSIKICAgeG1wOkNyZWF0b3JUb29sPSJHSU1QIDIuMTAiPgogICA8eG1wTU06SGlzdG9yeT4KICAgIDxyZGY6U2VxPgogICAgIDxyZGY6bGkKICAgICAgc3RFdnQ6YWN0aW9uPSJzYXZlZCIKICAgICAgc3RFdnQ6Y2hhbmdlZD0iLyIKICAgICAgc3RFdnQ6aW5zdGFuY2VJRD0ieG1wLmlpZDowNDJjOGMyYS1hMzE1LTRiNDAtOGE3ZC0zZjFjYTk3NDU5MGMiCiAgICAgIHN0RXZ0OnNvZnR3YXJlQWdlbnQ9IkdpbXAgMi4xMCAoTGludXgpIgogICAgICBzdEV2dDp3aGVuPSIyMDI0LTAxLTA1VDE0OjQ4OjIxKzAxOjAwIi8+CiAgICAgPHJkZjpsaQogICAgICBzdEV2dDphY3Rpb249InNhdmVkIgogICAgICBzdEV2dDpjaGFuZ2VkPSIvIgogICAgICBzdEV2dDppbnN0YW5jZUlEPSJ4bXAuaWlkOjc0YzYwN2M5LWMwZmEtNDgyNS05ODdjLWNiYzU0OTZhMTZkNyIKICAgICAgc3RFdnQ6c29mdHdhcmVBZ2VudD0iR2ltcCAyLjEwIChMaW51eCkiCiAgICAgIHN0RXZ0OndoZW49IjIwMjQtMDEtMDVUMTQ6NTE6NTkrMDE6MDAiLz4KICAgIDwvcmRmOlNlcT4KICAgPC94bXBNTTpIaXN0b3J5PgogIDwvcmRmOkRlc2NyaXB0aW9uPgogPC9yZGY6UkRGPgo8L3g6eG1wbWV0YT4KICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgCiAgICAgICAgICAgICAgICAgICAgICAgICAgIAo8P3hwYWNrZXQgZW5kPSJ3Ij8+r+yG4AAAAAZiS0dEAP8A/wD/oL2nkwAAAAlwSFlzAAAsSgAALEoBd3p0TQAAAAd0SU1FB+gBBQ0zO3HF9YoAAAPCSURBVFjD3ZZ/iFVVEMc/72W00UIXKeYZxdoPKqE4/bBk64/WIOSmUYYUFGEZeQuFbQ2pDTYeGVlKbFL/3ELaqMBKCFn0+iNsH1lhWe0JpZcku4uRb/4ILilsm8brj+bB5bX73nMrYh04nDtzz5wz3zNzZiYXhFGV6dNBYH6axBMibgC4zeS/A4PAM8C7wII6vU1A9yT7rQU2ZvhjwHpVP9jMkFn8M7oGmAOMAgKcB6wHOoCngCNAwc7ZnNEbBt4GHHCPAUuBU8Bc4GWgDKwGPhBxs1X9eCND8vy7lKr6fqDX+CtsnjCwo8BBVT+k6ovANvv/qvGp8TtV/QBwAGgpYuo9MgCMATngCeBCk4/aDQLcDVw3xX4dIu4QMNtu9yPgRuAy4I3MXlub2JWIOIA2oK+ZNyYFkiZxCSAIoy3AXguNsTSJiybvaADkBPCheWCHqvdm0H5V33kanu0FvrUQewx4YdpvJE3i74MwWgh8choG/GIh8re3JOK+yPD3qvpjDfYZVvUlETcEPD2d0KoHUw7CqAt4roW93reQmkx+oE42YfMh4BXgV+OPGn/U+D3ALBHXpup/a3R4ri79dqVJXArCqB3IpUl83MLp3DSJx+37LeDhjM6laRKP8j/TVB65ABgMwuiONIkrNRCNSMStBK4Gnlf1qYhbDNyg6tfZ//st1eaBwVwu916lMlwVcfOsplwC/ABsUvVjIq6v3sOqvkfE9VtW2yXiClZ7Dueb1Ih9QRhd1eKlLAV6rI4A3AqsMBAbgC1mWDvwTrVafbNQcGdZQukEvgLuBHaZ/grgQSumCzJF9UmgU8SdD+w2nW3N6sjlQCkIo/ktghkHVoq4mzOeEgO4WdUvUvWLgX7g0WqVa62QHgFiYAnwkog729R3qPpbaiNzTjuwHTgHuF3VV1opiAJ8GoTRSBBGI8CyBmu/BD4DXgf+MNk8C+F9mXXbbQ4std4F/AwMAXNU/Un7v1zEVW3szuh3m8dHatmv1creZq3DXLuNRrQauB64z/iKzRdl1lyZeaN7DewSYD/wooi7qVbhgYU21mb0f7S0vEjERf9Fi4Kq/w54rWasqi8DJaBXxK0Rcd3mha+t6dwDPAsct6pPxpsFoMvG0mxKV/UbzLMbRVzHVFlrAvi8BbvL+b9aGgA1zwEU7RZPGL/MutpiLWsBPaq+IuIeAtYBj1i326fqvxFxPwEXA8sz5xUNbK0nexz4GChOWkeYgZTnDKEskJMWHjMayCnggTSJyzMdyKo0ibfO6NgKwmjNmfBG/gQK6VFcQ3FNKgAAAABJRU5ErkJggg==" />
Šablona
Šablonu jsem postavil na Business template. Přidal jsem ještě některé styly na další úpravy. Některé jsem později vypnul, protože jsem našel jinou volbu v nastavení, které problém řešila.
/* [data-ref="product_table-product.item-th"], [data-ref="product_table-product.item-td"] { display:none; }*/ p[data-ref="company_details-company.id_number"]::before { content: "I\00010C: "; display: inline; /* nebo 'inline-block' pokud potřebujete další formátování */ } p[data-ref="company_details-company.id_number"], p[data-ref="company_details-company.id_number"] > p { display: inline-block; margin-bottom: 5px; } [data-ref="company_details-company.custom1"]{ margin-top: 10px; } p[data-ref="client_details-client.number"]:not(:empty)::before { content: "I\00010C: "; display: inline; /* nebo 'inline-block' pokud potřebujete další formátování */ } p[data-ref="client_details-client.number"], p[data-ref="client_details-client.number"] > p { display: inline-block; } p[data-ref="client_details-client.vat_number"]:not(:empty)::before { content: "DI\00010C: "; display: inline; /* nebo 'inline-block' pokud potřebujete další formátování */ } p[data-ref="client_details-client.vat_number"], p[data-ref="client_details-client.vat_number"] > p { display: inline-block; margin-bottom: 10px; /* Pro jistotu, aby nebyly žádné defaultní marginy */ } #payment-instructions{ font-size: 18px !important; padding-bottom: 30px; padding-top: 10px; } #payment-instructions strong{ font-size: 20px; } [data-ref="client_details-client.phone"] { margin-top: 10px } /*[data-ref="totals_table-net_subtotal"] { display: none } [data-ref="totals_table-net_subtotal-label"] { display: none } [data-ref="totals_table-subtotal-label"] { display: none } [data-ref="totals_table-subtotal"] { display: none }*/
A tady kód samotné šablony.
<div id="body"> <div class="header-container"> <img src="$company.logo" class="company-logo" alt="$company.name logo"> <div id="company-details"></div> <div id="company-address"></div> </div> <div class="client-and-entity-wrapper"> <div id="client-details"><p class="entity-issued-to">$entity_issued_to_label:</p></div> <div id="vendor-details"></div> <div id="shipping-details"></div> <div class="entity-details-wrapper"> <table id="entity-details" cellspacing="0" dir="$dir"></table> </div> </div> <div id="payment-instructions">Platbu <strong>$amount</strong> proveďte na účet číslo <strong>280 158 1174/2010</strong>, s variabilním symbolem <strong>$number</strong></div> <table id="product-table" cellspacing="0" data-ref="table"></table> <table id="task-table" cellspacing="0" data-ref="table"></table> <table id="delivery-note-table" cellspacing="0" data-ref="table"></table> <table id="statement-invoice-table" cellspacing="0" data-ref="table"></table> <div id="statement-invoice-table-totals" data-ref="statement-totals"></div> <table id="statement-payment-table" cellspacing="0" data-ref="table"></table> <div id="statement-payment-table-totals" data-ref="statement-totals"></div> <table id="statement-credit-table" cellspacing="0" data-ref="table"></table> <div id="statement-credit-table-totals" data-ref="statement-totals"></div> <table id="statement-aging-table" cellspacing="0" data-ref="table"></table> <div id="statement-aging-table-totals" data-ref="statement-totals"></div> <div id="table-totals" cellspacing="0">$status_logo</div> <img src="data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAABBQAAAF8CAYAAAB..." width="35%" style="display: block; margin-left: auto;" /> </div> <div> <img src="https://chart.googleapis.com/chart?cht=qr&chl=SPD*1.0*ACC:CZ8520100000002801581174*AM:$amount_raw*CC:CZK*X-VS:$number&chs=200x200&chld=L|0" class="qr-code img-thumbnail img-responsive" /> </div>
Výsledek pak vypadá takto: