/*************************************************************************** libMiniCash Copyright © 2013-2022 christoph holzheuer c.holzheuer@sourceworx.org This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 3 of the License, or (at your option) any later version. ***************************************************************************/ #include #include #include #include #include #include #include /** * Standardkonstruktor. * @param parent */ MCInputView::MCInputView( QWidget* parent ) : QWidget( parent ), _ui{new Ui::MCInputView} { _ui->setupUi( this ); _ui->_trSellerID->setFocus(); } /** * @brief Destruktor */ MCInputView::~MCInputView() { delete _ui; } /** * @brief Vorgabewerete der Eingabemaske setzen * @param parent * @param salesModel */ void MCInputView::setupDefaults( MCMainWindowBase* parent, MCSalesModel* salesModel ) { _parent = parent; Q_ASSERT( _parent != nullptr ); // model setzen _salesModel = salesModel; _ui->_trList->setModel( _salesModel ); _valCustId.setRegularExpression( QRegularExpression( miniCash::fCustID ) ); // Validator für die Kundennnummer _valItemNo.setRegularExpression( QRegularExpression( miniCash::fItemNo ) ); // Validator für die Kundennnummer; // Validator für die laufende Nummer des Artikels _valPrice.setRegularExpression( QRegularExpression( miniCash::fPrice ) ); // Validator für die Kundennnummer; // Validator für die Preisangabe _ui->_trSellerID->setValidator( &_valCustId ); _ui->_trItemNo->setValidator( &_valItemNo ); _ui->_trPrice->setValidator( &_valPrice ); // Doppelklick auf einen Eintrag in der View soll diesen löschen connect( _ui->_trList, SIGNAL( doubleClicked(QModelIndex) ), this, SLOT( onRemoveEntry(QModelIndex)) ); // hosianna : key event handling ist gar nicht nötig QShortcut* shortcutPayback = new QShortcut( QKeySequence( Qt::Key_F1 ), this ); QShortcut* shortcutSave = new QShortcut( QKeySequence( Qt::Key_F12 ), this ); connect( shortcutPayback, SIGNAL(activated()), this, SLOT( onCalculatePayback()) ); connect( shortcutSave, SIGNAL(activated()), _parent, SLOT( onSaveTransaction()) ); // Alle Transaktionen sichern connect( _ui->_trOK, SIGNAL(clicked()), _parent, SLOT( onSaveTransaction()) ); // Felder auch mit Enter weiterschalten connect( _ui->_trSellerID, SIGNAL(returnPressed()), this, SLOT( onMoveInputFocus()) ); connect( _ui->_trItemNo, SIGNAL(returnPressed()), this, SLOT( onMoveInputFocus()) ); // Transaktion fertig eingegeben? Dann prüfen connect( _ui->_trPrice, SIGNAL(editingFinished()),this, SLOT( onAddSalesItem()) ); _ui->_trPos->setText( "1" ); _ui->_trCount->setText( _parent->transCount() ); } /** * @brief Eingabefelder per Enter weiterschalten * * Die Eingabefelder (Kundennummer, laufende Nummer etc. ) sollen nicht nur per TAB * sondern auch per ENTER weitergeschaltet werden, also wird das Signal "returnPressed" * eingefangen und der Focus an das jeweils nächste Eingabeelement weitergereicht. */ void MCInputView::onMoveInputFocus() { QWidget* sigsender = dynamic_cast( sender() ); if( sigsender ) sigsender->nextInFocusChain()->setFocus(); } /** * @brief einen verkauften Artikel speichern * * Wird aufgerufen wenn ein verkaufter Artikel fertig eingegeben ist * (sprich: wenn das Preisfeld den Fokus verliert oder Enter gedrückt wird). * Nach erfolgreicher Überprüfung der Eingaben wird ein neuer Eintrag in die * Transaktionliste geschrieben. */ void MCInputView::onAddSalesItem() { /// murx, präventiv _ui->_trList->clearSelection(); QString custID = _ui->_trSellerID->text(); QString itemNo = _ui->_trItemNo->text(); QString price = _ui->_trPrice->text(); /// TODO: /// Bei Fehlern: /// - message im statusbar /// - feld dg rot, focus /// - tönchen /// _kein_ popup int pos = 0; if ( custID.isEmpty() || itemNo.isEmpty() || price.isEmpty() || _valCustId.validate( custID, pos ) != QValidator::Acceptable || _valItemNo.validate( itemNo, pos ) != QValidator::Acceptable || _valPrice.validate( price, pos ) != QValidator::Acceptable ) { QApplication::beep(); return; } /// den neuen Eintrag in der schicken liste speichern & anzeigen ... _salesModel->appendEntry( _parent->transCount(), custID, itemNo, price ); /// Die Liste Runterscrollen damit der Beitrag auch sichtbar wird _ui->_trList->scrollToBottom(); /// ... und die Lineedits wieder löschen ... _ui->_trSellerID->clear(); _ui->_trItemNo->clear(); _ui->_trPrice->clear(); /// positionscount hochzählen _ui->_trPos->setText( QString( "%0" ).arg( ++_poscount ) ); /// und die gesamtsumme sichern _overallSum += MCSalesModel::fromCurrency( price ); _ui->_trOverall->setText( MCSalesModel::toCurrency( _overallSum ) ); _ui->_trSellerID->setFocus(); } /** * @brief Das Rückgeld berechnen * * Zeigt einen einfachen Dialog, um das Rückgeld zu berechnen. */ void MCInputView::onCalculatePayback() { bool ok; double amount = QInputDialog::getDouble ( this, "Rückgeld berechnen", "Welchen Betrag haben Sie erhalten?", 0, 0, 1000, 2, &ok ); if( ok ) { QString ret( "Das Rückgeld beträgt: %0"); QMessageBox::information( this, "Rückgeld", ret.arg( MCSalesModel::toCurrency( amount - _overallSum ) ) ); } } /** * @brief einen Artikel per Doppelklick aus der * Verkaufsliste entfernen * @param idx * * Einen Verkaufseintrag per Doppelklick auf die entsprechende Zeile * in der View löschen. Die Gesamtsumme und die Positionszähler müssen * entsprechend angepasst werden. * */ void MCInputView::onRemoveEntry( QModelIndex idx ) { // murx, translate QMessageBox msg; msg.setWindowTitle( "Eintrag löschen" ); msg.setText( "Soll dieser Eintrag wirklich gelöscht werden?" ); msg.setStandardButtons(QMessageBox::Yes | QMessageBox::No); msg.addButton( "Ja", QMessageBox::YesRole); msg.addButton("Nein", QMessageBox::NoRole ); msg.setDefaultButton(QMessageBox::Yes); msg.setIcon ( QMessageBox::Question ); _ui->_trList->clearSelection(); if( msg.exec() == QMessageBox::No ) return; // die gesamtsumme anpassen QVariant var = _salesModel->item( idx.row(), 3 )->data( Qt::DisplayRole ); double price = MCSalesModel::fromCurrency( var.toString() ); double newprice = _overallSum - price; // oops we did it again ... _salesModel->removeRow( idx.row() ); // recalc maxpos _ui->_trPos->setText( QString( "%0" ).arg( --_poscount ) ); // neue summe _ui->_trOverall->setText( MCSalesModel::toCurrency( newprice ) ); _overallSum = newprice; _ui->_trList->clearSelection(); } /** * @brief Die Eingabemaske zurücksetzen * * Setzt die Eingabemaske nach einer Kundentransaktion zurück, * erhöht die internen Zähler und zeigt diese an. */ void MCInputView::onResetView() { _ui->_trSellerID->clear(); _ui->_trItemNo->clear(); _ui->_trPrice->clear(); // Gesamtsumme nicht vergessen _ui->_trOverall->setText( MCSalesModel::toCurrency( 0 ) ); // Zähler anzeigen _ui->_trCount->setText( _parent->transCount() ); _ui->_trPos->setText( "1" ); _overallSum = 0.0; _salesModel->removeRows( 0, _salesModel->rowCount() ); }