From 320501f63ceaff1affaa452e2f5c764e9ab38f58 Mon Sep 17 00:00:00 2001 From: konrad Date: Mon, 4 Jan 2010 18:22:06 +0000 Subject: [PATCH] customer management almost complete (contacts are missing) git-svn-id: https://silmor.de/svn/softmagic/smoke/trunk@402 6e3c4bff-ac9f-4ac1-96c5-d2ea494d3e33 --- src/dialogs/customerdlg.cpp | 374 ++++++++++++++++++++++++++++++++++++++-- src/dialogs/customerdlg.h | 142 +++++++++++++++- src/mwin/carttab.cpp | 10 +- src/mwin/overview.cpp | 19 ++- src/wext/MOAddress.cpp | 4 +- src/wext/MOAddress.h | 5 +- src/wext/MOCustomer.cpp | 6 + src/wext/MOCustomer.h | 10 + src/wext/MOCustomerInfo.h | 4 + wob/customer.wolf | 61 ++++++- www/inc/db/db.php | 3 + www/inc/db/db_mysql.php | 9 + www/inc/wbase/transaction.php | 6 + www/inc/wext/autoload.php | 1 + www/inc/wext/customer.php | 161 ++++++++++++++++++ 15 files changed, 775 insertions(+), 40 deletions(-) create mode 100644 www/inc/wext/customer.php diff --git a/src/dialogs/customerdlg.cpp b/src/dialogs/customerdlg.cpp index 58e772a..181dca4 100644 --- a/src/dialogs/customerdlg.cpp +++ b/src/dialogs/customerdlg.cpp @@ -18,12 +18,15 @@ #include #include #include +#include #include +#include #include #include #include #include #include +#include #include #include #include @@ -59,10 +62,10 @@ MCustomerListDialog::MCustomerListDialog(QWidget*par,bool isselect,qint64 presel 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(req->hasRole("setcustomer")); + p->setEnabled(req->hasRight(req->RCreateCustomer)); vl2->addWidget(p=new QPushButton(tr("Delete...")),0); connect(p,SIGNAL(clicked()),this,SLOT(deleteCustomer())); - p->setEnabled(req->hasRole("deletecustomer")); + p->setEnabled(req->hasRight(req->RDeleteCustomer)); vl2->addStretch(2); vl->addSpacing(15); vl->addLayout(hl=new QHBoxLayout,0); @@ -148,7 +151,7 @@ void MCustomerListDialog::editCustomer() //open dialog MCustomerDialog cd(gc.getcustomer().value(),this); if(cd.exec()==QDialog::Accepted) - updateList(); + updateList(m_list[i].customerid()); } void MCustomerListDialog::deleteCustomer() { @@ -207,49 +210,382 @@ MCustomerDialog::MCustomerDialog(MOCustomer c,QWidget*par) //layout QGridLayout *gl; - setLayout(gl=new QGridLayout); + QVBoxLayout*vl,*vl2; + QHBoxLayout*hl; + QTabWidget*tab; + QPushButton*p; + QWidget*w; + + setLayout(vl=new QVBoxLayout); + vl->addWidget(tab=new QTabWidget); + tab->addTab(w=new QWidget,tr("Customer")); + + w->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); - //FIXME -// m_cont->setPlainText(m_cust.contact()); + gl->addWidget(new QLabel(tr("First Name:")),++lc,0); + gl->addWidget(m_fname=new QLineEdit(m_cust.firstname()),lc,1); + gl->addWidget(new QLabel(tr("Title:")),++lc,0); + gl->addWidget(m_title=new QLineEdit(m_cust.title()),lc,1); gl->setRowMinimumHeight(++lc,10); gl->addWidget(new QLabel(tr("Web-Login/eMail:")),++lc,0); gl->addWidget(m_mail=new QLabel(m_cust.email()),lc,1); + gl->addWidget(p=new QPushButton(tr("Edit Login")),++lc,1); + p->setEnabled(false);//TODO: implement edit customer login 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.comments()); + gl->setRowStretch(lc,10); gl->setRowMinimumHeight(++lc,15); - QHBoxLayout*hl; - gl->addLayout(hl=new QHBoxLayout,++lc,0,1,2); + + tab->addTab(w=new QWidget,tr("Addresses")); + w->setLayout(vl2=new QVBoxLayout); + vl2->addWidget(m_addr=new MAddressListWidget(0,m_cust.addresses()),10); + vl2->addLayout(hl=new QHBoxLayout,0); + hl->addStretch(10); + hl->addWidget(p=new QPushButton(tr("Add Address")),0); + connect(p,SIGNAL(clicked()),m_addr,SLOT(createAddress())); + + tab->addTab(w=new QWidget,tr("Contact Information")); + w->setLayout(gl=new QGridLayout); + gl->addWidget(new QLabel(tr("Contact Information:")),++lc,0); + gl->addWidget(new QTextEdit,lc,1); + //FIXME +// m_cont->setPlainText(m_cust.contact()); + + + vl->addLayout(hl=new QHBoxLayout,0); hl->addStretch(10); - QPushButton*p; hl->addWidget(p=new QPushButton(tr("Save")),0); - connect(p,SIGNAL(clicked()),this,SLOT(accept())); + //make sure saving is faster than closing the dialog + connect(p,SIGNAL(clicked()),this,SLOT(accept()),Qt::QueuedConnection); connect(p,SIGNAL(clicked()),this,SLOT(save())); hl->addWidget(p=new QPushButton(tr("Cancel")),0); connect(p,SIGNAL(clicked()),this,SLOT(reject())); + + setSizeGripEnabled(true); } MOCustomer MCustomerDialog::getCustomer() { //copy data from input fields m_cust.setname(m_name->text()); - //TODO: redo address editing - //m_cust.setaddress(m_addr->toPlainText()); + m_cust.setfirstname(m_fname->text()); + m_cust.settitle(m_title->text()); + m_cust.setaddresses(m_addr->addressList()); //m_cust.setcontact(m_cont->toPlainText()); m_cust.setcomments(m_comm->toPlainText()); return m_cust; } void MCustomerDialog::save() -{/*TODO: +{ getCustomer(); - m_cust.save();*/ + if(m_cust.isValid()){ + MTChangeCustomer cc=req->queryChangeCustomer(m_cust); + if(cc.hasError()){ + QMessageBox::warning(this,tr("Warning"),tr("Error while changing customer data: %1").arg(cc.errorString())); + return; + } + m_cust=cc.getcustomer(); + }else{ + MTCreateCustomer cc=req->queryCreateCustomer(m_cust); + if(cc.hasError()){ + QMessageBox::warning(this,tr("Warning"),tr("Error while creating customer data: %1").arg(cc.errorString())); + return; + } + m_cust=cc.getcustomer(); + } +} + +/*****************************************************************************/ + +MAddressWidget::MAddressWidget(QWidget*parent,bool isselect) + :QFrame(parent) +{ + QVBoxLayout*vl; + QHBoxLayout*hl; + QPushButton*p; + setLayout(vl=new QVBoxLayout); + vl->addWidget(m_lab=new QLabel(" "),10); + vl->addLayout(hl=new QHBoxLayout,0); + if(isselect){ + hl->addWidget(p=new QPushButton(tr("Select"))); + connect(p,SIGNAL(clicked()),this,SLOT(selectClick())); + connect(this,SIGNAL(addrValid(bool)),p,SLOT(setEnabled(bool))); + } + hl->addWidget(p=new QPushButton(tr("Edit"))); + connect(p,SIGNAL(clicked()),this,SLOT(editClick())); + connect(this,SIGNAL(addrValid(bool)),p,SLOT(setEnabled(bool))); + hl->addWidget(p=new QPushButton(tr("Delete"))); + connect(p,SIGNAL(clicked()),this,SLOT(delClick())); + connect(this,SIGNAL(addrValid(bool)),p,SLOT(setEnabled(bool))); +} + +MOAddress MAddressWidget::address()const{return m_addr;} + +void MAddressWidget::setAddress(const MOAddress&a) +{ + m_addr=a; + emit addrValid(!a.addressid().isNull()); + setEnabled(!a.isdeleted().value()); + redisplay(); + emit addressChanged(m_addr); +} + +void MAddressWidget::redisplay() +{ + m_lab->setText(m_addr.fullAddress()); + m_lab->setMinimumSize(m_lab->sizeHint()); + m_lab->adjustSize(); + adjustSize(); +} + +void MAddressWidget::setAddress(qint64 id) +{ + setAddress(MTGetAddress::query(id).getaddress()); +} + +void MAddressWidget::clearAddress() +{ + m_addr=MOAddress(); + emit addrValid(false); + setEnabled(false); + redisplay(); + emit addressChanged(m_addr); +} + +void MAddressWidget::editClick() +{ + MAddressDialog d(this,m_addr); + if(d.exec()==QDialog::Accepted){ + m_addr=d.address(); + emit addrValid(!m_addr.addressid().isNull()); + setEnabled(!m_addr.isdeleted().value()); + redisplay(); + emit addressEdited(m_addr); + emit addressChanged(m_addr); + } +} + +void MAddressWidget::delClick() +{ + if(QMessageBox::question(this,tr("Delete Address"),tr("Really delete this address?\n%1").arg(m_addr.fullAddress()),QMessageBox::Yes|QMessageBox::No)!=QMessageBox::Yes) + return; + m_addr.setisdeleted(true); + setEnabled(false); + emit addressEdited(m_addr); + emit addressDeleted(m_addr); + emit addressChanged(m_addr); +} + +void MAddressWidget::selectClick() +{ + emit addressSelected(m_addr); + emit addressSelected(m_addr.addressid()); +} + +/*****************************************************************************/ + +//number of columns in the address list widget +#define ADDRCOLS 3 + +MAddressListWidget::MAddressListWidget(QWidget*parent,const QList&addr,bool isselect) + :QScrollArea(parent),m_select(isselect) +{ + map=new QSignalMapper(this); + connect(map,SIGNAL(mapped(int)),this,SLOT(addrEdit(int)),Qt::DirectConnection); + QWidget*w; + setWidget(w=new QWidget); + setWidgetResizable(true); + QVBoxLayout*vl; + w->setLayout(vl=new QVBoxLayout); + vl->addLayout(m_layout=new QGridLayout,0); + vl->addStretch(10); + for(int i=0;i(map->mapping(id)); + if(aw==0)return; + qDebug("handling edit"); + m_addr[id]=aw->address(); + aw->adjustSize(); + widget()->adjustSize(); +} + +void MAddressListWidget::addrSel(const MOAddress&a) +{ + m_sel=a; +} + +void MAddressListWidget::addAddr(const MOAddress&addr,bool vis) +{ + //create + int id=m_addr.size(); + m_addr<setAddress(addr); + aw->setFrameStyle(QFrame::Box|QFrame::Raised); + map->setMapping(aw,id); + //display + m_layout->addWidget(aw,id/ADDRCOLS,id%ADDRCOLS); + aw->setSizePolicy(QSizePolicy::Preferred,QSizePolicy::MinimumExpanding); + aw->adjustSize(); + widget()->adjustSize(); + if(vis)ensureWidgetVisible(aw); + //connections to myself + connect(aw,SIGNAL(addressEdited(const MOAddress&)),map,SLOT(map()),Qt::DirectConnection); + connect(aw,SIGNAL(addressSelected(const MOAddress&)),this,SLOT(addrSel(const MOAddress&)),Qt::DirectConnection); + //proxy connections + connect(aw,SIGNAL(addressEdited(const MOAddress&)),this,SIGNAL(addressEdited(const MOAddress&)),Qt::QueuedConnection); + connect(aw,SIGNAL(addressChanged(const MOAddress&)),this,SIGNAL(addressChanged(const MOAddress&)),Qt::QueuedConnection); + connect(aw,SIGNAL(addressDeleted(const MOAddress&)),this,SIGNAL(addressDeleted(const MOAddress&)),Qt::QueuedConnection); + connect(aw,SIGNAL(addressSelected(const MOAddress&)),this,SIGNAL(addressSelected(const MOAddress&)),Qt::QueuedConnection); + connect(aw,SIGNAL(addressSelected(qint64)),this,SIGNAL(addressSelected(qint64)),Qt::QueuedConnection); +} + +void MAddressListWidget::preselect(int i) +{ + if(i<0 || i>=m_addr.size())return; + MAddressWidget*aw=qobject_cast(map->mapping(i)); + if(!aw)return; + //set new selection + aw->setFrameStyle(QFrame::Box | QFrame::Plain); + aw->setLineWidth(2); + m_sel=m_addr[i]; + //make sure it is visible + ensureWidgetVisible(aw); + aw->adjustSize(); + widget()->adjustSize(); +} + +void MAddressListWidget::createAddress() +{ + MAddressDialog d(this); + if(d.exec()!=QDialog::Accepted)return; + addAddr(d.address()); + emit addressCreated(m_addr[m_addr.size()-1]); +} + +/*****************************************************************************/ + +MAddressDialog::MAddressDialog(QWidget*parent,MOAddress addr) + :QDialog(parent),m_addr(addr) +{ + if(!m_addr.addressid().isNull()) + setWindowTitle(tr("Edit Address")); + else + setWindowTitle(tr("Create Address")); + + QVBoxLayout*vl; + QHBoxLayout*hl; + QFormLayout*fl; + QPushButton*p; + setLayout(vl=new QVBoxLayout); + vl->addLayout(fl=new QFormLayout,0); + if(m_addr.isValid()) + fl->addRow(tr("Last used:"),new QLabel(QDateTime::fromTime_t(m_addr.lastused()).toString())); + fl->addRow(tr("Name:"),m_name=new QLineEdit(m_addr.name())); + fl->addRow(tr("Address:"),m_addr1=new QLineEdit(m_addr.addr1())); + fl->addRow(tr("Address:"),m_addr2=new QLineEdit(m_addr.addr2())); + fl->addRow(tr("City:"),m_city=new QLineEdit(m_addr.city())); + fl->addRow(tr("State:"),m_state=new QLineEdit(m_addr.state())); + fl->addRow(tr("ZIP Code:"),m_zip=new QLineEdit(m_addr.zipcode())); + fl->addRow(tr("Country:"),hl=new QHBoxLayout); + hl->addWidget(m_country=new QLineEdit(m_addr.country().value().name()),10); + m_country->setReadOnly(true); + hl->addWidget(p=new QPushButton("..."),0); + connect(p,SIGNAL(clicked()),this,SLOT(selectCountry())); + + vl->addStretch(10); + vl->addLayout(hl=new QHBoxLayout,0); + hl->addStretch(10); + hl->addWidget(p=new QPushButton(tr("Ok")),0); + connect(p,SIGNAL(clicked()),this,SLOT(accept())); + hl->addWidget(p=new QPushButton(tr("Cancel")),0); + connect(p,SIGNAL(clicked()),this,SLOT(reject())); +} + +MOAddress MAddressDialog::address() +{ + //set pseudo-ID to make it appear valid to other widgets + if(m_addr.addressid().isNull())m_addr.setaddressid(-1); + //set properties + m_addr.setname(m_name->text()); + m_addr.setaddr1(m_addr1->text()); + m_addr.setaddr2(m_addr2->text()); + m_addr.setcity(m_city->text()); + m_addr.setstate(m_state->text()); + m_addr.setzipcode(m_zip->text()); + //country and countryid is set by selectCountry + + return m_addr; +} + +void MAddressDialog::selectCountry() +{ + //get countries + QListcntry=MTGetAllCountries::query().getcountries(); + QStringList clst; + int cur=0; + QString curstr=m_country->text(); + for(int i=0;ihasRight(req->RCreateCountry)) + clst<setText(cntry[i].name()); + return; + } + } + //not found: must be the create new entry + QDialog d(this); + d.setWindowTitle(tr("Create New Country")); + QVBoxLayout*vl; + QHBoxLayout*hl; + QFormLayout*fl; + QLineEdit*name,*abbr; + QPushButton*p; + d.setLayout(vl=new QVBoxLayout); + vl->addLayout(fl=new QFormLayout); + fl->addRow(tr("Country Name:"),name=new QLineEdit); + fl->addRow(tr("Abbreviation:"),abbr=new QLineEdit); + vl->addStretch(10); + vl->addLayout(hl=new QHBoxLayout,0); + hl->addStretch(10); + hl->addWidget(p=new QPushButton(tr("Ok")),0); + connect(p,SIGNAL(clicked()),&d,SLOT(accept())); + hl->addWidget(p=new QPushButton(tr("Cancel")),0); + connect(p,SIGNAL(clicked()),&d,SLOT(reject())); + //wait and check + if(d.exec()!=QDialog::Accepted)return; + if(name->text().trimmed()=="" || abbr->text().trimmed()==""){ + QMessageBox::warning(this,tr("Warning"),tr("The country name and abbreviation must contain something!")); + return; + } + //create + MTCreateCountry cc=MTCreateCountry::query(abbr->text().trimmed(),name->text().trimmed()); + if(cc.hasError()){ + QMessageBox::warning(this,tr("Warning"),tr("Error while creating country: %1").arg(cc.errorString())); + return; + } + m_addr.setcountry(cc.getcountry()); + m_addr.setcountryid(m_addr.country().value().id()); + m_country->setText(m_addr.country().value().name()); } diff --git a/src/dialogs/customerdlg.h b/src/dialogs/customerdlg.h index 524ec69..bdd5a2c 100644 --- a/src/dialogs/customerdlg.h +++ b/src/dialogs/customerdlg.h @@ -15,7 +15,9 @@ #include #include +#include #include +#include #include "MOCustomerInfo.h" #include "MOCustomer.h" @@ -59,6 +61,141 @@ class QLineEdit; class QTextEdit; class QLabel; +/**displays exactly one address; even though it offers to edit or delete addresses, it does not actually do any change on the database*/ +class MAddressWidget:public QFrame +{ + Q_OBJECT + public: + /**creates the widget, if isselect==true a "select" button is shown*/ + MAddressWidget(QWidget*parent=0,bool isselect=false); + + /**returns the currently shown address*/ + MOAddress address()const; + + public slots: + /**sets the address to be shown, enables the buttons if it is valid*/ + void setAddress(const MOAddress&); + + /**convenience method: sets the address to be shown, retrieves it from the database*/ + void setAddress(qint64); + + /**clears the display, disables the buttons*/ + void clearAddress(); + + signals: + /**emitted if the address has changed, the parameter contains the current content; + this also emits if the address has changed or cleared programmatically, use addressEdited if you want only manual changes*/ + void addressChanged(const MOAddress&); + + /**emitted if the address was changed by the user, contains the current address content*/ + void addressEdited(const MOAddress&); + + /**emitted if the address was deleted by the user, addressEdited is also emitted*/ + void addressDeleted(const MOAddress&); + + /**emitted if the user presses the "select" button, contains the address*/ + void addressSelected(const MOAddress&); + + /**emitted if the user presses the "select" button, contains the address ID*/ + void addressSelected(qint64); + + /**internal: used to activate or de-activate buttons*/ + void addrValid(bool); + + private slots: + /**internal: the user clicked edit*/ + void editClick(); + /**internal: the user clicked delete*/ + void delClick(); + /**internal: the user clicked select*/ + void selectClick(); + /**internal: re-display the address*/ + void redisplay(); + + private: + MOAddress m_addr; + QLabel*m_lab; +}; + +class QSignalMapper; +class QGridLayout; + +/**widget that displays a list of addresses, it uses MAddressWidget to display every single address*/ +class MAddressListWidget:public QScrollArea +{ + Q_OBJECT + public: + /**creates the widget*/ + MAddressListWidget(QWidget*parent,const QList&,bool isselect=false); + + /**returns the current list*/ + QList addressList()const{return m_addr;} + + /**returns the selected address*/ + MOAddress selection()const{return m_sel;} + + signals: + /**emitted if the address has changed, the parameter contains the current content; + this also emits if the address has changed programmatically, use addressEdited if you want only manual changes*/ + void addressChanged(const MOAddress&); + + /**emitted if the address was changed by the user, contains the current address content*/ + void addressEdited(const MOAddress&); + + /**emitted if the address was deleted by the user, addressEdited is also emitted*/ + void addressDeleted(const MOAddress&); + + /**emitted if the user presses the "select" button, contains the address*/ + void addressSelected(const MOAddress&); + + /**emitted if the user presses the "select" button, contains the address ID*/ + void addressSelected(qint64); + + /**emitted if the user creates a new address via createAddress()*/ + void addressCreated(const MOAddress&); + + public slots: + /**asks the user for a new address*/ + void createAddress(); + + /**pre-selects an address by its position in the current address list, this method should only be called once!*/ + void preselect(int); + + private slots: + /**internal: used to change an address after editing*/ + void addrEdit(int); + + /**internal: used to remember the selected address*/ + void addrSel(const MOAddress&); + + /**internal: add an address widget, if the boolean is true it is also made visible*/ + void addAddr(const MOAddress&,bool v=false); + + private: + QListm_addr; + MOAddress m_sel; + QSignalMapper *map; + bool m_select; + QGridLayout*m_layout; +}; + +/**dialog for editing exactly one address*/ +class MAddressDialog:public QDialog +{ + Q_OBJECT + public: + /**creates the dialog, if no valid address is given it displays as "create address" otherwise as "edit address"*/ + MAddressDialog(QWidget*parent=0,MOAddress addr=MOAddress()); + + /**returns the address*/ + MOAddress address(); + private slots: + void selectCountry(); + private: + QLineEdit *m_name,*m_addr1,*m_addr2,*m_city,*m_state,*m_zip,*m_country; + MOAddress m_addr; +}; + /**edit a specific customer*/ class MCustomerDialog:public QDialog { @@ -76,8 +213,9 @@ class MCustomerDialog:public QDialog private: MOCustomer m_cust; - QLineEdit*m_name; - QTextEdit*m_addr,*m_cont,*m_comm; + QLineEdit*m_name,*m_fname,*m_title; + QTextEdit*m_comm; + MAddressListWidget*m_addr; QLabel*m_mail; }; diff --git a/src/mwin/carttab.cpp b/src/mwin/carttab.cpp index b02fedb..3b1566e 100644 --- a/src/mwin/carttab.cpp +++ b/src/mwin/carttab.cpp @@ -15,6 +15,7 @@ #include "misc.h" #include "msinterface.h" #include "orderwin.h" +#include "customerdlg.h" #include "carttab.h" @@ -90,7 +91,7 @@ MCartTab::MCartTab(QString pk) connect(p,SIGNAL(clicked()),this,SLOT(initCart())); //fill tables - if(!req->hasRole("createorder")&&!req->hasRole("createsale")){ + if(!req->hasRight(req->RCreateOrder)&&!req->hasRight(req->RCreateReservation)){ setEnabled(false); }else{ initCart(); @@ -140,11 +141,12 @@ void MCartTab::initCart() } void MCartTab::setCustomer() -{/*TODO - MCustomerListDialog mcl(req,this,true,customer.customerID()); +{ + MCustomerListDialog mcl(this,true,customer.id()); if(mcl.exec()!=QDialog::Accepted)return; customer=mcl.getCustomer(); - cartcustomer->setText(customer.getNameAddress());*/ + //TODO: follow up with address dialog +// cartcustomer->setText(customer.getNameAddress()); } static const int CART_TICKET=1; diff --git a/src/mwin/overview.cpp b/src/mwin/overview.cpp index 3eb19ae..ddfd59e 100644 --- a/src/mwin/overview.cpp +++ b/src/mwin/overview.cpp @@ -13,6 +13,7 @@ #include "main.h" #include "msinterface.h" #include "passwdchg.h" +#include "customerdlg.h" #include "overview.h" #include "eventstab.h" @@ -140,7 +141,7 @@ MOverview::MOverview(QString pk) eventtab->setEnabled(false); tab->setTabEnabled(tab->indexOf(eventtab),false); } - if(!req->hasRight(req->RCreateOrder)){ + if(!req->hasRight(req->RCreateOrder)&&!req->hasRight(req->RCreateReservation)){ tab->setTabEnabled(tab->indexOf(carttab),false); } if(!req->hasRight(req->RGetOrderList)){ @@ -192,9 +193,9 @@ void MOverview::setMyPassword() } void MOverview::customerMgmt() -{/*TODO - MCustomerListDialog mcl(req,this); - mcl.exec();*/ +{ + MCustomerListDialog mcl(this); + mcl.exec(); } void MOverview::editShipping() @@ -397,13 +398,17 @@ void MOverview::webSettings(bool showdlg) QComboBox *log; gl->addWidget(new QLabel(tr("Log Level:")),1,0); gl->addWidget(log=new QComboBox,1,1); + log->addItem(tr("No Logging"),MSInterface::LogNone); log->addItem(tr("Minimal Logging"),MSInterface::LogMinimal); + log->addItem(tr("Medium Logging"),MSInterface::LogInfo); log->addItem(tr("Log Details on Error"),MSInterface::LogOnError); log->addItem(tr("Always Log Details"),MSInterface::LogDetailed); switch(lvl){ - case MSInterface::LogMinimal:log->setCurrentIndex(0);break; - case MSInterface::LogOnError:log->setCurrentIndex(1);break; - case MSInterface::LogDetailed:log->setCurrentIndex(2);break; + case MSInterface::LogNone:log->setCurrentIndex(0);break; + case MSInterface::LogMinimal:log->setCurrentIndex(1);break; + case MSInterface::LogInfo:log->setCurrentIndex(2);break; + case MSInterface::LogOnError:log->setCurrentIndex(3);break; + case MSInterface::LogDetailed:log->setCurrentIndex(4);break; } gl->setRowMinimumHeight(2,15); gl->addLayout(hl=new QHBoxLayout,3,0,1,2); diff --git a/src/wext/MOAddress.cpp b/src/wext/MOAddress.cpp index 2f18aea..9a7d8cf 100644 --- a/src/wext/MOAddress.cpp +++ b/src/wext/MOAddress.cpp @@ -14,10 +14,10 @@ #include +static int moaid=qRegisterMetaType("MOAddress"); + QString MOAddress::fullAddress(QString nm)const { - //if not valid: return nothing - if(!isValid())return ""; //collect lines QStringList rl; if(name().isNull()){ diff --git a/src/wext/MOAddress.h b/src/wext/MOAddress.h index 1aea6d9..8c21328 100644 --- a/src/wext/MOAddress.h +++ b/src/wext/MOAddress.h @@ -15,6 +15,8 @@ #include "MOAddressAbstract.h" +#include + class MOAddress:public MOAddressAbstract { WOBJECT(MOAddress); @@ -22,9 +24,10 @@ class MOAddress:public MOAddressAbstract /**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)*/ + /**returns true if this is a valid address stored in the DB (ie. it has an address ID)*/ bool isValid()const{return !addressid().isNull() && addressid().value()>=0;} }; +Q_DECLARE_METATYPE(MOAddress); #endif diff --git a/src/wext/MOCustomer.cpp b/src/wext/MOCustomer.cpp index 93dec4d..587bc76 100644 --- a/src/wext/MOCustomer.cpp +++ b/src/wext/MOCustomer.cpp @@ -11,6 +11,7 @@ // #include "MOCustomer.h" +#include "MOCustomerInfo.h" #include "msinterface.h" MOCustomer::MOCustomer(qint64 i) @@ -20,6 +21,11 @@ MOCustomer::MOCustomer(qint64 i) operator=(gc.getcustomer().value()); } +MOCustomer::MOCustomer(const MOCustomerInfo&i) +{ + MOCustomer::MOCustomer(i.id()); +} + QString MOCustomer::address(int i) { if(i<0)return ""; diff --git a/src/wext/MOCustomer.h b/src/wext/MOCustomer.h index 5a81583..95a61f3 100644 --- a/src/wext/MOCustomer.h +++ b/src/wext/MOCustomer.h @@ -15,17 +15,27 @@ #include "MOCustomerAbstract.h" +class MOCustomerInfo; + class MOCustomer:public MOCustomerAbstract { WOBJECT(MOCustomer); public: /**shortcut: gets the customer from the DB*/ MOCustomer(qint64); + /**shortcut: extracts the ID from the info and retrieves the customer from the DB*/ + MOCustomer(const MOCustomerInfo&); /**returns whether the customer is valid*/ bool isValid(){return !id().isNull();} + /**alias for id()*/ + Nullable customerid()const{return id();} + /**returns the address of the customer*/ QString address(int i=0); + + /**returns the full name (incl. title)*/ + QString fullName()const{return title()+" "+name()+", "+firstname();} }; diff --git a/src/wext/MOCustomerInfo.h b/src/wext/MOCustomerInfo.h index cbf0a4e..dd6c7e9 100644 --- a/src/wext/MOCustomerInfo.h +++ b/src/wext/MOCustomerInfo.h @@ -18,7 +18,11 @@ class MOCustomerInfo:public MOCustomerInfoAbstract { WOBJECT(MOCustomerInfo); public: + /**returns the full name (incl. title)*/ QString fullName()const{return title()+" "+name()+", "+firstname();} + + /**alias for customerid()*/ + Nullable id()const{return customerid();} }; #endif diff --git a/wob/customer.wolf b/wob/customer.wolf index 152e3a0..5877844 100644 --- a/wob/customer.wolf +++ b/wob/customer.wolf @@ -31,13 +31,13 @@ - - + + - + - - + + @@ -123,6 +123,7 @@ + @@ -187,10 +188,60 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/www/inc/db/db.php b/www/inc/db/db.php index 137317c..87462f0 100644 --- a/www/inc/db/db.php +++ b/www/inc/db/db.php @@ -210,6 +210,9 @@ abstract class DbEngine if($dbScheme->isBlobColumn($table,$k)) $val.=$this->escapeBlob($v); else + if($dbScheme->isBoolColumn($table,$k)) + $val.=$this->escapeBool($v); + else //don't know how to escape it... $val.="NULL"; } diff --git a/www/inc/db/db_mysql.php b/www/inc/db/db_mysql.php index 83d13a8..3433025 100644 --- a/www/inc/db/db_mysql.php +++ b/www/inc/db/db_mysql.php @@ -245,6 +245,15 @@ class MysqlEngine extends DbEngine if($s === false||$s===null) return "NULL"; return "'".mysqli_real_escape_string($this->dbhdl,$s)."'"; } + + /**escapes booleans, overwrites the orignal to use "0" and "1" instead of "FALSE" and "TRUE"*/ + public function escapeBool($b) + { + $r=DbEngine::escapeBool($b); + if($r=="TRUE")return "1"; + if($r=="FALSE")return "0"; + return $r; + } }; ?> \ No newline at end of file diff --git a/www/inc/wbase/transaction.php b/www/inc/wbase/transaction.php index 7d3de02..09f164d 100644 --- a/www/inc/wbase/transaction.php +++ b/www/inc/wbase/transaction.php @@ -83,6 +83,12 @@ class WobTransactionBase { print("".xq($text)."\n"); exit(); } + + /**called internally if a transaction is not implemented*/ + protected function abortNotImplemented() + { + $this->abortWithError(tr("Transaction not implemented.")); + } }; ?> \ No newline at end of file diff --git a/www/inc/wext/autoload.php b/www/inc/wext/autoload.php index 5eadba0..82096e7 100644 --- a/www/inc/wext/autoload.php +++ b/www/inc/wext/autoload.php @@ -12,6 +12,7 @@ // $AUTOCLASS["WOArtist"]="inc/wext/artist.php"; +$AUTOCLASS["WOCustomer"]="inc/wext/customer.php"; $AUTOCLASS["WOEventPrice"]="inc/wext/event.php"; $AUTOCLASS["WOEvent"]="inc/wext/event.php"; $AUTOCLASS["WOOrder"]="inc/wext/order.php"; diff --git a/www/inc/wext/customer.php b/www/inc/wext/customer.php new file mode 100644 index 0000000..412df14 --- /dev/null +++ b/www/inc/wext/customer.php @@ -0,0 +1,161 @@ +, (C) 2010 +// +// Copyright: See README/COPYING files that come with this distribution +// +// + +class WOCustomer extends WOCustomerAbstract +{ + /**called from CreateCustomer transaction*/ + public static function createCustomer($trans) + { + global $db; + $cc=$trans->getcustomer(); + if(!is_a($cc,"WOCustomer")){ + $trans->abortWithError(tr("Not a valid customer object.")); + return; + } + //create customer + $ct=WTcustomer::newRow(); + $cc->toTablecustomer($ct); + $ct->revert("customerid"); + $ct->insert(); + $cc->set_id($ct->customerid); + //create addresses + foreach($cc->get_addresses() as $addr){ + //skip addresses that are deleted + if($addr->get_isdeleted())continue; + $at=WTaddress::newRow(); + $addr->toTableaddress($at); + $at->revert("addressid"); + $at->customerid=$cc->get_id(); + if($at->insert()===false){ + $trans->abortWithError("Database Error: ".$db->lastError()); + return; + } +// print_r($at); + } + //create contacts + foreach($cc->get_contacts() as $cont){ + $cn=WTcontact::newRow(); + $cont->toTablecontact($cn); + $cn->revert("contactid"); + $cn->customerid=$cc->get_id(); + $cn->insert(); + } + + //return + $trans->setcustomer(WOCustomer::fromTablecustomer($ct)); + } + + /**called from ChangeCustomer transaction*/ + public static function changeCustomer($trans) + { + global $db; + $cc=$trans->getcustomer(); + if(!is_a($cc,"WOCustomer")){ + $trans->abortWithError(tr("Not a valid customer object.")); + return; + } + $ct=WTcustomer::getFromDB($cc->get_id()); + if(!is_a($ct,"WTcustomer")){ + $trans->abortWithError(tr("Customer does not exist in the database.")); + return; + } + //create customer + $cc->toTablecustomer($ct); + if($ct->isChanged())$ct->update(); + //sync addresses + foreach($cc->get_addresses() as $addr){ + $at=WTaddress::getFromDB($addr->get_addressid()); + //new address? + $na=false; + if(!is_a($at,"WTaddress")){ + $na=true; + $at=WTaddress::newRow(); + } + if($at->customerid != $cc->get_id())$na=true; + //push data + $addr->toTableaddress($at); + $at->revert("customerid"); + $at->revert("addressid"); + if($na){ + //its new, force insert + $at->addressid=null; + $at->isdeleted=0; + $at->customerid=$cc->get_id(); + if($at->insert()===false){ + $trans->abortWithError("Database Error: ".$db->lastError()); + return; + } + }else{ + //its known + if($at->isChanged())$at->update(); + } + } + //sync contacts + foreach($cc->get_contacts() as $cont){ + $cn=WTcontact::getFromDB($cont->get_contactid()); + //new one? + $nc=false; + if(!is_a($cn,"WTcontact")){ + $cn=WTcontact::newRow(); + $nc=true; + } + if($cn->customerid != $cc->get_id())$nc=true; + //push data + $cont->toTablecontact($cn); + $cn->revert("contactid"); + $cn->revert("customerid"); + if($nc){ + //new one, insert + $cn->customerid=$cc->get_id(); + $cn->insert(); + }else{ + //known one, update + if($cn->isChanged())$cn->update(); + } + } + + //return + $trans->setcustomer(WOCustomer::fromTablecustomer($ct)); + } + + /**called from CreateCountry transaction*/ + public static function createCountry($trans) + { + $id=trim($trans->getabbrev()); + $nm=trim($trans->getname()); + if($id=="" || $nm==""){ + $trans->abortWithError(tr("Country ID and name must contain values!")); + return; + } + //check for existence + global $db; + $res=$db->select("country","*","countryid=".$db->escapeString($id)); + if(count($res)>0){ + $trans->abortWithError(tr("Country ID exists!")); + return; + } + $res=$db->select("country","*","countryname=".$db->escapeString($nm)); + if(count($res)>0){ + $trans->abortWithError(tr("Country name exists!")); + return; + } + //create + $tab=WTcountry::newRow(); + $tab->countryid=$id; + $tab->countryname=$nm; + $tab->insert(); + //return + $trans->setcountry(WOCountry::fromTablecountry($tab)); + } +}; +?> \ No newline at end of file -- 1.7.2.5