diff --git a/action.php b/action.php index d1ea966..0a4be2c 100644 --- a/action.php +++ b/action.php @@ -7,7 +7,6 @@ /** * Make things happen when buttons are pressed and forms submitted. */ - require_once __DIR__ . "/required.php"; if ($VARS['action'] !== "signout") { @@ -31,6 +30,28 @@ function returnToSender($msg, $arg = "") { } switch ($VARS['action']) { + case "itemsearch": + header("Content-Type: application/json"); + if (!is_empty($VARS['q'])) { + $where["AND"]["OR"] = [ + "name[~]" => $VARS['q'], + "code1[~]" => $VARS['q'], + "code2[~]" => $VARS['q'] + ]; + } else { + exit(json_encode(["status" => "ERROR", "items" => false])); + } + + $items = $binstack->select('items', [ + 'itemid (id)', + 'name', + 'code1', + 'code2', + 'cost', + 'price' + ], $where); + $items = (count($items) > 0 ? $items : false); + exit(json_encode(["status" => "OK", "items" => $items])); case "signout": session_destroy(); header('Location: index.php'); diff --git a/pages.php b/pages.php index 28de167..c27e0bc 100644 --- a/pages.php +++ b/pages.php @@ -16,6 +16,7 @@ define("PAGES", [ "navbar" => true, "icon" => "far fa-money-bill-alt", "scripts" => [ + "static/js/bsalert.js", "static/js/pos.js", ] ], diff --git a/pages/home.php b/pages/home.php index 1d44fbf..60a107f 100644 --- a/pages/home.php +++ b/pages/home.php @@ -3,4 +3,3 @@ * License, v. 2.0. If a copy of the MPL was not distributed with this * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ ?> -

Hello World

\ No newline at end of file diff --git a/pages/pos.php b/pages/pos.php index 06cc133..69ad71c 100644 --- a/pages/pos.php +++ b/pages/pos.php @@ -15,51 +15,17 @@
- +
" />
- +
- -
-
-
- Cool Widget -
-
- 659321 - - $10.23 - -
-
-
-
-
- $ -
- -
- - -
- -
- -
-
-
-
- +
diff --git a/required.php b/required.php index 55e7eec..33a53ec 100644 --- a/required.php +++ b/required.php @@ -92,6 +92,7 @@ date_default_timezone_set(TIMEZONE); use Medoo\Medoo; $database; +$binstack; try { $database = new Medoo([ 'database_type' => DB_TYPE, @@ -101,6 +102,14 @@ try { 'password' => DB_PASS, 'charset' => DB_CHARSET ]); + $binstack = new Medoo([ + 'database_type' => BINSTACK_DB_TYPE, + 'database_name' => BINSTACK_DB_NAME, + 'server' => BINSTACK_DB_SERVER, + 'username' => BINSTACK_DB_USER, + 'password' => BINSTACK_DB_PASS, + 'charset' => BINSTACK_DB_CHARSET + ]); } catch (Exception $ex) { //header('HTTP/1.1 500 Internal Server Error'); sendError("Database error. Try again later. $ex"); diff --git a/settings.template.php b/settings.template.php index 1b50875..90b338d 100644 --- a/settings.template.php +++ b/settings.template.php @@ -17,6 +17,15 @@ define("DB_USER", "nickelbox"); define("DB_PASS", ""); define("DB_CHARSET", "utf8"); +// BinStack database connection settings +define("BINSTACK_DB_TYPE", "mysql"); +define("BINSTACK_DB_NAME", "inventory"); +define("BINSTACK_DB_SERVER", "localhost"); +define("BINSTACK_DB_USER", "inventory"); +define("BINSTACK_DB_PASS", ""); +define("BINSTACK_DB_CHARSET", "utf8"); + + // Name of the app. define("SITE_TITLE", "NickelBox"); diff --git a/static/js/bsalert.js b/static/js/bsalert.js new file mode 100644 index 0000000..0877ab8 --- /dev/null +++ b/static/js/bsalert.js @@ -0,0 +1,91 @@ +/* + * This Source Code Form is subject to the terms of the Mozilla Public + * License, v. 2.0. If a copy of the MPL was not distributed with this + * file, You can obtain one at http://mozilla.org/MPL/2.0/. + */ + +function bsprompt(title, message, okbtn, cancelbtn, type, callback) { + var html = ''; + $("body").append(html); + $("#bsprompt-title").text(title); + $("#bsprompt-message").text(message); + $("#bsprompt-ok").text(okbtn); + $("#bsprompt-cancel").text(cancelbtn); + $("#bsprompt-input").attr("type", type); + $("#bsprompt-input").on("keypress", function (e) { + if (e.which === 13) { + callback($("#bsprompt-input").val()); + $("#bsprompt").modal("hide"); + } + }); + $("#bsprompt-ok").on("click", function () { + callback($("#bsprompt-input").val()); + $("#bsprompt").modal("hide"); + }); + $("#bsprompt").on("shown.bs.modal", function () { + $("#bsprompt-input").focus(); + }); + $("#bsprompt").on("hidden.bs.modal", function () { + $("#bsprompt").remove(); + }); + $("#bsprompt").modal("show"); +} + +function bschoices(title, message, options, cancelbtn, callback) { + var html = ''; + $("body").append(html); + $("#bschoices-title").text(title); + $("#bschoices-message").text(message); + $("#bschoices-cancel").text(cancelbtn); + for (var i = 0; i < options.length; i++) { + var text = options[i]["text"]; + var val = options[i]["val"]; + $("#bschoices-list").append('
' + text + '
'); + } + $(".bschoices-option").css("cursor", "pointer"); + $(".bschoices-option").on("click", function () { + callback($(this).data("value")); + $("#bschoices").modal("hide"); + }); + $("#bschoices").on("hidden.bs.modal", function () { + $("#bschoices").remove(); + }); + $("#bschoices").modal("show"); +} \ No newline at end of file diff --git a/static/js/pos.js b/static/js/pos.js index f1a1d2d..09819d1 100644 --- a/static/js/pos.js +++ b/static/js/pos.js @@ -9,13 +9,14 @@ function addItem(name, code, price) { updateQty($(".list-group-item[data-code='" + code + "']").find(".qty-plus"), 1); return; } + price = (price * 1.0).toFixed(2); $("#pos-lines-box").append('
' + '
' + '
' + name + '
' + '
' - + '' + code + '' + + '' + code + '' + '' + '$' + price @@ -24,16 +25,16 @@ function addItem(name, code, price) { + '
' + '
' + '
' - + '
' + + '
' + '
' - + '$' + + '$' + '
' - + '' + + '' + '
' - + '' + + '' + '' + '
' - + '' + + '' + '
' + '' + '
' @@ -42,7 +43,81 @@ function addItem(name, code, price) { + '
'); } +function findItem(q) { + function decodeThenAddItem(item) { + var code = item.code1; + console.log(code); + if (code == "" && item["code2"] != "") { + code = item["code2"]; + } else if (code == "") { + code = "---"; + } + var price = item['price']; + if (price == null || price == "" || price == 0) { + if (!$(".list-group-item[data-code='" + code + "']").length) { + bsprompt("Enter Price", + "No price set. Enter a price for this item:", + "Add Item", + "Cancel", + "number", + function (result) { + addItem(item['name'], code, result); + }); + return; + } + } + addItem(item['name'], code, price); + $("#barcode").val(""); + } + if (q == "") { + return; + } + $.get("action.php", { + action: "itemsearch", + q: q + }, function (data) { + if (data['items'].length == 1) { + decodeThenAddItem(data['items'][0]); + } else if (data['items'].length > 1) { + var options = []; + for (var i = 0; i < data['items'].length; i++) { + var text = data['items'][i]['name']; + if (data['items'][i]['price'] != null) { + text += " ($" + data['items'][i]['price'] + ")"; + } + options.push({"text": text, "val": data['items'][i]['id']}); + } + bschoices( + "Multiple Results", + "More than one item match the query. Pick the correct one:", + options, + "Cancel", + function (result) { + for (var i = 0; i < data['items'].length; i++) { + if (data['items'][i]['id'] == result) { + decodeThenAddItem(data['items'][i]); + break; + } + } + } + ); + } + }).fail(function () { + alert("Error"); + }); +} + +function removezero() { + $("#pos-lines-box .list-group-item").each(function () { + var qty = $(".item-qty", this).val() * 1.0; + if (qty == 0) { + $(this).remove(); + } + }); +} + function recalculate() { + removezero(); var total = 0.0; $("#pos-lines-box .list-group-item").each(function () { var each = $(".item-price", this).val() * 1.0; @@ -50,6 +125,7 @@ function recalculate() { var line = each * qty; $(".line-total", this).text(line.toFixed(2)); $(".item-price", this).val(each.toFixed(2)); + console.log(each.toFixed(2)); total += line; }); $(".grand-total").text(total.toFixed(2)); @@ -83,4 +159,36 @@ $("#pos-lines-box").on("click", ".qty-plus", function () { $("#pos-lines-box").on("change", ".item-qty,.item-price", function () { recalculate(); -}); \ No newline at end of file +}); + +$("#pos-lines-box").on("keypress", ".item-qty,.item-price", function (e) { + if (e.which === 13) { + recalculate(); + } +}); + +$("#barcode").on('keypress', function (e) { + if (e.which === 13) { + findItem($("#barcode").val()); + } +}); + +$("#barcodebtn").on("click", function () { + findItem($("#barcode").val()); +}); + +$("body").on("keypress", "input[type=money],input[type=number]", function (e) { + //console.log(String.fromCharCode(e.which) + "|" + e.which); + var c = String.fromCharCode(e.which); + var k = e.which; + if (/[0-9]|[\.]/.test(c)) { + // Numbers and period + } else if (k == 0 || k == 8) { + // Delete, backspace, etc + } else { + e.preventDefault(); + return false; + } +}); + +$("#barcode").focus(); \ No newline at end of file