#include <QDialog>
-#include "event.h"
+#include "MOEvent.h"
class QCheckBox;
class QDateTime;
void startTimeChanged(const QDateTime&);
void endTimeChanged(const QDateTime&);
private:
- MEvent event;
+ MOEvent event;
QDateTimeEdit*starttime,*endtime;
QLineEdit*title,*artist,*room,*price,*cancelreason;
QTextEdit*description;
//
#include "centbox.h"
-#include "event.h"
#include "labeldlg.h"
#include "misc.h"
#include "moneylog.h"
#include "orderwin.h"
#include "ticketrender.h"
#include "msinterface.h"
+#include "templates.h"
+
+#include "MOEvent.h"
#include <QApplication>
#include <QBoxLayout>
m->addAction(tr("Change Commen&t..."),this,SLOT(changeComment()))
->setEnabled(req->hasRole("setordercomment"));
m->addAction(tr("Change Sh&ipping Method..."),this,SLOT(changeShipping()))
- ->setEnabled(req->hasRole("changeordershipping"));
+ ->setEnabled(req->hasRight(req->ROrderChangeShipping));
m->addSeparator();
m->addAction(tr("MoneyLog for Order..."),this,SLOT(moneyLogOrder()))
->setEnabled(req->hasRole("moneylog"));
gl->addWidget(m_sentdate=new QLabel(m_order.sentDateTimeStr()),rw,1);
gl->addWidget(new QLabel(tr("Customer:")),++rw,0);
gl->addWidget(new QLabel(m_order.customer().value().fullName()),rw,1);
- gl->addWidget(new QLabel(tr("Delivery Address:")),++rw,0);
- //FIXME:gl->addWidget(lab=new QLabel(m_order.deliveryAddress()),rw,1);
- //lab->setWordWrap(true);
+ gl->addWidget(lab=new QLabel(tr("Delivery Address:")),++rw,0);
+ lab->setAlignment(Qt::AlignTop);
+ gl->addWidget(lab=new QLabel(m_order.fullDeliveryAddress(false)),rw,1);
+ lab->setWordWrap(true);lab->setFrameShape(lab->Box);lab->setFrameShadow(lab->Raised);
+ gl->addWidget(lab=new QLabel(tr("Invoice Address:")),++rw,0);
+ lab->setAlignment(Qt::AlignTop);
+ gl->addWidget(lab=new QLabel(m_order.fullInvoiceAddress(false)),rw,1);
+ lab->setWordWrap(true);lab->setFrameShape(lab->Box);lab->setFrameShadow(lab->Raised);
gl->addWidget(new QLabel(tr("Sold by:")),++rw,0);
gl->addWidget(new QLabel(m_order.soldby()),rw,1);
gl->addWidget(new QLabel(tr("Total Price:")),++rw,0);
gl->addWidget(new QLabel(tr("Order State:")),++rw,0);
gl->addWidget(m_state=new QLabel(m_order.orderStatusString()),rw,1);
gl->addWidget(new QLabel(tr("Shipping Method:")),++rw,0);
- //FIXME:
- gl->addWidget(m_shipmeth=new QLabel(/*m_order.shipping().description()*/"ship?"),rw,1);
+ gl->addWidget(m_shipmeth=new QLabel(m_order.shippingtype().value().description()),rw,1);
gl->addWidget(new QLabel(tr("Shipping Costs:")),++rw,0);
- gl->addWidget(m_shipprice=new QLabel(/*m_order.shipping().priceString()*/),rw,1);
- gl->addWidget(new QLabel(tr("Order Comment:")),++rw,0);
- //FIXME:
- gl->addWidget(m_comment=lab=new QLabel(/*m_order.comment()*/"comment?"),rw,1);
- lab->setWordWrap(true);
+ gl->addWidget(m_shipprice=new QLabel(cent2str(m_order.shippingcosts())),rw,1);
+ gl->addWidget(lab=new QLabel(tr("Order Comment:")),++rw,0);
+ lab->setAlignment(Qt::AlignTop);
+ gl->addWidget(m_comment=lab=new QLabel(m_order.comments()),rw,1);
+ lab->setWordWrap(true);lab->setFrameShape(lab->Box);lab->setFrameShadow(lab->Raised);
gl->setColumnStretch(0,0);
gl->setColumnStretch(1,10);
sz.setHeight(sz.height()+vsz.height()+40);
//TODO: limit this to the screen size; find a better measure than viewport
resize(sz);
-
- req->dataDir();
}
static const int ITEM_TICKET=1;
static const int ITEM_VOUCHER=2;
+static const int ITEM_ITEM=3;
void MOrderWindow::updateTable()
-{/*TODO:
+{
+ //get detail data
QList<MOTicket> tickets=m_order.tickets();
- QList<MEvent> events;
- if(tickets.size()>0)
- events=req->getAllEvents();
- QList<MVoucher> vouchers=m_order.vouchers();
+ QList<MOEvent> events;
+ if(tickets.size()>0){
+ QList<qint64>evid;
+ for(int i=0;i<tickets.size();i++)
+ if(!evid.contains(tickets[i].eventid()))
+ evid.append(tickets[i].eventid());
+ MTGetEventList gel=req->queryGetEventList(evid);
+ events=gel.getevents();
+ }
+ QList<MOVoucher> vouchers=m_order.vouchers();
+ QList<MOItemInfo> items=m_order.items();
+ //set up model
m_model->clear();
m_model->setHorizontalHeaderLabels(QStringList()<<tr("Item ID")<<tr("Description")<<tr("Start Time")<<tr("Status")<<tr("Price"));
- m_model->insertRows(0,tickets.size()+vouchers.size());
+ m_model->insertRows(0,tickets.size()+vouchers.size()+items.size());
+ //insert tickets
for(int i=0;i<tickets.size();i++){
- m_model->setData(m_model->index(i,0),tickets[i].ticketID());
+ m_model->setData(m_model->index(i,0),tickets[i].ticketid().value());
m_model->setData(m_model->index(i,0),ITEM_TICKET,Qt::UserRole);
m_model->setData(m_model->index(i,3),tickets[i].statusString());
m_model->setData(m_model->index(i,4),tickets[i].priceString());
//find event
- MEvent ev;int eid=tickets[i].eventID();
+ MOEvent ev;int eid=tickets[i].eventid();
for(int j=0;j<events.size();j++)
- if(events[j].eventId()==eid)
+ if(events[j].eventid().value()==eid)
ev=events[j];
//render remainder
- m_model->setData(m_model->index(i,1),ev.title());
+ m_model->setData(m_model->index(i,1),ev.title().value());
m_model->setData(m_model->index(i,2),ev.startTimeString());
}
+ //insert vouchers
int off=tickets.size();
for(int i=0;i<vouchers.size();i++){
m_model->setData(m_model->index(i+off,0),ITEM_VOUCHER,Qt::UserRole);
- m_model->setData(m_model->index(i+off,0),vouchers[i].voucherID());
+ m_model->setData(m_model->index(i+off,0),vouchers[i].voucherid().value());
m_model->setData(m_model->index(i+off,1),tr("Voucher (current value: %1)").arg(vouchers[i].valueString()));
m_model->setData(m_model->index(i+off,3),vouchers[i].statusString());
m_model->setData(m_model->index(i+off,4),vouchers[i].priceString());
}
- m_table->resizeColumnsToContents();*/
+ //TODO: insert items
+ off+=vouchers.size();
+ for(int i=0;i<items.size();i++){
+ m_model->setData(m_model->index(i+off,0),ITEM_ITEM,Qt::UserRole);
+ m_model->setData(m_model->index(i+off,0),items[i].itemid().value());
+ m_model->setData(m_model->index(i+off,1),tr("%1x %2").arg(items[i].amount().value()).arg(items[i].productname().value()));
+ m_model->setData(m_model->index(i+off,3),"");
+ m_model->setData(m_model->index(i+off,4),cent2str(items[i].totalprice()));
+ }
+ //refresh
+ m_table->resizeColumnsToContents();
}
void MOrderWindow::setChanged()
void MOrderWindow::printTickets()
{
- //FIXME:
- //printTickets(m_order.tickets());
+ printTickets(m_order.tickets());
}
void MOrderWindow::printVouchers()
{
- //FIXME
- //printVouchers(m_order.vouchers());
+ printVouchers(m_order.vouchers());
}
void MOrderWindow::printTickets(QList<MOTicket> ticketsin)
-{/*TODO
+{
//reduce ticket list to usable ones
- QList<MTicket> tickets;
+ QList<MOTicket> tickets;
for(int i=0;i<ticketsin.size();i++){
- if(ticketsin[i].status()==MTicket::Bought)
+ if(ticketsin[i].status()&MOTicket::MaskUsable)
tickets.append(ticketsin[i]);
}
//sanity check
return;
}
//get template
- MTemplate tf=req->getTemplate("ticket");
+ MTemplate tf=req->templateStore()->getTemplate("ticket");
if(!tf.isValid()){
QMessageBox::warning(this,tr("Warning"),tr("Unable to get template file (ticket.xtt). Giving up."));
return;
printer.newPage();
}
render.render(tickets[i],printer,&painter,p);
- }*/
+ }
}
void MOrderWindow::printVouchers(QList<MOVoucher> vouchersin)
-{/*TODO
+{
//reduce voucher list to usable ones
- QList<MVoucher>vouchers;
+ QList<MOVoucher>vouchers;
for(int i=0;i<vouchersin.size();i++){
- if(vouchersin[i].isValid() && vouchersin[i].value()>0 && vouchersin[i].xmlState()=="")
+ if(vouchersin[i].isValid() && vouchersin[i].value()>0)
vouchers.append(vouchersin[i]);
}
//sanity check
return;
}
//get template
- MTemplate tf=req->getTemplate("voucher");
+ MTemplate tf=req->templateStore()->getTemplate("voucher");
if(!tf.isValid()){
QMessageBox::warning(this,tr("Warning"),tr("Unable to get template file (voucher.xtt). Giving up."));
return;
printer.newPage();
}
render.render(vouchers[i],printer,&painter,p);
- }*/
+ }
}
void MOrderWindow::restorePrinter(QPrinter&prn,QString key)
close();*/
}
-void MOrderWindow::createSale()
-{
- createOrder(CreateSale);
-}
-
-void MOrderWindow::createReservation()
-{
- createOrder(CreateReservation);
-}
-
-void MOrderWindow::recheckOrder()
-{/*TODO
- //prune
- m_order.pruneInvalid();
- //now check
- MOrder ord;
- ord=m_order.createOrder("checkorder");
- if(!ord.isValid())return;
- //display final order
- MOrderWindow *ow=new MOrderWindow(parentWidget(),req,ord);
- ow->show();
- //undisplay self
- close();*/
-}
-
void MOrderWindow::shipOrder()
{/*TODO
if(QMessageBox::question(this,tr("Mark as shipped?"),tr("Mark this order as shipped now?"),QMessageBox::Yes|QMessageBox::No,QMessageBox::Yes)==QMessageBox::Yes){
}
void MOrderWindow::changeShipping()
-{/*TODO
+{
//create editor dialog
- MShippingChange d(this,req,m_order.shipping());
+ MShippingChange d(this,m_order.shippingtype(),m_order.shippingcosts());
//get status
if(d.exec()!=QDialog::Accepted)return;
//send to server
- m_order.sendShipping(d.selection());
+ int shipid=-1;
+ if(!d.selection().shipid().isNull())shipid=d.selection().shipid();
+ MTOrderChangeShipping ocs=req->queryOrderChangeShipping(m_order.orderid(),shipid,d.price());
+ if(ocs.hasError()){
+ QMessageBox::warning(this,tr("Warning"),tr("Error while changing shipping: %1").arg(ocs.errorString()));
+ return;
+ }
+ m_order=ocs.getorder();
//reset display
- m_shipmeth->setText(m_order.shipping().description());
- m_shipprice->setText(m_order.shipping().priceString());
- m_total->setText(m_order.totalPriceString());*/
+ m_shipmeth->setText(m_order.shippingtype().value().description());
+ m_shipprice->setText(cent2str(m_order.shippingcosts()));
+ m_total->setText(m_order.totalPriceString());
}
void MOrderWindow::moneyLogOrder()
cb->addItem(tr("Voucher: ")+vouchers[i].voucherid());
vl->addWidget(disp=new QLabel,10);
//get the templates
- /*TODO
- trender=new MTicketRenderer(req->getTemplate("ticket"));
- vrender=new MVoucherRenderer(req->getTemplate("voucher"));
- */
+ trender=new MTicketRenderer(req->templateStore()->getTemplate("ticket"));
+ vrender=new MVoucherRenderer(req->templateStore()->getTemplate("voucher"));
changeItem(0);
connect(cb,SIGNAL(currentIndexChanged(int)),this,SLOT(changeItem(int)));
}
MOrderItemView::~MOrderItemView()
{
- //FIXME
- //delete trender;
- //delete vrender;
+ delete trender;
+ delete vrender;
}
void MOrderItemView::changeItem(int idx)
-{/*TODO
+{
//ticket or voucher?
if(idx<tickets.size()){
QSizeF sz=trender->labelSize(*disp);
if(!vrender->render(vouchers[idx-tickets.size()],tick))
qDebug("unable to render");
disp->setPixmap(tick);
- }*/
+ }
}
/*************************************************************************************/
-MShippingChange::MShippingChange(QWidget*pa,MOShipping s)
+MShippingChange::MShippingChange(QWidget*pa,MOShipping s,int costs)
:QDialog(pa)
{
all=req->queryGetAllShipping().getshipping();
setWindowTitle(tr("Change Shipping Method"));
int cid=-1;
- //FIXME:
- //if(s.isValid())cid=s.id();
+ if(!s.shipid().isNull())cid=s.shipid();
QGridLayout*gl;
setLayout(gl=new QGridLayout);
connect(p,SIGNAL(clicked()),this,SLOT(reject()));
prc->setRange(0,1000000000);//hmm, even in Yen this should be big enough
- prc->setValue(s.cost());
- prc->setEnabled(req->hasRole("orderchangeshipping"));
+ prc->setValue(costs);
+ prc->setEnabled(req->hasRight(req->POrderChangeShipping_ChangePrice));
opt->addItem(tr("(None)","shipping method"));
int scid=0;
/**create a new order*/
void createOrder(Create mode=CreateOrder);
- /**create a sale*/
- void createSale();
-
- /**create a new reservation*/
- void createReservation();
-
- /**prune and recheck the order*/
- void recheckOrder();
-
/**money log for the order*/
void moneyLogOrder();
/**money log for a voucher*/
Q_OBJECT
public:
/**creates the dialog*/
- MShippingChange(QWidget*,MOShipping);
+ MShippingChange(QWidget*,MOShipping,int);
/**returns the selected shipping option, including corrected price*/
MOShipping selection()const;
HEADERS += \
iface/msinterface.h \
- iface/event.h \
iface/sslexception.h \
iface/customer.h
SOURCES += \
iface/msinterface.cpp \
- iface/event.cpp \
iface/sslexception.cpp \
iface/customer.cpp
#include "msinterface.h"
#include "main.h"
#include "sslexception.h"
+#include "templates.h"
#include <QDebug>
#include <QDir>
setLogLevel((LogLevel)set.value("webloglevel",LogOnError).toInt());
setWebTimeout(set.value("webtimeout",30).toInt()*1000);
sslexcept=new MSslExceptions(dataDir()+"/sslexceptions.xml");
+ temp=new MTemplateStore(pid);
}
MSInterface::~MSInterface()
logout();
if(sslexcept)delete sslexcept;
sslexcept=0;
+ if(temp)delete temp;
+ temp=0;
}
bool MSInterface::login(QString username,QString passwd)
class MSslExceptions;
+class MTemplateStore;
/**the MagicSmoke specific interface class - enhances the basic interface by some functionality needed in the MagicSmoke context*/
class MSInterface:public MInterface
/**initializes the interface, ie. retrieves language and scripts*/
void initialize();
+
+ /**returns a pointer to the template storage engine*/
+ MTemplateStore* templateStore(){return temp;}
public slots:
/**logs into the server, returns true on success*/
QByteArray servertranslation;
MSslExceptions*sslexcept;
bool didsslerror;
+ MTemplateStore *temp;
};
class MTemplateStore
{
protected:
- //FIXME friend class MWebRequest;
+ friend class MSInterface;
friend class MTemplateEditor;
/**instantiates the template subsystem*/
MTemplateStore(QString);
class QDomElement;
class QDomDocument;
+/**base class of all web based objects*/
class WObject:public QObject
{
protected:
WObject(){}
};
+/**this exception is thrown if the deserialization of an object fails on the XML parser level*/
class WDeserializerException:public WException
{
public:
WDeserializerException(QString e):WException(e,"Deserializer"){}
};
+/**the WOBJECT macro defines the necessary constructors if you just want to extend an abstract class without overwriting the constructors yourself*/
+#define WOBJECT(wob) public: \
+ wob():wob ## Abstract(){} \
+ wob(const wob&w):wob ## Abstract(w){} \
+ wob(const wob ## Abstract&w):wob ## Abstract(w){} \
+ wob(const QDomElement&w):wob ## Abstract(w){} \
+ wob& operator=(const wob&w){wob ## Abstract::operator=(w);return *this;} \
+ wob& operator=(const wob ## Abstract&w){wob ## Abstract::operator=(w);return *this;} \
+ private:
+
#endif
--- /dev/null
+//
+// C++ Implementation: MOAddress
+//
+// Description:
+//
+//
+// Author: Konrad Rosenbaum <konrad@silmor.de>, (C) 2009
+//
+// Copyright: See README/COPYING files that come with this distribution
+//
+//
+
+#include "MOAddress.h"
+
+#include <QStringList>
+
+QString MOAddress::fullAddress(QString nm)const
+{
+ //if not valid: return nothing
+ if(!isValid())return "";
+ //collect lines
+ QStringList rl;
+ if(name().isNull()){
+ if(nm!="")rl<<nm;
+ }else rl<<name();
+ if(!addr1().isNull())rl<<addr1();
+ if(!addr2().isNull())rl<<addr2();
+ if(!city().isNull())rl<<city();
+ if(!state().isNull())rl<<state();
+ if(!zipcode().isNull())rl<<zipcode();
+ if(!country().isNull())rl<<country().value().name();
+ //assemble
+ QString r;
+ for(int i=0;i<rl.size();i++){
+ if(i)r+="\n";
+ r+=rl[i];
+ }
+
+ return r;
+}
--- /dev/null
+//
+// C++ Interface: MOAddress
+//
+// Description:
+//
+//
+// Author: Konrad Rosenbaum <konrad@silmor.de>, (C) 2009
+//
+// Copyright: See README/COPYING files that come with this distribution
+//
+//
+
+#ifndef MAGICSMOKE_MADDRESS_H
+#define MAGICSMOKE_MADDRESS_H
+
+#include "MOAddressAbstract.h"
+
+class MOAddress:public MOAddressAbstract
+{
+ WOBJECT(MOAddress);
+ public:
+ /**returns the full address, if name is given and the address does not have its own name, it is included as top line*/
+ QString fullAddress(QString name=QString())const;
+
+ /**returns true if this is a valid address (ie. it has an address ID)*/
+ bool isValid()const{return !addressid().isNull() && addressid().value()>=0;}
+};
+
+
+#endif
--- /dev/null
+//
+// C++ Implementation: MOCustomerInfo
+//
+// Description:
+//
+//
+// Author: Konrad Rosenbaum <konrad@silmor.de>, (C) 2009
+//
+// Copyright: See README/COPYING files that come with this distribution
+//
+//
+
+#include "MOCustomerInfo.h"
+
#include "MOCustomerInfoAbstract.h"
class MOCustomerInfo:public MOCustomerInfoAbstract
{
+ WOBJECT(MOCustomerInfo);
public:
- MOCustomerInfo():MOCustomerInfoAbstract(){}
- MOCustomerInfo(const MOCustomerInfo&o):MOCustomerInfoAbstract(o){}
- MOCustomerInfo(const QDomElement&e):MOCustomerInfoAbstract(e){}
-
QString fullName()const{return title()+" "+name()+", "+firstname();}
};
//
//
-#include "event.h"
+#include "MOEvent.h"
#include <QCoreApplication>
#include <QDateTime>
#include "msinterface.h"
-MEvent::MEvent(qint64 i)
+MOEvent::MOEvent(qint64 i)
{
MTGetEvent ge=MSInterface::instance()->queryGetEvent(i);
if(ge.stage()==ge.Success)
operator=(ge.getevent().value());
}
-QRegExp MEvent::priceRegExp()const
+QRegExp MOEvent::priceRegExp()const
{
- return QRegExp(QCoreApplication::translate("MEvent","[0-9]+\\.[0-9]{2}","price validator regexp"));
+ return QRegExp(QCoreApplication::translate("MOEvent","[0-9]+\\.[0-9]{2}","price validator regexp"));
}
-QString MEvent::priceString()const
+QString MOEvent::priceString()const
{
qint64 dp=/*defaultprice()*/0;
QString ret=QString::number(dp/100);
- ret+=QCoreApplication::translate("MEvent",".","price decimal dot");
+ ret+=QCoreApplication::translate("MOEvent",".","price decimal dot");
ret+=QString::number((dp/10)%10);
ret+=QString::number(dp%10);
return ret;
}
-QString MEvent::startTimeString()const
+QString MOEvent::startTimeString()const
{
- return QDateTime::fromTime_t(start()).toString(QCoreApplication::translate("MEvent","yyyy-MM-dd hh:mm ap","date/time format"));
+ return QDateTime::fromTime_t(start()).toString(QCoreApplication::translate("MOEvent","yyyy-MM-dd hh:mm ap","date/time format"));
}
-QString MEvent::startDateString()const
+QString MOEvent::startDateString()const
{
- return QDateTime::fromTime_t(start()).toString(QCoreApplication::translate("MEvent","yyyy-MM-dd","date format"));
+ return QDateTime::fromTime_t(start()).toString(QCoreApplication::translate("MOEvent","yyyy-MM-dd","date format"));
}
-QString MEvent::endTimeString()const
+QString MOEvent::endTimeString()const
{
- return QDateTime::fromTime_t(end()).toString(QCoreApplication::translate("MEvent","yyyy-MM-dd hh:mm ap","date/time format"));
+ return QDateTime::fromTime_t(end()).toString(QCoreApplication::translate("MOEvent","yyyy-MM-dd hh:mm ap","date/time format"));
}
-void MEvent::setdefaultprice(QString str)
+void MOEvent::setdefaultprice(QString str)
{
- QStringList ps=str.split(QCoreApplication::translate("MEvent",".","price decimal dot"));
+ /*TODO: we have multiple prices now!
+ QStringList ps=str.split(QCoreApplication::translate("MOEvent",".","price decimal dot"));
qint64 prc=0;
if(ps.size()>=1)prc=ps[0].toInt()*100;
if(ps.size()>=2)prc+=ps[1].toInt();
- setdefaultprice(prc);
+ setdefaultprice(prc);*/
}
#define EVENT_H
#include <QString>
-#include <MOEvent.h>
+#include <MOEventAbstract.h>
/**encapsulation of an event, this class wraps the auto-generated event class to provide some convenience methods*/
-class MEvent:public MOEvent
+class MOEvent:public MOEventAbstract
{
+ WOBJECT(MOEvent);
public:
- /**creates an invalid event*/
- MEvent():MOEvent(){}
- /**copies an event*/
- MEvent(const MEvent&e):MOEvent(e){}
- /**copies an event*/
- MEvent(const MOEvent&e):MOEvent(e){}
/**get event directly from server*/
- MEvent(qint64);
- /**destructs an event*/
- ~MEvent(){}
+ MOEvent(qint64);
- /**copies the event*/
- MEvent& operator=(const MEvent&e){MOEvent::operator=(e);return *this;}
-
- /**updates data from the database, can be used to upgrade an incomplete event to a complete one*/
- //void refresh();
-
- /**saves all data back to the database, it returns an empty string on success, it does not do anything if the event is invalid or incomplete*/
- //QString save();
+ /**alias for id()*/
+ inline Nullable<qint64> eventid()const{return id();}
/**returns the start time of the event as localized string*/
QString startTimeString()const;
/**set the price as string*/
void setdefaultprice(QString);
- //inherit alternative definition
- inline void setdefaultprice(qint64 p){/*MOEvent::setdefaultprice(p);*/}
-
/**returns whether the event is valid. an event can be invalid if it is uninitialized (negative ID) or the server request failed*/
- //bool isValid()const{return m_valid;}
-
- /**requests to cancel the event from the DB; expects reason as argument; returns true on success*/
- //bool cancelEvent(QString);
+ bool isValid()const{return !eventid().isNull() && eventid().value()>0;}
};
#endif
return QDateTime::fromTime_t(senttime()).toString(QCoreApplication::translate("MOOrder","yyyy-MM-dd","date format"));
}
+QString MOOrder::fullInvoiceAddress(bool allowfallback)const
+{
+ if(!invoiceaddress().isNull() && invoiceaddress().value().isValid())
+ return invoiceaddress().value().fullAddress(customer().value().fullName());
+ //fall back
+ if(!allowfallback)return "";
+ if(!deliveryaddress().isNull() && deliveryaddress().value().isValid())
+ return deliveryaddress().value().fullAddress(customer().value().fullName());
+ //give up
+ return "";
+}
+
+QString MOOrder::fullDeliveryAddress(bool allowfallback)const
+{
+ if(!deliveryaddress().isNull() && deliveryaddress().value().isValid())
+ return deliveryaddress().value().fullAddress(customer().value().fullName());
+ //fall back
+ if(!allowfallback)return "";
+ if(!invoiceaddress().isNull() && invoiceaddress().value().isValid())
+ return invoiceaddress().value().fullAddress(customer().value().fullName());
+ //give up
+ return "";
+}
/**returns the shipping date only as string*/
QString sentDateStr();
+ /**returns the full invoice address, or delivery address if no explicit invoice address was given and allowfallback==true*/
+ QString fullInvoiceAddress(bool allowfallback=true)const;
+ /**returns the full delivery address, or invoice address if no explicit delivery address was given and allowfallback==true*/
+ QString fullDeliveryAddress(bool allowfallback=true)const;
};
#endif
#define MAGICSMOKE_MOTICKET_H
#include "MOTicketAbstract.h"
+#include "misc.h"
+
class MOTicket:public MOTicketAbstract
{
+ WOBJECT(MOTicket);
public:
- MOTicket():MOTicketAbstract(){}
- MOTicket(const MOTicket&m):MOTicketAbstract(m){}
- MOTicket(const QDomElement&e):MOTicketAbstract(e){}
-
+ /**returns the amount to be paid for this ticket; this may be 0 even if there is a price attached*/
int amountToPay()const{if(status()&MaskPay)return price();else return 0;}
+
+ /**returns the price as string*/
+ QString priceString()const{return cent2str(price());}
+
+ /**returns the ticket status as localized string*/
+ QString statusString()const{return TicketState2locstr(status());}
};
#endif
--- /dev/null
+//
+// C++ Interface: MOVoucher
+//
+// Description:
+//
+//
+// Author: Konrad Rosenbaum <konrad@silmor.de>, (C) 2009
+//
+// Copyright: See README/COPYING files that come with this distribution
+//
+//
+
+#ifndef MAGICSMOKE_MOVOUCHER_H
+#define MAGICSMOKE_MOVOUCHER_H
+
+#include "MOVoucherAbstract.h"
+#include "misc.h"
+
+class MOVoucher:public MOVoucherAbstract
+{
+ WOBJECT(MOVoucher);
+ public:
+ /**returns whether this is a valid voucher object (ie. it has a voucher ID)*/
+ bool isValid()const{return !voucherid().isNull();}
+ /**returns the current value as string*/
+ QString valueString()const{return cent2str(value());}
+ /**returns the status of the voucher as string*/
+ QString statusString()const{return VoucherState2locstr(status());}
+ /**returns the price as string*/
+ QString priceString()const{return cent2str(price());}
+};
+
+#endif
wext/MOOrder.h \
wext/MOOrderInfo.h \
wext/MORole.h \
- wext/MOTicket.h
+ wext/MOTicket.h \
+ wext/MOAddress.h \
+ wext/MOEvent.h
SOURCES += \
- wext/MOOrder.cpp
\ No newline at end of file
+ wext/MOCustomerInfo.cpp \
+ wext/MOOrder.cpp \
+ wext/MOAddress.cpp \
+ wext/MOEvent.cpp
\ No newline at end of file
</Mapping>
</Class>
<Class name="Address">
+ <Abstract lang="qt"/><!-- eg. fullAddress() method -->
<Property name="addressid" type="int64"/>
<Property name="customerid" type="int32"/>
<Property name="lastused" type="int64"/>
</Class>
<Class name="Event">
+ <Abstract lang="qt"/>
<Property name="id" type="int" id="yes"/>
<Property name="start" type="int64"/>
<Property name="end" type="int64"/>
</Output>
</Transaction>
+ <Transaction name="GetEventList">
+ <Input>
+ <Var name="eventids" type="List:int"/>
+ </Input>
+ <Call lang="php" method="Event::getEventList($this);"/>
+ <Output>
+ <Var name="events" type="List:Event"/>
+ </Output>
+ </Transaction>
+
<Transaction name="CancelEvent">
<Input>
<Var name="eventid" type="int"/>
</Transaction>
<Class name="Voucher">
+ <Abstract lang="qt"/>
<Enum name="VoucherState">
<Value name="Ok"/>
<Value name="InvalidValue"/>
<Transaction name="OrderRefund"/>
<Transaction name="UseVoucher"/>
+ <Transaction name="OrderChangeShipping">
+ <Doc>Changes the shipping option and/or price of an order</Doc>
+ <Privilege name="ChangePrice"/>
+ <Input>
+ <Var name="orderid" type="int">The order to be changed</Var>
+ <Var name="shippingid" type="int">the new shipping option or -1 if shipping is to be deleted</Var>
+ <Var name="shippingcosts" type="int">if the user has the privilege ChangePrice this field overrides the shipping costs, otherwise the default from the shipping table is used</Var>
+ </Input>
+ <Call lang="php" method="WOOrder::changeShipping($this);"/>
+ <Output>
+ <Var name="order" type="Order">a fresh copy of the changed order</Var>
+ </Output>
+ </Transaction>
+
<Transaction name="GetAllShipping">
<Input/>
+ <Call lang="php" method="$this->setshipping(WOShipping::fromTableArrayshipping(WTshipping::selectFromDB()));"/>
<Output>
<Var name="shipping" type="List:Shipping"/>
</Output>
void WocPHPServerOut::transInfo2()
{
WocProcessor*woc=WocProcessor::instance();
+ //transaction names
QString code=" static public function transactionNames(){\n\treturn array(";
QStringList tns=woc->transactionNames();
for(int i=0;i<tns.size();i++){
code+="\n\t\ttranslate(\"_TransactionNames\",\""+tns[i]+"\")";
}
code+=");\n }\n";
+ //privilege names
+ code+="static public function privilegeNames(){\n\treturn array(";
+ QStringList priv=woc->privilegeNames();
+ for(int i=0;i<priv.size();i++){
+ if(i)code+=",\n\t\t";else code+="\n\t\t";
+ code+="translate(\"_PrivilegeNames\",\""+priv[i]+"\")";
+ }
+ code+="\n\t);\n}\n";
+
m_transact.write(code.toAscii());
}
code+="protected function __construct(array $data,$isfromdb){parent::__construct($data,$isfromdb,\""+tbl.name()+"\");}\n\n";
//static new instance for insert only
- code+="public static function newRow(){return new WT"+tbl.name()+"(array(),false);}\n\n";
+ code+="public static function newRow(array $data=array()){return new WT"+tbl.name()+"($data,false);}\n\n";
//static get instance
QStringList cols=tbl.columns();
}
//implement enum check for set method of enum columns
if(tbl.columnType(cols[i]).startsWith("enum")){
- code+="private function verifyValue"+cols[i]+"($v){if(false";
+ code+="protected function verifyValue"+cols[i]+"($v){if(false";
QList<WocEnum>ens=tbl.columnEnums(cols[i]);
QList<int>envs;
for(int j=0;j<ens.size();j++){
//create audit stuff
if(tbl.isAuditable()){
code+="public function isAuditable(){return true;}\n";
- code+="protected function createAudit(){$ad=new WT"+tbl.name()+"_audit($this->data,false,\""+tbl.name()+"_audit\");\n";
+ code+="protected function createAudit(){$ad=WT"+tbl.name()+"_audit::newRow($this->data);\n";
code+="\treturn $ad->insert();\n}\n";
}
//direct execution
tf.write(trnExecute(trn).toAscii());
+ //privileges
+ tf.write(trnPrivileges(trn).toAscii());
+
//end
code="\n//end of class\n}\n";
tf.write(code.toAscii());
code+="private function do_execute(){"+trn.callFunction("php")+"}\n";
return code;
}
+
+QString WocPHPServerOut::trnPrivileges(const WocTransaction&trn)
+{
+ //privilege inventory
+ QString code;
+ code+="static public function privileges(){\n\treturn array(";
+ QString cn=trnClassName(trn);
+ QStringList priv=trn.privileges();
+ for(int i=0;i<priv.size();i++){
+ if(i)code+=",\n\t\t";else code+="\n\t\t";
+ code+="\""+priv[i]+"\"";
+ }
+ code+="\n\t);\n}\n";
+ //constants for use by custom code
+ for(int i=0;i<priv.size();i++)
+ code+="const Priv_"+priv[i]+"=\""+priv[i]+"\";\n";
+ //check method
+ code+="public function havePrivilege($priv){\n";
+ code+="\tif(!in_array($priv,self::privileges()))return false;\n";
+ code+="\treturn "+QString(m_hasrole).replace("%","(\""+trn.name()+":\".$priv)")+";\n}\n";
+
+ return code;
+}
QString trnGetSet(const WocTransaction&);
/**helper: create direct execution code for web interface*/
QString trnExecute(const WocTransaction&);
+ /**helper: create privilege check code for web interface*/
+ QString trnPrivileges(const WocTransaction&);
/**helper: return the PHP-class-name of a WocClass*/
QString className(const WocClass&c){return "WO"+c.name();}
return l;
}
+QStringList WocProcessor::privilegeNames()const
+{
+ QStringList l;
+ for(int i=0;i<m_transactions.size();i++){
+ QString cn=m_transactions[i].name();
+ QStringList priv=m_transactions[i].privileges();
+ for(int j=0;j<priv.size();j++)
+ l<<(cn+":"+priv[j]);
+ }
+ return l;
+}
+
/******************************************************************************
* WocOutput
******************************************************************************/
QString s=nl.at(i).toElement().text().trimmed();
if(s!="")m_docstrings<<s;
}
+ //privileges
+ nl=root.elementsByTagName("Privilege");
+ for(int i=0;i<nl.size();i++){
+ QString s=nl.at(i).toElement().attribute("name").trimmed();
+ if(s!="")m_privileges<<s;
+ }
}
bool WocTransaction::hasInput(QString v)const
/**return docu of output element*/
QString outputDoc(QString v)const
{if(m_outdoc.contains(v))return m_outdoc[v];else return "";}
+
+ /**return privileges that exist inside this transaction*/
+ QStringList privileges()const{return m_privileges;}
private:
QString m_name;
bool m_valid;
AuthMode m_mode;
QMap<QString,QString> m_call;
QList<QPair<QString,QString> >m_input,m_output;
+ QStringList m_privileges;
//docu
QStringList m_docstrings;
QMap<QString,QString>m_indoc,m_outdoc;
/**returns a list of table names*/
QStringList tableNames()const;
+ /**returns global docu*/
QStringList docStrings()const{return m_docstrings;}
+
+ /**returns the qualified names of all privileges*/
+ QStringList privilegeNames()const;
signals:
void sfinalize();
void newClass(const WocClass&);
//header
code+=" enum Right {\n NoRight";
QStringList r=WocProcessor::instance()->transactionNames();
+ QStringList p=WocProcessor::instance()->privilegeNames();
+ QStringList pp=p;
for(int i=0;i<r.size();i++)
code+=",\n R"+r[i];
+ for(int i=0;i<p.size();i++)
+ code+=",\n P"+pp[i].replace(':',"_");
code+="\n };\n";
code+=" static QString rightToString(Right);\n";
code+=" static Right stringToRight(QString);\n";
code="QString "+m_prefix+"Interface::rightToString(Right r)\n{\n\tswitch(r){\n";
for(int i=0;i<r.size();i++)
code+="\t\tcase R"+r[i]+":return \""+r[i]+"\";\n";
+ for(int i=0;i<p.size();i++)
+ code+="\t\tcase P"+pp[i]+":return \""+p[i]+"\";\n";
code+="\t\tdefault:return \"\";\n\t}\n}\n";
code+=m_prefix+"Interface::Right "+m_prefix+"Interface::stringToRight(QString s)\n{\n";
for(int i=0;i<r.size();i++)
code+="\tif(s==\""+r[i]+"\")return R"+r[i]+";else\n";
+ for(int i=0;i<p.size();i++)
+ code+="\tif(s==\""+p[i]+"\")return P"+pp[i]+";else\n";
code+="\treturn NoRight;\n}\n";
code+="QList<"+m_prefix+"Interface::Right> "+m_prefix+"Interface::allKnownRights()\n{\n";
code+="\tQList<Right> ret;ret";
for(int i=0;i<r.size();i++)
code+="<<R"+r[i];
+ for(int i=0;i<p.size();i++)
+ code+="<<P"+pp[i];
code+=";\n\treturn ret;\n}\n";
code+="QStringList "+m_prefix+"Interface::allKnownRightsString()\n{\n";
code+="\tQStringList ret;ret";
for(int i=0;i<r.size();i++)
code+="<<\""+r[i]+"\"";
+ for(int i=0;i<p.size();i++)
+ code+="<<\""+p[i]+"\"";
code+=";\n\treturn ret;\n}\n";
m_ifacecpp.write(code.toAscii());
}
$evlst=WOEvent::fromTableArrayevent(WTevent::selectFromDB("","ORDER BY starttime"));
$trans->setevents($evlst);
}
+
+ /**XML iface: get list of events*/
+ public static function getEventList($trans)
+ {
+ global $db;
+ $evlst=WOEvent::fromTableArrayevent(WTevent::selectFromDB("eventid in ".$db->escapeIntList($trans->geteventids())));
+ $trans->setevents($evlst);
+ }
};
/**machine-function: get the requested events as XML data*/
/**parent class of all tables*/
abstract class WobTable
{
- private $data;
- private $cdata;
+ protected $data;
+ protected $cdata;
private $isfromdb;
private $table;
/**constructs a basic table*/
protected function __construct(array $data,$isfromdb,$table)
{
- $this->data=$data;
+ $this->data=array();
+ if($isfromdb)$this->data=$data;
+ else
+ foreach($data as $k=>$d){
+ //silently ignore garbage
+ if(!$this->hasProperty($k))continue;
+ //verify non-garbage
+ $vm="verifyValue".$k;
+ if(method_exists($this,$vm))
+ if(!$this->$vm($d))
+ throw ValueOutOfRange($this->table,$k,$d);
+ //set
+ $this->data[$k]=$d;
+ }
$this->isfromdb=$isfromdb;
$this->table=$table;
$this->cdata=array();
$prc+=$it->amountToPay();
//add vouchers
foreach($this->prop_vouchers as $it)
- $prc+=$it->getprice();
+ $prc+=$it->get_price();
//add items
foreach($this->prop_items as $it)
- $prc+=$it->gettotalprice();
+ $prc+=$it->get_totalprice();
//return
return $prc;
}
if(count($res)>=0)
$trans->setorder(WOOrder::fromTableorder(WTorder::getFromDB($res[0]["orderid"])));
}
+
+ /**called by OrderChangeShipping transaction*/
+ static public function changeShipping($trans)
+ {
+ //get shipping
+ $shipid=$trans->getshippingid();
+// print_r($shipid);
+ if($shipid===false)$shipid=-1;else $shipid=$shipid+0;
+ if($shipid>=0){
+ $ship=WTshipping::getFromDB($shipid);
+ if($ship===false){
+ $trans->abortWithError(tr("Invalid shipping ID."));
+ return;
+ }
+ }
+ //get order
+ $ord=WTorder::getFromDB($trans->getorderid());
+ //get shipping costs
+ $cost=0;
+ if($shipid>=0)$cost=$ship->cost;
+ if($trans->havePrivilege(WtrOrderChangeShipping::Priv_ChangePrice)){
+ if($trans->getshippingcosts()!==false)
+ $cost=$trans->getshippingcosts();
+ }
+ //set order
+ $ord->shippingcosts=$cost;
+ if($shipid>=0)
+ $ord->shippingtype=$shipid;
+ else
+ $ord->shippingtype=null;
+ $ord->update();
+ //return order
+ $trans->setorder(WOOrder::fromTableorder($ord));
+ }
};
?>
\ No newline at end of file