added editor for flags
authorkonrad <konrad@6e3c4bff-ac9f-4ac1-96c5-d2ea494d3e33>
Sun, 25 Apr 2010 17:45:13 +0000 (17:45 +0000)
committerkonrad <konrad@6e3c4bff-ac9f-4ac1-96c5-d2ea494d3e33>
Sun, 25 Apr 2010 17:45:13 +0000 (17:45 +0000)
finished port of shipping editor

git-svn-id: https://silmor.de/svn/softmagic/smoke/trunk@442 6e3c4bff-ac9f-4ac1-96c5-d2ea494d3e33

src/dialogs/dialogs.pri
src/dialogs/flagedit.cpp [new file with mode: 0644]
src/dialogs/flagedit.h [new file with mode: 0644]
src/dialogs/shipping.cpp
src/mwin/overview.cpp
wob/basics.wolf
wob/order.wolf
www/inc/wext/autoload.php
www/inc/wext/flag.php [new file with mode: 0644]
www/inc/wext/shipping.php [new file with mode: 0644]

index dabe072..be7790b 100644 (file)
@@ -9,7 +9,8 @@ HEADERS += \
        dialogs/checkdlg.h \
        dialogs/passwdchg.h \
        dialogs/pricecatdlg.h \
-       dialogs/aclwin.h
+       dialogs/aclwin.h \
+       dialogs/flagedit.h
 
 SOURCES += \
        dialogs/configdialog.cpp \
@@ -22,6 +23,7 @@ SOURCES += \
        dialogs/checkdlg.cpp \
        dialogs/passwdchg.cpp \
        dialogs/pricecatdlg.cpp \
-       dialogs/aclwin.cpp
+       dialogs/aclwin.cpp \
+       dialogs/flagedit.cpp
 
 INCLUDEPATH += ./dialogs
\ No newline at end of file
diff --git a/src/dialogs/flagedit.cpp b/src/dialogs/flagedit.cpp
new file mode 100644 (file)
index 0000000..4fb2a24
--- /dev/null
@@ -0,0 +1,162 @@
+//
+// C++ Implementation: flagedit
+//
+// Description: 
+//
+//
+// Author: Konrad Rosenbaum <konrad@silmor.de>, (C) 2010
+//
+// Copyright: See COPYING file that comes with this distribution
+//
+//
+
+#include "flagedit.h"
+#include "MTGetValidFlags.h"
+
+#include <QBoxLayout>
+#include <QComboBox>
+#include <QCoreApplication>
+#include <QGridLayout>
+#include <QHeaderView>
+#include <QItemDelegate>
+#include <QLabel>
+#include <QPushButton>
+#include <QStandardItemModel>
+#include <QTableView>
+
+static const int MIGNORE=0;
+static const int MMUST=1;
+static const int MNOT=2;
+#define MMAX MNOT
+static const char *modes[]={
+       QT_TRANSLATE_NOOP("MFlagEditor","ignore"),
+       QT_TRANSLATE_NOOP("MFlagEditor","must have"),
+       QT_TRANSLATE_NOOP("MFlagEditor","must not have")
+};
+
+class MFlagEditorDelegate:public QItemDelegate
+{
+       public:
+               MFlagEditorDelegate(MFlagEditor*p):QItemDelegate(p){m_parent=p;}
+               
+               virtual QWidget * createEditor(QWidget*p,const QStyleOptionViewItem&,const QModelIndex& index) const{
+                       if(index.column()!=0)return 0;
+                       //create widget
+                       QComboBox *cb=new QComboBox(p);
+                       cb->setEditable(false);
+                       for(int i=0;i<=MMAX;i++)
+                               cb->addItem(QCoreApplication::translate("MFlagEditor",modes[i]));
+                       //set current
+                       cb->setCurrentIndex(m_parent->model->data(index,Qt::UserRole).toInt());
+                       //finish up
+                       return cb;
+               }
+               virtual void setModelData ( QWidget * editor, QAbstractItemModel * model, const QModelIndex & index ) const{
+                       if(index.column()!=0)return;
+                       QComboBox*cb=qobject_cast<QComboBox*>(editor);
+                       int c=cb->currentIndex();if(c<0)c=0;if(c>MMAX)c=MMAX;
+                       model->setData(index,QCoreApplication::translate("MFlagEditor",modes[c]));
+                       model->setData(index,c,Qt::UserRole);
+               }
+       private:
+               MFlagEditor*m_parent;
+};
+
+//static 
+QString MFlagEditor::edit(QWidget*parent,QString flags,QString label)
+{
+       MFlagEditor fe(parent,flags,label);
+       if(fe.exec()==QDialog::Accepted)
+               return fe.currentFlags();
+       else
+               return flags;
+}
+
+MFlagEditor::MFlagEditor(QWidget*par,QString f,QString l)
+       :QDialog(par)
+{
+       setWindowTitle(tr("Edit Flags"));
+       setSizeGripEnabled(true);
+       
+       //parse flags
+       flags=f.split(" ",QString::SkipEmptyParts);
+       //get all defined flags
+       allflags=MTGetValidFlags::query().getflags();
+       
+       //create widgets
+       QVBoxLayout*vl;
+       QHBoxLayout*hl;
+       QPushButton*p;
+       setLayout(vl=new QVBoxLayout);
+       if(l!=""){
+               vl->addWidget(new QLabel(l),0);
+               vl->addSpacing(15);
+       }
+       vl->addWidget(table=new QTableView,1);
+       table->setModel(model=new QStandardItemModel(this));
+       table->setItemDelegate(new MFlagEditorDelegate(this));
+       table->verticalHeader()->hide();
+       
+       vl->addSpacing(15);
+       vl->addLayout(hl=new QHBoxLayout,0);
+       hl->addStretch(1);
+       hl->addWidget(p=new QPushButton(tr("Reset")));
+       connect(p,SIGNAL(clicked()),this,SLOT(reset()));
+       hl->addSpacing(20);
+       hl->addWidget(p=new QPushButton(tr("Ok")));
+       connect(p,SIGNAL(clicked()),this,SLOT(accept()));
+       hl->addWidget(p=new QPushButton(tr("Cancel")));
+       connect(p,SIGNAL(clicked()),this,SLOT(reject()));
+       
+       //populate
+       reset();
+}
+
+QString MFlagEditor::currentFlags()const
+{
+       //gather
+       QStringList fl;
+       for(int i=0;i<model->rowCount();i++){
+               switch(model->data(model->index(i,0),Qt::UserRole).toInt()){
+                       case MMUST:fl.append("+"+allflags[i].flag());break;
+                       case MNOT:fl.append("-"+allflags[i].flag());break;
+                       default: /*ignore*/ break;
+               }
+       }
+       //convert to string
+       QString f;
+       for(int i=0;i<fl.size();i++){
+               if(i)f+=" ";
+               f+=fl[i];
+       }
+       return f;
+}
+QString MFlagEditor::originalFlags()const
+{
+       QString f;
+       for(int i=0;i<flags.size();i++){
+               if(i)f+=" ";
+               f+=flags[i];
+       }
+       return f;
+}
+void MFlagEditor::reset()
+{
+       model->clear();
+       model->insertRows(0,allflags.size());
+       model->insertColumns(0,3);
+       model->setHorizontalHeaderLabels(QStringList()<<tr("Mode")<<tr("Flag")<<tr("Description"));
+       for(int i=0;i<allflags.size();i++){
+               int md=MIGNORE;
+               QString f=allflags[i].flag();
+               if(flags.contains("+"+f))md=MMUST;else
+               if(flags.contains("-"+f))md=MNOT;
+               model->setData(model->index(i,0),tr(modes[md]));
+               model->setData(model->index(i,0),md,Qt::UserRole);
+               model->setData(model->index(i,1),f);
+               model->setData(model->index(i,2),allflags[i].description().value());
+       }
+       table->resizeColumnsToContents();
+}
+
+
diff --git a/src/dialogs/flagedit.h b/src/dialogs/flagedit.h
new file mode 100644 (file)
index 0000000..5f113db
--- /dev/null
@@ -0,0 +1,51 @@
+//
+// C++ Interface: flagedit
+//
+// Description: 
+//
+//
+// Author: Konrad Rosenbaum <konrad@silmor.de>, (C) 2010
+//
+// Copyright: See COPYING file that comes with this distribution
+//
+//
+
+#ifndef MAGICSMOKE_FLAGEDIT_H
+#define MAGICSMOKE_FLAGEDIT_H
+
+#include <QDialog>
+#include <QStringList>
+
+#include "MOFlag.h"
+
+class QStandardItemModel;
+class QTableView;
+
+/**enables the user to edit flags as defined by MagicSmoke*/
+class MFlagEditor:public QDialog
+{
+       Q_OBJECT
+       public:
+               /**convenience function: opens a flag editor and returns the result or the original string if unchanged*/
+               static QString edit(QWidget*parent,QString flags,QString label=QString());
+               
+               /**creates an editor window*/
+               MFlagEditor(QWidget*parent,QString flags,QString label=QString());
+               
+               /**returns the flag string corresponding to the current state of the editor*/
+               QString currentFlags()const;
+               /**returns the original string with which the editor was initialized*/
+               QString originalFlags()const;
+               
+       private:
+               friend class MFlagEditorDelegate;
+               QList<MOFlag>allflags;
+               QStringList flags;
+               QStandardItemModel*model;
+               QTableView*table;
+       private slots:
+               /**reset to original state*/
+               void reset();
+};
+
+#endif
index 47eecc9..86e3767 100644 (file)
@@ -13,6 +13,7 @@
 #include "misc.h"
 #include "shipping.h"
 #include "centbox.h"
+#include "flagedit.h"
 
 #include "MOShipping.h"
 
@@ -21,6 +22,7 @@
 #include <QApplication>
 #include <QDomDocument>
 #include <QDomElement>
+#include <QHeaderView>
 #include <QStandardItemModel>
 #include <QTableView>
 #include <QPushButton>
@@ -33,6 +35,7 @@ MShippingEditor::MShippingEditor(QWidget*par)
 {
        all=req->queryGetAllShipping().getshipping();
        setWindowTitle(tr("Edit Shipping Options"));
+       setSizeGripEnabled(true);
        
        QHBoxLayout*hl;
        QVBoxLayout*vl,*vl2;
@@ -41,6 +44,7 @@ MShippingEditor::MShippingEditor(QWidget*par)
        hl->addWidget(table=new QTableView,1);
        table->setModel(model=new QStandardItemModel(this));
        table->setEditTriggers(QAbstractItemView::NoEditTriggers);
+       table->verticalHeader()->hide();
        updateTable();
        hl->addLayout(vl2=new QVBoxLayout,0);
        QPushButton*p;
@@ -48,7 +52,7 @@ MShippingEditor::MShippingEditor(QWidget*par)
        connect(p,SIGNAL(clicked()),this,SLOT(changeDescription()));
        vl2->addWidget(p=new QPushButton(tr("Change Price")));
        connect(p,SIGNAL(clicked()),this,SLOT(changePrice()));
-       vl2->addWidget(p=new QPushButton(tr("Change Availability")));
+       vl2->addWidget(p=new QPushButton(tr("Change Flags")));
        connect(p,SIGNAL(clicked()),this,SLOT(changeAvail()));
        vl2->addSpacing(20);
        vl2->addWidget(p=new QPushButton(tr("Add Option")));
@@ -68,86 +72,81 @@ MShippingEditor::MShippingEditor(QWidget*par)
 void MShippingEditor::updateTable()
 {
        model->clear();
-       model->insertColumns(0,5);
+       model->insertColumns(0,4);
        model->insertRows(0,all.size());
-       model->setHorizontalHeaderLabels(QStringList()<<tr("ID")<<tr("Description")<<tr("Price")<<tr("Web")<<tr("Any User"));
+       model->setHorizontalHeaderLabels(QStringList()<<tr("ID")<<tr("Description")<<tr("Price")<<tr("Flags"));
        for(int i=0;i<all.size();i++){
                model->setData(model->index(i,0),all[i].shipid().value());
                model->setData(model->index(i,1),all[i].description().value());
                model->setData(model->index(i,2),cent2str(all[i].cost()));
-//             model->setData(model->index(i,3),all[i].canuseweb().value()?tr("Yes"):tr("No"));
-//             model->setData(model->index(i,4),all[i].canallusers().value()?tr("Yes"):tr("No"));
+               model->setData(model->index(i,3),all[i].flags().value());
        }
        table->resizeColumnsToContents();
 }
 
 void MShippingEditor::changeDescription()
-{/*TODO
+{
        //find item
        QModelIndexList lst=table->selectionModel()->selectedIndexes();
        if(lst.size()<1)return;
        QModelIndex idx=lst[0];
        //get shipping
-       MShipping s=all[idx.row()];
+       MOShipping s=all[idx.row()];
        //get new value
        QString r=QInputDialog::getText(this,tr("Shipping Option Description"),tr("Please select a new description for this shipping option:"),QLineEdit::Normal,s.description());
        if(r=="")return;
-       s.setDescription(r);
-       if(!s.save()){
-               QMessageBox::warning(this,tr("Warning"),tr("Could not store the changes."));
+       s.setdescription(r);
+       MTChangeShipping cs=MTChangeShipping::query(s);
+       if(cs.hasError()){
+               QMessageBox::warning(this,tr("Warning"),tr("Could not store the changes: %1").arg(cs.errorString()));
                return;
        }
-       all[idx.row()]=s;
-       updateTable();*/
+       all[idx.row()]=cs.getshipping();
+       updateTable();
 }
 
 void MShippingEditor::changePrice()
-{/*TODO
+{
        //find item
        QModelIndexList lst=table->selectionModel()->selectedIndexes();
        if(lst.size()<1)return;
        QModelIndex idx=lst[0];
        //get shipping
-       MShipping s=all[idx.row()];
+       MOShipping s=all[idx.row()];
        //get new value
        bool b;
-       int r=MCentDialog::getCents(this,tr("Shipping Option Price"),tr("Please select a new price for this shipping option:"),s.price(),1000000000,&b);
+       int r=MCentDialog::getCents(this,tr("Shipping Option Price"),tr("Please select a new price for this shipping option:"),s.cost(),1000000000,&b);
        if(!b)return;
-       s.setPrice(r);
-       if(!s.save()){
-               QMessageBox::warning(this,tr("Warning"),tr("Could not store the changes."));
+       s.setcost(r);
+       MTChangeShipping cs=MTChangeShipping::query(s);
+       if(cs.hasError()){
+               QMessageBox::warning(this,tr("Warning"),tr("Could not store the changes: %1").arg(cs.errorString()));
                return;
        }
-       all[idx.row()]=s;
-       updateTable();*/
+       all[idx.row()]=cs.getshipping();
+       updateTable();
 }
 void MShippingEditor::changeAvail()
-{/*TODO
+{
        //find item
        QModelIndexList lst=table->selectionModel()->selectedIndexes();
        if(lst.size()<1)return;
        QModelIndex idx=lst[0];
        //get shipping
-       MShipping s=all[idx.row()];
+       MOShipping s=all[idx.row()];
        //get new value
-       bool b;
-       QStringList opt;
-       opt<<tr("None")<<tr("Web Interface")<<tr("Any User")<<tr("Any User + Web Interface");
-       int cav=(s.webUsable()?1:0)|(s.anyUserCanUse()?2:0);
-       QString r=QInputDialog::getItem(this,tr("Shipping Option Availability"),tr("Please select a new availability for this shipping option:"),opt,cav,false,&b);
-       if(!b)return;
-       for(int i=0;i<opt.size();i++)if(r==opt[i])cav=i;
-       s.setWebUsable(cav&1);
-       s.setAnyUserCanUse(cav&2);
-       if(!s.save()){
+       s.setflags(MFlagEditor::edit(this,s.flags(),tr("Edit Flags of shipping option '%1'.").arg(s.description())));
+       //save
+       MTChangeShipping cs=MTChangeShipping::query(s);
+       if(cs.hasError()){
                QMessageBox::warning(this,tr("Warning"),tr("Could not store the changes."));
                return;
        }
        all[idx.row()]=s;
-       updateTable();*/
+       updateTable();
 }
 void MShippingEditor::addNew()
-{/*TODO
+{
        //get data
        //TODO: use a single dialog
        QString dsc=QInputDialog::getText(this,tr("Shipping Option Description"),tr("Please select a new description for this new shipping option:"));
@@ -155,42 +154,36 @@ void MShippingEditor::addNew()
        bool b;
        int prc=MCentDialog::getCents(this,tr("Shipping Option Price"),tr("Please select a new price for this new shipping option:"),0,1000000000,&b);
        if(!b)return;
-       QStringList opt;
-       opt<<tr("None")<<tr("Web Interface")<<tr("Any User")<<tr("Any User + Web Interface");
-       QString avl=QInputDialog::getItem(this,tr("Shipping Option Availability"),tr("Please select a new availability for this new shipping option:"),opt,3,false,&b);
-       if(!b)return;
        //create the option
-       MShipping s(req);
-       s.setDescription(dsc);
-       s.setPrice(prc);
-       int cav=4;
-       for(int i=0;i<opt.size();i++)if(avl==opt[i])cav=i;
-       s.setWebUsable(cav&1);
-       s.setAnyUserCanUse(cav&2);
-       if(!s.save()){
-               QMessageBox::warning(this,tr("Warning"),tr("Could not create the new option."));
+       MOShipping s;
+       s.setdescription(dsc);
+       s.setcost(prc);
+       MTCreateShipping cs=MTCreateShipping::query(s);
+       if(cs.hasError()){
+               QMessageBox::warning(this,tr("Warning"),tr("Could not store the data: %1").arg(cs.errorString()));
                return;
        }
-       all.append(s);
-       updateTable();*/
+       all.append(cs.getshipping());
+       updateTable();
 }
 
 void MShippingEditor::deleteShip()
-{/*TODO
+{
        //find item
        QModelIndexList lst=table->selectionModel()->selectedIndexes();
        if(lst.size()<1)return;
        QModelIndex idx=lst[0];
-       //get shipping
-       int id=all[idx.row()].id();
-       if(!req->request("deleteshipping",QString::number(id).toAscii())){
-               QMessageBox::warning(this,tr("Warning"),tr("Unable to delete this option."));
+       //ask
+       MOShipping s=all[idx.row()];
+       if(QMessageBox::question(this,tr("Really Delete?"),tr("Really delete shipping option '%1'?").arg(s.description()),QMessageBox::Yes|QMessageBox::No)!=QMessageBox::Yes)
                return;
-       }
-       if(req->responseStatus()!=MWebRequest::Ok){
-               QMessageBox::warning(this,tr("Warning"),tr("Unable to delete this option."));
+       //get shipping
+       int id=s.shipid();
+       MTDeleteShipping ds=MTDeleteShipping::query(id);
+       if(ds.hasError()){
+               QMessageBox::warning(this,tr("Warning"),tr("Unable to delete this option: %1").arg(ds.errorString()));
                return;
        }
        all.removeAt(idx.row());
-       updateTable();*/
+       updateTable();
 }
index e10fe88..74fe30d 100644 (file)
@@ -15,6 +15,7 @@
 #include "passwdchg.h"
 #include "customerdlg.h"
 #include "templatedlg.h"
+#include "shipping.h"
 
 #include "overview.h"
 #include "eventstab.h"
@@ -191,13 +192,13 @@ void MOverview::customerMgmt()
 }
 
 void MOverview::editShipping()
-{/*TODO
-       MShippingEditor se(req,this);
+{
+       MShippingEditor se(this);
        se.exec();
-       updateShipping();*/
+       carttab->updateShipping();
 }
 
-void MOverview::tabChanged(int idx)
+void MOverview::tabChanged(int /*idx*/)
 {
 //     qDebug("tab index %i",idx);
        QWidget*w=tab->currentWidget();
index ad717cc..69f041e 100644 (file)
                </Output>
        </Transaction>
        
-       <Transaction name="GetValidFlags" updating="no"/>
-               <!-- Call lang="php" method=" -->
+       <Class name="Flag">
+               <Doc>Transport class for flags and their descriptions. They are actually stored in the config table.</Doc>
+               <Abstract lang="php"/>
+               <Property name="flag" type="astring"/>
+               <Property name="description" type="string"/>
+       </Class>
+       <Transaction name="GetValidFlags" updating="no">
+               <Call lang="php" method="WOFlag::getAll($this);"/>
+               <Output>
+                       <Var name="flags" type="List:Flag"/>
+               </Output>
+       </Transaction>
 </Wolf>
index 7c32d03..f3eceae 100644 (file)
        
        <Class name="Shipping">
                <Doc>This class encapsulates shipping types.</Doc>
+               <Abstract lang="php"/>
                <Property name="shipid" type="int"/>
                <Property name="cost" type="int"/>
                <Property name="flags" type="string"/>
                        <Var name="shipping" type="List:Shipping"/>
                </Output>
        </Transaction>
+       <Transaction name="ChangeShipping">
+               <Input>
+                       <Var name="shipping" type="Shipping"/>
+               </Input>
+               <Call lang="php" method="WOShipping::change($this);"/>
+               <Output>
+                       <Var name="shipping" type="Shipping"/>
+               </Output>
+       </Transaction>
+       <Transaction name="CreateShipping">
+               <Input>
+                       <Var name="shipping" type="Shipping"/>
+               </Input>
+               <Call lang="php" method="WOShipping::create($this);"/>
+               <Output>
+                       <Var name="shipping" type="Shipping"/>
+               </Output>
+       </Transaction>
+       <Transaction name="DeleteShipping">
+               <Input>
+                       <Var name="shipid" type="int"/>
+               </Input>
+               <Call lang="php" method="WOShipping::remove($this);"/>
+               <Output/>
+       </Transaction>
        
        <Transaction name="GetValidVoucherPrices" updating="no">
                <Call lang="php" method="$this->setprices(explode(' ',$GLOBALS['db']->getConfig('ValidVouchers')));"/>
index 3c7d937..4ccd728 100644 (file)
@@ -5,7 +5,7 @@
 // Description: 
 //
 //
-// Author: Konrad Rosenbaum <konrad@silmor.de>, (C) 2009
+// Author: Konrad Rosenbaum <konrad@silmor.de>, (C) 2009-2010
 //
 // Copyright: See README/COPYING files that come with this distribution
 //
@@ -16,11 +16,13 @@ $AUTOCLASS["WOCartOrder"]="inc/wext/cart.php";
 $AUTOCLASS["WOCustomer"]="inc/wext/customer.php";
 $AUTOCLASS["WOEventPrice"]="inc/wext/event.php";
 $AUTOCLASS["WOEvent"]="inc/wext/event.php";
+$AUTOCLASS["WOFlag"]="inc/wext/flag.php";
 $AUTOCLASS["WOOrder"]="inc/wext/order.php";
 $AUTOCLASS["WOOrderInfo"]="inc/wext/order.php";
 $AUTOCLASS["WOPriceCategory"]="inc/wext/price.php";
 $AUTOCLASS["WORole"]="inc/wext/role.php";
 $AUTOCLASS["WORoom"]="inc/wext/room.php";
+$AUTOCLASS["WOShipping"]="inc/wext/shipping.php";
 $AUTOCLASS["WOTemplate"]="inc/wext/template.php";
 $AUTOCLASS["WOTicket"]="inc/wext/ticket.php";
 
diff --git a/www/inc/wext/flag.php b/www/inc/wext/flag.php
new file mode 100644 (file)
index 0000000..e5095b6
--- /dev/null
@@ -0,0 +1,32 @@
+<?php
+// +----------------------------------------------------------------------
+// | PHP Source                                                           
+// +----------------------------------------------------------------------
+// | Copyright (C) 2010 by Konrad Rosenbaum <konrad@silmor.de>
+// +----------------------------------------------------------------------
+// |
+// | Copyright: See COPYING file that comes with this distribution
+// +----------------------------------------------------------------------
+//
+
+class WOFlag extends WOFlagAbstract
+{
+       public static function getAll($trans)
+       {
+               global $db;
+               $cfgs=WTconfig::selectFromDb("ckey LIKE 'Flag %'");
+               $ret=array();
+               foreach($cfgs as $cfg){
+                       $k=explode(" ",$cfg->ckey);
+                       if(count($k)==2 && $k[0]=="Flag"){
+                               $f=new WOFlag;
+                               $f->setflag($k[1]);
+                               $f->setdescription($cfg->cval);
+                               $ret[]=$f;
+                       }
+               }
+               $trans->setflags($ret);
+       }
+};
+
+?>
diff --git a/www/inc/wext/shipping.php b/www/inc/wext/shipping.php
new file mode 100644 (file)
index 0000000..ea0c4e7
--- /dev/null
@@ -0,0 +1,45 @@
+<?php
+// +----------------------------------------------------------------------
+// | PHP Source                                                           
+// +----------------------------------------------------------------------
+// | Copyright (C) 2010 by Konrad Rosenbaum <konrad@silmor.de>
+// +----------------------------------------------------------------------
+// |
+// | Copyright: See COPYING file that comes with this distribution
+// +----------------------------------------------------------------------
+//
+
+/**implementation of access to shipping types*/
+class WOShipping extends WOShippingAbstract
+{
+       /**create a new shipping type*/
+       static public function create($trans)
+       {
+               $row=WTshipping::newRow();
+               $trans->getshipping()->toTableshipping($row);
+               $row->insert();
+               $trans->setshipping(WOShipping::fromTableshipping($row));
+       }
+       static public function change($trans)
+       {
+               $ship=$trans->getshipping();
+               $row=WTshipping::getFromDB($ship->getshipid());
+               if(!$row instanceof WTshipping){
+                       $trans->abortWithError(tr("Shipping type not found."));
+                       return;
+               }
+               $ship->toTableshipping($row);
+               if($row->update())
+                       $trans->setshipping(WOShipping::fromTableshipping($row));
+               else
+                       $trans->abortWithError(tr("Error while updating shipping information."));
+       }
+       static public function remove($trans)
+       {
+               $row=WTshipping::getFromDB($trans->getshipid());
+               if($row instanceof WTshipping)
+                       $row->deleteFromDb();
+       }
+};
+
+?>