CORE-POS/IS4C

View on GitHub
fannie/item/vendors/VendorIndexPage.php

Summary

Maintainability
F
4 days
Test Coverage
D
69%
<?php
/*******************************************************************************

    Copyright 2009,2013 Whole Foods Co-op

    This file is part of CORE-POS.

    CORE-POS is free software; you can redistribute it and/or modify
    it under the terms of the GNU General Public License as published by
    the Free Software Foundation; either version 2 of the License, or
    (at your option) any later version.

    CORE-POS is distributed in the hope that it will be useful,
    but WITHOUT ANY WARRANTY; without even the implied warranty of
    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
    GNU General Public License for more details.

    You should have received a copy of the GNU General Public License
    in the file license.txt along with IT CORE; if not, write to the Free Software
    Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA

*********************************************************************************/


/* --COMMENTS - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
    
    12Mar2013 Andy Theuninck Use API classes
     7Sep2012 Eric Lee Display vendorID in select.
                       Display both "Select" and "New" options.

*/

include(dirname(__FILE__) . '/../../config.php');
if (!class_exists('FannieAPI')) {
    include(__DIR__ . '/../../classlib2.0/FannieAPI.php');
}

class VendorIndexPage extends FannieRESTfulPage 
{
    protected $title = "Fannie : Manage Vendors";
    protected $header = "Manage Vendors";

    protected $must_authenticate = true;
    //protected $auth_classes = array('pricechange');
    private $canEdit = false;

    public $description = '[Vendor Editor] creates or update information about vendors.';

    public function preprocess()
    {
        $this->addRoute(
            'get<id><autoAdd>',
            'post<new><name>',
            'get<info>',
            'post<info>',
            'post<delivery>',
            'post<id><shipping>',
            'post<id><rate>',
            'post<id><inactive>',
            'post<id><autoID>'
        );
        $this->canEdit = FannieAuth::validateUserQuiet('pricechange'); 

        return parent::preprocess();
    }

    protected function post_id_autoID_handler()
    {
        if (!$this->canEdit) return false;

        $dbc = $this->connection;
        $dbc->selectDB($this->config->get('OP_DB'));
        $map = new AutoOrderMapModel($dbc);
        $map->vendorID($this->id);
        $enables = FormLib::get('autoEnable', array());
        $accounts = FormLib::get('autoAccount', array());
        for ($i=0; $i<count($this->autoID); $i++) {
            $map->storeID($this->autoID[$i]);
            $active = in_array($map->storeID(), $enables);
            $map->active($active ? 1 : 0);
            $map->accountID($accounts[$i]);
            $map->save();
        }

        $vendor = new VendorsModel($dbc);
        $vendor->vendorID($this->id);
        $vendor->orderMinimum(FormLib::get('minOrder', 0));
        $vendor->halfCases(FormLib::get('halfs', false) ? 1 : 0);
        $vendor->save();

        return false;
    }

    protected function get_id_autoAdd_handler()
    {
        $this->autoPopulate($this->id);

        return 'VendorIndexPage.php?vid=' . $this->id;
    }

    protected function post_new_name_handler()
    {
        if (!$this->canEdit) return false;
        echo $this->newVendor($this->name);

        return false;
    }

    protected function get_info_handler()
    {
        $this->getVendorInfo(FormLib::get('vid',0)); 

        return false;
    }

    protected function post_info_handler()
    {
        if (!$this->canEdit) return false;
        $id = FormLib::get('vendorID','');
        if ($id === '') {
            echo json_encode(array('error'=>1, 'msg'=>'Bad request'));
            return false;
        }

        $web = FormLib::get('website');
        if (!empty($web) && substr(strtolower($web),0,4) !== "http") {
            $web = 'http://'.$web;
        }
        $localID = FormLib::get('local-origin-id', 0);

        $dbc = FannieDB::get($this->config->get('OP_DB'));
        $vModel = new VendorsModel($dbc);
        $vModel->vendorID($id);
        $vModel->phone(FormLib::get('phone'));
        $vModel->fax(FormLib::get('fax'));
        $vModel->email(trim(FormLib::get('email')));
        $vModel->website($web);
        $vModel->notes(FormLib::get('notes'));
        $vModel->address(FormLib::get('address'));
        $vModel->city(FormLib::get('city'));
        $vModel->state(FormLib::get('state'));
        $vModel->zip(FormLib::get('zip'));
        $vModel->localOriginID($localID);
        $success = $vModel->save();

        $ret = array('error'=>0, 'msg'=>'');
        if ($success) {
            $ret['msg'] = 'Saved vendor information';
        } else {
            $ret['msg'] = 'Error saving vendor information';
            $ret['error'] = 1;
        }
        echo json_encode($ret);

        return false;
    }

    protected function post_id_inactive_handler()
    {
        if (!$this->canEdit) return false;
        $dbc = $this->connection;
        $dbc->setDefaultDB($this->config->OP_DB);
        $vModel = new VendorsModel($dbc);
        $vModel->vendorID($this->id);
        $vModel->inactive($this->inactive);
        $vModel->save();

        return false;
    }

    protected function post_id_shipping_handler()
    {
        if (!$this->canEdit) return false;
        $ret = array('error'=>0);
        if ($this->id === ''){
            $ret['error'] = 'Bad request';
        } else {
            $dbc = FannieDB::get($this->config->get('OP_DB'));
            $vModel = new VendorsModel($dbc);
            $vModel->vendorID($this->id);
            $vModel->shippingMarkup($this->shipping / 100.00);
            if (!$vModel->save()) {
                $ret['error'] = 'Save failed!';
            }
        }
        echo json_encode($ret);

        return false;
    }

    protected function post_id_rate_handler()
    {
        if (!$this->canEdit) return false;
        $ret = array('error'=>0);
        if ($this->id === ''){
            $ret['error'] = 'Bad request';
        } else {
            $dbc = $this->connection;
            $dbc->setDefaultDB($this->config->OP_DB);
            $vModel = new VendorsModel($dbc);
            $vModel->vendorID($this->id);
            $vModel->discountRate($this->rate / 100.00);
            if (!$vModel->save()) {
                $ret['error'] = 'Save failed!';
            }
        }
        echo json_encode($ret);

        return false;
    }

    protected function post_delivery_handler()
    {
        if (!$this->canEdit) return false;
        $delivery = new VendorDeliveriesModel(FannieDB::get($this->config->get('OP_DB')));
        $delivery->vendorID(FormLib::get('vID', 0));
        $delivery->frequency(FormLib::get('frequency', 'weekly'));
        $delivery->regular( FormLib::get('regular') ? 1 : 0 );
        $delivery->sunday( FormLib::get('sunday') ? 1 : 0 );
        $delivery->monday( FormLib::get('monday') ? 1 : 0 );
        $delivery->tuesday( FormLib::get('tuesday') ? 1 : 0 );
        $delivery->wednesday( FormLib::get('wednesday') ? 1 : 0 );
        $delivery->thursday( FormLib::get('thursday') ? 1 : 0 );
        $delivery->friday( FormLib::get('friday') ? 1 : 0 );
        $delivery->saturday( FormLib::get('saturday') ? 1 : 0 );
        $ret = array();
        if ($delivery->regular()) {
            $delivery->autoNext();
            $ts1 = strtotime($delivery->nextDelivery());
            $ts2 = strtotime($delivery->nextNextDelivery());
            if ($ts1 !== false && $ts2 !== false) {
                $ret['next'] = date('D, M jS', $ts1);
                $ret['nextNext'] = date('D, M jS', $ts2);
            }
        }
        $delivery->save();
        echo json_encode($ret);

        return false;
    }

    private function autoPopulate($vendorID)
    {
        if (!$this->canEdit) return false;
        $dbc = FannieDB::get($this->config->get('OP_DB'));
        
        $query = '
            SELECT p.upc,
                p.upc AS sku,
                p.brand,
                p.description,
                p.size,
                p.unitofmeasure,
                p.cost,
                0.00 AS saleCost,
                0 AS vendorDept
            FROM products AS p
                INNER JOIN vendors AS v ON p.default_vendor_id=v.vendorID
            WHERE v.vendorID=?
                AND p.upc NOT IN (
                    SELECT upc FROM vendorItems WHERE vendorID=?
                ) AND p.upc NOT IN (
                    SELECT upc FROM VendorAliases WHERE vendorID=?
                )';
        $prep = $dbc->prepare($query);
        $args = array($vendorID, $vendorID, $vendorID);
        $result = $dbc->execute($prep, $args);
        $item = new VendorItemsModel($dbc);
        while ($row = $dbc->fetch_row($result)) {
            $item->vendorID($vendorID);
            $item->upc($row['upc']);
            $item->sku($row['sku']);
            $item->brand($row['brand']);
            $item->description($row['description']);
            $item->units(1);
            $item->size($row['size'] . $row['unitofmeasure']);
            $item->cost($row['cost']);
            $item->saleCost(0);
            $item->vendorDept(0);
            $item->save();
        }
    }

    private function getVendorInfo($id)
    {
        $dbc = FannieDB::get($this->config->get('OP_DB'));
        $ret = "";
        $noEdit = !$this->canEdit ? 'disabled' : '';
        $noShow = !$this->canEdit ? 'collapse' : '';

        $model = new VendorsModel($dbc);
        $model->vendorID($id);
        $model->load();
        $ret .= '<div>';
        $ret .= "<b>Id</b>: $id &nbsp; <b>Name</b>: " . $model->vendorName();
        $ret .= ' <label>Active
            <input type="checkbox" onchange="vendorEditor.toggleActive(this, ' . $id . ')" ' 
                . ($model->inactive() == 1 ? '' : 'checked') . ' ' . $noEdit . ' />
            </label>';
        $ret .= sprintf(' | <a class="%s" href="RenameVendorPage.php?id=%d">Rename %s</a>', $noShow, $id, $model->vendorName());
        $ret .= sprintf(' | <a class="%s" href="DeleteVendorPage.php?id=%d">Delete %s</a>', $noShow, $id, $model->vendorName());
        $ret .= '</div>';

        $itemQ = $dbc->prepare("SELECT COUNT(*) FROM vendorItems WHERE vendorID=?");
        $itemR = $dbc->execute($itemQ,array($id));
        $num = 0;
        if ($itemR && $row = $dbc->fetch_row($itemR)) {
            $num = $row[0];
        }

        $ret .= '
            <div class="row">
                <div class="container-fluid col-sm-3">';

        $ret .= '
            <div class="panel panel-default">
                <div class="panel-heading">Catalog</div>
                <div class="panel-body">
                This vendor contains ' . $num . ' items<br />';
        if ($num > 0) {
            $ret .= "<a class=\"{$noShow}\" href=\"BrowseVendorItems.php?vid=$id\">Browse vendor catalog</a>";  
            if ($num <= 750) {
                $ret .= "<br />";
                $ret .= "<a class=\"{$noShow}\" href=\"EditVendorItems.php?id=$id\">Edit vendor catalog</a>";  
            }
        }
        $ret .= "<br />";
        $ret .= "<a class=\"{$noShow}\" href=\"UpdateUploadPage.php?vid=$id\">Upload & Update vendor catalog</a>";
        $ret .= "<br />";
        $ret .= "<a class=\"{$noShow}\" href=\"DefaultUploadPage.php?vid=$id\">Upload & Replace vendor catalog</a>";
        $ret .= "<br />";
        $ret .= "<a class=\"{$noShow}\" href=\"VendorIndexPage.php?id=$id&autoAdd=1\">Add existing items to catalog</a>";
        $ret .= '</div></div>';

        $ret .= '</div><div class="container-fluid col-sm-3">';

        $ret .= '
            <div class="panel panel-default">
                <div class="panel-heading">Mappings</div>
                <div class="panel-body">';
        $ret .= "<a class=\"{$noShow}\" href=\"VendorAliasesPage.php?id=$id\">Manage Aliases</a>";
        $ret .= "<br />";
        $ret .= "<a class=\"{$noShow}\" href=\"UploadPluMapPage.php?vid=$id\">Upload PLU/SKU mapping</a>";
        $ret .= "<br />";
        $ret .= "<a class=\"{$noShow}\" href=\"SkuMapPage.php?id=$id\">View or Edit PLU/SKU mapping</a>";
        $ret .= "<br />";
        $ret .= "<a class=\"{$noShow}\" href=\"UnitBreakdownPage.php?id=$id\">View or Edit Breakdown mapping</a>";
        $ret .= '</div></div>';

        $ret .= '</div><div class="container-fluid col-sm-3">';

        $ret .= '
            <div class="panel panel-default">
                <div class="panel-heading">Margin</div>
                <div class="panel-body">';

        $itemQ = $dbc->prepare("SELECT COUNT(*) FROM vendorDepartments WHERE vendorID=?");
        $itemR = $dbc->execute($itemQ,array($id));
        $num = 0;
        if ($itemR && $row = $dbc->fetch_row($itemR)) {
            $num = $row[0];
        }
        $ret .= '<p>';
        $ret .= "<a href=\"../../batches/UNFI/\">Vendor Price Batch Tools</a>";
        $ret .= "</p><p>";
        if ($num == 0) {
            $ret .= "<a class=\"{$noShow}\" href=\"VendorDepartmentEditor.php?vid=$id\">This vendor's items are not yet arranged into subcategories</a>";
            $ret .= '<p />';
            $ret .= "<a class=\"{$noShow}\" href=\"VendorDepartmentUploadPage.php?vid=$id\">Upload Subcategory List</a>";
        } else {
            $ret .= "This vendor's items are divided into ";
            $ret .= $num." subcategories";
            $ret .= "<br />";
            $ret .= "<a class=\"{$noShow}\" href=\"VendorDepartmentEditor.php?vid=$id\">View or Edit vendor subcategory margin(s)</a>";
            $ret .= "<br />";
            $ret .= "<a class=\"{$noShow}\" href=\"VendorMarginsPage.php?id=$id\">View or Edit vendor-specific POS department margins</a>";
            $ret .= '<p />';
            $ret .= "<a class=\"{$noShow}\" href=\"VendorDepartmentUploadPage.php?vid=$id\">Upload Subcategory List</a>";
        }
        $ret .= '</p>';
        $ret .= '
            <div class="form-group">
                <div class="input-group">
                    <span class="input-group-addon">Shipping</span>
                    <input type="text" id="vc-shipping" name="shipping" ' . $noEdit . '
                        onchange="vendorEditor.saveShipping(this.value);"
                        title="Markup percentage to account for shipping fees"
                        class="form-control" value="' . $model->shippingMarkup() * 100 . '" />
                    <span class="input-group-addon">%</span>
                </div>
            </div>
            <div class="form-group">
                <div class="input-group">
                    <span class="input-group-addon">Discount Rate</span>
                    <input type="text" id="vc-discount" name="discount-rate" ' . $noEdit . '
                        title="Markdown percentage from catalog list costs"
                        onchange="vendorEditor.saveDiscountRate(this.value);"
                        class="form-control" value="' . $model->discountRate() * 100 . '" />
                    <span class="input-group-addon">%</span>
                </div>
            </div>';
        $ret .= '</div></div>';

        $ret .= '</div></div>';

        $ret .= '
            <div class="panel panel-default">
                <div class="panel-heading">Contact Info</div>
                <div class="panel-body">
                    <div class="form-alerts"></div>';
        $ret .= '<form role="form" class="form-horizontal" onsubmit="vendorEditor.saveVC(' . $id . '); return false;" id="vcForm">';
        $ret .= '<div class="form-group">
            <label for="vcAddress" class="control-label col-sm-1">Address</label>
            <div class="col-sm-10">
            <input type="text" class="form-control" id="vcAddress" name="address" value="' . $model->address() . '" />
            </div>
            </div>';
        $ret .= '<div class="form-group">
            <label for="vcCity" class="control-label col-sm-1">City</label>
            <div class="col-sm-5">
            <input type="text" class="form-control" id="vcCity" name="city" value="' . $model->city() . '" />
            </div>
            <label for="vcZip" class="control-label col-sm-1">State</label>
            <div class="col-sm-1">
            <input type="text" class="form-control" id="vcState" name="state" value="' . $model->state() . '" />
            </div>
            <label for="vcZip" class="control-label col-sm-1">Zip</label>
            <div class="col-sm-2">
            <input type="text" class="form-control" id="vcZip" name="zip" value="' . $model->zip() . '" />
            </div>
            </div>';
        $ret .= '<div class="form-group">
            <label for="vcPhone" class="control-label col-sm-1">Phone</label>
            <div class="col-sm-5">
            <input type="tel" class="form-control" id="vcPhone" name="phone" value="' . $model->phone() . '" />
            </div>
            <label for="vcFax" class="control-label col-sm-1">Fax</label>
            <div class="col-sm-4">
            <input type="text" id="vcFax" class="form-control" name="fax" value="' . $model->fax() . '" />
            </div>
            </div>';
        $ret .= '<div class="form-group">
            <label for="vcEmail" class="control-label col-sm-1">Email</label>
            <div class="col-sm-5">
            <input type="text" class="form-control" id="vcEmail" name="email" value="' . $model->email() . '" />
            </div>
            <label for="vcWebsite" class="control-label col-sm-1">Website</label>
            <div class="col-sm-4">
            <input type="text" class="form-control" id="vcWebsite" name="website" value="' . $model->website() . '" />
            </div>
            </div>';
        $ret .= '<div class="form-group">
            <label for="vc-local-id" class="control-label col-sm-1">Local</label>
            <div class="col-sm-10">
                <select class="form-control" name="local-origin-id">
                <option value="0">No</option>';
        $origins = new OriginsModel($dbc);
        $origins->local(1);
        $locals = $origins->find('shortName');
        if (count($locals) == 0) {
            $ret .= sprintf('<option value="1" %s>Yes</option>',
                    ($model->localOriginID() == 1 ? 'selected' : ''));
        } else {
            foreach ($locals as $origin) {
                $ret .= sprintf('<option %s value="%d">%s</option>',
                    ($origin->originID() == $model->localOriginID() ? 'selected' : ''),
                    $origin->originID(), $origin->shortName());
            }
        }
        $ret .= '</select>
                </div>
            </div>';
        $ret .= '<div class="form-group">
            <label for="vcNotes" class="control-label col-sm-1">Ordering Notes</label>
            <div class="col-sm-10">
            <textarea class="form-control" rows="5" name="notes" id="vcNotes">' . $model->notes() . '</textarea>
            </div>
            </div>';
        $ret .= '<button ' . $noEdit . ' type="submit" class="btn btn-default">Save Vendor Contact Info</button>';
        $ret .= '</form>';
        $ret .= '</div></div>';

        $prodP = $dbc->prepare("SELECT super_name, count(*)
            FROM products AS p
                INNER JOIN MasterSuperDepts AS m ON p.department=m.dept_ID
            WHERE p.default_vendor_id=?
            GROUP BY super_name");
        $prodR = $dbc->execute($prodP, array($id));
        $supers = array();
        $sum = 0;
        while ($row = $dbc->fetchRow($prodR)) {
            $supers[$row['super_name']] = $row[1];
            $sum += $row[1];
        }
        arsort($supers);
        foreach (array_keys($supers) as $s) {
            $supers[$s] = sprintf('%.2f%%', $supers[$s] / $sum * 100);
        }
        $ret .= '<div class="panel panel-default">
            <div class="panel-heading">Product Mix</div>
            <div class="panel-body"><ul>';
        foreach ($supers as $s => $pct) {
            $ret .= '<li>' . $pct . ' ' . $s . '</li>';
        }
            
        $ret .= '</ul></div></div>';

        $stores = new StoresModel($dbc);
        $stores->hasOwnItems(1);
        $map = new AutoOrderMapModel($dbc);
        $map->vendorID($id);
        $ret .= '<div class="panel panel-default">
            <div class="panel-heading">Auto Order</div>
            <div class="panel-body">
            <div class="form-group">
                <label>Minimum Order</label>
                <div class="input-group">
                    <span class="input-group-addon">$</span>
                    <input type="text" name="minOrder" class="form-control auto-order"
                        value="' . $model->orderMinimum() . '" ' . $noEdit . ' />
                </div>
            </div>
            <div class="form-group">
                <label>Allow Half Cases
                    <input type="checkbox" name="halfs" class="auto-order" value="1"
                        ' . ($model->halfCases() ? 'checked' : '') . ' ' . $noEdit . ' />
                </label>
            </div>
            <table class="table table-bordered">
            <tr><th>Store</th><th>Enabled</th><th>Account#</th></tr>';
        foreach ($stores->find() as $store) {
            $map->storeID($store->storeID());
            $exists = $map->load();
            $ret .= sprintf('<tr>
                <td>%s</td>
                <input type="hidden" name="autoID[]" value="%d" class="auto-order" />
                <td><input type="checkbox" %s class="auto-order" name="autoEnable[]" value="%d" %s /></td>
                <td><input type="text" class="form-control auto-order" name="autoAccount[]" value="%s" %s /></td>
                </tr>',
                $store->description(),
                $store->storeID(),
                ($map->active() ? 'checked' : ''),
                $store->storeID(), $noEdit,
                $map->accountID(), $noEdit
            );
        }
        $ret .= '</table>
                <button type="button" class="btn btn-default" ' . $noEdit . '
                    onclick="vendorEditor.saveAutoOrder(' . $id . '); return false;">Save</button>
                    &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;
                    <a class="' . $noShow . '" href="ParsPage.php?id=' . $id . '">Pars Algorithm</a>
                </div>
            </div>';

        $delivery = new VendorDeliveriesModel($dbc);
        $delivery->vendorID($id);
        $delivery->load();
        $ret .= '<p class="form-inline form-group"><label class="control-label" for="deliverySelect">Delivery Schedule</label>: ';
        $ret .= '<select class="delivery form-control" name="frequency" id="deliverySelect"><option>Weekly</option></select>';
        $ret .= ' <label for="regular" class="control-label">Regular</label>: <input type="checkbox" class="delivery"
                    name="regular" id="regular" ' . ($delivery->regular() ? 'checked' : '') . ' />';
        
        $dt = mktime(0, 0, 0, 6, 15, 2014); // date doesn't matter; just need a sunday
        $labels = '';
        $checks = '';
        for ($i=0; $i<7; $i++) {
            $func = strtolower(date('l', $dt));
            $labels .= '<th><label for="' . $func . '">' . date('D', $dt) . '</label></th>'; 
            $checks .= '<td><input type="checkbox" id="' . $func . '" name="' . $func . '"
                        ' . ($delivery->$func() ? 'checked' : '') . ' class="delivery" ' . $noEdit . '/></td>';
            $dt = mktime(0, 0, 0, date('n', $dt), date('j', $dt)+1, date('Y', $dt));
        }
        $ret .= '<table class="table"><tr>' . $labels . '</tr><tr>' . $checks . '</tr></table>';
        $ret .= 'Next 2 deliveries: '
                . '<span id="nextDelivery">' . date('D, M jS', strtotime($delivery->nextDelivery())) . '</span>'
                . ' and '
                . '<span id="nextNextDelivery">' . date('D, M jS', strtotime($delivery->nextNextDelivery())) . '</span>';
        $ret .= '</p>';

        echo $ret;
    }

    private function newVendor($name)
    {
        $dbc = FannieDB::get($this->config->get('OP_DB'));

        $id = 1;    
        $p = $dbc->prepare("SELECT max(vendorID) FROM vendors");
        $rp = $dbc->execute($p);
        $rw = $dbc->fetch_row($rp);
        if ($rw[0] != "")
            $id = $rw[0]+1;

        $model = new VendorsModel($dbc);
        $model->vendorID($id);
        $model->vendorName($name);
        $model->vendorAbbreviation(substr($name, 0, 10));
        $model->save();

        return $id;
    }

    protected function get_view()
    {
        $dbc = FannieDB::get($this->config->get('OP_DB'));
        $vendors = "<option value=\"\">Select a vendor...</option>";
        $vendors .= "<option value=\"new\">New vendor...</option>";
        $q = $dbc->prepare("SELECT * FROM vendors ORDER BY vendorName");
        $rp = $dbc->execute($q);
        $vid = FormLib::get_form_value('vid');
        while($rw = $dbc->fetch_row($rp)){
            if ($vid !== '' && $vid == $rw[0])
                $vendors .= "<option selected value=$rw[0]>$rw[1]</option>";
            else
                $vendors .= "<option value=$rw[0]>$rw[1]</option>";
        }
        ob_start();
        ?>
        <p id="vendorarea">
        <select onchange="if (this.value=='new') vendorEditor.vendorNew(); else location='?vid='+this.value;" 
            id=vendorselect class="form-control chosen">
        <?php echo $vendors; ?>
        </select>
        </p>
        <p id="contentarea">
        <?php 
        if ($vid) { 
            echo $this->getVendorInfo($vid); 
            $this->addOnloadCommand("\$('.delivery').change(vendorEditor.saveDelivery);\n");
        } 
        ?>
        </p>
        <?php

        $this->addScript('index.js');
        $this->addOnloadCommand("\$('#vendorselect').focus();\n");
        $this->addScript('../../src/javascript/chosen/chosen.jquery.min.js');
        $this->addCssFile('../../src/javascript/chosen/bootstrap-chosen.css');
        $this->addOnloadCommand("\$('select.chosen').chosen();\n");

        return ob_get_clean();
    }

    public function helpContent()
    {
        return '<p>Vendors are the entities the store purchases its 
            products from. The most important data associated with
            a vendor is their catalog of items. A product that the store
            sells may correspond to one or more items in one or more
            catalogs - i.e. the item may be available from more than
            one vendor and/or may be availalbe in more than one case
            size. Keeping vendor catalogs up to date with accurate 
            costs helps manage retail pricing and margin.</p>
            <p>There are two fairly distinct paths to managing vendor
            catalogs. The best approach will differ depending what kind
            of information is available for a given vendor. The first
            approach begins with building a full vendor catalog. This
            is more practical if the catalog is available in a digital
            format. <em>Upload vendor catalog</em> is used to import
            all the catalog data. From there <em>Browse vendor catalog</em>
            can be used to add catalog items to the store\'s own products.
            </p>
            <p>The second approach begins with the store\'s own products
            and builds a minimal vendor catalog to match. This is more
            practical when a digital catalog is not available. <em>Add existing
            items to catalog</em> will create vendor catalog entries from
            the store\'s existing products that are assigned to this vendor.
            <em>Edit vendor catalog</em> can then adjust these catalog 
            entries as needed. While <em>Edit vendor catalog</em> can technically
            be used with catalog imported from digital files, this is a
            waste of time if catalogs are imported on a regular basis. Each
            subsequent import will end up overwriting all manual edits.
            Similarly, you can <em>Browse vendor catalog</em> with catalogs
            that were built from the store\'s existing products but there
            won\'t be any items that can be added to products.
            </p>
            <p>PLU/SKU mapping is for resolving situations where the
            store and the vendor use different UPCs. This is often
            the case with items sold in bulk using a PLU.</p>
            <p>Contact Info and Delivery Schedule are wholly optional.
            Jot down whatever is useful.</p>
            <p>Several margin adjustments can be associated with a vendor.
            An item\'s default margin is chosen, from lowest to highest priority, 
            from these options:
                <ul>
                    <li><em>(default)</em> The POS department\'s margin.</li>
                    <li>The vendor catalog subcategory\'s margin</li>
                    <li>The vendor <strong>and</strong> POS department specific margin</li>
                </ul>
            This structure creates increasingly specific overrides from the default, POS-department
            based margins. Higher priority rules only need to exist where the target margin
            deviates from the default. Both vendor subcategories and the additional vendor+POS-department
            overrides are entirely optional.</p>
            <p>Two additional adjustments can be applied <em>in addition</em> to the baseline margin above.
            The shipping percentage <strong>increases</strong> the item\'s cost before applying the
            baseline margin resulting in a higher retail price. The discount rate <strong>decreases</strong>
            an item\'s cost before applying the baseline margin resulting in a lower retail price. The names
            refer to common use cases, but in practice to price all a vendor\'s items e.g. 5% above or below
            the default POS department margin it\'s easier to use one of these fields than create dozens and/or
            hundreds of subcategory or vendor+POS-department overrides.</p>
            ';
    }

    public function unitTest($phpunit)
    {
        $phpunit->assertNotEquals(0, strlen($this->get_view()));
        $new = $this->newVendor('TEST VENDOR');
        $phpunit->assertEquals(true, is_numeric($new));
        $this->id=$new;
        $this->get_id_autoAdd_handler();

        $this->rate=100;
        $this->shipping=100;
        ob_start();
        $this->post_id_rate_handler();
        $this->post_id_shipping_handler();
        ob_end_clean();
        $this->inactive = 0;
        $this->post_id_inactive_handler();
        $vendor = new VendorsModel($this->connection);
        $vendor->vendorID($new);
        $phpunit->assertEquals(true, $vendor->load());
        $phpunit->assertEquals(1, $vendor->shippingMarkup());
        $phpunit->assertEquals(1, $vendor->discountRate());
        $phpunit->assertEquals(0, $vendor->inactive());

        $this->name = 'TEST';
        ob_start();
        $this->post_new_name_handler();
        $this->get_info_handler();
        ob_end_clean();
    }
}

FannieDispatch::conditionalExec();