From: Konrad Rosenbaum Date: Tue, 10 Jul 2012 17:39:35 +0000 (+0200) Subject: add customer creation wizard (not fully working yet) X-Git-Url: http://git.silmor.de/gitweb/?a=commitdiff_plain;h=c01190fac7a9dfbdd85abf397c9af34fef4f0fd8;p=web%2Fkonrad%2Fsmoke.git add customer creation wizard (not fully working yet) --- diff --git a/pack b/pack index c5c37fa..883f8f6 160000 --- a/pack +++ b/pack @@ -1 +1 @@ -Subproject commit c5c37fac1ab6c56d4879d74808a6ae9f44384bda +Subproject commit 883f8f6d0c8420b2ddae46b2345faa86e90a0230 diff --git a/src/dialogs/customerdlg.cpp b/src/dialogs/customerdlg.cpp index 64939c0..74d011c 100644 --- a/src/dialogs/customerdlg.cpp +++ b/src/dialogs/customerdlg.cpp @@ -13,23 +13,27 @@ #include "customerdlg.h" #include "msinterface.h" #include "misc.h" +#include "lambda.h" +#include "vlambda.h" -#include "MTGetAllCustomerNames" -#include "MTGetCustomer" -#include "MTDeleteCustomer" #include "MTChangeCustomer" #include "MTChangeCustomerMail" -#include "MTCreateCustomer" -#include "MTResetCustomerPassword" -#include "MTGetAllContactTypes" #include "MTCreateContactType" #include "MTCreateCountry" -#include "MTGetAllCountries" +#include "MTCreateCustomer" +#include "MTDeleteCustomer" #include "MTGetAddress" +#include "MTGetAllContactTypes" +#include "MTGetAllCountries" +#include "MTGetAllCustomerNames" +#include "MTGetCreateCustomerHints" +#include "MTGetCustomer" +#include "MTResetCustomerPassword" #include #include #include +#include #include #include #include @@ -43,6 +47,7 @@ #include #include #include +#include #include #include #include @@ -153,9 +158,12 @@ MOCustomerInfo MCustomerListDialog::getCustomer() void MCustomerListDialog::newCustomer() { - MCustomerDialog cd(MOCustomer(),this); - if(cd.exec()==QDialog::Accepted) - updateList(cd.getCustomer().id()); + MOCustomer c=MNewCustomerWizard::getNewCustomer(this); + if(c.isValid()) + updateList(c.id()); +// MCustomerDialog cd(MOCustomer(),this); +// if(cd.exec()==QDialog::Accepted) +// updateList(cd.getCustomer().id()); } void MCustomerListDialog::editCustomer() { @@ -439,6 +447,7 @@ void MContactTableDelegate::setEditorData(QWidget *editor, const QModelIndex &in } if(req->hasRight(req->RCreateContactType)) box->addItem(tr("(New Contact Type)"),-1); + box->setCurrentIndex(curidx); } if(c==1){//content ((QLineEdit*)editor)->setText(index.model()->data(index).toString()); @@ -732,6 +741,42 @@ MOAddress MAddressDialog::address() return m_addr; } +//static +MOCountry MAddressDialog::createNewCountry(QWidget* parent) +{ + QDialog d(parent); + 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 MOCountry(); + if(name->text().trimmed()=="" || abbr->text().trimmed()==""){ + QMessageBox::warning(parent,tr("Warning"),tr("The country name and abbreviation must contain something!")); + return MOCountry(); + } + //create + MTCreateCountry cc=MTCreateCountry::query(abbr->text().trimmed(),name->text().trimmed()); + if(cc.hasError()){ + QMessageBox::warning(parent,tr("Warning"),tr("Error while creating country: %1").arg(cc.errorString())); + return MOCountry(); + } + return cc.getcountry(); +} + void MAddressDialog::selectCountry() { //get countries @@ -744,7 +789,7 @@ void MAddressDialog::selectCountry() if(cntry[i].name().value() == curstr)cur=i; } if(req->hasRight(req->RCreateCountry)) - clst<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()); + MOCountry cc=createNewCountry(this); + if(cc.id().isNull())return; + m_addr.setcountry(cc); m_addr.setcountryid(m_addr.country().value().id()); m_country->setText(m_addr.country().value().name()); } @@ -870,3 +887,190 @@ void MAddressChoiceDialog::unselect() m_unsel=true; accept(); } + +/*****************************************************************************/ + +MNewCustomerWizard::MNewCustomerWizard(QWidget* parent, Qt::WindowFlags f): QDialog(parent, f) +{ + QWidget*w; + QHBoxLayout*hl; + QVBoxLayout*vl; + QGridLayout*gl; + QStackedLayout *sl; + setLayout(vl=new QVBoxLayout); + vl->addLayout(sl=new QStackedLayout); + //button bar + vl->addSpacing(15); + vl->addLayout(hl=new QHBoxLayout); + hl->addStretch(1); + QPushButton*p,*pprev,*pnext,*pdone; + hl->addWidget(p=new QPushButton(tr("Cancel"))); + p->setIcon(QIcon(":/cancel.png")); + connect(p,SIGNAL(clicked()),this,SLOT(reject())); + hl->addWidget(pprev=p=new QPushButton(tr("Back"))); + p->setIcon(QIcon(":/prev.png")); + connect(p,SIGNAL(clicked()),new MLambda([=](){sl->setCurrentIndex(sl->currentIndex()-1);},sl),SLOT(call())); + hl->addWidget(pnext=p=new QPushButton(tr("Next"))); + p->setIcon(QIcon(":/next.png")); + connect(p,SIGNAL(clicked()),new MLambda([=](){sl->setCurrentIndex(sl->currentIndex()+1);},sl),SLOT(call())); + hl->addWidget(pdone=p=new QPushButton(tr("Finish"))); + p->setIcon(QIcon(":/done.png")); + connect(p,SIGNAL(clicked()),this,SLOT(save())); + auto pagechange=new MVLambda([=](int idx){ + pprev->setEnabled(idx>0); + int max=sl->count()-1; + pnext->setEnabled(idxsetEnabled(idx>=max); + },sl); + connect(sl,SIGNAL(currentChanged(int)),pagechange,SLOT(call(int))); + + //get helper data + MTGetCreateCustomerHints cch=req->queryGetCreateCustomerHints(); + QStringList titles,cities,states; + if(!cch.hasError()){ + m_countrylist=cch.getcountries(); + m_typelist=cch.getcontacttypes(); + titles=cch.gettitles(); + cities=cch.getcities(); + states=cch.getstates(); + }else{ + //try something else + m_countrylist=req->queryGetAllCountries().getcountries(); + m_typelist=req->queryGetAllContactTypes().gettypes(); + } + + //address page + sl->addWidget(w=new QWidget); + int row=0; + w->setLayout(gl=new QGridLayout); + gl->addWidget(new QLabel(tr("Please enter name and address information.\nPlease enter it also if it is not needed immediately.")),row,0,1,2); + gl->addWidget(new QLabel(tr("Name:")),++row,0); + gl->addLayout(hl=new QHBoxLayout,row,1); + hl->addWidget(m_title=new QComboBox,1); + m_title->setEditable(true); + m_title->lineEdit()->setPlaceholderText(tr("Title")); + for(const QString&tt:titles)m_title->addItem(tt); + hl->addWidget(m_name=new QLineEdit,2); + m_name->setPlaceholderText(tr("Family Name")); + hl->addWidget(m_fname=new QLineEdit,2); + m_fname->setPlaceholderText(tr("Given Name")); + gl->addWidget(new QLabel(tr("Address:")),++row,0); + gl->addWidget(m_addr1=new QLineEdit,row,1); + m_addr1->setPlaceholderText(tr("123 Example Street")); + gl->addWidget(new QLabel(tr("City:")),++row,0); + gl->addLayout(hl=new QHBoxLayout,row,1); + hl->addWidget(m_zipcode=new QLineEdit,0); + m_zipcode->setPlaceholderText(tr("Zip Code")); + hl->addWidget(m_city=new QComboBox,1); + m_city->setEditable(true); + m_city->lineEdit()->setPlaceholderText(tr("Chose City")); + for(const QString&ct:cities)m_city->addItem(ct); + gl->addWidget(new QLabel(tr("State:")),++row,0); + gl->addWidget(m_state=new QComboBox,row,1); + m_state->setEditable(true); + m_state->lineEdit()->setPlaceholderText(tr("State (optional)")); + for(const QString&st:states)m_state->addItem(st); + gl->addWidget(new QLabel(tr("Country:")),++row,0); + gl->addLayout(hl=new QHBoxLayout,row,1); + hl->addWidget(m_country=new QComboBox,1); + updateCountry(); + if(req->hasRight(req->RCreateCountry)){ + hl->addWidget(p=new QPushButton(tr("New..."))); + connect(p,SIGNAL(clicked()),this,SLOT(newcountry())); + } + // ...spacing + gl->setColumnStretch(1,1); + gl->addWidget(new QFrame,++row,0,1,2); + gl->setRowStretch(row,1); + + //contacts page + QScrollArea*sa; + sl->addWidget(sa=new QScrollArea); + sa->setHorizontalScrollBarPolicy(Qt::ScrollBarAlwaysOff); + sa->setVerticalScrollBarPolicy(Qt::ScrollBarAsNeeded); + sa->setWidgetResizable(true); + sa->setWidget(w=new QWidget); + w->setLayout(gl=new QGridLayout); + gl->addWidget(new QLabel(tr("Please enter at least one way of contacting the customer.")),row=0,0,1,2); + for(const MOContactType&ct:m_typelist){ + gl->addWidget(new QLabel(ct.contacttype()),++row,0); + QLineEdit*le; + gl->addWidget(le=new QLineEdit,row,1); + le->setPlaceholderText(tr("Please enter %1","%1=contact type name").arg(ct.contacttype())); + m_contact.append(le); + } + + // ...spacing + gl->setColumnStretch(1,1); + gl->addWidget(new QFrame,++row,0,1,2); + gl->setRowStretch(row,1); + + //make sure buttons are initialized + pagechange->call(sl->currentIndex()); + //make size changeable + setSizeGripEnabled(true); +} + +void MNewCustomerWizard::save() +{ + //create customer + MOCustomer inp; + inp.setname(m_name->text()); + inp.setfirstname(m_fname->text()); + inp.settitle(m_title->currentText()); + MOAddress adr; + adr.setaddr1(m_addr1->text()); + adr.setcity(m_city->currentText()); + adr.setstate(m_state->currentText()); + adr.setzipcode(m_zipcode->text()); + //handle country + qDebug()<<"Country Idx"<currentIndex()<<"Name"<currentText()<<"ID"<itemData(m_country->currentIndex()).toString(); + return; +// adr.setcountryid(m_country->); + //complete addr + inp.addaddresses(adr); + //create customer + MTCreateCustomer cc=req->queryCreateCustomer(inp); + if(QMessageBox::warning(this,tr("Warning"),tr("There was an error while creating the customer: %1").arg(cc.errorString()),QMessageBox::Abort|QMessageBox::Retry)==QMessageBox::Retry)return; + //close dialog + accept(); +} + +void MNewCustomerWizard::updateCountry(QString id) +{ + //sort data + qSort(m_countrylist.begin(),m_countrylist.end(), + [](const MOCountry&a,const MOCountry&b){ + return a.name().value()itemData(m_country->currentIndex()).toString(); + int idx=-1; + //clear + m_country->clear(); + //add + for(MOCountry ct:m_countrylist){ + if(ct.id()==id)idx=m_country->count(); + m_country->addItem(ct.name(),ct.id().value()); + } + //pre-select (last one shown or new one created) + if(idx>=0)m_country->setCurrentIndex(idx); +} + +void MNewCustomerWizard::newcountry() +{ + //dialog + MOCountry co=MAddressDialog::createNewCountry(this); + if(co.id().isNull())return; + //add to list + m_countrylist.append(co); + updateCountry(co.id()); +} + +MOCustomer MNewCustomerWizard::getNewCustomer(QWidget*parent) +{ + //TODO: check which dialog to use + MNewCustomerWizard ncw(parent); + ncw.exec(); + return ncw.customer(); +} diff --git a/src/dialogs/customerdlg.h b/src/dialogs/customerdlg.h index 4342654..3e58725 100644 --- a/src/dialogs/customerdlg.h +++ b/src/dialogs/customerdlg.h @@ -23,6 +23,7 @@ #include "MOCustomerInfo" #include "MOCustomer" +class QComboBox; class QHBoxLayout; class QLineEdit; class QListView; @@ -233,6 +234,10 @@ class MAddressDialog:public QDialog /**returns the address*/ MOAddress address(); + + ///helper function to create a new country, used by MAddressDialog and MNewCustomerWizard + ///returns a valid country on success + static MOCountry createNewCountry(QWidget*parent=0); private slots: void selectCountry(); private: @@ -292,4 +297,28 @@ class MContactTableDelegate:public QItemDelegate mutable QListm_typelist; }; + +/**Wizard for creating a new customer.*/ +class MNewCustomerWizard:public QDialog +{ + Q_OBJECT + public: + MNewCustomerWizard(QWidget* parent = 0, Qt::WindowFlags f = 0); + + MOCustomer customer()const{return m_cust;} + + static MOCustomer getNewCustomer(QWidget*parent=0); + private slots: + void save(); + void newcountry(); + void updateCountry(QString id=QString()); + private: + MOCustomer m_cust; + QComboBox*m_title,*m_city,*m_state,*m_country; + QLineEdit*m_name,*m_fname,*m_addr1,*m_zipcode; + QListm_typelist; + QListm_countrylist; + QListm_contact; +}; + #endif diff --git a/src/images/cancel.png b/src/images/cancel.png new file mode 100644 index 0000000..fd285bc Binary files /dev/null and b/src/images/cancel.png differ diff --git a/src/images/done.png b/src/images/done.png new file mode 100644 index 0000000..dbfb948 Binary files /dev/null and b/src/images/done.png differ diff --git a/src/images/files.qrc b/src/images/files.qrc index 24bb789..bb5e883 100644 --- a/src/images/files.qrc +++ b/src/images/files.qrc @@ -3,12 +3,20 @@ See COPYING.GPL for details. --> + icon.png + arrowright.png arrowleft.png arrowup.png arrowdown.png arrowdiag.png + separator.png + + next.png + prev.png + cancel.png + done.png diff --git a/src/images/next.png b/src/images/next.png new file mode 100644 index 0000000..7700d6f Binary files /dev/null and b/src/images/next.png differ diff --git a/src/images/prev.png b/src/images/prev.png new file mode 100644 index 0000000..99dc873 Binary files /dev/null and b/src/images/prev.png differ diff --git a/wob/transact/customer.wolf b/wob/transact/customer.wolf index 2710452..50e61b1 100644 --- a/wob/transact/customer.wolf +++ b/wob/transact/customer.wolf @@ -133,4 +133,17 @@ + + + Returns all info that helps in creating customers, like common titles, cities, countries, etc. + + + + + + + + + + \ No newline at end of file diff --git a/www/config.php.template b/www/config.php.template index 3b41285..2a88141 100644 --- a/www/config.php.template +++ b/www/config.php.template @@ -62,6 +62,14 @@ $olddb->setCharacterSet("utf8"); // */ + +/////////// +//Development Options (comment these away in production systems) + +//WobTransaction::setDebugLevel(WobTransaction::DebugAll); + + + //////////// //Dedicated Client Configuration diff --git a/www/inc/machine/session.php b/www/inc/machine/session.php index df0798c..46ec1ab 100644 --- a/www/inc/machine/session.php +++ b/www/inc/machine/session.php @@ -5,9 +5,7 @@ /* TRANSLATOR php:: */ -//prune session cache -global $db; -$db->deleteRows("session","timeout<=".time()); + /**The session class*/ class Session @@ -18,6 +16,16 @@ class Session protected $rights=array(); protected $flags=array(); + ///initialize session sub-system + static public function initialize() + { + //prune session cache + global $db; + $db->beginTransaction(); + $db->deleteRows("session","timeout<=".time()); + $db->commitTransaction(); + } + /**construct the session object, check validity*/ public function __construct($trans) { diff --git a/www/inc/wext/customer.php b/www/inc/wext/customer.php index e961aa7..89a8166 100644 --- a/www/inc/wext/customer.php +++ b/www/inc/wext/customer.php @@ -592,6 +592,30 @@ class WOCustomer extends WOCustomerAbstract //go to checkout page redirectHome(array("mode"=>"checkout")); } + + static public function createHints($trans) + { + $trans->setcontacttypes( WOContactType::fromTableArraycontacttype( WTcontacttype::selectFromDB())); + $trans->setcountries( WOCountry::fromTableArraycountry( WTcountry::selectFromDB())); + global $db; + $tt=$db->select("customer","title","","GROUP BY title ORDER BY title"); + if($tt!==false){ + $r=array(); + foreach($tt as $t)$r[]=$t["title"]; + $trans->settitles($r); + } + $csl=$db->select("address","state,city","","GROUP BY city,state"); + if($csl!==false){ + $rs=array(); + $rc=array(); + foreach($csl as $cs){ + if(!in_array($cs["city"],$rc))$rc[]=$cs["city"]; + if(!in_array($cs["state"],$rs))$rs[]=$cs["state"]; + } + $trans->setcities($rc); + $trans->setstates($rs); + } + } }; //eof diff --git a/www/inc/wext/transaction.php b/www/inc/wext/transaction.php index 889b2c1..a3f9e10 100644 --- a/www/inc/wext/transaction.php +++ b/www/inc/wext/transaction.php @@ -21,17 +21,20 @@ class MSmokeTransaction extends WobTransaction protected function startTransaction($updating) { global $db; + WobTransaction::debug("Starting MSmoke Transaction as ".($updating?"updating":"read only"),WobTransaction::DebugTransactions); $db->setTransactionUpdating($updating); $db->beginTransaction(); } protected function commitTransaction() { global $db; + WobTransaction::debug("Comitting MSmoke Transaction",WobTransaction::DebugTransactions); $db->commitTransaction(); } protected function abortTransaction() { global $db; + WobTransaction::debug("Aborting MSmoke Transaction",WobTransaction::DebugTransactions); $db->rollbackTransaction(); } diff --git a/www/machine.php b/www/machine.php index 89c3989..3caef30 100644 --- a/www/machine.php +++ b/www/machine.php @@ -10,8 +10,12 @@ header("Content-Type: application/x-MagicSmoke"); include("inc/loader.php"); include("inc/loader_nonadmin.php"); +//init +Session::initialize(); + //let wob do the rest MSmokeTransaction::handle(); +WobTransaction::printDebug(); //done exit(0);