The <tt>cancelorder</tt> transaction is used to mark an order as cancelled. It also marks all tickets inside the order as cancelled and voids any vouchers in it. This transaction is only legal for orders in the "placed" state.
+<h3>Searching for an Order</h3>
+
+The <tt>orderbyticket</tt> transaction can be used to find an order by a ticket ID from that order. The request contains the ticket ID, the response contains the order ID or returns as error if not found.
+
<!-- ************************************************************************************
************************************************************************************
************************************************************************************ -->
The <tt>changeticketprice</tt> transaction can be used to change the price of a ticket. The request contains the ticket-ID and the new price in cent separated by a newline. The response is empty.
+<h3>Returning Tickets</h3>
+
+The <tt>ticketreturn</tt> transaction can be used to return a ticket that has not been used yet. The request contains the ticket-ID, the response is empty.
+
<!-- ************************************************************************************
************************************************************************************
************************************************************************************ -->
{
for(int i=0;i<m_tickets.size();i++){
if(m_tickets[i].ticketID()==tid){
- int op=m_tickets[i].price();
+ int op=m_tickets[i].amountToPay();
m_tickets[i].updatePrice(price);
- int np=m_tickets[i].price();
+ int np=m_tickets[i].amountToPay();
m_price+=np-op;
}
}
}
+QString MOrder::ticketReturn(QString tid)
+{
+ for(int i=0;i<m_tickets.size();i++){
+ if(m_tickets[i].ticketID()==tid){
+ int op=m_tickets[i].amountToPay();
+ QString r=m_tickets[i].ticketReturn();
+ int np=m_tickets[i].amountToPay();
+ m_price+=np-op;
+ return r;
+ }
+ }
+ return QT_TRANSLATE_NOOP("MOrder","This ticket is not part of this order.");
+}
+
MOrder MOrder::createOrder(QString type)
{
///////////////
//update locally
m_price=p;
}
+
+QString MTicket::ticketReturn()
+{
+ if(!isStored())return QT_TRANSLATE_NOOP("MTicket","Ticket is not stored, can't return it.");
+ if(!req->request("ticketreturn",m_id.toUtf8()))
+ return QT_TRANSLATE_NOOP("MTicket","Failed to execute request");
+ if(req->responseStatus()!=MWebRequest::Ok)
+ return QString::fromUtf8(req->responseBody());
+ m_status=Refund;
+ return "";
+}
+
+int MTicket::amountToPay()const
+{
+ if(m_status==Bought || m_status==Used)return m_price;
+ else return 0;
+}
/**returns the price of the ticket as localized string*/
QString priceString()const;
+ /**returns the amount that is to be paid for this ticket; this is identical to the price if the ticket is bought or used, it is zero otherwise*/
+ int amountToPay()const;
+
/**returns the ID of the event the ticket belongs to*/
qint32 eventID()const;
/**updates the price of this ticket, calls DB*/
void updatePrice(int);
+ /**attempts to return the ticket; returns empty string on success, error message on failure*/
+ QString ticketReturn();
+
protected:
friend class MOrder;
/**sets the order-ID of the ticket, used by MOrder*/
/**used to update the price of a ticket, calls DB*/
void updateTicketPrice(QString,int);
+ /**used to cancel/return a ticket from this order; returns empty string on success, error message on failure*/
+ QString ticketReturn(QString);
+
/**create a new order in the DB; returns it*/
MOrder createOrder(QString type="createorder");
m->addSeparator();
m->addAction(tr("Ch&ange Ticket-Price..."),this,SLOT(changeTicket()))
->setEnabled(req->hasRole("changeticketprice"));
+ m->addAction(tr("&Return Ticket..."),this,SLOT(ticketReturn()))
+ ->setEnabled(req->hasRole("ticketreturn"));
m->addSeparator();
m->addAction(tr("&Close"),this,SLOT(close()));
m=mb->addMenu(tr("&Payment"));
updateTable();
}
+void MOrderWindow::ticketReturn()
+{
+ if(!m_order.isValid())return;
+ //get ticket selection
+ QModelIndexList lst=m_tickettable->selectionModel()->selectedIndexes();
+ if(lst.size()<1)return;
+ QModelIndex idx=m_ticketmodel->index(lst[0].row(),0);
+ QString id=m_ticketmodel->data(idx).toString();
+ if(id=="")return;
+ //find ticket
+ QList<MTicket>tickets=m_order.tickets();
+ MTicket tick;
+ for(int i=0;i<tickets.size();i++)
+ if(tickets[i].ticketID()==id)
+ tick=tickets[i];
+ if(!tick.isValid())return;
+ //check state
+ if(tick.status()!=MTicket::Bought && tick.status()!=MTicket::Reserved){
+ QMessageBox::warning(this,tr("Warning"),tr("This ticket cannot be returned, it has already been used or is in the wrong state."));
+ return;
+ }
+ //ask nicely
+ if(QMessageBox::question(this,tr("Return Ticket"),tr("Do you really want to return this ticket?"),QMessageBox::Yes|QMessageBox::No)!=QMessageBox::Yes)return;
+ //submit
+ QString r=m_order.ticketReturn(tick.ticketID());
+ m_total->setText(m_order.totalPriceString());
+ updateTable();
+ if(r!="")QMessageBox::warning(this,tr("Warning"),trUtf8(r.toUtf8()));
+}
+
void MOrderWindow::cancelOrder()
{
if(QMessageBox::question(this,tr("Cancel Order?"),tr("Cancel this order now?"),QMessageBox::Yes|QMessageBox::No,QMessageBox::Yes)!=QMessageBox::Yes)return;
/**change a ticket price*/
void changeTicket();
+ /**return a ticket*/
+ void ticketReturn();
/**cancel the order*/
void cancelOrder();
m->addAction(tr("Add &Voucher"),this,SLOT(cartAddVoucher()))->setEnabled(false);
m->addAction(tr("&Remove Item"),this,SLOT(cartRemoveItem()));
m->addAction(tr("&Abort Shopping"),this,SLOT(initCart()));
- m->addSeparator();
- m->addAction(tr("&Show all orders"));
- m=mb->addMenu(tr("C&onfigure"));
+ m=mb->addMenu(tr("&Misc"));
+ m->addAction(tr("&Return ticket..."),this,SLOT(ticketReturn()));
//tabs
setCentralWidget(tab=new QTabWidget);
vl->addWidget(p=new QPushButton(tr("Details...")),0);
connect(p,SIGNAL(clicked()),this,SLOT(orderDetails()));
p->setEnabled(req->hasRole("getorder"));
+ vl->addSpacing(15);
+ vl->addWidget(p=new QPushButton(tr("Find by Ticket...")),0);
+ connect(p,SIGNAL(clicked()),this,SLOT(orderByTicket()));
+ p->setEnabled(req->hasRole("orderbyticket"));
vl->addStretch(10);
//Entrance Control Tab
om->show();
}
+void MOverview::orderByTicket()
+{
+ //get selected order
+ bool ok;
+ QString tid=QInputDialog::getText(this,tr("Enter Ticket"),tr("Please enter the ID of one of the tickets of the order you seek:"),QLineEdit::Normal,"",&ok);
+ if(!ok || tid=="")return;
+ //request it
+ if(!req->request("orderbyticket",tid.toUtf8())){
+ QMessageBox::warning(this,tr("Warning"),tr("Unable to query server."));
+ return;
+ }
+ if(req->responseStatus()!=MWebRequest::Ok){
+ QMessageBox::warning(this,tr("Warning"),tr(req->responseBody()));
+ return;
+ }
+ int id=req->responseBody().trimmed().toInt(&ok);
+ if(!ok || id<0){
+ QMessageBox::warning(this,tr("Warning"),tr("Server returned an invalid order ID."));
+ return;
+ }
+ //open order window
+ MOrderWindow *om=new MOrderWindow(this,req,MOrder(req,id));
+ om->setAttribute(Qt::WA_DeleteOnClose);
+ om->show();
+}
+
void MOverview::uploadTemplate()
{
//get file
QMessageBox::warning(this,tr("Warning"),tr("Unable to upload the template."));
}
+void MOverview::ticketReturn()
+{
+ //get ticket
+ bool ok;
+ QString tid=QInputDialog::getText(this,tr("Return Ticket"),tr("Please enter the ticket ID to return:"),QLineEdit::Normal,"",&ok);
+ if(!ok || tid=="")return;
+ MTicket tick(req,tid);
+ if(!tick.isValid()){
+ QMessageBox::warning(this,tr("Warning"),tr("This is not a valid ticket."));
+ return;
+ }
+ //check state
+ if(tick.status()!=MTicket::Bought && tick.status()!=MTicket::Reserved){
+ QMessageBox::warning(this,tr("Warning"),tr("This ticket cannot be returned, it has already been used or is in the wrong state."));
+ return;
+ }
+ //submit
+ QString r=tick.ticketReturn();
+ if(r!="")QMessageBox::warning(this,tr("Warning"),trUtf8(r.toUtf8()));
+}
+
+
/**********************************************/
MPasswordChange::MPasswordChange(QWidget*par,QString user)
/**upload Templates*/
void uploadTemplate();
+ /**return a ticket*/
+ void ticketReturn();
+ /**find an order by ticket*/
+ void orderByTicket();
+
private:
//my session object
QPointer<MWebRequest>req;
die(tr("Wrong state, cannot set order to cancelled."));
}
}
+
+//find an order
+function orderByTicketXml($ticket)
+{
+ global $db;
+ $res=$db->select("ticket","orderid","ticketid=".$db->escapeString($ticket));
+ if(count($res)<1){
+ header("X-MagicSmoke-Status: Error");
+ die(tr("Ticket not found."));
+ }
+ if($res[0]["orderid"]===NULL || $res[0]["orderid"]<0){
+ header("X-MagicSmoke-Status: Error");
+ die(tr("Ticket has no order."));
+ }
+ header("X-MagicSmoke-Status: Ok");
+ echo $res[0]["orderid"];
+}
+
?>
\ No newline at end of file
header("X-MagicSmoke-Status: Ok");
}
+function ticketReturnXml($tid)
+{
+ //get ticket
+ global $db;
+ $db->beginTransaction();
+ $res=$db->select("ticket","ticketid,status","ticketid=".$db->escapeString($tid));
+ if(count($res)<1){
+ $db->rollbackTransaction();
+ header("X-MagicSmoke-Status: Error");
+ die(tr("Unable to find this ticket."));
+ }
+ if($res[0]["status"]!=TICKET_BOUGHT && $res[0]["status"]!=TICKET_RESERVED){
+ $db->rollbackTransaction();
+ header("X-MagicSmoke-Status: Error");
+ die(tr("Ticket cannot be returned."));
+ }
+ $db->update("ticket",array("status"=>TICKET_CANCELLED),"ticketid=".$db->escapeString($tid));
+ $db->commitTransaction();
+ header("X-MagicSmoke-Status: Ok");
+}
+
?>
\ No newline at end of file
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("checkorder"),tr("createorder"),tr("createsale"),tr("getorderlist"),tr("getorder"),tr("orderpay"),tr("orderrefund"),tr("ordershipped"),tr("cancelorder"), //sell/order stuff
- tr("getticket"),tr("useticket"),tr("changeticketprice"),//ticket management
+ tr("checkorder"),tr("createorder"),tr("createsale"),tr("getorderlist"),tr("getorder"),tr("orderpay"),tr("orderrefund"),tr("ordershipped"),tr("cancelorder"),tr("orderbyticket"), //sell/order stuff
+ tr("getticket"),tr("useticket"),tr("changeticketprice"),tr("ticketreturn"),//ticket management
tr("gettemplatelist"),tr("gettemplate"),tr("settemplate") //templates
);
/**contains the low-level request name from the client*/
orderCancelXml(trim($REQUESTDATA));
exit();
}
+//find an order
+if($SMOKEREQUEST=="orderbyticket"){
+ orderByTicketXml(trim($REQUESTDATA));
+ exit();
+}
//get a ticket
if($SMOKEREQUEST=="getticket"){
changeTicketPriceXml(trim($REQUESTDATA));
exit();
}
+//return a ticket: cancels it
+if($SMOKEREQUEST=="ticketreturn"){
+ ticketReturnXml(trim($REQUESTDATA));
+ exit();
+}
//EOF
header("X-MagicSmoke-Status: Error");