diff --git a/application/appRc.qrc b/application/appRc.qrc
index afa9743..e2ffa4c 100644
--- a/application/appRc.qrc
+++ b/application/appRc.qrc
@@ -5,5 +5,6 @@
style.css
icons/settings.svg
translations/prodejna_cs_CZ.qm
+ icons/shop.ico
diff --git a/application/application.pro b/application/application.pro
index e87e91f..8d608ac 100644
--- a/application/application.pro
+++ b/application/application.pro
@@ -22,6 +22,8 @@ win32 {
INCLUDEPATH += $$ODB_INCLUDE_PREFIX/libodb-qt-2.4.0
INCLUDEPATH += $$ODB_INCLUDE_PREFIX/libodb-sqlite-2.4.0
INCLUDEPATH += $$ODB_INCLUDE_PREFIX/sqlite
+
+ RC_FILE = shop.rc
}
SOURCES += main.cpp\
@@ -61,3 +63,6 @@ RESOURCES += \
appRc.qrc
TRANSLATIONS = translations/prodejna_cz.ts
+
+DISTFILES += \
+ shop.rc
diff --git a/application/icons/shop.ico b/application/icons/shop.ico
new file mode 100644
index 0000000..b7a49f3
Binary files /dev/null and b/application/icons/shop.ico differ
diff --git a/application/logindialog.ui b/application/logindialog.ui
index b4fd75e..56111cb 100644
--- a/application/logindialog.ui
+++ b/application/logindialog.ui
@@ -59,7 +59,7 @@
-
-
+
-
diff --git a/application/main.cpp b/application/main.cpp
index 6b68e87..7712bbc 100644
--- a/application/main.cpp
+++ b/application/main.cpp
@@ -19,7 +19,7 @@ int main(int argc, char *argv[])
MainWindow w;
w.move(QApplication::desktop()->screen()->rect().center() - w.rect().center());
- w.show();
+ w.showMaximized();
return a.exec();
}
diff --git a/application/mainwindow.ui b/application/mainwindow.ui
index 4a52742..e97c89e 100644
--- a/application/mainwindow.ui
+++ b/application/mainwindow.ui
@@ -13,6 +13,10 @@
MainWindow
+
+
+ :/icons/shop.ico:/icons/shop.ico
+
@@ -56,12 +60,12 @@
0
0
1000
- 21
+ 19
-
+
+ -9999999999999.000000000000000
+
9999999999.989999771118164
diff --git a/shop/eetbatchdialog.cpp b/shop/eetbatchdialog.cpp
new file mode 100644
index 0000000..59232e4
--- /dev/null
+++ b/shop/eetbatchdialog.cpp
@@ -0,0 +1,19 @@
+#include "eetbatchdialog.h"
+#include "ui_eetbatchdialog.h"
+
+EetBatchDialog::EetBatchDialog(QWidget *parent) :
+ QDialog(parent),
+ ui(new Ui::EetBatchDialog)
+{
+ ui->setupUi(this);
+}
+
+EetBatchDialog::~EetBatchDialog()
+{
+ delete ui;
+}
+
+void EetBatchDialog::addLog(const QString &log)
+{
+ ui->logView->setPlainText(ui->logView->toPlainText() + log);
+}
diff --git a/shop/eetbatchdialog.h b/shop/eetbatchdialog.h
new file mode 100644
index 0000000..9c15fba
--- /dev/null
+++ b/shop/eetbatchdialog.h
@@ -0,0 +1,23 @@
+#ifndef EETBATCHDIALOG_H
+#define EETBATCHDIALOG_H
+
+#include
+
+namespace Ui {
+class EetBatchDialog;
+}
+
+class EetBatchDialog : public QDialog
+{
+ Q_OBJECT
+
+public:
+ explicit EetBatchDialog(QWidget *parent = 0);
+ ~EetBatchDialog();
+ void addLog(const QString &log);
+
+private:
+ Ui::EetBatchDialog *ui;
+};
+
+#endif // EETBATCHDIALOG_H
diff --git a/shop/eetbatchdialog.ui b/shop/eetbatchdialog.ui
new file mode 100644
index 0000000..2a6bd2e
--- /dev/null
+++ b/shop/eetbatchdialog.ui
@@ -0,0 +1,74 @@
+
+
+ EetBatchDialog
+
+
+
+ 0
+ 0
+ 324
+ 272
+
+
+
+ EET batch send
+
+
+ true
+
+
+
-
+
+
+ true
+
+
+
+ -
+
+
+ Qt::Horizontal
+
+
+ QDialogButtonBox::Close
+
+
+
+
+
+
+
+
+ buttonBox
+ accepted()
+ EetBatchDialog
+ accept()
+
+
+ 248
+ 254
+
+
+ 157
+ 274
+
+
+
+
+ buttonBox
+ rejected()
+ EetBatchDialog
+ reject()
+
+
+ 316
+ 260
+
+
+ 286
+ 274
+
+
+
+
+
diff --git a/shop/icons/sendEet.svg b/shop/icons/sendEet.svg
new file mode 100644
index 0000000..ce6a617
--- /dev/null
+++ b/shop/icons/sendEet.svg
@@ -0,0 +1,8 @@
+
\ No newline at end of file
diff --git a/shop/paydialog.cpp b/shop/paydialog.cpp
index e272503..7e61370 100644
--- a/shop/paydialog.cpp
+++ b/shop/paydialog.cpp
@@ -1,5 +1,6 @@
#include "paydialog.h"
#include "ui_paydialog.h"
+#include "shopservice.h"
PayDialog::PayDialog(QDecDouble total, QWidget *parent) :
QDialog(parent),
@@ -10,6 +11,10 @@ PayDialog::PayDialog(QDecDouble total, QWidget *parent) :
ui->labelTotal->setText(QString::number(total.toDouble(), 'f', 2));
ui->labelReturn->setText(QString::number(0, 'f', 2));
+ ui->recieved->setFocus();
+
+ ShopService srv;
+ ui->checkEet->setVisible(srv.isEetEnabled());
}
PayDialog::~PayDialog()
@@ -17,6 +22,11 @@ PayDialog::~PayDialog()
delete ui;
}
+bool PayDialog::sendToEet()
+{
+ return ui->checkEet->checkState() == Qt::Checked;
+}
+
void PayDialog::on_recieved_valueChanged(double value)
{
diff --git a/shop/paydialog.h b/shop/paydialog.h
index 55d81cb..fba7df2 100644
--- a/shop/paydialog.h
+++ b/shop/paydialog.h
@@ -15,6 +15,7 @@ class PayDialog : public QDialog
public:
explicit PayDialog(QDecDouble total, QWidget *parent = 0);
~PayDialog();
+ bool sendToEet();
private slots:
diff --git a/shop/paydialog.ui b/shop/paydialog.ui
index fd9d4a2..25db67f 100644
--- a/shop/paydialog.ui
+++ b/shop/paydialog.ui
@@ -6,8 +6,8 @@
0
0
- 449
- 134
+ 457
+ 168
@@ -105,7 +105,7 @@
- -
+
-
false
@@ -118,6 +118,19 @@
+ -
+
+
+ Send to EET portal
+
+
+ true
+
+
+ true
+
+
+
diff --git a/shop/paydvouchersdialog.cpp b/shop/paydvouchersdialog.cpp
index 9bca5d7..b4ee136 100644
--- a/shop/paydvouchersdialog.cpp
+++ b/shop/paydvouchersdialog.cpp
@@ -5,6 +5,7 @@
#include "receiptgenerator.h"
#include "shopservice.h"
+#include "eetbatchdialog.h"
PaydVouchersDialog::PaydVouchersDialog(QWidget *parent) :
QDialog(parent),
@@ -14,10 +15,30 @@ PaydVouchersDialog::PaydVouchersDialog(QWidget *parent) :
m_voucherModel = new AutoTableModel(this);
m_itemModel = new AutoTableModel(this);
+ m_voucherModel->setTranslations(Context::instance().plugin("SHOP")->translations());
+ m_itemModel->setTranslations(Context::instance().plugin("SHOP")->translations());
ui->tableVouchers->setModel(m_voucherModel);
ui->tableItems->setModel(m_itemModel);
+ ui->tableVouchers->setColumnHidden(5, true);
+ ui->tableVouchers->setColumnHidden(6, true);
+ ui->tableVouchers->setColumnHidden(7, true);
+ ui->tableVouchers->setColumnHidden(8, true);
+ ui->tableVouchers->setColumnHidden(9, true);
+ ui->tableVouchers->setColumnHidden(10, true);
+ ui->tableVouchers->setColumnHidden(12, true);
+ ui->tableVouchers->setColumnHidden(13, true);
+ ui->tableVouchers->setColumnHidden(14, true);
+ ui->tableVouchers->setColumnHidden(15, true);
+ ui->tableVouchers->setColumnHidden(16, true);
+ ui->tableVouchers->setColumnHidden(17, true);
+ ui->tableVouchers->horizontalHeader()->setSectionResizeMode(2, QHeaderView::Stretch);
+ ui->tableVouchers->horizontalHeader()->setSectionResizeMode(3, QHeaderView::Stretch);
+ ui->tableVouchers->horizontalHeader()->setSectionResizeMode(4, QHeaderView::Stretch);
+
+ ui->tableItems->horizontalHeader()->setSectionResizeMode(0, QHeaderView::Stretch);
+
ShopService srv;
m_voucherModel->setData(srv.paiedVouchers());
@@ -27,6 +48,23 @@ PaydVouchersDialog::PaydVouchersDialog(QWidget *parent) :
m_itemModel->setData(voucher->items());
ui->total->setText(QString::number(voucher->totalPrice().toDouble(), 'f', 2));
+ switch (voucher->eetStatus()) {
+ case Voucher::EET_NOT_ENTERING:
+ ui->lblEetStatus->setText(tr("not entering"));
+ break;
+ case Voucher::EET_FOR_SEND:
+ ui->lblEetStatus->setText(tr("for send"));
+ break;
+ case Voucher::EET_ERROR:
+ ui->lblEetStatus->setText(tr("error"));
+ break;
+ case Voucher::EET_SENT:
+ ui->lblEetStatus->setText(tr("sent"));
+ break;
+ default:
+ break;
+ }
+
ui->btnPrint->setEnabled(true);
ui->btnSave->setEnabled(true);
});
@@ -59,3 +97,36 @@ void PaydVouchersDialog::on_btnSave_clicked()
generator.save();
}
}
+
+void PaydVouchersDialog::on_btnEetNotSen_clicked(bool checked)
+{
+ ShopService srv;
+
+ if (checked)
+ {
+ m_voucherModel->setData(srv.vouchersForEet());
+ }
+ else
+ {
+ m_voucherModel->setData(srv.paiedVouchers());
+ }
+
+ m_itemModel->setData(QList());
+}
+
+void PaydVouchersDialog::on_btnSendEet_clicked()
+{
+ ShopService srv;
+ QList vouchers = srv.vouchersForEet();
+ EetBatchDialog *dialog = new EetBatchDialog(this);
+ dialog->setAttribute(Qt::WA_DeleteOnClose);
+ dialog->show();
+
+ foreach (VoucherPtr vch, vouchers) {
+ QString msg;
+ bool sent = srv.processEet(vch, msg);
+ dialog->addLog(vch->numSer() + ": ");
+ dialog->addLog(sent ? "OK\n" : tr("Error"));
+ dialog->addLog((msg.isEmpty() && !sent) ? "\n" : ": " + msg);
+ }
+}
diff --git a/shop/paydvouchersdialog.h b/shop/paydvouchersdialog.h
index 973e3f0..9c8f5bf 100644
--- a/shop/paydvouchersdialog.h
+++ b/shop/paydvouchersdialog.h
@@ -24,6 +24,10 @@ private slots:
void on_btnSave_clicked();
+ void on_btnEetNotSen_clicked(bool checked);
+
+ void on_btnSendEet_clicked();
+
private:
Ui::PaydVouchersDialog *ui;
diff --git a/shop/paydvouchersdialog.ui b/shop/paydvouchersdialog.ui
index 8512420..feeb4dd 100644
--- a/shop/paydvouchersdialog.ui
+++ b/shop/paydvouchersdialog.ui
@@ -6,8 +6,8 @@
0
0
- 798
- 514
+ 900
+ 650
@@ -72,6 +72,49 @@
+ -
+
+
+ ...
+
+
+
+ :/icons/filter.svg:/icons/filter.svg
+
+
+
+ 32
+ 32
+
+
+
+ true
+
+
+ true
+
+
+
+ -
+
+
+ ...
+
+
+
+ :/icons/sendEet.svg:/icons/sendEet.svg
+
+
+
+ 32
+ 32
+
+
+
+ true
+
+
+
-
@@ -90,6 +133,12 @@
-
+
+
+ 0
+ 300
+
+
QAbstractItemView::SingleSelection
@@ -110,6 +159,39 @@
+ -
+
+
+
-
+
+
+ EET:
+
+
+
+ -
+
+
+
+
+
+
+ -
+
+
+ Qt::Horizontal
+
+
+
+ 40
+ 20
+
+
+
+
+
+
+
-
@@ -167,6 +249,7 @@
+
diff --git a/shop/receiptgenerator.cpp b/shop/receiptgenerator.cpp
index 4f513e1..8bab43b 100644
--- a/shop/receiptgenerator.cpp
+++ b/shop/receiptgenerator.cpp
@@ -5,6 +5,11 @@
#include
#include
+#ifdef _WIN32
+#include
+#include
+#endif
+
const QString ReceiptGenerator::DIACRITIC = "ÂâÁáÄäĂ㥹ĆćČčÇçĎďĐđÉéËëĚěĘęÍíÎîĹ弾ŁłŃńŇňÓóÖöÔôŐőŔŕŘřŚśŠšŞşŤťŢţÚúÜüŮůŰűÝýŹźŽžŻż";
const QString ReceiptGenerator::NON_DIACRITIC = "AaAaAaAaAaCcCcCcDdDdEeEeEeEeIiIiLlLlLlNnNnOoOoOoOoRrRrSsSsSsTtTtUuUuUuUuYyZzZzZz";
@@ -43,7 +48,48 @@ void ReceiptGenerator::save()
void ReceiptGenerator::print()
{
+#ifdef _WIN32
+ SettingsService srvShopSettings("SHOP");
+ ShopSettingsPtr shopSettings = srvShopSettings.loadSettings();
+ QString printer = shopSettings->output();
+
+ HANDLE hPrinter;
+ DOC_INFO_1 docInfo;
+ DWORD dwJob;
+ DWORD dwBytes;
+ BOOL bStatus = FALSE;
+
+ if (OpenPrinter((LPWSTR)printer.toStdWString().c_str(), &hPrinter, NULL))
+ {
+ docInfo.pDocName = L"Uctenka";
+ docInfo.pOutputFile = NULL;
+ docInfo.pDatatype = L"RAW";
+
+ dwJob = StartDocPrinter(hPrinter, 1, (LPBYTE)&docInfo);
+ if (dwJob > 0)
+ {
+ if (!StartPagePrinter(hPrinter))
+ {
+ ClosePrinter(hPrinter);
+ return;
+ }
+ QByteArray data = generate();
+ BOOL bPrinted = WritePrinter(hPrinter, (LPBYTE)data.data(), data.length(), &dwBytes);
+ EndPagePrinter(hPrinter);
+ EndDocPrinter(hPrinter);
+
+ if (!bPrinted)
+ {
+ DWORD dwErr = GetLastError();
+ int i = 1;
+ }
+ }
+ }
+
+ ClosePrinter(hPrinter);
+#else
save();
+#endif
}
QString ReceiptGenerator::outputFile() const
@@ -77,6 +123,12 @@ QByteArray ReceiptGenerator::generate()
out.append("\x0a");
out.append(prepareString("IC: " + QString::number(gs->ic())));
out.append("\x0a");
+ out.append(prepareString("DIC: " + gs->dic()));
+ out.append("\x0a");
+ out.append(prepareString("ID provozovny: " + shopSettings->eetShopId()));
+ out.append("\x0a");
+ out.append(prepareString("ID pokladny: " + shopSettings->eetRegisterId()));
+ out.append("\x0a");
out.append("\x1b\x21");
out.append(printMode);
@@ -89,12 +141,14 @@ QByteArray ReceiptGenerator::generate()
out.append("\x0a");
foreach (QSharedPointer item, m_voucher->items()) {
+ QString count = QString::number(item->count());
QString name = item->name();
QString price = QString::number(item->price().toDouble(), 'f', 2);
int numSpaces = 0;
if ((name.length() + price.length()) < shopSettings->lettersPerLine())
{
+ name = count + "x " + name;
numSpaces = shopSettings->lettersPerLine() - (name.length() + price.length());
out.append(prepareString(name));
}
@@ -125,7 +179,7 @@ QByteArray ReceiptGenerator::generate()
out.append("\x1b\x21");
out.append(printMode);
- out.append("Celekem:");
+ out.append("Celkem:");
QString totalPrice = QString::number(m_voucher->totalPrice().toDouble(), 'f', 2);
int numSpaces = shopSettings->lettersPerLine() - (8 + totalPrice.length());
@@ -138,7 +192,18 @@ QByteArray ReceiptGenerator::generate()
out.append("\x1b\x21");
out.append((char)0);
out.append("\x0a");
- out.append("\x0a");
+ if (!m_voucher->eetBkp().isEmpty())
+ {
+ out.append("BKP:");
+ out.append("\x0a");
+ out.append(prepareString(m_voucher->eetBkp()));
+ out.append("\x0a");
+ out.append("FIK:");
+ out.append("\x0a");
+ out.append(prepareString(m_voucher->eetFik()));
+ out.append("\x0a");
+ out.append("\x0a");
+ }
out.append("\x0a");
out.append("\x0a");
out.append("\x0a");
diff --git a/shop/receiptloadform.cpp b/shop/receiptloadform.cpp
index 1eff0a6..f00c506 100644
--- a/shop/receiptloadform.cpp
+++ b/shop/receiptloadform.cpp
@@ -16,20 +16,23 @@ ReceiptLoadForm::ReceiptLoadForm(QWidget *parent) :
m_voucherModel->setData(srv.all(QString("status = %1").arg(QString::number(Voucher::NOT_PAID))));
m_voucherModel->setTranslations(Context::instance().plugin("SHOP")->translations());
ui->tabVouchers->setModel(m_voucherModel);
- ui->tabVouchers->hideColumn(3);
- ui->tabVouchers->hideColumn(4);
+ ui->tabVouchers->hideColumn(0);
+ ui->tabVouchers->hideColumn(1);
ui->tabVouchers->hideColumn(5);
ui->tabVouchers->hideColumn(6);
ui->tabVouchers->hideColumn(7);
ui->tabVouchers->hideColumn(8);
+ ui->tabVouchers->hideColumn(9);
ui->tabVouchers->hideColumn(10);
- ui->tabVouchers->horizontalHeader()->setSectionResizeMode(1, QHeaderView::Stretch);
- ui->tabVouchers->setColumnWidth(0, 190);
- ui->tabVouchers->setColumnWidth(2, 200);
+ ui->tabVouchers->hideColumn(12);
+ ui->tabVouchers->horizontalHeader()->setSectionResizeMode(2, QHeaderView::Stretch);
+ ui->tabVouchers->setColumnWidth(3, 200);
+ ui->tabVouchers->setColumnWidth(4, 200);
m_itemModel = new AutoTableModel(this);
m_itemModel->setCheckboxSelect(true);
ui->tabItems->setModel(m_itemModel);
+ ui->tabItems->horizontalHeader()->setSectionResizeMode(0, QHeaderView::Stretch);
connect(ui->tabVouchers->selectionModel(), &QItemSelectionModel::currentRowChanged, [this](const QModelIndex ¤t, QModelIndex){
ShopService srv;
@@ -58,7 +61,7 @@ void ReceiptLoadForm::on_lineEdit_textChanged(const QString &text)
{
QSortFilterProxyModel proxy;
proxy.setSourceModel(m_voucherModel);
- proxy.setFilterKeyColumn(0);
+ proxy.setFilterKeyColumn(2);
proxy.setFilterFixedString(text);
QModelIndex matchingIndex = proxy.mapToSource(proxy.index(0,0));
diff --git a/shop/receiptloadform.ui b/shop/receiptloadform.ui
index 4651ac7..792874f 100644
--- a/shop/receiptloadform.ui
+++ b/shop/receiptloadform.ui
@@ -31,7 +31,14 @@
-
-
+
+
+ QAbstractItemView::SingleSelection
+
+
+ QAbstractItemView::SelectRows
+
+
diff --git a/shop/receiptsaveform.cpp b/shop/receiptsaveform.cpp
index 8106eb4..a2dc864 100644
--- a/shop/receiptsaveform.cpp
+++ b/shop/receiptsaveform.cpp
@@ -45,7 +45,7 @@ ReceiptSaveForm::ReceiptSaveForm(QSharedPointer voucher, QWidget *paren
ui->buttonBox->button(QDialogButtonBox::Ok)->setEnabled(!text.isEmpty());
});
- m_binder.setData(new Voucher);
+ m_binder.setData(voucher.data());
AddressBookService srvAdb;
m_binder.registerBinding(ui->contact, ComboData::createComboData(srvAdb.all()));
m_binder.registerBinding(ui->name);
@@ -66,6 +66,21 @@ ReceiptSaveForm::~ReceiptSaveForm()
delete ui;
}
+VoucherPtr ReceiptSaveForm::selectedVoucher()
+{
+ if (ui->tabVouchers->currentIndex().isValid())
+ {
+ return m_voucherModel->itemFromIndex(ui->tabVouchers->currentIndex());
+ }
+
+ return VoucherPtr();
+}
+
+bool ReceiptSaveForm::saveAsNew()
+{
+ return m_saveAsNew;
+}
+
void ReceiptSaveForm::on_lineEdit_textChanged(const QString &text)
{
QSortFilterProxyModel proxy;
diff --git a/shop/receiptsaveform.h b/shop/receiptsaveform.h
index 663f3c4..09e6175 100644
--- a/shop/receiptsaveform.h
+++ b/shop/receiptsaveform.h
@@ -18,6 +18,9 @@ public:
explicit ReceiptSaveForm(QSharedPointer voucher, QWidget *parent = 0);
~ReceiptSaveForm();
+ VoucherPtr selectedVoucher();
+ bool saveAsNew();
+
private slots:
void on_lineEdit_textChanged(const QString &text);
@@ -28,7 +31,7 @@ private:
ObjectBinder m_binder;
AutoTableModel *m_voucherModel;
bool m_saveAsNew;
- QSharedPointer m_voucher;
+ VoucherPtr m_voucher;
// QDialog interface
public slots:
diff --git a/shop/receiptsaveform.ui b/shop/receiptsaveform.ui
index aec56a6..58bc2f6 100644
--- a/shop/receiptsaveform.ui
+++ b/shop/receiptsaveform.ui
@@ -7,7 +7,7 @@
0
0
804
- 513
+ 578
@@ -51,6 +51,12 @@
250
+
+ QAbstractItemView::SingleSelection
+
+
+ QAbstractItemView::SelectRows
+
diff --git a/shop/settings/shopsettings.cpp b/shop/settings/shopsettings.cpp
index 78064d3..38e6ad5 100644
--- a/shop/settings/shopsettings.cpp
+++ b/shop/settings/shopsettings.cpp
@@ -4,6 +4,11 @@ ShopSettings::ShopSettings(QObject *parent) : QObject(parent)
{
m_codepage = ASCII;
m_lettersPerLine = 48;
+
+ m_eetActive = false;
+ m_eetMode = 1;
+ m_eetTest = 0;
+ m_eetPlayground = 0;
}
QString ShopSettings::output() const
@@ -45,3 +50,83 @@ void ShopSettings::setByMessage(const QString &byMessage)
{
m_byMessage = byMessage;
}
+
+bool ShopSettings::eetActive() const
+{
+ return m_eetActive;
+}
+
+void ShopSettings::setEetActive(bool eetActive)
+{
+ m_eetActive = eetActive;
+}
+
+QString ShopSettings::eetShopId() const
+{
+ return m_eetShopId;
+}
+
+void ShopSettings::setEetShopId(const QString &eetShopId)
+{
+ m_eetShopId = eetShopId;
+}
+
+QString ShopSettings::eetRegisterId() const
+{
+ return m_eetRegisterId;
+}
+
+void ShopSettings::setEetRegisterId(const QString &eetRegisterId)
+{
+ m_eetRegisterId = eetRegisterId;
+}
+
+int ShopSettings::eetMode() const
+{
+ return m_eetMode;
+}
+
+void ShopSettings::setEetMode(int eetMode)
+{
+ m_eetMode = eetMode;
+}
+
+QString ShopSettings::eetCertificate() const
+{
+ return m_eetCertificate;
+}
+
+void ShopSettings::setEetCertificate(const QString &eetCertificate)
+{
+ m_eetCertificate = eetCertificate;
+}
+
+QString ShopSettings::eetKeyPassword() const
+{
+ return m_eetKeyPassword;
+}
+
+void ShopSettings::setEetKeyPassword(const QString &eetKeyPassword)
+{
+ m_eetKeyPassword = eetKeyPassword;
+}
+
+bool ShopSettings::eetTest() const
+{
+ return m_eetTest;
+}
+
+void ShopSettings::setEetTest(bool eetTest)
+{
+ m_eetTest = eetTest;
+}
+
+bool ShopSettings::eetPlayground() const
+{
+ return m_eetPlayground;
+}
+
+void ShopSettings::setEetPlayground(bool eetPlayground)
+{
+ m_eetPlayground = eetPlayground;
+}
diff --git a/shop/settings/shopsettings.h b/shop/settings/shopsettings.h
index acfb626..d57f892 100644
--- a/shop/settings/shopsettings.h
+++ b/shop/settings/shopsettings.h
@@ -9,6 +9,15 @@ class ShopSettings : public QObject
Q_PROPERTY(int lettersPerLine READ lettersPerLine WRITE setLettersPerLine)
Q_PROPERTY(QString byMessage READ byMessage WRITE setByMessage)
+ Q_PROPERTY(bool eetActive READ eetActive WRITE setEetActive)
+ Q_PROPERTY(QString eetShopId READ eetShopId WRITE setEetShopId)
+ Q_PROPERTY(QString eetRegisterId READ eetRegisterId WRITE setEetRegisterId)
+ Q_PROPERTY(int eetMode READ eetMode WRITE setEetMode)
+ Q_PROPERTY(QString eetCertificate READ eetCertificate WRITE setEetCertificate)
+ Q_PROPERTY(QString eetKeyPassword READ eetKeyPassword WRITE setEetKeyPassword)
+ Q_PROPERTY(bool eetTest READ eetTest WRITE setEetTest)
+ Q_PROPERTY(bool eetPlayground READ eetPlayground WRITE setEetPlayground)
+
Q_OBJECT
public:
@@ -31,11 +40,44 @@ public:
QString byMessage() const;
void setByMessage(const QString &byMessage);
+ bool eetActive() const;
+ void setEetActive(bool eetActive);
+
+ QString eetShopId() const;
+ void setEetShopId(const QString &eetShopId);
+
+ QString eetRegisterId() const;
+ void setEetRegisterId(const QString &eetRegisterId);
+
+ int eetMode() const;
+ void setEetMode(int eetMode);
+
+ QString eetCertificate() const;
+ void setEetCertificate(const QString &eetCertificate);
+
+ QString eetKeyPassword() const;
+ void setEetKeyPassword(const QString &eetKeyPassword);
+
+ bool eetTest() const;
+ void setEetTest(bool eetTest);
+
+ bool eetPlayground() const;
+ void setEetPlayground(bool eetPlayground);
+
private:
QString m_output;
CODEPAGE m_codepage;
int m_lettersPerLine;
QString m_byMessage;
+
+ bool m_eetActive;
+ QString m_eetShopId;
+ QString m_eetRegisterId;
+ int m_eetMode;
+ QString m_eetCertificate;
+ QString m_eetKeyPassword;
+ bool m_eetTest;
+ bool m_eetPlayground;
};
typedef QSharedPointer ShopSettingsPtr;
diff --git a/shop/settings/shopsettingsform.cpp b/shop/settings/shopsettingsform.cpp
index b7280bf..b919ee9 100644
--- a/shop/settings/shopsettingsform.cpp
+++ b/shop/settings/shopsettingsform.cpp
@@ -2,6 +2,8 @@
#include "ui_shopsettingsform.h"
#include
+#include
+#include
#include "shopservice.h"
ShopSettingsForm::ShopSettingsForm(QWidget *parent) :
@@ -14,6 +16,17 @@ ShopSettingsForm::ShopSettingsForm(QWidget *parent) :
registerBinding(ui->lettersPerLine);
registerBinding(ui->byMessage);
+ registerBinding(ui->eetActive);
+ registerBinding(ui->eetShopId);
+ registerBinding(ui->eetRegisterId);
+ QList listModes;
+ listModes << ComboData(0, tr("Simplifyed")) << ComboData(1, tr("Standard"));
+ registerBinding(ui->eetMode, listModes);
+ registerBinding(ui->eetCertificate);
+ registerBinding(ui->eetKeyPassword);
+ registerBinding(ui->eetTest);
+ registerBinding(ui->eetPlayground);
+
m_itemModel = new AutoTableModel();
}
@@ -41,3 +54,13 @@ bool ShopSettingsForm::saveRecord()
return true;
}
+
+void ShopSettingsForm::on_btnCertBrowse_clicked()
+{
+ QString certFile = QFileDialog::getOpenFileName(this, "Certificate file", "", "P12 Files (*.p12)");
+
+ if (!certFile.isEmpty())
+ {
+ ui->eetCertificate->setText(certFile);
+ }
+}
diff --git a/shop/settings/shopsettingsform.h b/shop/settings/shopsettingsform.h
index f46f875..ecefb41 100644
--- a/shop/settings/shopsettingsform.h
+++ b/shop/settings/shopsettingsform.h
@@ -29,6 +29,8 @@ public:
public slots:
bool saveRecord();
+private slots:
+ void on_btnCertBrowse_clicked();
};
#endif // SHOPSETTINGSFORM_H
diff --git a/shop/settings/shopsettingsform.ui b/shop/settings/shopsettingsform.ui
index 7e5b2e6..b3ba813 100644
--- a/shop/settings/shopsettingsform.ui
+++ b/shop/settings/shopsettingsform.ui
@@ -234,6 +234,121 @@
+
+
+ EET
+
+
+ -
+
+
+ Activate EET
+
+
+ true
+
+
+ false
+
+
+
-
+
+
+ Shop ID
+
+
+
+ -
+
+
+ -
+
+
+ Cash register ID
+
+
+
+ -
+
+
+ -
+
+
+ EET mode
+
+
+
+ -
+
+
+ -
+
+
+ Certificate file
+
+
+
+ -
+
+
+
+ 0
+
+
+ 0
+
+
+ 0
+
+
+ 0
+
+
-
+
+
+ -
+
+
+ ...
+
+
+
+
+
+
+ -
+
+
+ Private key password
+
+
+
+ -
+
+
+ QLineEdit::Password
+
+
+
+ -
+
+
+ Test mode
+
+
+
+ -
+
+
+ Communication with playground
+
+
+
+
+
+
+
+
diff --git a/shop/shop.json b/shop/shop.json
index ccd3cab..8b9be10 100644
--- a/shop/shop.json
+++ b/shop/shop.json
@@ -47,6 +47,11 @@ CREATE TABLE \"Voucher\" (
\"totalPriceVatSecondLower\" INTEGER NOT NULL,
\"totalPrice\" INTEGER NOT NULL,
\"status\" INTEGER NOT NULL,
+ \"eetStatus\" INTEGER NOT NULL,
+ \"eetSendDateTime\" TEXT NULL,
+ \"eetPkp\" TEXT,
+ \"eetBkp\" TEXT,
+ \"eetFik\" TEXT,
CONSTRAINT \"contact_fk\"
FOREIGN KEY (\"contact\")
REFERENCES \"AddressbookData\" (\"id\")
@@ -69,6 +74,7 @@ CREATE TABLE \"Voucher\" (
"vatRateHigh" : "Vysoká sazba",
"vatRateFirstLower" : "První snížená sazba",
"vatRateSecondLower" : "Druhá snížená sazba",
+ "vatAmount" : "Dan",
"priceNoVat" : "Cena zboží s nulovou DPH",
"priceVatHigh" : "Cena zboží s vysokou sazbou DPH",
"priceVatFirstLower" : "Cena zboží s první sníženou sazbou DPH",
@@ -78,7 +84,9 @@ CREATE TABLE \"Voucher\" (
"totalPriceVatFirstLower" : "Celková cena zboží s první sníženou sazbou DPH",
"totalPriceVatSecondLower" : "Celková cena zboží s druhou sníženou sazbou DPH",
"totalPrice" : "Celková cena",
- "status" : "Stav"
+ "status" : "Stav",
+ "numSer" : "Číslo",
+ "payDateTime" : "Datum"
}
}
}
diff --git a/shop/shop.pro b/shop/shop.pro
index 8f16e30..9551c44 100644
--- a/shop/shop.pro
+++ b/shop/shop.pro
@@ -29,7 +29,8 @@ SOURCES += shop.cpp \
shopitem.cpp \
isellableservice.cpp \
data/favorititem.cpp \
- settings/favoriteservice.cpp
+ settings/favoriteservice.cpp \
+ eetbatchdialog.cpp
HEADERS += shop.h\
shop_global.h \
@@ -52,7 +53,8 @@ HEADERS += shop.h\
paydvouchersdialog.h \
shopitem.h \
data/favorititem.h \
- settings/favoriteservice.h
+ settings/favoriteservice.h \
+ eetbatchdialog.h
include(../config_plugin.pri)
@@ -74,7 +76,8 @@ FORMS += \
receiptloadform.ui \
settings/shopsettingsform.ui \
paydialog.ui \
- paydvouchersdialog.ui
+ paydvouchersdialog.ui \
+ eetbatchdialog.ui
win32:CONFIG(release, debug|release): LIBS += -L$$OUT_PWD/../plugins/ -laddressbook
else:win32:CONFIG(debug, debug|release): LIBS += -L$$OUT_PWD/../plugins/ -laddressbook
@@ -86,3 +89,8 @@ INCLUDEPATH += $$PWD/
DEPENDPATH += $$PWD/../addressbook
TRANSLATIONS = translations/shop_cs_CZ.ts
+
+unix|win32: LIBS += -L$$PWD/../../build-EetCpp-Desktop-Debug/libEet -lEetCpp
+
+INCLUDEPATH += $$PWD/../../EetCpp/libEet
+DEPENDPATH += $$PWD/../../EetCpp/libEet
diff --git a/shop/shopform.cpp b/shop/shopform.cpp
index 4d29d80..d3cb461 100644
--- a/shop/shopform.cpp
+++ b/shop/shopform.cpp
@@ -12,6 +12,7 @@
#include
#include
#include
+#include
#include "shop-odb.hxx"
@@ -54,9 +55,13 @@ void ShopForm::loadLast()
connectItemSignals();
ui->total->setText(QString::number(m_voucher->totalPrice().toDouble(), 'f', 2));
- ui->temporarySaveButton->setEnabled(true);
- ui->saveButton->setEnabled(true);
- ui->payButton->setEnabled(true);
+
+ if (!m_voucher->items().isEmpty())
+ {
+ ui->temporarySaveButton->setEnabled(true);
+ ui->saveButton->setEnabled(true);
+ ui->payButton->setEnabled(true);
+ }
}
if (m_commodityModel == NULL)
@@ -73,6 +78,16 @@ void ShopForm::loadLast()
m_commodityModel->setData(srv.allSellableItems());
ui->commodityTable->horizontalHeader()->setSectionResizeMode(1, QHeaderView::Stretch);
ui->commodityTable->setColumnHidden(3, true);
+
+ if (srv.isEetEnabled())
+ {
+ ui->lblEetState->setText(srv.isEetOnline() ? tr("Online") : tr("Offline"));
+ }
+ else
+ {
+ ui->labelEete->setVisible(false);
+ ui->lblEetState->setVisible(false);
+ }
}
void ShopForm::fillRaceiptCombo()
@@ -119,13 +134,25 @@ void ShopForm::on_saveButton_clicked()
ReceiptSaveForm *form = new ReceiptSaveForm(m_voucher, this);
form->setAttribute(Qt::WA_DeleteOnClose);
- connect(form, &QDialog::accepted, [this]() {
+ connect(form, &QDialog::accepted, [this, form]() {
ShopService srv;
- m_voucher->setStatus(Voucher::NOT_PAID);
- srv.saveVoucher(m_voucher);
- m_voucher = srv.createVoucher();
+
+ if (form->saveAsNew())
+ {
+ m_voucher->setStatus(Voucher::NOT_PAID);
+ srv.saveVoucher(m_voucher);
+ createEmptyVoucher();
+ }
+ else
+ {
+ VoucherPtr selVoucher = form->selectedVoucher();
+ srv.moveItems(m_voucher->items(), m_voucher, selVoucher);
+ srv.calculate(selVoucher);
+ srv.updateVoucher(selVoucher);
+ createEmptyVoucher();
+ }
+
m_itemsModel->setData(m_voucher->items());
- ui->total->setText("0");
});
form->show();
@@ -303,9 +330,35 @@ void ShopForm::on_payButton_clicked()
dialog->setAttribute(Qt::WA_DeleteOnClose);
dialog->show();
- connect(dialog, &QDialog::accepted, [this](){
+ connect(dialog, &QDialog::accepted, [this, dialog](){
ShopService srv;
srv.pay(m_voucher);
+ m_voucher->setEetStatus(dialog->sendToEet() ? Voucher::EET_FOR_SEND : Voucher::EET_NOT_ENTERING);
+ srv.update(m_voucher);
+ QString eetMsg;
+
+ if (srv.isEetEnabled() && dialog->sendToEet())
+ {
+ bool eetRet = srv.processEet(m_voucher, eetMsg);
+
+ if (!eetRet)
+ {
+ QString errMsg = tr("EET communication error.\n");
+
+ if (!eetMsg.isEmpty())
+ {
+ errMsg += tr("Message from portal: ") + eetMsg + "\n";
+ }
+
+ errMsg += tr("Switch to offline?");
+
+ if (srv.isEetOnline() && QMessageBox::question(this, tr("EET error"), errMsg) == QMessageBox::Yes)
+ {
+ srv.setEetOnline(false);
+ ui->lblEetState->setText(srv.isEetOnline() ? tr("Online") : tr("Offline"));
+ }
+ }
+ }
ReceiptGenerator generator;
generator.setVoucher(m_voucher);
@@ -341,6 +394,7 @@ void ShopForm::on_commoditySearch_textChanged(const QString &text)
QSortFilterProxyModel proxy;
proxy.setSourceModel(m_commodityModel);
proxy.setFilterKeyColumn(0);
+ proxy.setFilterCaseSensitivity(Qt::CaseInsensitive);
proxy.setFilterFixedString(text);
auto moveToIndex = [this](const QModelIndex &matchingIndex) {
@@ -363,3 +417,11 @@ void ShopForm::on_commoditySearch_textChanged(const QString &text)
}
}
}
+
+void ShopForm::on_lblEetState_linkActivated(const QString &link)
+{
+ ShopService srv;
+ srv.setEetOnline(!srv.isEetOnline());
+
+ ui->lblEetState->setText(srv.isEetOnline() ? tr("Online") : tr("Offline"));
+}
diff --git a/shop/shopform.h b/shop/shopform.h
index d26d4ff..dee98dd 100644
--- a/shop/shopform.h
+++ b/shop/shopform.h
@@ -44,6 +44,8 @@ private slots:
void on_commoditySearch_textChanged(const QString &text);
+ void on_lblEetState_linkActivated(const QString &link);
+
private:
Ui::ShopForm *ui;
QSharedPointer m_voucher;
diff --git a/shop/shopform.ui b/shop/shopform.ui
index 270547c..35de415 100644
--- a/shop/shopform.ui
+++ b/shop/shopform.ui
@@ -37,12 +37,6 @@
-
-
-
- 500
- 16777215
-
-
-
@@ -399,6 +393,35 @@
-
+
+ 0
+
+
-
+
+
+ EET status:
+
+
+
+ -
+
+
+
+ 75
+ true
+
+
+
+ PointingHandCursor
+
+
+ <a href="#eet">dfghdfg</a>
+
+
+ Qt::RichText
+
+
+
-
@@ -526,7 +549,7 @@
- Show paied
+ Show paid
diff --git a/shop/shoprc.qrc b/shop/shoprc.qrc
index 77a3ead..6a447f7 100644
--- a/shop/shoprc.qrc
+++ b/shop/shoprc.qrc
@@ -5,5 +5,6 @@
icons/tempSave.svg
icons/paied.svg
icons/pay.svg
+ icons/sendEet.svg
diff --git a/shop/shopservice.cpp b/shop/shopservice.cpp
index 9aa6895..c07425a 100644
--- a/shop/shopservice.cpp
+++ b/shop/shopservice.cpp
@@ -3,6 +3,11 @@
#include "isellableservice.h"
#include "shop-odb.hxx"
+#include "settings/shopsettings.h"
+
+#include
+#include
+
ShopService::ShopService()
{
}
@@ -101,6 +106,7 @@ void ShopService::pay(VoucherPtr voucher)
voucher->setNumSer(numSerStr);
voucher->setStatus(Voucher::PAID);
+ voucher->setEetStatus(Voucher::EET_FOR_SEND);
voucher->setPayDateTime(QDateTime::currentDateTime());
this->update(voucher);
@@ -119,6 +125,105 @@ void ShopService::updateRelatedItem(VoucherItem* item, int countAdded)
selSrv->addedToVoucher(item->refId(), countAdded);
}
}
+
+bool ShopService::processEet(VoucherPtr voucher, QString &message)
+{
+ if (voucher->eetStatus() == Voucher::EET_NOT_ENTERING)
+ {
+ return true;
+ }
+
+ SettingsService srvSettings("SHOP");
+ ShopSettingsPtr settings = srvSettings.loadSettings();
+
+ loadSettings();
+ EetRequest request;
+ request.setCelkTrzba(voucher->totalPrice().toDouble());
+ request.setDatTrzby(voucher->payDateTime());
+ request.setIdPokl(settings->eetRegisterId());
+ request.setIdProvoz(settings->eetShopId());
+ request.setPrvniZaslani(voucher->eetStatus() == Voucher::EET_FOR_SEND);
+ request.setDicPopl(m_gs->dic());
+ request.setPoradCis(voucher->numSer());
+ request.setDatOdesl(QDateTime::currentDateTime());
+ request.setRezim((EetRequest::EetRezim)settings->eetMode());
+
+ EetSender *sender = new EetSender(this);
+ sender->setupSigner(settings->eetCertificate(), settings->eetKeyPassword());
+ sender->setPlayground(settings->eetPlayground());
+
+ QEventLoop loop;
+ bool replyFinished = false;
+
+ connect(sender, &EetSender::sendFinished, [this, voucher, sender, &loop, &replyFinished](){
+ Transaction tx;
+
+ voucher->setEetBkp(sender->resut()->bkp());
+ voucher->setEetPkp(sender->resut()->pkp());
+ voucher->setEetFik(sender->resut()->fik());
+
+ if (sender->resut()->status() == EetResult::RESPONSE_OK)
+ {
+ voucher->setEetSendDateTime(QDateTime::currentDateTime());
+ voucher->setEetStatus(Voucher::EET_SENT);
+ }
+ else
+ {
+ voucher->setEetStatus(Voucher::EET_ERROR);
+ }
+
+ this->update(voucher);
+ tx.commit();
+ sender->deleteLater();
+
+ loop.quit();
+ replyFinished = true;
+ });
+
+ sender->sendRequest(&request);
+
+ if (!replyFinished)
+ {
+ loop.exec();
+ }
+
+ auto addMessage = [&message](EetMessage *msg, const QString &label){
+ if (message.isEmpty())
+ {
+ message = label + "\n";
+ }
+
+ message += QString::number(msg->code()) + ": " + msg->message();
+ };
+
+ foreach (EetMessage *msg, sender->resut()->errors()) {
+ addMessage(msg, "Errors:");
+ }
+
+ foreach (EetMessage *msg, sender->resut()->warnings()) {
+ addMessage(msg, "Warnings:");
+ }
+
+ return voucher->eetStatus() == Voucher::EET_SENT;
+}
+
+void ShopService::setEetOnline(bool online)
+{
+ EetSender::m_online = online;
+}
+
+bool ShopService::isEetOnline()
+{
+ return EetSender::m_online;
+}
+
+bool ShopService::isEetEnabled()
+{
+ SettingsService srvSettings("SHOP");
+ ShopSettingsPtr settings = srvSettings.loadSettings();
+ return settings->eetActive();
+}
+
void ShopService::moveItems(QList items, VoucherPtr source, VoucherPtr target)
{
Transaction tx;
@@ -142,6 +247,11 @@ void ShopService::moveItems(QList items, VoucherPtr source, Vouc
{
erase(source);
}
+ else
+ {
+ calculate(source);
+ update(source);
+ }
tx.commit();
}
@@ -161,6 +271,12 @@ QList ShopService::paiedVouchers()
return all(QString("status = %1").arg(QString::number(Voucher::PAID)));
}
+QList ShopService::vouchersForEet()
+{
+ return all(QString("status = %1 AND eetStatus <> %2 AND eetStatus <> %3")
+ .arg(QString::number(Voucher::PAID), QString::number(Voucher::EET_SENT), QString::number(Voucher::EET_NOT_ENTERING)));
+}
+
QList ShopService::allSellableItems()
{
QList > items;
diff --git a/shop/shopservice.h b/shop/shopservice.h
index e4b5bf6..2a622bb 100644
--- a/shop/shopservice.h
+++ b/shop/shopservice.h
@@ -21,9 +21,14 @@ public:
void pay(VoucherPtr voucher);
void moveItems(QList items, VoucherPtr source, VoucherPtr target);
void updateRelatedItem(VoucherItem* item, int countAdded);
+ bool processEet(VoucherPtr voucher, QString &message);
+ void setEetOnline(bool online);
+ bool isEetOnline();
+ bool isEetEnabled();
QList savedVouchers();
QList tempVouchers();
QList paiedVouchers();
+ QList vouchersForEet();
QList allSellableItems();
private:
diff --git a/shop/translations/shop_cs_CZ.qm b/shop/translations/shop_cs_CZ.qm
index 4ea69b9..39c4086 100644
Binary files a/shop/translations/shop_cs_CZ.qm and b/shop/translations/shop_cs_CZ.qm differ
diff --git a/shop/translations/shop_cs_CZ.ts b/shop/translations/shop_cs_CZ.ts
index c92efdf..5bf6a5c 100644
--- a/shop/translations/shop_cs_CZ.ts
+++ b/shop/translations/shop_cs_CZ.ts
@@ -19,12 +19,12 @@
Cena
-
+
Počet
-
+
Sazba DPH
@@ -49,33 +49,46 @@
Druhá snížená
+
+ EetBatchDialog
+
+
+
+ EET odeslání neodeslaných účtenek
+
+
PayDialog
-
+ Platba
- Celkem:
+ Celkem:
-
+
-
+ Obdrženo
-
+ Vrátit
+
+
+
+
+ Odeslat na EET
@@ -83,43 +96,75 @@
-
+ Zaplacené účtenky
-
+ Vytisknout účtenku
-
+
-
+ Uložit účtenku
+
+
-
+
-
+
- Položky
+ Položky
-
+
+
+
+
+
+
- Celkem:
+ Celkem:
-
+
-
+
+
+
+
+
+ Nevstupuje
+
+
+
+
+ K odeslání
+
+
+
+
+ Chyba
-
+
+
+ Odesláno
+
+
+
-
+ Textové soubory (*.txt)
+
+
+
+
+ Chyba
@@ -140,7 +185,7 @@
Hledat
-
+
Položky
@@ -150,7 +195,7 @@
- Přidat k již uložené
+ Uložené účtenky
@@ -164,35 +209,35 @@
-
+ Uložení
-
+ Přidat k již uložené
-
+
-
+ Uložit jako novou
-
+
-
+ Nová účtenka
-
+
Název
-
+
Popis
-
+
Vyhledat kontakt
@@ -205,74 +250,133 @@
-
+
Zboží
-
+
Počet
-
+
Přidat položku
-
+
Přímý prodej
-
+
-
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
Účtenka
-
+
+
+ EET status:
+
+
+
+
+
+
+
+
Celkem:
-
+
-
+
Dočasné uložení
-
+
Uložení
-
+
Načíst
-
-
-
+
+
+ Zobrazit zaplacené
-
+
Zaplatit
+
+
+
+
+
+
+
+
+
+
+
+
+
+
-
+ << nevybráno >>
+
+
+
+
+ Chyba komunikace s EET
+
+
+
+
+ Zpráva z EET portálu:
+
+
+
+
+ Přepnout do offline?
+
+
+
+
+ Chyba EET
@@ -280,27 +384,102 @@
- Zboží
+ Prodejna nastavení
+
+
+
+
+ Nastavení rychlé volby
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
-
+
-
+ Tiskárna
-
+
-
+ Jméno tiskárny
-
+
-
+ Znaků na řádek
-
+
-
+ Patička
+
+
+
+
+ EET
+
+
+
+
+ Zapnout podporu EET
+
+
+
+
+ ID provozovny
+
+
+
+
+ ID zařízení
+
+
+
+
+ EET režim
+
+
+
+
+ Certifikát
+
+
+
+
+ Heslo k certifikátu
+
+
+
+
+ Testovací režim
+
+
+
+
+ Testovací EET server
+
+
+
+
+ Zjednodušený
+
+
+
+
+ Standartní