An easy point of sale system with automatic inventory tracking. https://netsyms.biz/apps/nickelbox/
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
 
 
 

368 lines
20 KiB

  1. <?php
  2. /*
  3. * This Source Code Form is subject to the terms of the Mozilla Public
  4. * License, v. 2.0. If a copy of the MPL was not distributed with this
  5. * file, You can obtain one at http://mozilla.org/MPL/2.0/.
  6. */
  7. $register = [
  8. "name" => lang("no cash", false),
  9. "id" => ""
  10. ];
  11. $registeropen = false;
  12. if (isset($_SESSION['register'])) {
  13. $registeropen = $database->has("registers", ['[>]cash_drawer' => ['registerid' => 'registerid']], ['AND' => ['open[!]' => null, 'close' => null, 'registers.registerid' => $_SESSION['register']]]);
  14. }
  15. if (isset($_GET['switch']) || !isset($_SESSION['register']) || !$registeropen) {
  16. require_once __DIR__ . "/../lib/chooseregister.php";
  17. } else {
  18. $register = $database->get('registers', ['registerid (id)', 'registername (name)'], ['registerid' => $_SESSION['register']]);
  19. $showgridbydefault = $binstack->count('items', ['AND' => ['price[!]' => null, 'price[!]' => 0]]) <= GRID_BY_DEFAULT_MAX_ITEMS;
  20. $items = [];
  21. $payments = [];
  22. $editing = false;
  23. $returning = false;
  24. if (isset($VARS['txid']) && $database->has('transactions', ['txid' => $VARS['txid']])) {
  25. $tx = $database->get('transactions', ['[>]customers' => 'customerid'], ['txid', 'discountpercent', 'transactions.customerid', 'customers.name (customername)', 'cashid', 'type'], ['txid' => $VARS['txid']]);
  26. if ($tx['type'] != 1) {
  27. header('Location: app.php?page=pos&msg=return_transaction_no_edit');
  28. die();
  29. }
  30. $items = $database->select('lines', ['lineid', 'amount', 'name', 'itemid', 'qty'], ['txid' => $tx['txid']]);
  31. if ($database->has('cash_drawer', ['AND' => ['cashid' => $tx['cashid'], 'open[!]' => null, 'close' => null]])) {
  32. $editing = true;
  33. $payments = $database->select('payments', ['[>]certificates' => 'certid', '[>]payment_types' => ['type' => 'typeid']], ['payments.amount', 'typename', 'icon', 'text', 'certcode'], ['txid' => $tx['txid']]);
  34. echo "<input type=\"hidden\" id=\"txid\" value=\"$tx[txid]\">";
  35. } else {
  36. $returning = true;
  37. echo "<input type=\"hidden\" id=\"return\" value=\"1\">";
  38. }
  39. }
  40. ?>
  41. <div class="modal fade" tabindex="-1" role="dialog" id="receiptmodal">
  42. <div class="modal-dialog" role="document">
  43. <div class="modal-content">
  44. <div class="modal-header">
  45. <h5 class="modal-title"><i class="fas fa-receipt"></i> <?php lang("receipt"); ?></h5>
  46. <button type="button" class="close" data-dismiss="modal" aria-label="Close">
  47. <span aria-hidden="true">&times;</span>
  48. </button>
  49. </div>
  50. <div class="modal-body">
  51. <div class="display-4 text-center" id="receiptchangediv"><?php lang("change"); ?>: $<span id="receiptchange">0.00</span></div>
  52. <iframe class="w-100 shadow-lg" id="receiptframe"></iframe>
  53. </div>
  54. <div class="modal-footer">
  55. <button type="button" class="btn btn-secondary" data-dismiss="modal"><?php lang("close"); ?></button>
  56. <button type="button" class="btn btn-primary" id="receiptprintbtn"><i class="fas fa-print"></i> <?php lang("print"); ?></button>
  57. </div>
  58. </div>
  59. </div>
  60. </div>
  61. <div class="modal fade" tabindex="-1" role="dialog" id="customermodal">
  62. <div class="modal-dialog modal-lg" role="document">
  63. <div class="modal-content">
  64. <div class="modal-header">
  65. <h5 class="modal-title"><i class="fas fa-user"></i> <?php lang("customer"); ?></h5>
  66. <button type="button" class="close" data-dismiss="modal" aria-label="Close">
  67. <span aria-hidden="true">&times;</span>
  68. </button>
  69. </div>
  70. <div class="modal-body">
  71. <div class="input-group">
  72. <input type="text" class="form-control" id="customersearch" placeholder="<?php lang("customer search"); ?>" />
  73. <div class="input-group-append">
  74. <button class="btn btn-link" type="button" id="customersearchbtn"><i class="fas fa-search"></i></button>
  75. </div>
  76. </div>
  77. <div class="list-group mt-2" id="customerselection">
  78. </div>
  79. </div>
  80. <div class="modal-footer">
  81. <button type="button" class="btn btn-secondary" data-dismiss="modal"><?php lang("close"); ?></button>
  82. </div>
  83. </div>
  84. </div>
  85. </div>
  86. <div class="modal fade" tabindex="-1" role="dialog" id="managermodal">
  87. <div class="modal-dialog modal-lg" role="document">
  88. <div class="modal-content">
  89. <div class="modal-header">
  90. <h5 class="modal-title"><i class="fas fa-cog"></i> <?php lang("register management"); ?></h5>
  91. <button type="button" class="close" data-dismiss="modal" aria-label="Close">
  92. <span aria-hidden="true">&times;</span>
  93. </button>
  94. </div>
  95. <div class="modal-body">
  96. <div class="row">
  97. <div class="col-12 col-md-6">
  98. <div class="input-group">
  99. <input type="text" class="form-control" id="transactionsearch" placeholder="<?php lang("transaction search"); ?>" />
  100. <div class="input-group-append">
  101. <button class="btn btn-link" type="button" id="transactionsearchbtn"><i class="fas fa-search"></i></button>
  102. </div>
  103. </div>
  104. <div class="list-group mt-2" id="transactionselection">
  105. </div>
  106. </div>
  107. <div class="col-12 col-md-6">
  108. <button type="button" class="btn btn-primary" id="xprintbtn"><i class="fas fa-print"></i> <?php lang("print"); ?></button>
  109. <iframe class="w-100 shadow-lg" id="xframe" src="action.php?action=xreport&format=html&register=<?php echo $register['id']; ?>"></iframe>
  110. </div>
  111. </div>
  112. </div>
  113. <div class="modal-footer">
  114. <button type="button" class="btn btn-secondary" data-dismiss="modal"><?php lang("close"); ?></button>
  115. </div>
  116. </div>
  117. </div>
  118. </div>
  119. <div class="row">
  120. <div class="col-12 col-md-6 order-1 order-md-0">
  121. <div class="card d-flex">
  122. <div class="card-header p-1">
  123. <div class="input-group">
  124. <div class="input-group-prepend">
  125. <span class="btn btn-default" id="gridviewbtn" title="<?php lang("grid view"); ?>"><i class="fas fa-th fa-fw"></i></span>
  126. </div>
  127. <?php
  128. if (isset($_SESSION['mobile'])) {
  129. ?>
  130. <div class="input-group-prepend">
  131. <span class="btn btn-default" onclick="scancode('#barcode'); mobilecode = true;">
  132. <i class="fas fa-barcode fa-fw"></i>
  133. </span>
  134. </div>
  135. <?php } ?>
  136. <input type="text" class="form-control" id="barcode" placeholder="<?php lang("barcode or search"); ?>" />
  137. <div class="input-group-append">
  138. <button class="btn btn-link" type="button" id="barcodebtn"><i class="fas fa-search"></i></button>
  139. </div>
  140. </div>
  141. </div>
  142. <div class="d-none justify-content-around flex-wrap" id="gridview">
  143. </div>
  144. <div>
  145. <div class="list-group list-group-flush" id="pos-lines-box">
  146. <?php
  147. foreach ($items as $i) {
  148. $linetotal = $i['amount'] * $i['qty'];
  149. $amount = $i['amount'];
  150. // Include percentage discount for returns
  151. if ($returning) {
  152. $linetotal *= 1.0 - ($tx['discountpercent'] / 100.0);
  153. $amount *= 1.0 - ($tx['discountpercent'] / 100);
  154. }
  155. ?>
  156. <div class="list-group-item" data-itemid="<?php echo $i['itemid']; ?>">
  157. <div class="d-flex w-100 justify-content-between mb-2">
  158. <h5 class="item-name"><?php echo $i['name']; ?></h5>
  159. <h5>
  160. <span class="badge badge-light">
  161. $<span class="line-total"><?php echo number_format($linetotal, 2); ?></span>
  162. </span>
  163. </h5>
  164. </div>
  165. <div class="d-inline-flex">
  166. <div class="input-group qty-control">
  167. <div class="input-group-prepend">
  168. <span class="input-group-text pr-1"><b>$</b></span>
  169. </div>
  170. <input type="money" class="form-control item-price" value="<?php echo number_format($amount, 2); ?>"/>
  171. <div class="input-group-prepend">
  172. <span class="input-group-text px-2"><i class="fas fa-times"></i></span>
  173. <button class="btn btn-red qty-minus" type="button"><i class="fas <?php
  174. if ($i['qty'] > 1) {
  175. echo "fa-minus";
  176. } else {
  177. echo "fa-trash";
  178. }
  179. ?>"></i></button>
  180. </div>
  181. <input type="number" class="form-control item-qty px-2" value="<?php echo $i['qty']; ?>" />
  182. <div class="input-group-append">
  183. <button class="btn btn-light-green qty-plus" type="button"><i class="fas fa-plus"></i></button>
  184. </div>
  185. </div>
  186. </div>
  187. </div>
  188. <?php
  189. }
  190. ?>
  191. </div>
  192. </div>
  193. </div>
  194. </div>
  195. <div class="col-12 col-md-6 order-0 order-md-1">
  196. <div class="card mb-3 mb-md-0">
  197. <div class="w-100 position-absolute d-flex align-items-start px-3 pt-2">
  198. <a href="#" class="mr-auto text-body" id="openmanagement" data-toggle="tooltip" title="<?php lang("manage register") ?>"><i class="fas fa-cog"></i> <?php lang("manage"); ?></a>
  199. <a href="app.php?page=pos&switch" class="ml-auto text-body" id="register" data-id="<?php echo $register['id']; ?>" data-toggle="tooltip" title="<?php lang("change register") ?>"><i class="fas fa-exchange-alt"></i> <?php echo $register['name']; ?></a>
  200. </div>
  201. <div class="display-4 p-1 p-md-3 text-center">$<span id="grand-total">0.00</span></div>
  202. <div class="card-body d-flex justify-content-center flex-wrap py-0 my-0">
  203. <div class="btn m-1" id="addcustomerbtn">
  204. <i class="fas fa-user-circle"></i>
  205. <span id="customerbtnlabel"><?php
  206. if ($editing && isset($tx['customername'])) {
  207. echo $tx['customername'];
  208. }
  209. ?></span>
  210. <span class="sr-only"><?php lang("customer"); ?></span>
  211. </div>
  212. <?php
  213. if (!$returning) {
  214. ?>
  215. <div class="btn m-1" id="discountpercentbtn" data-percent="<?php
  216. if ($editing && isset($tx['discountpercent']) && $tx['discountpercent'] != 0) {
  217. echo (float) $tx['discountpercent'];
  218. } else {
  219. echo "0";
  220. }
  221. ?>">
  222. <span id="discountpercentbtnlabel"><?php
  223. if ($editing && isset($tx['discountpercent']) && $tx['discountpercent'] != 0) {
  224. echo (float) $tx['discountpercent'];
  225. }
  226. ?></span>
  227. <i class="fas fa-percent"></i>
  228. <span class="sr-only"><?php lang("transaction discount"); ?></span>
  229. </div>
  230. <?php
  231. }
  232. ?>
  233. </div>
  234. <div class="card-body">
  235. <span class="btn btn-green btn-lg btn-block" id="paymentbtn"><i class="fas fa-money-bill-wave"></i> <?php
  236. if ($returning) {
  237. lang("enter refund");
  238. } else {
  239. lang("enter payment");
  240. }
  241. ?></span>
  242. </div>
  243. <div class="d-none" id="paymentui">
  244. <div class="card-body">
  245. <div class="d-flex justify-content-around flex-wrap">
  246. <?php
  247. $payment_methods = $database->select('payment_types', ['typeid (id)', 'typename (name)', 'icon', 'text']);
  248. $hideforreturns = ['check', 'free'];
  249. foreach ($payment_methods as $data) {
  250. if ($returning && in_array($data['name'], $hideforreturns)) {
  251. continue;
  252. }
  253. ?>
  254. <div class="card p-2 text-center m-1 payment-method-button" data-payment-method="<?php echo $data['name']; ?>" data-icon="<?php echo $data['icon']; ?>" data-text="<?php lang($data['text']); ?>">
  255. <i class="<?php echo $data['icon']; ?> fa-3x fa-fw"></i>
  256. <?php lang($data['text']); ?>
  257. </div>
  258. <?php
  259. }
  260. ?>
  261. </div>
  262. </div>
  263. <hr />
  264. <div class="row px-2 mb-3 text-center">
  265. <?php
  266. if ($returning) {
  267. ?>
  268. <div class="col-12 col-sm-4">
  269. <?php lang("refund"); ?> $<span id="paid-amount">0.00</span>
  270. </div>
  271. <div class="col-12 col-sm-4">
  272. <?php lang("owed"); ?> $<span id="owed-amount">0.00</span>
  273. </div>
  274. <div class="col-12 col-sm-4">
  275. <?php lang("change"); ?> $<span id="change-amount">0.00</span>
  276. </div>
  277. <?php
  278. } else {
  279. ?>
  280. <div class="col-12 col-sm-4">
  281. <?php lang("paid"); ?> $<span id="paid-amount">0.00</span>
  282. </div>
  283. <div class="col-12 col-sm-4">
  284. <?php lang("owed"); ?> $<span id="owed-amount">0.00</span>
  285. </div>
  286. <div class="col-12 col-sm-4">
  287. <?php lang("change"); ?> $<span id="change-amount">0.00</span>
  288. </div>
  289. <?php
  290. }
  291. ?>
  292. </div>
  293. <div class="list-group list-group-flush" id="payment-lines">
  294. <?php
  295. if ($editing) {
  296. foreach ($payments as $p) {
  297. if ($p['amount'] <= 0) {
  298. continue;
  299. }
  300. ?>
  301. <div class="list-group-item">
  302. <div class="input-group">
  303. <div class="input-group-prepend">
  304. <span class="input-group-text">
  305. <i class="<?php echo $p['icon']; ?> fa-fw mr-1"></i>
  306. <?php lang($p['text']); ?>
  307. </span>
  308. </div>
  309. <div class="input-group-prepend">
  310. <span class="input-group-text">
  311. $
  312. </span>
  313. </div>
  314. <input class="form-control payment-entry" type="money" data-type="<?php echo $p['typename']; ?>" value="<?php echo number_format($p['amount'], 2); ?>" />
  315. <?php
  316. if ($p['typename'] == 'giftcard') {
  317. ?>
  318. <div class="input-group-prepend input-group-append">
  319. <span class="input-group-text">
  320. #
  321. </span>
  322. </div>
  323. <input class="form-control giftcard-number" type="number" value="<?php echo $p['certcode']; ?>" />
  324. <?php
  325. }
  326. ?>
  327. <div class="input-group-append">
  328. <span class="btn btn-outline-danger remove-payment-btn">
  329. <i class="fas fa-trash"></i>
  330. </span>
  331. </div>
  332. </div>
  333. </div>
  334. <?php
  335. }
  336. }
  337. ?>
  338. <!-- Payments go here -->
  339. </div>
  340. <div class="card-body">
  341. <span class="btn btn-green btn-lg btn-block" id="finishbtn"><i class="fas fa-receipt"></i> <?php
  342. if ($editing) {
  343. lang("update");
  344. } else if ($returning) {
  345. lang("return");
  346. } else {
  347. lang("finish");
  348. }
  349. ?></span>
  350. </div>
  351. </div>
  352. </div>
  353. </div>
  354. </div>
  355. <script nonce="<?php echo $SECURE_NONCE; ?>">
  356. var showgridbydefault = <?php echo $showgridbydefault === true && $editing !== true && $returning !== true ? "true" : "false" ?>;
  357. </script>
  358. <?php
  359. }
  360. ?>