function upcscanned($entered) { $my_url = MiscLib::base_url(); $ret = $this->default_json(); /* force cashiers to enter a comment on refunds */ if (CoreLocal::get("refund") == 1 && CoreLocal::get("refundComment") == "") { $ret['udpmsg'] = 'twoPairs'; if (CoreLocal::get("SecurityRefund") > 20) { $ret['main_frame'] = $my_url . "gui-modules/adminlogin.php?class=RefundAdminLogin"; } else { $ret['main_frame'] = $my_url . 'gui-modules/refundComment.php'; } CoreLocal::set("refundComment", CoreLocal::get("strEntered")); return $ret; } if (CoreLocal::get('itemPD') > 0 && CoreLocal::get('SecurityLineItemDiscount') == 30 && CoreLocal::get('msgrepeat') == 0) { $ret['main_frame'] = $my_url . "gui-modules/adminlogin.php?class=LineItemDiscountAdminLogin"; return $ret; } /** 11Sep14 Andy Disabled until keypress double form submission is fixed on paycard confirmation screen. Depending on sequence can case flag to be raised, cleared, and re-raised leading to spurrious error notifications */ if (false && CoreLocal::get('paycardTendered')) { if (CoreLocal::get('msgrepeat') == 0 || CoreLocal::get('lastRepeat') != 'paycardAlreadyApplied') { CoreLocal::set('boxMsg', 'Card already tendered<br /> Confirm adding more items'); CoreLocal::set('lastRepeat', 'paycardAlreadyApplied'); $ret['main_frame'] = $my_url . 'gui-modules/boxMsg2.php'; return $ret; } else { if (CoreLocal::get('lastRepeat') == 'paycardAlreadyApplied') { CoreLocal::set('lastRepeat', ''); CoreLocal::set('paycardTendered', false); } } } $upc = $this->sanitizeUPC($entered); $quantity = CoreLocal::get("quantity"); if (CoreLocal::get("quantity") == 0 && CoreLocal::get("multiple") == 0) { $quantity = 1; } list($scaleStickerItem, $scalepriceUPC, $scalepricEAN) = $this->rewriteScaleSticker($upc); $db = Database::pDataConnect(); $table = $db->table_definition('products'); $query = "SELECT inUse,upc,description,normal_price,scale,deposit,\n qttyEnforced,department,local,cost,tax,foodstamp,discount,\n discounttype,specialpricemethod,special_price,groupprice,\n pricemethod,quantity,specialgroupprice,specialquantity,\n mixmatchcode,idEnforced,tareweight,scaleprice"; // New column 16Apr14 if (isset($table['line_item_discountable'])) { $query .= ', line_item_discountable'; } else { $query .= ', 1 AS line_item_discountable'; } // New column 16Apr14 if (isset($table['formatted_name'])) { $query .= ', formatted_name'; } else { $query .= ', \'\' AS formatted_name'; } // New column 25Nov14 if (isset($table['special_limit'])) { $query .= ', special_limit'; } else { $query .= ', 0 AS special_limit'; } $query .= " FROM products WHERE upc = '" . $upc . "'"; $result = $db->query($query); $num_rows = $db->num_rows($result); /* check for special upcs that aren't really products */ if ($num_rows == 0) { $objs = CoreLocal::get("SpecialUpcClasses"); foreach ($objs as $class_name) { $instance = new $class_name(); if ($instance->isSpecial($upc)) { return $instance->handle($upc, $ret); } } // no match; not a product, not special if ($db->table_exists('IgnoredBarcodes')) { // lookup UPC in tabe of ignored barcodes // this just suppresses any error message from // coming back $query = 'SELECT upc FROM IgnoredBarcodes WHERE upc=\'' . $upc . "'"; $result = $db->query($query); if ($result && $db->num_rows($result)) { return $this->default_json(); } } $handler = CoreLocal::get('ItemNotFound'); if ($handler === '' || !class_exists($handler)) { $handler = 'ItemNotFound'; } $obj = new $handler(); $ret = $obj->handle($upc, $ret); return $ret; } /* product exists BEGIN error checking round #1 */ $row = $db->fetch_array($result); /** If formatted_name is present, copy it directly over products.description. This way nothing further down the process has to worry about the distinction between two potential naming fields. */ if ($row['formatted_name'] != '') { $row['description'] = $row['formatted_name']; } /* Implementation of inUse flag * if the flag is not set, display a warning dialog noting this * and allowing the sale to be confirmed or canceled */ if ($row["inUse"] == 0) { TransRecord::addLogRecord(array('upc' => $row['upc'], 'description' => $row['description'], 'department' => $row['department'], 'charflag' => 'IU')); } /** Apply special department handlers based on item's department */ $deptmods = CoreLocal::get('SpecialDeptMap'); if (!is_array($deptmods) && $db->table_exists('SpecialDeptMap')) { $model = new \COREPOS\pos\lib\models\op\SpecialDeptMapModel($db); $deptmods = $model->buildMap(); CoreLocal::set('SpecialDeptMap', $deptmods); } if (is_array($deptmods) && isset($deptmods[$row['department']])) { foreach ($deptmods[$row['department']] as $mod) { $obj = new $mod(); $ret = $obj->handle($row['department'], $row['normal_price'], $ret); if ($ret['main_frame']) { return $ret; } } } /** Detect if a by-weight item has the same weight as the last by-weight item. This can indicate a stuck scale. The giant if determines whether the item is scalable, that we know the weight, and that we know the previous weight (lastWeight) Pre-weighed items (upc starts with 002) are ignored because they're not weighed here. Scalable items that cost one cent are ignored as a special case; they're normally entered by keying a quantity multiplier */ if ($num_rows > 0 && $row['scale'] == 1 && CoreLocal::get("lastWeight") > 0 && CoreLocal::get("weight") > 0 && abs(CoreLocal::get("weight") - CoreLocal::get("lastWeight")) < 0.0005 && !$scaleStickerItem && abs($row['normal_price']) > 0.01) { if (CoreLocal::get('msgrepeat') == 0) { CoreLocal::set("strEntered", $row["upc"]); CoreLocal::set("boxMsg", "<b>Same weight as last item</b>"); CoreLocal::set('boxMsgButtons', array('Confirm Weight [enter]' => '$(\'#reginput\').val(\'\');submitWrapper();', 'Cancel [clear]' => '$(\'#reginput\').val(\'CL\');submitWrapper();')); $ret['main_frame'] = $my_url . "gui-modules/boxMsg2.php?quiet=1"; return $ret; } } if ($row["idEnforced"] > 0) { $restrictQ = "SELECT upc,dept_ID FROM dateRestrict WHERE\n ( upc='{$row['upc']}' AND\n ( " . $db->datediff($db->now(), 'restrict_date') . "=0 OR\n " . $db->dayofweek($db->now()) . "=restrict_dow\n ) AND\n ( (restrict_start IS NULL AND restrict_end IS NULL) OR\n " . $db->curtime() . " BETWEEN restrict_start AND restrict_end\n )\n ) OR \n ( dept_ID='{$row['department']}' AND\n ( " . $db->datediff($db->now(), 'restrict_date') . "=0 OR\n " . $db->dayofweek($db->now()) . "=restrict_dow\n ) AND\n ( (restrict_start IS NULL AND restrict_end IS NULL) OR\n " . $db->curtime() . " BETWEEN restrict_start AND restrict_end\n )\n )"; $restrictR = $db->query($restrictQ); if ($db->num_rows($restrictR) > 0) { $ret['output'] = DisplayLib::boxMsg(_('product cannot be sold right now'), _('Date Restriction'), false, DisplayLib::standardClearButton()); return $ret; } list($bad_age, $ret) = PrehLib::ageCheck($row['idEnforced'], $ret); if ($bad_age === true) { return $ret; } } /** Apply automatic tare weight */ if ($row['tareweight'] > 0) { $peek = PrehLib::peekItem(); if (strstr($peek, "** Tare Weight") === False) { TransRecord::addTare($row['tareweight'] * 100); } } elseif ($row['scale'] != 0 && !CoreLocal::get("tare") && Plugin::isEnabled('PromptForTare') && !CoreLocal::get("tarezero")) { $ret['main_frame'] = $my_url . 'plugins/PromptForTare/TarePromptInputPage.php?class=UPC&item=' . $entered; return $ret; } else { CoreLocal::set('tarezero', False); } /* sanity check - ridiculous price (can break db column if it doesn't fit */ if (strlen($row["normal_price"]) > 8) { $ret['output'] = DisplayLib::boxMsg($upc . '<br />' . _("Claims to be more than \$100,000"), _('Invalid Item'), false, DisplayLib::standardClearButton()); return $ret; } $scale = $row["scale"] == 0 ? 0 : 1; $qttyEnforced = $row["qttyEnforced"]; /* use scaleprice bit column to indicate whether values should be interpretted as UPC or EAN */ $scaleprice = $row['scaleprice'] == 0 ? $scalepriceUPC : $scalepriceEAN; /* need a weight with this item retry the UPC in a few milliseconds and see */ if ($scale != 0 && CoreLocal::get("weight") == 0 && $qttyEnforced == 0 && CoreLocal::get("quantity") == 0 && !$scaleStickerItem) { CoreLocal::set("SNR", CoreLocal::get('strEntered')); $ret['output'] = DisplayLib::boxMsg(_("please put item on scale"), 'Weighed Item', true, DisplayLib::standardClearButton()); return $ret; } /* quantity required for this item. Send to entry page if one wasn't provided */ if ($qttyEnforced == 1 && CoreLocal::get("multiple") == 0 && (CoreLocal::get("msgrepeat" == 0) || CoreLocal::get('qttyvalid') == 0)) { $ret['main_frame'] = $my_url . 'gui-modules/QuantityEntryPage.php' . '?entered-item=' . CoreLocal::get('strEntered') . '&qty-mode=' . $scale; return $ret; } /* got a scale weight, make sure the tare is valid */ if ($scale != 0 && !$scaleStickerItem) { $quantity = CoreLocal::get("weight") - CoreLocal::get("tare"); if (CoreLocal::get("quantity") != 0) { $quantity = CoreLocal::get("quantity") - CoreLocal::get("tare"); } if ($quantity <= 0) { $ret['output'] = DisplayLib::boxMsg(_("item weight must be greater than tare weight"), _('Invalid Weight'), false, DisplayLib::standardClearButton()); return $ret; } CoreLocal::set("tare", 0); } /* non-scale items need integer quantities */ if ($row["scale"] == 0 && (int) CoreLocal::get("quantity") != CoreLocal::get("quantity")) { $ret['output'] = DisplayLib::boxMsg(_("fractional quantity cannot be accepted for this item"), _('Invalid Quantity'), false, DisplayLib::standardClearButton()); return $ret; } /* wedge I assume I don't like this being hard-coded, but since these UPCs are entries in products they can't go in a SpecialUPC object (unless SpecialUPC checks take place on every scan, but that's more overhead than I want on such a common operation */ if ($upc == "0000000008010" && CoreLocal::get("msgrepeat") == 0) { CoreLocal::set("boxMsg", "<b>" . $total . " gift certificate</b><br />\n " . _("insert document")); CoreLocal::set('boxMsgButtons', array('Endorse [enter]' => '$(\'#reginput\').val(\'\');submitWrapper();', 'Cancel [clear]' => '$(\'#reginput\').val(\'CL\');submitWrapper();')); $ret["main_frame"] = $my_url . "gui-modules/boxMsg2.php?endorse=giftcert&endorseAmt=" . $total; return $ret; } /* wedge I assume see 0000000008010 above */ if ($upc == "0000000008011" && CoreLocal::get("msgrepeat") == 0) { CoreLocal::set("boxMsg", "<b>" . $total . " class registration</b><br />\n " . _("insert form")); CoreLocal::set('boxMsgButtons', array('Endorse [enter]' => '$(\'#reginput\').val(\'\');submitWrapper();', 'Cancel [clear]' => '$(\'#reginput\').val(\'CL\');submitWrapper();')); $ret["main_frame"] = $my_url . "gui-modules/boxMsg2.php?endorse=classreg&endorseAmt=" . $total; return $ret; } /* END error checking round #1 */ // wfc uses deposit field to link another upc if (isset($row["deposit"]) && $row["deposit"] > 0) { $dupc = (int) $row["deposit"]; $this->addDeposit($dupc); } $upc = $row["upc"]; $row['numflag'] = isset($row["local"]) ? $row["local"] : 0; $row['description'] = str_replace("'", "", $row['description']); list($tax, $foodstamp, $discountable) = PrehLib::applyToggles($row['tax'], $row['foodstamp'], $row['discount']); $row['tax'] = $tax; $row['foodstamp'] = $foodstamp; $row['discount'] = $discountable; /** Enforce per-transaction sale limits */ if ($row['special_limit'] > 0) { $appliedQ = "\n SELECT SUM(quantity) AS saleQty\n FROM " . CoreLocal::get('tDatabase') . $db->sep() . "localtemptrans\n WHERE discounttype <> 0\n AND (\n upc='{$row['upc']}'\n OR (mixMatch='{$row['mixmatchcode']}' AND mixMatch<>''\n AND mixMatch<>'0' AND mixMatch IS NOT NULL)\n )"; $appliedR = $db->query($appliedQ); if ($appliedR && $db->num_rows($appliedR)) { $appliedW = $db->fetch_row($appliedR); if ($appliedW['saleQty'] + $quantity > $row['special_limit']) { $row['discounttype'] = 0; $row['special_price'] = 0; $row['specialpricemethod'] = 0; $row['specialquantity'] = 0; $row['specialgroupprice'] = 0; } } } /* BEGIN: figure out discounts by type */ /* get discount object CORE reserves values 0 through 63 in DiscountType::$MAP for default options. Additional discounts provided by plugins can use values 64 through 127. Because the DiscountTypeClasses array is zero-indexed, subtract 64 as an offset */ $discounttype = MiscLib::nullwrap($row["discounttype"]); $DiscountObject = null; $DTClasses = CoreLocal::get("DiscountTypeClasses"); if ($row['discounttype'] < 64 && isset(DiscountType::$MAP[$row['discounttype']])) { $class = DiscountType::$MAP[$row['discounttype']]; $DiscountObject = new $class(); } else { if ($row['discounttype'] >= 64 && isset($DTClasses[$row['discounttype'] - 64])) { $class = $DTClasses[$row['discounttype'] - 64]; $DiscountObject = new $class(); } else { // If the requested discounttype isn't available, // fallback to normal pricing. Debatable whether // this should be a hard error. $DiscountObject = new NormalPricing(); } } /* add in sticker price and calculate a quantity if the item is stickered, scaled, and on sale. otherwise, if the item is sticked, scaled, and not on sale but has a non-zero price attempt to calculate a quantity. this makes the quantity field more consistent for reporting purposes. however, if the calculated quantity somehow introduces a rounding error fall back to the sticker's price. for non-sale items, the price the customer pays needs to match the sticker price exactly. items that are not scaled do not need a fractional quantity and items that do not have a normal_price assigned cannot calculate a proper quantity. */ if ($scaleStickerItem) { if ($DiscountObject->isSale() && $scale == 1 && $row['normal_price'] != 0) { $quantity = MiscLib::truncate2($scaleprice / $row["normal_price"]); } else { if ($scale == 1 && $row['normal_price'] != 0) { $quantity = MiscLib::truncate2($scaleprice / $row["normal_price"]); if (round($scaleprice, 2) != round($quantity * $row['normal_price'], 2)) { $quantity = 1.0; $row['normal_price'] = $scaleprice; } } else { $row['normal_price'] = $scaleprice; } } } /* END: figure out discounts by type */ /* get price method object & add item CORE reserves values 0 through 99 in PriceMethod::$MAP for default methods. Additional methods provided by plugins can use values 100 and up. Because the PriceMethodClasses array is zero-indexed, subtract 100 as an offset */ $pricemethod = MiscLib::nullwrap($row["pricemethod"]); if ($DiscountObject->isSale()) { $pricemethod = MiscLib::nullwrap($row["specialpricemethod"]); } $PMClasses = CoreLocal::get("PriceMethodClasses"); $PriceMethodObject = null; $row['trans_subtype'] = $this->status; if ($pricemethod < 100 && isset(PriceMethod::$MAP[$pricemethod])) { $class = PriceMethod::$MAP[$pricemethod]; $PriceMethodObject = new $class(); } else { if ($pricemethod >= 100 && isset($PMClasses[$pricemethod - 100])) { $class = $PMClasses[$pricemethod - 100]; $PriceMethodObject = new $class(); } else { $PriceMethodObject = new BasicPM(); } } // prefetch: otherwise object members // pass out of scope in addItem() $prefetch = $DiscountObject->priceInfo($row, $quantity); $added = $PriceMethodObject->addItem($row, $quantity, $DiscountObject); if (!$added) { $ret['output'] = DisplayLib::boxMsg($PriceMethodObject->errorInfo(), '', false, DisplayLib::standardClearButton()); return $ret; } /* add discount notifications lines, if applicable */ $DiscountObject->addDiscountLine(); // cleanup, reset flags and beep if ($quantity != 0) { CoreLocal::set("msgrepeat", 0); CoreLocal::set("qttyvalid", 0); $ret['udpmsg'] = 'goodBeep'; } /* reset various flags and variables */ if (CoreLocal::get("tare") != 0) { CoreLocal::set("tare", 0); } CoreLocal::set("ttlflag", 0); CoreLocal::set("fntlflag", 0); CoreLocal::set("quantity", 0); CoreLocal::set("itemPD", 0); Database::setglobalflags(0); /* output item list, update totals footer */ $ret['redraw_footer'] = True; $ret['output'] = DisplayLib::lastpage(); if ($prefetch['unitPrice'] == 0 && $discounttype == 0) { $ret['main_frame'] = $my_url . 'gui-modules/priceOverride.php'; } return $ret; }
public function testPriceMethods() { if (!class_exists('lttLib')) { include dirname(__FILE__) . '/lttLib.php'; } lttLib::clear(); $db = Database::pDataConnect(); $q = "SELECT * FROM products WHERE upc='0000000000111'"; $r = $db->query($q); $row = $db->fetch_row($r); $discount = new NormalPricing(); $discount->priceInfo($row, 1); $pm = new BasicPM(); $pm->addItem($row, 1, $discount); $record = lttLib::genericRecord(); $record['upc'] = '0000000000111'; $record['description'] = 'WYNDMERE 5-8 DRAM BOTTLE'; $record['trans_type'] = 'I'; $record['trans_subtype'] = ''; $record['trans_status'] = ''; $record['department'] = 103; $record['quantity'] = 1; $record['ItemQtty'] = 1; $record['unitPrice'] = 1.65; $record['total'] = 1.65; $record['regPrice'] = 1.65; $record['tax'] = 1; $record['discountable'] = 1; $record['mixMatch'] = '499'; lttLib::verifyRecord(1, $record, $this); lttLib::clear(); $row['pricemethod'] = 1; $row['groupprice'] = 2; $row['quantity'] = 2; $discount = new NormalPricing(); $discount->priceInfo($row, 1); $pm = new GroupPM(); $pm->addItem($row, 1, $discount); $record = lttLib::genericRecord(); $record['upc'] = '0000000000111'; $record['description'] = 'WYNDMERE 5-8 DRAM BOTTLE'; $record['trans_type'] = 'I'; $record['trans_subtype'] = ''; $record['trans_status'] = ''; $record['department'] = 103; $record['quantity'] = 1; $record['ItemQtty'] = 1; $record['unitPrice'] = 1.0; $record['total'] = 1.0; $record['regPrice'] = 1.65; $record['tax'] = 1; $record['discountable'] = 1; $record['mixMatch'] = '499'; $record['volDiscType'] = 1; $record['volume'] = 2; $record['VolSpecial'] = 2.0; lttLib::verifyRecord(1, $record, $this); $pm->addItem($row, 1, $discount); $record = lttLib::genericRecord(); $record['upc'] = '0000000000111'; $record['description'] = 'WYNDMERE 5-8 DRAM BOTTLE'; $record['trans_type'] = 'I'; $record['trans_subtype'] = ''; $record['trans_status'] = ''; $record['department'] = 103; $record['quantity'] = 1; $record['ItemQtty'] = 1; $record['unitPrice'] = 1.0; $record['total'] = 1.0; $record['regPrice'] = 1.65; $record['tax'] = 1; $record['discountable'] = 1; $record['mixMatch'] = '499'; $record['volDiscType'] = 1; $record['volume'] = 2; $record['VolSpecial'] = 2.0; lttLib::verifyRecord(2, $record, $this); lttLib::clear(); $row['pricemethod'] = 2; $discount = new NormalPricing(); $discount->priceInfo($row, 1); $pm = new QttyEnforcedGroupPM(); $pm->addItem($row, 1, $discount); $record = lttLib::genericRecord(); $record['upc'] = '0000000000111'; $record['description'] = 'WYNDMERE 5-8 DRAM BOTTLE'; $record['trans_type'] = 'I'; $record['trans_subtype'] = ''; $record['trans_status'] = ''; $record['department'] = 103; $record['quantity'] = 1; $record['ItemQtty'] = 1; $record['unitPrice'] = 1.65; $record['total'] = 1.65; $record['regPrice'] = 1.65; $record['tax'] = 1; $record['discountable'] = 1; $record['mixMatch'] = '499'; $record['volDiscType'] = 2; $record['volume'] = 2; $record['VolSpecial'] = 2.0; lttLib::verifyRecord(1, $record, $this); $pm->addItem($row, 1, $discount); $record = lttLib::genericRecord(); $record['upc'] = '0000000000111'; $record['description'] = 'WYNDMERE 5-8 DRAM BOTTLE'; $record['trans_type'] = 'I'; $record['trans_subtype'] = ''; $record['trans_status'] = ''; $record['department'] = 103; $record['quantity'] = 1; $record['ItemQtty'] = 1; $record['unitPrice'] = 0.35; $record['total'] = 0.35; $record['regPrice'] = 1.65; $record['tax'] = 1; $record['discountable'] = 1; $record['mixMatch'] = '499'; $record['volDiscType'] = 2; $record['volume'] = 2; $record['VolSpecial'] = 2.0; $record['discount'] = 1.3; $record['matched'] = 2; lttLib::verifyRecord(2, $record, $this); lttLib::clear(); $db = Database::pDataConnect(); $item1 = '0027002000000'; $r = $db->query("SELECT * FROM products WHERE upc='{$item1}'"); $row1 = $db->fetch_row($r); $row1['normal_price'] = 9.99; $item2 = '0020140000000'; $r = $db->query("SELECT * FROM products WHERE upc='{$item2}'"); $row2 = $db->fetch_row($r); $row2['normal_price'] = 9.99; $discount1 = new NormalPricing(); $discount1->priceInfo($row1, 1); $discount2 = new NormalPricing(); $discount2->priceInfo($row2, 1); $pm = new SplitABGroupPM(); $pm->addItem($row1, 1, $discount1); $record = lttLib::genericRecord(); $record['upc'] = '0027002000000'; $record['description'] = 'HALF ROAST BEEF AND CHEDDAR'; $record['trans_type'] = 'I'; $record['trans_subtype'] = ''; $record['trans_status'] = ''; $record['department'] = 226; $record['quantity'] = 1; $record['ItemQtty'] = 1; $record['unitPrice'] = 9.99; $record['total'] = 9.99; $record['regPrice'] = 9.99; $record['tax'] = 2; $record['foodstamp'] = 1; $record['discountable'] = 1; $record['mixMatch'] = '-2'; $record['volDiscType'] = 3; $record['volume'] = 2; $record['VolSpecial'] = 0.5; lttLib::verifyRecord(1, $record, $this); $pm->addItem($row2, 1, $discount2); $record = lttLib::genericRecord(); $record['upc'] = '0020140000000'; $record['description'] = 'SOUP 16 OZ'; $record['trans_type'] = 'I'; $record['trans_subtype'] = ''; $record['trans_status'] = ''; $record['department'] = 66; $record['quantity'] = 1; $record['ItemQtty'] = 1; $record['unitPrice'] = 9.99; $record['total'] = 9.99; $record['regPrice'] = 9.99; $record['tax'] = 2; $record['foodstamp'] = 0; $record['discountable'] = 1; $record['mixMatch'] = '2'; $record['volDiscType'] = 3; $record['volume'] = 2; $record['VolSpecial'] = 0.5; $record['matched'] = 2; lttLib::verifyRecord(2, $record, $this); $record = lttLib::genericRecord(); $record['upc'] = 'ITEMDISCOUNT'; $record['description'] = ' * Item Discount'; $record['trans_type'] = 'I'; $record['department'] = 66; $record['quantity'] = 1; $record['ItemQtty'] = 1; $record['unitPrice'] = -0.25; $record['total'] = -0.25; $record['regPrice'] = -0.25; lttLib::verifyRecord(3, $record, $this); $record = lttLib::genericRecord(); $record['upc'] = 'ITEMDISCOUNT'; $record['description'] = ' * Item Discount'; $record['trans_type'] = 'I'; $record['department'] = 226; $record['quantity'] = 1; $record['ItemQtty'] = 1; $record['unitPrice'] = -0.25; $record['total'] = -0.25; $record['regPrice'] = -0.25; lttLib::verifyRecord(4, $record, $this); lttLib::clear(); $row1['pricemethod'] = 4; $row2['pricemethod'] = 4; $discount1 = new NormalPricing(); $discount1->priceInfo($row1, 1); $discount2 = new NormalPricing(); $discount2->priceInfo($row2, 1); $pm = new ABGroupPM(); $pm->addItem($row2, 1, $discount2); $record = lttLib::genericRecord(); $record['upc'] = '0020140000000'; $record['description'] = 'SOUP 16 OZ'; $record['trans_type'] = 'I'; $record['trans_subtype'] = ''; $record['trans_status'] = ''; $record['department'] = 66; $record['quantity'] = 1; $record['ItemQtty'] = 1; $record['unitPrice'] = 9.99; $record['total'] = 9.99; $record['regPrice'] = 9.99; $record['tax'] = 2; $record['foodstamp'] = 0; $record['discountable'] = 1; $record['mixMatch'] = '2'; $record['volDiscType'] = 4; $record['volume'] = 2; $record['VolSpecial'] = 0.5; lttLib::verifyRecord(1, $record, $this); $pm->addItem($row1, 1, $discount1); $record = lttLib::genericRecord(); $record['upc'] = '0027002000000'; $record['description'] = 'HALF ROAST BEEF AND CHEDDAR'; $record['trans_type'] = 'I'; $record['trans_subtype'] = ''; $record['trans_status'] = ''; $record['department'] = 226; $record['quantity'] = 1; $record['ItemQtty'] = 1; $record['unitPrice'] = 9.99; $record['total'] = 9.99; $record['regPrice'] = 9.99; $record['tax'] = 2; $record['discount'] = 0.5; $record['foodstamp'] = 1; $record['discountable'] = 1; $record['mixMatch'] = '-2'; $record['volDiscType'] = 4; $record['volume'] = 2; $record['VolSpecial'] = 0.5; $record['matched'] = 2; lttLib::verifyRecord(2, $record, $this); $record = lttLib::genericRecord(); $record['upc'] = 'ITEMDISCOUNT'; $record['description'] = ' * Item Discount'; $record['trans_type'] = 'I'; $record['department'] = 226; $record['quantity'] = 1; $record['ItemQtty'] = 1; $record['unitPrice'] = -0.5; $record['total'] = -0.5; $record['regPrice'] = -0.5; lttLib::verifyRecord(3, $record, $this); }
function preprocess() { $this->upc = ""; $this->found = false; $this->pricing = array('sale' => false, 'actual_price' => '', 'memPrice' => '', 'description', 'department', 'regular_price'); if (isset($_REQUEST['reginput']) && strtoupper($_REQUEST['reginput']) == "CL") { // cancel $this->change_page($this->page_url . "gui-modules/pos2.php"); return false; } else { if (isset($_REQUEST['reginput']) || isset($_REQUEST['upc'])) { // use reginput as UPC unless it's empty $this->upc = isset($_REQUEST['reginput']) ? $_REQUEST['reginput'] : ''; if ($this->upc == '' && isset($_REQUEST['upc'])) { $this->upc = $_REQUEST['upc']; } $this->upc = str_pad($this->upc, 13, '0', STR_PAD_LEFT); $db = Database::pDataConnect(); $query = "select inUse,upc,description,normal_price,scale,deposit,\n qttyEnforced,department,local,cost,tax,foodstamp,discount,\n discounttype,specialpricemethod,special_price,groupprice,\n pricemethod,quantity,specialgroupprice,specialquantity,\n mixmatchcode,idEnforced,tareweight,d.dept_name\n from products, departments d where department = d.dept_no\n AND upc = ?"; $prep = $db->prepare($query); $result = $db->execute($prep, array($this->upc)); $num_rows = $db->num_rows($result); // lookup item info if ($num_rows > 0) { $this->found = true; $row = $db->fetch_row($result); $discounttype = MiscLib::nullwrap($row["discounttype"]); $DiscountObject = null; // see UPC parser for explanation $DTClasses = CoreLocal::get("DiscountTypeClasses"); if ($row['discounttype'] < 64 && isset(DiscountType::$MAP[$row['discounttype']])) { $class = DiscountType::$MAP[$row['discounttype']]; $DiscountObject = new $class(); } else { if ($row['discounttype'] > 64 && isset($DTClasses[$row['discounttype'] - 64])) { $class = $DTClasses[$row['discounttype'] - 64]; $DiscountObject = new $class(); } else { // If the requested discounttype isn't available, // fallback to normal pricing. Debatable whether // this should be a hard error. $DiscountObject = new NormalPricing(); } } if ($DiscountObject->isSale()) { $this->pricing['sale'] = true; } $info = $DiscountObject->priceInfo($row, 1); $this->pricing['actual_price'] = sprintf('$%.2f%s', $info['unitPrice'], $row['scale'] > 0 ? ' /lb' : ''); $this->pricing['regular_price'] = sprintf('$%.2f%s', $info['regPrice'], $row['scale'] > 0 ? ' /lb' : ''); if ($info['memDiscount'] > 0) { $this->pricing['memPrice'] = sprintf('$%.2f%s', $info['unitPrice'] - $info['memDiscount'], $row['scale'] > 0 ? ' /lb' : ''); } $this->pricing['description'] = $row['description']; $this->pricing['department'] = $row['dept_name']; MiscLib::goodBeep(); } // user hit enter and there is a valid UPC present if (isset($_REQUEST['reginput']) && $_REQUEST['reginput'] == '' && $this->found) { CoreLocal::set("msgrepeat", 1); CoreLocal::set("strRemembered", $this->upc); $this->change_page($this->page_url . "gui-modules/pos2.php"); return false; } } } return true; }