V rámci kontextu Objednávka (agenda Prodejní objednávky) máme vytvořené 2 Dokumenty. Dokument s ID 4 je dodaný parametrizací, což poznáme podle upozornění [1.5] a vyplněného kódu [1.4]. Parametrizační dokumenty neupravujeme, ale pro provedení změny zkopírujeme jejich obsah a vytvoříme nový dokument. Nový dokument zobrazíme pouze požadovaným rolím [2.2] (nebo všem) a naopak parametrizační doument, který byl dosud zobrazován všem [1.2], nastavením rolí skryjeme, takže se nebude zobrazovat na detailu vybrané agendy.
U parametrizačních dokumentů upravujeme pouze pole Povoleno pro role, které se při aktualizaci systému nepřepíše.
Pro skrytí dokumentu pro většinu uživatelů nastavíme na Dokument správcovskou roli, respektive její ekvivalent. Případně můžeme vytvořit roli speciálně za účelem skrývání parametrizačních dokumentů. Toto má vliv pouze na zobrazení na detailu agendy z kontextu, nikoliv na přístup k nastavení dokumentu.
Pokud existuje alespoň jeden dokument s kontextem aktuální agendy, který nám není skrytý, zobrazí se na detailu karta Dokumenty [3.1]. Dokumenty s vyšší Váhou řazení [2.3] se zobrazí dříve [3.2]. Parametrizační dokumenty jsou podbarveny modře [3.3]. V závislosti na zvolené šabloně se nám zobrazí příslušné možnosti generování/vyplnění dokumentu a jeho stažení [3.4]/zobrazení [3.5]. Každý dokument lze navíc odeslat e-mailem [3.6].
Pro snazší tvorbu šablon použijte funkci náhledu kliknutím na ikonu oka .
V rámci šablony rozlišujeme hlavičku, tělo a patičku. Hlavička a patička se automaticky opakují na každé stránce vygenerovaného dokumentu v záhlaví, respektive v zápatí. Tělo představuje hlavní a zároveň povinnou část dokumentu (pokud šablonu nevkládáme souborem).
Doporučujeme zachovávat vzhled hlavičky a patičky šablony napříč dokumenty. Za tímto účelem jsme pro vás vytvořily fragmenty.
Pozor, nezaměňujte hlavičku, tělo a patičku šablony s HTML tagy
<head>
,<body>
a<footer>
. Jednotlivé části šablony NEJSOU EKVIVALENTY tagů a v rámci každé části zapisujeme tyto tagy zvlášť.
entity
získáváme další potřebná data dle pravidel Jexlu.Název funkce | Originál | Výsledek | Komentář |
---|---|---|---|
formatNumber | 1234567.7891 | 1 234 567,7891 | pokud není žádné číslo, nezobrazí se nic |
formatNumberOrZero | jako formatNumber, ale pokud není žádné číslo, zobrazí se nula | ||
formatCurrency | 1234567.7891 | 1 234 567,79 | pokud není žádné číslo, nezobrazí se nic |
1234567 | 1 234 567 | ||
formatCurrencyOrZero | jako formatCurrency, ale pokud není žádné číslo, zobrazí se nula | ||
formatCurrencyDecimal | 1234567.7891 | 1 234 567,79 | pokud není žádné číslo, nezobrazí se nic |
1234567 | 1 234 567,00 | ||
formatCurrencyDecimalOrZero | jako formatCurrencyDecimal, ale pokud není žádné číslo, zobrazí se 0,00 | ||
formatDate | 1999-05-04 | 04.05.1999 | |
formatMonth | 1999-05-04 | 05/1999 | |
convertMarkdownToHtml | ## Nadpis2 | <h2>Nadpis2</h2> |
pro správné konvertování obrázků je třeba do html hlavičky vložit <base href="{{#queryString}}{{/queryString}}"> , eventuelně obrázkům nastavit absolutní cestu |
queryString | {{#queryString}}nejaky text{{/queryString}} | https://my-company-name.factorify.cloudnejaky text |
|
storagePath | {{#storagePath}}nejaky text{{/storagePath}} | https://my-company-name.factorify.cloud/nejaky text |
{{currentUser}}
${currentUser}
Zástupka | Popis | Použití / Odvozené zástupky* |
---|---|---|
currentUser |
entita aktuálně přihlášeného uživatele | jméno člověka: currentUser.lastnameFirstname |
today |
dnešní datum | |
myCompany |
entita mé Společnosti | myCompany.www , myCompany.name ... |
myBillingAddress |
entita mé doručovací Adresy | myBillingAddress.name , myBillingAddress.addressLine , myBillingAddress.zip ... |
myBillingAddressForAccountingUnit |
entita Adresy nastavené na Účetní jednotce | stejné jako pro myBillingAddress |
logoUrl |
url malého loga společnosti, které je nahráno na Účetní jednotce; použito v parametrizovaných dokumentech | Mustache: <img src="{{#queryString}}/{{logoUrl}}{{/queryString}}"> Jexl: <img src="${queryService.queryString() + '/' + logoUrl}"> |
mediumLogoUrl |
url středního loga společnosti, které je nahráno na Účetní jednotce | viz logoUrl |
companyColor |
barva společnosti nastavená na Účetní jednotce | |
companyFileNumberText |
hodnota pole Zápis v obchodním rejstříku na Účetní jednotce | |
title |
název dokumentu | |
id |
id entity, ze které se tiskne dokument | |
entity |
entita, ze které se tiskne dokument; při použití Jexlu na základě této zástupky většinou získáváme všechna potřebná data | specifické dle entity |
*Pro zjištění, jaká pole existují u zástupek pro entity, se použije zástupka pro celou entitu (například myCompany), tak se zobrazí všechna pole i s hodnotami a následně je možné vybrat požadovaná pole.
Na konci dotazu nepíšeme středník!
Rozlišujeme 2 druhy parametrů:
:nazevParametru
; zástupky často vyžadují přidání Parametrů dotazu s předem definovanými kódy (viz sloupec Podmínka).Parametr (zástupka) | Poskytnutá data | Podmínka | Poznámka | |
---|---|---|---|---|
:accountingUnitId |
ID aktuální účetní jednotky | x | ||
:balanceSheet |
List<QueryAccountingStatementRow> *** |
parametry dotazu s kódy startDate a endDate , nepovinně costCenterId , projectId |
||
:balanceSheetValidation |
List<AccountDocumentBalance> = [{"accountNumber", "kind", "ignoreInStatements", "amount", "initialAmount"}] *** |
parametry dotazu s kódy startDate a endDate , nepovinně costCenterId , projectId |
||
:batchBom |
BatchBillOfMaterial = {"batchId", "carrierId", "goodsId", "goodsCode", "goodsName", "quantity", "parts"} ** |
parametr dotazu s kódem batchId |
||
:batchOrder |
BatchOrder = {"orderId", "salesOrderId"} ** |
parametr dotazu s kódem batchId |
||
:batchTree |
List<BatchNode> *** |
parametr dotazu s kódem batchId |
||
:economicResult |
AccountMonthBalance ** |
parametry dotazu s kódy startDate , endDate , nepovinně costCenterId , projectId , currency a accountIds |
||
:employerResponsibilityInsurance |
Map<ID osoby, částka> ** |
parametry dotazu s kódy year a month |
||
:id |
ID aktuální entity | pro účely testování/náhledu doplníme i jako parametr dotazu | při generování z detailu se doplní automaticky | |
:incomeStatement |
List<QueryAccountingStatementRow> *** |
parametry dotazu s kódy startDate , endDate , nepovinně costCenterId , projectId |
||
:paymentQr |
informace o platbě | pro účely testování/náhledu je třeba doplnit parametr dotazu s kódem id | funguje pro Účetní doklad, který není typu dobropis; zobrazení QR kódu v Jexlu: <img src="${queryService.queryString() + '/barcode?code=' + paymentQrAlias + '&type=QRCODE&height=200&width=200'}"/> zobrazení QR kódu v Mustache: <img src="{{#queryString}}/barcode?code={{paymentQrAlias}}&type=QRCODE&height=200&width=200{{/queryString}}"> |
|
:remainingHolidayDays |
List<RemainingHoliday> = [{"persond", "days"}] *** |
parametry dotazu s kódy year a month |
||
:supervisorStages |
List<StageSupervisor> = [{"id", "stageGroupId", "name", "type", "batchNoteEditable", "batches", "tasks"}] *** |
x | ||
:trialBalance |
List<AccountMoveGroup> *** |
parametry dotazu s kódy startDate a endDate , nepovinně costCenterId , projectId synthetic , currency a accountIds |
||
:userId |
ID aktuálně přihlášeného uživatele | x | ||
:vatReport |
Object ** |
pro účely testování/náhledu je třeba doplnit parametr dotazu s kódem id |
pro kontext Hlášení DPH |
**zobrazením objektu se nám ukážou dostupná data (soupis klíčů a hodnot), převedením na JSON ( :batchBom::JSON AS example) k nim pak můžeme přistupovat pomocí dot notation: objekt.klic
; například example.carrierId
***jedná se JSON pole (více JSON objektů), podobně jako u JSON objektu ho můžeme zobrazit, abychom viděli dostupná data, abychom k nim mohli přistupovat, musíme nejdříve získat jednotlivé JSON objekty
Pro unifikaci stylů, záhlaví a zápatí dokumentu používáme HTML fragmenty dokumentů, které vytváříme ve stejnojmenné agendě.
Pro použití fragmentu v dokumentu používáme specifický zápis: {{#kód-fragmentu#}}, tedy např.: {{#head#}}.
Podle obsahu se fragment vloží do html hlavičky (<head>
) nebo do těla (<body>
).
Aktuálně máme připravenou sadu 3+3 základních zástupek, a to vždy jeden pro Mustache a jeden pro Jexl:
<head>
do všech částí šablony.<body>
Hlavičky HTML šablony<body>
Patičky HTML šablonyPokud je ve fragmentu použita zástupka, ale požadujeme jinou hodnotu (typicky pro zástupku title
), přepíšeme tuto hodnotu použitím dané zástupky jakožto aliasu v SQL dotazu, eventuelně můžeme hodnotu přepsat v Jexlu.
Fragment a dokument musí zobrazovat data stejným způsobem (Mustache NEBO Jexl)!
Příklad Hlavičky HTML šablony vytvořené za použití HTML fragmentů:
Kód
<!DOCTYPE html>
<html lang="cs">
<head>{{#jexl-head#}}</head>
<body class="padding-bottom-half">{{#jexl-header#}}</body>
</html>
Výsledek
/* UNIVERSAL */
html,
body {
width: 100%;
margin: 0;
padding: 0;
left: 0;
top: 0;
-webkit-print-color-adjust: exact;
}
/* ROOT FONT STYLES */
* {
font-family: 'Open Sans', 'Helvetica Neue', sans-serif;
color: #333447;
font-size: 12px;
line-height: 1.5;
}
/* TYPOGRAPHY */
h1 {
font-size: 1.75rem;
margin-bottom: 10px;
}
h2 {
font-size: 1.5rem;
margin-bottom: 10px;
}
h3 {
font-size: 1.25rem;
margin-bottom: 10px;
}
h4 {
font-size: 1rem;
margin-bottom: 10px;
}
h5 {
font-size: 0.75rem;
margin-bottom: 10px;
}
h6 {
font-size: 0.5rem;
margin-bottom: 10px;
}
ul {
padding: 10px;
}
img {
width: 100%;
height: auto;
}
.nowrap {
white-space: nowrap;
}
.pre-line {
white-space: pre-line;
}
/* ==== GRID SYSTEM ==== */
* {
box-sizing: border-box;
}
*:before,
*:after {
box-sizing: border-box;
}
.row {
margin-right: -1rem;
margin-left: 0rem;
}
.row-no-gutters {
margin-right: 0;
margin-left: 0;
}
.row-no-gutters [class*='col-'] {
padding-right: 0;
padding-left: 0;
}
.col-1,
.col-sm-1,
.col-md-1,
.col-lg-1,
.col-2,
.col-sm-2,
.col-md-2,
.col-lg-2,
.col-3,
.col-sm-3,
.col-md-3,
.col-lg-3,
.col-4,
.col-sm-4,
.col-md-4,
.col-lg-4,
.col-5,
.col-sm-5,
.col-md-5,
.col-lg-5,
.col-6,
.col-sm-6,
.col-md-6,
.col-lg-6,
.col-7,
.col-sm-7,
.col-md-7,
.col-lg-7,
.col-8,
.col-sm-8,
.col-md-8,
.col-lg-8,
.col-9,
.col-sm-9,
.col-md-9,
.col-lg-9,
.col-10,
.col-sm-10,
.col-md-10,
.col-lg-10,
.col-11,
.col-sm-11,
.col-md-11,
.col-lg-11,
.col-12,
.col-sm-12,
.col-md-12,
.col-lg-12 {
position: relative;
min-height: 1px;
padding-right: 0rem;
padding-left: 1rem;
}
.col-1,
.col-2,
.col-3,
.col-4,
.col-5,
.col-6,
.col-7,
.col-8,
.col-9,
.col-10,
.col-11,
.col-12 {
float: left;
}
.col-12 {
width: 100%;
}
.col-11 {
width: 91.66666667%;
}
.col-10 {
width: 83.33333333%;
}
.col-9 {
width: 75%;
}
.col-8 {
width: 66.66666667%;
}
.col-7 {
width: 58.33333333%;
}
.col-6 {
width: 50%;
}
.col-5 {
width: 41.66666667%;
}
.col-4 {
width: 33.33333333%;
}
.col-3 {
width: 25%;
}
.col-2 {
width: 16.66666667%;
}
.col-1 {
width: 8.33333333%;
}
.width-auto {
width: auto;
}
.height-auto {
height: auto;
}
.clearfix:before,
.clearfix:after,
.container:before,
.container:after,
.container-fluid:before,
.container-fluid:after,
.row:before,
.row:after {
display: block;
content: '';
}
.clearfix:after,
.container:after,
.container-fluid:after,
.row:after {
clear: both;
}
/* ==== TABLES ==== */
table {
background-color: transparent;
border-collapse: collapse;
width: 100%;
max-width: 100%;
margin-bottom: 20px;
font-size: 1rem;
page-break-inside: avoid;
}
table col[class*='col-'] {
position: static;
display: table-column;
float: none;
}
table td[class*='col-'],
table th[class*='col-'] {
position: static;
display: table-cell;
float: none;
}
th {
text-align: left;
font-size: 1.1rem;
}
th, td {
line-height: 1.3 !important;
}
tr th.fake-row {
height: 0;
padding: 0 !important;
background: transparent !important;
border: none !important;
}
table > thead > tr > th,
table > tbody > tr > th,
table > tfoot > tr > th,
table > thead > tr > td,
table > tbody > tr > td,
table > tfoot > tr > td {
padding: 3px 6px;
vertical-align: middle;
border-top: 1px solid #ddd;
page-break-inside: avoid;
}
table > thead > tr > th,
table > tfoot > tr > th,
table > tbody.tfoot > tr > td,
table > tbody.tfoot > tr > th {
padding: 6px;
background: whitesmoke;
}
table > thead > tr > th {
vertical-align: bottom;
}
table > caption + thead > tr:first-child > th,
table > colgroup + thead > tr:first-child > th,
table > thead:first-child > tr:first-child > th,
table > caption + thead > tr:first-child > td,
table > colgroup + thead > tr:first-child > td,
table > thead:first-child > tr:first-child > td {
border-top: 0;
}
table > tbody + tbody {
border-top: 2px solid #ddd;
}
table > tbody + tbody:last-of-type {
border-width: 1px;
}
table > tfoot > tr:last-child th,
table > tfoot > tr:last-child td,
table > tbody.tfoot tr:last-child td,
table > tbody.tfoot tr:last-child th {
border-bottom: 2px solid #ddd;
}
.table-bordered {
border: 1px solid #ddd;
}
.table-bordered > thead > tr > th,
.table-bordered > tbody > tr > th,
.table-bordered > tfoot > tr > th,
.table-bordered > thead > tr > td,
.table-bordered > tbody > tr > td,
.table-bordered > tfoot > tr > td {
border: 1px solid #ddd;
}
.table-bordered > thead > tr > th,
.table-bordered > thead > tr > td {
border-bottom-width: 2px;
}
.table-striped > tbody > tr:nth-of-type(odd) {
background-color: #f9f9f9;
}
.table-striped-even > tbody > tr:nth-of-type(even) {
background-color: #f9f9f9;
}
),
.table-striped-2 > tbody > tr:nth-of-type(4n + 2) {
background-color: #f9f9f9;
}
.table-striped-even-2 > tbody > tr:nth-of-type(4n + 3),
.table-striped-even-2 > tbody > tr:nth-of-type(4n + 4) {
background-color: #f9f9f9;
}
.table-striped-even-3 > tbody > tr:nth-of-type(6n + 4),
.table-striped-even-3 > tbody > tr:nth-of-type(6n + 5),
.table-striped-even-3 > tbody > tr:nth-of-type(6n + 6) {
background-color: #f9f9f9;
}
.table-no-border > thead > tr > th,
.table-no-border > tbody > tr > th,
.table-no-border > tfoot > tr > th,
.table-no-border > thead > tr > td,
.table-no-border > tbody > tr > td,
.table-no-border > tfoot > tr > td {
border: none;
}
table > tbody > tr.hidden-row > td {
padding: 0;
border: none;
}
table > tbody > tr.hidden-row > td > div {
display: none;
}
.table-text-vertical-center th {
vertical-align: middle;
}
caption {
text-align: left;
font-size: 1.5rem;
margin-bottom: 20px;
font-weight: bold;
}
/* ==== HELPERS ==== */
.background-grey {
background: whitesmoke;
}
.background-transparent {
background-color: transparent;
}
.margin {
margin: 20px;
}
.margin-0 {
margin: 0;
}
.margin-half {
margin: 10px;
}
.margin-quarter {
margin: 5px;
}
.margin-x {
margin-top: 20px;
margin-bottom: 20px;
}
.margin-x-0 {
margin-top: 0;
margin-bottom: 0;
}
.margin-x-half {
margin-top: 10px;
margin-bottom: 10px;
}
.margin-x-quarter {
margin-top: 5px;
margin-bottom: 5px;
}
.margin-y {
margin-left: 20px;
margin-right: 20px;
}
.margin-y-0 {
margin-left: 0;
margin-right: 0;
}
.margin-y-half {
margin-left: 10px;
margin-right: 10px;
}
.margin-y-quarter {
margin-left: 5px;
margin-right: 5px;
}
.margin-top {
margin-top: 20px !important;
}
.margin-right {
margin-right: 20px !important;
}
.margin-bottom {
margin-bottom: 20px !important;
}
.margin-left {
margin-left: 20px !important;
}
.margin-top-0 {
margin-top: 0 !important;
}
.margin-right-0 {
margin-right: 0 !important;
}
.margin-bottom-0 {
margin-bottom: 0 !important;
}
.margin-left-0 {
margin-left: 0 !important;
}
.margin-top-half {
margin-top: 10px !important;
}
.margin-right-half {
margin-right: 10px !important;
}
.margin-bottom-half {
margin-bottom: 10px !important;
}
.margin-left-half {
margin-left: 10px !important;
}
.margin-top-quarter {
margin-top: 5px !important;
}
.margin-right-quarter {
margin-right: 5px !important;
}
.margin-bottom-quarter {
margin-bottom: 5px !important;
}
.margin-left-quarter {
margin-left: 5px !important;
}
.padding {
padding: 20px;
}
.padding-0 {
padding: 0;
}
.padding-half, .spacious-table-rows > td, .spacious-table-rows > th {
padding: 10px;
}
.padding-quarter {
padding: 5px;
}
.padding-x {
padding-top: 20px;
padding-bottom: 20px;
}
.padding-x-0 {
padding-top: 0;
padding-bottom: 0;
}
.padding-x-half, .higher-table-rows > td, .higher-table-rows > th {
padding-top: 10px;
padding-bottom: 10px;
}
.padding-x-quarter {
padding-top: 5px;
padding-bottom: 5px;
}
.padding-y {
padding-left: 20px;
padding-right: 20px;
}
.padding-y-0 {
padding-left: 0;
padding-right: 0;
}
.padding-y-half, .wider-table-rows > td, .wider-table-rows > th {
padding-left: 10px;
padding-right: 10px;
}
.padding-y-quarter {
padding-left: 5px;
padding-right: 5px;
}
.padding-top {
padding-top: 20px !important;
}
.padding-right {
padding-right: 20px !important;
}
.padding-bottom {
padding-bottom: 20px !important;
}
.padding-left {
padding-left: 20px !important;
}
.padding-top-0 {
padding-top: 0 !important;
}
.padding-right-0 {
padding-right: 0 !important;
}
.padding-bottom-0 {
padding-bottom: 0 !important;
}
.padding-left-0 {
padding-left: 0 !important;
}
.padding-top-half {
padding-top: 10px !important;
}
.padding-right-half {
padding-right: 10px !important;
}
.padding-bottom-half {
padding-bottom: 10px !important;
}
.padding-left-half {
padding-left: 10px !important;
}
.padding-top-quarter {
padding-top: 5px !important;
}
.padding-right-quarter {
padding-right: 5px !important;
}
.padding-bottom-quarter {
padding-bottom: 5px !important;
}
.padding-left-quarter {
padding-left: 5px !important;
}
.border {
border: 1px solid #dddddd !important;
}
.border-top {
border-top: 1px solid #dddddd !important;
}
.border-right {
border-right: 1px solid #dddddd !important;
}
.border-bottom {
border-bottom: 1px solid #dddddd !important;
}
.border-left {
border-left: 1px solid #dddddd !important;
}
.border-0 {
border: none !important;
}
.border-top-0 {
border-top: none !important;
}
.border-right-0 {
border-right: none !important;
}
.border-bottom-0 {
border-bottom: none !important;
}
.border-left-0 {
border-left: none !important;
}
.text-uppercase {
text-transform: uppercase;
}
.text-light {
font-weight: 300;
}
.text-regular {
font-weight: 400;
}
.text-strong {
font-weight: 700;
}
.text-white {
color: #fff;
}
/* POSITIONING */
.text-left {
text-align: left;
}
.text-right {
text-align: right;
}
.text-center {
text-align: center;
}
.text-justify {
text-align: justify;
}
.text-sm {
font-size: 0.8rem;
}
.text-md, .text-document-info div {
font-size: 1.2rem;
}
.text-lg {
font-size: 1.55rem;
}
.text-xl {
font-size: 2rem;
}
.whitespace-pre {
white-space: pre;
}
.spacer {
-webkit-box-flex: 1;
-webkit-flex: 1 1 auto;
flex: 1 1 auto;
}
.block {
display: block;
}
.flex {
display: -webkit-box;
display: -webkit-flex;
display: flex;
}
.flex-v-center {
-webkit-box-align: center;
-webkit-align-items: center;
align-items: center;
}
.page-break-inside-avoid {
page-break-inside: avoid;
}
.page-break-before, .new-page {
page-break-before: always;
}
.page-break-after {
page-break-after: always;
}
.page-break-inside-auto {
page-break-inside: auto;
}
/* ==== PARTIALS ==== */
/*HEADER*/
header {
margin-bottom: 1rem;
padding: 0.5rem 0;
border-bottom: solid 2px #ddd;
display: -webkit-box;
display: -webkit-flex;
display: flex;
-webkit-box-align: center;
-webkit-align-items: center;
align-items: center;
font-size: 0.8rem;
}
.header-address {
-webkit-box-flex: 3;
-webkit-flex: 3;
flex: 3;
display: -webkit-box;
display: -webkit-flex;
display: flex;
-webkit-box-align: center;
-webkit-align-items: center;
align-items: center;
}
.header-address > div {
max-width: 100px;
margin-right: 0.5rem;
}
.header-info {
-webkit-box-flex: 3;
-webkit-flex: 3;
flex: 3;
display: -webkit-box;
display: -webkit-flex;
display: flex;
}
.header-title {
-webkit-box-flex: 2;
-webkit-flex: 2;
flex: 2;
text-align: center;
margin: 0 0.5rem;
}
header ul {
list-style: none;
padding: 0;
margin: 0;
}
header h3,
header div {
line-height: 1.2;
margin: 0;
}
header.header-narrow {
-webkit-box-pack: justify;
-webkit-justify-content: space-between;
justify-content: space-between;
-webkit-box-align: end;
-webkit-align-items: end;
align-items: end;
}
header.header-narrow > div {
min-width: 25%;
max-width: 25%;
}
header.header-narrow > div:nth-child(2) {
min-width: 50%;
max-width: 50%;
-webkit-box-pack: center;
-webkit-justify-content: center;
justify-content: center;
}
header.header-narrow h2 {
line-height: 1.1;
}
/*FOOTER*/
footer {
display: -webkit-box;
display: -webkit-flex;
display: flex;
margin-top: 10px;
page-break-inside: avoid;
}
footer .item {
min-width: 25%;
max-width: 25%;
border-right: solid 1px #e4e5e9;
text-align: center;
min-height: 100%;
-webkit-box-align: center;
-webkit-align-items: center;
align-items: center;
-webkit-box-pack: center;
-webkit-justify-content: center;
justify-content: center;
}
footer .item-body {
display: -webkit-box;
display: -webkit-flex;
display: flex;
padding: 0.5rem;
-webkit-box-orient: vertical;
-webkit-box-direction: normal;
-webkit-flex-direction: column;
flex-direction: column;
}
footer .item i {
margin-bottom: 10px;
}
footer .item:last-child {
border: 0;
}