How to create a sales transactions page with PHP, jquery, and adminLTE. We have been at the end of the tutorial create a point of sale system with PHP. This article was the initial goal of the tutorial create a point of sale with PHP and AdminLTE. In this article, I will discuss how to create a simple sales page. In addition, the complete source of this project will share on this part. Let’s follow the tutorial
For those of you who don’t follow the tutorial from the first, please read them in advance every part via the following URL links.
- Creating login page – Tutorial Build Point Of Sale With PHP, PDO, MySQL And Jquery Part 1.
- Create Dynamic Menu and Dashboard Page – Tutorial Build Point Of Sale With PHP, PDO, MySQL And Jquery Part 2.
- Create Master User Form – Tutorial Build Point Of Sale With PHP, PDO, MySQL And Jquery Part 3.
- Create Master Item / Product Form – Tutorial Build Point Of Sale With PHP, PDO, MySQL And Jquery Part 4.
- Creating Sales Form / Point of sale – Tutorial Build Point Of Sale With PHP, PDO, MySQL And Jquery Part 5
Sales form is used to manage sales transactions. Every sale transaction done will reduce stock items and print struck sales. This module is still very simple because it is only used as a learning process.
Table of Contents
Tutorial Create a sales page with PHP, PDO, jquery and adminLTE
Database Preparation
Add 3 new tables in “pos” database: t_sale, t_sale_detail, temp_sale. To create 3 tables above please see the structure of the table in the following image:
A little explanation of the table:
t_sale is used to store primary data on sales transactions. Table t_sale_detail to store details of items that are on sale transaction with the certain transaction code. And the temp_sale table is used to store temporary of detail items, and the data in the temp_sale will be deleted when the transaction is successfully saved and or at the beginning of login, all of the temp_sale data on the user will be emptied.
Please create 3 new store procedure: saveSale, deleteSale, restore_stock_sale
saveSale
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 | DELIMITER $$ USE 'pos'$$ DROP PROCEDURE IF EXISTS 'saveSale'$$ CREATE PROCEDURE 'saveSale'(pre_sale_id VARCHAR(7), var_sale_date DATE , var_paid INT,discprcn DECIMAL(5,2),discrp INT,var_unique VARCHAR(13) ,iduser INT,var_note TEXT) BEGIN DECLARE v_finished INTEGER DEFAULT 0; DECLARE next_sale_id,next_value VARCHAR(10); DECLARE count_of_sale INT; DECLARE cid_item VARCHAR(6); DECLARE cname VARCHAR(100); DECLARE cqty,cdiscrp,cprice INT; DECLARE cunit VARCHAR(4); DECLARE cdiscprc DECIMAL(5,2); DECLARE tempsale CURSOR FOR SELECT id_item,item_name,qty,unit,price,discprc,discrp FROM temp_sale WHERE uniqid = var_unique AND id_user = iduser ; DECLARE CONTINUE HANDLER FOR NOT FOUND SET v_finished = 1; SELECT COUNT(sale_id) FROM t_sale WHERE SUBSTR(sale_id,1,7) = pre_sale_id INTO count_of_sale; IF count_of_sale = 0 THEN SET next_value = '1'; ELSE SELECT TRIM(CAST((CAST(SUBSTR(sale_id,8,3) AS UNSIGNED)+1) AS CHAR(3))) FROM t_sale WHERE SUBSTR(sale_id,1,7) = pre_sale_id ORDER BY sale_id DESC LIMIT 1 INTO next_value; END IF; IF (LENGTH(next_value) = 1) THEN SET next_sale_id=CONCAT(pre_sale_id,'00',next_value); ELSE IF (LENGTH(next_value) = 2) THEN SET next_sale_id=CONCAT(pre_sale_id,'0',next_value); ELSE SET next_sale_id=CONCAT(pre_sale_id,next_value); END IF ; END IF ; INSERT INTO t_sale(sale_id,id_user,sale_date, paid,disc_prcn,disc_rp,sts,note) VALUES (next_sale_id,iduser,var_sale_date,var_paid,discprcn,discrp,1,var_note); OPEN tempsale; get_tempsale: LOOP FETCH tempsale INTO cid_item,cname,cqty,cunit,cprice,cdiscprc,cdiscrp; IF v_finished = 1 THEN LEAVE get_tempsale; END IF; INSERT INTO t_sale_detail(sale_id,id_item,item_name,qty,unit,price,disc_prc,disc_rp) VALUES (next_sale_id,cid_item,cname,cqty,cunit,cprice,cdiscprc,cdiscrp); UPDATE m_item SET stock = stock - cqty WHERE id_item = cid_item; END LOOP get_tempsale; CLOSE tempsale; SELECT next_sale_id; END$$ DELIMITER ; |
saveSale store procedure is used to store transactions into the database.
deleteSale
1 2 3 4 5 6 7 8 9 10 11 12 13 | DELIMITER $$ USE 'pos'$$ DROP PROCEDURE IF EXISTS 'deleteSale'$$ CREATE DEFINER='root'@'localhost' PROCEDURE 'deleteSale'(x_sale_id VARCHAR(10),cnote TEXT) BEGIN CALL restore_stock_sale(x_sale_id); UPDATE t_sale SET sts = 0,note = cnote WHERE sale_id= x_sale_id; END$$ DELIMITER ; |
deleteSale store procedure is used to remove sales transactions from the database. The sales transaction is not deleted with DELETE MySQL function but only UPDATE MySQL by changing the sts field to 0. Because in Information system security, a transaction history is very important.
restore_stock_sale
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 | DELIMITER $$ USE 'pos'$$ DROP PROCEDURE IF EXISTS 'restore_stock_sale'$$ CREATE DEFINER='root'@'localhost' PROCEDURE 'restore_stock_sale'(var_sale_id VARCHAR(10)) BEGIN DECLARE v_finished INTEGER DEFAULT 0; DECLARE cid_item VARCHAR(6); DECLARE cqty INT; DECLARE deletesale CURSOR FOR SELECT id_item,qty FROM t_sale_detail WHERE sale_id = var_sale_id ; DECLARE CONTINUE HANDLER FOR NOT FOUND SET v_finished = 1; OPEN deletesale; get_deletesale: LOOP FETCH deletesale INTO cid_item,cqty; IF v_finished = 1 THEN LEAVE get_deletesale; END IF; UPDATE m_item SET stock = stock + cqty WHERE id_item = cid_item; END LOOP get_deletesale; CLOSE deletesale; END$$ DELIMITER ; |
restore_stock_sale store procedure is used to restore stock items as they were when sales transactions were removed.
In this section, we will add 4 new files in the sales folder (pos/application/sales/) and edit the pos.php file to add a list of MySQL queries in the sales table. Copy the following code on each file
autocomplete_item.php
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 | <?php session_start(); require _once ("../model/dbconn.php"); require _once ("../model/pos.php"); $term = trim(strip_tags($_GET['term'])); $row_set = array(); $pos = new pos(); $data = $pos->autoCompleteItem($term); foreach ($data[1] as $row) { $row['label']=htmlentities(stripslashes($row['item_name'])); $row['value']=htmlentities(stripslashes($row['item_name'])); if($row['note'] == '' or $row['note'] == null){ $row['note']=''; }else{ $row['note']='<dd><small> Note : '.$row['note'].'</small></dd>'; } $row['price']='<dd><small> Rp.'.number_format($row['price']).' /'.$row['unit'].'</small></dd>'; $row['id_item']=$row['id_item']; $row['unit']=$row['unit']; $row_set[] = $row; } echo json_encode($row_set); ?> |
v_pos.php
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 199 200 201 202 203 204 205 206 207 208 209 210 211 212 213 214 215 216 217 218 219 220 221 222 223 224 225 226 227 228 229 230 231 232 233 234 235 236 237 238 239 240 241 242 243 244 245 246 247 248 249 250 251 252 253 254 255 256 257 258 259 260 261 262 263 264 265 266 267 268 269 270 271 272 273 274 275 276 277 278 279 280 281 282 283 284 285 286 287 288 289 290 291 292 293 294 295 296 297 298 299 300 301 302 303 304 305 306 307 308 309 310 311 312 313 314 315 316 317 318 319 320 321 322 323 324 325 326 327 328 329 330 331 332 333 334 | <?php $titlepage="POINT OF SALE"; $idsmenu=2; include "../../library/config.php"; require _once("../model/dbconn.php"); require _once("../model/pos.php"); include "../layout/top-header.php"; include "../../library/check_login.php"; include "../../library/check_access.php"; ?> <link rel="stylesheet" href="../../dist/css/bootstrap-switch.min.css"> <link rel="stylesheet" href="../../plugins/datepicker/datepicker3.css"> <?php include "../layout/header.php"; ?> <section class="content"> <div class="row"> <div class="col-md-8"> <div class="box box-success"> <div class="box-header with-border"> <h3 class="bordercool">Point Of Sale</h3> <input type="text" class="form-control text-uppercase" id="txtsearchitem" placeholder="Search item name or item id here..."> </div><!--./ box header--> <div class="box-body"> <div class="box-body table-responsive no-padding"> <table id="table_transaction" class="table table-bordered table-hover "> <thead> <tr class="tableheader"> <th style="width:40px">#</th> <th style="width:60px">Id</th> <th style="width:250px">Item</th> <th style="width:120px">Price</th> <th style="width:60px">Qty</th> <th style="width:60px">Disc %</th> <th style="width:120px">Total</th> <th style="width:px"></th> </tr> </thead> <tbody></tbody> </table> </div> </div><!-- /.box-body --> </div><!-- /.box --> </div><!-- /.col-md-8 --> <div class="col-md-4"> <div class="box box-danger"> <div class="box-header with-border"> <button type="submit" title="Reset / cancel transaction" class="btn btn-primary bg-navy" id="btncancel" ><i class="fa fa-remove"></i> Reset</button> </div><!--./ box header--> <div class="box-body"> <div class="form-horizontal"> <div class="box-body"> <div class="form-group"> <label class="col-sm-3 control-label">Id Trans.</label> <div class="col-sm-9"> <div class="input-group "> <input type="text" class="form-control " id="txtidsales" value="J160412###" disabled> <span class="input-group-btn "> <button type="submit" title="Get last transaction" class="btn btn-primary " id="btnopentransaction" name="btnopentransaction"> <i class="fa fa-search"></i> </button> </span> </div> </div> </div> <div class="form-group"> <label class="col-sm-3 control-label">Date Trans.</label> <div class="col-sm-9"> <input readonly="" type="text" class="form-control txtsalesdate" id="txtsalesdate" value="20-04-2017" > </div> </div> <div class="form-group"> <label class="col-sm-3 control-label">Cashier</label> <div class="col-sm-9"> <input type="text" class="form-control " id="txtchasiername" value="admin" disabled> </div> </div> <div class="form-group"> <label class="col-sm-3 control-label"><a href="#" class="btndisc btndiscprc">Dsc %</a></label> <div class="col-sm-9"> <div class="input-group "> <input type="text" class="form-control decimal" id="txttotaldiscprc" value="0" > <span class="input-group-addon ">%</span> </div> </div> </div> <div class="form-group"> <label class="col-sm-3 control-label"><a href="#" class="btndisc btndiscrp">Dsc Rp</a></label> <div class="col-sm-9"> <div class="input-group"> <span class="input-group-addon">Rp.</span> <input type="text" class="form-control money textright" id="txttotaldiscrp" name="txttotaldiscrp" value="0" disabled> </div> </div> </div> <div class="form-group"> <label class="col-sm-3 control-label">Sub Total</label> <div class="col-sm-9"> <div class="input-group"> <span class="input-group-addon">Rp.</span> <input type="text" class="form-control " id="txtsubtotal" value="0" disabled> </div> </div> </div> </div> </div> <div class="info-box" style="margin-top:15px;"> <span class="info-box-icon bg-yellow">Rp.</span> <div class="info-box-content"> <span class="info-box-number newbox" id="txttotal">0</span> </div><!-- /.info-box-content --> </div> <div class="form-horizontal"> <div class="box-body"> <div class="form-group"> <label class="col-sm-12" control-label=""> <button type="submit" title="Payment (F9)" class="btn btn-primary btn-success btn-block btnpayment" id="btnpayment" > <i class="fa fa-shopping-cart"></i>[F9] Proccess Payment </button> </label> </div> </div> </div> </div> <!-- /.box-body --> </div><!-- /.box --> </div><!-- /.col-md-4 --> </div><!-- /.row --> </section><!-- /.content --> <div id="modaleditparam" class="modal fade "> <div class="modal-dialog modal-sm"> <div class="modal-content"> <div class="modal-header"> <button type="button" class="close" data-dismiss="modal">×</button> <h4 class="modal-title">Edit</h4> </div><!--modal header--> <div class="modal-body"> <div class="form-horizontal"> <div class="box-body"> <div class="form-group"> <label class="col-sm-12" control-label=""> <input type="text" class="form-control money textright" id="txtvalue" name="txtvalue" > <input type="hidden" id="txtdataparam" > <input type="hidden" id="txtkey"> </label> </div> <div class="form-group"> <label class="col-sm-2 control-label"> <button type="submit" class="btn btn-primary " id="btnubahedit" > <i class="fa fa-edit"></i> Edit </button> <span id="infoproses"></span> </label> <div class="col-sm-10"> </div> </div> </div> </div> </div> <div class="modal-footer"> <button type="button" class="btn btn-default" data-dismiss="modal">Close</button> </div><!--modal footer--> </div><!--modal-content--> </div><!--modal-dialog modal-lg--> </div><!--modaleditparam--> <div id="modalpayment" class="modal fade "> <div class="modal-dialog modal-md"> <div class="modal-content"> <div class="modal-header"> <button type="button" class="close" data-dismiss="modal">×</button> <h4 class="modal-title"></h4> <h3><i class="fa fa-shopping-cart"></i> Payment</h3> </div><!--modal header--> <div class="modal-body"> <div class="form-horizontal"> <div class="box-body"> <div class="form-group"> <label class="col-sm-4 control-label">Transaction Id</label> <div class="col-sm-8"> <input type="text" class="form-control " id="txtinfoidtrans" disabled=""> </div> </div> <div class="form-group"> <label class="col-sm-4 control-label">Transaction Date</label> <div class="col-sm-8"> <input type="text" class="form-control " id="txtinfodatetrans" disabled=""> </div> </div> <div class="form-group"> <label class="col-sm-4 control-label">Total Payable Amount</label> <div class="col-sm-8"> <div class="input-group"> <span class="input-group-addon">Rp.</span> <input type="text" class="form-control money textright" id="txtgrandtotal" value="0" disabled=""> </div> </div> </div> <div class="form-group"> <label class="col-sm-4 control-label">Paid</label> <div class="col-sm-8"> <div class="input-group"> <span class="input-group-addon">Rp.</span> <input type="text" class="form-control money textright" id="txtmoneypay" value="0" > </div> </div> </div> <div class="form-group"> <label class="col-sm-4 control-label">Return Change</label> <div class="col-sm-8"> <div class="input-group"> <span class="input-group-addon">Rp.</span> <input type="text" class="form-control money textright" id="txtoddmoney" value="0" disabled=""> </div> </div> </div> <div class="form-group"> <label class="col-sm-4 control-label">Note</label> <div class="col-sm-8"> <textarea class="form-control " maxlength="100" rows="3" id="txtnote" placeholder="Max 100 words"></textarea> </div> </div> <div class="form-group"> <label class="col-sm-12" control-label "=" "><hr></label> </div><div class="form-group "> <label class="col-sm-12 " control-label"=""><span style="color:white;background-color:red;padding:5px;">* Please double check the transaction before making the payment process </span> </label> </div> <div class="form-group"> <label class="col-sm-4 control-label"></label> <div class="col-sm-8"> <button type="submit" title="Save Transaction ?" class="btn btn-primary pull-right" id="btnsavetrans" ><i class="fa fa-save"></i> Proccess</button> </div> </div> <div class="form-group"> <label class="col-sm-4 control-label"><span id="infoproccesspayment"></span> </label> <div class="col-sm-8"> </div> </div> </div> </div> </div> <div class="modal-footer"> <button type="button" class="btn btn-default" data-dismiss="modal">Close</button> </div> <!--modal footer--> </div> <!--modal-content--> </div> <!--modal-dialog modal-lg--> </div> <div id="modallasttrans" class="modal fade "> <div class="modal-dialog modal-md"> <div class="modal-content"> <div class="modal-header"> <button type="button" class="close" data-dismiss="modal">×</button> <h4 class="modal-title">Lists of transaction</h4> </div> <!--modal header--> <div class="modal-body"> <div class="form-group"> <label for="Periode">Period : </label> <input readonly="" type="text" class="form-control txtperiode tgl" id="txtfirstperiod" value="20-04-2017" style="width:100px "> - <input readonly="" type="text" class="form-control txtperiode tgl" id="txtlastperiod" value="20-04-2017" style="width:100px "> <button type="submit" title="Search transaction" class="btn btn-primary " id="btnfiltersale" ><i class="fa fa-refresh"></i> Search</button> </div> <hr> <div class="box-body table-responsive no-padding"> <table id="table_last_transaction" class="table table-bordered table-hover table-striped"> <thead> <tr class="tableheader"> <th style="width:30px">#</th> <th style="width:87px">Date</th> <th style="width:87px">Id Trx</th> <th style="width:100px">Total</th> <th style="width:80px">Cashier</th> <th style="width:px"></th> </tr> </thead> <tbody></tbody> </table> </div> </div> <div class="modal-footer"> <button type="button" class="btn btn-default" data-dismiss="modal">Close</button> </div> <!--modal footer--> </div> <!--modal-content--> </div> <!--modal-dialog modal-lg--> </div> <div id="passwordmodal" class="modal fade "> <div class="modal-dialog modal-md"> <div class="modal-content"> <div class="modal-header"> <button type="button" class="close" data-dismiss="modal">×</button> <h4 class="modal-title">Password</h4> </div> <!--modal header--> <div class="modal-body"> <div class="form-horizontal"> <div class="box-body"> <div class="form-group"> <label class="col-sm-12" control-label "=" "><span id="ketpassword ">Type password before edit transaction</span></label> </div><div class="form-group "> <label class="col-sm-12 " control-label"=""> <input type="password" class="form-control " id="txtpass" name="txtpass" > <input type="hidden" id="txthidetrxid" > <input type="hidden" id="txthiddentrans" > </label> </div> <div class="form-group"> <label class="col-sm-2 control-label"> <button type="submit" class="btn btn-primary " id="btncheckpass" name="btncheckpass"><i class="fa fa-lock"></i> Authentication</button> <span id="infopassword"></span> </label> <div class="col-sm-10"> </div> </div> </div> </div> </div> <div class="modal-footer"> <button type="button" class="btn btn-default" data-dismiss="modal">Close</button> </div> <!--modal footer--> </div> <!--modal-content--> </div> <!--modal-dialog modal-lg--> </div> <?php include "../layout/footer.php"; //footer template ?> <?php include "../layout/bottom-footer.php"; //footer template ?> <script src="../../plugins/datepicker/bootstrap-datepicker.js"></script> <script src="../../dist/js/redirect.js"></script> <script src="j_pos.js"></script> </body> </html> |
Display the front end of the sales menu as shown below.
j_pos.js
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 199 200 201 202 203 204 205 206 207 208 209 210 211 212 213 214 215 216 217 218 219 220 221 222 223 224 225 226 227 228 229 230 231 232 233 234 235 236 237 238 239 240 241 242 243 244 245 246 247 248 249 250 251 252 253 254 255 256 257 258 259 260 261 262 263 264 265 266 267 268 269 270 271 272 273 274 275 276 277 278 279 280 281 282 283 284 285 286 287 288 289 290 291 292 293 294 295 296 297 298 299 300 301 302 303 304 305 306 307 308 309 310 311 312 313 314 315 316 317 318 319 320 321 322 323 324 325 326 327 328 329 330 331 332 333 334 335 336 337 338 339 340 341 342 343 344 345 346 347 348 349 350 351 352 353 354 355 356 357 358 359 360 361 362 363 364 365 366 367 368 369 370 371 372 373 374 375 376 377 378 379 380 381 382 383 384 385 386 387 388 389 390 391 392 393 394 395 396 397 398 399 400 401 402 403 404 405 406 407 408 409 410 411 412 413 414 415 416 417 418 419 420 421 422 423 424 425 426 427 428 429 430 431 432 433 434 435 436 437 438 439 440 441 442 443 444 445 446 447 448 449 450 451 452 453 454 455 456 457 458 459 460 461 462 463 464 465 466 467 468 469 470 471 472 473 474 475 476 477 478 479 480 481 482 483 484 485 486 487 488 489 490 491 492 493 494 495 496 497 498 499 500 501 502 503 504 505 506 507 508 509 510 511 512 513 514 515 516 517 518 519 520 521 522 523 524 525 526 527 528 529 530 531 532 533 534 535 536 537 538 539 540 541 542 543 544 545 546 547 548 549 550 551 552 553 554 555 556 557 558 559 560 561 562 563 564 565 566 567 568 569 570 571 572 573 574 575 576 577 578 579 580 581 582 583 584 585 586 587 588 589 590 591 592 593 594 595 596 597 598 599 600 601 602 603 604 605 606 607 608 609 610 611 612 613 614 615 616 617 618 619 620 621 622 623 624 625 626 627 628 | $(document).ready( function () { $('#txtsalesdate,#txtfirstperiod,#txtlastperiod').datepicker({ format: 'dd-mm-yyyy', }); function reposition() { var modal = $(this), dialog = modal.find('.modal-dialog'); modal.css('display', 'block'); dialog.css("margin-top", Math.max(0, ($(window).height() - dialog.height()) / 2)); } $('.modal').on('show.bs.modal', reposition); $(window).on('resize', function() { $('.modal:visible').each(reposition); }); $( "#modaleditparam" ).find( ".modal-footer" ).remove(); $( "#modalpayment" ).find( ".modal-footer" ).remove(); decimal(); money(); init_data(); $( "#txtsearchitem" ).autocomplete({ search : function(){$(this).addClass('working');}, open : function(){$(this).removeClass('working');}, source: function(request, response) { $.getJSON("autocomplete_item.php", { term: $('#txtsearchitem').val() }, response); }, minLength:1, select:function(event, ui){ temptabel(ui.item.id_item); } }).autocomplete( "instance" )._renderItem = function( ul, item ) { return $( "<li>" ) .append( "<dl><dt>"+item.label + "</dt>"+item.price+item.note+ "</dl>" ) .appendTo( ul ); }; }); $(document).on("click",'#btncheckpass',function(){ var trx = $("#txthiddentrans").val(); var id_sales = $("#txthidetrxid").val(); if(id_sales == '' || id_sales == null) { $.notify({ message: "No transaction processed" },{ type: 'warning', delay: 5000, }); return; } var pass=$("#txtpass").val(); var value = { pass : pass, method : "check_password" }; $.ajax( { url : "../model/check_password.php", type: "POST", data : value, success: function(data, textStatus, jqXHR) { var data = jQuery.parseJSON(data); if(data.auth == true) { $("#passwordmodal").modal("hide"); $("#txtpass").val(""); delete_trans(id_sales); }else{ $.notify({ message: "Password does not match" },{ type: 'danger', delay: 10000, }); set_focus("#txtpass"); return; } }, error: function(jqXHR, textStatus, errorThrown) { loading_stop(); } }); }); function delete_trans(sale_id) { var value = { sale_id : sale_id, method : "delete_trans" }; loading_start(); $.ajax( { url : "c_pos.php", type: "POST", data : value, success: function(data, textStatus, jqXHR) { var data = jQuery.parseJSON(data); if(data.result == true) { $("#btnfiltersale").click(); }else{ $.notify({ message: "Error delete transaction , Error : "+data.error },{ type: 'danger', delay: 10000, }); } loading_stop(); }, error: function(jqXHR, textStatus, errorThrown) { loading_stop(); } }); } $(document).on("click",".btndeletesale",function(){ $("#passwordmodal").modal("show"); $("#txthidetrxid").val($(this).attr("sale_id")); $("#txthiddentrans").val("D"); $("#notepassword").html("Please enter user password to delete transaction!"); set_focus("#txtpass"); }); $(document).on("click","#btnpayment",function(){ var id_trans = $("#txtidsales").val(); var tgl_trans = $("#txtsalesdate").val(); if(id_trans == '' || id_trans == null){ $.notify({ message: "Please fill out id transaction!" },{ type: 'warning', delay: 10000, }); return; } if(tgl_trans == '' || tgl_trans == null){ $.notify({ message: "Please fill out transaction date!" },{ type: 'warning', delay: 10000, }); return; } var value = { method : "check_tempsale" }; $.ajax( { url : "c_pos.php", type: "POST", data : value, success: function(data, textStatus, jqXHR) { var data = jQuery.parseJSON(data); if(data.tempsale == false) { $.notify({ message: "No items have been selected in the shopping cart list!" },{ type: 'warning', delay: 10000, }); set_focus("#txtsearchitem"); return; }else { var total = parseInt(cleanString($("#txttotal").html())); $("#txtinfoidtrans").val($("#txtidsales").val()); $("#txtinfodatetrans").val($("#txtsalesdate").val()); $("#txtgrandtotal").val(addCommas(total)); $("#txtmoneypay").val(addCommas(total)); $("#txtoddmoney").val(0); $("#modalpayment").modal("show"); set_focus("#txtmoneypay"); } }, error: function(jqXHR, textStatus, errorThrown) { } }); }) $(document).on("blur","#txtmoneypay",function (){ var total = parseInt(cleanString($("#txttotal").html())); var paid = parseInt(cleanString($(this).val())); var returnchange = paid - total; if(isNaN(returnchange)) { returnchange = 0; $("#txtmoneypay").val(addCommas(total)); } if(paid < total){ $("#txtmoneypay").val(addCommas(total)); $("#txtoddmoney").val(0); }else{ $("#txtoddmoney").val(addCommas(returnchange)); } }); $(document).on("click","#btnsavetrans",function() { var sale_id = $("#txtidsales").val(); var sale_date = $("#txtsalesdate").val(); var paid = parseInt(cleanString($("#txtmoneypay").val())); var disc_prcn = parseFloat(cleanString($("#txttotaldiscprc").val())); var disc_rp = parseInt(cleanString($("#txttotaldiscrp").val())); var note= $("#txtnote").val(); swal({ title: "Payment", text: "Save payment ?", type: "warning", showCancelButton: true, confirmButtonColor: "#DD6B55", confirmButtonText: "Purchase", closeOnConfirm: true }, function(){ $("#btnsavetrans").prop('disabled', true); proccess_waiting("#infoproccesspayment"); var value = { sale_id : sale_id, sale_date : sale_date, paid : paid, disc_prcn : disc_prcn, disc_rp : disc_rp, note : note, method : "save_trans" }; $.ajax( { url : "c_pos.php", type: "POST", data : value, success: function(data, textStatus, jqXHR) { $("#btnsavetrans").prop('disabled', false); $("#infoproccesspayment").html(""); var data = jQuery.parseJSON(data); if(data.result == true){ var xid_sales = data.xid_sales; $("#modalpayment").modal('hide'); setTimeout(function() { $.redirect("nota_jual.php",{ id_sales: xid_sales,duplikasi:0},'POST','_blank'); }, 500); // After 420 ms reset_data(); }else{ $.notify({ message: "Error save transaction, error :"+data.error },{ type: 'danger', delay: 10000, }); } }, error: function(jqXHR, textStatus, errorThrown) { $("#infoproccesspayment").html(""); $("#btnsavetrans").prop('disabled', false); } }); }); }) $(document).on("click",".btndiscprc",function (e){ e.preventDefault(); $("#txttotaldiscprc").prop('disabled', false); $("#txttotaldiscrp").prop('disabled', true); $("#txttotaldiscprc").focus(); }); $(document).on("click",".btndiscrp",function (e){ e.preventDefault(); $("#txttotaldiscrp").prop('disabled', false); $("#txttotaldiscprc").prop('disabled', true); $("#txttotaldiscrp").focus(); }); $(document).on("blur","#txttotaldiscprc",function(){ if (isNaN($(this).val())) { $(this).val(0); } if($(this).val() > 100 || $(this).val() < 0 ){ $(this).val(0); var prcn = 0; }else{ var prcn = parseFloat($(this).val()); } var subtotal = parseInt(cleanString($("#txtsubtotal").val())); var discrp = subtotal * (prcn/100); var total = subtotal - discrp; $("#txttotaldiscrp").val(addCommas(discrp)); $("#txttotal").html(addCommas(total)); }); $(document).on("blur","#txttotaldiscrp",function(){ var subtotal = parseInt(cleanString($("#txtsubtotal").val())); if(parseInt(cleanString($(this).val())) > subtotal || parseInt(cleanString($(this).val())) < 0 ){ $(this).val(0); var discrp = 0; }else{ var discrp = parseInt(cleanString($(this).val())); } var prcn = (discrp/subtotal) * 100; if(isNaN(prcn)){ prcn = 0; } if(isNaN(discrp)){ discrp = 0; } var total = subtotal - discrp; $("#txttotaldiscprc").val(prcn.toFixed(2)); $("#txttotal").html(addCommas(total)); }); $(document).on("click","#btnubahedit",function(){ var nilai = cleanString($("#txtvalue").val()); var jenis = $("#txtdataparam").val(); var key = $("#txtkey").val(); var value = { nilai: nilai, jenis:jenis, key:key, method : "updatedetail" }; $.ajax( { url : "c_pos.php", type: "POST", data : value, success: function(data, textStatus, jqXHR) { var data = jQuery.parseJSON(data); if(data.result ==1){ var table = $('#table_transaction').DataTable(); table.ajax.reload( null, false ); $( "#modaleditparam" ).modal("hide"); refresh_total(); }else{ $.notify({ message: "Error edit , error :"+data.error },{ type: 'danger', delay: 10000, }); } }, error: function(jqXHR, textStatus, errorThrown) { } }); }); $(document).on("click",".btndelete",function(){ var id_item = $(this).attr("id_item"); var value = { id_item: id_item, method : "deletedetail" }; $.ajax( { url : "c_pos.php", type: "POST", data : value, success: function(data, textStatus, jqXHR) { var data = jQuery.parseJSON(data); if(data.result ==1){ var table = $('#table_transaction').DataTable(); table.ajax.reload( null, false ); refresh_total(); }else{ $.notify({ message: "Error delete list item , error :"+data.error },{ type: 'danger', delay: 10000, }); } }, error: function(jqXHR, textStatus, errorThrown) { } }); }); $(document).on("click",".editparam",function(){ var dataparam=$(this).attr("dataparam"); var datatitle=$(this).attr("datatitle"); var val=$(this).attr("val"); var key = $(this).attr("key"); $( "#modaleditparam" ).find( ".modal-title" ).html(datatitle); $("#txtdataparam").val(dataparam); $("#txtvalue").val(val); $("#txtkey").val(key) $("#modaleditparam").modal("show"); set_focus("#txtvalue"); }) $(document).on("click",".btnnota",function(){ var idjual = $(this).attr("id_sales"); var jnsjual = $(this).attr("jns_jual"); if(jnsjual == 1) { $.redirect("nota_jual.php",{ id_sales: idjual,duplikasi:1},'POST','_blank'); }else{ $.redirect("nota_tempo.php",{ id_sales: idjual,duplikasi:1},'POST','_blank'); } }); $(document).on("click","#btncancel",function(){ swal({ title: "Reset", text: "Empty transaction ?", type: "warning", showCancelButton: true, confirmButtonColor: "#DD6B55", confirmButtonText: "Reset", closeOnConfirm: true }, function(){ reset_data(); }); }); function temptabel(idbrg){ var value = { id_item: idbrg, method : "save_temptable" }; $.ajax( { url : "c_pos.php", type: "POST", data : value, success: function(data, textStatus, jqXHR) { var data = jQuery.parseJSON(data); if(data.result ==1){ var table = $('#table_transaction').DataTable(); table.ajax.reload( null, false ); $("#txtsearchitem").val(""); refresh_total(); set_focus("#txtsearchitem"); }else{ $.notify({ message: "Error save item , error :"+data.error },{ type: 'danger', delay: 10000, }); } }, error: function(jqXHR, textStatus, errorThrown) { } }); } function refresh_total(){ var value = { method : "get_subtotal" }; $.ajax( { url : "c_pos.php", type: "POST", data : value, success: function(data, textStatus, jqXHR) { var data = jQuery.parseJSON(data); var subtotal = data.subtotal; $("#txtsubtotal").val(addCommas(subtotal)); $("#txttotaldiscprc").blur(); var discrp = cleanString($("#txttotaldiscrp").val()); var total =addCommas(subtotal - discrp); $("#txttotal").html(total); }, error: function(jqXHR, textStatus, errorThrown) { } }); } $(document).bind('keydown', 'f9', function(){ $("#btnpayment").click(); }); function newkdtrans(){ var tgl = $("#txtsalesdate").val(); var thn = tgl.substr(8, 4); var bln = tgl.substr(3, 2); var dy = tgl.substr(0, 2); var _first = 'J'; $("#txtidsales").val(_first+thn+bln+dy+'###'); } function reset_data(){ var value = { method : "reset_table" }; $.ajax( { url : "c_pos.php", type: "POST", data : value, success: function(data, textStatus, jqXHR) { var data = jQuery.parseJSON(data); if(data.result ==1){ var table = $('#table_transaction').DataTable(); table.ajax.reload( null, false ); $("#txttotaldiscprc").val(0); $("#txttotaldiscrp").val(0); $("#txtsubtotal").val(0); $("#txttotal").html("0"); $("#txtnote").val(""); refresh_total(); set_focus("#txtsearchitem"); }else{ $.notify({ message: "Can not reset data, error :"+data.error },{ type: 'danger', delay: 10000, }); } }, error: function(jqXHR, textStatus, errorThrown) { } }); } $(document).on("click","#btnopentransaction",function(){ $("#modallasttrans").modal("show"); $("#table_last_transaction tbody").html(""); }); $(document).on("click","#btnfiltersale",function(){ var first = $("#txtfirstperiod").val(); var last = $("#txtlastperiod").val(); var value = { first : first, last : last, method : "get_trans_sale" }; $.ajax( { url : "c_pos.php", type: "POST", data : value, success: function(data, textStatus, jqXHR) { var data = jQuery.parseJSON(data); $("#table_last_transaction tbody").html(data.hasil); }, error: function(jqXHR, textStatus, errorThrown) { } }); }); function init_data(){ var value = { method : "getdata" }; $('#table_transaction').DataTable({ "paging": false, "lengthChange": false, "searching": false, "ordering": false, "info": false, "responsive": true, "autoWidth": false, "pageLength": 50, "dom": '<"top"f>rtip', "columnDefs": [ { className: "textright", "targets": [ 3,4,5,6 ] } ], "ajax": { "url": "c_pos.php", "type": "POST", "data":value, }, "columns": [ { "data": "urutan" }, { "data": "id_item" }, { "data": "item_name" }, { "data": "price" }, { "data": "qty" }, { "data": "discprc" }, { "data": "subtotal" }, { "data": "button" }, ] }); $("#txttotaldiscprc").val(0); $("#txttotaldiscrp").val(0); $("#txtsubtotal").val(0); $("#txttotal").html("0"); refresh_total(); set_focus("#txtsearchitem"); newkdtrans(); } |
c_pos.php
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 199 200 201 202 203 204 205 206 207 208 209 210 211 212 213 214 215 216 217 218 219 | <?php session_start(); require_ once ("../model /dbconn.php"); require_ once ("../model /pos.php"); function display_to_sql($date){ return substr($date,6,4).'-'.substr($date,3,2).'-'.substr($date,0,2); } $method=$_POST['method']; if( isset( $_SERVER['HTTP_X_REQUESTED_WITH'] ) && ( $_SERVER['HTTP_X_REQUESTED_WITH'] == 'XMLHttpRequest' ) ) { $pos = new pos(); $menu = $pos->getSubMenuById(6); $menu_log = $menu[1]; if($method == 'get_subtotal'){ $uniqid = $_SESSION['pos_uniqid']; $kasir = $_SESSION['pos_id']; $pos = new pos(); $array = $pos->getSubTotalTempSale($kasir,$uniqid); $result = array(); $result['result'] = $array[0]; $result['subtotal']=(int)$array[1]; echo json_encode($result); } if($method == 'get_trans_sale') { $first = display_to_sql($_POST['first']); $last = display_to_sql($_POST['last']); $pos = new pos(); $array = $pos->getTransSale($first,$last); $html=''; $result = array(); if($array[0] == true) { $i=1; foreach ($array[1] as $key) { if($key['sts']== 0) { $html .= '<tr class="strikeout">'; $btn = 'delete'; }else { $html .= '<tr >'; $btn = '<button type="submit" sale_id="'.$key['sale_id'].'" title="Delete Transaction" class="btn btn-danger btn-sm btndeletesale " id="btndeletesale'.$key['sale_id'].'" name="" ><i class="fa fa-remove"></i></button>'; } $html .= ' <td class="tdstrike">'.$i.'</td> <td class="tdstrike">'.date('d/m/Y',strtotime($key['sale_date'])).'</td> <td class="tdstrike">'.$key['sale_id'].'</td> <td class="tdstrike" style="text-align:right">Rp. '.number_format($key['total']).'</td> <td class="tdstrike">'.$key['username'].'</td> <td class="tdstrike" style="min-width:80px">'.$btn.'</td> </tr>'; $i++; } $result['hasil'] = $html; } echo json_encode($result); } if($method == 'check_tempsale'){ $uniqid = $_SESSION['pos_uniqid']; $kasir = $_SESSION['pos_id']; $pos = new pos(); $array = $pos->getSubTotalTempSale($kasir,$uniqid); $result = array(); $hasil = $array[1]; if($hasil >=1){ $result['tempsale']=true; }else { $result['tempsale']=false; } echo json_encode($result); } if($method == 'save_trans') { $sale_id = substr($_POST['sale_id'],0,7); $sale_date = display_to_sql($_POST['sale_date']); $paid = $_POST['paid'];; $disc_prcn = $_POST['disc_prcn']; $disc_rp = $_POST['disc_rp']; $note = $_POST['note']; $uniqid = $_SESSION['pos_uniqid']; $id_user = $_SESSION['pos_id']; $pos = new pos(); $insert = $pos->saveSale($sale_id, $sale_date,$paid,$disc_prcn,$disc_rp,$uniqid,$id_user,$note); $retval['result'] = $insert[0]; $retval['error'] = $insert[1]; $retval['xsale_id'] = $insert[2]; echo json_encode($retval); } if($method == 'save_temptable') { $uniqid = $_SESSION['pos_uniqid']; $kasir = $_SESSION['pos_id']; $id_item = $_POST['id_item']; $pos = new pos(); $result = array(); $query = $pos->getItem($id_item); $data = $query[1]; $result['id_item'] = $data['id_item']; $result['item_name'] = $data['item_name']; $result['qty'] = 1; $result['unit'] = $data['unit']; $result['price'] = $data['price']; $result['discprcn'] = 0; $result['discrp'] = 0; $check = $pos->getCheckProduk($kasir,$uniqid,$result['id_item']); $jum = $check[1]; if($jum >=1) { $update = $pos->updateTempSale($kasir,$uniqid,$result['id_item']); $retval['result'] = $update[0]; $retval['error'] = $update[1]; } else { $insert = $pos->saveTempSale($kasir,$uniqid,$result['id_item'],$result['unit'],$result['item_name'],$result['qty'], $result['price'], $result['discprcn'],$result['discrp']); $retval['result'] = $insert[0]; $retval['error'] = $insert[1]; } echo json_encode($retval); } if($method == 'reset_table'){ $uniqid = $_SESSION['pos_uniqid']; $iduser = $_SESSION['pos_id']; $pos = new pos(); $reset = $pos->resetTempSaleByUserSession($iduser,$uniqid); $retval['result'] = $reset[0]; $retval['error'] = $reset[1]; echo json_encode($retval); } if($method == 'deletedetail'){ $id_item = $_POST['id_item']; $uniqid = $_SESSION['pos_uniqid']; $kasir = $_SESSION['pos_id']; $pos = new pos(); $delete = $pos->deleteTempSaleProduct($kasir,$uniqid,$id_item); $retval['result'] = $delete[0]; $retval['error'] = $delete[1]; echo json_encode($retval); } if($method == 'updatedetail'){ $value=$_POST['nilai']; $jenis = $_POST['jenis']; $uniqid = $_SESSION['pos_uniqid']; $kasir = $_SESSION['pos_id']; $pos = new pos(); $key = explode('|', base64 _decode($_POST['key'])); $id_item = $key[0]; $unit = $key[1]; if($jenis == 'hargajual') { $update = $pos->updateTempSaleHargaSale($kasir,$uniqid,$id_item ,$value); } else if($jenis == 'qty') { $update = $pos->updateTempSaleQty($kasir,$uniqid,$id_item ,$value); } else if($jenis == 'disc') { $update = $pos->updateTempSaleDisc($kasir,$uniqid,$id_item ,$value); } else { echo 'error'; } $retval['result'] = $update[0]; $retval['error'] = $update[1]; echo json_encode($retval); } if($method == 'getdata' ){ $uniqid = $_SESSION['pos_uniqid']; $kasir = $_SESSION['pos_id']; $pos = new pos(); $array = $pos->getListTempSale($kasir,$uniqid); $data = $array[1]; $i=0; foreach ($data as $key) { $keys = $key['id_item'].'|'.$key['unit']; $keys = base64_encode($keys); $total = ($key['price'] - ($key['price'] * $key['discprc'] /100) ) * $key['qty'] ; $data[$i]['price'] = '<a href="#" class="editparam" key="'.$keys.'" datatitle="Harga Sale" dataparam="hargajual" val="'.number_format($key['price']).'">'.number_format($key['price']).'</a>'; $data[$i]['qty'] = '<a href="#" class="editparam" key="'.$keys.'" datatitle="Qty" dataparam="qty" val="'.number_format($key['qty']).'">'.number_format($key['qty']).' '.$key['unit'].'</a>'; $data[$i]['discprc'] = '<a href="#" class="editparam" key="'.$keys.'" datatitle="Discount" dataparam="disc" val="'.number_format($key['discprc'],2).'">'.number_format($key['discprc'],2).'</a>'; $data[$i]['subtotal'] = '<span class="csubtotal">'.number_format($total)."</span>"; $data[$i]['button'] = '<button type="submit" id_item="'.$key['id_item'].'" unit="'.$key['unit'].'" class="btn btn-primary btndelete btn-sm" id="btndeletes'.$key['id_item'].'" ><i class="fa fa-remove"></i></button>'; $i++; } $datax = array('data' => $data); echo json_encode($datax); } if($method == 'delete_trans') { $sale_id = $_POST['sale_id']; $username = $_SESSION['pos_username']; $notehapus = 'Deleted by : '.$username.' ,at : '.date("l jS \of F Y h:i:s A"); $pos = new pos(); $array = $pos->deleteSale($sale_id,$notehapus); $data['result'] = $array[0]; $data['error'] = $array[1]; echo json_encode($data); } } else { exit('No direct access allowed.'); } ?> |
And add the following code in the pos.php file
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 199 200 201 202 203 204 205 206 207 208 209 210 211 212 213 214 215 216 217 218 219 220 221 222 223 224 225 226 227 228 229 230 231 232 233 234 235 236 237 238 239 240 241 242 243 244 245 246 247 248 249 250 251 252 253 254 255 256 257 258 259 260 261 262 263 264 265 266 267 268 269 270 271 272 273 274 275 276 277 278 279 280 281 282 283 284 285 286 287 288 289 290 291 292 293 294 295 296 297 298 299 300 301 302 303 304 305 306 307 308 309 310 311 312 313 314 315 316 317 318 319 320 321 322 323 324 325 326 327 328 329 330 331 332 333 334 335 336 337 338 339 340 341 342 343 344 345 346 347 348 349 350 351 352 353 354 355 356 357 358 359 360 361 362 363 364 365 366 367 368 369 370 371 372 373 374 375 376 377 378 379 380 381 382 383 384 385 386 387 388 389 390 391 392 393 394 395 396 397 | public function deleteTempSaleByUser($iduser) { $db = $this->dblocal; try { $stmt = $db->prepare("delete from temp_sale where id_user = :id"); $stmt->bindParam("id",$iduser); $stmt->execute(); $stat[0] = true; $stat[1] = "Success Delete!"; return $stat; } catch(PDOException $ex) { $stat[0] = false; $stat[1] = $ex->getMessage(); return $stat; } } public function resetTempSaleByUserSession($iduser,$uniqid) { $db = $this->dblocal; try { $stmt = $db->prepare("delete from temp_sale where id_user = :id and uniqid = :uniqid"); $stmt->bindParam("id",$iduser); $stmt->bindParam("uniqid",$uniqid); $stmt->execute(); $stat[0] = true; $stat[1] = "Success Delete!"; return $stat; } catch(PDOException $ex) { $stat[0] = false; $stat[1] = $ex->getMessage(); return $stat; } } public function getListTempSale($cashier,$uniqid){ $db = $this->dblocal; try { $stmt = $db->prepare("SELECT @rownum := @rownum + 1 AS urutan,t.* FROM temp_sale t, (SELECT @rownum := 0) r where t.id_user= :cashier and t.uniqid= :uniqid ORDER BY input_date ASC"); $stmt->bindParam("cashier",$cashier); $stmt->bindParam("uniqid",$uniqid); $stmt->execute(); $stat[0] = true; $stat[1] = $stmt->fetchAll(PDO::FETCH_ASSOC); return $stat; } catch(PDOException $ex) { $stat[0] = false; $stat[1] = $ex->getMessage(); return $stat; } } public function deleteTempSaleProduct($cashier,$uniqid,$id_item) { $db = $this->dblocal; try { $stmt = $db->prepare("delete from temp_sale where id_user = :id and uniqid = :uniqid and id_item = :id_item "); $stmt->bindParam("id",$cashier); $stmt->bindParam("uniqid",$uniqid); $stmt->bindParam("id_item",$id_item); $stmt->execute(); $stat[0] = true; $stat[1] = "Success Delete!"; return $stat; } catch(PDOException $ex) { $stat[0] = false; $stat[1] = $ex->getMessage(); return $stat; } } public function updateTempSale($cashier,$uniqid,$id_item) { $db = $this->dblocal; try { $stmt = $db->prepare("update temp_sale set qty=qty+1 where uniqid= :uniqid and id_user = :cashier and id_item = :id_item "); $stmt->bindParam("cashier",$cashier); $stmt->bindParam("uniqid",$uniqid); $stmt->bindParam("id_item",$id_item); $stmt->execute(); $stat[0] = true; $stat[1] = "Success Edit!"; return $stat; } catch(PDOException $ex) { $stat[0] = false; $stat[1] = $ex->getMessage(); return $stat; } } public function updateTempSaleHargaSale($cashier,$uniqid,$id_item,$value) { $db = $this->dblocal; try { $stmt = $db->prepare("update temp_sale set price = :value where uniqid= :uniqid and id_user = :cashier and id_item = :id_item "); $stmt->bindParam("cashier",$cashier); $stmt->bindParam("uniqid",$uniqid); $stmt->bindParam("id_item",$id_item); $stmt->bindParam("value",$value); $stmt->execute(); $stat[0] = true; $stat[1] = "Sukses Ubah!"; return $stat; } catch(PDOException $ex) { $stat[0] = false; $stat[1] = $ex->getMessage(); return $stat; } } public function updateTempSaleQty($cashier,$uniqid,$id_item ,$value) { $db = $this->dblocal; try { $stmt = $db->prepare("update temp_sale set qty= :value where uniqid= :uniqid and id_user = :cashier and id_item = :id_item "); $stmt->bindParam("cashier",$cashier); $stmt->bindParam("uniqid",$uniqid); $stmt->bindParam("id_item",$id_item); $stmt->bindParam("value",$value); $stmt->execute(); $stat[0] = true; $stat[1] = "Success Edit!"; return $stat; } catch(PDOException $ex) { $stat[0] = false; $stat[1] = $ex->getMessage(); return $stat; } } public function deleteSale($sale_id,$note) { $db = $this->dblocal; try { $stmt = $db->prepare("call deleteSale(:id,:note)"); $stmt->bindParam("id",$sale_id); $stmt->bindParam("note",$note); $stmt->execute(); $stat[0] = true; $stat[1] = 'Success Delete'; return $stat; } catch(PDOException $ex) { $stat[0] = false; $stat[1] = $ex->getMessage(); return $stat; } } public function updateTempSaleDisc($cashier,$uniqid,$id_item,$value) { $db = $this->dblocal; try { $stmt = $db->prepare("update temp_sale set discprc = :value where uniqid= :uniqid and id_user = :cashier and id_item = :id_item "); $stmt->bindParam("cashier",$cashier); $stmt->bindParam("uniqid",$uniqid); $stmt->bindParam("id_item",$id_item); $stmt->bindParam("value",$value); $stmt->execute(); $stat[0] = true; $stat[1] = "Success Edit!"; return $stat; } catch(PDOException $ex) { $stat[0] = false; $stat[1] = $ex->getMessage(); return $stat; } } public function saveTempSale($cashier,$uniqid,$id_item,$unit,$item_name,$qty,$price,$discprn,$discrp) { $db = $this->dblocal; try { $stmt = $db->prepare("insert into temp_sale(id_user, uniqid, id_item, item_name, qty, unit, price, discprc, discrp) values (:cashier , :uniqid , :id_item, :item_name, :qty, :unit, :price, :discprn, :discrp)"); $stmt->bindParam("cashier",$cashier); $stmt->bindParam("uniqid",$uniqid); $stmt->bindParam("id_item",$id_item); $stmt->bindParam("unit",$unit); $stmt->bindParam("item_name",$item_name); $stmt->bindParam("qty",$qty); $stmt->bindParam("price",$price); $stmt->bindParam("discprn",$discprn); $stmt->bindParam("discrp",$discrp); $stmt->execute(); $stat[0] = true; $stat[1] = "Success save!"; return $stat; } catch(PDOException $ex) { $stat[0] = false; $stat[1] = $ex->getMessage(); return $stat; } } public function saveSale($sale_id,$sale_date,$paid,$disc_prcn,$disc_rp,$uniqid,$id_user,$note) { $db = $this->dblocal; try { $stmt = $db->prepare("call saveSale( :sale_id, :sale_date, :paid, :disc_prcn, :disc_rp, :uniqid, :id_user, :note)"); $stmt->bindParam("sale_id",$sale_id); $stmt->bindParam("sale_date",$sale_date); $stmt->bindParam("paid",$paid); $stmt->bindParam("disc_prcn",$disc_prcn); $stmt->bindParam("disc_rp",$disc_rp); $stmt->bindParam("uniqid",$uniqid); $stmt->bindParam("id_user",$id_user); $stmt->bindParam("note",$note); $stmt->execute(); $stat[0] = true; $stat[1] = "Success Save!"; $stat[2] = $stmt->fetchColumn(0); return $stat; } catch(PDOException $ex) { $stat[0] = false; $stat[1] = $ex->getMessage(); return $stat; } } public function getSubTotalTempSale($cashier,$uniqid){ $db = $this->dblocal; try { $stmt = $db->prepare("SELECT SUM((price - (price*(discprc/100)))*qty)AS total FROM temp_sale where uniqid= :uniqid and id_user = :cashier"); $stmt->bindParam("cashier",$cashier); $stmt->bindParam("uniqid",$uniqid); $stmt->execute(); $stat[0] = true; $stat[1] = $stmt->fetchColumn(0); $stat[2] = $stmt->rowCount(); return $stat; } catch(PDOException $ex) { $stat[0] = false; $stat[1] = $ex->getMessage(); return $stat; } } public function checkTempSale($cashier,$uniqid){ $db = $this->dblocal; try { $stmt = $db->prepare("SELECT id_user,uniqid FROM temp_sale where uniqid= :uniqid and id_user = :cashier"); $stmt->bindParam("cashier",$cashier); $stmt->bindParam("uniqid",$uniqid); $stmt->execute(); $stat[0] = true; $stat[1] = $stmt->rowCount(); return $stat; } catch(PDOException $ex) { $stat[0] = false; $stat[1] = $ex->getMessage(); return $stat; } } public function getCheckProduk($cashier,$uniqid,$id_item ){ $db = $this->dblocal; try { $stmt = $db->prepare("select * from temp_sale where uniqid= :uniqid and id_user = :cashier and id_item = :id_item"); $stmt->bindParam("cashier",$cashier); $stmt->bindParam("uniqid",$uniqid); $stmt->bindParam("id_item",$id_item); $stmt->execute(); $stat[0] = true; $stat[1] = $stmt->rowCount(); return $stat; } catch(PDOException $ex) { $stat[0] = false; $stat[1] = $ex->getMessage(); return $stat; } } public function getTransSale($awal,$akhir,$order = 'desc') { $db = $this->dblocal; try { $stmt = $db->prepare("SELECT a.`sale_date`,a.`sale_id`, (SELECT SUM((d.price - (d.price*(d.disc_prc/100)))*d.qty) AS total FROM t_sale_detail d WHERE d.sale_id = a.sale_id)AS total, c.`username`,a.sts,a.paid,a.disc_rp FROM t_sale a INNER JOIN m_user c ON a.`id_user` = c.`id_user` where (a.`sale_date` BETWEEN :awal AND :akhir) ORDER BY sale_id ".$order ); $stmt->bindParam("awal",$awal); $stmt->bindParam("akhir",$akhir); $stmt->execute(); $stat[0] = true; $stat[1] = $stmt->fetchAll(PDO::FETCH_ASSOC); return $stat; } catch(PDOException $ex) { $stat[0] = false; $stat[1] = $ex->getMessage(); return $stat; } } public function getSaleId($id){ $db = $this->dblocal; try { $stmt = $db->prepare("SELECT a.* ,c.`username` FROM t_sale a INNER JOIN m_user c ON a.`id_user` = c.`id_user` where a.sale_id = :id"); $stmt->bindParam("id",$id); $stmt->execute(); $stat[0] = true; $stat[1] = $stmt->fetch(PDO::FETCH_ASSOC); return $stat; } catch(PDOException $ex) { $stat[0] = false; $stat[1] = $ex->getMessage(); return $stat; } } public function getSaleDetailIdSale($id) { $db = $this->dblocal; try { $stmt = $db->prepare("SELECT @rownum := @rownum + 1 AS urutan, a.*, (a.price - ((a.price * a.disc_prc) /100) ) * a.qty as total from t_sale_detail a,(SELECT @rownum := 0) r where a.sale_id = :id"); $stmt->bindParam("id",$id); $stmt->execute(); $stat[0] = true; $stat[1] = $stmt->fetchall(PDO::FETCH_ASSOC); return $stat; } catch(PDOException $ex) { $stat[0] = false; $stat[1] = $ex->getMessage(); return $stat; } } |
Up to this point, the tutorial how to create a point of sale system with PHP, PDO, jquery and adminLTE has been completed. A brief explanation on the sales transaction page:
To add an item to the shopping cart grid, we use the jquery UI autocomplete. By typing the item name or item code in the text box field, jquery will display a list of items like the following picture
Jquery ajax will call autocomplete function in autocomplete_item.php file
To add the number of items, the user can click on the item qty section and will display the modal dialog to change qty.
If the user selects the same item in the autocomplete box, it will automatically add qty item to the grid.
process payment button will display the transaction payment modal dialog like the following picture:
After the transaction has been processed, jquery will execute the redirect script to display the sales receipt on the new browser tab (in PDF format). For the tutorial create sales receipt with PDF, I will discuss in the bonus article
Javascript redirect is useful to replace form element in HTML. This script is very useful for me to send data using POST method without creating form element in HTML.
DONE!! The tutorial point of sale system with PHP has been completed. In accordance with my promise from the beginning, you can download the complete source code of this project on the download link below:
I hope this article is helpful for all of us. If you feel helped by this article, Please give me a donation or a gift. To keep me excited about creating articles. ;p
Bonus article php tutorial how to create pdf receipt note with fpdf php library
Hi,
I find this tutorial very interesting.
Can you share the bonus article to create the PDF file.
Thanks and best regards,
Greg
Hello Greg,
Thank you for reminding me of the bonus article how to create a receipt note with PDF
I will make articles soon 🙂
here the bonus article
https://seegatesite.com/how-to-create-receipt-note-pdf-with-php/
Hi,
This is a very great concept for learning CRUD. The problem is I’m more familiar with mysqli (I have never done a project in mysqli) and I’m finding it really hard to convert or rewrite the whole module in mysqli (from PDO). Could there by any chance you have done one with mysqli and share. I will really appreciate it if I get to learn more.
I hope to hear from you soon.
Read more here:
https://seegatesite.com/create-simple-crud-with-datatables-jquery-and-adminlte/
Just a suggestion:
You better learn to use PDO, because PHP 7 does not support mysqli anymore. And using PDO, More practical to develop a larger project in my opinion 🙂
Thank you very much for the advice. I’ll keep PDO into consideration.
I believe the function getListTempSale($cashier,$uniqid) in the pos.php file is to get the rows in temporary sales table so that they can be populated in the datatable. I however don’t understand the query:
$stmt = $db->prepare(“SELECT @rownum := @rownum + 1 AS urutan,t.*
FROM temp_sale t,
(SELECT @rownum := 0) r where t.id_user= :cashier and t.uniqid= :uniqid ORDER BY input_date ASC”);
What does @rownum represent? Another question is on (SELECT @rownum := 0) r, what does it represent too? Please help me understand these lines of code.
We can anticipate it by emptying the contents of the table based on the user id when you login the system 🙂
Index table to make it easy to make numbering 🙂 Read more here https://stackoverflow.com/questions/8509996/is-there-a-way-to-get-the-row-number-in-mysql-like-the-rownum-in-oracle
If you have any suggestions, maybe share with Me 🙂
I think that’s the only available way. I, however have a couple of questions. I am trying to rewrite the pos codes using mysqli but I’m getting errors.
1. How do I keep the session for the uniquid active for a particular sale, mine keeps on changing every time a product is saved in the temp_sale table.
2. About method getdata: Once I have written my query
, I fetch the results and try to loop one record after another. I get an error Invalid argument supplied for foreach().
The following is the full code snippet:
3. Still on getting data method, I don’t see you calling the item_name, what’s the magic? 😉
4. While inserting or selecting record, I get confused on the part about encoding using json. For instance, after selecting sum of subtotal, I wanted to store it in $result[‘subtotal’]=(int)$row[‘total’]; Am I correct by doing that?
5. In pdo, I see that you have used both fetchall and fetch assoc in the same line. What’s the equivalent of mysqli for that?
6. On the success callback of json, how do we know what array index of the argument data to call? I’m asking specifically for $data.subtotal.
7. Lastly, I’m getting the error – DataTables warning: table id=table_transaction – Invalid JSON response – what I’m I missing out?
Dear Hagler,
Thank you for contacting me :), I will try to help you as much as I can
1. In the example application I applied, I did not provide an example of how to hold a transaction on a temporary table for a particular sale. If you want to save certain transactions on the temporary table, please create a new table to store the transaction you want to hold. temp_sale table is only used to store transaction details on the POS menu display
2. Try checking your mysql query using command
See the error 🙂
3. isn’t magic, see the code
the item_name in the t.*
4. I do not understand the question number 4 🙂
5. Learn mysqli fetch all here https://www.w3schools.com/php/func_mysqli_fetch_all.asp
6. To cheack callback of json, please push F12 to the browser and find the Network tab and find url callback from your json and push the response tab. follow the image below https://seegatesite.com/json-response/
7. Please follow the answer number 6 to know your mysql error from response tab 🙂
Hope my English can be understood 🙂
Thank you for asking me 🙂
Dear Sigit,
Many thanks for getting back to me. Your English is ok, I got every sentence that you typed. Don’t mind about question 4, I did some research and found out that I was doing it the wrong way.
I was able to handle much of the questions but 2. I still don’t get it how you are able to keep the uniqid for a particular sales detail and have another uniqid for another sale. In your code, I see that you defined the session such that every time a user logs in, it is created. I however did not see how it changes when make another sale. Does it get destroyed after a sale and we get redirected?
Another thing that still gets on my nerve is the fact that I get an error after doing an autocomplete search and a product details gets saved in the temp sale table, my dataTable does not display the details. It gives me the following error: DataTables warning: table id=table_transaction – Invalid JSON response
Each user has a unique code to define their sales details. Each time a sales transaction is completed, the system will delete / resubmit the sales details in the temp_sale table for that user based on that unique code
Usually the error is caused by mysql query. To see the error you have to check through the network tab like the image I have given to you 🙂
Hi Sigit,
First of all thank you very much for sharing such a great article. Sigit, i have observed that you have skipped some of the DB scripts or table etc ? because when i try to execute a sale transaction with sample data i get following error:
“Syntax error or access violation: 1305 PROCEDURE pos.saveSale does not exist”,”xsale_id”:null}”
waiting for your prompt response. Thanks
Hii cloud,
your error is “Syntax error or access violation: 1305 PROCEDURE pos.saveSale does not exist”,”xsale_id”:null}”
you skipped saveSale store procedure in your database, please check again the above article, I have written the saveSale the store procedure 🙂
Hi
Nice and good tutorial but i didn’t see about nota_jual.php file. Can you please list that also
here we go
https://seegatesite.com/how-to-create-receipt-note-pdf-with-php/
Thank you for your prompt reply where is this nota_tempo.php file
nota_tempo.php similary with nota_jual.php, you can build it by your self 🙂
Man, You are really GREAT! keep going!
The password is wrong
Please check again your keyboard 🙂
pass : seegatesite.com
Dear Mr. Sigit,
May I know which js, css or other files that involves to display the modal to add product, user, etc ?
Regards,
Malphin
here :
https://seegatesite.com/create-master-item-product-form-tutorial-build-point-of-sale-with-php-pdo-mysql-and-jquery-part-4/
https://seegatesite.com/create-form-user-tutorial-build-point-of-sale-with-php-pdo-mysql-and-jquery-part-3/
Thanks Mr Sigit !
May I know where is the variable “xid_sales” from in “j_pos.js”?
in the statement:-
var xid_sales = data.xid_sales;
Find out and corrected it :-
var xid_sales = data.xid_sales;
change to,
var xid_sales = data.xsale_id;
Thank you very much Mr Sigit.
Mr Sigit,
may i know how to make edit form after process for this , because i only saw for delete not for edit the items.
Thnx, this is usefull tutorial
I have never provided a sales edit menu at POS. You can use the sales returns menu.
But in this example I did not make a sales return module.
You can make it yourself, if you experience errors, you can discuss with me
i’m looking for the code how did you generate the id_item = PB0002 , but i can’t found . can you give me the secret and enlightenment for this, because i’m searching in pos and c_item.php also not found how became PB001…PB002….PB003 and ect
to generate id_item, I used MySql store procedure. Doesnt use PHP
I try to download the whole script by liking your Facebook page but nothing happened. Still unable to download can you share it through my email.
https://seegatesite.com/point-of-sale-php-example-project-by-seegatesite/
Password: seegatesite.com
Thanks!
Which database are you using?
How can I run it in xampp i don’t see index.php in the downloaded file
hi friend
how should I go around this ($key = explode(‘|’, base64 _decode($_POST[‘key’]));. this line.
Thank You for your project. it’s very useful in helping me to complete my final project at my university. But I don’t know your username and password for this application.
can you tell me
you can create your own username and password from user table. Use password value with md5 function.thanks 🙂
hello I cant log in sir.. how can I change he log in T_T
Did you create a user on the login page?
see the example here :
https://seegatesite.com/tutorial-build-point-of-sale-with-php-pdo-mysql-and-jquery-part-1/
Thank you so much.
Nice work
I need source code in zip. can I get sir ?
please read the old comment :). I share the source code
First let me say how nice this interface is. I’ve been trying different tutorials trying to learn/understand and come up with a simple sale/receive/transaction system for my little business.
I’m not understanding the nota_jual.php & nota_tempo.php part. Are these just confirmation/results pages?
Has anyone had any luck creating these?
nota_jual.php is invoice. You can create invoice from this link https://seegatesite.com/how-to-create-receipt-note-pdf-with-php/