The <tt>setcustomer</tt> transaction is used to set details of the customer. The request contains a customer XML object as listed above, but without the mail attribute. The response is empty.
+<h3>Deleting and Merging Customers</h3>
+
+The <tt>deletecustomer</tt> transaction can be used to attempt to delete a customer from the database. It will fail if this customer still has any data (eg. orders) stored in the database. The request contains the ID of the customer to be deleted. The request may optionally contain a second customer ID separated from the first with a single space - if it does, the first customer is merged into the second one. The response is empty.<p>
+
+If customers are merged, the following rules are executed:
+<ul>
+<li>the first ID is the one to be deleted
+<li>all database objects (orders, tickets, vouchers, etc.pp.) of the first customer ID are transferred to the second one
+<li>all customer data (name, address, etc.) of the second customer ID is preserved, while the data of the first ID is deleted
+<li>exception: if the second ID has no web-login associated with it, but the first one does, then the login is re-assigned to the second ID before the first ID is deleted
+</ul>
<!-- ************************************************************************************
************************************************************************************
#include "webrequest.h"
#include <QBoxLayout>
+#include <QCheckBox>
+#include <QComboBox>
#include <QDomElement>
#include <QGridLayout>
#include <QLabel>
#include <QLineEdit>
#include <QListView>
+#include <QMessageBox>
#include <QPushButton>
#include <QStandardItemModel>
#include <QTextEdit>
connect(p,SIGNAL(clicked()),this,SLOT(editCustomer()));
vl2->addWidget(p=new QPushButton(tr("Create new...")),0);
connect(p,SIGNAL(clicked()),this,SLOT(newCustomer()));
+ p->setEnabled(m_req->hasRole("setcustomer"));
vl2->addWidget(p=new QPushButton(tr("Delete...")),0);
connect(p,SIGNAL(clicked()),this,SLOT(deleteCustomer()));
- p->setEnabled(false);
+ p->setEnabled(m_req->hasRole("deletecustomer"));
vl2->addStretch(2);
vl->addSpacing(15);
vl->addLayout(hl=new QHBoxLayout,0);
//get selection
QModelIndex idx=m_listview->currentIndex();
if(!idx.isValid())return;
- //return object
- int i=m_listmodel->data(idx,Qt::UserRole).toInt();
- if(i<0||i>=m_list.size())return;
- //TODO: delete it
-
+ //get pointer to customer
+ int dusr=m_listmodel->data(idx,Qt::UserRole).toInt();
+ if(dusr<0||dusr>=m_list.size())return;
+ //show delete dialog
+ QDialog d;
+ d.setWindowTitle(tr("Delete Customer"));
+ QVBoxLayout*vl;
+ d.setLayout(vl=new QVBoxLayout);
+ vl->addWidget(new QLabel(tr("Really delete this customer (%1)?").arg(m_listmodel->data(idx).toString())));
+ vl->addSpacing(20);
+ QCheckBox*cb;
+ vl->addWidget(cb=new QCheckBox(tr("merge with other entry:")));
+ QComboBox*cm;
+ vl->addWidget(cm=new QComboBox);
+ cm->setModel(m_listmodel);
+ cm->setEnabled(cb->isEnabled());
+ connect(cb,SIGNAL(toggled(bool)),cm,SLOT(setEnabled(bool)));
+ vl->addSpacing(20);
+ vl->addStretch(10);
+ QHBoxLayout*hl;
+ vl->addLayout(hl=new QHBoxLayout);
+ hl->addStretch(10);
+ QPushButton*p;
+ hl->addWidget(p=new QPushButton(tr("&Yes")));
+ connect(p,SIGNAL(clicked()),&d,SLOT(accept()));
+ hl->addWidget(p=new QPushButton(tr("&No")));
+ connect(p,SIGNAL(clicked()),&d,SLOT(reject()));
+ if(d.exec()!=QDialog::Accepted)return;
+ //compose request
+ QString rd=QString::number(m_list[dusr].customerID());
+ if(cb->isChecked()){
+ int musr=m_listmodel->data(m_listmodel->index(cm->currentIndex(),0),Qt::UserRole).toInt();
+ rd+=" ";
+ rd+=QString::number(m_list[musr].customerID());
+ }
+ //delete it
+ if(!m_req->request("deletecustomer",rd.toAscii())){
+ QMessageBox::warning(this,tr("Error"),tr("Failed to delete customer."));
+ return;
+ }
+ if(m_req->responseStatus()!=MWebRequest::Ok){
+ QMessageBox::warning(this,tr("Error"),tr("Failed to delete customer: %1").arg(tr(m_req->responseBody())));
+ return;
+ }
+ //update view
+ updateList();
}
{
getCustomer();
m_cust.save();
-}
\ No newline at end of file
+}
}
}
+/**machine interface: delete or merge customers*/
+function deleteCustomerXml($txt)
+{
+ global $db;
+ //find customer and mergee ID
+ $lst=explode(" ",trim($txt));
+ if($lst===false || count($lst)<1){
+ header("X-MagicSmoke-Status: Error");
+ echo tr("Cannot find customer ID to delete.");
+ return;
+ }
+ $cust=$lst[0]+0;
+ if(!is_numeric($lst[0]) || $cust < 0){
+ header("X-MagicSmoke-Status: Error");
+ echo tr("Invalid Customer ID, cannot delete.");
+ return;
+ }
+ $mrg=false;
+ if(count($lst)>1){
+ $mrg=$lst[1]+0;
+ if(!is_numeric($lst[1]) || $mrg < 0){
+ header("X-MagicSmoke-Status: Error");
+ echo tr("Invalid Customer ID, cannot merge.");
+ return;
+ }
+ }
+ //start transaction
+ $db->beginTransaction();
+ //find both IDs
+ $res=$db->select("customer","customerid","customerid=".$db->escapeInt($cust));
+ if($res===false || count($res)<1){
+ header("X-MagicSmoke-Status: Error");
+ echo tr("Cannot find Customer ID, cannot delete.");
+ $db->rollbackTransaction();
+ return;
+ }
+ if($mrg!==false){
+ $res=$db->select("customer","customerid","customerid=".$db->escapeInt($mrg));
+ if($res===false || count($res)<1){
+ header("X-MagicSmoke-Status: Error");
+ echo tr("Cannot find Customer ID, cannot delete.");
+ $db->rollbackTransaction();
+ return;
+ }
+ }
+ //cancel all sessions of deletee
+ $db->deleteRows("websession","customerid=".$db->escapeInt($cust));
+ //if merge:
+ if($mrg!==false){
+ //rewrite DB objects (orders)
+ $b=$db->update("order",array("customerid"=>$mrg),"customerid=".$db->escapeInt($cust))!==false;
+ //merge web-account; delete if another exists, otherwise move it
+ $res=$db->select("webuser","customerid","customerid=".$db->escapeInt($mrg));
+ if($res===false || count($res)<1){
+ $b&=$db->update("webuser",array("customerid"=>$mrg),"customerid=".$db->escapeInt($cust))!==false;
+ }else{
+ $db->deleteRows("webuser","customerid=".$db->escapeInt($cust));
+ }
+ //check success
+ if(!$b){
+ header("X-MagicSmoke-Status: Error");
+ echo tr("Cannot merge customers.");
+ $db->rollbackTransaction();
+ return;
+ }
+ }
+ //attempt deletion
+ $b=$db->deleteRows("webuser","customerid=".$db->escapeInt($cust))!==false;
+ $b&=$db->deleteRows("customer","customerid=".$db->escapeInt($cust))!==false;
+ if(!$b){
+ header("X-MagicSmoke-Status: Error");
+ echo tr("Cannot delete customer.");
+ $db->rollbackTransaction();
+ return;
+ }
+ //success!
+ $db->commitTransaction();
+ header("X-MagicSmoke-Status: Ok");
+}
+
?>
\ No newline at end of file
{
$b=mysqli_query($this->dbhdl,$this->sqlDelete($table,$where));
// echo mysqli_error($this->dbhdl);
- if($b)return mysqli_affected_rows($this->dbhdl);
+ if($b!==false)return mysqli_affected_rows($this->dbhdl);
else return false;
}
tr("gethosts"),tr("sethost"),tr("addhost"),tr("deletehost"), //host management
tr("geteventlist"),tr("geteventdata"),tr("seteventdata"),tr("eventsummary"),tr("cancelevent"),//event infos
tr("getroomdata"),tr("setroomdata"),//room infos
- tr("getcustomerlist"),tr("getcustomer"),tr("setcustomer"), //customer info
+ tr("getcustomerlist"),tr("getcustomer"),tr("setcustomer"),tr("deletecustomer"), //customer info
tr("checkorder"),tr("createorder"),tr("createsale"),tr("getorderlist"),tr("getorder"),tr("orderpay"),tr("orderrefund"),tr("ordershipped"),tr("cancelorder"),tr("orderbyticket"),tr("getordersbyevents"),tr("setordercomment"), //sell/order stuff
tr("getticket"),tr("useticket"),tr("changeticketprice"),tr("ticketreturn"),//ticket management
tr("gettemplatelist"),tr("gettemplate"),tr("settemplate") //templates
exit();
}
+//delete/merge a specific customer
+if($SMOKEREQUEST=="deletecustomer"){
+ deleteCustomerXml($REQUESTDATA);
+ exit();
+}
+
//check that the order can be executed
if($SMOKEREQUEST=="checkorder"){
createOrderXml($REQUESTDATA,"check");