wbase
Web object base classes.
+iface
+ MagicSmoke web interface classes (derived from wbase/*)
+
wob
generated web objects - auto created by woc from ../wob/magicsmoke.wolf
-iface
- MagicSmoke web interface classes (derived from wbase/*)
+wext
+ extensions for autogenerated abstract classes (derived from wob/*Abstract.h)
widgets
some simple helper widgets
//FIXME:gl->addWidget(lab=new QLabel(m_order.deliveryAddress()),rw,1);
//lab->setWordWrap(true);
gl->addWidget(new QLabel(tr("Sold by:")),++rw,0);
- gl->addWidget(new QLabel(m_order.seller()),rw,1);
+ gl->addWidget(new QLabel(m_order.soldby()),rw,1);
gl->addWidget(new QLabel(tr("Total Price:")),++rw,0);
gl->addWidget(m_total=new QLabel(m_order.totalPriceString()),rw,1);
gl->addWidget(new QLabel(tr("Already Paid:")),++rw,0);
bool MOrder::isReservation()const
{
- return state()==Reserved;
+ return status()==Reserved;
}
bool MOrder::canOrder()const
QString MOrder::orderStatusString()const
{
- return OrderState2str(state());
+ return OrderState2str(status());
}
QString MOrder::totalPriceString(int off)const
bool MOrder::needsPayment()const
{
- if(state()==Placed || state()==Sent)
+ if(status()==Placed || status()==Sent)
if(amountpaid()<totalprice())return true;
return false;
}
bool MOrder::needsRefund()const
{
- if(state()==Cancelled)
+ if(status()==Cancelled)
return amountpaid()>0;
- if(state()==Placed || state()==Sent)
+ if(status()==Placed || status()==Sent)
return amountpaid()>totalprice();
return false;
}
int MOrder::amountToPay()const
{
- if(state()==Placed || state()==Sent)
+ if(status()==Placed || status()==Sent)
if(amountpaid()<totalprice())return totalprice()-amountpaid();
return 0;
}
int MOrder::amountToRefund()const
{
- if(state()==Cancelled)
+ if(status()==Cancelled)
return amountpaid();
- if(state()==Placed || state()==Sent)
+ if(status()==Placed || status()==Sent)
if(amountpaid()>totalprice())
return amountpaid()-totalprice();
return 0;
bool MOrder::isSent()const
{
//only in placed mode there is a need for action, hence in all other modes we assume sent
- return state()!=Placed;
+ return status()!=Placed;
}
p->setEnabled(req->hasRole("orderbyticket"));
vl->addWidget(p=new QPushButton(tr("Find by Event...")),0);
connect(p,SIGNAL(clicked()),this,SLOT(orderByEvent()));
- p->setEnabled(req->hasRole("getordersbyevents"));
+ p->setEnabled(req->hasRight(req->RGetOrdersByEvents));
vl->addWidget(p=new QPushButton(tr("Find by Customer...")),0);
connect(p,SIGNAL(clicked()),this,SLOT(orderByCustomer()));
p->setEnabled(req->hasRole("getorderlist"));
//fill tables
- if(req->hasRole("getorderlist")){
+ if(req->hasRight(req->RGetOrderList)){
updateOrders();
}else{
setEnabled(false);
}
}
+qint64 MOrdersTab::oldestOrderStamp(int age)
+{
+ if(age<0){//age not given, get configuration
+ QSettings set;
+ set.beginGroup("profiles/"+profilekey);
+ age=set.value("maxorderage",0).toInt();
+ }
+ //zero means no limit
+ if(age<=0)return 0;
+ //calculate
+ return QDateTime::currentDateTime().addDays(-age).toTime_t();
+}
//helper: finds out whether an order should be printed.
-static inline bool candoUpdateOrders(int omode,const MOrder&ord)
+static inline bool candoUpdateOrders(int omode,const MOOrderInfo&ord)
{
if(omode==ORDERALL)return true;
if((omode&ORDERPAY)!=0 && ord.needsPayment())return true;
return false;
}
-void MOrdersTab::updateOrders()
-{/*TODO
+void MOrdersTab::resetModel()
+{
ordermodel->clear();
ordermodel->setHorizontalHeaderLabels(QStringList()<<tr("Status")<<tr("Total")<<tr("Paid")<<tr("Customer"));
+}
+
+void MOrdersTab::addOrderToModel(const MOOrderInfo&ord,const QList<MOCustomerInfo>&cust)
+{
+ int cl=0;
+ ordermodel->insertRow(cl);
+ ordermodel->setHeaderData(cl,Qt::Vertical,ord.orderid().value());
+ ordermodel->setData(ordermodel->index(cl,0),ord.orderStatusString());
+ ordermodel->setData(ordermodel->index(cl,0),ord.orderid().value(),Qt::UserRole);
+ ordermodel->setData(ordermodel->index(cl,1),ord.totalPriceString());
+ ordermodel->setData(ordermodel->index(cl,2),ord.amountPaidString());
+ int cid=ord.customerid();
+ //TODO: make this more effective:
+ for(int j=0;j<cust.size();j++)
+ if(cust[j].customerid().value()==cid)
+ ordermodel->setData(ordermodel->index(cl,3),cust[j].fullName());
+ cl++;
+}
+
+void MOrdersTab::updateOrders()
+{
+ resetModel();
int omode=ordermode->itemData(ordermode->currentIndex()).toInt();
if(omode==ORDERNONE)return;
- QList<MOrder> orders=req->getAllOrders();
- if(orders.size()==0)return;
- QList<MCustomer> cust=req->getAllCustomers();
- int cl=0;
+ MTGetOrderList ol=req->queryGetOrderList(oldestOrderStamp());
+ if(ol.hasError()){
+ QMessageBox::warning(this,tr("Warning"),tr("There was a problem retrieving the order list: %1").arg(ol.errorString()));
+ return;
+ }
+ QList<MOOrderInfo> orders=ol.getorders();
+ QList<MOCustomerInfo> cust=ol.getcustomers();
for(int i=0;i<orders.size();i++){
if(!candoUpdateOrders(omode,orders[i]))continue;
- ordermodel->insertRow(cl);
- ordermodel->setHeaderData(cl,Qt::Vertical,orders[i].orderID());
- ordermodel->setData(ordermodel->index(cl,0),orders[i].orderStatusString());
- ordermodel->setData(ordermodel->index(cl,0),orders[i].orderID(),Qt::UserRole);
- ordermodel->setData(ordermodel->index(cl,1),orders[i].totalPriceString());
- ordermodel->setData(ordermodel->index(cl,2),orders[i].amountPaidString());
- int cid=orders[i].customerID();
- //TODO: make this more effective:
- for(int j=0;j<cust.size();j++)
- if(cust[j].customerID()==cid)
- ordermodel->setData(ordermodel->index(cl,3),cust[j].name());
- cl++;
+ addOrderToModel(orders[i],cust);
}
- ordertable->resizeColumnsToContents();*/
+ ordertable->resizeColumnsToContents();
}
void MOrdersTab::orderDetails()
}
void MOrdersTab::orderByEvent()
-{/*TODO
+{
//display selection dialog
QDialog d(this);
d.setWindowTitle(tr("Select Event"));
QTableView*tv;
vl->addWidget(tv=new QTableView,10);
tv->setEditTriggers(QAbstractItemView::NoEditTriggers);
+ QStandardItemModel*eventmodel=emit eventModel();
tv->setModel(eventmodel);
tv->resizeColumnsToContents();
vl->addLayout(hl=new QHBoxLayout,0);
return;
}
//get events
- QList<int>eventids;
+ QList<qint64>eventids;
for(int i=0;i<ilst.size();i++){
int eid=eventmodel->data(eventmodel->index(ilst[i].row(),0),Qt::UserRole).toInt();
if(!eventids.contains(eid))eventids.append(eid);
}
//request data and display
- //TODO: unify this part with updateOrders
- ordermodel->clear();
- ordermodel->setHorizontalHeaderLabels(QStringList()<<tr("Status")<<tr("Total")<<tr("Paid")<<tr("Customer"));
- QList<MOrder> orders=req->getOrdersByEvents(eventids);
- if(orders.size()==0)return;
- QList<MCustomer> cust=req->getAllCustomers();
+ resetModel();
+ MTGetOrdersByEvents obe=req->queryGetOrdersByEvents(eventids,oldestOrderStamp());
+ if(obe.hasError()){
+ QMessageBox::warning(this,tr("Warning"),tr("There was a problem retrieving the order list: %1").arg(obe.errorString()));
+ return;
+ }
+ QList<MOOrderInfo> orders=obe.getorders();
+ QList<MOCustomerInfo> cust=obe.getcustomers();
for(int cl=0;cl<orders.size();cl++){
- ordermodel->insertRow(cl);
- ordermodel->setHeaderData(cl,Qt::Vertical,orders[cl].orderID());
- ordermodel->setData(ordermodel->index(cl,0),orders[cl].orderStatusString());
- ordermodel->setData(ordermodel->index(cl,0),orders[cl].orderID(),Qt::UserRole);
- ordermodel->setData(ordermodel->index(cl,1),orders[cl].totalPriceString());
- ordermodel->setData(ordermodel->index(cl,2),orders[cl].amountPaidString());
- int cid=orders[cl].customerID();
- //TODO: make this more effective:
- for(int j=0;j<cust.size();j++)
- if(cust[j].customerID()==cid)
- ordermodel->setData(ordermodel->index(cl,3),cust[j].name());
+ addOrderToModel(orders[cl],cust);
}
- ordermode->setCurrentIndex(ordermode->count()-1);*/
+ ordermode->setCurrentIndex(ordermode->count()-1);
}
void MOrdersTab::orderByCustomer()
class QTableView;
class MSInterface;
+class MOOrderInfo;
+class MOCustomerInfo;
/**Main Overview Window: order list tab*/
class MOrdersTab:public QWidget
/**find and display order by order ID*/
void orderByOrder();
+ signals:
+ /**needs to be connected to the event tab*/
+ QStandardItemModel*eventModel();
+
private:
+ /**helper function: enters a single order into the model*/
+ void addOrderToModel(const MOOrderInfo&,const QList<MOCustomerInfo>&);
+ /**helper function: resets the model to an empty state*/
+ void resetModel();
+ /**returns timestamp for oldest order; if age is given it returns a timestamp age days in the past, if age is not given it uses the configured time*/
+ qint64 oldestOrderStamp(int age=-1);
+
//the profile associated with this session
QString profilekey;
//widgets
//Order List Tab
tab->addTab(ordertab=new MOrdersTab(pk),tr("Order List"));
+ connect(ordertab,SIGNAL(eventModel()),eventtab,SLOT(eventModel()),Qt::DirectConnection);
//Entrance Control Tab
tab->addTab(entrancetab=new MEntranceTab(pk),tr("Entrance"));
m=mb->addMenu(tr("C&onfigure"));
m->addAction(tr("&Auto-Refresh settings..."),this,SLOT(setRefresh()));
m->addAction(tr("&Server Access settings..."),this,SLOT(webSettings()));
+ m->addAction(tr("&Display settings..."),this,SLOT(displaySettings()));
m=mb->addMenu(tr("&Admin"));
m->addAction(tr("Backup &Settings..."),this,SLOT(backupSettings()))
eventtab->setEnabled(false);
tab->setTabEnabled(tab->indexOf(eventtab),false);
}
- if(!req->hasRole("createorder")&&!req->hasRole("createsale")){
+ if(!req->hasRight(req->RCreateOrder)&&!req->hasRight(req->RCreateSale)){
tab->setTabEnabled(tab->indexOf(carttab),false);
}
- if(!req->hasRole("getorderlist")){
+ if(!req->hasRight(req->RGetOrderList)){
tab->setTabEnabled(tab->indexOf(ordertab),false);
}
if(!req->hasRight(req->RGetAllUsers)){
req->setWebTimeout(timeout*1000);
}
+void MOverview::displaySettings()
+{
+ QSettings set;
+ set.beginGroup("profiles/"+profilekey);
+ //get settings
+ int maxage=set.value("maxeventage", 0).toInt();
+ int maxageo=set.value("maxorderage", 0).toInt();
+ //dialog
+ QDialog d;
+ d.setWindowTitle(tr("Display Settings"));
+ QGridLayout*gl;
+ QHBoxLayout*hl;
+ d.setLayout(gl=new QGridLayout);
+ int cl=0;
+ gl->addWidget(new QLabel(tr("Maximum event age (days, 0=show all):")),cl,0);
+ QSpinBox*mage;
+ gl->addWidget(mage=new QSpinBox,cl,1);
+ mage->setRange(0,99999);
+ mage->setValue(maxage);
+ gl->addWidget(new QLabel(tr("Maximum order list age (days, 0=show all):")),++cl,0);
+ QSpinBox*oage;
+ gl->addWidget(oage=new QSpinBox,cl,1);
+ oage->setRange(0,99999);
+ oage->setValue(maxageo);
+ gl->setRowMinimumHeight(++cl,15);
+ gl->addLayout(hl=new QHBoxLayout,++cl,0,1,2);
+ hl->addStretch(10);
+ 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;
+ //write settings
+ maxage=mage->value();
+ maxageo=oage->value();
+ set.setValue("maxeventage",maxage);
+ set.setValue("maxorderage",maxageo);
+}
+
+
void MOverview::doBackup()
{
baktimer.stop();
/**web request settings dialog; shows the dialog per default, just copies settings from registry to webrequest object if false*/
void webSettings(bool dlg=true);
+ /**display property settings*/
+ void displaySettings();
+
/**do a backup now*/
void doBackup();
include(mwin/mwin.pri)
#build generated stuff last
+include(wext/wext.pri)
include(wob/wob.pri)
--- /dev/null
+//
+// C++ Interface: unabstract
+//
+// Description: removes abstract flag from classes that only need to be abstract in PHP
+//
+//
+// Author: Konrad Rosenbaum <konrad@silmor.de>, (C) 2009
+//
+// Copyright: See README/COPYING files that come with this distribution
+//
+//
+
+#ifndef MAGICSMOKE_MOCUSTOMER_H
+#define MAGICSMOKE_MOCUSTOMER_H
+
+#include "MOCustomerInfoAbstract.h"
+class MOCustomerInfo:public MOCustomerInfoAbstract
+{
+ public:
+ MOCustomerInfo():MOCustomerInfoAbstract(){}
+ MOCustomerInfo(const MOCustomerInfo&o):MOCustomerInfoAbstract(o){}
+ MOCustomerInfo(const QDomElement&e):MOCustomerInfoAbstract(e){}
+
+ QString fullName()const{return title()+" "+name()+", "+firstname();}
+};
+
+#endif
--- /dev/null
+//
+// C++ Interface: unabstract
+//
+// Description: removes abstract flag from classes that only need to be abstract in PHP
+//
+//
+// Author: Konrad Rosenbaum <konrad@silmor.de>, (C) 2009
+//
+// Copyright: See README/COPYING files that come with this distribution
+//
+//
+
+#ifndef MAGICSMOKE_MOORDER_H
+#define MAGICSMOKE_MOORDER_H
+
+#include "MOOrderAbstract.h"
+class MOOrder:public MOOrderAbstract
+{
+ public:
+ MOOrder():MOOrderAbstract(){}
+ MOOrder(const MOOrder&o):MOOrderAbstract(o){}
+ MOOrder(const QDomElement&e):MOOrderAbstract(e){}
+
+};
+
+#endif
--- /dev/null
+//
+// C++ Interface: unabstract
+//
+// Description: removes abstract flag from classes that only need to be abstract in PHP
+//
+//
+// Author: Konrad Rosenbaum <konrad@silmor.de>, (C) 2009
+//
+// Copyright: See README/COPYING files that come with this distribution
+//
+//
+
+#ifndef MAGICSMOKE_MOORDERI_H
+#define MAGICSMOKE_MOORDERI_H
+
+#include "MOOrderInfoAbstract.h"
+#include "misc.h"
+
+class MOOrderInfo:public MOOrderInfoAbstract
+{
+ public:
+ MOOrderInfo(const MOOrderInfo&o):MOOrderInfoAbstract(o){}
+ MOOrderInfo(const QDomElement&e):MOOrderInfoAbstract(e){}
+
+ QString totalPriceString()const{return cent2str(totalprice());}
+ QString amountPaidString()const{return cent2str(amountpaid());}
+ QString orderStatusString()const{return OrderState2str(status());}
+
+ bool needsPayment()const{return amountpaid()<totalprice();}
+ bool needsRefund()const{return amountpaid()>totalprice();}
+ bool isSent()const{return status()==Sent;}
+ bool isReservation()const{return status()==Reserved;}
+};
+
+#endif
\ No newline at end of file
--- /dev/null
+//
+// C++ Interface: MOTicket
+//
+// Description:
+//
+//
+// Author: Konrad Rosenbaum <konrad@silmor.de>, (C) 2009
+//
+// Copyright: See README/COPYING files that come with this distribution
+//
+//
+
+#ifndef MAGICSMOKE_MOTICKET_H
+#define MAGICSMOKE_MOTICKET_H
+
+#include "MOTicketAbstract.h"
+class MOTicket:public MOTicketAbstract
+{
+ public:
+ MOTicket():MOTicketAbstract(){}
+ MOTicket(const MOTicket&m):MOTicketAbstract(m){}
+ MOTicket(const QDomElement&e):MOTicketAbstract(e){}
+
+ int amountToPay()const{if(status()&MaskPay)return price();else return 0;}
+};
+
+#endif
--- /dev/null
+INCLUDEPATH += ./wext