コード例 #1
0
ファイル: MemberID.php プロジェクト: phpsmith/IS4C
 function parse($str)
 {
     if ($str == "0ID") {
         // Member zero clears member info from the transaction
         PrehLib::clearMember();
         $ret = array("main_frame" => false, "output" => DisplayLib::lastpage(), "target" => ".baseHeight", "redraw_footer" => true);
         return $ret;
     } else {
         if (CoreLocal::get('RestrictDefaultNonMem') == 1 && $str == CoreLocal::get('defaultNonMem') . 'ID') {
             // PrehLib::ttl will automatically prompt for member if it
             // has not been entered; otherwise just total
             $ret = $this->default_json();
             $try = PrehLib::ttl();
             if ($try !== true) {
                 $ret['main_frame'] = $try . '?idSearch=' . CoreLocal::get('defaultNonMem');
             } else {
                 $ret['output'] = DisplayLib::lastpage();
             }
             return $ret;
         } else {
             // always re-apply other member numbers
             $ret = PrehLib::memberID(substr($str, 0, strlen($str) - 2));
             return $ret;
         }
     }
 }
コード例 #2
0
ファイル: posCustDisplay.php プロジェクト: phpsmith/IS4C
 public function body_content()
 {
     echo $this->noinput_header();
     ?>
     <div class="baseHeight">
     <?php 
     if (CoreLocal::get("plainmsg") && strlen(CoreLocal::get("plainmsg")) > 0) {
         echo DisplayLib::printheaderb();
         echo "<div class=\"centerOffset\">";
         echo DisplayLib::plainmsg(CoreLocal::get("plainmsg"));
         echo "</div>";
     } else {
         // No input and no messages, so
         // list the items
         if (CoreLocal::get("End") == 1) {
             echo DisplayLib::printReceiptfooter(true);
         } else {
             echo DisplayLib::lastpage(true);
         }
     }
     echo "</div>";
     // end base height
     echo "<div id=\"footer\">";
     echo DisplayLib::printfooter(true);
     echo '</div>';
 }
コード例 #3
0
ファイル: PartialReceipt.php プロジェクト: phpsmith/IS4C
 function parse($str)
 {
     $ret = $this->default_json();
     $ret['receipt'] = 'partial';
     $ret['output'] = DisplayLib::lastpage();
     return $ret;
 }
コード例 #4
0
ファイル: TenderOut.php プロジェクト: phpsmith/IS4C
 function tender_out($asTender)
 {
     $ret = $this->default_json();
     Database::getsubtotals();
     if (CoreLocal::get("amtdue") <= 0.005) {
         CoreLocal::set("change", -1 * CoreLocal::get("amtdue"));
         $cash_return = CoreLocal::get("change");
         if ($asTender != "FS") {
             TransRecord::addchange($cash_return, 'CA');
         }
         CoreLocal::set("End", 1);
         $ret['output'] = DisplayLib::printReceiptFooter();
         $ret['redraw_footer'] = true;
         $ret['receipt'] = 'full';
         TransRecord::finalizeTransaction();
     } else {
         CoreLocal::set("change", 0);
         CoreLocal::set("fntlflag", 0);
         $ttl_result = PrehLib::ttl();
         TransRecord::debugLog('Tender Out (PrehLib): ' . print_r($ttl_result, true));
         TransRecord::debugLog('Tender Out (amtdue): ' . print_r(CoreLocal::get('amtdue'), true));
         $ret['output'] = DisplayLib::lastpage();
     }
     return $ret;
 }
コード例 #5
0
ファイル: AccessProgramParser.php プロジェクト: phpsmith/IS4C
 public function parse($str)
 {
     $ret = $this->default_json();
     if (CoreLocal::get('memberID') == '0') {
         $ret['output'] = DisplayLib::boxMsg(_("Apply member number first"), _('No member selected'), false, array_merge(array('Member Search [ID]' => 'parseWrapper(\'ID\');'), DisplayLib::standardClearButton()));
         return $ret;
     }
     if ($str == 'ACCESS') {
         if (CoreLocal::get('AccessQuickMenu') != '' && class_exists('QuickMenuLauncher')) {
             $qm = new QuickMenuLauncher();
             return $qm->parse('QM' . CoreLocal::get('AccessQuickMenu'));
         } else {
             $str = 'ACCESS0';
         }
     }
     if ($str !== 'ACCESS6' && CoreLocal::get('AccessSelection') === '') {
         CoreLocal::set('AccessSelection', $str);
         $ret['main_frame'] = MiscLib::baseURL() . 'gui-modules/adminlogin.php?class=AccessProgramParser';
         return $ret;
     } else {
         CoreLocal::set('AccessSelection', '');
     }
     $selection = substr($str, 6);
     TransRecord::addRecord(array('upc' => 'ACCESS', 'description' => 'ACCESS SIGNUP', 'quantity' => 1, 'ItemQtty' => 1, 'numflag' => $selection));
     $ret['output'] = DisplayLib::lastpage();
     $ret['receipt'] = 'accessSignupSlip';
     return $ret;
 }
コード例 #6
0
ファイル: Totals.php プロジェクト: phpsmith/IS4C
 function parse($str)
 {
     $ret = $this->default_json();
     if ($str == "FNTL") {
         $ret['main_frame'] = MiscLib::base_url() . 'gui-modules/fsTotalConfirm.php';
     } elseif ($str == "TETL") {
         $ret['main_frame'] = MiscLib::base_url() . 'gui-modules/requestInfo.php?class=Totals';
     } elseif ($str == "FTTL") {
         PrehLib::finalttl();
     } elseif ($str == "TL") {
         CoreLocal::set('End', 0);
         $chk = PrehLib::ttl();
         if ($chk !== True) {
             $ret['main_frame'] = $chk;
         }
     } elseif ($str == "MTL") {
         $chk = PrehLib::omtr_ttl();
         if ($chk !== True) {
             $ret['main_frame'] = $chk;
         }
     } elseif ($str == "WICTL") {
         $ttl = PrehLib::wicableTotal();
         $ret['output'] = DisplayLib::boxMsg(_('WIC Total') . sprintf(': $%.2f', $ttl), '', true, DisplayLib::standardClearButton());
         // return early since output has been set
         return $ret;
     }
     if (!$ret['main_frame']) {
         $ret['output'] = DisplayLib::lastpage();
         $ret['redraw_footer'] = True;
     }
     return $ret;
 }
コード例 #7
0
ファイル: Comment.php プロジェクト: phpsmith/IS4C
 function parse($str)
 {
     $ret = $this->default_json();
     if (strlen($str) > 2) {
         $comment = substr($str, 2);
         TransRecord::addcomment($comment);
         $ret['output'] = DisplayLib::lastpage();
     } else {
         $ret['main_frame'] = MiscLib::base_url() . 'gui-modules/bigComment.php';
     }
     return $ret;
 }
コード例 #8
0
ファイル: ClubCard.php プロジェクト: phpsmith/IS4C
 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;
 }
コード例 #9
0
ファイル: WfcMadCouponParser.php プロジェクト: phpsmith/IS4C
 function parse($str)
 {
     Database::getsubtotals();
     $amt = CoreLocal::get('runningTotal') - CoreLocal::get('transDiscount');
     $madCoup = number_format($amt * 0.05, 2);
     if ($madCoup > 2.5) {
         $madCoup = 2.5;
     }
     TransRecord::addRecord(array('upc' => "MAD Coupon", 'description' => "Member Appreciation Coupon", 'trans_type' => "I", 'trans_subtype' => "CP", 'trans_status' => "C", 'quantity' => 1, 'ItemQtty' => 1, 'unitPrice' => -1 * $madCoup, 'total' => -1 * $madCoup, 'regPrice' => -1 * $madCoup, 'voided' => 17));
     $ret = $this->default_json();
     $ret['output'] = DisplayLib::lastpage();
     $ret['redraw_footer'] = true;
     return $ret;
 }
コード例 #10
0
ファイル: AutoTare.php プロジェクト: phpsmith/IS4C
 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;
 }
コード例 #11
0
ファイル: NeedDiscountParser.php プロジェクト: phpsmith/IS4C
 function parse($str)
 {
     $ret = $this->default_json();
     if (CoreLocal::get('isMember') !== 1) {
         $ret['output'] = DisplayLib::boxMsg(_("Apply member number first"), _('No member selected'), false, array_merge(array('Member Search [ID]' => 'parseWrapper(\'ID\');'), DisplayLib::standardClearButton()));
         return $ret;
     } elseif (CoreLocal::get('NeedDiscountFlag') == 1) {
         $ret['output'] = DisplayLib::boxMsg(_("discount already applied"), '', false, DisplayLib::standardClearButton());
         return $ret;
     } else {
         CoreLocal::set('NeedDiscountFlag', 1);
         $NBDisc = CoreLocal::get('needBasedPercent') * 100;
         DiscountModule::updateDiscount(new DiscountModule($NBDisc, 'NeedBasedDiscount'));
         $ret['output'] = DisplayLib::lastpage();
         $ret['redraw_footer'] = true;
         return $ret;
     }
 }
コード例 #12
0
ファイル: LineItemDiscount.php プロジェクト: phpsmith/IS4C
 function parse($str)
 {
     $ret = $this->default_json();
     // this is the currently selected item
     $transID = CoreLocal::get("currentid");
     $row = PrehLib::peekItem(true, $transID);
     if ($row === false) {
         // this shouldn't happen unless there's some weird session problem
         $ret['output'] = DisplayLib::boxMsg(_("Item not found"), '', false, DisplayLib::standardClearButton());
     } else {
         if ($row['trans_type'] != 'I' && $row['trans_type'] != 'D') {
             // only items & open rings are discountable
             $ret['output'] = DisplayLib::boxMsg(_("Line is not discountable"), '', false, DisplayLib::standardClearButton());
         } elseif ($row['discounttype'] != 0) {
             // for simplicity, sale items cannot be discounted
             // this also prevents using this function more than
             // once on a single item
             $ret['output'] = DisplayLib::boxMsg(_("Item already discounted"), '', false, DisplayLib::standardClearButton());
         } else {
             // discount is simply the total times the
             //   non-member discount percentage
             // total is discounted immediately using
             //   the non-member percentage
             // memDiscount is the difference between total
             //   member discount and the non-member discount
             //   since the non-member discount is applied
             //   immediately
             // setting discounttype=2 makes the member discount
             //   apply when a [valid] member number is entered
             $discQ = sprintf("UPDATE localtemptrans SET\n                    discount=(regPrice * quantity * %f), \n                    total=(total-(regPrice*quantity*%f)),\n                    memDiscount=((regPrice*quantity*%f) - (regPrice*quantity*%f)),\n                    discounttype=2\n                    WHERE trans_id=%d", CoreLocal::get("LineItemDiscountNonMem"), CoreLocal::get("LineItemDiscountNonMem"), CoreLocal::get("LineItemDiscountMem"), CoreLocal::get("LineItemDiscountNonMem"), $transID);
             $dbc = Database::tDataConnect();
             $discR = $dbc->query($discQ);
             // add notification line for nonMem discount
             TransRecord::adddiscount($row['regPrice'] * $row['quantity'] * CoreLocal::get("LineItemDiscountNonMem"), $row['department']);
             // footer should be redrawn since savings and totals
             // have changed. Output is the list of items
             $ret['redraw_footer'] = true;
             $ret['output'] = DisplayLib::lastpage();
         }
     }
     return $ret;
 }
コード例 #13
0
ファイル: undo_confirm.php プロジェクト: phpsmith/IS4C
 function body_content()
 {
     echo $this->input_header();
     ?>
     <div class="baseHeight">
     <?php 
     if (empty($this->msg)) {
         echo DisplayLib::lastpage();
     } else {
         echo $this->msg;
     }
     ?>
     </div>
     <?php 
     echo "<div id=\"footer\">";
     echo DisplayLib::printfooter();
     echo "</div>";
     $this->add_onload_command("\$('#reginput').keyup(function(ev){\n                    switch(ev.keyCode){\n                    case 33:\n                        \$('#reginput').val('U11');\n                        \$('#formlocal').submit();\n                        break;\n                    case 38:\n                        \$('#reginput').val('U');\n                        \$('#formlocal').submit();\n                        break;\n                    case 34:\n                        \$('#reginput').val('D11');\n                        \$('#formlocal').submit();\n                        break;\n                    case 40:\n                        \$('#reginput').val('D');\n                        \$('#formlocal').submit();\n                        break;\n                    }\n                });\n");
     $this->add_onload_command("undoInstructions();");
 }
コード例 #14
0
ファイル: HouseCoupon.php プロジェクト: phpsmith/IS4C
 public function handle($upc, $json)
 {
     $coupID = ltrim(substr($upc, -5), "0");
     $leadDigits = substr($upc, 3, 5);
     $qualified = $this->checkQualifications($coupID);
     if ($qualified !== true) {
         $json['output'] = $qualified;
         return $json;
     }
     $available = $this->checkLimits($coupID);
     if ($available !== true) {
         $json['output'] = $available;
         return $json;
     }
     $add = $this->getValue($coupID);
     TransRecord::addhousecoupon($upc, $add['department'], -1 * $add['value'], $add['description']);
     $json['output'] = DisplayLib::lastpage();
     $json['udpmsg'] = 'goodBeep';
     $json['redraw_footer'] = true;
     return $json;
 }
コード例 #15
0
ファイル: RRR.php プロジェクト: phpsmith/IS4C
 function parse($str)
 {
     $ret = $this->default_json();
     $qty = 1;
     if ($str != "RRR") {
         $split = explode("*", $str);
         if (!is_numeric($split[0])) {
             return true;
         }
         $qty = $split[0];
     }
     $no_trans = CoreLocal::get('LastID') == 0 ? true : false;
     $this->add($qty);
     $ret['output'] = DisplayLib::lastpage();
     $ret['udpmsg'] = 'goodBeep';
     Database::getsubtotals();
     if ($no_trans && CoreLocal::get("runningTotal") == 0) {
         TransRecord::finalizeTransaction(true);
     }
     return $ret;
 }
コード例 #16
0
ファイル: AnnualMeetingParser.php プロジェクト: phpsmith/IS4C
 function parse($str)
 {
     $ret = $this->default_json();
     if (strlen($str) == 4) {
         CoreLocal::set('qmInput', $str);
         $desc = $this->descriptions[$str];
         $opts = array($desc . ' (Steak)' => 'M', $desc . ' (Risotto)' => 'V', $desc . ' (Squash V)' => 'S');
         if ($str == 1041) {
             $opts[$desc . ' (Kids)'] = 'K';
         }
         CoreLocal::set('qmNumber', $opts);
         $plugin_info = new QuickMenus();
         $ret['main_frame'] = $plugin_info->pluginUrl() . '/QMDisplay.php';
         return $ret;
     } else {
         $flag = strtoupper($str[4]);
         $plu = substr($str, 0, 4);
         $price = $flag == 'K' ? 5.0 : 20.0;
         TransRecord::addRecord(array('upc' => str_pad($plu, 13, '0', STR_PAD_LEFT), 'description' => $this->descriptions[$plu] . ' (' . $flag . ')', 'trans_type' => 'I', 'department' => 235, 'quantity' => 1.0, 'ItemQtty' => 1.0, 'unitPrice' => $price, 'total' => $price, 'regPrice' => $price, 'charflag' => $flag));
         $ret['output'] = DisplayLib::lastpage();
         $ret['redraw_footer'] = True;
         return $ret;
     }
 }
コード例 #17
0
ファイル: CouponCode.php プロジェクト: phpsmith/IS4C
 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;
 }
コード例 #18
0
ファイル: BaseLibsTest.php プロジェクト: phpsmith/IS4C
 public function testDisplayLib()
 {
     $footer = DisplayLib::printfooter();
     $this->assertInternalType('string', $footer);
     $this->assertNotEmpty($footer);
     $pmsg = DisplayLib::plainmsg('test message');
     $this->assertInternalType('string', $pmsg);
     $this->assertNotEmpty($pmsg);
     $this->assertContains('test message', $pmsg);
     $mbox = DisplayLib::msgbox('test msgbox', '', True);
     $this->assertInternalType('string', $mbox);
     $this->assertNotEmpty($mbox);
     $this->assertContains('test msgbox', $mbox);
     $xbox = DisplayLib::xboxMsg('test xboxMsg');
     $this->assertInternalType('string', $xbox);
     $this->assertNotEmpty($xbox);
     $this->assertContains('test xboxMsg', $xbox);
     $bmsg = DisplayLib::boxMsg('test boxMsg', '', True);
     $this->assertInternalType('string', $bmsg);
     $this->assertNotEmpty($bmsg);
     $this->assertContains('test boxMsg', $bmsg);
     $unk = DisplayLib::inputUnknown();
     $this->assertInternalType('string', $unk);
     $this->assertNotEmpty($unk);
     $headerb = DisplayLib::printheaderb();
     $this->assertInternalType('string', $headerb);
     $this->assertNotEmpty($headerb);
     $item = DisplayLib::printItem('name', 'weight', '1.99', 'T', 1);
     $this->assertInternalType('string', $item);
     $this->assertNotEmpty($item);
     $itemC = DisplayLib::printItemColor('004080', 'name', 'weight', '1.99', 'T', 2);
     $this->assertInternalType('string', $itemC);
     $this->assertNotEmpty($itemC);
     $itemH = DisplayLib::printItemColorHilite('004080', 'name', 'weight', '1.99', 'T');
     $this->assertInternalType('string', $itemH);
     $this->assertNotEmpty($itemH);
     CoreLocal::set('weight', 0);
     CoreLocal::set('scale', 0);
     CoreLocal::set('SNR', 0);
     $basic = DisplayLib::scaledisplaymsg();
     $this->assertInternalType('string', $basic);
     $this->assertEquals('0.00 lb', $basic);
     $scale_in_out = array('S11000' => '0.00 lb', 'S11001' => '0.01 lb', 'S11' => '_ _ _ _', 'S141' => '_ _ _ _', 'S143' => '0.00 lb', 'S145' => 'err -0', 'S142' => 'error', 'ASDF' => '? ? ? ?', 'S144000' => '0.00 lb', 'S144002' => '0.02 lb');
     foreach ($scale_in_out as $input => $output) {
         $test = DisplayLib::scaledisplaymsg($input);
         $this->assertInternalType('array', $test);
         $this->assertArrayHasKey('display', $test);
         $this->assertEquals($output, $test['display']);
     }
     $this->assertEquals(1, CoreLocal::get('scale'));
     $this->assertEquals(0.02, CoreLocal::get('weight'));
     CoreLocal::set('SNR', '4011');
     $both = DisplayLib::scaledisplaymsg('S11050');
     $this->assertInternalType('array', $both);
     $this->assertArrayHasKey('display', $both);
     $this->assertArrayHasKey('upc', $both);
     $this->assertEquals('0.50 lb', $both['display']);
     $this->assertEquals('4011', $both['upc']);
     $list = DisplayLib::listItems(0, 0);
     $this->assertInternalType('string', $list);
     $rf = DisplayLib::printReceiptFooter();
     $this->assertInternalType('string', $rf);
     $draw = DisplayLib::drawItems(0, 11, 0);
     $this->assertInternalType('string', $draw);
     $lp = DisplayLib::lastpage();
     $this->assertInternalType('string', $lp);
     $this->assertEquals($lp, $list);
 }
コード例 #19
0
ファイル: PrehLib.php プロジェクト: phpsmith/IS4C
 /**
   Add a percent discount notification
   @param $strl discount percentage
   @param $json keyed array
   @return An array see Parser::default_json()
   @deprecated
   Use discountnotify() instead. This just adds
   hard-coded percentages and PLUs that likely
   aren't applicable anywhere but the Wedge.
 */
 public static function percentDiscount($strl, $json = array())
 {
     if ($strl == 10.01) {
         $strl = 10;
     }
     if (!is_numeric($strl) || $strl > 100 || $strl < 0) {
         $json['output'] = DisplayLib::boxMsg(_("discount invalid"), '', false, DisplayLib::standardClearButton());
     } else {
         if ($strl != 0) {
             TransRecord::discountnotify($strl);
         }
         $dbc = Database::tDataConnect();
         $dbc->query("update localtemptrans set percentDiscount = " . $strl);
         $chk = self::ttl();
         if ($chk !== true) {
             $json['main_frame'] = $chk;
         }
         $json['output'] = DisplayLib::lastpage();
     }
     return $json;
 }
コード例 #20
0
ファイル: UPC.php プロジェクト: phpsmith/IS4C
 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;
 }
コード例 #21
0
ファイル: DatabarCoupon.php プロジェクト: phpsmith/IS4C
 public function handle($upc, $json)
 {
     $pos = 0;
     $first_req = array();
     /* STEP 1 - REQUIRED FIELDS */
     // remove prefix 8110
     $pos += 4;
     // grab company prefix length, remove it from barcode
     $prefix_length = (int) $upc[$pos] + 6;
     $pos += 1;
     // grab company prefix, remove from barcode
     $first_req['man_id'] = substr($upc, $pos, $prefix_length);
     $pos += $prefix_length;
     // this way all prefixes map against
     // localtemptrans.upc[2,length]
     if ($prefix_length == 6) {
         $first_req['man_id'] = "0" . $first_req['man_id'];
     }
     // grab offer code, remove from barcode
     $offer = substr($upc, $pos, 6);
     $pos += 6;
     // read value length
     $val_length = (int) $upc[$pos];
     $pos += 1;
     // read value
     $value = (int) substr($upc, $pos, $val_length);
     $pos += $val_length;
     // read primary requirement length
     $req_length = (int) $upc[$pos];
     $pos += 1;
     // read primary requirement value
     $first_req['value'] = substr($upc, $pos, $req_length);
     $pos += $req_length;
     // read primary requirement type-code
     $first_req['code'] = $upc[$pos];
     $pos += 1;
     // read primary requirement family code
     $first_req['family'] = substr($upc, $pos, 3);
     $pos += 3;
     /* END REQUIRED FIELDS */
     /* example:
        
           barcode: 8110100707340143853100110110
            company prefix length    => 1 (+6)
            company prefix        => 0070734
            offer code        => 014385
            value length        => 3
            value            => 100
            primary req length    => 1
            primary req value    => 1
            primary req code    => 0
            primary req family    => 110                
        */
     /* STEP 2 - CHECK FOR OPTIONAL FIELDS */
     // second required item
     $second_req = array();
     $req_rules_code = 1;
     $duplicate_prefix_flag = false;
     if (isset($upc[$pos]) && $upc[$pos] == "1") {
         $pos += 1;
         $rules_code = $upc[$pos];
         $pos += 1;
         $sr_length = (int) $upc[$pos];
         $pos += 1;
         $second_req['value'] = substr($upc, $pos, $sr_length);
         $pos += $sr_length;
         $second_req['code'] = $upc[$pos];
         $pos += 1;
         $second_req['family'] = substr($upc, $pos, 3);
         $pos += 3;
         $sm_length = (int) $upc[$pos] + 6;
         $pos += 1;
         if ($sm_length == 15) {
             // 9+6
             $second_req['man_id'] = $first_req['man_id'];
             $duplicate_prefix_flag = true;
         } else {
             $second_req['man_id'] = substr($upc, $pos, $sm_length);
             $pos += $sm_length;
             if ($sm_length == 6) {
                 $second_req['man_id'] = "0" . $second_req['man_id'];
             }
         }
     }
     // third required item
     $third_req = array();
     if (isset($upc[$pos]) && $upc[$pos] == "2") {
         $pos += 1;
         $tr_length = (int) $upc[$pos];
         $pos += 1;
         $third_req['value'] = substr($upc, $pos, $tr_length);
         $pos += $tr_length;
         $third_req['code'] = $upc[$pos];
         $pos += 1;
         $third_req['family'] = substr($upc, $pos, 3);
         $pos += 3;
         $tm_length = (int) $upc[$pos] + 6;
         $pos += 1;
         if ($tm_length == 15) {
             // 9+6
             $third_req['man_id'] = $first_req['man_id'];
             $duplicate_prefix_flag = true;
         } else {
             $third_req['man_id'] = substr($upc, $pos, $tm_length);
             $pos += $tm_length;
             if ($tm_length == 6) {
                 $third_req['man_id'] = "0" . $third_req['man_id'];
             }
         }
     }
     if ($duplicate_prefix_flag) {
         $first_req['man_id'] .= $first_req['family'];
         $second_req['man_id'] .= $second_req['family'];
         $third_req['man_id'] .= $third_req['family'];
     }
     // expiration date
     if (isset($upc[$pos]) && $upc[$pos] == "3") {
         $pos += 1;
         $expires = substr($upc, $pos, 6);
         $pos += 6;
         $y = "20" . substr($expires, 0, 2);
         $m = substr($expires, 2, 2);
         $d = substr($expires, 4, 2);
         $tstamp = mktime(23, 59, 59, $m, $d, $y);
         if ($tstamp < time()) {
             $json['output'] = DisplayLib::boxMsg("Coupon expired {$m}/{$d}/{$y}");
             return $json;
         }
     }
     // start date
     if (isset($upc[$pos]) && $upc[$pos] == "4") {
         $pos += 1;
         $starts = substr($upc, $pos, 6);
         $pos += 6;
         $y = "20" . substr($starts, 0, 2);
         $m = substr($starts, 2, 2);
         $d = substr($starts, 4, 2);
         $tstamp = mktime(0, 0, 0, $m, $d, $y);
         if ($tstamp > time()) {
             $json['output'] = DisplayLib::boxMsg("Coupon not valid until {$m}/{$d}/{$y}");
             return $json;
         }
     }
     // serial number
     $serial = false;
     if (isset($upc[$pos]) && $upc[$pos] == "5") {
         $pos += 1;
         $serial_length = (int) $upc[$pos] + 6;
         $pos += 1;
         $serial = substr($upc, $pos, $serial_length);
         $pos += $serial_length;
     }
     // retailer
     $retailer = false;
     if (isset($upc[$pos]) && $upc[$pos] == "6") {
         $pos += 1;
         $rt_length = (int) $upc[$pos] + 6;
         $pos += 1;
         $retailer = substr($upc, $pos, $rt_length);
         $pos += $rt_length;
     }
     /* END OPTIONAL FIELDS */
     /* STEP 3 - The Miscellaneous Field
           This field is also optional, but filling in
           the default values here will make code
           that validates coupons and calculates values
           consistent 
        */
     $misc = array('value_code' => 0, 'value_applies' => 0, 'store_coupon' => 0, 'no_multiply' => 0);
     if (isset($upc[$pos]) && $upc[$pos] == "9") {
         $pos += 1;
         $misc['value_code'] = $upc[$pos];
         $pos += 1;
         $misc['value_applies'] = $upc[$pos];
         $pos += 1;
         $misc['store_coupon'] = $upc[$pos];
         $pos += 1;
         $misc['no_multiply'] = $upc[$pos];
         $pos += 1;
     }
     /* END Miscellaneous Field */
     /* STEP 4 - validate coupon requirements */
     $primary = $this->validateRequirement($first_req, $json);
     if (!$primary && (count($second_req) == 0 || $req_rules_code == 1 || $req_rules_code == 2)) {
         // if the primary requirement isn't valid and
         //    a) there are no more requirments, or
         //    b) the primary requirement is mandatory
         // return the json. Error message should have been
         // set up by validateRequirement()
         return $json;
     }
     $secondary = $this->validateRequirement($second_req, $json);
     if (!$secondary && (count($third_req) == 0 || $req_rules_code == 1)) {
         // if the secondary requirment isn't valid and
         //    a) there are no more requirments, or
         //    b) all requirements are mandatory
         // return the json. Error message should have been
         // set up by validateRequirement()
         return $json;
     }
     $tertiary = $this->validateRequirement($third_req, $json);
     // compare requirement results with rules
     // return error message if applicable
     switch ($req_rules_code) {
         case '0':
             // any requirement can be used
             if (!$primary && !$secondary && !$tertiary) {
                 return $json;
             }
             break;
         case '1':
             // all required
             if (!$primary || !$secondary || !$tertiary) {
                 return $json;
             }
             break;
         case '2':
             // primary + second OR third
             if (!$primary) {
                 return $json;
             } else {
                 if (!$secondary && !$tertiary) {
                     return $json;
                 }
             }
             break;
         case '3':
             // either second or third. seems odd, may
             // be misreading documentation on this one
             if (!$secondary && !$tertiary) {
                 return $json;
             }
             break;
         default:
             $json['output'] = DisplayLib::boxMsg("Malformed coupon");
             return $json;
     }
     /* End requirement validation */
     /* STEP 5 - determine coupon value */
     $val_arr = $first_req;
     if ($misc['value_applies'] == 1) {
         $val_arr = $second_req;
     } else {
         if ($misc['value_applies'] == 2) {
             $val_arr = $third_req;
         }
     }
     $value = 0;
     switch ($misc['value_code']) {
         case '0':
             // value in cents
         // value in cents
         case '6':
             $value = MiscLib::truncate2($val_arr['value'] / 100.0);
             break;
         case '1':
             // free item
             $value = $val_arr['price'];
             break;
         case '2':
             // multiple free items
             $value = MiscLib::truncate2($val_arr['price'] * $val_arr['value']);
             break;
         case '5':
             // percent off
             $value = MiscLib::truncate2($val_arr['price'] * ($val_arr['value'] / 100.0));
             break;
         default:
             $json['output'] = DisplayLib::boxMsg("Error: bad coupon");
             return $json;
     }
     /* attempt to cram company prefix and offer code
                into 13 characters
     
                First character is zero
                Next characters are company prefix
                Remaining characters are offer code in base-36
     
                The first zero is there so that the company
                prefix will "line up" with matching items in
                localtemptrans
     
                The offer code is converted to base-36 to 
                reduce its character count.
     
                Offer code won't always fit. This is just best
                effort. I've already seen a real coupon using
                a 10 digit prefix. In theory there could even
                be a 12 digit prefix leaving no room for the
                offer code at all.
             */
     $upc_start = "0" . $val_arr['man_id'];
     $offer = base_convert($offer, 10, 36);
     $remaining = 13 - strlen($upc_start);
     if (strlen($offer) < $remaining) {
         $offer = str_pad($offer, $remaining, '0', STR_PAD_LEFT);
     } elseif (strlen($offer) > $remaining) {
         $offer = substr($offer, 0, $remaining);
     }
     $coupon_upc = $upc_start . $offer;
     TransRecord::addCoupon($coupon_upc, $row['department'], -1 * $value);
     $json['output'] = DisplayLib::lastpage();
     return $json;
 }
コード例 #22
0
ファイル: pos2.php プロジェクト: phpsmith/IS4C
 function body_content()
 {
     $lines = CoreLocal::get('screenLines');
     if (!$lines === '' || !is_numeric($lines)) {
         $lines = 11;
     }
     $this->input_header('action="pos2.php" onsubmit="return submitWrapper();"');
     if (CoreLocal::get("timeout") != "") {
         $this->add_onload_command("enableScreenLock();\n");
     }
     $this->add_onload_command("\$('#reginput').keydown(function(ev){\n                    switch(ev.which){\n                    case 33:\n                        parseWrapper('U{$lines}');\n                        break;\n                    case 38:\n                        parseWrapper('U');\n                        break;\n                    case 34:\n                        parseWrapper('D{$lines}');\n                        break;\n                    case 40:\n                        parseWrapper('D');\n                        break;\n                    case 9:\n                        parseWrapper('TFS');\n                        return false;\n                    case 69:\n                    case 101:\n                        return getScaleWeight();\n                    }\n                });\n");
     /*
     if (CoreLocal::get("msgrepeat") == 1)
         $this->add_onload_command("submitWrapper();");
     */
     ?>
     <div class="baseHeight">
     <?php 
     CoreLocal::set("quantity", 0);
     CoreLocal::set("multiple", 0);
     CoreLocal::set("casediscount", 0);
     // set memberID if not set already
     if (!CoreLocal::get("memberID")) {
         CoreLocal::set("memberID", "0");
     }
     if (CoreLocal::get("plainmsg") && strlen(CoreLocal::get("plainmsg")) > 0) {
         echo DisplayLib::printheaderb();
         echo "<div class=\"centerOffset\">";
         echo DisplayLib::plainmsg(CoreLocal::get("plainmsg"));
         CoreLocal::set("plainmsg", 0);
         echo "</div>";
     } elseif (!empty($this->display)) {
         echo $this->display;
     } else {
         echo DisplayLib::lastpage();
     }
     echo "</div>";
     // end base height
     echo "<div id=\"footer\">";
     echo DisplayLib::printfooter();
     echo "</div>";
     if (CoreLocal::get("touchscreen")) {
         echo '<div style="text-align: center;">
         <button type="submit" 
             class="quick_button pos-button coloredBorder"
             style="margin: 0 10px 0 0;"
             onclick="parseWrapper(\'QO1001\');">
             Items
         </button>
         <button type="submit"
             class="quick_button pos-button coloredBorder"
             style="margin: 0 10px 0 0;"
             onclick="parseWrapper(\'QO1002\');">
             Total
         </button>
         <button type="submit" 
             class="quick_button pos-button coloredBorder"
             style="margin: 0 10px 0 0;"
             onclick="parseWrapper(\'QO1003\');">
             Member
         </button>
         <button type="submit" 
             class="quick_button pos-button coloredBorder"
             style="margin: 0 10px 0 0;"
             onclick="parseWrapper(\'QO1004\');">
             Tender
         </button>
         <button type="submit"
             class="quick_button pos-button coloredBorder"
             style="margin: 0 10px 0 0;"
             onclick="parseWrapper(\'QO1005\');">
             Misc
         </button>
         </div>';
     }
 }
コード例 #23
0
ファイル: Void.php プロジェクト: phpsmith/IS4C
 public function parse($str)
 {
     $ret = $this->default_json();
     if (is_numeric(CoreLocal::get('VoidLimit')) && CoreLocal::get('VoidLimit') > 0) {
         Database::getsubtotals();
         if (CoreLocal::get('voidTotal') > CoreLocal::get('VoidLimit') && CoreLocal::get('voidOverride') != 1) {
             CoreLocal::set('strRemembered', CoreLocal::get('strEntered'));
             CoreLocal::set('voidOverride', 0);
             $ret['main_frame'] = MiscLib::base_url() . 'gui-modules/adminlogin.php?class=Void';
             return $ret;
         }
     }
     if (strlen($str) > 2) {
         $ret = $this->voidupc(substr($str, 2), $ret);
     } elseif (CoreLocal::get("currentid") == 0) {
         $ret['output'] = DisplayLib::boxMsg(_("No Item on Order"), '', false, DisplayLib::standardClearButton());
     } else {
         $id = CoreLocal::get("currentid");
         $status = PrehLib::checkstatus($id);
         $this->discounttype = $status['discounttype'];
         $this->discountable = $status['discountable'];
         $this->caseprice = $status['caseprice'];
         $this->scaleprice = $status['scaleprice'];
         /**
           Voided values:
             2 => "you saved" line
             3 => subtotal line
             4 => discount notice
             5 => % Discount line
             6 => tare weight, case disc notice,
             8 => FS change, regular change
             10 => tax exempt
         */
         if ($status['voided'] == 2) {
             // void preceeding item
             $ret = $this->voiditem($id - 1, $ret);
         } else {
             if ($status['voided'] == 3 || $status['voided'] == 6 || $status['voided'] == 8) {
                 $ret['output'] = DisplayLib::boxMsg(_("Cannot void this entry"), '', false, DisplayLib::standardClearButton());
             } else {
                 if ($status['voided'] == 4 || $status['voided'] == 5) {
                     PrehLib::percentDiscount(0);
                 } else {
                     if ($status['voided'] == 10) {
                         TransRecord::reverseTaxExempt();
                     } else {
                         if ($status['status'] == "V") {
                             $ret['output'] = DisplayLib::boxMsg(_("Item already voided"), '', false, DisplayLib::standardClearButton());
                         } else {
                             $ret = $this->voiditem($id, $ret);
                         }
                     }
                 }
             }
         }
     }
     if (empty($ret['output']) && empty($ret['main_frame'])) {
         $ret['output'] = DisplayLib::lastpage();
         $ret['redraw_footer'] = true;
         $ret['udpmsg'] = 'goodBeep';
     } elseif (empty($ret['main_frame'])) {
         $ret['udpmsg'] = 'errorBeep';
     }
     return $ret;
 }