diff --git a/application/mainwindow.cpp b/application/mainwindow.cpp index 546ac36..a03046b 100644 --- a/application/mainwindow.cpp +++ b/application/mainwindow.cpp @@ -42,16 +42,19 @@ MainWindow::MainWindow(QWidget *parent) : int i = 0; foreach (IPlugin *plugin, Context::instance().plugins()) { - QToolButton *plugButton = new QToolButton(this); - plugButton->setText(plugin->pluginName()); - plugButton->setIcon(plugin->pluginIcon()); - plugButton->setIconSize(QSize(32, 32)); - plugButton->setAutoRaise(true); - plugButton->setToolButtonStyle(Qt::ToolButtonTextUnderIcon); - ui->navigation->layout()->addWidget(plugButton); - plugButton->setProperty(PLUGIN_INDEX, i); + if (plugin->pluginId() != "CORE") + { + QToolButton *plugButton = new QToolButton(this); + plugButton->setText(plugin->pluginName()); + plugButton->setIcon(plugin->pluginIcon()); + plugButton->setIconSize(QSize(32, 32)); + plugButton->setAutoRaise(true); + plugButton->setToolButtonStyle(Qt::ToolButtonTextUnderIcon); + ui->navigation->layout()->addWidget(plugButton); + plugButton->setProperty(PLUGIN_INDEX, i); + connect(plugButton, SIGNAL(clicked()), this, SLOT(openPlugin()) ); + } i++; - connect(plugButton, SIGNAL(clicked()), this, SLOT(openPlugin()) ); } ((QVBoxLayout*)ui->navigation->layout())->addStretch(1); diff --git a/commodity/commodityform.cpp b/commodity/commodityform.cpp index 7daacdd..f8c2cba 100644 --- a/commodity/commodityform.cpp +++ b/commodity/commodityform.cpp @@ -30,11 +30,6 @@ CommodityForm::~CommodityForm() void CommodityForm::registerCombos() { - QList ct; - Service cts; - foreach (QSharedPointer ctd , cts.all()) { - ComboData cd(ctd); - ct << cd; - } - registerBinding(ui->type,ct); + Service srvComTypes; + registerBinding(ui->type, ComboData::createComboData(srvComTypes.all())); } diff --git a/core/combodata.h b/core/combodata.h index 2e8bfff..945984a 100644 --- a/core/combodata.h +++ b/core/combodata.h @@ -20,6 +20,20 @@ public: QString label() const; void setLabel(const QString &label); + template + static QList createComboData(QList > list) { + QList data; + foreach (QSharedPointer item, list) { + QSharedPointer qObj = qSharedPointerDynamicCast(item); + if (!qObj.isNull()) + { + data << ComboData(qObj); + } + } + + return data; + } + private: QVariant m_index; QString m_label; diff --git a/core/context.cpp b/core/context.cpp index 9d6042a..c658df6 100644 --- a/core/context.cpp +++ b/core/context.cpp @@ -15,6 +15,8 @@ #include "users/users.h" #include "roles/roles.h" #include "permissionservice.h" +#include "seasonservice.h" +#include "numberseriesservice.h" Context::~Context() { @@ -50,7 +52,7 @@ void Context::loadPlugins() m_plugins.append(new Users); m_plugins.append(new Roles); - QDir pluginsDir(qApp->applicationDirPath() + "/../plugins"); + QDir pluginsDir(qApp->applicationDirPath() + PLUGIN_ROOT); foreach (QString fileName, pluginsDir.entryList(QStringList() << "*.so" << "*.dll")) { QPluginLoader pluginLoader(pluginsDir.absoluteFilePath(fileName)); @@ -86,6 +88,8 @@ void Context::openDb(const QString &path) m_dbOpened = true; checkPermissions(); + checkSeason(); + checkNumberSeries(); } void Context::destroy() @@ -121,6 +125,16 @@ Context::Context() m_dbOpened = false; } +SeasonPtr Context::currentSeason() const +{ + return m_currentSeason; +} + +void Context::setCurrentSeason(const SeasonPtr ¤tSeason) +{ + m_currentSeason = currentSeason; +} + QSharedPointer Context::currentUser() const { return m_currentUser; @@ -253,3 +267,44 @@ void Context::checkPermissions() permService.checkForAdmin(); } + +void Context::checkSeason() +{ + SeasonService srv; + QSharedPointer season = srv.active(); + + if (season.isNull()) + { + season = QSharedPointer(new Season()); + season->setName("<>"); + season->setValidFrom(QDate::currentDate()); + season->setActive(true); + srv.save(season); + } + + m_currentSeason = season; +} + +void Context::checkNumberSeries() +{ + NumberSeriesService srv; + SeasonService sesSrv; + QSharedPointer curSeason = sesSrv.active(); + + foreach (IPlugin *plugin, m_plugins) { + if (plugin->hasNumberSeries()) + { + QSharedPointer numSer = srv.forPlugin(plugin->pluginId()); + + if (numSer.isNull()) + { + numSer = QSharedPointer(new NumberSeries()); + numSer->setPrefix(plugin->numberSeriesPrefix()); + numSer->setPluginId(plugin->pluginId()); + numSer->setSeason(curSeason); + + srv.save(numSer); + } + } + } +} diff --git a/core/context.h b/core/context.h index 7d28143..2ff1eac 100644 --- a/core/context.h +++ b/core/context.h @@ -39,6 +39,11 @@ public: odb::session &session(); + SeasonPtr currentSeason() const; + void setCurrentSeason(const SeasonPtr ¤tSeason); + + void checkNumberSeries(); + private: Context(); QList m_plugins; @@ -47,6 +52,7 @@ private: bool m_dbOpened; odb::session m_session; QSharedPointer m_currentUser; + SeasonPtr m_currentSeason; QStringList m_solved; @@ -55,6 +61,7 @@ private: void solveDep(IPlugin *plugin, const QSqlDatabase &db, const QMap &schemaMap); void createSchema(IPlugin *plugin, const QSqlDatabase &db, const QMap &schemaMap); void checkPermissions(); + void checkSeason(); }; #endif // CONTEXT_H diff --git a/core/core.pro b/core/core.pro index 5b64143..8b9a091 100644 --- a/core/core.pro +++ b/core/core.pro @@ -52,7 +52,12 @@ SOURCES += \ settingsform.cpp \ settings/globalsettingsform.cpp \ permissionevaluator.cpp \ - objectbinder.cpp + objectbinder.cpp \ + data/numberseries.cpp \ + data/season.cpp \ + seasonservice.cpp \ + numberseriesservice.cpp \ + settings/seasonnamedialog.cpp HEADERS += core.h\ core_global.h \ @@ -104,7 +109,12 @@ HEADERS += core.h\ settings/globalsettingsform.h \ formbinder.h \ permissionevaluator.h \ - objectbinder.h + objectbinder.h \ + data/numberseries.h \ + data/season.h \ + seasonservice.h \ + numberseriesservice.h \ + settings/seasonnamedialog.h unix { target.path = /usr/lib @@ -138,7 +148,8 @@ FORMS += \ savefilterdialog.ui \ filterdialog.ui \ settingsform.ui \ - settings/globalsettingsform.ui + settings/globalsettingsform.ui \ + settings/seasonnamedialog.ui OTHER_FILES += \ users/metaData.json \ @@ -146,6 +157,9 @@ OTHER_FILES += \ CONFIG(debug, release|debug):DEFINES += _DEBUG +win32:CONFIG(release, debug|release):DEFINES += PLUGIN_ROOT=\\\"/plugins\\\" +else:unix:CONFIG(release, debug|release):DEFINES += PLUGIN_ROOT=\\\"/usr/lib/prodejna/plugins\\\" + win32:CONFIG(release, debug|release): LIBS += -L$$OUT_PWD/../qdecimal/lib/ -lqdecimal -ldecnumber else:win32:CONFIG(debug, debug|release): LIBS += -L$$OUT_PWD/../qdecimal/lib/ -lqdecimal -ldecnumber else:unix: LIBS += -L$$OUT_PWD/../qdecimal/lib/ -lqdecimal -ldecnumber diff --git a/core/data/core-data.h b/core/data/core-data.h index c1f1e1e..b8c8a88 100644 --- a/core/data/core-data.h +++ b/core/data/core-data.h @@ -4,11 +4,15 @@ class User; class Permission; class Role; +class Season; +class NumberSeries; #include "user.h" #include "role.h" #include "permission.h" #include "system.h" +#include "search.h" +#include "numberseries.h" #endif // COREDATA_H diff --git a/core/data/numberseries.cpp b/core/data/numberseries.cpp new file mode 100644 index 0000000..2813c82 --- /dev/null +++ b/core/data/numberseries.cpp @@ -0,0 +1,75 @@ +#include "numberseries.h" +#include "../context.h" +#include "../iplugin.h" + +NumberSeries::NumberSeries(QObject *parent) : QObject(parent) +{ + m_id = 0; + m_lastNumber = 0; +} + +int NumberSeries::id() const +{ + return m_id; +} + +void NumberSeries::setId(int id) +{ + m_id = id; +} + +QString NumberSeries::prefix() const +{ + return m_prefix; +} + +void NumberSeries::setPrefix(const QString &prefix) +{ + m_prefix = prefix; +} + +int NumberSeries::lastNumber() const +{ + return m_lastNumber; +} + +void NumberSeries::setLastNumber(int lastNumber) +{ + m_lastNumber = lastNumber; +} + +QString NumberSeries::pluginId() const +{ + return m_pluginId; +} + +void NumberSeries::setPluginId(const QString &pluginId) +{ + m_pluginId = pluginId; +} + +QSharedPointer NumberSeries::season() const +{ + return m_season; +} + +void NumberSeries::setSeason(const QSharedPointer &season) +{ + m_season = season; +} + +QString NumberSeries::seasonName() const +{ + if (!m_season.isNull()) + { + return m_season->name(); + } + + return ""; +} + +QString NumberSeries::pluginName() const +{ + IPlugin *plugin = Context::instance().plugin(m_pluginId); + return plugin != NULL ? plugin->pluginName() : ""; +} diff --git a/core/data/numberseries.h b/core/data/numberseries.h new file mode 100644 index 0000000..d97257e --- /dev/null +++ b/core/data/numberseries.h @@ -0,0 +1,55 @@ +#ifndef NUMBERSERIES_H +#define NUMBERSERIES_H + +#include +#include + +#include + +#include "season.h" +#include "core_global.h" + +#pragma db object +class CORESHARED_EXPORT NumberSeries : public QObject +{ + Q_OBJECT + Q_PROPERTY(QString prefix READ prefix WRITE setPrefix) + Q_PROPERTY(int lastNumber READ lastNumber WRITE setLastNumber) + Q_PROPERTY(QString pluginName READ pluginName) + Q_PROPERTY(QString seasonName READ seasonName) +public: + explicit NumberSeries(QObject *parent = 0); + + int id() const; + void setId(int id); + + QString prefix() const; + void setPrefix(const QString &prefix); + + int lastNumber() const; + void setLastNumber(int lastNumber); + + QString pluginId() const; + void setPluginId(const QString &pluginId); + + QSharedPointer season() const; + void setSeason(const QSharedPointer &season); + + QString seasonName() const; + + QString pluginName() const; + +private: + friend class odb::access; + +#pragma db id auto + int m_id; + QString m_prefix; + int m_lastNumber; + QString m_pluginId; + QSharedPointer m_season; +}; + +typedef QSharedPointer NumberSeriesPtr; + +#endif // NUMBERSERIES_H diff --git a/core/data/season.cpp b/core/data/season.cpp new file mode 100644 index 0000000..8328f08 --- /dev/null +++ b/core/data/season.cpp @@ -0,0 +1,58 @@ +#include "season.h" + +Season::Season(QObject *parent) + :QObject(parent) +{ + m_id = 0; + m_active = false; +} + +QString Season::name() const +{ + return m_name; +} + +void Season::setName(const QString &name) +{ + m_name = name; +} + +QDate Season::validFrom() const +{ + return m_validFrom; +} + +void Season::setValidFrom(const QDate &validFrom) +{ + m_validFrom = validFrom; +} + +QDate Season::validTo() const +{ + return m_validTo; +} + +void Season::setValidTo(const QDate &validTo) +{ + m_validTo = validTo; +} + +bool Season::active() const +{ + return m_active; +} + +void Season::setActive(bool active) +{ + m_active = active; +} + +int Season::id() const +{ + return m_id; +} + +void Season::setId(int id) +{ + m_id = id; +} diff --git a/core/data/season.h b/core/data/season.h new file mode 100644 index 0000000..e96e852 --- /dev/null +++ b/core/data/season.h @@ -0,0 +1,51 @@ +#ifndef SEASON_H +#define SEASON_H + +#include "core_global.h" + +#include +#include +#include + +#include + +#pragma db object +class CORESHARED_EXPORT Season : public QObject +{ + Q_OBJECT + Q_PROPERTY(QString name READ name WRITE setName) + Q_PROPERTY(QDate validFrom READ validFrom WRITE setValidFrom) + Q_PROPERTY(QDate validTo READ validTo WRITE setValidTo) + Q_PROPERTY(bool active READ active WRITE setActive) +public: + explicit Season(QObject *parent = 0); + + QString name() const; + void setName(const QString &name); + + QDate validFrom() const; + void setValidFrom(const QDate &validFrom); + + QDate validTo() const; + void setValidTo(const QDate &validTo); + + bool active() const; + void setActive(bool active); + + int id() const; + void setId(int id); + +private: + friend class odb::access; + +#pragma db id auto + int m_id; + QString m_name; + QDate m_validFrom; + QDate m_validTo; + bool m_active; +}; + +typedef QSharedPointer SeasonPtr; + +#endif // SEASON_H diff --git a/core/define.h b/core/define.h index 74647ff..1cee27f 100644 --- a/core/define.h +++ b/core/define.h @@ -13,5 +13,13 @@ #define TO_DEC(num) QDecDouble((double)num / DEC_MULTIPLE) #define FROM_DEC(num) num.toDouble() * DEC_MULTIPLE +#ifndef PLUGIN_ROOT + #ifdef _WIN32 + #define PLUGIN_ROOT "/../../plugins" + #else + #define PLUGIN_ROOT "/../plugins" + #endif +#endif + #endif // DEFINE_H diff --git a/core/iplugin.h b/core/iplugin.h index 018b2dc..afebb9b 100644 --- a/core/iplugin.h +++ b/core/iplugin.h @@ -77,6 +77,9 @@ public: virtual QIcon pluginIcon() { return QIcon(); } QMap translations() { return m_translations; } + virtual bool hasNumberSeries() { return false; } + virtual QString numberSeriesPrefix() { return ""; } + protected: QTranslator* translatorFrom(QString fileName) { QTranslator *trans = new QTranslator(); diff --git a/core/metaData.json b/core/metaData.json index 5821dc8..e3df92f 100644 --- a/core/metaData.json +++ b/core/metaData.json @@ -74,6 +74,23 @@ CREATE TABLE \"Permission\" ( \"createDate\" TEXT NULL, \"active\" INTEGER NOT NULL); +CREATE TABLE \"Season\" ( + \"id\" INTEGER NOT NULL PRIMARY KEY AUTOINCREMENT, + \"name\" TEXT NULL, + \"validFrom\" TEXT NULL, + \"validTo\" TEXT NULL, + \"active\" INTEGER NOT NULL); + +CREATE TABLE \"NumberSeries\" ( + \"id\" INTEGER NOT NULL PRIMARY KEY AUTOINCREMENT, + \"prefix\" TEXT NULL, + \"lastNumber\" INTEGER NOT NULL, + \"pluginId\" TEXT NULL, + \"season\" INTEGER NULL, + CONSTRAINT \"season_fk\" + FOREIGN KEY (\"season\") + REFERENCES \"Season\" (\"id\") + DEFERRABLE INITIALLY DEFERRED); " ], "dependencies" : [] } diff --git a/core/numberseriesservice.cpp b/core/numberseriesservice.cpp new file mode 100644 index 0000000..ecd121c --- /dev/null +++ b/core/numberseriesservice.cpp @@ -0,0 +1,53 @@ +#include "numberseriesservice.h" +#include "seasonservice.h" +#include "core-odb.hxx" + +NumberSeriesService::NumberSeriesService() +{ + +} + +QSharedPointer NumberSeriesService::forPluginAndSeason(QString pluginId, QSharedPointer season) +{ + QList > series = all(QString("pluginId = '%1' AND season = %2").arg(pluginId, QString::number(season->id()))); + + if (!series.isEmpty()) + { + return series[0]; + } + + return QSharedPointer(); +} + +QSharedPointer NumberSeriesService::forPlugin(QString pluginId) +{ + SeasonService sesSrv; + QSharedPointer currentSeason = sesSrv.active(); + + if (!currentSeason.isNull()) + { + return forPluginAndSeason(pluginId, currentSeason); + } + + return QSharedPointer(); +} + +QSharedPointer NumberSeriesService::nextForPlugin(QString pluginId) +{ + QSharedPointer numSer = forPlugin(pluginId); + + if (numSer.isNull()) + { + return QSharedPointer(); + } + + numSer->setLastNumber(numSer->lastNumber() + 1); + update(numSer); + + return numSer; +} + +QList > NumberSeriesService::allForSeason(QSharedPointer season) +{ + return all(QString("season = %1").arg(QString::number(season->id()))); +} diff --git a/core/numberseriesservice.h b/core/numberseriesservice.h new file mode 100644 index 0000000..d2e1ed0 --- /dev/null +++ b/core/numberseriesservice.h @@ -0,0 +1,20 @@ +#ifndef NUMBERSERIESSERVICE_H +#define NUMBERSERIESSERVICE_H + +#include "data/numberseries.h" +#include "data/season.h" +#include "service.h" +#include "core_global.h" + +class CORESHARED_EXPORT NumberSeriesService : public Service +{ +public: + NumberSeriesService(); + + QSharedPointer forPluginAndSeason(QString pluginId, QSharedPointer season); + QSharedPointer forPlugin(QString pluginId); + QSharedPointer nextForPlugin(QString pluginId); + QList > allForSeason(QSharedPointer season); +}; + +#endif // NUMBERSERIESSERVICE_H diff --git a/core/seasonservice.cpp b/core/seasonservice.cpp new file mode 100644 index 0000000..f22256b --- /dev/null +++ b/core/seasonservice.cpp @@ -0,0 +1,34 @@ +#include "seasonservice.h" + +#include "core-odb.hxx" + +SeasonService::SeasonService() +{ + +} + +QSharedPointer SeasonService::active() +{ + QList > seasons = all("active = 1"); + if (seasons.count() > 0) + { + return seasons[0]; + } + + return QSharedPointer(); +} + +void SeasonService::activate(QSharedPointer season) +{ + Transaction tx; + + foreach (QSharedPointer ses, all()) { + ses->setActive(false); + update(ses); + } + + season->setActive(true); + update(season); + + tx.commit(); +} diff --git a/core/seasonservice.h b/core/seasonservice.h new file mode 100644 index 0000000..738c8c4 --- /dev/null +++ b/core/seasonservice.h @@ -0,0 +1,18 @@ +#ifndef SEASONSERVICE_H +#define SEASONSERVICE_H + +#include + +#include "data/season.h" +#include "service.h" +#include "core_global.h" + +class CORESHARED_EXPORT SeasonService : public Service +{ +public: + SeasonService(); + QSharedPointer active(); + void activate(QSharedPointer season); +}; + +#endif // SEASONSERVICE_H diff --git a/core/settings/globalsettings.h b/core/settings/globalsettings.h index 9c782a3..14e6933 100644 --- a/core/settings/globalsettings.h +++ b/core/settings/globalsettings.h @@ -80,4 +80,6 @@ signals: public slots: }; +typedef QSharedPointer GlobalSettingsPtr; + #endif // GLOBALSETTINGS_H diff --git a/core/settings/globalsettingsform.cpp b/core/settings/globalsettingsform.cpp index 3aab7c6..06cf031 100644 --- a/core/settings/globalsettingsform.cpp +++ b/core/settings/globalsettingsform.cpp @@ -1,8 +1,14 @@ #include "globalsettingsform.h" #include "ui_globalsettingsform.h" +#include + +#include "seasonnamedialog.h" #include "globalsettings.h" #include "../settingsservice.h" +#include "../seasonservice.h" +#include "../numberseriesservice.h" +#include "core-odb.hxx" GlobalSettingsForm::GlobalSettingsForm(QWidget *parent) : FormBinder(parent), @@ -21,6 +27,10 @@ GlobalSettingsForm::GlobalSettingsForm(QWidget *parent) : registerBinding(ui->vatHigh); registerBinding(ui->vatFirstLower); registerBinding(ui->vatSecondLower); + + m_seriesModel = new AutoTableModel(this); + m_seriesModel->setEditableCols(QList() << 0); + ui->tableNumSer->setModel(m_seriesModel); } GlobalSettingsForm::~GlobalSettingsForm() @@ -28,8 +38,61 @@ GlobalSettingsForm::~GlobalSettingsForm() delete ui; } +void GlobalSettingsForm::loadSeasons() +{ + ui->season->clear(); + SeasonService srv; + m_seasons = srv.all(); + + foreach (SeasonPtr season, m_seasons) { + ui->season->addItem(season->name()); + + if (season->active()) + { + ui->season->setCurrentIndex(ui->season->count() - 1); + } + } +} + +void GlobalSettingsForm::loadNumSeries() +{ + NumberSeriesService srvNumSer; + SeasonService srvSeason; + + if (ui->season->currentIndex() >= 0) + { + SeasonPtr currentSeason = m_seasons[ui->season->currentIndex()]; + m_seriesModel->setData(srvNumSer.allForSeason(currentSeason)); + } +} + bool GlobalSettingsForm::saveRecord() { + SeasonService srvSeason; + NumberSeriesService srvNumSer; + + SeasonPtr selSeason = m_seasons[ui->season->currentIndex()]; + if (selSeason->id() != Context::instance().currentSeason()->id()) + { + if (QMessageBox::question(this, tr("Switch season"), tr("Realy switch active season?")) == QMessageBox::Yes) + { + srvSeason.activate(selSeason); + Context::instance().setCurrentSeason(selSeason); + } + else + { + return false; + } + } + + foreach (SeasonPtr season, m_seasons) { + srvSeason.update(season); + } + + foreach (NumberSeriesPtr numSer, m_seriesModel->list()) { + srvNumSer.update(numSer); + } + bindToData(); SettingsService srv("CORE"); srv.saveSettings(entity()); @@ -43,9 +106,52 @@ void GlobalSettingsForm::loadEntity() QSharedPointer settings = srv.loadSettings(); setEntity(settings); ui->grpVat->setEnabled(settings->vatPayer()); + + loadSeasons(); + loadNumSeries(); } void GlobalSettingsForm::on_vatPayer_toggled(bool checked) { ui->grpVat->setEnabled(checked); } + +void GlobalSettingsForm::on_season_currentIndexChanged(int) +{ + loadNumSeries(); +} + +void GlobalSettingsForm::on_btnEditName_clicked() +{ + SeasonPtr selSeason = m_seasons[ui->season->currentIndex()]; + SeasonNameDialog *dialog = new SeasonNameDialog(selSeason, this); + dialog->setAttribute(Qt::WA_DeleteOnClose); + dialog->show(); + + connect(dialog, &QDialog::accepted, [this](){ + this->loadSeasons(); + }); +} + +void GlobalSettingsForm::on_btnNew_clicked() +{ + if (QMessageBox::question(this, tr("New season"), tr("Realy create new season and switch to it?")) == QMessageBox::Yes) + { + SeasonPtr newSeason = SeasonPtr(new Season); + SeasonNameDialog *dialog = new SeasonNameDialog(newSeason, this); + dialog->setAttribute(Qt::WA_DeleteOnClose); + dialog->show(); + + connect(dialog, &QDialog::accepted, [this, newSeason](){ + SeasonService srv; + newSeason->setValidFrom(QDate::currentDate()); + srv.save(newSeason); + srv.activate(newSeason); + Context::instance().setCurrentSeason(newSeason); + Context::instance().checkNumberSeries(); + + this->loadSeasons(); + this->loadNumSeries(); + }); + } +} diff --git a/core/settings/globalsettingsform.h b/core/settings/globalsettingsform.h index e355b3f..8db5838 100644 --- a/core/settings/globalsettingsform.h +++ b/core/settings/globalsettingsform.h @@ -4,6 +4,8 @@ #include #include "../formbinder.h" #include "globalsettings.h" +#include "../autotablemodel.h" +#include "../data/numberseries.h" namespace Ui { class GlobalSettingsForm; @@ -19,6 +21,11 @@ public: private: Ui::GlobalSettingsForm *ui; + AutoTableModel *m_seriesModel; + QList m_seasons; + + void loadSeasons(); + void loadNumSeries(); // IForm interface public slots: @@ -29,6 +36,9 @@ public: void loadEntity() override; private slots: void on_vatPayer_toggled(bool checked); + void on_season_currentIndexChanged(int index); + void on_btnEditName_clicked(); + void on_btnNew_clicked(); }; #endif // GLOBALSETTINGSFORM_H diff --git a/core/settings/globalsettingsform.ui b/core/settings/globalsettingsform.ui index 5a87665..0907e4c 100644 --- a/core/settings/globalsettingsform.ui +++ b/core/settings/globalsettingsform.ui @@ -6,194 +6,293 @@ 0 0 - 586 - 419 + 759 + 552 Form - - - - Company info - - - - QFormLayout::AllNonFixedFieldsGrow - - - - - IC - - - - - - - - - - VAT number - - - - - - - - - - VAT payer - - - - - - - - 0 - 0 - - - - VAT rates - - - - - - High - - - - - - - QAbstractSpinBox::NoButtons - - - - - - - First lower - - - - - - - QAbstractSpinBox::NoButtons - - - - - - - Second lower - - - - - - - QAbstractSpinBox::NoButtons - - - - - - - - - - - - Contact + + + QTabWidget::North - - - - - Firm Name - - - - - - - - - - Street - - - - - - - - - - House Number - - - - - - - - - - City - - - - - - - - - - ZIP code - - - - - - - - - - - - - Logo + + QTabWidget::Rounded + + + 0 + + + Qt::ElideNone - - - - - Logo - - - - - - - Select file - - - - + + + Base settings + + + + + + Contact + + + + + + Firm Name + + + + + + + + + + Street + + + + + + + + + + House Number + + + + + + + + + + City + + + + + + + + + + ZIP code + + + + + + + + + + + + + Logo + + + + + + Logo + + + + + + + Select file + + + + + + + + + + Company info + + + + QFormLayout::AllNonFixedFieldsGrow + + + + + IC + + + + + + + + + + VAT number + + + + + + + + + + VAT payer + + + + + + + + 0 + 0 + + + + VAT rates + + + + + + High + + + + + + + QAbstractSpinBox::NoButtons + + + + + + + First lower + + + + + + + QAbstractSpinBox::NoButtons + + + + + + + Second lower + + + + + + + QAbstractSpinBox::NoButtons + + + + + + + + + + + + + + Number series + + + + + + Qt::Horizontal + + + + 40 + 20 + + + + + + + + + 120 + 0 + + + + + + + + Edit name + + + + :/icons/edit.svg:/icons/edit.svg + + + + + + + Season + + + + + + + Create new + + + + :/icons/new.svg:/icons/new.svg + + + false + + + + + + + Number series + + + + + + + + + + - + + + diff --git a/core/settings/seasonnamedialog.cpp b/core/settings/seasonnamedialog.cpp new file mode 100644 index 0000000..ef3dcd2 --- /dev/null +++ b/core/settings/seasonnamedialog.cpp @@ -0,0 +1,24 @@ +#include "seasonnamedialog.h" +#include "ui_seasonnamedialog.h" + +SeasonNameDialog::SeasonNameDialog(SeasonPtr season, QWidget *parent) : + QDialog(parent), + ui(new Ui::SeasonNameDialog) +{ + ui->setupUi(this); + + m_binder.registerBinding(ui->name); + m_binder.setData(season.data()); + m_binder.bindToUi(); +} + +SeasonNameDialog::~SeasonNameDialog() +{ + delete ui; +} + +void SeasonNameDialog::accept() +{ + m_binder.bindToData(); + QDialog::accept(); +} diff --git a/core/settings/seasonnamedialog.h b/core/settings/seasonnamedialog.h new file mode 100644 index 0000000..ffa7b31 --- /dev/null +++ b/core/settings/seasonnamedialog.h @@ -0,0 +1,30 @@ +#ifndef SEASONNAMEDIALOG_H +#define SEASONNAMEDIALOG_H + +#include + +#include "../data/season.h" +#include "../objectbinder.h" + +namespace Ui { +class SeasonNameDialog; +} + +class SeasonNameDialog : public QDialog +{ + Q_OBJECT + +public: + explicit SeasonNameDialog(SeasonPtr season, QWidget *parent = 0); + ~SeasonNameDialog(); + +private: + Ui::SeasonNameDialog *ui; + ObjectBinder m_binder; + + // QDialog interface +public slots: + void accept(); +}; + +#endif // SEASONNAMEDIALOG_H diff --git a/core/settings/seasonnamedialog.ui b/core/settings/seasonnamedialog.ui new file mode 100644 index 0000000..35e4ce9 --- /dev/null +++ b/core/settings/seasonnamedialog.ui @@ -0,0 +1,77 @@ + + + SeasonNameDialog + + + + 0 + 0 + 406 + 82 + + + + Season + + + true + + + + + + Season name + + + + + + + + + + Qt::Horizontal + + + QDialogButtonBox::Cancel|QDialogButtonBox::Ok + + + + + + + + + buttonBox + accepted() + SeasonNameDialog + accept() + + + 248 + 254 + + + 157 + 274 + + + + + buttonBox + rejected() + SeasonNameDialog + reject() + + + 316 + 260 + + + 286 + 274 + + + + + diff --git a/core/settingsform.ui b/core/settingsform.ui index f6b41b7..3041060 100644 --- a/core/settingsform.ui +++ b/core/settingsform.ui @@ -16,6 +16,10 @@ Settings + + + :/icons/settings.svg:/icons/settings.svg + @@ -39,6 +43,8 @@ - + + + diff --git a/qdecimal/common.pri b/qdecimal/common.pri index 7d8b6fa..5414398 100644 --- a/qdecimal/common.pri +++ b/qdecimal/common.pri @@ -6,7 +6,7 @@ #DEFINES += DECEXTFLAG=1 # default is 1 #DEFINES += DECLITEND=0 # default is 1 -CONFIG += debug +#CONFIG += debug if(win32) { @@ -24,7 +24,7 @@ if(win32) { #msvc2010 onwards above flags are deprecated. # Use Run-time checks for stack corruption and uninitialized var use - QMAKE_CXXFLAGS += /RTC1 + #QMAKE_CXXFLAGS += /RTC1 } } # end win32 diff --git a/shop/data/voucher.cpp b/shop/data/voucher.cpp index 55b330c..5ad6cf4 100644 --- a/shop/data/voucher.cpp +++ b/shop/data/voucher.cpp @@ -210,6 +210,26 @@ QDecDouble Voucher::VatAmountSecondLower() return TO_DEC(m_totalPriceVatSecondLower) - TO_DEC(m_priceVatSecondLower); } +QString Voucher::numSer() const +{ + return m_numSer; +} + +void Voucher::setNumSer(const QString &numSer) +{ + m_numSer = numSer; +} + +QDateTime Voucher::payDateTime() const +{ + return m_payDateTime; +} + +void Voucher::setPayDateTime(const QDateTime &payDateTime) +{ + m_payDateTime = payDateTime; +} + int Voucher::id() const { return m_id; diff --git a/shop/data/voucher.h b/shop/data/voucher.h index 6d18076..36063d1 100644 --- a/shop/data/voucher.h +++ b/shop/data/voucher.h @@ -16,6 +16,8 @@ class Voucher : public QObject { Q_OBJECT + Q_PROPERTY(QString numSer READ numSer WRITE setNumSer) + Q_PROPERTY(QDateTime payDateTime READ payDateTime WRITE setPayDateTime) Q_PROPERTY(QString name READ name WRITE setName) Q_PROPERTY(QString description READ description WRITE setDescription) Q_PROPERTY(QSharedPointer contact READ contact WRITE setContact) @@ -102,10 +104,18 @@ public: QDecDouble vatAmountFirstLower(); QDecDouble VatAmountSecondLower(); + QString numSer() const; + void setNumSer(const QString &numSer); + + QDateTime payDateTime() const; + void setPayDateTime(const QDateTime &payDateTime); + private: friend class odb::access; #pragma db id auto int m_id; + QString m_numSer; + QDateTime m_payDateTime; QString m_name; QString m_description; QSharedPointer m_contact; diff --git a/shop/icons/paied.svg b/shop/icons/paied.svg new file mode 100644 index 0000000..8f2b8d2 --- /dev/null +++ b/shop/icons/paied.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/shop/icons/pay.svg b/shop/icons/pay.svg new file mode 100644 index 0000000..305a6d0 --- /dev/null +++ b/shop/icons/pay.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/shop/icons/tempSave.svg b/shop/icons/tempSave.svg new file mode 100644 index 0000000..297aebd --- /dev/null +++ b/shop/icons/tempSave.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/shop/paydialog.cpp b/shop/paydialog.cpp new file mode 100644 index 0000000..e272503 --- /dev/null +++ b/shop/paydialog.cpp @@ -0,0 +1,33 @@ +#include "paydialog.h" +#include "ui_paydialog.h" + +PayDialog::PayDialog(QDecDouble total, QWidget *parent) : + QDialog(parent), + ui(new Ui::PayDialog) +{ + ui->setupUi(this); + m_total = total; + + ui->labelTotal->setText(QString::number(total.toDouble(), 'f', 2)); + ui->labelReturn->setText(QString::number(0, 'f', 2)); +} + +PayDialog::~PayDialog() +{ + delete ui; +} + + +void PayDialog::on_recieved_valueChanged(double value) +{ + if (value >= m_total.toDouble()) + { + ui->buttonBox->setEnabled(true); + ui->labelReturn->setText(QString::number(value - m_total.toDouble(), 'f', 2)); + } + else + { + ui->buttonBox->setEnabled(false); + ui->labelReturn->setText(QString::number(0, 'f', 2)); + } +} diff --git a/shop/paydialog.h b/shop/paydialog.h new file mode 100644 index 0000000..55d81cb --- /dev/null +++ b/shop/paydialog.h @@ -0,0 +1,28 @@ +#ifndef PAYDIALOG_H +#define PAYDIALOG_H + +#include +#include + +namespace Ui { +class PayDialog; +} + +class PayDialog : public QDialog +{ + Q_OBJECT + +public: + explicit PayDialog(QDecDouble total, QWidget *parent = 0); + ~PayDialog(); + +private slots: + + void on_recieved_valueChanged(double value); + +private: + Ui::PayDialog *ui; + QDecDouble m_total; +}; + +#endif // PAYDIALOG_H diff --git a/shop/paydialog.ui b/shop/paydialog.ui new file mode 100644 index 0000000..fd9d4a2 --- /dev/null +++ b/shop/paydialog.ui @@ -0,0 +1,158 @@ + + + PayDialog + + + + 0 + 0 + 449 + 134 + + + + Recieve money + + + true + + + + + + + 12 + 75 + true + + + + Total: + + + + + + + + 12 + 75 + true + + + + 0 + + + Qt::AlignRight|Qt::AlignTrailing|Qt::AlignVCenter + + + + + + + + 12 + + + + Recieved + + + + + + + + 12 + + + + Qt::AlignRight|Qt::AlignTrailing|Qt::AlignVCenter + + + QAbstractSpinBox::NoButtons + + + 99999.990000000005239 + + + + + + + + 12 + + + + Return + + + + + + + + 12 + + + + 0 + + + Qt::AlignRight|Qt::AlignTrailing|Qt::AlignVCenter + + + + + + + false + + + Qt::Horizontal + + + QDialogButtonBox::Ok + + + + + + + + + buttonBox + accepted() + PayDialog + accept() + + + 248 + 254 + + + 157 + 274 + + + + + buttonBox + rejected() + PayDialog + reject() + + + 316 + 260 + + + 286 + 274 + + + + + diff --git a/shop/paydvouchersdialog.cpp b/shop/paydvouchersdialog.cpp new file mode 100644 index 0000000..9bca5d7 --- /dev/null +++ b/shop/paydvouchersdialog.cpp @@ -0,0 +1,61 @@ +#include "paydvouchersdialog.h" +#include "ui_paydvouchersdialog.h" + +#include + +#include "receiptgenerator.h" +#include "shopservice.h" + +PaydVouchersDialog::PaydVouchersDialog(QWidget *parent) : + QDialog(parent), + ui(new Ui::PaydVouchersDialog) +{ + ui->setupUi(this); + + m_voucherModel = new AutoTableModel(this); + m_itemModel = new AutoTableModel(this); + + ui->tableVouchers->setModel(m_voucherModel); + ui->tableItems->setModel(m_itemModel); + + ShopService srv; + m_voucherModel->setData(srv.paiedVouchers()); + + connect(ui->tableVouchers->selectionModel(), &QItemSelectionModel::currentRowChanged, [this, &srv](const QModelIndex ¤t, const QModelIndex &) { + QSharedPointer voucher = m_voucherModel->itemFromIndex(current); + srv.loadItems(voucher); + m_itemModel->setData(voucher->items()); + ui->total->setText(QString::number(voucher->totalPrice().toDouble(), 'f', 2)); + + ui->btnPrint->setEnabled(true); + ui->btnSave->setEnabled(true); + }); +} + +PaydVouchersDialog::~PaydVouchersDialog() +{ + delete ui; +} + +void PaydVouchersDialog::on_btnPrint_clicked() +{ + QSharedPointer voucher = m_voucherModel->itemFromIndex(ui->tableVouchers->currentIndex()); + + ReceiptGenerator generator; + generator.setVoucher(voucher); + generator.print(); +} + +void PaydVouchersDialog::on_btnSave_clicked() +{ + QString fileToSave = QFileDialog::getSaveFileName(this, tr("Save receipt"), "", tr("Text files (*.txt)")); + QSharedPointer voucher = m_voucherModel->itemFromIndex(ui->tableVouchers->currentIndex()); + + if (!fileToSave.isEmpty()) + { + ReceiptGenerator generator; + generator.setVoucher(voucher); + generator.setOutputFile(fileToSave); + generator.save(); + } +} diff --git a/shop/paydvouchersdialog.h b/shop/paydvouchersdialog.h new file mode 100644 index 0000000..973e3f0 --- /dev/null +++ b/shop/paydvouchersdialog.h @@ -0,0 +1,34 @@ +#ifndef PAYDVOUCHERSDIALOG_H +#define PAYDVOUCHERSDIALOG_H + +#include +#include "data/voucher.h" + +#include + +namespace Ui { +class PaydVouchersDialog; +} + +class PaydVouchersDialog : public QDialog +{ + Q_OBJECT + +public: + explicit PaydVouchersDialog(QWidget *parent = 0); + ~PaydVouchersDialog(); + +private slots: + + void on_btnPrint_clicked(); + + void on_btnSave_clicked(); + +private: + Ui::PaydVouchersDialog *ui; + + AutoTableModel *m_voucherModel; + AutoTableModel *m_itemModel; +}; + +#endif // PAYDVOUCHERSDIALOG_H diff --git a/shop/paydvouchersdialog.ui b/shop/paydvouchersdialog.ui new file mode 100644 index 0000000..8512420 --- /dev/null +++ b/shop/paydvouchersdialog.ui @@ -0,0 +1,173 @@ + + + PaydVouchersDialog + + + + 0 + 0 + 798 + 514 + + + + Paied vouchers + + + true + + + + + + + + + false + + + Print receipt + + + + + + + :/icons/print.svg:/icons/print.svg + + + + 32 + 32 + + + + true + + + + + + + false + + + Save receipt + + + ... + + + + :/icons/save.svg:/icons/save.svg + + + + 32 + 32 + + + + true + + + + + + + Qt::Horizontal + + + + 40 + 20 + + + + + + + + + + + QAbstractItemView::SingleSelection + + + QAbstractItemView::SelectRows + + + + + + + Items + + + + + + + + + + + + + + + Qt::Horizontal + + + + 40 + 20 + + + + + + + + + 12 + + + + Total: + + + + + + + + 100 + 0 + + + + + 12 + 75 + true + + + + 0 + + + Qt::AlignRight|Qt::AlignTrailing|Qt::AlignVCenter + + + + + + + + + + + + + diff --git a/shop/receiptgenerator.cpp b/shop/receiptgenerator.cpp new file mode 100644 index 0000000..e9c9e6e --- /dev/null +++ b/shop/receiptgenerator.cpp @@ -0,0 +1,151 @@ +#include "receiptgenerator.h" +#include +#include + +#include +#include + +const QString ReceiptGenerator::DIACRITIC = "ÂâÁáÄäĂ㥹ĆćČčÇçĎďĐđÉéËëĚěĘęÍíÎîĹ弾ŁłŃńŇňÓóÖöÔôŐőŔŕŘřŚśŠšŞşŤťŢţÚúÜüŮůŰűÝýŹźŽžŻż"; +const QString ReceiptGenerator::NON_DIACRITIC = "AaAaAaAaAaCcCcCcDdDdEeEeEeEeIiIiLlLlLlNnNnOoOoOoOoRrRrSsSsSsTtTtUuUuUuUuYyZzZzZz"; + +ReceiptGenerator::ReceiptGenerator() +{ + +} + +void ReceiptGenerator::setVoucher(const QSharedPointer &voucher) +{ + m_voucher = voucher; +} + +void ReceiptGenerator::setSettings(const ShopSettingsPtr &settings) +{ + m_settings = settings; +} + +void ReceiptGenerator::save() +{ + SettingsService srvShopSettings("SHOP"); + ShopSettingsPtr shopSettings = srvShopSettings.loadSettings(); + + QString outFile = m_outputFile; + + if (outFile.isEmpty()) + { + outFile = shopSettings->output(); + } + + QFile file(outFile); + file.open(QIODevice::WriteOnly); + file.write(generate()); + file.close(); +} + +void ReceiptGenerator::print() +{ + save(); +} + +QString ReceiptGenerator::outputFile() const +{ + return m_outputFile; +} + +void ReceiptGenerator::setOutputFile(const QString &outputFile) +{ + m_outputFile = outputFile; +} + +QByteArray ReceiptGenerator::generate() +{ + QByteArray out; + + SettingsService srvGsSettings("CORE"); + SettingsService srvShopSettings("SHOP"); + + ShopSettingsPtr shopSettings = srvShopSettings.loadSettings(); + GlobalSettingsPtr gs = srvGsSettings.loadSettings(); + + out.append("\x1b\x40\x1b\x61\x01"); + out.append(prepareString(gs->firmName())); + out.append("\x0a"); + out.append(prepareString(gs->street() + " " + gs->houseNumber())); + out.append("\x0a"); + out.append(prepareString(gs->zipCode() + " " + gs->city())); + out.append("\x0a"); + out.append(prepareString("IC: " + gs->ic())); + out.append("\x0a"); + out.append("\x1b\x61\0"); + + for (int i = 0; i < shopSettings->lettersPerLine(); i++ ) + { + out.append("_"); + } + out.append("\x0a"); + + foreach (QSharedPointer item, m_voucher->items()) { + QString name = item->name(); + QString price = QString::number(item->price().toDouble(), 'f', 2); + + int numSpaces = 0; + if ((name.length() + price.length()) < shopSettings->lettersPerLine()) + { + numSpaces = shopSettings->lettersPerLine() - (name.length() + price.length()); + out.append(prepareString(name)); + } + else + { + numSpaces = shopSettings->lettersPerLine() - (name.length() + price.length()); + out.append(prepareString(name)); + out.append("\x0a"); + } + + for (int i = 0; i < numSpaces; i++) + { + out.append(" "); + } + out.append(prepareString(price)); + out.append("\x0a"); + } + + for (int i = 0; i < shopSettings->lettersPerLine(); i++ ) + { + out.append("_"); + } + out.append("\x0a"); + + char printMode = 8 | 16 ; + out.append("\x1b\x21"); + out.append(printMode); + out.append("Celekem:"); + + QString totalPrice = QString::number(m_voucher->totalPrice().toDouble(), 'f', 2); + int numSpaces = shopSettings->lettersPerLine() - (8 * 2 + totalPrice.length() * 2); + for (int i = 0; i < numSpaces; i++) + { + out.append(" "); + } + + out.append(prepareString(totalPrice)); + out.append("\x1b\x21\0"); + out.append("\x0a"); + out.append("\x0a"); + out.append("\x0a"); + + return out; +} + +QByteArray ReceiptGenerator::prepareString(const QString &str) +{ + QString strOut = str; + + //ToDo - dát do nastavení + + for (int i = 0; i < DIACRITIC.length(); i++) + { + strOut = strOut.replace(DIACRITIC.at(i), NON_DIACRITIC.at(i)); + } + + QTextCodec *codec = QTextCodec::codecForName("IBM850"); + return codec->fromUnicode(strOut); +} diff --git a/shop/receiptgenerator.h b/shop/receiptgenerator.h new file mode 100644 index 0000000..ea7a47f --- /dev/null +++ b/shop/receiptgenerator.h @@ -0,0 +1,35 @@ +#ifndef RECEIPTGENERATOR_H +#define RECEIPTGENERATOR_H + +#include "data/voucher.h" +#include "settings/shopsettings.h" + +class ReceiptGenerator +{ +public: + ReceiptGenerator(); + + void setVoucher(const QSharedPointer &voucher); + + void setSettings(const ShopSettingsPtr &settings); + + void save(); + void print(); + + QString outputFile() const; + void setOutputFile(const QString &outputFile); + +private: + static const QString DIACRITIC; + static const QString NON_DIACRITIC; + + QSharedPointer m_voucher; + ShopSettingsPtr m_settings; + + QString m_outputFile; + + QByteArray generate(); + QByteArray prepareString(const QString &str); +}; + +#endif // RECEIPTGENERATOR_H diff --git a/shop/receiptsaveform.cpp b/shop/receiptsaveform.cpp index 1abc244..7cd16cf 100644 --- a/shop/receiptsaveform.cpp +++ b/shop/receiptsaveform.cpp @@ -45,15 +45,9 @@ ReceiptSaveForm::ReceiptSaveForm(QSharedPointer voucher, QWidget *paren ui->buttonBox->button(QDialogButtonBox::Ok)->setEnabled(!text.isEmpty()); }); + m_binder.setData(new Voucher); AddressBookService srvAdb; - QList comboData; - foreach (QSharedPointer adb, srvAdb.all()) { - comboData << ComboData(adb); - } - - m_voucher = voucher; - m_binder.setData(m_voucher.data()); - m_binder.registerBinding(ui->contact, comboData); + m_binder.registerBinding(ui->contact, ComboData::createComboData(srvAdb.all())); m_binder.registerBinding(ui->name); m_binder.registerBinding(ui->description); m_binder.bindToUi(); @@ -106,27 +100,3 @@ void ReceiptSaveForm::on_radioAdd_toggled(bool checked) ui->buttonBox->button(QDialogButtonBox::Ok)->setEnabled(!ui->name->text().isEmpty()); } } - -void ReceiptSaveForm::accept() -{ - ShopService srv; - m_binder.bindToData(); - if (m_saveAsNew) - { - m_voucher->setStatus(Voucher::NOT_PAID); - srv.updateVoucher(m_voucher); - } - else - { - QSharedPointer voucher = m_voucherModel->itemFromIndex(ui->tabVouchers->currentIndex()); - foreach (QSharedPointer item, m_voucher->items()) { - voucher->addItem(item); - } - - srv.calculate(voucher); - srv.updateVoucher(voucher); - srv.erase(m_voucher); - } - - QDialog::accept(); -} diff --git a/shop/settings/shopsettings.cpp b/shop/settings/shopsettings.cpp new file mode 100644 index 0000000..78064d3 --- /dev/null +++ b/shop/settings/shopsettings.cpp @@ -0,0 +1,47 @@ +#include "shopsettings.h" + +ShopSettings::ShopSettings(QObject *parent) : QObject(parent) +{ + m_codepage = ASCII; + m_lettersPerLine = 48; +} + +QString ShopSettings::output() const +{ + return m_output; +} + +void ShopSettings::setOutput(const QString &output) +{ + m_output = output; +} + +ShopSettings::CODEPAGE ShopSettings::codepage() const +{ + return m_codepage; +} + +void ShopSettings::setCodepage(const CODEPAGE &codepage) +{ + m_codepage = codepage; +} + +int ShopSettings::lettersPerLine() const +{ + return m_lettersPerLine; +} + +void ShopSettings::setLettersPerLine(int lettersPerLine) +{ + m_lettersPerLine = lettersPerLine; +} + +QString ShopSettings::byMessage() const +{ + return m_byMessage; +} + +void ShopSettings::setByMessage(const QString &byMessage) +{ + m_byMessage = byMessage; +} diff --git a/shop/settings/shopsettings.h b/shop/settings/shopsettings.h new file mode 100644 index 0000000..acfb626 --- /dev/null +++ b/shop/settings/shopsettings.h @@ -0,0 +1,43 @@ +#ifndef RECEIPTSETTINGS_H +#define RECEIPTSETTINGS_H + +#include + +class ShopSettings : public QObject +{ + Q_PROPERTY(QString output READ output WRITE setOutput) + Q_PROPERTY(int lettersPerLine READ lettersPerLine WRITE setLettersPerLine) + Q_PROPERTY(QString byMessage READ byMessage WRITE setByMessage) + + Q_OBJECT +public: + + enum CODEPAGE + { + ASCII + }; + + explicit ShopSettings(QObject *parent = 0); + + QString output() const; + void setOutput(const QString &output); + + CODEPAGE codepage() const; + void setCodepage(const CODEPAGE &codepage); + + int lettersPerLine() const; + void setLettersPerLine(int lettersPerLine); + + QString byMessage() const; + void setByMessage(const QString &byMessage); + +private: + QString m_output; + CODEPAGE m_codepage; + int m_lettersPerLine; + QString m_byMessage; +}; + +typedef QSharedPointer ShopSettingsPtr; + +#endif // RECEIPTSETTINGS_H diff --git a/shop/settings/shopsettingsform.cpp b/shop/settings/shopsettingsform.cpp new file mode 100644 index 0000000..18c2b1d --- /dev/null +++ b/shop/settings/shopsettingsform.cpp @@ -0,0 +1,36 @@ +#include "shopsettingsform.h" +#include "ui_shopsettingsform.h" + +#include + +ShopSettingsForm::ShopSettingsForm(QWidget *parent) : + FormBinder(parent), + ui(new Ui::ShopSettingsForm) +{ + ui->setupUi(this); + + registerBinding(ui->output); + registerBinding(ui->lettersPerLine); + registerBinding(ui->byMessage); +} + +ShopSettingsForm::~ShopSettingsForm() +{ + delete ui; +} + +void ShopSettingsForm::loadEntity() +{ + SettingsService srv("SHOP"); + ShopSettingsPtr settings = srv.loadSettings(); + setEntity(settings); +} + +bool ShopSettingsForm::saveRecord() +{ + bindToData(); + SettingsService srv("SHOP"); + srv.saveSettings(entity()); + + return true; +} diff --git a/shop/settings/shopsettingsform.h b/shop/settings/shopsettingsform.h new file mode 100644 index 0000000..42bb46f --- /dev/null +++ b/shop/settings/shopsettingsform.h @@ -0,0 +1,31 @@ +#ifndef SHOPSETTINGSFORM_H +#define SHOPSETTINGSFORM_H + +#include +#include +#include "shopsettings.h" + +namespace Ui { +class ShopSettingsForm; +} + +class ShopSettingsForm : public FormBinder +{ + Q_OBJECT + +public: + explicit ShopSettingsForm(QWidget *parent = 0); + ~ShopSettingsForm(); + +private: + Ui::ShopSettingsForm *ui; + + // IForm interface +public: + void loadEntity(); + +public slots: + bool saveRecord(); +}; + +#endif // SHOPSETTINGSFORM_H diff --git a/shop/settings/shopsettingsform.ui b/shop/settings/shopsettingsform.ui new file mode 100644 index 0000000..405dd54 --- /dev/null +++ b/shop/settings/shopsettingsform.ui @@ -0,0 +1,60 @@ + + + ShopSettingsForm + + + + 0 + 0 + 608 + 450 + + + + Form + + + + + + Printer + + + + + + Output device + + + + + + + + + + Letters per line + + + + + + + + + + Footer text + + + + + + + + + + + + + + diff --git a/shop/shop.cpp b/shop/shop.cpp index 448c811..4f6ae67 100644 --- a/shop/shop.cpp +++ b/shop/shop.cpp @@ -2,6 +2,7 @@ #include #include "shopform.h" #include "shopservice.h" +#include "settings/shopsettingsform.h" Shop::Shop() @@ -12,6 +13,7 @@ void Shop::initServiceUi() { m_ui = new ShopForm(); m_service = new ShopService(); + m_settingsUi = new ShopSettingsForm(); } QIcon Shop::pluginIcon() @@ -31,3 +33,13 @@ QTranslator *Shop::translator() { return translatorFrom(":/translations/shop_"); } + +bool Shop::hasNumberSeries() +{ + return true; +} + +QString Shop::numberSeriesPrefix() +{ + return "PD"; +} diff --git a/shop/shop.h b/shop/shop.h index 2d36993..a3b061b 100644 --- a/shop/shop.h +++ b/shop/shop.h @@ -24,6 +24,8 @@ public: virtual QIcon pluginIcon(); virtual QWidget *ui() override; QTranslator *translator(); + bool hasNumberSeries(); + QString numberSeriesPrefix(); }; #endif // SHOP_H diff --git a/shop/shop.json b/shop/shop.json index 7f9c44e..9f54cc6 100644 --- a/shop/shop.json +++ b/shop/shop.json @@ -29,6 +29,8 @@ CREATE TABLE \"Voucher\" ( \"id\" INTEGER NOT NULL PRIMARY KEY AUTOINCREMENT, + \"numSer\" TEXT NULL, + \"payDateTime\" TEXT NULL, \"name\" TEXT NULL, \"description\" TEXT NULL, \"contact\" INTEGER NULL, diff --git a/shop/shop.pro b/shop/shop.pro index d626e77..3bcd021 100644 --- a/shop/shop.pro +++ b/shop/shop.pro @@ -21,7 +21,12 @@ SOURCES += shop.cpp \ receiptloadform.cpp \ data/voucheritem.cpp \ shopservice.cpp \ - directsaleitem.cpp + directsaleitem.cpp \ + receiptgenerator.cpp \ + settings/shopsettings.cpp \ + settings/shopsettingsform.cpp \ + paydialog.cpp \ + paydvouchersdialog.cpp HEADERS += shop.h\ shop_global.h \ @@ -36,7 +41,12 @@ HEADERS += shop.h\ data/shop-data.h \ isellableservice.h \ shopservice.h \ - directsaleitem.h + directsaleitem.h \ + receiptgenerator.h \ + settings/shopsettings.h \ + settings/shopsettingsform.h \ + paydialog.h \ + paydvouchersdialog.h unix { target.path = /usr/lib @@ -89,6 +99,9 @@ FORMS += \ directsaleform.ui \ temporaryreceiptsaveform.ui \ receiptsaveform.ui \ - receiptloadform.ui + receiptloadform.ui \ + settings/shopsettingsform.ui \ + paydialog.ui \ + paydvouchersdialog.ui TRANSLATIONS = translations/shop_cs_CZ.ts diff --git a/shop/shopform.cpp b/shop/shopform.cpp index df2cdf5..48a6f97 100644 --- a/shop/shopform.cpp +++ b/shop/shopform.cpp @@ -5,6 +5,9 @@ #include "receiptsaveform.h" #include "receiptloadform.h" #include "shopservice.h" +#include "receiptgenerator.h" +#include "paydialog.h" +#include "paydvouchersdialog.h" #include #include #include "shop-odb.hxx" @@ -18,6 +21,7 @@ ShopForm::ShopForm(QWidget *parent) : ui->temporarySaveButton->setEnabled(false); ui->saveButton->setEnabled(false); + ui->payButton->setEnabled(false); } ShopForm::~ShopForm() @@ -48,6 +52,7 @@ void ShopForm::loadLast() ui->total->setText(QString::number(m_voucher->totalPrice().toDouble(), 'f', 2)); ui->temporarySaveButton->setEnabled(true); ui->saveButton->setEnabled(true); + ui->payButton->setEnabled(true); } } @@ -136,6 +141,7 @@ void ShopForm::onCountChanged() ui->total->setText(QString::number(m_voucher->totalPrice().toDouble(), 'f', 2)); ui->temporarySaveButton->setEnabled(!m_voucher->items().isEmpty()); ui->saveButton->setEnabled(!m_voucher->items().isEmpty()); + ui->payButton->setEnabled(!m_voucher->items().isEmpty()); if (m_voucher->status() == Voucher::NEW && m_voucher->id() == 0) { @@ -173,10 +179,7 @@ void ShopForm::doTempSave(bool comboChanged) } else { - m_voucher = srv.createVoucher(); - ui->total->setText("0"); - ui->temporarySaveButton->setEnabled(false); - ui->saveButton->setEnabled(false); + createEmptyVoucher(); } fillRaceiptCombo(); @@ -202,6 +205,7 @@ void ShopForm::changeReceipt() ui->temporarySaveButton->setEnabled(true); ui->saveButton->setEnabled(true); + ui->payButton->setEnabled(true); fillRaceiptCombo(); } @@ -213,6 +217,16 @@ void ShopForm::connectItemSignals() } } +void ShopForm::createEmptyVoucher() +{ + ShopService srv; + m_voucher = srv.createVoucher(); + ui->total->setText("0"); + ui->temporarySaveButton->setEnabled(false); + ui->saveButton->setEnabled(false); + ui->payButton->setEnabled(false); +} + void ShopForm::on_receiptCombo_currentIndexChanged(int) { if (!m_voucher.isNull() && m_voucher->items().isEmpty()) @@ -233,3 +247,31 @@ void ShopForm::on_receiptCombo_currentIndexChanged(int) doTempSave(true); } } + +void ShopForm::on_payButton_clicked() +{ + PayDialog *dialog = new PayDialog(m_voucher->totalPrice(), this); + dialog->setAttribute(Qt::WA_DeleteOnClose); + dialog->show(); + + connect(dialog, &QDialog::accepted, [this](){ + ShopService srv; + srv.pay(m_voucher); + + ReceiptGenerator generator; + generator.setVoucher(m_voucher); + generator.print(); + + createEmptyVoucher(); + m_itemsModel->setData(m_voucher->items()); + }); + + +} + +void ShopForm::on_showPaiedButton_clicked() +{ + PaydVouchersDialog *dialog = new PaydVouchersDialog(this); + dialog->setAttribute(Qt::WA_DeleteOnClose); + dialog->show(); +} diff --git a/shop/shopform.h b/shop/shopform.h index df37aa8..36cb250 100644 --- a/shop/shopform.h +++ b/shop/shopform.h @@ -33,6 +33,10 @@ private slots: void on_receiptCombo_currentIndexChanged(int index); + void on_payButton_clicked(); + + void on_showPaiedButton_clicked(); + private: Ui::ShopForm *ui; QSharedPointer m_voucher; @@ -42,6 +46,7 @@ private: void doTempSave(bool comboChanged); void changeReceipt(); void connectItemSignals(); + void createEmptyVoucher(); }; #endif // SHOPFORM_H diff --git a/shop/shopform.ui b/shop/shopform.ui index 40a0a21..56dceaf 100644 --- a/shop/shopform.ui +++ b/shop/shopform.ui @@ -269,30 +269,112 @@ + + + 10 + + Temporary Save + + + :/icons/tempSave.svg:/icons/tempSave.svg + + + + 32 + 32 + + + + + 10 + + Save + + + :/icons/save.svg:/icons/save.svg + + + + 32 + 32 + + + + + 10 + + Load + + + :/icons/edit.svg:/icons/edit.svg + + + + 32 + 32 + + + + + + + + + 10 + + + + Show paied + + + + :/icons/paied.svg:/icons/paied.svg + + + + 32 + 32 + + + + + 10 + + Pay + + + :/icons/pay.svg:/icons/pay.svg + + + + 32 + 32 + + @@ -305,6 +387,7 @@ + diff --git a/shop/shoprc.qrc b/shop/shoprc.qrc index 2961e1c..77a3ead 100644 --- a/shop/shoprc.qrc +++ b/shop/shoprc.qrc @@ -2,5 +2,8 @@ icons/shop.svg translations/shop_cs_CZ.qm + icons/tempSave.svg + icons/paied.svg + icons/pay.svg diff --git a/shop/shopservice.cpp b/shop/shopservice.cpp index 5bd7964..15e52a4 100644 --- a/shop/shopservice.cpp +++ b/shop/shopservice.cpp @@ -1,4 +1,5 @@ #include "shopservice.h" +#include "numberseriesservice.h" #include "shop-odb.hxx" ShopService::ShopService() @@ -76,6 +77,7 @@ void ShopService::calculateItem(QSharedPointer item) else { item->setPrice(item->unitPrice() * item->count()); + item->setPriceWitouthVat(item->price()); } } @@ -85,6 +87,39 @@ void ShopService::loadItems(QSharedPointer voucher) voucher->setItems(srv.all(QString("voucher = %1").arg(voucher->id()))); } +void ShopService::pay(QSharedPointer 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->setStatus(Voucher::PAID); + voucher->setPayDateTime(QDateTime::currentDateTime()); + + this->update(voucher); + + tx.commit(); +} + +QList > ShopService::savedVouchers() +{ + return all(QString("status = %1").arg(QString::number(Voucher::NOT_PAID))); +} + +QList > ShopService::tempVouchers() +{ + return all(QString("status = %1").arg(QString::number(Voucher::TEMPORARY))); +} + +QList > ShopService::paiedVouchers() +{ + return all(QString("status = %1").arg(QString::number(Voucher::PAID))); +} + QDecDouble ShopService::includeVat(QDecDouble price, Enums::VatType vatType) { return price * ((vatRate(vatType) / 100) + QDecDouble(1)); diff --git a/shop/shopservice.h b/shop/shopservice.h index 5b70012..0c626d1 100644 --- a/shop/shopservice.h +++ b/shop/shopservice.h @@ -18,6 +18,10 @@ public: void calculate(QSharedPointer voucher); void calculateItem(QSharedPointer item); void loadItems(QSharedPointer voucher); + void pay(QSharedPointer voucher); + QList > savedVouchers(); + QList > tempVouchers(); + QList > paiedVouchers(); private: QDecDouble includeVat(QDecDouble price, Enums::VatType vatType);