Add refunds, close #14
This commit is contained in:
parent
d1a5b57934
commit
a07820c666
101
action.php
101
action.php
@ -200,6 +200,107 @@ switch ($VARS['action']) {
|
|||||||
return true;
|
return true;
|
||||||
});
|
});
|
||||||
|
|
||||||
|
if (!is_null($error)) {
|
||||||
|
exit(json_encode(["status" => "ERROR", "message" => $error]));
|
||||||
|
} else {
|
||||||
|
exit(json_encode(["status" => "OK", "txid" => $oktx]));
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
case "finish_return":
|
||||||
|
header("Content-Type: application/json");
|
||||||
|
$error = null;
|
||||||
|
$oktx = null;
|
||||||
|
$database->action(function ($database) {
|
||||||
|
global $VARS, $binstack, $error, $oktx;
|
||||||
|
|
||||||
|
$items = $VARS['items'];
|
||||||
|
$payments = $VARS['payments'];
|
||||||
|
$customer = $VARS['customer'];
|
||||||
|
$register = $VARS['register'];
|
||||||
|
$cashid = null;
|
||||||
|
|
||||||
|
if ($customer != "" && !$database->has('customers', ['customerid' => $customer])) {
|
||||||
|
$error = lang("invalid customer", false);
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
if ($register != "" && !$database->has('registers', ['registerid' => $register])) {
|
||||||
|
$error = lang("invalid register", false);
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
if ($register != "" && !$database->has('cash_drawer', ['AND' => ['registerid' => $register, 'close' => null]])) {
|
||||||
|
$error = lang("cash not open", false);
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
if ($register != "") {
|
||||||
|
$cashid = $database->get('cash_drawer', 'cashid', ['AND' => ['registerid' => $register, 'close' => null]]);
|
||||||
|
}
|
||||||
|
|
||||||
|
$totaldue = 0.00;
|
||||||
|
$totalrefund = 0.00;
|
||||||
|
foreach ($items as $i) {
|
||||||
|
$totaldue += $i['each'] * $i['qty'];
|
||||||
|
if (!$binstack->has('items', ['itemid' => $i['id']])) {
|
||||||
|
$error = lang("invalid item", false);
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
foreach ($payments as $p) {
|
||||||
|
if (!$database->has('payment_types', ['typename' => $p['type']])) {
|
||||||
|
$error = lang("invalid payment type", false);
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
$totalrefund += $p['amount'];
|
||||||
|
if ($p['type'] == "giftcard") {
|
||||||
|
if (!$database->has('certificates', ['AND' => ['amount[>=]' => $p['amount'], 'deleted[!]' => 1, 'certcode' => $p['code']]])) {
|
||||||
|
$error = lang("invalid giftcard", false);
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
$database->insert('transactions', [
|
||||||
|
'txdate' => date('Y-m-d H:i:s'),
|
||||||
|
'customerid' => ($customer != "" ? $customer : null),
|
||||||
|
'type' => 2,
|
||||||
|
'cashier' => $_SESSION['uid'],
|
||||||
|
'cashid' => $cashid,
|
||||||
|
'discountpercent' => 0.0
|
||||||
|
]);
|
||||||
|
$txid = $database->id();
|
||||||
|
|
||||||
|
foreach ($items as $i) {
|
||||||
|
$item = $binstack->get('items', ['name', 'qty'], ['itemid' => $i['id']]);
|
||||||
|
|
||||||
|
$database->insert('lines', [
|
||||||
|
'txid' => $txid,
|
||||||
|
'amount' => $i['each'],
|
||||||
|
'name' => $item['name'],
|
||||||
|
'itemid' => $i['id'],
|
||||||
|
'qty' => $i['qty'] * -1.0
|
||||||
|
]);
|
||||||
|
}
|
||||||
|
|
||||||
|
foreach ($payments as $p) {
|
||||||
|
$certid = null;
|
||||||
|
if ($p['type'] == "giftcard") {
|
||||||
|
$certid = $database->get('certificates', 'certid', ['certcode' => $p['code']]);
|
||||||
|
$database->update('certificates', ['amount[+]' => $p['amount']], ['certid' => $certid]);
|
||||||
|
}
|
||||||
|
$type = $database->get('payment_types', 'typeid', ['typename' => $p['type']]);
|
||||||
|
$database->insert('payments', [
|
||||||
|
'amount' => $p['amount'] * -1.0,
|
||||||
|
'data' => '',
|
||||||
|
'type' => $type,
|
||||||
|
'txid' => $txid,
|
||||||
|
'certid' => $certid
|
||||||
|
]);
|
||||||
|
}
|
||||||
|
|
||||||
|
$oktx = $txid;
|
||||||
|
return true;
|
||||||
|
});
|
||||||
|
|
||||||
if (!is_null($error)) {
|
if (!is_null($error)) {
|
||||||
exit(json_encode(["status" => "ERROR", "message" => $error]));
|
exit(json_encode(["status" => "ERROR", "message" => $error]));
|
||||||
} else {
|
} else {
|
||||||
|
@ -121,4 +121,8 @@ define("STRINGS", [
|
|||||||
"cash already closed" => "Cash already closed, cannot edit this transaction. Process a return instead.",
|
"cash already closed" => "Cash already closed, cannot edit this transaction. Process a return instead.",
|
||||||
"update" => "Update",
|
"update" => "Update",
|
||||||
"transaction search" => "Search transactions (by Tx ID or customer)",
|
"transaction search" => "Search transactions (by Tx ID or customer)",
|
||||||
|
"return" => "Return",
|
||||||
|
"enter refund" => "Enter Refund",
|
||||||
|
"refund" => "Refund",
|
||||||
|
"cannot edit return transaction" => "Cannot edit a return transaction."
|
||||||
]);
|
]);
|
||||||
|
@ -48,5 +48,9 @@ define("MESSAGES", [
|
|||||||
"register_name_taken" => [
|
"register_name_taken" => [
|
||||||
"string" => "register name taken",
|
"string" => "register name taken",
|
||||||
"type" => "danger"
|
"type" => "danger"
|
||||||
]
|
],
|
||||||
|
"return_transaction_no_edit" => [
|
||||||
|
"string" => "cannot edit return transaction",
|
||||||
|
"type" => "danger"
|
||||||
|
],
|
||||||
]);
|
]);
|
||||||
|
@ -14,7 +14,7 @@ class GenerateReceipt {
|
|||||||
const RECEIPT_TYPE_X = 2;
|
const RECEIPT_TYPE_X = 2;
|
||||||
const RECEIPT_TYPE_Z = 3;
|
const RECEIPT_TYPE_Z = 3;
|
||||||
|
|
||||||
static function transactionReceipt($transaction) {
|
private static function saleReceipt($transaction) {
|
||||||
global $database;
|
global $database;
|
||||||
$receipt = new Receipt();
|
$receipt = new Receipt();
|
||||||
$tx = $database->get('transactions', ['txid', 'txdate', 'customerid', 'type', 'cashier', 'discountpercent'], ['txid' => $transaction]);
|
$tx = $database->get('transactions', ['txid', 'txdate', 'customerid', 'type', 'cashier', 'discountpercent'], ['txid' => $transaction]);
|
||||||
@ -90,6 +90,82 @@ class GenerateReceipt {
|
|||||||
return $receipt;
|
return $receipt;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private static function returnReceipt($transaction) {
|
||||||
|
global $database;
|
||||||
|
$receipt = new Receipt();
|
||||||
|
$tx = $database->get('transactions', ['txid', 'txdate', 'customerid', 'type', 'cashier', 'discountpercent'], ['txid' => $transaction]);
|
||||||
|
// Info
|
||||||
|
$txid = $tx['txid'];
|
||||||
|
$datetime = date(DATETIME_FORMAT, strtotime($tx['txdate']));
|
||||||
|
$type = $tx['type'];
|
||||||
|
$cashier = getUserByID($tx['cashier'])['name'];
|
||||||
|
$customerid = $tx['customerid'];
|
||||||
|
|
||||||
|
// Items
|
||||||
|
$itemlines = [];
|
||||||
|
$items = $database->select('lines', ['amount', 'name', 'itemid', 'qty'], ['txid' => $txid]);
|
||||||
|
$subtotal = 0.0;
|
||||||
|
$paid = 0.0;
|
||||||
|
foreach ($items as $i) {
|
||||||
|
$itemlines[] = new ReceiptLine(
|
||||||
|
$i['name'], (float) $i['qty'] . '@' . number_format($i['amount'], 2), '$' . number_format($i['qty'] * $i['amount'] * 1.0, 2)
|
||||||
|
);
|
||||||
|
$subtotal += $i['qty'] * $i['amount'] * 1.0;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Payments
|
||||||
|
$total = $subtotal * (1.0 - ((float) $tx['discountpercent'] / 100));
|
||||||
|
$paymentlines = [];
|
||||||
|
$payments = $database->select('payments', [
|
||||||
|
'[>]payment_types' => ['type' => 'typeid']
|
||||||
|
], [
|
||||||
|
'amount', 'type', 'typename', 'text'
|
||||||
|
], [
|
||||||
|
'txid' => $txid
|
||||||
|
]);
|
||||||
|
foreach ($payments as $p) {
|
||||||
|
$paymentlines[] = new ReceiptLine(lang($p['text'], false), "", '$' . number_format($p['amount'] * -1.0, 2));
|
||||||
|
$paid += $p['amount'] * 1.0;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Totals
|
||||||
|
$subtotalline = new ReceiptLine("Subtotal:", "", '$' . number_format($subtotal, 2));
|
||||||
|
$paidline = new ReceiptLine("Refund:", "", '$' . number_format($paid * -1.0, 2), ReceiptLine::LINEFORMAT_BOLD);
|
||||||
|
$totalline = new ReceiptLine("Total:", "", '$' . number_format($subtotal, 2), ReceiptLine::LINEFORMAT_BOLD);
|
||||||
|
|
||||||
|
$receipt->appendLine(new ReceiptLine("Date: $datetime"));
|
||||||
|
$receipt->appendLine(new ReceiptLine("Tx. ID: $txid"));
|
||||||
|
$receipt->appendLine(new ReceiptLine("Cashier: $cashier"));
|
||||||
|
if (!is_null($customerid) && !empty($customerid)) {
|
||||||
|
$customer = $database->get('customers', 'name', ['customerid' => $customerid]);
|
||||||
|
$receipt->appendLine(new ReceiptLine("Customer: $customer"));
|
||||||
|
}
|
||||||
|
$receipt->appendBreak();
|
||||||
|
$receipt->appendLines($itemlines);
|
||||||
|
$receipt->appendBreak();
|
||||||
|
$receipt->appendLine($subtotalline);
|
||||||
|
$receipt->appendLine($totalline);
|
||||||
|
$receipt->appendBreak();
|
||||||
|
$receipt->appendLines($paymentlines);
|
||||||
|
$receipt->appendBreak();
|
||||||
|
$receipt->appendLine($paidline);
|
||||||
|
|
||||||
|
return $receipt;
|
||||||
|
}
|
||||||
|
|
||||||
|
static function transactionReceipt($transaction) {
|
||||||
|
global $database;
|
||||||
|
$txtype = $database->get('transactions', 'type', ['txid' => $transaction]);
|
||||||
|
switch ($txtype) {
|
||||||
|
case 1:
|
||||||
|
return GenerateReceipt::saleReceipt($transaction);
|
||||||
|
case 2:
|
||||||
|
return GenerateReceipt::returnReceipt($transaction);
|
||||||
|
default:
|
||||||
|
return new Receipt();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
static function xReceipt($registerid) {
|
static function xReceipt($registerid) {
|
||||||
global $database;
|
global $database;
|
||||||
$receipt = new Receipt();
|
$receipt = new Receipt();
|
||||||
|
189
pages/pos.php
189
pages/pos.php
@ -22,12 +22,22 @@ if (isset($_GET['switch']) || !isset($_SESSION['register']) || !$registeropen) {
|
|||||||
$items = [];
|
$items = [];
|
||||||
$payments = [];
|
$payments = [];
|
||||||
$editing = false;
|
$editing = false;
|
||||||
|
$returning = false;
|
||||||
if (isset($VARS['txid']) && $database->has('transactions', ['txid' => $VARS['txid']])) {
|
if (isset($VARS['txid']) && $database->has('transactions', ['txid' => $VARS['txid']])) {
|
||||||
$editing = true;
|
$tx = $database->get('transactions', ['[>]customers' => 'customerid'], ['txid', 'discountpercent', 'transactions.customerid', 'customers.name (customername)', 'cashid', 'type'], ['txid' => $VARS['txid']]);
|
||||||
$items = $database->select('lines', ['lineid', 'amount', 'name', 'itemid', 'qty'], ['txid' => $VARS['txid']]);
|
if ($tx['type'] != 1) {
|
||||||
$payments = $database->select('payments', ['[>]certificates' => 'certid', '[>]payment_types' => ['type' => 'typeid']], ['payments.amount', 'typename', 'icon', 'text', 'certcode'], ['txid' => $VARS['txid']]);
|
header('Location: app.php?page=pos&msg=return_transaction_no_edit');
|
||||||
$tx = $database->get('transactions', ['[>]customers' => 'customerid'], ['txid', 'discountpercent', 'transactions.customerid', 'customers.name (customername)'], ['txid' => $VARS['txid']]);
|
die();
|
||||||
echo "<input type=\"hidden\" id=\"txid\" value=\"$VARS[txid]\">";
|
}
|
||||||
|
$items = $database->select('lines', ['lineid', 'amount', 'name', 'itemid', 'qty'], ['txid' => $tx['txid']]);
|
||||||
|
if ($database->has('cash_drawer', ['AND' => ['cashid' => $tx['cashid'], 'open[!]' => null, 'close' => null]])) {
|
||||||
|
$editing = true;
|
||||||
|
$payments = $database->select('payments', ['[>]certificates' => 'certid', '[>]payment_types' => ['type' => 'typeid']], ['payments.amount', 'typename', 'icon', 'text', 'certcode'], ['txid' => $tx['txid']]);
|
||||||
|
echo "<input type=\"hidden\" id=\"txid\" value=\"$tx[txid]\">";
|
||||||
|
} else {
|
||||||
|
$returning = true;
|
||||||
|
echo "<input type=\"hidden\" id=\"return\" value=\"1\">";
|
||||||
|
}
|
||||||
}
|
}
|
||||||
?>
|
?>
|
||||||
<div class="modal fade" tabindex="-1" role="dialog" id="receiptmodal">
|
<div class="modal fade" tabindex="-1" role="dialog" id="receiptmodal">
|
||||||
@ -40,11 +50,11 @@ if (isset($_GET['switch']) || !isset($_SESSION['register']) || !$registeropen) {
|
|||||||
</button>
|
</button>
|
||||||
</div>
|
</div>
|
||||||
<div class="modal-body">
|
<div class="modal-body">
|
||||||
<div class="display-4 text-center"><?php lang("change"); ?>: $<span id="receiptchange">0.00</span></div>
|
<div class="display-4 text-center" id="receiptchangediv"><?php lang("change"); ?>: $<span id="receiptchange">0.00</span></div>
|
||||||
<iframe class="w-100 shadow-lg" id="receiptframe"></iframe>
|
<iframe class="w-100 shadow-lg" id="receiptframe"></iframe>
|
||||||
</div>
|
</div>
|
||||||
<div class="modal-footer">
|
<div class="modal-footer">
|
||||||
<button type="button" class="btn btn-secondary" data-dismiss="modal"><?php lang("new sale"); ?></button>
|
<button type="button" class="btn btn-secondary" data-dismiss="modal"><?php lang("close"); ?></button>
|
||||||
<button type="button" class="btn btn-primary" id="receiptprintbtn"><i class="fas fa-print"></i> <?php lang("print"); ?></button>
|
<button type="button" class="btn btn-primary" id="receiptprintbtn"><i class="fas fa-print"></i> <?php lang("print"); ?></button>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
@ -141,13 +151,20 @@ if (isset($_GET['switch']) || !isset($_SESSION['register']) || !$registeropen) {
|
|||||||
<div class="list-group list-group-flush" id="pos-lines-box">
|
<div class="list-group list-group-flush" id="pos-lines-box">
|
||||||
<?php
|
<?php
|
||||||
foreach ($items as $i) {
|
foreach ($items as $i) {
|
||||||
|
$linetotal = $i['amount'] * $i['qty'];
|
||||||
|
$amount = $i['amount'];
|
||||||
|
// Include percentage discount for returns
|
||||||
|
if ($returning) {
|
||||||
|
$linetotal *= 1.0 - ($tx['discountpercent'] / 100.0);
|
||||||
|
$amount *= 1.0 - ($tx['discountpercent'] / 100);
|
||||||
|
}
|
||||||
?>
|
?>
|
||||||
<div class="list-group-item" data-itemid="<?php echo $i['itemid']; ?>">
|
<div class="list-group-item" data-itemid="<?php echo $i['itemid']; ?>">
|
||||||
<div class="d-flex w-100 justify-content-between mb-2">
|
<div class="d-flex w-100 justify-content-between mb-2">
|
||||||
<h5 class="item-name"><?php echo $i['name']; ?></h5>
|
<h5 class="item-name"><?php echo $i['name']; ?></h5>
|
||||||
<h5>
|
<h5>
|
||||||
<span class="badge badge-light">
|
<span class="badge badge-light">
|
||||||
$<span class="line-total"><?php echo number_format($i['amount'] * $i['qty'], 2); ?></span>
|
$<span class="line-total"><?php echo number_format($linetotal, 2); ?></span>
|
||||||
</span>
|
</span>
|
||||||
</h5>
|
</h5>
|
||||||
</div>
|
</div>
|
||||||
@ -156,7 +173,7 @@ if (isset($_GET['switch']) || !isset($_SESSION['register']) || !$registeropen) {
|
|||||||
<div class="input-group-prepend">
|
<div class="input-group-prepend">
|
||||||
<span class="input-group-text pr-1"><b>$</b></span>
|
<span class="input-group-text pr-1"><b>$</b></span>
|
||||||
</div>
|
</div>
|
||||||
<input type="money" class="form-control item-price" value="<?php echo number_format($i['amount'], 2); ?>"/>
|
<input type="money" class="form-control item-price" value="<?php echo number_format($amount, 2); ?>"/>
|
||||||
<div class="input-group-prepend">
|
<div class="input-group-prepend">
|
||||||
<span class="input-group-text px-2"><i class="fas fa-times"></i></span>
|
<span class="input-group-text px-2"><i class="fas fa-times"></i></span>
|
||||||
<button class="btn btn-red qty-minus" type="button"><i class="fas <?php
|
<button class="btn btn-red qty-minus" type="button"><i class="fas <?php
|
||||||
@ -199,31 +216,47 @@ if (isset($_GET['switch']) || !isset($_SESSION['register']) || !$registeropen) {
|
|||||||
?></span>
|
?></span>
|
||||||
<span class="sr-only"><?php lang("customer"); ?></span>
|
<span class="sr-only"><?php lang("customer"); ?></span>
|
||||||
</div>
|
</div>
|
||||||
<div class="btn m-1" id="discountpercentbtn" data-percent="<?php
|
<?php
|
||||||
if ($editing && isset($tx['discountpercent']) && $tx['discountpercent'] != 0) {
|
if (!$returning) {
|
||||||
echo (float) $tx['discountpercent'];
|
?>
|
||||||
} else {
|
<div class="btn m-1" id="discountpercentbtn" data-percent="<?php
|
||||||
echo "0";
|
if ($editing && isset($tx['discountpercent']) && $tx['discountpercent'] != 0) {
|
||||||
|
echo (float) $tx['discountpercent'];
|
||||||
|
} else {
|
||||||
|
echo "0";
|
||||||
|
}
|
||||||
|
?>">
|
||||||
|
<span id="discountpercentbtnlabel"><?php
|
||||||
|
if ($editing && isset($tx['discountpercent']) && $tx['discountpercent'] != 0) {
|
||||||
|
echo (float) $tx['discountpercent'];
|
||||||
|
}
|
||||||
|
?></span>
|
||||||
|
<i class="fas fa-percent"></i>
|
||||||
|
<span class="sr-only"><?php lang("transaction discount"); ?></span>
|
||||||
|
</div>
|
||||||
|
<?php
|
||||||
}
|
}
|
||||||
?>">
|
?>
|
||||||
<span id="discountpercentbtnlabel"><?php
|
|
||||||
if ($editing && isset($tx['discountpercent']) && $tx['discountpercent'] != 0) {
|
|
||||||
echo (float) $tx['discountpercent'];
|
|
||||||
}
|
|
||||||
?></span>
|
|
||||||
<i class="fas fa-percent"></i>
|
|
||||||
<span class="sr-only"><?php lang("transaction discount"); ?></span>
|
|
||||||
</div>
|
|
||||||
</div>
|
</div>
|
||||||
<div class="card-body">
|
<div class="card-body">
|
||||||
<span class="btn btn-green btn-lg btn-block" id="paymentbtn"><i class="fas fa-money-bill-wave"></i> <?php lang("enter payment"); ?></span>
|
<span class="btn btn-green btn-lg btn-block" id="paymentbtn"><i class="fas fa-money-bill-wave"></i> <?php
|
||||||
|
if ($returning) {
|
||||||
|
lang("enter refund");
|
||||||
|
} else {
|
||||||
|
lang("enter payment");
|
||||||
|
}
|
||||||
|
?></span>
|
||||||
</div>
|
</div>
|
||||||
<div class="d-none" id="paymentui">
|
<div class="d-none" id="paymentui">
|
||||||
<div class="card-body">
|
<div class="card-body">
|
||||||
<div class="d-flex justify-content-around flex-wrap">
|
<div class="d-flex justify-content-around flex-wrap">
|
||||||
<?php
|
<?php
|
||||||
$payment_methods = $database->select('payment_types', ['typeid (id)', 'typename (name)', 'icon', 'text']);
|
$payment_methods = $database->select('payment_types', ['typeid (id)', 'typename (name)', 'icon', 'text']);
|
||||||
|
$hideforreturns = ['check', 'free'];
|
||||||
foreach ($payment_methods as $data) {
|
foreach ($payment_methods as $data) {
|
||||||
|
if ($returning && in_array($data['name'], $hideforreturns)) {
|
||||||
|
continue;
|
||||||
|
}
|
||||||
?>
|
?>
|
||||||
<div class="card p-2 text-center m-1 payment-method-button" data-payment-method="<?php echo $data['name']; ?>" data-icon="<?php echo $data['icon']; ?>" data-text="<?php lang($data['text']); ?>">
|
<div class="card p-2 text-center m-1 payment-method-button" data-payment-method="<?php echo $data['name']; ?>" data-icon="<?php echo $data['icon']; ?>" data-text="<?php lang($data['text']); ?>">
|
||||||
<i class="<?php echo $data['icon']; ?> fa-3x fa-fw"></i>
|
<i class="<?php echo $data['icon']; ?> fa-3x fa-fw"></i>
|
||||||
@ -236,57 +269,77 @@ if (isset($_GET['switch']) || !isset($_SESSION['register']) || !$registeropen) {
|
|||||||
</div>
|
</div>
|
||||||
<hr />
|
<hr />
|
||||||
<div class="row px-2 mb-3 text-center">
|
<div class="row px-2 mb-3 text-center">
|
||||||
<div class="col-12 col-sm-4">
|
<?php
|
||||||
<?php lang("paid"); ?> $<span id="paid-amount">0.00</span>
|
if ($returning) {
|
||||||
</div>
|
?>
|
||||||
<div class="col-12 col-sm-4">
|
<div class="col-12 col-sm-4">
|
||||||
<?php lang("owed"); ?> $<span id="owed-amount">0.00</span>
|
<?php lang("refund"); ?> $<span id="paid-amount">0.00</span>
|
||||||
</div>
|
</div>
|
||||||
<div class="col-12 col-sm-4">
|
<div class="col-12 col-sm-4">
|
||||||
<?php lang("change"); ?> $<span id="change-amount">0.00</span>
|
<?php lang("owed"); ?> $<span id="owed-amount">0.00</span>
|
||||||
</div>
|
</div>
|
||||||
|
<div class="col-12 col-sm-4">
|
||||||
|
<?php lang("change"); ?> $<span id="change-amount">0.00</span>
|
||||||
|
</div>
|
||||||
|
<?php
|
||||||
|
} else {
|
||||||
|
?>
|
||||||
|
<div class="col-12 col-sm-4">
|
||||||
|
<?php lang("paid"); ?> $<span id="paid-amount">0.00</span>
|
||||||
|
</div>
|
||||||
|
<div class="col-12 col-sm-4">
|
||||||
|
<?php lang("owed"); ?> $<span id="owed-amount">0.00</span>
|
||||||
|
</div>
|
||||||
|
<div class="col-12 col-sm-4">
|
||||||
|
<?php lang("change"); ?> $<span id="change-amount">0.00</span>
|
||||||
|
</div>
|
||||||
|
<?php
|
||||||
|
}
|
||||||
|
?>
|
||||||
</div>
|
</div>
|
||||||
<div class="list-group list-group-flush" id="payment-lines">
|
<div class="list-group list-group-flush" id="payment-lines">
|
||||||
<?php
|
<?php
|
||||||
foreach ($payments as $p) {
|
if ($editing) {
|
||||||
if ($p['amount'] <= 0) {
|
foreach ($payments as $p) {
|
||||||
continue;
|
if ($p['amount'] <= 0) {
|
||||||
}
|
continue;
|
||||||
?>
|
}
|
||||||
<div class="list-group-item">
|
?>
|
||||||
<div class="input-group">
|
<div class="list-group-item">
|
||||||
<div class="input-group-prepend">
|
<div class="input-group">
|
||||||
<span class="input-group-text">
|
<div class="input-group-prepend">
|
||||||
<i class="<?php echo $p['icon']; ?> fa-fw mr-1"></i>
|
|
||||||
<?php lang($p['text']); ?>
|
|
||||||
</span>
|
|
||||||
</div>
|
|
||||||
<div class="input-group-prepend">
|
|
||||||
<span class="input-group-text">
|
|
||||||
$
|
|
||||||
</span>
|
|
||||||
</div>
|
|
||||||
<input class="form-control payment-entry" type="money" data-type="<?php echo $p['typename']; ?>" value="<?php echo number_format($p['amount'], 2); ?>" />
|
|
||||||
<?php
|
|
||||||
if ($p['typename'] == 'giftcard') {
|
|
||||||
?>
|
|
||||||
<div class="input-group-prepend input-group-append">
|
|
||||||
<span class="input-group-text">
|
<span class="input-group-text">
|
||||||
#
|
<i class="<?php echo $p['icon']; ?> fa-fw mr-1"></i>
|
||||||
|
<?php lang($p['text']); ?>
|
||||||
</span>
|
</span>
|
||||||
</div>
|
</div>
|
||||||
<input class="form-control giftcard-number" type="number" value="<?php echo $p['certcode']; ?>" />
|
<div class="input-group-prepend">
|
||||||
|
<span class="input-group-text">
|
||||||
|
$
|
||||||
|
</span>
|
||||||
|
</div>
|
||||||
|
<input class="form-control payment-entry" type="money" data-type="<?php echo $p['typename']; ?>" value="<?php echo number_format($p['amount'], 2); ?>" />
|
||||||
<?php
|
<?php
|
||||||
}
|
if ($p['typename'] == 'giftcard') {
|
||||||
?>
|
?>
|
||||||
<div class="input-group-append">
|
<div class="input-group-prepend input-group-append">
|
||||||
<span class="btn btn-outline-danger remove-payment-btn">
|
<span class="input-group-text">
|
||||||
<i class="fas fa-trash"></i>
|
#
|
||||||
</span>
|
</span>
|
||||||
|
</div>
|
||||||
|
<input class="form-control giftcard-number" type="number" value="<?php echo $p['certcode']; ?>" />
|
||||||
|
<?php
|
||||||
|
}
|
||||||
|
?>
|
||||||
|
<div class="input-group-append">
|
||||||
|
<span class="btn btn-outline-danger remove-payment-btn">
|
||||||
|
<i class="fas fa-trash"></i>
|
||||||
|
</span>
|
||||||
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
<?php
|
||||||
<?php
|
}
|
||||||
}
|
}
|
||||||
?>
|
?>
|
||||||
<!-- Payments go here -->
|
<!-- Payments go here -->
|
||||||
@ -296,6 +349,8 @@ if (isset($_GET['switch']) || !isset($_SESSION['register']) || !$registeropen) {
|
|||||||
<span class="btn btn-green btn-lg btn-block" id="finishbtn"><i class="fas fa-receipt"></i> <?php
|
<span class="btn btn-green btn-lg btn-block" id="finishbtn"><i class="fas fa-receipt"></i> <?php
|
||||||
if ($editing) {
|
if ($editing) {
|
||||||
lang("update");
|
lang("update");
|
||||||
|
} else if ($returning) {
|
||||||
|
lang("return");
|
||||||
} else {
|
} else {
|
||||||
lang("finish");
|
lang("finish");
|
||||||
}
|
}
|
||||||
@ -306,7 +361,7 @@ if (isset($_GET['switch']) || !isset($_SESSION['register']) || !$registeropen) {
|
|||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
<script nonce="<?php echo $SECURE_NONCE; ?>">
|
<script nonce="<?php echo $SECURE_NONCE; ?>">
|
||||||
var showgridbydefault = <?php echo $showgridbydefault === true && $editing !== true ? "true" : "false" ?>;
|
var showgridbydefault = <?php echo $showgridbydefault === true && $editing !== true && $returning !== true ? "true" : "false" ?>;
|
||||||
</script>
|
</script>
|
||||||
<?php
|
<?php
|
||||||
}
|
}
|
||||||
|
@ -63,4 +63,7 @@ $(document).ready(function () {
|
|||||||
recalculate();
|
recalculate();
|
||||||
$("#paymentui").removeClass("d-none");
|
$("#paymentui").removeClass("d-none");
|
||||||
}
|
}
|
||||||
|
if ($("#return").length) {
|
||||||
|
recalculate();
|
||||||
|
}
|
||||||
});
|
});
|
@ -64,7 +64,59 @@ function sendTransactionToServer(callback) {
|
|||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
|
function sendReturnToServer(callback) {
|
||||||
|
var items = [];
|
||||||
|
var payments = [];
|
||||||
|
var customer = customerid;
|
||||||
|
var register = $("#register").data('id');
|
||||||
|
|
||||||
|
$("#pos-lines-box .list-group-item").each(function () {
|
||||||
|
var each = $(".item-price", this).val() * 1.0;
|
||||||
|
var qty = $(".item-qty", this).val() * 1.0;
|
||||||
|
var code = $(this).data("code");
|
||||||
|
var id = $(this).data("itemid");
|
||||||
|
items.push({
|
||||||
|
each: each,
|
||||||
|
qty: qty,
|
||||||
|
code: code,
|
||||||
|
id: id
|
||||||
|
});
|
||||||
|
});
|
||||||
|
$("#payment-lines .list-group-item").each(function () {
|
||||||
|
var amount = $(".payment-entry", this).val() * 1.0;
|
||||||
|
var type = $(".payment-entry", this).data("type");
|
||||||
|
var code = '';
|
||||||
|
if ($(".giftcard-number", this).length) {
|
||||||
|
code = $(".giftcard-number", this).val();
|
||||||
|
}
|
||||||
|
payments.push({
|
||||||
|
amount: amount,
|
||||||
|
type: type,
|
||||||
|
code: code
|
||||||
|
});
|
||||||
|
});
|
||||||
|
|
||||||
|
console.log(payments);
|
||||||
|
|
||||||
|
$.post("action.php", {
|
||||||
|
action: "finish_return",
|
||||||
|
items: items,
|
||||||
|
payments: payments,
|
||||||
|
customer: customer,
|
||||||
|
register: register
|
||||||
|
}, function (data) {
|
||||||
|
if (data.status == "OK") {
|
||||||
|
callback(data);
|
||||||
|
} else {
|
||||||
|
bsalert("Error", "The return could not be completed: " + data.message);
|
||||||
|
}
|
||||||
|
}).fail(function () {
|
||||||
|
bsalert("Error", "The return could not be completed due to an unknown error.");
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
function showReceipt(txid) {
|
function showReceipt(txid) {
|
||||||
|
$("#receiptchangediv").removeClass("d-none");
|
||||||
$("#receiptframe").attr("src", 'action.php?action=getreceipt&txid=' + txid);
|
$("#receiptframe").attr("src", 'action.php?action=getreceipt&txid=' + txid);
|
||||||
$("#receiptmodal").modal();
|
$("#receiptmodal").modal();
|
||||||
}
|
}
|
||||||
@ -78,10 +130,22 @@ function finishTransaction() {
|
|||||||
$("#finishbtn").click(function () {
|
$("#finishbtn").click(function () {
|
||||||
recalculate();
|
recalculate();
|
||||||
var owed = $("#owed-amount").text() * 1.0;
|
var owed = $("#owed-amount").text() * 1.0;
|
||||||
if (owed > 0) {
|
if ($("#return").length) {
|
||||||
bsalert("Incomplete Transaction", "The customer still owes $" + owed.toFixed(2) + ". Add a payment or remove items until everything is paid for.");
|
if (owed > 0) {
|
||||||
|
bsalert("Incomplete Transaction", "The customer is still owed $" + owed.toFixed(2) + ". Add a payment or remove items until the customer is not owed anything.");
|
||||||
|
} else if ($("#change-amount").text() * 1.0 > 0) {
|
||||||
|
bsalert("Incomplete Transaction", "The customer would need to pay you $" + ($("#change-amount").text() * 1.0).toFixed(2) + " for the refund. Adjust payments until the change is zero.");
|
||||||
|
} else {
|
||||||
|
sendReturnToServer(function (data) {
|
||||||
|
showReceipt(data.txid);
|
||||||
|
});
|
||||||
|
}
|
||||||
} else {
|
} else {
|
||||||
finishTransaction();
|
if (owed > 0) {
|
||||||
|
bsalert("Incomplete Transaction", "The customer still owes $" + owed.toFixed(2) + ". Add a payment or remove items until everything is paid for.");
|
||||||
|
} else {
|
||||||
|
finishTransaction();
|
||||||
|
}
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
|
||||||
|
@ -36,8 +36,11 @@ function showTransactionList(search) {
|
|||||||
if (data['transactions'][i]['cashier']['name'] != "") {
|
if (data['transactions'][i]['cashier']['name'] != "") {
|
||||||
cashiername = '<i class="fas fa-id-card-alt"></i> ' + data['transactions'][i]['cashier']['name'];
|
cashiername = '<i class="fas fa-id-card-alt"></i> ' + data['transactions'][i]['cashier']['name'];
|
||||||
}
|
}
|
||||||
|
buttons += '<span data-txid=' + data['transactions'][i]['txid'] + '" class="btn btn-sm btn-primary printreceiptbtn"><i class="fas fa-receipt"></i> Receipt</span> ';
|
||||||
if (data['transactions'][i]['editable'] === true) {
|
if (data['transactions'][i]['editable'] === true) {
|
||||||
buttons += '<a href="app.php?page=pos&txid=' + data['transactions'][i]['txid'] + '" class="btn btn-sm btn-primary"><i class="fas fa-edit"></i> Edit</a>';
|
buttons += '<a href="app.php?page=pos&txid=' + data['transactions'][i]['txid'] + '" class="btn btn-sm btn-info"><i class="fas fa-edit"></i> Edit</a>';
|
||||||
|
} else {
|
||||||
|
buttons += '<a href="app.php?page=pos&txid=' + data['transactions'][i]['txid'] + '" class="btn btn-sm btn-info"><i class="fas fa-undo-alt"></i> Return</a>';
|
||||||
}
|
}
|
||||||
html += '<div class="list-group-item transaction d-flex justify-content-between flex-wrap">'
|
html += '<div class="list-group-item transaction d-flex justify-content-between flex-wrap">'
|
||||||
+ '<div>' + buttons + '</div>'
|
+ '<div>' + buttons + '</div>'
|
||||||
@ -64,4 +67,11 @@ $("#transactionsearch").on('keypress', function (e) {
|
|||||||
$("#transactionsearchbtn").on("click", function () {
|
$("#transactionsearchbtn").on("click", function () {
|
||||||
showCustomerList($("#transactionsearch").val());
|
showCustomerList($("#transactionsearch").val());
|
||||||
$("#transactionsearch").val("");
|
$("#transactionsearch").val("");
|
||||||
|
});
|
||||||
|
|
||||||
|
$("#managermodal").on("click", ".printreceiptbtn", function () {
|
||||||
|
$("#managermodal").modal("hide");
|
||||||
|
$("#receiptchangediv").addClass("d-none");
|
||||||
|
$("#receiptframe").attr("src", 'action.php?action=getreceipt&txid=' + $(this).data("txid"));
|
||||||
|
$("#receiptmodal").modal();
|
||||||
});
|
});
|
Loading…
x
Reference in New Issue
Block a user