#include "shopform.h" #include "ui_shopform.h" #include "directsaleform.h" #include "temporaryreceiptsaveform.h" #include "receiptsaveform.h" #include "receiptloadform.h" #include "paydialog.h" #include "shopservice.h" #include "receiptgenerator.h" #include "paydvouchersdialog.h" #include "isellableservice.h" #include #include #include #include #include #include #include "data/favorititem.h" #include "favbutton.h" void payVoucherFromUI(const VoucherPtr& voucher, PayDialog *dialog, ShopForm *form) { ShopService srv; srv.pay(voucher); voucher->setEetStatus(dialog->sendToEet() ? Voucher::EET_FOR_SEND : Voucher::EET_NOT_ENTERING); srv.update(voucher); QString eetMsg; if (srv.isEetEnabled() && dialog->sendToEet()) { bool eetRet = srv.processEet(voucher, eetMsg); if (!eetRet) { QString errMsg = QObject::tr("EET communication error.\n"); if (!eetMsg.isEmpty()) { errMsg += QObject::tr("Message from portal: ") + eetMsg + "\n"; } errMsg += QObject::tr("Switch to offline?"); if (srv.isEetOnline() && QMessageBox::question(nullptr, QObject::tr("EET error"), errMsg) == QMessageBox::Yes) { srv.setEetOnline(false); if (form != nullptr) { form->setEetStatusText(srv.isEetOnline() ? QObject::tr("Online") : QObject::tr("Offline")); } } } } ReceiptGenerator generator; generator.setVoucher(voucher); generator.print(); } ShopForm::ShopForm(QWidget *parent) : QWidget(parent), ui(new Ui::ShopForm) { ui->setupUi(this); m_itemsModel = nullptr; m_commodityModel = nullptr; m_itemFound = false; ui->temporarySaveButton->setEnabled(false); ui->saveButton->setEnabled(false); ui->payButton->setEnabled(false); m_itemCtxMenu.reset(new QMenu()); m_itemCtxMenu->addAction(ui->actionDelete_items); ui->actualReceipt->addAction(ui->actionDelete_items); connect(ui->actualReceipt->selectionModel(), &QItemSelectionModel::selectionChanged, [this](const QItemSelection &selected, const QItemSelection &) { ui->actionDelete_items->setEnabled(!selected.isEmpty()); }); } ShopForm::~ShopForm() { delete ui; } void ShopForm::loadLast() { if (m_itemsModel == nullptr) { m_itemsModel = new AutoTableModel(this); m_itemsModel->setEditableCols(QList() << 2); 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); SettingsService srv("CORE"); GlobalSettingsPtr settings = srv.loadSettings(); if (!settings->vatPayer()) { ui->actualReceipt->setColumnHidden(5, true); ui->widgetVAT->setVisible(false); } ui->actualReceipt->setColumnHidden(6, true); ui->actualReceipt->setColumnWidth(2, 50); ui->actualReceipt->horizontalHeader()->setSectionResizeMode(1, QHeaderView::Stretch); } ShopService srv; QList > receipt = srv.all(QString("status = %1").arg(QString::number(Voucher::NEW))); if (!receipt.isEmpty()) { m_voucher = receipt[0]; srv.load(m_voucher); m_itemsModel->setData(m_voucher->items()); connectItemSignals(); //ui->total->setText(QString::number(m_voucher->totalPrice().toDouble(), 'f', 2)); setTotalText(); if (!m_voucher->items().isEmpty()) { ui->temporarySaveButton->setEnabled(true); ui->saveButton->setEnabled(true); ui->payButton->setEnabled(true); } } if (m_commodityModel == nullptr) { m_commodityModel = new AutoTableModel(this); m_commodityModel->setTranslations(Context::instance().plugin("SHOP")->translations()); ui->commodityTable->setModel(m_commodityModel); connect(ui->commodityTable->selectionModel(), &QItemSelectionModel::currentRowChanged, [this](const QModelIndex ¤t, const QModelIndex &){ ui->btnAddItem->setEnabled(current.isValid()); }); } m_commodityModel->setData(srv.allSellableItems()); ui->commodityTable->horizontalHeader()->setSectionResizeMode(1, QHeaderView::Stretch); ui->commodityTable->setColumnHidden(4, true); ui->commodityTable->setColumnHidden(5, true); ui->commodityTable->setColumnHidden(2, true); ui->commodityTable->setColumnWidth(3, 90); ui->commodityTable->verticalScrollBar()->setStyleSheet("QScrollBar:vertical { width: 30px; }"); ui->actualReceipt->verticalScrollBar()->setStyleSheet("QScrollBar:vertical { width: 30px; }"); if (srv.isEetEnabled()) { ui->lblEetState->setText(srv.isEetOnline() ? tr("Online") : tr("Offline")); } else { ui->labelEete->setVisible(false); ui->lblEetState->setVisible(false); } } void ShopForm::loadButtons(const ShopSettingsPtr& settings) { Service srvFav; QMap btnMap; clearFavButtons(); foreach (FavoritItemPtr item, srvFav.all()) { btnMap[item->favButtonName()] = item; } ShopService srv; auto allItems = srv.allSellableItems(); for (int i = 0; i < settings->favBtnRows(); i++) { for (int j = 0; j < settings->favBtnCols(); j++) { auto *btn = new QToolButton(ui->favorites); QString btnName = QString::number(i) + "_" + QString::number(j); btn->setObjectName(btnName); if (settings->favBtnSize() > 0) { btn->setMinimumHeight(settings->favBtnSize()); btn->setMinimumWidth(settings->favBtnSize()); } btn->setSizePolicy(QSizePolicy::Expanding, QSizePolicy::Fixed); ((QGridLayout*)ui->favorites->layout())->addWidget(btn, i + 1, j); if (btnMap[btnName] != nullptr) { btn->setText(btnMap[btnName]->shortName()); auto shItem = std::find_if(allItems.begin(), allItems.end(),[btnMap, btn](auto it) -> bool { return btnMap[btn->objectName()]->refId() == it->id() && btnMap[btn->objectName()]->pluginId() == it->pluginId(); }); if (shItem != allItems.end()) { btn->setStyleSheet("background: " + shItem->data()->color() + ";"); btn->update(); } connect(btn, &FavButton::clicked, [this, btnMap, btn](bool){ FavoritItemPtr item = btnMap[btn->objectName()]; IPlugin *plugin = Context::instance().plugin(item->pluginId()); IService *service = (plugin != nullptr ? plugin->service() : nullptr); ISellableService *selSrv = dynamic_cast(service); if (selSrv != nullptr) { addItem(selSrv->shopItem(item->refId()), 1); } }); } } } ui->commoditySearch->setFocus(); } void ShopForm::fillReceiptCombo() { bool oldState = ui->receiptCombo->blockSignals(true); ShopService srv; QList > receipts = srv.all(QString("status = %1").arg(QString::number(Voucher::TEMPORARY))); ui->receiptCombo->clear(); ui->receiptCombo->addItem(tr("<< empty >>")); foreach (QSharedPointer voucher, receipts) { ui->receiptCombo->addItem(voucher->name(), (qlonglong)voucher->id()); } ui->receiptCombo->blockSignals(oldState); } void ShopForm::setEetStatusText(const QString &statusText) { ui->lblEetState->setText(statusText); } void ShopForm::setupForm() { SettingsService srv("SHOP"); ShopSettingsPtr settings = srv.loadSettings(); ui->spnCount->setVisible(settings->showCount()); ui->lblCount->setVisible(settings->showCount()); loadLast(); fillReceiptCombo(); loadButtons(settings); loadCatButtons(); } void ShopForm::on_directSale_clicked() { SettingsService srv("SHOP"); ShopSettingsPtr settings = srv.loadSettings(); DirectSaleForm *form = new DirectSaleForm(this, settings->defaultVat()); form->setAttribute(Qt::WA_DeleteOnClose); connect(form, &QDialog::accepted, [this, form](){ addItem(form->shopItem(), ((DirectSaleItem*)form->shopItem().data())->count()); }); form->show(); } void ShopForm::on_temporarySaveButton_clicked() { doTempSave(false); } void ShopForm::on_saveButton_clicked() { ReceiptSaveForm *form = new ReceiptSaveForm(m_voucher, this); form->setAttribute(Qt::WA_DeleteOnClose); connect(form, &QDialog::accepted, [this, form]() { ShopService srv; if (form->saveAsNew()) { m_voucher->setStatus(Voucher::NOT_PAID); m_voucher->setSaveDateTime(QDateTime::currentDateTime()); srv.update(m_voucher); createEmptyVoucher(); } else { VoucherPtr selVoucher = form->selectedVoucher(); srv.moveItems(m_voucher->items(), m_voucher, selVoucher); srv.calculate(selVoucher); srv.update(selVoucher); createEmptyVoucher(); } m_itemsModel->setData(m_voucher->items()); }); form->show(); } void ShopForm::on_loadButton_clicked() { ReceiptLoadForm *form = new ReceiptLoadForm(this); form->setAttribute(Qt::WA_DeleteOnClose); connect(form, &QDialog::accepted, [this, form](){ if (form->selectedItems().isEmpty()) { return; } ShopService srv; if (m_voucher.isNull()) { m_voucher = srv.createVoucher(); } srv.moveItems(form->selectedItems(), form->selectedVoucher(), this->m_voucher); m_voucher->setDescription(form->selectedVoucher()->description()); m_voucher->setName(form->selectedVoucher()->name()); m_voucher->setContact(form->selectedVoucher()->contact()); m_itemsModel->setData(m_voucher->items()); connectItemSignals(); onCountChanged(); }); form->show(); } void ShopForm::onCountChanged(int oldCount/* = 0*/) { VoucherItem *item = qobject_cast(sender()); if (item != nullptr && item->count() == 0) { for (int i = 0; i < m_voucher->items().count(); i++) { if (m_voucher->items()[i].data() == item) { m_voucher->removeItem(m_voucher->items()[i]); m_itemsModel->setData(m_voucher->items()); } } } recalculate(); updateItemCount(item, oldCount); } void ShopForm::createVoucher() { ShopService srv; m_voucher = srv.createVoucher(); } void ShopForm::doTempSave(bool comboChanged) { TemporaryReceiptSaveForm *form = new TemporaryReceiptSaveForm(m_voucher, this); form->setAttribute(Qt::WA_DeleteOnClose); connect(form, &QDialog::accepted, [this, comboChanged](){ ShopService srv; if (!m_voucher->items().isEmpty()) { m_voucher->setStatus(Voucher::TEMPORARY); srv.update(m_voucher); } if (comboChanged && ui->receiptCombo->currentIndex() > 0) { changeReceipt(); } else { createEmptyVoucher(); } fillReceiptCombo(); m_itemsModel->setData(m_voucher->items()); }); form->show(); } void ShopForm::changeReceipt() { ShopService srv; m_voucher = srv.loadById(ui->receiptCombo->currentData().toInt()); if (m_voucher->items().isEmpty()) { srv.load(m_voucher); } connectItemSignals(); m_voucher->setStatus(Voucher::NEW); srv.update(m_voucher); m_itemsModel->setData(m_voucher->items()); //ui->total->setText(m_voucher->totalPrice().toString()); setTotalText(); ui->temporarySaveButton->setEnabled(true); ui->saveButton->setEnabled(true); ui->payButton->setEnabled(true); fillReceiptCombo(); } void ShopForm::connectItemSignals() { foreach (QSharedPointer item, m_voucher->items()) { connect(item.data(), SIGNAL(countChanged(int)), this, SLOT(onCountChanged(int))); } } void ShopForm::createEmptyVoucher() { ShopService srv; m_voucher = srv.createVoucher(); //ui->total->setText("0"); setTotalText(); ui->temporarySaveButton->setEnabled(false); ui->saveButton->setEnabled(false); ui->payButton->setEnabled(false); } void ShopForm::addItem(const QSharedPointer& item, int count) { if (m_voucher.isNull()) { createVoucher(); } IPlugin *plugin = Context::instance().plugin(item->pluginId()); IService *service = (plugin != nullptr ? plugin->service() : nullptr); 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 != nullptr && selSrv->seller() != nullptr) { ISeller *seller = selSrv->seller(); seller->disconnect(); connect(seller, &ISeller::itemPrepared, addFunc); seller->prepareItem(); } else { addFunc(item, count); } ui->actualReceipt->scrollToBottom(); ui->commoditySearch->setFocus(); ui->commoditySearch->setText(""); } void ShopForm::setTotalText() { ui->total->setText(QString::number(m_voucher->totalPrice().toDouble(), 'f', 2)); ui->vatRateHigh->setText(QString::number(m_voucher->vatRateHigh().toDouble(), 'f', 0) + "%"); ui->vatRateFirstLow->setText(QString::number(m_voucher->vatRateFirstLower().toDouble(), 'f', 0) + "%"); ui->vatRateSecondLow->setText(QString::number(m_voucher->vatRateSecondLower().toDouble(), 'f', 0) + "%"); ui->priceVatHigh->setText(QString::number(m_voucher->priceVatHigh().toDouble(), 'f', 2)); ui->priceVatFirstLower->setText(QString::number(m_voucher->priceVatFirstLower().toDouble(), 'f', 2)); ui->priceVatSecondLower->setText(QString::number(m_voucher->priceVatSecondLower().toDouble(), 'f', 2)); ui->vatHigh->setText(QString::number((m_voucher->totalPriceVatHigh() - m_voucher->priceVatHigh()).toDouble(), 'f', 2)); ui->vatFirstLower->setText(QString::number((m_voucher->totalPriceVatFirstLower() - m_voucher->priceVatFirstLower()).toDouble(), 'f', 2)); ui->vatSecondLower->setText(QString::number((m_voucher->totalPriceVatSecondLower() - m_voucher->priceVatSecondLower()).toDouble(), 'f', 2)); ui->totalPriceVatHigh->setText(QString::number(m_voucher->totalPriceVatHigh().toDouble(), 'f', 2)); ui->totalPriceFirstLower->setText(QString::number(m_voucher->totalPriceVatFirstLower().toDouble(), 'f', 2)); ui->totalPriceSecondLower->setText(QString::number(m_voucher->totalPriceVatSecondLower().toDouble(), 'f', 2)); ui->priceNoVat->setText(QString::number(m_voucher->priceNoVat().toDouble(), 'f', 2)); } void ShopForm::updateItemCount(VoucherItem *item, int oldCount) { if (item != nullptr) { ShopService srv; int countAdded = item->count() - oldCount; srv.updateRelatedItem(item, countAdded); } } void ShopForm::recalculate() { ShopService srv; srv.calculate(m_voucher); this->m_itemsModel->setData(m_voucher->items()); setTotalText(); 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) { srv.save(m_voucher); } else { srv.update(m_voucher); } } void ShopForm::on_receiptCombo_currentIndexChanged(int) { if (!m_voucher.isNull() && m_voucher->items().isEmpty()) { ShopService srv; srv.erase(m_voucher); changeReceipt(); return; } if (m_voucher.isNull()) { changeReceipt(); } else { 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, dialog](){ payVoucherFromUI(m_voucher, dialog, this); createEmptyVoucher(); m_itemsModel->setData(m_voucher->items()); }); } void ShopForm::on_showPaidButton_clicked() { PaydVouchersDialog *dialog = new PaydVouchersDialog(this); dialog->setAttribute(Qt::WA_DeleteOnClose); dialog->show(); } void ShopForm::on_btnAddItem_clicked() { IShopItemPtr item = m_commodityModel->itemFromIndex(ui->commodityTable->currentIndex()); addItem(item, ui->spnCount->value()); } void ShopForm::on_commoditySearch_textChanged(const QString &text) { for (int i = 0; i < 2; i++) { QString replacedText = text; if (i == 1) { replacedText = Helper::replaceByNumbers(text); //ui->commoditySearch->setText(replacedText); } QSortFilterProxyModel proxy; proxy.setSourceModel(m_commodityModel); proxy.setFilterKeyColumn(0); proxy.setFilterCaseSensitivity(Qt::CaseInsensitive); proxy.setFilterFixedString(replacedText); auto moveToIndex = [this](const QModelIndex &matchingIndex) { ui->commodityTable->scrollTo(matchingIndex,QAbstractItemView::EnsureVisible); ui->commodityTable->setCurrentIndex(matchingIndex); }; QModelIndex matchingIndex = proxy.mapToSource(proxy.index(0,0)); if(matchingIndex.isValid()) { moveToIndex(matchingIndex); m_itemFound = true; break; } else { proxy.setFilterKeyColumn(1); matchingIndex = proxy.mapToSource(proxy.index(0,0)); if (matchingIndex.isValid()) { moveToIndex(matchingIndex); m_itemFound = true; break; } else { m_itemFound = false; } } } } void ShopForm::on_lblEetState_linkActivated(const QString &) { ShopService srv; srv.setEetOnline(!srv.isEetOnline()); ui->lblEetState->setText(srv.isEetOnline() ? tr("Online") : tr("Offline")); } void ShopForm::on_commoditySearch_returnPressed() { if (m_itemFound) { IShopItemPtr item = m_commodityModel->itemFromIndex(ui->commodityTable->currentIndex()); addItem(item, ui->spnCount->value()); } ui->commoditySearch->clear(); } void ShopForm::on_actionDelete_items_triggered() { if (QMessageBox::question(this, tr("Delete items"), tr("Really delete selected voucher items?")) == QMessageBox::Yes) { QList forDelete; for (const auto& row : ui->actualReceipt->selectionModel()->selectedIndexes()) { forDelete << m_itemsModel->itemFromIndex(row); } for (auto& item : forDelete) { m_voucher->removeItem(item); int oldCount = item->count(); item->setCount(0); updateItemCount(item.data(), oldCount); } recalculate(); m_itemsModel->setData(m_voucher->items()); } } void ShopForm::on_actualReceipt_customContextMenuRequested(const QPoint &pos) { QPoint globalPos = ui->actualReceipt->mapToGlobal(pos); m_itemCtxMenu->exec(globalPos); } void ShopForm::clearFavButtons() { foreach (QWidget *child, ui->favorites->findChildren()) { if (child->objectName() != "directSale") { delete child; } } } void ShopForm::loadFavCatButtons(const QString& category) { SettingsService srvSettings("SHOP"); ShopSettingsPtr settings = srvSettings.loadSettings(); if (category.isEmpty()) { loadButtons(settings); return; } clearFavButtons(); ShopService srv; auto all = srv.allSellableItems(category); if (all.count() == 0) { return; } auto square = std::sqrt(all.count()); int cols = static_cast(square); int rows = cols; if (square - cols != 0) { if (cols > 1) { ++rows; } else { ++cols; } } if (cols * rows < all.count()) { ++cols; } int index = 0; for (int i = 0; i < rows; i++) { for (int j = 0; j < cols; j++) { if (index >= all.count()) { break; } auto item = all[index]; ++index; auto *btn = new QToolButton(ui->favorites); if (settings->favBtnSize() > 0) { btn->setMinimumHeight(settings->favBtnSize()); btn->setMinimumWidth(settings->favBtnSize()); } btn->setText(item->shortName()); btn->setSizePolicy(QSizePolicy::Expanding, QSizePolicy::Fixed); ((QGridLayout*)ui->favorites->layout())->addWidget(btn, i + 1, j); btn->setStyleSheet("background: " + item->color() + ";"); btn->update(); connect(btn, &QToolButton::clicked, [this, item](bool){ addItem(item, 1); }); } } } void ShopForm::loadCatButtons() { ShopService srv; auto allCat = srv.allCategories(); for (const auto btnFav : ui->widgetCategories->findChildren()) { if (btnFav->objectName() != "btnFav") { delete btnFav; } } for (const auto& cat : allCat.keys()) { auto catButton = new QToolButton(ui->widgetCategories); catButton->setText(cat); catButton->setMinimumHeight(45); catButton->setSizePolicy(QSizePolicy::Expanding, QSizePolicy::Fixed); catButton->setStyleSheet("background: " + allCat[cat] + ";"); catButton->update(); connect(catButton, &QPushButton::clicked, [this, cat](bool){ loadFavCatButtons(cat); }); ui->widgetCategories->layout()->addWidget(catButton); } } void ShopForm::on_btnFav_clicked() { loadFavCatButtons(""); }