· 6 years ago · Sep 13, 2019, 11:32 PM
1<!DOCTYPE html>
2<html>
3<head>
4 <meta charset="utf-8">
5 <meta http-equiv="X-UA-Compatible" content="IE=edge">
6 <link rel="icon" type="image/png" href="img/brand/favicon.png">
7
8 <!-- CSRF Token -->
9 <!--<meta name="csrf-token" content="{{ csrf_token() }}">-->
10
11 <title>POS | EmiFoodLovers</title>
12
13 <!-- Styles -->
14 <link href="css/bootstrap-glyphicons.min.css" rel="stylesheet">
15 <link href="css/bootstrap.min.css" rel="stylesheet">
16 <link href="https://cdnjs.cloudflare.com/ajax/libs/material-design-iconic-font/2.2.0/css/material-design-iconic-font.css" rel="stylesheet" >
17 <!-- @ stack("extra-css") -->
18 <link href="css/jquery.toast.css" rel="stylesheet">
19 <link href="css/style.css" rel="stylesheet">
20 <link href="css/app.css" rel="stylesheet">
21 <link href="css/colors/blue.css" id="theme" rel="stylesheet">
22</head>
23
24<body>
25
26
27<div id="sales-receipt" class="sideNav bg-white">
28 <div class="container">
29 <div class="row justify-content-end">
30 <div class="col-md-12 px-5">
31 <div class="row">
32 <div class="col-md-12">
33 <div class="pull-left">
34 <button class="btn btn-info btn-md" onclick="window.location.reload();">
35 <i class="mdi mdi-arrow-left-bold pr-2"></i> Next Sale
36 </button>
37 </div>
38 <div class="pull-right">
39 <button id="print" class="btn btn-danger btn-md" type="button"> <span><i class="fa fa-print pr-1"></i> Print</span> </button>
40 </div>
41 </div>
42 </div>
43 </div>
44 </div>
45 </div>
46
47 <div class="printableArea">
48 <div class="container">
49 <div class="mb-3">
50 <div class="row justify-content-between">
51 <div class="col-md-12 p-5 printableArea">
52 <h4>
53 <strong>SALES RECEIPT</strong><br>
54 <label>Transaction No:</label> <span id="trans-no"></span>
55 </h4>
56
57 <hr>
58
59 <div class="row">
60 <div class="col-md-12">
61 <div class="pull-left">
62 <address>
63 <h2 class="mb-0">
64 <strong class="text-danger">
65 <!-- {{ env("app_name") }} -->
66 </strong>
67 </h2>
68 <h6 class="text-muted m-1-5">
69 <span id="org-contact"></span><br>
70 <span id="org-address"></span>
71 </h6>
72 </address>
73 </div>
74
75 <div class="pull-right text-right">
76 <address>
77 <p>
78 <strong><!--Date: {{ \Carbon\Carbon::now(config("timezone"))->format('D, M j, Y g:i:s A') }} --> </strong>
79 </p>
80 </address>
81 </div>
82 </div>
83
84
85 <div class="col-md-12">
86 <div class="table-responsive m-t-40" style="clear:both">
87 <table class="table table-hover">
88 <thead>
89 <tr>
90 <th class="text-center">#</th>
91 <th>Product</th>
92 <th class="text-right">Quantity</th>
93 <th class="text-right">Unit Cost (<span class="naira">N</span>)</th>
94 <th class="text-right">Total (<span class="naira">N</span>)</th>
95 </tr>
96 </thead>
97
98 <tbody id="receipt-table"></tbody>
99 </table>
100 </div>
101 </div>
102
103 <div class="col-md-12">
104 <div class="pull-right text-right">
105 <hr>
106 <h3 class="pl-4 mb-2"><strong>Total: </strong><span class="naira">N</span><span id="sell-total"></span></h3>
107 <h6 class="pl-4"><strong>Amount Paid: </strong><span class="naira">N</span><span id="amount-paid"></span></h6>
108 <h6 class="pl-4"><strong>Remaining Balance: </strong><span class="naira">N</span><span id="paid-balance"></span></h6>
109 <h6 class="pl-4"><strong>Change: </strong><span class="naira">N</span><span id="paid-change"></span></h6>
110 <hr>
111 </div>
112 <div class="clearfix"></div>
113 <div class="text-center">
114 <h5 class="text-uppercase">Thank you for buying from us</h5>
115 <p class="text-muted">Returns are only accepted within 24 working hours from the time of purchase, on show of this receipt, and given the item is in an acceptable good condition</p>
116 </div>
117 <hr>
118 </div>
119 </div>
120 </div>
121 </div>
122 </div>
123 </div>
124 </div>
125</div>
126
127<div id="pay-drawer" class="sideNav">
128 <div class="container">
129 <div class="nav-top mb-3">
130 <div class="row justify-content-between">
131 <div class="col-md-3">
132 <button class="btn btn-danger" onclick="closeDrawer();">
133 <i class="mdi mdi-arrow-left-bold pr-2"></i>Return to POS
134 </button>
135 </div>
136
137 <div class="col-md-3 text-center">
138 <h3>Cash Tender & Change</h3>
139 </div>
140
141 <div class="col-md-3">
142 <button class="btn btn-success pull-right sell-button d-none">
143 Sell Products<i class="mdi mdi-arrow-right-bold pl-2"></i>
144 </button>
145 </div>
146 </div>
147 </div>
148
149 <div class="payment mt-3">
150 <div class="row">
151 <div class="col-md-4 payment-method pr-5">
152 <h4 class="pt-3">Select a payment method</h4>
153 <div class="">
154 <button class="btn payment-btn" data-mode="cash">Cash</button>
155 <button class="btn payment-btn" data-mode="cheque">Cheque</button>
156 <button class="btn payment-btn" data-mode="card">Credit/Debit Card</button>
157 </div>
158 </div>
159
160 <div class="col-md-8 payment-input">
161 <div class="payment-input-scroll d-block">
162 <div class="cart-total py-3">
163 <h5 class="px-5 mb-2">Total Amount:</h5>
164 <h1><span class="naira">N</span><span class="payment-total"></span></h1>
165 </div>
166
167 <div class="input-boxes my-5">
168 <!-- For cash payments -->
169 <div id="cash-payment" class="d-none">
170 <div class="row">
171 <div class="col-md-6">
172 <div class="form-group">
173 <label for="txtAmountTendered">Cash Tendered:</label>
174 <div class="input-group">
175 <span class="input-group-addon naira">N</span>
176 <input type="number" id="txtAmountTendered"
177 class="form-control input-lg cash-tendered"
178 name="cash_amount_tendered">
179 <span class="input-group-addon">.00</span>
180 </div>
181 </div>
182 </div>
183
184 <div class="col-md-6">
185 <div class="form-group">
186 <label for="txtChange">Change:</label>
187 <div class="input-group">
188 <span class="input-group-addon naira">N</span>
189 <input type="number" id="txtChange"
190 class="form-control input-lg cash-change" name="cash_change">
191 <span class="input-group-addon">.00</span>
192 </div>
193 </div>
194 </div>
195 </div>
196
197 <div class="row">
198 <div class="col-md-6">
199 <div class="form-group">
200 <label for="txtRemainingAmount">Remaining Amount:</label>
201 <div class="input-group">
202 <span class="input-group-addon naira">N</span>
203 <input type="number" id="txtRemainingAmount"
204 class="form-control input-lg cash-remaining-amount" value="0"
205 name="cash_remaining_amount">
206 <span class="input-group-addon">.00</span>
207 </div>
208 </div>
209 </div>
210
211 <div class="col-md-6">
212 <div class="form-group">
213 <label for="txtRemarks">Remarks:</label>
214 <textarea name="remarks" class="form-control input-lg" id="txtRemarks"
215 cols="30" rows="5"></textarea>
216 </div>
217 </div>
218 </div>
219 </div>
220 </div>
221 </div>
222 </div>
223 </div>
224 </div>
225 </div>
226</div>
227
228<div class="pos-body">
229 <div class="pos">
230 <div class="pos-top-header">
231 <div class="pos-branding">
232 <img class="pos-logo img-fluid" src="img/brand/logo-pos.png">
233 <!-- @if(Auth::check()) -->
234 <a id="switchUser" class="username dropdown-toggle waves-effect waves-dark" href="#"
235 data-toggle="dropdown" aria-haspopup="true" aria-expanded="false">
236 <span><!--{ { Auth: : user()-> username }} --></span>
237 </a>
238 <!--@endif -->
239 <div class="dropdown-menu dropdown-menu-right" aria-labelledby="switchUser">
240 <a class="dropdown-item" href="#">Switch User</a>
241 <a href="#" class="dropdown-item"
242 onclick="event.preventDefault(); document.getElementById('logout-form').submit()">Logout</a>
243 <form id="logout-form" action="{{ route('logout') }}" method="POST" style="display: none;">
244 <!-- {{ csrf_field() }} -->
245 </form>
246 </div>
247 </div>
248
249 <!-- @if(Auth::check())
250 @if(Auth::user()->authorizeRoles(["Manager"])) -->
251 <div class="right-header">
252 <div class="header-button">
253 <a href="{{ route('index') }}">Return Home</a>
254 </div>
255 </div>
256 <!-- @endif
257 @endif -->
258 </div>
259 <div class="pos-content">
260 <div class="window">
261 <div class="sub-window-container">
262 <div class="sub-window-container-fix">
263 <div class="screen">
264 <div class="left-pane">
265 <div class="window">
266 <div class="cart-window">
267 <div class="cart-window-container">
268 <div class="cart-window-container-fix">
269 <div class="order-container">
270 <div class="order-scroll">
271 <div class="order">
272 <div class="order-list">
273 <div class="order-empty">
274 <i class="mdi mdi-cart"></i>
275 <h4>Your shopping cart is empty</h4>
276 </div>
277 </div>
278
279 <div class='summary d-none clearfix'>
280 <div class='line'>
281 <div class='entry total'>
282 <span class='label pr-2'>Total:</span>
283 <span class='pr-1'><span
284 style="text-decoration: line-through">N</span></span><span
285 class='value'>0.00</span>
286 <div class='sub-entry'>Taxes: <span style='text-decoration: line-through'>N</span><span class='value'>0.00</span></div>
287 </div>
288 </div>
289 </div>
290 </div>
291 </div>
292 </div>
293 </div>
294 </div>
295 </div>
296
297 <div class="keypad-window collapsed">
298 <div class="keypad-window-container">
299 <div class="keypad-window-container-fix">
300 <div class="action-pad">
301 <button id="btnClearCart" class="button clear-cart">
302 <i class="mdi mdi-delete"></i>
303 <span>Clear Cart</span>
304 </button>
305 <button id="btnPay" class="button pay">
306 <div class="pay-circle">
307 <i class="mdi mdi-chevron-right"></i>
308 </div>
309 <span>Payment</span>
310 </button>
311 </div>
312
313 <div class="num-pad">
314 <button class="input-button number-char">1</button>
315 <button class="input-button number-char">2</button>
316 <button class="input-button number-char">3</button>
317 <button class="mode-button selected-mode" data-mode="quantity">Qty
318 </button>
319 <br>
320 <button class="input-button number-char">4</button>
321 <button class="input-button number-char">5</button>
322 <button class="input-button number-char">6</button>
323 <button class="mode-button" data-mode="discount">Disc</button>
324 <br>
325 <button class="input-button number-char">7</button>
326 <button class="input-button number-char">8</button>
327 <button class="input-button number-char">9</button>
328 <button class="mode-button" data-mode="price">Price</button>
329 <br>
330 <button class="input-button number-minus">+/-</button>
331 <button class="input-button number-char">0</button>
332 <button class="input-button number-char">.</button>
333 <button class="input-button numpad-backspace">
334 <img height="21" width="24"
335 src="img/pos/backspace.png"
336 style="pointer-events: none;">
337 </button>
338 </div>
339 </div>
340 </div>
341 </div>
342 </div>
343 </div>
344
345 <div class="right-pane">
346 <table class="layout-table">
347 <tbody>
348 <tr class="header-row">
349 <td class="header-cell">
350 <div>
351 <header class="right-pane-header">
352 <div class="breadcrumbs">
353 <span class="breadcrumb">
354 <span class="breadcrumb-button breadcrumb-home">
355 <i class="mdi mdi-home"></i>
356 </span>
357 </span>
358 </div>
359 <div class="select-category">
360 <span>Search Category:</span>
361 <select id="ddlSelectCategory" name="prod-category">
362 <!-- @ foreach($categories as $category) -->
363 <option value="1">PC</option>
364 <option value="2">Mobile</option>
365 <option value="3">Accesoire</option>
366 <!--<option value="{ { $ category->id }}">{ { $ category->name }}</option>
367 @ endforeach -->
368 </select>
369 </div>
370 <div class="search-box">
371 <form action="/product/barcode/find" onsubmit="event.preventDefault(); searchBarcode();">
372 <input placeholder="Search products" id="txtSearch" name="search">
373 </form>
374 <span class="search-clear"></span>
375 </div>
376 </header>
377 </div>
378 </td>
379 </tr>
380 <tr class="content-row">
381 <td class="content-cell">
382 <div class="content-container">
383 <div class="product-list-container">
384 <div class="product-list-scroll touch-scroll">
385 <div class="product-list">
386 <!-- @ if(isset($products))
387 @ foreach($products as $product) -->
388 <div class="product" id="p-{ { $ product->batch_id } }"
389 data-batch-id="1"
390 data-name="LENOVO"
391 data-price="20.5">
392
393 <div class="product-img">
394 <img src="img/pos/4.jpg"class="img-fluid">
395 <span class="price-tag">
396 <strong>
397 <span style="text-decoration: line-through">DT</span><span class="price">20.5<!--{{ $product->retail_price }}--></span>
398 </strong>
399 </span>
400 </div>
401 <div class="product-name">
402 Lenovo
403 <!--{{ $ product->variation_name }} -->
404 </div>
405 </div>
406 <div class="product" id="p-{ { $ product->batch_id } }"
407 data-batch-id="1"
408 data-name="LENOVO"
409 data-price="20.5">
410
411 <div class="product-img">
412 <img src="img/pos/4.jpg"class="img-fluid">
413 <span class="price-tag">
414 <strong>
415 <span style="text-decoration: line-through">DT</span><span class="price">20.5<!--{{ $product->retail_price }}--></span>
416 </strong>
417 </span>
418 </div>
419 <div class="product-name">
420 Lenovo
421 <!--{{ $ product->variation_name }} -->
422 </div>
423 </div>
424 <div class="product" id="p-{ { $ product->batch_id } }"
425 data-batch-id="1"
426 data-name="LENOVO"
427 data-price="20.5">
428
429 <div class="product-img">
430 <img src="img/pos/4.jpg"class="img-fluid">
431 <span class="price-tag">
432 <strong>
433 <span style="text-decoration: line-through">DT</span><span class="price">20.5<!--{{ $product->retail_price }}--></span>
434 </strong>
435 </span>
436 </div>
437 <div class="product-name">
438 Lenovo
439 <!--{{ $ product->variation_name }} -->
440 </div>
441 </div>
442 <!-- @ endforeach
443 @ endif -->
444 </div>
445 </div>
446 </div>
447 </div>
448 </td>
449 </tr>
450 </tbody>
451 </table>
452 </div>
453 </div>
454 </div>
455 </div>
456 </div>
457 </div>
458 </div>
459</div>
460
461
462<!-- Scripts -->
463<script src="js/jquery.min.js "></script>
464<script src="js/popper.min.js"></script>
465<script src="js/bootstrap.min.js"></script>
466<script src="js/jquery.slimscroll.js"></script>
467<script src="js/waves.js"></script>
468<script src="js/sticky-kit.min.js"></script>
469<script src="js/moment.min.js"></script>
470<script src="js/HelperFunctions.js"></script>
471<script src="js/jquery.toast.js"></script>
472<script src="js/jquery.printArea.js"></script>
473<script type="text/javascript">
474
475 var clicked = 0;
476 var remove = 0;
477 var price_clicked = 0;
478 var price_remove = 0;
479
480 $(document).ready(function () {
481 $("#txtSearch").change(function (e) {
482 findProduct();
483 });
484
485 // Get cart items (if any), and display in cart
486 getCartAndDisplay();
487
488 // Begin processing customer payment
489 $("#btnPay").click(function () {
490 var jqxhr = $.ajax({
491 url: "/pos/cart/process",
492 type: "get"
493 });
494
495 jqxhr.done(function (response, textStatus, jqXHR) {
496 if (response.success != "") {
497 var payment_total = currencyFormat.format(document.getElementsByClassName("summary")[0].firstElementChild.children[0]
498 .children[2].innerText.replace(",", "").replace(".00", "").replace(",", ""));
499 $(".payment-total").text(payment_total);
500
501 // On pass of process conditions, move to cash tender and change
502 // Reveal sidebar drawer
503 openDrawer();
504 }
505 });
506
507 jqxhr.fail(function (textStatus, errorThrown) {
508 $.toast({
509 heading: 'Error!',
510 text: "Ensure your cart is not empty or the total price is above zero (0.00)",
511 position: 'top-right',
512 loaderBg: '#ff6849',
513 icon: 'info',
514 hideAfter: 4000,
515 stack: 6
516 });
517 });
518 });
519
520 // Payment options buttons - Cash, Cheque, or Card
521 $(".payment-btn").click(function (e) {
522 e.preventDefault();
523 $(".payment-btn").removeClass("selected");
524 $(this).addClass("selected");
525 $("#cash-payment").removeClass("d-none");
526 });
527
528 // Handle all cash tendered and remaining balance/change values
529 $(".cash-tendered").keyup(function () {
530 var cash_value = $(this).val();
531 var cart_total_payment = document.getElementsByClassName("summary")[0].firstElementChild.children[0]
532 .children[2].innerText.replace(",", "").replace(".00", "").replace(",", "");
533
534 var change = parseInt(cart_total_payment, 10) - parseInt(cash_value, 10);
535 if (change > 0) {
536 $(".cash-change").val("0");
537 $(".cash-remaining-amount").val(change);
538 } else if (change < 0) {
539 $(".cash-change").val(change.toString().replace("-", ""));
540 $(".cash-remaining-amount").val("0");
541 } else {
542 $(".cash-change").val("0");
543 $(".cash-remaining-amount").val("0");
544 }
545
546 if (parseInt($(".cash-remaining-amount").val(), 10) != 0) {
547 $(".sell-button").removeClass("d-none");
548 }
549 });
550
551 // Reduce product stock according to sold quantity
552 $(".sell-button").click(function () {
553 // Ensure cash tendered is not empty
554 var tendered = $(".cash-tendered").val();
555 if (parseInt(tendered, 10) == 0) {
556 $.toast({
557 heading: 'Invalid Amount',
558 text: "Amount tendered cannot be zero",
559 position: 'top-right',
560 loaderBg: '#ff6849',
561 icon: 'error',
562 hideAfter: 7000,
563 stack: 6
564 });
565 return;
566 }
567
568 // Get change and balance remaining
569 var change = $(".cash-change").val();
570 var remaining = $(".cash-remaining-amount").val();
571 var payment_method = $(".payment-btn.selected").data("mode");
572 var remarks = $("#txtRemarks").val();
573
574 $.ajaxSetup({
575 headers: {
576 'X-CSRF-TOKEN': $('meta[name="csrf-token"]').attr('content')
577 }
578 });
579
580 var jqxhr = $.ajax({
581 url: "/pos/cart/sell",
582 type: "POST",
583 data: {
584 "tendered": tendered, "payment_method": payment_method,
585 "change": change, "balance_remaining": remaining, "remarks": remarks
586 }
587 });
588
589 jqxhr.done(function (response, textStatus, jqXHR) {
590 // Clear cart from session using ajax
591 $.ajax({
592 url: "/pos/cart/delete/all",
593 type: "get",
594 success: function(data, textStatus, jqXHR) {
595 // Display cart empty
596 $(".order-empty").removeClass("d-none");
597 }
598 });
599
600 // Show sales receipt page
601 $("#trans-no").text(response.sales_group.receipt_no);
602
603 // Append items to table
604 var items = response.items;
605 var count = 1;
606 $.each(items, function (k, v) {
607 var row = "<tr>";
608 row += "<td class=\"text-center\">" + count + "</td>";
609 row += "<td>" + v.name + "</td>";
610 row += "<td class=\"text-right\">" + v.quantity + "</td>";
611 row += "<td class=\"text-right\">" + currencyFormat.format(v.price) + "</td>";
612 row += "<td class=\"text-right\">" + currencyFormat.format(v.price * v.quantity) + "</td>";
613
614 $("#receipt-table").append(row);
615 count++;
616 });
617
618 // Total value
619 $("#sell-total").text(currencyFormat.format(response.sales_group.total_amount));
620 $("#amount-paid").text(currencyFormat.format(response.sales_group.amount_tendered));
621 $("#paid-balance").text(currencyFormat.format(response.sales_group.balance_due));
622 $("#paid-change").text(currencyFormat.format(response.sales_group.change_amount));
623
624 // Organisation Address & Contact
625 var _address = '123 Address Street, Address.';
626 var _contact = '00000000000';
627 if(response.settings) {
628 _address = response.settings.org_address;
629 _contact = response.settings.org_contact;
630 }
631
632
633 $("#org-address").text(_address);
634 $("#org-contact").text(_contact);
635
636 closeDrawer();
637 showReceipt();
638 });
639 });
640
641 // Print receipt
642 $("#print").click(function() {
643 var mode = 'popup' //'iframe'; //popup
644 var close = true;
645 var options = {
646 mode: mode,
647 popClose: close
648 };
649 $("div.printableArea").printArea(options);
650 });
651
652 // Remove all items from cart
653 $("#btnClearCart").click(function () {
654 // Remove all cart items
655 $(".order").find(".order-lines").remove();
656
657 // Hide summary div and set total price to zero
658 $(".summary").addClass("d-none");
659 $(".summary").find(".value").first().text("0");
660
661 // Clear cart from session using ajax
662 var jqxhr = $.ajax({
663 url: "/pos/cart/delete/all",
664 type: "get"
665 });
666
667 jqxhr.done(function (response, textStatus, jqXHR) {
668 $.toast({
669 heading: 'Cart Is Empty',
670 text: response.success,
671 position: 'top-right',
672 loaderBg: '#ff6849',
673 icon: 'info',
674 hideAfter: 4000,
675 stack: 6
676 });
677
678 // Display cart empty
679 $(".order-empty").removeClass("d-none");
680 });
681 });
682
683 // Customize scroll button for cart display
684 $('.order-scroll').slimScroll({
685 position: 'right',
686 size: "5px",
687 height: '100%'
688 });
689
690 // On clicking a product card, hide the .order-empty div
691 // then retrieve product details using AJAX
692 $("div.product").click(function (e) {
693 clicked = 0;
694 var id = $(this).attr("id").toString().replace("p-", "");
695 var name = $(this).data("name");
696 var price = $(this).data("price");
697 var qty = 1;
698 if (!$(".order-empty").hasClass("d-none")) {
699 $(".order-empty").addClass("d-none");
700 }
701
702 AddProductToCart([id, name, price, qty]);
703 });
704
705 // On clicking a mode button, toggle the .selected-mode class
706 // to indicate the active mode
707 $(".mode-button").click(function () {
708 if ($(".mode-button").has("selected-mode")) {
709 $(".mode-button").removeClass("selected-mode");
710 $(this).addClass("selected-mode");
711 }
712 });
713
714 // Numbers button
715 $(".number-char").click(function () {
716 if ($(".selected").length > 0) {
717 clicked++;
718 price_clicked++;
719 var mode = $(".selected-mode").data("mode");
720 var item_qty = document.getElementsByClassName("selected")[0].children[2].children[0].children[0].children[0];
721 var item_unit_price = document.getElementsByClassName("selected")[0].children[2].children[0].children[2];
722 var item_total_price = parseFloat(item_qty.innerText * item_unit_price.innerText);
723 var cart_total_price = $(".summary").find(".value").first().text().replace(",", "").replace(".00", "");
724
725 switch (mode) {
726 case "quantity":
727 if (price_clicked > 0) price_clicked = 0;
728
729 if ($(this).text() == ".") {
730 if (clicked == 1) {
731 clicked = 0;
732 }
733 return;
734 }
735
736 var num = parseInt($(this).text(), 10);
737 if (clicked == 1) {
738 item_qty.innerText = num;
739 clicked++;
740 remove = 0;
741 } else {
742 item_qty.innerText = item_qty.innerText + num;
743 }
744
745 // Re-calculate item and cart total price based on current qty
746 var updatedItemTotalPrice = parseFloat(item_qty.innerText * item_unit_price.innerText);
747 var updatedCartTotalPrice = updatedItemTotalPrice + ((parseFloat(cart_total_price) - item_total_price));
748
749 // Update item and cart total price
750 document.getElementsByClassName("selected")[0].children[1].children[1].innerText = currencyFormat.format(updatedItemTotalPrice);
751 $(".summary").find(".value").first().text(currencyFormat.format(updatedCartTotalPrice));
752 break;
753 case "discount":
754 if ($(this).text() == ".") {
755 return;
756 }
757 if (clicked > 0) clicked = 0;
758 if (price_clicked > 0) price_clicked = 0;
759 break;
760 case "price":
761 if ($(this).text() == ".") {
762 if (price_clicked == 1) {
763 price_clicked = 0;
764 }
765 return;
766 }
767 if (clicked > 0) clicked = 0;
768 var price = parseFloat($(this).text());
769
770 if (price_clicked == 1) {
771 item_unit_price.innerText = price;
772 price_clicked++;
773 } else {
774 item_unit_price.innerText = item_unit_price.innerText + price;
775 }
776
777 // Re-calculate item and cart total price based on current price
778 var updatedItemTotalPrice = parseFloat(item_qty.innerText * item_unit_price.innerText);
779 var updatedCartTotalPrice = updatedItemTotalPrice + ((parseFloat(cart_total_price) - item_total_price));
780
781 // Update item and cart total price
782 document.getElementsByClassName("selected")[0].children[1].children[1].innerText = currencyFormat.format(updatedItemTotalPrice);
783 $(".summary").find(".value").first().text(currencyFormat.format(updatedCartTotalPrice));
784 break;
785 }
786
787 var id = $(".selected").parent().data("id");
788 var name = $(".selected").parent().data("name");
789 UpdateProduct([id, name, item_unit_price.innerText, item_qty.innerText]);
790 }
791 });
792
793 // Backward delete/remove button
794 $(".numpad-backspace").click(function () {
795 if ($(".selected").length > 0) {
796 var mode = $(".selected-mode").data("mode");
797 var item_unit_price = document.getElementsByClassName("selected")[0].children[2].children[0].children[2];
798 var itemQty = document.getElementsByClassName("selected")[0].children[2].children[0].children[0].children[0];
799 var item_total_price = parseFloat(itemQty.innerText) * parseFloat(item_unit_price.innerText);
800 var cart_total_price = $(".summary").find(".value").first().text().replace(".00", "").replace(",", "").replace(",", "").replace(",", "");
801
802 switch (mode) {
803 case "quantity":
804 if (remove == 0) {
805 if (itemQty.innerText.length == 1) {
806 itemQty.innerText = 0;
807 clicked = 0;
808 remove = 1;
809 } else {
810 itemQty.innerText = itemQty.innerText.substring(0, (itemQty.innerText.length - 1));
811 }
812
813 // Re-calculate item and cart total price based on current qty
814 var updatedItemTotalPrice = parseFloat(itemQty.innerText * item_unit_price.innerText);
815 var updatedCartTotalPrice = parseFloat(cart_total_price) - (item_total_price - updatedItemTotalPrice);
816
817 //UpdateProduct([item_id, item_name, item_unit_price.innerText, cart_item.innerText]);
818
819 // Update item and cart total price
820 document.getElementsByClassName("selected")[0].children[1].children[1].innerText = currencyFormat.format(updatedItemTotalPrice);
821 $(".summary").find(".value").first().text(currencyFormat.format(updatedCartTotalPrice));
822
823 } else {
824 remove = 0;
825
826 // Remove item from CartCollection
827 var item_id = $(".selected").parent().data("id");
828 RemoveProduct(item_id);
829
830 // Remove from UI
831 $(".selected").parent().remove();
832 if ($(".selected").find().length == 0 && $(".order-lines").find().prevObject.length == 0) {
833 $(".summary").addClass("d-none");
834 $(".order-empty").removeClass("d-none");
835 }
836 }
837 break;
838 case "discount":
839 break;
840 case "price":
841 if (price_remove == 0) {
842 if (item_unit_price.innerText.length == 1 || item_unit_price.innerText == "0.00") {
843 item_unit_price.innerText = "0.00";
844 clicked = 0;
845 price_clicked = 0;
846 price_remove = 1;
847 } else {
848 item_unit_price.innerText = item_unit_price.innerText.substring(0, (item_unit_price.innerText.length - 1));
849 }
850
851 // Re-calculate item and cart total price based on current qty
852 var updatedItemSubTotal = itemQty.innerText * item_unit_price.innerText;
853 var updatedCartTotal = parseFloat(cart_total_price) - (item_total_price - updatedItemSubTotal);
854
855 // Update item and cart total price
856 document.getElementsByClassName("selected")[0].children[1].children[1].innerText = currencyFormat.format(updatedItemSubTotal);
857 $(".summary").find(".value").first().text(currencyFormat.format(updatedCartTotal));
858 } else {
859 price_remove = 0;
860 }
861 break;
862 }
863
864 if ($(".selected").length > 0) {
865 var id = $(".selected").parent().data("id");
866 var name = $(".selected").parent().data("name");
867 UpdateProduct([id, name, item_unit_price.innerText, itemQty.innerText]);
868 }
869 }
870 });
871 });
872
873 function searchBarcode() {
874 var barcode = $("#txtSearch").val();
875 $.ajax({
876 url: "/product/barcode/find",
877 type: "GET",
878 data: {"barcode": barcode},
879 dataType: "json",
880 success: function(data) {
881 if(typeof data.product == "string") {
882 $.toast({
883 heading: 'Error!',
884 text: "Barcode is not associated with any product",
885 position: 'top-right',
886 loaderBg: '#ff6849',
887 icon: 'info',
888 hideAfter: 4000,
889 stack: 6
890 });
891 }
892
893 $(".product").remove();
894 var variations = data.variations;
895 var url = "{{ asset('/inventory/products/') }}" + "/";
896 $.each(variations, function(k, v) {
897 var pname = v.product_name.toString();
898 for(var i=0; i <= v.product_name.toString().length; i++) {
899 pname = pname.replace(" ", "%20");
900 }
901 var img_url = url + pname + "/" + v.variation_img;
902 var html = "<div class=\"product\" id=\"p-" + v.batch_id + "\" data-batch-id=\"" + v.batch_id +
903 "\" data-name=\"" + v.variation_name + "\" data-price=\"" + v.retail_price + "\"> <div class=\"product-img\"><img src=" +
904 img_url + " class=\"img-fluid\">";
905 html += "<span class=\"price-tag\"><strong><span style=\"text-decoration: line-through\">N</span>" +
906 "<span class=\"price\">" + v.retail_price + "</span></strong></span>";
907 html += "</div><div class=\"product-name\">" + v.variation_name + "</div></div>";
908 $(".product-list").append(html);
909 });
910 }
911 });
912 }
913
914 function findProduct() {
915
916 }
917
918 // Open cash tender drawer
919 function openDrawer() {
920 document.getElementById("pay-drawer").style.width = "100%";
921 }
922
923 // Close cash tender drawer
924 function closeDrawer() {
925 document.getElementById("pay-drawer").style.width = "0";
926 }
927
928 function showReceipt() {
929 document.getElementById("sales-receipt").style.width = "100%";
930 }
931
932 function hideReceipt() {
933 document.getElementById("sales-receipt").style.width = "0";
934 }
935
936 // Retrieve cart items in session and display
937 function getCartAndDisplay() {
938 var jqxhr = $.ajax({
939 url: "/pos/cart",
940 type: "GET",
941 dataType: "json"
942 });
943
944 jqxhr.done(function (response, textStatus, jqXHR) {
945 // This will remove the 'selected' class from already existing cart item
946 // Remember this runs only when a new product is clicked, so logically it
947 // will remove highlight from the previously highlighted div element
948 // to enable the newly added div element to have the 'selected' class
949 if (response.length > 0) {
950 if (!$(".order-empty").hasClass("d-none")) {
951 $(".order-empty").addClass("d-none");
952 }
953
954 // Loop through result, create html and append to cart
955 // TODO: Add items to a sort of cart collection
956 var total_price = 0.00;
957 $.each(response, function (k, v) {
958 for (var key in v) {
959 var cart_item = "<ul class='order-lines' onclick='event.preventDefault(); clickedCartItem(" + v[key].id + ");' id='" + v[key].id + "' data-id='" + v[key].id + "' data-name='" + v[key].name + "'>";
960 cart_item += "<li class='order-line'><span class='product-name'>" +
961 v[key].name + "</span><span class='price'><span style='text-decoration: line-through'>N</span><span class='price-value'>"
962 + currencyFormat.format(parseFloat(v[key].quantity) * parseFloat(v[key].price)) + "</span></span><ul class='info-list'><li class='info'>" +
963 "<em>Qty: <span id='prod-quantity'>" + v[key].quantity + "</span></em>" + " at "
964 + "<span style='text-decoration: line-through'>N</span><span class='price-value'>" + v[key].price + "</span>"
965 + "</li></ul></li></ul>";
966
967 total_price = total_price + (parseFloat(v[key].price) * parseFloat(v[key].quantity));
968
969 $(".order-scroll > .order > .order-list").append(cart_item);
970 }
971 });
972
973 // Update cart total price
974 document.getElementsByClassName("summary")[0].firstElementChild.children[0]
975 .children[2].innerText = currencyFormat.format(total_price);
976
977 // Show price summary
978 if ($(".summary").hasClass("d-none")) {
979 $(".summary").removeClass("d-none");
980 }
981 }
982
983 // If no item in cart, length of '.order-lines' will be zero(0)
984 // If zero, show the 'cart is empty' icon and text
985 // Also, remove cart total price summary
986 // This is important for a case where no item is in cart list
987 // I think this is redundant or if not, too much work.
988 // TODO: Make code more efficient.
989 if (parseInt($(".order").find(".order-lines").length) == 0) {
990 if ($(".order-empty").hasClass("d-none")) {
991 $(".order-empty").removeClass("d-none");
992 }
993
994 if (!$(".summary").hasClass("d-none")) {
995 $(".summary").addClass("d-none");
996 }
997 }
998 });
999 }
1000
1001 // Toggle selection for cart items (on item click event)
1002 function clickedCartItem(id) {
1003 clicked = 0;
1004 $(".selected").removeClass("selected");
1005 var order = document.getElementById(id);
1006 $(".order-line").removeClass("selected");
1007 $(".order-list").find("#" + id).children(".order-line").addClass("selected");
1008 }
1009
1010 // Logic for displaying products and details in cart
1011 function AddProductToCart(values) {
1012 var id = values[0];
1013 var name = values[1];
1014 var price = values[2];
1015 var quantity = values[3];
1016
1017 $.ajaxSetup({
1018 headers: {
1019 'X-CSRF-TOKEN': $('meta[name="csrf-token"]').attr('content')
1020 }
1021 });
1022
1023 var jqxhr = $.ajax({
1024 url: "/pos/cart/store",
1025 type: "POST",
1026 data: {"batch_id": id, "name": name, "price": price, "quantity": quantity}
1027 });
1028
1029 jqxhr.done(function (response, textStatus, jqXHR) {
1030 if ($(".order-line").hasClass("selected")) {
1031 $(".order-line").removeClass("selected");
1032 }
1033
1034 var product = $("#p-" + id);
1035
1036 if(response.new_batch_exists == "true" || response.new_batch_exists == "regular") {
1037 if(response.new_batch) {
1038 var new_batch = response.new_batch;
1039 id = new_batch.id;
1040 price = new_batch.retail_price;
1041
1042 // If request has exceeded current stock quantity and a new stock exists,
1043 // replace batch_id of product in the list with the new batch_id
1044 product.attr("id", "p-"+id);
1045 product.attr("data-batch-id", id);
1046 product.attr("data-price", price);
1047 product.find(".price").text(price);
1048 }
1049
1050 var item_exists = document.getElementById(id);
1051 if (item_exists == null) {
1052 appendToCart(id, name, price, quantity);
1053 } else {
1054 // Re-highlight already existing cart item (div)
1055 if (!item_exists.firstElementChild.classList.contains("selected")) {
1056 item_exists.firstElementChild.classList.add("selected");
1057 }
1058
1059 // Update product quantity
1060 var qty = item_exists.firstElementChild.children[2].children[0].children[0]
1061 .children["prod-quantity"].innerHTML;
1062 item_exists.firstElementChild.children[2].children[0].children[0]
1063 .children["prod-quantity"].innerHTML = (parseInt(qty, 10) + 1).toString();
1064
1065 // update item subtotal
1066 var item_price = item_exists.firstElementChild.children[2].children[0].children[2].innerText;
1067 var updatedItemTotalPrice = (parseInt(qty, 10) + 1) * item_price;
1068 document.getElementsByClassName("selected")[0].children[1].children[1].innerText = currencyFormat.format(updatedItemTotalPrice);
1069
1070 // Update cart total price
1071 var displayed_total_unit_price = document.getElementsByClassName("summary")[0]
1072 .firstElementChild.children[0].children[2].innerText.replace(",", "").replace(".00", "");
1073 document.getElementsByClassName("summary")[0]
1074 .firstElementChild.children[0].children[2]
1075 .innerText = currencyFormat.format(parseFloat(displayed_total_unit_price) + parseFloat(item_price));
1076
1077 // Update PHP cart in session
1078 var batch_id = item_exists.attributes[2].value;
1079 var product_name = item_exists.attributes[4].value;
1080 var product_price = parseInt(item_price, 10);
1081 var product_quantity = (parseInt(qty, 10) + 1);
1082
1083 UpdateProduct([batch_id, product_name, product_price, product_quantity]);
1084 }
1085
1086 } else if(response.new_batch_exists == "false") {
1087 // remove item from product listing
1088 product.remove();
1089
1090 // display a message
1091 $.toast({
1092 heading: "Stock is Finished",
1093 text: "Product stock has been exhausted!",
1094 position: 'top-right',
1095 loaderBg: '#ff6849',
1096 icon: "info",
1097 hideAfter: 6000,
1098 stack: 6
1099 });
1100 }
1101 });
1102 }
1103
1104 // Update an existing cart item
1105 function UpdateProduct(values) {
1106 var id = values[0];
1107 var name = values[1];
1108 var price = values[2];
1109 var quantity = values[3];
1110
1111 $.ajaxSetup({
1112 headers: {
1113 'X-CSRF-TOKEN': $('meta[name="csrf-token"]').attr('content')
1114 }
1115 });
1116
1117 var jqxhr = $.ajax({
1118 url: "/pos/cart/store",
1119 type: "POST",
1120 data: {"batch_id": id, "name": name, "price": price, "quantity": quantity}
1121 });
1122
1123 // Callback handler that will be called on success
1124 jqxhr.done(function (response, textStatus, jqXHR) {
1125 /*$.each(response, function(k, v) {
1126 for (var key in v) {
1127 var cart_item = "<ul class='order-lines' onclick='event.preventDefault(); clickedCartItem(" + v[key].id + ");' id='" + v[key].id + "' data-id='" + v[key].id + "' data-name='" + v[key].name + "'>";
1128 cart_item += "<li class='order-line selected'><span class='product-name'>" +
1129 name + "</span><span class='price'><span style='text-decoration: line-through'>N</span><span class='price-value'>"
1130 + currencyFormat.format(v[key].price) + "</span></span><ul class='info-list'><li class='info'>" +
1131 "<em>Qty: <span id='prod-quantity'>" + v[key].quantity + "</span></em>" + " at "
1132 + "<span style='text-decoration: line-through'>N</span><span class='price-value'>" + v[key].price + "</span>"
1133 + "</li></ul></li></ul>";
1134 console.log(cart_item);
1135 }
1136 });*/
1137 });
1138 }
1139
1140 // Remove a product from cart based on given id
1141 function RemoveProduct(id) {
1142 var jqxhr = $.ajax({
1143 url: "/pos/cart/delete/" + id,
1144 type: "DELETE"
1145 });
1146
1147 jqxhr.done(function (response, textStatus, jqXHR) {
1148 // Show toast notification
1149 });
1150 }
1151
1152 // Append new item to cart
1153 function appendToCart(id, name, price, quantity) {
1154 var cart_item = "<ul class='order-lines' onclick='event.preventDefault(); clickedCartItem(" + id + ");' id='" + id + "' data-id='" + id + "' data-name='" + name + "'>";
1155 cart_item += "<li class='order-line selected'><span class='product-name'>" +
1156 name + "</span><span class='price'><span style='text-decoration: line-through'>N</span><span class='price-value'>"
1157 + currencyFormat.format(price) + "</span></span><ul class='info-list'><li class='info'>" +
1158 "<em>Qty: <span id='prod-quantity'>" + quantity + "</span></em>" + " at "
1159 + "<span style='text-decoration: line-through'>N</span><span class='price-value'>" + price + "</span>"
1160 + "</li></ul></li></ul>";
1161
1162 var total_price = document.getElementsByClassName("summary")[0].firstElementChild.children[0]
1163 .children[2].innerText.replace(",", "").replace(".00", "");
1164 total_price = parseFloat(total_price) + parseFloat(price * quantity);
1165
1166 $(".order-scroll > .order > .order-list").append(cart_item);
1167
1168 // Update cart total price
1169 document.getElementsByClassName("summary")[0].firstElementChild.children[0]
1170 .children[2].innerText = currencyFormat.format(total_price);
1171
1172 // Show price summary
1173 if ($(".summary").hasClass("d-none")) {
1174 $(".summary").removeClass("d-none");
1175 }
1176 }
1177</script>
1178</body>