diff --git a/addressbook/addressbook.json b/addressbook/addressbook.json index ce7ac2f..5a41280 100644 --- a/addressbook/addressbook.json +++ b/addressbook/addressbook.json @@ -8,7 +8,7 @@ "default" : "", "CZ" : "" }, - "schemaVersion" : 1, + "schemaVersion" : 2, "sql" : [ "CREATE TABLE \"AddressbookData\" ( \"id\" INTEGER NOT NULL PRIMARY KEY AUTOINCREMENT, @@ -21,10 +21,14 @@ \"addressCity\" TEXT NULL, \"addressStreet\" TEXT NULL, \"addressHouseNumber\" TEXT NULL, - \"addressZipCode\" TEXT NULL);" + \"addressZipCode\" TEXT NULL); +", + +"ALTER TABLE AddressbookData ADD \"country\" INTEGER NULL; +" ], - "dependencies" : [], + "dependencies" : [ "COUNTRYREGISTER" ], "translations" : { "CZ" : { "title" : "Titul", diff --git a/addressbook/addressbook.pro b/addressbook/addressbook.pro index 91a39b1..f88dd05 100644 --- a/addressbook/addressbook.pro +++ b/addressbook/addressbook.pro @@ -32,6 +32,7 @@ include(../config_plugin.pri) ODB_FILES = addressbook/data/addressbookdata.h H_DIR = $$PWD/data/*.h +ODB_OTHER_INCLUDES = -I $$PWD/../countryregister/data include(../odb.pri) OTHER_FILES += \ @@ -43,3 +44,11 @@ FORMS += \ RESOURCES += \ addressbookrc.qrc TRANSLATIONS = translations/addressbook_cs_CZ.ts + +win32:CONFIG(release, debug|release): LIBS += -L$$OUT_PWD/../plugins/ -lcountryregister +else:win32:CONFIG(debug, debug|release): LIBS += -L$$OUT_PWD/../plugins/ -lcountryregister +else:unix: LIBS += -L$$OUT_PWD/../plugins/ -lcountryregister + +INCLUDEPATH += $$PWD/../countryregister/data +INCLUDEPATH += $$PWD/../countryregister + diff --git a/addressbook/addressbookform.cpp b/addressbook/addressbookform.cpp index 0ea80db..e6d30f9 100644 --- a/addressbook/addressbookform.cpp +++ b/addressbook/addressbookform.cpp @@ -1,5 +1,6 @@ #include "addressbookform.h" #include "ui_addressbookform.h" +#include AddressbookForm::AddressbookForm(QWidget *parent) : AutoForm(parent), @@ -22,3 +23,9 @@ AddressbookForm::~AddressbookForm() { delete ui; } + +void AddressbookForm::registerCombos() +{ + Service srv; + registerBinding(ui->country, ComboData::createComboData(srv.all())); +} diff --git a/addressbook/addressbookform.h b/addressbook/addressbookform.h index 7888b7d..85eb79c 100644 --- a/addressbook/addressbookform.h +++ b/addressbook/addressbookform.h @@ -20,6 +20,10 @@ public: private: Ui::AddressbookForm *ui; + + // FormBinder interface +protected: + void registerCombos(); }; diff --git a/addressbook/addressbookform.ui b/addressbook/addressbookform.ui index 8500b86..853d121 100644 --- a/addressbook/addressbookform.ui +++ b/addressbook/addressbookform.ui @@ -6,8 +6,8 @@ 0 0 - 400 - 300 + 610 + 407 @@ -115,8 +115,35 @@ + + + + Country + + + + + + + true + + + + + title + firstName + lastName + birthDate + idCardNumber + ztp + addressCity + addressStreet + addressHouseNumber + addressZipCode + country + diff --git a/addressbook/addressbookservice.cpp b/addressbook/addressbookservice.cpp index 1f491fd..97a6979 100644 --- a/addressbook/addressbookservice.cpp +++ b/addressbook/addressbookservice.cpp @@ -10,9 +10,22 @@ AddressBookService::~AddressBookService() { } -QList > AddressBookService::all(const QString &where) +AddressbookDataPtr AddressBookService::copyAddress(AddressbookDataPtr address) { - Service srv; - return srv.all(where); + AddressbookDataPtr newAddress(new AddressbookData()); + + newAddress->setTitle(address->title()); + newAddress->setFirstName(address->firstName()); + newAddress->setLastName(address->lastName()); + newAddress->setBirthDate(address->birthDate()); + newAddress->setIdCardNumber(address->idCardNumber()); + newAddress->setZtp(address->ztp()); + newAddress->setAddressStreet(address->addressStreet()); + newAddress->setAddressHouseNumber(address->addressHouseNumber()); + newAddress->setAddressZipCode(address->addressZipCode()); + newAddress->setAddressCity(address->addressCity()); + newAddress->setCountry(address->country()); + + return newAddress; } diff --git a/addressbook/addressbookservice.h b/addressbook/addressbookservice.h index 6b8ee4d..4d458ec 100644 --- a/addressbook/addressbookservice.h +++ b/addressbook/addressbookservice.h @@ -3,17 +3,18 @@ #include #include +#include #include "data/addressbookdata.h" #include "addressbook_global.h" -class ADDRESSBOOKSHARED_EXPORT AddressBookService +class ADDRESSBOOKSHARED_EXPORT AddressBookService : public Service { public: AddressBookService(); ~AddressBookService(); - QList > all(const QString &where = ""); + AddressbookDataPtr copyAddress(AddressbookDataPtr address); }; #endif // ADDRESSBOOKSERVICE_H diff --git a/addressbook/data/addressbookdata.cpp b/addressbook/data/addressbookdata.cpp index 0b002d0..71ca016 100644 --- a/addressbook/data/addressbookdata.cpp +++ b/addressbook/data/addressbookdata.cpp @@ -3,6 +3,7 @@ AddressbookData::AddressbookData(QObject * parent) :ComboItem(parent) { + m_ztp = false; } QString AddressbookData::title() const @@ -105,6 +106,19 @@ void AddressbookData::setId(int id) m_id = id; } +QSharedPointer AddressbookData::country() const +{ + return m_country; +} + +void AddressbookData::setCountry(const QSharedPointer &country) +{ + if (qobject_cast(country.data()) != NULL) + { + m_country = qSharedPointerDynamicCast(country); + } +} + bool AddressbookData::eq(ComboItem *other) { AddressbookData *adb = qobject_cast(other); @@ -113,7 +127,7 @@ bool AddressbookData::eq(ComboItem *other) QString AddressbookData::toString() { - return m_firstName + " " + m_lastName + ", " + m_addressStreet + " " + m_addressHouseNumber + ", " + m_addressCity; + return m_lastName + " " + m_firstName + ", " + m_addressStreet + " " + m_addressHouseNumber + ", " + m_addressCity; } diff --git a/addressbook/data/addressbookdata.h b/addressbook/data/addressbookdata.h index 114d4dc..4a250aa 100644 --- a/addressbook/data/addressbookdata.h +++ b/addressbook/data/addressbookdata.h @@ -6,8 +6,10 @@ #include #include #include +#include #include +#include #if defined(ADDRESSBOOK_LIBRARY) # define ADDRESSBOOKSHARED_EXPORT Q_DECL_EXPORT @@ -29,6 +31,7 @@ class ADDRESSBOOKSHARED_EXPORT AddressbookData : public ComboItem Q_PROPERTY(QString addressStreet READ addressStreet WRITE setAddressStreet) Q_PROPERTY(QString addressHouseNumber READ addressHouseNumber WRITE setAddressHouseNumber) Q_PROPERTY(QString addressZipCode READ addressZipCode WRITE setAddressZipCode) + Q_PROPERTY(QSharedPointer country READ country WRITE setCountry) public: AddressbookData(QObject *parent = 0); @@ -65,6 +68,9 @@ public: int id() const; void setId(int id); + QSharedPointer country() const; + void setCountry(const QSharedPointer &country); + private: friend class odb::access; #pragma db id auto @@ -79,6 +85,7 @@ private: QString m_addressStreet; QString m_addressHouseNumber; QString m_addressZipCode; + CountryDataPtr m_country; // ComboItem interface public: @@ -86,4 +93,6 @@ public: virtual QString toString(); }; +typedef QSharedPointer AddressbookDataPtr; + #endif // ADDRESSBOOKDATA_H diff --git a/addressbook/translations/addressbook_cs_CZ.qm b/addressbook/translations/addressbook_cs_CZ.qm index 61e7a6c..d4525d9 100644 Binary files a/addressbook/translations/addressbook_cs_CZ.qm and b/addressbook/translations/addressbook_cs_CZ.qm differ diff --git a/addressbook/translations/addressbook_cs_CZ.ts b/addressbook/translations/addressbook_cs_CZ.ts index 64d466c..7d3d8ab 100644 --- a/addressbook/translations/addressbook_cs_CZ.ts +++ b/addressbook/translations/addressbook_cs_CZ.ts @@ -58,5 +58,10 @@ ZIP PSČ + + + Country + Stát + diff --git a/application/mainwindow.cpp b/application/mainwindow.cpp index 989eb1d..e7327da 100644 --- a/application/mainwindow.cpp +++ b/application/mainwindow.cpp @@ -42,7 +42,7 @@ MainWindow::MainWindow(QWidget *parent) : int i = 0; foreach (IPlugin *plugin, Context::instance().plugins()) { - if (plugin->pluginId() != "CORE") + if (plugin->pluginId() != "CORE" && plugin->showIcon()) { QToolButton *plugButton = new QToolButton(this); plugButton->setText(plugin->pluginName()); @@ -81,26 +81,16 @@ void MainWindow::openPlugin() QVariant var = QObject::sender()->property(PLUGIN_INDEX); IPlugin *plugin = Context::instance().plugins().at(var.toInt()); - for (int i = 0; i < ui->tabWidget->count(); i++) { - if (ui->tabWidget->widget(i)->objectName() == plugin->pluginId()) { - ui->tabWidget->setCurrentIndex(i); - return; - } - } - - if (plugin->ui() != NULL) - { - ui->tabWidget->addTab(plugin->ui(), plugin->pluginIcon(), plugin->pluginName()); - ui->tabWidget->widget(ui->tabWidget->count() - 1)->setObjectName(plugin->pluginId()); - ui->tabWidget->setCurrentIndex(ui->tabWidget->count() - 1); - } + openPlugin(plugin); } void MainWindow::on_actionOpen_database_triggered() { - /*QFileDialog dialog(this); - dialog.setNameFilter(tr("Database Files (*.db)")); - dialog.setWindowTitle(tr("Open Database"));*/ + int tabCount = ui->tabWidget->count(); + for (int i = 0; i < tabCount; i++) + { + ui->tabWidget->removeTab(0); + } QString dbFile = QFileDialog::getOpenFileName(this, "Open Database", "", "Database Files (*.db)"); if (!dbFile.isEmpty()) @@ -118,6 +108,12 @@ void MainWindow::on_tabWidget_tabCloseRequested(int index) void MainWindow::on_actionLogin_triggered() { + int tabCount = ui->tabWidget->count(); + for (int i = 0; i < tabCount; i++) + { + ui->tabWidget->removeTab(0); + } + QSharedPointer u; Context::instance().setCurrentUser(u); m_lblUser->setText(""); @@ -144,3 +140,51 @@ void MainWindow::on_actionSettings_triggered() SettingsForm *settings = new SettingsForm(this); settings->show(); } + +void MainWindow::on_actionPost_register_triggered() +{ + IPlugin *plugZipCodes = Context::instance().plugin("POSTREGISTER"); + + if (plugZipCodes != NULL) + { + openPlugin(plugZipCodes); + } +} + +void MainWindow::openPlugin(IPlugin *plugin) +{ + for (int i = 0; i < ui->tabWidget->count(); i++) { + if (ui->tabWidget->widget(i)->objectName() == plugin->pluginId()) { + ui->tabWidget->setCurrentIndex(i); + return; + } + } + + if (plugin->ui() != NULL) + { + ui->tabWidget->addTab(plugin->ui(), plugin->pluginIcon(), plugin->pluginName()); + ui->tabWidget->widget(ui->tabWidget->count() - 1)->setObjectName(plugin->pluginId()); + ui->tabWidget->setCurrentIndex(ui->tabWidget->count() - 1); + } +} + +void MainWindow::on_actionCountry_register_triggered() +{ + IPlugin *plugCountryReg = Context::instance().plugin("COUNTRYREGISTER"); + + if (plugCountryReg != NULL) + { + openPlugin(plugCountryReg); + } + +} + +void MainWindow::on_actionAbout_Qt_triggered() +{ + QMessageBox::aboutQt(this); +} + +void MainWindow::on_actionAbout_triggered() +{ + QMessageBox::about(this, tr("About prodejna"), tr("Modular cash register software under GPL license.\n(C) 2015 - 2017 Josef Rokos, Zdenek Jonák")); +} diff --git a/application/mainwindow.h b/application/mainwindow.h index 305ab1b..717f073 100644 --- a/application/mainwindow.h +++ b/application/mainwindow.h @@ -9,6 +9,8 @@ #define PLUGIN_INDEX "plug_index" +class IPlugin; + namespace Ui { class MainWindow; } @@ -33,10 +35,19 @@ private slots: void on_actionSettings_triggered(); + void on_actionPost_register_triggered(); + + void on_actionCountry_register_triggered(); + + void on_actionAbout_Qt_triggered(); + + void on_actionAbout_triggered(); + private: Ui::MainWindow *ui; LoginDialog *m_loginDialog; QLabel *m_lblUser; + void openPlugin(IPlugin *plugin); // QWidget interface protected: diff --git a/application/mainwindow.ui b/application/mainwindow.ui index e97c89e..886c2be 100644 --- a/application/mainwindow.ui +++ b/application/mainwindow.ui @@ -60,7 +60,7 @@ 0 0 1000 - 19 + 25 @@ -72,7 +72,23 @@ + + + &Registers + + + + + + + Help + + + + + + @@ -116,6 +132,26 @@ Settings + + + &Post register + + + + + &Country register + + + + + About + + + + + About Qt + + diff --git a/application/translations/prodejna_cz.qm b/application/translations/prodejna_cz.qm index f98d37d..a529dd5 100644 Binary files a/application/translations/prodejna_cz.qm and b/application/translations/prodejna_cz.qm differ diff --git a/application/translations/prodejna_cz.ts b/application/translations/prodejna_cz.ts index 35ab4a0..46285ee 100644 --- a/application/translations/prodejna_cz.ts +++ b/application/translations/prodejna_cz.ts @@ -28,20 +28,54 @@ &Soubor - + + &Registers + Číse&lníky + + + + Help + Pomoc + + + &Exit &Konec - + &Open database... &Otevřít databázi... - + &Login... &Přihlásit... + + + &Post register + Číselník PSČ + + + + &Country register + Číselník států + + + + About + O aplikaci + + + + About Qt + O QT + + + Post register + Číselník adres + File Soubor @@ -59,10 +93,22 @@ Přihlásit se... - - + + Settings Nastavení + + + About prodejna + O aplikaci prodejna + + + + Modular cash register software under GPL license. +(C) 2015 - 2017 Josef Rokos, Zdenek Jonák + Modulární pokladní aplikace pod GPL license. +(C) 2015 - 2017 Josef Rokos, Zdenek Jonák + diff --git a/camp/addservicedialog.cpp b/camp/addservicedialog.cpp new file mode 100644 index 0000000..7b813dd --- /dev/null +++ b/camp/addservicedialog.cpp @@ -0,0 +1,27 @@ +#include "addservicedialog.h" +#include "ui_addservicedialog.h" + +AddServiceDialog::AddServiceDialog(AccServicePtr service, QWidget *parent) : + QDialog(parent), + ui(new Ui::AddServiceDialog) +{ + ui->setupUi(this); + + ui->editName->setText(service->accServiceName()); + ui->editPrice->setValue(service->price().toDouble()); +} + +AddServiceDialog::~AddServiceDialog() +{ + delete ui; +} + +QString AddServiceDialog::description() +{ + return ui->editDescription->text(); +} + +QDecDouble AddServiceDialog::price() +{ + return QDecDouble(ui->editPrice->value()); +} diff --git a/camp/addservicedialog.h b/camp/addservicedialog.h new file mode 100644 index 0000000..31ba935 --- /dev/null +++ b/camp/addservicedialog.h @@ -0,0 +1,27 @@ +#ifndef ADDSERVICEDIALOG_H +#define ADDSERVICEDIALOG_H + +#include +#include +#include + +namespace Ui { +class AddServiceDialog; +} + +class AddServiceDialog : public QDialog +{ + Q_OBJECT + +public: + explicit AddServiceDialog(AccServicePtr service, QWidget *parent = 0); + ~AddServiceDialog(); + + QString description(); + QDecDouble price(); + +private: + Ui::AddServiceDialog *ui; +}; + +#endif // ADDSERVICEDIALOG_H diff --git a/camp/addservicedialog.ui b/camp/addservicedialog.ui new file mode 100644 index 0000000..d02a1c7 --- /dev/null +++ b/camp/addservicedialog.ui @@ -0,0 +1,105 @@ + + + AddServiceDialog + + + + 0 + 0 + 400 + 143 + + + + Dialog + + + + + + Service name + + + + + + + true + + + + + + + Qt::Horizontal + + + QDialogButtonBox::Cancel|QDialogButtonBox::Ok + + + + + + + + + + Description + + + + + + + QAbstractSpinBox::NoButtons + + + 999999.989999999990687 + + + + + + + Price + + + + + + + + + buttonBox + accepted() + AddServiceDialog + accept() + + + 248 + 254 + + + 157 + 274 + + + + + buttonBox + rejected() + AddServiceDialog + reject() + + + 316 + 260 + + + 286 + 274 + + + + + diff --git a/camp/camp.cpp b/camp/camp.cpp new file mode 100644 index 0000000..7c11e23 --- /dev/null +++ b/camp/camp.cpp @@ -0,0 +1,33 @@ +#include "camp.h" + +#include "campgrid.h" +#include "campform.h" +#include "campservice.h" +#include "settings/campsettingsform.h" + +Camp::Camp() +{ +} + +void Camp::initServiceUi() +{ + m_service = new CampService(); + m_ui = new CampGrid(); + ((CampGrid*)m_ui)->setForm(new CampForm()); + m_settingsUi = new CampSettingsForm(); +} + +QIcon Camp::pluginIcon() +{ + return QIcon(":/icons/campPlugin.svg"); +} + +QTranslator *Camp::translator() +{ + return translatorFrom(":/translations/camp_"); +} + +bool Camp::hasNumberSeries() +{ + return true; +} diff --git a/camp/camp.h b/camp/camp.h new file mode 100644 index 0000000..a27fd14 --- /dev/null +++ b/camp/camp.h @@ -0,0 +1,29 @@ +#ifndef CAMP_H +#define CAMP_H + +#include "camp_global.h" +#include +#include +#include + +class CAMPSHARED_EXPORT Camp : public QObject, IMetaDataPlugin +{ + Q_OBJECT + + Q_PLUGIN_METADATA(IID PluginInterface_iid FILE "camp.json") + Q_INTERFACES(IPlugin) + +public: + Camp(); + +protected: + void initServiceUi() Q_DECL_OVERRIDE; + + // IPlugin interface +public: + virtual QIcon pluginIcon(); + QTranslator *translator(); + bool hasNumberSeries(); +}; + +#endif // CAMP_H diff --git a/camp/camp.json b/camp/camp.json new file mode 100644 index 0000000..cbbecf4 --- /dev/null +++ b/camp/camp.json @@ -0,0 +1,107 @@ +{ + "id" : "CAMP", + "name" : { + "default" : "Camp", + "CZ" : "Kemp" + }, + "descriptoin" : { + "default" : "", + "CZ" : "" + }, + "schemaVersion" : 5, + "sql" : [ +"CREATE TABLE \"CampData\" ( + \"id\" INTEGER NOT NULL PRIMARY KEY AUTOINCREMENT, + \"numSer\" TEXT NULL, + \"start\" TEXT NULL, + \"end\" TEXT NULL, + \"ownerFirstame\" TEXT NULL, + \"ownerLastname\" TEXT NULL, + \"ownerAddress\" TEXT NULL, + \"totalPrice\" INTEGER NOT NULL, + \"sale\" INTEGER NOT NULL, + \"fixedSale\" INTEGER NOT NULL, + \"season\" INTEGER NULL, + CONSTRAINT \"season_fk\" + FOREIGN KEY (\"season\") + REFERENCES \"Season\" (\"id\") + DEFERRABLE INITIALLY DEFERRED); + +CREATE TABLE \"AddressItem\" ( + \"id\" INTEGER NOT NULL PRIMARY KEY AUTOINCREMENT, + \"firstName\" TEXT NULL, + \"lastName\" TEXT NULL, + \"address\" TEXT NULL, + \"adbItem\" INTEGER NULL, + \"price\" INTEGER NOT NULL, + \"campData\" INTEGER NOT NULL, + \"personPrice\" INTEGER NULL, + CONSTRAINT \"adbItem_fk\" + FOREIGN KEY (\"adbItem\") + REFERENCES \"AddressbookData\" (\"id\") + DEFERRABLE INITIALLY DEFERRED, + CONSTRAINT \"campData_fk\" + FOREIGN KEY (\"campData\") + REFERENCES \"CampData\" (\"id\") + DEFERRABLE INITIALLY DEFERRED, + CONSTRAINT \"personPrice_fk\" + FOREIGN KEY (\"personPrice\") + REFERENCES \"PersonPrice\" (\"id\") + DEFERRABLE INITIALLY DEFERRED); + +CREATE TABLE \"ServiceItem\" ( + \"id\" INTEGER NOT NULL PRIMARY KEY AUTOINCREMENT, + \"name\" TEXT NULL, + \"code\" TEXT NULL, + \"price\" INTEGER NOT NULL, + \"salePossible\" INTEGER NOT NULL, + \"type\" INTEGER NOT NULL, + \"campData\" INTEGER NOT NULL, + CONSTRAINT \"campData_fk\" + FOREIGN KEY (\"campData\") + REFERENCES \"CampData\" (\"id\") + DEFERRABLE INITIALLY DEFERRED); + +CREATE TABLE \"Sale\" ( + \"id\" INTEGER NOT NULL PRIMARY KEY AUTOINCREMENT, + \"sale\" INTEGER NOT NULL, + \"fixed\" INTEGER NOT NULL); + +CREATE TABLE \"PersonPrice\" ( + \"id\" INTEGER NOT NULL PRIMARY KEY AUTOINCREMENT, + \"description\" TEXT NULL, + \"fromAge\" INTEGER NOT NULL, + \"toAge\" INTEGER NOT NULL, + \"price\" INTEGER NOT NULL, + \"active\" INTEGER NOT NULL); +", + +"ALTER TABLE Sale ADD \"description\" TEXT NULL; +", + +"ALTER TABLE AddressItem ADD \"owner\" INTEGER NULL; +", + +"ALTER TABLE ServiceItem ADD \"sale\" INTEGER NULL; +ALTER TABLE ServiceItem ADD \"description\" TEXT NULL; +", + +"ALTER TABLE ServiceItem ADD \"totalPrice\" INTEGER NULL; +ALTER TABLE ServiceItem ADD \"fullPrice\" INTEGER NULL; +ALTER TABLE CampData ADD \"fullPrice\" INTEGER NULL; +ALTER TABLE CampData ADD \"totalSale\" INTEGER NULL; +" + ], + "dependencies" : [ "ADDRESSBOOK", "SHOP", "SERVICES" ], + "translations" : { + "CZ" : { + "name" : "Název", + "shortName" : "Zobrazit na účtence", + "code" : "Kód", + "type" : "Druh", + "price" : "Cena", + "vat" : "DPH", + "count" : "Počet" + } + } +} diff --git a/camp/camp.pro b/camp/camp.pro new file mode 100644 index 0000000..8e2c548 --- /dev/null +++ b/camp/camp.pro @@ -0,0 +1,104 @@ +#------------------------------------------------- +# +# Project created by QtCreator 2017-04-19T09:20:32 +# +#------------------------------------------------- + +QT += widgets sql + +TARGET = camp +TEMPLATE = lib + +DEFINES += CAMP_LIBRARY + +# The following define makes your compiler emit warnings if you use +# any feature of Qt which as been marked as deprecated (the exact warnings +# depend on your compiler). Please consult the documentation of the +# deprecated API in order to know how to port your code away from it. +DEFINES += QT_DEPRECATED_WARNINGS + +# You can also make your code fail to compile if you use deprecated APIs. +# In order to do so, uncomment the following line. +# You can also select to disable deprecated APIs only up to a certain version of Qt. +#DEFINES += QT_DISABLE_DEPRECATED_BEFORE=0x060000 # disables all the APIs deprecated before Qt 6.0.0 + +SOURCES += camp.cpp \ + data/campdata.cpp \ + data/addressitem.cpp \ + data/serviceitem.cpp \ + campgrid.cpp \ + campform.cpp \ + data/sale.cpp \ + settings/campsettingsform.cpp \ + data/personprice.cpp \ + settings/campsettings.cpp \ + campwizard.cpp \ + campservice.cpp \ + addservicedialog.cpp \ + campshopitem.cpp \ + campseller.cpp + +HEADERS += camp.h\ + camp_global.h \ + data/campdata.h \ + data/addressitem.h \ + data/serviceitem.h \ + data/camp-data.h \ + campgrid.h \ + campform.h \ + data/sale.h \ + settings/campsettingsform.h \ + data/personprice.h \ + settings/campsettings.h \ + campwizard.h \ + campservice.h \ + addservicedialog.h \ + campshopitem.h \ + campseller.h + +include(../config_plugin.pri) + +ODB_FILES = camp/data/camp-data.h +H_DIR = $$PWD/data/*.h +ODB_OTHER_INCLUDES = -I $$PWD/../shop -I $$PWD/../addressbook/data -I $$PWD/../countryregister/data -I $$PWD/../services/data +include(../odb.pri) + +win32:CONFIG(release, debug|release): LIBS += -L$$OUT_PWD/../plugins/ -lshop +else:win32:CONFIG(debug, debug|release): LIBS += -L$$OUT_PWD/../plugins/ -lshop +else:unix: LIBS += -L$$OUT_PWD/../plugins/ -lshop + +INCLUDEPATH += $$PWD/../shop +DEPENDPATH += $$PWD/../shop + +win32:CONFIG(release, debug|release): LIBS += -L$$OUT_PWD/../plugins/ -laddressbook +else:win32:CONFIG(debug, debug|release): LIBS += -L$$OUT_PWD/../plugins/ -laddressbook +else:unix: LIBS += -L$$OUT_PWD/../plugins/ -laddressbook + +INCLUDEPATH += $$PWD/../addressbook +INCLUDEPATH += $$PWD/../addressbook/data +DEPENDPATH += $$PWD/../addressbook + +INCLUDEPATH += $$PWD/../countryregister/data +INCLUDEPATH += $$PWD/../countryregister + +win32:CONFIG(release, debug|release): LIBS += -L$$OUT_PWD/../plugins/ -lservices +else:win32:CONFIG(debug, debug|release): LIBS += -L$$OUT_PWD/../plugins/ -lservices +else:unix: LIBS += -L$$OUT_PWD/../plugins/ -lservices + +INCLUDEPATH += $$PWD/../services +INCLUDEPATH += $$PWD/../services/data +DEPENDPATH += $$PWD/../services + +TRANSLATIONS = translations/camp_cs_CZ.ts + +DISTFILES += \ + camp.json + +RESOURCES += \ + camprc.qrc + +FORMS += \ + campform.ui \ + settings/campsettingsform.ui \ + campwizard.ui \ + addservicedialog.ui diff --git a/camp/camp_global.h b/camp/camp_global.h new file mode 100644 index 0000000..758c402 --- /dev/null +++ b/camp/camp_global.h @@ -0,0 +1,12 @@ +#ifndef CAMP_GLOBAL_H +#define CAMP_GLOBAL_H + +#include + +#if defined(CAMP_LIBRARY) +# define CAMPSHARED_EXPORT Q_DECL_EXPORT +#else +# define CAMPSHARED_EXPORT Q_DECL_IMPORT +#endif + +#endif // CAMP_GLOBAL_H diff --git a/camp/campform.cpp b/camp/campform.cpp new file mode 100644 index 0000000..69e805d --- /dev/null +++ b/camp/campform.cpp @@ -0,0 +1,14 @@ +#include "campform.h" +#include "ui_campform.h" + +CampForm::CampForm(QWidget *parent) : + AutoForm(parent), + ui(new Ui::CampForm) +{ + ui->setupUi(this); +} + +CampForm::~CampForm() +{ + delete ui; +} diff --git a/camp/campform.h b/camp/campform.h new file mode 100644 index 0000000..6c4d302 --- /dev/null +++ b/camp/campform.h @@ -0,0 +1,25 @@ +#ifndef CAMPFORM_H +#define CAMPFORM_H + +#include +#include +#include "data/camp-data.h" +#include "camp-odb.hxx" + +namespace Ui { +class CampForm; +} + +class CampForm : public AutoForm +{ + Q_OBJECT + +public: + explicit CampForm(QWidget *parent = 0); + ~CampForm(); + +private: + Ui::CampForm *ui; +}; + +#endif // CAMPFORM_H diff --git a/camp/campform.ui b/camp/campform.ui new file mode 100644 index 0000000..6a03d53 --- /dev/null +++ b/camp/campform.ui @@ -0,0 +1,19 @@ + + + CampForm + + + + 0 + 0 + 462 + 403 + + + + Form + + + + + diff --git a/camp/campgrid.cpp b/camp/campgrid.cpp new file mode 100644 index 0000000..73a07a7 --- /dev/null +++ b/camp/campgrid.cpp @@ -0,0 +1,28 @@ +#include "campgrid.h" +#include "campwizard.h" +#include "campservice.h" + +CampGrid::CampGrid(QWidget *parent) : GridForm(parent) +{ + setTableModel(new AutoTableModel); +} + +void CampGrid::handleNewRecord() +{ + CampService srv; + CampDataPtr data = srv.create(); + CampWizard *wizard = new CampWizard(); + wizard->setAttribute(Qt::WA_DeleteOnClose); + wizard->setData(data); + + connect(wizard, &QDialog::accepted, [this, data](){ + addRow(data); + }); + + wizard->show(); +} + +void CampGrid::handleEditRecord() +{ + +} diff --git a/camp/campgrid.h b/camp/campgrid.h new file mode 100644 index 0000000..ff36e96 --- /dev/null +++ b/camp/campgrid.h @@ -0,0 +1,19 @@ +#ifndef CAMPGRID_H +#define CAMPGRID_H + +#include +#include "data/camp-data.h" +#include "camp-odb.hxx" + +class CampGrid : public GridForm +{ +public: + CampGrid(QWidget *parent = NULL); + + // IGridForm interface +protected: + void handleNewRecord(); + void handleEditRecord(); +}; + +#endif // CAMPGRID_H diff --git a/camp/camprc.qrc b/camp/camprc.qrc new file mode 100644 index 0000000..2b79da0 --- /dev/null +++ b/camp/camprc.qrc @@ -0,0 +1,6 @@ + + + icons/campPlugin.svg + translations/camp_cs_CZ.qm + + diff --git a/camp/campseller.cpp b/camp/campseller.cpp new file mode 100644 index 0000000..17f9eb9 --- /dev/null +++ b/camp/campseller.cpp @@ -0,0 +1,28 @@ +#include "campseller.h" + +#include "campwizard.h" +#include "campservice.h" +#include "data/camp-data.h" +#include "campshopitem.h" + +CampSeller::CampSeller(QObject *parent) + :ISeller(parent) +{ +} + +void CampSeller::prepareItem() +{ + CampWizard *wizard = new CampWizard(); + wizard->setAttribute(Qt::WA_DeleteOnClose); + + CampService srv; + CampDataPtr data = srv.create(); + wizard->setData(data); + wizard->show(); + + connect(wizard, &QDialog::accepted, [this, data](){ + CampShopItemPtr item(new CampShopItem); + item->setUnitPrice(data->totalPrice()); + emit itemPrepared(item, 1); + }); +} diff --git a/camp/campseller.h b/camp/campseller.h new file mode 100644 index 0000000..dac681e --- /dev/null +++ b/camp/campseller.h @@ -0,0 +1,17 @@ +#ifndef CAMPSELLER_H +#define CAMPSELLER_H + +#include + +class CampSeller : public ISeller +{ + Q_OBJECT +public: + explicit CampSeller(QObject *parent = 0); + + // ISeller interface +public: + void prepareItem(); +}; + +#endif // CAMPSELLER_H diff --git a/camp/campservice.cpp b/camp/campservice.cpp new file mode 100644 index 0000000..4aed30e --- /dev/null +++ b/camp/campservice.cpp @@ -0,0 +1,315 @@ +#include "campservice.h" +#include +#include +#include +#include "campshopitem.h" +#include "campseller.h" +#include + +CampService::CampService() +{ + m_pluginId = "CAMP"; + m_seller = new CampSeller(this); +} + +void CampService::addPerson(CampDataPtr data, AddressbookDataPtr address) +{ + AddressItemPtr addrItem(new AddressItem); + + addrItem->setAdbItem(address); + addrItem->setAddress(address->toString()); + addrItem->setFirstName(address->firstName()); + addrItem->setLastName(address->lastName()); + addrItem->setCampData(data); + + if (data->people().isEmpty()) + { + setOwner(data, addrItem); + } + + data->addPerson(addrItem); +} + +void CampService::addService(CampDataPtr data, AccServicePtr service) +{ + ServiceItemPtr serviceItem(new ServiceItem); + + serviceItem->setName(service->accServiceName()); + serviceItem->setCode(service->accServiceCode()); + serviceItem->setPrice(service->price()); + serviceItem->setSalePossible(service->salePossible()); + serviceItem->setType(service->serviceType()); + + data->addServiceItem(serviceItem); +} + +void CampService::addService(CampDataPtr data, AccServicePtr service, QDecDouble price, QString description) +{ + ServiceItemPtr item = addServiceInt(data, service); + item->setPrice(price); + item->setDescription(description); +} + +void CampService::setOwner(CampDataPtr data, AddressItemPtr person) +{ + foreach (AddressItemPtr p, data->people()) { + p->setOwner(false); + } + + person->setOwner(true); + + data->setOwnerFirstame(person->firstName()); + data->setOwnerLastname(person->lastName()); + data->setOwnerAddress(person->address()); +} + +CampDataPtr CampService::create() +{ + CampDataPtr data(new CampData); + data->setStart(QDate::currentDate()); + data->setEnd(QDate::currentDate()); + + return data; +} + +void CampService::calculate(CampDataPtr data) +{ + SettingsService srv("CAMP"); + m_settings = srv.loadSettings(); + + calcServices(data); + calcPeople(data); + calcPrice(data); +} + +void CampService::saveCamp(CampDataPtr data) +{ + if (!checkPermission(PERM_ADD)) + { + return; + } + + SeasonService seasonSrv; + SeasonPtr season = seasonSrv.active(); + data->setSeason(season); + + Transaction tr; + try + { + odb::database *db = Context::instance().db(); + + NumberSeriesService numSrv; + data->setNumSer(numSrv.nextStrForPlugin("CAMP")); + + db->persist(data); + + foreach (ServiceItemPtr item, data->services()) { + item->setCampData(data.toWeakRef()); + db->persist(item); + } + + foreach (AddressItemPtr item, data->people()) { + item->setCampData(data.toWeakRef()); + db->persist(item); + } + + tr.commit(); + } + catch (const odb::exception &ex) + { + emit dbError(ex.what()); + emit dbErrorUpdate(ex.what()); + return; + } +} + +void CampService::calcPeople(CampDataPtr data) +{ + foreach (ServiceItemPtr service, data->services()) { + if (service->type() == AccService::ACCFEE) + { + data->removeServiceItem(service); + } + } + + Service srvPrices; + QList prices = srvPrices.all("active = 1"); + int days = data->start().daysTo(data->end()); + + foreach (AddressItemPtr item, data->people()) { + QDate first(1,1,1); + qint64 daysStart = item->adbItem()->birthDate().daysTo(data->start()); + first = first.addDays(daysStart); + int startAge = first.year() - 1; + + first = QDate(1,1,1); + qint64 daysEnd = item->adbItem()->birthDate().daysTo(data->end()); + first = first.addDays(daysEnd); + int endAge = first.year() - 1; + + if (!item->personPrice().isNull()) + { + item->setPrice(item->personPrice()->price() * days); + addAccFee(data, item, startAge, endAge, days); + continue; + } + else + { + item->setPrice(0); + } + + foreach (PersonPricePtr price, prices) { + if (price->fromAge() <= endAge && price->toAge() >= endAge) + { + item->setPersonPrice(price); + item->setPrice(price->price() * days); + break; + } + } + + if (item->adbItem()->ztp()) + { + continue; + } + + addAccFee(data, item, startAge, endAge, days); + } +} + +void CampService::calcServices(CampDataPtr data) +{ + QDecDouble sale = data->sale(); + bool fixedSale = data->fixedSale(); + int days = data->start().daysTo(data->end()); + + foreach (ServiceItemPtr item, data->services()) { + item->setFullPrice(item->price() * days); + + if (sale != QDecDouble(0) && !fixedSale && item->salePossible()) + { + QDecDouble itemSale = (item->fullPrice() * sale) / 100; + item->setSale(itemSale); + item->setTotalPrice(item->fullPrice() - itemSale); + } + else + { + item->setSale(0); + item->setTotalPrice(item->fullPrice()); + } + } +} + +void CampService::calcPrice(CampDataPtr data) +{ + QDecDouble totalPrice(0); + QDecDouble sale(0); + + foreach (ServiceItemPtr service, data->services()) { + totalPrice += service->totalPrice(); + sale += service->sale(); + } + + foreach (AddressItemPtr addr, data->people()) { + totalPrice += addr->price(); + } + + if (data->fixedSale()) + { + totalPrice -= data->sale(); + sale = data->sale(); + } + + switch (m_settings->rounding()) { + case Enums::R_UP: + totalPrice = QDecDouble(ceil(totalPrice.toDouble() * pow(10, m_settings->decimalPlaces())) / pow(10, m_settings->decimalPlaces())); + break; + case Enums::R_DOWN: + totalPrice = QDecDouble(floor(totalPrice.toDouble() * pow(10, m_settings->decimalPlaces())) / pow(10, m_settings->decimalPlaces())); + break; + case Enums::R_MATH: + totalPrice = QDecDouble(round(totalPrice.toDouble() * pow(10, m_settings->decimalPlaces())) / pow(10, m_settings->decimalPlaces())); + break; + case Enums::R_NONE: + break; + } + + data->setTotalPrice(totalPrice); + data->setTotalSale(sale); +} + +void CampService::addAccFee(CampDataPtr data, AddressItemPtr item, int startAge, int endAge, int days) +{ + auto addAccService = [this, item, data](int count){ + ServiceItemPtr srvItem(new ServiceItem); + + srvItem->setName(item->firstName() + " " + item->lastName()); + srvItem->setDescription(m_settings->accFeeText()); + srvItem->setPrice(m_settings->accFee()); + srvItem->setTotalPrice(m_settings->accFee() * count); + srvItem->setFullPrice(srvItem->totalPrice()); + srvItem->setType(AccService::ACCFEE); + srvItem->setSalePossible(false); + srvItem->setCampData(data); + data->addServiceItem(srvItem); + }; + + if (startAge == endAge || (startAge >= m_settings->accFeeStartAge() && startAge <= m_settings->accFeeEndAge())) + { + if (endAge >= m_settings->accFeeStartAge() && endAge <= m_settings->accFeeEndAge()) + { + addAccService(days); + } + } + else + { + if (endAge >= m_settings->accFeeStartAge() && endAge <= m_settings->accFeeEndAge()) + { + QDate tmp(data->end().year(), item->adbItem()->birthDate().month(), item->adbItem()->birthDate().day()); + int count = tmp.daysTo(data->end()); + + addAccService(count); + } + } +} + +QList CampService::shopItems() +{ + CampShopItemPtr item(new CampShopItem); + + QList items; + items.append(item); + + return items; +} + +ShopItemPtr CampService::shopItem(int ) +{ + return CampShopItemPtr(new CampShopItem); +} + +void CampService::addedToVoucher(int , int ) +{ + +} + +ISeller *CampService::seller() +{ + return m_seller; +} + +ServiceItemPtr CampService::addServiceInt(CampDataPtr data, AccServicePtr service) +{ + ServiceItemPtr serviceItem(new ServiceItem); + + serviceItem->setName(service->accServiceName()); + serviceItem->setCode(service->accServiceCode()); + serviceItem->setPrice(service->price()); + serviceItem->setSalePossible(service->salePossible()); + serviceItem->setType(service->serviceType()); + serviceItem->setCampData(data); + + data->addServiceItem(serviceItem); + + return serviceItem; +} + diff --git a/camp/campservice.h b/camp/campservice.h new file mode 100644 index 0000000..4097836 --- /dev/null +++ b/camp/campservice.h @@ -0,0 +1,42 @@ +#ifndef CAMPSERVICE_H +#define CAMPSERVICE_H + +#include +#include +#include +#include +#include "data/camp-data.h" +#include "settings/campsettings.h" +#include "camp-odb.hxx" + +class CampService : public Service, public ISellableService +{ +public: + CampService(); + + void addPerson(CampDataPtr data, AddressbookDataPtr address); + void addService(CampDataPtr data, AccServicePtr service); + void addService(CampDataPtr data, AccServicePtr service, QDecDouble price, QString description); + void setOwner(CampDataPtr data, AddressItemPtr person); + CampDataPtr create(); + void calculate(CampDataPtr data); + void saveCamp(CampDataPtr data); + +private: + ServiceItemPtr addServiceInt(CampDataPtr data, AccServicePtr service); + void calcPeople(CampDataPtr data); + void calcServices(CampDataPtr data); + void calcPrice(CampDataPtr data); + void addAccFee(CampDataPtr data, AddressItemPtr item, int startAge, int endAge, int days); + CampSettingsPtr m_settings; + ISeller *m_seller; + + // ISellableService interface +public: + QList shopItems(); + ShopItemPtr shopItem(int itemId); + void addedToVoucher(int itemId, int countAdded); + ISeller *seller(); +}; + +#endif // CAMPSERVICE_H diff --git a/camp/campshopitem.cpp b/camp/campshopitem.cpp new file mode 100644 index 0000000..8c2547d --- /dev/null +++ b/camp/campshopitem.cpp @@ -0,0 +1,48 @@ +#include "campshopitem.h" + +CampShopItem::CampShopItem(QObject *parent) + :ShopItem(parent) +{ + m_unitPrice = QDecDouble(0); + m_vatType = Enums::NONE; +} + +QString CampShopItem::name() +{ + return "Camp"; +} + +QString CampShopItem::shortName() +{ + return "Camp"; +} + +QDecDouble CampShopItem::unitPrice() +{ + return m_unitPrice; +} + +Enums::VatType CampShopItem::vatType() +{ + return m_vatType; +} + +QString CampShopItem::pluginId() +{ + return "CAMP"; +} + +QString CampShopItem::code() +{ + return "Camp"; +} + +void CampShopItem::setUnitPrice(const QDecDouble &unitPrice) +{ + m_unitPrice = unitPrice; +} + +void CampShopItem::setVatType(const Enums::VatType &vatType) +{ + m_vatType = vatType; +} diff --git a/camp/campshopitem.h b/camp/campshopitem.h new file mode 100644 index 0000000..60a4767 --- /dev/null +++ b/camp/campshopitem.h @@ -0,0 +1,34 @@ +#ifndef CAMPSHOPITEM_H +#define CAMPSHOPITEM_H + +#include + +class CampShopItem : public ShopItem +{ +public: + CampShopItem(QObject *parent = 0); + + // IShopItem interface +public: + QString name(); + QString shortName(); + QDecDouble unitPrice(); + Enums::VatType vatType(); + QString pluginId(); + + // ShopItem interface +public: + QString code(); + + void setUnitPrice(const QDecDouble &unitPrice); + + void setVatType(const Enums::VatType &vatType); + +private: + QDecDouble m_unitPrice; + Enums::VatType m_vatType; +}; + +typedef QSharedPointer CampShopItemPtr; + +#endif // CAMPSHOPITEM_H diff --git a/camp/campwizard.cpp b/camp/campwizard.cpp new file mode 100644 index 0000000..8bbf952 --- /dev/null +++ b/camp/campwizard.cpp @@ -0,0 +1,405 @@ +#include "campwizard.h" +#include "ui_campwizard.h" +#include "campservice.h" +#include "addservicedialog.h" + +#include +#include +#include + +//////////////////////////////////// +/// \brief AddressHelper::AddressHelper +/// \param parent +/// +AddressHelper::AddressHelper(QObject *parent) + :QObject(parent) +{ + m_address = AddressbookDataPtr(new AddressbookData); +} + +QSharedPointer AddressHelper::address() const +{ + return m_address; +} + +void AddressHelper::setAddress(const QSharedPointer &address) +{ + if (qobject_cast(address.data()) != NULL) + { + m_address = qSharedPointerDynamicCast(address); + } +} + +AddressbookDataPtr AddressHelper::addr() const +{ + return m_address; +} + +void AddressHelper::setAddr(const AddressbookDataPtr &address) +{ + m_address = address; +} + +AddressbookDataPtr AddressHelper::newAddress() +{ + AddressBookService adbSrv; + m_copyAddress = adbSrv.copyAddress(m_address); + + return m_copyAddress; +} + +AddressbookDataPtr AddressHelper::copyAddress() +{ + if (m_copyAddress.isNull()) + { + m_copyAddress = AddressbookDataPtr(new AddressbookData); + } + + return m_copyAddress; +} + +////////////////////////////////////////////////////////////// +/// \brief SaleHelper::SaleHelper +/// \param parent +/// +SaleHelper::SaleHelper(QObject *parent) :QObject(parent) +{ + m_sale = SalePtr(new Sale); +} + +SalePtr SaleHelper::salePtr() const +{ + return m_sale; +} + +void SaleHelper::setSalePtr(const SalePtr &sale) +{ + m_sale = sale; +} + +QSharedPointer SaleHelper::sale() const +{ + return m_sale; +} + +void SaleHelper::setSale(const QSharedPointer &sale) +{ + if (qobject_cast(sale.data()) != NULL) + { + m_sale = qSharedPointerDynamicCast(sale); + emit saleChanged(); + } +} + +/////////////////////////////////////////////////////////// +/// \brief CampWizard::CampWizard +/// \param parent +/// +CampWizard::CampWizard(QWidget *parent) : + QWizard(parent), + ui(new Ui::CampWizard) +{ + ui->setupUi(this); + + m_peopleModel = new AutoTableModel(this); + ui->tablePeople->setModel(m_peopleModel); + ui->tablePeople->hideColumn(2); + ui->tablePeople->hideColumn(3); + ui->tablePeople->horizontalHeader()->setSectionResizeMode(0, QHeaderView::Stretch); + ui->tablePeople->horizontalHeader()->setSectionResizeMode(1, QHeaderView::Stretch); + + connect(ui->tablePeople->selectionModel(), &QItemSelectionModel::currentRowChanged, [this](QModelIndex, QModelIndex){ + ui->btnRemove->setEnabled(!m_data->people().isEmpty()); + ui->btnOwner->setEnabled(!m_data->people().isEmpty()); + }); + + m_dataBinder = new ObjectBinder(this); + m_dataBinder->registerBinding(ui->start); + m_dataBinder->registerBinding(ui->end); + m_dataBinder->registerBinding(ui->totalPrice); + m_dataBinder->registerBinding(ui->totalSale); + + m_addrHelper = new AddressHelper(this); + + Service addrSrv; + m_addrHelperBinder = new ObjectBinder(this); + m_addrHelperBinder->registerBinding(ui->address, ComboData::createComboData(addrSrv.all())); + m_addrHelperBinder->setData(m_addrHelper); + + m_addressBinder = new ObjectBinder(this); + m_addressBinder->registerBinding(ui->title); + m_addressBinder->registerBinding(ui->firstName); + m_addressBinder->registerBinding(ui->lastName); + m_addressBinder->registerBinding(ui->birthDate); + m_addressBinder->registerBinding(ui->idCardNumber); + m_addressBinder->registerBinding(ui->ztp); + m_addressBinder->registerBinding(ui->addressStreet); + m_addressBinder->registerBinding(ui->addressHouseNumber); + m_addressBinder->registerBinding(ui->addressZipCode); + m_addressBinder->registerBinding(ui->addressCity); + + Service coutrySrv; + m_addressBinder->registerBinding(ui->country, ComboData::createComboData(coutrySrv.all())); + + m_addressBinder->setData(m_addrHelper->copyAddress().data()); + m_addressBinder->bindToUi(); + + m_bindAddrCombo = true; + + Service serviceSrv; + m_servicesModel = new AutoTableModel(this); + m_servicesModel->setData(serviceSrv.all()); + ui->tableServices->setModel(m_servicesModel); + + ui->tableServices->hideColumn(1); + ui->tableServices->hideColumn(3); + ui->tableServices->hideColumn(4); + ui->tableServices->hideColumn(5); + ui->tableServices->hideColumn(6); + + ui->tableServices->horizontalHeader()->setSectionResizeMode(0, QHeaderView::Stretch); + + m_itemsModel = new AutoTableModel(); + ui->tableItems->setModel(m_itemsModel); + + ui->tableItems->hideColumn(1); + ui->tableItems->hideColumn(4); + ui->tableItems->hideColumn(5); + ui->tableItems->hideColumn(6); + + ui->tableItems->horizontalHeader()->setSectionResizeMode(2, QHeaderView::Stretch); + + connect(ui->tableServices->selectionModel(), &QItemSelectionModel::currentRowChanged, [this](QModelIndex current, QModelIndex){ + ui->btnAddService->setEnabled(current.isValid()); + }); + + connect(ui->tableItems->selectionModel(), &QItemSelectionModel::currentRowChanged, [this](QModelIndex, QModelIndex){ + ui->btnRemoveService->setEnabled(!m_data->services().isEmpty()); + }); + + m_saleHelper = new SaleHelper(this); + m_saleBinder = new ObjectBinder(this); + Service saleSrv; + m_saleBinder->registerBinding(ui->sale, ComboData::createComboData(saleSrv.all())); + m_saleBinder->setData(m_saleHelper); + m_saleBinder->bindToUi(); + + ui->tabPeople->setModel(m_peopleModel); + ui->tabPeople->hideColumn(0); + ui->tabPeople->hideColumn(1); + ui->tabPeople->hideColumn(4); + ui->tabPeople->horizontalHeader()->setSectionResizeMode(2, QHeaderView::Stretch); + + ui->tabServices->setModel(m_itemsModel); + ui->tabServices->hideColumn(1); + ui->tabServices->hideColumn(6); + ui->tabServices->horizontalHeader()->setSectionResizeMode(0, QHeaderView::Stretch); + ui->tabServices->horizontalHeader()->setSectionResizeMode(2, QHeaderView::Stretch); +} + +CampWizard::~CampWizard() +{ + delete ui; +} + +void CampWizard::setData(const CampDataPtr &data) +{ + m_data = data; + + m_dataBinder->setData(data.data()); + m_dataBinder->bindToUi(); + m_addrHelperBinder->bindToUi(); + + m_peopleModel->setData(data->people()); + m_itemsModel->setData(data->services()); +} + +void CampWizard::on_btnAdd_clicked() +{ + m_addressBinder->bindToData(); + + CampService srv; + AddressBookService adbSrv; + + if (ui->groupNew->isChecked()) + { + AddressbookDataPtr newAddr = adbSrv.copyAddress(m_addrHelper->copyAddress()); + adbSrv.save(newAddr); + srv.addPerson(m_data, newAddr); + + m_bindAddrCombo = false; + m_addrHelperBinder->registerBinding(ui->address, ComboData::createComboData(adbSrv.all())); + m_addrHelperBinder->bindToUi(); + m_bindAddrCombo = true; + } + else + { + srv.addPerson(m_data, m_addrHelper->addr()); + } + + m_peopleModel->setData(m_data->people()); +} + + +void CampWizard::on_address_currentIndexChanged(int) +{ + if (m_bindAddrCombo) + { + AddressBookService adbSrv; + m_addrHelperBinder->bindToData(); + m_addressBinder->setData(m_addrHelper->newAddress().data()); + m_addressBinder->bindToUi(); + } +} + +void CampWizard::on_btnRemove_clicked() +{ + AddressItemPtr selAddr = m_peopleModel->itemFromIndex(ui->tablePeople->currentIndex()); + m_data->removePerson(selAddr); + m_peopleModel->setData(m_data->people()); + + ui->btnOwner->setEnabled(false); + ui->btnRemove->setEnabled(false); +} + +void CampWizard::on_btnOwner_clicked() +{ + CampService srv; + AddressItemPtr selAddr = m_peopleModel->itemFromIndex(ui->tablePeople->currentIndex()); + srv.setOwner(m_data, selAddr); + + QModelIndex currIndex = ui->tablePeople->currentIndex(); + m_peopleModel->setData(m_data->people()); + ui->tablePeople->setCurrentIndex(currIndex); +} + +void CampWizard::on_groupNew_clicked(bool checked) +{ + if (checked) + { + ui->address->setEnabled(false); + } + else + { + ui->address->setEnabled(true); + } +} + +void CampWizard::on_CampWizard_currentIdChanged(int id) +{ + if (id == 2) + { + CampService srv; + srv.calculate(m_data); + + m_dataBinder->bindToUi(); + m_itemsModel->setData(m_data->services()); + + ui->lFrom->setText(m_data->start().toString("d. M. yyyy")); + ui->lTo->setText(m_data->end().toString("d. M. yyyy")); + ui->lDays->setText(QString::number(m_data->start().daysTo(m_data->end()))); + ui->lOwner->setText(m_data->ownerAddress()); + } +} + +void CampWizard::on_btnAddService_clicked() +{ + AccServicePtr service = m_servicesModel->itemFromIndex(ui->tableServices->currentIndex()); + AddServiceDialog *dialog = new AddServiceDialog(service, this); + + dialog->setAttribute(Qt::WA_DeleteOnClose); + + connect(dialog, &QDialog::accepted, [=](){ + CampService srv; + srv.addService(m_data, service, dialog->price(), dialog->description()); + m_itemsModel->setData(m_data->services()); + }); + + dialog->show(); +} + +void CampWizard::on_btnRemoveService_clicked() +{ + ServiceItemPtr item = m_itemsModel->itemFromIndex(ui->tableItems->currentIndex()); + m_data->removeServiceItem(item); + m_itemsModel->setData(m_data->services()); + + ui->btnRemoveService->setEnabled(false); +} + +void CampWizard::on_checkSale_clicked() +{ + ui->sale->setEnabled(ui->checkSale->isChecked()); + applySale(); +} + +void CampWizard::applySale() +{ + if (m_data.isNull()) + { + return; + } + + if (ui->checkSale->isChecked()) + { + m_saleBinder->bindToData(); + m_data->setSale(m_saleHelper->salePtr()->sale()); + m_data->setFixedSale(m_saleHelper->salePtr()->fixed()); + } + else + { + m_data->setSale(QDecDouble(0)); + } +} + +void CampWizard::on_sale_currentIndexChanged(int) +{ + applySale(); +} + +bool CampWizard::validateCurrentPage() +{ + m_dataBinder->bindToData(); + + if (currentPage() == ui->peoplePage && m_data->people().isEmpty()) + { + QMessageBox::critical(this, tr("Error"), tr("Add people.")); + return false; + } + + if (currentPage() == ui->peoplePage && m_data->start() >= m_data->end()) + { + QMessageBox::critical(this, tr("Error"), tr("Start date is after or equals end date.")); + return false; + } + + if (currentPage() == ui->servicePage && m_data->services().isEmpty()) + { + QMessageBox::critical(this, tr("Error"), tr("Add service.")); + return false; + } + + return true; +} + +void CampWizard::accept() +{ + CampService srv; + srv.saveCamp(m_data); + bool success = true; + + connect(&srv, &IService::dbError, [this, &success](QString msg){ + QMessageBox::critical(this, tr("Database error"), tr(msg.toStdString().c_str())); + success = false; + }); + + connect(&srv, &IService::permissionDenied, [this, &success](QString msg){ + QMessageBox::critical(this, "Permission denied", msg.toStdString().c_str()); + success = false; + }); + + if (success) + { + QDialog::accept(); + } +} diff --git a/camp/campwizard.h b/camp/campwizard.h new file mode 100644 index 0000000..4c5bcaf --- /dev/null +++ b/camp/campwizard.h @@ -0,0 +1,115 @@ +#ifndef CAMPWIZARD_H +#define CAMPWIZARD_H + +#include +#include "data/camp-data.h" +#include +#include +#include +#include + +class AddressHelper : public QObject +{ + Q_OBJECT + Q_PROPERTY(QSharedPointer address READ address WRITE setAddress) + +public: + AddressHelper(QObject *parent = NULL); + + QSharedPointer address() const; + void setAddress(const QSharedPointer &address); + + AddressbookDataPtr addr() const; + void setAddr(const AddressbookDataPtr &address); + + AddressbookDataPtr newAddress(); + AddressbookDataPtr copyAddress(); + +private: + AddressbookDataPtr m_address; + AddressbookDataPtr m_copyAddress; +}; + +class SaleHelper : public QObject +{ + Q_OBJECT + Q_PROPERTY(QSharedPointer sale READ sale WRITE setSale NOTIFY saleChanged) + +public: + SaleHelper(QObject *parent = NULL); + + SalePtr salePtr() const; + void setSalePtr(const SalePtr &sale); + + QSharedPointer sale() const; + void setSale(const QSharedPointer &sale); + +signals: + void saleChanged(); + +private: + SalePtr m_sale; +}; + +namespace Ui { +class CampWizard; +} + +class CampWizard : public QWizard +{ + Q_OBJECT + +public: + explicit CampWizard(QWidget *parent = 0); + ~CampWizard(); + + void setData(const CampDataPtr &data); + +private slots: + void on_btnAdd_clicked(); + + void on_address_currentIndexChanged(int index); + + void on_btnRemove_clicked(); + + void on_btnOwner_clicked(); + + void on_groupNew_clicked(bool checked); + + void on_CampWizard_currentIdChanged(int id); + + void on_btnAddService_clicked(); + + void on_btnRemoveService_clicked(); + + void on_checkSale_clicked(); + + void applySale(); + + void on_sale_currentIndexChanged(int index); + +private: + Ui::CampWizard *ui; + CampDataPtr m_data; + ObjectBinder *m_dataBinder; + ObjectBinder *m_addrHelperBinder; + ObjectBinder *m_addressBinder; + AddressHelper *m_addrHelper; + ObjectBinder *m_saleBinder; + SaleHelper *m_saleHelper; + + AutoTableModel *m_peopleModel; + AutoTableModel *m_servicesModel; + AutoTableModel *m_itemsModel; + bool m_bindAddrCombo; + + // QWizard interface +public: + bool validateCurrentPage(); + + // QDialog interface +public slots: + void accept(); +}; + +#endif // CAMPWIZARD_H diff --git a/camp/campwizard.ui b/camp/campwizard.ui new file mode 100644 index 0000000..422df1d --- /dev/null +++ b/camp/campwizard.ui @@ -0,0 +1,845 @@ + + + CampWizard + + + Qt::ApplicationModal + + + + 0 + 0 + 948 + 684 + + + + Camp record + + + + :/icons/campPlugin.svg:/icons/campPlugin.svg + + + QWizard::ClassicStyle + + + + + + + + 0 + + + + + From + + + + + + + d. M. yyyy + + + true + + + + + + + To + + + + + + + d. M. yyyy + + + true + + + + + + + Qt::Horizontal + + + + 40 + 20 + + + + + + + + + + + People + + + + + + + 450 + 16777215 + + + + + + + Existing address + + + + + + + Add + + + + :/icons/new.svg:/icons/new.svg + + + + + + + + 0 + 0 + + + + + 0 + 0 + + + + &New address + + + true + + + false + + + + + + Title + + + + + + + + + + First name + + + + + + + + + + Last name + + + + + + + + + + Date of birth + + + + + + + d. MM. yyyy + + + true + + + + + + + ID card + + + + + + + + + + ZTP + + + + + + + Street + + + + + + + + + + House number + + + + + + + + + + ZIP code + + + + + + + + + + City + + + + + + + + + + Country + + + + + + + + 450 + 16777215 + + + + true + + + + + + + + + + + 0 + 0 + + + + true + + + + + + + + + + + 150 + 0 + + + + + 0 + + + 0 + + + 0 + + + 0 + + + + + + + + Qt::Horizontal + + + + 40 + 20 + + + + + + + + false + + + Remove + + + ... + + + + :/icons/remove.svg:/icons/remove.svg + + + + 24 + 24 + + + + true + + + + + + + false + + + Owner + + + ... + + + + :/icons/ok.svg:/icons/ok.svg + + + + 24 + 24 + + + + false + + + true + + + + + + + Qt::Horizontal + + + + 40 + 20 + + + + + + + + + + + + 380 + 0 + + + + QAbstractItemView::NoEditTriggers + + + QAbstractItemView::SelectRows + + + + + + + + + + + + + + + + + Services + + + + + + + + + + + + Qt::Vertical + + + + 20 + 40 + + + + + + + + false + + + ... + + + + :/icons/new.svg:/icons/new.svg + + + + 32 + 32 + + + + true + + + + + + + false + + + ... + + + + :/icons/remove.svg:/icons/remove.svg + + + + 32 + 32 + + + + true + + + + + + + Qt::Vertical + + + + 20 + 40 + + + + + + + + + + + + + + + + + Sale + + + + + + Apply sale + + + + + + + false + + + + + + + + + + + + + + Summary + + + + + + + 0 + + + 0 + + + 0 + + + + + From: + + + + + + + TextLabel + + + + + + + To: + + + + + + + TextLabel + + + + + + + Qt::Horizontal + + + + 40 + 20 + + + + + + + + + + + + 0 + + + 0 + + + 0 + + + + + Days: + + + + + + + TextLabel + + + + + + + Qt::Horizontal + + + + 40 + 20 + + + + + + + + + + + + 0 + + + 0 + + + 0 + + + + + Owner: + + + + + + + TextLabel + + + + + + + Qt::Horizontal + + + + 40 + 20 + + + + + + + + + + + People: + + + + + + + + + + Services: + + + + + + + + + + + + + Sale: + + + + + + + + 75 + true + + + + Total: + + + + + + + true + + + false + + + true + + + QAbstractSpinBox::NoButtons + + + 999999999.990000009536743 + + + + + + + + 75 + true + + + + true + + + false + + + true + + + QAbstractSpinBox::NoButtons + + + 999999999.990000009536743 + + + + + + + + + + + + + Print + + + + :/icons/print.svg:/icons/print.svg + + + + + + + Qt::Horizontal + + + + 40 + 20 + + + + + + + + + + + + + + + start + end + address + groupNew + title + firstName + lastName + birthDate + idCardNumber + ztp + addressStreet + addressHouseNumber + addressZipCode + addressCity + country + btnAdd + btnRemove + btnOwner + tablePeople + btnAddService + btnRemoveService + tableItems + tabPeople + tabServices + pushButton_2 + checkSale + sale + tableServices + + + + + + + diff --git a/camp/data/addressitem.cpp b/camp/data/addressitem.cpp new file mode 100644 index 0000000..a9d17ea --- /dev/null +++ b/camp/data/addressitem.cpp @@ -0,0 +1,99 @@ +#include "addressitem.h" +#include + +AddressItem::AddressItem(QObject *parent) : QObject(parent) +{ + m_id = 0; + m_price = 0; + m_owner = false; +} + +int AddressItem::id() const +{ + return m_id; +} + +void AddressItem::setId(int id) +{ + m_id = id; +} + +QString AddressItem::firstName() const +{ + return m_firstName; +} + +void AddressItem::setFirstName(const QString &firstName) +{ + m_firstName = firstName; +} + +QString AddressItem::lastName() const +{ + return m_lastName; +} + +void AddressItem::setLastName(const QString &lastName) +{ + m_lastName = lastName; +} + +QString AddressItem::address() const +{ + return m_address; +} + +void AddressItem::setAddress(const QString &address) +{ + m_address = address; +} + +QDecDouble AddressItem::price() const +{ + return TO_DEC(m_price); +} + +void AddressItem::setPrice(QDecDouble price) +{ + m_price = FROM_DEC(price); +} + +QWeakPointer AddressItem::campData() const +{ + return m_campData; +} + +void AddressItem::setCampData(const QWeakPointer &campData) +{ + m_campData = campData; +} + +PersonPricePtr AddressItem::personPrice() const +{ + return m_personPrice; +} + +void AddressItem::setPersonPrice(const PersonPricePtr &personPrice) +{ + m_personPrice = personPrice; +} + +AddressbookDataPtr AddressItem::adbItem() const +{ + return m_adbItem; +} + +void AddressItem::setAdbItem(const AddressbookDataPtr &adbItem) +{ + m_adbItem = adbItem; +} + +bool AddressItem::owner() const +{ + return m_owner; +} + +void AddressItem::setOwner(bool owner) +{ + m_owner = owner; +} diff --git a/camp/data/addressitem.h b/camp/data/addressitem.h new file mode 100644 index 0000000..c82117f --- /dev/null +++ b/camp/data/addressitem.h @@ -0,0 +1,70 @@ +#ifndef ADDRESSITEM_H +#define ADDRESSITEM_H + +#include "camp-data.h" +#include +#include +#include +#include +#include + +#include + +class CampData; + +#pragma db object +class AddressItem : public QObject +{ + Q_OBJECT + Q_PROPERTY(QString firstName READ firstName WRITE setFirstName) + Q_PROPERTY(QString lastName READ lastName WRITE setLastName) + Q_PROPERTY(QString address READ address WRITE setAddress) + Q_PROPERTY(QDecDouble price READ price WRITE setPrice) + Q_PROPERTY(bool owner READ owner WRITE setOwner) + +public: + explicit AddressItem(QObject *parent = 0); + + int id() const; + void setId(int id); + + QString firstName() const; + void setFirstName(const QString &firstName); + + QString lastName() const; + void setLastName(const QString &lastName); + + QString address() const; + void setAddress(const QString &address); + + QDecDouble price() const; + void setPrice(QDecDouble price); + + QWeakPointer campData() const; + void setCampData(const QWeakPointer &campData); + + PersonPricePtr personPrice() const; + void setPersonPrice(const PersonPricePtr &personPrice); + + AddressbookDataPtr adbItem() const; + void setAdbItem(const AddressbookDataPtr &adbItem); + + bool owner() const; + void setOwner(bool owner); + +private: + friend class odb::access; +#pragma db id auto + int m_id; + QString m_firstName; + QString m_lastName; + QString m_address; + AddressbookDataPtr m_adbItem; + int m_price; + #pragma db not_null + QWeakPointer m_campData; + PersonPricePtr m_personPrice; + bool m_owner; +}; + +#endif // ADDRESSITEM_H diff --git a/camp/data/camp-data.h b/camp/data/camp-data.h new file mode 100644 index 0000000..43ce501 --- /dev/null +++ b/camp/data/camp-data.h @@ -0,0 +1,24 @@ +#ifndef CAMP_DATA_H +#define CAMP_DATA_H + +#include + +class CampData; +class AddressItem; +class ServiceItem; +class Sale; +class PersonPrice; + +typedef QSharedPointer CampDataPtr; +typedef QSharedPointer ServiceItemPtr; +typedef QSharedPointer AddressItemPtr; +typedef QSharedPointer SalePtr; +typedef QSharedPointer PersonPricePtr; + +#include "campdata.h" +#include "addressitem.h" +#include "serviceitem.h" +#include "sale.h" +#include "personprice.h" + +#endif // CAMP_DATA_H diff --git a/camp/data/campdata.cpp b/camp/data/campdata.cpp new file mode 100644 index 0000000..fdaa25c --- /dev/null +++ b/camp/data/campdata.cpp @@ -0,0 +1,181 @@ +#include "campdata.h" +#include + +CampData::CampData(QObject *parent) : QObject(parent) +{ + m_id = 0; + m_totalPrice = 0; + m_sale = 0; + m_totalSale = 0; + m_ownerFirstame = false; +} + +int CampData::id() const +{ + return m_id; +} + +void CampData::setId(int id) +{ + m_id = id; +} + +QDate CampData::start() const +{ + return m_start; +} + +void CampData::setStart(const QDate &start) +{ + m_start = start; +} + +QDate CampData::end() const +{ + return m_end; +} + +void CampData::setEnd(const QDate &end) +{ + m_end = end; +} + +QString CampData::ownerFirstame() const +{ + return m_ownerFirstame; +} + +void CampData::setOwnerFirstame(const QString &ownerFirstame) +{ + m_ownerFirstame = ownerFirstame; +} + +QString CampData::ownerLastname() const +{ + return m_ownerLastname; +} + +void CampData::setOwnerLastname(const QString &ownerLastname) +{ + m_ownerLastname = ownerLastname; +} + +QString CampData::ownerAddress() const +{ + return m_ownerAddress; +} + +void CampData::setOwnerAddress(const QString &ownerAddress) +{ + m_ownerAddress = ownerAddress; +} + +QOdbList CampData::services() const +{ + return m_services; +} + +void CampData::setServices(const QOdbList > &services) +{ + m_services = services; +} + +void CampData::addServiceItem(ServiceItemPtr serviceItem) +{ + m_services.append(serviceItem); +} + +void CampData::removeServiceItem(ServiceItemPtr serviceItem) +{ + m_services.removeOne(serviceItem); +} + +QOdbList CampData::people() const +{ + return m_people; +} + +void CampData::setPeople(const QOdbList &people) +{ + m_people = people; +} + +void CampData::addPerson(AddressItemPtr person) +{ + m_people.append(person); +} + +void CampData::removePerson(AddressItemPtr person) +{ + m_people.removeOne(person); +} + +QDecDouble CampData::totalPrice() const +{ + return TO_DEC(m_totalPrice); +} + +void CampData::setTotalPrice(QDecDouble totalPrice) +{ + m_totalPrice = FROM_DEC(totalPrice); +} + +SeasonPtr CampData::season() const +{ + return m_season; +} + +void CampData::setSeason(const SeasonPtr &season) +{ + m_season = season; +} + +QDecDouble CampData::sale() const +{ + return TO_DEC(m_sale); +} + +void CampData::setSale(QDecDouble sale) +{ + m_sale = FROM_DEC(sale); +} + +bool CampData::fixedSale() const +{ + return m_fixedSale; +} + +void CampData::setFixedSale(bool fixedSale) +{ + m_fixedSale = fixedSale; +} + +QString CampData::numSer() const +{ + return m_numSer; +} + +void CampData::setNumSer(const QString &numSer) +{ + m_numSer = numSer; +} + +QDecDouble CampData::totalSale() const +{ + return TO_DEC(m_totalSale); +} + +void CampData::setTotalSale(QDecDouble totalSale) +{ + m_totalSale = FROM_DEC(totalSale); +} + +QDecDouble CampData::fullPrice() const +{ + return TO_DEC(m_fullPrice); +} + +void CampData::setFullPrice(QDecDouble fullPrice) +{ + m_fullPrice = FROM_DEC(fullPrice); +} diff --git a/camp/data/campdata.h b/camp/data/campdata.h new file mode 100644 index 0000000..17b6536 --- /dev/null +++ b/camp/data/campdata.h @@ -0,0 +1,102 @@ +#ifndef CAMPDATA_H +#define CAMPDATA_H + +#include "camp-data.h" +#include +#include +#include +#include +#include + +#include + +#pragma db object +class CampData : public QObject +{ + Q_OBJECT + Q_PROPERTY(QString numSer READ numSer WRITE setNumSer) + Q_PROPERTY(QDate start READ start WRITE setStart) + Q_PROPERTY(QDate end READ end WRITE setEnd) + Q_PROPERTY(QString ownerFirstame READ ownerFirstame WRITE setOwnerFirstame) + Q_PROPERTY(QString ownerLastname READ ownerLastname WRITE setOwnerLastname) + Q_PROPERTY(QString ownerAddress READ ownerAddress WRITE setOwnerAddress) + Q_PROPERTY(QDecDouble totalPrice READ totalPrice WRITE setTotalPrice) + Q_PROPERTY(QDecDouble sale READ sale WRITE setSale) + Q_PROPERTY(bool fixedSale READ fixedSale WRITE setFixedSale) + Q_PROPERTY(QDecDouble totalSale READ totalSale WRITE setTotalSale) + +public: + explicit CampData(QObject *parent = 0); + + int id() const; + void setId(int id); + + QDate start() const; + void setStart(const QDate &start); + + QDate end() const; + void setEnd(const QDate &end); + + QString ownerFirstame() const; + void setOwnerFirstame(const QString &ownerFirstame); + + QString ownerLastname() const; + void setOwnerLastname(const QString &ownerLastname); + + QString ownerAddress() const; + void setOwnerAddress(const QString &ownerAddress); + + QOdbList > services() const; + void setServices(const QOdbList > &services); + void addServiceItem(ServiceItemPtr serviceItem); + void removeServiceItem(ServiceItemPtr serviceItem); + + QOdbList people() const; + void setPeople(const QOdbList &people); + void addPerson(AddressItemPtr person); + void removePerson(AddressItemPtr person); + + QDecDouble totalPrice() const; + void setTotalPrice(QDecDouble totalPrice); + + SeasonPtr season() const; + void setSeason(const SeasonPtr &season); + + QDecDouble sale() const; + void setSale(QDecDouble sale); + + bool fixedSale() const; + void setFixedSale(bool fixedSale); + + QString numSer() const; + void setNumSer(const QString &numSer); + + QDecDouble totalSale() const; + void setTotalSale(QDecDouble totalSale); + + QDecDouble fullPrice() const; + void setFullPrice(QDecDouble fullPrice); + +private: + friend class odb::access; +#pragma db id auto + int m_id; + QString m_numSer; + QDate m_start; + QDate m_end; + QString m_ownerFirstame; + QString m_ownerLastname; + QString m_ownerAddress; + #pragma db value_not_null inverse(m_campData) + QOdbList m_services; + #pragma db value_not_null inverse(m_campData) + QOdbList m_people; + int m_fullPrice; + int m_totalPrice; + int m_sale; + int m_totalSale; + bool m_fixedSale; + SeasonPtr m_season; +}; + +#endif // CAMPDATA_H diff --git a/camp/data/personprice.cpp b/camp/data/personprice.cpp new file mode 100644 index 0000000..16bd3ae --- /dev/null +++ b/camp/data/personprice.cpp @@ -0,0 +1,71 @@ +#include "personprice.h" +#include + +PersonPrice::PersonPrice(QObject *parent) : QObject(parent) +{ + m_id = 0; + m_fromAge = 0; + m_toAge = 0; + m_price = 0; + m_active = true; +} + +int PersonPrice::id() const +{ + return m_id; +} + +void PersonPrice::setId(int id) +{ + m_id = id; +} + +QString PersonPrice::description() const +{ + return m_description; +} + +void PersonPrice::setDescription(const QString &description) +{ + m_description = description; +} + +int PersonPrice::fromAge() const +{ + return m_fromAge; +} + +void PersonPrice::setFromAge(int fromAge) +{ + m_fromAge = fromAge; +} + +int PersonPrice::toAge() const +{ + return m_toAge; +} + +void PersonPrice::setToAge(int toAge) +{ + m_toAge = toAge; +} + +QDecDouble PersonPrice::price() const +{ + return TO_DEC(m_price); +} + +void PersonPrice::setPrice(QDecDouble price) +{ + m_price = FROM_DEC(price); +} + +bool PersonPrice::active() const +{ + return m_active; +} + +void PersonPrice::setActive(bool active) +{ + m_active = active; +} diff --git a/camp/data/personprice.h b/camp/data/personprice.h new file mode 100644 index 0000000..72711c5 --- /dev/null +++ b/camp/data/personprice.h @@ -0,0 +1,50 @@ +#ifndef PERSONPRICE_H +#define PERSONPRICE_H + +#include +#include +#include + +#pragma db object +class PersonPrice : public QObject +{ + Q_OBJECT + Q_PROPERTY(QString description READ description WRITE setDescription) + Q_PROPERTY(int fromAge READ fromAge WRITE setFromAge) + Q_PROPERTY(int toAge READ toAge WRITE setToAge) + Q_PROPERTY(QDecDouble price READ price WRITE setPrice) + Q_PROPERTY(bool active READ active WRITE setActive) + +public: + explicit PersonPrice(QObject *parent = 0); + + int id() const; + void setId(int id); + + QString description() const; + void setDescription(const QString &description); + + int fromAge() const; + void setFromAge(int fromAge); + + int toAge() const; + void setToAge(int toAge); + + QDecDouble price() const; + void setPrice(QDecDouble price); + + bool active() const; + void setActive(bool active); + +private: + friend class odb::access; +#pragma db id auto + int m_id; + QString m_description; + int m_fromAge; + int m_toAge; + int m_price; + bool m_active; +}; + +#endif // PERSONPRICE_H diff --git a/camp/data/sale.cpp b/camp/data/sale.cpp new file mode 100644 index 0000000..c85dddf --- /dev/null +++ b/camp/data/sale.cpp @@ -0,0 +1,66 @@ +#include "sale.h" +#include + +Sale::Sale(QObject *parent) : ComboItem(parent) +{ + m_id = 0; + m_sale = 0; + m_fixed = false; +} + +int Sale::id() const +{ + return m_id; +} + +void Sale::setId(int id) +{ + m_id = id; +} + +QDecDouble Sale::sale() const +{ + return TO_DEC(m_sale); +} + +void Sale::setSale(QDecDouble sale) +{ + m_sale = FROM_DEC(sale); +} + +bool Sale::fixed() const +{ + return m_fixed; +} + +void Sale::setFixed(bool fixed) +{ + m_fixed = fixed; +} + +QString Sale::description() const +{ + return m_description; +} + +void Sale::setDescription(const QString &description) +{ + m_description = description; +} + +bool Sale::eq(ComboItem *other) +{ + Sale *sale = qobject_cast(other); + + if (sale == NULL) + { + return false; + } + + return this->m_id == sale->m_id && this->m_sale == sale->m_sale && this->m_fixed == sale->m_fixed; +} + +QString Sale::toString() +{ + return m_description; +} diff --git a/camp/data/sale.h b/camp/data/sale.h new file mode 100644 index 0000000..e0ae25b --- /dev/null +++ b/camp/data/sale.h @@ -0,0 +1,46 @@ +#ifndef SALE_H +#define SALE_H + +#include +#include +#include +#include + +#pragma db object +class Sale : public ComboItem +{ + Q_OBJECT + Q_PROPERTY(QString description READ description WRITE setDescription) + Q_PROPERTY(QDecDouble sale READ sale WRITE setSale) + Q_PROPERTY(bool fixed READ fixed WRITE setFixed) + +public: + explicit Sale(QObject *parent = 0); + + int id() const; + void setId(int id); + + QDecDouble sale() const; + void setSale(QDecDouble sale); + + bool fixed() const; + void setFixed(bool fixed); + + QString description() const; + void setDescription(const QString &description); + +private: + friend class odb::access; +#pragma db id auto + int m_id; + QString m_description; + int m_sale; + bool m_fixed; + + // ComboItem interface +public: + bool eq(ComboItem *other); + QString toString(); +}; + +#endif // SALE_H diff --git a/camp/data/serviceitem.cpp b/camp/data/serviceitem.cpp new file mode 100644 index 0000000..4ed2171 --- /dev/null +++ b/camp/data/serviceitem.cpp @@ -0,0 +1,122 @@ +#include "serviceitem.h" +#include + +ServiceItem::ServiceItem(QObject *parent) : QObject(parent) +{ + m_id = 0; + m_salePossible = false; + m_sale = 0; + m_price = 0; + m_totalPrice = 0; + m_type = AccService::OTHER; +} + +int ServiceItem::id() const +{ + return m_id; +} + +void ServiceItem::setId(int id) +{ + m_id = id; +} + +QString ServiceItem::name() const +{ + return m_name; +} + +void ServiceItem::setName(const QString &name) +{ + m_name = name; +} + +QString ServiceItem::code() const +{ + return m_code; +} + +void ServiceItem::setCode(const QString &code) +{ + m_code = code; +} + +QDecDouble ServiceItem::price() const +{ + return TO_DEC(m_price); +} + +void ServiceItem::setPrice(QDecDouble price) +{ + m_price = FROM_DEC(price); +} + +bool ServiceItem::salePossible() const +{ + return m_salePossible; +} + +void ServiceItem::setSalePossible(bool salePossible) +{ + m_salePossible = salePossible; +} + +AccService::ServiceType ServiceItem::type() const +{ + return m_type; +} + +void ServiceItem::setType(const AccService::ServiceType &type) +{ + m_type = type; +} + +QWeakPointer ServiceItem::campData() const +{ + return m_campData; +} + +void ServiceItem::setCampData(const QWeakPointer &campData) +{ + m_campData = campData; +} + +QString ServiceItem::description() const +{ + return m_description; +} + +void ServiceItem::setDescription(const QString &description) +{ + m_description = description; +} + +QDecDouble ServiceItem::sale() const +{ + return TO_DEC(m_sale); +} + +void ServiceItem::setSale(QDecDouble sale) +{ + m_sale = FROM_DEC(sale); +} + +QDecDouble ServiceItem::totalPrice() const +{ + return TO_DEC(m_totalPrice); +} + +void ServiceItem::setTotalPrice(QDecDouble totalPrice) +{ + m_totalPrice = FROM_DEC(totalPrice); +} + +QDecDouble ServiceItem::fullPrice() const +{ + return TO_DEC(m_fullPrice); +} + +void ServiceItem::setFullPrice(QDecDouble fullPrice) +{ + m_fullPrice = FROM_DEC(fullPrice); +} diff --git a/camp/data/serviceitem.h b/camp/data/serviceitem.h new file mode 100644 index 0000000..44b2f4a --- /dev/null +++ b/camp/data/serviceitem.h @@ -0,0 +1,81 @@ +#ifndef SREVICEITEM_H +#define SREVICEITEM_H + +#include "camp-data.h" +#include +#include +#include +#include + +#include +#include + +class CampData; + +#pragma db object +class ServiceItem : public QObject +{ + Q_OBJECT + Q_PROPERTY(QString name READ name WRITE setName) + Q_PROPERTY(QString code READ code WRITE setCode) + Q_PROPERTY(QString description READ description WRITE setDescription) + Q_PROPERTY(QDecDouble price READ price WRITE setPrice) + Q_PROPERTY(QDecDouble sale READ sale WRITE setSale) + Q_PROPERTY(QDecDouble totalPrice READ totalPrice WRITE setTotalPrice) + Q_PROPERTY(AccService::ServiceType type READ type WRITE setType) + Q_ENUMS(AccService::ServiceType) + +public: + explicit ServiceItem(QObject *parent = 0); + + int id() const; + void setId(int id); + + QString name() const; + void setName(const QString &name); + + QString code() const; + void setCode(const QString &code); + + QDecDouble price() const; + void setPrice(QDecDouble price); + + bool salePossible() const; + void setSalePossible(bool salePossible); + + AccService::ServiceType type() const; + void setType(const AccService::ServiceType &type); + + QWeakPointer campData() const; + void setCampData(const QWeakPointer &campData); + + QString description() const; + void setDescription(const QString &description); + + QDecDouble sale() const; + void setSale(QDecDouble sale); + + QDecDouble totalPrice() const; + void setTotalPrice(QDecDouble totalPrice); + + QDecDouble fullPrice() const; + void setFullPrice(QDecDouble fullPrice); + +private: + friend class odb::access; +#pragma db id auto + int m_id; + QString m_name; + QString m_code; + QString m_description; + int m_price; + int m_fullPrice; + int m_totalPrice; + int m_sale; + bool m_salePossible; + AccService::ServiceType m_type; + #pragma db not_null + QWeakPointer m_campData; +}; + +#endif // SREVICEITEM_H diff --git a/camp/icons/campPlugin.svg b/camp/icons/campPlugin.svg new file mode 100644 index 0000000..88f894a --- /dev/null +++ b/camp/icons/campPlugin.svg @@ -0,0 +1,7 @@ + \ No newline at end of file diff --git a/camp/settings/campsettings.cpp b/camp/settings/campsettings.cpp new file mode 100644 index 0000000..0178dc1 --- /dev/null +++ b/camp/settings/campsettings.cpp @@ -0,0 +1,70 @@ +#include "campsettings.h" +#include +#include + +CampSettings::CampSettings(QObject *parent) : QObject(parent) +{ + m_accFee = 0; + m_rounding = Enums::R_MATH; + m_decimalPlaces = 0; +} + +QDecDouble CampSettings::accFee() const +{ + return TO_DEC(m_accFee); +} + +void CampSettings::setAccFee(QDecDouble accFee) +{ + m_accFee = FROM_DEC(accFee); +} + +Enums::Rounding CampSettings::rounding() const +{ + return m_rounding; +} + +void CampSettings::setRounding(const Enums::Rounding &rounding) +{ + m_rounding = rounding; +} + +int CampSettings::decimalPlaces() const +{ + return m_decimalPlaces; +} + +void CampSettings::setDecimalPlaces(int decimalPlaces) +{ + m_decimalPlaces = decimalPlaces; +} + +int CampSettings::accFeeStartAge() const +{ + return m_accFeeStartAge; +} + +void CampSettings::setAccFeeStartAge(int accFeeStartAge) +{ + m_accFeeStartAge = accFeeStartAge; +} + +int CampSettings::accFeeEndAge() const +{ + return m_accFeeEndAge; +} + +void CampSettings::setAccFeeEndAge(int accFeeEndAge) +{ + m_accFeeEndAge = accFeeEndAge; +} + +QString CampSettings::accFeeText() const +{ + return m_accFeeText; +} + +void CampSettings::setAccFeeText(const QString &accFeeText) +{ + m_accFeeText = accFeeText; +} diff --git a/camp/settings/campsettings.h b/camp/settings/campsettings.h new file mode 100644 index 0000000..cf12832 --- /dev/null +++ b/camp/settings/campsettings.h @@ -0,0 +1,51 @@ +#ifndef CAMPSETTINGS_H +#define CAMPSETTINGS_H + +#include +#include +#include +#include + +class CampSettings : public QObject +{ + Q_OBJECT + Q_PROPERTY(QDecDouble accFee READ accFee WRITE setAccFee) + Q_PROPERTY(int accFeeStartAge READ accFeeStartAge WRITE setAccFeeStartAge) + Q_PROPERTY(int accFeeEndAge READ accFeeEndAge WRITE setAccFeeEndAge) + Q_PROPERTY(Enums::Rounding rounding READ rounding WRITE setRounding) + Q_PROPERTY(int decimalPlaces READ decimalPlaces WRITE setDecimalPlaces) + Q_PROPERTY(QString accFeeText READ accFeeText WRITE setAccFeeText) + +public: + explicit CampSettings(QObject *parent = 0); + + QDecDouble accFee() const; + void setAccFee(QDecDouble accFee); + + Enums::Rounding rounding() const; + void setRounding(const Enums::Rounding &rounding); + + int decimalPlaces() const; + void setDecimalPlaces(int decimalPlaces); + + int accFeeStartAge() const; + void setAccFeeStartAge(int accFeeStartAge); + + int accFeeEndAge() const; + void setAccFeeEndAge(int accFeeEndAge); + + QString accFeeText() const; + void setAccFeeText(const QString &accFeeText); + +private: + int m_accFee; + int m_accFeeStartAge; + int m_accFeeEndAge; + QString m_accFeeText; + Enums::Rounding m_rounding; + int m_decimalPlaces; +}; + +typedef QSharedPointer CampSettingsPtr; + +#endif // CAMPSETTINGS_H diff --git a/camp/settings/campsettingsform.cpp b/camp/settings/campsettingsform.cpp new file mode 100644 index 0000000..ed481cb --- /dev/null +++ b/camp/settings/campsettingsform.cpp @@ -0,0 +1,175 @@ +#include "camp-odb.hxx" +#include "campsettingsform.h" +#include "ui_campsettingsform.h" + +#include +#include +#include + +CampSettingsForm::CampSettingsForm(QWidget *parent) : + FormBinder(parent), + ui(new Ui::CampSettingsForm) +{ + ui->setupUi(this); + + m_personPriceModel = new AutoTableModel(); + m_personPriceModel->setEditableCols(QList() << 0 << 1 << 2 << 3); + m_saleModel = new AutoTableModel(); + m_saleModel->setEditableCols(QList() << 0 << 1 << 2); + + ui->tablePersonPrices->setModel(m_personPriceModel); + ui->tableSales->setModel(m_saleModel); + + ui->tablePersonPrices->horizontalHeader()->setSectionResizeMode(0, QHeaderView::Stretch); + ui->tableSales->horizontalHeader()->setSectionResizeMode(0, QHeaderView::Stretch); + + QScroller::grabGesture(ui->tablePersonPrices, QScroller::LeftMouseButtonGesture); + QScroller::grabGesture(ui->tableSales, QScroller::LeftMouseButtonGesture); + + connect(ui->tablePersonPrices->selectionModel(), &QItemSelectionModel::currentRowChanged, [this](){ + ui->btnPriceDisable->setEnabled(ui->tablePersonPrices->currentIndex().isValid()); + ui->btnPriceRemove->setEnabled(ui->tablePersonPrices->currentIndex().isValid()); + ui->btnPriceDisable->setChecked(m_personPriceModel->itemFromIndex(ui->tablePersonPrices->currentIndex())->active()); + }); + + connect(ui->tableSales->selectionModel(), &QItemSelectionModel::currentRowChanged, [this](){ + ui->btnSaleRemove->setEnabled(ui->tableSales->currentIndex().isValid()); + }); + + registerBinding(ui->accFee); + registerBinding(ui->accFeeStartAge); + registerBinding(ui->accFeeEndAge); + registerBinding(ui->decimalPlaces); + registerBinding(ui->accFeeText); + QList roundings ; + roundings << ComboData(Enums::R_NONE, tr("None")) + << ComboData(Enums::R_UP, tr("Up")) + << ComboData(Enums::R_DOWN, tr("Down")) + << ComboData(Enums::R_MATH, tr("Mathematic")); + registerBinding(ui->rounding, roundings); +} + +CampSettingsForm::~CampSettingsForm() +{ + delete ui; +} + +bool CampSettingsForm::saveRecord() +{ + bindToData(); + SettingsService srv("CAMP"); + srv.saveSettings(entity()); + + Service personSrv; + Service saleSrv; + bool ret = true; + + connect(&personSrv, &IService::dbErrorDelete, [&ret, this](QString){ + QMessageBox::critical(this, tr("Cannot delete"), tr("Price already used")); + ret = false; + }); + + foreach (PersonPricePtr p, personSrv.all()) { + bool found = false; + foreach (PersonPricePtr price, m_personPriceModel->list()) { + if (price->id() == p->id()) + { + found = true; + break; + } + } + + if (!found) + { + personSrv.erase(p); + } + } + + foreach (PersonPricePtr p, m_personPriceModel->list()) { + bool found = false; + foreach (PersonPricePtr price, personSrv.all()) { + if (price->id() == p->id()) + { + found = true; + break; + } + } + + if (!found) + { + personSrv.save(p); + } + else + { + personSrv.update(p); + } + } + + foreach (SalePtr s, saleSrv.all()) { + saleSrv.erase(s); + } + + foreach (SalePtr s, m_saleModel->list()) { + saleSrv.save(s); + } + + return ret; +} + +void CampSettingsForm::loadEntity() +{ + SettingsService srv("CAMP"); + CampSettingsPtr settings = srv.loadSettings(); + setEntity(settings); + + Service personSrv; + Service saleSrv; + + m_personPriceModel->setData(personSrv.all()); + m_saleModel->setData(saleSrv.all()); + + ui->btnPriceDisable->setEnabled(false); + ui->btnPriceRemove->setEnabled(false); + ui->btnSaleRemove->setEnabled(false); +} + +void CampSettingsForm::on_btnPriceAdd_clicked() +{ + PersonPricePtr price(new PersonPrice()); + m_personPriceModel->addRow(price); +} + +void CampSettingsForm::on_btnSaleAdd_clicked() +{ + SalePtr sale(new Sale()); + m_saleModel->addRow(sale); +} + +void CampSettingsForm::on_btnPriceRemove_clicked() +{ + m_personPriceModel->removeRowAt(ui->tablePersonPrices->currentIndex()); +} + +void CampSettingsForm::on_btnPriceDisable_clicked() +{ + PersonPricePtr price = m_personPriceModel->itemFromIndex(ui->tablePersonPrices->currentIndex()); + price->setActive(!price->active()); +} + +void CampSettingsForm::on_btnPriceFilter_clicked() +{ + Service srv; + if (ui->btnPriceFilter->isChecked()) + { + m_personPriceModel->setData(srv.all("active = 1")); + } + else + { + m_personPriceModel->setData(srv.all()); + } +} + +void CampSettingsForm::on_btnSaleRemove_clicked() +{ + m_saleModel->removeRowAt(ui->tableSales->currentIndex()); +} diff --git a/camp/settings/campsettingsform.h b/camp/settings/campsettingsform.h new file mode 100644 index 0000000..cca493e --- /dev/null +++ b/camp/settings/campsettingsform.h @@ -0,0 +1,51 @@ +#ifndef CAMPSETTINGSFORM_H +#define CAMPSETTINGSFORM_H + +#include +#include + +#include "campsettings.h" +#include "data/camp-data.h" +#include +#include + +namespace Ui { +class CampSettingsForm; +} + +class CampSettingsForm : public FormBinder +{ + Q_OBJECT + +public: + explicit CampSettingsForm(QWidget *parent = 0); + ~CampSettingsForm(); + + // IForm interface +public slots: + bool saveRecord(); + + // IForm interface +public: + void loadEntity(); + +private slots: + void on_btnPriceAdd_clicked(); + + void on_btnSaleAdd_clicked(); + + void on_btnPriceRemove_clicked(); + + void on_btnPriceDisable_clicked(); + + void on_btnPriceFilter_clicked(); + + void on_btnSaleRemove_clicked(); + +private: + Ui::CampSettingsForm *ui; + AutoTableModel *m_personPriceModel; + AutoTableModel *m_saleModel; +}; + +#endif // CAMPSETTINGSFORM_H diff --git a/camp/settings/campsettingsform.ui b/camp/settings/campsettingsform.ui new file mode 100644 index 0000000..1bc29ff --- /dev/null +++ b/camp/settings/campsettingsform.ui @@ -0,0 +1,333 @@ + + + CampSettingsForm + + + + 0 + 0 + 995 + 641 + + + + Form + + + + + + + + + Person prices + + + + + + + 0 + + + 0 + + + 0 + + + 0 + + + + + Add + + + ... + + + + :/icons/new.svg:/icons/new.svg + + + true + + + + + + + false + + + Remove + + + ... + + + + :/icons/remove.svg:/icons/remove.svg + + + true + + + + + + + false + + + Deactivate + + + ... + + + + :/icons/ok.svg:/icons/ok.svg + + + true + + + true + + + + + + + Filter active + + + ... + + + + :/icons/filter.svg:/icons/filter.svg + + + true + + + true + + + + + + + Qt::Horizontal + + + + 40 + 20 + + + + + + + + + + + + 550 + 0 + + + + + + + + + + + Sales + + + + + + + 0 + + + 0 + + + 0 + + + 0 + + + + + Add + + + ... + + + + :/icons/new.svg:/icons/new.svg + + + true + + + + + + + false + + + Remove + + + ... + + + + :/icons/remove.svg:/icons/remove.svg + + + true + + + + + + + Qt::Horizontal + + + + 40 + 20 + + + + + + + + + + + + + + + + + + + + Other settings + + + + + + Accommodation fee + + + + + + + Rounding + + + + + + + + + + Decimal places + + + + + + + QAbstractSpinBox::NoButtons + + + 0 + + + 100000.000000000000000 + + + + + + + Fee start age + + + + + + + QAbstractSpinBox::NoButtons + + + + + + + QAbstractSpinBox::NoButtons + + + 99999.990000000005239 + + + + + + + Fee end age + + + + + + + QAbstractSpinBox::NoButtons + + + + + + + Fee description + + + + + + + + + + + + + + + + diff --git a/camp/translations/camp_cs_CZ.qm b/camp/translations/camp_cs_CZ.qm new file mode 100644 index 0000000..53dcfbd Binary files /dev/null and b/camp/translations/camp_cs_CZ.qm differ diff --git a/camp/translations/camp_cs_CZ.ts b/camp/translations/camp_cs_CZ.ts new file mode 100644 index 0000000..9cb6004 --- /dev/null +++ b/camp/translations/camp_cs_CZ.ts @@ -0,0 +1,376 @@ + + + + + AddServiceDialog + + + Dialog + Služba + + + + Service name + Jméno služby + + + + Description + Popis + + + + Price + Cena + + + + CampForm + + + Form + Ubytování + + + + CampSettingsForm + + + Form + Nastavení ubytování + + + + Person prices + Ubytování lidí + + + + + Add + Nový + + + + + + + + + ... + ... + + + + + Remove + Odebrat + + + + Deactivate + Odstranit + + + + Filter active + Filtr + + + + Sales + Slevy + + + + Other settings + Ostatní nastavení + + + + Accommodation fee + Rekreační poplatek + + + + Rounding + Zaokrouhlování + + + + Decimal places + Desetinných míst + + + + Fee start age + Poplatek od věku + + + + Fee end age + Poplatek do věku + + + + Fee description + Název na dokladu + + + + None + Žádné + + + + Up + Nahoru + + + + Down + Dolu + + + + Mathematic + Matematické + + + + Cannot delete + Nelze smazat + + + + Price already used + Cena je používána + + + + CampWizard + + + Camp record + Nové ubytování + + + + From + Od + + + + + d. M. yyyy + + + + + To + Do + + + + People + Ubytovaný + + + + Existing address + Existující adresa + + + + Add + Přidat + + + New address + Nová adresa + + + + &New address + &Nová adresa + + + + Title + Titul + + + + First name + Křestní jméno + + + + Last name + Příjmení + + + + Date of birth + Datum narození + + + + d. MM. yyyy + + + + + ID card + Číslo dokladu + + + + ZTP + ZTP + + + + Street + Ulice + + + + House number + Číslo popisné + + + + ZIP code + PSČ + + + + City + Město + + + + Country + Stát + + + + Remove + Odebrat + + + + + + + ... + ... + + + + Owner + Vlastník + + + + Services + Služby + + + + Sale + Sleva + + + + Apply sale + Uplatnit slevu + + + + Summary + Shrnutí + + + + From: + Od: + + + + + + + TextLabel + + + + + To: + Do: + + + + Days: + Počet dní: + + + + Owner: + Vlastník: + + + + People: + Ubytovaní: + + + + Services: + Služby: + + + + Sale: + Sleva: + + + + Total: + Celkem: + + + + Print + Tisk + + + + + + Error + Chyba + + + + Add people. + Přidání lidí. + + + + Start date is after or equals end date. + Datum začátku je stejné nebo menší než datum konce. + + + + Add service. + Přidat službu. + + + + Database error + Chyba databáze + + + diff --git a/commodity/commodityservice.cpp b/commodity/commodityservice.cpp index 941292d..507d6db 100644 --- a/commodity/commodityservice.cpp +++ b/commodity/commodityservice.cpp @@ -35,3 +35,8 @@ ShopItemPtr CommodityService::shopItem(int itemId) CommodityDataPtr item = this->loadById(itemId); return qSharedPointerDynamicCast(item); } + +ISeller *CommodityService::seller() +{ + return NULL; +} diff --git a/commodity/commodityservice.h b/commodity/commodityservice.h index 0e10d97..028e98b 100644 --- a/commodity/commodityservice.h +++ b/commodity/commodityservice.h @@ -15,7 +15,7 @@ public: QList shopItems() override; void addedToVoucher(int itemId, int countAdded) override; virtual ShopItemPtr shopItem(int itemId) override; - + ISeller *seller() override; }; #endif // COMMODITYSERVICE_H diff --git a/config_plugin.pri b/config_plugin.pri index 2552b0c..c9f90d2 100644 --- a/config_plugin.pri +++ b/config_plugin.pri @@ -17,6 +17,7 @@ else:win32:CONFIG(debug, debug|release): LIBS += -L$$OUT_PWD/../core/debug/ -lco else:unix: LIBS += -L$$OUT_PWD/../core/ -lcore INCLUDEPATH += $$PWD/core +INCLUDEPATH += $$PWD/core/data DEPENDPATH += $$PWD/core win32:CONFIG(release, debug|release): LIBS += -L$$OUT_PWD/../qdecimal/lib/ -lqdecimal -ldecnumber diff --git a/core/autotablemodel.h b/core/autotablemodel.h index 2b12a38..1fd9aed 100644 --- a/core/autotablemodel.h +++ b/core/autotablemodel.h @@ -6,6 +6,7 @@ #include #include #include +#include #include "../qdecimal/src/QDecDouble.hh" @@ -151,7 +152,7 @@ public: const char *prop = rawEntity->metaObject()->property(column + 1).name(); std::sort(ALL(m_list), [prop, order](QSharedPointer entA, QSharedPointer entB) -> bool { - if (order == Qt::AscendingOrder) { + if (order == Qt::DescendingOrder) { return ((QObject*)entA.data())->property(prop) < ((QObject*)entB.data())->property(prop); } else { return ((QObject*)entB.data())->property(prop) < ((QObject*)entA.data())->property(prop); @@ -264,7 +265,14 @@ public: QSharedPointer entity = m_list.at(index.row()); QObject *rawEntity = (QObject*)entity.data(); - rawEntity->setProperty(rawEntity->metaObject()->property(index.column() + 1).name(), value); + QVariant val = value; + if (rawEntity->property(rawEntity->metaObject()->property(index.column() + 1).name()).canConvert()) + { + QDecDouble dec(val.toDouble()); + val = QVariant::fromValue(dec); + } + + rawEntity->setProperty(rawEntity->metaObject()->property(index.column() + 1).name(), val); } if (role == Qt::CheckStateRole) diff --git a/core/core.pro b/core/core.pro index fe4434a..7d40d7c 100644 --- a/core/core.pro +++ b/core/core.pro @@ -62,7 +62,11 @@ SOURCES += \ settings/seasonnamedialog.cpp \ reporting/report.cpp \ reporting/reportviewer.cpp \ - reporting/reportdialog.cpp + reporting/reportdialog.cpp \ + csvimporter.cpp \ + importdialog.cpp \ + importprogress.cpp \ + reporting/variablefiller.cpp HEADERS += core.h\ core_global.h \ @@ -122,7 +126,13 @@ HEADERS += core.h\ settings/seasonnamedialog.h \ reporting/report.h \ reporting/reportviewer.h \ - reporting/reportdialog.h + reporting/reportdialog.h \ + iimporter.h \ + csvimporter.h \ + iimportprogress.h \ + importdialog.h \ + importprogress.h \ + reporting/variablefiller.h unix { target.path = /usr/lib @@ -157,7 +167,9 @@ FORMS += \ settings/globalsettingsform.ui \ settings/seasonnamedialog.ui \ reporting/reportviewer.ui \ - reporting/reportdialog.ui + reporting/reportdialog.ui \ + importdialog.ui \ + importprogress.ui OTHER_FILES += \ users/metaData.json \ diff --git a/core/csvimporter.cpp b/core/csvimporter.cpp new file mode 100644 index 0000000..7c8f136 --- /dev/null +++ b/core/csvimporter.cpp @@ -0,0 +1,93 @@ +#include "csvimporter.h" +#include +#include + +CsvImporter::CsvImporter(const QMetaObject *metaObject, QObject *parent) + :QObject(parent), + IImporter(metaObject) +{ + m_parsed = false; + m_currentRec = 1; + m_error = false; +} + +void CsvImporter::setImportFile(const QString &fileName) +{ + m_fileName = fileName; +} + +int CsvImporter::recordCount() +{ + if (!m_parsed) + { + parseFile(); + } + + return m_lines.count() - 1; +} + +QSharedPointer CsvImporter::nextRecord() +{ + if (!m_parsed) + { + parseFile(); + } + + QObject *entity = m_metaObject->newInstance(); + + if (entity == NULL || m_currentRec > recordCount()) + { + ++m_currentRec; + return QSharedPointer(); + } + + QStringList props = m_header.split(m_separator); + QString line = m_lines[m_currentRec]; + QStringList values = line.split(m_separator); + + for (int i = 0; i < props.size(); i++) { + QString property = props[i]; + QString value = values[i]; + if (!entity->setProperty(property.toStdString().c_str(), QVariant(value))) + { + m_error = true; + emit noSuchProperty(property); + + ++m_currentRec; + return QSharedPointer(); + } + } + + ++m_currentRec; + + return QSharedPointer(entity); +} + +bool CsvImporter::isError() +{ + return m_error; +} + +void CsvImporter::parseFile() +{ + QFile file(m_fileName); + + if (!file.open(QFile::ReadOnly | QFile::Text)) + { + m_error = true; + emit parseError(); + return; + } + + QByteArray data = file.readAll(); + QString strData(data); + + m_lines = strData.split("\n"); + m_header = m_lines[0]; + m_parsed = true; +} + +void CsvImporter::setSeparator(const QString &separator) +{ + m_separator = separator; +} diff --git a/core/csvimporter.h b/core/csvimporter.h new file mode 100644 index 0000000..59a5489 --- /dev/null +++ b/core/csvimporter.h @@ -0,0 +1,40 @@ +#ifndef CSVIMPORTER_H +#define CSVIMPORTER_H + +#include "iimporter.h" +#include +#include + +class CORESHARED_EXPORT CsvImporter : public QObject, public IImporter +{ + Q_OBJECT + +public: + explicit CsvImporter(const QMetaObject *metaObject, QObject *parent = NULL); + + // IImporter interface +public: + void setImportFile(const QString &fileName); + int recordCount(); + QSharedPointer nextRecord(); + bool isError(); + + void setSeparator(const QString &separator); + +signals: + void parseError(); + void noSuchProperty(QString propName); + +private: + void parseFile(); + + QString m_header; + QString m_separator; + QString m_fileName; + QStringList m_lines; + bool m_parsed; + bool m_error; + int m_currentRec; +}; + +#endif // CSVIMPORTER_H diff --git a/core/enums.h b/core/enums.h index 65adf26..14dec69 100644 --- a/core/enums.h +++ b/core/enums.h @@ -9,6 +9,7 @@ class CORESHARED_EXPORT Enums : public QObject Q_OBJECT Q_ENUMS(VatType) + Q_ENUMS(Rounding) public: enum VatType @@ -19,6 +20,14 @@ public: SECOND_LOWER }; + enum Rounding + { + R_NONE, + R_UP, + R_DOWN, + R_MATH + }; + Enums() { } diff --git a/core/exprevaluator.cpp b/core/exprevaluator.cpp index 16c0686..3256ec3 100644 --- a/core/exprevaluator.cpp +++ b/core/exprevaluator.cpp @@ -63,7 +63,13 @@ bool ExprEvaluator::evaluate(QObject *object, const QString &exp) QString oper; QVariant cond; parseExpr(exp, value, oper, cond, object); - return m_operations[oper](value, cond); + + if (cond.isValid()) + { + return m_operations[oper](value, cond); + } + + return true; } } @@ -87,6 +93,10 @@ void ExprEvaluator::parseExpr(const QString &exp, QVariant &value, QString &oper QStringList expCat = exp.trimmed().split(" "); value = object->property(expCat[0].toStdString().c_str()); oper = expCat[1]; - condition = expCat[2].replace("%20", " "); + + if (expCat.size() > 2) + { + condition = expCat[2].replace("%20", " "); + } } diff --git a/core/gridform.h b/core/gridform.h index 54642b8..fd72813 100644 --- a/core/gridform.h +++ b/core/gridform.h @@ -5,6 +5,8 @@ #include #include #include +#include +#include #include "autoform.h" #include "autotablemodel.h" @@ -12,6 +14,9 @@ #include "iplugin.h" #include "igridform.h" #include "iservice.h" +#include "importdialog.h" +#include "csvimporter.h" +#include "importprogress.h" template class GridForm : public IGridForm @@ -52,8 +57,7 @@ public: connect(m_form, &IForm::recordAdded, [this](){ //service()->save(form()->entity()); - m_tableModel->addRow(form()->entity()); - emit dataChanged(); + addRow(form()->entity()); }); connect(m_form, &IForm::recordUpdated, [this](){ //service()->update(form()->entity()); @@ -81,6 +85,7 @@ public: } virtual void setTranslations(const QMap &translations) { + Q_ASSERT(m_tableModel != NULL); m_tableModel->setTranslations(translations); } @@ -111,6 +116,7 @@ public slots: connect(tableView()->horizontalHeader(), SIGNAL(sectionResized(int,int,int)), this, SLOT(widthChanged(int,int,int))); hideColumns(hide); + enableButtons(); return !m_permissionDenied; } @@ -162,10 +168,19 @@ private: bool m_serviceConnected; bool m_permissionDenied; +private slots: + // IGridForm interface protected: - void handleNewRecord() override + virtual void handleNewRecord() override { + PermissionEvaluator permEv; + if (!permEv.hasPermission(pluginId(), PERM_ADD)) + { + QMessageBox::critical(this, tr("Permission denied"), tr("You don't have permission to add new record.")); + return; + } + if (m_form == NULL) { Q_ASSERT(false); @@ -177,8 +192,15 @@ protected: m_formHandler->showForm(m_form); } - void handleEditRecord() override + virtual void handleEditRecord() override { + PermissionEvaluator permEv; + if (!permEv.hasPermission(pluginId(), PERM_EDIT)) + { + QMessageBox::critical(this, tr("Permission denied"), tr("You don't have permission to edit record.")); + return; + } + if (m_form == NULL || m_tableModel == NULL || tableView()->currentIndex().row() < 0) { Q_ASSERT(false); @@ -192,6 +214,13 @@ protected: void handleDeleteRecord() override { + PermissionEvaluator permEv; + if (!permEv.hasPermission(pluginId(), PERM_DELETE)) + { + QMessageBox::critical(this, tr("Permission denied"), tr("You don't have permission to delete record.")); + return; + } + m_permissionDenied = false; connectService(); if (m_form == NULL || m_tableModel == NULL || tableView()->currentIndex().row() < 0) @@ -214,6 +243,58 @@ protected: } } } + + virtual int currentRecordId() + { + if (tableView()->currentIndex().isValid()) + { + return m_tableModel->itemFromIndex(tableView()->currentIndex())->id(); + } + + return 0; + } + + void addRow(QSharedPointer entity) + { + m_tableModel->addRow(entity); + emit dataChanged(); + } + + void showImportButton() + { + QHBoxLayout *tbLayout = qobject_cast(this->toolbar()->layout()); + + if (tbLayout != NULL) + { + QToolButton *btnImport = new QToolButton(this->toolbar()); + btnImport->setIcon(QIcon(":/icons/import.svg")); + btnImport->setAutoRaise(true); + btnImport->setIconSize(QSize(24, 24)); + btnImport->setToolTip(tr("Import")); + tbLayout->insertWidget(tbLayout->count() - 1, btnImport); + + connect(btnImport, &QToolButton::clicked, [this](){ + ImportDialog *dlg = new ImportDialog(this); + dlg->setAttribute(Qt::WA_DeleteOnClose); + dlg->show(); + + connect(dlg, &QDialog::accepted, [this, dlg](){ + T dataObj; + CsvImporter importer(dataObj.metaObject()); + + importer.setImportFile(dlg->fileName()); + importer.setSeparator(dlg->separator()); + + ImportProgress *progress = new ImportProgress(); + progress->move(QApplication::desktop()->screen()->rect().center() - progress->rect().center()); + progress->setWindowModality(Qt::ApplicationModal); + progress->show(); + + service()->importData(&importer, progress); + }); + }); + } + } }; #endif // GRIDFORM_H diff --git a/core/icons/import.svg b/core/icons/import.svg new file mode 100644 index 0000000..60c43bb --- /dev/null +++ b/core/icons/import.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/core/igridform.cpp b/core/igridform.cpp index f98d651..319f195 100644 --- a/core/igridform.cpp +++ b/core/igridform.cpp @@ -22,10 +22,17 @@ IGridForm::IGridForm(QWidget *parent) : m_columnDialog = new ColumnDialog(this); connect(m_columnDialog, SIGNAL(accepted()), this, SLOT(columnsAccepted())); + + m_varFiller = new VariableFiller(); } IGridForm::~IGridForm() { + if (m_varFiller != NULL) + { + delete m_varFiller; + } + delete ui; } @@ -54,6 +61,21 @@ QTableView *IGridForm::tableView() return ui->tableView; } +QWidget *IGridForm::toolbar() +{ + return ui->widget; +} + +void IGridForm::setReportVarFiller(VariableFiller *filler) +{ + if (m_varFiller != NULL) + { + delete m_varFiller; + } + + m_varFiller = filler; +} + void IGridForm::hideColumns(const QList &cols) { foreach (int col, cols) { @@ -66,6 +88,11 @@ QWidget *IGridForm::filterWidget() return ui->filterWidget; } +void IGridForm::enableButtons() +{ + ui->btnNew->setEnabled(canAddRecord()); +} + void IGridForm::on_btnNew_clicked() { @@ -138,8 +165,8 @@ void IGridForm::on_tableView_clicked(const QModelIndex &) { if (ui->tableView->currentIndex().isValid()) { - ui->btnEdit->setEnabled(true); - ui->btnDelete->setEnabled(true); + ui->btnEdit->setEnabled(canEditRecord()); + ui->btnDelete->setEnabled(canDeleteRecord()); } } @@ -147,6 +174,12 @@ void IGridForm::on_btnPrint_clicked() { ReportDialog *dialog = new ReportDialog(this); dialog->setAttribute(Qt::WA_DeleteOnClose); + + if (m_varFiller != NULL) + { + m_varFiller->fillList(Context::instance().plugin(pluginId())->reports(), currentRecordId()); + } + dialog->setReports(Context::instance().plugin(pluginId())->reports()); dialog->show(); } diff --git a/core/igridform.h b/core/igridform.h index 7017afa..b733387 100644 --- a/core/igridform.h +++ b/core/igridform.h @@ -6,11 +6,13 @@ #include #include #include +#include #include "columndialog.h" #include "filterui.h" #include "defaultformhandler.h" #include "core_global.h" +#include "reporting/variablefiller.h" namespace Ui { class GridForm; @@ -27,7 +29,9 @@ public: void setPluginId(const QString &pluginId); QString pluginId(); QTableView *tableView(); + QWidget *toolbar(); virtual void setTranslations(const QMap &translations) = 0; + void setReportVarFiller(VariableFiller *filler); signals: void dataChanged(); @@ -39,8 +43,13 @@ protected: virtual void handleNewRecord() = 0; virtual void handleEditRecord() = 0; virtual void handleDeleteRecord() = 0; + virtual bool canAddRecord() { return true; } + virtual bool canEditRecord() { return true; } + virtual bool canDeleteRecord() { return true; } + virtual int currentRecordId() = 0; void hideColumns(const QList &cols); QWidget *filterWidget(); + void enableButtons(); private slots: void on_btnNew_clicked(); @@ -63,6 +72,7 @@ private: Ui::GridForm *ui; QMenu *m_contextMenu; ColumnDialog *m_columnDialog; + VariableFiller *m_varFiller; protected: FilterUi *m_filterUi; diff --git a/core/iimporter.h b/core/iimporter.h new file mode 100644 index 0000000..5326071 --- /dev/null +++ b/core/iimporter.h @@ -0,0 +1,23 @@ +#ifndef IIMPORTER_H +#define IIMPORTER_H + +#include +#include +#include +#include "core_global.h" + +class CORESHARED_EXPORT IImporter +{ +public: + explicit IImporter(const QMetaObject *metaObject) { m_metaObject = metaObject; } + + virtual void setImportFile(const QString &fileName) = 0; + virtual int recordCount() = 0; + virtual QSharedPointer nextRecord() = 0; + virtual bool isError() = 0; + +protected: + const QMetaObject *m_metaObject; +}; + +#endif // IIMPORTER_H diff --git a/core/iimportprogress.h b/core/iimportprogress.h new file mode 100644 index 0000000..49fc035 --- /dev/null +++ b/core/iimportprogress.h @@ -0,0 +1,11 @@ +#ifndef IIMPORTPROGRESS_H +#define IIMPORTPROGRESS_H + +class IImportProgress +{ +public: + virtual void updateProgress(int currentPos) = 0; + virtual bool terminate() = 0; +}; + +#endif // IIMPORTPROGRESS_H diff --git a/core/importdialog.cpp b/core/importdialog.cpp new file mode 100644 index 0000000..17c1a9d --- /dev/null +++ b/core/importdialog.cpp @@ -0,0 +1,36 @@ +#include "importdialog.h" +#include "ui_importdialog.h" +#include "importprogress.h" +#include "csvimporter.h" + +#include +#include +#include + +ImportDialog::ImportDialog(QWidget *parent) : + QDialog(parent), + ui(new Ui::ImportDialog) +{ + ui->setupUi(this); +} + +ImportDialog::~ImportDialog() +{ + delete ui; +} + +QString ImportDialog::fileName() +{ + return ui->editFile->text(); +} + +QString ImportDialog::separator() +{ + return ui->editSeparator->text(); +} + +void ImportDialog::on_btnFile_clicked() +{ + QString file = QFileDialog::getOpenFileName(this, tr("Import file"), "", tr("All Files (*.*)")); + ui->editFile->setText(file); +} diff --git a/core/importdialog.h b/core/importdialog.h new file mode 100644 index 0000000..8fe18a1 --- /dev/null +++ b/core/importdialog.h @@ -0,0 +1,30 @@ +#ifndef IMPORTDIALOG_H +#define IMPORTDIALOG_H + +#include +#include +#include "iservice.h" + +namespace Ui { +class ImportDialog; +} + +class ImportDialog : public QDialog +{ + Q_OBJECT + +public: + explicit ImportDialog(QWidget *parent = 0); + ~ImportDialog(); + + QString fileName(); + QString separator(); + +private slots: + void on_btnFile_clicked(); + +private: + Ui::ImportDialog *ui; +}; + +#endif // IMPORTDIALOG_H diff --git a/core/importdialog.ui b/core/importdialog.ui new file mode 100644 index 0000000..92c1be7 --- /dev/null +++ b/core/importdialog.ui @@ -0,0 +1,109 @@ + + + ImportDialog + + + + 0 + 0 + 454 + 115 + + + + Import data + + + + + + File + + + + + + + Separator + + + + + + + + + + Qt::Horizontal + + + QDialogButtonBox::Cancel|QDialogButtonBox::Ok + + + + + + + + 0 + + + 0 + + + 0 + + + 0 + + + + + + + + ... + + + + + + + + + + + + buttonBox + accepted() + ImportDialog + accept() + + + 248 + 254 + + + 157 + 274 + + + + + buttonBox + rejected() + ImportDialog + reject() + + + 316 + 260 + + + 286 + 274 + + + + + diff --git a/core/importprogress.cpp b/core/importprogress.cpp new file mode 100644 index 0000000..6434aef --- /dev/null +++ b/core/importprogress.cpp @@ -0,0 +1,34 @@ +#include "importprogress.h" +#include "ui_importprogress.h" + +ImportProgress::ImportProgress(QWidget *parent) : + QWidget(parent), + ui(new Ui::ImportProgress) +{ + ui->setupUi(this); + ui->progressBar->setRange(0, 100); + ui->progressBar->setValue(0); + + m_terminate = false; +} + +ImportProgress::~ImportProgress() +{ + delete ui; +} + +void ImportProgress::on_btnCancel_clicked() +{ + m_terminate = true; + this->close(); +} + +void ImportProgress::updateProgress(int currentPos) +{ + ui->progressBar->setValue(currentPos); +} + +bool ImportProgress::terminate() +{ + return m_terminate; +} diff --git a/core/importprogress.h b/core/importprogress.h new file mode 100644 index 0000000..81fd1bd --- /dev/null +++ b/core/importprogress.h @@ -0,0 +1,32 @@ +#ifndef IMPORTPROGRESS_H +#define IMPORTPROGRESS_H + +#include +#include "iimportprogress.h" + +namespace Ui { +class ImportProgress; +} + +class ImportProgress : public QWidget, public IImportProgress +{ + Q_OBJECT + +public: + explicit ImportProgress(QWidget *parent = 0); + ~ImportProgress(); + +private slots: + void on_btnCancel_clicked(); + +private: + Ui::ImportProgress *ui; + bool m_terminate; + + // IImportProgress interface +public: + void updateProgress(int currentPos); + bool terminate(); +}; + +#endif // IMPORTPROGRESS_H diff --git a/core/importprogress.ui b/core/importprogress.ui new file mode 100644 index 0000000..6af7af7 --- /dev/null +++ b/core/importprogress.ui @@ -0,0 +1,35 @@ + + + ImportProgress + + + + 0 + 0 + 400 + 165 + + + + Import progress + + + + + + 24 + + + + + + + Cenacel + + + + + + + + diff --git a/core/iplugin.h b/core/iplugin.h index e669d13..b8f620f 100644 --- a/core/iplugin.h +++ b/core/iplugin.h @@ -8,6 +8,7 @@ #include #include #include +#include #include "service.h" #include "igridform.h" @@ -51,6 +52,13 @@ public: virtual void init(const QJsonObject &metaData) = 0; virtual QWidget *ui() { + PermissionEvaluator permEv; + if (!permEv.hasPermission(pluginId(), PERM_READ)) + { + QMessageBox::critical(m_ui, QObject::tr("Permission denied"), QObject::tr("You don't have permission to open this plugin.")); + return NULL; + } + IGridForm *form = qobject_cast(m_ui); bool filled = true; @@ -75,6 +83,7 @@ public: return (Service*)m_service; } + virtual bool showIcon() { return true; } virtual QTranslator* translator() { return NULL; } virtual QIcon pluginIcon() { return QIcon(); } QMap translations() { return m_translations; } diff --git a/core/numberseriesservice.cpp b/core/numberseriesservice.cpp index ecd121c..0d7204a 100644 --- a/core/numberseriesservice.cpp +++ b/core/numberseriesservice.cpp @@ -51,3 +51,12 @@ QList > NumberSeriesService::allForSeason(QSharedPo { return all(QString("season = %1").arg(QString::number(season->id()))); } + +QString NumberSeriesService::nextStrForPlugin(QString pluginId) +{ + NumberSeriesPtr numSer = nextForPlugin(pluginId); + QString numSerStr; + numSerStr.sprintf("%s%05d", numSer->prefix().toStdString().c_str(), numSer->lastNumber()); + + return numSerStr; +} diff --git a/core/numberseriesservice.h b/core/numberseriesservice.h index d2e1ed0..e97e477 100644 --- a/core/numberseriesservice.h +++ b/core/numberseriesservice.h @@ -15,6 +15,7 @@ public: QSharedPointer forPlugin(QString pluginId); QSharedPointer nextForPlugin(QString pluginId); QList > allForSeason(QSharedPointer season); + QString nextStrForPlugin(QString pluginId); }; #endif // NUMBERSERIESSERVICE_H diff --git a/core/rc.qrc b/core/rc.qrc index 952aa60..9c37bcd 100644 --- a/core/rc.qrc +++ b/core/rc.qrc @@ -24,5 +24,6 @@ icons/zoomIn.svg icons/zoomOut.svg icons/report.svg + icons/import.svg diff --git a/core/reporting/report.cpp b/core/reporting/report.cpp index 5b3fb45..d204046 100644 --- a/core/reporting/report.cpp +++ b/core/reporting/report.cpp @@ -55,7 +55,7 @@ void Report::setVariables(const QMap &variables) m_variables = variables; } -void Report::addVariable(const QString &varName, const QString &value) +void Report::setVariable(const QString &varName, const QString &value) { m_variables[varName] = value; } diff --git a/core/reporting/report.h b/core/reporting/report.h index 4a84170..fc048e3 100644 --- a/core/reporting/report.h +++ b/core/reporting/report.h @@ -27,7 +27,7 @@ public: QMap variables() const; void setVariables(const QMap &variables); - void addVariable(const QString &varName, const QString &value); + void setVariable(const QString &varName, const QString &value); private: QString m_name; diff --git a/core/reporting/reportviewer.cpp b/core/reporting/reportviewer.cpp index 49a2fb1..2ce3a49 100644 --- a/core/reporting/reportviewer.cpp +++ b/core/reporting/reportviewer.cpp @@ -32,6 +32,10 @@ void ReportViewer::setReport(ReportPtr report) m_report->loadFromByteArray(&data); m_report->setReportFileName(reportPath); m_report->dataManager()->setReportVariable("dbPath", Context::instance().settings()->value("db/path", "").toString()); + + foreach (QString key, report->variables().keys()) { + m_report->dataManager()->setReportVariable(key, report->variables()[key]); + } } void ReportViewer::openPreview() diff --git a/core/reporting/variablefiller.cpp b/core/reporting/variablefiller.cpp new file mode 100644 index 0000000..5ae0a8f --- /dev/null +++ b/core/reporting/variablefiller.cpp @@ -0,0 +1,52 @@ +#include "variablefiller.h" +#include "../settingsservice.h" + +VariableFiller::VariableFiller() +{ +} + +VariableFiller::~VariableFiller() +{ +} + +void VariableFiller::fill(ReportPtr report, int recordId) +{ + if (m_settings.isNull()) + { + loadSettings(); + } + + QMap vars; + vars[COMPANY] = m_settings->firmName(); + vars[STREET] = m_settings->street(); + vars[HOUSE_NUMBER] = m_settings->houseNumber(); + vars[CITY] = m_settings->city(); + vars[ZIP_CODE] = m_settings->zipCode(); + vars[IC] = QString::number(m_settings->ic()); + vars[DIC] = m_settings->dic(); + vars[LOGO_PATH] = m_settings->logoPath(); + + if (recordId > 0) + { + vars[RECORD_ID] = QString::number(recordId); + } + else + { + vars[RECORD_ID] = ""; + } + + report->setVariables(vars); +} + +void VariableFiller::fillList(QList reports, int recordId) +{ + foreach (ReportPtr report, reports) { + fill(report, recordId); + } +} + +void VariableFiller::loadSettings() +{ + SettingsService srv("CORE"); + m_settings = srv.loadSettings(); +} diff --git a/core/reporting/variablefiller.h b/core/reporting/variablefiller.h new file mode 100644 index 0000000..e410747 --- /dev/null +++ b/core/reporting/variablefiller.h @@ -0,0 +1,32 @@ +#ifndef VARIABLEFILLER_H +#define VARIABLEFILLER_H + +#include "report.h" +#include "../settings/globalsettings.h" +#include "../core_global.h" + +#define COMPANY "COMPANY" +#define STREET "STREET" +#define HOUSE_NUMBER "HOUSE_NUMBER" +#define CITY "CITY" +#define ZIP_CODE "ZIP_CODE" +#define IC "IC" +#define DIC "DIC" +#define LOGO_PATH "LOGO_PATH" +#define RECORD_ID "RECORD_ID" + +class CORESHARED_EXPORT VariableFiller +{ +public: + VariableFiller(); + virtual ~VariableFiller(); + + virtual void fill(ReportPtr report, int recordId = 0); + void fillList(QList reports, int recordId = 0); + void loadSettings(); + +private: + GlobalSettingsPtr m_settings; +}; + +#endif // VARIABLEFILLER_H diff --git a/core/service.h b/core/service.h index e3267db..94c3760 100644 --- a/core/service.h +++ b/core/service.h @@ -4,6 +4,8 @@ #include #include #include +#include +#include #include #include @@ -14,6 +16,8 @@ #include "context.h" #include "iservice.h" #include "permissionevaluator.h" +#include "iimporter.h" +#include "iimportprogress.h" #include "transaction.h" @@ -178,6 +182,45 @@ public: } } + bool importData(IImporter *importer, IImportProgress *progress = NULL) { + int count = importer->recordCount(); + + if (importer->isError()) { + return false; + } + + for (int i = 0; i < count - 1; i++) { + QSharedPointer qentity = importer->nextRecord(); + + if (importer->isError() || qentity.isNull()) { + return false; + } + + QSharedPointer entity = qentity.dynamicCast(); + if (!entity.isNull()) { + this->save(entity); + } + else + { + return false; + } + + qApp->processEvents(); + + if (progress != NULL && progress->terminate()) + { + return true; + } + + if (progress != NULL) + { + progress->updateProgress(i * 100 / count); + } + } + + return true; + } + protected: bool checkPermission(const QString &permission) { if (!m_pluginId.isEmpty()) { diff --git a/core/settings/globalsettingsform.cpp b/core/settings/globalsettingsform.cpp index 06cf031..834ce6e 100644 --- a/core/settings/globalsettingsform.cpp +++ b/core/settings/globalsettingsform.cpp @@ -2,6 +2,7 @@ #include "ui_globalsettingsform.h" #include +#include #include "seasonnamedialog.h" #include "globalsettings.h" @@ -107,6 +108,11 @@ void GlobalSettingsForm::loadEntity() setEntity(settings); ui->grpVat->setEnabled(settings->vatPayer()); + if (!settings->logoPath().isEmpty()) + { + ui->lblLogo->setPixmap(QPixmap(settings->logoPath())); + } + loadSeasons(); loadNumSeries(); } @@ -155,3 +161,13 @@ void GlobalSettingsForm::on_btnNew_clicked() }); } } + +void GlobalSettingsForm::on_pushButton_clicked() +{ + QString logoPath = QFileDialog::getOpenFileName(this, tr("Select logo"), "", tr("Images (*.png *.xpm *.jpg)")); + if (!logoPath.isEmpty()) + { + entity()->setLogoPath(logoPath); + ui->lblLogo->setPixmap(QPixmap(logoPath)); + } +} diff --git a/core/settings/globalsettingsform.h b/core/settings/globalsettingsform.h index 8db5838..4c1ba7e 100644 --- a/core/settings/globalsettingsform.h +++ b/core/settings/globalsettingsform.h @@ -39,6 +39,7 @@ private slots: void on_season_currentIndexChanged(int index); void on_btnEditName_clicked(); void on_btnNew_clicked(); + void on_pushButton_clicked(); }; #endif // GLOBALSETTINGSFORM_H diff --git a/core/settings/globalsettingsform.ui b/core/settings/globalsettingsform.ui index 0907e4c..b73cfad 100644 --- a/core/settings/globalsettingsform.ui +++ b/core/settings/globalsettingsform.ui @@ -99,9 +99,24 @@ - + + + + 180 + 160 + + + + + 180 + 160 + + - Logo + + + + true diff --git a/core/settingsform.cpp b/core/settingsform.cpp index 3a32235..8009cc6 100644 --- a/core/settingsform.cpp +++ b/core/settingsform.cpp @@ -6,6 +6,8 @@ #include "iplugin.h" #include "iform.h" +#include + SettingsForm::SettingsForm(QWidget *parent) : QDialog(parent), ui(new Ui::SettingsForm) @@ -39,6 +41,12 @@ void SettingsForm::on_buttonBox_accepted() void SettingsForm::accept() { + if (!Context::instance().currentUser()->isAdmin()) + { + QMessageBox::critical(this, tr("Permission denied"), tr("You don't have permission to save settings.")); + return; + } + for (int i = 0; i < ui->tabWidget->count(); i++) { IForm *tab = qobject_cast(ui->tabWidget->widget(i)); diff --git a/core/settingsform.ui b/core/settingsform.ui index 3041060..9675024 100644 --- a/core/settingsform.ui +++ b/core/settingsform.ui @@ -9,8 +9,8 @@ 0 0 - 800 - 600 + 1000 + 700 diff --git a/core/settingsservice.h b/core/settingsservice.h index 15aa258..45dcb4b 100644 --- a/core/settingsservice.h +++ b/core/settingsservice.h @@ -8,6 +8,7 @@ #include #include +#include #include "data/system.h" #include "service.h" @@ -50,8 +51,19 @@ public: { QDecDouble dec(TO_DEC(varVal.toInt())); varVal = QVariant::fromValue(dec); + objSettings->setProperty(propName, varVal); + continue; + } + + // all other numbers are int + if (varVal.toInt() > 0) + { + objSettings->setProperty(propName, varVal.toInt()); + } + else + { + objSettings->setProperty(propName, varVal); } - objSettings->setProperty(propName, varVal); } return settingsObj; diff --git a/core/translations/core_cs_CZ.qm b/core/translations/core_cs_CZ.qm index 7ddb2a5..2507f9a 100644 Binary files a/core/translations/core_cs_CZ.qm and b/core/translations/core_cs_CZ.qm differ diff --git a/core/translations/core_cs_CZ.ts b/core/translations/core_cs_CZ.ts index 755bc6b..667ed57 100644 --- a/core/translations/core_cs_CZ.ts +++ b/core/translations/core_cs_CZ.ts @@ -4,14 +4,12 @@ AutoForm - Database error - Chyba databáze + Chyba databáze - Permission denied - Nedostatečná oprávnění + Nedostatečná oprávnění @@ -131,63 +129,63 @@ Hlavní nastavení - + Company info Informace o společnosti - + IC IČO - + VAT number DIČ - + VAT payer Plátce DPH - + VAT rates Sazby DPH - + High Vysoká - + First lower První snížená - + Second lower Druhá snížená - - + + Number series Číselné řady - + Edit name Upravit název - + Season Sezóna - + Create new Vytvořit novou @@ -223,35 +221,44 @@ - Logo Logo - + Select file Vyber soubor - + Switch season Změna sezóny - + Realy switch active season? Opravdu si přejete změnit aktivní sezónu? - + New season Nová sezóna - + Realy create new season and switch to it? Opravdu si přejete vytvořit novou sezónu a přepnout na ni? + + + Select logo + Vybrat logo + + + + Images (*.png *.xpm *.jpg) + Obrázky (*.png *.xpm *.jpg) + GridForm @@ -282,7 +289,6 @@ - Delete record Smazat záznam @@ -317,15 +323,177 @@ Vybrat sloupce - - Database error - Chyba databáze + Chyba databáze - Realy delete this record? - Opravdu si přejete smazat tento záznam? + Opravdu si přejete smazat tento záznam? + + + + ImportDialog + + + Import data + Import dat + + + + File + Soubor + + + + Separator + Oddělovač + + + + ... + ... + + + + Import file + Importovat soubor + + + + All Files (*.*) + Všechny soubory (*.*) + + + + ImportProgress + + + Import progress + Průběh importu + + + + Cenacel + Zrušit + + + + QObject + + + Permission denied + Nedostatečná oprávnění + + + + You don't have permission to open this plugin. + Nemáte oprávnění otevřít tento modul + + + + ReportDialog + + + Reports + Sestavy + + + + Print reports + Tisk sestavy + + + + Preview + Zobrazit + + + + Print + Tisk + + + + Close + Zavřít + + + + ReportViewer + + + Report + Sestava + + + + + Close + Zavřít + + + + + Print + Tisk + + + + + Export to PDF + Export do PDF + + + + + Edit + Upravit + + + + + Page up + Další strana + + + + of + z + + + + Page: + Strana: + + + + + Page down + Předchozí strana + + + + + Zoom out + Oddálit + + + + + Zoom in + Přiblížit + + + + + Fit horizontal + Vyplnit na šířku + + + + + Fit vertical + Vyplnit na výšku @@ -380,6 +548,64 @@ Settings Nastavení + + + Permission denied + Nedostatečná oprávnění + + + + You don't have permission to save settings. + Nemáte oprávnění uložit nastavení + + + + T + + + + + Database error + Chyba databáze + + + + + + + Permission denied + Nedostatečná oprávnění + + + + You don't have permission to add new record. + Nemáte oprávnění přidat nový záznam. + + + + You don't have permission to edit record. + Nemáte oprávnění upravit záznam. + + + + You don't have permission to delete record. + Nemáte oprávnění smazat záznam. + + + + Delete record + Smazat záznam + + + + Realy delete this record? + Opravdu si přejete smazat tento záznam? + + + + Import + Import + UserForm diff --git a/core/users/userform.cpp b/core/users/userform.cpp index 1b8ce7d..9631dfc 100644 --- a/core/users/userform.cpp +++ b/core/users/userform.cpp @@ -77,12 +77,12 @@ bool UserForm::bindOtherToData() } -void UserForm::on_password_textChanged(const QString &arg1) +void UserForm::on_password_textChanged(const QString &) { m_passChanged = true; } -void UserForm::on_retypePassword_textChanged(const QString &arg1) +void UserForm::on_retypePassword_textChanged(const QString &) { m_passChanged = true; } diff --git a/countryregister/countryregister.cpp b/countryregister/countryregister.cpp new file mode 100644 index 0000000..c910852 --- /dev/null +++ b/countryregister/countryregister.cpp @@ -0,0 +1,18 @@ +#include "countryregister.h" + +#include "countryregistergrid.h" + +CountryRegister::CountryRegister() +{ +} + +void CountryRegister::initServiceUi() +{ + m_service = new Service(); + m_ui = new CountryRegisterGrid(); +} + +bool CountryRegister::showIcon() +{ + return false; +} diff --git a/countryregister/countryregister.h b/countryregister/countryregister.h new file mode 100644 index 0000000..1ef0041 --- /dev/null +++ b/countryregister/countryregister.h @@ -0,0 +1,27 @@ +#ifndef COUNTRYREGISTER_H +#define COUNTRYREGISTER_H + +#include "countryregister_global.h" +#include +#include + +class COUNTRYREGISTERSHARED_EXPORT CountryRegister : public QObject, IMetaDataPlugin +{ + Q_OBJECT + + Q_PLUGIN_METADATA(IID PluginInterface_iid FILE "countryregister.json") + Q_INTERFACES(IPlugin) + +public: + CountryRegister(); + + // IMetaDataPlugin interface +protected: + void initServiceUi(); + + // IPlugin interface +public: + bool showIcon(); +}; + +#endif // COUNTRYREGISTER_H diff --git a/countryregister/countryregister.json b/countryregister/countryregister.json new file mode 100644 index 0000000..de2fbe8 --- /dev/null +++ b/countryregister/countryregister.json @@ -0,0 +1,34 @@ +{ + "id" : "COUNTRYREGISTER", + "name" : { + "default" : "Country register", + "CZ" : "Číselník zemí" + }, + "descriptoin" : { + "default" : "", + "CZ" : "" + }, + "schemaVersion" : 1, + "sql" : [ + "CREATE TABLE \"CountryData\" ( + \"id\" INTEGER NOT NULL PRIMARY KEY AUTOINCREMENT, + \"code2\" TEXT NULL, + \"code3\" TEXT NULL, + \"czechFullName\" TEXT NULL, + \"czechName\" TEXT NULL, + \"englishFullName\" TEXT NULL, + \"englishName\" TEXT NULL); + " + ], + "dependencies" : [ ], + "translations" : { + "CZ" : { + "code2" : "Dvoupísmená zkratka", + "code3" : "Trojpísmená zkratka", + "czechFullName" : "Český název", + "czechName" : "Zkrácený český název", + "englishFullName" : "Anglický název", + "englishName" : "Zkrácený anglický název" + } + } +} diff --git a/countryregister/countryregister.pro b/countryregister/countryregister.pro new file mode 100644 index 0000000..71763f2 --- /dev/null +++ b/countryregister/countryregister.pro @@ -0,0 +1,41 @@ +#------------------------------------------------- +# +# Project created by QtCreator 2017-05-03T21:05:30 +# +#------------------------------------------------- + +QT += widgets sql + +TARGET = countryregister +TEMPLATE = lib + +DEFINES += COUNTRYREGISTER_LIBRARY + +# The following define makes your compiler emit warnings if you use +# any feature of Qt which as been marked as deprecated (the exact warnings +# depend on your compiler). Please consult the documentation of the +# deprecated API in order to know how to port your code away from it. +DEFINES += QT_DEPRECATED_WARNINGS + +# You can also make your code fail to compile if you use deprecated APIs. +# In order to do so, uncomment the following line. +# You can also select to disable deprecated APIs only up to a certain version of Qt. +#DEFINES += QT_DISABLE_DEPRECATED_BEFORE=0x060000 # disables all the APIs deprecated before Qt 6.0.0 + +SOURCES += countryregister.cpp \ + countryregistergrid.cpp \ + data/countrydata.cpp + +HEADERS += countryregister.h\ + countryregister_global.h \ + countryregistergrid.h \ + data/countrydata.h + +include(../config_plugin.pri) + +ODB_FILES = countryregister/data/countrydata.h +H_DIR = $$PWD/data/*.h +include(../odb.pri) + +DISTFILES += \ + countryregister.json diff --git a/countryregister/countryregister_global.h b/countryregister/countryregister_global.h new file mode 100644 index 0000000..a5fd140 --- /dev/null +++ b/countryregister/countryregister_global.h @@ -0,0 +1,12 @@ +#ifndef COUNTRYREGISTER_GLOBAL_H +#define COUNTRYREGISTER_GLOBAL_H + +#include + +#if defined(COUNTRYREGISTER_LIBRARY) +# define COUNTRYREGISTERSHARED_EXPORT Q_DECL_EXPORT +#else +# define COUNTRYREGISTERSHARED_EXPORT Q_DECL_IMPORT +#endif + +#endif // COUNTRYREGISTER_GLOBAL_H diff --git a/countryregister/countryregistergrid.cpp b/countryregister/countryregistergrid.cpp new file mode 100644 index 0000000..1ce8902 --- /dev/null +++ b/countryregister/countryregistergrid.cpp @@ -0,0 +1,23 @@ +#include "countryregistergrid.h" +#include "countryregister-odb.hxx" + +CountryRegisterGrid::CountryRegisterGrid(QWidget *parent) : GridForm(parent) +{ + setTableModel(new AutoTableModel()); + showImportButton(); +} + +bool CountryRegisterGrid::canAddRecord() +{ + return false; +} + +bool CountryRegisterGrid::canEditRecord() +{ + return false; +} + +bool CountryRegisterGrid::canDeleteRecord() +{ + return false; +} diff --git a/countryregister/countryregistergrid.h b/countryregister/countryregistergrid.h new file mode 100644 index 0000000..d1addfd --- /dev/null +++ b/countryregister/countryregistergrid.h @@ -0,0 +1,20 @@ +#ifndef COUNTRYREGISTERGRID_H +#define COUNTRYREGISTERGRID_H + +#include +#include "data/countrydata.h" + +class CountryRegisterGrid : public GridForm +{ + +public: + explicit CountryRegisterGrid(QWidget *parent = NULL); + + // IGridForm interface +protected: + bool canAddRecord(); + bool canEditRecord(); + bool canDeleteRecord(); +}; + +#endif // COUNTRYREGISTERGRID_H diff --git a/countryregister/data/countrydata.cpp b/countryregister/data/countrydata.cpp new file mode 100644 index 0000000..147b92d --- /dev/null +++ b/countryregister/data/countrydata.cpp @@ -0,0 +1,93 @@ +#include "countrydata.h" + +CountryData::CountryData(QObject *parent) : ComboItem(parent) +{ + +} + +int CountryData::id() const +{ + return m_id; +} + +void CountryData::setId(int id) +{ + m_id = id; +} + +QString CountryData::code2() const +{ + return m_code2; +} + +void CountryData::setCode2(const QString &code2) +{ + m_code2 = code2; +} + +QString CountryData::code3() const +{ + return m_code3; +} + +void CountryData::setCode3(const QString &code3) +{ + m_code3 = code3; +} + +QString CountryData::czechFullName() const +{ + return m_czechFullName; +} + +void CountryData::setCzechFullName(const QString &czechFullName) +{ + m_czechFullName = czechFullName; +} + +QString CountryData::czechName() const +{ + return m_czechName; +} + +void CountryData::setCzechName(const QString &czechName) +{ + m_czechName = czechName; +} + +QString CountryData::englishFullName() const +{ + return m_englishFullName; +} + +void CountryData::setEnglishFullName(const QString &englishFullName) +{ + m_englishFullName = englishFullName; +} + +QString CountryData::englishName() const +{ + return m_englishName; +} + +void CountryData::setEnglishName(const QString &englishName) +{ + m_englishName = englishName; +} + +bool CountryData::eq(ComboItem *other) +{ + CountryData *obj = qobject_cast(other); + + if (obj == NULL) + { + return false; + } + + return this == obj || (m_id == obj->m_id && m_code2 == obj->m_code2 && m_code3 == obj->m_code3); +} + +QString CountryData::toString() +{ + return m_czechName + " (" + m_code3 + ")"; +} diff --git a/countryregister/data/countrydata.h b/countryregister/data/countrydata.h new file mode 100644 index 0000000..4caffb2 --- /dev/null +++ b/countryregister/data/countrydata.h @@ -0,0 +1,64 @@ +#ifndef COUNTRYDATA_H +#define COUNTRYDATA_H + +#include +#include +#include +#include +#include + +#pragma db object +class CountryData : public ComboItem +{ + Q_OBJECT + Q_PROPERTY(QString code2 READ code2 WRITE setCode2) + Q_PROPERTY(QString code3 READ code3 WRITE setCode3) + Q_PROPERTY(QString czechFullName READ czechFullName WRITE setCzechFullName) + Q_PROPERTY(QString czechName READ czechName WRITE setCzechName) + Q_PROPERTY(QString englishFullName READ englishFullName WRITE setEnglishFullName) + Q_PROPERTY(QString englishName READ englishName WRITE setEnglishName) +public: + Q_INVOKABLE explicit CountryData(QObject *parent = 0); + + int id() const; + void setId(int id); + + QString code2() const; + void setCode2(const QString &code2); + + QString code3() const; + void setCode3(const QString &code3); + + QString czechFullName() const; + void setCzechFullName(const QString &czechFullName); + + QString czechName() const; + void setCzechName(const QString &czechName); + + QString englishFullName() const; + void setEnglishFullName(const QString &englishFullName); + + QString englishName() const; + void setEnglishName(const QString &englishName); + +private: + friend class odb::access; +#pragma db id auto + int m_id; + QString m_code2; + QString m_code3; + QString m_czechFullName; + QString m_czechName; + QString m_englishFullName; + QString m_englishName; + + + // ComboItem interface +public: + bool eq(ComboItem *other); + QString toString(); +}; + +typedef QSharedPointer CountryDataPtr; + +#endif // COUNTRYDATA_H diff --git a/odb.pri b/odb.pri index 44fb68f..c778674 100644 --- a/odb.pri +++ b/odb.pri @@ -45,6 +45,7 @@ DEFINES += DATABASE_SQLITE ODB_FLAGS += -I $$[QT_INSTALL_HEADERS] ODB_FLAGS += -I $$[QT_INSTALL_HEADERS]/QtCore ODB_FLAGS += -I $$PWD/core +ODB_FLAGS += -I $$PWD/core/data ODB_FLAGS += -I $$PWD/qdecimal/src ODB_FLAGS += -I $$PWD/qdecimal/decnumber ODB_FLAGS += $$ODB_OTHER_INCLUDES diff --git a/postregister/data/postdata.cpp b/postregister/data/postdata.cpp new file mode 100644 index 0000000..5ed831c --- /dev/null +++ b/postregister/data/postdata.cpp @@ -0,0 +1,76 @@ +#include "postdata.h" + +PostData::PostData(QObject *parent) + :QObject(parent) +{ +} + +QString PostData::townPart() const +{ + return m_townPart; +} + +void PostData::setTownPart(const QString &townPart) +{ + m_townPart = townPart; +} + +int PostData::id() const +{ + return m_id; +} + +void PostData::setId(int id) +{ + m_id = id; +} + +QString PostData::zipCode() const +{ + return m_zipCode; +} + +void PostData::setZipCode(const QString &zipCode) +{ + m_zipCode = zipCode; +} + +QString PostData::postName() const +{ + return m_postName; +} + +void PostData::setPostName(const QString &postName) +{ + m_postName = postName; +} + +QString PostData::code() const +{ + return m_code; +} + +void PostData::setCode(const QString &code) +{ + m_code = code; +} + +QString PostData::township() const +{ + return m_township; +} + +void PostData::setTownship(const QString &township) +{ + m_township = township; +} + +QString PostData::town() const +{ + return m_town; +} + +void PostData::setTown(const QString &town) +{ + m_town = town; +} diff --git a/postregister/data/postdata.h b/postregister/data/postdata.h new file mode 100644 index 0000000..c7cd2b7 --- /dev/null +++ b/postregister/data/postdata.h @@ -0,0 +1,55 @@ +#ifndef POSTDATA_H +#define POSTDATA_H + +#include +#include +#include + +#pragma db object +class PostData : public QObject +{ + Q_OBJECT + Q_PROPERTY(QString townPart READ townPart WRITE setTownPart) + Q_PROPERTY(QString zipCode READ zipCode WRITE setZipCode) + Q_PROPERTY(QString postName READ postName WRITE setPostName) + Q_PROPERTY(QString code READ code WRITE setCode) + Q_PROPERTY(QString township READ township WRITE setTownship) + Q_PROPERTY(QString town READ town WRITE setTown) + +public: + Q_INVOKABLE explicit PostData(QObject *parent = NULL); + + QString townPart() const; + void setTownPart(const QString &townPart); + + int id() const; + void setId(int id); + + QString zipCode() const; + void setZipCode(const QString &zipCode); + + QString postName() const; + void setPostName(const QString &postName); + + QString code() const; + void setCode(const QString &code); + + QString township() const; + void setTownship(const QString &township); + + QString town() const; + void setTown(const QString &town); + +private: + friend class odb::access; +#pragma db id auto + int m_id; + QString m_townPart; + QString m_zipCode; + QString m_postName; + QString m_code; + QString m_township; + QString m_town; +}; + +#endif // POSTDATA_H diff --git a/postregister/postregister.cpp b/postregister/postregister.cpp new file mode 100644 index 0000000..7824837 --- /dev/null +++ b/postregister/postregister.cpp @@ -0,0 +1,18 @@ +#include "postregister.h" + +#include "postregistergrid.h" + +PostRegister::PostRegister() +{ +} + +void PostRegister::initServiceUi() +{ + m_service = new Service(); + m_ui = new PostRegisterGrid(); +} + +bool PostRegister::showIcon() +{ + return false; +} diff --git a/postregister/postregister.h b/postregister/postregister.h new file mode 100644 index 0000000..8f39bd9 --- /dev/null +++ b/postregister/postregister.h @@ -0,0 +1,26 @@ +#ifndef POSTREGISTER_H +#define POSTREGISTER_H + +#include "postregister_global.h" +#include +#include + +class POSTREGISTERSHARED_EXPORT PostRegister : public QObject, IMetaDataPlugin +{ + Q_OBJECT + + Q_PLUGIN_METADATA(IID PluginInterface_iid FILE "postregister.json") + Q_INTERFACES(IPlugin) +public: + PostRegister(); + + // IMetaDataPlugin interface +protected: + void initServiceUi(); + + // IPlugin interface +public: + bool showIcon(); +}; + +#endif // POSTREGISTER_H diff --git a/postregister/postregister.json b/postregister/postregister.json new file mode 100644 index 0000000..b96a491 --- /dev/null +++ b/postregister/postregister.json @@ -0,0 +1,34 @@ +{ + "id" : "POSTREGISTER", + "name" : { + "default" : "Post register", + "CZ" : "Číselník PSČ" + }, + "descriptoin" : { + "default" : "", + "CZ" : "" + }, + "schemaVersion" : 1, + "sql" : [ +"CREATE TABLE \"PostData\" ( + \"id\" INTEGER NOT NULL PRIMARY KEY AUTOINCREMENT, + \"townPart\" TEXT NULL, + \"zipCode\" TEXT NULL, + \"postName\" TEXT NULL, + \"code\" TEXT NULL, + \"township\" TEXT NULL, + \"town\" TEXT NULL); +" + ], + "dependencies" : [ ], + "translations" : { + "CZ" : { + "townPart" : "Část obce", + "zipCode" : "PSČ", + "postName" : "Pošta", + "code" : "Kód", + "township" : "Okres", + "town" : "Obec" + } + } +} diff --git a/postregister/postregister.pro b/postregister/postregister.pro new file mode 100644 index 0000000..264a39a --- /dev/null +++ b/postregister/postregister.pro @@ -0,0 +1,45 @@ +#------------------------------------------------- +# +# Project created by QtCreator 2017-04-21T08:14:36 +# +#------------------------------------------------- + +QT += widgets sql + +TARGET = postregister +TEMPLATE = lib + +DEFINES += POSTREGISTER_LIBRARY + +# The following define makes your compiler emit warnings if you use +# any feature of Qt which as been marked as deprecated (the exact warnings +# depend on your compiler). Please consult the documentation of the +# deprecated API in order to know how to port your code away from it. +DEFINES += QT_DEPRECATED_WARNINGS + +# You can also make your code fail to compile if you use deprecated APIs. +# In order to do so, uncomment the following line. +# You can also select to disable deprecated APIs only up to a certain version of Qt. +#DEFINES += QT_DISABLE_DEPRECATED_BEFORE=0x060000 # disables all the APIs deprecated before Qt 6.0.0 + +SOURCES += postregister.cpp \ + data/postdata.cpp \ + postregistergrid.cpp + +HEADERS += postregister.h\ + postregister_global.h \ + data/postdata.h \ + postregistergrid.h + +include(../config_plugin.pri) + +ODB_FILES = postregister/data/postdata.h +H_DIR = $$PWD/data/*.h +include(../odb.pri) + +DISTFILES += \ + postregister.json + +FORMS += + +RESOURCES += diff --git a/postregister/postregister_global.h b/postregister/postregister_global.h new file mode 100644 index 0000000..99d2cc7 --- /dev/null +++ b/postregister/postregister_global.h @@ -0,0 +1,12 @@ +#ifndef POSTREGISTER_GLOBAL_H +#define POSTREGISTER_GLOBAL_H + +#include + +#if defined(POSTREGISTER_LIBRARY) +# define POSTREGISTERSHARED_EXPORT Q_DECL_EXPORT +#else +# define POSTREGISTERSHARED_EXPORT Q_DECL_IMPORT +#endif + +#endif // POSTREGISTER_GLOBAL_H diff --git a/postregister/postregistergrid.cpp b/postregister/postregistergrid.cpp new file mode 100644 index 0000000..4a0c1fd --- /dev/null +++ b/postregister/postregistergrid.cpp @@ -0,0 +1,27 @@ +#include "postregistergrid.h" +#include +#include + +#include "postregister-odb.hxx" + +PostRegisterGrid::PostRegisterGrid(QWidget *parent) + :GridForm(parent) +{ + setTableModel(new AutoTableModel()); + showImportButton(); +} + +bool PostRegisterGrid::canAddRecord() +{ + return false; +} + +bool PostRegisterGrid::canEditRecord() +{ + return false; +} + +bool PostRegisterGrid::canDeleteRecord() +{ + return false; +} diff --git a/postregister/postregistergrid.h b/postregister/postregistergrid.h new file mode 100644 index 0000000..226de16 --- /dev/null +++ b/postregister/postregistergrid.h @@ -0,0 +1,19 @@ +#ifndef POSTREGISTERGRID_H +#define POSTREGISTERGRID_H + +#include +#include "data/postdata.h" + +class PostRegisterGrid : public GridForm +{ +public: + PostRegisterGrid(QWidget *parent = NULL); + + // IGridForm interface +protected: + bool canAddRecord(); + bool canEditRecord(); + bool canDeleteRecord(); +}; + +#endif // POSTREGISTERGRID_H diff --git a/prodejna.pro b/prodejna.pro index f5e7574..a139d4f 100644 --- a/prodejna.pro +++ b/prodejna.pro @@ -5,9 +5,11 @@ SUBDIRS += \ qdecimal \ core \ application \ - accommodation \ services \ addressbook \ shop \ - commodity + commodity \ + camp \ + postregister \ + countryregister diff --git a/qdecimal/src/QDecDouble.cc b/qdecimal/src/QDecDouble.cc index 793d576..7685c88 100644 --- a/qdecimal/src/QDecDouble.cc +++ b/qdecimal/src/QDecDouble.cc @@ -28,7 +28,10 @@ QDecDouble& QDecDouble::fromDouble(double d) #if defined(_MSC_VER) _snprintf(str, MaxStrSize, "%.*g", QDecNumDigits, d); #else + char *curLoc = setlocale(LC_NUMERIC, NULL); + setlocale(LC_NUMERIC, "C"); snprintf(str, MaxStrSize, "%.*g", QDecNumDigits, d); + setlocale(LC_NUMERIC, curLoc); #endif return fromString(str); diff --git a/services/data/accservice.h b/services/data/accservice.h index cda12f9..9b10971 100644 --- a/services/data/accservice.h +++ b/services/data/accservice.h @@ -4,6 +4,7 @@ #include #include #include +#include #include @@ -28,7 +29,7 @@ public: - enum ServiceType { CAR,TENT,OTHER }; + enum ServiceType { CAR,TENT,OTHER,ACCFEE }; int id() const; void setId(int id); @@ -68,4 +69,7 @@ private: Enums::VatType m_vatType; }; + +typedef QSharedPointer AccServicePtr; + #endif // ACCSERVICE_H diff --git a/shop/data/voucher.cpp b/shop/data/voucher.cpp index 4a8f5be..e656ccd 100644 --- a/shop/data/voucher.cpp +++ b/shop/data/voucher.cpp @@ -291,6 +291,16 @@ void Voucher::setSaveDateTime(const QDateTime &saveDateTime) m_saveDateTime = saveDateTime; } +SeasonPtr Voucher::season() const +{ + return m_season; +} + +void Voucher::setSeason(const SeasonPtr &season) +{ + m_season = season; +} + int Voucher::id() const { return m_id; diff --git a/shop/data/voucher.h b/shop/data/voucher.h index 70ee1a0..d4108ad 100644 --- a/shop/data/voucher.h +++ b/shop/data/voucher.h @@ -6,6 +6,7 @@ #include #include #include +#include #include #include @@ -143,6 +144,9 @@ public: QDateTime saveDateTime() const; void setSaveDateTime(const QDateTime &saveDateTime); + SeasonPtr season() const; + void setSeason(const SeasonPtr &season); + private: friend class odb::access; #pragma db id auto @@ -173,6 +177,7 @@ private: #pragma db value_not_null inverse(m_voucher) QOdbList > m_items; VoucherStatus m_status; + SeasonPtr m_season; }; typedef QSharedPointer VoucherPtr; diff --git a/shop/isellableservice.h b/shop/isellableservice.h index f1b3020..1125009 100644 --- a/shop/isellableservice.h +++ b/shop/isellableservice.h @@ -3,6 +3,7 @@ #include "shop_global.h" #include "shopitem.h" +#include "iseller.h" #include #include @@ -14,6 +15,7 @@ public: virtual QList shopItems() = 0; virtual ShopItemPtr shopItem(int itemId) = 0; virtual void addedToVoucher(int itemId, int countAdded) = 0; + virtual ISeller *seller() = 0; }; #endif // ISELLABLESERVICE_H diff --git a/shop/iseller.cpp b/shop/iseller.cpp new file mode 100644 index 0000000..6d75caa --- /dev/null +++ b/shop/iseller.cpp @@ -0,0 +1,9 @@ +#include "iseller.h" + +ISeller::ISeller(QObject *parent) : QObject(parent) +{ +} + +ISeller::~ISeller() +{ +} diff --git a/shop/iseller.h b/shop/iseller.h new file mode 100644 index 0000000..de3aa59 --- /dev/null +++ b/shop/iseller.h @@ -0,0 +1,22 @@ +#ifndef ISELLER_H +#define ISELLER_H + +#include + +#include "ishopitem.h" +#include "shop_global.h" + +class SHOPSHARED_EXPORT ISeller : public QObject +{ + Q_OBJECT +public: + explicit ISeller(QObject *parent = 0); + virtual ~ISeller(); + + virtual void prepareItem() = 0; + +signals: + void itemPrepared(QSharedPointer item, int count); +}; + +#endif // ISELLER_H diff --git a/shop/paydvouchersdialog.cpp b/shop/paydvouchersdialog.cpp index dee6199..72a1e09 100644 --- a/shop/paydvouchersdialog.cpp +++ b/shop/paydvouchersdialog.cpp @@ -16,11 +16,12 @@ 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->setSortingEnabled(true); ui->tableVouchers->setColumnHidden(2, true); ui->tableVouchers->setColumnHidden(6, true); ui->tableVouchers->setColumnHidden(7, true); @@ -43,6 +44,7 @@ PaydVouchersDialog::PaydVouchersDialog(QWidget *parent) : ShopService srv; m_voucherModel->setData(srv.paiedVouchers()); + ui->tableVouchers->sortByColumn(0,Qt::AscendingOrder); connect(ui->tableVouchers->selectionModel(), &QItemSelectionModel::currentRowChanged, [this, &srv](const QModelIndex ¤t, const QModelIndex &) { QSharedPointer voucher = m_voucherModel->itemFromIndex(current); diff --git a/shop/shop.cpp b/shop/shop.cpp index bc2c7b7..bc3bd85 100644 --- a/shop/shop.cpp +++ b/shop/shop.cpp @@ -24,6 +24,12 @@ QIcon Shop::pluginIcon() QWidget *Shop::ui() { QWidget *uiWidget = IPlugin::ui(); + + if (uiWidget == NULL) + { + return NULL; + } + qobject_cast(uiWidget)->loadLast(); qobject_cast(uiWidget)->fillRaceiptCombo(); qobject_cast(uiWidget)->loadButtons(); diff --git a/shop/shop.json b/shop/shop.json index f0087a2..63efeee 100644 --- a/shop/shop.json +++ b/shop/shop.json @@ -8,7 +8,7 @@ "default" : "", "CZ" : "" }, - "schemaVersion" : 5, + "schemaVersion" : 6, "sql" : [ "CREATE TABLE \"VoucherItem\" ( \"id\" INTEGER NOT NULL PRIMARY KEY AUTOINCREMENT, @@ -72,6 +72,10 @@ CREATE TABLE \"Voucher\" ( \"favButtonName\" TEXT NULL); ", "ALTER TABLE \"FavoritItem\" ADD \"shortName\" TEXT NULL; +", + +"ALTER TABLE \"Voucher\" ADD \"season\" INTEGER NULL; +UPDATE \"Voucher\" SET season = (SELECT id FROM \"Season\" WHERE active = 1); " ], "dependencies" : [ "ADDRESSBOOK" ], diff --git a/shop/shop.pro b/shop/shop.pro index 3a4210f..99f3424 100644 --- a/shop/shop.pro +++ b/shop/shop.pro @@ -9,7 +9,7 @@ QT += widgets sql TARGET = shop TEMPLATE = lib -#CONFIG += eet +CONFIG += eet DEFINES += SHOP_LIBRARY @@ -31,7 +31,8 @@ SOURCES += shop.cpp \ shopitem.cpp \ isellableservice.cpp \ data/favorititem.cpp \ - eetbatchdialog.cpp + eetbatchdialog.cpp \ + iseller.cpp HEADERS += shop.h\ shop_global.h \ @@ -55,7 +56,8 @@ HEADERS += shop.h\ shopitem.h \ data/favorititem.h \ eetbatchdialog.h \ - favbutton.h + favbutton.h \ + iseller.h include(../config_plugin.pri) @@ -63,7 +65,7 @@ OTHER_FILES += shop.json ODB_FILES = shop/data/shop-data.h H_DIR = $$PWD/data/*.h -ODB_OTHER_INCLUDES = -I $$PWD/../addressbook/data -I $$PWD/ +ODB_OTHER_INCLUDES = -I $$PWD/../addressbook/data -I $$PWD/../countryregister/data -I $$PWD/ include(../odb.pri) RESOURCES += \ @@ -89,6 +91,9 @@ INCLUDEPATH += $$PWD/../addressbook INCLUDEPATH += $$PWD/ DEPENDPATH += $$PWD/../addressbook +INCLUDEPATH += $$PWD/../countryregister/data +INCLUDEPATH += $$PWD/../countryregister + TRANSLATIONS = translations/shop_cs_CZ.ts win32 { diff --git a/shop/shopform.cpp b/shop/shopform.cpp index afe8098..ac7be7e 100644 --- a/shop/shopform.cpp +++ b/shop/shopform.cpp @@ -46,6 +46,10 @@ void ShopForm::loadLast() m_itemsModel->setTranslations(Context::instance().plugin("SHOP")->translations()); ui->actualReceipt->setModel(m_itemsModel); ui->actualReceipt->setColumnHidden(0, true); + ui->actualReceipt->setColumnHidden(3, true); + ui->actualReceipt->setColumnHidden(4, true); + ui->actualReceipt->setColumnHidden(5, true); + ui->actualReceipt->setColumnHidden(6, true); ui->actualReceipt->horizontalHeader()->setSectionResizeMode(1, QHeaderView::Stretch); } @@ -366,11 +370,31 @@ void ShopForm::addItem(QSharedPointer item, int count) createVoucher(); } - ShopService srv; - srv.addShopItem(m_voucher, item, count); - this->m_itemsModel->addRow(m_voucher->items()[m_voucher->items().count() - 1]); - connect(m_voucher->items()[m_voucher->items().count() - 1].data(), SIGNAL(countChanged(int)), this, SLOT(onCountChanged(int))); - onCountChanged(); + IPlugin *plugin = Context::instance().plugin(item->pluginId()); + IService *service = (plugin != NULL ? plugin->service() : NULL); + ISellableService *selSrv = dynamic_cast(service); + + auto addFunc = [this](QSharedPointer shopItem, int itemCount){ + ShopService srv; + srv.addShopItem(m_voucher, shopItem, itemCount); + this->m_itemsModel->addRow(m_voucher->items()[m_voucher->items().count() - 1]); + connect(m_voucher->items()[m_voucher->items().count() - 1].data(), SIGNAL(countChanged(int)), this, SLOT(onCountChanged(int))); + onCountChanged(); + }; + + if (selSrv != NULL && selSrv->seller() != NULL) + { + ISeller *seller = selSrv->seller(); + + seller->disconnect(); + connect(seller, &ISeller::itemPrepared, addFunc); + + seller->prepareItem(); + } + else + { + addFunc(item, count); + } ui->actualReceipt->scrollToBottom(); ui->commoditySearch->setFocus(); @@ -508,4 +532,5 @@ void ShopForm::on_commoditySearch_returnPressed() ShopItemPtr item = m_commodityModel->itemFromIndex(ui->commodityTable->currentIndex()); addItem(item, ui->spnCount->value()); } + ui->commoditySearch->clear(); } diff --git a/shop/shopform.ui b/shop/shopform.ui index 380e31b..9c02e50 100644 --- a/shop/shopform.ui +++ b/shop/shopform.ui @@ -153,25 +153,31 @@ + + + + + + + Receipt + + + + + + + + + + + + - - - - Receipt - - - - - - - - - @@ -376,8 +382,8 @@ - + diff --git a/shop/shopservice.cpp b/shop/shopservice.cpp index b528ae4..74dec20 100644 --- a/shop/shopservice.cpp +++ b/shop/shopservice.cpp @@ -7,6 +7,7 @@ #include #include +#include ShopService::ShopService() { @@ -101,11 +102,7 @@ void ShopService::pay(VoucherPtr voucher) Transaction tx; NumberSeriesService srvNs; - NumberSeriesPtr numSer = srvNs.nextForPlugin("SHOP"); - QString numSerStr; - numSerStr.sprintf("%s%05d", numSer->prefix().toStdString().c_str(), numSer->lastNumber()); - - voucher->setNumSer(numSerStr); + voucher->setNumSer(srvNs.nextStrForPlugin("SHOP")); voucher->setStatus(Voucher::PAID); voucher->setEetStatus(Voucher::EET_FOR_SEND); voucher->setPayDateTime(QDateTime::currentDateTime()); @@ -345,6 +342,10 @@ QDecDouble ShopService::vatRate(Enums::VatType vatType) void ShopService::saveVoucher(VoucherPtr entity) { + SeasonService seasonSrv; + SeasonPtr season = seasonSrv.active(); + entity->setSeason(season); + Transaction tr; odb::database *db = Context::instance().db(); diff --git a/shop/translations/shop_cs_CZ.qm b/shop/translations/shop_cs_CZ.qm index 39c4086..3d44de6 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 5bf6a5c..6713a77 100644 --- a/shop/translations/shop_cs_CZ.ts +++ b/shop/translations/shop_cs_CZ.ts @@ -105,7 +105,7 @@ - + Save receipt Uložit účtenku @@ -137,32 +137,32 @@ - + not entering Nevstupuje - + for send K odeslání - + error Chyba - + sent Odesláno - + Text files (*.txt) Textové soubory (*.txt) - + Error Chyba @@ -255,126 +255,112 @@ Zboží - + Count Počet - + Add Item Přidat položku - + Direct Sale Přímý prodej - + Ctrl+D - - - - - - - - - - - ... - - - - + Receipt Účtenka - + EET status: EET status: - + <a href="#eet">dfghdfg</a> - + Total: Celkem: - + 0 - + Temporary Save Dočasné uložení - + Save Uložení - + Load Načíst - + Show paid Zobrazit zaplacené - + Pay Zaplatit - - - + + + <a href="#eet">Online</a> - - - + + + <a href="#eet">Offline</a> - + << empty >> << nevybráno >> - + EET communication error. Chyba komunikace s EET - + Message from portal: Zpráva z EET portálu: - + Switch to offline? Přepnout do offline? - + EET error Chyba EET @@ -392,92 +378,97 @@ Nastavení rychlé volby - - - - - - - - - - - + ... - + Printer Tiskárna - + + Columns + Sloupců + + + + Rows + Řádků + + + + Size + Velikost + + + Output device Jméno tiskárny - + Letters per line Znaků na řádek - + Footer text Patička - + EET EET - + Activate EET Zapnout podporu EET - + Shop ID ID provozovny - + Cash register ID ID zařízení - + EET mode EET režim - + Certificate file Certifikát - + Private key password Heslo k certifikátu - + Test mode Testovací režim - + Communication with playground Testovací EET server - + Simplifyed Zjednodušený - + Standard Standartní