add payment types
authorKonrad Rosenbaum <konrad@silmor.de>
Sat, 31 Dec 2011 17:57:43 +0000 (18:57 +0100)
committerKonrad Rosenbaum <konrad@silmor.de>
Sat, 31 Dec 2011 17:57:43 +0000 (18:57 +0100)
src/dialogs/orderwin.cpp
src/dialogs/payedit.cpp
src/dialogs/payedit.h
wob/db/user.wolf
wob/transact/order.wolf
www/inc/wext/order.php

index fe45e70..1953906 100644 (file)
 //
 
 #include "centbox.h"
+#include "customerdlg.h"
 #include "labeldlg.h"
 #include "misc.h"
+#include "msinterface.h"
 #include "odtrender.h"
 #include "orderauditdlg.h"
 #include "orderwin.h"
-#include "ticketrender.h"
-#include "msinterface.h"
+#include "payedit.h"
 #include "templates.h"
-#include "customerdlg.h"
+#include "ticketrender.h"
 
 #include "MOEvent"
 
@@ -701,18 +702,27 @@ void MOrderWindow::initPrintBuffer()
 void MOrderWindow::payment()
 {
        //get value
-       bool ok;
-       int pay=MCentDialog::getCents(this,tr("Enter Payment"),tr("Please enter the amount that has been paid:"),m_order.amountToPay(),m_order.amountToPay(),&ok);
-       if(!ok)return;
+       MPaymentDialog pd(this);
+       pd.setMaximum(m_order.amountToPay());
+       pd.setValue(m_order.amountToPay());
+       if(pd.exec()!=QDialog::Accepted)return;
+       int pay=pd.value();
        if(pay<=0)return;
        //submit
-       MTOrderPay op=req->queryOrderPay(m_order.orderid(),pay,"","");
+       MTOrderPay op=req->queryOrderPay(m_order.orderid(),pay,pd.paytype(),pd.paydata());
        if(op.hasError()){
                QMessageBox::warning(this,tr("Warning"),tr("Error while trying to pay: %1").arg(op.errorString()));
                return;
        }
        m_order=op.getorder();
        updateData();
+       //tell user if less money was required
+       if(op.getamount()<pay)
+               QMessageBox::information(this,tr("Payment Info"),
+                  tr("Payment successful, but only %1 was required, please hand back the remaining %2.")
+                  .arg(cent2str(op.getamount()))
+                  .arg(cent2str(pay-op.getamount()))
+               );
 }
 
 void MOrderWindow::payvoucher()
index 2abf9d4..b561e5b 100644 (file)
@@ -18,6 +18,7 @@
 #include "msinterface.h"
 
 #include <QApplication>
+#include <QDebug>
 #include <QDomDocument>
 #include <QDomElement>
 #include <QFormLayout>
 #include <QMessageBox>
 #include <QInputDialog>
 #include <QBoxLayout>
+#include <QComboBox>
+
+static QList<MOPaymentType> getPayTypeCache(bool force=false);
+static QString getDefaultPayType(bool force=false);
+static void invalidatePayTypeCache();
+
+//+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
+// payment type editor
 
 MPaymentEditor::MPaymentEditor(QWidget*par)
        :QDialog(par)
 {
-       all=req->queryGetPaymentTypes().getpaytypes();
+       all=getPayTypeCache(true);
        setWindowTitle(tr("Edit Payment Options"));
        setSizeGripEnabled(true);
        
-       QHBoxLayout*hl;
+       QHBoxLayout*hl,*hl2;
        QVBoxLayout*vl,*vl2;
        setLayout(vl=new QVBoxLayout);
        vl->addLayout(hl=new QHBoxLayout,1);
-       hl->addWidget(table=new QTableView,1);
+       hl->addLayout(vl2=new QVBoxLayout);
+       vl2->addWidget(table=new QTableView,1);
        table->setModel(model=new QStandardItemModel(this));
        table->setEditTriggers(QAbstractItemView::NoEditTriggers);
        table->verticalHeader()->hide();
        updateTable();
+       vl2->addLayout(hl2=new QHBoxLayout);
+       hl2->addWidget(new QLabel(tr("Default Payment Type:")));
+       hl2->addWidget(deftype=new QLabel(getDefaultPayType()),1);
        hl->addLayout(vl2=new QVBoxLayout,0);
        QPushButton*p;
+       bool b=req->hasRight(req->RSetPaymentType);
        vl2->addWidget(p=new QPushButton(tr("Change Description")));
        connect(p,SIGNAL(clicked()),this,SLOT(changeDescription()));
+       p->setEnabled(b);
        vl2->addWidget(p=new QPushButton(tr("Change Data")));
        connect(p,SIGNAL(clicked()),this,SLOT(changeData()));
+       p->setEnabled(b);
        vl2->addWidget(p=new QPushButton(tr("Change Flags")));
        connect(p,SIGNAL(clicked()),this,SLOT(changeAvail()));
+       p->setEnabled(b);
+       vl2->addWidget(p=new QPushButton(tr("Change Default")));
+       connect(p,SIGNAL(clicked()),this,SLOT(changeDefault()));
+       p->setEnabled(req->hasRight(req->RSetDefaultPaymentType));
        vl2->addSpacing(20);
        vl2->addWidget(p=new QPushButton(tr("Add Option")));
        connect(p,SIGNAL(clicked()),this,SLOT(addNew()));
+       p->setEnabled(b);
        vl2->addWidget(p=new QPushButton(tr("Delete Option")));
        connect(p,SIGNAL(clicked()),this,SLOT(deletePay()));
+       p->setEnabled(req->hasRight(req->RDeletePaymentType));
        vl2->addStretch(1);
        
        vl->addSpacing(15);
        vl->addLayout(hl=new QHBoxLayout,0);
        hl->addStretch(10);
-       hl->addWidget(p=new QPushButton(tr("Ok")));
+       hl->addWidget(p=new QPushButton(tr("Close")));
        connect(p,SIGNAL(clicked()),this,SLOT(accept()));
-       hl->addWidget(p=new QPushButton(tr("Cancel")));
-       connect(p,SIGNAL(clicked()),this,SLOT(reject()));
 }
 void MPaymentEditor::updateTable()
 {
@@ -104,6 +124,7 @@ void MPaymentEditor::changeDescription()
        }
        all[idx.row()]=cs.getpaytype();
        updateTable();
+       invalidatePayTypeCache();
 }
 
 void MPaymentEditor::changeData()
@@ -148,6 +169,7 @@ void MPaymentEditor::changeData()
        }
        all[idx.row()]=cs.getpaytype();
        updateTable();
+       invalidatePayTypeCache();
 }
 void MPaymentEditor::changeAvail()
 {
@@ -167,7 +189,52 @@ void MPaymentEditor::changeAvail()
        }
        all[idx.row()]=s;
        updateTable();
+       invalidatePayTypeCache();
 }
+
+void MPaymentEditor::changeDefault()
+{
+       //dialog
+       QDialog d(this);
+       d.setWindowTitle(tr("Set Default Payment Type"));
+       QVBoxLayout*vl;
+       d.setLayout(vl=new QVBoxLayout);
+       vl->addWidget(new QLabel("Please chose a default payment type:"));
+       QComboBox*box;
+       vl->addWidget(box=new QComboBox);
+       box->setModel(model);
+       QString cdef=deftype->text();
+       for(int i=0;i<model->rowCount();i++){
+               if(model->data(model->index(i,0)).toString()==cdef)
+                       box->setCurrentIndex(i);
+       }
+       vl->addSpacing(15);
+       vl->addStretch(1);
+       QHBoxLayout*hl;
+       vl->addLayout(hl=new QHBoxLayout);
+       hl->addStretch(1);
+       QPushButton*p;
+       hl->addWidget(p=new QPushButton(tr("Ok")));
+       connect(p,SIGNAL(clicked()),&d,SLOT(accept()));
+       hl->addWidget(p=new QPushButton(tr("Cancel")));
+       connect(p,SIGNAL(clicked()),&d,SLOT(reject()));
+       if(d.exec()!=QDialog::Accepted)return;
+       //get the new default
+       QString ndef=box->currentText();
+       if(ndef==cdef)return;
+       //check for flags
+       if(model->data(model->index(box->currentIndex(),4)).toString().trimmed()!="")
+               QMessageBox::warning(this, tr("Warning"), tr("The payment type '%1' has flags set, it may not be usable for every user, please consider removing those flags.").arg(ndef));
+       //actually set it
+       MTSetDefaultPaymentType dpt=req->querySetDefaultPaymentType(ndef);
+       if(dpt.hasError())
+               QMessageBox::warning(this,tr("Warning"),tr("Unable to set the new default: %1").arg(dpt.errorString()));
+       else{
+               deftype->setText(ndef);
+               invalidatePayTypeCache();
+       }
+}
+
 void MPaymentEditor::addNew()
 {
        //get new values
@@ -183,7 +250,7 @@ void MPaymentEditor::addNew()
        fl->addRow(tr("Description:"),descr=new QLineEdit);
        fl->addRow(tr("Data Name (human readable):"),dname=new QLineEdit);
        fl->addRow(tr("Data Default (pattern):"),dpat=new QLineEdit);
-       fl->addRow(new QLabel(tr("Hint: %Y=year, %M=month, %D=day, %%=%-sign, %O=order ID, %U=user")));
+       fl->addRow(new QLabel(tr("Hint: %Y=year, %M=month, %D=day, %H=hour(0..23), %h=hour(1..12), %m=minute, %a=AM/PM, %%=%-sign")));
        MFlagWidget*flgw;
        fl->addRow(tr("Flags:"),flgw=new MFlagWidget);
        flgw->setEditorLabel(tr("Edit flags of the new payment option:"));
@@ -212,6 +279,7 @@ void MPaymentEditor::addNew()
        }
        all.append(cs.getpaytype());
        updateTable();
+       invalidatePayTypeCache();
 }
 
 void MPaymentEditor::deletePay()
@@ -232,4 +300,151 @@ void MPaymentEditor::deletePay()
        }
        all.removeAt(idx.row());
        updateTable();
+       invalidatePayTypeCache();
+}
+
+
+//+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
+
+MPaymentDialog::MPaymentDialog(QWidget* parent, Qt::WindowFlags f): QDialog(parent, f)
+{
+       setWindowTitle(tr("Payment"));
+       QFormLayout*fl;
+       setLayout(fl=new QFormLayout);
+       fl->addRow(new QLabel(tr("Please enter the payment data below.")));
+       fl->addRow(tr("Amount paid:"),m_cent=new MCentSpinBox);
+       fl->addRow(tr("Payment Type:"),m_ptype=new QComboBox);
+       connect(m_ptype,SIGNAL(currentIndexChanged(int)),this,SLOT(setPType()));
+       fl->addRow(m_dlabel=new QLabel(tr("Data?:")),m_data=new QLineEdit);
+       fl->addRow(new QLabel("  "));
+       QHBoxLayout*hl;
+       fl->addRow(hl=new QHBoxLayout);
+       hl->addStretch(1);
+       QPushButton*p;
+       hl->addWidget(p=new QPushButton(tr("Ok")));
+       connect(p,SIGNAL(clicked()),this,SLOT(accept()));
+       hl->addWidget(p=new QPushButton(tr("Cancel")));
+       connect(p,SIGNAL(clicked()),this,SLOT(reject()));
+       
+       setSizeGripEnabled(true);
+       
+       //preset ptype
+       QList<MOPaymentType>pt=getPayTypeCache();
+       QString dp=getDefaultPayType();
+       int idx=0;
+       foreach(MOPaymentType p,pt){
+               if(req->checkFlags(p.flags())){
+                       m_ptype->addItem(p.name(),QVariant::fromValue<MOPaymentType>(p));
+                       if(p.name()==dp)idx=m_ptype->count()-1;
+               }
+       }
+       m_ptype->setCurrentIndex(idx);
+       
+       //update
+       setPType();
+}
+
+void MPaymentDialog::setMaximum(qint64 m)
+{
+       m_cent->setRange(0,m);
+}
+
+void MPaymentDialog::setValue(qint64 v)
+{
+       m_cent->setValue(v);
+}
+
+qint64 MPaymentDialog::value() const
+{
+       return m_cent->value();
+}
+
+QString MPaymentDialog::paytype() const
+{
+       return m_ptype->currentText();
+}
+
+QString MPaymentDialog::paydata() const
+{
+       if(m_data->isEnabled())return m_data->text();
+       else return QString();
+}
+
+void MPaymentDialog::setPType()
+{
+       //get the data
+       MOPaymentType pt=m_ptype->itemData(m_ptype->currentIndex()).value<MOPaymentType>();
+       //do we have a data name?
+       if(pt.dataname().value().trimmed().isEmpty()){
+               m_dlabel->setText("...");
+               m_data->setText("");
+               m_data->setEnabled(false);
+               return;
+       }
+       //normal setting
+       m_dlabel->setText(pt.dataname()+":");
+       m_data->setEnabled(true);
+       //calculate and set pattern
+       QString dtxt,dpat=pt.datapreset();
+       bool isperc=false;
+       foreach(QChar c,dpat){
+               if(isperc){
+                       switch(c.toAscii()){
+                               case '%':dtxt+='%';break;
+                               case 'Y':dtxt+=QString::number(QDate::currentDate().year());break;
+                               case 'M':dtxt+=QDate::currentDate().toString("MM");break;
+                               case 'D':dtxt+=QDate::currentDate().toString("dd");break;
+                               case 'H':dtxt+=QTime::currentTime().toString("HH");break;
+                               case 'h':dtxt+=QTime::currentTime().toString("hh ap").split(" ").at(0);break;
+                               case 'm':dtxt+=QTime::currentTime().toString("mm");break;
+                               case 'a':dtxt+=QTime::currentTime().toString("ap");break;
+                               default:dtxt+='%';dtxt+=c;break;
+                       }
+                       isperc=false;
+               }else{
+                       if(c=='%')isperc=true;
+                       else dtxt+=c;
+               }
+       }
+       if(isperc)dtxt+='%';
+       m_data->setText(dtxt);
+}
+
+
+//+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
+// cache of payment types, used by payment dialog
+
+static QList<MOPaymentType> c_paytypes;
+static QString c_defpay;
+static QDateTime c_nextupdate;
+
+static QList<MOPaymentType> getPayTypeCache(bool force)
+{
+       if(!force){
+               if(!c_nextupdate.isValid() || c_nextupdate <= QDateTime::currentDateTime())
+                       force=true;
+       }
+       if(!force)return c_paytypes;
+       //get data
+       MTGetPaymentTypes gpt=req->queryGetPaymentTypes();
+       if(gpt.hasError())
+               qDebug()<<"Warning: unable to fetch payment type data:"<<gpt.errorString();
+       else{
+               c_paytypes=gpt.getpaytypes();
+               c_defpay=gpt.getdefaultpaytype();
+               c_nextupdate=QDateTime::currentDateTime().addSecs(300);
+       }
+       //return it
+       return c_paytypes;
+}
+static QString getDefaultPayType(bool force)
+{
+       //use above for getting data
+       getPayTypeCache(force);
+       //return data
+       return c_defpay;
+}
+static void invalidatePayTypeCache()
+{
+       c_nextupdate=QDateTime();
 }
index a25da50..0895e00 100644 (file)
 #include <QString>
 #include <QDialog>
 
+class QLabel;
+class QComboBox;
+class QLineEdit;
+class MCentSpinBox;
 class QStandardItemModel;
 class QTableView;
 
 #include "MOPaymentType"
 
+///an editor for payment types, this is a direct interface to the paymenttype table on the server side
 class MPaymentEditor:public QDialog
 {
        Q_OBJECT
        public:
+               ///instantiate the editor
                MPaymentEditor(QWidget*);
        
        private slots:
+               /// \internal change the description of the paytype
                void changeDescription();
+               /// \internal change the data type of the paytype
                void changeData();
+               /// \internal change the flags of the paytype
                void changeAvail();
+               /// \internal change the default paytype
+               void changeDefault();
+               /// \internal create a new paytype
                void addNew();
+               /// \internal delete a paytype
                void deletePay();
+               /// \internal update the table of paytypes
                void updateTable();
                
        private:
                QList<MOPaymentType>all;
                QStandardItemModel*model;
                QTableView*table;
+               QLabel*deftype;
+};
+
+///simple dialog to enter payment data
+class MPaymentDialog:public QDialog
+{
+       Q_OBJECT
+       public:
+               ///instantiate the dialog
+               MPaymentDialog(QWidget* parent = 0, Qt::WindowFlags f = 0);
+               
+               ///returns the currently set money value in cents
+               qint64 value()const;
+               
+               ///returns the selected payment type
+               QString paytype()const;
+               ///returns the currently entered payment data
+               QString paydata()const;
+               
+       public slots:
+               ///set the current money value in cents
+               void setValue(qint64);
+               ///set the maximum that can be entered
+               void setMaximum(qint64);
+               
+       private slots:
+               /// \internal update the data fields
+               void setPType();
+       private:
+               MCentSpinBox*m_cent;
+               QComboBox*m_ptype;
+               QLineEdit*m_data;
+               QLabel*m_dlabel;
 };
 
 #endif
index 94e46fb..0df860a 100644 (file)
                <Preset><V col="rolename" val="OrderHighPrivilege"/><V col="rightname" val="ChangeOrderAddress"/></Preset>
                <Preset><V col="rolename" val="OrderHighPrivilege"/><V col="rightname" val="GetMyOrders"/></Preset>
                <Preset><V col="rolename" val="OrderHighPrivilege"/><V col="rightname" val="GetOrdersByUser"/></Preset>
+               <Preset><V col="rolename" val="OrderHighPrivilege"/><V col="rightname" val="GetPaymentTypes"/></Preset>
+               <Preset><V col="rolename" val="OrderHighPrivilege"/><V col="rightname" val="SetPaymentType"/></Preset>
+               <Preset><V col="rolename" val="OrderHighPrivilege"/><V col="rightname" val="SetDefaultPaymentType"/></Preset>
+               <Preset><V col="rolename" val="OrderHighPrivilege"/><V col="rightname" val="DeletePaymentType"/></Preset>
                <Preset><V col="rolename" val="OrderListing"/><V col="rightname" val="GetOrder"/></Preset>
                <Preset><V col="rolename" val="OrderListing"/><V col="rightname" val="GetOrderByBarcode"/></Preset>
                <Preset><V col="rolename" val="OrderListing"/><V col="rightname" val="GetOrderList"/></Preset>
                <Preset><V col="rolename" val="OrderMoney"/><V col="rightname" val="OrderPay"/></Preset>
                <Preset><V col="rolename" val="OrderMoney"/><V col="rightname" val="OrderRefund"/></Preset>
                <Preset><V col="rolename" val="OrderMoney"/><V col="rightname" val="UseVoucher"/></Preset>
+               <Preset><V col="rolename" val="OrderMoney"/><V col="rightname" val="GetPaymentTypes"/></Preset>
                <Preset><V col="rolename" val="OrderTickets"/><V col="rightname" val="CreateOrder"/></Preset>
                <Preset><V col="rolename" val="OrderTickets"/><V col="rightname" val="CreateOrder:CanOrderTicket"/></Preset>
                <Preset><V col="rolename" val="OrderVouchers"/><V col="rightname" val="CreateOrder"/></Preset>
index 921e8e6..21f1232 100644 (file)
        
        <Transaction name="GetPaymentTypes" update="no">
                <Doc>returns the valid payment types</Doc>
-               <Call lang="php" method="$this->setpaytypes(WOPaymentType::fromTableArraypaymenttype(WTpaymenttype::selectFromDB()));"/>
+               <Call lang="php" method="WOOrder::getPaymentTypesTransaction($this);"/>
                <Output>
                        <Var name="paytypes" type="List:PaymentType"/>
+                       <Var name="defaultpaytype" type="string"/>
                </Output>
        </Transaction>
        <Transaction name="SetPaymentType">
                        <Var name="paytype" type="PaymentType"/>
                </Output>
        </Transaction>
+       <Transaction name="SetDefaultPaymentType">
+               <Doc>sets the payment type that is used per default</Doc>
+               <Input>
+                       <Var name="defaultpaytype" type="string"/>
+               </Input>
+               <Call lang="php" method="WOOrder::setDefaultPayTypeTransaction($this);"/>
+               <Output>
+                       <Var name="defaultpaytype" type="PaymentType"/>
+               </Output>
+       </Transaction>
        <Transaction name="DeletePaymentType">
                <Doc>deletes a payment type</Doc>
                <Input>
index 266cdce..e20881c 100644 (file)
@@ -334,10 +334,30 @@ class WOOrder extends WOOrderAbstract
                        $trans->setamount(0);
                        return;
                }
+               //check payment type
+               $ptype=$trans->getpaytype();
+               $ptn=count(WTpaymenttype::selectFromDB());
+               if($ptn==0){
+                       //none configured, just use the data
+                       $ord->paydata=$trans->getpaydata();
+               }else{
+                       //get the one specified
+                       $pt=WTpaymenttype::getFromDB($ptype);
+                       if(!is_a($pt,"WTpaymenttype")){
+                               $trans->abortWithError(tr("unknown payment type"));
+                               return;
+                       }
+                       global $session;
+                       if(!$session->checkFlags($pt->flags)){
+                               $trans->abortWithError(tr("you are not allowed to use this payment type"));
+                               return;
+                       }
+                       $ord->paytype=$ptype;
+                       if(strlen($pt->dataname)>0)
+                               $ord->paydata=$trans->getpaydata();
+               }
                //make corrections
                $ord->amountpaid+=$pay;
-               $ord->paytype=$trans->getpaytype();
-               $ord->paydata=$trans->getpaydata();
                $ord->update();
                //return (redo object conversion: calculated data has changed!)
                $trans->setorder(WOOrder::fromTableorder($ord));
@@ -843,6 +863,14 @@ class WOOrder extends WOOrderAbstract
                $trans->setorder(WOOrder::fromTableorder(WTorder::getFromDB($oid)/*$ord*/));
        }
        
+       static public function getPaymentTypesTransaction($trans)
+       {
+               $pts=WOPaymentType::fromTableArraypaymenttype(WTpaymenttype::selectFromDB());
+               $trans->setpaytypes($pts);
+               global $db;
+               $trans->setdefaultpaytype($db->getConfig("defaultpaytype"));
+       }
+       
        static public function setPayTypeTransaction($trans)
        {
                $pt=$trans->getpaytype();
@@ -872,6 +900,21 @@ class WOOrder extends WOOrderAbstract
                //delete
                $ptt->deleteFromDb();
        }
+       
+       static public function setDefaultPayTypeTransaction($trans)
+       {
+               global $db;
+               //check that the type exists
+               $dpt=$trans->getdefaultpaytype();
+               $pt=WTpaymenttype::getFromDB($dpt);
+               if(!is_a($pt,"WTpaymenttype")){
+                       $trans->abortWithError(tr("The payment type does not exist, cannot set it as default."));
+                       return;
+               }
+               //set it
+               $db->setConfig("defaultpaytype",$dpt);
+               $trans->setdefaultpaytype(WOPaymentType::fromTablepaymenttype($pt));
+       }
 };
 
 ?>
\ No newline at end of file