From 049314a2455df4748c569c9034bd0a6eb14b3ebb Mon Sep 17 00:00:00 2001 From: Josef Rokos Date: Wed, 13 Apr 2016 21:34:49 +0200 Subject: [PATCH 1/2] Added class ObjectBinder for common data binding. --- core/core.pro | 6 ++- core/formbinder.h | 88 +++++++--------------------------------- core/objectbinder.cpp | 93 +++++++++++++++++++++++++++++++++++++++++++ core/objectbinder.h | 37 +++++++++++++++++ shop/shopservice.cpp | 6 +++ shop/shopservice.h | 11 +++++ 6 files changed, 165 insertions(+), 76 deletions(-) create mode 100644 core/objectbinder.cpp create mode 100644 core/objectbinder.h create mode 100644 shop/shopservice.cpp create mode 100644 shop/shopservice.h diff --git a/core/core.pro b/core/core.pro index 02834c2..c9a1656 100644 --- a/core/core.pro +++ b/core/core.pro @@ -51,7 +51,8 @@ SOURCES += \ settings/globalsettings.cpp \ settingsform.cpp \ settings/globalsettingsform.cpp \ - permissionevaluator.cpp + permissionevaluator.cpp \ + objectbinder.cpp HEADERS += core.h\ core_global.h \ @@ -102,7 +103,8 @@ HEADERS += core.h\ settingsform.h \ settings/globalsettingsform.h \ formbinder.h \ - permissionevaluator.h + permissionevaluator.h \ + objectbinder.h unix { target.path = /usr/lib diff --git a/core/formbinder.h b/core/formbinder.h index dcac7a9..79614fb 100644 --- a/core/formbinder.h +++ b/core/formbinder.h @@ -11,6 +11,7 @@ #include "combodata.h" #include "ivalidator.h" #include "iform.h" +#include "objectbinder.h" #include "../qdecimal/src/QDecDouble.hh" @@ -19,31 +20,31 @@ class FormBinder : public IForm { public: - explicit FormBinder(QWidget *parent = NULL) : IForm(parent) {} + explicit FormBinder(QWidget *parent = NULL) : IForm(parent) { + connect(&m_binder, &ObjectBinder::validationError, [this](QString msg){ + emit this->validationError(msg); + }); + } virtual ~FormBinder() { - foreach (IValidator *val, m_validators) { - delete val; - } - m_validators.clear(); + } void registerBinding(QWidget *widget) { - if (!m_bindWidgets.contains(widget)) { - m_bindWidgets.append(widget); - } + m_binder.registerBinding(widget); } void registerBinding(QComboBox *combo, const QList &values) { - m_bindCombos[combo] = values; + m_binder.registerBinding(combo, values); } void registerValidator(IValidator *validator) { - m_validators.append(validator); + m_binder.registerValidator(validator); } void setEntity(QSharedPointer entity) { m_entity = entity; + m_binder.setData(m_entity.data()); bindToUi(); } @@ -60,77 +61,16 @@ protected: void bindToUi() { registerCombos(); - foreach (QWidget *widget, m_bindWidgets) { - const char* prop = widget->metaObject()->userProperty().name(); - QVariant value = ((QObject*)m_entity.data())->property(widget->objectName().toStdString().c_str()); - if (value.canConvert()) - { - widget->setProperty(prop, value.value().toString()); - } - else - { - widget->setProperty(prop, value); - } - } - - foreach (QComboBox *combo, m_bindCombos.keys()) { - int idx = 0; - QVariant field = ((QObject*)m_entity.data())->property(combo->objectName().toStdString().c_str()); - - combo->clear(); - for (int i = 0; i < m_bindCombos[combo].size(); i++) { - ComboData data = m_bindCombos[combo][i]; - combo->addItem(data.label(), data.index()); - - if (data.index().canConvert()) { - ComboItem* ci = qobject_cast(data.index().value()); - ComboItem* ciField = qobject_cast(field.value()); - if (ci->eq(ciField)) { - idx = i; - } - } - else if (field == data.index()) { - idx = i; - } - } - - combo->setCurrentIndex(idx); - } - + m_binder.bindToUi(); bindOtherToUi(); } bool bindToData() { - foreach (IValidator *val, m_validators) { - if (!val->validate()) { - emit validationError(val->errMessage()); - return false; - } - } - - foreach (QWidget *widget, m_bindWidgets) { - const char* prop = widget->metaObject()->userProperty().name(); - - QVariant val = widget->property(prop); - if (((QObject*)m_entity.data())->property(widget->objectName().toStdString().c_str()).canConvert()) - { - QDecDouble dec(val.toDouble()); - val = QVariant::fromValue(dec); - } - ((QObject*)m_entity.data())->setProperty(widget->objectName().toStdString().c_str(), val); - } - - foreach (QComboBox *combo, m_bindCombos.keys()) { - ((QObject*)m_entity.data())->setProperty(combo->objectName().toStdString().c_str(), combo->currentData()); - } - - return bindOtherToData(); + return m_binder.bindToData() && bindOtherToData(); } private: - QList m_bindWidgets; - QHash > m_bindCombos; - QList m_validators; + ObjectBinder m_binder; }; #endif // FORMBINDER_H diff --git a/core/objectbinder.cpp b/core/objectbinder.cpp new file mode 100644 index 0000000..655df8b --- /dev/null +++ b/core/objectbinder.cpp @@ -0,0 +1,93 @@ +#include "objectbinder.h" +#include + +ObjectBinder::ObjectBinder(QObject *parent) + :QObject(parent) +{ + m_data = NULL; +} + +void ObjectBinder::registerBinding(QWidget *widget) { + if (!m_bindWidgets.contains(widget)) { + m_bindWidgets.append(widget); + } +} + +void ObjectBinder::registerBinding(QComboBox *combo, const QList &values) { + m_bindCombos[combo] = values; +} + +void ObjectBinder::registerValidator(IValidator *validator) { + m_validators.append(validator); +} + +void ObjectBinder::setData(QObject *data) +{ + m_data = data; +} + +void ObjectBinder::bindToUi() { + foreach (QWidget *widget, m_bindWidgets) { + const char* prop = widget->metaObject()->userProperty().name(); + QVariant value = m_data->property(widget->objectName().toStdString().c_str()); + if (value.canConvert()) + { + widget->setProperty(prop, value.value().toString()); + } + else + { + widget->setProperty(prop, value); + } + } + + foreach (QComboBox *combo, m_bindCombos.keys()) { + int idx = 0; + QVariant field = m_data->property(combo->objectName().toStdString().c_str()); + + combo->clear(); + for (int i = 0; i < m_bindCombos[combo].size(); i++) { + ComboData data = m_bindCombos[combo][i]; + combo->addItem(data.label(), data.index()); + + if (data.index().canConvert()) { + ComboItem* ci = qobject_cast(data.index().value()); + ComboItem* ciField = qobject_cast(field.value()); + if (ci->eq(ciField)) { + idx = i; + } + } + else if (field == data.index()) { + idx = i; + } + } + + combo->setCurrentIndex(idx); + } +} + +bool ObjectBinder::bindToData() { + foreach (IValidator *val, m_validators) { + if (!val->validate()) { + emit validationError(val->errMessage()); + return false; + } + } + + foreach (QWidget *widget, m_bindWidgets) { + const char* prop = widget->metaObject()->userProperty().name(); + + QVariant val = widget->property(prop); + if (m_data->property(widget->objectName().toStdString().c_str()).canConvert()) + { + QDecDouble dec(val.toDouble()); + val = QVariant::fromValue(dec); + } + m_data->setProperty(widget->objectName().toStdString().c_str(), val); + } + + foreach (QComboBox *combo, m_bindCombos.keys()) { + m_data->setProperty(combo->objectName().toStdString().c_str(), combo->currentData()); + } + + return true; +} diff --git a/core/objectbinder.h b/core/objectbinder.h new file mode 100644 index 0000000..e752909 --- /dev/null +++ b/core/objectbinder.h @@ -0,0 +1,37 @@ +#ifndef OBJECTBINDER_H +#define OBJECTBINDER_H + +#include +#include +#include +#include +#include +#include "ivalidator.h" +#include "combodata.h" +#include "core_global.h" + +class CORESHARED_EXPORT ObjectBinder : public QObject +{ + Q_OBJECT + +public: + explicit ObjectBinder(QObject *parent = NULL); + + void registerBinding(QWidget *widget); + void registerBinding(QComboBox *combo, const QList &values); + void registerValidator(IValidator *validator); + void setData(QObject *data); + void bindToUi(); + bool bindToData(); + +signals: + void validationError(QString msg); + +private: + QList m_bindWidgets; + QHash > m_bindCombos; + QList m_validators; + QObject *m_data; +}; + +#endif // OBJECTBINDER_H diff --git a/shop/shopservice.cpp b/shop/shopservice.cpp new file mode 100644 index 0000000..11a1d1f --- /dev/null +++ b/shop/shopservice.cpp @@ -0,0 +1,6 @@ +#include "shopservice.h" + +ShopService::ShopService() +{ + +} diff --git a/shop/shopservice.h b/shop/shopservice.h new file mode 100644 index 0000000..3d406e9 --- /dev/null +++ b/shop/shopservice.h @@ -0,0 +1,11 @@ +#ifndef SHOPSERVICE_H +#define SHOPSERVICE_H + + +class ShopService +{ +public: + ShopService(); +}; + +#endif // SHOPSERVICE_H \ No newline at end of file From 2ed7d7077b3da66cbd7e10cf33de16fe2d83938e Mon Sep 17 00:00:00 2001 From: Josef Rokos Date: Wed, 13 Apr 2016 22:37:41 +0200 Subject: [PATCH 2/2] Implemented base functionality of DirectSaleForm. --- core/core.h | 1 + shop/data/voucheritem.cpp | 5 ++++- shop/data/voucheritem.h | 2 -- shop/directsaleform.cpp | 23 ++++++++++++++++++++ shop/directsaleform.h | 16 +++++++++++++- shop/directsaleform.ui | 4 ++-- shop/directsaleitem.cpp | 46 +++++++++++++++++++++++++++++++++++++++ shop/directsaleitem.h | 42 +++++++++++++++++++++++++++++++++++ shop/ishopitem.h | 6 +++-- shop/shop.cpp | 2 ++ shop/shop.pro | 12 ++++++---- shop/shopform.cpp | 12 ++++++++++ shop/shopform.h | 5 +++++ shop/shopservice.cpp | 31 ++++++++++++++++++++++++++ shop/shopservice.h | 13 +++++++++-- 15 files changed, 206 insertions(+), 14 deletions(-) create mode 100644 shop/directsaleitem.cpp create mode 100644 shop/directsaleitem.h diff --git a/core/core.h b/core/core.h index 7b5f590..b94ea6c 100644 --- a/core/core.h +++ b/core/core.h @@ -12,5 +12,6 @@ #include "settingsservice.h" #include "settingsform.h" #include "enums.h" +#include "objectbinder.h" #endif // CORE_H diff --git a/shop/data/voucheritem.cpp b/shop/data/voucheritem.cpp index 353f255..3129b58 100644 --- a/shop/data/voucheritem.cpp +++ b/shop/data/voucheritem.cpp @@ -3,7 +3,10 @@ VoucherItem::VoucherItem(QObject *parent) : QObject(parent) { - + m_price = 0; + m_unitPrice = 0; + m_count = 0; + m_refId = 0; } int VoucherItem::id() const diff --git a/shop/data/voucheritem.h b/shop/data/voucheritem.h index 31b1b08..0457c57 100644 --- a/shop/data/voucheritem.h +++ b/shop/data/voucheritem.h @@ -17,8 +17,6 @@ class VoucherItem : public QObject Q_PROPERTY(int count READ count WRITE setCount) Q_PROPERTY(QDecDouble unitPrice READ unitPrice WRITE setUnitPrice) Q_PROPERTY(QDecDouble price READ price WRITE setPrice) - Q_PROPERTY(int refId READ refId WRITE setRefId) - Q_PROPERTY(QString itemPlugin READ itemPlugin WRITE setItemPlugin) Q_PROPERTY(Enums::VatType vatType READ vatType WRITE setVatType) public: diff --git a/shop/directsaleform.cpp b/shop/directsaleform.cpp index af3cfbf..8db5c48 100644 --- a/shop/directsaleform.cpp +++ b/shop/directsaleform.cpp @@ -6,9 +6,32 @@ DirectSaleForm::DirectSaleForm(QWidget *parent) : ui(new Ui::DirectSaleForm) { ui->setupUi(this); + m_shopItem = QSharedPointer(new DirectSaleItem); + + m_binder.setData(m_shopItem.data()); + m_binder.registerBinding(ui->name); + m_binder.registerBinding(ui->unitPrice); + m_binder.registerBinding(ui->count); + m_binder.bindToUi(); } DirectSaleForm::~DirectSaleForm() { delete ui; } + +QSharedPointer DirectSaleForm::shopItem() const +{ + return m_shopItem; +} + +void DirectSaleForm::on_buttonBox_rejected() +{ + this->reject(); +} + +void DirectSaleForm::on_buttonBox_accepted() +{ + m_binder.bindToData(); + this->accept(); +} diff --git a/shop/directsaleform.h b/shop/directsaleform.h index ce7b5c3..4c797ef 100644 --- a/shop/directsaleform.h +++ b/shop/directsaleform.h @@ -2,7 +2,12 @@ #define DIRECTSALEFORM_H #include -#include +#include +#include +#include + +#include "ishopitem.h" +#include "directsaleitem.h" namespace Ui { class DirectSaleForm; @@ -16,8 +21,17 @@ public: explicit DirectSaleForm(QWidget *parent = 0); ~DirectSaleForm(); + QSharedPointer shopItem() const; + +private slots: + void on_buttonBox_rejected(); + + void on_buttonBox_accepted(); + private: Ui::DirectSaleForm *ui; + ObjectBinder m_binder; + QSharedPointer m_shopItem; }; #endif // DIRECTSALEFORM_H diff --git a/shop/directsaleform.ui b/shop/directsaleform.ui index da465b0..952f906 100644 --- a/shop/directsaleform.ui +++ b/shop/directsaleform.ui @@ -22,7 +22,7 @@ - + @@ -32,7 +32,7 @@ - + diff --git a/shop/directsaleitem.cpp b/shop/directsaleitem.cpp new file mode 100644 index 0000000..f08bdde --- /dev/null +++ b/shop/directsaleitem.cpp @@ -0,0 +1,46 @@ +#include "directsaleitem.h" + +DirectSaleItem::DirectSaleItem(QObject *parent) : QObject(parent) +{ + m_count = 1; +} + +int DirectSaleItem::id() +{ + return 0; +} + +QString DirectSaleItem::name() +{ + return m_name; +} + +QDecDouble DirectSaleItem::unitPrice() +{ + return m_unitPrice; +} + +QString DirectSaleItem::pluginId() +{ + return ""; +} + +int DirectSaleItem::count() const +{ + return m_count; +} + +void DirectSaleItem::setCount(int count) +{ + m_count = count; +} + +void DirectSaleItem::setName(const QString &name) +{ + m_name = name; +} + +void DirectSaleItem::setUnitPrice(const QDecDouble &unitPrice) +{ + m_unitPrice = unitPrice; +} diff --git a/shop/directsaleitem.h b/shop/directsaleitem.h new file mode 100644 index 0000000..243ec5d --- /dev/null +++ b/shop/directsaleitem.h @@ -0,0 +1,42 @@ +#ifndef DIRECTSALEITEM_H +#define DIRECTSALEITEM_H + +#include +#include +#include "ishopitem.h" + +class DirectSaleItem : public QObject, public IShopItem +{ + Q_OBJECT + Q_PROPERTY(QString name READ name WRITE setName) + Q_PROPERTY(QDecDouble unitPrice READ unitPrice WRITE setUnitPrice) + Q_PROPERTY(int count READ count WRITE setCount) + +public: + explicit DirectSaleItem(QObject *parent = 0); + +signals: + +public slots: + + // IShopItem interface +public: + int id() override; + QString name() override; + QDecDouble unitPrice() override; + QString pluginId() override; + + int count() const; + void setCount(int count); + + void setName(const QString &name); + + void setUnitPrice(const QDecDouble &unitPrice); + +private: + QString m_name; + QDecDouble m_unitPrice; + int m_count; +}; + +#endif // DIRECTSALEITEM_H diff --git a/shop/ishopitem.h b/shop/ishopitem.h index d13cfe8..5a9c799 100644 --- a/shop/ishopitem.h +++ b/shop/ishopitem.h @@ -9,8 +9,10 @@ class SHOPSHARED_EXPORT IShopItem { public: - QString name() = 0; - QDecDouble unitPrice() = 0; + virtual int id() = 0; + virtual QString name() = 0; + virtual QDecDouble unitPrice() = 0; + virtual QString pluginId() = 0; }; #endif // ISHOPITEM_H diff --git a/shop/shop.cpp b/shop/shop.cpp index 76cf3df..711df43 100644 --- a/shop/shop.cpp +++ b/shop/shop.cpp @@ -1,6 +1,7 @@ #include "shop.h" #include #include "shopform.h" +#include "shopservice.h" Shop::Shop() @@ -10,6 +11,7 @@ Shop::Shop() void Shop::initServiceUi() { m_ui = new ShopForm(); + m_service = new ShopService(); } QIcon Shop::pluginIcon() diff --git a/shop/shop.pro b/shop/shop.pro index 8a2da7a..75cbb3a 100644 --- a/shop/shop.pro +++ b/shop/shop.pro @@ -18,8 +18,10 @@ SOURCES += shop.cpp \ directsaleform.cpp \ temporaryreceiptsaveform.cpp \ receiptsaveform.cpp \ - receiptloadform.cpp - data/voucheritem.cpp + receiptloadform.cpp \ + data/voucheritem.cpp \ + shopservice.cpp \ + directsaleitem.cpp HEADERS += shop.h\ shop_global.h \ @@ -28,11 +30,13 @@ HEADERS += shop.h\ directsaleform.h \ temporaryreceiptsaveform.h \ receiptsaveform.h \ - receiptloadform.h + receiptloadform.h \ ishopitem.h \ data/voucheritem.h \ data/shop-data.h \ - isellableservice.h + isellableservice.h \ + shopservice.h \ + directsaleitem.h unix { target.path = /usr/lib diff --git a/shop/shopform.cpp b/shop/shopform.cpp index 1deeae4..56d466f 100644 --- a/shop/shopform.cpp +++ b/shop/shopform.cpp @@ -4,12 +4,17 @@ #include "temporaryreceiptsaveform.h" #include "receiptsaveform.h" #include "receiptloadform.h" +#include "shopservice.h" ShopForm::ShopForm(QWidget *parent) : QWidget(parent), ui(new Ui::ShopForm) { ui->setupUi(this); + ShopService srv; + m_voucher = srv.createVoucher(); + m_itemsModel = new AutoTableModel(this); + ui->actualReceipt->setModel(m_itemsModel); } ShopForm::~ShopForm() @@ -20,6 +25,13 @@ ShopForm::~ShopForm() void ShopForm::on_directSale_clicked() { DirectSaleForm *form = new DirectSaleForm(this); + + connect(form, &QDialog::accepted, [this, form](){ + ShopService srv; + srv.addShopItem(m_voucher, form->shopItem(), ((DirectSaleItem*)form->shopItem().data())->count()); + this->m_itemsModel->addRow(m_voucher->items()[m_voucher->items().count() - 1]); + }); + form->show(); } diff --git a/shop/shopform.h b/shop/shopform.h index 9e5ca23..e62453b 100644 --- a/shop/shopform.h +++ b/shop/shopform.h @@ -2,6 +2,9 @@ #define SHOPFORM_H #include +#include +#include "data/shop-data.h" +#include namespace Ui { class ShopForm; @@ -26,6 +29,8 @@ private slots: private: Ui::ShopForm *ui; + QSharedPointer m_voucher; + AutoTableModel *m_itemsModel; }; #endif // SHOPFORM_H diff --git a/shop/shopservice.cpp b/shop/shopservice.cpp index 11a1d1f..3441ef3 100644 --- a/shop/shopservice.cpp +++ b/shop/shopservice.cpp @@ -4,3 +4,34 @@ ShopService::ShopService() { } + +QSharedPointer ShopService::createVoucher() +{ + QSharedPointer voucher(new Voucher); + voucher->setStatus(Voucher::NEW); + return voucher; +} + +void ShopService::addShopItem(QSharedPointer voucher, QSharedPointer item, int count) +{ + QSharedPointer vItem(new VoucherItem); + vItem->setName(item->name()); + vItem->setUnitPrice(item->unitPrice()); + vItem->setCount(count); + vItem->setRefId(item->id()); + vItem->setItemPlugin(item->pluginId()); + + voucher->addItem(vItem); +} + +void ShopService::calculate(QSharedPointer voucher) +{ + QDecDouble total; + + foreach (QSharedPointer item, voucher->items()) { + QDecDouble itemPrice = item->unitPrice() * item->count(); + total += itemPrice; + } + + voucher->setTotalPrice(total); +} diff --git a/shop/shopservice.h b/shop/shopservice.h index 3d406e9..77212f7 100644 --- a/shop/shopservice.h +++ b/shop/shopservice.h @@ -1,11 +1,20 @@ #ifndef SHOPSERVICE_H #define SHOPSERVICE_H +#include -class ShopService +#include + +#include "data/shop-data.h" +#include "ishopitem.h" + +class ShopService : public Service { public: ShopService(); + QSharedPointer createVoucher(); + void addShopItem(QSharedPointer voucher, QSharedPointer item, int count); + void calculate(QSharedPointer voucher); }; -#endif // SHOPSERVICE_H \ No newline at end of file +#endif // SHOPSERVICE_H