Exemple #1
0
 function addItem($row, $quantity, $priceObj)
 {
     if ($quantity == 0) {
         return False;
     }
     // enforce limit on discounting sale items
     $dsi = CoreLocal::get('DiscountableSaleItems');
     if ($dsi == 0 && $dsi !== '' && $priceObj->isSale()) {
         $row['discount'] = 0;
     }
     /*
       Use "quantity" field in products record as a per-transaction
       limit. This is analogous to a similar feature with sale items.
     */
     if (!$priceObj->isSale() && $row['quantity'] > 0) {
         $db = Database::tDataConnect();
         $query = "SELECT SUM(quantity) as qty FROM localtemptrans\n                WHERE upc='{$row['upc']}'";
         $result = $db->query($query);
         if ($db->num_rows($result) > 0) {
             $chkRow = $db->fetch_row($result);
             if ($chkRow['qty'] + $quantity > $row['quantity']) {
                 $this->error_msg = _("item only allows ") . $row['quantity'] . _(" per transaction");
                 return False;
             }
         }
     }
     $pricing = $priceObj->priceInfo($row, $quantity);
     TransRecord::addRecord(array('upc' => $row['upc'], 'description' => $row['description'], 'trans_type' => 'I', 'trans_subtype' => isset($row['trans_subtype']) ? $row['trans_subtype'] : '', 'department' => $row['department'], 'quantity' => $quantity, 'unitPrice' => $pricing['unitPrice'], 'total' => MiscLib::truncate2($pricing['unitPrice'] * $quantity), 'regPrice' => $pricing['regPrice'], 'scale' => $row['scale'], 'tax' => $row['tax'], 'foodstamp' => $row['foodstamp'], 'discount' => $pricing['discount'], 'memDiscount' => $pricing['memDiscount'], 'discountable' => $row['discount'], 'discounttype' => $row['discounttype'], 'ItemQtty' => $quantity, 'volDiscType' => $row['pricemethod'], 'volume' => $row['quantity'], 'VolSpecial' => $row['groupprice'], 'mixMatch' => $row['mixmatchcode'], 'cost' => isset($row['cost']) ? $row['cost'] * $quantity : 0.0, 'numflag' => isset($row['numflag']) ? $row['numflag'] : 0, 'charflag' => isset($row['charflag']) ? $row['charflag'] : ''));
     return true;
 }
Exemple #2
0
 function preprocess()
 {
     // check for posts before drawing anything, so we can redirect
     if (isset($_REQUEST['reginput'])) {
         $input = strtoupper(trim($_REQUEST['reginput']));
         // CL always exits
         if ($input == "CL") {
             CoreLocal::set("msgrepeat", 0);
             CoreLocal::set("toggletax", 0);
             CoreLocal::set("togglefoodstamp", 0);
             $this->change_page(MiscLib::baseURL() . "gui-modules/pos2.php");
             return false;
         } elseif ($input == "") {
             $this->change_page('BitCoinPaymentPage.php?amount=' . CoreLocal::get('amtdue'));
             return false;
         } elseif ($input != "" && substr($input, -2) != "CL") {
             // any other input is an alternate amount
             // convert cents to dollars and make sure it's valid
             $this->amt = $input;
             if (is_numeric($input)) {
                 $this->amt = MiscLib::truncate2($this->amt / 100.0);
             }
             if ($this->validateAmount($this->amt)) {
                 $this->change_page('BitCoinPaymentPage.php?amount=' . $this->amt);
                 return false;
             }
         }
     }
     // post?
     return true;
 }
 /**
   Check for errors
   @return True or an error message string
 */
 public function errorCheck()
 {
     if (MiscLib::truncate2(CoreLocal::get("amtdue")) < MiscLib::truncate2($this->amount)) {
         return DisplayLib::xboxMsg(_("tender cannot exceed purchase amount"), DisplayLib::standardClearButton());
     }
     return true;
 }
Exemple #4
0
 public function priceInfo($row, $quantity = 1)
 {
     if (is_array($this->savedInfo)) {
         return $this->savedInfo;
     }
     $ret = array();
     $ret["regPrice"] = $row['normal_price'];
     $ret["unitPrice"] = $row['special_price'];
     /* if not by weight, just use the sticker price 
           (for scaled items, the UPC parse module
           calculates a weight estimate and sets a quantity
           so normal_price can be used. This could be done
           for all items, but typically the deli doesn't
           keep good track of whether their items are
           marked scale correctly since it only matters when an
           item goes on sale
        */
     if (isset($row['stickerprice']) && $row['scale'] == 0) {
         $ret['regPrice'] = $row['stickerprice'];
     }
     $ret['discount'] = ($ret['regPrice'] - $row['special_price']) * $quantity;
     $ret['memDiscount'] = 0;
     if ($row['line_item_discountable'] == 1 && CoreLocal::get("itemPD") > 0) {
         $discount = $row['special_price'] * (CoreLocal::get("itemPD") / 100);
         $ret["unitPrice"] = $row['special_price'] - $discount;
         $ret["discount"] += $discount * $quantity;
     }
     // enforce per-transaction limit
     if ($row['specialpricemethod'] == 0 && $row['specialquantity'] > 0) {
         $tdb = Database::tDataConnect();
         $chkQ = "SELECT sum(ItemQtty) FROM\n                localtemptrans WHERE upc='{$row['upc']}'";
         if (strlen($row['mixmatchcode']) > 0 && $row['mixmatchcode'][0] == 'b') {
             $chkQ .= " OR mixMatch='{$row['mixmatchcode']}'";
         }
         $chkR = $tdb->query($chkQ);
         $prevSales = 0;
         if ($tdb->num_rows($chkR) > 0) {
             $prevSales = array_pop($tdb->fetch_row($chkR));
         }
         if ($prevSales >= $row['specialquantity']) {
             // already sold the limit; use non-sale price
             $ret['unitPrice'] = $row['normal_price'];
             $ret['discount'] = 0;
         } else {
             if ($prevSales + $quantity > $row['specialquantity']) {
                 // this multiple qty ring will pass the limit
                 // set discount based on appropriate quantity
                 // and adjust unitPrice so total comes out correctly
                 $discountQty = $row['specialquantity'] - $prevSales;
                 $ret['discount'] = ($ret['regPrice'] - $row['special_price']) * $discountQty;
                 $total = $ret['regPrice'] * $quantity - $ret['discount'];
                 $ret['unitPrice'] = MiscLib::truncate2($total / $quantity);
             }
         }
     }
     $this->savedRow = $row;
     $this->savedInfo = $ret;
     return $ret;
 }
Exemple #5
0
 public function calculate($discountable_total = 0)
 {
     $discount = parent::calculate();
     if (CoreLocal::get('NeedDiscountFlag') === 1) {
         $extra = 0.05 * CoreLocal::get('discountableTotal');
         $discount = MiscLib::truncate2($discount + $extra);
     }
     return $discount;
 }
Exemple #6
0
 function addItem($row, $quantity, $priceObj)
 {
     if ($quantity == 0) {
         return false;
     }
     $pricing = $priceObj->priceInfo($row, $quantity);
     TransRecord::addRecord(array('upc' => $row['upc'], 'description' => $row['description'], 'trans_type' => 'I', 'trans_subtype' => isset($row['trans_subtype']) ? $row['trans_subtype'] : '', 'department' => $row['department'], 'quantity' => $quantity, 'unitPrice' => $pricing['unitPrice'], 'total' => MiscLib::truncate2($pricing['unitPrice'] * $quantity), 'regPrice' => $pricing['regPrice'], 'scale' => $row['scale'], 'tax' => $row['tax'], 'foodstamp' => $row['foodstamp'], 'discount' => $pricing['discount'], 'memDiscount' => $pricing['memDiscount'], 'discountable' => $row['discounttype'] > 0 ? 0 : $row['discount'], 'discounttype' => $row['discounttype'], 'ItemQtty' => $quantity, 'volDiscType' => $row['pricemethod'], 'volume' => $row['quantity'], 'VolSpecial' => $row['groupprice'], 'mixMatch' => $row['mixmatchcode'], 'cost' => isset($row['cost']) ? $row['cost'] * $quantity : 0.0, 'numflag' => isset($row['numflag']) ? $row['numflag'] : 0, 'charflag' => isset($row['charflag']) ? $row['charflag'] : ''));
     return True;
 }
Exemple #7
0
 /**
   Check for errors
   @return True or an error message string
 */
 public function errorCheck()
 {
     global $CORE_LOCAL;
     $this->conn = CoopCredLib::ccDataConnect();
     if ($this->conn === False) {
         return "Error: ccDataConnect() failed.";
     }
     $programOK = CoopCredLib::programOK($this->tender_code, $this->conn);
     if ($programOK !== True) {
         return DisplayLib::boxMsg("{$programOK}");
     }
     $subtotals = CoopCredLib::getCCredSubtotals($this->tender_code, $this->conn);
     if ($subtotals !== True) {
         return DisplayLib::boxMsg("{$subtotals}");
     }
     $pc = $CORE_LOCAL->get("CCredProgramCode");
     //$pc = $CORE_LOCAL->get("programCode");
     /* For Refunding the total without entering the exact amount
      *  i.e. with QA alone.
      */
     if ($this->amount == '' && $this->DefaultTotal() < 0) {
         $this->amount = $this->DefaultTotal();
     }
     /* No Available Balance.
      */
     if ($CORE_LOCAL->get("{$pc}availBal") < 0) {
         return DisplayLib::boxMsg(_("Member") . " #" . $CORE_LOCAL->get("memberID") . ' ' . _("does not have enough Coop Cred in ") . '<b>' . $CORE_LOCAL->get("{$pc}programName") . '</b>' . _(" to cover this purchase."));
     }
     /* Tender more than Available Balance
      * the amount remaining less the amount of this type already tendered
      * in the current transaction.
      * I think availBal already includes memChargeTotal.
      */
     if (abs($CORE_LOCAL->get("{$pc}memChargeTotal")) + $this->amount >= $CORE_LOCAL->get("{$pc}availBal") + 0.005) {
         $memChargeCommitted = $CORE_LOCAL->get("{$pc}availBal") + $CORE_LOCAL->get("{$pc}memChargeTotal");
         return DisplayLib::xboxMsg(_("The amount of Coop Cred you have in ") . '<b>' . $CORE_LOCAL->get("{$pc}programName") . '</b>' . _(" is only \$") . number_format($memChargeCommitted, 2) . '.');
     }
     /* Tender more than Amount Due.
      */
     if (MiscLib::truncate2($CORE_LOCAL->get("amtdue")) < MiscLib::truncate2($this->amount)) {
         return DisplayLib::xboxMsg(_("The amount of Coop Cred tendered may not exceed the Amount Due."));
     }
     /* Add the tender to those used in this transaction.
      */
     if ($CORE_LOCAL->get('CCredTendersUsed') == '') {
         $CORE_LOCAL->set('CCredTendersUsed', array("{$this->tender_code}" => $CORE_LOCAL->get("CCredProgramID")));
     } else {
         $tu = $CORE_LOCAL->get('CCredTendersUsed');
         if (!array_key_exists("{$this->tender_code}", $tu)) {
             $tu["{$this->tender_code}"] = $CORE_LOCAL->get("CCredProgramID");
             $CORE_LOCAL->set('CCredTendersUsed', $tu);
         }
     }
     return true;
     // errorCheck()
 }
 /**
   Check for errors
   @return True or an error message string
 */
 public function errorCheck()
 {
     if (MiscLib::truncate2(CoreLocal::get("amtdue")) < MiscLib::truncate2($this->amount)) {
         return DisplayLib::xboxMsg(_("store transfer exceeds purchase amount"), DisplayLib::standardClearButton());
     }
     $db = Database::pDataConnect();
     $query = 'SELECT chargeOk FROM custdata WHERE chargeOk=1 AND CardNo=' . CoreLocal::get('memberID');
     $result = $db->query($query);
     if ($db->num_rows($result) == 0) {
         return DisplayLib::xboxMsg(_("member cannot make transfers"), DisplayLib::standardClearButton());
     }
     return true;
 }
Exemple #9
0
 function parse($str)
 {
     $ret = $this->default_json();
     $query = "select upc,description,VolSpecial,quantity,\n            total,discount,memDiscount,discountable,\n            unitPrice,scale,foodstamp,voided,discounttype,\n            trans_type,trans_status,department,regPrice,\n            tax,volume,volDiscType\n            from localtemptrans where \n            trans_id = " . CoreLocal::get("currentid");
     $connection = Database::tDataConnect();
     $result = $connection->query($query);
     $num_rows = $connection->num_rows($result);
     if ($num_rows > 0) {
         $row = $connection->fetch_array($result);
         $strUPC = $row["upc"];
         $strDescription = $row["description"];
         $dblVolSpecial = $row["VolSpecial"];
         $dblquantity = -0.5 * $row["quantity"];
         $dblTotal = MiscLib::truncate2(-1 * 0.5 * $row["total"]);
         // invoked truncate2 rounding function to fix half-penny errors apbw 3/7/05
         $strCardNo = CoreLocal::get("memberID");
         $dblDiscount = $row["discount"];
         $dblmemDiscount = $row["memDiscount"];
         $intDiscountable = $row["discountable"];
         $dblUnitPrice = $row["unitPrice"];
         $intScale = MiscLib::nullwrap($row["scale"]);
         if ($row["foodstamp"] != 0) {
             $intFoodStamp = 1;
         } else {
             $intFoodStamp = 0;
         }
         $intdiscounttype = MiscLib::nullwrap($row["discounttype"]);
         if ($row["voided"] == 20) {
             $ret['output'] = DisplayLib::boxMsg(_("Discount already taken"), '', false, DisplayLib::standardClearButton());
         } elseif ($row["trans_type"] == "T" or $row["trans_status"] == "D" or $row["trans_status"] == "V" or $row["trans_status"] == "C") {
             $ret['output'] = DisplayLib::boxMsg(_("Item cannot be discounted"), '', false, DisplayLib::standardClearButton());
         } elseif (strncasecmp($strDescription, "Club Card", 9) == 0) {
             //----- edited by abpw 2/15/05 -----
             $ret['output'] = DisplayLib::boxMsg(_("Item cannot be discounted"), '', false, DisplayLib::standardClearButton());
         } elseif (CoreLocal::get("tenderTotal") < 0 and $intFoodStamp == 1 and -1 * $dblTotal > CoreLocal::get("fsEligible")) {
             $ret['output'] = DisplayLib::boxMsg(_("Item already paid for"), '', false, DisplayLib::standardClearButton());
         } elseif (CoreLocal::get("tenderTotal") < 0 and -1 * $dblTotal > CoreLocal::get("runningTotal") - CoreLocal::get("taxTotal")) {
             $ret['output'] = DisplayLib::boxMsg(_("Item already paid for"), '', false, DisplayLib::standardClearButton());
         } else {
             // --- added partial item desc to club card description - apbw 2/15/05 ---
             TransRecord::addRecord(array('upc' => $strUPC, 'description' => "Club Card: " . substr($strDescription, 0, 19), 'trans_type' => "I", 'trans_status' => "J", 'department' => $row["department"], 'quantity' => $dblquantity, 'unitPrice' => $dblUnitPrice, 'total' => $dblTotal, 'regPrice' => 0.5 * $row["regPrice"], 'scale' => $intScale, 'tax' => $row["tax"], 'foodstamp' => $intFoodStamp, 'discount' => $dblDiscount, 'memDiscount' => $dblmemDiscount, 'discountable' => $intDiscountable, 'discounttype' => $intdiscounttype, 'ItemQtty' => $dblquantity, 'volDiscType' => $row["volDiscType"], 'volume' => $row["volume"], 'VolSpecial' => $dblVolSpecial));
             $update = "update localtemptrans set voided = 20 where trans_id = " . CoreLocal::get("currentid");
             $connection = Database::tDataConnect();
             $connection->query($update);
             CoreLocal::set("TTLflag", 0);
             CoreLocal::set("TTLRequested", 0);
             $ret['output'] = DisplayLib::lastpage();
         }
     }
     return $ret;
 }
Exemple #10
0
 public function priceInfo($row, $quantity = 1)
 {
     if (is_array($this->savedInfo)) {
         return $this->savedInfo;
     }
     $ret = array();
     $ret["regPrice"] = $row['normal_price'];
     $ret["unitPrice"] = $row['normal_price'];
     $ret['discount'] = 0;
     $ret['memDiscount'] = MiscLib::truncate2($row['special_price'] * $quantity);
     if (CoreLocal::get("isMember")) {
         $ret['unitPrice'] -= $row['special_price'];
     }
     $this->savedRow = $row;
     $this->savedInfo = $ret;
     return $ret;
 }
Exemple #11
0
 function parse($str)
 {
     $ret = $this->default_json();
     $left = substr($str, 0, strlen($str) - 2);
     if ($left == "") {
         $left = 1;
     }
     if (strlen($left) > 4) {
         $ret['output'] = DisplayLib::boxMsg(MiscLib::truncate2($left / 100) . _(" tare not supported"), _('Invalid Tare'), false, DisplayLib::standardClearButton());
     } elseif ($left / 100 > CoreLocal::get("weight") && CoreLocal::get("weight") > 0) {
         $ret['output'] = DisplayLib::boxMsg(_("Tare cannot be") . "<br />" . _("greater than item weight"), _('Excess Tare'), false, DisplayLib::standardClearButton());
     } else {
         TransRecord::addTare($left);
         $ret['output'] = DisplayLib::lastpage();
     }
     return $ret;
 }
Exemple #12
0
 /**
   Check for errors
   @return True or an error message string
 */
 public function errorCheck()
 {
     $charge_ok = PrehLib::chargeOk();
     $buttons = array('[clear]' => 'parseWrapper(\'CL\');');
     if ($charge_ok == 0) {
         return DisplayLib::boxMsg(_("member") . ' ' . CoreLocal::get("memberID") . '<br />' . _("is not authorized") . '<br />' . _("to make charges"), 'Not Allowed', false, $buttons);
     } else {
         if (CoreLocal::get("availBal") < 0) {
             return DisplayLib::boxMsg(_("member") . ' ' . CoreLocal::get("memberID") . '<br />' . _("is over limit"), 'Over Limit', false, $buttons);
         } elseif (abs(CoreLocal::get("memChargeTotal")) + $this->amount >= CoreLocal::get("availBal") + 0.005) {
             $memChargeRemain = CoreLocal::get("availBal");
             $memChargeCommitted = $memChargeRemain + CoreLocal::get("memChargeTotal");
             return DisplayLib::xboxMsg(_("available balance for charge") . '<br />' . _("is only \$") . $memChargeCommitted, $buttons);
         } elseif (MiscLib::truncate2(CoreLocal::get("amtdue")) < MiscLib::truncate2($this->amount)) {
             return DisplayLib::xboxMsg(_("charge tender exceeds purchase amount"), $buttons);
         }
     }
     return true;
 }
Exemple #13
0
 public function priceInfo($row, $quantity = 1)
 {
     if (is_array($this->savedInfo)) {
         return $this->savedInfo;
     }
     $ret = array();
     $ret["regPrice"] = $row['normal_price'];
     $ret["unitPrice"] = $row['normal_price'];
     $ret['discount'] = 0;
     $ret['memDiscount'] = 0;
     if (CoreLocal::get("casediscount") > 0 && CoreLocal::get("casediscount") <= 100) {
         $casediscount = (100 - CoreLocal::get("casediscount")) / 100;
         $ret['unitPrice'] = MiscLib::truncate2($casediscount * $ret['unitPrice']);
         $ret['regPrice'] = $ret['unitPrice'];
         CoreLocal::set("casediscount", 0);
     }
     $this->savedRow = $row;
     $this->savedInfo = $ret;
     return $ret;
 }
Exemple #14
0
 public function testMiscLib()
 {
     chdir(dirname(__FILE__) . '/../../pos/is4c-nf/gui-modules/');
     $rel = MiscLib::baseURL();
     $this->assertEquals('../', $rel);
     $this->assertEquals(1, MiscLib::nullwrap(1));
     $this->assertEquals(1.5, MiscLib::nullwrap(1.5));
     $this->assertEquals('test', MiscLib::nullwrap('test'));
     $this->assertEquals(0, MiscLib::nullwrap(False));
     $this->assertEquals(1, MiscLib::truncate2(1));
     $this->assertEquals(1.99, MiscLib::truncate2(1.99));
     $this->assertEquals(1.99, MiscLib::truncate2("1.99"));
     $this->assertEquals(1.35, MiscLib::truncate2("1.345"));
     $hostCheck = MiscLib::pingport(CoreLocal::get('localhost'), CoreLocal::get('DBMS'));
     $this->assertInternalType('integer', $hostCheck);
     $hostCheck = MiscLib::win32();
     $this->assertInternalType('integer', $hostCheck);
     $scale = MiscLib::scaleObject();
     if ($scale !== 0) {
         $this->assertInstanceOf('ScaleDriverWrapper', $scale);
     }
 }
Exemple #15
0
 public function priceInfo($row, $quantity = 1)
 {
     if (is_array($this->savedInfo)) {
         return $this->savedInfo;
     }
     $ret = array();
     $ret["regPrice"] = $row['normal_price'];
     $ret["unitPrice"] = $row['normal_price'];
     $ret['discount'] = 0;
     $ret['memDiscount'] = MiscLib::truncate2(($ret['regPrice'] - $row['special_price']) * $quantity);
     if (CoreLocal::get("isMember") == 1 || CoreLocal::get("memberID") == CoreLocal::get("visitingMem") && CoreLocal::get('visitingMem') !== '') {
         $ret["unitPrice"] = $row['special_price'];
     }
     if ($row['line_item_discountable'] == 1 && CoreLocal::get("itemPD") > 0) {
         $discount = $ret['unitPrice'] * (CoreLocal::get("itemPD") / 100);
         $ret["unitPrice"] -= $discount;
         $ret["discount"] += $discount * $quantity;
     }
     $this->savedRow = $row;
     $this->savedInfo = $ret;
     return $ret;
 }
Exemple #16
0
 function addItem($row, $quantity, $priceObj)
 {
     if ($quantity == 0) {
         return false;
     }
     $pricing = $priceObj->priceInfo($row, $quantity);
     // enforce limit on discounting sale items
     $dsi = CoreLocal::get('DiscountableSaleItems');
     if ($dsi == 0 && $dsi !== '' && $priceObj->isSale()) {
         $row['discount'] = 0;
     }
     if ($priceObj->isSale()) {
         $disc = $pricing['unitPrice'] - $row['specialgroupprice'] / $row['specialquantity'];
         if ($priceObj->isMemberSale() || $priceObj->isStaffSale()) {
             $pricing['memDiscount'] = MiscLib::truncate2($disc * $quantity);
         } else {
             $pricing['discount'] = MiscLib::truncate2($disc * $quantity);
         }
     } else {
         $pricing['unitPrice'] = $row['groupprice'] / $row['quantity'];
     }
     TransRecord::addRecord(array('upc' => $row['upc'], 'description' => $row['description'], 'trans_type' => 'I', 'trans_subtype' => isset($row['trans_subtype']) ? $row['trans_subtype'] : '', 'department' => $row['department'], 'quantity' => $quantity, 'unitPrice' => $pricing['unitPrice'], 'total' => MiscLib::truncate2($pricing['unitPrice'] * $quantity), 'regPrice' => $pricing['regPrice'], 'scale' => $row['scale'], 'tax' => $row['tax'], 'foodstamp' => $row['foodstamp'], 'discount' => $pricing['discount'], 'memDiscount' => $pricing['memDiscount'], 'discountable' => $row['discount'], 'discounttype' => $row['discounttype'], 'ItemQtty' => $quantity, 'volDiscType' => $priceObj->isSale() ? $row['specialpricemethod'] : $row['pricemethod'], 'volume' => $priceObj->isSale() ? $row['specialquantity'] : $row['quantity'], 'VolSpecial' => $priceObj->isSale() ? $row['specialgroupprice'] : $row['groupprice'], 'mixMatch' => $row['mixmatchcode'], 'cost' => isset($row['cost']) ? $row['cost'] * $quantity : 0.0, 'numflag' => isset($row['numflag']) ? $row['numflag'] : 0, 'charflag' => isset($row['charflag']) ? $row['charflag'] : ''));
     return True;
 }
Exemple #17
0
 public function handle($upc, $json)
 {
     /**
       Adjust string index of pieces
       based on whether check digits
       have been included
     */
     $man_id_start = 3;
     $fam_start = 8;
     $val_start = 11;
     if ($this->ean && CoreLocal::get('EanIncludeCheckDigits') == 1 || !$this->ean && CoreLocal::get('UpcIncludeCheckDigits') == 1) {
         $man_id_start = 2;
         $fam_start = 9;
         $val_start = 10;
     }
     $man_id = substr($upc, $man_id_start, 5);
     $fam = substr($upc, $fam_start, 3);
     $val = substr($upc, $val_start, 2);
     $db = Database::pDataConnect();
     $query = "select Value,Qty from couponcodes where Code = '" . $val . "'";
     $result = $db->query($query);
     $num_rows = $db->num_rows($result);
     if ($num_rows == 0) {
         $json['output'] = DisplayLib::boxMsg(_("coupon type unknown") . "<br />" . _("enter coupon manually"), '', false, DisplayLib::standardClearButton());
         return $json;
     }
     $query2 = "SELECT reason, threshold FROM disableCoupon WHERE upc='{$upc}'";
     $result2 = $db->query($query2);
     if ($result2 && $db->num_rows($result2) > 0) {
         $row = $db->fetch_row($result2);
         if ($row['threshold'] <= 0) {
             $json['output'] = DisplayLib::boxMsg($row['reason'], _("coupon disabled"), false, DisplayLib::standardClearButton());
             return $json;
         } else {
             $transDB = Database::tDataConnect();
             $q = "SELECT SUM(quantity) FROM localtemptrans WHERE upc='{$upc}'";
             $r = $transDB->query($q);
             if ($transDB->num_rows($r) > 0) {
                 $w = $transDB->fetch_row($r);
                 $qty = $w[0];
                 if ($qty >= $row['threshold']) {
                     $json['output'] = DisplayLib::boxMsg(_('coupon already applied'), '', false, DisplayLib::standardClearButton());
                     return $json;
                 }
             }
         }
     }
     $row = $db->fetch_array($result);
     $value = $row["Value"];
     $qty = $row["Qty"];
     if ($fam == "992") {
         // 992 basically means blanket accept
         // Old method of asking cashier to assign a department
         // just creates confusion
         // Instead I just try to guess, otherwise use zero
         // (since that's what would happen anyway when the
         // confused cashier does a generic coupon tender)
         $value = MiscLib::truncate2($value);
         CoreLocal::set("couponupc", $upc);
         CoreLocal::set("couponamt", $value);
         $dept = 0;
         $db = Database::tDataConnect();
         // SQL strings are indexed starting w/ one instead of zero
         // hence $man_id_start+1
         $query = "select department from localtemptrans \n                WHERE substring(upc," . ($man_id_start + 1) . ",5)='{$man_id}' \n                GROUP BY department\n                ORDER BY count(*) desc";
         $result = $db->query($query);
         if ($db->num_rows($result) > 0) {
             $row = $db->fetch_row($result);
             $dept = $row['department'];
         }
         TransRecord::addCoupon($upc, $dept, $value);
         $json['output'] = DisplayLib::lastpage();
         return $json;
     }
     // validate coupon
     $db = Database::tDataConnect();
     $fam = substr($fam, 0, 2);
     /* the idea here is to track exactly which
                items in the transaction a coupon was 
                previously applied to
     
                SQL strings are indexed starting w/ one instead of zero
                hence $man_id_start+1
             */
     $query = "select max(t.unitPrice) as unitPrice,\n            max(t.department) as department,\n            max(t.ItemQtty) as itemQtty,\n            sum(case when c.quantity is null then 0 else c.quantity end) as couponQtty,\n            max(case when c.quantity is not null then 0 else t.foodstamp end) as foodstamp,\n            max(case when c.quantity is not null then 0 else t.tax end) as tax,\n            max(t.emp_no) as emp_no,\n            max(t.trans_no) as trans_no,\n            t.trans_id from\n            localtemptrans as t left join couponApplied as c\n            on t.emp_no=c.emp_no and t.trans_no=c.trans_no\n            and t.trans_id=c.trans_id\n            where (substring(t.upc," . ($man_id_start + 1) . ",5)='{$man_id}'";
     /* not right per the standard, but organic valley doesn't
      * provide consistent manufacturer ids in the same goddamn
      * coupon book */
     if ($this->ean) {
         $query .= " or substring(t.upc," . $man_id_start . ",5)='{$man_id}'";
     }
     $query .= ") and t.trans_status <> 'C'\n            group by t.trans_id\n            order by t.unitPrice desc";
     $result = $db->query($query);
     $num_rows = $db->num_rows($result);
     /* no item w/ matching manufacturer */
     if ($num_rows == 0) {
         $json['output'] = DisplayLib::boxMsg(_("product not found") . "<br />" . _("in transaction"), '', false, DisplayLib::standardClearButton());
         return $json;
     }
     /* count up per-item quantites that have not
        yet had a coupon applied to them */
     $available = array();
     $emp_no = $transno = $dept = $foodstamp = $tax = -1;
     $act_qty = 0;
     while ($row = $db->fetch_array($result)) {
         if ($row["itemQtty"] - $row["couponQtty"] > 0) {
             $id = $row["trans_id"];
             $available["{$id}"] = array(0, 0);
             $available["{$id}"][0] = $row["unitPrice"];
             $available["{$id}"][1] += $row["itemQtty"];
             $available["{$id}"][1] -= $row["couponQtty"];
             $act_qty += $available["{$id}"][1];
         }
         if ($emp_no == -1) {
             $emp_no = $row["emp_no"];
             $transno = $row["trans_no"];
             $dept = $row["department"];
             $foodstamp = $row["foodstamp"];
             $tax = $row['tax'];
         }
     }
     /* every line has maximum coupons applied */
     if (count($available) == 0) {
         $json['output'] = DisplayLib::boxMsg(_("Coupon already applied") . "<br />" . _("for this item"), '', false, DisplayLib::standardClearButton());
         return $json;
     }
     /* insufficient number of matching items */
     if ($qty > $act_qty) {
         $msg = sprintf(_("coupon requires %d items"), $qty) . "<br />" . sprintf(_("there are only %d item(s)"), $act_qty) . "<br />" . _("in this transaction");
         $json['output'] = DisplayLib::boxMsg($msg, '', false, DisplayLib::standardClearButton());
         return $json;
     }
     /* free item, multiple choices
        needs work, obviously */
     if ($value == 0 && count($available) > 1) {
         // decide which item(s)
         // manually by cashier maybe?
     }
     /* log the item(s) this coupon is
        being applied to */
     $applied = 0;
     foreach (array_keys($available) as $id) {
         if ($value == 0) {
             $value = -1 * $available["{$id}"][0];
         }
         if ($qty <= $available["{$id}"][1]) {
             $q = "INSERT INTO couponApplied \n                    (emp_no,trans_no,quantity,trans_id)\n                    VALUES (\n                    {$emp_no},{$transno},{$qty},{$id})";
             $r = $db->query($q);
             $applied += $qty;
         } else {
             $q = "INSERT INTO couponApplied \n                    (emp_no,trans_no,quantity,trans_id)\n                    VALUES (\n                    {$emp_no},{$transno}," . $available["{$id}"][1] . ",{$id})";
             $r = $db->query($q);
             $applied += $available["{$id}"][1];
         }
         if ($applied >= $qty) {
             break;
         }
     }
     $value = MiscLib::truncate2($value);
     $json['udpmsg'] = 'goodBeep';
     TransRecord::addCoupon($upc, $dept, $value, $foodstamp, $tax);
     $json['output'] = DisplayLib::lastpage();
     $json['redraw_footer'] = True;
     return $json;
 }
Exemple #18
0
 /**
   Add foodstamp elgibile total record
 */
 public static function fsEligible()
 {
     Database::getsubtotals();
     if (CoreLocal::get("fsEligible") < 0 && False) {
         CoreLocal::set("boxMsg", "Foodstamp eligible amount inapplicable<P>Please void out earlier tender and apply foodstamp first");
         CoreLocal::set('boxMsgButtons', array('Dismiss [clear]' => '$(\'#reginput\').val(\'CL\');submitWrapper();'));
         return MiscLib::baseURL() . "gui-modules/boxMsg2.php";
     } else {
         CoreLocal::set("fntlflag", 1);
         Database::setglobalvalue("FntlFlag", 1);
         if (CoreLocal::get("ttlflag") != 1) {
             return self::ttl();
         } else {
             TransRecord::addRecord(array('description' => 'Foodstamps Eligible', 'trans_type' => '0', 'trans_status' => 'D', 'unitPrice' => MiscLib::truncate2(CoreLocal::get('fsEligible')), 'voided' => 7));
         }
         return true;
     }
 }
Exemple #19
0
 function body_content()
 {
     $result = $this->temp_result;
     $num_rows = $this->temp_num_rows;
     if ($num_rows == 0) {
         $this->productsearchbox(_("no match found") . "<br />" . _("next search or enter upc"));
     } else {
         $this->add_onload_command("selectSubmit('#search', '#selectform', '#filter-span')\n");
         // originally 390
         if (CoreLocal::get('touchscreen')) {
             $maxSelectWidth = 470;
         } else {
             $maxSelectWidth = 530;
         }
         echo "<div class=\"baseHeight\">" . "<div class=\"listbox\">" . "<form name=\"selectform\" method=\"post\" action=\"{$_SERVER['PHP_SELF']}\"" . " id=\"selectform\">" . "<select name=\"search\" id=\"search\" " . ' style="min-height: 200px; min-width: 220px;' . " max-width: {$maxSelectWidth}px;\"" . "size=" . $this->boxSize . " onblur=\"\$('#search').focus();\" " . "ondblclick=\"document.forms['selectform'].submit();\">";
         $selected = "selected";
         foreach ($result as $row) {
             $price = $row["normal_price"];
             if ($row["scale"] != 0) {
                 $Scale = "S";
             } else {
                 $Scale = " ";
             }
             $price = MiscLib::truncate2($price);
             echo "<option value='" . $row["upc"] . "' " . $selected . ">" . $row["upc"] . " - " . $row["description"] . " -- [" . $price . "] " . $Scale . "\n";
             $selected = "";
         }
         echo "</select>" . '<div id="filter-span"></div>' . "</div>";
         if (CoreLocal::get('touchscreen')) {
             echo '<div class="listbox listboxText">' . DisplayLib::touchScreenScrollButtons() . '</div>';
         }
         echo "<div class=\"listboxText coloredText centerOffset\">" . _("use arrow keys") . '<br />' . _("to navigate") . '<br />' . _("the list") . '<p><button type="submit" class="pos-button wide-button coloredArea">
                 OK <span class="smaller">[enter]</span>
                 </button></p>' . '<p><button type="submit" class="pos-button wide-button errorColoredArea"
                 onclick="$(\'#search\').append($(\'<option>\').val(\'\'));$(\'#search\').val(\'\');">
                 Cancel <span class="smaller">[clear]</span>
                 </button></p>' . "</div><!-- /.listboxText coloredText .centerOffset -->" . "</form>" . "<div class=\"clear\"></div>";
         echo "</div>";
     }
     $this->add_onload_command("\$('#search').focus();\n");
 }
Exemple #20
0
 /**
   Calculate the discount based on current
   transaction state
   @return double discount amount
 
   Note return value should be positive unless
   you're doing something odd
 */
 public function calculate($discountable_total = 0)
 {
     if ($discountable_total == 0) {
         $discountable_total = CoreLocal::get('discountableTotal');
     }
     return MiscLib::truncate2($this->my_discount / 100.0 * $discountable_total);
 }
Exemple #21
0
 function addItem($row, $quantity, $priceObj)
 {
     if ($quantity == 0) {
         return false;
     }
     $pricing = $priceObj->priceInfo($row, $quantity);
     $department = $row['department'];
     // enforce limit on discounting sale items
     $dsi = CoreLocal::get('DiscountableSaleItems');
     if ($dsi == 0 && $dsi !== '' && $priceObj->isSale()) {
         $row['discount'] = 0;
     }
     $mixMatch = $row['mixmatchcode'];
     /* group definition: number of items
        that make up a group, price for a
        full set. Use "special" rows if the
        item is on sale */
     $groupQty = $row['quantity'];
     $groupPrice = $row['groupprice'];
     if ($priceObj->isSale()) {
         $groupQty = $row['specialquantity'];
         $groupPrice = $row['specialgroupprice'];
     }
     /* not straight-up interchangable
      * ex: buy item A, get $1 off item B
      * need strict pairs AB 
      *
      * type 3 tries to split the discount amount
      * across A & B's departments; type 4
      * does not 
      */
     $qualMM = abs($mixMatch);
     $discMM = -1 * abs($mixMatch);
     $dbt = Database::tDataConnect();
     // lookup existing qualifiers (i.e., item As)
     // by-weight items are rounded down here
     $q1 = "SELECT floor(sum(ItemQtty)),max(department) \n            FROM localtemptrans WHERE mixMatch='{$qualMM}' \n            and trans_status <> 'R'";
     $r1 = $dbt->query($q1);
     $quals = 0;
     $dept1 = 0;
     if ($dbt->num_rows($r1) > 0) {
         $rowq = $dbt->fetch_row($r1);
         $quals = round($rowq[0]);
         $dept1 = $rowq[1];
     }
     // lookup existing discounters (i.e., item Bs)
     // by-weight items are counted per-line here
     //
     // extra checks to make sure the maximum
     // discount on scale items is "free"
     $q2 = "SELECT sum(CASE WHEN scale=0 THEN ItemQtty ELSE 1 END),\n            max(department),max(scale),max(total) FROM localtemptrans \n            WHERE mixMatch='{$discMM}' \n            and trans_status <> 'R'";
     $r2 = $dbt->query($q2);
     $dept2 = 0;
     $discs = 0;
     $discountIsScale = false;
     $scaleDiscMax = 0;
     if ($dbt->num_rows($r2) > 0) {
         $rowd = $dbt->fetch_row($r2);
         $discs = round($rowd[0]);
         $dept2 = $rowd[1];
         if ($rowd[2] == 1) {
             $discountIsScale = true;
         }
         $scaleDiscMax = $rowd[3];
     }
     if ($quantity != (int) $quantity && $mixMatch < 0) {
         $discountIsScale = true;
         $scaleDiscMax = $quantity * $unitPrice;
     }
     // items that have already been used in an AB set
     $q3 = "SELECT sum(matched) FROM localtemptrans WHERE\n            mixmatch IN ('{$qualMM}','{$discMM}')";
     $r3 = $dbt->query($q3);
     $matches = 0;
     if ($r3 && $dbt->num_rows($r3) > 0) {
         $w3 = $dbt->fetch_row($r3);
         $matches = $w3[0];
     }
     // reduce totals by existing matches
     // implicit: quantity required for B = 1
     // i.e., buy X item A save on 1 item B
     $matches = $matches / $groupQty;
     $quals -= $matches * ($groupQty - 1);
     $discs -= $matches;
     // where does the currently scanned item go?
     if ($mixMatch > 0) {
         $quals = $quals > 0 ? $quals + floor($quantity) : floor($quantity);
         $dept1 = $department;
     } else {
         // again, scaled items count once per line
         if ($quantity != (int) $quantity) {
             $discs = $discs > 0 ? $discs + 1 : 1;
         } else {
             $discs = $discs > 0 ? $discs + $quantity : $quantity;
         }
         $dept2 = $department;
     }
     // count up complete sets
     $sets = 0;
     while ($discs > 0 && $quals >= $groupQty - 1) {
         $discs -= 1;
         $quals -= $groupQty - 1;
         $sets++;
     }
     if ($sets > 0) {
         $maxDiscount = $sets * $groupPrice;
         if ($scaleDiscMax != 0 && $maxDiscount > $scaleDiscMax) {
             $maxDiscount = $scaleDiscMax;
         }
         // if the current item is by-weight, quantity
         // decrement has to be corrected, but matches
         // should still be an integer
         $ttlMatches = $sets;
         if ($quantity != (int) $quantity) {
             $sets = $quantity;
         }
         $quantity = $quantity - $sets;
         TransRecord::addRecord(array('upc' => $row['upc'], 'description' => $row['description'], 'trans_type' => 'I', 'trans_subtype' => isset($row['trans_subtype']) ? $row['trans_subtype'] : '', 'department' => $row['department'], 'quantity' => $sets, 'unitPrice' => $pricing['unitPrice'], 'total' => MiscLib::truncate2($sets * $pricing['unitPrice']), 'regPrice' => $pricing['regPrice'], 'scale' => $row['scale'], 'tax' => $row['tax'], 'foodstamp' => $row['foodstamp'], 'memDiscount' => $priceObj->isMemberSale() || $priceObj->isStaffSale() ? MiscLib::truncate2($maxDiscount) : 0, 'discountable' => $row['discount'], 'discounttype' => $row['discounttype'], 'ItemQtty' => $sets, 'volDiscType' => $priceObj->isSale() ? $row['specialpricemethod'] : $row['pricemethod'], 'volume' => $priceObj->isSale() ? $row['specialquantity'] : $row['quantity'], 'VolSpecial' => $priceObj->isSale() ? $row['specialgroupprice'] : $row['groupprice'], 'mixMatch' => $row['mixmatchcode'], 'matched' => $ttlMatches * $groupQty, 'cost' => isset($row['cost']) ? $row['cost'] * $sets * $groupQty : 0.0, 'numflag' => isset($row['numflag']) ? $row['numflag'] : 0, 'charflag' => isset($row['charflag']) ? $row['charflag'] : ''));
         if (!$priceObj->isMemberSale() && !$priceObj->isStaffSale()) {
             TransRecord::additemdiscount($dept1, MiscLib::truncate2($maxDiscount / 2.0));
             TransRecord::additemdiscount($dept2, MiscLib::truncate2($maxDiscount / 2.0));
         }
     }
     /* any remaining quantity added without
        grouping discount */
     if ($quantity > 0) {
         TransRecord::addRecord(array('upc' => $row['upc'], 'description' => $row['description'], 'trans_type' => 'I', 'trans_subtype' => isset($row['trans_subtype']) ? $row['trans_subtype'] : '', 'department' => $row['department'], 'quantity' => $quantity, 'unitPrice' => $pricing['unitPrice'], 'total' => MiscLib::truncate2($pricing['unitPrice'] * $quantity), 'regPrice' => $pricing['regPrice'], 'scale' => $row['scale'], 'tax' => $row['tax'], 'foodstamp' => $row['foodstamp'], 'discountable' => $row['discount'], 'discounttype' => $row['discounttype'], 'ItemQtty' => $quantity, 'volDiscType' => $priceObj->isSale() ? $row['specialpricemethod'] : $row['pricemethod'], 'volume' => $priceObj->isSale() ? $row['specialquantity'] : $row['quantity'], 'VolSpecial' => $priceObj->isSale() ? $row['specialgroupprice'] : $row['groupprice'], 'mixMatch' => $row['mixmatchcode'], 'cost' => isset($row['cost']) ? $row['cost'] * $quantity : 0.0, 'numflag' => isset($row['numflag']) ? $row['numflag'] : 0, 'charflag' => isset($row['charflag']) ? $row['charflag'] : ''));
     }
     return True;
 }
Exemple #22
0
 function addItem($row, $quantity, $priceObj)
 {
     if ($quantity == 0) {
         return false;
     }
     $pricing = $priceObj->priceInfo($row, $quantity);
     // enforce limit on discounting sale items
     $dsi = CoreLocal::get('DiscountableSaleItems');
     if ($dsi == 0 && $dsi !== '' && $priceObj->isSale()) {
         $row['discount'] = 0;
     }
     /* group definition: number of items
        that make up a group, price for a
        full set. Use "special" rows if the
        item is on sale */
     $groupQty = $row['quantity'];
     $groupPrice = $row['groupprice'];
     if ($priceObj->isSale()) {
         $groupQty = $row['specialquantity'];
         $groupPrice = $row['specialgroupprice'];
     }
     /* calculate how many complete sets are
        present in this scan and how many remain
        after complete sets */
     $new_sets = floor($quantity / $groupQty);
     $remainder = $quantity % $groupQty;
     /* add complete sets */
     if ($new_sets > 0) {
         $percentDiscount = 0;
         if (!$priceObj->isSale() && $pricing['unitPrice'] != $row['normal_price']) {
             $percentDiscount = ($row['normal_price'] - $pricing['unitPrice']) / $row['normal_price'];
             $groupPrice *= 1 - $percentDiscount;
         } else {
             if ($priceObj->isSale() && $pricing['unitPrice'] != $row['special_price']) {
                 $percentDiscount = ($row['special_price'] - $pricing['unitPrice']) / $row['special_price'];
                 $groupPrice *= 1 - $percentDiscount;
             }
         }
         /* discount for complete set */
         $discount = $new_sets * ($pricing['unitPrice'] * $groupQty - $groupPrice);
         $total = $new_sets * $groupQty * $pricing['unitPrice'] - $discount;
         $unit = $total / ($new_sets * $groupQty);
         $memDiscount = 0;
         if ($priceObj->isMemberSale() || $priceObj->isStaffSale()) {
             $memDiscount = $discount;
             $discount = 0;
         }
         TransRecord::addRecord(array('upc' => $row['upc'], 'description' => $row['description'], 'trans_type' => 'I', 'trans_subtype' => isset($row['trans_subtype']) ? $row['trans_subtype'] : '', 'department' => $row['department'], 'quantity' => $new_sets * $groupQty, 'unitPrice' => MiscLib::truncate2($unit), 'total' => MiscLib::truncate2($total), 'regPrice' => $pricing['regPrice'], 'scale' => $row['scale'], 'tax' => $row['tax'], 'foodstamp' => $row['foodstamp'], 'discount' => $discount, 'memDiscount' => $memDiscount, 'discountable' => $row['discount'], 'discounttype' => $row['discounttype'], 'ItemQtty' => $new_sets * $groupQty, 'volDiscType' => $priceObj->isSale() ? $row['specialpricemethod'] : $row['pricemethod'], 'volume' => $priceObj->isSale() ? $row['specialquantity'] : $row['quantity'], 'VolSpecial' => $priceObj->isSale() ? $row['specialgroupprice'] : $row['groupprice'], 'mixMatch' => $row['mixmatchcode'], 'matched' => $new_sets * $groupQty, 'cost' => isset($row['cost']) ? $row['cost'] * $new_sets * $groupQty : 0.0, 'numflag' => isset($row['numflag']) ? $row['numflag'] : 0, 'charflag' => isset($row['charflag']) ? $row['charflag'] : ''));
         if ($percentDiscount != 0) {
             $discount -= $pricing['discount'];
         }
         TransRecord::adddiscount($discount, $row['department']);
         $quantity = $quantity - $new_sets * $groupQty;
         if ($quantity < 0) {
             $quantity = 0;
         }
     }
     /* if potential matches remain, check for sets */
     if ($remainder > 0) {
         /* count items in the transaction
            from the given group, minus
            items that have already been used
            in a grouping */
         $mixMatch = $row["mixmatchcode"];
         $queryt = "select sum(ItemQtty - matched) as mmqtty, \n                mixMatch from localtemptrans \n                where trans_status <> 'R' AND \n                mixMatch = '" . $mixMatch . "' group by mixMatch";
         if (!$mixMatch || $mixMatch == '0') {
             $mixMatch = 0;
             $queryt = "select sum(ItemQtty - matched) as mmqtty from " . "localtemptrans where trans_status<>'R' AND " . "upc = '" . $row['upc'] . "' group by upc";
         }
         $dbt = Database::tDataConnect();
         $resultt = $dbt->query($queryt);
         $num_rowst = $dbt->num_rows($resultt);
         $trans_qty = 0;
         if ($num_rowst > 0) {
             $rowt = $dbt->fetch_array($resultt);
             $trans_qty = floor($rowt['mmqtty']);
         }
         /* remainder from current scan plus existing
            unmatched items complete a new set, so
            add one item with the group discount */
         if ($trans_qty + $remainder >= $groupQty) {
             /* adjusted price for the "last" item in a set */
             $priceAdjust = $groupPrice - ($groupQty - 1) * $pricing['unitPrice'];
             $discount = $pricing['unitPrice'] - $priceAdjust;
             $memDiscount = 0;
             if ($priceObj->isMemberSale() || $priceObj->isStaffSale()) {
                 $memDiscount = $discount;
                 $discount = 0;
             }
             TransRecord::addRecord(array('upc' => $row['upc'], 'description' => $row['description'], 'trans_type' => 'I', 'trans_subtype' => isset($row['trans_subtype']) ? $row['trans_subtype'] : '', 'department' => $row['department'], 'quantity' => 1, 'unitPrice' => $pricing['unitPrice'] - $discount, 'total' => $pricing['unitPrice'] - $discount, 'regPrice' => $pricing['regPrice'], 'scale' => $row['scale'], 'tax' => $row['tax'], 'foodstamp' => $row['foodstamp'], 'discount' => $discount, 'memDiscount' => $memDiscount, 'discountable' => $row['discount'], 'discounttype' => $row['discounttype'], 'ItemQtty' => 1, 'volDiscType' => $priceObj->isSale() ? $row['specialpricemethod'] : $row['pricemethod'], 'volume' => $priceObj->isSale() ? $row['specialquantity'] : $row['quantity'], 'VolSpecial' => $priceObj->isSale() ? $row['specialgroupprice'] : $row['groupprice'], 'mixMatch' => $row['mixmatchcode'], 'matched' => $groupQty, 'cost' => isset($row['cost']) ? $row['cost'] * $new_sets * $groupQty : 0.0, 'numflag' => isset($row['numflag']) ? $row['numflag'] : 0, 'charflag' => isset($row['charflag']) ? $row['charflag'] : ''));
             $quantity -= 1;
             if ($quantity < 0) {
                 $quantity = 0;
             }
         }
     }
     /* any remaining quantity added without
        grouping discount */
     if ($quantity > 0) {
         TransRecord::addRecord(array('upc' => $row['upc'], 'description' => $row['description'], 'trans_type' => 'I', 'trans_subtype' => isset($row['trans_subtype']) ? $row['trans_subtype'] : '', 'department' => $row['department'], 'quantity' => $quantity, 'unitPrice' => $pricing['unitPrice'], 'total' => MiscLib::truncate2($pricing['unitPrice'] * $quantity), 'regPrice' => $pricing['regPrice'], 'scale' => $row['scale'], 'tax' => $row['tax'], 'foodstamp' => $row['foodstamp'], 'discountable' => $row['discount'], 'discounttype' => $row['discounttype'], 'ItemQtty' => $quantity, 'volDiscType' => $priceObj->isSale() ? $row['specialpricemethod'] : $row['pricemethod'], 'volume' => $priceObj->isSale() ? $row['specialquantity'] : $row['quantity'], 'VolSpecial' => $priceObj->isSale() ? $row['specialgroupprice'] : $row['groupprice'], 'mixMatch' => $row['mixmatchcode'], 'cost' => isset($row['cost']) ? $row['cost'] * $quantity : 0.0, 'numflag' => isset($row['numflag']) ? $row['numflag'] : 0, 'charflag' => isset($row['charflag']) ? $row['charflag'] : ''));
     }
     return True;
 }
Exemple #23
0
 private function rewriteScaleSticker($upc)
 {
     $scalePrefix = '002';
     $scaleStickerItem = false;
     $scaleCheckDigits = false;
     if (CoreLocal::get('UpcIncludeCheckDigits') == 1) {
         $scalePrefix = '02';
         $scaleCheckDigits = true;
     }
     $scalepriceUPC = 0;
     $scalepriceEAN = 0;
     // prefix indicates it is a scale-sticker
     if (substr($upc, 0, strlen($scalePrefix)) == $scalePrefix) {
         $scaleStickerItem = true;
         // extract price portion of the barcode
         // position varies depending whether a check
         // digit is present in the upc
         if ($scaleCheckDigits) {
             $scalepriceUPC = MiscLib::truncate2(substr($upc, 8, 4) / 100);
             $scalepriceEAN = MiscLib::truncate2(substr($upc, 7, 5) / 100);
         } else {
             $scalepriceUPC = MiscLib::truncate2(substr($upc, -4) / 100);
             $scalepriceEAN = MiscLib::truncate2(substr($upc, -5) / 100);
         }
         $rewrite_class = CoreLocal::get('VariableWeightReWriter');
         if ($rewrite_class === '' || !class_exists($rewrite_class)) {
             $rewrite_class = 'ZeroedPriceReWrite';
         }
         $rewriter = new $rewrite_class();
         $upc = $rewriter->translate($upc, $scaleCheckDigits);
         // I think this is WFC special casing; needs revising.
         if ($upc == "0020006000000" || $upc == "0020010000000") {
             $scalepriceUPC *= -1;
         }
     }
     return array($scaleStickerItem, $scalepriceUPC, $scalepriceEAN);
 }
Exemple #24
0
 public static function frankgiftcert($amount)
 {
     $ref = trim(CoreLocal::get("CashierNo")) . "-" . trim(CoreLocal::get("laneno")) . "-" . trim(CoreLocal::get("transno"));
     $time_now = strftime("%m/%d/%y", time());
     // apbw 3/10/05 "%D" didn't work - Franking patch
     $next_year_stamp = mktime(0, 0, 0, date("m"), date("d"), date("Y") + 1);
     $next_year = strftime("%m/%d/%y", $next_year_stamp);
     // apbw 3/10/05 "%D" didn't work - Franking patch
     // lines 200-207 edited 03/24/05 apbw Wedge Printer Swap Patch
     $output = "";
     $output .= str_repeat("\n", 6);
     $output .= "ref: " . $ref . "\n";
     $output .= str_repeat(" ", 5) . $time_now;
     $output .= str_repeat(" ", 12) . $next_year;
     $output .= str_repeat("\n", 3);
     $output .= str_repeat(" ", 75);
     $output .= "\$" . MiscLib::truncate2($amount);
     self::endorse($output);
 }
Exemple #25
0
 /**
   Add cash drop record
 */
 public static function addCashDrop($amt)
 {
     self::addRecord(array('upc' => 'DROP', 'description' => 'Cash Drop', 'trans_type' => 'I', 'trans_status' => 'X', 'quantity' => 1, 'unitPrice' => MiscLib::truncate2(-1 * $amt), 'total' => MiscLib::truncate2(-1 * $amt), 'ItemQtty' => 1, 'charflag' => 'CD'));
 }
Exemple #26
0
 function addItem($row, $quantity, $priceObj)
 {
     if ($quantity == 0) {
         return false;
     }
     $pricing = $priceObj->priceInfo($row, $quantity);
     // enforce limit on discounting sale items
     $dsi = CoreLocal::get('DiscountableSaleItems');
     if ($dsi == 0 && $dsi !== '' && $priceObj->isSale()) {
         $row['discount'] = 0;
     }
     $stem = substr($mixMatch, 0, 10);
     $sets = 99;
     // count up total sets
     for ($i = 0; $i <= $volume; $i++) {
         $tmp = $stem . "_q" . $i;
         if ($volume == $i) {
             $tmp = $stem . '_d';
         }
         $chkQ = "SELECT sum(CASE WHEN scale=0 THEN ItemQtty ELSE 1 END) \n                FROM localtemptrans WHERE mixmatch='{$tmp}' \n                and trans_status<>'R'";
         $chkR = $dbt->query($chkQ);
         $tsets = 0;
         if ($dbt->num_rows($chkR) > 0) {
             $tsets = array_pop($dbt->fetch_row($chkR));
         }
         if ($tmp == $mixMatch) {
             $tsets += is_int($quantity) ? $quantity : 1;
         }
         if ($tsets < $sets) {
             $sets = $tsets;
         }
         // item not found, no point continuing
         if ($sets == 0) {
             break;
         }
     }
     // count existing sets
     $matches = 0;
     $mQ = "SELECT sum(matched) FROM localtemptrans WHERE\n            left(mixmatch,11)='{$stem}_'";
     $mR = $dbt->query($mQ);
     if ($dbt->num_rows($mR) > 0) {
         $matches = array_pop($dbt->fetch_row($mR));
     }
     $sets -= $matches;
     // this means the current item
     // completes a new set
     if ($sets > 0) {
         if ($priceObj->isSale()) {
             if ($priceObj->isMemberSale() || $priceObj->isStaffSale()) {
                 $pricing['memDiscount'] = MiscLib::truncate2($row['specialgroupprice'] * $quantity);
             } else {
                 $pricing['discount'] = MiscLib::truncate2($row['specialgroupprice'] * $quantity);
             }
         } else {
             $pricing['unitPrice'] = $pricing['unitPrice'] - $row['specialgroupprice'];
         }
         TransRecord::addRecord(array('upc' => $row['upc'], 'description' => $row['description'], 'trans_type' => 'I', 'trans_subtype' => isset($row['trans_subtype']) ? $row['trans_subtype'] : '', 'department' => $row['department'], 'quantity' => $quantity, 'unitPrice' => $pricing['unitPrice'], 'total' => MiscLib::truncate2($pricing['unitPrice'] * $quantity), 'regPrice' => $pricing['regPrice'], 'scale' => $row['scale'], 'tax' => $row['tax'], 'foodstamp' => $row['foodstamp'], 'discount' => $pricing['discount'], 'memDiscount' => $pricing['memDiscount'], 'discountable' => $row['discount'], 'discounttype' => $row['discounttype'], 'ItemQtty' => $quantity, 'volDiscType' => $priceObj->isSale() ? $row['specialpricemethod'] : $row['pricemethod'], 'volume' => $priceObj->isSale() ? $row['specialquantity'] : $row['quantity'], 'VolSpecial' => $priceObj->isSale() ? $row['specialgroupprice'] : $row['groupprice'], 'mixmatch' => $row['mixmatchcode'], 'matched' => $sets, 'cost' => isset($row['cost']) ? $row['cost'] * $quantity : 0.0, 'numflag' => isset($row['numflag']) ? $row['numflag'] : 0, 'charflag' => isset($row['charflag']) ? $row['charflag'] : ''));
     } else {
         // not a new set, treat as a regular item
         TransRecord::addRecord(array('upc' => $row['upc'], 'description' => $row['description'], 'trans_type' => 'I', 'trans_subtype' => isset($row['trans_subtype']) ? $row['trans_subtype'] : '', 'department' => $row['department'], 'quantity' => $quantity, 'unitPrice' => $pricing['unitPrice'], 'total' => MiscLib::truncate2($pricing['unitPrice'] * $quantity), 'regPrice' => $pricing['regPrice'], 'scale' => $row['scale'], 'tax' => $row['tax'], 'foodstamp' => $row['foodstamp'], 'discount' => $pricing['discount'], 'memDiscount' => $pricing['memDiscount'], 'discountable' => $row['discount'], 'discounttype' => $row['discounttype'], 'ItemQtty' => $quantity, 'volDiscType' => $row['pricemethod'], 'volume' => $row['quantity'], 'VolSpecial' => $row['groupprice'], 'mixMatch' => $row['mixmatchcode'], 'cost' => isset($row['cost']) ? $row['cost'] * $quantity : 0.0, 'numflag' => isset($row['numflag']) ? $row['numflag'] : 0, 'charflag' => isset($row['charflag']) ? $row['charflag'] : ''));
     }
     return True;
 }
Exemple #27
0
 /**
   Calculate taxes using new-style taxView.
   @return an array of records each containing:
     - id
     - description
     - amount (taxes actually due)
     - exempt (taxes exempted because of foodstamps) 
   There will always be one record for each existing tax rate.
 */
 public static function LineItemTaxes()
 {
     $db = Database::tDataConnect();
     $q = "SELECT id, description, taxTotal, fsTaxable, fsTaxTotal, foodstampTender, taxrate\n        FROM taxView ORDER BY taxrate DESC";
     $r = $db->query($q);
     $taxRows = array();
     $fsTenderTTL = 0.0;
     while ($w = $db->fetch_row($r)) {
         $w['fsExempt'] = 0.0;
         $taxRows[] = $w;
         $fsTenderTTL = $w['foodstampTender'];
     }
     // loop through line items and deal with
     // foodstamp tax exemptions
     for ($i = 0; $i < count($taxRows); $i++) {
         if (abs($fsTenderTTL) <= 0.005) {
             continue;
         }
         if (abs($fsTenderTTL - $taxRows[$i]['fsTaxable']) < 0.005) {
             // CASE 1:
             //    Available foodstamp tender matches foodstamp taxable total
             //    Decrement line item tax by foodstamp tax total
             //    No FS tender left, so exemption ends
             $taxRows[$i]['taxTotal'] = MiscLib::truncate2($taxRows[$i]['taxTotal'] - $taxRows[$i]['fsTaxTotal']);
             $taxRows[$i]['fsExempt'] = $taxRows[$i]['fsTaxTotal'];
             $fsTenderTTL = 0;
         } else {
             if ($fsTenderTTL > $taxRows[$i]['fsTaxable']) {
                 // CASE 2:
                 //    Available foodstamp tender exeeds foodstamp taxable total
                 //    Decrement line item tax by foodstamp tax total
                 //    Decrement foodstamp tender total to reflect amount not yet applied
                 $taxRows[$i]['taxTotal'] = MiscLib::truncate2($taxRows[$i]['taxTotal'] - $taxRows[$i]['fsTaxTotal']);
                 $taxRows[$i]['fsExempt'] = $taxRows[$i]['fsTaxTotal'];
                 $fsTenderTTL = MiscLib::truncate2($fsTenderTTL - $taxRows[$i]['fsTaxable']);
             } else {
                 // CASE 3:
                 //    Available foodstamp tender is less than foodstamp taxable total
                 //    Decrement line item tax proprotionally to foodstamp tender available
                 //    No FS tender left, so exemption ends
                 $percentageApplied = $fsTenderTTL / $taxRows[$i]['fsTaxable'];
                 $exemption = MiscLib::truncate2($taxRows[$i]['fsTaxTotal'] * $percentageApplied);
                 $taxRows[$i]['taxTotal'] = MiscLib::truncate2($taxRows[$i]['taxTotal'] - $exemption);
                 $taxRows[$i]['fsExempt'] = $exemption;
                 $fsTenderTTL = 0;
             }
         }
     }
     $ret = array();
     foreach ($taxRows as $tr) {
         $ret[] = array('rate_id' => $tr['id'], 'description' => $tr['description'], 'amount' => $tr['taxTotal'], 'exempt' => $tr['fsExempt']);
     }
     return $ret;
 }
Exemple #28
0
 private function validateRequirement(&$req, &$json)
 {
     $db = Database::tDataConnect();
     /* simple case first; just wants total transaction value 
           no company prefixing
        */
     if ($req['code'] == 2) {
         $q = "SELECT SUM(total) FROM localtemptrans WHERE\n                trans_type IN ('I','D','M')";
         $r = $db->query($q);
         $ttl_required = MiscLib::truncate2($req['value'] / 100.0);
         if ($db->num_rows($r) == 0) {
             $json['output'] = DisplayLib::boxMsg("Coupon requires transaction of at least \${$ttl_required}");
             return false;
         }
         $w = $dbc->fetch_row($r);
         if ($w[0] < $ttl_required) {
             $json['output'] = DisplayLib::boxMsg("Coupon requires transaction of at least \${$ttl_required}");
             return false;
         }
         return true;
     }
     $query = sprintf("SELECT\n            max(CASE WHEN trans_status<>'C' THEN unitPrice ELSE 0 END) as price,\n            sum(CASE WHEN trans_status<>'C' THEN total ELSE 0 END) as total,\n            max(department) as department,\n            sum(CASE WHEN trans_status<>'C' THEN ItemQtty ELSE 0 END) as qty,\n            sum(CASE WHEN trans_status='C' THEN 1 ELSE 0 END) as couponqtty\n            FROM localtemptrans WHERE\n            substring(upc,2,%d) = '%s'", strlen($req['man_id']), $req['man_id']);
     $result = $db->query($query);
     if ($db->num_rows($result) <= 0) {
         $json['output'] = DisplayLib::boxMsg("Coupon requirements not met");
         return false;
     }
     $row = $db->fetch_row($result);
     $req['price'] = $row['price'];
     switch ($req['code']) {
         case '0':
             // various qtty requirements
         // various qtty requirements
         case '3':
         case '4':
             $available_qty = $row['qty'] - $row['couponqtty'] * $req['value'];
             if ($available_qty < $req['value']) {
                 // Coupon requirement not met
                 if ($row['couponqtty'] > 0) {
                     $json['output'] = DisplayLib::boxMsg("Coupon already applied");
                 } else {
                     $json['output'] = DisplayLib::boxMsg("Coupon requires " . $req['value'] . " items");
                 }
                 return false;
             }
             break;
         case '1':
             $available_ttl = $row['total'] - $row['couponqtty'] * $req['value'];
             if ($available_ttl < $req['value']) {
                 // Coupon requirement not met
                 if ($row['couponqtty'] > 0) {
                     $json['output'] = DisplayLib::boxMsg("Coupon already applied");
                 } else {
                     $json['output'] = DisplayLib::boxMsg("Coupon requires " . $req['value'] . " items");
                 }
                 return false;
             }
             break;
         case '9':
             $json['output'] = DisplayLib::boxMsg("Tender coupon manually");
             return false;
         default:
             $json['output'] = DisplayLib::boxMsg("Error: bad coupon");
             return false;
     }
     return true;
     // requirement validated
 }
Exemple #29
0
 function addItem($row, $quantity, $priceObj)
 {
     if ($quantity == 0) {
         return false;
     }
     // enforce limit on discounting sale items
     $dsi = CoreLocal::get('DiscountableSaleItems');
     if ($dsi == 0 && $dsi !== '' && $priceObj->isSale()) {
         $row['discount'] = 0;
     }
     $pricing = $priceObj->priceInfo($row, $quantity);
     /* group definition: number of items
        that make up a group, price for a
        full set. Use "special" rows if the
        item is on sale */
     $groupQty = $row['quantity'];
     $groupPrice = $row['groupprice'];
     if ($priceObj->isSale()) {
         $groupQty = $row['specialquantity'];
         $groupPrice = $row['specialgroupprice'];
     }
     /* count items in the transaction
                from the given group 
     
                Also note the total of items already
                rung in that did not receive a discount
             */
     $mixMatch = $row["mixmatchcode"];
     $queryt = "select sum(ItemQtty) as mmqtty, \n            sum(CASE WHEN discount=0 THEN total ELSE 0 END) as unDiscountedTotal,\n            mixMatch from localtemptrans \n            where trans_status <> 'R' AND \n            mixMatch = '" . $mixMatch . "' group by mixMatch";
     if (!$mixMatch || $mixMatch == '0') {
         $mixMatch = 0;
         $queryt = "select sum(ItemQtty) as mmqtty, \n                sum(CASE WHEN discount=0 THEN total ELSE 0 END) as unDiscountedTotal,\n                from " . "localtemptrans where trans_status<>'R' AND " . "upc = '" . $row['upc'] . "' group by upc";
     }
     $dbt = Database::tDataConnect();
     $resultt = $dbt->query($queryt);
     $num_rowst = $dbt->num_rows($resultt);
     $trans_qty = 0;
     $undisc_ttl = 0;
     if ($num_rowst > 0) {
         $rowt = $dbt->fetch_array($resultt);
         $trans_qty = floor($rowt['mmqtty']);
         $undisc_ttl = $rowt['unDiscountedTotal'];
     }
     /* include the items in this ring */
     $trans_qty += $quantity;
     /* if purchases exceed then requirement, apply
        the discount */
     if ($trans_qty >= $groupQty) {
         $discountAmt = $pricing['unitPrice'] * $groupPrice;
         if ($trans_qty - $quantity < $groupQty) {
             /* this ring puts us over the threshold.
                extra math to account for discount on
                previously rung items */
             $totalDiscount = $undisc_ttl * $groupPrice + $discountAmt * $quantity;
             $actualTotal = $pricing['unitPrice'] * $quantity - $totalDiscount;
             $pricing['discount'] = $totalDiscount;
             $pricing['unitPrice'] = $actualTotal / $quantity;
         } else {
             $pricing['discount'] = $discountAmt * $quantity;
             $pricing['unitPrice'] -= $discountAmt;
         }
     }
     /* add the item */
     TransRecord::addRecord(array('upc' => $row['upc'], 'description' => $row['description'], 'trans_type' => 'I', 'trans_subtype' => isset($row['trans_subtype']) ? $row['trans_subtype'] : '', 'department' => $row['department'], 'quantity' => $quantity, 'unitPrice' => $pricing['unitPrice'], 'total' => MiscLib::truncate2($pricing['unitPrice'] * $quantity), 'regPrice' => $pricing['regPrice'], 'scale' => $row['scale'], 'tax' => $row['tax'], 'foodstamp' => $row['foodstamp'], 'discount' => $pricing['discount'], 'discountable' => $row['discount'], 'discounttype' => $row['discounttype'], 'ItemQtty' => $quantity, 'volDiscType' => $priceObj->isSale() ? $row['specialpricemethod'] : $row['pricemethod'], 'volume' => $priceObj->isSale() ? $row['specialquantity'] : $row['quantity'], 'VolSpecial' => $priceObj->isSale() ? $row['specialgroupprice'] : $row['groupprice'], 'mixMatch' => $row['mixmatchcode'], 'cost' => isset($row['cost']) ? $row['cost'] * $quantity : 0.0, 'numflag' => isset($row['numflag']) ? $row['numflag'] : 0, 'charflag' => isset($row['charflag']) ? $row['charflag'] : ''));
     return True;
 }
Exemple #30
0
 private function addStaffCoffeeDiscount()
 {
     if (CoreLocal::get("staffCoffeeDiscount") != 0) {
         self::addItem("DISCOUNT", "** Coffee Discount **", "I", "", "", 0, 1, MiscLib::truncate2(-1 * CoreLocal::get("staffCoffeeDiscount")), MiscLib::truncate2(-1 * CoreLocal::get("staffCoffeeDiscount")), 0, 0, 0, 0, 0, 0, 1, 0, 1, 0, 0, 0, 0, 0, 2);
     }
 }