Difference between revisions of "VbzCart/archive/code/SpecialVbzAdmin"
(version from Rizzo -- not the latest, but need to compare) |
m (Woozle moved page VbzCart/code/SpecialVbzAdmin to VbzCart/archive/code/SpecialVbzAdmin) |
||
(2 intermediate revisions by the same user not shown) | |||
Line 1: | Line 1: | ||
<php><?php | <php><?php | ||
/* | /* | ||
− | + | NAME: SpecialVbzAdmin | |
− | + | PURPOSE: Special page for administering VbzCart | |
− | + | AUTHOR: Woozle (Nick) Staddon | |
− | + | REQUIRES: | |
− | + | Tabber extension for tabs on Supplier admin page | |
− | + | TreeAndMenu extension (tentatively) for category management | |
− | + | VERSION: | |
− | + | 2009-03-10 0.0 (Wzl) Started writing | |
− | + | had a few functions implemented by June or so, but not enough to process anything | |
+ | 2009-07-09 (Wzl) | ||
+ | rewrote menu functions as classes | ||
+ | started on Shipments | ||
+ | 2009-10-04 (Wzl) | ||
+ | menu classes now in separate file; removed from here | ||
+ | added 'orders' and 'order' pages/classes | ||
+ | 2009-10-06 (Wzl) clsTitles -> clsVbzTitles, clsTitle -> clsVbzTitle | ||
+ | 2010-06-27 (Wzl) new functionality in Bins, Images; moved catalog rebuild out to standalone script | ||
+ | 2010-09-22 (Wzl) working on email confirmation of orders (finally) | ||
+ | 2011-02-06 (Wzl) extensive work since 9/22... most features usable | ||
+ | 2011-12-21 (Wzl) extracted clsVbzAdminData into base.admin.php so it could be used from command line | ||
*/ | */ | ||
$wgSpecialPages['VbzAdmin'] = 'SpecialVbzAdmin'; # Let MediaWiki know about your new special page. | $wgSpecialPages['VbzAdmin'] = 'SpecialVbzAdmin'; # Let MediaWiki know about your new special page. | ||
Line 17: | Line 28: | ||
'description' => 'special page for VbzCart administration', | 'description' => 'special page for VbzCart administration', | ||
'author' => 'Woozle (Nick) Staddon', | 'author' => 'Woozle (Nick) Staddon', | ||
− | 'version' => ' | + | 'version' => '2011-12-21 unreleased' |
); | ); | ||
global $dbgShowLibs; | global $dbgShowLibs; | ||
$dbgShowLibs = TRUE; | $dbgShowLibs = TRUE; | ||
− | |||
− | |||
− | |||
if (!defined('LIBMGR')) { | if (!defined('LIBMGR')) { | ||
require('libmgr.php'); | require('libmgr.php'); | ||
} | } | ||
//clsLibMgr::$doDebug = TRUE; | //clsLibMgr::$doDebug = TRUE; | ||
− | clsLibMgr::Add('vbz. | + | clsLibMgr::Add('vbz.site', KFP_LIB_VBZ.'/site.php',__FILE__,__LINE__); |
− | clsLibMgr::Add('vbz. | + | clsLibMgr::Add('vbz.shop', KFP_LIB_VBZ.'/shop.php',__FILE__,__LINE__); |
− | clsLibMgr::Add(' | + | clsLibMgr::Add('vbz.ckout', KFP_LIB_VBZ.'/ckout.php',__FILE__,__LINE__); |
− | clsLibMgr::Load('vbz. | + | clsLibMgr::Add('vbz.topic', KFP_LIB_VBZ.'/topic.php',__FILE__,__LINE__); |
− | clsLibMgr::Load('vbz.shop'); | + | clsLibMgr::Add('admin.events', KFP_MW_PLUGINS.'/lib/admin.events.php',__FILE__,__LINE__); |
− | clsLibMgr::Load('forms'); | + | clsLibMgr::Add('admin.forms', KFP_MW_PLUGINS.'/lib/admin.forms.php',__FILE__,__LINE__); |
+ | clsLibMgr::Add('vbz.admin.base', KFP_LIB_VBZ.'/base.admin.php',__FILE__,__LINE__); | ||
+ | clsLibMgr::Add('vbz.admin.cache', KFP_LIB_VBZ.'/admin.cache.php',__FILE__,__LINE__); | ||
+ | clsLibMgr::Add('vbz.admin.cat', KFP_LIB_VBZ.'/admin.cat.php',__FILE__,__LINE__); | ||
+ | clsLibMgr::Add('vbz.admin.sess',KFP_LIB_VBZ.'/admin.sess.php',__FILE__,__LINE__); | ||
+ | clsLibMgr::Add('vbz.admin.cart',KFP_LIB_VBZ.'/admin.cart.php',__FILE__,__LINE__); | ||
+ | clsLibMgr::Add('vbz.admin.ord', KFP_LIB_VBZ.'/admin.ord.php',__FILE__,__LINE__); | ||
+ | clsLibMgr::Add('vbz.admin.pkg', KFP_LIB_VBZ.'/admin.pkg.php',__FILE__,__LINE__); | ||
+ | clsLibMgr::Add('vbz.admin.cust',KFP_LIB_VBZ.'/admin.cust.php',__FILE__,__LINE__); | ||
+ | clsLibMgr::Add('vbz.admin.rstk',KFP_LIB_VBZ.'/admin.rstk.php',__FILE__,__LINE__); | ||
+ | clsLibMgr::Add('vbz.admin.stock',KFP_LIB_VBZ.'/admin.stock.php',__FILE__,__LINE__); | ||
+ | clsLibMgr::Add('richtext', KFP_MW_PLUGINS.'/richtext.php',__FILE__,__LINE__); | ||
+ | clsLibMgr::Add('menus', KFP_MW_PLUGINS.'/menu.php',__FILE__,__LINE__); | ||
+ | clsLibMgr::Load('vbz.site' ,__FILE__,__LINE__); | ||
+ | clsLibMgr::Load('vbz.shop' ,__FILE__,__LINE__); | ||
+ | clsLibMgr::Load('vbz.ckout' ,__FILE__,__LINE__); | ||
+ | clsLibMgr::Load('vbz.topic' ,__FILE__,__LINE__); | ||
+ | clsLibMgr::Load('admin.events' ,__FILE__,__LINE__); | ||
+ | clsLibMgr::Load('admin.forms' ,__FILE__,__LINE__); | ||
+ | clsLibMgr::Load('vbz.admin.base' ,__FILE__,__LINE__); | ||
+ | clsLibMgr::Load('vbz.admin.cache' ,__FILE__,__LINE__); | ||
+ | clsLibMgr::Load('vbz.admin.cat' ,__FILE__,__LINE__); | ||
+ | clsLibMgr::Load('vbz.admin.sess' ,__FILE__,__LINE__); | ||
+ | clsLibMgr::Load('vbz.admin.ord' ,__FILE__,__LINE__); | ||
+ | clsLibMgr::Load('vbz.admin.pkg' ,__FILE__,__LINE__); | ||
+ | clsLibMgr::Load('vbz.admin.cart' ,__FILE__,__LINE__); | ||
+ | clsLibMgr::Load('vbz.admin.cust' ,__FILE__,__LINE__); | ||
+ | clsLibMgr::Load('vbz.admin.rstk' ,__FILE__,__LINE__); | ||
+ | clsLibMgr::Load('vbz.admin.stock' ,__FILE__,__LINE__); | ||
+ | clsLibMgr::Load('richtext' ,__FILE__,__LINE__); | ||
+ | clsLibMgr::Load('menus' ,__FILE__,__LINE__); | ||
− | define(' | + | define('kwp_DocPfx','htyp:VbzCart/'); |
+ | define('kwp_DocTblPfx',kwp_DocPfx.'tables/'); | ||
+ | define('kwp_DocPrcPfx',kwp_DocPfx.'procs/'); | ||
+ | define('kwp_DocTermPfx',kwp_DocPfx.'ui/terms/'); | ||
+ | //echo 'LIB LOG:'.clsLibMgr::$Log; | ||
− | + | if (!defined('KS_CHAR_URL_ASSIGN')) { | |
− | + | define('KS_CHAR_URL_ASSIGN',':'); // character used for encoding values in wiki-internal URLs | |
− | + | } | |
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | define('KS_CHAR_URL_ASSIGN',':'); // character used for encoding values in wiki-internal URLs | ||
// data source names -- these are used only by admin functions; general tables are in store.php | // data source names -- these are used only by admin functions; general tables are in store.php | ||
define('KSQL_DS_ITEMS_TO_SHIP','qryStock_forOpenOrders'); | define('KSQL_DS_ITEMS_TO_SHIP','qryStock_forOpenOrders'); | ||
+ | |||
+ | function Date_DefaultYear($iDate,$iYear,$iSmallerPfx='<small>',$iSmallerSfx='</small>') { | ||
+ | if (empty($iDate)) { | ||
+ | return NULL; | ||
+ | } else { | ||
+ | $dtIn = strtotime($iDate); | ||
+ | $yrIn = date('Y',$dtIn); | ||
+ | $doYr = ($yrIn != $iYear); | ||
+ | $out = ''; | ||
+ | if ($doYr) { | ||
+ | $out .= $iSmallerPfx; | ||
+ | } | ||
+ | $ftIn = date('m/d',$dtIn); | ||
+ | $out .= $ftIn; | ||
+ | if ($doYr) { | ||
+ | $out .= '<br>'.$yrIn; | ||
+ | $out .= $iSmallerSfx; | ||
+ | } | ||
+ | return $out; | ||
+ | } | ||
+ | } | ||
function wfSpecialVbzAdmin() { | function wfSpecialVbzAdmin() { | ||
Line 59: | Line 113: | ||
$app = new SpecialVbzAdmin($wgRequest); | $app = new SpecialVbzAdmin($wgRequest); | ||
+ | } | ||
+ | function NextSeq($iData) { | ||
+ | if ($iData->HasRows()) { | ||
+ | $intMax = 0; | ||
+ | while ($iData->NextRow()) { | ||
+ | if ($iData->Seq > $intMax) { | ||
+ | $intMax = $iData->Seq; | ||
+ | } | ||
+ | } | ||
+ | return $intMax+1; | ||
+ | } else { | ||
+ | return 1; | ||
+ | } | ||
} | } | ||
− | + | /* DEACTIVATED 2010-11-08 | |
− | |||
function VbzDb() { | function VbzDb() { | ||
static $objDb; | static $objDb; | ||
Line 69: | Line 135: | ||
$objDb = new clsVbzAdminData(KS_DB_VBZCART); | $objDb = new clsVbzAdminData(KS_DB_VBZCART); | ||
$objDb->Open(); | $objDb->Open(); | ||
− | |||
} | } | ||
return $objDb; | return $objDb; | ||
} | } | ||
+ | */ | ||
+ | class SpecialVbzAdmin extends SpecialPageApp { | ||
+ | protected $args; | ||
+ | protected $objDB; | ||
− | + | public function __construct() { | |
− | public | + | global $wgMessageCache,$wgUser; |
− | + | global $vgUserName,$vgPage; | |
− | |||
− | |||
− | |||
− | + | parent::__construct( 'VbzAdmin' ); | |
− | $ | + | $this->includable( TRUE ); |
+ | $this->SetTitle('VbzAdmin'); | ||
+ | $vgUserName = 'wiki:'.$wgUser->getName(); | ||
+ | $vgPage = $this; | ||
} | } | ||
− | + | /*---- | |
− | + | USAGE: Must be called before parent::SetHeaders() | |
− | + | */ | |
− | + | public function SetTitle($iText) { | |
− | + | global $wgMessageCache; | |
− | + | ||
− | + | $wgMessageCache->addMessage('vbzadmin',$iText); | |
− | |||
− | public function | ||
− | $ | ||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
} | } | ||
− | + | protected function DB() { | |
− | + | if (!isset($this->objDB)) { | |
− | + | $this->objDB = new clsVbzAdminData(KS_DB_VBZCART); | |
− | + | $this->objDB->Open(); | |
− | |||
− | protected function | ||
− | |||
− | |||
− | |||
− | |||
− | if (isset($this-> | ||
− | $ | ||
− | |||
− | |||
} | } | ||
− | return $ | + | return $this->objDB; |
} | } | ||
− | + | function execute( $par ) { | |
+ | global $wgUser; | ||
− | + | $doAdmin = $wgUser->isAllowed('editinterface'); | |
− | + | $this->GetArgs($par); | |
− | |||
− | |||
− | |||
− | |||
− | + | if ($doAdmin) { | |
− | + | $this->RegObjs($this->ClassList()); | |
− | + | $this->HandlePageArgs(); | |
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | $this-> | ||
− | |||
− | |||
} | } | ||
− | |||
− | |||
− | |||
− | + | $this->setHeaders(); | |
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | + | $this->doMenu($doAdmin); | |
− | |||
− | |||
− | |||
− | |||
− | + | if ($doAdmin) { | |
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | if ($ | ||
$this->doAdmin(); | $this->doAdmin(); | ||
} else { | } else { | ||
$this->doUser(); | $this->doUser(); | ||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
} | } | ||
} | } | ||
− | + | protected function doMenu($iAdmin) { | |
− | |||
global $wgOut; | global $wgOut; | ||
− | + | ||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
$wtSelf = 'Special:'.$this->name(); | $wtSelf = 'Special:'.$this->name(); | ||
$objMenu = new clsMenu($wtSelf); | $objMenu = new clsMenu($wtSelf); | ||
− | $objMenu->Add($objRow = new clsMenuRow('Stock','menu.stock')); | + | if ($iAdmin) { |
− | + | $objMenu->Add($objRow = new clsMenuRow('Stock','menu.stock')); | |
− | + | $objRow->Add(new clsMenuItem('stock places','place')); | |
− | + | $objRow->Add(new clsMenuItem('stock bins','bin')); | |
− | + | $objMenu->Add($objRow = new clsMenuRow('Catalog','menu.cat')); | |
− | + | $objRow->Add(new clsMenuItem('suppliers','supp')); | |
− | + | $objRow->Add(new clsMenuItem('images','cat.img')); | |
− | + | $objRow->Add(new clsMenuItem('topics','topic')); | |
− | + | $objRow->Add(new clsMenuItem('search','cat.search')); | |
− | + | $objMenu->Add($objRow = new clsMenuRow('Restocks','menu.rstk')); | |
+ | $objRow->Add(new clsMenuItem('needed','rstk.need')); | ||
+ | $objRow->Add(new clsMenuItem('expected','rstk.wait')); | ||
+ | $objRow->Add(new clsMenuItem('past','rstk.past')); | ||
+ | $objMenu->Add($objRow = new clsMenuRow('Orders','menu.orders')); | ||
+ | $objRow->Add(new clsMenuItem('carts','cart')); | ||
+ | $objRow->Add(new clsMenuItem('orders',KS_URL_PAGE_ORDER)); | ||
+ | $objRow->Add(new clsMenuItem('charges','chg')); | ||
+ | $objMenu->Add($objRow = new clsMenuRow('Ship','menu.ship')); | ||
+ | $objRow->Add(new clsMenuItem('items to ship','toship')); | ||
+ | $objRow->Add(new clsMenuItem('shipments','shpmt')); | ||
+ | $objMenu->Add($objRow = new clsMenuRow('Utilities','menu.utils')); | ||
+ | $objRow->Add(new clsMenuItem('cache tables','cache')); | ||
+ | $objRow->Add(new clsMenuItem('ccard encryption','migr.encr')); | ||
+ | $objRow->Add(new clsMenuItem('update stats','util.stats')); | ||
+ | $objRow->Add(new clsMenuItem('price list','util.plist')); | ||
+ | $objRow->Add(new clsMenuItem('inventory','util.inv')); | ||
+ | $objMenu->Add($objRow = new clsMenuRow('Logs','menu.logs')); | ||
+ | $objRow->Add(new clsMenuItem('general','log.misc')); | ||
+ | $objRow->Add(new clsMenuItem('carts','log.cart')); | ||
+ | } | ||
− | $out = $objMenu->WikiText($page); | + | $wgOut->addHTML('<table style="background: #ccffcc;"><tr><td>'); |
+ | $out = $objMenu->WikiText($this->page); | ||
$out .= $objMenu->Execute(); | $out .= $objMenu->Execute(); | ||
− | |||
− | |||
$wgOut->addWikiText($out,TRUE); $out = ''; | $wgOut->addWikiText($out,TRUE); $out = ''; | ||
$wgOut->addHTML('</td></tr></table>'); | $wgOut->addHTML('</td></tr></table>'); | ||
− | if ( | + | // a little diagnostic info |
− | $ | + | $isFnd = FALSE; |
− | $ | + | $out .= '<small>'; |
− | switch ($page) { | + | if (is_object($this->tbl)) { |
− | + | $out .= 'table class: <b>'.get_class($this->tbl).'</b>'; | |
− | + | $isFnd = TRUE; | |
− | + | } | |
− | + | if (is_object($this->obj)) { | |
− | + | $out .'record class: <b>'.get_class($this->obj).'</b>'; | |
− | + | $isFnd = TRUE; | |
− | + | } | |
− | + | if (!$isFnd) { | |
− | + | $out .= 'No classes found for page ['.$this->page.'].'; | |
− | + | } | |
− | + | $out .= '</small>'; | |
− | + | $wgOut->addHTML($out); $out = ''; | |
− | + | ||
− | + | } | |
− | + | protected function ClassList() { | |
− | + | $ar = array( | |
− | + | //'clsAdminCacheFlows', | |
− | + | //'clsAdminCacheProc', | |
− | + | //'clsAdminCacheTables', | |
− | + | //'VbzAdminCartLines', | |
− | + | //'VbzAdminCartLog', | |
− | + | 'VbzAdminCarts', | |
− | + | 'VbzAdminCatalogs', | |
− | $this-> | + | 'clsAdminCustAddrs', |
− | + | 'VbzAdminCustCards', | |
− | $this-> | + | 'clsAdminCustEmails', |
+ | 'clsAdminCustNames', | ||
+ | 'clsAdminCustPhones', | ||
+ | 'VbzAdminCusts', | ||
+ | 'VbzAdminDepts', | ||
+ | 'clsAdminEvents', | ||
+ | 'clsAdminImages', | ||
+ | 'VbzAdminItems', | ||
+ | //'clsAdminItems_info_Cat', | ||
+ | 'VbzAdminOrderChgs', | ||
+ | 'VbzAdminOrderItems', | ||
+ | //'VbzAdminOrderPulls', | ||
+ | 'VbzAdminOrders', | ||
+ | 'VbzAdminOrderTrxacts', | ||
+ | //'VbzAdminOrderTrxTypes', | ||
+ | 'VbzAdminOrderMsgs', | ||
+ | //'clsAdminRstkReqItems', | ||
+ | 'clsAdminRstkReqs', | ||
+ | //'VbzAdminSessions', | ||
+ | 'VbzAdminStkItems', | ||
+ | 'VbzAdminSuppliers', | ||
+ | 'VbzAdminTitles', | ||
+ | //'VbzAdminTitles_info_Cat', | ||
+ | //'VbzAdminTitles_info_Item', | ||
+ | //'clsAdminTitleTopic_Titles', | ||
+ | //'clsAdminTitleTopic_Topics', | ||
+ | 'clsAdminTopics', | ||
+ | |||
+ | //'clsCMITems', | ||
+ | 'clsCtgGroups', | ||
+ | //'clsCtgTitles', | ||
+ | //'clsOrderPullTypes', | ||
+ | 'clsPackages', | ||
+ | //'clsPkgLines', | ||
+ | 'clsShipments', | ||
+ | //'clsStkLog', | ||
+ | //'clsTitleTopics_base', | ||
+ | //'clsRstkRcdLines', | ||
+ | 'clsRstkRcds', | ||
+ | //'VbzStockBinLog', | ||
+ | 'VbzStockBins', | ||
+ | 'VbzStockPlaces', | ||
+ | ); | ||
+ | return $ar; | ||
+ | } | ||
+ | /*----- | ||
+ | PURPOSE: do stuff that only admins are allowed to do | ||
+ | */ | ||
+ | public function doAdmin() { | ||
+ | global $wgOut; | ||
+ | $obj = $this->obj; | ||
+ | $tbl = $this->tbl; | ||
+ | |||
+ | $out =NULL; | ||
+ | $didPage = FALSE; | ||
+ | |||
+ | if (is_object($obj)) { | ||
+ | $out = $obj->AdminPage(); | ||
+ | $didPage = TRUE; | ||
+ | } elseif (is_object($tbl)) { | ||
+ | $out = $tbl->AdminPage(); | ||
+ | $didPage = TRUE; | ||
+ | } | ||
+ | |||
+ | if (!$didPage) { | ||
+ | $page = $this->page; | ||
+ | $idObj = $this->idObj; | ||
+ | $doObj = $this->doObj; | ||
+ | |||
+ | if (!is_null($page)) { | ||
+ | $dbVBZ = $this->DB(); | ||
+ | |||
+ | $out = NULL; | ||
+ | switch ($page) { | ||
+ | case 'cache': | ||
+ | case 'cache.tbl': | ||
+ | case 'cache.proc': | ||
+ | $this->DB()->CacheMgr()->MenuDispatch($page,$idObj); | ||
+ | break; | ||
+ | case 'cat.search': | ||
+ | $tbl = $dbVBZ->Titles_Cat(); | ||
+ | $out = $tbl->SearchPage(); | ||
+ | break; | ||
+ | case 'log.cart': | ||
+ | $objTbl = new VbzAdminCartLog($dbVBZ); | ||
+ | $out = $objTbl->AdminPage(); | ||
+ | break; | ||
+ | case 'log.misc': | ||
+ | $objLog = new clsAdminEvents($dbVBZ); | ||
+ | $objLog->ListPage(); | ||
+ | break; | ||
+ | case 'migr.encr': | ||
+ | $objCards = $dbVBZ->CustCards(); | ||
+ | $objCards->EncryptAdmin(); | ||
+ | break; | ||
+ | case 'rstk.need': | ||
+ | $objTbl = $dbVBZ->RstkReqs(); | ||
+ | $objTbl->AdminItemsNeeded(); | ||
+ | break; | ||
+ | case 'rstk.past': | ||
+ | $objTbl = $dbVBZ->RstkReqs(); | ||
+ | $objRows = $objTbl->RowsInactive(); | ||
+ | $out = $objRows->AdminList(); | ||
+ | break; | ||
+ | case 'rstk-rcd': | ||
+ | $objTbl = $dbVBZ->RstkRcds(); | ||
+ | $objRow = $objTbl->GetItem($idObj); | ||
+ | $out = $objRow->AdminPage(); | ||
+ | break; | ||
+ | case 'rstk-req': | ||
+ | $objTbl = $dbVBZ->RstkReqs(); | ||
+ | $objRow = $objTbl->GetItem($idObj); | ||
+ | $out = $objRow->AdminPage(); | ||
+ | break; | ||
+ | case 'rstk.wait': | ||
+ | $objTbl = $dbVBZ->RstkReqs(); | ||
+ | $objRows = $objTbl->RowsActive(); | ||
+ | $out = $objRows->AdminList(); | ||
+ | break; | ||
+ | case 'toship': | ||
+ | $this->doStockToShip(); | ||
+ | break; | ||
+ | case 'util.stats': | ||
+ | $this->DoUpdateStats(); | ||
+ | break; | ||
+ | case 'util.plist': | ||
+ | $this->DoPriceList(); | ||
+ | break; | ||
+ | case 'util.inv': | ||
+ | $this->DoInvCompare(); | ||
+ | break; | ||
+ | default: | ||
+ | $out = 'Select from the menu above.'; | ||
} | } | ||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
} | } | ||
} | } | ||
− | + | if (!is_null($out)) { | |
− | + | $wgOut->AddWikiText($out,TRUE); | |
+ | } | ||
+ | } | ||
+ | public function doCharges() { | ||
+ | global $wgOut; | ||
+ | global $vgPage; | ||
+ | |||
+ | $doAll = $vgPage->Arg('all'); | ||
+ | $strMnuAll = $this->SelfLink_WT(array('all' => TRUE),'all'); | ||
+ | $strMnuUnp = $this->SelfLink_WT(array('all' => FALSE),'to process'); | ||
+ | |||
+ | $objTbl = new VbzAdminOrderChgs($this->DB()); | ||
+ | if ($doAll) { | ||
+ | $strMenu = "$strMnuUnp .. '''$strMnuAll'''"; | ||
+ | $strDescr = ' in database'; | ||
+ | $sqlFilt = NULL; | ||
+ | } else { | ||
+ | $strMenu = "'''$strMnuUnp''' .. $strMnuAll"; | ||
+ | $strDescr = ' to be processed'; | ||
+ | $sqlFilt = '(WhenDecided IS NULL) AND ((WhenXmitted IS NULL) OR isSuccess) AND (WhenVoided IS NULL) AND (WhenHeldUp IS NULL)'; | ||
+ | } | ||
+ | $objRows = $objTbl->GetData($sqlFilt,NULL,'ID DESC'); | ||
+ | $wgOut->AddWikiText("'''Show Charges''': $strMenu", TRUE); | ||
+ | $arArgs['descr'] = $strDescr; | ||
+ | $wgOut->AddWikiText($objRows->AdminTable($arArgs),TRUE); | ||
+ | } | ||
+ | public function doUser() { | ||
global $wgOut; | global $wgOut; | ||
/* | /* | ||
Line 317: | Line 433: | ||
// individual admin functions | // individual admin functions | ||
− | + | public function doStockToShip() { | |
global $wgOut; | global $wgOut; | ||
− | $dbVBZ = | + | $dbVBZ = $this->DB(); |
$out = '==Stock to Ship=='."\n"; | $out = '==Stock to Ship=='."\n"; | ||
$wgOut->addWikiText($out,TRUE); $out = ''; | $wgOut->addWikiText($out,TRUE); $out = ''; | ||
Line 331: | Line 447: | ||
$idBin = $objRows->ID_Bin; | $idBin = $objRows->ID_Bin; | ||
$strOrd = $objRows->OrdText?$objRows->OrdText:'?ord#?'; | $strOrd = $objRows->OrdText?$objRows->OrdText:'?ord#?'; | ||
− | $wtItem = '{{faint|'.$idItem.'}} '. | + | $wtItem = '{{faint|'.$idItem.'}} '.SelfLink_Page('item','id',$idItem,$objRows->ItemText); |
− | $wtOrder = '{{faint|'.$idOrd.'}} '. | + | $wtOrder = '{{faint|'.$idOrd.'}} '.SelfLink_Page(KS_URL_PAGE_ORDER,'id',$idOrd,$strOrd); |
− | $wtBin = '{{faint|'.$idBin.'}} '. | + | $wtBin = '{{faint|'.$idBin.'}} '.SelfLink_Page('bin','id',$idBin,$objRows->BinText); |
$wtQtyNeed = $objRows->QtyOpen; | $wtQtyNeed = $objRows->QtyOpen; | ||
$intQtyForShip = $objRows->QtyForSale; | $intQtyForShip = $objRows->QtyForSale; | ||
Line 344: | Line 460: | ||
} | } | ||
$out .= "\n|}\n(Retrieval complete.)"; | $out .= "\n|}\n(Retrieval complete.)"; | ||
− | + | } else { | |
$out = 'No stock items available for open orders.'; | $out = 'No stock items available for open orders.'; | ||
− | + | } | |
− | + | $wgOut->addWikiText($out,TRUE); $out = ''; | |
} | } | ||
+ | /* | ||
public function doCacheTables() { | public function doCacheTables() { | ||
− | + | $this->DB()->CacheMgr()->AdminPage(); | |
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
} | } | ||
+ | */ | ||
public function doSuppliers() { | public function doSuppliers() { | ||
− | $ | + | $objSupps = $this->DB()->Suppliers(); |
− | |||
$objSupps->ListPage(); | $objSupps->ListPage(); | ||
} | } | ||
public function doSupplier($iID) { | public function doSupplier($iID) { | ||
− | $ | + | $objSupps = $this->DB()->Suppliers(); |
− | |||
$objSupp = $objSupps->GetItem($iID); | $objSupp = $objSupps->GetItem($iID); | ||
− | $objSupp-> | + | return $objSupp->AdminPage(); |
} | } | ||
public function doDept($iID) { | public function doDept($iID) { | ||
− | $ | + | $objDepts = $this->DB()->Depts(); |
− | |||
$objDept = $objDepts->GetItem($iID); | $objDept = $objDepts->GetItem($iID); | ||
− | $objDept->InfoPage(); | + | return $objDept->InfoPage(); |
} | } | ||
public function doTitle($iID) { | public function doTitle($iID) { | ||
− | $ | + | $objTitles = $this->DB()->Titles(); |
− | |||
$objTitle = $objTitles->GetItem($iID); | $objTitle = $objTitles->GetItem($iID); | ||
− | $objTitle->InfoPage(); | + | return $objTitle->InfoPage(); |
} | } | ||
− | + | public function doItem($iID) { | |
− | + | $objTbl = $this->DB()->Items(); | |
− | + | $objRow = $objTbl->GetItem($iID); | |
− | public function | + | return $objRow->InfoPage(); |
− | return $ | ||
} | } | ||
− | public function | + | public function doImgAdmin() { |
− | return $ | + | $objTbl = $this->DB()->Images(); |
+ | return $objTbl->AdminPage_Unassigned(); | ||
} | } | ||
− | + | /*---- | |
− | + | TO DO: This really should be rewritten as a method of clsContactNode | |
− | + | USED BY: VbzAdminOrder::DoSetupCart() in admin.ord.php | |
− | + | HISTORY: | |
− | + | 2011-04-17 using AdminLink() on customer object instead of hand-building the links | |
− | + | */ | |
− | + | function CheckPersonMatches(clsPerson $iPerson,VbzAdminCart $iCart) { | |
− | + | $objDB = $this->DB(); | |
− | + | $objPage = $this; | |
− | + | $objPerson = $iPerson; | |
− | + | $objCart = $iCart; | |
− | + | //$arLink = $iLinkArr; | |
− | + | ||
− | + | $strName = $objPerson->FormName(); | |
− | + | $strDescr = $objPerson->Descr(); | |
− | + | ||
− | + | $objName = $iPerson->Node('name'); | |
− | + | if (!is_object($objName)) { | |
− | + | echo $iPerson->DumpHTML(); | |
− | / | + | throw new exception('Internal error: missing object in tree.'); |
− | + | } | |
− | + | $strCustName = $objName->Value(); | |
− | + | ||
+ | $out = "\n<hr>Contact information for <b>$strDescr</b>:"; | ||
+ | |||
+ | $out .= "\n<li> <b>Customer</b>: ".$strCustName; | ||
+ | $out .= "\n<ul>"; | ||
+ | if ($objCart->DataItem(KSI_SHIP_IS_CARD)) { | ||
+ | $strAddrShip = 'Address'; | ||
+ | } else { | ||
+ | // $strCardAddr = $objPerson->Card->Addr->AsSingleLine(); | ||
+ | $objPay = $objPerson->Payment(); | ||
+ | if (is_null($objPay)) { | ||
+ | /* | ||
+ | 2011-10-04 this isn't a problem as long as _one_ of the calls has payment in iPerson | ||
+ | echo 'Person object tree:'; | ||
+ | echo $objPerson->DumpHTML(); | ||
+ | throw new exception('Payment object is NULL'); | ||
+ | */ | ||
+ | $strCardAddr = NULL; // so later code knows not to try using it | ||
+ | } else { | ||
+ | $strCardAddr = $objPay->Addr()->AsSingleLine(); | ||
+ | $out .= "\n<li> <b>Card Address</b>: ".$strCardAddr.'</li>'; | ||
+ | $strAddrShip = 'Shipping Address'; | ||
+ | } | ||
+ | } | ||
+ | if ($objPerson->HasContact()) { | ||
+ | $objAddr = $objPerson->Contact()->Addr(); | ||
+ | if ($objAddr) { | ||
+ | $strShipAddr = $objAddr->AsSingleLine(); | ||
+ | $out .= "\n<li> <b>$strAddrShip</b>: ".$strShipAddr.'</li>'; | ||
+ | $out .= "\n<ul><li><b>Searching as</b>: ".clsCustAddrs::Searchable($strShipAddr).'</li></ul>'; | ||
+ | } | ||
+ | if ($objPerson->Contact()->HasEmail()) { | ||
+ | $strEmail = $objPerson->Contact()->Email()->Value(); | ||
+ | $out .= "\n<li> <b>Email</b>: ".$strEmail.'</li>'; | ||
+ | } | ||
+ | if ($objPerson->Contact()->HasPhone()) { | ||
+ | $strPhone = $objPerson->Contact()->Phone()->Value(); | ||
+ | $out .= "\n<li> <b>Phone</b>: ".$strPhone.'</li>'; | ||
+ | } | ||
+ | } | ||
+ | $out .= "\n</ul>"; | ||
− | $out = | + | // Look for matches to existing contacts |
− | $ | + | $out .= "\nChecking <b>$strDescr</b> for matches to existing customers..."; |
− | + | // -- name | |
− | if ( | + | // --- customer |
− | + | $objRows = $objDB->CustNames()->Find($strCustName); | |
− | + | if ($objRows->HasRows()) { | |
+ | while ($objRows->NextRow()) { | ||
+ | $idCont = $objRows->ID_Cust; | ||
+ | $idName = $objRows->ID; | ||
+ | $arSame[$idCont]['name'] = $objRows->RowCopy(); | ||
+ | } | ||
+ | } | ||
+ | // --- destination (if different) | ||
+ | if (isset($strDestName)) { | ||
+ | $objRows = $objDB->CustNames()->Find($strDestName); | ||
+ | if ($objRows->HasRows()) { | ||
+ | while ($objRows->NextRow()) { | ||
+ | $idCont = $objRows->ID_Cust; | ||
+ | $idName = $objRows->ID; | ||
+ | $arSame[$idCont]['name'] = $objRows->RowCopy(); | ||
+ | } | ||
} | } | ||
+ | } | ||
+ | |||
+ | // -- address | ||
+ | // --- card | ||
+ | if ($objCart->DataItem(KSI_SHIP_IS_CARD)) { | ||
+ | $strAddrShip = 'addr'; | ||
} else { | } else { | ||
− | $ | + | $strAddrShip = 'addr-ship'; |
+ | if (!is_null($strCardAddr)) { | ||
+ | $objRows = $objDB->CustAddrs()->Find($strCardAddr); | ||
+ | if ($objRows->HasRows()) { | ||
+ | while ($objRows->NextRow()) { | ||
+ | $idCont = $objRows->ID_Cust; | ||
+ | $idName = $objRows->ID; | ||
+ | $arSame[$idCont]['addr-card'] = $objRows->RowCopy(); | ||
+ | } | ||
+ | } | ||
+ | } | ||
+ | } | ||
+ | // --- shipping | ||
+ | if (isset($strCardAddr)) { | ||
+ | $objRows = $objDB->CustAddrs()->Find($strCardAddr); | ||
+ | if ($objRows->HasRows()) { | ||
+ | while ($objRows->NextRow()) { | ||
+ | $idCont = $objRows->ID_Cust; | ||
+ | $idName = $objRows->ID; | ||
+ | $arSame[$idCont][$strAddrShip] = $objRows->RowCopy(); | ||
+ | } | ||
+ | } | ||
} | } | ||
− | / | + | if (isset($objPerson->Contact)) { |
− | + | // -- phone | |
− | + | if (isset($strPhone)) { | |
− | + | $objRows = $objDB->CustPhones()->Find($strPhone); | |
− | + | if ($objRows->HasRows()) { | |
− | + | while ($objRows->NextRow()) { | |
− | + | $idCont = $objRows->ID_Cust; | |
+ | $idName = $objRows->ID; | ||
+ | $arSame[$idCont]['phone'] = $objRows->RowCopy(); | ||
+ | } | ||
+ | } | ||
+ | } | ||
− | + | // -- email | |
− | + | if (isset($strEmail)) { // sometimes this isn't set; this may be a bug. figure out why later. | |
− | + | $objRows = $objDB->CustEmails()->Find($strEmail); | |
− | + | if ($objRows->HasRows()) { | |
− | + | while ($objRows->NextRow()) { | |
− | + | $idCont = $objRows->ID_Cust; | |
− | + | $idName = $objRows->ID; | |
+ | $arSame[$idCont]['email'] = $objRows->RowCopy(); | ||
+ | } | ||
+ | } | ||
+ | } | ||
+ | } | ||
+ | // -- credit card | ||
+ | $strCard = $objCart->DataItem(KSI_CUST_CARD_NUM); | ||
+ | $objRows = $objDB->CustCards()->Find($strCard); | ||
+ | if ($objRows->HasRows()) { | ||
+ | while ($objRows->NextRow()) { | ||
+ | $idCont = $objRows->ID_Cust; | ||
+ | $idName = $objRows->ID; | ||
+ | $arSame[$idCont]['card'] = $objRows->RowCopy(); | ||
+ | } | ||
+ | } | ||
+ | // Report any matches found: | ||
+ | if (isset($arSame)) { | ||
+ | $out .= "\nChoose how to resolve the match:"; | ||
+ | $out .= "\n<ul>"; | ||
+ | foreach ($arSame as $idCont=>$val) { | ||
+ | $objCust = $objDB->Custs($idCont); | ||
+ | $htLink = $objCust->AdminLink_status(); | ||
− | + | $out .= "\n<li><input type=radio name=\"$strName\" value=\"$idCont\">Use contact #$htLink</a>:"; | |
− | + | $out .= "\n<ul>"; | |
− | + | foreach($val as $vkey=>$vval) { | |
− | + | $strDescr = $vval->ShortDescr(); | |
− | + | $out .= "\n<li> <b>$vkey</b>: $strDescr</li>"; | |
+ | } | ||
+ | $out .= "\n</ul></li>"; | ||
+ | } | ||
+ | $out .= "\n<li><input type=radio name=\"$strName\" value=\"new\">Create new contact record</li>"; | ||
+ | $out .= "\n</ul>"; | ||
+ | } else { | ||
+ | // 2011-07-28 removing "create new records" link; should be created on import if none found | ||
+ | // $htURL = $objPage->SelfURL(array('allnew'=>TRUE)); | ||
+ | // $htLink = '<a href="'.$htURL.'">create new records</a>'; | ||
+ | $out .= "\n<br>No matches found; new contact records will be created."; | ||
+ | $out .= '<input type=hidden name="cust" value=new /><input type=hidden name="ship" value=new />'; | ||
+ | } | ||
+ | return $out; | ||
} | } | ||
− | + | protected function DoUpdateStats() { | |
− | + | $objVars = $this->objDB->VarsGlobal(); | |
− | + | ||
− | + | $sqlStkQty = 'SELECT SUM(QtyForSale) AS Qty FROM qryStkItms_for_sale'; | |
+ | $intStkQty = 0; | ||
− | $ | + | $objVars->Val('stat.stock.qty',$intStkQty); // total stock quantity |
− | |||
− | |||
− | |||
− | |||
− | |||
} | } | ||
− | + | protected function DoPriceList() { | |
− | global $ | + | global $wgOut,$wgRequest; |
+ | global $vgPage; | ||
+ | |||
+ | $vgPage->UseHTML(); | ||
+ | |||
+ | $doCheck = $wgRequest->GetBool('btnCheck'); | ||
− | + | $out = NULL; | |
− | + | $out .= 'Enter <s>catalog numbers or</s> item IDs:'; | |
− | $ | + | if ($doCheck) { |
+ | $txt = $wgRequest->GetText('list'); | ||
+ | $xts = new xtString($txt); | ||
+ | $xts->ReplaceSequence("\n\t ", ' ',0); | ||
+ | $ar = explode (' ',$xts->Value); | ||
− | + | $pos = strpos ($txt,':'); // colon means there are quantities | |
− | + | $hasQtys = is_numeric($pos); | |
− | + | ||
− | + | $htTxt = htmlspecialchars($txt); | |
− | + | $htTxtRows = 3; | |
− | |||
− | |||
− | |||
− | |||
− | |||
} else { | } else { | ||
− | + | $htTxt = ''; | |
+ | $htTxtRows = 30; | ||
} | } | ||
− | if ($ | + | if ($doCheck) { |
− | $out = | + | $out .= '<table width=100%><tr><td width=10%>'; |
− | + | if ($hasQtys) { | |
− | if ($ | + | $htQtyCol = '<th>Qty</th>'; |
− | $ | + | } else { |
− | $ | + | $htQtyCol = ''; |
+ | } | ||
+ | |||
+ | $objDB = $this->DB(); | ||
+ | $out .= '</td><td valign=top>'; | ||
+ | $out .= '<table><tr><th>ID</th>'.$htQtyCol.'<th>Cat #</th><th>Name</th><th>Exact</th><th>Rounded</th></tr>'; | ||
+ | $arItems = array(); | ||
+ | $arQtys = array(); | ||
+ | foreach ($ar as $word) { | ||
+ | // if word contains a colon, ignore it and everything after (so we can use that format here even though qty is irrelevant): | ||
+ | $pos = strpos ($word,':'); | ||
+ | if ($pos) { | ||
+ | $qty = substr($word,$pos+1); | ||
+ | $word = substr($word,0,$pos); | ||
+ | } else { | ||
+ | $qty = NULL; | ||
+ | } | ||
+ | if (is_numeric($word)) { | ||
+ | $id = $word; | ||
+ | $objItem = $objDB->Items($id); | ||
− | $ | + | if (is_object($objItem)) { |
− | + | $id = $objItem->Value('ID'); | |
− | + | if (!array_key_exists($id,$arItems)) { | |
− | + | $arItems[$id] = $objItem->Values(); | |
+ | $arCatNums[$objItem->Value('CatNum')] = $id; | ||
+ | } | ||
+ | $arQtys[$id] = NzArray($arQtys,$id)+$qty; | ||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
} else { | } else { | ||
− | + | $out .= "\n<tr>" | |
− | $ | + | .'<td>'.$id.'</td><td colspan=2>not found</td></tr>'; |
} | } | ||
− | // | + | } else { |
− | + | // to be written | |
− | + | } | |
− | + | } | |
+ | |||
+ | ksort($arCatNums); | ||
+ | |||
+ | foreach ($arCatNums as $catnum => $id) { | ||
+ | //echo '<br>CATNUM=['.$catnum.'] ID=['.$id.']'; | ||
+ | $arVals = $arItems[$id]; | ||
+ | $objItem->Values($arVals); // load the row into the object | ||
+ | |||
+ | $mnSellExact = $objItem->Value('PriceSell'); | ||
+ | $mnSellRound = round($mnSellExact) + 1.00; | ||
+ | |||
+ | $out .= "\n<tr>" | ||
+ | .'<td>'.$objItem->AdminLink().'</td>'; | ||
+ | if ($hasQtys) { | ||
+ | $qty = $arQtys[$id]; | ||
+ | if (is_null($qty)) { | ||
+ | $out .= '<td></td>'; | ||
} else { | } else { | ||
− | $ | + | $out .= "<td align=right>$qty</td>"; |
− | |||
− | |||
− | |||
− | |||
− | |||
} | } | ||
+ | } | ||
+ | $out .= | ||
+ | '<td>'.$objItem->Value('CatNum').'</td>' | ||
+ | .'<td>'.$objItem->FullDescr_HTML().'</td>' | ||
+ | .'<td>'.$mnSellExact.'</td>' | ||
+ | .'<td>'.$mnSellRound.'</td>' | ||
+ | .'</tr>'; | ||
+ | } | ||
+ | $out .= '</tr></table>'; // item listing table | ||
+ | $out .= '</td></tr></table>'; // outer table | ||
+ | } | ||
+ | |||
+ | $out .= '<form method=post>'; | ||
+ | $out .= '<textarea name=list rows='.$htTxtRows.'>'.$htTxt.'</textarea>'; | ||
+ | $out .= '<input type=submit name=btnCheck value="Check" />'; | ||
+ | $out .= '</form>'; | ||
+ | |||
+ | $wgOut->AddHTML($out); | ||
+ | return NULL; // caller expects wikitext | ||
+ | } | ||
+ | private function DoInvCompare() { | ||
+ | global $vgPage; | ||
+ | global $wgOut,$wgRequest; | ||
+ | |||
+ | $txtStart = $wgRequest->GetText('txtStart'); | ||
+ | $txtFinish = $wgRequest->GetText('txtFinish'); | ||
+ | |||
+ | $vgPage->UseHTML(); | ||
+ | |||
+ | $htStart = htmlspecialchars($txtStart); | ||
+ | $htFinish = htmlspecialchars($txtFinish); | ||
+ | |||
+ | $fxParse = function($iText) { | ||
+ | $ar = preg_split('/ /',$iText); | ||
+ | foreach ($ar as $item) { | ||
+ | list($id,$qty) = preg_split('/:/',$item); | ||
+ | $arOut[$id] = $qty; | ||
+ | } | ||
+ | return $arOut; | ||
+ | }; | ||
− | + | $arStart = $fxParse($txtStart); | |
− | + | $arFinish = $fxParse($txtFinish); | |
− | + | $arDiff = array(); | |
− | + | foreach ($arStart as $id => $qty) { | |
− | + | $qtyFinish = nzArray($arFinish,$id); | |
− | + | if ($qty != $qtyFinish) { | |
− | + | $arDiff[$id] = 'old:'.$qty.' new:'.$qtyFinish; | |
− | + | } | |
− | + | } | |
− | + | foreach ($arFinish as $id => $qty) { | |
− | + | $qtyStart = nzArray($arStart,$id); | |
− | + | if (!array_key_exists($id,$arStart)) { | |
− | + | $arDiff[$id] = 'new:'.$qty; | |
− | + | } | |
+ | } | ||
+ | |||
+ | $out = '<form method=post action="'.$vgPage->SelfURL().'">'; | ||
+ | $out .= 'Display difference between two inventory counts:'; | ||
+ | $out .= '<table width=100%><tr>'; | ||
+ | $out .= "<td>Starting inventory:<textarea rows=10 name=txtStart>$txtStart</textarea></td>"; | ||
+ | $out .= "<td>Ending inventory:<textarea rows=10 name=txtFinish>$txtFinish</textarea></td>"; | ||
+ | $out .= '<tr><td colspan=2 align=center><input type=submit name=btnCalc value="Compare"></td></tr>'; | ||
+ | $out .= '</tr></table>'; | ||
+ | $out .= '</form>'; | ||
− | + | if (count($arDiff) > 0) { | |
− | + | $tbl = $this->DB()->Items(); | |
− | + | $out .= '<table>'; | |
− | + | foreach ($arDiff as $id => $txt) { | |
− | + | $obj = $tbl->GetItem($id); | |
− | + | $out .= '<tr><td>'.$obj->AdminLink_friendly().'</td><td>'.$txt.'</td></tr>'; | |
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
} | } | ||
− | $out .= | + | $out .= '</table>'; |
} else { | } else { | ||
− | $out .= ' | + | $cnt = count($arStart); |
+ | $out .= $cnt.' item'.Pluralize($cnt).' compared - inventories are identical.'; | ||
} | } | ||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | + | $wgOut->AddHTML($out); | |
− | $ | + | return NULL; // caller expects wikitext |
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | return NULL; | ||
} | } | ||
} | } | ||
− | class | + | /* ***** |
+ | * CATALOG DATA | ||
+ | */ | ||
+ | class VbzAdminSuppliers extends clsSuppliers { | ||
public function __construct($iDB) { | public function __construct($iDB) { | ||
parent::__construct($iDB); | parent::__construct($iDB); | ||
− | + | $this->ClassSng('VbzAdminSupplier'); | |
− | |||
− | $this->ClassSng(' | ||
} | } | ||
− | public function | + | public function AdminPage() { |
global $wgOut; | global $wgOut; | ||
+ | global $vgPage; | ||
− | $ | + | $vgPage->UseWiki(); |
− | |||
− | $out = | + | $out = '==Suppliers=='; |
$wgOut->addWikiText($out,TRUE); $out = ''; | $wgOut->addWikiText($out,TRUE); $out = ''; | ||
− | + | $objRecs = $this->GetData(); | |
− | + | if ($objRecs->HasRows()) { | |
− | + | $out = "{| class=sortable\n|-\n! ID || A? || Code || Actions || Name"; | |
− | + | $isOdd = TRUE; | |
− | + | while ($objRecs->NextRow()) { | |
− | + | $strCatKey = $objRecs->CatKey; | |
− | + | $id = $objRecs->ID; | |
− | + | $wtActions = | |
− | + | '['.KWP_CAT.strtolower($strCatKey)." shop] " | |
− | + | .$objRecs->AdminLink('manage'); | |
− | + | $wtCatNum = $strCatKey; | |
− | + | $wtStyle = $isOdd?'background:#ffffff;':'background:#cccccc;'; | |
− | while ($ | + | $isActive = $objRecs->isActive; |
− | + | if ($isActive) { | |
− | $ | + | $wtName = '[['.$objRecs->Name.']]'; |
− | $ | ||
− | $ | ||
− | if | ||
− | $ | ||
} else { | } else { | ||
− | $ | + | $wtName = $objRecs->Name; |
+ | $wtStyle .= ' color: #888888;'; | ||
} | } | ||
+ | $out .= "\n|- style=\"$wtStyle\"\n| ".$id | ||
+ | .' || '.($isActive?'√':'') | ||
+ | .' || '.$wtCatNum | ||
+ | .' || '.$wtActions | ||
+ | .' || '.$wtName; | ||
+ | $isOdd = !$isOdd; | ||
} | } | ||
− | |||
− | |||
$out .= "\n|}"; | $out .= "\n|}"; | ||
} else { | } else { | ||
− | $out = | + | $out = 'No suppliers have been created yet.'; |
+ | } | ||
+ | $wgOut->addWikiText($out,TRUE); $out = ''; | ||
+ | } | ||
+ | } | ||
+ | class VbzAdminSupplier extends clsSupplier { | ||
+ | /*==== | ||
+ | HISTORY: | ||
+ | 2010-12-05 boilerplate event logging added to VbzAdminSupplier | ||
+ | */ | ||
+ | protected function Log() { | ||
+ | if (!is_object($this->logger)) { | ||
+ | $this->logger = new clsLogger_DataSet($this,$this->objDB->Events()); | ||
} | } | ||
− | return $out; | + | return $this->logger; |
+ | } | ||
+ | public function StartEvent(array $iArgs) { | ||
+ | return $this->Log()->StartEvent($iArgs); | ||
+ | } | ||
+ | public function FinishEvent(array $iArgs=NULL) { | ||
+ | return $this->Log()->FinishEvent($iArgs); | ||
+ | } | ||
+ | public function EventListing() { | ||
+ | return $this->Log()->EventListing(); | ||
+ | } | ||
+ | //==== | ||
+ | /*---- | ||
+ | HISTORY: | ||
+ | 2010-10-11 Replaced existing code with call to static function | ||
+ | */ | ||
+ | public function AdminLink($iText=NULL,$iPopup=NULL,array $iarArgs=NULL) { | ||
+ | return clsAdminData::_AdminLink($this,$iText,$iPopup,$iarArgs); | ||
+ | } | ||
+ | public function AdminLink_name() { | ||
+ | return $this->AdminLink($this->Name); | ||
+ | } | ||
+ | /*---- | ||
+ | HISTORY: | ||
+ | 2010-11-04 Created so AdminPage() can use HTML | ||
+ | 2011-02-16 Disabled until I figure out why it isn't redundant | ||
+ | */ | ||
+ | /* | ||
+ | public function ShopLink($iText=NULL) { | ||
+ | return '<a href="'.KWP_CAT.strtolower($this->CatKey).'">'.$iText.'</a>'; | ||
} | } | ||
− | + | */ | |
− | + | public function PageTitle() { | |
− | + | global $vgPage; | |
− | + | $doShow = $vgPage->Arg('show'); | |
− | + | return $this->Value('CatKey').':'.$doShow; | |
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
} | } | ||
− | + | /*---- | |
− | + | RETURNS: object for Supplier's Topic | |
− | public function | + | HISTORY: |
− | + | 2011-10-01 written -- replacing Departments with Topics | |
+ | */ | ||
+ | public function TopicObj() { | ||
+ | $id = $this->Value('ID_Topic'); | ||
+ | if (is_null($id)) { | ||
+ | return NULL; | ||
+ | } else { | ||
+ | $row = $this->Engine()->Topics($id); | ||
+ | return $row; | ||
+ | } | ||
} | } | ||
− | public function | + | /*---- |
− | + | RETURNS: nicely-formatted link to Supplier's Topic | |
− | + | HISTORY: | |
− | $ | + | 2011-10-01 written -- replacing Departments with Topics |
+ | */ | ||
+ | public function TopicLink($iNone='<i>n/a</i>') { | ||
+ | $row = $this->TopicObj(); | ||
+ | if (is_object($row)) { | ||
+ | return $row->AdminLink_name(); | ||
} else { | } else { | ||
− | $ | + | return $iNone; |
} | } | ||
− | |||
} | } | ||
− | public function | + | /*---- |
− | global $wgOut; | + | */ |
+ | public function AdminPage() { | ||
+ | global $wgOut,$wgRequest; | ||
+ | global $vgPage,$vgOut; | ||
+ | |||
+ | $vgPage->UseHTML(); | ||
+ | $out = NULL; | ||
+ | |||
+ | $doEdit = $vgPage->Arg('edit'); | ||
+ | $doSave = $wgRequest->GetBool('btnSave'); | ||
+ | |||
+ | // save edits before showing events | ||
+ | $ftSaveStatus = NULL; | ||
+ | if ($doEdit || $doSave) { | ||
+ | $this->BuildEditForm(); | ||
+ | if ($doSave) { | ||
+ | $ftSaveStatus = $this->AdminSave(); | ||
+ | } | ||
+ | } | ||
+ | |||
+ | $strCatKey = $this->CatKey; | ||
+ | $strName = $this->Name; | ||
+ | |||
+ | $doDeptAdd = $vgPage->Arg('add.dept'); | ||
+ | |||
+ | $objPage = new clsWikiFormatter($vgPage); | ||
+ | $objSection = new clsWikiSection($objPage,$strName.' ('.$strCatKey.')'); | ||
+ | $out = $objSection->Generate(); | ||
+ | $wgOut->AddHTML($out); $out = ''; | ||
+ | |||
+ | $objSection = new clsWikiSection($objPage,'Current Record (ID '.$this->ID.')',NULL,3); | ||
+ | $objSection->ToggleAdd('edit'); | ||
+ | $out = $objSection->Generate(); | ||
+ | |||
+ | if ($doEdit) { | ||
+ | $out .= $objSection->FormOpen(); | ||
+ | |||
+ | $objForm = $this->objForm; | ||
+ | $ftName = $objForm->Render('Name'); | ||
+ | $ftCatKey = $objForm->Render('CatKey'); | ||
+ | $ftTopic = $objForm->Render('ID_Topic'); | ||
+ | $ftActive = $objForm->Render('isActive'); | ||
+ | } else { | ||
+ | $ftName = $vgOut->InternalLink($strName); | ||
+ | $ftCatKey = $this->ShopLink($strCatKey); | ||
+ | $ftTopic = $this->TopicLink(); | ||
+ | $ftActive = NoYes($this->isActive); | ||
+ | } | ||
+ | |||
+ | $ftID = $this->AdminLink(); | ||
+ | |||
+ | $out .= $vgOut->TableOpen(); | ||
+ | |||
+ | $out .= $vgOut->TblRowOpen(); | ||
+ | $out .= $vgOut->TblCell('<b>ID</b>:','align=right'); | ||
+ | $out .= $vgOut->TblCell($ftID); | ||
+ | $out .= $vgOut->TblRowShut(); | ||
+ | |||
+ | $out .= $vgOut->TblRowOpen(); | ||
+ | $out .= $vgOut->TblCell('<b>Name</b>:','align=right'); | ||
+ | $out .= $vgOut->TblCell($ftName); | ||
+ | $out .= $vgOut->TblRowShut(); | ||
+ | |||
+ | $out .= $vgOut->TblRowOpen(); | ||
+ | $out .= $vgOut->TblCell('<b>CatKey</b>:','align=right'); | ||
+ | $out .= $vgOut->TblCell($ftCatKey); | ||
+ | $out .= $vgOut->TblRowShut(); | ||
+ | |||
+ | $out .= $vgOut->TblRowOpen(); | ||
+ | $out .= $vgOut->TblCell('<b>Topic</b>:','align=right'); | ||
+ | $out .= $vgOut->TblCell($ftTopic); | ||
+ | $out .= $vgOut->TblRowShut(); | ||
+ | |||
+ | $out .= $vgOut->TblRowOpen(); | ||
+ | $out .= $vgOut->TblCell('<b>Active</b>:','align=right'); | ||
+ | $out .= $vgOut->TblCell($ftActive); | ||
+ | $out .= $vgOut->TblRowShut(); | ||
+ | |||
+ | $out .= $vgOut->TableShut(); | ||
− | $out = '== | + | if ($doEdit) { |
− | + | $out .= '<b>Edit notes</b>: <input type=text name="EvNotes" size=40><br>'; | |
− | + | $out .= '<input type=submit name="btnSave" value="Save">'; | |
− | $out .= | + | $out .= '<input type=submit name="btnCancel" value="Cancel">'; |
+ | $out .= '<input type=reset value="Reset">'; | ||
+ | $out .= '</form>'; | ||
} | } | ||
− | + | ||
− | $out .= | + | $vgOut->addText($out,TRUE); $out = ''; |
+ | |||
+ | // show submenu | ||
+ | $arMnu = array( | ||
+ | 'dept' => '.departments.'.$strName.' departments', | ||
+ | 'cat' => '.catalogs.'.$strName.' wholesale catalogs', | ||
+ | 'rreq' => '.restocks.'.$strName.' restock requests', | ||
+ | 'ctg' => '.catalog groups.groups for organizing '.$strName.' catalog items' | ||
+ | ); | ||
+ | $out = '<b>Manage</b>: '.$vgPage->SelfLinkMenu('show',$arMnu); | ||
+ | $vgOut->AddText($out); $out = ''; | ||
+ | |||
+ | $doShow = $vgPage->Arg('show'); | ||
+ | |||
+ | //$vgPage->UseWiki(); | ||
+ | switch ($doShow) { | ||
+ | /* Some remediation needed here. Some of these output in wikitext, others in HTML. | ||
+ | All of them seem to output directly, rather than returning rendered text. | ||
+ | */ | ||
+ | case 'dept': | ||
+ | $objSection = new clsWikiSection($objPage,'Departments',NULL,3); | ||
+ | $objSection->ToggleAdd('add','add a department to '.$strName,'add.dept'); | ||
+ | $out = $objSection->Generate(); | ||
+ | $wgOut->addHTML($out,TRUE); $out = ''; | ||
+ | $out .= $this->DeptsListing(); | ||
+ | break; | ||
+ | case 'cat': | ||
+ | $objSection = new clsWikiSection($objPage,'Catalogs',NULL,3); | ||
+ | $arLink = array( | ||
+ | 'page' => $this->objDB->CtgSrcs()->ActionKey(), | ||
+ | 'id' => 'new', | ||
+ | 'supp' => $this->ID | ||
+ | ); | ||
+ | $objSection->ActionAdd('add','add a catalog to '.$strName,FALSE,$arLink); | ||
+ | $out = $objSection->Generate(); | ||
+ | $wgOut->addHTML($out,TRUE); $out = ''; | ||
+ | $out .= $this->CatalogAdmin(); | ||
+ | break; | ||
+ | case 'rreq': | ||
+ | $objSection = new clsWikiSection($objPage,'Restock Requests',NULL,3); | ||
+ | $out = $objSection->Generate(); | ||
+ | $wgOut->addHTML($out,TRUE); $out = ''; | ||
+ | $out .= $this->RstkReqAdmin(); | ||
+ | break; | ||
+ | case 'ctg': | ||
+ | $objSection = new clsWikiSection($objPage,'Catalog Groups','catalog management groups',3); | ||
+ | $objSection->ArgsToKeep(array('show','page','id')); | ||
+ | $objSection->ToggleAdd('edit','edit the list of groups','edit.ctg'); | ||
+ | $out = $objSection->Generate(); | ||
+ | $wgOut->addHTML($out,TRUE); $out = ''; | ||
+ | $doEdit = $vgPage->Arg('edit.ctg'); | ||
+ | $out .= $this->CtgGrpAdmin($doEdit); | ||
+ | break; | ||
+ | default: | ||
+ | $out = ''; | ||
} | } | ||
− | $ | + | $vgOut->addText($out); |
− | + | } | |
− | + | /*---- | |
− | + | ACTION: Save user changes to the record | |
− | $ | + | HISTORY: |
− | $out | + | 2010-11-06 copied from VbzStockBin to VbzAdminItem |
− | $ | + | 2011-01-26 copied from VbzAdminItem to clsAdminTopic |
+ | 2011-10-02 copied from clsAdminTopic to VbzAdminSupplier | ||
+ | */ | ||
+ | public function AdminSave() { | ||
+ | global $vgOut; | ||
+ | |||
+ | $out = $this->objForm->Save(); | ||
+ | $vgOut->AddText($out); | ||
} | } | ||
− | + | /*---- | |
− | + | HISTORY: | |
+ | 2010-11-06 adapted from VbzStockBin for VbzAdminTitle | ||
+ | 2011-10-01 adapted from VbzAdminTitle for VbzAdminSupplier | ||
+ | */ | ||
+ | private function BuildEditForm() { | ||
+ | global $vgOut; | ||
+ | |||
+ | if (is_null($this->objForm)) { | ||
+ | // create fields & controls | ||
+ | $objForm = new clsForm_DataSet($this,$vgOut); | ||
+ | //$objCtrls = new clsCtrls($objForm->Fields()); | ||
+ | //$objCtrls = $objForm; | ||
+ | |||
+ | $objForm->AddField(new clsField('Name'), new clsCtrlHTML(array('size'=>25))); | ||
+ | $objForm->AddField(new clsFieldNum('ID_Topic'), new clsCtrlHTML()); | ||
+ | $objForm->AddField(new clsField('CatKey'), new clsCtrlHTML(array('size'=>8))); | ||
+ | $objForm->AddField(new clsFieldBool('isActive'), new clsCtrlHTML_CheckBox()); | ||
+ | $objForm->AddField(new clsField('Notes'), new clsCtrlHTML_TextArea(array('height'=>3,'width'=>50))); | ||
+ | |||
+ | $this->objForm = $objForm; | ||
+ | //$this->objCtrls = $objCtrls; | ||
+ | } | ||
} | } | ||
− | public function | + | public function DeptsListing() { |
− | $ | + | $out = $this->objDB->Depts()->Listing_forSupp($this->ID,$this); |
− | |||
return $out; | return $out; | ||
} | } | ||
− | + | /*%%%% | |
− | $ | + | SECTION: Data Entry Management |
− | + | PROCESS: | |
+ | * User enters a list of Titles or Items in a textarea box, one per line. | ||
+ | * Each line is checked against Supplier catalog #s | ||
+ | * if found, shows details for the title/item and provides option to approve it in the final resultset | ||
+ | * if not found, gives user the option to give more information identifying the Title/Item, such as | ||
+ | our catalog # (or what our catalog # would be if the Title/Item existed in the database) | ||
+ | */ | ||
+ | /*---- | ||
+ | PURPOSE: renders form for reconciliation of a user-entered list of Titles from a Supplier source document | ||
+ | INPUT: | ||
+ | $iTitles[line #] = array of title information, format to be determined | ||
+ | ['id'] = ID of Title record to be approved as matching the input | ||
+ | ['scat'] = supplier's catalog number | ||
+ | ['ocat'] = our catalog number (may be hypothetical) | ||
+ | ['$buy'] = cost to us | ||
+ | ['$sell'] = our selling price (to customer) | ||
+ | ['name'] = descriptive name for the Title | ||
+ | RETURNS: HTML code for reconciliation form. Does not include <form> tags or buttons. | ||
+ | */ | ||
/* | /* | ||
− | $ | + | public function AdminTitles_form_entry(array $iTitles) { |
− | + | die('This function is not ready yet!'); | |
− | + | ||
− | + | if (count($iTitles) > 0) { | |
− | $ | + | $isOdd = TRUE; |
− | $out .= " | + | $isReady = TRUE; // ready to enter - all items have been identified |
+ | $out .= '<table><tr><th>ID</th><th>Cat#</th><th>Title</th><th>Qty</th><th>Price</th></tr>'; | ||
+ | foreach ($iTitles as $cnt => $data) { | ||
+ | $ftStyle = $isOdd?'background:#ffffff;':'background:#eeeeee;'; | ||
+ | $htAttr = ' style="'.$ftStyle.'"'; | ||
+ | $isOdd = !$isOdd; | ||
+ | |||
+ | $strScat = nz($data['scat']); | ||
+ | $strInvTitle = nz($data['title']); | ||
+ | $strPrBuy = nz($data['$buy']); | ||
+ | $strPrSell = nz($data['$sell']); | ||
+ | $strQty = nz($arOut['qty']); | ||
+ | $out .= "<tr$htAttr><td></td><td>$strScat</td><td>$strInvTitle</td><td align=center>$strQty</td><td align=right>$strPrice</td></tr>"; | ||
+ | |||
} | } | ||
− | |||
} else { | } else { | ||
− | $out = ' | + | $out = 'No titles entered.'; |
} | } | ||
+ | } | ||
*/ | */ | ||
− | + | /*---- | |
− | + | PURPOSE: renders form for reconciliation of a user-entered list of Items from a Supplier source document | |
− | + | (same as AdminTitles_form_entry() but for Items instead of Titles) | |
− | + | ACTION: Renders an Item-reconciliation form | |
− | public function | + | INPUT: output from AdminItems_data_check() |
− | + | OUTPUT: returned data | |
− | + | RETURNS: HTML of form containing data AdminItems_form_receive() is expecting to see | |
− | + | */ | |
− | + | public function AdminItems_form_entry(array $iData) { | |
− | + | $cntItems = count($iData); | |
− | + | ||
− | + | if ($cntItems > 0) { | |
+ | $strPfx = $this->Value('CatKey'); | ||
+ | $isOdd = TRUE; | ||
+ | $out = '<table><tr>' | ||
+ | .'<th></th>' | ||
+ | .'<th>status</th>' | ||
+ | .'<th>ID</th>' | ||
+ | .'<th>Our Cat#</th>' | ||
+ | .'<th>SCat#</th>' | ||
+ | .'<th>What</th>' | ||
+ | .'<th>Qty</th>' | ||
+ | .'<th>$buy</th>' | ||
+ | .'<th>$sell</th>' | ||
+ | .'</tr>'; | ||
+ | foreach ($iData as $idx => $row) { | ||
+ | $ftStyle = $isOdd?'background:#ffffff;':'background:#eeeeee;'; | ||
+ | $htAttr = ' style="'.$ftStyle.'"'; | ||
+ | $isOdd = !$isOdd; | ||
+ | |||
+ | $idItem = nz($row['id']); | ||
+ | $strOCat = nz($row['ocat']); | ||
+ | $strSCat = nz($row['scat']); | ||
+ | $strInvTitle = nz($row['name']); | ||
+ | $strPrBuy = nz($row['$buy']); | ||
+ | $strPrSell = nz($row['$sell']); | ||
+ | $strQty = nz($row['qty']); | ||
+ | $objItem = $row['@obj']; | ||
+ | |||
+ | $htOCat = $strOCat; | ||
+ | $htItem = NULL; | ||
+ | |||
+ | $cnOCat = "ocat[$idx]"; | ||
+ | |||
+ | $canUpdSCat = FALSE; | ||
+ | $canUpdDescr = FALSE; | ||
+ | |||
+ | if (is_null($objItem)) { | ||
+ | //$cntNoItem++; | ||
+ | if (!empty($strOCat)) { | ||
+ | $arOkAdd[$idx] = $data; | ||
+ | } | ||
+ | // let user enter our catalog # | ||
+ | $htOCat = $strPfx.'-<input name="'.$cnOCat.'" size=15 value="'.htmlspecialchars($strOCat).'">'; | ||
+ | } else { | ||
+ | $data['obj'] = $objItem; | ||
+ | $arOkFnd[$idx] = $data; | ||
+ | $strOCat = $objItem->Value('CatNum'); | ||
+ | $idItem = $objItem->KeyValue(); | ||
+ | |||
+ | $htOCat = $strOCat.'<input type=hidden name="'.$cnOCat.'" value="'.htmlspecialchars($strOCat).'">'; | ||
+ | $htItem = $objItem->AdminLink().'<input type=hidden name="id['.$idx.']" value="'.$idItem.'">'; | ||
+ | $htOCat = $strOCat; | ||
+ | |||
+ | // compare entered values with recorded values | ||
+ | // -- supplier catalog # | ||
+ | $strSCatEnt = $strSCat; // entered | ||
+ | $strSCatRec = $objItem->Supp_CatNum; // recorded | ||
+ | if ($strSCatEnt != $strSCatRec) { | ||
+ | $canUpdSCat = TRUE; | ||
+ | } | ||
+ | // -- title | ||
+ | $strDescrEnt = $strInvTitle; // entered | ||
+ | $strDescrRec = $objItem->Descr; // recorded | ||
+ | if ($strDescrEnt != $strDescrRec) { | ||
+ | $canUpdDescr = TRUE; | ||
+ | } | ||
+ | } | ||
− | + | $htSCat = $strSCat.'<input type=hidden name="scat['.$idx.']" value="'.htmlspecialchars($strSCat).'">'; | |
− | + | if ($canUpdSCat) { | |
+ | if (empty($strSCatRec)) { | ||
+ | $strAct = 'save this'; | ||
+ | } else { | ||
+ | $strAct = 'replace <b>'.$strSCatRec.'</b>'; | ||
+ | } | ||
+ | $htSCat .= '<br><small><input type=checkbox name="do-upd-scat['.$idx.']">'.$strAct.'</small>'; | ||
+ | } | ||
+ | $htName = $strInvTitle.'<input type=hidden name="name['.$idx.']" value="'.htmlspecialchars($strInvTitle).'">'; | ||
+ | if ($canUpdDescr) { | ||
+ | if (empty($strDescrRec)) { | ||
+ | $strAct = 'save this'; | ||
+ | } else { | ||
+ | $strAct = 'replace <b>'.$strDescrRec.'</b>'; | ||
+ | } | ||
+ | $htName .= '<br><small><input type=checkbox name="do-upd-desc['.$idx.']">'.$strAct.'</small>'; | ||
+ | } | ||
− | + | $htQty = $strQty.'<input type=hidden name="qty['.$idx.']" value='.$strQty.'>'; | |
− | + | ||
− | + | $htPrBuy = $strPrBuy.'<input type=hidden name="$buy['.$idx.']" value="'.$strPrBuy.'">'; | |
− | + | $htPrSell = $strPrSell.'<input type=hidden name="$sell['.$idx.']" value="'.$strPrSell.'">'; | |
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | + | switch ($row['@state']) { | |
− | + | case 'use': | |
− | + | $htStatus = '<span style="color: #008800"><b>ready</b></span>'; | |
− | + | break; | |
− | + | case 'add': | |
+ | $htStatus = '<span style="color: #000088" title="there is enough info to add this item">addable</span>'; | ||
+ | break; | ||
+ | default: | ||
+ | $htStatus = '<span color=red title="need more information">?</span>'; | ||
+ | } | ||
− | + | $out .= "\n<tr$htAttr>" | |
− | + | ."\n\t<td>$idx.</td>" | |
− | + | ."\n\t<td>$htStatus</td>" | |
− | + | ."\n\t<td>$htItem</td>" | |
− | + | ."\n\t<td>$htOCat</td>" | |
− | + | ."\n\t<td>$htSCat</td>" | |
− | + | ."\n\t<td>$htName</td>" | |
− | + | ."\n\t<td align=center>$htQty</td>" | |
− | + | ."\n\t<td align=right>$htPrBuy</td>" | |
− | + | ."\n\t<td align=right>$htPrSell</td>" | |
− | + | ."\n\t</tr>"; | |
− | |||
− | |||
− | |||
− | |||
− | |||
− | $ | ||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | / | ||
} | } | ||
+ | $out .= '</table>'; | ||
+ | } else { | ||
+ | $out = 'No titles entered.'; | ||
} | } | ||
return $out; | return $out; | ||
} | } | ||
− | + | /*---- | |
− | + | ACTION: Receives user data from form rendered by AdminItems_form_entry() | |
− | public function | + | INPUT: http POST data from Item reconciliation form |
− | $ | + | id[line #] = array of Item IDs, where known |
− | $ | + | name[line #] = array of item descriptions |
− | return $ | + | qty[line #] = array of item quantities |
+ | scat[line #] = array of supplier catalog numbers for each line, entered by user | ||
+ | ocat[line #] = array of our catalog numbers for each line, entered by user | ||
+ | $buy[line #] = array of price-to-us for each line, entered by user | ||
+ | $sell[line #] = array of price-to-customer for each line, entered by user | ||
+ | NOTE: sell[] is not currently used in any known scenario. Possibly it should be removed. | ||
+ | RETURNS: array of all received data, but indexed by line number first | ||
+ | includes the following fields: | ||
+ | ['qty'] = item quantity | ||
+ | ['ocat'] = catalog number entered by the user | ||
+ | to be used either for looking up the item or creating it | ||
+ | FUTURE: This should be generalized somehow | ||
+ | */ | ||
+ | public function AdminItems_form_receive() { | ||
+ | global $wgRequest; | ||
+ | |||
+ | $arCols = array('id','name','qty','ocat','scat','$buy','$sell','do-upd-scat','do-upd-desc'); | ||
+ | foreach ($arCols as $col) { | ||
+ | $arOut[$col] = $wgRequest->GetArray($col); | ||
+ | } | ||
+ | $arRtn = ArrayPivot($arOut); | ||
+ | //echo '<pre>'.print_r($arRtn,TRUE).'</pre>'; | ||
+ | return $arRtn; | ||
} | } | ||
− | public function | + | /*---- |
− | + | ACTION: Check item data against database and return status information | |
− | + | INPUT: | |
− | + | $iItems[line #]: array in format returned by AdminItems_form_receive() | |
− | + | RETURNS: | |
+ | ['#add'] = number of rows which need to be added to the catalog | ||
+ | ['#use'] = number of rows which are ready to be used (item exists in catalog) | ||
+ | ['rows'] = input data with additional fields: | ||
+ | ['@state']: status of line as indicated by one of the following strings: | ||
+ | 'use' = item has been found, so this line is ready to use | ||
+ | 'add' = item not found, but there is enough information to create it | ||
+ | ['@obj'] is the Item object (only included if @state = 'use') | ||
+ | */ | ||
+ | public function AdminItems_data_check(array $iItems) { | ||
+ | if (count($iItems) > 0) { | ||
+ | $cntUse = 0; | ||
+ | $cntAdd = 0; | ||
+ | $cntUpd = 0; // count of updatable fields | ||
+ | $arRows = array(); | ||
+ | $strCatPfx = $this->Value('CatKey'); | ||
+ | foreach ($iItems as $idx => $data) { | ||
+ | $idItem = nz($data['id']); | ||
+ | |||
+ | $strOCatRaw = nz($data['ocat']); | ||
+ | $strOCatFull = $strCatPfx.'-'.$strOCatRaw; | ||
+ | $gotOCat = !empty($strOCatRaw); | ||
+ | |||
+ | $strSCat = nz($data['scat']); | ||
+ | |||
+ | $data['@state'] = NULL; | ||
+ | $data['@obj'] = NULL; | ||
+ | if (empty($idItem)) { | ||
+ | if ($gotOCat) { | ||
+ | // look up item using our catalog # | ||
+ | $objItem = $this->objDB->Items()->Get_byCatNum($strOCatFull); | ||
+ | } else { | ||
+ | // look up item using supplier catalog # | ||
+ | $objItem = $this->GetItem_bySCatNum($strSCat); | ||
+ | } | ||
+ | if (is_null($objItem)) { | ||
+ | if ($gotOCat) { | ||
+ | $data['@state'] = 'add'; | ||
+ | $cntAdd++; | ||
+ | } | ||
+ | } | ||
+ | } else { | ||
+ | $objItem = $this->objDB->Items($idItem); | ||
+ | } | ||
+ | if (is_object($objItem)) { | ||
+ | $data['@obj'] = $objItem; | ||
+ | $data['@state'] = 'use'; | ||
+ | $cntUse++; | ||
− | + | // compare entered values with recorded values | |
− | + | // -- supplier catalog # | |
− | + | $strSCatEnt = $strSCat; // entered | |
− | + | $strSCatRec = $objItem->Supp_CatNum; // recorded | |
− | + | if ($strSCatEnt != $strSCatRec) { | |
− | + | $cntUpd++; | |
− | + | $data['@can-upd-scat'] = TRUE; | |
− | + | } else { | |
− | $ | + | $data['@can-upd-scat'] = FALSE; |
+ | } | ||
+ | // -- title | ||
+ | $strDescrEnt = nz($data['name']); // entered | ||
+ | $strDescrRec = $objItem->Descr; // recorded | ||
+ | if ($strDescrEnt != $strDescrRec) { | ||
+ | $cntUpd++; | ||
+ | $data['@can-upd-desc'] = TRUE; | ||
+ | } else { | ||
+ | $data['@can-upd-desc'] = FALSE; | ||
+ | } | ||
+ | } | ||
+ | $arRows[$idx] = $data; | ||
+ | } // foreach ($iItems...) | ||
+ | } else { | ||
+ | $arRtn = NULL; | ||
} | } | ||
− | $ | + | $arRtn = array( |
− | + | 'rows' => $arRows, | |
− | + | '#use' => $cntUse, | |
− | $ | + | '#upd' => $cntUpd, |
+ | '#add' => $cntAdd); | ||
+ | return $arRtn; | ||
} | } | ||
− | public function | + | /*---- |
− | $ | + | ACTION: Creates listed catalog items |
− | + | INPUT: Array of items as returned by AdminItems_data_check() | |
− | $ | + | RETURNS: HTML to display (messages) |
− | + | */ | |
− | + | public function AdminItems_data_add(array $iItems) { | |
− | + | $out = ''; | |
− | + | ||
− | + | $tblItems = $this->objDB->Items(); | |
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | + | $cntItems = count($iItems); | |
− | + | $txtOCats = ''; | |
+ | foreach ($iItems as $idx => $row) { | ||
+ | $txtOCats .= ' '.$row['ocat']; | ||
+ | } | ||
+ | $strEv = 'Adding '.$cntItems.' item'.Pluralize($cntItems).':'.$txtOCats; | ||
− | + | $arEv = array( | |
− | + | 'descr' => SQLValue($strEv), | |
− | + | 'where' => SQLValue(__METHOD__), | |
− | + | 'code' => SQLValue('RI+') // Reconcile Items: add | |
− | + | ); | |
+ | $this->StartEvent($arEv); | ||
− | + | $strCatPfx = $this->Value('CatKey'); | |
− | + | foreach ($iItems as $idx => $row) { | |
− | + | $strOCat = $strCatPfx.'-'.strtoupper($row['ocat']); | |
− | + | $arAdd = array( | |
− | + | 'CatNum' => SQLValue($strOCat), | |
− | + | 'isCurrent' => 'FALSE', // we don't actually know anything about availability yet | |
− | + | 'ID_Title' => 0, // needs to be assigned to a title | |
− | + | 'Descr' => SQLValue($row['name']), | |
− | + | 'Supp_CatNum' => SQLValue($row['scat']) | |
− | + | ); | |
− | + | if (!empty($row['$buy'])) { | |
− | $ | + | $arAdd['PriceBuy'] = SQLValue($row['$buy']); |
− | |||
− | |||
− | |||
} | } | ||
+ | if (!empty($row['$sell'])) { | ||
+ | $arAdd['PriceSell'] = SQLValue($row['$sell']); | ||
+ | } | ||
+ | //$out .= '<pre>'.print_r($arAdd,TRUE).'</pre>'; | ||
+ | $tblItems->Insert($arAdd); | ||
} | } | ||
+ | $out = $strEv; | ||
+ | $this->FinishEvent(); | ||
return $out; | return $out; | ||
} | } | ||
− | + | /*---- | |
+ | ACTION: Renders drop-down box of all Suppliers, with the current one as default | ||
+ | USED BY: Restock edit screen | ||
+ | HISTORY: | ||
+ | 2011-03-02 What happened? Apparently this method used to exist, but got deleted without a trace. | ||
+ | Rewriting from scratch. | ||
+ | */ | ||
+ | public function DropDown($iName=NULL,$iNone=NULL) { | ||
+ | $strName = is_null($iName)?($this->Table->ActionKey()):$iName; // control name defaults to action key | ||
− | + | $rs = $this->Table->GetData(); | |
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | $ | + | if ($rs->HasRows()) { |
− | + | $out = "\n<SELECT NAME=$strName>"; | |
− | + | if (!is_null($iNone)) { | |
− | + | $out .= DropDown_row(NULL,$iNone,$iDefault); | |
− | + | } | |
− | + | while ($rs->NextRow()) { | |
− | while ($ | + | $id = $rs->Value('ID'); |
− | $ | + | $txtAbbr = $rs->Value('CatKey'); |
− | $ | + | $htAbbr = is_null($txtAbbr)?'':($txtAbbr.' '); |
− | + | $htShow = $htAbbr.$rs->Value('Name'); | |
− | + | $out .= DropDown_row($id,$htShow,$this->Value('ID')); | |
− | |||
− | |||
− | $ | ||
− | |||
− | $ | ||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | $out .= | ||
− | |||
} | } | ||
− | $out .= "\n | + | $out .= "\n</select>"; |
+ | return $out; | ||
} else { | } else { | ||
− | + | return NULL; | |
} | } | ||
− | |||
} | } | ||
− | } | + | /*---- |
− | + | ACTION: Renders drop-down box of active departments for this supplier | |
− | public function | + | RETURNS: HTML code |
− | + | */ | |
+ | public function Depts_DropDown($iName=NULL,$iDefault=NULL,$iNone=NULL) { | ||
+ | $objRecs = $this->objDB->Depts()->Data_forSupp($this->ID,'isActive'); | ||
+ | $out = $objRecs->DropDown($iName,$iDefault,$iNone); | ||
+ | return $out; | ||
+ | } | ||
+ | public function CatalogAdmin() { | ||
+ | $objTbl = $this->objDB->Catalogs(); | ||
+ | $objRows = $objTbl->GetData('ID_Supplier='.$this->ID,NULL,'ID DESC'); | ||
+ | $out = $objRows->AdminList(); | ||
+ | return $out; | ||
+ | } | ||
+ | public function RstkReqAdmin() { | ||
+ | $objTbl = $this->objDB->RstkReqs(); | ||
+ | $objRows = $objTbl->GetData('ID_Supplier='.$this->ID,NULL,'IFNULL(WhenOrdered,WhenCreated) DESC'); | ||
+ | $out = $objRows->AdminList(); | ||
+ | return $out; | ||
+ | } | ||
+ | public function CtgGrpAdmin($iEdit) { | ||
+ | $objTbl = $this->objDB->CtgGrps(); | ||
+ | $id = $this->KeyValue(); | ||
+ | $objRows = $objTbl->GetData('ID_Supplier='.$id,NULL,'Sort'); | ||
+ | $out = $objRows->AdminList($iEdit,array('ID_Supplier'=>$id)); | ||
+ | return $out; | ||
+ | } | ||
+ | /*----- | ||
+ | ACTION: Finds the last restock request for the given supplier | ||
+ | RETURNS: the last request by date and the last request sorted by (our) PO # | ||
+ | */ | ||
+ | public function LastReq() { | ||
+ | //$sqlBase = 'SELECT * FROM `rstk_req` WHERE ID_Supplier='.$this->ID; | ||
+ | $sqlBase = 'WHERE ID_Supplier='.$this->ID; | ||
+ | $sql = $sqlBase.' ORDER BY PurchOrdNum DESC LIMIT 1;'; | ||
+ | //$objRow = $this->objDB->DataSet($sql); | ||
+ | $objRow = $this->objDB->RstkReqs()->DataSet($sql); | ||
+ | $objRow->NextRow(); | ||
+ | $arOut['by purch ord'] = $objRow->RowCopy(); | ||
+ | |||
+ | $sql = $sqlBase.' ORDER BY WhenOrdered DESC LIMIT 1;'; | ||
+ | //$objRow = $this->objDB->DataSet($sql); | ||
+ | $objRow = $this->objDB->RstkReqs()->DataSet($sql); | ||
+ | $objRow->NextRow(); | ||
+ | $arOut['by ord date'] = $objRow->RowCopy(); | ||
− | $ | + | return $arOut; |
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
} | } | ||
− | public function | + | /*---- |
− | $ | + | ACTION: Checks each item in the list to see if it corresponds to a given item for the current supplier |
− | return $ | + | INPUT: Array of supplier catalog numbers |
+ | OUTPUT: Array in this format: | ||
+ | array[cat#] = item object (if found) or NULL (if not found) | ||
+ | */ | ||
+ | /* | ||
+ | public function FindItems(array $iList) { | ||
+ | $objTblItems = $this->objDB->Items(); | ||
+ | foreach ($iList as $catnum) { | ||
+ | $strCat = rtrim($catnum,';#!'); // remove comments | ||
+ | $strCat = trim($strCat); // remove leading & trailing whitespace | ||
+ | if (!empty($strCat)) { | ||
+ | $sqlFind = 'Supp_CatNum="'.$strCat.'"'; | ||
+ | $objItem = $objTblItems->GetData($sqlFind); | ||
+ | if (is_null($objItem)) { | ||
+ | $arOut[$strCat] = NULL; | ||
+ | } else { | ||
+ | $arOut[$strCat] = $objItem->RowCopy(); | ||
+ | } | ||
+ | } | ||
+ | } | ||
+ | return $arOut; | ||
} | } | ||
+ | */ | ||
+ | // DEPRECATED - use GetItem_bySCatNum() | ||
+ | public function FindItem($iCatNum) { return $this->GetItem_bySCatNum($iCatNum); } | ||
} | } | ||
Line 969: | Line 1,623: | ||
$this->ClassSng('VbzAdminDept'); | $this->ClassSng('VbzAdminDept'); | ||
} | } | ||
− | public function Listing_forSupp($iSuppID,$iSuppObj=NULL) { | + | public function Data_forSupp($iSupp,$iFilt=NULL) { |
+ | $sqlFilt = "ID_Supplier=$iSupp"; | ||
+ | if (!is_null($iFilt)) { | ||
+ | $sqlFilt = "($sqlFilt) AND ($iFilt)"; | ||
+ | } | ||
+ | $objRecs = $this->GetData($sqlFilt,NULL,'isActive, Sort, CatKey, PageKey'); | ||
+ | return $objRecs; | ||
+ | } | ||
+ | public function Listing_forSupp($iSuppID,clsSupplier $iSuppObj=NULL) { | ||
global $wgOut; | global $wgOut; | ||
Line 979: | Line 1,641: | ||
$strSuppKey = strtolower($objSupp->CatKey); | $strSuppKey = strtolower($objSupp->CatKey); | ||
− | $objRecs = $this->GetData('ID_Supplier='.$iSuppID,'VbzAdminDept','Sort'); | + | $objRecs = $this->GetData('ID_Supplier='.$iSuppID,'VbzAdminDept','isActive, Sort, CatKey, PageKey'); |
if ($objRecs->HasRows()) { | if ($objRecs->HasRows()) { | ||
$out = "{| class=sortable\n|-\n! ID || A? || Cat || Page || Sort || Name || Description"; | $out = "{| class=sortable\n|-\n! ID || A? || Cat || Page || Sort || Name || Description"; | ||
Line 989: | Line 1,651: | ||
} else { | } else { | ||
$strPagePath = $strSuppKey.'/'.strtolower($strPageCode); | $strPagePath = $strSuppKey.'/'.strtolower($strPageCode); | ||
− | $wtPageCode = '[ | + | $wtPageCode = '['.KWP_CAT.$strPagePath.' '.$strPageCode.']'; |
} | } | ||
$id = $objRecs->ID; | $id = $objRecs->ID; | ||
− | $wtID = | + | $wtID = SelfLink_Page('dept','id',$id,$id); |
$wtStyle = $isOdd?'background:#ffffff;':'background:#cccccc;'; | $wtStyle = $isOdd?'background:#ffffff;':'background:#cccccc;'; | ||
$isActive = $objRecs->isActive; | $isActive = $objRecs->isActive; | ||
Line 1,016: | Line 1,678: | ||
} | } | ||
class VbzAdminDept extends clsDept { | class VbzAdminDept extends clsDept { | ||
− | public function InfoPage() { | + | /*---- |
− | global $wgOut; | + | HISTORY: |
+ | 2010-10-11 Replaced existing code with call to static function | ||
+ | */ | ||
+ | public function AdminLink($iText=NULL,$iPopup=NULL,array $iarArgs=NULL) { | ||
+ | return clsAdminData::_AdminLink($this,$iText,$iPopup,$iarArgs); | ||
+ | } | ||
+ | public function AdminLink_name() { | ||
+ | $strPgKey = strtoupper($this->Value('PageKey')); | ||
+ | $out = (is_null($strPgKey))?'':($strPgKey.' '); | ||
+ | $out .= $this->Value('Name'); | ||
+ | return $this->AdminLink($out); | ||
+ | } | ||
+ | public function DropDown($iName=NULL,$iDefault=NULL,$iNone=NULL) { | ||
+ | $strName = is_null($iName)?($this->Table->ActionKey()):$iName; // control name defaults to action key | ||
+ | |||
+ | if ($this->HasRows()) { | ||
+ | $out = "\n<SELECT NAME=$strName>"; | ||
+ | if (!is_null($iNone)) { | ||
+ | $out .= DropDown_row(NULL,$iNone,$iDefault); | ||
+ | } | ||
+ | while ($this->NextRow()) { | ||
+ | $id = $this->ID; | ||
+ | $htAbbr = (is_null($this->PageKey))?'':($this->PageKey.' '); | ||
+ | $htShow = $htAbbr.$this->Name; | ||
+ | $out .= DropDown_row($id,$htShow,$iDefault); | ||
+ | } | ||
+ | $out .= "\n</select>"; | ||
+ | return $out; | ||
+ | } else { | ||
+ | return NULL; | ||
+ | } | ||
+ | } | ||
+ | /* 2010-11-06 commenting out old event handling | ||
+ | public function StartEvent($iWhere,$iCode,$iDescr,$iNotes=NULL) { | ||
+ | $arEvent = array( | ||
+ | 'type' => clsEvents::kTypeDept, | ||
+ | 'id' => $this->ID, | ||
+ | 'where' => $iWhere, | ||
+ | 'code' => $iCode, | ||
+ | 'descr' => $iDescr | ||
+ | ); | ||
+ | if (!is_null($iNotes)) { | ||
+ | $arEvent['notes'] = $iNotes; | ||
+ | } | ||
+ | $this->idEvent = $this->objDB->Events()->StartEvent($arEvent); | ||
+ | } | ||
+ | public function FinishEvent() { | ||
+ | $this->objDB->Events()->FinishEvent($this->idEvent); | ||
+ | } | ||
+ | */ | ||
+ | /*---- | ||
+ | HISTORY: | ||
+ | 2010-10-20 changing event logging to use helper class | ||
+ | 2010-11-07 added StartEvent(), FinishEvent() | ||
+ | */ | ||
+ | protected function Log() { | ||
+ | if (!is_object($this->logger)) { | ||
+ | $this->logger = new clsLogger_DataSet($this,$this->objDB->Events()); | ||
+ | } | ||
+ | return $this->logger; | ||
+ | } | ||
+ | public function StartEvent(array $iArgs) { | ||
+ | return $this->Log()->StartEvent($iArgs); | ||
+ | } | ||
+ | public function FinishEvent(array $iArgs=NULL) { | ||
+ | return $this->Log()->FinishEvent($iArgs); | ||
+ | } | ||
+ | public function EventListing() { | ||
+ | return $this->Log()->EventListing(); | ||
+ | /* | ||
+ | $objTbl = $this->objDB->Events(); | ||
+ | $objRows = $objTbl->GetData('(ModType="'.clsEvents::kTypeDept.'") AND (ModIndex='.$this->ID.')'); | ||
+ | if ($objRows->HasRows()) { | ||
+ | $out = $objRows->AdminRows(); | ||
+ | } else { | ||
+ | $out = 'No events found for this department.'; | ||
+ | } | ||
+ | return $out; | ||
+ | */ | ||
+ | } | ||
+ | /*---- | ||
+ | HISTORY: | ||
+ | 2011-09-25 renamed from InfoPage() to AdminPage() | ||
+ | */ | ||
+ | public function AdminPage() { | ||
+ | global $wgOut,$wgRequest; | ||
+ | global $vgPage; | ||
$strCatKey = $this->CatKey; | $strCatKey = $this->CatKey; | ||
$strPageKey = $this->PageKey; | $strPageKey = $this->PageKey; | ||
− | $out = '== | + | if (empty($strPageKey)) { |
+ | $strShopKey = strtolower($strCatKey); | ||
+ | } else { | ||
+ | $strShopKey = strtolower($strPageKey); | ||
+ | } | ||
+ | $strAction = $vgPage->Arg('do'); | ||
+ | $doEdit = ($strAction == 'edit'); | ||
+ | $doEnter = ($strAction == 'enter'); | ||
+ | |||
+ | $doTitleCheck = $wgRequest->GetBool('btnCheck'); | ||
+ | $doTitleAdd = $wgRequest->GetBool('btnAdd'); | ||
+ | $doEnterBox = $doEnter || $doTitleCheck || $doTitleAdd; | ||
+ | |||
+ | $strTitle = '“'.$this->Name.'” Department'; | ||
+ | |||
+ | $vgPage->UseHTML(); | ||
+ | $objPage = new clsWikiFormatter($vgPage); | ||
+ | //$objSection = new clsWikiAdminSection($strName); | ||
+ | $objSection = new clsWikiSection($objPage,$strTitle); | ||
+ | //$out = $objSection->HeaderHtml_Edit(); | ||
+ | $objSection->ActionAdd('edit'); | ||
+ | $objSection->ActionAdd('enter','enter titles for this department'); | ||
+ | $out = $objSection->Generate(); | ||
+ | |||
+ | $wgOut->AddHTML($out); $out = ''; | ||
+ | |||
+ | if ($doEnterBox) { | ||
+ | $out = '<table align=right><tr><td><h3>Enter Titles</h3>'; | ||
+ | $doShowForm = $doEnter || $doTitleCheck; | ||
+ | if ($doShowForm) { | ||
+ | $out .= $objSection->FormOpen(); | ||
+ | } | ||
+ | $txtNotes = $wgRequest->GetText('notes'); | ||
+ | $htNotes = 'Notes: <input type=text name=notes size=25 value="'.htmlspecialchars($txtNotes).'">'; | ||
+ | if ($doEnter) { | ||
+ | // STAGE 1: display form for entering titles | ||
+ | $out .= 'Enter titles to check:<br>'; | ||
+ | $out .= '<textarea name=titles cols=5 rows=30></textarea>'; | ||
+ | $out .= '<br>'.$htNotes; | ||
+ | $out .= '<br><input type=submit name="btnCheck" value="Check">'; | ||
+ | } elseif ($doTitleCheck) { | ||
+ | // STAGE 2: check entered titles, allow user to fix problems & confirm | ||
+ | $strTitles = $wgRequest->getText('titles'); | ||
+ | //$arTitles = $this->ParseSubmittedTitles($strTitles); | ||
+ | $arTitles = ParseTextLines($strTitles); | ||
+ | if (is_array($arTitles)) { | ||
+ | $doDeptOnly = $this->AffectsCatNum(); | ||
+ | $out .= '<table>'; | ||
+ | foreach ($arTitles as $strCatKey=>$strName) { | ||
+ | $sqlFilt = ''; | ||
+ | if ($doDeptOnly) { | ||
+ | $sqlFilt = '(ID_Dept='.$this->ID.') AND '; | ||
+ | } | ||
+ | $sqlFilt .= 'CatKey='.SQLValue($strCatKey); | ||
+ | $objTitles = $this->objDB->Titles()->GetData($sqlFilt); | ||
+ | if ($objTitles->HasRows()) { | ||
+ | $htStatus = ''; | ||
+ | $htMatches = ''; | ||
+ | while ($objTitles->NextRow()) { | ||
+ | $htTitle = $objTitles->AdminLink($objTitles->CatNum()).': '.$objTitles->Name; | ||
+ | $htMatches .= '<tr><td></td><td><small>'.$htTitle.'</td></tr>'; | ||
+ | } | ||
+ | } else { | ||
+ | $htStatus = '<td><font size=-2 color=green>new</font></td>'; | ||
+ | $htMatches = ''; | ||
+ | } | ||
+ | $out .= '<tr><td>'.$strCatKey.'</td><td>'.$strName.'</td>'.$htStatus.'</tr>'; | ||
+ | $out .= $htMatches; | ||
+ | } | ||
+ | $out .= '</table>'; | ||
+ | } | ||
+ | $out .= $htNotes.'<br>'; | ||
+ | $out .= '<input type=hidden name="titles" value="'.htmlspecialchars($strTitles).'">'; | ||
+ | $out .= '<input type=submit name="btnAdd" value="Add Titles">'; | ||
+ | } else { | ||
+ | // STAGE 3; process entered titles -- add them to the data: | ||
+ | $strTitles = $wgRequest->getText('titles'); | ||
+ | $arTitles = $this->ParseSubmittedTitles($strTitles); | ||
+ | $cntTitles = count($arTitles); | ||
+ | $strAddText = 'Add '.$cntTitles.' title'.Pluralize($cntTitles); | ||
+ | $this->StartEvent(__METHOD__,'ADD',$strAddText,$txtNotes); | ||
+ | $out .= '<table>'; | ||
+ | $objTitles = $this->objDB->Titles(); | ||
+ | foreach ($arTitles as $strCatKey=>$strName) { | ||
+ | $idTitle = $objTitles->Add($strCatKey,$strName,$this->ID,$txtNotes); | ||
+ | $objTitle = $this->objDB->Titles()->GetItem($idTitle); | ||
+ | $out .= '<tr><td>'.$objTitle->AdminLink($objTitle->CatNum()).'</td><td>'.$objTitle->Name.'</td></tr>'; | ||
+ | } | ||
+ | $out .= '</table>'; | ||
+ | $this->FinishEvent(); | ||
+ | } | ||
+ | if ($doShowForm) { | ||
+ | $out .= '<input type=submit name="btnCancel" value="Cancel">'; | ||
+ | $out .= '<input type=reset value="Reset">'; | ||
+ | $out .= '</form>'; | ||
+ | } | ||
+ | $out .= '</td></tr></table>'; | ||
+ | $wgOut->AddHTML($out); $out = ''; | ||
+ | } | ||
+ | |||
+ | if ($doEdit) { | ||
+ | $out .= $objSection->FormOpen(); | ||
+ | } else { | ||
+ | } | ||
+ | |||
+ | $vgPage->UseWiki(); | ||
$out .= "\n* '''ID''': ".$this->ID; | $out .= "\n* '''ID''': ".$this->ID; | ||
− | $out .= "\n* ''' | + | $out .= "\n* '''Supplier''': ".$this->SuppObj()->AdminLink_name(); |
− | $out .= "\n* ''' | + | $out .= "\n* '''CatKey''': $strCatKey"; |
− | $out .= "\n* ''' | + | $out .= "\n* '''PageKey''': $strPageKey"; |
+ | $out .= "\n* '''Shop''': [".$this->URL_Abs().' '.$this->URL_Rel().']'; | ||
$out .= "\n===Titles==="; | $out .= "\n===Titles==="; | ||
$wgOut->addWikiText($out,TRUE); $out = ''; | $wgOut->addWikiText($out,TRUE); $out = ''; | ||
$out = $this->TitleListing(); | $out = $this->TitleListing(); | ||
$wgOut->addWikiText($out,TRUE); $out = ''; | $wgOut->addWikiText($out,TRUE); $out = ''; | ||
+ | |||
+ | if ($doEdit) { | ||
+ | $out .= '<input type=submit name="btnSave" value="Save">'; | ||
+ | $out .= '<input type=submit name="btnCancel" value="Cancel">'; | ||
+ | $out .= '<input type=reset value="Reset">'; | ||
+ | $out .= '</form>'; | ||
+ | } | ||
+ | $wgOut->AddHTML($out); $out = ''; | ||
+ | $wgOut->addWikiText('===Events===',TRUE); | ||
+ | $out = $this->EventListing(); | ||
+ | $wgOut->addWikiText($out,TRUE); | ||
} | } | ||
public function TitleListing() { | public function TitleListing() { | ||
− | $out = $this->objDB-> | + | $out = $this->objDB->Titles_Item()->Listing_forDept($this); |
return $out; | return $out; | ||
+ | } | ||
+ | /*---- | ||
+ | ACTION: Add a list of titles to this department | ||
+ | INPUT: | ||
+ | iTitles: array | ||
+ | iTitles[catkey] = name | ||
+ | iEvent: array to be passed to event log | ||
+ | */ | ||
+ | public function AddTitles(array $iTitles,array $iEvent=NULL) { | ||
+ | $cntTitles = count($iTitles); | ||
+ | if ($cntTitles > 0) { | ||
+ | $strDescr = 'adding '.$cntTitles.' title'.Pluralize($cntTitles); | ||
+ | $iEvent['descr'] = StrCat($iEvent['descr'],$strDescr,' '); | ||
+ | $iEvent['where'] = nz($iEvent['where'],__METHOD__); | ||
+ | $iEvent['code'] = 'ADM'; // add multiple | ||
+ | $this->StartEvent($iEvent); | ||
+ | $cntAdded = 0; | ||
+ | $cntError = 0; | ||
+ | $txtAdded = ''; | ||
+ | $txtError = ''; | ||
+ | $tblTitles = $this->objDB->Titles(); | ||
+ | foreach ($iTitles as $catnum => $name) { | ||
+ | $arIns = array( | ||
+ | 'Name' => SQLValue($name), | ||
+ | 'CatKey' => SQLValue($catnum), | ||
+ | 'ID_Dept' => $this->ID, | ||
+ | 'DateAdded' => 'NOW()' | ||
+ | ); | ||
+ | $ok = $tblTitles->Insert($arIns); | ||
+ | if ($ok) { | ||
+ | $idNew = $tblTitles->LastID(); | ||
+ | $cntAdded++; | ||
+ | $txtAdded .= '['.$catnum.' ID='.$idNew.']'; | ||
+ | } else { | ||
+ | $cntError++; | ||
+ | $txtError .= '['.$catnum.' Error: '.$this->objDB->getError().']'; | ||
+ | } | ||
+ | } | ||
+ | if ($cntError > 0) { | ||
+ | $txtDescr = $cntError.' error'.Pluralize($cntError).': '.$txtError; | ||
+ | $txtDescr .= ' and '; | ||
+ | } else { | ||
+ | $txtDescr = 'Success:'; | ||
+ | } | ||
+ | $txtDescr .= $cntAdded.' title'.Pluralize($cntAdded).' added '.$txtAdded; | ||
+ | $arEv = array( | ||
+ | 'descrfin' => SQLValue($txtDescr), | ||
+ | 'error' => SQLValue($cntError > 0) | ||
+ | ); | ||
+ | $this->FinishEvent($arEv); | ||
+ | } | ||
} | } | ||
} | } | ||
− | class VbzAdminTitles extends | + | class VbzAdminTitles extends clsVbzTitles { |
public function __construct($iDB) { | public function __construct($iDB) { | ||
parent::__construct($iDB); | parent::__construct($iDB); | ||
$this->ClassSng('VbzAdminTitle'); | $this->ClassSng('VbzAdminTitle'); | ||
+ | $this->ActionKey('title'); | ||
+ | } | ||
+ | public function Add($iCatKey,$iName,$iDept,$iNotes) { | ||
+ | // log start of event | ||
+ | $arEvent = array( | ||
+ | 'type' => clsEvents::kTypeTitle, | ||
+ | 'id' => NULL, | ||
+ | 'where' => __METHOD__, | ||
+ | 'code' => 'add', | ||
+ | 'descr' => 'new title in dept. '.$iDept.': '.$iCatKey.': '.$iName | ||
+ | ); | ||
+ | if (!is_null($iNotes)) { | ||
+ | $arEvent['notes'] = $iNotes; | ||
+ | } | ||
+ | $idEvent = $this->objDB->Events()->StartEvent($arEvent); | ||
+ | |||
+ | // add the title record | ||
+ | $arIns = array( | ||
+ | 'CatKey' => SQLValue($iCatKey), | ||
+ | 'Name' => SQLValue($iName), | ||
+ | 'ID_Dept' => $iDept, | ||
+ | 'DateAdded' => 'NOW()' | ||
+ | ); | ||
+ | $this->Insert($arIns); | ||
+ | $idTitle = $this->objDB->NewID(__METHOD__); | ||
+ | |||
+ | // log the event's completion | ||
+ | $arUpd = array('id' => $idTitle); | ||
+ | $this->objDB->Events()->FinishEvent($idEvent,$arUpd); | ||
+ | return $idTitle; | ||
+ | } | ||
+ | /*---- | ||
+ | HISTORY: | ||
+ | 2010-11-15 Changed to use qryTitles_Item_info instead of qryCat_Titles_Item_stats | ||
+ | */ | ||
+ | public function Data_Imageless() { | ||
+ | //$sql = 'SELECT t.ID_Title AS ID, t.* FROM `qryCat_Titles_Item_stats` AS t LEFT JOIN `cat_images` AS i ON t.ID_Title=i.ID_Title' | ||
+ | $sql = 'SELECT t.* FROM `qryTitles_Item_info` AS t LEFT JOIN `cat_images` AS i ON t.ID=i.ID_Title' | ||
+ | .' WHERE (i.ID IS NULL) AND (cntForSale > 0)'; | ||
+ | $this->ClassSng('VbzAdminTitle_info_Item'); | ||
+ | $objRows = $this->DataSQL($sql); | ||
+ | return $objRows; | ||
+ | } | ||
+ | } | ||
+ | class VbzAdminTitle extends clsVbzTitle { | ||
+ | /*---- | ||
+ | HISTORY: | ||
+ | 2010-10-20 changing event logging to use helper class | ||
+ | 2010-11-08 conversion complete: added StartEvent() and FinishEvent(), deleted commented code | ||
+ | */ | ||
+ | //---- | ||
+ | // BOILERPLATE: event logging | ||
+ | protected function Log() { | ||
+ | if (!is_object($this->logger)) { | ||
+ | $this->logger = new clsLogger_DataSet($this,$this->objDB->Events()); | ||
+ | } | ||
+ | return $this->logger; | ||
+ | } | ||
+ | public function EventListing() { | ||
+ | return $this->Log()->EventListing(); | ||
+ | } | ||
+ | public function StartEvent(array $iArgs) { | ||
+ | return $this->Log()->StartEvent($iArgs); | ||
+ | } | ||
+ | public function FinishEvent(array $iArgs=NULL) { | ||
+ | return $this->Log()->FinishEvent($iArgs); | ||
+ | } | ||
+ | // BOILERPLATE: admin HTML | ||
+ | /*---- | ||
+ | HISTORY: | ||
+ | 2010-10-11 Replaced existing code with call to static function | ||
+ | */ | ||
+ | public function AdminLink($iText=NULL,$iPopup=NULL,array $iarArgs=NULL) { | ||
+ | return clsAdminData::_AdminLink($this,$iText,$iPopup,$iarArgs); | ||
+ | } | ||
+ | public function AdminLink_name() { | ||
+ | return $this->AdminLink($this->Value('Name')); | ||
+ | } | ||
+ | public function AdminURL(array $iArgs=NULL) { | ||
+ | return clsAdminData::_AdminURL($this,$iArgs); | ||
+ | } | ||
+ | // END BOILERPLATE | ||
+ | //---- | ||
+ | /*---- | ||
+ | ACTION: | ||
+ | Return the current title name | ||
+ | If a value is given, update it to the new value first (returns old value) | ||
+ | If an event array is given, log the event | ||
+ | HISTORY: | ||
+ | 2010-11-07 adapted from clsItem::SCatNum() | ||
+ | */ | ||
+ | public function Name($iVal=NULL,array $iEvent=NULL) { | ||
+ | $strOld = $this->Name; | ||
+ | if (!is_null($iVal)) { | ||
+ | if (is_array($iEvent)) { | ||
+ | $iEvent['descr'] = StrCat($iEvent['descr'],'renaming title',': '); | ||
+ | $iEvent['params'] = nz($iEvent['params']).':old=['.$strOld.']'; | ||
+ | $iEvent['code'] = 'NN'; // new name | ||
+ | $this->StartEvent($iEvent); | ||
+ | } | ||
+ | $arUpd = array('Name'=>SQLValue($iVal)); | ||
+ | $this->Update($arUpd); | ||
+ | if (is_array($iEvent)) { | ||
+ | $this->FinishEvent(); | ||
+ | } | ||
+ | } | ||
+ | return $strOld; | ||
+ | } | ||
+ | /*---- | ||
+ | RETURNS: Text suitable for use as a title for this Title | ||
+ | (Ok, can *you* think of a better method name?) | ||
+ | HISTORY: | ||
+ | 2010-11-19 Created for AdminPage() | ||
+ | */ | ||
+ | public function Title() { | ||
+ | return $this->CatNum().' '.$this->Name; | ||
+ | } | ||
+ | public function DeptObj() { | ||
+ | $objDept = $this->objDB->Depts()->GetItem($this->ID_Dept); | ||
+ | return $objDept; | ||
+ | } | ||
+ | public function ShopLink($iText) { | ||
+ | return $this->LinkAbs().$iText.'</a>'; | ||
+ | } | ||
+ | public function PageTitle() { | ||
+ | return $this->CatNum('-'); | ||
+ | } | ||
+ | /*---- | ||
+ | RETURNS: List of titles as formatted text | ||
+ | HISTORY: | ||
+ | 2011-10-01 created for revised catalog entry -- no departments anymore, need more topic info | ||
+ | */ | ||
+ | public function TopicList_ft($iNone='-') { | ||
+ | $rcs = $this->Topics(); // recordset of Topics for this Title | ||
+ | if ($rcs->HasRows()) { | ||
+ | $out = ''; | ||
+ | while ($rcs->NextRow()) { | ||
+ | $out .= ' '.$rcs->AdminLink(); | ||
+ | } | ||
+ | } else { | ||
+ | $out = $iNone; | ||
+ | } | ||
+ | return $out; | ||
+ | } | ||
+ | /*---- | ||
+ | HISTORY: | ||
+ | 2011-02-23 Finally renamed from InfoPage() to AdminPage() | ||
+ | */ | ||
+ | public function AdminPage() { | ||
+ | global $wgOut,$wgRequest; | ||
+ | global $vgPage,$vgOut; | ||
+ | |||
+ | $doEdit = $vgPage->Arg('edit'); | ||
+ | $doSave = $wgRequest->GetBool('btnSave'); | ||
+ | |||
+ | $vgPage->UseHTML(); | ||
+ | |||
+ | // save edits before showing events | ||
+ | $ftSaveStatus = NULL; | ||
+ | if ($doEdit || $doSave) { | ||
+ | $this->BuildEditForm(); | ||
+ | if ($doSave) { | ||
+ | $ftSaveStatus = $this->AdminSave(); | ||
+ | } | ||
+ | } | ||
+ | |||
+ | $isMissing = is_null($this->ID); | ||
+ | if ($isMissing) { | ||
+ | $strTitle = 'Missing Record'; | ||
+ | $this->ID = $vgPage->Arg('ID'); | ||
+ | } else { | ||
+ | // items | ||
+ | $ftItems = $this->ItemListing(); | ||
+ | $htImages = $this->ImageListing(); // this may update the thumbnails, so do it before showing them | ||
+ | $htGroups = $this->CMGrpListing(); | ||
+ | $wtEvents = $this->EventListing(); | ||
+ | |||
+ | $objTbl = $this->objDB->Images(); | ||
+ | $htThumbs = $objTbl->Thumbnails($this->ID); | ||
+ | if (!is_null($htThumbs)) { | ||
+ | $wgOut->AddHTML('<table align=right><tr><td>'.$htThumbs.'</td></tr></table>'); | ||
+ | } | ||
+ | |||
+ | //$strCatNum = $this->CatNum(); | ||
+ | $strCatPage = $this->CatNum('/'); | ||
+ | |||
+ | $strTitle = 'Title: '.$this->Title(); | ||
+ | } | ||
+ | |||
+ | $objPage = new clsWikiFormatter($vgPage); | ||
+ | $objSection = new clsWikiSection($objPage,$strTitle); | ||
+ | $objSection->ToggleAdd('edit'); | ||
+ | $out = $objSection->Generate(); | ||
+ | $wgOut->AddHTML($out); $out = ''; | ||
+ | $vgOut->AddText($ftSaveStatus); | ||
+ | |||
+ | $objSupp = $this->SuppObj(); | ||
+ | assert(is_object($objSupp)); | ||
+ | |||
+ | if ($doEdit) { | ||
+ | $out .= $objSection->FormOpen(); | ||
+ | |||
+ | $ftCatKey = $this->objForm->Ctrl('CatKey')->Render(); | ||
+ | $ftSuppCN = $this->objForm->Ctrl('Supplier_CatNum')->Render(); | ||
+ | $ftSupp = $objSupp->DropDown('ID_Supp'); | ||
+ | $ftDept = $objSupp->Depts_DropDown('ID_Dept',$this->ID_Dept); | ||
+ | $ftName = $this->objForm->Ctrl('Name')->Render(); | ||
+ | $ftSearch = $this->objForm->Ctrl('Search')->Render(); | ||
+ | $ftDescr = $this->objForm->Ctrl('Desc')->Render(); | ||
+ | $ftNotes = $this->objForm->Ctrl('Notes')->Render(); | ||
+ | $ftWhAdded = $this->objForm->Ctrl('DateAdded')->Render(); | ||
+ | $ftWhChckd = $this->objForm->Ctrl('DateChecked')->Render(); | ||
+ | $ftWhUnavl = $this->objForm->Ctrl('DateUnavail')->Render(); | ||
+ | } else { | ||
+ | $ftCatKey = htmlspecialchars($this->CatKey); | ||
+ | $ftSuppCN = htmlspecialchars($this->Supplier_CatNum); | ||
+ | $ftSupp = $objSupp->AdminLink_name(); | ||
+ | $objDept = $this->DeptObj(); | ||
+ | if (is_object($objDept)) { | ||
+ | $ftDept = $objDept->AdminLink($objDept->Name); | ||
+ | } else { | ||
+ | $ftDept = 'not set'; | ||
+ | } | ||
+ | $ftName = htmlspecialchars($this->Name); | ||
+ | $ftSearch = htmlspecialchars($this->Search); | ||
+ | $ftDescr = htmlspecialchars($this->Desc); | ||
+ | $ftNotes = htmlspecialchars($this->Notes); | ||
+ | $ftWhAdded = $this->DateAdded; | ||
+ | $ftWhChckd = $this->DateChecked; | ||
+ | $ftWhUnavl = $this->DateUnavail; | ||
+ | } | ||
+ | $out .= '<table>'; | ||
+ | $out .= '<tr><td align=right><b>ID</b>:</td><td>'.$this->ID.' ['.$this->ShopLink('shop').']'; | ||
+ | $out .= '</td></tr>'; | ||
+ | $out .= '<tr><td align=right><b>Cat Key</b>:</td><td>'.$ftCatKey; | ||
+ | $out .= '</td></tr>'; | ||
+ | $out .= '<tr><td align=right title="supplier catalog #"><b>SC#</b>:</td><td>'.$ftSuppCN; | ||
+ | $out .= '</td></tr>'; | ||
+ | $out .= '<tr><td align=right><b>Supplier</b>:</td><td>'.$ftSupp; | ||
+ | $out .= '</td></tr>'; | ||
+ | $out .= '<tr><td align=right><b>Dept</b>:</td><td>'.$ftDept; | ||
+ | $out .= '</td></tr>'; | ||
+ | $out .= '<tr><td align=right><b>Name</b>:</td><td>'.$ftName; | ||
+ | $out .= '</td></tr>'; | ||
+ | $out .= '<tr><td align=right><b>Search</b>:</td><td>'.$ftSearch; | ||
+ | $out .= '</td></tr>'; | ||
+ | $out .= '<tr><td align=right><b>When Added</b>:</td><td>'.$ftWhAdded; | ||
+ | $out .= '</td></tr>'; | ||
+ | $out .= '<tr><td align=right><b>When Checked</b>:</td><td>'.$ftWhChckd; | ||
+ | $out .= '</td></tr>'; | ||
+ | $out .= '<tr><td align=right><b>When Unavailable</b>:</td><td>'.$ftWhUnavl; | ||
+ | $out .= '</td></tr>'; | ||
+ | $out .= '</table>'; | ||
+ | if ($doEdit) { | ||
+ | $out .= '<b>Edit notes</b>: <input type=text name="EvNotes" size=40><br>'; | ||
+ | $out .= '<input type=submit name="btnSave" value="Save">'; | ||
+ | $out .= '<input type=submit name="btnCancel" value="Cancel">'; | ||
+ | $out .= '<input type=reset value="Reset">'; | ||
+ | $out .= '</form>'; | ||
+ | } | ||
+ | $wgOut->addHTML($out); $out = ''; | ||
+ | |||
+ | if (!$isMissing) { | ||
+ | $wgOut->addWikiText('===Items===',TRUE); | ||
+ | $vgOut->addText($ftItems); | ||
+ | $wgOut->addHTML($htImages); // Images | ||
+ | $wgOut->addWikiText('===Topics===',TRUE); | ||
+ | $wgOut->addHTML($this->TopicListing()); | ||
+ | $wgOut->addHTML($htGroups); // Catalog Groups | ||
+ | $wgOut->addWikiText('===Events===',TRUE); | ||
+ | $wgOut->addWikiText($wtEvents,TRUE); | ||
+ | } | ||
+ | } | ||
+ | /*---- | ||
+ | HISTORY: | ||
+ | 2010-11-06 adapted from VbzStockBin for VbzAdminTitle | ||
+ | */ | ||
+ | private function BuildEditForm() { | ||
+ | global $vgOut; | ||
+ | |||
+ | if (is_null($this->objForm)) { | ||
+ | // create fields & controls | ||
+ | $objForm = new clsForm_DataSet($this,$vgOut); | ||
+ | //$objCtrls = new clsCtrls($objForm->Fields()); | ||
+ | //$objCtrls = $objForm; | ||
+ | |||
+ | $objForm->AddField(new clsField('CatKey'), new clsCtrlHTML(array('size'=>8))); | ||
+ | $objForm->AddField(new clsField('Supplier_CatNum'), new clsCtrlHTML(array('size'=>25))); | ||
+ | $objForm->AddField(new clsFieldNum('ID_Supp'), new clsCtrlHTML()); | ||
+ | $objForm->AddField(new clsFieldNum('ID_Dept'), new clsCtrlHTML()); | ||
+ | $objForm->AddField(new clsField('Name'), new clsCtrlHTML(array('size'=>25))); | ||
+ | $objForm->AddField(new clsField('Search'), new clsCtrlHTML(array('size'=>25))); | ||
+ | $objForm->AddField(new clsField('Desc'), new clsCtrlHTML(array('size'=>25))); | ||
+ | $objForm->AddField(new clsField('Notes'), new clsCtrlHTML()); | ||
+ | $objForm->AddField(new clsFieldTime('DateAdded'), new clsCtrlHTML()); | ||
+ | $objForm->AddField(new clsFieldTime('DateChecked'), new clsCtrlHTML()); | ||
+ | $objForm->AddField(new clsFieldTime('DateUnavail'), new clsCtrlHTML()); | ||
+ | |||
+ | $this->objForm = $objForm; | ||
+ | //$this->objCtrls = $objCtrls; | ||
+ | } | ||
+ | } | ||
+ | public function AdminSave() { | ||
+ | global $wgRequest; | ||
+ | global $vgOut; | ||
+ | |||
+ | // check input for problems | ||
+ | $strCatKeyNew = $wgRequest->GetText('CatKey'); | ||
+ | $strCatKeyOld = $this->CatKey; | ||
+ | $ok = TRUE; // ok to save unless CatKey conflict | ||
+ | $out = ''; | ||
+ | if ($strCatKeyNew != $strCatKeyOld) { | ||
+ | $ok = FALSE; // don't save unless CatKey passes tests | ||
+ | // if catkey is being changed, then check new number for duplicates | ||
+ | $objSupp = $this->SuppObj(); | ||
+ | $objMatch = $objSupp->GetTitle_byCatKey($strCatKeyNew,'VbzAdminTitle'); | ||
+ | if (is_null($objMatch)) { | ||
+ | $ok = TRUE; | ||
+ | } else { | ||
+ | /* | ||
+ | Requested catkey matches an existing title. | ||
+ | Look for other titles with the same base catkey (in same supplier), | ||
+ | on the theory that this will represent a list of previous renames | ||
+ | for this catkey. | ||
+ | */ | ||
+ | $objMatch->NextRow(); | ||
+ | $out = 'Your entered CatKey ['.$strCatKeyNew.'] has already been used for '.$objMatch->AdminLink($objMatch->Name); | ||
+ | $objMatch = $objSupp->GetTitles_byCatKey($strCatKeyOld,'VbzAdminTitle'); | ||
+ | if (!is_null($objMatch)) { | ||
+ | // there are some similar entries -- show them: | ||
+ | $out .= ' Other similar CatKeys:'; | ||
+ | while ($objMatch->NextRow()) { | ||
+ | $out .= ' '.$objMatch->AdminLink($objMatch->CatKey); | ||
+ | } | ||
+ | } | ||
+ | } | ||
+ | } | ||
+ | if ($ok) { | ||
+ | $out .= $this->objForm->Save($wgRequest->GetText('EvNotes')); | ||
+ | } | ||
+ | return $out; | ||
+ | } | ||
+ | public function ItemListing() { | ||
+ | $out = $this->objDB->Items()->Listing_forTitle($this); | ||
+ | return $out; | ||
+ | } | ||
+ | public function ImageListing() { | ||
+ | $objTbl = $this->objDB->Images(); | ||
+ | $arArgs = array( | ||
+ | 'filt' => 'ID_Title='.$this->ID, | ||
+ | 'sort' => 'AttrSort,ID', | ||
+ | 'event.obj' => $this, | ||
+ | 'title.id' => $this->ID, | ||
+ | 'new' => TRUE | ||
+ | ); | ||
+ | $out = $objTbl->AdminPage($arArgs); | ||
+ | |||
+ | // $objRows = $objTbl->GetData('ID_Title='.$this->ID,NULL,'AttrSort'); | ||
+ | // $out = $objRows->AdminList(); | ||
+ | return $out; | ||
+ | } | ||
+ | /*---- | ||
+ | RETURNS: Editable listing of topics for this Title | ||
+ | */ | ||
+ | protected function TopicListing() { | ||
+ | global $wgRequest; | ||
+ | global $vgPage; | ||
+ | |||
+ | $tblTitleTopics = $this->Engine()->TitleTopics(); | ||
+ | |||
+ | $me = $this; | ||
+ | $arOpts = $this->Engine()->Topics()->TopicListing_base_array(); | ||
+ | $arOpts['fHandleData_Change_Start'] = function($iText) use ($me) { | ||
+ | $arEv = array( | ||
+ | 'descr' => 'Adding '.$iText, | ||
+ | 'code' => 'topic++', | ||
+ | 'where' => __METHOD__ | ||
+ | ); | ||
+ | $me->StartEvent($arEv); | ||
+ | }; | ||
+ | |||
+ | $arOpts['fHandleData_Change_Finish'] = function($iText) use ($me) { | ||
+ | $arEv = array( | ||
+ | 'descrfin' => $iText | ||
+ | ); | ||
+ | $me->FinishEvent($arEv); | ||
+ | }; | ||
+ | $arOpts['fHandleData_Change_Item'] = function($iVal) use ($me,$tblTitleTopics) { | ||
+ | $sqlTopic = $iVal; | ||
+ | $arIns = array( | ||
+ | 'ID_Title' => SQLValue($me->KeyValue()), | ||
+ | 'ID_Topic' => $sqlTopic | ||
+ | ); | ||
+ | $db = $tblTitleTopics->Engine(); | ||
+ | $db->ClearError(); | ||
+ | $ok = $tblTitleTopics->Insert($arIns); | ||
+ | if (!$ok) { | ||
+ | $strErr = $db->getError(); | ||
+ | $out = $sqlTopic.': '.$strErr.' (SQL:'.$tblTitleTopics->sqlExec.')'; | ||
+ | } else { | ||
+ | $out = SQLValue($sqlTopic); | ||
+ | } | ||
+ | return $out; | ||
+ | }; | ||
+ | |||
+ | $ctrlList = new clsWidget_ShortList(); | ||
+ | $ctrlList->Options($arOpts); | ||
+ | $htStatus = $ctrlList->HandleInput(); | ||
+ | |||
+ | $doRmvTopics = $wgRequest->GetBool('btnRmvTopics'); | ||
+ | |||
+ | // begin output phase | ||
+ | $out = ''; | ||
+ | |||
+ | if ($doRmvTopics) { | ||
+ | $arTopics = $wgRequest->GetArray('rmvTitle'); | ||
+ | $cnt = $tblTitleTopics->DelTopics($this->Value('ID'),$arTopics); | ||
+ | $out .= 'Removed '.$cnt.' topic'.Pluralize($cnt).':'; | ||
+ | foreach ($arTopics as $id => $on) { | ||
+ | $objTopic = $tblTopics->GetItem($id); | ||
+ | $out .= ' '.$objTopic->AdminLink(); | ||
+ | } | ||
+ | } | ||
+ | /* | ||
+ | $htPath = $vgPage->SelfURL(); | ||
+ | $out = "\n<form method=post action=\"$htPath\">"; | ||
+ | */ | ||
+ | $out .= "\n<form method=post>"; | ||
+ | |||
+ | $rs = $this->Topics(); | ||
+ | if ($rs->HasRows()) { | ||
+ | while ($rs->NextRow()) { | ||
+ | |||
+ | $id = $rs->KeyString(); | ||
+ | $ftName = $rs->AdminLink_name(); | ||
+ | |||
+ | $out .= "\n[<input type=checkbox name=\"rmvTitle[$id]\">$ftName ]"; | ||
+ | } | ||
+ | $out .= '<br><input type=submit name="btnRmvTopics" value="Remove Checked">'; | ||
+ | } else { | ||
+ | $out .= '<i>None found.</i>'; | ||
+ | } | ||
+ | /* | ||
+ | $out .= '<input type=submit name="btnAddTopics" value="Add These:">'; | ||
+ | $out .= '<input size=40 name=txtNewTitles> (IDs separated by spaces)'; | ||
+ | */ | ||
+ | $out .= '<br>'.$htStatus; | ||
+ | $out .= $ctrlList->RenderForm_Entry(); | ||
+ | |||
+ | $out .= '</form>'; | ||
+ | return $out; | ||
+ | } | ||
+ | /*---- | ||
+ | RETURNS: Listing of CM (catalog management) groups for this title | ||
+ | HISTORY: | ||
+ | 2011-02-06 added controls to allow deactivating/activating selected rows | ||
+ | */ | ||
+ | protected function CMGrpListing() { | ||
+ | global $wgRequest; | ||
+ | global $vgOut; | ||
+ | |||
+ | $out = $vgOut->Header('Catalog Groups',3); | ||
+ | |||
+ | $tblCMT = $this->objDB->CtgTitles(); // catalog management titles | ||
+ | $tblCMS = $this->objDB->CtgSrcs(); // catalog management sources | ||
+ | $tblCMG = $this->objDB->CtgGrps(); // catalog management groups | ||
+ | |||
+ | $doEnable = $wgRequest->GetBool('btnCtgEnable'); | ||
+ | $doDisable = $wgRequest->GetBool('btnCtgDisable'); | ||
+ | if ($doEnable || $doDisable) { | ||
+ | $arChg = $wgRequest->GetArray('ctg'); | ||
+ | $out .= $doEnable?'Activating':'Deactivating'; | ||
+ | foreach ($arChg as $id => $on) { | ||
+ | $out .= ' '.$id; | ||
+ | $arUpd = array( | ||
+ | 'isActive' => SQLValue($doEnable) | ||
+ | ); | ||
+ | $tblCMT->Update($arUpd,'ID='.$id); | ||
+ | } | ||
+ | } | ||
+ | |||
+ | $rsRows = $tblCMT->GetData('ID_Title='.$this->ID); | ||
+ | if ($rsRows->HasRows()) { | ||
+ | $out .= '<form method=post>'; | ||
+ | $out .= $vgOut->TableOpen(); | ||
+ | $out .= $vgOut->TblRowOpen(NULL,TRUE); | ||
+ | $out .= $vgOut->TblCell('ID'); | ||
+ | $out .= $vgOut->TblCell('A?'); | ||
+ | $out .= $vgOut->TblCell('Catalog'); | ||
+ | $out .= $vgOut->TblCell('Group'); | ||
+ | $out .= $vgOut->TblCell('Discontinued'); | ||
+ | $out .= $vgOut->TblCell('Grp Code'); | ||
+ | $out .= $vgOut->TblCell('Grp Descr'); | ||
+ | $out .= $vgOut->TblCell('Grp Sort'); | ||
+ | $out .= $vgOut->TblCell('Supp Cat #'); | ||
+ | $out .= $vgOut->TblCell('Notes'); | ||
+ | $out .= $vgOut->TblRowShut(); | ||
+ | while ($rsRows->NextRow()) { | ||
+ | $isActive = $rsRows->isActive; | ||
+ | $htActive = $isActive?'√':'-'; | ||
+ | |||
+ | $objCMSrce = $tblCMS->GetItem($rsRows->ID_Source); | ||
+ | $objCMGrp = $tblCMG->GetItem($rsRows->ID_Group); | ||
+ | if ($objCMSrce->HasRows()) { | ||
+ | $htCMSrce = $objCMSrce->AdminLink_name(); | ||
+ | } else { | ||
+ | $htCMSrce = '?'.$rsRows->ID_Source; | ||
+ | } | ||
+ | if ($objCMGrp->HasRows()) { | ||
+ | $htCMGrp = $objCMGrp->AdminLink_name(); | ||
+ | } else { | ||
+ | $htCMGrp = '?'.$rsRows->ID_Group; | ||
+ | } | ||
+ | |||
+ | $out .= $vgOut->TblRowOpen(); | ||
+ | $htID = '<input type=checkbox name="ctg['.$rsRows->KeyValue().']">'.$rsRows->AdminLink(); | ||
+ | $out .= $vgOut->TblCell($htID); | ||
+ | $out .= $vgOut->TblCell($htActive); | ||
+ | $out .= $vgOut->TblCell($htCMSrce); | ||
+ | $out .= $vgOut->TblCell($htCMGrp); | ||
+ | // $out .= $vgOut->TblCell($rsRows->ID_Source); | ||
+ | // $out .= $vgOut->TblCell($rsRows->ID_Group); | ||
+ | |||
+ | $out .= $vgOut->TblCell($rsRows->WhenDiscont); | ||
+ | $out .= $vgOut->TblCell($rsRows->GroupCode); | ||
+ | $out .= $vgOut->TblCell($rsRows->GroupDescr); | ||
+ | $out .= $vgOut->TblCell($rsRows->GroupSort); | ||
+ | $out .= $vgOut->TblCell($rsRows->Supp_CatNum); | ||
+ | $out .= $vgOut->TblCell($rsRows->Notes); | ||
+ | $out .= $vgOut->TblRowShut(); | ||
+ | } | ||
+ | $out .= $vgOut->TableShut(); | ||
+ | $out .= '<input type=submit name=btnCtgDisable value="Deactivate Selected">'; | ||
+ | $out .= '<input type=submit name=btnCtgEnable value="Activate Selected">'; | ||
+ | $out .= '</form>'; | ||
+ | } else { | ||
+ | $out .= 'None found.'; | ||
+ | } | ||
+ | return $out; | ||
+ | } | ||
+ | } | ||
+ | /*==== | ||
+ | PURPOSE: VbzAdminTitles with additional catalog information | ||
+ | */ | ||
+ | class VbzAdminTitles_info_Cat extends VbzAdminTitles { | ||
+ | public function __construct($iDB) { | ||
+ | parent::__construct($iDB); | ||
+ | $this->Name('qryCat_Titles'); | ||
+ | } | ||
+ | public function Search_forText_SQL($iFind) { | ||
+ | $sqlFind = '"%'.$iFind.'%"'; | ||
+ | return "(Name LIKE $sqlFind) OR (Descr LIKE $sqlFind) OR (Search LIKE $sqlFind) OR (CatNum LIKE $sqlFind)"; | ||
+ | } | ||
+ | public function SearchPage() { | ||
+ | global $wgOut,$wgRequest; | ||
+ | global $vgPage; | ||
+ | |||
+ | $strFind = $wgRequest->GetText('txtSearch'); | ||
+ | |||
+ | $vgPage->UseHTML(); | ||
+ | $out = "\n<form method=post>"; | ||
+ | $htFind = htmlspecialchars($strFind); | ||
+ | $out .= 'Search for:<input name=txtSearch size=40 value="'.$htFind.'"><input type=submit name=btnSearch value="Go">'; | ||
+ | $out .= '</form>'; | ||
+ | $wgOut->AddHTML($out); $out = ''; | ||
+ | |||
+ | |||
+ | //$tblTitles = $this->Engine()->Titles(); | ||
+ | $tblTitles = $this; | ||
+ | $tblItems = $this->Engine()->Items(); | ||
+ | $tblImgs = $this->Engine()->Images(); | ||
+ | |||
+ | $arTitles = NULL; | ||
+ | |||
+ | $rs = $tblTitles->Search_forText($strFind); | ||
+ | if ($rs->HasRows()) { | ||
+ | while ($rs->NextRow()) { | ||
+ | $id = $rs->ID; | ||
+ | $arTitles[$id] = $rs->Values(); | ||
+ | } | ||
+ | } | ||
+ | |||
+ | if (!empty($strFind)) { | ||
+ | $out .= '<br><b>Searching for</b> "'.$htFind.'":<br>'; | ||
+ | $wgOut->AddHTML($out); $out = ''; | ||
+ | |||
+ | $rs = $tblItems->Search_byCatNum($strFind); | ||
+ | if (is_object($rs)) { | ||
+ | while ($rs->NextRow()) { | ||
+ | $id = $rs->Value('ID_Title'); | ||
+ | if (!isset($arTitles[$id])) { | ||
+ | $obj = $tblTitles->GetItem($id); | ||
+ | $arTitles[$id] = $obj->Values(); | ||
+ | } | ||
+ | } | ||
+ | } | ||
+ | |||
+ | if (!is_null($arTitles)) { | ||
+ | if (empty($obj)) { | ||
+ | $obj = $tblTitles->SpawnItem(); | ||
+ | } | ||
+ | $out .= '<table align=left style="border: solid black 1px;"><tr><td>'; | ||
+ | $ftImgs = ''; | ||
+ | $isFirst = TRUE; | ||
+ | foreach ($arTitles as $id => $row) { | ||
+ | $obj->Values($row); | ||
+ | $txtCatNum = $obj->CatNum(); | ||
+ | $txtName = $obj->Value('Name'); | ||
+ | if ($isFirst) { | ||
+ | $isFirst = FALSE; | ||
+ | } else { | ||
+ | $out .= "\n<br>"; | ||
+ | } | ||
+ | $out .= $obj->AdminLink($txtCatNum).' '.$txtName; | ||
+ | |||
+ | $txtTitle = $txtCatNum.' “'.htmlspecialchars($txtName).'”'; | ||
+ | $ftImg = $tblImgs->Thumbnails($id,array('title'=>$txtTitle)); | ||
+ | $ftImgs .= '<a href="'.$obj->AdminURL().'">'.$ftImg.'</a>'; | ||
+ | } | ||
+ | $out .= '</td></tr></table>'.$ftImgs; | ||
+ | } | ||
+ | |||
+ | $wgOut->AddHTML($out); $out = ''; | ||
+ | } | ||
+ | |||
+ | return $out; | ||
+ | } | ||
+ | } | ||
+ | /*==== | ||
+ | PURPOSE: VbzAdminTitles with additional item (and stock) information | ||
+ | */ | ||
+ | class VbzAdminTitles_info_Item extends VbzAdminTitles { | ||
+ | public function __construct($iDB) { | ||
+ | parent::__construct($iDB); | ||
+ | $this->Name('qryTitles_Item_info'); | ||
+ | $this->ClassSng('VbzAdminTitle_info_Item'); | ||
} | } | ||
public function Listing_forDept($iDeptObj) { | public function Listing_forDept($iDeptObj) { | ||
global $wgOut; | global $wgOut; | ||
+ | global $vgPage; | ||
global $sql; | global $sql; | ||
+ | |||
+ | $vgPage->UseHTML(); | ||
$objDept = $iDeptObj; | $objDept = $iDeptObj; | ||
$idDept = $objDept->ID; | $idDept = $objDept->ID; | ||
// $strSuppKey = strtolower($objSupp->CatKey); | // $strSuppKey = strtolower($objSupp->CatKey); | ||
+ | // $objRecs = $this->GetData('ID_Dept='.$idDept,'VbzAdminTitle','CatKey'); | ||
+ | //$objRecs = $this->DataSQL('SELECT t.ID_Title AS ID, t.* FROM qryCat_Titles_Item_stats AS t WHERE t.ID_Dept='.$idDept); | ||
+ | $objRecs = $this->GetData('ID_Dept='.$idDept,NULL,'CatKey'); | ||
+ | |||
+ | $out = $objRecs->AdminList(); | ||
+ | $wgOut->addHTML($out); | ||
+ | } | ||
+ | } | ||
+ | class VbzAdminTitle_info_Item extends VbzAdminTitle { | ||
+ | /*---- | ||
+ | RETURNS: listing of titles in the current dataset | ||
+ | HISTORY: | ||
+ | 2010-11-16 "in print" column now showing cntInPrint instead of cntForSale | ||
+ | */ | ||
+ | public function AdminList(array $iarArgs=NULL) { | ||
+ | $objRecs = $this; | ||
− | |||
if ($objRecs->HasRows()) { | if ($objRecs->HasRows()) { | ||
− | $out = " | + | $out = "\n<table class=sortable>" |
+ | ."\n<tr>" | ||
+ | .'<th>ID</th>' | ||
+ | .'<th>Name</th>' | ||
+ | .'<th>Cat #</th>' | ||
+ | .'<th><small>CatKey</small></th>' | ||
+ | .'<th>SCat#</th>' | ||
+ | .'<th>When Added</th>' | ||
+ | .'<th title="number of item records"><small>item<br>recs</small></th>' | ||
+ | .'<th title="number of items in print"><small>items<br>in print</small></th>' | ||
+ | .'<th>stk<br>qty</th>' | ||
+ | .'</tr>'; | ||
$isOdd = TRUE; | $isOdd = TRUE; | ||
while ($objRecs->NextRow()) { | while ($objRecs->NextRow()) { | ||
− | + | $ftID = $objRecs->AdminLink(); | |
− | $ | + | $ftName = $objRecs->Name; |
− | $ | + | $ftCatNum = $objRecs->CatNum(); |
− | $wtStyle = $isOdd?'background:#ffffff;':'background:# | + | $ftCatKey = $objRecs->Row['CatKey']; |
− | $isActive = | + | $ftSCatNum = $objRecs->Row['Supplier_CatNum']; |
− | if ( | + | $ftWhen = $objRecs->DateAdded; |
+ | |||
+ | // FUTURE: If we're using this on a dataset which does not have these fields, | ||
+ | // test for them and then retrieve them the slow way if not found. | ||
+ | $qtyStk = $objRecs->qtyForSale; | ||
+ | //$cntAva = $objRecs->cntForSale; | ||
+ | $cntPrn = $objRecs->cntInPrint; | ||
+ | $cntItm = $objRecs->cntItems; | ||
+ | |||
+ | $isActive = (($qtyStk > 0) || ($cntPrn > 0)); | ||
+ | $isPassive = (nz($cntItm) == 0); | ||
+ | |||
+ | $isOdd = !$isOdd; | ||
+ | $wtStyle = $isOdd?'background:#ffffff;':'background:#eeeeee;'; | ||
+ | |||
+ | if ($isActive) { | ||
+ | $wtStyle .= ' font-weight: bold;'; | ||
+ | } | ||
+ | if ($isPassive) { | ||
$wtStyle .= ' color: #888888;'; | $wtStyle .= ' color: #888888;'; | ||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
} | } | ||
− | $ | + | $out .= "\n<tr style=\"$wtStyle\">". |
+ | "<td>$ftID</td>". | ||
+ | "<td>$ftName</td>". | ||
+ | "<td>$ftCatNum</td>". | ||
+ | "<td>$ftCatKey</td>". | ||
+ | "<td>$ftSCatNum</td>". | ||
+ | "<td>$ftWhen</td>". | ||
+ | "<td align=right>$cntItm</td>". | ||
+ | "<td align=right>$cntPrn</td>". | ||
+ | "<td align=right>$qtyStk</td>". | ||
+ | '</tr>'; | ||
} | } | ||
− | $out .= "\n | + | $out .= "\n</table>"; |
} else { | } else { | ||
− | $out = ' | + | if (isset($iarArgs['none'])) { |
+ | $out .= $iarArgs['none']; | ||
+ | } else { | ||
+ | $out .= 'No titles found.'; | ||
+ | } | ||
} | } | ||
− | + | return $out; | |
} | } | ||
} | } | ||
− | class | + | /***** |
− | public function | + | GROUP: Item administration |
− | + | */ | |
+ | class VbzAdminItems extends clsItems { | ||
+ | // STATIC section // | ||
+ | /*---- | ||
+ | HISTORY: | ||
+ | 2010-10-13 Re-enabled as a boilerplate call | ||
+ | */ | ||
+ | public static function AdminLink($iID,$iShow=NULL,$iPopup=NULL) { | ||
+ | return clsAdminTable::AdminLink($iID,$iShow,$iPopup); | ||
+ | } | ||
+ | // DYNAMIC section // | ||
+ | public function __construct($iDB) { | ||
+ | parent::__construct($iDB); | ||
+ | $this->ClassSng('VbzAdminItem'); | ||
+ | $this->ActionKey('item'); | ||
+ | } | ||
+ | public function Listing_forTitle(clsVbzTitle $iTitleObj) { | ||
+ | $objTitle = $iTitleObj; | ||
+ | $idTitle = $objTitle->ID; | ||
+ | //$cntRow = 0; | ||
− | $ | + | $objRecs = $this->GetData('(IFNULL(isDumped,0)=0) AND (ID_Title='.$idTitle.')','VbzAdminItem','ItOpt_Sort'); |
− | + | return $objRecs->AdminList(); | |
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | $ | ||
} | } | ||
− | public function | + | /*---- |
− | $out = $ | + | ACTION: Updates fields in given catalog items |
+ | Does not log an event (maybe it should?) | ||
+ | INPUT: Array of items as returned by AdminItems_data_check() | ||
+ | RETURNS: HTML to display (messages) | ||
+ | FUTURE: This possibly should be in a helper class | ||
+ | HISTORY: | ||
+ | 2011-01-04 partially written | ||
+ | */ | ||
+ | public function AdminItems_data_update(array $iItems) { | ||
+ | $out = "\n<ul>"; | ||
+ | foreach ($iItems as $idx => $row) { | ||
+ | $obj = $row['@obj']; | ||
+ | $id = $obj->KeyValue(); | ||
+ | $out .= "\n<li>Row $idx ID=$id:\n<ul>"; | ||
+ | $arUpd = NULL; | ||
+ | if (!empty($row['do-upd-scat'])) { | ||
+ | $arUpd['Supp_CatNum'] = SQLValue($row['scat']); | ||
+ | $out .= "\n<li>scat# [".$obj->Supp_CatNum.']=>['.$row['scat'].']'; | ||
+ | } | ||
+ | if (!empty($row['do-upd-desc'])) { | ||
+ | $arUpd['Descr'] = SQLValue($row['name']); | ||
+ | $out .= "\n<li>descr [".$obj->Descr.']=>['.$row['name'].']'; | ||
+ | } | ||
+ | $out .= "\n</ul>"; | ||
+ | $obj->Update($arUpd); | ||
+ | } | ||
+ | $out .= "\n</ul>"; | ||
return $out; | return $out; | ||
} | } | ||
} | } | ||
− | class | + | class VbzAdminItem extends clsItem { |
− | public function | + | private $idEvent; |
− | + | ||
− | + | /*---- | |
+ | HISTORY: | ||
+ | 2010-10-11 Added iarArgs parameter | ||
+ | */ | ||
+ | public function AdminLink($iText=NULL,$iPopup=NULL,array $iarArgs=NULL) { | ||
+ | return clsAdminData::_AdminLink($this,$iText,$iPopup,$iarArgs); | ||
+ | } | ||
+ | public function AdminLink_name() { | ||
+ | return $this->AdminLink($this->DescLong()); // can make this more elaborate later | ||
+ | } | ||
+ | /*---- | ||
+ | PURPOSE: Like AdminLink_name(). but okay to take up more room to provide more info | ||
+ | HISTORY: | ||
+ | 2010-11-24 created | ||
+ | */ | ||
+ | public function AdminLink_friendly() { | ||
+ | $strItem = $this->AdminLink_CatNum(); | ||
+ | $strFull = $strItem.' '.$this->DescLong_ht(); | ||
+ | return $strFull; | ||
+ | } | ||
+ | /*---- | ||
+ | HISTORY: | ||
+ | 2010-11-27 created | ||
+ | */ | ||
+ | public function AdminLink_CatNum() { | ||
+ | return $this->AdminLink($this->CatNum,$this->DescLong()); | ||
+ | } | ||
+ | /*---- | ||
+ | HISTORY: | ||
+ | 2010-11-06 replaced old event logging with boilerplate calls to helper class | ||
+ | */ | ||
+ | protected function Log() { | ||
+ | if (!is_object($this->logger)) { | ||
+ | $this->logger = new clsLogger_DataSet($this,$this->objDB->Events()); | ||
+ | } | ||
+ | return $this->logger; | ||
+ | } | ||
+ | public function EventListing() { | ||
+ | return $this->Log()->EventListing(); | ||
+ | } | ||
+ | public function StartEvent(array $iArgs) { | ||
+ | return $this->Log()->StartEvent($iArgs); | ||
+ | } | ||
+ | public function FinishEvent(array $iArgs=NULL) { | ||
+ | return $this->Log()->FinishEvent($iArgs); | ||
+ | } | ||
+ | /*---- | ||
+ | ACTION: | ||
+ | Return the current supplier catalog number | ||
+ | If a value is given, update it to the new value first (returns old value) | ||
+ | If an event array is given, log the event | ||
+ | */ | ||
+ | public function SCatNum($iVal=NULL,array $iEvent=NULL) { | ||
+ | $strOld = $this->Supp_CatNum; | ||
+ | if (!is_null($iVal)) { | ||
+ | if (is_array($iEvent)) { | ||
+ | $iEvent['params'] = nz($iEvent['params']).':old=['.$strOld.']'; | ||
+ | $iEvent['code'] = 'SCN'; | ||
+ | $this->StartEvent($iEvent); | ||
+ | } | ||
+ | $arUpd = array('Supp_CatNum'=>SQLValue($iVal)); | ||
+ | $this->Update($arUpd); | ||
+ | if (is_array($iEvent)) { | ||
+ | $this->FinishEvent(); | ||
+ | } | ||
+ | } | ||
+ | return $strOld; | ||
} | } | ||
− | public function | + | public function AdminList() { |
− | global $ | + | global $vgPage,$vgOut; |
global $sql; | global $sql; | ||
− | |||
− | |||
$cntRow = 0; | $cntRow = 0; | ||
− | $ | + | if ($this->HasRows()) { |
− | + | $out = $vgOut->TableOpen('class=sortable'); | |
− | + | $out .= $vgOut->TblRowOpen(NULL,TRUE); | |
+ | $out .= $vgOut->TblCell('ID'); | ||
+ | $out .= $vgOut->TblCell('Cat #'); | ||
+ | $out .= $vgOut->TblCell('Status'); | ||
+ | $out .= $vgOut->TblCell('Description'); | ||
+ | $out .= $vgOut->TblCell('$ buy'); | ||
+ | $out .= $vgOut->TblCell('$ sell'); | ||
+ | $out .= $vgOut->TblRowShut(); | ||
$isOdd = TRUE; | $isOdd = TRUE; | ||
− | while ($ | + | while ($this->NextRow()) { |
− | + | $id = $this->ID; | |
− | $id = $ | + | //$wtID = SelfLink_Page('item','id',$id,$id); |
− | $wtID = | + | $wtID = $this->AdminLink(); |
$wtStyle = $isOdd?'background:#ffffff;':'background:#cccccc;'; | $wtStyle = $isOdd?'background:#ffffff;':'background:#cccccc;'; | ||
− | $isActive = $ | + | $isActive = $this->isForSale; |
− | $isInPrint = $ | + | $isCurrent = $this->isCurrent; |
− | $isPulled = $ | + | $isInPrint = $this->isInPrint; |
+ | $isPulled = $this->isPulled; | ||
if ($isActive) { | if ($isActive) { | ||
$cntRow++; | $cntRow++; | ||
Line 1,136: | Line 2,850: | ||
$wtStyle .= ' text-decoration: line-through;'; | $wtStyle .= ' text-decoration: line-through;'; | ||
} | } | ||
− | $ | + | $strStatus = ''; |
− | + | if ($isActive) { $strStatus .= '<span title="A=active" style="color:green;">A</span>'; } | |
− | + | if ($isCurrent) { $strStatus .= '<span title="C=current" style="color: #006600;">C</span>'; } | |
− | + | if ($isInPrint) { $strStatus .= '<span title="P=in print" style="color: blue;">P</span>'; } | |
− | + | if ($isPulled) { $strStatus .= '<span title="U=pulled" style="color: red;">U</span>'; } | |
− | + | $out .= $vgOut->TblRowOpen('style="'.$wtStyle.'"'); | |
− | if (!is_null($ | + | $out .= $vgOut->TblCell($wtID); |
− | $out .= | + | $out .= $vgOut->TblCell($this->CatNum); |
+ | $out .= $vgOut->TblCell($strStatus,'align=center'); | ||
+ | $out .= $vgOut->TblCell($this->ItOpt_Descr); | ||
+ | $out .= $vgOut->TblCell(DataCurr($this->PriceBuy)); | ||
+ | $out .= $vgOut->TblCell(DataCurr($this->PriceSell)); | ||
+ | $out .= $vgOut->TblRowShut(); | ||
+ | if (!is_null($this->Descr)) { | ||
+ | $out .= $vgOut->TblRowOpen('style="'.$wtStyle.'"'); | ||
+ | $out .= $vgOut->TblCell($this->Descr,'colspan=4'); | ||
+ | $out .= $vgOut->TblRowShut(); | ||
} | } | ||
$isOdd = !$isOdd; | $isOdd = !$isOdd; | ||
//$objLine = $objRecs->CloneFields(); | //$objLine = $objRecs->CloneFields(); | ||
− | $objLine = clone $ | + | $objLine = clone $this; |
} | } | ||
− | $out .= | + | $out .= $vgOut->TableShut(); |
− | /* | + | } else { |
− | $ | + | $out = 'No items listed. (SQL='.$sql.')'; |
− | + | } | |
− | + | return $out; | |
+ | } | ||
+ | public function Title() { | ||
+ | return $this->objDB->Titles()->GetItem($this->ID_Title); | ||
+ | } | ||
+ | public function ItTyp() { | ||
+ | return $this->objDB->ItTyps()->GetItem($this->ID_ItTyp); | ||
+ | } | ||
+ | public function FullDescr($iSep=' ') { | ||
+ | $objTitle = $this->Title(); | ||
+ | return $objTitle->Name.$iSep.$this->ItOpt_Descr; | ||
+ | } | ||
+ | public function FullDescr_HTML($iSep=' ') { | ||
+ | $objTitle = $this->Title(); | ||
+ | $objItTyp = $this->ItTyp(); | ||
+ | if ($objItTyp->IsNew()) { | ||
+ | $out = '(no item type)'; | ||
+ | } else { | ||
+ | $out = | ||
+ | // $objTitle->SelfLink($objTitle->Name).$iSep. | ||
+ | $objTitle->AdminLink($objTitle->Name).$iSep. | ||
+ | $objItTyp->Row['NameSng'].$iSep. | ||
+ | $this->ItOpt_Descr; | ||
+ | } | ||
+ | return $out; | ||
+ | } | ||
+ | /* 2010-11-11 This should be completely obsolete, right? | ||
+ | protected function ReceiveForm() { | ||
+ | global $wgOut,$wgRequest; | ||
+ | |||
+ | if ($wgRequest->getCheck('btnSave')) { | ||
+ | $intQtyNew = $wgRequest->GetInt('StkMin'); | ||
+ | $arUpd['QtyMin_Stk'] = $intQtyNew; | ||
+ | $intQtyOld = $this->QtyMin_Stk; | ||
+ | if ($intQtyOld == $intQtyNew) { | ||
+ | $out = 'No change requested; min qty is already '.$intQtyOld.'.'; | ||
+ | } else { | ||
+ | $strDescr = 'Updating per-item stock minimum from '.$intQtyOld.' to '.$intQtyNew; | ||
+ | $out = $strDescr; | ||
+ | $this->StartEvent(__METHOD__,'UPD',$strDescr); | ||
+ | $this->Update($arUpd); | ||
+ | $this->Reload(); | ||
+ | $this->FinishEvent(); | ||
} | } | ||
+ | $wgOut->AddWikiText($out); | ||
+ | } | ||
+ | } | ||
*/ | */ | ||
− | + | /*---- | |
− | + | HISTORY: | |
+ | 2011-02-24 Finally renamed from InfoPage() to AdminPage() | ||
+ | */ | ||
+ | public function AdminPage() { | ||
+ | global $wgOut,$wgRequest; | ||
+ | global $vgPage; | ||
+ | |||
+ | $strCatNum = $this->CatNum; | ||
+ | |||
+ | //$this->ReceiveForm(); | ||
+ | |||
+ | $vgPage->UseHTML(); | ||
+ | $objTitle = $this->Title(); | ||
+ | $strTitleName = $objTitle->Name; | ||
+ | $ftTitleLink = (is_object($objTitle))?($objTitle->AdminLink($strTitleName)):'title N/A'; | ||
+ | $strTitle = 'Item: '.$strCatNum.' ('.$this->ID.') - '.$this->FullDescr(); | ||
+ | |||
+ | $objPage = new clsWikiFormatter($vgPage); | ||
+ | $objSection = new clsWikiSection($objPage,$strTitle); | ||
+ | $objSection->ToggleAdd('edit'); | ||
+ | //$objSection->ActionAdd('view'); | ||
+ | $out = $objSection->Generate(); | ||
+ | |||
+ | $strAction = $vgPage->Arg('do'); | ||
+ | $doAdd = ($strAction == 'add'); | ||
+ | $doEdit = $vgPage->Arg('edit'); | ||
+ | $doSave = $wgRequest->GetBool('btnSave'); | ||
+ | |||
+ | if ($doEdit || $doSave) { | ||
+ | $this->BuildEditForm(); | ||
+ | if ($doSave) { | ||
+ | $this->AdminSave(); | ||
} | } | ||
+ | } | ||
+ | $ftPriceSell = $this->PriceSell; // this can be edited if item is not in print | ||
+ | if ($doEdit) { | ||
+ | $out .= $objSection->FormOpen(); | ||
+ | $objForm = $this->objForm; | ||
+ | $ftCatNum = $objForm->Render('CatNum'); | ||
+ | $ftCatSfx = $objForm->Render('CatSfx'); | ||
+ | $ftDescr = $objForm->Render('Descr'); | ||
+ | if (!$this->isInPrint) { | ||
+ | $ftPriceSell = $objForm->Render('PriceSell'); | ||
+ | } | ||
+ | $ftPriceList = $objForm->Render('PriceList'); | ||
+ | $ftSCatNum = $objForm->Render('Supp_CatNum'); | ||
+ | $ftStkMin = $objForm->Render('QtyMin_Stk'); | ||
} else { | } else { | ||
− | $out = ' | + | $ftCatNum = $this->CatNum; |
+ | $ftCatSfx = $this->CatSfx; | ||
+ | $ftDescr = $this->Descr; | ||
+ | $ftPriceList = $this->PriceList; | ||
+ | $ftSCatNum = $this->Supp_CatNum; | ||
+ | $ftStkMin = $this->QtyMin_Stk; | ||
+ | } | ||
+ | // non-editable fields: | ||
+ | $ftTitle = $ftTitleLink; | ||
+ | $ftPriceBuy = $this->PriceBuy; | ||
+ | $ftItOpt = $this->ID_ItOpt; | ||
+ | $ftIODescr = $this->ItOpt_Descr; | ||
+ | $ftIOSort = $this->ItOpt_Sort; | ||
+ | $ftGrpCode = $this->GrpCode; | ||
+ | $ftGrpDescr = $this->GrpDescr; | ||
+ | $ftGrpSort = $this->GrpSort; | ||
+ | |||
+ | $out .= '<ul>'; | ||
+ | $out .= '<li> <b>ID</b>: '.$this->ID; | ||
+ | $out .= '<li> <b>Cat #</b>: '.$ftCatNum.' <b>suffix</b>: '.$ftCatSfx; | ||
+ | $out .= '<li> <b>Description</b>: '.$ftDescr; | ||
+ | $out .= '<li> <b>Prices</b>: '.$ftItOpt; | ||
+ | $out .= '<ul>'; | ||
+ | $out .= '<li> <b>Buy</b>: '.$ftPriceBuy; | ||
+ | $out .= '<li> <b>Sell</b>: '.$ftPriceSell; | ||
+ | $out .= '<li> <i><b>List</b>: '.$ftPriceList.'</i>'; | ||
+ | $out .= '</ul>'; | ||
+ | $out .= '<li> <b>Item Option</b>: '.$ftItOpt; | ||
+ | $out .= '<ul>'; | ||
+ | $out .= '<li> <b>Descr</b>: '.$ftIODescr; | ||
+ | $out .= '<li> <b>Sort</b>: '.$ftIOSort; | ||
+ | $out .= '</ul>'; | ||
+ | $out .= '<li> <b>Group</b> - <b>code</b>: '.$ftGrpCode.' <b>descr</b>: '.$ftGrpDescr.' <b>sort</b>: '.$ftGrpSort; | ||
+ | $out .= '<li> <b>Title</b>: '.$ftTitle; | ||
+ | $out .= '<li> <b>Stk Min</b>: '.$ftStkMin; | ||
+ | $out .= '<li> <b>Status</b>:'; | ||
+ | if ($this->isMaster) { $out .= ' MASTER'; } | ||
+ | if ($this->isForSale) { $out .= ' FOR-SALE'; } | ||
+ | if ($this->isInPrint) { $out .= ' IN-PRINT'; } | ||
+ | if ($this->isCloseOut) { $out .= ' CLOSEOUT'; } | ||
+ | if ($this->isPulled) { $out .= ' PULLED'; } | ||
+ | if ($this->isDumped) { $out .= ' DUMPED'; } | ||
+ | $out .= '<li> <b>Supplier Cat #</b>:'.$ftSCatNum; | ||
+ | $out .= '</ul>'; | ||
+ | |||
+ | if ($doEdit) { | ||
+ | $out .= '<input type=submit name="btnSave" value="Save">'; | ||
+ | $out .= '<input type=reset value="Reset">'; | ||
+ | $out .= '</form>'; | ||
} | } | ||
− | $wgOut-> | + | $wgOut->AddHTML($out); |
+ | $wgOut->AddHTML("<h3>Stock</h3>"); | ||
+ | $wgOut->AddWikiText($this->StockListing(),TRUE); | ||
+ | $wgOut->AddHTML("<h3>Orders</h3>"); | ||
+ | $wgOut->AddWikiText($this->OrderListing(),TRUE); | ||
+ | $wgOut->AddHTML("<h3>Restocks</h3>"); | ||
+ | $wgOut->AddWikiText($this->RestockListing(),TRUE); | ||
+ | $wgOut->AddHTML('<h3>Events</h3>'); | ||
+ | $wgOut->AddWikiText($this->EventListing(),TRUE); | ||
} | } | ||
− | + | /*---- | |
− | + | HISTORY: | |
− | + | 2010-11-06 adapted from VbzStockBin | |
− | + | */ | |
+ | private function BuildEditForm() { | ||
+ | global $vgOut; | ||
+ | |||
+ | if (is_null($this->objForm)) { | ||
+ | // create fields & controls | ||
+ | $objForm = new clsForm_DataSet($this,$vgOut); | ||
+ | //$objCtrls = new clsCtrls($objForm->Fields()); | ||
+ | |||
+ | $objForm->AddField(new clsField('Descr'), new clsCtrlHTML(array('size'=>40))); | ||
+ | $objForm->AddField(new clsField('CatNum'), new clsCtrlHTML()); | ||
+ | $objForm->AddField(new clsField('CatSfx'), new clsCtrlHTML(array('size'=>5))); | ||
+ | $objForm->AddField(new clsFieldNum('PriceSell'), new clsCtrlHTML()); | ||
+ | $objForm->AddField(new clsFieldNum('PriceList'), new clsCtrlHTML()); | ||
+ | $objForm->AddField(new clsField('Supp_CatNum'), new clsCtrlHTML()); | ||
+ | $objForm->AddField(new clsFieldNum('QtyMin_Stk'), new clsCtrlHTML(array('size'=>3))); | ||
− | + | $this->objForm = $objForm; | |
− | + | //$this->objCtrls = $objCtrls; | |
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
} | } | ||
− | $out | + | } |
− | $out | + | /*---- |
+ | ACTION: Save user changes to the record | ||
+ | HISTORY: | ||
+ | 2010-11-06 copied from VbzStockBin to VbzAdminItem | ||
+ | */ | ||
+ | public function AdminSave() { | ||
+ | global $vgOut; | ||
+ | |||
+ | $out = $this->objForm->Save(); | ||
+ | $vgOut->AddText($out); | ||
+ | } | ||
+ | public function StockListing() { | ||
+ | $out = $this->objDB->StkItems()->Listing_forItem($this); | ||
return $out; | return $out; | ||
} | } | ||
− | public function | + | public function OrderListing() { |
− | $out = $this->objDB-> | + | $objTbl = $this->objDB->OrdItems(); |
+ | $objRows = $objTbl->GetData('ID_Item='.$this->ID); | ||
+ | $out = $objRows->AdminTable_forItem(); | ||
+ | return $out; | ||
+ | } | ||
+ | public function RestockListing() { | ||
+ | $objTbl = $this->objDB->RstkReqItems(); | ||
+ | $objRows = $objTbl->GetData('ID_Item='.$this->ID); | ||
+ | $out = $objRows->AdminList('No restocks found for this item'); | ||
return $out; | return $out; | ||
} | } | ||
− | + | /*---- | |
− | /* | + | RETURNS: wikitext which links to the catalog page for the item |
− | + | NOTE: Since the store doesn't yet have pages for each item, | |
− | + | this returns a link to the item's Title page | |
− | + | FUTURE: create StoreLink() function which uses RichText object | |
+ | */ | ||
+ | public function StoreLink_WT($iText) { | ||
+ | return '[[vbznet:cat/'.$this->Title()->URL_part().'|'.$iText.']]'; | ||
+ | } | ||
+ | // FUNCTION DEPRECATED - remove eventually | ||
+ | public function AdminLink_WT($iText) { | ||
+ | return '[[{{FULLPAGENAME}}/page'.KS_CHAR_URL_ASSIGN.'item/id'.KS_CHAR_URL_ASSIGN.$this->ID.'|'.$iText.']]'; | ||
+ | } | ||
+ | // FUNCTION DEPRECATED - remove eventually | ||
+ | public function StoreLink_HT($iText) { | ||
+ | return '<a href="'.KWP_CAT.$this->Title()->URL_part().'" title="browse in store">'.$iText.'</a>'; | ||
+ | } | ||
+ | } | ||
+ | class clsAdminItems_info_Cat extends clsItems_info_Cat { | ||
+ | public function __construct($iDB) { | ||
+ | parent::__construct($iDB); | ||
+ | $this->ActionKey('item'); | ||
+ | } | ||
+ | } | ||
+ | /******* | ||
+ | IMAGES | ||
*/ | */ | ||
− | + | class clsAdminImages extends clsImages { | |
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | class | ||
public function __construct($iDB) { | public function __construct($iDB) { | ||
parent::__construct($iDB); | parent::__construct($iDB); | ||
− | $this->ClassSng(' | + | $this->Name('cat_images'); |
+ | $this->KeyName('ID'); | ||
+ | $this->ClassSng('clsAdminImage'); | ||
} | } | ||
− | public function | + | /*----- |
− | global $ | + | ACTION: Processes form data, shows section header, loads image dataset, calls clsAdminImage::AdminList() to render |
− | global $ | + | INPUT: |
+ | iarArgs: array of options | ||
+ | ['filt'] = SQL filter for dataset to show ("WHERE" clause) | ||
+ | ['sort'] = sorting order for dataset to show ("ORDER BY" clause) | ||
+ | ['event.obj'] = object used for event logging | ||
+ | ['title.id'] = ID_Title to use for new records | ||
+ | ['new']: if TRUE, allow user to create new records when editing | ||
+ | */ | ||
+ | public function AdminPage(array $iarArgs) { | ||
+ | global $wgRequest; | ||
+ | global $vgPage,$vgOut; | ||
+ | |||
+ | $out = ''; | ||
+ | |||
+ | // get URL input | ||
+ | $doEdit = ($vgPage->Arg('edit.img')); | ||
+ | $doAdd = ($vgPage->Arg('add.img')); | ||
+ | $arArgs = $iarArgs; | ||
+ | $arArgs['edit'] = $doEdit; | ||
+ | $sqlFilt = $arArgs['filt']; | ||
+ | $sqlSort = $arArgs['sort']; | ||
+ | |||
+ | // display section header | ||
+ | // $strName = 'Images'; | ||
+ | |||
+ | $vgPage->UseHTML(); | ||
+ | $objPage = new clsWikiFormatter($vgPage); | ||
+ | $objSection = new clsWikiSection($objPage,'Images',NULL,3); | ||
+ | $objSection->ToggleAdd('edit','edit image records','edit.img'); | ||
+ | $objSection->ToggleAdd('add','add multiple image records','add.img'); | ||
+ | $out .= $objSection->Generate(); | ||
+ | |||
+ | // handle possible form requests | ||
+ | |||
+ | // -- bulk-entry form stage 1: check input | ||
+ | if ($wgRequest->getBool('btnCheckImgs')) { | ||
+ | $doCheck = TRUE; | ||
+ | $xts = new xtString($wgRequest->GetText('txtImgs')); | ||
+ | $arLines = $xts->ParseTextLines(array('line'=>'arr')); | ||
+ | $htForm = "\nImages submitted:\n<ul>"; | ||
+ | foreach ($arLines as $idx => $arLine) { | ||
+ | $txtURL = $arLine[0]; | ||
+ | $txtSize = isset($arLine[1])?$arLine[1]:NULL; | ||
+ | |||
+ | $rsFldr = $this->Engine()->Folders()->FindBest($txtURL); | ||
+ | if (is_null($rsFldr)) { | ||
+ | $htForm .= "\n<li>No folder found for <b>$txtUrl</b></li>"; | ||
+ | } else { | ||
+ | $fsFldr = $rsFldr->Value('PathPart'); | ||
+ | $fsImg = $rsFldr->Remainder($txtURL); | ||
+ | $idFldr = $rsFldr->KeyValue(); | ||
+ | |||
+ | $ftSize = empty($txtSize)?'':'<b>'.$txtSize.'</b> '; | ||
+ | $htForm .= "\n<li>$ftSize$fsFldr<a href=\"$fsFldr$fsImg\">$fsImg</a></li>"; | ||
+ | $htForm .= '<input type=hidden name="img-fldr['.$idx.']" value='.$idFldr.'>'; | ||
+ | $htForm .= '<input type=hidden name="img-spec['.$idx.']" value="'.$fsImg.'">'; | ||
+ | if (!is_null($txtSize)) { | ||
+ | $htForm .= '<input type=hidden name="img-size['.$idx.']" value="'.$txtSize.'">'; | ||
+ | } | ||
+ | } | ||
+ | } | ||
+ | $htForm .= '</ul>'; | ||
+ | } else { $doCheck = FALSE; } | ||
+ | // -- bulk-entry form stage 2: create records | ||
+ | if ($wgRequest->getBool('btnAddImgs')) { | ||
+ | $arFldrs = $wgRequest->GetArray('img-fldr'); | ||
+ | $arSpecs = $wgRequest->GetArray('img-spec'); | ||
+ | $arSizes = $wgRequest->GetArray('img-size'); | ||
+ | $idTitle = $vgPage->Arg('id'); | ||
+ | assert('!empty($idTitle);'); | ||
+ | |||
+ | // log event to the title | ||
+ | $objTitle = $this->Engine()->Titles($idTitle); | ||
+ | $cntImgs = count($arFldrs); | ||
+ | $arEv = array( | ||
+ | 'descr' => 'Adding '.$cntImgs.' image'.Pluralize($cntImgs), | ||
+ | 'where' => __METHOD__, | ||
+ | 'code' => 'IMG++' | ||
+ | ); | ||
+ | $objTitle->StartEvent($arEv); | ||
+ | |||
+ | foreach ($arFldrs as $idx => $idFldr) { | ||
+ | $fs = $arSpecs[$idx]; | ||
+ | $sz = $arSizes[$idx]; | ||
+ | $arIns = array( | ||
+ | 'ID_Folder' => $idFldr, | ||
+ | 'isActive' => 'TRUE', | ||
+ | 'Spec' => SQLValue($fs), | ||
+ | 'ID_Title' => $idTitle, | ||
+ | 'WhenAdded' => 'NOW()' | ||
+ | ); | ||
+ | if (!empty($sz)) { | ||
+ | $arIns['Ab_Size'] = SQLValue($sz); | ||
+ | } | ||
+ | $this->Insert($arIns); | ||
+ | $strNew = ' '.$this->LastID(); | ||
+ | } | ||
+ | $arEv = array( | ||
+ | 'descrfin' => 'New ID'.Pluralize($cntImgs).':'.$strNew | ||
+ | ); | ||
+ | $objTitle->FinishEvent($arEv); | ||
+ | } | ||
+ | // -- existing item edit form | ||
+ | if ($wgRequest->getBool('btnSaveImgs')) { | ||
+ | |||
+ | $arUpdate = $wgRequest->getArray('update'); | ||
+ | $arDelete = $wgRequest->getArray('del'); | ||
+ | $arActive = $wgRequest->getArray('isActive'); | ||
+ | $arFolder = $wgRequest->getArray('ID_Folder'); | ||
+ | $arFileSpec = $wgRequest->getArray('txtFileSpec'); | ||
+ | $arAttrSize = $wgRequest->getArray('txtAttrSize'); | ||
+ | $arAttrFldr = $wgRequest->getArray('txtAttrFldr'); | ||
+ | $arAttrDispl = $wgRequest->getArray('txtAttrDispl'); | ||
+ | $arAttrSort = $wgRequest->getArray('txtAttrSort'); | ||
+ | |||
+ | if (count($arActive > 0)) { | ||
+ | // add any reactivated rows to the update list | ||
+ | foreach ($arActive as $id => $null) { | ||
+ | $arUpdate[$id] = TRUE; | ||
+ | } | ||
+ | } | ||
− | + | $cntRows = count($arUpdate); | |
− | + | if ($cntRows > 0) { | |
+ | $out .= '<b>Updating</b>: '; | ||
+ | $txtEvDescr = 'Checking '.$cntRows.' record'.Pluralize($cntRows); | ||
+ | $txtRowEdits = ''; | ||
+ | $txtRowFlips = ''; | ||
− | + | $doLog = isset($arArgs['event.obj']); | |
− | + | if ($doLog) { | |
− | + | $objLog = $arArgs['event.obj']; | |
− | + | $arEv = array( | |
− | + | 'descr' => $txtEvDescr, | |
− | + | 'where' => __METHOD__, | |
+ | 'code' => 'IMG SVM' // image save multiple | ||
+ | ); | ||
+ | $objLog->StartEvent($arEv); | ||
+ | } | ||
− | $ | + | $cntUpd = 0; |
− | + | foreach ($arUpdate as $id => $null) { | |
+ | $isActive = isset($arActive[$id]); | ||
+ | $isNew = ($id == 'new'); | ||
+ | if (empty($arFileSpec[$id])) { | ||
+ | $isNew = FALSE; // nothing to save | ||
+ | } | ||
+ | $objImg = $this->GetItem($id); | ||
− | + | if ($isNew) { | |
− | + | $isDiff = TRUE; | |
− | + | $doSaveActive = TRUE; | |
− | + | $doSaveValues = TRUE; | |
− | + | } else { | |
− | + | $isDiff = ((int)$isActive != (int)$objImg->isActive); | |
+ | $isStateChg = $isDiff; | ||
+ | $doSaveActive = $isDiff; | ||
+ | $doSaveValues = !$isDiff; | ||
+ | } | ||
+ | if (!$isDiff) { | ||
+ | $arUpd = array( | ||
+ | 'ID_Folder' => $arFolder[$id], | ||
+ | 'Spec' => $arFileSpec[$id], | ||
+ | 'Ab_Size' => $arAttrSize[$id], | ||
+ | 'AttrFldr' => nz($arAttrFldr[$id]), | ||
+ | 'AttrDispl' => nz($arAttrDispl[$id]), | ||
+ | 'AttrSort' => nz($arAttrSort[$id]) | ||
+ | ); | ||
+ | $isDiff = !$objImg->SameAs($arUpd); | ||
+ | } | ||
+ | $arUpd = NULL; | ||
+ | if ($isDiff) { | ||
+ | if ($doSaveValues) { | ||
+ | $arUpd = array( | ||
+ | 'ID_Folder' => SQLValue($arFolder[$id]), | ||
+ | 'Spec' => SQLValue($arFileSpec[$id]), | ||
+ | 'Ab_Size' => SQLValue($arAttrSize[$id]), | ||
+ | 'AttrFldr' => SQLValue(nz($arAttrFldr[$id])), | ||
+ | 'AttrDispl' => SQLValue(nz($arAttrDispl[$id])), | ||
+ | 'AttrSort' => SQLValue(nz($arAttrSort[$id])) | ||
+ | ); | ||
+ | $txtRowEdits .= ' #'.$id; | ||
+ | } | ||
+ | if ($doSaveActive) { | ||
+ | $arUpd['isActive'] = SQLValue($isActive); | ||
+ | $txtRowFlips .= ' #'.$id.'('.NoYes($isActive,'off','ON').')'; | ||
+ | } | ||
+ | if ($isNew) { | ||
+ | // create new record | ||
+ | $idTitle = (int)$arArgs['title.id']; | ||
+ | assert('is_int($idTitle)'); | ||
+ | $arUpd['ID_Title'] = $idTitle; | ||
+ | $this->Insert($arUpd); | ||
+ | } else { | ||
+ | // not new: just update | ||
+ | $objImg->Update($arUpd); | ||
+ | //global $sql; | ||
+ | //$out .= '<br>SQL: '.$objImg->sqlExec; | ||
+ | } | ||
+ | $cntUpd++; | ||
+ | } | ||
} | } | ||
− | $ | + | if ($doLog) { |
− | + | $txtStat = $cntUpd.' image'.Pluralize($cntUpd).' updated -'; | |
− | + | if (!empty($txtRowFlips)) { | |
− | + | $txtStat .= ' toggled:'.$txtRowEdits; | |
− | + | } | |
− | + | if (!empty($txtRowEdits)) { | |
− | + | $txtStat .= ' edits:'.$txtRowEdits; | |
− | + | } | |
− | + | $arEv = array( | |
− | $ | + | 'descrfin' => SQLValue($txtStat) |
+ | ); | ||
+ | $objLog->FinishEvent($arEv); | ||
} | } | ||
+ | $out .= $txtStat; | ||
+ | } else { | ||
+ | $out .= 'No image records selected for update.'; | ||
+ | } | ||
+ | } | ||
+ | // render edit form outer shell: | ||
+ | if ($doEdit || $doAdd || $doCheck) { | ||
+ | $arLink = $vgPage->Args(array('page','id')); | ||
+ | $urlSelf = $vgPage->SelfURL($arLink,TRUE); | ||
+ | $arArgs['pfx'] = '<form method=post action="'.$urlSelf.'">'; | ||
+ | |||
+ | if ($doEdit) { | ||
+ | $sfx = '<input type=submit name=btnSaveImgs value="Save">'; | ||
+ | $sfx .= '<input type=reset value="Revert">'; | ||
+ | } | ||
+ | if ($doAdd) { | ||
+ | $sfx = 'Enter images, one complete URL per line:'; | ||
+ | $sfx .= '<textarea name=txtImgs rows=6></textarea>'; | ||
+ | $sfx .= '<input type=submit name=btnCheckImgs value="Check">'; | ||
+ | } | ||
+ | if ($doCheck) { | ||
+ | $sfx = $htForm; // calculated earlier | ||
+ | $sfx .= '<input type=submit name=btnAddImgs value="Add These">'; | ||
+ | } | ||
+ | $sfx .= '</form>'; | ||
+ | $arArgs['sfx'] = $sfx; | ||
+ | } | ||
+ | |||
+ | // load the latest data and show it in a table: | ||
+ | $arArgs['none'] = 'No images found.'; | ||
+ | $objRows = $this->GetData($sqlFilt,NULL,$sqlSort); | ||
+ | $out .= $objRows->AdminList($arArgs); | ||
+ | |||
+ | return $out; | ||
+ | } | ||
+ | /*---- | ||
+ | HISTORY: | ||
+ | 2010-10-19 Adapted from AdminPage() | ||
+ | 2010-11-16 Commented out editing functions, per earlier thought, after partly updating them. | ||
+ | Note: they were written for AdminPage(). | ||
+ | */ | ||
+ | public function AdminPage_Unassigned() { | ||
+ | global $wgRequest,$wgOut; | ||
+ | global $vgPage,$vgOut; | ||
+ | |||
+ | $out = ''; | ||
+ | |||
+ | // get URL input | ||
+ | $doEdit = ($vgPage->Arg('edit.img')); | ||
+ | $arArgs['edit'] = $doEdit; | ||
+ | |||
+ | // display section header | ||
+ | // $strName = 'Images'; | ||
+ | |||
+ | $vgPage->UseHTML(); | ||
+ | $objPage = new clsWikiFormatter($vgPage); | ||
+ | $objSection = new clsWikiSection($objPage,'Unassigned Images',NULL,3); | ||
+ | $objSection->ToggleAdd('edit','edit image records','edit.img'); | ||
+ | $out .= $objSection->Generate(); | ||
+ | |||
+ | // load the latest data and show it in a table: | ||
+ | $arArgs['none'] = 'No unassigned images found.'; | ||
+ | $sqlFilt = 'ID_Title IS NULL'; | ||
+ | $sqlSort = NULL; // maybe this could be useful later | ||
+ | $objRows = $this->GetData($sqlFilt,NULL,$sqlSort); | ||
+ | $out .= $objRows->AdminList($arArgs); | ||
+ | |||
+ | $objSection = new clsWikiSection($objPage,'Imageless Active Titles',NULL,3); | ||
+ | $out .= $objSection->Generate(); | ||
+ | $objRows = $this->objDB->Titles()->Data_Imageless(); | ||
+ | $out .= $objRows->AdminList($arArgs); | ||
+ | |||
+ | $wgOut->AddHTML($out); $out = NULL; | ||
+ | return $out; | ||
+ | } | ||
+ | } | ||
+ | class clsAdminImage extends clsImage { | ||
+ | /*----- | ||
+ | ACTION: Renders dataset as a table | ||
+ | INPUT: iarArgs | ||
+ | none: text to insert as description if no records | ||
+ | pfx: html to include before table rows, if there is data | ||
+ | sfx: html to include after table rows, if there is data | ||
+ | edit: render editable fields | ||
+ | new: allow entering new records -- show edit even if no data | ||
+ | */ | ||
+ | public function AdminList(array $iarArgs) { | ||
+ | $out = ''; | ||
+ | $doNew = nz($iarArgs['new']); | ||
+ | if ($doNew || $this->HasRows()) { | ||
+ | $doEdit = nz($iarArgs['edit']); | ||
+ | $out .= nz($iarArgs['pfx']); | ||
+ | $out .= "\n<table>"; | ||
+ | $out .= '<tr><td colspan=4></td><th colspan=4 bgcolor="#cceeff">attributes</th></tr>'; | ||
+ | $out .= '<tr>' | ||
+ | .'<th>ID</th>' | ||
+ | .'<th>A?</th>' | ||
+ | .'<th>folder</th>' | ||
+ | .'<th>filename</th>' | ||
+ | .'<th>size</th>' | ||
+ | .'<th bgcolor="#cceeff">folder</th>' | ||
+ | .'<th bgcolor="#cceeff">description</th>' | ||
+ | .'<th bgcolor="#cceeff">sorting</th>' | ||
+ | .'</tr>'; | ||
+ | $isOdd = FALSE; | ||
+ | while ($this->NextRow()) { | ||
+ | $out .= $this->AdminListRow($doEdit,$isOdd); | ||
$isOdd = !$isOdd; | $isOdd = !$isOdd; | ||
} | } | ||
− | $out .= "\n | + | if ($doEdit) { |
+ | // when editing, we also allow for adding a new record | ||
+ | $out .= $this->AdminListRow($doEdit,$isOdd,TRUE); | ||
+ | } | ||
+ | $out .= "\n</table>"; | ||
+ | $out .= nz($iarArgs['sfx']); | ||
} else { | } else { | ||
− | $out = ' | + | if (isset($iarArgs['none'])) { |
+ | $out .= $iarArgs['none']; | ||
+ | } else { | ||
+ | $out .= 'No images found.'; | ||
+ | } | ||
} | } | ||
return $out; | return $out; | ||
} | } | ||
− | } | + | protected function AdminListRow($iEdit,$iOdd,$iNew=FALSE) { |
− | + | $isOdd = $iOdd; | |
− | + | $doEdit = $iEdit; | |
− | + | ||
− | + | if ($iNew) { | |
+ | $doEdit = TRUE; | ||
+ | $isActive = TRUE; | ||
+ | $id = 'new'; | ||
+ | $txtFileSpec = ''; | ||
+ | $txtFolder = ''; | ||
+ | $txtAttrSize = ''; | ||
+ | $txtAttrFldr = ''; | ||
+ | $txtAttrDispl = ''; | ||
+ | $txtAttrSort = ''; | ||
+ | } else { | ||
+ | $id = $this->ID; | ||
+ | $wtID = $id; | ||
+ | $isActive = $this->isActive; | ||
+ | $txtFileSpec = $this->Spec; | ||
+ | $txtFolder = $this->FolderPath(); | ||
+ | $txtAttrSize = $this->Ab_Size; | ||
+ | $txtAttrFldr = $this->AttrFldr; | ||
+ | $txtAttrDispl = $this->AttrDispl; | ||
+ | $txtAttrSort = $this->AttrSort; | ||
+ | } | ||
+ | |||
+ | $wtStyle = $isOdd?'background:#ffffff;':'background:#eeeeee;'; | ||
+ | if ($isActive) { | ||
+ | $wtStyleCell = ''; | ||
+ | $ftActive = '√'; | ||
+ | } else { | ||
+ | $wtStyle .= ' color: #888888;'; | ||
+ | $wtStyleCell = ' style="text-decoration: line-through;"'; | ||
+ | $ftActive = ''; | ||
+ | } | ||
+ | if ($doEdit) { | ||
+ | // replace field values with editable versions | ||
+ | if ($isActive) { | ||
+ | $wtID = '<input type=hidden name=update['.$id.'] value=1>'.$id; | ||
+ | } else { | ||
+ | $wtID = '<input type=checkbox name=del['.$id.'] title="check rows to delete">'.$id; | ||
+ | } | ||
+ | $htEnabled = $isActive?'':' disabled'; | ||
+ | $ftActive = '<input type=checkbox name=isActive['.$id.'] title="check if this image should be used"'.($isActive?' checked':'').'>'; | ||
+ | $htFolder = $this->objDB->Folders()->DropDown('ID_Folder['.$id.']',$this->ID_Folder); | ||
+ | $htFileSpec = '<input'.$htEnabled.' size=20 name=txtFileSpec['.$id.'] value="'.htmlspecialchars($txtFileSpec).'">'; | ||
+ | $htAttrSize = '<input'.$htEnabled.' size=4 name=txtAttrSize['.$id.'] value="'.htmlspecialchars($txtAttrSize).'">'; | ||
+ | $htAttrFldr = '<input'.$htEnabled.' size=4 name=txtAttrFldr['.$id.'] value="'.htmlspecialchars($txtAttrFldr).'">'; | ||
+ | $htAttrDispl = '<input'.$htEnabled.' size=10 name=txtAttrDispl['.$id.'] value="'.htmlspecialchars($txtAttrDispl).'">'; | ||
+ | $htAttrSort = '<input'.$htEnabled.' size=2 name=txtAttrSort['.$id.'] value="'.htmlspecialchars($txtAttrSort).'">'; | ||
+ | } else { | ||
+ | $htFolder = $txtFolder; | ||
+ | $htFileSpec = $txtFileSpec = '<a href="'.$this->WebSpec().'">'.$txtFileSpec.'</a>'; | ||
+ | |||
+ | $htAttrSize = $txtAttrSize; | ||
+ | $htAttrFldr = $txtAttrFldr; | ||
+ | $htAttrDispl = $txtAttrDispl; | ||
+ | $htAttrSort = $txtAttrSort; | ||
+ | } | ||
+ | |||
+ | $out = "\n<tr style=\"$wtStyle\">". | ||
+ | "\n<td align=right$wtStyleCell>$wtID</td>". | ||
+ | "\n<td$wtStyleCell>$ftActive</td>". | ||
+ | "\n<td$wtStyleCell>$htFolder</td>". | ||
+ | "\n<td$wtStyleCell>$htFileSpec</td>". | ||
+ | "\n<td$wtStyleCell>$htAttrSize</td>". | ||
+ | "\n<td$wtStyleCell>$htAttrFldr</td>". | ||
+ | "\n<td$wtStyleCell>$htAttrDispl</td>". | ||
+ | "\n<td$wtStyleCell>$htAttrSort</td>". | ||
+ | "\n</tr>"; | ||
+ | |||
+ | return $out; | ||
} | } | ||
} | } | ||
+ | /****** | ||
+ | SHIPPING | ||
+ | */ | ||
class clsShipments extends clsVbzTable { | class clsShipments extends clsVbzTable { | ||
public function __construct($iDB) { | public function __construct($iDB) { | ||
Line 1,265: | Line 3,547: | ||
$this->KeyName('ID'); | $this->KeyName('ID'); | ||
$this->ClassSng('clsShipment'); | $this->ClassSng('clsShipment'); | ||
+ | $this->ActionKey('shpmt'); | ||
} | } | ||
protected function _newItem() { | protected function _newItem() { | ||
return new clsCatPage($this); | return new clsCatPage($this); | ||
} | } | ||
− | public function | + | public function GetActive($iSort=NULL) { |
+ | $objRows = $this->GetData('WhenClosed IS NULL',NULL,$iSort); | ||
+ | return $objRows; | ||
+ | } | ||
+ | public function AdminPage() { | ||
global $wgOut; | global $wgOut; | ||
+ | global $vgPage; | ||
$out = '==Shipments=='; | $out = '==Shipments=='; | ||
$wgOut->addWikiText($out,TRUE); $out = ''; | $wgOut->addWikiText($out,TRUE); $out = ''; | ||
+ | |||
+ | $vgPage->UseWiki(); | ||
+ | |||
$objRecs = $this->GetData(NULL,NULL,'ID DESC'); | $objRecs = $this->GetData(NULL,NULL,'ID DESC'); | ||
if ($objRecs->HasRows()) { | if ($objRecs->HasRows()) { | ||
Line 1,280: | Line 3,571: | ||
while ($objRecs->NextRow()) { | while ($objRecs->NextRow()) { | ||
$id = $objRecs->ID; | $id = $objRecs->ID; | ||
− | $wtID = | + | //$wtID = SelfLink_Page('shipmt','id',$id,$id); |
+ | $wtID = $objRecs->AdminLink(); | ||
$wtStyle = $isOdd?'background:#ffffff;':'background:#cccccc;'; | $wtStyle = $isOdd?'background:#ffffff;':'background:#cccccc;'; | ||
$wtCode = $objRecs->Abbr; | $wtCode = $objRecs->Abbr; | ||
Line 1,308: | Line 3,600: | ||
} | } | ||
} | } | ||
− | class clsShipment extends | + | class clsShipment extends clsVbzRecs { |
− | public function InfoPage() { | + | /*---- |
+ | HISTORY: | ||
+ | 2010-10-11 Added iarArgs parameter | ||
+ | */ | ||
+ | public function AdminLink($iText=NULL,$iPopup=NULL,array $iarArgs=NULL) { | ||
+ | return clsAdminData::_AdminLink($this,$iText,$iPopup,$iarArgs); | ||
+ | } | ||
+ | public function AdminLink_name() { | ||
+ | return $this->AdminLink($this->ShortName()); | ||
+ | } | ||
+ | public function ShortName() { | ||
+ | return $this->Value('Abbr'); | ||
+ | } | ||
+ | /*---- | ||
+ | ACTION: Redirect to the url of the admin page for this object | ||
+ | HISTORY: | ||
+ | 2010-11-26 copied from VbzAdminCatalog to clsRstkRcd | ||
+ | 2011-01-02 copied from clsRstkRcd to VbzAdminOrderTrxact | ||
+ | 2011-09-24 copied from VbzAdminOrderTrxact to clsShipment | ||
+ | */ | ||
+ | public function AdminRedirect(array $iarArgs=NULL) { | ||
+ | return clsAdminData::_AdminRedirect($this,$iarArgs); | ||
+ | } | ||
+ | /*----- | ||
+ | TO DO: | ||
+ | * Convert old-style edit/header to new, wherever that is | ||
+ | HISTORY: | ||
+ | 2011-03-29 renamed from InfoPage() to AdminPage() | ||
+ | */ | ||
+ | public function AdminPage() { | ||
+ | global $wgOut,$wgRequest; | ||
+ | global $vgPage; | ||
+ | |||
+ | $vgPage->UseHTML(); | ||
+ | |||
+ | // check for form data | ||
+ | $doNew = ($vgPage->Arg('id') == 'new'); | ||
+ | $didAdd = FALSE; | ||
+ | |||
+ | // 2011-09-02 This was the old code for saving a new record. Keeping it in case tweaks are needed to the new code. | ||
+ | /* | ||
+ | if ($wgRequest->getBool('btnCreate')) { | ||
+ | $wgOut->AddWikiText('==Creating Shipment==',TRUE); | ||
+ | // create new record from form data | ||
+ | $strAbbr = $wgRequest->getText('abbr'); | ||
+ | $strDescr = $wgRequest->getText('descr'); | ||
+ | $strNotes = $wgRequest->getText('notes'); | ||
+ | |||
+ | $arEv = array( | ||
+ | 'descr' => 'new shipment', | ||
+ | 'where' => __METHOD__, | ||
+ | 'code' => 'new' | ||
+ | ); | ||
+ | $this->StartEvent($arEv); | ||
+ | $arIns = array( | ||
+ | 'id' => 0, | ||
+ | 'WhenCreated' => 'NOW()', | ||
+ | 'Abbr' => SQLValue($strAbbr), | ||
+ | 'Descr' => SQLValue($strDescr), | ||
+ | 'Notes' => SQLValue($strNotes) | ||
+ | ); | ||
+ | $this->Table->Insert($arIns); | ||
+ | $this->ID = $this->Table->LastID(); | ||
+ | $wgOut->AddWikiText('New ID='.$this->ID,TRUE); | ||
+ | $this->Reload(); // load the newly-created record | ||
+ | $didAdd = TRUE; // a new record has just been created | ||
+ | $this->FinishEvent(array('id'=>$this->ID)); | ||
+ | } | ||
+ | */ | ||
+ | |||
+ | // check for more actions: | ||
+ | $doEdit = ($doNew || $vgPage->Arg('edit')); | ||
+ | $doClose = $vgPage->Arg('close'); | ||
+ | $doSave = $wgRequest->getBool('btnSave'); | ||
+ | |||
+ | if ($doClose) { | ||
+ | // add up totals | ||
+ | $objRecs = $this->PkgsData(); | ||
+ | if ($objRecs->HasRows()) { | ||
+ | $wgOut->AddWikiText('==Closing Shipment==',TRUE); | ||
+ | $ok = TRUE; | ||
+ | $dlrShip = 0; | ||
+ | $dlrPack = 0; | ||
+ | $cntPkgErr = 0; | ||
+ | $out = ''; | ||
+ | while ($objRecs->NextRow()) { | ||
+ | $out .= '<br>Pkg ID '.$objRecs->AdminLink(); | ||
+ | if (is_null($objRecs->ShipCost)) { | ||
+ | $out .= ': no shipping cost!'; | ||
+ | $ok = FALSE; | ||
+ | $cntPkgErr++; | ||
+ | } elseif (is_null($objRecs->PkgCost)) { | ||
+ | $out .= ': no materials cost!'; | ||
+ | $ok = FALSE; | ||
+ | $cntPkgErr++; | ||
+ | } else { | ||
+ | $dlrShip += $objRecs->ShipCost; | ||
+ | $dlrPack += $objRecs->PkgCost; | ||
+ | } | ||
+ | } | ||
+ | if ($ok) { | ||
+ | $strUpd = '$'.$dlrShip.' shipping, $'.$dlrPack.' materials'; | ||
+ | $out = '<br>Cost totals: '.$strUpd; | ||
+ | } else { | ||
+ | $out .= '<br>'.$cntPkgErr.Pluralize($cntPkgErr,' package has','packages have').' missing information.'; | ||
+ | } | ||
+ | } else { | ||
+ | $ok = FALSE; | ||
+ | $out = 'No packages in shipment; nothing to close.'; | ||
+ | } | ||
+ | $wgOut->AddHTML($out); $out=NULL; | ||
+ | |||
+ | if ($ok) { | ||
+ | // log the attempt | ||
+ | $arEv = array( | ||
+ | 'descr' => 'closing shipment: '.$strUpd, | ||
+ | 'where' => __METHOD__, | ||
+ | 'code' => 'CLO' | ||
+ | ); | ||
+ | $this->StartEvent($arEv); | ||
+ | |||
+ | // fill in stats | ||
+ | $arUpd = array( | ||
+ | 'WhenClosed' => 'NOW()', | ||
+ | 'OrderCost' => $dlrShip, | ||
+ | 'SupplCost' => $dlrPack | ||
+ | ); | ||
+ | $this->Update($arUpd); | ||
+ | global $sql; | ||
+ | $out = '<br>Shipment updated - SQL: '.$sql; | ||
+ | $this->Reload(); | ||
+ | |||
+ | // log the completion | ||
+ | $this->FinishEvent(); | ||
+ | $wgOut->AddWikiText($out,TRUE); $out=NULL; | ||
+ | } | ||
+ | } | ||
+ | |||
+ | if ($doEdit || $doSave) { | ||
+ | $this->BuildEditForm(); | ||
+ | if ($doSave) { | ||
+ | $this->AdminSave(); | ||
+ | } | ||
+ | } | ||
+ | |||
+ | $htAbbr = htmlspecialchars($this->Abbr); | ||
+ | $htDescr = htmlspecialchars($this->Descr); | ||
+ | $htNotes = htmlspecialchars($this->Notes); | ||
+ | // values which are always static | ||
+ | if ($doNew) { | ||
+ | $strID = 'NEW'; | ||
+ | $strTitle = 'NEW Shipment'; | ||
+ | } else { | ||
+ | if ($didAdd) { | ||
+ | $strID = $this->AdminLink(); | ||
+ | } else { | ||
+ | $strID = $this->ID; | ||
+ | } | ||
+ | $strTitle = 'Shipment '.$htAbbr; | ||
+ | } | ||
+ | $out = ''; | ||
+ | if ($doEdit) { | ||
+ | // open editing form | ||
+ | $sqlID = $doNew?'new':$this->ID; | ||
+ | $arLink = array( | ||
+ | 'edit' => FALSE, | ||
+ | 'id' => $sqlID | ||
+ | ); | ||
+ | $htPath = $vgPage->SelfURL($arLink); | ||
+ | $out .= "\n<form method=post action=\"$htPath\">"; | ||
+ | // code for editable values | ||
+ | /* | ||
+ | $strAbbr = '<input name=abbr type=text size=16 value="'.$htAbbr.'">'; | ||
+ | $strDescr = '<input name=descr type=text size=50 value="'.$htDescr.'">'; | ||
+ | $strNotes = '<textarea name=notes width=50 height=3>'.$htNotes.'</textarea>'; | ||
+ | */ | ||
+ | $objForm = $this->objForm; | ||
+ | $ctrlAbbr = $objForm->Render('Abbr'); | ||
+ | $ctrlDescr = $objForm->Render('Descr'); | ||
+ | $ctrlNotes = $objForm->Render('Notes'); | ||
+ | |||
+ | $ctrlWhenCre = $objForm->Render('WhenCreated'); | ||
+ | $ctrlWhenShp = $objForm->Render('WhenShipped'); | ||
+ | $ctrlCostRcpt = '$'.$objForm->Render('ReceiptCost'); | ||
+ | $ctrlCostOuts = '$'.$objForm->Render('OutsideCost'); | ||
+ | $ctrlCostOrdr = '$'.$objForm->Render('OrderCost'); | ||
+ | $ctrlCostSupp = '$'.$objForm->Render('SupplCost'); | ||
+ | $ctrlCarrier = $objForm->Render('Carrier'); | ||
+ | |||
+ | $ctrlIsDedic = $objForm->Render('isDedicated'); | ||
+ | $ctrlIsOnHold = $objForm->Render('isOnHold'); | ||
+ | $ctrlStatus = $ctrlIsDedic.'dedicated '.$ctrlIsOnHold.'on hold'; | ||
+ | |||
+ | $htClose = ''; | ||
+ | } else { | ||
+ | // Only allow closing the shipment if we're not editing. | ||
+ | // Clicking a link from edit mode loses any edits. | ||
+ | if (is_null($this->WhenClosed)) { | ||
+ | $arLink = array( | ||
+ | 'close' => TRUE, | ||
+ | ); | ||
+ | $htClose = ' ['.$vgPage->SelfLink($arLink,'close the shipment','set closing timestamp and add up totals').']'; | ||
+ | } else { | ||
+ | $htClose = ''; // already closed | ||
+ | } | ||
+ | |||
+ | // code for static values | ||
+ | $ctrlAbbr = $htAbbr; | ||
+ | $ctrlDescr = $htDescr; | ||
+ | $ctrlNotes = $htNotes; | ||
+ | |||
+ | $ctrlWhenCre = $this->WhenCreated; | ||
+ | $ctrlWhenShp = $this->WhenShipped; | ||
+ | $ctrlCostRcpt = $this->ReceiptCost; | ||
+ | $ctrlCostOuts = $this->OutsideCost; | ||
+ | $ctrlCostOrdr = $this->OrderCost; | ||
+ | $ctrlCostSupp = $this->SupplCost; | ||
+ | $ctrlCarrier = $this->Carrier; | ||
+ | |||
+ | $isDedicated = (ord($this->isDedicated)); | ||
+ | $isOnHold = (ord($this->isOnHold)); | ||
+ | if ($isDedicated || $isOnHold) { | ||
+ | $ctrlStatus = ($isDedicated?'Dedicated':'') . ($isOnHold?' OnHold':''); | ||
+ | } else { | ||
+ | $ctrlStatus = '<i>normal</i>'; | ||
+ | } | ||
+ | } | ||
+ | // non-editable controls | ||
+ | $ctrlWhenClo = $this->WhenClosed.$htClose; | ||
+ | |||
+ | $out .= WikiSectionHdr_Edit($strTitle,$doEdit); // old style | ||
+ | // $out .= "\n<h2>$strTitle</h2>"; | ||
+ | |||
+ | $out .= "\n<table>"; | ||
+ | $out .= "\n<tr><td align=right valign=top><b>ID</b>:</td><td>$strID</td></tr>"; | ||
+ | $out .= "\n<tr><td align=right valign=top><b>Name</b>:</td><td>$ctrlAbbr</td></tr>"; | ||
+ | $out .= "\n<tr><td align=right valign=top><b>Description</b>:</td><td>$ctrlDescr</td></tr>"; | ||
+ | $out .= "\n<tr><td align=right valign=top><b>Type</b>:</td><td>$ctrlStatus</td></tr>"; | ||
+ | if (!$doNew) { | ||
+ | $out .= "\n<tr><td align=right valign=top><b>When Created</b>:</td><td>$ctrlWhenCre</td></tr>"; | ||
+ | $out .= "\n<tr><td align=right valign=top><b>When Shipped</b>:</td><td>$ctrlWhenShp</td></tr>"; | ||
+ | $out .= "\n<tr><td align=right valign=top><b>When Closed</b>:</td><td>$ctrlWhenClo</td></tr>"; | ||
+ | $out .= "\n<tr><td align=right valign=top><b>Receipt Cost</b>:</td><td>$ctrlCostRcpt</td></tr>"; | ||
+ | $out .= "\n<tr><td align=right valign=top><b>Outside Cost</b>:</td><td>$ctrlCostOuts</td></tr>"; | ||
+ | $out .= "\n<tr><td align=right valign=top><b>Order Cost</b>:</td><td>$ctrlCostOrdr</td></tr>"; | ||
+ | $out .= "\n<tr><td align=right valign=top><b>Supplier Cost</b>:</td><td>$ctrlCostSupp</td></tr>"; | ||
+ | } | ||
+ | $out .= "\n<tr><td align=right valign=top><b>Carrier</b>:</td><td>$ctrlCarrier</td></tr>"; | ||
+ | $out .= "\n<tr><td align=right valign=top><b>Notes</b>:</td><td>$ctrlNotes</td></tr>"; | ||
+ | $out .= "\n</table>"; | ||
+ | if ($doEdit) { | ||
+ | // form buttons | ||
+ | if ($doNew) { | ||
+ | // next line needed only if we have special code for Create vs. Save | ||
+ | // $out .= '<input type=submit name="btnCreate" value="Create">'; | ||
+ | // 2011-09-02 testing this instead: | ||
+ | $out .= '<input type=submit name="btnSave" value="Create">'; | ||
+ | } else { | ||
+ | $out .= '<input type=submit name="btnSave" value="Save">'; | ||
+ | $out .= '<input type=reset value="Revert">'; | ||
+ | } | ||
+ | // close editing form | ||
+ | $out .= "\n</form>"; | ||
+ | } | ||
+ | $wgOut->addHTML($out); $out = ''; | ||
+ | |||
+ | if (!$doNew) { | ||
+ | $wgOut->addWikiText('===Packages===',TRUE); $out = ''; | ||
+ | $out .= $this->PkgTable(); | ||
+ | $wgOut->addWikiText($out,TRUE); $out = ''; | ||
+ | |||
+ | $wgOut->addWikiText('===Events===',TRUE); | ||
+ | $out = $this->EventListing(); | ||
+ | $wgOut->addWikiText($out,TRUE); $out = ''; | ||
+ | } | ||
+ | } | ||
+ | /*---- | ||
+ | HISTORY: | ||
+ | 2011-02-17 Updated to use objForm instead of objFlds/objCtrls | ||
+ | */ | ||
+ | private function BuildEditForm() { | ||
+ | global $vgOut; | ||
+ | |||
+ | // create fields & controls | ||
+ | |||
+ | if (is_null($this->objForm)) { | ||
+ | $objForm = new clsForm_DataSet($this,$vgOut); | ||
+ | |||
+ | $objForm->AddField(new clsFieldTime('WhenCreated'), new clsCtrlHTML()); | ||
+ | $objForm->AddField(new clsFieldTime('WhenShipped'), new clsCtrlHTML()); | ||
+ | //$objCtrls->AddField(new clsFieldTime('WhenClosed'), new clsCtrlHTML()); | ||
+ | $objForm->AddField(new clsFieldNum('ReceiptCost'), new clsCtrlHTML(array('size'=>5))); | ||
+ | $objForm->AddField(new clsFieldNum('OutsideCost'), new clsCtrlHTML(array('size'=>5))); | ||
+ | $objForm->AddField(new clsFieldNum('OrderCost'), new clsCtrlHTML(array('size'=>5))); | ||
+ | $objForm->AddField(new clsFieldNum('SupplCost'), new clsCtrlHTML(array('size'=>5))); | ||
+ | $objForm->AddField(new clsField('Carrier'), new clsCtrlHTML()); | ||
+ | $objForm->AddField(new clsField('Abbr'), new clsCtrlHTML(array('size'=>16))); | ||
+ | $objForm->AddField(new clsField('Descr'), new clsCtrlHTML(array('size'=>50))); | ||
+ | $objForm->AddField(new clsField('Notes'), new clsCtrlHTML_TextArea(array('height'=>3,'width'=>50))); | ||
+ | $objForm->AddField(new clsFieldBool('isDedicated'), new clsCtrlHTML_CheckBox()); | ||
+ | $objForm->AddField(new clsFieldBool('isOnHold'), new clsCtrlHTML_CheckBox()); | ||
+ | |||
+ | $this->objForm = $objForm; | ||
+ | } | ||
+ | } | ||
+ | /*----- | ||
+ | ACTION: Save the user's edits to the shipment | ||
+ | HISTORY: | ||
+ | 2011-02-17 Retired old custom code; now using objForm helper object | ||
+ | */ | ||
+ | private function AdminSave() { | ||
+ | global $vgOut; | ||
+ | |||
+ | $out = $this->objForm->Save(); | ||
+ | $vgOut->AddText($out); | ||
+ | /* 2011-02-17 old code | ||
global $wgOut; | global $wgOut; | ||
− | $ | + | // get the form data and note any changes |
− | $ | + | $objFlds = $this->objCtrls->Fields(); |
− | $ | + | $objFlds->RecvVals(); |
− | $ | + | // get the list of field updates |
− | $ | + | $arUpd = $objFlds->DataUpdates(); |
− | $wgOut-> | + | // log that we are about to update |
− | $ | + | $strDescr = 'Edited: '.$objFlds->DescrUpdates(); |
− | $ | + | $wgOut->AddWikiText('==Saving Edit==',TRUE); |
+ | $wgOut->AddWikiText($strDescr,TRUE); | ||
+ | |||
+ | $arEv = array( | ||
+ | 'descr' => $strDescr, | ||
+ | 'where' => __METHOD__, | ||
+ | 'code' => 'ED' | ||
+ | ); | ||
+ | $this->StartEvent($arEv); | ||
+ | // update the recordset | ||
+ | $this->Update($arUpd); | ||
+ | global $sql; | ||
+ | $wgOut->AddWikiText('<br>SQL='.$sql,TRUE); | ||
+ | $this->Reload(); | ||
+ | // log completion | ||
+ | $this->FinishEvent(); | ||
+ | */ | ||
+ | } | ||
+ | public function PkgsData() { | ||
+ | $objTbl = $this->objDB->Pkgs(); | ||
+ | $objRows = $objTbl->GetData('(ID_Shipment='.$this->KeyValue().') AND (WhenVoided IS NULL)'); | ||
+ | return $objRows; | ||
} | } | ||
public function PkgTable() { | public function PkgTable() { | ||
− | $ | + | /* |
− | $out = $ | + | //$objTbl = new clsPackages($this->objDB); |
+ | $objTbl = $this->objDB->Pkgs(); | ||
+ | $objRows = $objTbl->GetData('ID_Shipment='.$this->ID); | ||
+ | */ | ||
+ | $objRows = $this->PkgsData(); | ||
+ | $arArgs = array( | ||
+ | 'descr' => ' for this shipment', | ||
+ | 'omit' => '', | ||
+ | 'ord' => $this->ID_Order | ||
+ | ); | ||
+ | $out = $objRows->AdminTable($arArgs); | ||
+ | return $out; | ||
+ | } | ||
+ | /*---- | ||
+ | HISTORY: | ||
+ | 2010-10-23 added event logging using helper class | ||
+ | */ | ||
+ | protected function Log() { | ||
+ | if (!is_object($this->logger)) { | ||
+ | $this->logger = new clsLogger_DataSet($this,$this->objDB->Events()); | ||
+ | } | ||
+ | return $this->logger; | ||
+ | } | ||
+ | public function EventListing() { | ||
+ | return $this->Log()->EventListing(); | ||
+ | } | ||
+ | public function DropDown($iName,$iDefault=NULL) { | ||
+ | if ($this->HasRows()) { | ||
+ | $out = '<select name="'.$iName.'">'."\n"; | ||
+ | while ($this->NextRow()) { | ||
+ | $id = $this->Value('ID'); | ||
+ | if ($id == $iDefault) { | ||
+ | $htSelect = " selected"; | ||
+ | } else { | ||
+ | $htSelect = ''; | ||
+ | } | ||
+ | $htDescr = $this->Descr(); | ||
+ | $out .= "<option$htSelect value=\"$id\">$htDescr</option>\n"; | ||
+ | } | ||
+ | $out .= '</select>'; | ||
+ | } else { | ||
+ | $out = 'No shipments matching filter'; | ||
+ | } | ||
+ | return $out; | ||
+ | } | ||
+ | public function Descr() { | ||
+ | $out = $this->Abbr; | ||
return $out; | return $out; | ||
} | } | ||
} | } | ||
− | class | + | /****** |
+ | TOPIC MANAGEMENT | ||
+ | */ | ||
+ | class clsAdminTopics extends clsTopics { | ||
+ | |||
public function __construct($iDB) { | public function __construct($iDB) { | ||
parent::__construct($iDB); | parent::__construct($iDB); | ||
− | $this-> | + | $this->ClassSng('clsAdminTopic'); |
− | $this-> | + | $this->ActionKey('topic'); |
− | |||
} | } | ||
− | + | protected function AdminRedirect() { | |
− | + | global $vgPage; | |
− | $ | + | global $wgOut; |
− | $ | + | $ar = array('page'=>$this->ActionKey()); |
− | + | $url = $vgPage->SelfURL($ar,TRUE); | |
− | + | $wgOut->redirect($url); | |
− | + | } | |
− | + | public function RootNode() { | |
− | + | $objRoot = $this->SpawnItem(); | |
+ | $objRoot->ID = NULL; | ||
+ | return $objRoot; | ||
+ | } | ||
+ | /*---- | ||
+ | PURPOSE: renders tree with colors and links suitable for admin usage | ||
+ | LATER: The parent method should be generalized for color and link-function | ||
+ | */ | ||
+ | /* | ||
+ | public function RenderTree($iTwig=NULL) { | ||
+ | if (is_null($iTwig)) { | ||
+ | $objRoot = $this->RootNode(); | ||
+ | } else { | ||
+ | $objRoot = $this->GetItem($iTwig); | ||
+ | } | ||
+ | $out = $objRoot->DrawTree(); | ||
+ | return $out; | ||
+ | } | ||
+ | */ | ||
+ | public function ListTitles_unassigned() { | ||
+ | global $vgPage; | ||
− | + | $sql = 'SELECT tc.*, t.Name' | |
− | + | .' FROM (_titles AS tc LEFT JOIN cat_title_x_topic AS tt ON tc.ID=tt.ID_Title)' | |
− | + | .' LEFT JOIN cat_titles AS t ON tc.ID=t.ID' | |
+ | .' WHERE (tt.ID_Title IS NULL) AND (tc.cntForSale > 0)'; | ||
+ | $rs = $this->Engine()->DataSet($sql,$this->Engine()->Titles()->ClassSng()); | ||
+ | if ($rs->HasRows()) { | ||
+ | $vgPage->UseHTML(); | ||
+ | $rs->Table = $this->Engine()->Titles(); | ||
+ | $out = "\n<ul>"; | ||
+ | while ($rs->NextRow()) { | ||
+ | $out .= "\n<li>".$rs->AdminLink($rs->Value('CatNum')).' '.$rs->Value('Name').'</li>'; | ||
} | } | ||
+ | $out .= "\n</ul>"; | ||
+ | } else { | ||
+ | $out = 'All active titles have topics.'; | ||
} | } | ||
− | |||
return $out; | return $out; | ||
} | } | ||
− | + | public function Data_forTitle($iTitle) { | |
− | + | $sql = 'SELECT bt.* FROM cat_topic AS bt LEFT JOIN cat_title_x_topic AS bx ON bx.ID_Topic=bt.ID WHERE ID_Title='.$iTitle; | |
− | + | $objRows = $this->Engine()->DataSet($sql,$this->ClassSng()); | |
− | + | return $objRows; | |
− | |||
− | |||
− | |||
− | public function | ||
− | |||
− | |||
} | } | ||
− | public function | + | public function AdminPage() { |
global $wgOut; | global $wgOut; | ||
+ | global $vgPage,$vgOut; | ||
− | $out = '== | + | $out = "\n".'<table align=right style="border: solid black 1px;"><tr><td><h3>Unassigned Titles</h3>'; |
− | $ | + | $out .= $this->ListTitles_unassigned(); |
− | $ | + | $out .= "\n</td></tr></table>"; |
− | $ | + | |
− | if ($ | + | $arLink = array('rebuild'=>TRUE); |
− | $out = "''' | + | $htLink = $vgPage->SelfURL($arLink,TRUE); |
− | + | ||
− | + | $doRebuild = $vgPage->Arg('rebuild'); | |
− | + | ||
− | + | if ($doRebuild) { | |
− | + | // apparently there's no way to display a message without preventing the redirect | |
+ | $this->RenderTree(TRUE); | ||
+ | $this->AdminRedirect(); | ||
+ | } else { | ||
+ | $out .= "\n".'[<a href="'.$htLink.'">rebuild tree</a>]'; | ||
+ | |||
+ | $this->TreeCtrl()->FileForCSS('dtree.css'); | ||
+ | $out .= $this->RenderTree(FALSE); | ||
+ | } | ||
+ | $wgOut->AddHTML($out); $out = ''; | ||
+ | return $out; | ||
+ | } | ||
+ | /*---- | ||
+ | RETURNS: options array for entering topics | ||
+ | USAGE: | ||
+ | 1. fill in fHandleData_Change_Start, fHandleData_Change_Finish, fHandleData_Change_Item | ||
+ | 2. Then, where $arOpts is the array returned: | ||
+ | $ctrlList = new clsWidget_ShortList(); | ||
+ | $ctrlList->Options($arOpts); | ||
+ | $htOut = $ctrlList->HandleInput(); | ||
+ | HISTORY: | ||
+ | 2011-09-29 adapted from VbzAdminTitle::TopicListing() | ||
+ | */ | ||
+ | public function TopicListing_base_array() { | ||
+ | $tblTopics = $this; | ||
+ | $tblTopics->doBranch(TRUE); | ||
+ | $arOpts = array( | ||
+ | 'name' => 'title', | ||
+ | 'btnChk_Text' => 'Enter topics:', | ||
+ | 'btnChg_Text' => '<= Add', | ||
+ | 'txtCargo_sng' => 'topic ID', | ||
+ | 'txtCargo_plr' => 'topic IDs', | ||
+ | 'txtProd_sng' => 'topic', | ||
+ | 'txtProd_plr' => 'topics', | ||
+ | 'txtConf_list' => 'Adding', | ||
+ | 'fHandleData_Check' => function($iVal) use ($tblTopics) { | ||
+ | $obj = $tblTopics->GetItem($iVal); // for now, assume topic is ID | ||
− | + | $arOut['html'] = $obj->AdminLink_name(); | |
− | + | $arOut['text'] = $obj->KeyValue(); | |
− | + | return $arOut; | |
− | + | }, | |
− | + | ); | |
− | + | return $arOpts; | |
− | + | } | |
− | + | } | |
− | + | class clsAdminTopic extends clsTopic { | |
− | + | /*---- | |
− | + | HISTORY: | |
+ | 2010-12-05 boilerplate event logging added | ||
+ | */ | ||
+ | //---- | ||
+ | // BOILERPLATE: event logging | ||
+ | protected function Log() { | ||
+ | if (!is_object($this->logger)) { | ||
+ | $this->logger = new clsLogger_DataSet($this,$this->objDB->Events()); | ||
+ | } | ||
+ | return $this->logger; | ||
+ | } | ||
+ | public function StartEvent(array $iArgs) { | ||
+ | return $this->Log()->StartEvent($iArgs); | ||
+ | } | ||
+ | public function FinishEvent(array $iArgs=NULL) { | ||
+ | return $this->Log()->FinishEvent($iArgs); | ||
+ | } | ||
+ | public function EventListing() { | ||
+ | return $this->Log()->EventListing(); | ||
+ | } | ||
+ | // BOILERPLATE: admin HTML | ||
+ | public function AdminURL() { | ||
+ | return clsAdminData::_AdminURL($this); | ||
+ | } | ||
+ | public function AdminLink($iText=NULL,$iPopup=NULL,array $iarArgs=NULL) { | ||
+ | $strPopup = $this->AdminLink_default_popup($iPopup); | ||
+ | return clsAdminData::_AdminLink($this,$iText,$strPopup,$iarArgs); | ||
+ | } | ||
+ | // END BOILERPLATES | ||
+ | //---- | ||
+ | // | ||
+ | // Boilerplate auxiliary functions | ||
+ | public function AdminLink_name() { | ||
+ | if ($this->IsNew()) { | ||
+ | return 'root'; | ||
+ | } else { | ||
+ | $txtShow = $this->Value('Name'); | ||
+ | if ($this->doBranch()) { | ||
+ | $txtPopup = $this->RenderBranch_text('<'); | ||
+ | } else { | ||
+ | $txtPopup = $this->NameFull(); | ||
} | } | ||
− | $out | + | return $this->AdminLink($txtShow,$txtPopup); |
+ | } | ||
+ | } | ||
+ | protected function AdminLink_default_popup($iOverrideText) { | ||
+ | if (is_null($iOverrideText)) { | ||
+ | $out = $this->Value('Name'); | ||
} else { | } else { | ||
− | $out = ' | + | $out = $iOverrideText; |
+ | } | ||
+ | return $out; | ||
+ | } | ||
+ | // END boilerplate auxiliary | ||
+ | //---- | ||
+ | public function RenderBranch($iSep="←") { | ||
+ | $ftFullName = htmlspecialchars($this->Value('FullName')); | ||
+ | $out = $this->AdminLink($this->Value('TreeName'),$ftFullName); | ||
+ | if ($this->HasParent()) { | ||
+ | $out .= $iSep.$this->ParentObj()->RenderBranch($iSep); | ||
} | } | ||
− | $ | + | return $out; |
+ | } | ||
+ | public function Tree_RenderTwig($iCntTitles) { | ||
+ | $cntTitles = $iCntTitles; | ||
+ | $txtNoun = ' title'.Pluralize($cntTitles).' available'; // for topic #'.$id; | ||
+ | $out = ' [<b><span style="color: #00cc00;" title="'.$cntTitles.$txtNoun.'">'.$cntTitles.'</span></b>]'; | ||
+ | // $txt = $this->Value('CatNum').' '.$this->Value('Name'); | ||
+ | return $out; | ||
+ | } | ||
+ | public function Tree_AddTwig(clsTreeNode $iTwig,$iText) { | ||
+ | $id = $this->Value('ID'); | ||
+ | // $objSub = $iTwig->Add($id,$iText,$this->ShopURL()); | ||
+ | $objSub = $iTwig->Add($id,$iText,$this->AdminURL()); | ||
+ | return $objSub; | ||
} | } | ||
− | + | public function AdminPage() { | |
− | + | global $wgOut,$wgRequest; | |
− | public function | + | global $vgPage,$vgOut; |
− | global $wgOut; | + | |
+ | $doEdit = $vgPage->Arg('edit'); | ||
+ | $doSave = $wgRequest->GetBool('btnSave'); | ||
+ | $doRmvTitles = $wgRequest->GetBool('btnRmvTitles'); | ||
+ | |||
+ | $vgPage->UseHTML(); | ||
+ | |||
+ | $strTitle = 'Topic: '.$this->Value('Name'); | ||
+ | |||
+ | $objPage = new clsWikiFormatter($vgPage); | ||
+ | $objSection = new clsWikiSection($objPage,$strTitle); | ||
+ | $objSection->ToggleAdd('edit'); | ||
+ | //$objSection->ActionAdd('view'); | ||
+ | $out = $objSection->Generate(); | ||
+ | |||
+ | // save edits before re-displaying data | ||
+ | |||
+ | // edits to this record | ||
+ | $ftSaveStatus = NULL; | ||
+ | if ($doEdit || $doSave) { | ||
+ | $this->BuildEditForm(); | ||
+ | if ($doSave) { | ||
+ | $ftSaveStatus = $this->AdminSave(); | ||
+ | } | ||
+ | } | ||
+ | |||
+ | // topic deletion | ||
+ | if ($doRmvTitles) { | ||
+ | // TO BE WRITTEN | ||
+ | } | ||
+ | |||
+ | if ($doEdit) { | ||
+ | $out .= $objSection->FormOpen(); | ||
+ | $objForm = $this->objForm; | ||
+ | |||
+ | $ctParent = $objForm->Render('ID_Parent'); | ||
+ | $ctName = $objForm->Render('Name'); | ||
+ | $ctNameTree = $objForm->Render('NameTree'); | ||
+ | $ctNameFull = $objForm->Render('NameFull'); | ||
+ | $ctNameMeta = $objForm->Render('NameMeta'); | ||
+ | $ctUsage = $objForm->Render('Usage'); | ||
+ | $ctSort = $objForm->Render('Sort'); | ||
+ | $ctVariants = $objForm->Render('Variants'); | ||
+ | $ctMispeled = $objForm->Render('Mispeled'); | ||
+ | } else { | ||
+ | $ctParent = $this->ParentObj()->AdminLink_name(); | ||
+ | $ctName = $this->Value('Name'); | ||
+ | $ctNameTree = $this->Value('NameTree'); | ||
+ | $ctNameFull = $this->Value('NameFull'); | ||
+ | $ctNameMeta = $this->Value('NameMeta'); | ||
+ | $ctUsage = $this->Value('Usage'); | ||
+ | $ctSort = $this->Value('Sort'); | ||
+ | $ctVariants = $this->Value('Variants'); | ||
+ | $ctMispeled = $this->Value('Mispeled'); | ||
+ | } | ||
− | $ | + | $out .= '<ul>'; |
− | $ | + | $out .= '<li> <b>ID</b>: '.$this->KeyValue().' ['.$this->ShopLink('shop').']'; |
− | $ | + | $out .= '<li> <b>Parent</b>: '.$ctParent; |
+ | $out .= '<li> <b>Name</b>: '.$ctName; | ||
+ | $out .= '<ul>'; | ||
+ | $out .= '<li> <b>in tree</b>: '.$ctNameTree; | ||
+ | $out .= '<li> <b>complete</b>: '.$ctNameFull; | ||
+ | $out .= '<li> <b>meta</b>: '.$ctNameMeta; | ||
+ | $out .= '</ul>'; | ||
+ | $out .= '<li> <b>Usage</b>: '.$ctUsage; | ||
+ | $out .= '<li> <b>Searching</b>: '; | ||
+ | $out .= '<ul>'; | ||
+ | $out .= '<li> <b>variants</b>: '.$ctVariants; | ||
+ | $out .= '<li> <b>misspellings</b>: '.$ctMispeled; | ||
+ | $out .= '<li> <b>sort by</b>: '.$ctSort; | ||
+ | $out .= '</ul>'; | ||
+ | $out .= '</ul>'; | ||
− | $out = '== | + | if ($doEdit) { |
− | + | $out .= '<input type=submit name="btnSave" value="Save">'; | |
− | + | $out .= '<input type=reset value="Reset">'; | |
− | + | $out .= '</form>'; | |
− | + | } | |
− | + | $wgOut->AddHTML($out); | |
− | + | $wgOut->AddHTML("<h3>Subtopics</h3>"); | |
− | $wgOut-> | + | $wgOut->AddHTML($this->SubtopicListing()); |
− | $ | + | $wgOut->AddHTML("<h3>Titles</h3>"); |
− | $ | + | $wgOut->AddHTML($this->TitleListing()); |
− | $wgOut-> | ||
− | |||
− | $ | ||
− | |||
} | } | ||
− | /* | + | /*---- |
− | + | ACTION: Save user changes to the record | |
− | */ | + | HISTORY: |
− | public function | + | 2010-11-06 copied from VbzStockBin to VbzAdminItem |
− | $ | + | 2011-01-26 copied from VbzAdminItem to clsAdminTopic |
− | + | */ | |
+ | public function AdminSave() { | ||
+ | global $vgOut; | ||
+ | |||
+ | $out = $this->objForm->Save(); | ||
+ | $vgOut->AddText($out); | ||
} | } | ||
− | /* | + | /*---- |
− | + | HISTORY: | |
− | */ | + | 2010-11-06 adapted from VbzStockBin for VbzAdminTitle |
− | + | 2011-01-26 adapted from VbzAdminTitle | |
− | $ | + | */ |
− | + | private function BuildEditForm() { | |
+ | global $vgOut; | ||
+ | |||
+ | if (is_null($this->objForm)) { | ||
+ | // create fields & controls | ||
+ | $objForm = new clsForm_DataSet($this,$vgOut); | ||
+ | //$objCtrls = new clsCtrls($objForm->Fields()); | ||
+ | //$objCtrls = $objForm; | ||
+ | |||
+ | $objForm->AddField(new clsFieldNum('ID_Parent'), new clsCtrlHTML()); | ||
+ | $objForm->AddField(new clsField('Name'), new clsCtrlHTML(array('size'=>20))); | ||
+ | $objForm->AddField(new clsField('NameTree'), new clsCtrlHTML(array('size'=>15))); | ||
+ | $objForm->AddField(new clsField('NameFull'), new clsCtrlHTML(array('size'=>25))); | ||
+ | $objForm->AddField(new clsField('NameMeta'), new clsCtrlHTML(array('size'=>25))); | ||
+ | $objForm->AddField(new clsField('Usage'), new clsCtrlHTML(array('size'=>25))); | ||
+ | $objForm->AddField(new clsField('Sort'), new clsCtrlHTML(array('size'=>5))); | ||
+ | $objForm->AddField(new clsField('Variants'), new clsCtrlHTML(array('size'=>40))); | ||
+ | $objForm->AddField(new clsField('Mispeled'), new clsCtrlHTML(array('size'=>40))); | ||
+ | |||
+ | $this->objForm = $objForm; | ||
+ | //$this->objCtrls = $objCtrls; | ||
+ | } | ||
} | } | ||
− | + | protected function SubtopicListing() { | |
− | // | + | global $wgRequest; |
− | + | ||
− | + | $htStatus = NULL; | |
− | + | ||
− | if ($ | + | // set up the entry widget |
− | $out = "\n | + | $ctrlList = new clsWidget_ShortList(); |
+ | $me = $this; | ||
+ | $arOpts = array( | ||
+ | 'name' => 'topic', | ||
+ | 'btnChk_Text' => 'Enter subtopics:', | ||
+ | 'btnChg_Text' => '<= Create', | ||
+ | 'txtCargo_sng' => 'topic name', | ||
+ | 'txtCargo_plr' => 'topic names', | ||
+ | 'txtProd_sng' => 'subtopic', | ||
+ | 'txtProd_plr' => 'subtopics', | ||
+ | 'fHandleData_Check' => function($iVal) { | ||
+ | $arOut['html'] = $iVal; | ||
+ | $arOut['text'] = $iVal; | ||
+ | return $arOut; | ||
+ | }, | ||
+ | 'fHandleData_Change_Start' => function($iText) use ($me) { | ||
+ | $arEv = array( | ||
+ | 'descr' => 'Adding '.$iText, | ||
+ | 'code' => 'sub++', | ||
+ | 'where' => __METHOD__ | ||
+ | ); | ||
+ | $me->StartEvent($arEv); | ||
+ | }, | ||
+ | 'fHandleData_Change_Finish' => function($iText) use ($me) { | ||
+ | $arEv = array( | ||
+ | 'descrfin' => $iText | ||
+ | ); | ||
+ | $me->FinishEvent($arEv); | ||
+ | }, | ||
+ | 'fHandleData_Change_Item' => function($iVal) use ($me) { | ||
+ | $txt = $iVal; | ||
+ | $arIns = array( | ||
+ | 'ID_Parent' => SQLValue($me->KeyValue()), | ||
+ | 'Name' => SQLValue($txt) | ||
+ | ); | ||
+ | $me->Table->Insert($arIns); | ||
+ | $out = $me->Table->LastID(); | ||
+ | return $out; | ||
+ | }, | ||
+ | ); | ||
+ | $ctrlList->Options($arOpts); | ||
+ | $htStatus = $ctrlList->HandleInput(); | ||
+ | |||
+ | $out = "\n<form method=post>"; | ||
+ | |||
+ | |||
+ | $rs = $this->Subtopics(); | ||
+ | if ($rs->HasRows()) { | ||
+ | $out .= "\n<table class=sortable>"; | ||
+ | $out .= "\n<tr><th>ID</th><th>Name</th><th>in tree</th><th>full</th><th>sort</th><th>variants</th><th>mis-spellings</th></tr>"; | ||
$isOdd = TRUE; | $isOdd = TRUE; | ||
− | while ($ | + | while ($rs->NextRow()) { |
− | |||
$isOdd = !$isOdd; | $isOdd = !$isOdd; | ||
+ | $ftStyleShade = $isOdd?'ffffff':'#cccccc'; | ||
+ | $ftStyle = ' style="background: '.$ftStyleShade.';"'; | ||
− | $id = $ | + | $id = $rs->KeyString(); |
− | $ | + | $ftID = $rs->AdminLink(); |
− | $ | + | $ftName = $rs->Value('Name'); |
− | + | $ftNameTree = $rs->Value('NameTree'); | |
− | $ | + | $ftNameFull = $rs->Value('NameFull'); |
− | $ | + | $ftSort = $rs->Value('Sort'); |
− | + | $ftVari = $rs->Value('Variants'); | |
− | $ | + | $ftMisp = $rs->Value('Mispeled'); |
− | $ | ||
− | $out .= | + | $out .= "\n<tr$ftStyle>" |
− | + | ."<td>$ftID</td>" | |
− | ." | + | ."<td>$ftName</td>" |
− | ." | + | ."<td>$ftNameTree</td>" |
− | ." | + | ."<td>$ftNameFull</td>" |
− | ." | + | ."<td>$ftSort</td>" |
− | ." | + | ."<td>$ftVari</td>" |
− | ." | + | ."<td>$ftMisp</td>" |
− | ; | + | ."</tr>"; |
} | } | ||
+ | $out .= "\n</table>"; | ||
} else { | } else { | ||
− | $out = | + | $out .= '<i>None found.</i>'; |
} | } | ||
+ | $out .= '<br>'.$htStatus; | ||
+ | $out .= $ctrlList->RenderForm_Entry(); | ||
+ | $out .= '</form>'; | ||
return $out; | return $out; | ||
} | } | ||
− | } | + | protected function TitleListing() { |
− | // | + | global $wgRequest; |
− | + | global $vgPage; | |
− | + | ||
− | + | // check for any form actions | |
− | $this->Name(' | + | $doChk = $wgRequest->GetBool('btnChkTitles'); |
− | $ | + | $doAdd = $wgRequest->GetBool('btnAddTitles'); |
+ | $doRmv = $wgRequest->GetBool('btnRmvTitles'); | ||
+ | |||
+ | $htStatus = NULL; | ||
+ | |||
+ | // pass-along vars for anon functions | ||
+ | $tblTitles = $this->Engine()->Titles(); // for anon function to use | ||
+ | $tblTitleTopics = $this->Engine()->TitleTopics(); | ||
+ | $me = $this; | ||
+ | |||
+ | $ctrlList = new clsWidget_ShortList(); | ||
+ | $arOpts = array( | ||
+ | 'name' => 'title', | ||
+ | 'btnChk_Text' => 'Enter titles:', | ||
+ | 'btnChg_Text' => '<= Add', | ||
+ | 'txtCargo_sng' => 'title ID', | ||
+ | 'txtCargo_plr' => 'title IDs', | ||
+ | 'txtProd_sng' => 'title', | ||
+ | 'txtProd_plr' => 'titles', | ||
+ | 'fHandleData_Check' => function($iVal) use ($tblTitles) { | ||
+ | $obj = $tblTitles->GetItem($iVal); // for now, assume title is ID | ||
+ | |||
+ | $arOut['html'] = $obj->AdminLink($obj->CatNum(),$obj->Value('Name')); | ||
+ | //$arOut['text'] = $obj->KeyValue().'('.$obj->CatNum().')'; | ||
+ | $arOut['text'] = $obj->KeyValue(); | ||
+ | return $arOut; | ||
+ | }, | ||
+ | 'fHandleData_Change_Start' => function($iText) use ($me) { | ||
+ | $arEv = array( | ||
+ | 'descr' => 'Adding '.$iText, | ||
+ | 'code' => 'sub++', | ||
+ | 'where' => __METHOD__ | ||
+ | ); | ||
+ | $me->StartEvent($arEv); | ||
+ | }, | ||
+ | 'fHandleData_Change_Finish' => function($iText) use ($me) { | ||
+ | $arEv = array( | ||
+ | 'descrfin' => $iText | ||
+ | ); | ||
+ | $me->FinishEvent($arEv); | ||
+ | }, | ||
+ | 'fHandleData_Change_Item' => function($iVal) use ($me,$tblTitleTopics) { | ||
+ | $txt = $iVal; | ||
+ | $arIns = array( | ||
+ | 'ID_Title' => SQLValue($txt), | ||
+ | 'ID_Topic' => SQLValue($me->KeyValue()) | ||
+ | ); | ||
+ | //$this->Engine()->TitleTopics()->Insert($arIns); | ||
+ | $sql = $tblTitleTopics->Insert($arIns); | ||
+ | $out = SQLValue($txt); | ||
+ | return $out; | ||
+ | }, | ||
+ | ); | ||
+ | $ctrlList->Options($arOpts); | ||
+ | $htStatus = $ctrlList->HandleInput(); | ||
+ | if ($wgRequest->GetBool('btnRmvTitles')) { | ||
+ | $arRmv = $wgRequest->GetArray('rmvTitle'); | ||
+ | $cntRmv = count($arRmv); | ||
+ | $arEv = array( | ||
+ | 'descr' => 'Removing '.$cntRmv.' title'.Pluralize($cntRmv).' from this topic', | ||
+ | 'code' => 'TTL--', | ||
+ | 'where' => __METHOD__ | ||
+ | ); | ||
+ | $this->StartEvent($arEv); | ||
+ | $txtRmv = ''; | ||
+ | foreach ($arRmv as $id => $on) { | ||
+ | $sqlFilt = '(ID_Topic='.$this->ID.') AND (ID_Title='.$id.')'; | ||
+ | $this->Engine()->TitleTopics()->Delete($sqlFilt); | ||
+ | $txtRmv .= ' '.$id; | ||
+ | } | ||
+ | $arEv = array( | ||
+ | 'descrfin' => 'Titles removed:'.$txtRmv | ||
+ | ); | ||
+ | $this->FinishEvent($arEv); | ||
+ | $htStatus .= 'Titles removed:'.$txtRmv; | ||
+ | } | ||
+ | |||
+ | $out = "\n<form name=\"add-titles\" method=post>"; | ||
+ | |||
+ | $rs = $this->Titles(); | ||
+ | if ($rs->HasRows()) { | ||
+ | $out .= "\n<table class=sortable>"; | ||
+ | $out .= "\n<tr><th>ID</th><th>Cat #</th><th>Name</th><th>Dept</th><th>When Added</th><th>When Unavail</th></tr>"; | ||
+ | $isOdd = TRUE; | ||
+ | while ($rs->NextRow()) { | ||
+ | $isOdd = !$isOdd; | ||
+ | $ftStyleShade = $isOdd?'ffffff':'#cccccc'; | ||
+ | $ftStyle = ' style="background: '.$ftStyleShade.';"'; | ||
+ | |||
+ | $id = $rs->KeyString(); | ||
+ | $ftID = $rs->AdminLink(); | ||
+ | $ftCatNum = $rs->CatNum(); | ||
+ | $ftName = $rs->Value('Name'); | ||
+ | $rsDept = $rs->DeptObj(); | ||
+ | $ftDept = $rsDept->AdminLink_name(); | ||
+ | $ftAdded = $rs->Value('DateAdded'); | ||
+ | $ftUnavail = $rs->Value('DateUnavail'); | ||
+ | |||
+ | $out .= "\n<tr$ftStyle>" | ||
+ | ."<td><input type=checkbox name=\"rmvTitle[$id]\">$ftID</td>" | ||
+ | ."<td>$ftCatNum</td>" | ||
+ | ."<td>$ftName</td>" | ||
+ | ."<td>$ftDept</td>" | ||
+ | ."<td>$ftAdded</td>" | ||
+ | ."<td>$ftUnavail</td>" | ||
+ | ."</tr>"; | ||
+ | } | ||
+ | $out .= "\n</table>"; | ||
+ | $out .= '<input type=submit name="btnRmvTitles" value="Remove Checked">'; | ||
+ | } else { | ||
+ | $out .= '<i>None found.</i>'; | ||
+ | } | ||
+ | $out .= '<br>'.$htStatus; | ||
+ | $out .= $ctrlList->RenderForm_Entry(); | ||
+ | /* | ||
+ | $out .= '<input type=submit name="btnChkTitles" value="Add These:">'; | ||
+ | $out .= '<input size=40 name=txtNewTitles> (IDs separated by spaces)'; | ||
+ | */ | ||
+ | $out .= '</form>'; | ||
+ | return $out; | ||
} | } | ||
+ | /*---- | ||
+ | What uses this? | ||
+ | |||
+ | */ | ||
+ | public function AdminList() { | ||
+ | $objRecs = $this; | ||
− | |||
− | |||
if ($objRecs->HasRows()) { | if ($objRecs->HasRows()) { | ||
− | $out = " | + | $out = "{| class=sortable\n|-\n! ID || Name || Abbr || When Avail || Superceded || Status"; |
$isOdd = TRUE; | $isOdd = TRUE; | ||
while ($objRecs->NextRow()) { | while ($objRecs->NextRow()) { | ||
− | $wtStyle | + | $objTopic = $this->objDB->Topics()->GetItem($this->ID_Topic); |
+ | $id = $objTopic->ID; | ||
+ | $ftID = $id; | ||
+ | $out .= "\n|- style=\"$wtStyle\"". | ||
+ | "\n| ".$ftID. | ||
+ | ' || '.$objRecs->Name. | ||
+ | ' || '.$objRecs->Abbr. | ||
+ | ' || '.$strDate. | ||
+ | ' || '.$strSuper. | ||
+ | ' || '.$strStatus; | ||
$isOdd = !$isOdd; | $isOdd = !$isOdd; | ||
+ | } | ||
+ | $out .= "\n|}"; | ||
+ | } else { | ||
+ | $out = 'No topics found.'; | ||
+ | } | ||
+ | return $out; | ||
+ | } | ||
+ | /*---- | ||
+ | HISTORY: | ||
+ | 2010-10-11 Created -- then discovered that it probably doesn't need | ||
+ | to be a separate function... but I think it makes things clearer. | ||
+ | */ | ||
+ | public function Twigs() { | ||
+ | if (is_null($this->ID)) { | ||
+ | $sql = 'ID_Parent IS NULL'; | ||
+ | } else { | ||
+ | $sql = 'ID_Parent='.$this->ID; | ||
+ | } | ||
+ | $objRows = $this->Table->GetData($sql,NULL,'Sort,NameTree,Name'); | ||
+ | return $objRows; | ||
+ | } | ||
+ | public function DrawTree($iLevel=0,$iRootName="Topics") { | ||
+ | global $vgPage; | ||
− | + | $out = ''; | |
− | + | $intLevel = $iLevel + 1; | |
+ | $strIndent = str_repeat('*',$intLevel); | ||
− | $out .= "\n|- | + | $objRows = $this->Twigs(); |
+ | if ($objRows->HasRows()) { | ||
+ | if (empty($iLevel)) { | ||
+ | $strName = $this->Name; | ||
+ | if (empty($strName)) { | ||
+ | $strName = $iRootName; | ||
+ | } | ||
+ | $out .= "\n{{#tree:id=root|root='''$strName'''|"; | ||
+ | $vgPage->UseWiki(); | ||
+ | } | ||
+ | while ($objRows->NextRow()) { | ||
+ | $strNameTree = $objRows->NameTree; | ||
+ | $strTwig = ifEmpty($strNameTree,$objRows->Name); | ||
+ | $out .= "\n$strIndent".$objRows->AdminLink($strTwig); | ||
+ | $out .= $objRows->DrawTree($intLevel); | ||
} | } | ||
+ | if ($iLevel == 0) { | ||
+ | $out .= "\n}}"; | ||
+ | $vgPage->UseWiki(); | ||
+ | } | ||
+ | return $out; | ||
} else { | } else { | ||
− | $ | + | if (empty($iLevel)) { |
+ | return 'NO TOPICS FOUND'; | ||
+ | } else { | ||
+ | return NULL; | ||
+ | } | ||
} | } | ||
− | |||
} | } | ||
} | } | ||
− | class | + | class clsAdminTitleTopic_Titles extends clsTitleTopic_Titles { |
− | public function | + | public function __construct(clsDatabase $iDB) { |
− | + | parent::__construct($iDB); | |
+ | $this->ClassSng('VbzAdminTitle'); | ||
+ | $this->ActionKey($this->Engine()->Titles()->ActionKey()); | ||
+ | } | ||
+ | } | ||
+ | class clsAdminTitleTopic_Topics extends clsTitleTopic_Topics { | ||
+ | public function __construct(clsDatabase $iDB) { | ||
+ | parent::__construct($iDB); | ||
+ | $this->ClassSng('clsAdminTopic'); | ||
+ | $this->ActionKey($this->Engine()->Topics()->ActionKey()); | ||
+ | } | ||
+ | } | ||
+ | /*========== | ||
+ | | UTILITY FUNCTIONS | ||
+ | | These should probably go into a separate file at some point | ||
+ | */ | ||
+ | /*---- | ||
+ | PURPOSE: This is the newer version of WhoString_wt | ||
+ | which uses WhoAdmin, WhoSystem, and WhoNetwork | ||
+ | instead of VbzUser, SysUser, and Machine | ||
+ | */ | ||
+ | function WhoString2_wt($iRow) { | ||
+ | $htUnknown = '<span style="color: #888888;">?</span>'; | ||
− | + | if (isset($iRow['WhoSystem'])) { | |
− | + | $strSysUser = $iRow['WhoSystem']; | |
− | + | $hasSysUser = TRUE; | |
− | } else { | + | } else { |
− | + | $strSysUser = NULL; | |
− | + | $hasSysUser = FALSE; | |
− | + | } | |
+ | $strMachine = $iRow['WhoNetwork']; | ||
+ | $strVbzUser = $iRow['WhoAdmin']; | ||
+ | |||
+ | $htSysUser = is_null($strSysUser)?$htUnknown:$strSysUser; | ||
+ | $htMachine = is_null($strMachine)?$htUnknown:$strMachine; | ||
+ | $htVbzUser = is_null($strVbzUser)?$htUnknown:$strVbzUser; | ||
+ | |||
+ | $htWho = $htVbzUser; | ||
+ | if ($hasSysUser) { | ||
+ | $htWho .= '/'.$htSysUser; | ||
} | } | ||
+ | $htWho .= '@'.$htMachine; | ||
+ | |||
+ | return $htWho; | ||
} | } | ||
/* | /* | ||
− | + | STATUS: DEPRECATED | |
+ | Where possible, convert table fieldnames to be compatible with WhoString2_wt | ||
+ | */ | ||
+ | function WhoString_wt($iRow) { | ||
+ | $htUnknown = '<span style="color: #888888;">?</span>'; | ||
+ | |||
+ | if (isset($iRow['SysUser'])) { | ||
+ | $strSysUser = $iRow['SysUser']; | ||
+ | $hasSysUser = TRUE; | ||
+ | } else { | ||
+ | $strSysUser = NULL; | ||
+ | $hasSysUser = FALSE; | ||
+ | } | ||
+ | $strMachine = $iRow['Machine']; | ||
+ | $strVbzUser = $iRow['VbzUser']; | ||
+ | |||
+ | $htSysUser = is_null($strSysUser)?$htUnknown:$strSysUser; | ||
+ | $htMachine = is_null($strMachine)?$htUnknown:$strMachine; | ||
+ | $htVbzUser = is_null($strVbzUser)?$htUnknown:$strVbzUser; | ||
+ | |||
+ | $htWho = $htVbzUser; | ||
+ | if ($hasSysUser) { | ||
+ | $htWho .= '/'.$htSysUser; | ||
+ | } | ||
+ | $htWho .= '@'.$htMachine; | ||
+ | |||
+ | return $htWho; | ||
} | } | ||
− | + | function SelfLink_Page($iPage,$iKey,$iVal,$iText=NULL) { | |
− | </php> | + | $strText = (is_null($iText))?$iVal:$iText; |
+ | if (is_null($strText)) { | ||
+ | return NULL; | ||
+ | } else { | ||
+ | return '[[{{FULLPAGENAME}}/page'.KS_CHAR_URL_ASSIGN.$iPage.'/'.$iKey.KS_CHAR_URL_ASSIGN.$iVal.'|'.$strText.']]'; | ||
+ | } | ||
+ | } | ||
+ | |||
+ | function WikiSelfLink($iArgs,$iText) { | ||
+ | // this function is deprecated; gradually convert to SelfLink and then rename it | ||
+ | return '[{{fullurl:{{FULLPAGENAME}}|'.$iArgs.'}} '.$iText.']'; | ||
+ | } | ||
+ | function WikiSectionHdr($iTitle,$iMenuName,array $iMenu) { | ||
+ | global $vgPage; | ||
+ | |||
+ | $out = '<h2>'; | ||
+ | foreach ($iMenu as $name=>$arLink) { | ||
+ | $htPath = $arLink['path']; | ||
+ | $htPopup = $arLink['popup']; | ||
+ | $htDispl = $arLink['displ']; | ||
+ | $out .= '<span class="editsection">[<a href="'.$htPath.'" title="'.$htPopup.'">'.$htDispl.'</a>]</span> '; | ||
+ | } | ||
+ | $out .= '<span class="mw-headline">'.$iTitle.'</span></h2>'; | ||
+ | return $out; | ||
+ | } | ||
+ | function WikiSectionHdr_Edit($iTitle,$iEditTitle) { | ||
+ | global $vgPage; | ||
+ | // global $vgOut; | ||
+ | |||
+ | $doEdit = $vgPage->Arg('edit'); | ||
+ | $arLink = array( | ||
+ | 'edit' => !$doEdit, | ||
+ | 'page' => $vgPage->Arg('page'), | ||
+ | 'id' => $vgPage->Arg('id') | ||
+ | ); | ||
+ | $htPath = $vgPage->SelfURL($arLink,TRUE); | ||
+ | |||
+ | $out = '<h2>'; | ||
+ | if ($doEdit) { | ||
+ | $out .= '<span class="editsection">[<a href="'.$htPath.'" title="View '.$iEditTitle.'">view</a>]</span> '; | ||
+ | } else { | ||
+ | $out .= '<span class="editsection">[<a href="'.$htPath.'" title="Edit '.$iEditTitle.'">edit</a>]</span> '; | ||
+ | } | ||
+ | $out .= '<span class="mw-headline">'.$iTitle.'</span></h2>'; | ||
+ | return $out; | ||
+ | } | ||
+ | |||
+ | if (!function_exists('TimeStamp_HideTime')) { | ||
+ | //-- | ||
+ | function TimeStamp_HideTime($iStamp) { | ||
+ | |||
+ | if (is_string($iStamp)) { | ||
+ | $intStamp = strtotime($iStamp); | ||
+ | } else if (is_int($iStamp)) { | ||
+ | $intStamp = $iStamp; | ||
+ | } else { | ||
+ | $intStamp = NULL; | ||
+ | } | ||
+ | if (!is_null($intStamp)) { | ||
+ | return date('Y-m-d',$intStamp); | ||
+ | } else { | ||
+ | return NULL; | ||
+ | } | ||
+ | } | ||
+ | //-- | ||
+ | } | ||
+ | |||
+ | function IsWebSecure() { | ||
+ | if (isset($_SERVER["HTTPS"])) { | ||
+ | return $_SERVER["HTTPS"] == 'on'; | ||
+ | } else { | ||
+ | return FALSE; | ||
+ | } | ||
+ | }</php> |
Latest revision as of 02:08, 19 December 2014
<php><?php /*
NAME: SpecialVbzAdmin PURPOSE: Special page for administering VbzCart AUTHOR: Woozle (Nick) Staddon REQUIRES: Tabber extension for tabs on Supplier admin page TreeAndMenu extension (tentatively) for category management VERSION: 2009-03-10 0.0 (Wzl) Started writing had a few functions implemented by June or so, but not enough to process anything 2009-07-09 (Wzl) rewrote menu functions as classes started on Shipments 2009-10-04 (Wzl) menu classes now in separate file; removed from here added 'orders' and 'order' pages/classes 2009-10-06 (Wzl) clsTitles -> clsVbzTitles, clsTitle -> clsVbzTitle 2010-06-27 (Wzl) new functionality in Bins, Images; moved catalog rebuild out to standalone script 2010-09-22 (Wzl) working on email confirmation of orders (finally) 2011-02-06 (Wzl) extensive work since 9/22... most features usable 2011-12-21 (Wzl) extracted clsVbzAdminData into base.admin.php so it could be used from command line
- /
$wgSpecialPages['VbzAdmin'] = 'SpecialVbzAdmin'; # Let MediaWiki know about your new special page. $wgExtensionCredits['other'][] = array(
'name' => 'Special:VbzAdmin',
'url' => 'http://htyp.org/VbzCart',
'description' => 'special page for VbzCart administration', 'author' => 'Woozle (Nick) Staddon',
'version' => '2011-12-21 unreleased' ); global $dbgShowLibs; $dbgShowLibs = TRUE;
if (!defined('LIBMGR')) {
require('libmgr.php');
} //clsLibMgr::$doDebug = TRUE; clsLibMgr::Add('vbz.site', KFP_LIB_VBZ.'/site.php',__FILE__,__LINE__); clsLibMgr::Add('vbz.shop', KFP_LIB_VBZ.'/shop.php',__FILE__,__LINE__); clsLibMgr::Add('vbz.ckout', KFP_LIB_VBZ.'/ckout.php',__FILE__,__LINE__); clsLibMgr::Add('vbz.topic', KFP_LIB_VBZ.'/topic.php',__FILE__,__LINE__); clsLibMgr::Add('admin.events', KFP_MW_PLUGINS.'/lib/admin.events.php',__FILE__,__LINE__); clsLibMgr::Add('admin.forms', KFP_MW_PLUGINS.'/lib/admin.forms.php',__FILE__,__LINE__); clsLibMgr::Add('vbz.admin.base', KFP_LIB_VBZ.'/base.admin.php',__FILE__,__LINE__); clsLibMgr::Add('vbz.admin.cache', KFP_LIB_VBZ.'/admin.cache.php',__FILE__,__LINE__); clsLibMgr::Add('vbz.admin.cat', KFP_LIB_VBZ.'/admin.cat.php',__FILE__,__LINE__); clsLibMgr::Add('vbz.admin.sess',KFP_LIB_VBZ.'/admin.sess.php',__FILE__,__LINE__); clsLibMgr::Add('vbz.admin.cart',KFP_LIB_VBZ.'/admin.cart.php',__FILE__,__LINE__); clsLibMgr::Add('vbz.admin.ord', KFP_LIB_VBZ.'/admin.ord.php',__FILE__,__LINE__); clsLibMgr::Add('vbz.admin.pkg', KFP_LIB_VBZ.'/admin.pkg.php',__FILE__,__LINE__); clsLibMgr::Add('vbz.admin.cust',KFP_LIB_VBZ.'/admin.cust.php',__FILE__,__LINE__); clsLibMgr::Add('vbz.admin.rstk',KFP_LIB_VBZ.'/admin.rstk.php',__FILE__,__LINE__); clsLibMgr::Add('vbz.admin.stock',KFP_LIB_VBZ.'/admin.stock.php',__FILE__,__LINE__); clsLibMgr::Add('richtext', KFP_MW_PLUGINS.'/richtext.php',__FILE__,__LINE__); clsLibMgr::Add('menus', KFP_MW_PLUGINS.'/menu.php',__FILE__,__LINE__); clsLibMgr::Load('vbz.site' ,__FILE__,__LINE__); clsLibMgr::Load('vbz.shop' ,__FILE__,__LINE__); clsLibMgr::Load('vbz.ckout' ,__FILE__,__LINE__); clsLibMgr::Load('vbz.topic' ,__FILE__,__LINE__); clsLibMgr::Load('admin.events' ,__FILE__,__LINE__); clsLibMgr::Load('admin.forms' ,__FILE__,__LINE__); clsLibMgr::Load('vbz.admin.base' ,__FILE__,__LINE__); clsLibMgr::Load('vbz.admin.cache' ,__FILE__,__LINE__); clsLibMgr::Load('vbz.admin.cat' ,__FILE__,__LINE__); clsLibMgr::Load('vbz.admin.sess' ,__FILE__,__LINE__); clsLibMgr::Load('vbz.admin.ord' ,__FILE__,__LINE__); clsLibMgr::Load('vbz.admin.pkg' ,__FILE__,__LINE__); clsLibMgr::Load('vbz.admin.cart' ,__FILE__,__LINE__); clsLibMgr::Load('vbz.admin.cust' ,__FILE__,__LINE__); clsLibMgr::Load('vbz.admin.rstk' ,__FILE__,__LINE__); clsLibMgr::Load('vbz.admin.stock' ,__FILE__,__LINE__); clsLibMgr::Load('richtext' ,__FILE__,__LINE__); clsLibMgr::Load('menus' ,__FILE__,__LINE__);
define('kwp_DocPfx','htyp:VbzCart/'); define('kwp_DocTblPfx',kwp_DocPfx.'tables/'); define('kwp_DocPrcPfx',kwp_DocPfx.'procs/'); define('kwp_DocTermPfx',kwp_DocPfx.'ui/terms/'); //echo 'LIB LOG:'.clsLibMgr::$Log;
if (!defined('KS_CHAR_URL_ASSIGN')) {
define('KS_CHAR_URL_ASSIGN',':'); // character used for encoding values in wiki-internal URLs
}
// data source names -- these are used only by admin functions; general tables are in store.php define('KSQL_DS_ITEMS_TO_SHIP','qryStock_forOpenOrders');
function Date_DefaultYear($iDate,$iYear,$iSmallerPfx='',$iSmallerSfx='') {
if (empty($iDate)) {
return NULL;
} else {
$dtIn = strtotime($iDate);
$yrIn = date('Y',$dtIn);
$doYr = ($yrIn != $iYear);
$out = ;
if ($doYr) {
$out .= $iSmallerPfx;
}
$ftIn = date('m/d',$dtIn);
$out .= $ftIn;
if ($doYr) {
$out .= '
'.$yrIn;
$out .= $iSmallerSfx;
}
return $out;
}
}
function wfSpecialVbzAdmin() { // This registers the page's class. I think. global $wgRequest;
$app = new SpecialVbzAdmin($wgRequest); } function NextSeq($iData) {
if ($iData->HasRows()) {
$intMax = 0; while ($iData->NextRow()) { if ($iData->Seq > $intMax) { $intMax = $iData->Seq; } } return $intMax+1;
} else {
return 1;
}
}
/* DEACTIVATED 2010-11-08 function VbzDb() {
static $objDb;
if (!isset($objDb)) {
$objDb = new clsVbzAdminData(KS_DB_VBZCART); $objDb->Open();
} return $objDb;
}
- /
class SpecialVbzAdmin extends SpecialPageApp {
protected $args; protected $objDB;
public function __construct() {
global $wgMessageCache,$wgUser; global $vgUserName,$vgPage;
parent::__construct( 'VbzAdmin' ); $this->includable( TRUE );
$this->SetTitle('VbzAdmin');
$vgUserName = 'wiki:'.$wgUser->getName(); $vgPage = $this;
} /*---- USAGE: Must be called before parent::SetHeaders() */ public function SetTitle($iText) {
global $wgMessageCache;
$wgMessageCache->addMessage('vbzadmin',$iText); } protected function DB() {
if (!isset($this->objDB)) { $this->objDB = new clsVbzAdminData(KS_DB_VBZCART); $this->objDB->Open(); } return $this->objDB;
} function execute( $par ) {
global $wgUser;
$doAdmin = $wgUser->isAllowed('editinterface'); $this->GetArgs($par);
if ($doAdmin) { $this->RegObjs($this->ClassList()); $this->HandlePageArgs(); }
$this->setHeaders();
$this->doMenu($doAdmin);
if ($doAdmin) { $this->doAdmin(); } else { $this->doUser(); }
} protected function doMenu($iAdmin) {
global $wgOut;
$wtSelf = 'Special:'.$this->name();
$objMenu = new clsMenu($wtSelf); if ($iAdmin) { $objMenu->Add($objRow = new clsMenuRow('Stock','menu.stock')); $objRow->Add(new clsMenuItem('stock places','place')); $objRow->Add(new clsMenuItem('stock bins','bin')); $objMenu->Add($objRow = new clsMenuRow('Catalog','menu.cat')); $objRow->Add(new clsMenuItem('suppliers','supp')); $objRow->Add(new clsMenuItem('images','cat.img')); $objRow->Add(new clsMenuItem('topics','topic')); $objRow->Add(new clsMenuItem('search','cat.search')); $objMenu->Add($objRow = new clsMenuRow('Restocks','menu.rstk')); $objRow->Add(new clsMenuItem('needed','rstk.need')); $objRow->Add(new clsMenuItem('expected','rstk.wait')); $objRow->Add(new clsMenuItem('past','rstk.past')); $objMenu->Add($objRow = new clsMenuRow('Orders','menu.orders')); $objRow->Add(new clsMenuItem('carts','cart')); $objRow->Add(new clsMenuItem('orders',KS_URL_PAGE_ORDER)); $objRow->Add(new clsMenuItem('charges','chg')); $objMenu->Add($objRow = new clsMenuRow('Ship','menu.ship')); $objRow->Add(new clsMenuItem('items to ship','toship')); $objRow->Add(new clsMenuItem('shipments','shpmt')); $objMenu->Add($objRow = new clsMenuRow('Utilities','menu.utils')); $objRow->Add(new clsMenuItem('cache tables','cache')); $objRow->Add(new clsMenuItem('ccard encryption','migr.encr')); $objRow->Add(new clsMenuItem('update stats','util.stats')); $objRow->Add(new clsMenuItem('price list','util.plist')); $objRow->Add(new clsMenuItem('inventory','util.inv')); $objMenu->Add($objRow = new clsMenuRow('Logs','menu.logs')); $objRow->Add(new clsMenuItem('general','log.misc')); $objRow->Add(new clsMenuItem('carts','log.cart')); }
$wgOut->addHTML('
');
$out = $objMenu->WikiText($this->page); $out .= $objMenu->Execute(); $wgOut->addWikiText($out,TRUE); $out = ; $wgOut->addHTML(' |
');
// a little diagnostic info $isFnd = FALSE; $out .= ''; if (is_object($this->tbl)) { $out .= 'table class: '.get_class($this->tbl).''; $isFnd = TRUE; } if (is_object($this->obj)) { $out .'record class: '.get_class($this->obj).''; $isFnd = TRUE; } if (!$isFnd) { $out .= 'No classes found for page ['.$this->page.'].'; } $out .= ''; $wgOut->addHTML($out); $out = ;
} protected function ClassList() {
$ar = array( //'clsAdminCacheFlows', //'clsAdminCacheProc', //'clsAdminCacheTables', //'VbzAdminCartLines', //'VbzAdminCartLog', 'VbzAdminCarts', 'VbzAdminCatalogs', 'clsAdminCustAddrs', 'VbzAdminCustCards', 'clsAdminCustEmails', 'clsAdminCustNames', 'clsAdminCustPhones', 'VbzAdminCusts', 'VbzAdminDepts', 'clsAdminEvents', 'clsAdminImages', 'VbzAdminItems', //'clsAdminItems_info_Cat', 'VbzAdminOrderChgs', 'VbzAdminOrderItems', //'VbzAdminOrderPulls', 'VbzAdminOrders', 'VbzAdminOrderTrxacts', //'VbzAdminOrderTrxTypes', 'VbzAdminOrderMsgs', //'clsAdminRstkReqItems', 'clsAdminRstkReqs', //'VbzAdminSessions', 'VbzAdminStkItems', 'VbzAdminSuppliers', 'VbzAdminTitles', //'VbzAdminTitles_info_Cat', //'VbzAdminTitles_info_Item', //'clsAdminTitleTopic_Titles', //'clsAdminTitleTopic_Topics', 'clsAdminTopics',
//'clsCMITems', 'clsCtgGroups', //'clsCtgTitles', //'clsOrderPullTypes', 'clsPackages', //'clsPkgLines', 'clsShipments', //'clsStkLog', //'clsTitleTopics_base', //'clsRstkRcdLines', 'clsRstkRcds', //'VbzStockBinLog', 'VbzStockBins', 'VbzStockPlaces', ); return $ar;
} /*----- PURPOSE: do stuff that only admins are allowed to do */ public function doAdmin() {
global $wgOut; $obj = $this->obj; $tbl = $this->tbl;
$out =NULL; $didPage = FALSE;
if (is_object($obj)) { $out = $obj->AdminPage(); $didPage = TRUE; } elseif (is_object($tbl)) { $out = $tbl->AdminPage(); $didPage = TRUE; }
if (!$didPage) { $page = $this->page; $idObj = $this->idObj; $doObj = $this->doObj;
if (!is_null($page)) { $dbVBZ = $this->DB();
$out = NULL; switch ($page) { case 'cache': case 'cache.tbl': case 'cache.proc': $this->DB()->CacheMgr()->MenuDispatch($page,$idObj); break; case 'cat.search': $tbl = $dbVBZ->Titles_Cat(); $out = $tbl->SearchPage(); break; case 'log.cart': $objTbl = new VbzAdminCartLog($dbVBZ); $out = $objTbl->AdminPage(); break; case 'log.misc': $objLog = new clsAdminEvents($dbVBZ); $objLog->ListPage(); break; case 'migr.encr': $objCards = $dbVBZ->CustCards(); $objCards->EncryptAdmin(); break; case 'rstk.need': $objTbl = $dbVBZ->RstkReqs(); $objTbl->AdminItemsNeeded(); break; case 'rstk.past': $objTbl = $dbVBZ->RstkReqs(); $objRows = $objTbl->RowsInactive(); $out = $objRows->AdminList(); break; case 'rstk-rcd': $objTbl = $dbVBZ->RstkRcds(); $objRow = $objTbl->GetItem($idObj); $out = $objRow->AdminPage(); break; case 'rstk-req': $objTbl = $dbVBZ->RstkReqs(); $objRow = $objTbl->GetItem($idObj); $out = $objRow->AdminPage(); break; case 'rstk.wait': $objTbl = $dbVBZ->RstkReqs(); $objRows = $objTbl->RowsActive(); $out = $objRows->AdminList(); break; case 'toship': $this->doStockToShip(); break; case 'util.stats': $this->DoUpdateStats(); break; case 'util.plist': $this->DoPriceList(); break; case 'util.inv': $this->DoInvCompare(); break; default: $out = 'Select from the menu above.'; } } } if (!is_null($out)) { $wgOut->AddWikiText($out,TRUE); }
} public function doCharges() {
global $wgOut; global $vgPage;
$doAll = $vgPage->Arg('all'); $strMnuAll = $this->SelfLink_WT(array('all' => TRUE),'all'); $strMnuUnp = $this->SelfLink_WT(array('all' => FALSE),'to process');
$objTbl = new VbzAdminOrderChgs($this->DB()); if ($doAll) { $strMenu = "$strMnuUnp .. $strMnuAll"; $strDescr = ' in database'; $sqlFilt = NULL; } else { $strMenu = "$strMnuUnp .. $strMnuAll"; $strDescr = ' to be processed'; $sqlFilt = '(WhenDecided IS NULL) AND ((WhenXmitted IS NULL) OR isSuccess) AND (WhenVoided IS NULL) AND (WhenHeldUp IS NULL)'; } $objRows = $objTbl->GetData($sqlFilt,NULL,'ID DESC'); $wgOut->AddWikiText("Show Charges: $strMenu", TRUE); $arArgs['descr'] = $strDescr; $wgOut->AddWikiText($objRows->AdminTable($arArgs),TRUE);
} public function doUser() {
global $wgOut; /* PURPOSE: do only stuff that regular users are allowed to do
- /
$wgOut->AddWikiText('Hello regular user! I haven\'t written anything for you yet, but soon (Josh permitting).');
}
// individual admin functions
public function doStockToShip() {
global $wgOut;
$dbVBZ = $this->DB(); $out = '==Stock to Ship=='."\n"; $wgOut->addWikiText($out,TRUE); $out = ; $objRows = $dbVBZ->DataSet('SELECT * FROM '.KSQL_DS_ITEMS_TO_SHIP); if ($objRows->hasRows()) { $out = "{| class=sortable \n|-\n! item || order || # needed || # avail || bin"; while ($objRows->NextRow()) { $idItem = $objRows->ID_Item; $idOrd = $objRows->ID_Order; $idBin = $objRows->ID_Bin; $strOrd = $objRows->OrdText?$objRows->OrdText:'?ord#?'; $wtItem = ''.$idItem.' '.SelfLink_Page('item','id',$idItem,$objRows->ItemText); $wtOrder = ''.$idOrd.' '.SelfLink_Page(KS_URL_PAGE_ORDER,'id',$idOrd,$strOrd); $wtBin = ''.$idBin.' '.SelfLink_Page('bin','id',$idBin,$objRows->BinText); $wtQtyNeed = $objRows->QtyOpen; $intQtyForShip = $objRows->QtyForSale; $intQtyForSale = $objRows->QtyForSale; $wtQtyAvail = $intQtyForShip; if ($intQtyForShip != $intQtyForSale) { $wtQtyAvail .= ' ('.$intQtyForSale.')'; } $out .= "\n|-\n| $wtItem || $wtOrder || $wtQtyNeed || $wtQtyAvail || $wtBin"; } $out .= "\n|}\n(Retrieval complete.)"; } else { $out = 'No stock items available for open orders.'; } $wgOut->addWikiText($out,TRUE); $out = ;
}
/*
public function doCacheTables() {
$this->DB()->CacheMgr()->AdminPage();
}
- /
public function doSuppliers() {
$objSupps = $this->DB()->Suppliers(); $objSupps->ListPage();
} public function doSupplier($iID) {
$objSupps = $this->DB()->Suppliers(); $objSupp = $objSupps->GetItem($iID); return $objSupp->AdminPage();
} public function doDept($iID) {
$objDepts = $this->DB()->Depts(); $objDept = $objDepts->GetItem($iID); return $objDept->InfoPage();
} public function doTitle($iID) {
$objTitles = $this->DB()->Titles(); $objTitle = $objTitles->GetItem($iID); return $objTitle->InfoPage();
} public function doItem($iID) {
$objTbl = $this->DB()->Items(); $objRow = $objTbl->GetItem($iID); return $objRow->InfoPage();
} public function doImgAdmin() {
$objTbl = $this->DB()->Images(); return $objTbl->AdminPage_Unassigned();
} /*---- TO DO: This really should be rewritten as a method of clsContactNode USED BY: VbzAdminOrder::DoSetupCart() in admin.ord.php HISTORY:
2011-04-17 using AdminLink() on customer object instead of hand-building the links
*/ function CheckPersonMatches(clsPerson $iPerson,VbzAdminCart $iCart) {
$objDB = $this->DB(); $objPage = $this; $objPerson = $iPerson; $objCart = $iCart; //$arLink = $iLinkArr;
$strName = $objPerson->FormName(); $strDescr = $objPerson->Descr();
$objName = $iPerson->Node('name'); if (!is_object($objName)) { echo $iPerson->DumpHTML(); throw new exception('Internal error: missing object in tree.'); } $strCustName = $objName->Value();
$out = "\n
Contact information for $strDescr:"; $out .= "\n
- ";
if ($objCart->DataItem(KSI_SHIP_IS_CARD)) {
$strAddrShip = 'Address';
} else {
// $strCardAddr = $objPerson->Card->Addr->AsSingleLine();
$objPay = $objPerson->Payment();
if (is_null($objPay)) {
/*
2011-10-04 this isn't a problem as long as _one_ of the calls has payment in iPerson
echo 'Person object tree:';
echo $objPerson->DumpHTML();
throw new exception('Payment object is NULL');
*/
$strCardAddr = NULL; // so later code knows not to try using it
} else {
$strCardAddr = $objPay->Addr()->AsSingleLine();
$out .= "\n
- Card Address: ".$strCardAddr.' '; $strAddrShip = 'Shipping Address'; } } if ($objPerson->HasContact()) { $objAddr = $objPerson->Contact()->Addr(); if ($objAddr) { $strShipAddr = $objAddr->AsSingleLine(); $out .= "\n
- $strAddrShip: ".$strShipAddr.' '; $out .= "\n
- Searching as: ".clsCustAddrs::Searchable($strShipAddr).'
- Email: ".$strEmail.' '; } if ($objPerson->Contact()->HasPhone()) { $strPhone = $objPerson->Contact()->Phone()->Value(); $out .= "\n
- Phone: ".$strPhone.' '; } } $out .= "\n
} if ($objPerson->Contact()->HasEmail()) { $strEmail = $objPerson->Contact()->Email()->Value();
$out .= "\n// Look for matches to existing contacts $out .= "\nChecking $strDescr for matches to existing customers..."; // -- name // --- customer $objRows = $objDB->CustNames()->Find($strCustName); if ($objRows->HasRows()) { while ($objRows->NextRow()) { $idCont = $objRows->ID_Cust; $idName = $objRows->ID; $arSame[$idCont]['name'] = $objRows->RowCopy(); } } // --- destination (if different) if (isset($strDestName)) { $objRows = $objDB->CustNames()->Find($strDestName); if ($objRows->HasRows()) { while ($objRows->NextRow()) { $idCont = $objRows->ID_Cust; $idName = $objRows->ID; $arSame[$idCont]['name'] = $objRows->RowCopy(); } } }
// -- address // --- card if ($objCart->DataItem(KSI_SHIP_IS_CARD)) { $strAddrShip = 'addr'; } else { $strAddrShip = 'addr-ship'; if (!is_null($strCardAddr)) { $objRows = $objDB->CustAddrs()->Find($strCardAddr); if ($objRows->HasRows()) { while ($objRows->NextRow()) { $idCont = $objRows->ID_Cust; $idName = $objRows->ID; $arSame[$idCont]['addr-card'] = $objRows->RowCopy(); } } } } // --- shipping if (isset($strCardAddr)) { $objRows = $objDB->CustAddrs()->Find($strCardAddr); if ($objRows->HasRows()) { while ($objRows->NextRow()) { $idCont = $objRows->ID_Cust; $idName = $objRows->ID; $arSame[$idCont][$strAddrShip] = $objRows->RowCopy(); } } } if (isset($objPerson->Contact)) { // -- phone if (isset($strPhone)) { $objRows = $objDB->CustPhones()->Find($strPhone); if ($objRows->HasRows()) { while ($objRows->NextRow()) { $idCont = $objRows->ID_Cust; $idName = $objRows->ID; $arSame[$idCont]['phone'] = $objRows->RowCopy(); } } }
// -- email if (isset($strEmail)) { // sometimes this isn't set; this may be a bug. figure out why later. $objRows = $objDB->CustEmails()->Find($strEmail); if ($objRows->HasRows()) { while ($objRows->NextRow()) { $idCont = $objRows->ID_Cust; $idName = $objRows->ID; $arSame[$idCont]['email'] = $objRows->RowCopy(); } } } } // -- credit card $strCard = $objCart->DataItem(KSI_CUST_CARD_NUM); $objRows = $objDB->CustCards()->Find($strCard); if ($objRows->HasRows()) { while ($objRows->NextRow()) { $idCont = $objRows->ID_Cust; $idName = $objRows->ID; $arSame[$idCont]['card'] = $objRows->RowCopy(); } } // Report any matches found: if (isset($arSame)) { $out .= "\nChoose how to resolve the match:";
$out .= "\n- ";
foreach ($arSame as $idCont=>$val) {
$objCust = $objDB->Custs($idCont);
$htLink = $objCust->AdminLink_status();
$out .= "\n
- <input type=radio name=\"$strName\" value=\"$idCont\">Use contact #$htLink</a>:";
$out .= "\n
- ";
foreach($val as $vkey=>$vval) {
$strDescr = $vval->ShortDescr();
$out .= "\n
- $vkey: $strDescr "; } $out .= "\n
";
- <input type=radio name=\"$strName\" value=\"new\">Create new contact record "; $out .= "\n
}
$out .= "\n } else {
// 2011-07-28 removing "create new records" link; should be created on import if none found
// $htURL = $objPage->SelfURL(array('allnew'=>TRUE));
// $htLink = '<a href="'.$htURL.'">create new records</a>';
$out .= "\n
No matches found; new contact records will be created.";
$out .= '<input type=hidden name="cust" value=new /><input type=hidden name="ship" value=new />';
}
return $out;
} protected function DoUpdateStats() {
$objVars = $this->objDB->VarsGlobal();
$sqlStkQty = 'SELECT SUM(QtyForSale) AS Qty FROM qryStkItms_for_sale'; $intStkQty = 0;
$objVars->Val('stat.stock.qty',$intStkQty); // total stock quantity
} protected function DoPriceList() {
global $wgOut,$wgRequest; global $vgPage;
$vgPage->UseHTML();
$doCheck = $wgRequest->GetBool('btnCheck');
$out = NULL;
$out .= 'Enter catalog numbers or item IDs:';
if ($doCheck) { $txt = $wgRequest->GetText('list'); $xts = new xtString($txt); $xts->ReplaceSequence("\n\t ", ' ',0); $ar = explode (' ',$xts->Value);
$pos = strpos ($txt,':'); // colon means there are quantities $hasQtys = is_numeric($pos);
$htTxt = htmlspecialchars($txt); $htTxtRows = 3; } else { $htTxt = ; $htTxtRows = 30; }
if ($doCheck) {
$out .= '';} else { $htQtyCol = ; }
$objDB = $this->DB();
$out .= '';
if ($hasQtys) { $htQtyCol = ' | Qty | ';
$out .= ''.$htQtyCol.'';
$arItems = array(); $arQtys = array(); foreach ($ar as $word) { // if word contains a colon, ignore it and everything after (so we can use that format here even though qty is irrelevant): $pos = strpos ($word,':'); if ($pos) { $qty = substr($word,$pos+1); $word = substr($word,0,$pos); } else { $qty = NULL; } if (is_numeric($word)) { $id = $word; $objItem = $objDB->Items($id); if (is_object($objItem)) { $id = $objItem->Value('ID'); if (!array_key_exists($id,$arItems)) { $arItems[$id] = $objItem->Values(); $arCatNums[$objItem->Value('CatNum')] = $id; } $arQtys[$id] = NzArray($arQtys,$id)+$qty; } else { $out .= "\n" .'';} } else { // to be written } } ksort($arCatNums); foreach ($arCatNums as $catnum => $id) {
//echo ' $mnSellExact = $objItem->Value('PriceSell'); $mnSellRound = round($mnSellExact) + 1.00; $out .= "\n" .'';if ($hasQtys) { $qty = $arQtys[$id]; if (is_null($qty)) { $out .= '';} else { $out .= "";} } $out .= '' .'' .'' .'' .''; } $out .= '
|
---|
}
$out .= '<form method=post>'; $out .= '<textarea name=list rows='.$htTxtRows.'>'.$htTxt.'</textarea>'; $out .= '<input type=submit name=btnCheck value="Check" />'; $out .= '</form>';
$wgOut->AddHTML($out); return NULL; // caller expects wikitext
} private function DoInvCompare() {
global $vgPage; global $wgOut,$wgRequest;
$txtStart = $wgRequest->GetText('txtStart'); $txtFinish = $wgRequest->GetText('txtFinish');
$vgPage->UseHTML();
$htStart = htmlspecialchars($txtStart); $htFinish = htmlspecialchars($txtFinish);
$fxParse = function($iText) { $ar = preg_split('/ /',$iText); foreach ($ar as $item) { list($id,$qty) = preg_split('/:/',$item); $arOut[$id] = $qty; } return $arOut; };
$arStart = $fxParse($txtStart); $arFinish = $fxParse($txtFinish);
$arDiff = array(); foreach ($arStart as $id => $qty) { $qtyFinish = nzArray($arFinish,$id); if ($qty != $qtyFinish) { $arDiff[$id] = 'old:'.$qty.' new:'.$qtyFinish; } } foreach ($arFinish as $id => $qty) { $qtyStart = nzArray($arStart,$id); if (!array_key_exists($id,$arStart)) { $arDiff[$id] = 'new:'.$qty; } }
$out = '<form method=post action="'.$vgPage->SelfURL().'">'; $out .= 'Display difference between two inventory counts:';
$out .= ''; $out .= ""; $out .= ""; $out .= ''; $out .= 'Starting inventory:<textarea rows=10 name=txtStart>$txtStart</textarea> | Ending inventory:<textarea rows=10 name=txtFinish>$txtFinish</textarea> |
<input type=submit name=btnCalc value="Compare"> |
$out .= '</form>';
if (count($arDiff) > 0) { $tbl = $this->DB()->Items();
$out .= ''; foreach ($arDiff as $id => $txt) { $obj = $tbl->GetItem($id); $out .= '';}
$out .= ''.$obj->AdminLink_friendly().' | '.$txt.' |
} else { $cnt = count($arStart); $out .= $cnt.' item'.Pluralize($cnt).' compared - inventories are identical.'; }
$wgOut->AddHTML($out); return NULL; // caller expects wikitext
}
}
/* *****
- CATALOG DATA
- /
class VbzAdminSuppliers extends clsSuppliers {
public function __construct($iDB) {
parent::__construct($iDB); $this->ClassSng('VbzAdminSupplier');
} public function AdminPage() {
global $wgOut; global $vgPage;
$vgPage->UseWiki();
$out = '==Suppliers=='; $wgOut->addWikiText($out,TRUE); $out = ; $objRecs = $this->GetData(); if ($objRecs->HasRows()) { $out = "{| class=sortable\n|-\n! ID || A? || Code || Actions || Name"; $isOdd = TRUE; while ($objRecs->NextRow()) { $strCatKey = $objRecs->CatKey; $id = $objRecs->ID; $wtActions = '['.KWP_CAT.strtolower($strCatKey)." shop] " .$objRecs->AdminLink('manage'); $wtCatNum = $strCatKey; $wtStyle = $isOdd?'background:#ffffff;':'background:#cccccc;'; $isActive = $objRecs->isActive; if ($isActive) { $wtName = '[['.$objRecs->Name.']]'; } else { $wtName = $objRecs->Name; $wtStyle .= ' color: #888888;'; } $out .= "\n|- style=\"$wtStyle\"\n| ".$id .' || '.($isActive?'√':) .' || '.$wtCatNum .' || '.$wtActions .' || '.$wtName; $isOdd = !$isOdd; } $out .= "\n|}"; } else { $out = 'No suppliers have been created yet.'; } $wgOut->addWikiText($out,TRUE); $out = ;
}
} class VbzAdminSupplier extends clsSupplier {
/*==== HISTORY:
2010-12-05 boilerplate event logging added to VbzAdminSupplier
*/ protected function Log() {
if (!is_object($this->logger)) { $this->logger = new clsLogger_DataSet($this,$this->objDB->Events()); } return $this->logger;
} public function StartEvent(array $iArgs) {
return $this->Log()->StartEvent($iArgs);
} public function FinishEvent(array $iArgs=NULL) {
return $this->Log()->FinishEvent($iArgs);
} public function EventListing() {
return $this->Log()->EventListing();
} //==== /*---- HISTORY:
2010-10-11 Replaced existing code with call to static function
*/ public function AdminLink($iText=NULL,$iPopup=NULL,array $iarArgs=NULL) {
return clsAdminData::_AdminLink($this,$iText,$iPopup,$iarArgs);
} public function AdminLink_name() {
return $this->AdminLink($this->Name);
} /*---- HISTORY:
2010-11-04 Created so AdminPage() can use HTML 2011-02-16 Disabled until I figure out why it isn't redundant
*/
/*
public function ShopLink($iText=NULL) {
return '<a href="'.KWP_CAT.strtolower($this->CatKey).'">'.$iText.'</a>';
}
- /
public function PageTitle() {
global $vgPage;
$doShow = $vgPage->Arg('show'); return $this->Value('CatKey').':'.$doShow;
} /*---- RETURNS: object for Supplier's Topic HISTORY:
2011-10-01 written -- replacing Departments with Topics
*/ public function TopicObj() {
$id = $this->Value('ID_Topic'); if (is_null($id)) { return NULL; } else { $row = $this->Engine()->Topics($id); return $row; }
} /*---- RETURNS: nicely-formatted link to Supplier's Topic HISTORY:
2011-10-01 written -- replacing Departments with Topics
*/ public function TopicLink($iNone='n/a') {
$row = $this->TopicObj(); if (is_object($row)) { return $row->AdminLink_name(); } else { return $iNone; }
} /*---- */ public function AdminPage() {
global $wgOut,$wgRequest; global $vgPage,$vgOut;
$vgPage->UseHTML(); $out = NULL;
$doEdit = $vgPage->Arg('edit'); $doSave = $wgRequest->GetBool('btnSave');
// save edits before showing events $ftSaveStatus = NULL; if ($doEdit || $doSave) { $this->BuildEditForm(); if ($doSave) { $ftSaveStatus = $this->AdminSave(); } }
$strCatKey = $this->CatKey; $strName = $this->Name;
$doDeptAdd = $vgPage->Arg('add.dept');
$objPage = new clsWikiFormatter($vgPage); $objSection = new clsWikiSection($objPage,$strName.' ('.$strCatKey.')'); $out = $objSection->Generate(); $wgOut->AddHTML($out); $out = ;
$objSection = new clsWikiSection($objPage,'Current Record (ID '.$this->ID.')',NULL,3); $objSection->ToggleAdd('edit'); $out = $objSection->Generate();
if ($doEdit) { $out .= $objSection->FormOpen();
$objForm = $this->objForm; $ftName = $objForm->Render('Name'); $ftCatKey = $objForm->Render('CatKey'); $ftTopic = $objForm->Render('ID_Topic'); $ftActive = $objForm->Render('isActive'); } else { $ftName = $vgOut->InternalLink($strName); $ftCatKey = $this->ShopLink($strCatKey); $ftTopic = $this->TopicLink(); $ftActive = NoYes($this->isActive); }
$ftID = $this->AdminLink();
$out .= $vgOut->TableOpen();
$out .= $vgOut->TblRowOpen(); $out .= $vgOut->TblCell('ID:','align=right'); $out .= $vgOut->TblCell($ftID); $out .= $vgOut->TblRowShut();
$out .= $vgOut->TblRowOpen(); $out .= $vgOut->TblCell('Name:','align=right'); $out .= $vgOut->TblCell($ftName); $out .= $vgOut->TblRowShut();
$out .= $vgOut->TblRowOpen(); $out .= $vgOut->TblCell('CatKey:','align=right'); $out .= $vgOut->TblCell($ftCatKey); $out .= $vgOut->TblRowShut();
$out .= $vgOut->TblRowOpen(); $out .= $vgOut->TblCell('Topic:','align=right'); $out .= $vgOut->TblCell($ftTopic); $out .= $vgOut->TblRowShut();
$out .= $vgOut->TblRowOpen(); $out .= $vgOut->TblCell('Active:','align=right'); $out .= $vgOut->TblCell($ftActive); $out .= $vgOut->TblRowShut();
$out .= $vgOut->TableShut();
if ($doEdit) {
$out .= 'Edit notes: <input type=text name="EvNotes" size=40>
';
$out .= '<input type=submit name="btnSave" value="Save">';
$out .= '<input type=submit name="btnCancel" value="Cancel">';
$out .= '<input type=reset value="Reset">';
$out .= '</form>';
}
$vgOut->addText($out,TRUE); $out = ;
// show submenu $arMnu = array( 'dept' => '.departments.'.$strName.' departments', 'cat' => '.catalogs.'.$strName.' wholesale catalogs', 'rreq' => '.restocks.'.$strName.' restock requests', 'ctg' => '.catalog groups.groups for organizing '.$strName.' catalog items' ); $out = 'Manage: '.$vgPage->SelfLinkMenu('show',$arMnu); $vgOut->AddText($out); $out = ;
$doShow = $vgPage->Arg('show');
//$vgPage->UseWiki(); switch ($doShow) { /* Some remediation needed here. Some of these output in wikitext, others in HTML.
All of them seem to output directly, rather than returning rendered text.
- /
case 'dept': $objSection = new clsWikiSection($objPage,'Departments',NULL,3); $objSection->ToggleAdd('add','add a department to '.$strName,'add.dept'); $out = $objSection->Generate(); $wgOut->addHTML($out,TRUE); $out = ; $out .= $this->DeptsListing(); break; case 'cat': $objSection = new clsWikiSection($objPage,'Catalogs',NULL,3); $arLink = array( 'page' => $this->objDB->CtgSrcs()->ActionKey(), 'id' => 'new', 'supp' => $this->ID ); $objSection->ActionAdd('add','add a catalog to '.$strName,FALSE,$arLink); $out = $objSection->Generate(); $wgOut->addHTML($out,TRUE); $out = ; $out .= $this->CatalogAdmin(); break; case 'rreq': $objSection = new clsWikiSection($objPage,'Restock Requests',NULL,3); $out = $objSection->Generate(); $wgOut->addHTML($out,TRUE); $out = ; $out .= $this->RstkReqAdmin(); break; case 'ctg': $objSection = new clsWikiSection($objPage,'Catalog Groups','catalog management groups',3); $objSection->ArgsToKeep(array('show','page','id')); $objSection->ToggleAdd('edit','edit the list of groups','edit.ctg'); $out = $objSection->Generate(); $wgOut->addHTML($out,TRUE); $out = ; $doEdit = $vgPage->Arg('edit.ctg'); $out .= $this->CtgGrpAdmin($doEdit); break; default: $out = ; } $vgOut->addText($out);
} /*---- ACTION: Save user changes to the record HISTORY:
2010-11-06 copied from VbzStockBin to VbzAdminItem 2011-01-26 copied from VbzAdminItem to clsAdminTopic 2011-10-02 copied from clsAdminTopic to VbzAdminSupplier
*/ public function AdminSave() {
global $vgOut;
$out = $this->objForm->Save(); $vgOut->AddText($out);
} /*---- HISTORY:
2010-11-06 adapted from VbzStockBin for VbzAdminTitle 2011-10-01 adapted from VbzAdminTitle for VbzAdminSupplier
*/ private function BuildEditForm() {
global $vgOut;
if (is_null($this->objForm)) { // create fields & controls $objForm = new clsForm_DataSet($this,$vgOut); //$objCtrls = new clsCtrls($objForm->Fields()); //$objCtrls = $objForm;
$objForm->AddField(new clsField('Name'), new clsCtrlHTML(array('size'=>25))); $objForm->AddField(new clsFieldNum('ID_Topic'), new clsCtrlHTML()); $objForm->AddField(new clsField('CatKey'), new clsCtrlHTML(array('size'=>8))); $objForm->AddField(new clsFieldBool('isActive'), new clsCtrlHTML_CheckBox()); $objForm->AddField(new clsField('Notes'), new clsCtrlHTML_TextArea(array('height'=>3,'width'=>50)));
$this->objForm = $objForm; //$this->objCtrls = $objCtrls; }
} public function DeptsListing() {
$out = $this->objDB->Depts()->Listing_forSupp($this->ID,$this); return $out;
} /*%%%% SECTION: Data Entry Management PROCESS: * User enters a list of Titles or Items in a textarea box, one per line. * Each line is checked against Supplier catalog #s * if found, shows details for the title/item and provides option to approve it in the final resultset * if not found, gives user the option to give more information identifying the Title/Item, such as
our catalog # (or what our catalog # would be if the Title/Item existed in the database)
*/ /*---- PURPOSE: renders form for reconciliation of a user-entered list of Titles from a Supplier source document INPUT:
$iTitles[line #] = array of title information, format to be determined ['id'] = ID of Title record to be approved as matching the input ['scat'] = supplier's catalog number ['ocat'] = our catalog number (may be hypothetical) ['$buy'] = cost to us ['$sell'] = our selling price (to customer) ['name'] = descriptive name for the Title
RETURNS: HTML code for reconciliation form. Does not include <form> tags or buttons. */
/*
public function AdminTitles_form_entry(array $iTitles) {
die('This function is not ready yet!');
if (count($iTitles) > 0) { $isOdd = TRUE; $isReady = TRUE; // ready to enter - all items have been identified
$out .= '';foreach ($iTitles as $cnt => $data) { $ftStyle = $isOdd?'background:#ffffff;':'background:#eeeeee;'; $htAttr = ' style="'.$ftStyle.'"'; $isOdd = !$isOdd;
$strScat = nz($data['scat']); $strInvTitle = nz($data['title']); $strPrBuy = nz($data['$buy']); $strPrSell = nz($data['$sell']); $strQty = nz($arOut['qty']);
$out .= "<tr$htAttr>";} } else { $out = 'No titles entered.'; }
}
- /
/*---- PURPOSE: renders form for reconciliation of a user-entered list of Items from a Supplier source document
(same as AdminTitles_form_entry() but for Items instead of Titles)
ACTION: Renders an Item-reconciliation form INPUT: output from AdminItems_data_check() OUTPUT: returned data RETURNS: HTML of form containing data AdminItems_form_receive() is expecting to see */ public function AdminItems_form_entry(array $iData) {
$cntItems = count($iData);
if ($cntItems > 0) { $strPfx = $this->Value('CatKey'); $isOdd = TRUE;
$out = 'ID | Cat# | Title | Qty | Price |
---|---|---|---|---|
$strScat | $strInvTitle | $strQty | $strPrice |
<input type=checkbox name="do-upd-scat['.$idx.']">'.$strAct.''; } $htName = $strInvTitle.'<input type=hidden name="name['.$idx.']" value="'.htmlspecialchars($strInvTitle).'">'; if ($canUpdDescr) { if (empty($strDescrRec)) { $strAct = 'save this'; } else { $strAct = 'replace '.$strDescrRec.''; } $htName .= '
<input type=checkbox name="do-upd-desc['.$idx.']">'.$strAct.''; } $htQty = $strQty.'<input type=hidden name="qty['.$idx.']" value='.$strQty.'>'; $htPrBuy = $strPrBuy.'<input type=hidden name="$buy['.$idx.']" value="'.$strPrBuy.'">'; $htPrSell = $strPrSell.'<input type=hidden name="$sell['.$idx.']" value="'.$strPrSell.'">'; switch ($row['@state']) { case 'use': $htStatus = 'ready'; break; case 'add': $htStatus = 'addable'; break; default: $htStatus = '?'; } $out .= "\n<tr$htAttr>" ."\n\t" ."\n\t" ."\n\t" ."\n\t" ."\n\t" ."\n\t" ."\n\t" ."\n\t" ."\n\t" ."\n\t"; } $out .= '
status | ID | Our Cat# | SCat# | What | Qty | $buy | $sell | |
---|---|---|---|---|---|---|---|---|
$idx. | $htStatus | $htItem | $htOCat | $htSCat | $htName | $htQty | $htPrBuy | $htPrSell |
} else { $out = 'No titles entered.'; } return $out;
} /*---- ACTION: Receives user data from form rendered by AdminItems_form_entry() INPUT: http POST data from Item reconciliation form
id[line #] = array of Item IDs, where known name[line #] = array of item descriptions qty[line #] = array of item quantities scat[line #] = array of supplier catalog numbers for each line, entered by user ocat[line #] = array of our catalog numbers for each line, entered by user $buy[line #] = array of price-to-us for each line, entered by user $sell[line #] = array of price-to-customer for each line, entered by user
NOTE: sell[] is not currently used in any known scenario. Possibly it should be removed. RETURNS: array of all received data, but indexed by line number first
includes the following fields: ['qty'] = item quantity ['ocat'] = catalog number entered by the user to be used either for looking up the item or creating it
FUTURE: This should be generalized somehow */ public function AdminItems_form_receive() {
global $wgRequest;
$arCols = array('id','name','qty','ocat','scat','$buy','$sell','do-upd-scat','do-upd-desc'); foreach ($arCols as $col) { $arOut[$col] = $wgRequest->GetArray($col); } $arRtn = ArrayPivot($arOut);
//echo ''.print_r($arRtn,TRUE).'';
return $arRtn;
} /*---- ACTION: Check item data against database and return status information INPUT:
$iItems[line #]: array in format returned by AdminItems_form_receive()
RETURNS:
['#add'] = number of rows which need to be added to the catalog ['#use'] = number of rows which are ready to be used (item exists in catalog) ['rows'] = input data with additional fields: ['@state']: status of line as indicated by one of the following strings: 'use' = item has been found, so this line is ready to use 'add' = item not found, but there is enough information to create it ['@obj'] is the Item object (only included if @state = 'use')
*/ public function AdminItems_data_check(array $iItems) {
if (count($iItems) > 0) { $cntUse = 0; $cntAdd = 0; $cntUpd = 0; // count of updatable fields $arRows = array(); $strCatPfx = $this->Value('CatKey'); foreach ($iItems as $idx => $data) { $idItem = nz($data['id']);
$strOCatRaw = nz($data['ocat']); $strOCatFull = $strCatPfx.'-'.$strOCatRaw; $gotOCat = !empty($strOCatRaw);
$strSCat = nz($data['scat']);
$data['@state'] = NULL; $data['@obj'] = NULL; if (empty($idItem)) { if ($gotOCat) { // look up item using our catalog # $objItem = $this->objDB->Items()->Get_byCatNum($strOCatFull); } else { // look up item using supplier catalog # $objItem = $this->GetItem_bySCatNum($strSCat); } if (is_null($objItem)) { if ($gotOCat) { $data['@state'] = 'add'; $cntAdd++; } } } else { $objItem = $this->objDB->Items($idItem); } if (is_object($objItem)) { $data['@obj'] = $objItem; $data['@state'] = 'use'; $cntUse++;
// compare entered values with recorded values // -- supplier catalog # $strSCatEnt = $strSCat; // entered $strSCatRec = $objItem->Supp_CatNum; // recorded if ($strSCatEnt != $strSCatRec) { $cntUpd++; $data['@can-upd-scat'] = TRUE; } else { $data['@can-upd-scat'] = FALSE; } // -- title $strDescrEnt = nz($data['name']); // entered $strDescrRec = $objItem->Descr; // recorded if ($strDescrEnt != $strDescrRec) { $cntUpd++; $data['@can-upd-desc'] = TRUE; } else { $data['@can-upd-desc'] = FALSE; } } $arRows[$idx] = $data; } // foreach ($iItems...) } else { $arRtn = NULL; } $arRtn = array( 'rows' => $arRows, '#use' => $cntUse, '#upd' => $cntUpd, '#add' => $cntAdd); return $arRtn;
} /*---- ACTION: Creates listed catalog items INPUT: Array of items as returned by AdminItems_data_check() RETURNS: HTML to display (messages) */ public function AdminItems_data_add(array $iItems) {
$out = ;
$tblItems = $this->objDB->Items();
$cntItems = count($iItems); $txtOCats = ; foreach ($iItems as $idx => $row) { $txtOCats .= ' '.$row['ocat']; } $strEv = 'Adding '.$cntItems.' item'.Pluralize($cntItems).':'.$txtOCats;
$arEv = array( 'descr' => SQLValue($strEv), 'where' => SQLValue(__METHOD__), 'code' => SQLValue('RI+') // Reconcile Items: add ); $this->StartEvent($arEv);
$strCatPfx = $this->Value('CatKey'); foreach ($iItems as $idx => $row) { $strOCat = $strCatPfx.'-'.strtoupper($row['ocat']); $arAdd = array( 'CatNum' => SQLValue($strOCat), 'isCurrent' => 'FALSE', // we don't actually know anything about availability yet 'ID_Title' => 0, // needs to be assigned to a title 'Descr' => SQLValue($row['name']), 'Supp_CatNum' => SQLValue($row['scat']) ); if (!empty($row['$buy'])) { $arAdd['PriceBuy'] = SQLValue($row['$buy']); } if (!empty($row['$sell'])) { $arAdd['PriceSell'] = SQLValue($row['$sell']); }
//$out .= ''.print_r($arAdd,TRUE).'';
$tblItems->Insert($arAdd); } $out = $strEv; $this->FinishEvent(); return $out;
} /*---- ACTION: Renders drop-down box of all Suppliers, with the current one as default USED BY: Restock edit screen HISTORY:
2011-03-02 What happened? Apparently this method used to exist, but got deleted without a trace. Rewriting from scratch.
*/ public function DropDown($iName=NULL,$iNone=NULL) {
$strName = is_null($iName)?($this->Table->ActionKey()):$iName; // control name defaults to action key
$rs = $this->Table->GetData();
if ($rs->HasRows()) { $out = "\n<SELECT NAME=$strName>"; if (!is_null($iNone)) { $out .= DropDown_row(NULL,$iNone,$iDefault); } while ($rs->NextRow()) { $id = $rs->Value('ID'); $txtAbbr = $rs->Value('CatKey'); $htAbbr = is_null($txtAbbr)?:($txtAbbr.' '); $htShow = $htAbbr.$rs->Value('Name'); $out .= DropDown_row($id,$htShow,$this->Value('ID')); } $out .= "\n</select>"; return $out; } else { return NULL; }
} /*---- ACTION: Renders drop-down box of active departments for this supplier RETURNS: HTML code */ public function Depts_DropDown($iName=NULL,$iDefault=NULL,$iNone=NULL) {
$objRecs = $this->objDB->Depts()->Data_forSupp($this->ID,'isActive'); $out = $objRecs->DropDown($iName,$iDefault,$iNone); return $out;
} public function CatalogAdmin() {
$objTbl = $this->objDB->Catalogs(); $objRows = $objTbl->GetData('ID_Supplier='.$this->ID,NULL,'ID DESC'); $out = $objRows->AdminList(); return $out;
} public function RstkReqAdmin() {
$objTbl = $this->objDB->RstkReqs(); $objRows = $objTbl->GetData('ID_Supplier='.$this->ID,NULL,'IFNULL(WhenOrdered,WhenCreated) DESC'); $out = $objRows->AdminList(); return $out;
} public function CtgGrpAdmin($iEdit) {
$objTbl = $this->objDB->CtgGrps(); $id = $this->KeyValue(); $objRows = $objTbl->GetData('ID_Supplier='.$id,NULL,'Sort'); $out = $objRows->AdminList($iEdit,array('ID_Supplier'=>$id)); return $out;
} /*----- ACTION: Finds the last restock request for the given supplier RETURNS: the last request by date and the last request sorted by (our) PO # */ public function LastReq() {
//$sqlBase = 'SELECT * FROM `rstk_req` WHERE ID_Supplier='.$this->ID; $sqlBase = 'WHERE ID_Supplier='.$this->ID; $sql = $sqlBase.' ORDER BY PurchOrdNum DESC LIMIT 1;'; //$objRow = $this->objDB->DataSet($sql); $objRow = $this->objDB->RstkReqs()->DataSet($sql); $objRow->NextRow(); $arOut['by purch ord'] = $objRow->RowCopy();
$sql = $sqlBase.' ORDER BY WhenOrdered DESC LIMIT 1;'; //$objRow = $this->objDB->DataSet($sql); $objRow = $this->objDB->RstkReqs()->DataSet($sql); $objRow->NextRow(); $arOut['by ord date'] = $objRow->RowCopy();
return $arOut;
} /*---- ACTION: Checks each item in the list to see if it corresponds to a given item for the current supplier INPUT: Array of supplier catalog numbers OUTPUT: Array in this format:
array[cat#] = item object (if found) or NULL (if not found)
*/
/*
public function FindItems(array $iList) {
$objTblItems = $this->objDB->Items(); foreach ($iList as $catnum) { $strCat = rtrim($catnum,';#!'); // remove comments $strCat = trim($strCat); // remove leading & trailing whitespace if (!empty($strCat)) { $sqlFind = 'Supp_CatNum="'.$strCat.'"'; $objItem = $objTblItems->GetData($sqlFind); if (is_null($objItem)) { $arOut[$strCat] = NULL; } else { $arOut[$strCat] = $objItem->RowCopy(); } } } return $arOut;
}
- /
// DEPRECATED - use GetItem_bySCatNum() public function FindItem($iCatNum) { return $this->GetItem_bySCatNum($iCatNum); }
}
class VbzAdminDepts extends clsDepts {
public function __construct($iDB) {
parent::__construct($iDB); $this->ClassSng('VbzAdminDept');
} public function Data_forSupp($iSupp,$iFilt=NULL) {
$sqlFilt = "ID_Supplier=$iSupp"; if (!is_null($iFilt)) { $sqlFilt = "($sqlFilt) AND ($iFilt)"; } $objRecs = $this->GetData($sqlFilt,NULL,'isActive, Sort, CatKey, PageKey'); return $objRecs;
} public function Listing_forSupp($iSuppID,clsSupplier $iSuppObj=NULL) {
global $wgOut;
if (is_null($iSuppObj)) { $objSupp = $this->objDB->Suppliers()->GetItem($iSuppID); } else { $objSupp = $iSuppObj; } $strSuppKey = strtolower($objSupp->CatKey);
$objRecs = $this->GetData('ID_Supplier='.$iSuppID,'VbzAdminDept','isActive, Sort, CatKey, PageKey'); if ($objRecs->HasRows()) { $out = "{| class=sortable\n|-\n! ID || A? || Cat || Page || Sort || Name || Description"; $isOdd = TRUE; while ($objRecs->NextRow()) { $strPageCode = $objRecs->PageKey; if (is_null($strPageCode)) { $wtPageCode = $strPageCode; } else { $strPagePath = $strSuppKey.'/'.strtolower($strPageCode); $wtPageCode = '['.KWP_CAT.$strPagePath.' '.$strPageCode.']'; } $id = $objRecs->ID; $wtID = SelfLink_Page('dept','id',$id,$id); $wtStyle = $isOdd?'background:#ffffff;':'background:#cccccc;'; $isActive = $objRecs->isActive; if (!$isActive) { $wtStyle .= ' color: #888888;'; } $out .= "\n|- style=\"$wtStyle\"". "\n| ".$wtID. ' || '.($isActive?'√':). ' || '.$objRecs->CatKey. ' || '.$wtPageCode. ' || '.$objRecs->Sort. ' || '.$objRecs->Name. ' || '.$objRecs->Descr; $isOdd = !$isOdd; } $out .= "\n|}"; } else { $out = 'This supplier has no departments.'; } $wgOut->addWikiText($out,TRUE); $out = ;
}
} class VbzAdminDept extends clsDept {
/*---- HISTORY:
2010-10-11 Replaced existing code with call to static function
*/ public function AdminLink($iText=NULL,$iPopup=NULL,array $iarArgs=NULL) {
return clsAdminData::_AdminLink($this,$iText,$iPopup,$iarArgs);
} public function AdminLink_name() {
$strPgKey = strtoupper($this->Value('PageKey')); $out = (is_null($strPgKey))?:($strPgKey.' '); $out .= $this->Value('Name'); return $this->AdminLink($out);
} public function DropDown($iName=NULL,$iDefault=NULL,$iNone=NULL) {
$strName = is_null($iName)?($this->Table->ActionKey()):$iName; // control name defaults to action key
if ($this->HasRows()) { $out = "\n<SELECT NAME=$strName>"; if (!is_null($iNone)) { $out .= DropDown_row(NULL,$iNone,$iDefault); } while ($this->NextRow()) { $id = $this->ID; $htAbbr = (is_null($this->PageKey))?:($this->PageKey.' '); $htShow = $htAbbr.$this->Name; $out .= DropDown_row($id,$htShow,$iDefault); } $out .= "\n</select>"; return $out; } else { return NULL; }
}
/* 2010-11-06 commenting out old event handling
public function StartEvent($iWhere,$iCode,$iDescr,$iNotes=NULL) {
$arEvent = array( 'type' => clsEvents::kTypeDept, 'id' => $this->ID, 'where' => $iWhere, 'code' => $iCode, 'descr' => $iDescr ); if (!is_null($iNotes)) { $arEvent['notes'] = $iNotes; } $this->idEvent = $this->objDB->Events()->StartEvent($arEvent);
} public function FinishEvent() {
$this->objDB->Events()->FinishEvent($this->idEvent);
}
- /
/*---- HISTORY:
2010-10-20 changing event logging to use helper class 2010-11-07 added StartEvent(), FinishEvent()
*/ protected function Log() {
if (!is_object($this->logger)) { $this->logger = new clsLogger_DataSet($this,$this->objDB->Events()); } return $this->logger;
} public function StartEvent(array $iArgs) {
return $this->Log()->StartEvent($iArgs);
} public function FinishEvent(array $iArgs=NULL) {
return $this->Log()->FinishEvent($iArgs);
} public function EventListing() {
return $this->Log()->EventListing(); /* $objTbl = $this->objDB->Events(); $objRows = $objTbl->GetData('(ModType="'.clsEvents::kTypeDept.'") AND (ModIndex='.$this->ID.')'); if ($objRows->HasRows()) { $out = $objRows->AdminRows(); } else { $out = 'No events found for this department.'; } return $out;
- /
} /*---- HISTORY:
2011-09-25 renamed from InfoPage() to AdminPage()
*/ public function AdminPage() {
global $wgOut,$wgRequest; global $vgPage;
$strCatKey = $this->CatKey; $strPageKey = $this->PageKey; if (empty($strPageKey)) { $strShopKey = strtolower($strCatKey); } else { $strShopKey = strtolower($strPageKey); } $strAction = $vgPage->Arg('do'); $doEdit = ($strAction == 'edit'); $doEnter = ($strAction == 'enter');
$doTitleCheck = $wgRequest->GetBool('btnCheck'); $doTitleAdd = $wgRequest->GetBool('btnAdd'); $doEnterBox = $doEnter || $doTitleCheck || $doTitleAdd;
$strTitle = '“'.$this->Name.'” Department';
$vgPage->UseHTML(); $objPage = new clsWikiFormatter($vgPage); //$objSection = new clsWikiAdminSection($strName); $objSection = new clsWikiSection($objPage,$strTitle); //$out = $objSection->HeaderHtml_Edit(); $objSection->ActionAdd('edit'); $objSection->ActionAdd('enter','enter titles for this department'); $out = $objSection->Generate();
$wgOut->AddHTML($out); $out = ;
if ($doEnterBox) {
$out = 'Enter Titles'; $doShowForm = $doEnter || $doTitleCheck;
if ($doShowForm) {
$out .= $objSection->FormOpen();
}
$txtNotes = $wgRequest->GetText('notes');
$htNotes = 'Notes: <input type=text name=notes size=25 value="'.htmlspecialchars($txtNotes).'">';
if ($doEnter) {
// STAGE 1: display form for entering titles
$out .= 'Enter titles to check: } } else { $htStatus = '';$htMatches = ; } $out .= ''.$htStatus.'';$out .= $htMatches; } $out .= '
}
$out .= $htNotes.' } $out .= '
$this->FinishEvent(); } if ($doShowForm) { $out .= '<input type=submit name="btnCancel" value="Cancel">'; $out .= '<input type=reset value="Reset">'; $out .= '</form>'; } $out .= ' |
$wgOut->AddHTML($out); $out = ; }
if ($doEdit) { $out .= $objSection->FormOpen(); } else { }
$vgPage->UseWiki(); $out .= "\n* ID: ".$this->ID; $out .= "\n* Supplier: ".$this->SuppObj()->AdminLink_name(); $out .= "\n* CatKey: $strCatKey"; $out .= "\n* PageKey: $strPageKey"; $out .= "\n* Shop: [".$this->URL_Abs().' '.$this->URL_Rel().']'; $out .= "\n===Titles==="; $wgOut->addWikiText($out,TRUE); $out = ; $out = $this->TitleListing(); $wgOut->addWikiText($out,TRUE); $out = ;
if ($doEdit) { $out .= '<input type=submit name="btnSave" value="Save">'; $out .= '<input type=submit name="btnCancel" value="Cancel">'; $out .= '<input type=reset value="Reset">'; $out .= '</form>'; } $wgOut->AddHTML($out); $out = ; $wgOut->addWikiText('===Events===',TRUE); $out = $this->EventListing(); $wgOut->addWikiText($out,TRUE);
} public function TitleListing() {
$out = $this->objDB->Titles_Item()->Listing_forDept($this); return $out;
} /*---- ACTION: Add a list of titles to this department INPUT:
iTitles: array iTitles[catkey] = name iEvent: array to be passed to event log
*/ public function AddTitles(array $iTitles,array $iEvent=NULL) {
$cntTitles = count($iTitles); if ($cntTitles > 0) { $strDescr = 'adding '.$cntTitles.' title'.Pluralize($cntTitles); $iEvent['descr'] = StrCat($iEvent['descr'],$strDescr,' '); $iEvent['where'] = nz($iEvent['where'],__METHOD__); $iEvent['code'] = 'ADM'; // add multiple $this->StartEvent($iEvent); $cntAdded = 0; $cntError = 0; $txtAdded = ; $txtError = ; $tblTitles = $this->objDB->Titles(); foreach ($iTitles as $catnum => $name) { $arIns = array( 'Name' => SQLValue($name), 'CatKey' => SQLValue($catnum), 'ID_Dept' => $this->ID, 'DateAdded' => 'NOW()' ); $ok = $tblTitles->Insert($arIns); if ($ok) { $idNew = $tblTitles->LastID(); $cntAdded++; $txtAdded .= '['.$catnum.' ID='.$idNew.']'; } else { $cntError++; $txtError .= '['.$catnum.' Error: '.$this->objDB->getError().']'; } } if ($cntError > 0) { $txtDescr = $cntError.' error'.Pluralize($cntError).': '.$txtError; $txtDescr .= ' and '; } else { $txtDescr = 'Success:'; } $txtDescr .= $cntAdded.' title'.Pluralize($cntAdded).' added '.$txtAdded; $arEv = array( 'descrfin' => SQLValue($txtDescr), 'error' => SQLValue($cntError > 0) ); $this->FinishEvent($arEv); }
}
} class VbzAdminTitles extends clsVbzTitles {
public function __construct($iDB) {
parent::__construct($iDB); $this->ClassSng('VbzAdminTitle'); $this->ActionKey('title');
} public function Add($iCatKey,$iName,$iDept,$iNotes) { // log start of event
$arEvent = array( 'type' => clsEvents::kTypeTitle, 'id' => NULL, 'where' => __METHOD__, 'code' => 'add', 'descr' => 'new title in dept. '.$iDept.': '.$iCatKey.': '.$iName ); if (!is_null($iNotes)) { $arEvent['notes'] = $iNotes; } $idEvent = $this->objDB->Events()->StartEvent($arEvent);
// add the title record
$arIns = array( 'CatKey' => SQLValue($iCatKey), 'Name' => SQLValue($iName), 'ID_Dept' => $iDept, 'DateAdded' => 'NOW()' ); $this->Insert($arIns); $idTitle = $this->objDB->NewID(__METHOD__);
// log the event's completion
$arUpd = array('id' => $idTitle); $this->objDB->Events()->FinishEvent($idEvent,$arUpd); return $idTitle;
} /*---- HISTORY:
2010-11-15 Changed to use qryTitles_Item_info instead of qryCat_Titles_Item_stats
*/ public function Data_Imageless() {
//$sql = 'SELECT t.ID_Title AS ID, t.* FROM `qryCat_Titles_Item_stats` AS t LEFT JOIN `cat_images` AS i ON t.ID_Title=i.ID_Title' $sql = 'SELECT t.* FROM `qryTitles_Item_info` AS t LEFT JOIN `cat_images` AS i ON t.ID=i.ID_Title' .' WHERE (i.ID IS NULL) AND (cntForSale > 0)'; $this->ClassSng('VbzAdminTitle_info_Item'); $objRows = $this->DataSQL($sql); return $objRows;
}
} class VbzAdminTitle extends clsVbzTitle {
/*---- HISTORY:
2010-10-20 changing event logging to use helper class 2010-11-08 conversion complete: added StartEvent() and FinishEvent(), deleted commented code
*/ //---- // BOILERPLATE: event logging protected function Log() {
if (!is_object($this->logger)) { $this->logger = new clsLogger_DataSet($this,$this->objDB->Events()); } return $this->logger;
} public function EventListing() {
return $this->Log()->EventListing();
} public function StartEvent(array $iArgs) {
return $this->Log()->StartEvent($iArgs);
} public function FinishEvent(array $iArgs=NULL) {
return $this->Log()->FinishEvent($iArgs);
} // BOILERPLATE: admin HTML /*---- HISTORY:
2010-10-11 Replaced existing code with call to static function
*/ public function AdminLink($iText=NULL,$iPopup=NULL,array $iarArgs=NULL) {
return clsAdminData::_AdminLink($this,$iText,$iPopup,$iarArgs);
} public function AdminLink_name() {
return $this->AdminLink($this->Value('Name'));
} public function AdminURL(array $iArgs=NULL) {
return clsAdminData::_AdminURL($this,$iArgs);
} // END BOILERPLATE //---- /*---- ACTION:
Return the current title name If a value is given, update it to the new value first (returns old value) If an event array is given, log the event
HISTORY:
2010-11-07 adapted from clsItem::SCatNum()
*/ public function Name($iVal=NULL,array $iEvent=NULL) {
$strOld = $this->Name; if (!is_null($iVal)) { if (is_array($iEvent)) { $iEvent['descr'] = StrCat($iEvent['descr'],'renaming title',': '); $iEvent['params'] = nz($iEvent['params']).':old=['.$strOld.']'; $iEvent['code'] = 'NN'; // new name $this->StartEvent($iEvent); } $arUpd = array('Name'=>SQLValue($iVal)); $this->Update($arUpd); if (is_array($iEvent)) { $this->FinishEvent(); } } return $strOld;
} /*---- RETURNS: Text suitable for use as a title for this Title
(Ok, can *you* think of a better method name?)
HISTORY:
2010-11-19 Created for AdminPage()
*/ public function Title() {
return $this->CatNum().' '.$this->Name;
} public function DeptObj() {
$objDept = $this->objDB->Depts()->GetItem($this->ID_Dept); return $objDept;
} public function ShopLink($iText) {
return $this->LinkAbs().$iText.'</a>';
} public function PageTitle() {
return $this->CatNum('-');
} /*---- RETURNS: List of titles as formatted text HISTORY:
2011-10-01 created for revised catalog entry -- no departments anymore, need more topic info
*/ public function TopicList_ft($iNone='-') {
$rcs = $this->Topics(); // recordset of Topics for this Title if ($rcs->HasRows()) { $out = ; while ($rcs->NextRow()) { $out .= ' '.$rcs->AdminLink(); } } else { $out = $iNone; } return $out;
} /*---- HISTORY:
2011-02-23 Finally renamed from InfoPage() to AdminPage()
*/ public function AdminPage() {
global $wgOut,$wgRequest; global $vgPage,$vgOut;
$doEdit = $vgPage->Arg('edit'); $doSave = $wgRequest->GetBool('btnSave');
$vgPage->UseHTML();
// save edits before showing events $ftSaveStatus = NULL; if ($doEdit || $doSave) { $this->BuildEditForm(); if ($doSave) { $ftSaveStatus = $this->AdminSave(); } }
$isMissing = is_null($this->ID); if ($isMissing) { $strTitle = 'Missing Record'; $this->ID = $vgPage->Arg('ID'); } else { // items $ftItems = $this->ItemListing(); $htImages = $this->ImageListing(); // this may update the thumbnails, so do it before showing them $htGroups = $this->CMGrpListing(); $wtEvents = $this->EventListing();
$objTbl = $this->objDB->Images(); $htThumbs = $objTbl->Thumbnails($this->ID); if (!is_null($htThumbs)) {
$wgOut->AddHTML(''.$htThumbs.' |
}
//$strCatNum = $this->CatNum(); $strCatPage = $this->CatNum('/');
$strTitle = 'Title: '.$this->Title(); }
$objPage = new clsWikiFormatter($vgPage); $objSection = new clsWikiSection($objPage,$strTitle); $objSection->ToggleAdd('edit'); $out = $objSection->Generate(); $wgOut->AddHTML($out); $out = ; $vgOut->AddText($ftSaveStatus);
$objSupp = $this->SuppObj(); assert(is_object($objSupp));
if ($doEdit) { $out .= $objSection->FormOpen();
$ftCatKey = $this->objForm->Ctrl('CatKey')->Render(); $ftSuppCN = $this->objForm->Ctrl('Supplier_CatNum')->Render(); $ftSupp = $objSupp->DropDown('ID_Supp'); $ftDept = $objSupp->Depts_DropDown('ID_Dept',$this->ID_Dept); $ftName = $this->objForm->Ctrl('Name')->Render(); $ftSearch = $this->objForm->Ctrl('Search')->Render(); $ftDescr = $this->objForm->Ctrl('Desc')->Render(); $ftNotes = $this->objForm->Ctrl('Notes')->Render(); $ftWhAdded = $this->objForm->Ctrl('DateAdded')->Render(); $ftWhChckd = $this->objForm->Ctrl('DateChecked')->Render(); $ftWhUnavl = $this->objForm->Ctrl('DateUnavail')->Render(); } else { $ftCatKey = htmlspecialchars($this->CatKey); $ftSuppCN = htmlspecialchars($this->Supplier_CatNum); $ftSupp = $objSupp->AdminLink_name(); $objDept = $this->DeptObj(); if (is_object($objDept)) { $ftDept = $objDept->AdminLink($objDept->Name); } else { $ftDept = 'not set'; } $ftName = htmlspecialchars($this->Name); $ftSearch = htmlspecialchars($this->Search); $ftDescr = htmlspecialchars($this->Desc); $ftNotes = htmlspecialchars($this->Notes); $ftWhAdded = $this->DateAdded; $ftWhChckd = $this->DateChecked; $ftWhUnavl = $this->DateUnavail; }
$out .= ''; $out .= ''; $out .= ''; $out .= ''; $out .= ''; $out .= ''; $out .= ''; $out .= ''; $out .= ''; $out .= ''; $out .= ''; $out .= 'ID: | '.$this->ID.' ['.$this->ShopLink('shop').']'; $out .= ' |
Cat Key: | '.$ftCatKey; $out .= ' |
SC#: | '.$ftSuppCN; $out .= ' |
Supplier: | '.$ftSupp; $out .= ' |
Dept: | '.$ftDept; $out .= ' |
Name: | '.$ftName; $out .= ' |
Search: | '.$ftSearch; $out .= ' |
When Added: | '.$ftWhAdded; $out .= ' |
When Checked: | '.$ftWhChckd; $out .= ' |
When Unavailable: | '.$ftWhUnavl; $out .= ' |
if ($doEdit) {
$out .= 'Edit notes: <input type=text name="EvNotes" size=40>
';
$out .= '<input type=submit name="btnSave" value="Save">';
$out .= '<input type=submit name="btnCancel" value="Cancel">';
$out .= '<input type=reset value="Reset">';
$out .= '</form>';
}
$wgOut->addHTML($out); $out = ;
if (!$isMissing) { $wgOut->addWikiText('===Items===',TRUE); $vgOut->addText($ftItems); $wgOut->addHTML($htImages); // Images $wgOut->addWikiText('===Topics===',TRUE); $wgOut->addHTML($this->TopicListing()); $wgOut->addHTML($htGroups); // Catalog Groups $wgOut->addWikiText('===Events===',TRUE); $wgOut->addWikiText($wtEvents,TRUE); }
} /*---- HISTORY:
2010-11-06 adapted from VbzStockBin for VbzAdminTitle
*/ private function BuildEditForm() {
global $vgOut;
if (is_null($this->objForm)) { // create fields & controls $objForm = new clsForm_DataSet($this,$vgOut); //$objCtrls = new clsCtrls($objForm->Fields()); //$objCtrls = $objForm;
$objForm->AddField(new clsField('CatKey'), new clsCtrlHTML(array('size'=>8))); $objForm->AddField(new clsField('Supplier_CatNum'), new clsCtrlHTML(array('size'=>25))); $objForm->AddField(new clsFieldNum('ID_Supp'), new clsCtrlHTML()); $objForm->AddField(new clsFieldNum('ID_Dept'), new clsCtrlHTML()); $objForm->AddField(new clsField('Name'), new clsCtrlHTML(array('size'=>25))); $objForm->AddField(new clsField('Search'), new clsCtrlHTML(array('size'=>25))); $objForm->AddField(new clsField('Desc'), new clsCtrlHTML(array('size'=>25))); $objForm->AddField(new clsField('Notes'), new clsCtrlHTML()); $objForm->AddField(new clsFieldTime('DateAdded'), new clsCtrlHTML()); $objForm->AddField(new clsFieldTime('DateChecked'), new clsCtrlHTML()); $objForm->AddField(new clsFieldTime('DateUnavail'), new clsCtrlHTML());
$this->objForm = $objForm; //$this->objCtrls = $objCtrls; }
} public function AdminSave() {
global $wgRequest; global $vgOut;
// check input for problems $strCatKeyNew = $wgRequest->GetText('CatKey'); $strCatKeyOld = $this->CatKey; $ok = TRUE; // ok to save unless CatKey conflict $out = ; if ($strCatKeyNew != $strCatKeyOld) { $ok = FALSE; // don't save unless CatKey passes tests // if catkey is being changed, then check new number for duplicates $objSupp = $this->SuppObj(); $objMatch = $objSupp->GetTitle_byCatKey($strCatKeyNew,'VbzAdminTitle'); if (is_null($objMatch)) { $ok = TRUE; } else { /* Requested catkey matches an existing title. Look for other titles with the same base catkey (in same supplier), on the theory that this will represent a list of previous renames for this catkey. */ $objMatch->NextRow(); $out = 'Your entered CatKey ['.$strCatKeyNew.'] has already been used for '.$objMatch->AdminLink($objMatch->Name); $objMatch = $objSupp->GetTitles_byCatKey($strCatKeyOld,'VbzAdminTitle'); if (!is_null($objMatch)) { // there are some similar entries -- show them: $out .= ' Other similar CatKeys:'; while ($objMatch->NextRow()) { $out .= ' '.$objMatch->AdminLink($objMatch->CatKey); } } } } if ($ok) { $out .= $this->objForm->Save($wgRequest->GetText('EvNotes')); } return $out;
} public function ItemListing() {
$out = $this->objDB->Items()->Listing_forTitle($this); return $out;
} public function ImageListing() {
$objTbl = $this->objDB->Images(); $arArgs = array( 'filt' => 'ID_Title='.$this->ID, 'sort' => 'AttrSort,ID', 'event.obj' => $this, 'title.id' => $this->ID, 'new' => TRUE ); $out = $objTbl->AdminPage($arArgs);
// $objRows = $objTbl->GetData('ID_Title='.$this->ID,NULL,'AttrSort'); // $out = $objRows->AdminList(); return $out;
} /*---- RETURNS: Editable listing of topics for this Title */ protected function TopicListing() {
global $wgRequest; global $vgPage;
$tblTitleTopics = $this->Engine()->TitleTopics();
$me = $this; $arOpts = $this->Engine()->Topics()->TopicListing_base_array(); $arOpts['fHandleData_Change_Start'] = function($iText) use ($me) { $arEv = array( 'descr' => 'Adding '.$iText, 'code' => 'topic++', 'where' => __METHOD__ ); $me->StartEvent($arEv); };
$arOpts['fHandleData_Change_Finish'] = function($iText) use ($me) { $arEv = array( 'descrfin' => $iText ); $me->FinishEvent($arEv); }; $arOpts['fHandleData_Change_Item'] = function($iVal) use ($me,$tblTitleTopics) { $sqlTopic = $iVal; $arIns = array( 'ID_Title' => SQLValue($me->KeyValue()), 'ID_Topic' => $sqlTopic ); $db = $tblTitleTopics->Engine(); $db->ClearError(); $ok = $tblTitleTopics->Insert($arIns); if (!$ok) { $strErr = $db->getError(); $out = $sqlTopic.': '.$strErr.' (SQL:'.$tblTitleTopics->sqlExec.')'; } else { $out = SQLValue($sqlTopic); } return $out; };
$ctrlList = new clsWidget_ShortList(); $ctrlList->Options($arOpts); $htStatus = $ctrlList->HandleInput();
$doRmvTopics = $wgRequest->GetBool('btnRmvTopics');
// begin output phase $out = ;
if ($doRmvTopics) { $arTopics = $wgRequest->GetArray('rmvTitle'); $cnt = $tblTitleTopics->DelTopics($this->Value('ID'),$arTopics); $out .= 'Removed '.$cnt.' topic'.Pluralize($cnt).':'; foreach ($arTopics as $id => $on) { $objTopic = $tblTopics->GetItem($id); $out .= ' '.$objTopic->AdminLink(); } } /* $htPath = $vgPage->SelfURL(); $out = "\n<form method=post action=\"$htPath\">";
- /
$out .= "\n<form method=post>";
$rs = $this->Topics(); if ($rs->HasRows()) { while ($rs->NextRow()) {
$id = $rs->KeyString(); $ftName = $rs->AdminLink_name();
$out .= "\n[<input type=checkbox name=\"rmvTitle[$id]\">$ftName ]";
}
$out .= '
<input type=submit name="btnRmvTopics" value="Remove Checked">';
} else {
$out .= 'None found.';
}
/*
$out .= '<input type=submit name="btnAddTopics" value="Add These:">';
$out .= '<input size=40 name=txtNewTitles> (IDs separated by spaces)';
- /
$out .= '
'.$htStatus;
$out .= $ctrlList->RenderForm_Entry();
$out .= '</form>'; return $out;
} /*---- RETURNS: Listing of CM (catalog management) groups for this title HISTORY:
2011-02-06 added controls to allow deactivating/activating selected rows
*/ protected function CMGrpListing() {
global $wgRequest; global $vgOut;
$out = $vgOut->Header('Catalog Groups',3);
$tblCMT = $this->objDB->CtgTitles(); // catalog management titles $tblCMS = $this->objDB->CtgSrcs(); // catalog management sources $tblCMG = $this->objDB->CtgGrps(); // catalog management groups
$doEnable = $wgRequest->GetBool('btnCtgEnable'); $doDisable = $wgRequest->GetBool('btnCtgDisable'); if ($doEnable || $doDisable) { $arChg = $wgRequest->GetArray('ctg'); $out .= $doEnable?'Activating':'Deactivating'; foreach ($arChg as $id => $on) { $out .= ' '.$id; $arUpd = array( 'isActive' => SQLValue($doEnable) ); $tblCMT->Update($arUpd,'ID='.$id); } }
$rsRows = $tblCMT->GetData('ID_Title='.$this->ID); if ($rsRows->HasRows()) { $out .= '<form method=post>'; $out .= $vgOut->TableOpen(); $out .= $vgOut->TblRowOpen(NULL,TRUE); $out .= $vgOut->TblCell('ID'); $out .= $vgOut->TblCell('A?'); $out .= $vgOut->TblCell('Catalog'); $out .= $vgOut->TblCell('Group'); $out .= $vgOut->TblCell('Discontinued'); $out .= $vgOut->TblCell('Grp Code'); $out .= $vgOut->TblCell('Grp Descr'); $out .= $vgOut->TblCell('Grp Sort'); $out .= $vgOut->TblCell('Supp Cat #'); $out .= $vgOut->TblCell('Notes'); $out .= $vgOut->TblRowShut(); while ($rsRows->NextRow()) { $isActive = $rsRows->isActive; $htActive = $isActive?'√':'-';
$objCMSrce = $tblCMS->GetItem($rsRows->ID_Source); $objCMGrp = $tblCMG->GetItem($rsRows->ID_Group); if ($objCMSrce->HasRows()) { $htCMSrce = $objCMSrce->AdminLink_name(); } else { $htCMSrce = '?'.$rsRows->ID_Source; } if ($objCMGrp->HasRows()) { $htCMGrp = $objCMGrp->AdminLink_name(); } else { $htCMGrp = '?'.$rsRows->ID_Group; }
$out .= $vgOut->TblRowOpen(); $htID = '<input type=checkbox name="ctg['.$rsRows->KeyValue().']">'.$rsRows->AdminLink(); $out .= $vgOut->TblCell($htID); $out .= $vgOut->TblCell($htActive); $out .= $vgOut->TblCell($htCMSrce); $out .= $vgOut->TblCell($htCMGrp); // $out .= $vgOut->TblCell($rsRows->ID_Source); // $out .= $vgOut->TblCell($rsRows->ID_Group);
$out .= $vgOut->TblCell($rsRows->WhenDiscont); $out .= $vgOut->TblCell($rsRows->GroupCode); $out .= $vgOut->TblCell($rsRows->GroupDescr); $out .= $vgOut->TblCell($rsRows->GroupSort); $out .= $vgOut->TblCell($rsRows->Supp_CatNum); $out .= $vgOut->TblCell($rsRows->Notes); $out .= $vgOut->TblRowShut(); } $out .= $vgOut->TableShut(); $out .= '<input type=submit name=btnCtgDisable value="Deactivate Selected">'; $out .= '<input type=submit name=btnCtgEnable value="Activate Selected">'; $out .= '</form>'; } else { $out .= 'None found.'; } return $out;
}
} /*====
PURPOSE: VbzAdminTitles with additional catalog information
- /
class VbzAdminTitles_info_Cat extends VbzAdminTitles {
public function __construct($iDB) {
parent::__construct($iDB); $this->Name('qryCat_Titles');
} public function Search_forText_SQL($iFind) {
$sqlFind = '"%'.$iFind.'%"'; return "(Name LIKE $sqlFind) OR (Descr LIKE $sqlFind) OR (Search LIKE $sqlFind) OR (CatNum LIKE $sqlFind)";
} public function SearchPage() {
global $wgOut,$wgRequest; global $vgPage;
$strFind = $wgRequest->GetText('txtSearch');
$vgPage->UseHTML(); $out = "\n<form method=post>"; $htFind = htmlspecialchars($strFind); $out .= 'Search for:<input name=txtSearch size=40 value="'.$htFind.'"><input type=submit name=btnSearch value="Go">'; $out .= '</form>'; $wgOut->AddHTML($out); $out = ;
//$tblTitles = $this->Engine()->Titles();
$tblTitles = $this;
$tblItems = $this->Engine()->Items();
$tblImgs = $this->Engine()->Images();
$arTitles = NULL;
$rs = $tblTitles->Search_forText($strFind); if ($rs->HasRows()) { while ($rs->NextRow()) { $id = $rs->ID; $arTitles[$id] = $rs->Values(); } }
if (!empty($strFind)) {
$out .= '
Searching for "'.$htFind.'":
';
$wgOut->AddHTML($out); $out = ;
$rs = $tblItems->Search_byCatNum($strFind); if (is_object($rs)) { while ($rs->NextRow()) { $id = $rs->Value('ID_Title'); if (!isset($arTitles[$id])) { $obj = $tblTitles->GetItem($id); $arTitles[$id] = $obj->Values(); } } }
if (!is_null($arTitles)) { if (empty($obj)) { $obj = $tblTitles->SpawnItem(); }
$out .= '';
$ftImgs = ;
$isFirst = TRUE;
foreach ($arTitles as $id => $row) {
$obj->Values($row);
$txtCatNum = $obj->CatNum();
$txtName = $obj->Value('Name');
if ($isFirst) {
$isFirst = FALSE;
} else {
$out .= "\n $txtTitle = $txtCatNum.' “'.htmlspecialchars($txtName).'”'; $ftImg = $tblImgs->Thumbnails($id,array('title'=>$txtTitle)); $ftImgs .= '<a href="'.$obj->AdminURL().'">'.$ftImg.'</a>'; } $out .= ' |
}
$wgOut->AddHTML($out); $out = ; }
return $out;
}
} /*====
PURPOSE: VbzAdminTitles with additional item (and stock) information
- /
class VbzAdminTitles_info_Item extends VbzAdminTitles {
public function __construct($iDB) {
parent::__construct($iDB); $this->Name('qryTitles_Item_info'); $this->ClassSng('VbzAdminTitle_info_Item');
} public function Listing_forDept($iDeptObj) {
global $wgOut; global $vgPage; global $sql;
$vgPage->UseHTML();
$objDept = $iDeptObj; $idDept = $objDept->ID; // $strSuppKey = strtolower($objSupp->CatKey); // $objRecs = $this->GetData('ID_Dept='.$idDept,'VbzAdminTitle','CatKey'); //$objRecs = $this->DataSQL('SELECT t.ID_Title AS ID, t.* FROM qryCat_Titles_Item_stats AS t WHERE t.ID_Dept='.$idDept); $objRecs = $this->GetData('ID_Dept='.$idDept,NULL,'CatKey');
$out = $objRecs->AdminList(); $wgOut->addHTML($out);
}
} class VbzAdminTitle_info_Item extends VbzAdminTitle {
/*---- RETURNS: listing of titles in the current dataset HISTORY:
2010-11-16 "in print" column now showing cntInPrint instead of cntForSale
*/ public function AdminList(array $iarArgs=NULL) {
$objRecs = $this;
if ($objRecs->HasRows()) {
$out = "\n" ."\n" .'' .'' .'' .'' .'' .'' .'' .'' .'' .''; $isOdd = TRUE; while ($objRecs->NextRow()) { $ftID = $objRecs->AdminLink(); $ftName = $objRecs->Name; $ftCatNum = $objRecs->CatNum(); $ftCatKey = $objRecs->Row['CatKey']; $ftSCatNum = $objRecs->Row['Supplier_CatNum']; $ftWhen = $objRecs->DateAdded; // FUTURE: If we're using this on a dataset which does not have these fields, // test for them and then retrieve them the slow way if not found. $qtyStk = $objRecs->qtyForSale; //$cntAva = $objRecs->cntForSale; $cntPrn = $objRecs->cntInPrint; $cntItm = $objRecs->cntItems; $isActive = (($qtyStk > 0) || ($cntPrn > 0)); $isPassive = (nz($cntItm) == 0); $isOdd = !$isOdd; $wtStyle = $isOdd?'background:#ffffff;':'background:#eeeeee;'; if ($isActive) { $wtStyle .= ' font-weight: bold;'; } if ($isPassive) { $wtStyle .= ' color: #888888;'; } $out .= "\n". "". "". "". "". "". "". "". "". "". ''; } $out .= "\nID | Name | Cat # | CatKey | SCat# | When Added | item recs | items in print | stk qty |
---|---|---|---|---|---|---|---|---|
$ftID | $ftName | $ftCatNum | $ftCatKey | $ftSCatNum | $ftWhen | $cntItm | $cntPrn | $qtyStk |
} else { if (isset($iarArgs['none'])) { $out .= $iarArgs['none']; } else { $out .= 'No titles found.'; } } return $out;
}
} /*****
GROUP: Item administration
- /
class VbzAdminItems extends clsItems { // STATIC section //
/*---- HISTORY:
2010-10-13 Re-enabled as a boilerplate call
*/ public static function AdminLink($iID,$iShow=NULL,$iPopup=NULL) {
return clsAdminTable::AdminLink($iID,$iShow,$iPopup);
}
// DYNAMIC section //
public function __construct($iDB) {
parent::__construct($iDB); $this->ClassSng('VbzAdminItem'); $this->ActionKey('item');
} public function Listing_forTitle(clsVbzTitle $iTitleObj) {
$objTitle = $iTitleObj; $idTitle = $objTitle->ID; //$cntRow = 0;
$objRecs = $this->GetData('(IFNULL(isDumped,0)=0) AND (ID_Title='.$idTitle.')','VbzAdminItem','ItOpt_Sort'); return $objRecs->AdminList();
} /*---- ACTION: Updates fields in given catalog items
Does not log an event (maybe it should?)
INPUT: Array of items as returned by AdminItems_data_check() RETURNS: HTML to display (messages) FUTURE: This possibly should be in a helper class HISTORY:
2011-01-04 partially written
*/ public function AdminItems_data_update(array $iItems) {$out = "\n
- ";
foreach ($iItems as $idx => $row) {
$obj = $row['@obj'];
$id = $obj->KeyValue();
$out .= "\n
- Row $idx ID=$id:\n
- ";
$arUpd = NULL;
if (!empty($row['do-upd-scat'])) {
$arUpd['Supp_CatNum'] = SQLValue($row['scat']);
$out .= "\n
- scat# [".$obj->Supp_CatNum.']=>['.$row['scat'].']'; } if (!empty($row['do-upd-desc'])) { $arUpd['Descr'] = SQLValue($row['name']); $out .= "\n
- descr [".$obj->Descr.']=>['.$row['name'].']'; } $out .= "\n
$obj->Update($arUpd); }
$out .= "\n
return $out;
}
} class VbzAdminItem extends clsItem {
private $idEvent;
/*---- HISTORY:
2010-10-11 Added iarArgs parameter
*/ public function AdminLink($iText=NULL,$iPopup=NULL,array $iarArgs=NULL) {
return clsAdminData::_AdminLink($this,$iText,$iPopup,$iarArgs);
} public function AdminLink_name() {
return $this->AdminLink($this->DescLong()); // can make this more elaborate later
} /*---- PURPOSE: Like AdminLink_name(). but okay to take up more room to provide more info HISTORY:
2010-11-24 created
*/ public function AdminLink_friendly() {
$strItem = $this->AdminLink_CatNum(); $strFull = $strItem.' '.$this->DescLong_ht(); return $strFull;
} /*---- HISTORY:
2010-11-27 created
*/ public function AdminLink_CatNum() {
return $this->AdminLink($this->CatNum,$this->DescLong());
} /*---- HISTORY:
2010-11-06 replaced old event logging with boilerplate calls to helper class
*/ protected function Log() {
if (!is_object($this->logger)) { $this->logger = new clsLogger_DataSet($this,$this->objDB->Events()); } return $this->logger;
} public function EventListing() {
return $this->Log()->EventListing();
} public function StartEvent(array $iArgs) {
return $this->Log()->StartEvent($iArgs);
} public function FinishEvent(array $iArgs=NULL) {
return $this->Log()->FinishEvent($iArgs);
} /*---- ACTION:
Return the current supplier catalog number If a value is given, update it to the new value first (returns old value) If an event array is given, log the event
*/ public function SCatNum($iVal=NULL,array $iEvent=NULL) {
$strOld = $this->Supp_CatNum; if (!is_null($iVal)) { if (is_array($iEvent)) { $iEvent['params'] = nz($iEvent['params']).':old=['.$strOld.']'; $iEvent['code'] = 'SCN'; $this->StartEvent($iEvent); } $arUpd = array('Supp_CatNum'=>SQLValue($iVal)); $this->Update($arUpd); if (is_array($iEvent)) { $this->FinishEvent(); } } return $strOld;
} public function AdminList() {
global $vgPage,$vgOut; global $sql;
$cntRow = 0;
if ($this->HasRows()) { $out = $vgOut->TableOpen('class=sortable'); $out .= $vgOut->TblRowOpen(NULL,TRUE); $out .= $vgOut->TblCell('ID'); $out .= $vgOut->TblCell('Cat #'); $out .= $vgOut->TblCell('Status'); $out .= $vgOut->TblCell('Description'); $out .= $vgOut->TblCell('$ buy'); $out .= $vgOut->TblCell('$ sell'); $out .= $vgOut->TblRowShut(); $isOdd = TRUE; while ($this->NextRow()) { $id = $this->ID; //$wtID = SelfLink_Page('item','id',$id,$id); $wtID = $this->AdminLink(); $wtStyle = $isOdd?'background:#ffffff;':'background:#cccccc;'; $isActive = $this->isForSale; $isCurrent = $this->isCurrent; $isInPrint = $this->isInPrint; $isPulled = $this->isPulled; if ($isActive) { $cntRow++; } else { $wtStyle .= ' color: #888888;'; } if (!$isInPrint) { $wtStyle .= ' font-style: italic;'; } if ($isPulled) { $wtStyle .= ' text-decoration: line-through;'; } $strStatus = ; if ($isActive) { $strStatus .= 'A'; } if ($isCurrent) { $strStatus .= 'C'; } if ($isInPrint) { $strStatus .= 'P'; } if ($isPulled) { $strStatus .= 'U'; } $out .= $vgOut->TblRowOpen('style="'.$wtStyle.'"'); $out .= $vgOut->TblCell($wtID); $out .= $vgOut->TblCell($this->CatNum); $out .= $vgOut->TblCell($strStatus,'align=center'); $out .= $vgOut->TblCell($this->ItOpt_Descr); $out .= $vgOut->TblCell(DataCurr($this->PriceBuy)); $out .= $vgOut->TblCell(DataCurr($this->PriceSell)); $out .= $vgOut->TblRowShut(); if (!is_null($this->Descr)) { $out .= $vgOut->TblRowOpen('style="'.$wtStyle.'"'); $out .= $vgOut->TblCell($this->Descr,'colspan=4'); $out .= $vgOut->TblRowShut(); }
$isOdd = !$isOdd; //$objLine = $objRecs->CloneFields(); $objLine = clone $this; } $out .= $vgOut->TableShut(); } else { $out = 'No items listed. (SQL='.$sql.')'; } return $out;
} public function Title() {
return $this->objDB->Titles()->GetItem($this->ID_Title);
} public function ItTyp() {
return $this->objDB->ItTyps()->GetItem($this->ID_ItTyp);
} public function FullDescr($iSep=' ') {
$objTitle = $this->Title(); return $objTitle->Name.$iSep.$this->ItOpt_Descr;
} public function FullDescr_HTML($iSep=' ') {
$objTitle = $this->Title(); $objItTyp = $this->ItTyp(); if ($objItTyp->IsNew()) { $out = '(no item type)'; } else { $out =
// $objTitle->SelfLink($objTitle->Name).$iSep.
$objTitle->AdminLink($objTitle->Name).$iSep. $objItTyp->Row['NameSng'].$iSep. $this->ItOpt_Descr; } return $out;
}
/* 2010-11-11 This should be completely obsolete, right?
protected function ReceiveForm() {
global $wgOut,$wgRequest;
if ($wgRequest->getCheck('btnSave')) { $intQtyNew = $wgRequest->GetInt('StkMin'); $arUpd['QtyMin_Stk'] = $intQtyNew; $intQtyOld = $this->QtyMin_Stk; if ($intQtyOld == $intQtyNew) { $out = 'No change requested; min qty is already '.$intQtyOld.'.'; } else { $strDescr = 'Updating per-item stock minimum from '.$intQtyOld.' to '.$intQtyNew; $out = $strDescr; $this->StartEvent(__METHOD__,'UPD',$strDescr); $this->Update($arUpd); $this->Reload(); $this->FinishEvent(); } $wgOut->AddWikiText($out); }
}
- /
/*---- HISTORY:
2011-02-24 Finally renamed from InfoPage() to AdminPage()
*/ public function AdminPage() {
global $wgOut,$wgRequest; global $vgPage;
$strCatNum = $this->CatNum;
//$this->ReceiveForm();
$vgPage->UseHTML(); $objTitle = $this->Title(); $strTitleName = $objTitle->Name; $ftTitleLink = (is_object($objTitle))?($objTitle->AdminLink($strTitleName)):'title N/A'; $strTitle = 'Item: '.$strCatNum.' ('.$this->ID.') - '.$this->FullDescr();
$objPage = new clsWikiFormatter($vgPage); $objSection = new clsWikiSection($objPage,$strTitle); $objSection->ToggleAdd('edit'); //$objSection->ActionAdd('view'); $out = $objSection->Generate();
$strAction = $vgPage->Arg('do'); $doAdd = ($strAction == 'add'); $doEdit = $vgPage->Arg('edit'); $doSave = $wgRequest->GetBool('btnSave');
if ($doEdit || $doSave) { $this->BuildEditForm(); if ($doSave) { $this->AdminSave(); } }
$ftPriceSell = $this->PriceSell; // this can be edited if item is not in print if ($doEdit) { $out .= $objSection->FormOpen(); $objForm = $this->objForm;
$ftCatNum = $objForm->Render('CatNum'); $ftCatSfx = $objForm->Render('CatSfx'); $ftDescr = $objForm->Render('Descr'); if (!$this->isInPrint) { $ftPriceSell = $objForm->Render('PriceSell'); } $ftPriceList = $objForm->Render('PriceList'); $ftSCatNum = $objForm->Render('Supp_CatNum'); $ftStkMin = $objForm->Render('QtyMin_Stk'); } else { $ftCatNum = $this->CatNum; $ftCatSfx = $this->CatSfx; $ftDescr = $this->Descr; $ftPriceList = $this->PriceList; $ftSCatNum = $this->Supp_CatNum; $ftStkMin = $this->QtyMin_Stk; } // non-editable fields: $ftTitle = $ftTitleLink; $ftPriceBuy = $this->PriceBuy; $ftItOpt = $this->ID_ItOpt; $ftIODescr = $this->ItOpt_Descr; $ftIOSort = $this->ItOpt_Sort; $ftGrpCode = $this->GrpCode; $ftGrpDescr = $this->GrpDescr; $ftGrpSort = $this->GrpSort;
$out .= '- ';
$out .= '
- ID: '.$this->ID; $out .= '
- Cat #: '.$ftCatNum.' suffix: '.$ftCatSfx; $out .= '
- Description: '.$ftDescr; $out .= '
- Prices: '.$ftItOpt;
$out .= '
- ';
$out .= '
- Buy: '.$ftPriceBuy; $out .= '
- Sell: '.$ftPriceSell; $out .= '
- List: '.$ftPriceList.''; $out .= '
- Item Option: '.$ftItOpt;
$out .= '
- ';
$out .= '
- Descr: '.$ftIODescr; $out .= '
- Sort: '.$ftIOSort; $out .= '
- Group - code: '.$ftGrpCode.' descr: '.$ftGrpDescr.' sort: '.$ftGrpSort; $out .= '
- Title: '.$ftTitle; $out .= '
- Stk Min: '.$ftStkMin; $out .= '
- Status:'; if ($this->isMaster) { $out .= ' MASTER'; } if ($this->isForSale) { $out .= ' FOR-SALE'; } if ($this->isInPrint) { $out .= ' IN-PRINT'; } if ($this->isCloseOut) { $out .= ' CLOSEOUT'; } if ($this->isPulled) { $out .= ' PULLED'; } if ($this->isDumped) { $out .= ' DUMPED'; } $out .= '
- Supplier Cat #:'.$ftSCatNum; $out .= '
if ($doEdit) { $out .= '<input type=submit name="btnSave" value="Save">'; $out .= '<input type=reset value="Reset">'; $out .= '</form>'; } $wgOut->AddHTML($out);
$wgOut->AddHTML("Stock
");$wgOut->AddWikiText($this->StockListing(),TRUE);
$wgOut->AddHTML("Orders
");$wgOut->AddWikiText($this->OrderListing(),TRUE);
$wgOut->AddHTML("Restocks
");$wgOut->AddWikiText($this->RestockListing(),TRUE);
$wgOut->AddHTML('Events
');$wgOut->AddWikiText($this->EventListing(),TRUE);
} /*---- HISTORY:
2010-11-06 adapted from VbzStockBin
*/ private function BuildEditForm() {
global $vgOut;
if (is_null($this->objForm)) { // create fields & controls $objForm = new clsForm_DataSet($this,$vgOut); //$objCtrls = new clsCtrls($objForm->Fields());
$objForm->AddField(new clsField('Descr'), new clsCtrlHTML(array('size'=>40))); $objForm->AddField(new clsField('CatNum'), new clsCtrlHTML()); $objForm->AddField(new clsField('CatSfx'), new clsCtrlHTML(array('size'=>5))); $objForm->AddField(new clsFieldNum('PriceSell'), new clsCtrlHTML()); $objForm->AddField(new clsFieldNum('PriceList'), new clsCtrlHTML()); $objForm->AddField(new clsField('Supp_CatNum'), new clsCtrlHTML()); $objForm->AddField(new clsFieldNum('QtyMin_Stk'), new clsCtrlHTML(array('size'=>3)));
$this->objForm = $objForm; //$this->objCtrls = $objCtrls; }
} /*---- ACTION: Save user changes to the record HISTORY:
2010-11-06 copied from VbzStockBin to VbzAdminItem
*/ public function AdminSave() {
global $vgOut;
$out = $this->objForm->Save(); $vgOut->AddText($out);
} public function StockListing() {
$out = $this->objDB->StkItems()->Listing_forItem($this); return $out;
} public function OrderListing() {
$objTbl = $this->objDB->OrdItems(); $objRows = $objTbl->GetData('ID_Item='.$this->ID); $out = $objRows->AdminTable_forItem(); return $out;
} public function RestockListing() {
$objTbl = $this->objDB->RstkReqItems(); $objRows = $objTbl->GetData('ID_Item='.$this->ID); $out = $objRows->AdminList('No restocks found for this item'); return $out;
} /*---- RETURNS: wikitext which links to the catalog page for the item NOTE: Since the store doesn't yet have pages for each item,
this returns a link to the item's Title page
FUTURE: create StoreLink() function which uses RichText object */ public function StoreLink_WT($iText) {
return '[[vbznet:cat/'.$this->Title()->URL_part().'|'.$iText.']]';
}
// FUNCTION DEPRECATED - remove eventually
public function AdminLink_WT($iText) {
return '[[VbzCart/archive/code/SpecialVbzAdmin/page'.KS_CHAR_URL_ASSIGN.'item/id'.KS_CHAR_URL_ASSIGN.$this->ID.'|'.$iText.']]';
}
// FUNCTION DEPRECATED - remove eventually
public function StoreLink_HT($iText) {
return '<a href="'.KWP_CAT.$this->Title()->URL_part().'" title="browse in store">'.$iText.'</a>';
}
} class clsAdminItems_info_Cat extends clsItems_info_Cat {
public function __construct($iDB) {
parent::__construct($iDB); $this->ActionKey('item');
}
} /*******
IMAGES
- /
class clsAdminImages extends clsImages {
public function __construct($iDB) {
parent::__construct($iDB); $this->Name('cat_images'); $this->KeyName('ID'); $this->ClassSng('clsAdminImage');
} /*----- ACTION: Processes form data, shows section header, loads image dataset, calls clsAdminImage::AdminList() to render INPUT:
iarArgs: array of options ['filt'] = SQL filter for dataset to show ("WHERE" clause) ['sort'] = sorting order for dataset to show ("ORDER BY" clause) ['event.obj'] = object used for event logging ['title.id'] = ID_Title to use for new records ['new']: if TRUE, allow user to create new records when editing
*/ public function AdminPage(array $iarArgs) {
global $wgRequest; global $vgPage,$vgOut;
$out = ;
// get URL input $doEdit = ($vgPage->Arg('edit.img')); $doAdd = ($vgPage->Arg('add.img')); $arArgs = $iarArgs; $arArgs['edit'] = $doEdit; $sqlFilt = $arArgs['filt']; $sqlSort = $arArgs['sort'];
// display section header // $strName = 'Images';
$vgPage->UseHTML(); $objPage = new clsWikiFormatter($vgPage); $objSection = new clsWikiSection($objPage,'Images',NULL,3); $objSection->ToggleAdd('edit','edit image records','edit.img'); $objSection->ToggleAdd('add','add multiple image records','add.img'); $out .= $objSection->Generate();
// handle possible form requests
// -- bulk-entry form stage 1: check input if ($wgRequest->getBool('btnCheckImgs')) { $doCheck = TRUE; $xts = new xtString($wgRequest->GetText('txtImgs')); $arLines = $xts->ParseTextLines(array('line'=>'arr'));
$htForm = "\nImages submitted:\n- ";
foreach ($arLines as $idx => $arLine) {
$txtURL = $arLine[0];
$txtSize = isset($arLine[1])?$arLine[1]:NULL;
$rsFldr = $this->Engine()->Folders()->FindBest($txtURL);
if (is_null($rsFldr)) {
$htForm .= "\n
- No folder found for $txtUrl "; } else { $fsFldr = $rsFldr->Value('PathPart'); $fsImg = $rsFldr->Remainder($txtURL); $idFldr = $rsFldr->KeyValue(); $ftSize = empty($txtSize)?:''.$txtSize.' '; $htForm .= "\n
- $ftSize$fsFldr<a href=\"$fsFldr$fsImg\">$fsImg</a> "; $htForm .= '<input type=hidden name="img-fldr['.$idx.']" value='.$idFldr.'>'; $htForm .= '<input type=hidden name="img-spec['.$idx.']" value="'.$fsImg.'">'; if (!is_null($txtSize)) { $htForm .= '<input type=hidden name="img-size['.$idx.']" value="'.$txtSize.'">'; } } } $htForm .= '
} else { $doCheck = FALSE; } // -- bulk-entry form stage 2: create records if ($wgRequest->getBool('btnAddImgs')) { $arFldrs = $wgRequest->GetArray('img-fldr'); $arSpecs = $wgRequest->GetArray('img-spec'); $arSizes = $wgRequest->GetArray('img-size'); $idTitle = $vgPage->Arg('id'); assert('!empty($idTitle);');
// log event to the title $objTitle = $this->Engine()->Titles($idTitle); $cntImgs = count($arFldrs); $arEv = array( 'descr' => 'Adding '.$cntImgs.' image'.Pluralize($cntImgs), 'where' => __METHOD__, 'code' => 'IMG++' ); $objTitle->StartEvent($arEv);
foreach ($arFldrs as $idx => $idFldr) { $fs = $arSpecs[$idx]; $sz = $arSizes[$idx]; $arIns = array( 'ID_Folder' => $idFldr, 'isActive' => 'TRUE', 'Spec' => SQLValue($fs), 'ID_Title' => $idTitle, 'WhenAdded' => 'NOW()' ); if (!empty($sz)) { $arIns['Ab_Size'] = SQLValue($sz); } $this->Insert($arIns); $strNew = ' '.$this->LastID(); } $arEv = array( 'descrfin' => 'New ID'.Pluralize($cntImgs).':'.$strNew ); $objTitle->FinishEvent($arEv); } // -- existing item edit form if ($wgRequest->getBool('btnSaveImgs')) {
$arUpdate = $wgRequest->getArray('update'); $arDelete = $wgRequest->getArray('del'); $arActive = $wgRequest->getArray('isActive'); $arFolder = $wgRequest->getArray('ID_Folder'); $arFileSpec = $wgRequest->getArray('txtFileSpec'); $arAttrSize = $wgRequest->getArray('txtAttrSize'); $arAttrFldr = $wgRequest->getArray('txtAttrFldr'); $arAttrDispl = $wgRequest->getArray('txtAttrDispl'); $arAttrSort = $wgRequest->getArray('txtAttrSort');
if (count($arActive > 0)) { // add any reactivated rows to the update list foreach ($arActive as $id => $null) { $arUpdate[$id] = TRUE; } }
$cntRows = count($arUpdate); if ($cntRows > 0) { $out .= 'Updating: '; $txtEvDescr = 'Checking '.$cntRows.' record'.Pluralize($cntRows); $txtRowEdits = ; $txtRowFlips = ;
$doLog = isset($arArgs['event.obj']); if ($doLog) { $objLog = $arArgs['event.obj']; $arEv = array( 'descr' => $txtEvDescr, 'where' => __METHOD__, 'code' => 'IMG SVM' // image save multiple ); $objLog->StartEvent($arEv); }
$cntUpd = 0; foreach ($arUpdate as $id => $null) { $isActive = isset($arActive[$id]); $isNew = ($id == 'new'); if (empty($arFileSpec[$id])) { $isNew = FALSE; // nothing to save } $objImg = $this->GetItem($id);
if ($isNew) {
$isDiff = TRUE;
$doSaveActive = TRUE;
$doSaveValues = TRUE;
} else {
$isDiff = ((int)$isActive != (int)$objImg->isActive);
$isStateChg = $isDiff;
$doSaveActive = $isDiff;
$doSaveValues = !$isDiff;
}
if (!$isDiff) {
$arUpd = array(
'ID_Folder' => $arFolder[$id],
'Spec' => $arFileSpec[$id],
'Ab_Size' => $arAttrSize[$id],
'AttrFldr' => nz($arAttrFldr[$id]),
'AttrDispl' => nz($arAttrDispl[$id]),
'AttrSort' => nz($arAttrSort[$id])
);
$isDiff = !$objImg->SameAs($arUpd);
}
$arUpd = NULL;
if ($isDiff) {
if ($doSaveValues) {
$arUpd = array(
'ID_Folder' => SQLValue($arFolder[$id]),
'Spec' => SQLValue($arFileSpec[$id]),
'Ab_Size' => SQLValue($arAttrSize[$id]),
'AttrFldr' => SQLValue(nz($arAttrFldr[$id])),
'AttrDispl' => SQLValue(nz($arAttrDispl[$id])),
'AttrSort' => SQLValue(nz($arAttrSort[$id]))
);
$txtRowEdits .= ' #'.$id;
}
if ($doSaveActive) {
$arUpd['isActive'] = SQLValue($isActive);
$txtRowFlips .= ' #'.$id.'('.NoYes($isActive,'off','ON').')';
}
if ($isNew) {
// create new record
$idTitle = (int)$arArgs['title.id'];
assert('is_int($idTitle)');
$arUpd['ID_Title'] = $idTitle;
$this->Insert($arUpd);
} else {
// not new: just update
$objImg->Update($arUpd);
//global $sql;
//$out .= '
SQL: '.$objImg->sqlExec;
}
$cntUpd++;
}
}
if ($doLog) {
$txtStat = $cntUpd.' image'.Pluralize($cntUpd).' updated -';
if (!empty($txtRowFlips)) {
$txtStat .= ' toggled:'.$txtRowEdits;
}
if (!empty($txtRowEdits)) {
$txtStat .= ' edits:'.$txtRowEdits;
}
$arEv = array(
'descrfin' => SQLValue($txtStat)
);
$objLog->FinishEvent($arEv);
}
$out .= $txtStat;
} else {
$out .= 'No image records selected for update.';
}
}
// render edit form outer shell: if ($doEdit || $doAdd || $doCheck) { $arLink = $vgPage->Args(array('page','id')); $urlSelf = $vgPage->SelfURL($arLink,TRUE); $arArgs['pfx'] = '<form method=post action="'.$urlSelf.'">';
if ($doEdit) { $sfx = '<input type=submit name=btnSaveImgs value="Save">'; $sfx .= '<input type=reset value="Revert">'; } if ($doAdd) { $sfx = 'Enter images, one complete URL per line:'; $sfx .= '<textarea name=txtImgs rows=6></textarea>'; $sfx .= '<input type=submit name=btnCheckImgs value="Check">'; } if ($doCheck) { $sfx = $htForm; // calculated earlier $sfx .= '<input type=submit name=btnAddImgs value="Add These">'; } $sfx .= '</form>'; $arArgs['sfx'] = $sfx; }
// load the latest data and show it in a table: $arArgs['none'] = 'No images found.'; $objRows = $this->GetData($sqlFilt,NULL,$sqlSort); $out .= $objRows->AdminList($arArgs);
return $out;
} /*---- HISTORY:
2010-10-19 Adapted from AdminPage() 2010-11-16 Commented out editing functions, per earlier thought, after partly updating them. Note: they were written for AdminPage().
*/ public function AdminPage_Unassigned() {
global $wgRequest,$wgOut; global $vgPage,$vgOut;
$out = ;
// get URL input $doEdit = ($vgPage->Arg('edit.img')); $arArgs['edit'] = $doEdit;
// display section header // $strName = 'Images';
$vgPage->UseHTML(); $objPage = new clsWikiFormatter($vgPage); $objSection = new clsWikiSection($objPage,'Unassigned Images',NULL,3); $objSection->ToggleAdd('edit','edit image records','edit.img'); $out .= $objSection->Generate();
// load the latest data and show it in a table: $arArgs['none'] = 'No unassigned images found.'; $sqlFilt = 'ID_Title IS NULL'; $sqlSort = NULL; // maybe this could be useful later $objRows = $this->GetData($sqlFilt,NULL,$sqlSort); $out .= $objRows->AdminList($arArgs);
$objSection = new clsWikiSection($objPage,'Imageless Active Titles',NULL,3); $out .= $objSection->Generate(); $objRows = $this->objDB->Titles()->Data_Imageless(); $out .= $objRows->AdminList($arArgs);
$wgOut->AddHTML($out); $out = NULL; return $out;
}
} class clsAdminImage extends clsImage {
/*----- ACTION: Renders dataset as a table INPUT: iarArgs
none: text to insert as description if no records pfx: html to include before table rows, if there is data sfx: html to include after table rows, if there is data edit: render editable fields new: allow entering new records -- show edit even if no data
*/ public function AdminList(array $iarArgs) {
$out = ; $doNew = nz($iarArgs['new']); if ($doNew || $this->HasRows()) { $doEdit = nz($iarArgs['edit']); $out .= nz($iarArgs['pfx']);
$out .= "\n"; $out .= ''; $out .= '' .'' .'' .'' .'' .'' .'' .'' .'' .''; $isOdd = FALSE; while ($this->NextRow()) { $out .= $this->AdminListRow($doEdit,$isOdd); $isOdd = !$isOdd; } if ($doEdit) { // when editing, we also allow for adding a new record $out .= $this->AdminListRow($doEdit,$isOdd,TRUE); } $out .= "\nattributes | |||||||
---|---|---|---|---|---|---|---|
ID | A? | folder | filename | size | folder | description | sorting |
$out .= nz($iarArgs['sfx']); } else { if (isset($iarArgs['none'])) { $out .= $iarArgs['none']; } else { $out .= 'No images found.'; } } return $out;
} protected function AdminListRow($iEdit,$iOdd,$iNew=FALSE) {
$isOdd = $iOdd; $doEdit = $iEdit;
if ($iNew) { $doEdit = TRUE; $isActive = TRUE; $id = 'new'; $txtFileSpec = ; $txtFolder = ; $txtAttrSize = ; $txtAttrFldr = ; $txtAttrDispl = ; $txtAttrSort = ; } else { $id = $this->ID; $wtID = $id; $isActive = $this->isActive; $txtFileSpec = $this->Spec; $txtFolder = $this->FolderPath(); $txtAttrSize = $this->Ab_Size; $txtAttrFldr = $this->AttrFldr; $txtAttrDispl = $this->AttrDispl; $txtAttrSort = $this->AttrSort; }
$wtStyle = $isOdd?'background:#ffffff;':'background:#eeeeee;'; if ($isActive) { $wtStyleCell = ; $ftActive = '√'; } else { $wtStyle .= ' color: #888888;'; $wtStyleCell = ' style="text-decoration: line-through;"'; $ftActive = ; } if ($doEdit) { // replace field values with editable versions if ($isActive) { $wtID = '<input type=hidden name=update['.$id.'] value=1>'.$id; } else { $wtID = '<input type=checkbox name=del['.$id.'] title="check rows to delete">'.$id; } $htEnabled = $isActive?:' disabled'; $ftActive = '<input type=checkbox name=isActive['.$id.'] title="check if this image should be used"'.($isActive?' checked':).'>'; $htFolder = $this->objDB->Folders()->DropDown('ID_Folder['.$id.']',$this->ID_Folder); $htFileSpec = '<input'.$htEnabled.' size=20 name=txtFileSpec['.$id.'] value="'.htmlspecialchars($txtFileSpec).'">'; $htAttrSize = '<input'.$htEnabled.' size=4 name=txtAttrSize['.$id.'] value="'.htmlspecialchars($txtAttrSize).'">'; $htAttrFldr = '<input'.$htEnabled.' size=4 name=txtAttrFldr['.$id.'] value="'.htmlspecialchars($txtAttrFldr).'">'; $htAttrDispl = '<input'.$htEnabled.' size=10 name=txtAttrDispl['.$id.'] value="'.htmlspecialchars($txtAttrDispl).'">'; $htAttrSort = '<input'.$htEnabled.' size=2 name=txtAttrSort['.$id.'] value="'.htmlspecialchars($txtAttrSort).'">'; } else { $htFolder = $txtFolder; $htFileSpec = $txtFileSpec = '<a href="'.$this->WebSpec().'">'.$txtFileSpec.'</a>';
$htAttrSize = $txtAttrSize; $htAttrFldr = $txtAttrFldr; $htAttrDispl = $txtAttrDispl; $htAttrSort = $txtAttrSort; }
$out = "\n". "\n$wtID". "\n<td$wtStyleCell>$ftActive". "\n<td$wtStyleCell>$htFolder". "\n<td$wtStyleCell>$htFileSpec". "\n<td$wtStyleCell>$htAttrSize". "\n<td$wtStyleCell>$htAttrFldr". "\n<td$wtStyleCell>$htAttrDispl". "\n<td$wtStyleCell>$htAttrSort". "\n"; return $out; } } /****** SHIPPING- /
- /
Pkg ID '.$objRecs->AdminLink(); if (is_null($objRecs->ShipCost)) { $out .= ': no shipping cost!'; $ok = FALSE; $cntPkgErr++; } elseif (is_null($objRecs->PkgCost)) { $out .= ': no materials cost!'; $ok = FALSE; $cntPkgErr++; } else { $dlrShip += $objRecs->ShipCost; $dlrPack += $objRecs->PkgCost; } } if ($ok) { $strUpd = '$'.$dlrShip.' shipping, $'.$dlrPack.' materials'; $out = '
Cost totals: '.$strUpd; } else { $out .= '
'.$cntPkgErr.Pluralize($cntPkgErr,' package has','packages have').' missing information.'; } } else { $ok = FALSE; $out = 'No packages in shipment; nothing to close.'; } $wgOut->AddHTML($out); $out=NULL; if ($ok) { // log the attempt $arEv = array( 'descr' => 'closing shipment: '.$strUpd, 'where' => __METHOD__, 'code' => 'CLO' ); $this->StartEvent($arEv); // fill in stats $arUpd = array( 'WhenClosed' => 'NOW()', 'OrderCost' => $dlrShip, 'SupplCost' => $dlrPack ); $this->Update($arUpd); global $sql; $out = '
Shipment updated - SQL: '.$sql; $this->Reload(); // log the completion $this->FinishEvent(); $wgOut->AddWikiText($out,TRUE); $out=NULL; } } if ($doEdit || $doSave) { $this->BuildEditForm(); if ($doSave) { $this->AdminSave(); } } $htAbbr = htmlspecialchars($this->Abbr); $htDescr = htmlspecialchars($this->Descr); $htNotes = htmlspecialchars($this->Notes); // values which are always static if ($doNew) { $strID = 'NEW'; $strTitle = 'NEW Shipment'; } else { if ($didAdd) { $strID = $this->AdminLink(); } else { $strID = $this->ID; } $strTitle = 'Shipment '.$htAbbr; } $out = ; if ($doEdit) { // open editing form $sqlID = $doNew?'new':$this->ID; $arLink = array( 'edit' => FALSE, 'id' => $sqlID ); $htPath = $vgPage->SelfURL($arLink); $out .= "\n<form method=post action=\"$htPath\">"; // code for editable values /* $strAbbr = '<input name=abbr type=text size=16 value="'.$htAbbr.'">'; $strDescr = '<input name=descr type=text size=50 value="'.$htDescr.'">'; $strNotes = '<textarea name=notes width=50 height=3>'.$htNotes.'</textarea>';
- /
$strTitle
"; $out .= "\n"; $out .= "\n"; $out .= "\n"; $out .= "\n"; $out .= "\n";if (!$doNew) {
$out .= "\n"; $out .= "\n"; $out .= "\n"; $out .= "\n"; $out .= "\n"; $out .= "\n"; $out .= "\n";}
$out .= "\n"; $out .= "\n"; $out .= "\nID: | $strID |
Name: | $ctrlAbbr |
Description: | $ctrlDescr |
Type: | $ctrlStatus |
When Created: | $ctrlWhenCre |
When Shipped: | $ctrlWhenShp |
When Closed: | $ctrlWhenClo |
Receipt Cost: | $ctrlCostRcpt |
Outside Cost: | $ctrlCostOuts |
Order Cost: | $ctrlCostOrdr |
Supplier Cost: | $ctrlCostSupp |
Carrier: | $ctrlCarrier |
Notes: | $ctrlNotes |
if ($doEdit) { // form buttons if ($doNew) { // next line needed only if we have special code for Create vs. Save // $out .= '<input type=submit name="btnCreate" value="Create">'; // 2011-09-02 testing this instead: $out .= '<input type=submit name="btnSave" value="Create">'; } else { $out .= '<input type=submit name="btnSave" value="Save">'; $out .= '<input type=reset value="Revert">'; } // close editing form $out .= "\n</form>"; } $wgOut->addHTML($out); $out = ;
if (!$doNew) { $wgOut->addWikiText('===Packages===',TRUE); $out = ; $out .= $this->PkgTable(); $wgOut->addWikiText($out,TRUE); $out = ;
$wgOut->addWikiText('===Events===',TRUE); $out = $this->EventListing(); $wgOut->addWikiText($out,TRUE); $out = ; }
} /*---- HISTORY:
2011-02-17 Updated to use objForm instead of objFlds/objCtrls
*/ private function BuildEditForm() {
global $vgOut;
// create fields & controls
if (is_null($this->objForm)) { $objForm = new clsForm_DataSet($this,$vgOut);
$objForm->AddField(new clsFieldTime('WhenCreated'), new clsCtrlHTML()); $objForm->AddField(new clsFieldTime('WhenShipped'), new clsCtrlHTML()); //$objCtrls->AddField(new clsFieldTime('WhenClosed'), new clsCtrlHTML()); $objForm->AddField(new clsFieldNum('ReceiptCost'), new clsCtrlHTML(array('size'=>5))); $objForm->AddField(new clsFieldNum('OutsideCost'), new clsCtrlHTML(array('size'=>5))); $objForm->AddField(new clsFieldNum('OrderCost'), new clsCtrlHTML(array('size'=>5))); $objForm->AddField(new clsFieldNum('SupplCost'), new clsCtrlHTML(array('size'=>5))); $objForm->AddField(new clsField('Carrier'), new clsCtrlHTML()); $objForm->AddField(new clsField('Abbr'), new clsCtrlHTML(array('size'=>16))); $objForm->AddField(new clsField('Descr'), new clsCtrlHTML(array('size'=>50))); $objForm->AddField(new clsField('Notes'), new clsCtrlHTML_TextArea(array('height'=>3,'width'=>50))); $objForm->AddField(new clsFieldBool('isDedicated'), new clsCtrlHTML_CheckBox()); $objForm->AddField(new clsFieldBool('isOnHold'), new clsCtrlHTML_CheckBox());
$this->objForm = $objForm; }
} /*----- ACTION: Save the user's edits to the shipment HISTORY:
2011-02-17 Retired old custom code; now using objForm helper object
*/ private function AdminSave() {
global $vgOut;
$out = $this->objForm->Save(); $vgOut->AddText($out); /* 2011-02-17 old code global $wgOut;
// get the form data and note any changes $objFlds = $this->objCtrls->Fields(); $objFlds->RecvVals(); // get the list of field updates $arUpd = $objFlds->DataUpdates(); // log that we are about to update $strDescr = 'Edited: '.$objFlds->DescrUpdates(); $wgOut->AddWikiText('==Saving Edit==',TRUE); $wgOut->AddWikiText($strDescr,TRUE);
$arEv = array(
'descr' => $strDescr,
'where' => __METHOD__,
'code' => 'ED'
);
$this->StartEvent($arEv);
// update the recordset
$this->Update($arUpd);
global $sql;
$wgOut->AddWikiText('
SQL='.$sql,TRUE);
$this->Reload();
// log completion
$this->FinishEvent();
- /
} public function PkgsData() {
$objTbl = $this->objDB->Pkgs(); $objRows = $objTbl->GetData('(ID_Shipment='.$this->KeyValue().') AND (WhenVoided IS NULL)'); return $objRows;
} public function PkgTable() {
/* //$objTbl = new clsPackages($this->objDB); $objTbl = $this->objDB->Pkgs(); $objRows = $objTbl->GetData('ID_Shipment='.$this->ID);
- /
$objRows = $this->PkgsData(); $arArgs = array( 'descr' => ' for this shipment', 'omit' => , 'ord' => $this->ID_Order ); $out = $objRows->AdminTable($arArgs); return $out;
} /*---- HISTORY:
2010-10-23 added event logging using helper class
*/ protected function Log() {
if (!is_object($this->logger)) { $this->logger = new clsLogger_DataSet($this,$this->objDB->Events()); } return $this->logger;
} public function EventListing() {
return $this->Log()->EventListing();
} public function DropDown($iName,$iDefault=NULL) {
if ($this->HasRows()) { $out = '<select name="'.$iName.'">'."\n"; while ($this->NextRow()) { $id = $this->Value('ID'); if ($id == $iDefault) { $htSelect = " selected"; } else { $htSelect = ; } $htDescr = $this->Descr(); $out .= "<option$htSelect value=\"$id\">$htDescr</option>\n"; } $out .= '</select>'; } else { $out = 'No shipments matching filter'; } return $out;
} public function Descr() {
$out = $this->Abbr; return $out;
}
} /******
TOPIC MANAGEMENT
- /
class clsAdminTopics extends clsTopics {
public function __construct($iDB) {
parent::__construct($iDB); $this->ClassSng('clsAdminTopic'); $this->ActionKey('topic');
} protected function AdminRedirect() {
global $vgPage; global $wgOut;
$ar = array('page'=>$this->ActionKey()); $url = $vgPage->SelfURL($ar,TRUE); $wgOut->redirect($url);
} public function RootNode() {
$objRoot = $this->SpawnItem(); $objRoot->ID = NULL; return $objRoot;
} /*---- PURPOSE: renders tree with colors and links suitable for admin usage LATER: The parent method should be generalized for color and link-function */
/*
public function RenderTree($iTwig=NULL) {
if (is_null($iTwig)) { $objRoot = $this->RootNode(); } else { $objRoot = $this->GetItem($iTwig); } $out = $objRoot->DrawTree(); return $out;
}
- /
public function ListTitles_unassigned() {
global $vgPage;
$sql = 'SELECT tc.*, t.Name' .' FROM (_titles AS tc LEFT JOIN cat_title_x_topic AS tt ON tc.ID=tt.ID_Title)' .' LEFT JOIN cat_titles AS t ON tc.ID=t.ID' .' WHERE (tt.ID_Title IS NULL) AND (tc.cntForSale > 0)'; $rs = $this->Engine()->DataSet($sql,$this->Engine()->Titles()->ClassSng()); if ($rs->HasRows()) { $vgPage->UseHTML(); $rs->Table = $this->Engine()->Titles();
$out = "\n- ";
while ($rs->NextRow()) {
$out .= "\n
- ".$rs->AdminLink($rs->Value('CatNum')).' '.$rs->Value('Name').' '; } $out .= "\n
} else { $out = 'All active titles have topics.'; } return $out;
} public function Data_forTitle($iTitle) {
$sql = 'SELECT bt.* FROM cat_topic AS bt LEFT JOIN cat_title_x_topic AS bx ON bx.ID_Topic=bt.ID WHERE ID_Title='.$iTitle; $objRows = $this->Engine()->DataSet($sql,$this->ClassSng()); return $objRows;
} public function AdminPage() {
global $wgOut; global $vgPage,$vgOut;
$out = "\n".'Unassigned Titles';$out .= $this->ListTitles_unassigned(); $out .= "\n |
$arLink = array('rebuild'=>TRUE); $htLink = $vgPage->SelfURL($arLink,TRUE);
$doRebuild = $vgPage->Arg('rebuild');
if ($doRebuild) { // apparently there's no way to display a message without preventing the redirect $this->RenderTree(TRUE); $this->AdminRedirect(); } else { $out .= "\n".'[<a href="'.$htLink.'">rebuild tree</a>]';
$this->TreeCtrl()->FileForCSS('dtree.css'); $out .= $this->RenderTree(FALSE); } $wgOut->AddHTML($out); $out = ; return $out;
} /*---- RETURNS: options array for entering topics USAGE:
1. fill in fHandleData_Change_Start, fHandleData_Change_Finish, fHandleData_Change_Item 2. Then, where $arOpts is the array returned: $ctrlList = new clsWidget_ShortList(); $ctrlList->Options($arOpts); $htOut = $ctrlList->HandleInput();
HISTORY:
2011-09-29 adapted from VbzAdminTitle::TopicListing()
*/ public function TopicListing_base_array() {
$tblTopics = $this; $tblTopics->doBranch(TRUE); $arOpts = array( 'name' => 'title', 'btnChk_Text' => 'Enter topics:', 'btnChg_Text' => '<= Add', 'txtCargo_sng' => 'topic ID', 'txtCargo_plr' => 'topic IDs', 'txtProd_sng' => 'topic', 'txtProd_plr' => 'topics', 'txtConf_list' => 'Adding', 'fHandleData_Check' => function($iVal) use ($tblTopics) { $obj = $tblTopics->GetItem($iVal); // for now, assume topic is ID
$arOut['html'] = $obj->AdminLink_name(); $arOut['text'] = $obj->KeyValue(); return $arOut; }, ); return $arOpts;
}
} class clsAdminTopic extends clsTopic {
/*---- HISTORY:
2010-12-05 boilerplate event logging added
*/ //---- // BOILERPLATE: event logging protected function Log() {
if (!is_object($this->logger)) { $this->logger = new clsLogger_DataSet($this,$this->objDB->Events()); } return $this->logger;
} public function StartEvent(array $iArgs) {
return $this->Log()->StartEvent($iArgs);
} public function FinishEvent(array $iArgs=NULL) {
return $this->Log()->FinishEvent($iArgs);
} public function EventListing() {
return $this->Log()->EventListing();
} // BOILERPLATE: admin HTML public function AdminURL() {
return clsAdminData::_AdminURL($this);
} public function AdminLink($iText=NULL,$iPopup=NULL,array $iarArgs=NULL) {
$strPopup = $this->AdminLink_default_popup($iPopup); return clsAdminData::_AdminLink($this,$iText,$strPopup,$iarArgs);
} // END BOILERPLATES //---- // // Boilerplate auxiliary functions public function AdminLink_name() {
if ($this->IsNew()) { return 'root'; } else { $txtShow = $this->Value('Name'); if ($this->doBranch()) { $txtPopup = $this->RenderBranch_text('<'); } else { $txtPopup = $this->NameFull(); } return $this->AdminLink($txtShow,$txtPopup); }
} protected function AdminLink_default_popup($iOverrideText) {
if (is_null($iOverrideText)) { $out = $this->Value('Name'); } else { $out = $iOverrideText; } return $out;
} // END boilerplate auxiliary //---- public function RenderBranch($iSep="←") {
$ftFullName = htmlspecialchars($this->Value('FullName')); $out = $this->AdminLink($this->Value('TreeName'),$ftFullName); if ($this->HasParent()) { $out .= $iSep.$this->ParentObj()->RenderBranch($iSep); } return $out;
} public function Tree_RenderTwig($iCntTitles) {
$cntTitles = $iCntTitles; $txtNoun = ' title'.Pluralize($cntTitles).' available'; // for topic #'.$id; $out = ' ['.$cntTitles.']'; // $txt = $this->Value('CatNum').' '.$this->Value('Name'); return $out;
} public function Tree_AddTwig(clsTreeNode $iTwig,$iText) {
$id = $this->Value('ID'); // $objSub = $iTwig->Add($id,$iText,$this->ShopURL()); $objSub = $iTwig->Add($id,$iText,$this->AdminURL()); return $objSub;
} public function AdminPage() {
global $wgOut,$wgRequest; global $vgPage,$vgOut;
$doEdit = $vgPage->Arg('edit'); $doSave = $wgRequest->GetBool('btnSave'); $doRmvTitles = $wgRequest->GetBool('btnRmvTitles');
$vgPage->UseHTML();
$strTitle = 'Topic: '.$this->Value('Name');
$objPage = new clsWikiFormatter($vgPage); $objSection = new clsWikiSection($objPage,$strTitle); $objSection->ToggleAdd('edit'); //$objSection->ActionAdd('view'); $out = $objSection->Generate();
// save edits before re-displaying data
// edits to this record $ftSaveStatus = NULL; if ($doEdit || $doSave) { $this->BuildEditForm(); if ($doSave) { $ftSaveStatus = $this->AdminSave(); } }
// topic deletion if ($doRmvTitles) { // TO BE WRITTEN }
if ($doEdit) { $out .= $objSection->FormOpen(); $objForm = $this->objForm;
$ctParent = $objForm->Render('ID_Parent'); $ctName = $objForm->Render('Name'); $ctNameTree = $objForm->Render('NameTree'); $ctNameFull = $objForm->Render('NameFull'); $ctNameMeta = $objForm->Render('NameMeta'); $ctUsage = $objForm->Render('Usage'); $ctSort = $objForm->Render('Sort'); $ctVariants = $objForm->Render('Variants'); $ctMispeled = $objForm->Render('Mispeled'); } else { $ctParent = $this->ParentObj()->AdminLink_name(); $ctName = $this->Value('Name'); $ctNameTree = $this->Value('NameTree'); $ctNameFull = $this->Value('NameFull'); $ctNameMeta = $this->Value('NameMeta'); $ctUsage = $this->Value('Usage'); $ctSort = $this->Value('Sort'); $ctVariants = $this->Value('Variants'); $ctMispeled = $this->Value('Mispeled'); }
$out .= '- ';
$out .= '
- ID: '.$this->KeyValue().' ['.$this->ShopLink('shop').']'; $out .= '
- Parent: '.$ctParent; $out .= '
- Name: '.$ctName;
$out .= '
- ';
$out .= '
- in tree: '.$ctNameTree; $out .= '
- complete: '.$ctNameFull; $out .= '
- meta: '.$ctNameMeta; $out .= '
- Usage: '.$ctUsage; $out .= '
- Searching: ';
$out .= '
- ';
$out .= '
- variants: '.$ctVariants; $out .= '
- misspellings: '.$ctMispeled; $out .= '
- sort by: '.$ctSort; $out .= '
if ($doEdit) { $out .= '<input type=submit name="btnSave" value="Save">'; $out .= '<input type=reset value="Reset">'; $out .= '</form>'; } $wgOut->AddHTML($out);
$wgOut->AddHTML("Subtopics
");$wgOut->AddHTML($this->SubtopicListing());
$wgOut->AddHTML("Titles
");$wgOut->AddHTML($this->TitleListing());
} /*---- ACTION: Save user changes to the record HISTORY:
2010-11-06 copied from VbzStockBin to VbzAdminItem 2011-01-26 copied from VbzAdminItem to clsAdminTopic
*/ public function AdminSave() {
global $vgOut;
$out = $this->objForm->Save(); $vgOut->AddText($out);
} /*---- HISTORY:
2010-11-06 adapted from VbzStockBin for VbzAdminTitle 2011-01-26 adapted from VbzAdminTitle
*/ private function BuildEditForm() {
global $vgOut;
if (is_null($this->objForm)) { // create fields & controls $objForm = new clsForm_DataSet($this,$vgOut); //$objCtrls = new clsCtrls($objForm->Fields()); //$objCtrls = $objForm;
$objForm->AddField(new clsFieldNum('ID_Parent'), new clsCtrlHTML()); $objForm->AddField(new clsField('Name'), new clsCtrlHTML(array('size'=>20))); $objForm->AddField(new clsField('NameTree'), new clsCtrlHTML(array('size'=>15))); $objForm->AddField(new clsField('NameFull'), new clsCtrlHTML(array('size'=>25))); $objForm->AddField(new clsField('NameMeta'), new clsCtrlHTML(array('size'=>25))); $objForm->AddField(new clsField('Usage'), new clsCtrlHTML(array('size'=>25))); $objForm->AddField(new clsField('Sort'), new clsCtrlHTML(array('size'=>5))); $objForm->AddField(new clsField('Variants'), new clsCtrlHTML(array('size'=>40))); $objForm->AddField(new clsField('Mispeled'), new clsCtrlHTML(array('size'=>40)));
$this->objForm = $objForm; //$this->objCtrls = $objCtrls; }
} protected function SubtopicListing() {
global $wgRequest;
$htStatus = NULL;
// set up the entry widget $ctrlList = new clsWidget_ShortList(); $me = $this; $arOpts = array( 'name' => 'topic', 'btnChk_Text' => 'Enter subtopics:', 'btnChg_Text' => '<= Create', 'txtCargo_sng' => 'topic name', 'txtCargo_plr' => 'topic names', 'txtProd_sng' => 'subtopic', 'txtProd_plr' => 'subtopics', 'fHandleData_Check' => function($iVal) { $arOut['html'] = $iVal; $arOut['text'] = $iVal; return $arOut; }, 'fHandleData_Change_Start' => function($iText) use ($me) { $arEv = array( 'descr' => 'Adding '.$iText, 'code' => 'sub++', 'where' => __METHOD__ ); $me->StartEvent($arEv); }, 'fHandleData_Change_Finish' => function($iText) use ($me) { $arEv = array( 'descrfin' => $iText ); $me->FinishEvent($arEv); }, 'fHandleData_Change_Item' => function($iVal) use ($me) { $txt = $iVal; $arIns = array( 'ID_Parent' => SQLValue($me->KeyValue()), 'Name' => SQLValue($txt) ); $me->Table->Insert($arIns); $out = $me->Table->LastID(); return $out; }, ); $ctrlList->Options($arOpts); $htStatus = $ctrlList->HandleInput();
$out = "\n<form method=post>";
$rs = $this->Subtopics();
if ($rs->HasRows()) {
$isOdd = TRUE; while ($rs->NextRow()) { $isOdd = !$isOdd; $ftStyleShade = $isOdd?'ffffff':'#cccccc'; $ftStyle = ' style="background: '.$ftStyleShade.';"';
$id = $rs->KeyString(); $ftID = $rs->AdminLink(); $ftName = $rs->Value('Name'); $ftNameTree = $rs->Value('NameTree'); $ftNameFull = $rs->Value('NameFull'); $ftSort = $rs->Value('Sort'); $ftVari = $rs->Value('Variants'); $ftMisp = $rs->Value('Mispeled');
$out .= "\n<tr$ftStyle>"
."" ."" ."" ."" ."" ."" ."" .""; } $out .= "\nID | Name | in tree | full | sort | variants | mis-spellings |
---|---|---|---|---|---|---|
$ftID | $ftName | $ftNameTree | $ftNameFull | $ftSort | $ftVari | $ftMisp |
} else {
$out .= 'None found.';
}
$out .= '
'.$htStatus;
$out .= $ctrlList->RenderForm_Entry();
$out .= '</form>';
return $out;
} protected function TitleListing() {
global $wgRequest; global $vgPage;
// check for any form actions $doChk = $wgRequest->GetBool('btnChkTitles'); $doAdd = $wgRequest->GetBool('btnAddTitles'); $doRmv = $wgRequest->GetBool('btnRmvTitles');
$htStatus = NULL;
// pass-along vars for anon functions $tblTitles = $this->Engine()->Titles(); // for anon function to use $tblTitleTopics = $this->Engine()->TitleTopics(); $me = $this;
$ctrlList = new clsWidget_ShortList(); $arOpts = array( 'name' => 'title', 'btnChk_Text' => 'Enter titles:', 'btnChg_Text' => '<= Add', 'txtCargo_sng' => 'title ID', 'txtCargo_plr' => 'title IDs', 'txtProd_sng' => 'title', 'txtProd_plr' => 'titles', 'fHandleData_Check' => function($iVal) use ($tblTitles) { $obj = $tblTitles->GetItem($iVal); // for now, assume title is ID
$arOut['html'] = $obj->AdminLink($obj->CatNum(),$obj->Value('Name')); //$arOut['text'] = $obj->KeyValue().'('.$obj->CatNum().')'; $arOut['text'] = $obj->KeyValue(); return $arOut; }, 'fHandleData_Change_Start' => function($iText) use ($me) { $arEv = array( 'descr' => 'Adding '.$iText, 'code' => 'sub++', 'where' => __METHOD__ ); $me->StartEvent($arEv); }, 'fHandleData_Change_Finish' => function($iText) use ($me) { $arEv = array( 'descrfin' => $iText ); $me->FinishEvent($arEv); }, 'fHandleData_Change_Item' => function($iVal) use ($me,$tblTitleTopics) { $txt = $iVal; $arIns = array( 'ID_Title' => SQLValue($txt), 'ID_Topic' => SQLValue($me->KeyValue()) ); //$this->Engine()->TitleTopics()->Insert($arIns); $sql = $tblTitleTopics->Insert($arIns); $out = SQLValue($txt); return $out; }, ); $ctrlList->Options($arOpts); $htStatus = $ctrlList->HandleInput(); if ($wgRequest->GetBool('btnRmvTitles')) { $arRmv = $wgRequest->GetArray('rmvTitle'); $cntRmv = count($arRmv); $arEv = array( 'descr' => 'Removing '.$cntRmv.' title'.Pluralize($cntRmv).' from this topic', 'code' => 'TTL--', 'where' => __METHOD__ ); $this->StartEvent($arEv); $txtRmv = ; foreach ($arRmv as $id => $on) { $sqlFilt = '(ID_Topic='.$this->ID.') AND (ID_Title='.$id.')'; $this->Engine()->TitleTopics()->Delete($sqlFilt); $txtRmv .= ' '.$id; } $arEv = array( 'descrfin' => 'Titles removed:'.$txtRmv ); $this->FinishEvent($arEv); $htStatus .= 'Titles removed:'.$txtRmv; }
$out = "\n<form name=\"add-titles\" method=post>";
$rs = $this->Titles(); if ($rs->HasRows()) {
$out .= "\n"; $out .= "\n";$isOdd = TRUE; while ($rs->NextRow()) { $isOdd = !$isOdd; $ftStyleShade = $isOdd?'ffffff':'#cccccc'; $ftStyle = ' style="background: '.$ftStyleShade.';"';
$id = $rs->KeyString(); $ftID = $rs->AdminLink(); $ftCatNum = $rs->CatNum(); $ftName = $rs->Value('Name'); $rsDept = $rs->DeptObj(); $ftDept = $rsDept->AdminLink_name(); $ftAdded = $rs->Value('DateAdded'); $ftUnavail = $rs->Value('DateUnavail');
$out .= "\n<tr$ftStyle>"
."" ."" ."" ."" ."" ."" .""; } $out .= "\nID | Cat # | Name | Dept | When Added | When Unavail |
---|---|---|---|---|---|
<input type=checkbox name=\"rmvTitle[$id]\">$ftID | $ftCatNum | $ftName | $ftDept | $ftAdded | $ftUnavail |
$out .= '<input type=submit name="btnRmvTitles" value="Remove Checked">';
} else {
$out .= 'None found.';
}
$out .= '
'.$htStatus;
$out .= $ctrlList->RenderForm_Entry();
/*
$out .= '<input type=submit name="btnChkTitles" value="Add These:">';
$out .= '<input size=40 name=txtNewTitles> (IDs separated by spaces)';
- /
$out .= '</form>'; return $out;
} /*---- What uses this?
*/ public function AdminList() {
$objRecs = $this;
if ($objRecs->HasRows()) { $out = "{| class=sortable\n|-\n! ID || Name || Abbr || When Avail || Superceded || Status"; $isOdd = TRUE; while ($objRecs->NextRow()) { $objTopic = $this->objDB->Topics()->GetItem($this->ID_Topic); $id = $objTopic->ID; $ftID = $id; $out .= "\n|- style=\"$wtStyle\"". "\n| ".$ftID. ' || '.$objRecs->Name. ' || '.$objRecs->Abbr. ' || '.$strDate. ' || '.$strSuper. ' || '.$strStatus; $isOdd = !$isOdd; } $out .= "\n|}"; } else { $out = 'No topics found.'; } return $out;
} /*---- HISTORY:
2010-10-11 Created -- then discovered that it probably doesn't need to be a separate function... but I think it makes things clearer.
*/ public function Twigs() {
if (is_null($this->ID)) { $sql = 'ID_Parent IS NULL'; } else { $sql = 'ID_Parent='.$this->ID; } $objRows = $this->Table->GetData($sql,NULL,'Sort,NameTree,Name'); return $objRows;
} public function DrawTree($iLevel=0,$iRootName="Topics") {
global $vgPage;
$out = ; $intLevel = $iLevel + 1; $strIndent = str_repeat('*',$intLevel);
$objRows = $this->Twigs(); if ($objRows->HasRows()) { if (empty($iLevel)) { $strName = $this->Name; if (empty($strName)) { $strName = $iRootName; } $out .= "\n{{#tree:id=root|root=$strName|"; $vgPage->UseWiki(); } while ($objRows->NextRow()) { $strNameTree = $objRows->NameTree; $strTwig = ifEmpty($strNameTree,$objRows->Name); $out .= "\n$strIndent".$objRows->AdminLink($strTwig); $out .= $objRows->DrawTree($intLevel); } if ($iLevel == 0) { $out .= "\n}}"; $vgPage->UseWiki(); } return $out; } else { if (empty($iLevel)) { return 'NO TOPICS FOUND'; } else { return NULL; } }
}
} class clsAdminTitleTopic_Titles extends clsTitleTopic_Titles {
public function __construct(clsDatabase $iDB) {
parent::__construct($iDB);
$this->ClassSng('VbzAdminTitle');
$this->ActionKey($this->Engine()->Titles()->ActionKey());
}
} class clsAdminTitleTopic_Topics extends clsTitleTopic_Topics {
public function __construct(clsDatabase $iDB) {
parent::__construct($iDB); $this->ClassSng('clsAdminTopic'); $this->ActionKey($this->Engine()->Topics()->ActionKey());
}
} /*========== | UTILITY FUNCTIONS | These should probably go into a separate file at some point
- /
/*----
PURPOSE: This is the newer version of WhoString_wt which uses WhoAdmin, WhoSystem, and WhoNetwork instead of VbzUser, SysUser, and Machine
- /
function WhoString2_wt($iRow) {
$htUnknown = '?';
if (isset($iRow['WhoSystem'])) {
$strSysUser = $iRow['WhoSystem']; $hasSysUser = TRUE;
} else {
$strSysUser = NULL; $hasSysUser = FALSE;
} $strMachine = $iRow['WhoNetwork']; $strVbzUser = $iRow['WhoAdmin'];
$htSysUser = is_null($strSysUser)?$htUnknown:$strSysUser; $htMachine = is_null($strMachine)?$htUnknown:$strMachine; $htVbzUser = is_null($strVbzUser)?$htUnknown:$strVbzUser;
$htWho = $htVbzUser; if ($hasSysUser) {
$htWho .= '/'.$htSysUser;
} $htWho .= '@'.$htMachine;
return $htWho;
} /*
STATUS: DEPRECATED Where possible, convert table fieldnames to be compatible with WhoString2_wt
- /
function WhoString_wt($iRow) {
$htUnknown = '?';
if (isset($iRow['SysUser'])) {
$strSysUser = $iRow['SysUser']; $hasSysUser = TRUE;
} else {
$strSysUser = NULL; $hasSysUser = FALSE;
} $strMachine = $iRow['Machine']; $strVbzUser = $iRow['VbzUser'];
$htSysUser = is_null($strSysUser)?$htUnknown:$strSysUser; $htMachine = is_null($strMachine)?$htUnknown:$strMachine; $htVbzUser = is_null($strVbzUser)?$htUnknown:$strVbzUser;
$htWho = $htVbzUser; if ($hasSysUser) {
$htWho .= '/'.$htSysUser;
} $htWho .= '@'.$htMachine;
return $htWho;
} function SelfLink_Page($iPage,$iKey,$iVal,$iText=NULL) {
$strText = (is_null($iText))?$iVal:$iText; if (is_null($strText)) {
return NULL;
} else {
return ''.$strText.'';
}
}
function WikiSelfLink($iArgs,$iText) { // this function is deprecated; gradually convert to SelfLink and then rename it
return ''.$iText.'';
} function WikiSectionHdr($iTitle,$iMenuName,array $iMenu) {
global $vgPage;$out = '
'; foreach ($iMenu as $name=>$arLink) { $htPath = $arLink['path']; $htPopup = $arLink['popup']; $htDispl = $arLink['displ']; $out .= '[<a href="'.$htPath.'" title="'.$htPopup.'">'.$htDispl.'</a>] '; } $out .= ''.$iTitle.'
';return $out;
} function WikiSectionHdr_Edit($iTitle,$iEditTitle) {
global $vgPage;
// global $vgOut;
$doEdit = $vgPage->Arg('edit'); $arLink = array( 'edit' => !$doEdit, 'page' => $vgPage->Arg('page'), 'id' => $vgPage->Arg('id') ); $htPath = $vgPage->SelfURL($arLink,TRUE);$out = '
'; if ($doEdit) { $out .= '[<a href="'.$htPath.'" title="View '.$iEditTitle.'">view</a>] '; } else { $out .= '[<a href="'.$htPath.'" title="Edit '.$iEditTitle.'">edit</a>] '; } $out .= ''.$iTitle.'
';return $out;
}
if (!function_exists('TimeStamp_HideTime')) { //-- function TimeStamp_HideTime($iStamp) {
if (is_string($iStamp)) {
$intStamp = strtotime($iStamp);
} else if (is_int($iStamp)) {
$intStamp = $iStamp;
} else {
$intStamp = NULL;
} if (!is_null($intStamp)) {
return date('Y-m-d',$intStamp);
} else {
return NULL;
}
} //-- }
function IsWebSecure() {
if (isset($_SERVER["HTTPS"])) {
return $_SERVER["HTTPS"] == 'on';
} else {
return FALSE;
}
}</php>