From: konrad Date: Sun, 9 Mar 2008 18:58:22 +0000 (+0000) Subject: Cart handling, some drafting on orders X-Git-Url: http://git.silmor.de/gitweb/?a=commitdiff_plain;h=176d717f9503e6484ee8c551652169fed27cc8c6;p=konrad%2Fsmoke.git Cart handling, some drafting on orders git-svn-id: https://silmor.de/svn/softmagic/smoke/trunk@111 6e3c4bff-ac9f-4ac1-96c5-d2ea494d3e33 --- diff --git a/doc/prog_protocol.html b/doc/prog_protocol.html index f22d5a0..1f520b0 100644 --- a/doc/prog_protocol.html +++ b/doc/prog_protocol.html @@ -372,8 +372,26 @@ The getcustomerlist transaction returns a short list of customers. The </CustomerList> +

Customer Details

+ +The getcustomer transaction returns detailed information about a customer. The request contains the ID of the customer, the response contains:

+ +

+<Customer id="integer ID" name="full name" mail="login-mail-for-webinterface">
+  <Address> address info</Address>
+  <Contact> contact information</Contact>
+  <Comment> system internal comment</Comment>
+</Customer>
+
+ +The "mail" attribute is optional - it is only reported for customers that have a web-interface account. +

Orders and Sales

+

Creating Orders/Sales

+ +The createorder transaction creates an open order. The createsale transactions creates an order that is marked as delivered and paid. The request is an order object, the response is a copy of that object with prices filled in. (???) +

Templates

Templates are used for printouts and documents. There are several types of templates:

diff --git a/src/customer.cpp b/src/customer.cpp index 2b0fd25..40a2a29 100644 --- a/src/customer.cpp +++ b/src/customer.cpp @@ -18,20 +18,58 @@ #include #include #include +#include +#include +#include +#include MCustomer::MCustomer() { m_req=0; m_id=-1; + m_iscomplete=false; } MCustomer::MCustomer(MWebRequest*r,const QDomElement&el) { m_req=r; + m_iscomplete=false; + scanXml(el); +} + +void MCustomer::scanXml(const QDomElement&el) +{ + //get basic information bool b; m_id=el.attribute("id","-1").toInt(&b); if(!b)m_id=-1; m_name=el.attribute("name"); + //scan for details + m_iscomplete=false; + QDomNodeList nl; + nl=el.elementsByTagName("Contact"); + if(nl.size()>0){ + m_contact=nl.at(0).toElement().text(); + } + nl=el.elementsByTagName("Address"); + if(nl.size()>0){ + m_address=nl.at(0).toElement().text(); + } + m_mail=el.attribute("mail"); + nl=el.elementsByTagName("Comment"); + if(nl.size()>0){ + m_comment=nl.at(0).toElement().text(); + } +} + +void MCustomer::getUpdate() +{ + if(m_id<0)return; + if(!m_req->request("getcustomer",QString::number(m_id).toAscii()))return; + QDomDocument doc; + if(!doc.setContent(m_req->responseBody()))return; + QDomElement root=doc.documentElement(); + scanXml(root); } MCustomer::MCustomer(const MCustomer&c) @@ -39,6 +77,11 @@ MCustomer::MCustomer(const MCustomer&c) m_req=c.m_req; m_id=c.m_id; m_name=c.m_name; + m_address=c.m_address; + m_contact=c.m_contact; + m_mail=c.m_mail; + m_comment=c.m_comment; + m_iscomplete=c.m_iscomplete; } MCustomer& MCustomer::operator=(const MCustomer&c) @@ -46,6 +89,11 @@ MCustomer& MCustomer::operator=(const MCustomer&c) m_req=c.m_req; m_id=c.m_id; m_name=c.m_name; + m_address=c.m_address; + m_contact=c.m_contact; + m_mail=c.m_mail; + m_comment=c.m_comment; + m_iscomplete=c.m_iscomplete; return *this; } @@ -66,9 +114,59 @@ QString MCustomer::name() QString MCustomer::getNameAddress() { - return m_name; + return m_name+"\n"+address(); } +QString MCustomer::address() +{ + if(!m_iscomplete)getUpdate(); + return m_address; +} + +QString MCustomer::contact() +{ + if(!m_iscomplete)getUpdate(); + return m_contact; +} + +QString MCustomer::mail() +{ + if(!m_iscomplete)getUpdate(); + return m_mail; +} + +QString MCustomer::comment() +{ + if(!m_iscomplete)getUpdate(); + return m_comment; +} + +void MCustomer::setName(QString n){m_name=n;} +void MCustomer::setAddress(QString a){m_address=a;} +void MCustomer::setContact(QString c){m_contact=c;} +void MCustomer::setComment(QString c){m_comment=c;} + +void MCustomer::save() +{ + //create XML + QDomDocument doc; + QDomElement cse=doc.createElement("Customer"); + cse.setAttribute("id",m_id); + cse.setAttribute("name",m_name); + QDomElement el=doc.createElement("Address"); + el.appendChild(doc.createTextNode(m_address)); + cse.appendChild(el); + el=doc.createElement("Contact"); + el.appendChild(doc.createTextNode(m_contact)); + cse.appendChild(el); + el=doc.createElement("Comment"); + el.appendChild(doc.createTextNode(m_comment)); + cse.appendChild(el); + doc.appendChild(cse); + //request + m_req->request("setcustomer",doc.toByteArray()); + //TODO: do something useful with the result +} /*********************************************************/ @@ -92,8 +190,12 @@ MCustomerListDialog::MCustomerListDialog(MWebRequest*r,QWidget*par,bool isselect hl->addLayout(vl2=new QVBoxLayout,0); QPushButton*p; vl2->addWidget(p=new QPushButton(tr("Details...")),0); + connect(p,SIGNAL(clicked()),this,SLOT(editCustomer())); vl2->addWidget(p=new QPushButton(tr("Create new...")),0); + connect(p,SIGNAL(clicked()),this,SLOT(newCustomer())); vl2->addWidget(p=new QPushButton(tr("Delete...")),0); + connect(p,SIGNAL(clicked()),this,SLOT(deleteCustomer())); + p->setEnabled(false); vl2->addStretch(2); vl->addSpacing(15); vl->addLayout(hl=new QHBoxLayout,0); @@ -145,3 +247,92 @@ MCustomer MCustomerListDialog::getCustomer() if(i<0||i>=m_list.size())return MCustomer(); return m_list[i]; } + +void MCustomerListDialog::newCustomer() +{ + MCustomerDialog cd(MCustomer(),this); + if(cd.exec()==QDialog::Accepted) + updateList(); +} +void MCustomerListDialog::editCustomer() +{ + //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; + //open dialog + MCustomerDialog cd(m_list[i],this); + if(cd.exec()==QDialog::Accepted) + updateList(); +} +void MCustomerListDialog::deleteCustomer() +{ + //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 + +} + + +/****************************************************************/ + +MCustomerDialog::MCustomerDialog(MCustomer c,QWidget*par) + :QDialog(par),m_cust(c) +{ + if(m_cust.isValid()) + setWindowTitle(tr("Customer %1").arg(m_cust.name())); + else + setWindowTitle(tr("New Customer")); + + //layout + QGridLayout *gl; + setLayout(gl=new QGridLayout); + int lc=0; + gl->addWidget(new QLabel(tr("Name:")),lc,0); + gl->addWidget(m_name=new QLineEdit(m_cust.name()),lc,1); + gl->addWidget(new QLabel(tr("Address:")),++lc,0); + gl->addWidget(m_addr=new QTextEdit,lc,1); + m_addr->setPlainText(m_cust.address()); + gl->addWidget(new QLabel(tr("Contact Information:")),++lc,0); + gl->addWidget(m_cont=new QTextEdit,lc,1); + m_cont->setPlainText(m_cust.contact()); + gl->setRowMinimumHeight(++lc,10); + gl->addWidget(new QLabel(tr("Web-Login/eMail:")),++lc,0); + gl->addWidget(m_mail=new QLabel(m_cust.mail()),lc,1); + gl->setRowMinimumHeight(++lc,10); + gl->addWidget(new QLabel(tr("Comment:")),++lc,0,1,2); + gl->addWidget(m_comm=new QTextEdit,++lc,0,1,2); + m_comm->setPlainText(m_cust.comment()); + gl->setRowMinimumHeight(++lc,15); + QHBoxLayout*hl; + gl->addLayout(hl=new QHBoxLayout,++lc,0,1,2); + hl->addStretch(10); + QPushButton*p; + hl->addWidget(p=new QPushButton(tr("Save")),0); + connect(p,SIGNAL(clicked()),this,SLOT(accept())); + connect(p,SIGNAL(clicked()),this,SLOT(save())); + hl->addWidget(p=new QPushButton(tr("Cancel")),0); + connect(p,SIGNAL(clicked()),this,SLOT(reject())); +} + +MCustomer MCustomerDialog::getCustomer() +{ + //copy data from input fields + m_cust.setName(m_name->text()); + m_cust.setAddress(m_addr->toPlainText()); + m_cust.setContact(m_cont->toPlainText()); + m_cust.setComment(m_comm->toPlainText()); + return m_cust; +} + +void MCustomerDialog::save() +{ + getCustomer(); + m_cust.save(); +} \ No newline at end of file diff --git a/src/customer.h b/src/customer.h index 3e0b2a0..eead30b 100644 --- a/src/customer.h +++ b/src/customer.h @@ -42,12 +42,47 @@ class MCustomer /**returns the customers name*/ QString name(); + /**sets the name of the customer*/ + void setName(QString); + + /**returns the address of the customer*/ + QString address(); + + /**sets the address of the customer*/ + void setAddress(QString); + + /**returns the contact information*/ + QString contact(); + + /**sets the contact info of the customer*/ + void setContact(QString); + + /**returns the login-mail-address for the web-interface*/ + QString mail(); + + /**returns the comment data*/ + QString comment(); + + /**sets the comment for the customer*/ + void setComment(QString); + /**returns the customers name and address*/ QString getNameAddress(); + + /**saves the data back to the server; this does not transfer web-login data*/ + void save(); + private: qint64 m_id; - QString m_name; + QString m_name,m_address,m_contact,m_mail,m_comment; + bool m_iscomplete; MWebRequest*m_req; + + /**internal: requests data update*/ + void getUpdate(); + + /**internal helper: scan XML data*/ + void scanXml(const QDomElement&); }; class QListView; @@ -61,7 +96,16 @@ class MCustomerListDialog:public QDialog /**creates a new customer list dialog; expects a usable webrequest object and a parent, if isselect is set to true it offers a select button, if selected is set to a matching customerID it will be pre-selected*/ MCustomerListDialog(MWebRequest*,QWidget*,bool isselect=false,qint64 selected=-1); + /**returns the selected customer*/ MCustomer getCustomer(); + + private slots: + /**internal: new customer*/ + void newCustomer(); + /**internal: edit selected customer*/ + void editCustomer(); + /**internal: delete selected customer*/ + void deleteCustomer(); private: QList m_list; @@ -73,4 +117,30 @@ class MCustomerListDialog:public QDialog void updateList(); }; +class QLineEdit; +class QTextEdit; +class QLabel; + +/**edit a specific customer*/ +class MCustomerDialog:public QDialog +{ + Q_OBJECT + public: + /**creates a new customer dialog*/ + MCustomerDialog(MCustomer,QWidget*); + + /**returns the customer as currently entered*/ + MCustomer getCustomer(); + + private slots: + /**internal: save data*/ + void save(); + + private: + MCustomer m_cust; + QLineEdit*m_name; + QTextEdit*m_addr,*m_cont,*m_comm; + QLabel*m_mail; +}; + #endif diff --git a/src/overview.cpp b/src/overview.cpp index ad7eb1b..b2364ae 100644 --- a/src/overview.cpp +++ b/src/overview.cpp @@ -33,6 +33,7 @@ #include #include #include +#include MOverview::MOverview(MWebRequest*mw,QString pk) { @@ -55,7 +56,7 @@ MOverview::MOverview(MWebRequest*mw,QString pk) m->addAction(tr("&New Event..."),this,SLOT(newEvent()))->setEnabled(req->hasRole("createevent")); m=mb->addMenu(tr("&Customer")); - m->addAction(tr("&Show all customers")); + m->addAction(tr("&Show all customers"),this,SLOT(customerMgmt())); m=mb->addMenu(tr("C&art")); m->addAction(tr("Add &Ticket")); @@ -95,14 +96,21 @@ MOverview::MOverview(MWebRequest*mw,QString pk) carttab->setLayout(vl=new QVBoxLayout); vl->addLayout(hl=new QHBoxLayout); QVBoxLayout*vl2; - hl->addLayout(vl2=new QVBoxLayout,1); - vl2->addWidget(new QTableView,10); + hl->addLayout(vl2=new QVBoxLayout,2); + vl2->addWidget(carttable=new QTableView,10); + carttable->setModel(cartmodel=new QStandardItemModel(this)); + carttable->setSelectionMode(QAbstractItemView::SingleSelection); + carttable->setItemDelegate(new MCartTableDelegate(this)); QHBoxLayout*hl2; vl2->addLayout(hl2=new QHBoxLayout,0); hl2->addStretch(10); hl2->addWidget(p=new QPushButton(tr("Add Ticket")),0); + connect(p,SIGNAL(clicked()),this,SLOT(cartAddTicket())); hl2->addWidget(p=new QPushButton(tr("Add Voucher")),0); + connect(p,SIGNAL(clicked()),this,SLOT(cartAddVoucher())); + p->setEnabled(false); hl2->addWidget(p=new QPushButton(tr("Remove Item")),0); + connect(p,SIGNAL(clicked()),this,SLOT(cartRemoveItem())); QFrame*frm; hl->addWidget(frm=new QFrame,0); frm->setFrameShape(QFrame::VLine); @@ -114,10 +122,10 @@ MOverview::MOverview(MWebRequest*mw,QString pk) frm->setFrameShape(QFrame::HLine); vl2->addSpacing(10); vl2->addWidget(new QLabel(tr("Delivery Address:")),0); - vl2->addWidget(new QTextEdit); + vl2->addWidget(cartaddr=new QTextEdit); vl2->addSpacing(10); vl2->addWidget(new QLabel(tr("Comments:")),0); - vl2->addWidget(new QTextEdit); + vl2->addWidget(cartcomment=new QTextEdit); vl2->addStretch(10); vl->addWidget(frm=new QFrame,0); frm->setFrameShape(QFrame::HLine); @@ -125,9 +133,12 @@ MOverview::MOverview(MWebRequest*mw,QString pk) hl->addStretch(10); hl->addWidget(p=new QPushButton(tr("Order Items"))); p->setEnabled(req->hasRole("createorder")); + connect(p,SIGNAL(clicked()),this,SLOT(cartOrder())); hl->addWidget(p=new QPushButton(tr("Sell Items"))); p->setEnabled(req->hasRole("createsale")); + connect(p,SIGNAL(clicked()),this,SLOT(cartSell())); hl->addWidget(p=new QPushButton(tr("Clear"))); + connect(p,SIGNAL(clicked()),this,SLOT(initCart())); //user tab tab->addTab(usertab=new QWidget,tr("Users")); @@ -202,6 +213,8 @@ MOverview::MOverview(MWebRequest*mw,QString pk) if(!req->hasRole("createorder")&&!req->hasRole("createsale")){ carttab->setEnabled(false); tab->setTabEnabled(tab->indexOf(carttab),false); + }else{ + initCart(); } if(req->hasRole("getusers")){ updateUsers(); @@ -569,6 +582,37 @@ void MOverview::exportHost() void MOverview::eventOrderTicket() { + //get selected event + int id; + QModelIndexList ilst=eventtable->selectionModel()->selectedIndexes(); + if(ilst.size()<1)return; + QModelIndex idx=eventmodel->index(ilst[0].row(),0); + id=eventmodel->data(idx,Qt::UserRole).toInt(); + if(id<0)return; + //activate order tab + tab->setCurrentWidget(carttab); + //insert event into table + int cr=cartmodel->rowCount(); + cartmodel->insertRows(cr,1); + cartmodel->setData(cartmodel->index(cr,0),1); + cartmodel->setData(cartmodel->index(cr,0),id,Qt::UserRole); + cartmodel->setData(cartmodel->index(cr,1),eventmodel->data(eventmodel->index(ilst[0].row(),1))); + cartmodel->setData(cartmodel->index(cr,2),eventmodel->data(eventmodel->index(ilst[0].row(),0))); + carttable->resizeColumnToContents(0); + carttable->resizeColumnToContents(1); + carttable->resizeColumnToContents(2); +} + +void MOverview::initCart() +{ + //clear cart + cartmodel->clear(); + cartmodel->setHorizontalHeaderLabels(QStringList()<setPlainText(""); + cartcomment->setPlainText(""); } void MOverview::setCustomer() @@ -579,6 +623,73 @@ void MOverview::setCustomer() cartcustomer->setText(customer.getNameAddress()); } +void MOverview::cartAddTicket() +{ + //create ticket selection dialog + QDialog dlg; + dlg.setWindowTitle(tr("Select Event to order Ticket")); + QTableView*tv; + QHBoxLayout*hl; + QVBoxLayout*vl; + dlg.setLayout(vl=new QVBoxLayout); + vl->addWidget(tv=new QTableView,10); + tv->setModel(eventmodel); + tv->setEditTriggers(QAbstractItemView::NoEditTriggers); + tv->resizeColumnToContents(0); + tv->resizeColumnToContents(1); + vl->addSpacing(15); + vl->addLayout(hl=new QHBoxLayout,0); + hl->addStretch(10); + QPushButton*p; + hl->addWidget(p=new QPushButton(tr("Select")),0); + connect(p,SIGNAL(clicked()),&dlg,SLOT(accept())); + hl->addWidget(p=new QPushButton(tr("Cancel")),0); + connect(p,SIGNAL(clicked()),&dlg,SLOT(reject())); + //wait for it + if(dlg.exec()==QDialog::Accepted){ + //get selection + QModelIndex idx=tv->currentIndex(); + if(!idx.isValid())return; + int id=eventmodel->data(eventmodel->index(idx.row(),0),Qt::UserRole).toInt(); + if(id<0)return; + //copy to cart + int cr=cartmodel->rowCount(); + cartmodel->insertRows(cr,1); + cartmodel->setData(cartmodel->index(cr,0),1); + cartmodel->setData(cartmodel->index(cr,0),id,Qt::UserRole); + cartmodel->setData(cartmodel->index(cr,1),eventmodel->data(eventmodel->index(idx.row(),1))); + cartmodel->setData(cartmodel->index(cr,2),eventmodel->data(eventmodel->index(idx.row(),0))); + carttable->resizeColumnToContents(0); + carttable->resizeColumnToContents(1); + carttable->resizeColumnToContents(2); + } +} + +void MOverview::cartRemoveItem() +{ + //get selection + QModelIndex idx=carttable->currentIndex(); + if(!idx.isValid())return; + //remove row + cartmodel->removeRow(idx.row()); +} + +void MOverview::cartOrder() +{ + //TODO: implement +} + +void MOverview::cartSell() +{ + //TODO: implement +} + +void MOverview::customerMgmt() +{ + MCustomerListDialog mcl(req,this); + mcl.exec(); +} + /**********************************************/ @@ -626,3 +737,43 @@ QString MPasswordChange::newPassword() if(newpwd1->text()!=newpwd2->text())return ""; return newpwd1->text(); } + + +/********************************************************************************/ + +MCartTableDelegate::MCartTableDelegate(QObject*p) + :QItemDelegate(p) +{ +} + +QWidget *MCartTableDelegate::createEditor(QWidget *parent, + const QStyleOptionViewItem &/* option */, + const QModelIndex & index ) const +{ + //base class + if(index.column()!=0)return 0; + + QSpinBox *editor = new QSpinBox(parent); + editor->setRange(0,1000); + editor->installEventFilter(const_cast(this)); + return editor; +} + +void MCartTableDelegate::setEditorData(QWidget *editor, const QModelIndex &index) const +{ + //name field + int c=index.column(); + if(c==0) + ((QSpinBox*)editor)->setValue(index.model()->data(index).toInt()); +} + +void MCartTableDelegate::setModelData(QWidget *editor, QAbstractItemModel *model, + const QModelIndex &index) const +{ + //name field + int c=index.column(); + if(c==0){ + int newval=((QSpinBox*)editor)->value(); + model->setData(index,newval); + } +} diff --git a/src/overview.h b/src/overview.h index 567151d..c92c5fc 100644 --- a/src/overview.h +++ b/src/overview.h @@ -16,6 +16,7 @@ #include #include #include +#include #include "customer.h" @@ -85,6 +86,21 @@ class MOverview:public QMainWindow /**decide what customer to use*/ void setCustomer(); + /**initialize cart tab*/ + void initCart(); + /**add a ticket to the cart*/ + void cartAddTicket(); + /**add a voucher to the cart*/ + //void cartAddVoucher(); + /**remove item from the cart*/ + void cartRemoveItem(); + /**send the order to the server*/ + void cartOrder(); + /**send the order to the server as sold*/ + void cartSell(); + + /**manage customers*/ + void customerMgmt(); private: //my session object @@ -94,10 +110,11 @@ class MOverview:public QMainWindow //widgets QTabWidget*tab; QWidget*eventtab,*carttab,*usertab,*hosttab; - QTableView*eventtable,*usertable,*hosttable; - QStandardItemModel*eventmodel,*usermodel,*hostmodel; + QTableView*eventtable,*usertable,*hosttable,*carttable; + QStandardItemModel*eventmodel,*usermodel,*hostmodel,*cartmodel; QPushButton*thishostbutton; QLabel*cartcustomer; + QTextEdit *cartaddr,*cartcomment; //cart MCustomer customer; }; @@ -118,4 +135,19 @@ class MPasswordChange:public QDialog QLineEdit *oldpwd,*newpwd1,*newpwd2; }; +/**Helper class for shopping cart: allow editing amount, but nothing else*/ +class MCartTableDelegate:public QItemDelegate +{ + public: + MCartTableDelegate(QObject *parent = 0); + + QWidget *createEditor(QWidget *parent, const QStyleOptionViewItem &option, + const QModelIndex &index) const; + + void setEditorData(QWidget *editor, const QModelIndex &index) const; + void setModelData(QWidget *editor, QAbstractItemModel *model, + const QModelIndex &index) const; +}; + + #endif diff --git a/src/smoke.pro b/src/smoke.pro index 7e59249..ab359f9 100644 --- a/src/smoke.pro +++ b/src/smoke.pro @@ -53,7 +53,9 @@ HEADERS = \ checkdlg.h \ ../www/machine.php \ ../www/inc/machine/session.php \ - ../www/inc/machine/host.php + ../www/inc/machine/host.php \ + ../www/inc/machine/template.php \ + ../www/inc/classes/customer.php RESOURCES += files.qrc