diff --git a/commodity/commodity.json b/commodity/commodity.json index 16e6e92..ea01c09 100644 --- a/commodity/commodity.json +++ b/commodity/commodity.json @@ -40,5 +40,10 @@ CREATE TABLE \"CommodityData\" ( "vat" : "DPH", "count" : "Počet" } - } + }, + + "reports" : [ + { "name" : "Ceník", "description" : "Všechny položky v ceníku", "listReport" : true, "file" : "pokus.lrxml" }, + { "name" : "Nezpalcené účtenky", "description" : "Všechny nezaplacené účtenky", "listReport" : true, "file" : "pokus.lrxml" } + ] } diff --git a/core/core.pro b/core/core.pro index ffaaed2..fe4434a 100644 --- a/core/core.pro +++ b/core/core.pro @@ -6,7 +6,7 @@ #iconset: https://www.iconfinder.com/iconsets/snipicons -QT += widgets sql +QT += widgets sql printsupport TARGET = core TEMPLATE = lib @@ -59,7 +59,10 @@ SOURCES += \ data/season.cpp \ seasonservice.cpp \ numberseriesservice.cpp \ - settings/seasonnamedialog.cpp + settings/seasonnamedialog.cpp \ + reporting/report.cpp \ + reporting/reportviewer.cpp \ + reporting/reportdialog.cpp HEADERS += core.h\ core_global.h \ @@ -116,7 +119,10 @@ HEADERS += core.h\ data/season.h \ seasonservice.h \ numberseriesservice.h \ - settings/seasonnamedialog.h + settings/seasonnamedialog.h \ + reporting/report.h \ + reporting/reportviewer.h \ + reporting/reportdialog.h unix { target.path = /usr/lib @@ -149,7 +155,9 @@ FORMS += \ filterdialog.ui \ settingsform.ui \ settings/globalsettingsform.ui \ - settings/seasonnamedialog.ui + settings/seasonnamedialog.ui \ + reporting/reportviewer.ui \ + reporting/reportdialog.ui OTHER_FILES += \ users/metaData.json \ @@ -160,6 +168,9 @@ CONFIG(debug, release|debug):DEFINES += _DEBUG win32:CONFIG(release, debug|release):DEFINES += PLUGIN_ROOT=\\\"/plugins\\\" else:unix:CONFIG(release, debug|release):DEFINES += PLUGIN_ROOT=\\\"/usr/lib/prodejna/plugins\\\" +win32:CONFIG(release, debug|release):DEFINES += REPORT_ROOT=\\\"/reports\\\" +else:unix:CONFIG(release, debug|release):DEFINES += REPORT_ROOT=\\\"/usr/share/prodejna/reports\\\" + win32:CONFIG(release, debug|release): LIBS += -L$$OUT_PWD/../qdecimal/lib/ -lqdecimal -ldecnumber else:win32:CONFIG(debug, debug|release): LIBS += -L$$OUT_PWD/../qdecimal/lib/ -lqdecimal -ldecnumber else:unix: LIBS += -L$$OUT_PWD/../qdecimal/lib/ -lqdecimal -ldecnumber @@ -167,4 +178,28 @@ else:unix: LIBS += -L$$OUT_PWD/../qdecimal/lib/ -lqdecimal -ldecnumber INCLUDEPATH += $$PWD/../qdecimal/src INCLUDEPATH += $$PWD/../qdecimal/decnumber +unix{ + ARCH_TYPE = unix + macx{ + ARCH_TYPE = macx + } + linux{ + !contains(QT_ARCH, x86_64){ + ARCH_TYPE = linux32 + }else{ + ARCH_TYPE = linux64 + } + } +} +win32 { + ARCH_TYPE = win32 +} + +win32:CONFIG(release, debug|release): LIBS += -L$$PWD/../../LimeReport/build/$${QT_VERSION}/$${ARCH_TYPE}/release/lib/ -llimereport +else:win32:CONFIG(debug, debug|release): LIBS += -L$$PWD/../../LimeReport/build/$${QT_VERSION}/$${ARCH_TYPE}/debug/lib/ -llimereport +else:unix: LIBS += -L$$PWD/../../LimeReport/build/$${QT_VERSION}/$${ARCH_TYPE}/debug/lib/ -llimereport + +INCLUDEPATH += $$PWD/../../LimeReport/include +DEPENDPATH += $$PWD/../../LimeReport/include + TRANSLATIONS = translations/core_cs_CZ.ts diff --git a/core/define.h b/core/define.h index 1cee27f..6ca3f2d 100644 --- a/core/define.h +++ b/core/define.h @@ -21,5 +21,13 @@ #endif #endif +#ifndef REPORT_ROOT + #ifdef _WIN32 + #define REPORT_ROOT "/../../reports" + #else + #define REPORT_ROOT "/../reports" + #endif +#endif + #endif // DEFINE_H diff --git a/core/icons/close.svg b/core/icons/close.svg new file mode 100644 index 0000000..7914770 --- /dev/null +++ b/core/icons/close.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/core/icons/fitHorizontal.svg b/core/icons/fitHorizontal.svg new file mode 100644 index 0000000..a340144 --- /dev/null +++ b/core/icons/fitHorizontal.svg @@ -0,0 +1,4 @@ + \ No newline at end of file diff --git a/core/icons/fitVertical.svg b/core/icons/fitVertical.svg new file mode 100644 index 0000000..8d14680 --- /dev/null +++ b/core/icons/fitVertical.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/core/icons/pageDown.svg b/core/icons/pageDown.svg new file mode 100644 index 0000000..e3ef9e0 --- /dev/null +++ b/core/icons/pageDown.svg @@ -0,0 +1,4 @@ + \ No newline at end of file diff --git a/core/icons/pageUp.svg b/core/icons/pageUp.svg new file mode 100644 index 0000000..2901b59 --- /dev/null +++ b/core/icons/pageUp.svg @@ -0,0 +1,4 @@ + \ No newline at end of file diff --git a/core/icons/pdf.svg b/core/icons/pdf.svg new file mode 100644 index 0000000..a05dc65 --- /dev/null +++ b/core/icons/pdf.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/core/icons/report.svg b/core/icons/report.svg new file mode 100644 index 0000000..297aebd --- /dev/null +++ b/core/icons/report.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/core/icons/zoomIn.svg b/core/icons/zoomIn.svg new file mode 100644 index 0000000..3900376 --- /dev/null +++ b/core/icons/zoomIn.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/core/icons/zoomOut.svg b/core/icons/zoomOut.svg new file mode 100644 index 0000000..b26c65c --- /dev/null +++ b/core/icons/zoomOut.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/core/igridform.cpp b/core/igridform.cpp index ef75adc..f98d651 100644 --- a/core/igridform.cpp +++ b/core/igridform.cpp @@ -7,6 +7,8 @@ #include "context.h" #include "filterui.h" +#include "iplugin.h" +#include "reporting/reportdialog.h" IGridForm::IGridForm(QWidget *parent) : QWidget(parent), @@ -132,7 +134,7 @@ void IGridForm::on_btnFilter_toggled(bool checked) } } -void IGridForm::on_tableView_clicked(const QModelIndex &index) +void IGridForm::on_tableView_clicked(const QModelIndex &) { if (ui->tableView->currentIndex().isValid()) { @@ -140,3 +142,11 @@ void IGridForm::on_tableView_clicked(const QModelIndex &index) ui->btnDelete->setEnabled(true); } } + +void IGridForm::on_btnPrint_clicked() +{ + ReportDialog *dialog = new ReportDialog(this); + dialog->setAttribute(Qt::WA_DeleteOnClose); + dialog->setReports(Context::instance().plugin(pluginId())->reports()); + dialog->show(); +} diff --git a/core/igridform.h b/core/igridform.h index 27aead5..7017afa 100644 --- a/core/igridform.h +++ b/core/igridform.h @@ -55,6 +55,8 @@ private slots: void on_tableView_clicked(const QModelIndex &index); + void on_btnPrint_clicked(); + private: QString m_pluginId; IFormHandler *m_formHandler; diff --git a/core/imetadataplugin.cpp b/core/imetadataplugin.cpp index cc1e709..50e57e2 100644 --- a/core/imetadataplugin.cpp +++ b/core/imetadataplugin.cpp @@ -48,6 +48,11 @@ QStringList IMetaDataPlugin::dependsOn() return m_dependsOn; } +ReportList IMetaDataPlugin::reports() +{ + return m_reports; +} + void IMetaDataPlugin::init(const QJsonObject &metaData) { parseMetaData(metaData); @@ -105,6 +110,19 @@ void IMetaDataPlugin::parseMetaData(const QJsonObject &metaData) m_translations[key] = trLocalized.toObject()[key].toString(); } } + + QJsonValue repArray = data.toObject()["reports"]; + foreach (QJsonValue repVal, repArray.toArray()) { + QJsonObject repObj = repVal.toObject(); + + ReportPtr report = ReportPtr(new Report()); + report->setName(repObj["name"].toString()); + report->setDescription(repObj["description"].toString()); + report->setListReport(repObj["listReport"].toBool()); + report->setFile(repObj["file"].toString()); + + m_reports.append(report); + } } QString IMetaDataPlugin::parseLocaleText(const QJsonObject &object) diff --git a/core/imetadataplugin.h b/core/imetadataplugin.h index ece23ca..1eb7fa1 100644 --- a/core/imetadataplugin.h +++ b/core/imetadataplugin.h @@ -20,6 +20,7 @@ public: virtual int schemaVersion(); virtual QStringList schemas(); virtual QStringList dependsOn(); + virtual ReportList reports(); virtual void init(const QJsonObject &metaData); @@ -34,6 +35,7 @@ private: int m_schemaVersion; QStringList m_schemas; QStringList m_dependsOn; + ReportList m_reports; QString parseLocaleText(const QJsonObject &object); }; diff --git a/core/iplugin.h b/core/iplugin.h index afebb9b..e669d13 100644 --- a/core/iplugin.h +++ b/core/iplugin.h @@ -11,6 +11,7 @@ #include "service.h" #include "igridform.h" +#include "reporting/report.h" class IPlugin { @@ -45,6 +46,7 @@ public: virtual int schemaVersion() = 0; virtual QStringList schemas() = 0; virtual QStringList dependsOn() = 0; + virtual ReportList reports() = 0; virtual void init(const QJsonObject &metaData) = 0; diff --git a/core/rc.qrc b/core/rc.qrc index e01dea7..952aa60 100644 --- a/core/rc.qrc +++ b/core/rc.qrc @@ -15,5 +15,14 @@ icons/usersPlugin.svg icons/rolesPlugin.svg translations/core_cs_CZ.qm + icons/close.svg + icons/fitHorizontal.svg + icons/fitVertical.svg + icons/pageDown.svg + icons/pageUp.svg + icons/pdf.svg + icons/zoomIn.svg + icons/zoomOut.svg + icons/report.svg diff --git a/core/reporting/report.cpp b/core/reporting/report.cpp new file mode 100644 index 0000000..5b3fb45 --- /dev/null +++ b/core/reporting/report.cpp @@ -0,0 +1,61 @@ +#include "report.h" + +Report::Report() +{ + +} + +QString Report::name() const +{ + return m_name; +} + +void Report::setName(const QString &name) +{ + m_name = name; +} + +QString Report::description() const +{ + return m_description; +} + +void Report::setDescription(const QString &description) +{ + m_description = description; +} + +QString Report::file() const +{ + return m_file; +} + +void Report::setFile(const QString &file) +{ + m_file = file; +} + +bool Report::listReport() const +{ + return m_listReport; +} + +void Report::setListReport(bool listReport) +{ + m_listReport = listReport; +} + +QMap Report::variables() const +{ + return m_variables; +} + +void Report::setVariables(const QMap &variables) +{ + m_variables = variables; +} + +void Report::addVariable(const QString &varName, const QString &value) +{ + m_variables[varName] = value; +} diff --git a/core/reporting/report.h b/core/reporting/report.h new file mode 100644 index 0000000..4a84170 --- /dev/null +++ b/core/reporting/report.h @@ -0,0 +1,43 @@ +#ifndef REPORT_H +#define REPORT_H + +#include +#include +#include +#include + +#include "../core_global.h" + +class CORESHARED_EXPORT Report +{ +public: + Report(); + + QString name() const; + void setName(const QString &name); + + QString description() const; + void setDescription(const QString &description); + + QString file() const; + void setFile(const QString &file); + + bool listReport() const; + void setListReport(bool listReport); + + QMap variables() const; + void setVariables(const QMap &variables); + void addVariable(const QString &varName, const QString &value); + +private: + QString m_name; + QString m_description; + QString m_file; + bool m_listReport; + QMap m_variables; +}; + +typedef QSharedPointer ReportPtr; +typedef QList ReportList; + +#endif // REPORT_H diff --git a/core/reporting/reportdialog.cpp b/core/reporting/reportdialog.cpp new file mode 100644 index 0000000..787831b --- /dev/null +++ b/core/reporting/reportdialog.cpp @@ -0,0 +1,75 @@ +#include "reportdialog.h" +#include "ui_reportdialog.h" + +#include +#include + +#include "reportviewer.h" + +ReportDialog::ReportDialog(QWidget *parent) : + QDialog(parent), + ui(new Ui::ReportDialog) +{ + ui->setupUi(this); +} + +ReportDialog::~ReportDialog() +{ + delete ui; +} + +void ReportDialog::setReports(ReportList reports) +{ + QStandardItemModel *model = qobject_cast(ui->listReports->model()); + + if (model == NULL) + { + model = new QStandardItemModel(0, 1); + } + else + { + model->clear(); + } + + foreach (ReportPtr report, reports) { + QStandardItem *item = new QStandardItem((report->listReport() ? QIcon(":/icons/list.svg") : QIcon(":/icons/report.svg")), report->name()); + model->appendRow(item); + } + + ui->listReports->setModel(model); + m_reports = reports; + + connect(ui->listReports->selectionModel(), &QItemSelectionModel::currentRowChanged, [this](const QModelIndex, QModelIndex){ + ui->textDescription->setText(m_reports[ui->listReports->currentIndex().row()]->description()); + }); + + + if (!reports.isEmpty()) + { + ui->btnPreview->setEnabled(true); + ui->btnPrint->setEnabled(true); + + ui->listReports->setCurrentIndex(model->index(0, 0)); + } +} + +void ReportDialog::on_btnPreview_clicked() +{ + ReportViewer *viewer = new ReportViewer(this); + viewer->setAttribute(Qt::WA_DeleteOnClose); + + viewer->setReport(m_reports[ui->listReports->currentIndex().row()]); + viewer->openPreview(); +} + +void ReportDialog::on_btnPrint_clicked() +{ + ReportViewer viever; + viever.setReport(m_reports[ui->listReports->currentIndex().row()]); + viever.directPrint(); +} + +void ReportDialog::on_btnClose_clicked() +{ + close(); +} diff --git a/core/reporting/reportdialog.h b/core/reporting/reportdialog.h new file mode 100644 index 0000000..cc7795a --- /dev/null +++ b/core/reporting/reportdialog.h @@ -0,0 +1,33 @@ +#ifndef REPORTDIALOG_H +#define REPORTDIALOG_H + +#include +#include "report.h" + +namespace Ui { +class ReportDialog; +} + +class ReportDialog : public QDialog +{ + Q_OBJECT + +public: + explicit ReportDialog(QWidget *parent = 0); + ~ReportDialog(); + + void setReports(ReportList reports); + +private slots: + void on_btnPreview_clicked(); + + void on_btnPrint_clicked(); + + void on_btnClose_clicked(); + +private: + Ui::ReportDialog *ui; + ReportList m_reports; +}; + +#endif // REPORTDIALOG_H diff --git a/core/reporting/reportdialog.ui b/core/reporting/reportdialog.ui new file mode 100644 index 0000000..fd2540c --- /dev/null +++ b/core/reporting/reportdialog.ui @@ -0,0 +1,194 @@ + + + ReportDialog + + + + 0 + 0 + 569 + 442 + + + + Reports + + + true + + + + 0 + + + 0 + + + 0 + + + 9 + + + + + background-color: rgb(255, 255, 255); + + + QFrame::StyledPanel + + + QFrame::Raised + + + + + + + 32 + 32 + + + + + 36 + 36 + + + + + + + :/icons/print.svg + + + true + + + + + + + + 10 + 75 + true + + + + color: rgb(0, 0, 0); + + + Print reports + + + Qt::AlignCenter + + + + + + + + + + + 0 + + + + + QAbstractItemView::SelectRows + + + + + + + + + + + 16777215 + 90 + + + + + + + + 16777215 + 16777215 + + + + + + + + + + + + + + Qt::Horizontal + + + + 40 + 20 + + + + + + + + false + + + Preview + + + + :/icons/report.svg:/icons/report.svg + + + + + + + false + + + Print + + + + :/icons/print.svg:/icons/print.svg + + + + + + + Close + + + + :/icons/close.svg:/icons/close.svg + + + + + + + + + + + + + diff --git a/core/reporting/reportviewer.cpp b/core/reporting/reportviewer.cpp new file mode 100644 index 0000000..8666c33 --- /dev/null +++ b/core/reporting/reportviewer.cpp @@ -0,0 +1,90 @@ +#include "reportviewer.h" +#include "ui_reportviewer.h" + +#include "../context.h" + +#include +#include +#include + +ReportViewer::ReportViewer(QWidget *parent) : + QDialog(parent), + ui(new Ui::ReportViewer) +{ + ui->setupUi(this); + m_report = NULL; +} + +ReportViewer::~ReportViewer() +{ + delete ui; +} + +void ReportViewer::setReport(ReportPtr report) +{ + m_report = new LimeReport::ReportEngine(this); + + QString reportPath = qApp->applicationDirPath() + REPORT_ROOT + "/" + report->file(); + QFile file(reportPath); + file.open(QFile::ReadOnly); + + m_report->loadFromByteArray(&file.readAll()); + m_report->setReportFileName(reportPath); + m_report->dataManager()->setReportVariable("dbPath", Context::instance().settings()->value("db/path", "").toString()); +} + +void ReportViewer::openPreview() +{ + Q_ASSERT(m_report != NULL); + + showMaximized(); + + m_prevWidget = m_report->createPreviewWidget(this); + + connect(m_prevWidget, SIGNAL(pagesSet(int)), this, SLOT(slotPageSet(int))); + connect(ui->pageNavigator, SIGNAL(valueChanged(int)), m_prevWidget, SLOT(pageNavigatorChanged(int))); + connect(ui->btnPrint, SIGNAL(clicked(bool)), m_prevWidget, SLOT(print())); + connect(ui->btnPdf, SIGNAL(clicked(bool)), m_prevWidget, SLOT(printToPDF())); + connect(ui->btnPageUp, SIGNAL(clicked(bool)), m_prevWidget, SLOT(priorPage())); + connect(ui->btnPageDown, SIGNAL(clicked(bool)), m_prevWidget, SLOT(nextPage())); + connect(ui->btnZoomIn, SIGNAL(clicked(bool)), m_prevWidget, SLOT(zoomIn())); + connect(ui->btnZoomOut, SIGNAL(clicked(bool)), m_prevWidget, SLOT(zoomOut())); + connect(ui->btnFitHoriz, SIGNAL(clicked(bool)), m_prevWidget, SLOT(fitWidth())); + connect(ui->btnFitVert, SIGNAL(clicked(bool)), m_prevWidget, SLOT(fitPage())); + + ui->reportLayout->addWidget(m_prevWidget); + m_prevWidget->refreshPages(); +} + +void ReportViewer::directPrint(bool dialog) +{ + Q_ASSERT(m_report != NULL); + + QPrinter printer(QPrinter::HighResolution); + + if (dialog || !printer.isValid()) + { + m_report->printReport(); + } + else + { + m_report->printReport(&printer); + } +} + +void ReportViewer::on_btnClose_clicked() +{ + close(); +} + +void ReportViewer::on_btnEdit_clicked() +{ + m_report->designReport(); +} + +void ReportViewer::slotPageSet(int page) +{ + ui->pageNavigator->setSuffix(ui->pageNavigator->suffix() + QString::number(page)); + ui->pageNavigator->setMinimum(1); + ui->pageNavigator->setMaximum(page); +} diff --git a/core/reporting/reportviewer.h b/core/reporting/reportviewer.h new file mode 100644 index 0000000..376874e --- /dev/null +++ b/core/reporting/reportviewer.h @@ -0,0 +1,41 @@ +#ifndef REPORTVIEWER_H +#define REPORTVIEWER_H + +#include +#include "report.h" + +namespace Ui { +class ReportViewer; +} + +namespace LimeReport { +class PreviewReportWidget; +class ReportEngine; +} + +class ReportViewer : public QDialog +{ + Q_OBJECT + +public: + explicit ReportViewer(QWidget *parent = 0); + ~ReportViewer(); + void setReport(ReportPtr report); + void openPreview(); + void directPrint(bool dialog = true); + +private slots: + void on_btnClose_clicked(); + + void on_btnEdit_clicked(); + + void slotPageSet(int page); + +private: + Ui::ReportViewer *ui; + + LimeReport::PreviewReportWidget *m_prevWidget; + LimeReport::ReportEngine *m_report; +}; + +#endif // REPORTVIEWER_H diff --git a/core/reporting/reportviewer.ui b/core/reporting/reportviewer.ui new file mode 100644 index 0000000..6ad907f --- /dev/null +++ b/core/reporting/reportviewer.ui @@ -0,0 +1,312 @@ + + + ReportViewer + + + + 0 + 0 + 914 + 675 + + + + Report + + + + + + + + + Close + + + Close + + + + :/icons/close.svg:/icons/close.svg + + + + 24 + 24 + + + + true + + + + + + + Print + + + Print + + + + :/icons/print.svg:/icons/print.svg + + + + 24 + 24 + + + + true + + + + + + + Export to PDF + + + Export to PDF + + + + :/icons/pdf.svg:/icons/pdf.svg + + + + 24 + 24 + + + + true + + + + + + + Edit + + + Edit + + + + :/icons/edit.svg:/icons/edit.svg + + + + 24 + 24 + + + + true + + + + + + + Page up + + + Page up + + + + :/icons/pageUp.svg:/icons/pageUp.svg + + + + 24 + 24 + + + + true + + + + + + + of + + + Page: + + + + + + + Page down + + + Page down + + + + :/icons/pageDown.svg:/icons/pageDown.svg + + + + 24 + 24 + + + + true + + + + + + + Zoom out + + + Zoom out + + + + :/icons/zoomOut.svg:/icons/zoomOut.svg + + + + 24 + 24 + + + + true + + + + + + + Zoom in + + + Zoom in + + + + :/icons/zoomIn.svg:/icons/zoomIn.svg + + + + 24 + 24 + + + + true + + + + + + + Fit horizontal + + + Fit horizontal + + + + :/icons/fitHorizontal.svg:/icons/fitHorizontal.svg + + + + 24 + 24 + + + + true + + + + + + + Fit vertical + + + Fit vertical + + + + :/icons/fitVertical.svg:/icons/fitVertical.svg + + + + 24 + 24 + + + + true + + + + + + + Qt::Horizontal + + + + 40 + 20 + + + + + + + + + + + + 0 + 0 + + + + + 0 + + + 0 + + + 0 + + + 0 + + + 0 + + + + + + + + + + + + + + diff --git a/shop/shop.json b/shop/shop.json index 6fd5750..92e2b84 100644 --- a/shop/shop.json +++ b/shop/shop.json @@ -94,5 +94,9 @@ CREATE TABLE \"Voucher\" ( "saveDateTime" : "Datum uložení", "insertDate" : "Datum vložení" } - } + }, + "reports" : [ + { "name" : "Zpalcené účtenky", "description" : "Všechny zaplacené účtenky", "listReport" : 1, "file" : "vouchers.lrxml" }, + { "name" : "Nezpalcené účtenky", "description" : "Všechny nezaplacené účtenky", "listReport" : 1, "file" : "vouchers_n.lrxml" } + ] }