Files
miniCashAll/libMiniCash/mcinputview.cpp
2025-08-05 22:37:51 +02:00

275 lines
8.0 KiB
C++

/***************************************************************************
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 <QInputDialog>
#include <QMessageBox>
#include <QShortcut>
#include <mcinputview.h>
#include <mcmainwindowbase.h>
#include <mcsalesmodel.h>
#include <ui_mcinputview.h>
/**
* 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<QWidget*>( 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() );
}