예제 #1
0
 /**
   Assign batch to all stores
   @param $batchID [int] batch ID
 */
 public static function initBatch($batchID)
 {
     $dbc = FannieDB::get(FannieConfig::config('OP_DB'));
     $map = new StoreBatchMapModel($dbc);
     $stores = new StoresModel($dbc);
     foreach ($stores->find() as $s) {
         $map->storeID($s->storeID());
         $map->batchID($batchID);
         $map->save();
     }
 }
예제 #2
0
 protected function get_view()
 {
     ob_start();
     ?>
     <div id="alert-area"></div>
     <form action="AddCashierPage.php" method="post">
     <div class="form-group">
         <label>First Name</label>
         <input type=text name=fname required class="form-control" />
     </div>
     <div class="form-group">
         <label>Last Name</label>
         <input type=text name=lname class="form-control" />
     </div>
     <div class="form-group">
         <label>Privileges</label>
         <select name="fes" class="form-control">
             <option value=20>Regular</option>
             <option value=30>Manager</option>
         </select>
     </div>
     <div class="form-group">
         <label>Birthdate</label>
         <input type="text" class="form-control date-field" name="birthdate" id="birth-date-field"
             placeholder="Optional; for stores selling age-restricted items" />
     </div>
     <?php 
     if ($this->config->get('STORE_MODE') == 'HQ') {
         echo '<div class="form-group">';
         $dbc = $this->connection;
         $stores = new StoresModel($dbc);
         $mapP = $dbc->prepare('SELECT storeID FROM StoreEmployeeMap WHERE storeID=? AND empNo=?');
         foreach ($stores->find('storeID') as $s) {
             $mapR = $dbc->execute($mapP, array($s->storeID(), $emp_no));
             $checked = $mapR && $dbc->numRows($mapR) ? 'checked' : '';
             printf('<label>
                 <input type="checkbox" name="store[]" value="%d" %s />
                 %s
                 </label> | ', $s->storeID(), $checked, $s->description());
         }
         echo '</div>';
     }
     ?>
     <p>
         <button type="submit" class="btn btn-default">Create Cashier</button>
     </p>
     </form>
     <?php 
     $ret = ob_get_clean();
     $this->add_onload_command("\$('input.form-control:first').focus();\n");
     return $ret;
 }
예제 #3
0
 public function saveAllStores()
 {
     $current_store = $this->store_id();
     if ($this->upc() == '') {
         return false;
     }
     $stores = new StoresModel($dbc);
     $ret = true;
     foreach ($stores->find() as $store) {
         $this->store_id($store->storeID());
         if (!$this->save()) {
             $ret = false;
         }
     }
     if ($current_store) {
         $this->store_id($current_store);
     }
     return $ret;
 }
예제 #4
0
 public function get_view()
 {
     $dbc = $this->connection;
     $dbc->selectDB($this->config->get('OP_DB'));
     $query = '
         SELECT store_id,
             COUNT(*) AS numItems
         FROM products
         WHERE store_id NOT IN (
             SELECT storeID FROM Stores
         )
         GROUP BY store_id
         ORDER BY store_id';
     $result = $dbc->query($query);
     if ($dbc->numRows($result) == 0) {
         return '<div class="alert alert-success">All items belong to stores</div>';
     }
     $ret = '<table class="table table-bordered">';
     $ret .= '<tr>
         <th>Current store ID</th>
         <th># of items</th>
         <th>Re-assign to store</th>
         </tr>';
     $stores = new StoresModel($dbc);
     $opts = $stores->toOptions();
     while ($w = $dbc->fetchRow($result)) {
         $ret .= sprintf('
             <tr>
                 <td>%d</td>
                 <td>%d</td>
                 <td class="form-inline">
                     <form method="post">
                         <select name="newID" class="form-control">
                             <option value="">Choose store</option>
                             %s
                         </select>
                         <input type="hidden" name="oldID" value="%d" />
                         <button type="submit" class="btn btn-default btn-sm">Re-Assign</button>
                     </form>
                 </td>
             </tr>', $w['store_id'], $w['numItems'], $opts, $w['store_id']);
     }
     $ret .= '</table>';
     return $ret;
 }
예제 #5
0
function getCustomerForm($orderID, $memNum = "0")
{
    global $FANNIE_OP_DB, $TRANS, $FANNIE_TRANS_DB, $canEdit;
    $dbc = FannieDB::get($FANNIE_OP_DB);
    if (empty($orderID)) {
        $orderID = createEmptyOrder();
    }
    $names = array();
    $pn = 1;
    $status_row = array('Type' => 'REG', 'status' => '');
    $table = "PendingSpecialOrder";
    $dbc = FannieDB::get($FANNIE_TRANS_DB);
    $orderModel = new SpecialOrdersModel($dbc);
    $orderModel->specialOrderID($orderID);
    $orderModel->load();
    $dbc = FannieDB::get($FANNIE_OP_DB);
    // detect member UPC entry
    if ($memNum > 9999999) {
        $p = $dbc->prepare_statement("SELECT card_no FROM memberCards WHERE upc=?");
        $r = $dbc->exec_statement($p, array(BarcodeLib::padUPC($memNum)));
        if ($dbc->num_rows($r) > 0) {
            $w = $dbc->fetch_row($r);
            $memNum = $w['card_no'];
        } else {
            $memNum = "";
        }
    }
    // look up member id if applicable
    if ($memNum === "0") {
        $findMem = $dbc->prepare_statement("SELECT card_no,voided FROM {$TRANS}{$table} WHERE order_id=?");
        $memR = $dbc->exec_statement($findMem, array($orderID));
        if ($dbc->num_rows($memR) > 0) {
            $memW = $dbc->fetch_row($memR);
            $memNum = $memW['card_no'];
            $pn = $memW['voided'];
        }
    } else {
        if ($memNum == "") {
            $p = $dbc->prepare_statement("UPDATE {$TRANS}PendingSpecialOrder SET card_no=?,voided=0\n            WHERE order_id=?");
            $r = $dbc->exec_statement($p, array(0, $orderID));
        } else {
            $p = $dbc->prepare_statement("UPDATE {$TRANS}PendingSpecialOrder SET card_no=?\n            WHERE order_id=?");
            $r = $dbc->exec_statement($p, array($memNum, $orderID));
            // clear contact fields if member number changed
            // so that defaults are reloaded from meminfo
            $dbc = FannieDB::get($FANNIE_TRANS_DB);
            $orderModel->street('');
            $orderModel->phone('');
            $orderModel->save();
            $orderModel->specialOrderID($orderID);
            $orderModel->load();
            $dbc = FannieDB::get($FANNIE_OP_DB);
            if ($dbc->table_exists('SpecialOrderContact')) {
                $p = $dbc->prepare_statement("UPDATE {$TRANS}SpecialOrderContact SET\n                street='',phone='' WHERE card_no=?");
                $r = $dbc->exec_statement($p, array($orderID));
            }
            // look up personnum, correct if it hasn't been set
            $pQ = $dbc->prepare_statement("SELECT voided FROM {$TRANS}PendingSpecialOrder\n            WHERE order_id=?");
            $pR = $dbc->exec_statement($pQ, array($orderID));
            $pnW = $dbc->fetch_row($pR);
            $pn = $pnW['voided'];
            if ($pn == 0) {
                $pn = 1;
                $upP = $dbc->prepare_statement("UPDATE {$TRANS}PendingSpecialOrder SET voided=?\n                WHERE order_id=?");
                $upR = $dbc->exec_statement($upP, array($pn, $orderID));
            }
        }
    }
    if ($memNum != 0) {
        $namesP = $dbc->prepare_statement("SELECT personNum,FirstName,LastName FROM custdata\n            WHERE CardNo=? ORDER BY personNum");
        $namesR = $dbc->exec_statement($namesP, array($memNum));
        while ($namesW = $dbc->fetch_row($namesR)) {
            $names[$namesW['personNum']] = array($namesW['FirstName'], $namesW['LastName']);
        }
        // load member contact info into order
        // on first go so it can be edited separately
        $current_street = $orderModel->street();
        $current_phone = $orderModel->phone();
        if (empty($current_street) && empty($current_phone)) {
            $contactQ = $dbc->prepare_statement("SELECT street,city,state,zip,phone,email_1,email_2\n                    FROM meminfo WHERE card_no=?");
            $contactR = $dbc->exec_statement($contactQ, array($memNum));
            if ($dbc->num_rows($contactR) > 0) {
                $contact_row = $dbc->fetch_row($contactR);
                $dbc = FannieDB::get($FANNIE_TRANS_DB);
                $orderModel->street($contact_row['street']);
                $orderModel->city($contact_row['city']);
                $orderModel->state($contact_row['state']);
                $orderModel->zip($contact_row['zip']);
                $orderModel->phone($contact_row['phone']);
                $orderModel->altPhone($contact_row['email_2']);
                $orderModel->email($contact_row['email_1']);
                $orderModel->save();
                $orderModel->specialOrderID($orderID);
                $orderModel->load();
                $dbc = FannieDB::get($FANNIE_OP_DB);
                if ($dbc->table_exists($TRANS . 'SpecialOrderContact')) {
                    $upP = $dbc->prepare_statement("UPDATE {$TRANS}SpecialOrderContact SET street=?,city=?,state=?,zip=?,\n                            phone=?,email_1=?,email_2=? WHERE card_no=?");
                    $upR = $dbc->exec_statement($upP, array($contact_row['street'], $contact_row['city'], $contact_row['state'], $contact_row['zip'], $contact_row['phone'], $contact_row['email_1'], $contact_row['email_2'], $orderID));
                }
            }
        }
        $statusQ = $dbc->prepare_statement("SELECT Type FROM custdata WHERE CardNo=?");
        $statusR = $dbc->exec_statement($statusQ, array($memNum));
        $status_row = $dbc->fetch_row($statusR);
        if ($status_row['Type'] == 'INACT') {
            $status_row['status'] = 'Inactive';
        } elseif ($status_row['Type'] == 'INACT2') {
            $status_row['status'] = 'Inactive';
        } elseif ($status_row['Type'] == 'TERM') {
            $status_row['status'] = 'Terminated';
        }
    }
    $q = $dbc->prepare_statement("SELECT entry_date FROM {$TRANS}SpecialOrderHistory \n            WHERE order_id=? AND entry_type='CONFIRMED'");
    $r = $dbc->exec_statement($q, array($orderID));
    $confirm_date = "";
    if ($dbc->num_rows($r) > 0) {
        $confirm_date = array_pop($dbc->fetch_row($r));
    }
    $callback = 2;
    $user = '******';
    $orderDate = "";
    $q = $dbc->prepare_statement("SELECT datetime,numflag,mixMatch FROM \n            {$TRANS}PendingSpecialOrder WHERE order_id=? AND trans_id=0");
    $r = $dbc->exec_statement($q, array($orderID));
    if ($dbc->num_rows($r) > 0) {
        list($orderDate, $callback, $user) = $dbc->fetch_row($r);
    }
    $status = array(0 => "New, No Call", 3 => "New, Call", 1 => "Called/waiting", 2 => "Pending", 4 => "Placed", 5 => "Arrived");
    $order_status = $orderModel->statusFlag();
    $ret = "";
    $ret .= '<table width="95%" cellpadding="4" cellspacing=4" border="0">';
    $ret .= '<tr><td align="left" valign="top">';
    $ret .= sprintf('<input type="hidden" id="orderID" value="%d" />', $orderID);
    $ret .= sprintf('<b>Owner Number</b>: <input type="text" size="6"
            id="memNum" value="%s" onchange="memNumEntered();"
            />', $memNum == 0 ? '' : $memNum);
    $ret .= '<br />';
    $ret .= '<b>Owner</b>: ' . ($status_row['Type'] == 'PC' ? 'Yes' : 'No');
    $ret .= sprintf('<input type="hidden" id="isMember" value="%s" />', $status_row['Type']);
    $ret .= '<br />';
    if (!empty($status_row['status'])) {
        $ret .= '<b>Account status</b>: ' . $status_row['status'];
        $ret .= '<br />';
    }
    $ret .= '</td>';
    $ret .= '<td valign="top">';
    if ($canEdit) {
        $ret .= '<b>Status</b>: ';
        $ret .= sprintf('<select id="orderStatus" onchange="updateStatus(%d, this.value);">', $orderID);
        foreach ($status as $k => $v) {
            $ret .= sprintf('<option %s value="%d">%s</option>', $k == $order_status ? 'selected' : '', $k, $v);
        }
        $ret .= '</select><p />';
    }
    $ret .= '<b>Store</b>: ';
    $ret .= sprintf('<select onchange="updateStore(%d, this.value);">', $orderID);
    $stores = new StoresModel($dbc);
    $ret .= '<option value="0">Choose...</option>';
    $ret .= $stores->toOptions($orderModel->storeID());
    $ret .= '</select>';
    $ret .= '</td>';
    $ret .= '<td align="right" valign="top">';
    $ret .= "<input type=\"submit\" value=\"Done\"\n        onclick=\"validateAndHome();return false;\" />";
    $username = checkLogin();
    $prints = array();
    $cachepath = sys_get_temp_dir() . "/ordercache/";
    if (file_exists("{$cachepath}{$username}.prints")) {
        $prints = unserialize(file_get_contents("{$cachepath}{$username}.prints"));
    } else {
        $fp = fopen("{$cachepath}{$username}.prints", 'w');
        fwrite($fp, serialize($prints));
        fclose($fp);
    }
    $ret .= sprintf('<br />Queue tags <input type="checkbox" %s onclick="togglePrint(\'%s\',%d);" />', isset($prints[$orderID]) ? 'checked' : '', $username, $orderID);
    $ret .= sprintf('<br /><a href="tagpdf.php?oids[]=%d" target="_tags%d">Print Now</a>', $orderID, $orderID);
    $ret .= '</td></tr></table>';
    $extra = "";
    $extra .= '<table width="95%" cellpadding="4" cellspacing=4" border="0">';
    $extra .= '<tr><td align="left" valign="top">';
    $extra .= "<b>Taken by</b>: " . $user . "<br />";
    $extra .= "<b>On</b>: " . date("M j, Y g:ia", strtotime($orderDate)) . "<br />";
    $extra .= '</td><td align="right" valign="top">';
    $extra .= '<b>Call to Confirm</b>: ';
    $extra .= '<select id="ctcselect" onchange="saveCtC(this.value,' . $orderID . ');">';
    $extra .= '<option value="2"></option>';
    if ($callback == 1) {
        $extra .= '<option value="1" selected>Yes</option>';
        $extra .= '<option value="0">No</option>';
    } else {
        if ($callback == 0) {
            $extra .= '<option value="1">Yes</option>';
            $extra .= '<option value="0" selected>No</option>';
        } else {
            $extra .= '<option value="1">Yes</option>';
            $extra .= '<option value="0">No</option>';
        }
    }
    $extra .= '</select><br />';
    $extra .= '<span id="confDateSpan">' . (!empty($confirm_date) ? 'Confirmed ' . $confirm_date : 'Not confirmed') . "</span> ";
    $extra .= '<input type="checkbox" onclick="saveConfirmDate(this.checked,' . $orderID . ');" ';
    if (!empty($confirm_date)) {
        $extra .= "checked";
    }
    $extra .= ' /><br />';
    $extra .= "<input type=\"submit\" value=\"Done\"\n        onclick=\"validateAndHome();return false;\" />";
    $extra .= '</td></tr></table>';
    $ret .= '<table cellspacing="0" cellpadding="4" border="1">';
    // names
    if (empty($names)) {
        $ret .= sprintf('<tr><th>First Name</th><td>
                <input type="text" id="t_firstName" 
                value="%s" onchange="saveFN(%d,this.value);" 
                /></td>', $orderModel->firstName(), $orderID);
        $ret .= sprintf('<th>Last Name</th><td><input 
                type="text" id="t_lastName" value="%s"
                onchange="saveLN(%d,this.value);" /></td>', $orderModel->lastName(), $orderID);
    } else {
        $ret .= sprintf('<tr><th>Name</th><td colspan="2"><select id="s_personNum"
            onchange="savePN(%d,this.value);">', $orderID);
        foreach ($names as $p => $n) {
            $ret .= sprintf('<option value="%d" %s>%s %s</option>', $p, $p == $pn ? 'selected' : '', $n[0], $n[1]);
        }
        $ret .= '</select></td>';
        $ret .= '<td>&nbsp;</td>';
    }
    $ret .= sprintf('<td colspan="4">For Department:
        <select id="nDept" onchange="saveNoteDept(%d,$(this).val());">
        <option value="0">Choose...</option>', $orderID);
    $sQ = $dbc->prepare_statement("select superID,super_name from MasterSuperDepts\n        where superID > 0\n        group by superID,super_name\n        order by super_name");
    $sR = $dbc->exec_statement($sQ);
    while ($sW = $dbc->fetch_row($sR)) {
        $ret .= sprintf('<option value="%d" %s>%s</option>', $sW['superID'], $sW['superID'] == $orderModel->noteSuperID() ? 'selected' : '', $sW['super_name']);
    }
    $ret .= "</select></td></tr>";
    // address
    $street = $orderModel->street();
    $street2 = '';
    if (strstr($street, "\n")) {
        list($street, $street2) = explode("\n", $street, 2);
    }
    $ret .= sprintf('<tr><th>Address</th><td><input type="text" id="t_addr1" value="%s" 
        onchange="saveAddr(%d);" /></td><th>E-mail</th><td><input type="text" 
        id="t_email" value="%s" onchange="saveEmail(%d,this.value);" /></td>
        <td rowspan="2" colspan="4">
        <textarea id="nText" rows="5" cols="25" 
        onchange="saveText(%d,this.value);">%s</textarea>
        </td></tr>
        <tr><th>Addr (2)</th><td><input type="text" id="t_addr2" value="%s" 
        onchange="saveAddr(%d);" /></td><th>City</th><td><input type="text" id="t_city" 
        value="%s" size="10" onchange="saveCity(%d,this.value);" /></td></tr>
        <tr><th>Phone</th><td><input 
        type="text" id="t_ph1" value="%s" onchange="savePh(%d,this.value);" /></td>
        <th>Alt. Phone</th><td><input type="text" id="t_ph2" value="%s" 
        onchange="savePh2(%d,this.value);" /></td>
        <th>State</th>
        <td><input type="text" id="t_state" value="%s" size="2" onchange="saveState(%d,this.value);"
        /></td><th>Zip</th><td><input type="text" id="t_zip" value="%s" size="5" 
        onchange="saveZip(%d,this.value); " /></td></tr>', $street, $orderID, $orderModel->email(), $orderID, $orderID, $orderModel->notes(), $street2, $orderID, $orderModel->city(), $orderID, $orderModel->phone(), $orderID, $orderModel->altPhone(), $orderID, $orderModel->state(), $orderID, $orderModel->zip(), $orderID);
    $ret .= '</table>';
    return $ret . "`" . $extra;
}
예제 #6
0
 public function run()
 {
     global $FANNIE_OP_DB, $FANNIE_SERVER, $FANNIE_TRANS_DB;
     $dbc = FannieDB::get($FANNIE_OP_DB);
     $local_dtrans = $FANNIE_TRANS_DB . $dbc->sep() . 'dtransactions';
     $max1 = $dbc->prepare('
                 SELECT MAX(store_row_id) AS done
                 FROM ' . $local_dtrans . '
                 WHERE store_id=?
             ');
     $max2 = $dbc->prepare('
                 SELECT MAX(store_row_id) AS done
                 FROM ' . $FANNIE_TRANS_DB . $dbc->sep() . 'transarchive
                 WHERE store_id=?
             ');
     $stores = new StoresModel($dbc);
     foreach ($stores->find() as $store) {
         if ($store->dbHost() == $FANNIE_SERVER) {
             // that's me! just continue.
             continue;
         } else {
             if ($store->pull() == 0) {
                 // configured not to pull from this store
                 continue;
             }
         }
         $remoteID = $store->storeID();
         $lowerBound = 0;
         $dtransMax = $dbc->execute($max1, array($remoteID));
         if ($dtransMax === false) {
             $this->cronMsg('Polling problem: cannot lookup info in dtransactions', FannieLogger::WARNING);
             continue;
         } else {
             if ($dbc->num_rows($dtransMax) > 0) {
                 $row = $dbc->fetch_row($dtransMax);
                 $lowerBound = $row['done'];
             }
         }
         if ($lowerBound == 0) {
             $transarchiveMax = $dbc->execute($max2, array($remoteID));
             if ($transarchiveMax === false) {
                 $this->cronMsg('Polling problem: cannot lookup info in transarchive', FannieLogger::WARNING);
                 continue;
             } else {
                 if ($dbc->num_rows($transarchiveMax) > 0) {
                     $row = $dbc->fetch_row($transarchiveMax);
                     $lowerBound = $row['done'];
                 }
             }
         }
         $connect = $dbc->add_connection($store->dbHost(), $store->dbDriver(), $store->transDB(), $store->dbUser(), $store->dbPassword());
         $columns = $dbc->getMatchingColumns($local_dtrans, $FANNIE_OP_DB, 'dtransactions', $store->transDB());
         $selectQ = 'SELECT ' . $columns . '
                     FROM dtransactions
                     WHERE store_id = ' . (int) $store->storeID() . '
                         AND store_row_id > ' . (int) $lowerBound;
         $insertQ = 'INSERT INTO ' . $local_dtrans . ' (' . $columns . ')';
         // note:
         // using operational DB on the local side
         // and transaction DB on the remote side
         // reduces chances of a name collision
         $dbc->transfer($store->transDB(), $selectQ, $FANNIE_OP_DB, $insertQ);
     }
 }
예제 #7
0
    public function showEditForm($upc, $display_mode = 1, $expand_mode = 1)
    {
        $FANNIE_PRODUCT_MODULES = FannieConfig::config('PRODUCT_MODULES', array());
        $upc = BarcodeLib::padUPC($upc);
        $trimmed = ltrim($upc, '0');
        $barcode_type = '';
        if (strlen($trimmed) == '12') {
            // probably EAN-13 w/o check digi
            $barcode_type = 'EAN';
        } elseif (strlen($trimmed) == 11 && $trimmed[0] == '2') {
            // variable price UPC
            $barcode_type = 'Scale';
        } elseif (strlen($trimmed) <= 11 && strlen($trimmed) >= 6) {
            // probably UPC-A w/o check digit
            $barcode_type = 'UPC';
        } else {
            $barcode_type = 'PLU';
        }
        $ret = '<div id="BaseItemFieldset" class="panel panel-default">';
        $dbc = $this->db();
        $q = '
            SELECT
                p.description,
                p.pricemethod,
                p.normal_price,
                p.cost,
                CASE 
                    WHEN p.size IS NULL OR p.size=\'\' OR p.size=\'0\' AND v.size IS NOT NULL THEN v.size 
                    ELSE p.size 
                END AS size,
                p.unitofmeasure,
                p.modified,
                p.last_sold,
                p.special_price,
                p.end_date,
                p.subdept,
                p.department,
                p.tax,
                p.foodstamp,
                p.scale,
                p.qttyEnforced,
                p.discount,
                p.line_item_discountable,
                p.brand AS manufacturer,
                x.distributor,
                u.description as ldesc,
                p.default_vendor_id,
                v.units AS caseSize,
                v.sku,
                p.inUse,
                p.idEnforced,
                p.local,
                p.deposit,
                p.discounttype,
                p.wicable,
                p.store_id
            FROM products AS p 
                LEFT JOIN prodExtra AS x ON p.upc=x.upc 
                LEFT JOIN productUser AS u ON p.upc=u.upc 
                LEFT JOIN vendorItems AS v ON p.upc=v.upc AND p.default_vendor_id = v.vendorID
            WHERE p.upc=?';
        $p_def = $dbc->tableDefinition('products');
        if (!isset($p_def['last_sold'])) {
            $q = str_replace('p.last_sold', 'NULL as last_sold', $q);
        }
        $p = $dbc->prepare($q);
        $r = $dbc->exec_statement($p, array($upc));
        $store_model = new StoresModel($dbc);
        $store_model->hasOwnItems(1);
        $stores = array();
        foreach ($store_model->find('storeID') as $obj) {
            $stores[$obj->storeID()] = $obj;
        }
        $items = array();
        $rowItem = array();
        $prevUPC = False;
        $nextUPC = False;
        $likeCode = False;
        if ($dbc->num_rows($r) > 0) {
            //existing item
            while ($w = $dbc->fetch_row($r)) {
                $items[$w['store_id']] = $w;
                $rowItem = $w;
            }
            /**
              Lookup default vendor & normalize
            */
            $product = new ProductsModel($dbc);
            $product->upc($upc);
            $product->load();
            $vendor = new VendorsModel($dbc);
            $vendor->vendorID($product->default_vendor_id());
            if ($vendor->load()) {
                $rowItem['distributor'] = $vendor->vendorName();
            }
            /* find previous and next items in department */
            $pnP = $dbc->prepare_statement('SELECT upc FROM products WHERE department=? ORDER BY upc');
            $pnR = $dbc->exec_statement($pnP, array($product->department()));
            $passed_it = False;
            while ($pnW = $dbc->fetch_row($pnR)) {
                if (!$passed_it && $upc != $pnW[0]) {
                    $prevUPC = $pnW[0];
                } else {
                    if (!$passed_it && $upc == $pnW[0]) {
                        $passed_it = True;
                    } else {
                        if ($passed_it) {
                            $nextUPC = $pnW[0];
                            break;
                        }
                    }
                }
            }
            $lcP = $dbc->prepare_statement('SELECT likeCode FROM upcLike WHERE upc=?');
            $lcR = $dbc->exec_statement($lcP, array($upc));
            if ($dbc->num_rows($lcR) > 0) {
                $lcW = $dbc->fetch_row($lcR);
                $likeCode = $lcW['likeCode'];
            }
            if (FannieConfig::config('STORE_MODE') == 'HQ') {
                $default_id = array_keys($items);
                $default_id = $default_id[0];
                $default_item = $items[$default_id];
                foreach ($stores as $id => $info) {
                    if (!isset($items[$id])) {
                        $items[$id] = $default_item;
                    }
                }
            }
        } else {
            // default values for form fields
            $rowItem = array('description' => '', 'normal_price' => 0, 'pricemethod' => 0, 'size' => '', 'unitofmeasure' => '', 'modified' => '', 'ledesc' => '', 'manufacturer' => '', 'distributor' => '', 'default_vendor_id' => 0, 'department' => 0, 'subdept' => 0, 'tax' => 0, 'foodstamp' => 0, 'scale' => 0, 'qttyEnforced' => 0, 'discount' => 1, 'line_item_discountable' => 1, 'caseSize' => '', 'sku' => '', 'inUse' => 1, 'idEnforced' => 0, 'local' => 0, 'deposit' => 0, 'cost' => 0, 'discounttype' => 0, 'wicable' => 0);
            /**
              Check for entries in the vendorItems table to prepopulate
              fields for the new item
            */
            $vendorP = "\n                SELECT \n                    i.description,\n                    i.brand as manufacturer,\n                    i.cost,\n                    v.vendorName as distributor,\n                    d.margin,\n                    i.vendorID,\n                    i.srp,\n                    i.size,\n                    i.units,\n                    i.sku,\n                    i.vendorID as default_vendor_id\n                FROM vendorItems AS i \n                    LEFT JOIN vendors AS v ON i.vendorID=v.vendorID\n                    LEFT JOIN vendorDepartments AS d ON i.vendorDept=d.deptID AND d.vendorID=i.vendorID\n                WHERE i.upc=?";
            $args = array($upc);
            $vID = FormLib::get_form_value('vid', '');
            if ($vID !== '') {
                $vendorP .= ' AND i.vendorID=?';
                $args[] = $vID;
            }
            $vendorP .= ' ORDER BY i.vendorID';
            $vendorP = $dbc->prepare_statement($vendorP);
            $vendorR = $dbc->exec_statement($vendorP, $args);
            if ($dbc->num_rows($vendorR) > 0) {
                $v = $dbc->fetch_row($vendorR);
                $ret .= "<div><i>This product is in the " . $v['distributor'] . " catalog. Values have\n                    been filled in where possible</i></div>";
                $rowItem['description'] = $v['description'];
                $rowItem['manufacturer'] = $v['manufacturer'];
                $rowItem['cost'] = $v['cost'];
                $rowItem['distributor'] = $v['distributor'];
                $rowItem['normal_price'] = $v['srp'];
                $rowItem['default_vendor_id'] = $v['vendorID'];
                $rowItem['size'] = $v['size'];
                $rowItem['caseSize'] = $v['units'];
                $rowItem['sku'] = $v['sku'];
                while ($v = $dbc->fetch_row($vendorR)) {
                    $ret .= sprintf('This product is also in <a href="?searchupc=%s&vid=%d">%s</a><br />', $upc, $v['vendorID'], $v['distributor']);
                }
            }
            /**
              Look for items with a similar UPC to guess what
              department this item goes in. If found, use 
              department settings to fill in some defaults
            */
            $rowItem['department'] = 0;
            $search = substr($upc, 0, 12);
            $searchP = $dbc->prepare('SELECT department FROM products WHERE upc LIKE ?');
            while (strlen($search) >= 8) {
                $searchR = $dbc->execute($searchP, array($search . '%'));
                if ($dbc->numRows($searchR) > 0) {
                    $searchW = $dbc->fetchRow($searchR);
                    $rowItem['department'] = $searchW['department'];
                    break;
                }
                $search = substr($search, 0, strlen($search) - 1);
            }
            /**
              If no match is found, pick the most
              commonly used department
            */
            if ($rowItem['department'] == 0) {
                $commonQ = '
                    SELECT department,
                        COUNT(*)
                    FROM products
                    GROUP BY department
                    ORDER BY COUNT(*) DESC';
                $commonR = $dbc->query($commonQ);
                if ($commonR && $dbc->numRows($commonR)) {
                    $commonW = $dbc->fetchRow($commonR);
                    $rowItem['department'] = $commonW['department'];
                }
            }
            /**
              Get defaults for chosen department
            */
            $dmodel = new DepartmentsModel($dbc);
            $dmodel->dept_no($rowItem['department']);
            if ($dmodel->load()) {
                $rowItem['tax'] = $dmodel->dept_tax();
                $rowItem['foodstamp'] = $dmodel->dept_fs();
                $rowItem['discount'] = $dmodel->dept_discount();
            }
            foreach ($stores as $id => $obj) {
                $items[$id] = $rowItem;
            }
        }
        $ret .= '<div class="panel-heading">';
        if ($prevUPC) {
            $ret .= ' <a class="btn btn-default btn-xs small" href="ItemEditorPage.php?searchupc=' . $prevUPC . '"
                title="Previous item in this department">
                <span class="glyphicon glyphicon-chevron-left"></span></a> ';
        }
        $ret .= '<strong>UPC</strong>
                <span class="text-danger">';
        switch ($barcode_type) {
            case 'EAN':
            case 'UPC':
                $ret .= substr($upc, 0, 3) . '<a class="text-danger iframe fancyboxLink" href="../reports/ProductLine/ProductLineReport.php?prefix=' . substr($upc, 3, 5) . '" title="Product Line">' . '<strong>' . substr($upc, 3, 5) . '</strong>' . '</a>' . substr($upc, 8);
                break;
            case 'Scale':
                $ret .= substr($upc, 0, 3) . '<strong>' . substr($upc, 3, 4) . '</strong>' . substr($upc, 7);
                break;
            case 'PLU':
                $trimmed = ltrim($upc, '0');
                if (strlen($trimmed) < 13) {
                    $ret .= str_repeat('0', 13 - strlen($trimmed)) . '<strong>' . $trimmed . '</strong>';
                } else {
                    $ret .= $upc;
                }
                break;
            default:
                $ret .= $upc;
        }
        $ret .= '</span>';
        $ret .= '<input type="hidden" id="upc" name="upc" value="' . $upc . '" />';
        if ($nextUPC) {
            $ret .= ' <a class="btn btn-default btn-xs small" href="ItemEditorPage.php?searchupc=' . $nextUPC . '"
                title="Next item in this department">
                <span class="glyphicon glyphicon-chevron-right"></span></a>';
        }
        $ret .= ' <label style="color:darkmagenta;">Modified</label>
                <span style="color:darkmagenta;">' . $rowItem['modified'] . '</span>';
        $ret .= ' | <label style="color:darkmagenta;">Last Sold</label>
                <span style="color:darkmagenta;">' . (empty($rowItem['last_sold']) ? 'n/a' : $rowItem['last_sold']) . '</span>';
        $ret .= '</div>';
        // end panel-heading
        $ret .= '<div class="panel-body">';
        $new_item = false;
        if ($dbc->num_rows($r) == 0) {
            // new item
            $ret .= "<div class=\"alert alert-warning\">Item not found.  You are creating a new one.</div>";
            $new_item = true;
        }
        $nav_tabs = '<ul id="store-tabs" class="nav nav-tabs small" role="tablist">';
        $ret .= '{{nav_tabs}}<div class="tab-content">';
        $active_tab = true;
        foreach ($items as $store_id => $rowItem) {
            $tabID = 'store-tab-' . $store_id;
            $store_description = 'n/a';
            if (isset($stores[$store_id])) {
                $store_description = $stores[$store_id]->description();
            }
            $nav_tabs .= '<li role="presentation" ' . ($active_tab ? 'class="active"' : '') . '>' . '<a href="#' . $tabID . '" aria-controls="' . $tabID . '" ' . 'onclick="$(\'.tab-content .chosen-select:visible\').chosen();"' . 'role="tab" data-toggle="tab">' . $store_description . '</a></li>';
            $ret .= '<div role="tabpanel" class="tab-pane' . ($active_tab ? ' active' : '') . '"
                id="' . $tabID . '">';
            $ret .= '<input type="hidden" class="store-id" name="store_id[]" value="' . $store_id . '" />';
            $ret .= '<table class="table table-bordered">';
            $limit = 30 - strlen(isset($rowItem['description']) ? $rowItem['description'] : '');
            $ret .= <<<HTML
<tr>
    <th class="text-right">Description</th>
    <td colspan="5">
        <div class="input-group" style="width:100%;">
            <input type="text" maxlength="30" class="form-control syncable-input" required
                name="descript[]" id="descript" value="{{description}}"
                onkeyup="\$(this).next().html(30-(this.value.length));" />
            <span class="input-group-addon">{{limit}}</span>
        </div>
    </td>
    <th class="text-right">Cost</th>
    <td>
        <div class="input-group">
            <span class="input-group-addon">\$</span>
            <input type="text" id="cost{{store_id}}" name="cost[]" 
                class="form-control price-field cost-input syncable-input"
                value="{{cost}}" data-store-id="{{store_id}}"
                onkeydown="if (typeof nosubmit == 'function') nosubmit(event);"
                onkeyup="if (typeof nosubmit == 'function') nosubmit(event);" 
                onchange="\$('.default_vendor_cost').val(this.value);"
            />
        </div>
    </td>
    <th class="text-right">Price</th>
    <td>
        <div class="input-group">
            <span class="input-group-addon">\$</span>
            <input type="text" id="price{{store_id}}" name="price[]" 
                class="form-control price-field price-input syncable-input"
                data-store-id="{{store_id}}"
                required value="{{normal_price}}" />
        </div>
    </td>
</tr>
HTML;
            $ret = str_replace('{{description}}', $rowItem['description'], $ret);
            $ret = str_replace('{{limit}}', $limit, $ret);
            $ret = str_replace('{{cost}}', sprintf('%.2f', $rowItem['cost']), $ret);
            $ret = str_replace('{{normal_price}}', sprintf('%.2f', $rowItem['normal_price']), $ret);
            // no need to display this field twice
            if (!isset($FANNIE_PRODUCT_MODULES['ProdUserModule'])) {
                $ret .= '
                    <tr>
                        <th>Long Desc.</th>
                        <td colspan="5">
                        <input type="text" size="60" name="puser_description" maxlength="255"
                            ' . (!$active_tab ? ' disabled ' : '') . '
                            value="' . $rowItem['ldesc'] . '" class="form-control" />
                        </td>
                    </tr>';
            }
            $ret .= '
                <tr>
                    <th class="text-right">Brand</th>
                    <td colspan="5">
                        <input type="text" name="manufacturer[]" 
                            class="form-control input-sm brand-field syncable-input"
                            value="' . $rowItem['manufacturer'] . '" />
                    </td>';
            /**
              Check products.default_vendor_id to see if it is a 
              valid reference to the vendors table
            */
            $normalizedVendorID = false;
            if (isset($rowItem['default_vendor_id']) && $rowItem['default_vendor_id'] != 0) {
                $normalizedVendor = new VendorsModel($dbc);
                $normalizedVendor->vendorID($rowItem['default_vendor_id']);
                if ($normalizedVendor->load()) {
                    $normalizedVendorID = $normalizedVendor->vendorID();
                }
            }
            /**
              Use a <select> box if the current vendor corresponds to a valid
              entry OR if no vendor entry exists. Only allow free text
              if it's already in place
            */
            $ret .= ' <th class="text-right">Vendor</th> ';
            if ($normalizedVendorID || empty($rowItem['distributor'])) {
                $ret .= '<td colspan="3" class="form-inline"><select name="distributor[]" 
                            class="chosen-select form-control vendor_field syncable-input"
                            onchange="vendorChanged(this.value);">';
                $ret .= '<option value="0">Select a vendor</option>';
                $vendors = new VendorsModel($dbc);
                foreach ($vendors->find('vendorName') as $v) {
                    $ret .= sprintf('<option %s>%s</option>', $v->vendorID() == $normalizedVendorID ? 'selected' : '', $v->vendorName());
                }
                $ret .= '</select>';
            } else {
                $ret .= "<td colspan=\"3\"><input type=text name=distributor[] size=8 value=\"" . (isset($rowItem['distributor']) ? $rowItem['distributor'] : "") . "\" class=\"form-control vendor-field syncable-input\" />";
            }
            $ret .= ' <button type="button" 
                        title="Create new vendor"
                        class="btn btn-default btn-sm newVendorButton">
                        <span class="glyphicon glyphicon-plus"></span></button>';
            $ret .= '</td></tr>';
            // end row
            if (isset($rowItem['discounttype']) && $rowItem['discounttype'] != 0) {
                /* show sale info */
                $batchP = $dbc->prepare_statement("\n                    SELECT b.batchName, \n                        b.batchID \n                    FROM batches AS b \n                        LEFT JOIN batchList as l on b.batchID=l.batchID \n                    WHERE '" . date('Y-m-d') . "' BETWEEN b.startDate AND b.endDate \n                        AND (l.upc=? OR l.upc=?)");
                $batchR = $dbc->exec_statement($batchP, array($upc, 'LC' . $likeCode));
                $batch = array('batchID' => 0, 'batchName' => "Unknown");
                if ($dbc->num_rows($batchR) > 0) {
                    $batch = $dbc->fetch_row($batchR);
                }
                $ret .= '<td class="alert-success" colspan="8">';
                $ret .= sprintf("<strong>Sale Price:</strong>\n                    %.2f (<em>Batch: <a href=\"%sbatches/newbatch/EditBatchPage.php?id=%d\">%s</a></em>)", $rowItem['special_price'], FannieConfig::config('URL'), $batch['batchID'], $batch['batchName']);
                list($date, $time) = explode(' ', $rowItem['end_date']);
                $ret .= "<strong>End Date:</strong>\n                        {$date} \n                        (<a href=\"EndItemSale.php?id={$upc}\">Unsale Now</a>)";
                $ret .= '</td>';
            }
            $supers = array();
            $depts = array();
            $subs = array();
            $range_limit = FannieAuth::validateUserLimited('pricechange');
            $deptQ = '
                SELECT dept_no,
                    dept_name,
                    subdept_no,
                    subdept_name,
                    s.dept_ID,
                    MIN(m.superID) AS superID
                FROM departments AS d
                    LEFT JOIN subdepts AS s ON d.dept_no=s.dept_ID
                    LEFT JOIN superdepts AS m ON d.dept_no=m.dept_ID ';
            if (is_array($range_limit) && count($range_limit) == 2) {
                $deptQ .= ' WHERE m.superID BETWEEN ? AND ? ';
            } else {
                $range_limit = array();
            }
            $deptQ .= '
                GROUP BY d.dept_no,
                    d.dept_name,
                    s.subdept_no,
                    s.subdept_name,
                s.dept_ID
                ORDER BY d.dept_no, s.subdept_name';
            $p = $dbc->prepare($deptQ);
            $r = $dbc->execute($p, $range_limit);
            $superID = '';
            while ($w = $dbc->fetch_row($r)) {
                if (!isset($depts[$w['dept_no']])) {
                    $depts[$w['dept_no']] = $w['dept_name'];
                }
                if ($w['dept_no'] == $rowItem['department']) {
                    $superID = $w['superID'];
                }
                if (!isset($supers[$w['superID']])) {
                    $supers[$w['superID']] = array();
                }
                $supers[$w['superID']][] = $w['dept_no'];
                if ($w['subdept_no'] == '') {
                    continue;
                }
                if (!isset($subs[$w['dept_ID']])) {
                    $subs[$w['dept_ID']] = '';
                }
                $subs[$w['dept_ID']] .= sprintf('<option %s value="%d">%d %s</option>', $w['subdept_no'] == $rowItem['subdept'] ? 'selected' : '', $w['subdept_no'], $w['subdept_no'], $w['subdept_name']);
            }
            $ret .= '<tr>
                <th class="text-right">Dept</th>
                <td colspan="7" class="form-inline">
                <select id="super-dept{{store_id}}" name="super[]"
                    class="form-control chosen-select syncable-input" 
                    onchange="chainSuperDepartment(\'../ws/\', this.value, {dept_start:\'#department{{store_id}}\', callback:function(){$(\'#department{{store_id}}\').trigger(\'chosen:updated\');baseItemChainSubs({{store_id}});}});">';
            $names = new SuperDeptNamesModel($dbc);
            if (is_array($range_limit) && count($range_limit) == 2) {
                $names->superID($range_limit[0], '>=');
                $names->superID($range_limit[1], '<=');
            }
            foreach ($names->find('superID') as $obj) {
                $ret .= sprintf('<option %s value="%d">%s</option>', $obj->superID() == $superID ? 'selected' : '', $obj->superID(), $obj->super_name());
            }
            $ret .= '</select>
                <select name="department[]" id="department{{store_id}}" 
                    class="form-control chosen-select syncable-input" 
                    onchange="baseItemChainSubs({{store_id}});">';
            foreach ($depts as $id => $name) {
                if (is_numeric($superID) && is_array($supers[$superID])) {
                    if (!in_array($id, $supers[$superID]) && $id != $rowItem['department']) {
                        continue;
                    }
                }
                $ret .= sprintf('<option %s value="%d">%d %s</option>', $id == $rowItem['department'] ? 'selected' : '', $id, $id, $name);
            }
            $ret .= '</select>';
            $jsVendorID = $rowItem['default_vendor_id'] > 0 ? $rowItem['default_vendor_id'] : 'no-vendor';
            $ret .= '<select name="subdept[]" id="subdept{{store_id}}" 
                class="form-control chosen-select syncable-input">';
            $ret .= isset($subs[$rowItem['department']]) ? $subs[$rowItem['department']] : '<option value="0">None</option>';
            $ret .= '</select>';
            $ret .= '</td>
                <th class="small text-right">SKU</th>
                <td colspan="2">
                    <input type="text" name="vendorSKU" class="form-control input-sm"
                        value="' . $rowItem['sku'] . '" 
                        onchange="$(\'#vsku' . $jsVendorID . '\').val(this.value);" 
                        ' . ($jsVendorID == 'no-vendor' || !$active_tab ? 'disabled' : '') . '
                        id="product-sku-field" />
                </td>
                </tr>';
            $taxQ = $dbc->prepare_statement('SELECT id,description FROM taxrates ORDER BY id');
            $taxR = $dbc->exec_statement($taxQ);
            $rates = array();
            while ($taxW = $dbc->fetch_row($taxR)) {
                array_push($rates, array($taxW[0], $taxW[1]));
            }
            array_push($rates, array("0", "NoTax"));
            $ret .= '<tr>
                <th class="small text-right">Tax</th>
                <td>
                <select name="tax[]" id="tax{{store_id}}" 
                    class="form-control input-sm syncable-input">';
            foreach ($rates as $r) {
                $ret .= sprintf('<option %s value="%d">%s</option>', isset($rowItem['tax']) && $rowItem['tax'] == $r[0] ? 'selected' : '', $r[0], $r[1]);
            }
            $ret .= '</select></td>';
            $ret .= '<td colspan="4" class="small">
                <label>FS
                <input type="checkbox" value="{{store_id}}" name="FS[]" id="FS{{store_id}}"
                    class="syncable-checkbox"
                    ' . ($rowItem['foodstamp'] == 1 ? 'checked' : '') . ' />
                </label>
                &nbsp;&nbsp;&nbsp;&nbsp;
                <label>Scale
                <input type="checkbox" value="{{store_id}}" name="Scale[]" 
                    class="scale-checkbox syncable-checkbox"
                    ' . ($rowItem['scale'] == 1 ? 'checked' : '') . ' />
                </label>
                &nbsp;&nbsp;&nbsp;&nbsp;
                <label>QtyFrc
                <input type="checkbox" value="{{store_id}}" name="QtyFrc[]" 
                    class="qty-checkbox syncable-checkbox"
                    ' . ($rowItem['qttyEnforced'] == 1 ? 'checked' : '') . ' />
                </label>
                &nbsp;&nbsp;&nbsp;&nbsp;
                <label>WIC
                <input type="checkbox" value="{{store_id}}" name="prod-wicable[]" 
                    class="prod-wicable-checkbox syncable-checkbox"
                    ' . ($rowItem['wicable'] == 1 ? 'checked' : '') . '  />
                </label>
                &nbsp;&nbsp;&nbsp;&nbsp;
                <label>InUse
                <input type="checkbox" value="{{store_id}}" name="prod-in-use[]" 
                    class="in-use-checkbox syncable-checkbox"
                    ' . ($rowItem['inUse'] == 1 ? 'checked' : '') . ' 
                    onchange="$(\'#extra-in-use-checkbox\').prop(\'checked\', $(this).prop(\'checked\'));" />
                </label>
                </td>
                <th class="small text-right">Discount</th>
                <td class="col-sm-1">
                <select id="discount-select{{store_id}}" name="discount[]" 
                    class="form-control input-sm syncable-input">';
            $disc_opts = array(0 => 'No', 1 => 'Yes', 2 => 'Trans Only', 3 => 'Line Only');
            if ($rowItem['discount'] == 1 && $rowItem['line_item_discountable'] == 1) {
                $rowItem['discount'] = 1;
            } elseif ($rowItem['discount'] == 1 && $rowItem['line_item_discountable'] == 0) {
                $rowItem['discount'] = 2;
            } elseif ($rowItem['discount'] == 0 && $rowItem['line_item_discountable'] == 1) {
                $rowItem['discount'] = 3;
            }
            foreach ($disc_opts as $id => $val) {
                $ret .= sprintf('<option %s value="%d">%s</option>', $id == $rowItem['discount'] ? 'selected' : '', $id, $val);
            }
            $ret .= '</select></td>
                <th class="small text-right">Deposit</th>
                <td colspan="2">
                    <input type="text" name="deposit-upc[]" class="form-control input-sm syncable-input"
                        value="' . ($rowItem['deposit'] != 0 ? $rowItem['deposit'] : '') . '" 
                        placeholder="Deposit Item PLU/UPC"
                        onchange="$(\'#deposit\').val(this.value);" />
                </td>
                </tr>';
            $ret .= '
                <tr>
                    <th class="small text-right">Case Size</th>
                    <td class="col-sm-1">
                        <input type="text" name="caseSize" class="form-control input-sm"
                            id="product-case-size"
                            value="' . $rowItem['caseSize'] . '" 
                            onchange="$(\'#vunits' . $jsVendorID . '\').val(this.value);" 
                            ' . ($jsVendorID == 'no-vendor' || !$active_tab ? 'disabled' : '') . ' />
                    </td>
                    <th class="small text-right">Pack Size</th>
                    <td class="col-sm-1">
                        <input type="text" name="size[]" 
                            class="form-control input-sm product-pack-size syncable-input"
                            value="' . $rowItem['size'] . '" 
                            onchange="$(\'#vsize' . $jsVendorID . '\').val(this.value);" />
                    </td>
                    <th class="small text-right">Unit of measure</th>
                    <td class="col-sm-1">
                        <input type="text" name="unitm[]" 
                            class="form-control input-sm unit-of-measure syncable-input"
                            value="' . $rowItem['unitofmeasure'] . '" />
                    </td>
                    <th class="small text-right">Age Req</th>
                    <td class="col-sm-1">
                        <select name="id-enforced[]" class="form-control input-sm id-enforced syncable-input"
                            onchange="$(\'#idReq\').val(this.value);">';
            $ages = array('n/a' => 0, 18 => 18, 21 => 21);
            foreach ($ages as $label => $age) {
                $ret .= sprintf('<option %s value="%d">%s</option>', $age == $rowItem['idEnforced'] ? 'selected' : '', $age, $label);
            }
            $ret .= '</select>
                </td>
                <th class="small text-right">Local</th>
                <td>
                    <select name="prod-local[]" class="form-control input-sm prod-local syncable-input"
                        onchange="$(\'#local-origin-id\').val(this.value);">';
            $local_opts = array(0 => 'No');
            $origin = new OriginsModel($dbc);
            $local_opts = array_merge($local_opts, $origin->getLocalOrigins());
            if (count($local_opts) == 1) {
                $local_opts[1] = 'Yes';
                // generic local if no origins defined
            }
            foreach ($local_opts as $id => $val) {
                $ret .= sprintf('<option value="%d" %s>%s</option>', $id, $id == $rowItem['local'] ? 'selected' : '', $val);
            }
            $ret .= '</select>
                    </td>
                    </tr>
                </div>';
            $ret .= '</table>';
            $ret .= '</div>';
            $ret = str_replace('{{store_id}}', $store_id, $ret);
            $active_tab = false;
            if (FannieConfig::config('STORE_MODE') != 'HQ') {
                break;
            }
        }
        $ret .= '</div>';
        // sync button will copy current tab values to all other store tabs
        if (!$new_item && FannieConfig::config('STORE_MODE') == 'HQ') {
            $nav_tabs .= '<li><label title="Apply update to all stores">
                <input type="checkbox" id="store-sync" checked /> Sync</label></li>';
        }
        $nav_tabs .= '</ul>';
        // only show the store tabs in HQ mode
        if (FannieConfig::config('STORE_MODE') == 'HQ') {
            $ret = str_replace('{{nav_tabs}}', $nav_tabs, $ret);
        } else {
            $ret = str_replace('{{nav_tabs}}', '', $ret);
        }
        $ret .= <<<HTML
<div id="newVendorDialog" title="Create new Vendor" class="collapse">
    <fieldset>
        <label for="newVendorName">Vendor Name</label>
        <input type="text" name="newVendorName" id="newVendorName" class="form-control" />
    </fieldset>
</div>
HTML;
        $ret .= '</div>';
        // end panel-body
        $ret .= '</div>';
        // end panel
        return $ret;
    }
예제 #8
0
파일: FormLib.php 프로젝트: phpsmith/IS4C
 /**
   Get <select> box for the store ID
   @param $field_name [string] select.name (default 'store')
   @return keyed [array]
     - html => [string] select box
     - names => [array] store names
 */
 public static function storePicker($field_name = 'store')
 {
     $op_db = FannieConfig::config('OP_DB');
     $dbc = FannieDB::getReadOnly($op_db);
     $stores = new StoresModel($dbc);
     $current = FormLib::get($field_name, 0);
     $labels = array(0 => _('All Stores'));
     $ret = '<select name="' . $field_name . '" class="form-control">';
     $ret .= '<option value="0">' . $labels[0] . '</option>';
     foreach ($stores->find('storeID') as $store) {
         $ret .= sprintf('<option %s value="%d">%s</option>', $store->storeID() == $current ? 'selected' : '', $store->storeID(), $store->description());
         $labels[$store->storeID()] = $store->description();
     }
     $ret .= '</select>';
     return array('html' => $ret, 'names' => $labels);
 }
예제 #9
0
    function body_content()
    {
        global $FANNIE_OP_DB;
        $dbc = FannieDB::get($FANNIE_OP_DB);
        $ret = '';
        if (!empty($this->messages)) {
            $ret .= '<blockquote style="background: solid 1x black; 
                padding: 5px; margin: 5px;">';
            $ret .= $this->messages;
            $ret .= '</blockquote>';
        }
        $emp_no = FormLib::get_form_value('emp_no', 0);
        $employee = new EmployeesModel($dbc);
        $employee->emp_no($emp_no);
        $employee->load();
        ob_start();
        ?>
        <div id="alert-area"></div>
        <form action="<?php 
        echo filter_input(INPUT_SERVER, 'PHP_SELF');
        ?>
" method="post">
        <div class="form-group">
            <label>First Name</label>
            <input type="text" name="fname" value="<?php 
        echo $employee->FirstName();
        ?>
"
                class="form-control" required />
        </div>
        <div class="form-group">
            <label>Last Name</label>
            <input type="text" name="lname" value="<?php 
        echo $employee->LastName();
        ?>
"
                class="form-control" />
        </div>
        <div class="form-group">
            <label>Password</label>
            <input type="text" name="passwd" value="<?php 
        echo $employee->CashierPassword();
        ?>
"
                class="form-control" required />
        </div>
        <div class="form-group">
            <label>Privileges</label>
            <select name="fes" class="form-control">
            <option value="20" <?php 
        echo $employee->frontendsecurity() <= 20 ? 'selected' : '';
        ?>
>Regular</option>
            <option value="30" <?php 
        echo $employee->frontendsecurity() > 20 ? 'selected' : '';
        ?>
>Manager</option>
            </select>
        </div>
        <div class="form-group">
            <label>Active
                <input type="checkbox" name="active" class="checkbox-inline"
                    <?php 
        echo $employee->EmpActive() == 1 ? 'checked' : '';
        ?>
 />
            </label>
        </div>
        <div class="form-group">
            <label>Birthdate</label>
            <input type="text" class="form-control date-field" name="birthdate" 
                id="birth-date-field" value="<?php 
        echo $employee->birthdate();
        ?>
"
                placeholder="Optional; for stores selling age-restricted items" />
        </div>
        <?php 
        if ($this->config->get('STORE_MODE') == 'HQ') {
            echo '<div class="form-group">';
            $stores = new StoresModel($dbc);
            $mapP = $dbc->prepare('SELECT storeID FROM StoreEmployeeMap WHERE storeID=? AND empNo=?');
            foreach ($stores->find('storeID') as $s) {
                $mapR = $dbc->execute($mapP, array($s->storeID(), $emp_no));
                $checked = $mapR && $dbc->numRows($mapR) ? 'checked' : '';
                printf('<label>
                    <input type="checkbox" name="store[]" value="%d" %s />
                    %s
                    </label> | ', $s->storeID(), $checked, $s->description());
            }
            echo '</div>';
        }
        ?>
        <p>
            <button type="submit" class="btn btn-default">Save</button>
            <button type="button" class="btn btn-default"
                onclick="location='ViewCashiersPage.php';return false;">Back</button>
        </p>
        <input type="hidden" name="emp_no" value="<?php 
        echo $emp_no;
        ?>
" />
        </form>
        <?php 
        $this->add_onload_command("\$('input.form-control:first').focus();\n");
        return ob_get_clean();
    }
예제 #10
0
 protected function get_orderID_customer_handler()
 {
     $dbc = $this->connection;
     $dbc->selectDB($this->config->get('OP_DB'));
     $TRANS = $this->config->get('TRANS_DB') . $dbc->sep();
     $orderID = $this->orderID;
     try {
         $memNum = $this->form->memNum;
     } catch (Exception $ex) {
         $memNum = '0';
     }
     $canEdit = FannieAuth::validateUserQuiet('ordering_edit');
     if (empty($orderID)) {
         $orderID = $this->createEmptyOrder();
     }
     $names = array();
     $personNum = 1;
     $status_row = array('Type' => 'REG', 'status' => '');
     $dbc->selectDB($this->config->get('TRANS_DB'));
     $orderModel = new SpecialOrdersModel($dbc);
     $orderModel->specialOrderID($orderID);
     $orderModel->load();
     $dbc->selectDB($this->config->get('OP_DB'));
     // detect member UPC entry
     if ($memNum > 9999999) {
         $cards = new MemberCardsModel($dbc);
         $cards->upc(BarcodeLib::padUPC($memNum));
         $memNum = '';
         foreach ($cards->find() as $c) {
             $memNum = $c->card_no();
             break;
         }
     }
     // look up member id if applicable
     if ($memNum === "0") {
         $findMem = $dbc->prepare("SELECT card_no,voided FROM {$TRANS}PendingSpecialOrder WHERE order_id=?");
         $memR = $dbc->execute($findMem, array($orderID));
         if ($dbc->numRows($memR) > 0) {
             $memW = $dbc->fetchRow($memR);
             $memNum = $memW['card_no'];
             $personNum = $memW['voided'];
         }
     } elseif ($memNum == "") {
         $prep = $dbc->prepare("UPDATE {$TRANS}PendingSpecialOrder SET card_no=?,voided=0\n                WHERE order_id=?");
         $dbc->execute($prep, array(0, $orderID));
     } else {
         $prep = $dbc->prepare("UPDATE {$TRANS}PendingSpecialOrder SET card_no=?\n                WHERE order_id=?");
         $dbc->execute($prep, array($memNum, $orderID));
         // clear contact fields if member number changed
         // so that defaults are reloaded from meminfo
         $dbc->selectDB($this->config->get('TRANS_DB'));
         $orderModel->street('');
         $orderModel->phone('');
         $orderModel->save();
         $orderModel->specialOrderID($orderID);
         $orderModel->load();
         $dbc->selectDB($this->config->get('OP_DB'));
         // look up personnum, correct if it hasn't been set
         $pendQ = $dbc->prepare_statement("SELECT voided FROM {$TRANS}PendingSpecialOrder\n                WHERE order_id=?");
         $personNum = $dbc->getValue($pendQ, array($orderID));
         if ($personNum == 0) {
             $personNum = 1;
             $upP = $dbc->prepare_statement("UPDATE {$TRANS}PendingSpecialOrder SET voided=?\n                    WHERE order_id=?");
             $upR = $dbc->exec_statement($upP, array($personNum, $orderID));
         }
     }
     if ($memNum != 0) {
         $custdata = new CustdataModel($dbc);
         $custdata->CardNo($memNum);
         foreach ($custdata->find('personNum') as $c) {
             $names[$c->personNum()] = array($c->FirstName(), $c->LastName());
         }
         // load member contact info into order
         // on first go so it can be edited separately
         $current_street = $orderModel->street();
         $current_phone = $orderModel->phone();
         if (empty($current_street) && empty($current_phone)) {
             $contactQ = $dbc->prepare_statement("SELECT street,city,state,zip,phone,email_1,email_2\n                        FROM meminfo WHERE card_no=?");
             $contactR = $dbc->exec_statement($contactQ, array($memNum));
             if ($dbc->num_rows($contactR) > 0) {
                 $contact_row = $dbc->fetch_row($contactR);
                 $dbc->selectDB($this->config->get('TRANS_DB'));
                 $orderModel->street($contact_row['street']);
                 $orderModel->city($contact_row['city']);
                 $orderModel->state($contact_row['state']);
                 $orderModel->zip($contact_row['zip']);
                 $orderModel->phone($contact_row['phone']);
                 $orderModel->altPhone($contact_row['email_2']);
                 $orderModel->email($contact_row['email_1']);
                 $orderModel->save();
                 $orderModel->specialOrderID($orderID);
                 $orderModel->load();
                 $dbc->selectDB($this->config->get('OP_DB'));
             }
         }
         if ($custdata->load()) {
             $status_row['Type'] = $custdata->Type();
             if ($status_row['Type'] == 'INACT') {
                 $status_row['status'] = 'Inactive';
             } elseif ($status_row['Type'] == 'INACT2') {
                 $status_row['status'] = 'Inactive';
             } elseif ($status_row['Type'] == 'TERM') {
                 $status_row['status'] = 'Terminated';
             }
         }
     }
     $prep = $dbc->prepare_statement("SELECT entry_date FROM {$TRANS}SpecialOrderHistory \n                WHERE order_id=? AND entry_type='CONFIRMED'");
     $confirm_date = $dbc->getValue($prep, array($orderID));
     $callback = 2;
     $user = '******';
     $orderDate = "";
     $prep = $dbc->prepare_statement("SELECT datetime,numflag,mixMatch FROM \n                {$TRANS}PendingSpecialOrder WHERE order_id=? AND trans_id=0");
     $res = $dbc->exec_statement($prep, array($orderID));
     if ($dbc->num_rows($res) > 0) {
         list($orderDate, $callback, $user) = $dbc->fetch_row($res);
     }
     $status = array(0 => "New, No Call", 3 => "New, Call", 1 => "Called/waiting", 2 => "Pending", 4 => "Placed", 5 => "Arrived");
     $order_status = $orderModel->statusFlag();
     $ret = "";
     $ret .= sprintf('<input type="hidden" id="orderID" value="%d" />', $orderID);
     $ret .= '<div class="row form-inline"><div class="col-sm-4 text-left">';
     $ret .= sprintf('<b>Owner Number</b>: <input type="text" size="6"
             id="memNum" value="%s" class="form-control price-field input-sm" 
             />', $memNum == 0 ? '' : $memNum);
     $ret .= '<br />';
     $ret .= '<b>Owner</b>: ' . ($status_row['Type'] == 'PC' ? 'Yes' : 'No');
     $ret .= sprintf('<input type="hidden" id="isMember" value="%s" />', $status_row['Type']);
     $ret .= '<br />';
     if (!empty($status_row['status'])) {
         $ret .= '<b>Account status</b>: ' . $status_row['status'];
         $ret .= '<br />';
     }
     $ret .= '</div><div class="col-sm-4 text-center">';
     if ($canEdit) {
         $ret .= '<b>Status</b>: ';
         $ret .= '<select id="orderStatus" class="form-control input-sm">';
         foreach ($status as $k => $v) {
             $ret .= sprintf('<option %s value="%d">%s</option>', $k == $order_status ? 'selected' : '', $k, $v);
         }
         $ret .= '</select><p />';
     }
     $ret .= '<b>Store</b>: ';
     $ret .= '<select id="orderStore" class="form-control input-sm">';
     $ret .= '<option value="0">Choose...</option>';
     $stores = new StoresModel($dbc);
     $ret .= $stores->toOptions($orderModel->storeID());
     $ret .= '</select>';
     $ret .= '</div><div class="col-sm-4 text-right">';
     $ret .= "<a href=\"\" class=\"btn btn-default btn-sm done-btn\">Done</a>";
     $username = FannieAuth::checkLogin();
     $prints = array();
     $cachepath = sys_get_temp_dir() . "/ordercache/";
     if (file_exists("{$cachepath}{$username}.prints")) {
         $prints = unserialize(file_get_contents("{$cachepath}{$username}.prints"));
     } else {
         $fptr = fopen("{$cachepath}{$username}.prints", 'w');
         fwrite($fptr, serialize($prints));
         fclose($fptr);
     }
     $ret .= sprintf('<br />Queue tags <input type="checkbox" %s class="print-cb" />', isset($prints[$orderID]) ? 'checked' : '', $username, $orderID);
     $ret .= sprintf('<br /><a href="tagpdf.php?oids[]=%d" target="_tags%d">Print Now</a>', $orderID, $orderID);
     $ret .= '</div></div>';
     $extra = "";
     $extra .= '<div class="row"><div class="col-sm-6 text-left">';
     $extra .= "<b>Taken by</b>: " . $user . "<br />";
     $extra .= "<b>On</b>: " . date("M j, Y g:ia", strtotime($orderDate)) . "<br />";
     $extra .= '</div><div class="col-sm-6 text-right form-inline">';
     $extra .= '<b>Call to Confirm</b>: ';
     $extra .= '<select id="ctcselect" class="form-control input-sm">';
     $extra .= '<option value="2"></option>';
     if ($callback == 1) {
         $extra .= '<option value="1" selected>Yes</option>';
         $extra .= '<option value="0">No</option>';
     } else {
         if ($callback == 0) {
             $extra .= '<option value="1">Yes</option>';
             $extra .= '<option value="0" selected>No</option>';
         } else {
             $extra .= '<option value="1">Yes</option>';
             $extra .= '<option value="0">No</option>';
         }
     }
     $extra .= '</select><br />';
     $extra .= '<span id="confDateSpan">' . (!empty($confirm_date) ? 'Confirmed ' . $confirm_date : 'Not confirmed') . "</span> ";
     $extra .= '<input type="checkbox" id="confirm-date" ';
     if (!empty($confirm_date)) {
         $extra .= "checked";
     }
     $extra .= ' /><br />';
     $extra .= "<a href=\"\" class=\"btn btn-default btn-sm done-btn\">Done</a>";
     $extra .= '</div></div>';
     $ret .= '<table class="table table-bordered">';
     // names
     if (empty($names)) {
         $ret .= sprintf('<tr><th>First Name</th><td>
                 <input type="text" id="t_firstName" name="fn"
                 class="form-control input-sm conact-field"
                 value="%s" 
                 /></td>', $orderModel->firstName());
         $ret .= sprintf('<th>Last Name</th><td><input 
                 type="text" id="t_lastName" value="%s" name="ln"
                 class="form-control input-sm contact-field"
                 /></td>', $orderModel->lastName());
     } else {
         $ret .= '<tr><th>Name</th><td colspan="2"><select id="s_personNum"
             class="form-control input-sm">';
         foreach ($names as $p => $n) {
             $ret .= sprintf('<option value="%d" %s>%s %s</option>', $p, $p == $personNum ? 'selected' : '', $n[0], $n[1]);
         }
         $ret .= '</select></td>';
         $ret .= '<td>&nbsp;</td>';
     }
     $ret .= '<td colspan="4" class="form-inline">For Department:
         <select id="nDept" class="form-control input-sm contact-field" 
             name="noteDept">
         <option value="0">Choose...</option>';
     $superQ = $dbc->prepare_statement("select superID,super_name from MasterSuperDepts\n            where superID > 0\n            group by superID,super_name\n            order by super_name");
     $superR = $dbc->exec_statement($superQ);
     while ($superW = $dbc->fetch_row($superR)) {
         $ret .= sprintf('<option value="%d" %s>%s</option>', $superW['superID'], $superW['superID'] == $orderModel->noteSuperID() ? 'selected' : '', $superW['super_name']);
     }
     $ret .= "</select></td></tr>";
     // address
     $street = $orderModel->street();
     $street2 = '';
     if (strstr($street, "\n")) {
         list($street, $street2) = explode("\n", $street, 2);
     }
     $ret .= sprintf('
         <tr>
             <th>Address</th>
             <td>
                 <input type="text" id="t_addr1" value="%s" 
                     class="form-control input-sm contact-field"
                     name="addr" />
             </td>
             <th>E-mail</th>
             <td>
                 <input type="text" id="t_email" value="%s" 
                     class="form-control input-sm contact-field"
                     name="email" />
             </td>
             <td rowspan="2" colspan="4">
                 <textarea id="nText" rows="5" cols="25" 
                     class="form-control input-sm contact-field" name="noteText"
                     >%s</textarea>
             </td>
         </tr>
         <tr>
             <th>Addr (2)</th>
             <td>
                 <input type="text" id="t_addr2" value="%s" 
                     class="form-control input-sm contact-field"
                     name="addr2" />
             </td>
             <th>City</th>
             <td>
                 <input type="text" id="t_city" name="city"
                     class="form-control input-sm contact-field"
                     value="%s" size="10" />
             </td>
         </tr>
         <tr>
             <th>Phone</th>
             <td>
                 <input type="text" id="t_ph1" name="ph1"
                     class="form-control input-sm contact-field"
                     value="%s" />
             </td>
             <th>Alt. Phone</th>
             <td>
                 <input type="text" id="t_ph2" value="%s" name="ph2"
                     class="form-control input-sm contact-field" />
             </td>
             <th>State</th>
             <td>
                 <input type="text" id="t_state" value="%s" size="2" 
                     class="form-control input-sm contact-field"
                     name="state"  />
             </td>
             <th>Zip</th>
             <td>
                 <input type="text" id="t_zip" value="%s" size="5" 
                     class="form-control input-sm contact-field"
                     name="zip" />
             </td>
         </tr>', $street, $orderModel->email(), $orderModel->notes(), $street2, $orderModel->city(), $orderModel->phone(), $orderModel->altPhone(), $orderModel->state(), $orderModel->zip());
     $ret .= '</table>';
     echo json_encode(array('customer' => $ret, 'footer' => $extra));
     return false;
 }
예제 #11
0
    public function body_content()
    {
        include dirname(__FILE__) . '/../config.php';
        ob_start();
        echo showInstallTabs('Stores');
        ?>

<form action=InstallStoresPage.php method=post>
<h1 class="install">
    <?php 
        if (!$this->themed) {
            echo "<h1 class='install'>{$this->header}</h1>";
        }
        ?>
</h1>
<p class="ichunk">Revised 23Apr2014</p>
<?php 
        if (is_writable('../config.php')) {
            echo "<div class=\"alert alert-success\"><i>config.php</i> is writeable</div>";
        } else {
            echo "<div class=\"alert alert-danger\"><b>Error</b>: config.php is not writeable</div>";
        }
        ?>
<hr />
<h4 class="install">Stores</h4>
<p class="ichunk" style="margin:0.0em 0em 0.4em 0em;">
<?php 
        $model = new StoresModel(FannieDB::get($FANNIE_OP_DB));
        $model->dbHost($FANNIE_SERVER);
        $myself = $model->find();
        if (count($myself) == 0) {
            echo '<i>No entry found for this store. Adding one automatically...</i><br />';
            $model->description('CURRENT STORE');
            $model->save();
        } else {
            if (count($myself) > 1) {
                echo '<i>Warning: more than one entry for store host: ' . $FANNIE_SERVER . '</i><br />';
            } else {
                echo '<i>This store is #' . installTextField('FANNIE_STORE_ID', $FANNIE_STORE_ID, $myself[0]->storeID()) . '</i><br />';
            }
        }
        $model->reset();
        echo '<label>Mode</label>';
        echo installSelectField('FANNIE_STORE_MODE', $FANNIE_STORE_MODE, array('STORE' => 'Single Store', 'HQ' => 'HQ'), 'STORE');
        $supportedTypes = array('none' => '');
        if (extension_loaded('pdo') && extension_loaded('pdo_mysql')) {
            $supportedTypes['PDO_MYSQL'] = 'PDO MySQL';
        }
        if (extension_loaded('mysqli')) {
            $supportedTypes['MYSQLI'] = 'MySQLi';
        }
        if (extension_loaded('mysql')) {
            $supportedTypes['MYSQL'] = 'MySQL';
        }
        if (extension_loaded('mssql')) {
            $supportedTypes['MSSQL'] = 'MSSQL';
        }
        ?>
<table class="table">
<tr>
    <th>Store #</th><th>Description</th><th>DB Host</th>
    <th>Driver</th><th>Username</th><th>Password</th>
    <th>Operational DB</th>
    <th>Transaction DB</th>
    <th>Push</th>
    <th>Pull</th>
    <th>Own Items</th>
    <th>Delete Entry</th>
</tr>
<?php 
        foreach ($model->find('storeID') as $store) {
            printf('<tr %s>
            <td>%d<input type="hidden" name="storeID[]" value="%d" /></td>
            <td><input type="text" class="form-control" name="storeName[]" value="%s" /></td>
            <td><input type="text" class="form-control" name="storeHost[]" value="%s" /></td>', $store->dbHost() == $FANNIE_SERVER ? 'class="info"' : '', $store->storeID(), $store->storeID(), $store->description(), $store->dbHost());
            echo '<td><select name="storeDriver[]" class="form-control">';
            foreach ($supportedTypes as $key => $label) {
                printf('<option %s value="%s">%s</option>', $store->dbDriver() == $key ? 'selected' : '', $key, $label);
            }
            echo '</select></td>';
            printf('<td><input type="text" class="form-control" name="storeUser[]" value="%s" /></td>
            <td><input type="password" class="form-control" name="storePass[]" value="%s" /></td>
            <td><input type="text" class="form-control" name="storeOp[]" value="%s" /></td>
            <td><input type="text" class="form-control" name="storeTrans[]" value="%s" /></td>
            <td><input type="checkbox" name="storePush[]" value="%d" %s /></td>
            <td><input type="checkbox" name="storePull[]" value="%d" %s /></td>
            <td><input type="checkbox" name="storeItems[]" value="%d" %s /></td>
            <td><input type="checkbox" name="storeDelete[]" value="%d" /></td>
            </tr>', $store->dbUser(), $store->dbPassword(), $store->opDB(), $store->transDB(), $store->storeID(), $store->push() ? 'checked' : '', $store->storeID(), $store->pull() ? 'checked' : '', $store->storeID(), $store->hasOwnItems() ? 'checked' : '', $store->storeID());
        }
        ?>
</table>
</p>
<hr />
<h4 class="install">Testing Connections</h4>
<p class="ichunk" style="margin:0.0em 0em 0.4em 0em;">
    <ul>
<?php 
        foreach ($model->find('storeID') as $store) {
            $test = db_test_connect($store->dbHost(), $store->dbDriver(), $store->transDB(), $store->dbUser(), $store->dbPassword());
            echo '<li> Store #' . $store->storeID() . ': ' . ($test ? 'Connected' : 'No connection') . '</li>';
        }
        ?>
    </ul>
    <i>Note: it's OK if this store's connection fails as long as it succeeds
       on the "Necessities" tab.</i>
</p>
<hr />
<h4 class="install">Read-only Database Server(s)</h4>
<p class="ichunk" style="margin:0.0em 0em 0.4em 0em;">
Specify one or more database servers that can be used strictly
for read operations. If more than one database is listed, read-only
queries will be load-balanced across them.
<?php 
        if (!isset($FANNIE_READONLY_JSON)) {
            $FANNIE_READONLY_JSON = json_encode(array(array('host' => $FANNIE_SERVER, 'type' => $FANNIE_SERVER_DBMS, 'user' => $FANNIE_SERVER_USER, 'pw' => $FANNIE_SERVER_PW)));
        }
        confset('FANNIE_READONLY_JSON', "'{$FANNIE_READONLY_JSON}'");
        ?>
<textarea rows="10" cols="30" name="FANNIE_READONLY_JSON" class="form-control">
<?php 
        echo \COREPOS\Fannie\API\lib\FannieUI::prettyJSON($FANNIE_READONLY_JSON);
        ?>
</textarea>
<hr />
<p>
<button type=submit name="saveButton" value="Save" class="btn btn-default">Save</button>
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;
<button type=submit name="addButton" value="Add Another Store" class="btn btn-default">Add Another Store</button>
</p>
</form>

<?php 
        return ob_get_clean();
        // body_content
    }
예제 #12
0
 protected function showBatchDisplay($id, $order = 'natural')
 {
     global $FANNIE_SERVER_DBMS, $FANNIE_URL;
     $dbc = $this->connection;
     $uid = getUID($this->current_user);
     $uid = ltrim($uid, '0');
     $orderby = '';
     switch ($order) {
         case 'upc_a':
             $orderby = 'ORDER BY b.upc ASC';
             break;
         case 'upc_d':
             $orderby = 'ORDER BY b.upc DESC';
             break;
         case 'desc_a':
             $orderby = 'ORDER BY description ASC';
             break;
         case 'desc_d':
             $orderby = 'ORDER BY description DESC';
             break;
         case 'price_a':
             $orderby = 'ORDER BY p.normal_price ASC';
             break;
         case 'price_d':
             $orderby = 'ORDER BY p.normal_price DESC';
             break;
         case 'sale_a':
             $orderby = 'ORDER BY b.salePrice ASC';
             break;
         case 'sale_d':
             $orderby = 'ORDER BY b.salePrice DESC';
             break;
         case 'loc_a':
             $orderby = 'ORDER BY m.super_name,y.subsection,y.shelf_set,y.shelf';
             break;
         case 'loc_d':
             $orderby = 'ORDER BY m.super_name DESC,y.subsection DESC,y.shelf_set DESC,y.shelf DESC';
             break;
         case 'brand_a':
             $orderby = 'ORDER BY p.brand ASC';
             break;
         case 'brand_d':
             $orderby = 'ORDER BY p.brand DESC';
             break;
         case 'natural':
         default:
             $orderby = 'ORDER BY b.listID DESC';
             break;
     }
     $model = new BatchesModel($dbc);
     $model->batchID($id);
     $model->load();
     $name = $model->batchName();
     $type = $model->batchType();
     $dtype = $model->discountType();
     $start = strtotime($model->startDate());
     $end = strtotime($model->endDate()) + 60 * 60 * 24;
     $typeModel = new BatchTypeModel($dbc);
     $typeModel->batchTypeID($type);
     $typeModel->load();
     if ($typeModel->editorUI() == 2) {
         return $this->showPairedBatchDisplay($id, $name);
     }
     $limit = $model->transLimit();
     $hasLimit = $limit > 0 ? true : false;
     $saleHeader = "Sale Price";
     if ($dtype == 3) {
         $saleHeader = "\$ Discount";
     } elseif ($dtype == 4) {
         $saleHeader = "% Discount";
     } elseif ($dtype == 0) {
         $saleHeader = "New price";
     }
     $fetchArgs = array();
     $fetchQ = "\n            SELECT b.upc,\n                CASE \n                    WHEN l.likeCode IS NULL THEN p.description\n                    ELSE l.likeCodeDesc \n                END AS description,\n                p.normal_price,\n                b.salePrice,\n                CASE WHEN c.upc IS NULL then 0 ELSE 1 END as isCut,\n                b.quantity,\n                b.pricemethod,\n                m.super_name, \n                y.subsection, \n                y.shelf_set, \n                y.shelf,\n                p.brand\n            FROM batchList AS b \n                " . DTrans::joinProducts('b') . "\n                LEFT JOIN likeCodes AS l ON b.upc = CONCAT('LC',CONVERT(l.likeCode,CHAR))\n                LEFT JOIN batchCutPaste AS c ON b.upc=c.upc AND b.batchID=c.batchID\n                LEFT JOIN prodPhysicalLocation AS y ON b.upc=y.upc\n                LEFT JOIN superDeptNames AS m ON y.section=m.superID\n            WHERE b.batchID = ? \n            {$orderby}";
     $fetchArgs[] = $id;
     if ($dbc->dbms_name() == "mssql") {
         $fetchQ = "select b.upc,\n                    case when l.likecode is null then p.description\n                    else l.likecodedesc end as description,\n                    p.normal_price,b.salePrice,\n                    CASE WHEN c.upc IS NULL then 0 ELSE 1 END as isCut,\n                    b.quantity,b.pricemethod\n                    from batchList as b \n                        " . DTrans::joinProducts('b') . "\n                        left join likeCodes as l on\n                    b.upc = 'LC'+convert(varchar,l.likecode)\n                    left join batchCutPaste as c ON\n                    b.upc=c.upc AND b.batchID=c.batchID\n                    where b.batchID = ? {$orderby}";
     }
     $sections = array();
     if ($dbc->tableExists('FloorSections')) {
         $floor = new FloorSectionsModel($dbc);
         foreach ($floor->find() as $f) {
             $sections[$f->floorSectionID()] = $f->name();
         }
         $fetchQ = str_replace('y.subsection', 'y.floorSectionID', $fetchQ);
     }
     $fetchP = $dbc->prepare_statement($fetchQ);
     $fetchR = $dbc->exec_statement($fetchP, $fetchArgs);
     $overlapP = $dbc->prepare('
         SELECT b.batchID,
             b.batchName
         FROM batchList as l
             INNER JOIN batches AS b ON b.batchID=l.batchID
         WHERE l.upc=?
             AND l.batchID <> ?
             AND b.discounttype <> 0
             AND (
                 (b.startDate BETWEEN ? AND ?)
                 OR
                 (b.endDate BETWEEN ? AND ?)
             )
     ');
     $overlap_args = array($model->startDate(), $model->endDate(), $model->startDate(), $model->endDate());
     $cpCount = $dbc->prepare_statement("SELECT count(*) FROM batchCutPaste WHERE uid=?");
     $res = $dbc->exec_statement($cpCount, array($uid));
     $row = $dbc->fetch_row($res);
     $cpCount = $row[0];
     $ret = "<span class=\"newBatchBlack\"><b>Batch name</b>: {$name}</span> | ";
     $ret .= '<b>Sale Dates</b>: ' . date('Y-m-d', strtotime($model->startDate())) . ' - ' . date('Y-m-d', strtotime($model->endDate())) . '<br />';
     if ($this->config->get('STORE_MODE') === 'HQ') {
         $stores = new StoresModel($dbc);
         $mapP = $dbc->prepare('SELECT storeID FROM StoreBatchMap WHERE storeID=? AND batchID=?');
         foreach ($stores->find('storeID') as $s) {
             $mapR = $dbc->execute($mapP, array($s->storeID(), $id));
             $checked = $mapR && $dbc->numRows($mapR) ? 'checked' : '';
             $ret .= sprintf('<label>
                 <input type="checkbox" onchange="toggleStore(%d, %d);" %s />
                 %s
                 </label> | ', $s->storeID(), $id, $checked, $s->description());
         }
         $ret .= '<br />';
     }
     $ret .= "<a href=\"BatchListPage.php\">Back to batch list</a> | ";
     $ret .= sprintf('<input type="hidden" id="batch-discount-type" value="%d" />', $model->discountType());
     /**
       Price change batches probably want the upcoming retail
       rather than the current retail. Current sales will want
       the current sale price; future sales will want the future
       sale price. Past sales probably won't print signs under
       normal circumstances.
     */
     $future_mode = false;
     if ($model->discountType() == 0) {
         $future_mode = true;
     } elseif (strtotime($model->startDate()) >= strtotime(mktime(0, 0, 0, date('n'), date('j'), date('Y')))) {
         $future_mode = true;
     }
     $ret .= sprintf('<input type="hidden" id="batch-future-mode" value="%d" />', $future_mode ? 1 : 0);
     $ret .= "<a href=\"../../admin/labels/SignFromSearch.php?batch={$id}\">Print Sale Signs</a> | ";
     $ret .= "<a href=\"BatchSignStylesPage.php?id={$id}\">Sign Pricing</a> | ";
     $ret .= "<a href=\"{$FANNIE_URL}admin/labels/BatchShelfTags.php?batchID%5B%5D={$id}\">Print Shelf Tags</a> | ";
     $ret .= "<a href=\"\" onclick=\"generateTags({$id}); return false;\">Auto-tag</a> | ";
     if ($cpCount > 0) {
         $ret .= "<a href=\"EditBatchPage.php?id={$id}&paste=1\">Paste Items ({$cpCount})</a> | ";
     }
     if ($dtype == 0 || time() >= $start && time() <= $end) {
         $ret .= "<a href=\"\" onclick=\"forceNow({$id}); return false;\">Force batch</a> | ";
     }
     if ($dtype != 0) {
         $ret .= "<a href=\"\" onclick=\"unsaleNow({$id}); return false;\">Stop Sale</a> ";
     }
     if ($dtype == 0) {
         $ret .= " <a href=\"\" onclick=\"trimPcBatch({$id}); return false;\">Trim Unchanged</a> ";
     } else {
         $ret .= " | <span id=\"edit-limit-link\"><a href=\"\" \n                onclick=\"editTransLimit(); return false;\">" . ($hasLimit ? 'Edit' : 'Add') . " Limit</a></span>";
         $ret .= "<span id=\"save-limit-link\" class=\"collapse\"><a href=\"\" onclick=\"saveTransLimit({$id}); return false;\">Save Limit</a></span>";
         $ret .= " <span class=\"form-group form-inline\" id=\"currentLimit\" style=\"color:#000;\">{$limit}</span>";
     }
     $ret .= "<br />";
     $ret .= "<table id=yeoldetable class=\"table\">";
     $ret .= "<tr>";
     if ($orderby != "ORDER BY b.upc ASC") {
         $ret .= "<th><a href=\"EditBatchPage.php?id={$id}&sort=upc_a\">UPC</a></th>";
     } else {
         $ret .= "<th><a href=\"EditBatchPage.php?id={$id}&sort=upc_d\">UPC</a></th>";
     }
     if ($orderby != "ORDER BY p.brand ASC") {
         $ret .= "<th><a href=\"EditBatchPage.php?id={$id}&sort=brand_a\">Brand</a></th>";
     } else {
         $ret .= "<th><a href=\"EditBatchPage.php?id={$id}&sort=brand_d\">Brand</a></th>";
     }
     if ($orderby != "ORDER BY description ASC") {
         $ret .= "<th><a href=\"EditBatchPage.php?id={$id}&sort=desc_a\">Description</a></th>";
     } else {
         $ret .= "<th><a href=\"EditBatchPage.php?id={$id}&sort=desc_d\">Description</a></th>";
     }
     if ($orderby != "ORDER BY p.normal_price DESC") {
         $ret .= "<th><a href=\"EditBatchPage.php?id={$id}&sort=price_d\">Normal Price</a></th>";
     } else {
         $ret .= "<th><a href=\"EditBatchPage.php?id={$id}&sort=price_a\">Normal Price</a></th>";
     }
     if ($orderby != "ORDER BY b.salePrice DESC") {
         $ret .= "<th><a href=\"EditBatchPage.php?id={$id}&sort=sale_d\">{$saleHeader}</a></th>";
     } else {
         $ret .= "<th><a href=\"EditBatchPage.php?id={$id}&sort=sale_a\">{$saleHeader}</a></th>";
     }
     $ret .= "<th colspan=\"3\">&nbsp;</th>";
     if ($orderby != 'ORDER BY m.super_name,y.subsection,y.shelf_set,y.shelf') {
         $ret .= "<th><a href=\"EditBatchPage.php?id={$id}&sort=loc_a\">Location</a></th>";
     } else {
         $ret .= "<th><a href=\"EditBatchPage.php?id={$id}&sort=loc_d\">Location</a></th>";
     }
     $ret .= "</tr>";
     $colors = array('#ffffff', '#ffffcc');
     $cur = 0;
     while ($fetchW = $dbc->fetch_array($fetchR)) {
         $cur = ($cur + 1) % 2;
         $ret .= "<tr>";
         $fetchW['upc'] = rtrim($fetchW['upc']);
         if (substr($fetchW['upc'], 0, 2) == "LC") {
             $likecode = rtrim(substr($fetchW['upc'], 2));
             $ret .= "<td bgcolor={$colors[$cur]}>" . $fetchW['upc'];
             $ret .= " <a href=\"\" onclick=\"\$('.lc-item-{$likecode}').toggle(); return false;\">[+]</a>";
             $ret .= "</td>";
         } else {
             $conflict = '';
             if ($dtype != 0) {
                 $overlapR = $dbc->execute($overlapP, array_merge(array($fetchW['upc'], $id), $overlap_args));
                 if ($overlapR && $dbc->numRows($overlapR)) {
                     $overlap = $dbc->fetchRow($overlapR);
                     $conflict = sprintf('<a href="EditBatchPage.php?id=%d" target="_batch%d"
                                             title="Conflicts with batch %s" class="btn btn-xs btn-danger">
                                             <span class="glyphicon glyphicon-exclamation-sign">
                                             </span></a>', $overlap['batchID'], $overlap['batchID'], $overlap['batchName']);
                 }
             }
             $ret .= "<td bgcolor={$colors[$cur]}><a href=\"{$FANNIE_URL}item/ItemEditorPage.php?searchupc={$fetchW['upc']}\" \n                    target=\"_new{$fetchW['upc']}\">{$fetchW['upc']}</a>{$conflict}</td>";
         }
         $ret .= "<td bgcolor={$colors[$cur]}>{$fetchW['brand']}</td>";
         $ret .= "<td bgcolor={$colors[$cur]}>{$fetchW['description']}</td>";
         $ret .= "<td bgcolor={$colors[$cur]}>{$fetchW['normal_price']}</td>";
         $qtystr = $fetchW['pricemethod'] > 0 && is_numeric($fetchW['quantity']) && $fetchW['quantity'] > 0 ? $fetchW['quantity'] . " for " : "";
         $qty = is_numeric($fetchW['quantity']) && $fetchW['quantity'] > 0 ? $fetchW['quantity'] : 1;
         $ret .= "<td bgcolor={$colors[$cur]} class=\"\">";
         $ret .= '<span id="editable-text-' . $fetchW['upc'] . '">';
         $ret .= '<span class="editable-' . $fetchW['upc'] . ($qty == 1 ? ' collapse ' : '') . '"' . ' id="item-qty-' . $fetchW['upc'] . '" data-name="qty">' . $qty . ' for </span>';
         $ret .= "<span class=\"editable-{$fetchW['upc']}\" \n                    id=\"sale-price-{$fetchW['upc']}\" data-name=\"price\">" . sprintf("%.2f</span>", $fetchW['salePrice']);
         $ret .= '</span>';
         $ret .= '<div class="form-group form-inline collapse" id="editable-fields-' . $fetchW['upc'] . '">';
         $ret .= '<div class="input-group">';
         $ret .= sprintf('<input type="text" class="form-control" name="qty" value="%d" />', $qty);
         $ret .= '<span class="input-group-addon">for</span>';
         $ret .= '<span class="input-group-addon">$</span>';
         $ret .= sprintf('<input text="text" class="form-control" name="price" value="%.2f" />', $fetchW['salePrice']);
         $ret .= '</div></div></td>';
         $ret .= "<td bgcolor={$colors[$cur]} id=editLink{$fetchW['upc']}>\n                <a href=\"\" class=\"edit\" onclick=\"editUpcPrice('{$fetchW['upc']}'); return false;\">\n                    " . \COREPOS\Fannie\API\lib\FannieUI::editIcon() . "</a>\n                <a href=\"\" class=\"save collapse\" onclick=\"saveUpcPrice('{$fetchW['upc']}'); return false;\">\n                    " . \COREPOS\Fannie\API\lib\FannieUI::saveIcon() . "</a>\n                </td>";
         $ret .= "<td bgcolor={$colors[$cur]}><a href=\"\" \n                onclick=\"deleteUPC.call(this, {$id}, '{$fetchW['upc']}'); return false;\">" . \COREPOS\Fannie\API\lib\FannieUI::deleteIcon() . "</a>\n                </td>";
         if ($fetchW['isCut'] == 1) {
             $ret .= "<td bgcolor={$colors[$cur]} id=cpLink{$fetchW['upc']}>\n                    <a href=\"\" id=\"unCut{$fetchW['upc']}\" onclick=\"cutItem('{$fetchW['upc']}',{$id},{$uid}, 0); return false;\">Undo</a>\n                    <a href=\"\" class=\"collapse\" id=\"doCut{$fetchW['upc']}\" onclick=\"cutItem('{$fetchW['upc']}',{$id},{$uid}, 1); return false;\">Cut</a>\n                    </td>";
         } else {
             $ret .= "<td bgcolor={$colors[$cur]} id=cpLink{$fetchW['upc']}>\n                    <a href=\"\" class=\"collapse\" id=\"unCut{$fetchW['upc']}\" onclick=\"cutItem('{$fetchW['upc']}',{$id},{$uid},0); return false;\">Undo</a>\n                    <a href=\"\" id=\"doCut{$fetchW['upc']}\" onclick=\"cutItem('{$fetchW['upc']}',{$id},{$uid},1); return false;\">Cut</a>\n                    </td>";
         }
         $loc = 'n/a';
         if (!empty($fetchW['subsection'])) {
             $loc = substr($fetchW['super_name'], 0, 4);
             $loc .= $fetchW['subsection'] . ', ';
             $loc .= 'Unit ' . $fetchW['shelf_set'] . ', ';
             $loc .= 'Shelf ' . $fetchW['shelf'];
         } elseif (!empty($fetchW['floorSectionID'])) {
             $loc = $sections[$fetchW['floorSectionID']];
         }
         $ret .= "<td bgcolor={$colors[$cur]}>" . $loc . '</td>';
         $ret .= '<input type="hidden" class="batch-hidden-upc" value="' . $fetchW['upc'] . '" />';
         $ret .= "</tr>";
         if (substr($fetchW['upc'], 0, 2) == "LC") {
             $likecode = rtrim(substr($fetchW['upc'], 2));
             $ret .= self::likeToTable($dbc, $likecode, $fetchW['salePrice']);
         }
     }
     $ret .= "</table>";
     $ret .= "<input type=hidden id=currentBatchID value={$id} />";
     return $ret;
 }
예제 #13
0
 public function get_view()
 {
     $dbc = $this->connection;
     $dbc->selectDB($this->config->get('OP_DB'));
     $stores = new StoresModel($dbc);
     $prod = $dbc->prepare('
         SELECT COUNT(*)
         FROM products
         WHERE store_id=?');
     $mismatch = false;
     $current_count = null;
     $ret = '<ul>';
     foreach ($stores->find() as $s) {
         $ret .= '<li>' . $s->description();
         $count = $dbc->getValue($prod, array($s->storeID()));
         $ret .= ' ' . number_format((int) $count) . ' items</li>';
         if ($current_count !== null && $count != $current_count) {
             $mismatch = true;
         }
         $current_count = $count;
     }
     $ret .= '</ul>';
     if ($mismatch) {
         $ret .= '<div class="alert alert-danger">Incomplete items detected</div>';
         /* do not enable until multi-store products table is ready to go
            $ret .= '<form method="post">
                <button type="submit" name="submit" class="btn btn-default">
                Fix Discrepancies
                </button>
                </form>';
            */
     }
     return $ret;
 }