has('customers', ['customerid' => $customer])) { exit(json_encode(["status" => "ERROR", "message" => lang("invalid customer", false)])); // exit(json_encode(["status" => "ERROR", "message" => lang("", false)])); } if ($register != "" && !$database->has('registers', ['registerid' => $register])) { exit(json_encode(["status" => "ERROR", "message" => lang("invalid register", false)])); } if ($register != "" && !$database->has('cash_drawer', ['AND' => ['registerid' => $register, 'close' => null]])) { exit(json_encode(["status" => "ERROR", "message" => lang("cash not open", false)])); } $totalcharge = 0.00; $totalpaid = 0.00; $change = 0.0; foreach ($items as $i) { $totalcharge += $i['each'] * $i['qty']; if (!$binstack->has('items', ['itemid' => $i['id']])) { exit(json_encode(["status" => "ERROR", "message" => lang("invalid item", false)])); } } foreach ($payments as $p) { if (!$database->has('payment_types', ['typename' => $p['type']])) { exit(json_encode(["status" => "ERROR", "message" => lang("invalid payment type", false)])); } $totalpaid += $p['amount']; if ($p['type'] == "giftcard") { if (!$database->has('certificates', ['AND' => ['amount[>=]' => $p['amount'], 'deleted[!]' => 1, 'certcode' => $p['code']]])) { exit(json_encode(["status" => "ERROR", "message" => lang("invalid giftcard", false)])); } } } if (is_numeric($discountpercent) && $discountpercent > 0 && $discountpercent < 100) { $discountpercent = $discountpercent * 1.0; $totalcharge *= 1.0 - ($discountpercent / 100.0); } else { $discountpercent = 0.0; } if ($totalcharge > $totalpaid) { exit(json_encode(["status" => "ERROR", "message" => lang("insufficient payment", false)])); } $cashid = null; if ($register != "") { $cashid = $database->get('cash_drawer', 'cashid', ['AND' => ['registerid' => $register, 'close' => null]]); } $database->insert('transactions', [ 'txdate' => date('Y-m-d H:i:s'), 'customerid' => ($customer != "" ? $customer : null), 'type' => 1, 'cashier' => $_SESSION['uid'], 'cashid' => $cashid, 'discountpercent' => $discountpercent ]); $txid = $database->id(); foreach ($items as $i) { $item = $binstack->get('items', ['name', 'qty'], ['itemid' => $i['id']]); $database->insert('lines', [ 'txid' => $txid, 'amount' => $i['each'], 'name' => $item['name'], 'itemid' => $i['id'], 'qty' => $i['qty'] ]); $binstack->update('items', [ 'qty[-]' => $i['qty'] ], [ 'itemid' => $i['id'] ]); } foreach ($payments as $p) { $certid = null; if ($p['type'] == "giftcard") { $certid = $database->get('certificates', 'certid', ['certcode' => $p['code']]); } $type = $database->get('payment_types', 'typeid', ['typename' => $p['type']]); $database->insert('payments', [ 'amount' => $p['amount'], 'data' => '', 'type' => $type, 'txid' => $txid, 'certid' => $certid ]); } if ($totalcharge < $totalpaid) { $change = $totalpaid - $totalcharge; $database->insert('payments', [ 'amount' => $change * -1.0, 'data' => '', 'type' => 1, 'txid' => $txid, 'certid' => null ]); } exit(json_encode(["status" => "OK", "txid" => $txid])); break; case "getreceipt": require_once __DIR__ . "/lib/generatereceipt.php"; $format = "html"; $width = 64; if (isset($VARS['width']) && preg_match("/[0-9]+/", $VARS['width']) && (int) $VARS['width'] > 0) { $width = (int) $VARS['width']; } if (isset($VARS['format'])) { $format = $VARS['format']; } if (!$database->has('transactions', ['txid' => $VARS['txid']])) { header("Content-Type: application/json"); exit(json_encode(["status" => "ERROR", "txid" => null])); } $receipt = GenerateReceipt::getReceipt(GenerateReceipt::RECEIPT_TYPE_TRANSACTION, $VARS['txid']); exit(GenerateReceipt::outputReceipt($receipt, $format, $width, "Tx. #" . $VARS['txid'])); break; 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); if (!empty($VARS['customer']) && $database->has('customers', ['customerid' => $VARS['customer']])) { for ($n = 0; $n < count($items); $n++) { $i = $items[$n]; if ($database->has('customer_pricing', ['AND' => ['itemid' => $i['id'], 'customerid' => $VARS['customer']]])) { $items[$n]['price'] = $database->get('customer_pricing', 'price', ['AND' => ['itemid' => $i['id'], 'customerid' => $VARS['customer']]]); } } } $items = (count($items) > 0 ? $items : false); exit(json_encode(["status" => "OK", "items" => $items])); case "getgriditems": header("Content-Type: application/json"); $items = $binstack->select('items', [ 'itemid (id)', 'name', 'price', 'code1', 'code2' ], [ 'AND' => ['price[!]' => null, 'price[!]' => 0] ]); if (!empty($VARS['customer']) && $database->has('customers', ['customerid' => $VARS['customer']])) { for ($n = 0; $n < count($items); $n++) { $i = $items[$n]; if ($database->has('customer_pricing', ['AND' => ['itemid' => $i['id'], 'customerid' => $VARS['customer']]])) { $items[$n]['price'] = $database->get('customer_pricing', 'price', ['AND' => ['itemid' => $i['id'], 'customerid' => $VARS['customer']]]); } } } for ($n = 0; $n < count($items); $n++) { if ($items[$n]['code1'] != "") { $items[$n]['code'] = $items[$n]["code1"]; } else if ($items[$n]['code1'] == "" && $items[$n]['code1'] != "") { $items[$n]['code'] = $items[$n]["code2"]; } else if (code == "") { $items[$n]['code'] = "---"; } } $items = (count($items) > 0 ? $items : false); exit(json_encode(["status" => "OK", "items" => $items])); case "customersearch": header("Content-Type: application/json"); if (!is_empty($VARS['q'])) { $where["AND"]["OR"] = [ "customerid" => $VARS['q'], "name[~]" => $VARS['q'], "email[~]" => $VARS['q'], "phone[~]" => $VARS['q'] ]; } else { exit(json_encode(["status" => "ERROR", "customers" => false])); } $where["LIMIT"] = 10; $customers = $database->select('customers', [ 'customerid (id)', 'name', 'email', 'phone', 'address', 'notes' ], $where); $customers = (count($customers) > 0 ? $customers : false); exit(json_encode(["status" => "OK", "customers" => $customers])); case "giftcard_lookup": header("Content-Type: application/json"); $code = $VARS['code']; if (empty($code)) { exit(json_encode(["status" => "ERROR", "cards" => []])); } $cards = $database->select('certificates', ['certid (id)', 'certcode (code)', 'amount (balance)', 'start_amount (amount)'], ['certcode' => $code]); exit(json_encode(["status" => "OK", "cards" => $cards])); break; case "editcustomer": $insert = true; if (is_empty($VARS['id'])) { $insert = true; } else { if ($database->has('customers', ['customerid' => $VARS['id']])) { $insert = false; } else { returnToSender("invalid_customerid"); } } if (is_empty($VARS['name'])) { returnToSender('invalid_parameters'); } $data = [ 'name' => $VARS['name'], 'email' => $VARS['email'], 'phone' => $VARS['phone'], 'address' => $VARS['address'], 'notes' => $VARS['notes'] ]; $customerid = null; if ($insert) { $database->insert('customers', $data); $customerid = $database->id(); } else { $database->update('customers', $data, ['customerid' => $VARS['id']]); $customerid = $VARS['id']; } if (!is_null($customerid)) { $custprices = $VARS['pricing']; $newcustprices = []; $oldcustprices = $database->select('customer_pricing', ['itemid (item)', 'price'], ['customerid' => $customerid]); foreach ($custprices as $cp) { if (!$binstack->has('items', ['itemid' => $cp['item']])) { continue; } if (!is_numeric($cp['price'])) { continue; } $newcustprices[] = $cp; $oldcustprices = array_filter($oldcustprices, function ($var) { if ($cp['item'] == $var['item']) { return false; } return true; }); } foreach ($oldcustprices as $cp) { $database->delete('customer_pricing', ['AND' => ['itemid' => $cp['item'], 'customerid' => $customerid]]); } foreach ($newcustprices as $cp) { if ($database->has('customer_pricing', ['AND' => ['itemid' => $cp['item'], 'customerid' => $customerid]])) { $database->update('customer_pricing', ['price' => $cp['price']], ['AND' => ['itemid' => $cp['item'], 'customerid' => $customerid]]); } else { $database->insert('customer_pricing', ['price' => $cp['price'], 'itemid' => $cp['item'], 'customerid' => $customerid]); } } } returnToSender("customer_saved"); case "set_register": $regid = $VARS['register']; if (!$database->has('registers', ['registerid' => $regid])) { returnToSender("invalid_parameters"); } if (!$database->has('cash_drawer', ['AND' => ['registerid' => $regid, 'close' => null]])) { returnToSender("cash_not_open"); } $cashid = $database->get('cash_drawer', 'cashid', ['AND' => ['registerid' => $regid, 'close' => null]]); $_SESSION['register'] = (int) $regid; returnToSender("register_set"); break; case "opencash": $regid = $VARS['register']; $start = $VARS['startamount']; if (!$database->has('registers', ['registerid' => $regid])) { returnToSender("invalid_parameters"); } if ($database->has('cash_drawer', ['AND' => ['registerid' => $regid, 'close' => null]])) { returnToSender("cash_already_open"); } if (!is_numeric($start) || (float) $start < 0) { $start = 0.0; } $database->insert('cash_drawer', [ 'registerid' => $regid, 'open' => date('Y-m-d H:i:s'), 'close' => null, 'start_amount' => $start, 'end_amount' => null ]); returnToSender("cash_opened"); break; case "closecash": $regid = $VARS['register']; if (!$database->has('registers', ['registerid' => $regid])) { returnToSender("invalid_parameters"); } if (!$database->has('cash_drawer', ['AND' => ['registerid' => $regid, 'close' => null]])) { returnToSender("cash_not_open"); } $cash = $database->get('cash_drawer', ['cashid', 'start_amount'], ['AND' => ['registerid' => $regid, 'close' => null]]); $balance = (float) $cash['start_amount']; $rows = $database->select("payments", [ "[>]transactions" => ['txid' => 'txid'] ], 'amount', [ 'AND' => [ 'transactions.cashid' => $cash['cashid'], 'payments.type' => 1 ] ]); foreach ($rows as $row) { $balance += $row; } $database->update('cash_drawer', [ 'close' => date('Y-m-d H:i:s'), 'end_amount' => $balance ], [ 'cashid' => $cash['cashid'] ]); returnToSender("cash_closed"); break; case "editregister": $insert = true; if (empty($VARS['id'])) { $insert = true; } else { if ($database->has('registers', ['registerid' => $VARS['id']])) { $insert = false; } else { returnToSender("invalid_parameters"); } } if (is_empty($VARS['name'])) { returnToSender('invalid_parameters'); } if ($database->has('registers', ['AND' => ['registerid[!]' => $VARS['id'], 'registername' => $VARS['name']]])) { returnToSender("register_name_taken"); } $data = [ 'registername' => $VARS['name'] ]; if ($insert) { $database->insert('registers', $data); } else { $database->update('registers', $data, ['registerid' => $VARS['id']]); } returnToSender("register_saved"); case "xreport": require_once __DIR__ . "/lib/generatereceipt.php"; $format = "html"; $width = 64; if (isset($VARS['width']) && preg_match("/[0-9]+/", $VARS['width']) && (int) $VARS['width'] > 0) { $width = (int) $VARS['width']; } if (isset($VARS['format'])) { $format = $VARS['format']; } if (!$database->has('cash_drawer', ['AND' => ['registerid' => $VARS['register'], 'open[!]' => null, 'close' => null]])) { header("Content-Type: application/json"); exit(json_encode(["status" => "ERROR"])); } $receipt = GenerateReceipt::getReceipt(GenerateReceipt::RECEIPT_TYPE_X, null, $VARS['register']); exit(GenerateReceipt::outputReceipt($receipt, $format, $width, "X Report")); break; case "session_keepalive": header("Content-Type: application/json"); exit(json_encode(["status" => "OK"])); case "signout": session_destroy(); header('Location: index.php'); die("Logged out."); }