Merge pull request #3026 from opensourcepos/cash-rounding-register

Correct issues with cash rounding.
This commit is contained in:
Steve Ireland authored and GitHub committed 2021-02-08 08:26:47 -05:00
commit 68a2292d49
9 files changed
+291 -95

No files matched your search

+10
View File
@@ -144,3 +144,13 @@ define('SALE_TYPE_RETURN', 4);
define('PERCENT', 0);
define('FIXED', 1);
define('PRICE_MODE_STANDARD', 0);
define('PRICE_MODE_KIT', 1);
define('PAYMENT_TYPE_UNASSIGNED', '--');
define('CASH_ADJUSTMENT_TRUE', 1);
define('CASH_ADJUSTMENT_FALSE', 0);
define('CASH_MODE_TRUE', 1);
define('CASH_MODE_FALSE', 0);
+93 -29
View File
@@ -2,10 +2,6 @@
require_once("Secure_Controller.php");
define('PRICE_MODE_STANDARD', 0);
define('PRICE_MODE_KIT', 1);
define('PAYMENT_TYPE_UNASSIGNED', '--');
class Sales extends Secure_Controller
{
public function __construct()
@@ -263,7 +259,7 @@ class Sales extends Secure_Controller
$data = array();
$payment_type = $this->input->post('payment_type');
if($payment_type != $this->lang->line('sales_giftcard'))
if($payment_type !== $this->lang->line('sales_giftcard'))
{
$this->form_validation->set_rules('amount_tendered', 'lang:sales_amount_tendered', 'trim|required|callback_numeric');
}
@@ -274,7 +270,7 @@ class Sales extends Secure_Controller
if($this->form_validation->run() == FALSE)
{
if($payment_type == $this->lang->line('sales_giftcard'))
if($payment_type === $this->lang->line('sales_giftcard'))
{
$data['error'] = $this->lang->line('sales_must_enter_numeric_giftcard');
}
@@ -285,7 +281,7 @@ class Sales extends Secure_Controller
}
else
{
if($payment_type == $this->lang->line('sales_giftcard'))
if($payment_type === $this->lang->line('sales_giftcard'))
{
// in case of giftcard payment the register input amount_tendered becomes the giftcard number
$giftcard_num = $this->input->post('amount_tendered');
@@ -316,7 +312,7 @@ class Sales extends Secure_Controller
$this->sale_lib->add_payment($payment_type, $amount_tendered);
}
}
elseif($payment_type == $this->lang->line('sales_rewards'))
elseif($payment_type === $this->lang->line('sales_rewards'))
{
$customer_id = $this->sale_lib->get_customer();
$package_id = $this->Customer->get_info($customer_id)->package_id;
@@ -348,6 +344,20 @@ class Sales extends Secure_Controller
}
}
}
elseif($payment_type === $this->lang->line('sales_cash'))
{
$amount_due = $this->sale_lib->get_total();
$sales_total = $this->sale_lib->get_total(FALSE);
$amount_tendered = $this->input->post('amount_tendered');
$this->sale_lib->add_payment($payment_type, $amount_tendered);
$cash_adjustment_amount = $amount_due - $sales_total;
if($cash_adjustment_amount <> 0)
{
$this->session->set_userdata('cash_mode', CASH_MODE_TRUE);
$this->sale_lib->add_payment($this->lang->line('sales_cash_adjustment'), $cash_adjustment_amount, CASH_ADJUSTMENT_TRUE);
}
}
else
{
$amount_tendered = $this->input->post('amount_tendered');
@@ -571,22 +581,22 @@ class Sales extends Secure_Controller
$data['payments_total'] = $totals['payment_total'];
$data['payments_cover_total'] = $totals['payments_cover_total'];
$data['cash_rounding'] = $this->session->userdata('cash_rounding');
$data['cash_mode'] = $this->session->userdata('cash_mode');
$data['prediscount_subtotal'] = $totals['prediscount_subtotal'];
$data['cash_total'] = $totals['cash_total'];
$data['non_cash_total'] = $totals['total'];
$data['cash_amount_due'] = $totals['cash_amount_due'];
$data['non_cash_amount_due'] = $totals['amount_due'];
if($data['cash_rounding'])
if($data['cash_mode'])
{
$data['total'] = $totals['cash_total'];
$data['amount_due'] = $totals['cash_amount_due'];
}
else
{
$data['total'] = $totals['total'];
$data['amount_due'] = $totals['amount_due'];
}
$data['amount_change'] = $data['amount_due'] * -1;
if($data['amount_change'] > 0)
@@ -609,6 +619,7 @@ class Sales extends Secure_Controller
if($this->sale_lib->is_invoice_mode())
{
$invoice_format = $this->config->item('sales_invoice_format');
// generate final invoice number (if using the invoice in sales by receipt mode then the invoice number can be manually entered or altered in some way
if(!empty($invoice_format) && $invoice_number == NULL)
{
@@ -787,6 +798,7 @@ class Sales extends Secure_Controller
// generate email attachment: invoice in pdf format
$html = $this->load->view("sales/" . $type . "_email", $sale_data, TRUE);
// load pdf helper
$this->load->helper(array('dompdf', 'file'));
$filename = sys_get_temp_dir() . '/' . $this->lang->line("sales_" . $type) . '-' . str_replace('/', '-', $number) . '.pdf';
@@ -903,7 +915,9 @@ class Sales extends Secure_Controller
private function _load_sale_data($sale_id)
{
$this->sale_lib->clear_all();
$this->sale_lib->reset_cash_flags();
$cash_rounding = $this->sale_lib->reset_cash_rounding();
$data['cash_rounding'] = $cash_rounding;
$sale_info = $this->Sale->get_info($sale_id)->row_array();
$this->sale_lib->copy_entire_sale($sale_id);
$data = array();
@@ -922,18 +936,18 @@ class Sales extends Secure_Controller
// Returns 'subtotal', 'total', 'cash_total', 'payment_total', 'amount_due', 'cash_amount_due', 'payments_cover_total'
$totals = $this->sale_lib->get_totals($tax_details[0]);
$this->session->set_userdata('cash_adjustment_amount', $totals['cash_adjustment_amount']);
$data['subtotal'] = $totals['subtotal'];
$data['total'] = $totals['total'];
$data['payments_total'] = $totals['payment_total'];
$data['payments_cover_total'] = $totals['payments_cover_total'];
$data['cash_rounding'] = $this->session->userdata('cash_rounding');
$data['cash_mode'] = $this->session->userdata('cash_mode');
$data['prediscount_subtotal'] = $totals['prediscount_subtotal'];
$data['cash_total'] = $totals['cash_total'];
$data['non_cash_total'] = $totals['total'];
$data['cash_amount_due'] = $totals['cash_amount_due'];
$data['non_cash_amount_due'] = $totals['amount_due'];
if($this->session->userdata('cash_rounding'))
if($data['cash_mode'] && ($data['selected_payment_type'] === $this->lang->line('sales_cash') || $data['payments_total'] > 0))
{
$data['total'] = $totals['cash_total'];
$data['amount_due'] = $totals['cash_amount_due'];
@@ -943,6 +957,7 @@ class Sales extends Secure_Controller
$data['total'] = $totals['total'];
$data['amount_due'] = $totals['amount_due'];
}
$data['amount_change'] = $data['amount_due'] * -1;
$employee_info = $this->Employee->get_info($this->sale_lib->get_employee());
@@ -1013,6 +1028,11 @@ class Sales extends Secure_Controller
$sale_id = -1;
$this->session->set_userdata('sale_id', -1);
}
$cash_rounding = $this->sale_lib->reset_cash_rounding();
// cash_rounding indicates only that the site is configured for cash rounding
$data['cash_rounding'] = $cash_rounding;
$data['cart'] = $this->sale_lib->get_cart();
$customer_info = $this->_load_customer_data($this->sale_lib->get_customer(), $data, TRUE);
@@ -1027,22 +1047,29 @@ class Sales extends Secure_Controller
$data['taxes'] = $tax_details[0];
$data['discount'] = $this->sale_lib->get_discount();
$data['payments'] = $this->sale_lib->get_payments();
// Returns 'subtotal', 'total', 'cash_total', 'payment_total', 'amount_due', 'cash_amount_due', 'payments_cover_total'
$totals = $this->sale_lib->get_totals($tax_details[0]);
$data['item_count'] = $totals['item_count'];
$data['total_units'] = $totals['total_units'];
$data['subtotal'] = $totals['subtotal'];
$data['total'] = $totals['total'];
$data['payments_total'] = $totals['payment_total'];
$data['payments_cover_total'] = $totals['payments_cover_total'];
$data['cash_rounding'] = $this->session->userdata('cash_rounding');
// cash_mode indicates whether this sale is going to be processed using cash_rounding
$cash_mode = $this->session->userdata('cash_mode');
$data['cash_mode'] = $cash_mode;
$data['prediscount_subtotal'] = $totals['prediscount_subtotal'];
$data['cash_total'] = $totals['cash_total'];
$data['non_cash_total'] = $totals['total'];
$data['cash_amount_due'] = $totals['cash_amount_due'];
$data['non_cash_amount_due'] = $totals['amount_due'];
if($data['cash_rounding'])
$data['selected_payment_type'] = $this->sale_lib->get_payment_type();
if($data['cash_mode'] && ($data['selected_payment_type'] == $this->lang->line('sales_cash') || $data['payments_total'] > 0))
{
$data['total'] = $totals['cash_total'];
$data['amount_due'] = $totals['cash_amount_due'];
@@ -1052,11 +1079,12 @@ class Sales extends Secure_Controller
$data['total'] = $totals['total'];
$data['amount_due'] = $totals['amount_due'];
}
$data['amount_change'] = $data['amount_due'] * -1;
$data['comment'] = $this->sale_lib->get_comment();
$data['email_receipt'] = $this->sale_lib->is_email_receipt();
$data['selected_payment_type'] = $this->sale_lib->get_payment_type();
if($customer_info && $this->config->item('customer_reward_enable') == TRUE)
{
$data['payment_options'] = $this->Sale->get_payment_options(TRUE, TRUE);
@@ -1143,8 +1171,8 @@ class Sales extends Secure_Controller
$data['selected_employee_id'] = $sale_info['employee_id'];
$data['selected_employee_name'] = $this->xss_clean($employee_info->first_name . ' ' . $employee_info->last_name);
$data['sale_info'] = $sale_info;
$balance_due = $sale_info['amount_due'] - $sale_info['amount_tendered'];
if($balance_due < 0)
$balance_due = round($sale_info['amount_due'] - $sale_info['amount_tendered'] + $sale_info['cash_refund'], totals_decimals(), PHP_ROUND_HALF_UP);
if(!$this->sale_lib->reset_cash_rounding() && $balance_due < 0)
{
$balance_due = 0;
}
@@ -1165,12 +1193,19 @@ class Sales extends Secure_Controller
$data['balance_due'] = $balance_due != 0;
// don't allow gift card to be a payment option in a sale transaction edit because it's a complex change
$new_payment_options = $this->xss_clean($this->Sale->get_payment_options(FALSE));
$data['payment_options'] = $new_payment_options;
$payment_options = $this->Sale->get_payment_options(FALSE);
if($this->sale_lib->reset_cash_rounding())
{
$payment_options[$this->lang->line('sales_cash_adjustment')] = $this->lang->line('sales_cash_adjustment');
}
$data['payment_options'] = $this->xss_clean($payment_options);
// Set up a slightly modified list of payment types for new payment entry
$new_payment_options["--"] = $this->lang->line('common_none_selected_text');
$data['new_payment_options'] = $new_payment_options;
$payment_options["--"] = $this->lang->line('common_none_selected_text');
$data['new_payment_options'] = $this->xss_clean($payment_options);
$this->load->view('sales/form', $data);
}
@@ -1248,6 +1283,7 @@ class Sales extends Secure_Controller
// In order to maintain tradition the only element that can change on prior payments is the payment type
$payments = array();
$amount_tendered = 0;
$number_of_payments = $this->input->post('number_of_payments');
for($i = 0; $i < $number_of_payments; ++$i)
{
@@ -1257,6 +1293,20 @@ class Sales extends Secure_Controller
$refund_type = $this->input->post('refund_type_' . $i);
$cash_refund = $this->input->post('refund_amount_' . $i);
if($payment_type == $this->lang->line('sales_cash_adjustment'))
{
$cash_adjustment = CASH_ADJUSTMENT_TRUE;
}
else
{
$cash_adjustment = CASH_ADJUSTMENT_FALSE;
}
if(!$cash_adjustment)
{
$amount_tendered += $payment_amount - $cash_refund;
}
// if the refund is not cash ...
if(empty(strstr($refund_type, $this->lang->line('sales_cash'))))
{
@@ -1270,11 +1320,8 @@ class Sales extends Secure_Controller
}
}
// To maintain tradition we will also delete any payments with 0 amount
// assuming these are mistakes introduced at sale time.
// This is now done in models/Sale.php
$payments[] = array('payment_id' => $payment_id, 'payment_type' => $payment_type, 'payment_amount' => $payment_amount, 'cash_refund' => $cash_refund, 'employee_id' => $employee_id);
$payments[] = array('payment_id' => $payment_id, 'payment_type' => $payment_type, 'payment_amount' => $payment_amount, 'cash_refund' => $cash_refund, 'cash_adjustment' => $cash_adjustment, 'employee_id' => $employee_id);
}
$payment_id = -1;
@@ -1283,7 +1330,24 @@ class Sales extends Secure_Controller
if($payment_type != PAYMENT_TYPE_UNASSIGNED && $payment_amount <> 0)
{
$payments[] = array('payment_id' => $payment_id, 'payment_type' => $payment_type, 'payment_amount' => $payment_amount, 'cash_refund' => 0.00, 'employee_id' => $employee_id);
$cash_refund = 0;
if($payment_type == $this->lang->line('sales_cash_adjustment'))
{
$cash_adjustment = CASH_ADJUSTMENT_TRUE;
}
else
{
$cash_adjustment = CASH_ADJUSTMENT_FALSE;
$amount_tendered += $payment_amount;
$sale_info = $this->Sale->get_info($sale_id)->row_array();
if($amount_tendered > $sale_info['amount_due'])
{
$cash_refund = $amount_tendered - $sale_info['amount_due'];
}
}
$payments[] = array('payment_id' => $payment_id, 'payment_type' => $payment_type, 'payment_amount' => $payment_amount, 'cash_refund' => $cash_refund, 'cash_adjustment' => $cash_adjustment, 'employee_id' => $employee_id);
}
$this->Inventory->update('POS '.$sale_id, ['trans_date' => $sale_time]);
@@ -10,6 +10,7 @@ $lang["sales_amount_tendered"] = "Amount Tendered";
$lang["sales_authorized_signature"] = "Authorised Signature";
$lang["sales_cancel_sale"] = "Cancel";
$lang["sales_cash"] = "Cash";
$lang["sales_cash_adjustment"] = "Cash Adjustment";
$lang["sales_cash_deposit"] = "Cash Deposit";
$lang["sales_cash_filter"] = "Cash";
$lang["sales_change_due"] = "Change Due";
@@ -10,6 +10,7 @@ $lang["sales_amount_tendered"] = "Amount Tendered";
$lang["sales_authorized_signature"] = "Authorized Signature";
$lang["sales_cancel_sale"] = "Cancel";
$lang["sales_cash"] = "Cash";
$lang["sales_cash_adjustment"] = "Cash Adjustment";
$lang["sales_cash_deposit"] = "Cash Deposit";
$lang["sales_cash_filter"] = "Cash";
$lang["sales_change_due"] = "Change Due";
+112 -32
View File
@@ -366,8 +366,14 @@ class Sale_lib
$this->CI->session->set_userdata('sales_payments', $payments_data);
}
// Multiple Payments
public function add_payment($payment_id, $payment_amount)
/**
* Adds a new payment to the payments array or updates an existing one.
* It will also disable cash_mode if an non-qualifying payment type is added.
* @param $payment_id
* @param $payment_amount
* @param int $cash_adjustment
*/
public function add_payment($payment_id, $payment_amount, $cash_adjustment = CASH_ADJUSTMENT_FALSE)
{
$payments = $this->get_payments();
if(isset($payments[$payment_id]))
@@ -378,11 +384,20 @@ class Sale_lib
else
{
//add to existing array
$payment = array($payment_id => array('payment_type' => $payment_id, 'payment_amount' => $payment_amount, 'cash_refund' => 0));
$payment = array($payment_id => array('payment_type' => $payment_id, 'payment_amount' => $payment_amount,
'cash_refund' => 0, 'cash_adjustment' => $cash_adjustment));
$payments += $payment;
}
if($this->CI->session->userdata('cash_mode'))
{
if($this->CI->session->userdata('cash_rounding') && $payment_id != $this->CI->lang->line('sales_cash') && $payment_id != $this->CI->lang->line('sales_cash_adjustment'))
{
$this->CI->session->set_userdata('cash_mode', CASH_MODE_FALSE);
}
}
$this->set_payments($payments);
}
@@ -402,11 +417,28 @@ class Sale_lib
return FALSE;
}
// Multiple Payments
/**
* Delete the selected payment from the payment array and if cash rounding is enabled
* and the payment type is one of the cash types then automatically delete the other
* @param $payment_id
*/
public function delete_payment($payment_id)
{
$payments = $this->get_payments();
unset($payments[urldecode($payment_id)]);
$decoded_payment_id = urldecode($payment_id);
unset($payments[$decoded_payment_id]);
$cash_rounding = $this->reset_cash_rounding();
if($cash_rounding)
{
if($decoded_payment_id == $this->CI->lang->line('sales_cash'))
{
unset($payments[$this->CI->lang->line('sales_cash_adjustment')]);
}
if($decoded_payment_id == $this->CI->lang->line('sales_cash_adjustment'))
{
unset($payments[$this->CI->lang->line('sales_cash')]);
}
}
$this->set_payments($payments);
}
@@ -416,18 +448,30 @@ class Sale_lib
$this->CI->session->unset_userdata('sales_payments');
}
// Multiple Payments
/**
* Retrieve the total payments made, excluding any cash adjustments
* and establish if cash_mode is in play
*/
public function get_payments_total()
{
$subtotal = 0.0;
$this->reset_cash_flags();
$cash_mode_eligible = CASH_MODE_TRUE;
foreach($this->get_payments() as $payments)
{
$subtotal = bcadd($payments['payment_amount'], $subtotal);
if($this->CI->session->userdata('cash_rounding') && $this->CI->lang->line('sales_cash') != $payments['payment_type'])
if(!$payments['cash_adjustment'])
{
$this->CI->session->set_userdata('cash_rounding', 0);
$subtotal = bcadd($payments['payment_amount'], $subtotal);
}
if($this->CI->lang->line('sales_cash') != $payments['payment_type'] && $this->CI->lang->line('sales_cash_adjustment') != $payments['payment_type'])
{
$cash_mode_eligible = CASH_MODE_FALSE;
}
}
if($cash_mode_eligible && $this->CI->session->userdata('cash_rounding'))
{
$this->CI->session->set_userdata('cash_mode', CASH_MODE_TRUE);
}
return $subtotal;
@@ -435,12 +479,10 @@ class Sale_lib
/**
* Returns 'subtotal', 'total', 'cash_total', 'payment_total', 'amount_due', 'cash_amount_due', 'paid_in_full'
* 'subtotal', 'discounted_subtotal', 'tax_exclusive_subtotal', 'item_count', 'total_units'
* 'subtotal', 'discounted_subtotal', 'tax_exclusive_subtotal', 'item_count', 'total_units', 'cash_adjustment_amount'
*/
public function get_totals($taxes)
{
$cash_rounding = $this->CI->session->userdata('cash_rounding');
$totals = array();
$prediscount_subtotal = 0.0;
@@ -489,6 +531,11 @@ class Sale_lib
$totals['total'] = $total;
$totals['tax_total'] = $sales_tax;
$payment_total = $this->get_payments_total();
$totals['payment_total'] = $payment_total;
$cash_rounding = $this->CI->session->userdata('cash_rounding');
$cash_mode = $this->CI->session->userdata('cash_mode');
if($cash_rounding)
{
$cash_total = $this->check_for_cash_rounding($total);
@@ -500,16 +547,13 @@ class Sale_lib
$totals['cash_total'] = $cash_total;
}
$payment_total = $this->get_payments_total();
$totals['payment_total'] = $payment_total;
$amount_due = bcsub($total, $payment_total);
$totals['amount_due'] = $amount_due;
$cash_amount_due = bcsub($cash_total, $payment_total);
$totals['cash_amount_due'] = $cash_amount_due;
if($cash_rounding)
if($cash_mode)
{
$current_due = $cash_amount_due;
}
@@ -532,6 +576,14 @@ class Sale_lib
$totals['item_count'] = $item_count;
$totals['total_units'] = $total_units;
$totals['cash_adjustment_amount'] = 0;
if($totals['payments_cover_total'])
{
$totals['cash_adjustment_amount'] = round($cash_total - $totals['total'], totals_decimals(), PHP_ROUND_HALF_UP);
}
$cash_mode = $this->CI->session->userdata('cash_mode');
return $totals;
}
@@ -1006,9 +1058,34 @@ class Sale_lib
$this->add_item($row->item_id, $row->quantity_purchased, $row->item_location, $row->discount, $row->discount_type, PRICE_MODE_STANDARD, NULL, NULL, $row->item_unit_price, $row->description, $row->serialnumber, $sale_id, TRUE, $row->print_option);
}
$this->CI->session->set_userdata('cash_mode', CASH_MODE_FALSE);
// Establish cash_mode for this sale by inspecting the payments
if($this->CI->session->userdata('cash_rounding'))
{
$cash_types_only = true;
foreach($this->CI->Sale->get_sale_payments($sale_id)->result() as $row)
{
if($row->payment_type != $this->CI->lang->line('sales_cash') && $row->payment_type != $this->CI->lang->line('sales_cash_adjustment'))
{
$cash_types_only = FALSE;
}
}
if($cash_types_only)
{
$this->CI->session->set_userdata('cash_mode', CASH_MODE_TRUE);
}
else
{
$this->CI->session->set_userdata('cash_mode', CASH_MODE_FALSE);
}
}
// Now load payments
foreach($this->CI->Sale->get_sale_payments($sale_id)->result() as $row)
{
$this->add_payment($row->payment_type, $row->payment_amount);
$this->add_payment($row->payment_type, $row->payment_amount, $row->cash_adjustment);
}
$this->set_customer($this->CI->Sale->get_customer($sale_id)->person_id);
@@ -1051,18 +1128,13 @@ class Sale_lib
$this->CI->session->unset_userdata('payment_type');
}
public function reset_cash_flags()
/**
* Determines if cash rounding should be a consideration for this site
* It also set resets the cash mode to disabled which will then be re-evaluated when
* retrieving payments.
*/
public function reset_cash_rounding()
{
if($this->CI->config->item('payment_options_order') != 'cashdebitcredit')
{
$cash_mode = 1;
}
else
{
$cash_mode = 0;
}
$this->CI->session->set_userdata('cash_mode', $cash_mode);
$cash_rounding_code = $this->CI->config->item('cash_rounding_code');
if(cash_decimals() < totals_decimals() || $cash_rounding_code == Rounding_mode::HALF_FIVE)
@@ -1074,6 +1146,9 @@ class Sale_lib
$cash_rounding = 0;
}
$this->CI->session->set_userdata('cash_rounding', $cash_rounding);
$this->CI->session->set_userdata('cash_mode', CASH_MODE_FALSE);
return $cash_rounding;
}
public function is_customer_taxable()
@@ -1234,11 +1309,16 @@ class Sale_lib
return $subtotal;
}
public function get_total()
/**
* Calculates the total sales amount with the default option to include cash rounding
* @param bool $include_cash_rounding
* @return float|int|string
*/
public function get_total($include_cash_rounding = TRUE)
{
$total = $this->calculate_subtotal(TRUE);
$cash_rounding = $this->CI->session->userdata('cash_rounding');
$cash_mode = $this->CI->session->userdata('cash_mode');
if(!$this->CI->config->item('tax_included'))
{
@@ -1249,7 +1329,7 @@ class Sale_lib
}
}
if($cash_rounding)
if($include_cash_rounding && $cash_mode)
{
$total = $this->check_for_cash_rounding($total);
}
@@ -0,0 +1,20 @@
<?php if (!defined('BASEPATH')) exit('No direct script access allowed');
class Migration_cashrounding extends CI_Migration
{
public function __construct()
{
parent::__construct();
}
public function up()
{
$this->db->query('ALTER TABLE ' . $this->db->dbprefix('sales_payments') . ' ADD COLUMN `cash_adjustment` tinyint NOT NULL DEFAULT 0 AFTER `cash_refund`');
}
public function down()
{
$this->db->query('ALTER TABLE ' . $this->db->dbprefix('sales_payments') . ' DROP COLUMN `cash_adjustment`');
}
}
?>
+44 -27
View File
@@ -15,7 +15,9 @@ class Sale extends CI_Model
' (PRIMARY KEY(sale_id), INDEX(sale_id))
(
SELECT payments.sale_id AS sale_id,
IFNULL(SUM(payments.payment_amount), 0) AS sale_payment_amount,
SUM(CASE WHEN payments.cash_adjustment = 0 THEN payments.payment_amount ELSE 0 END) AS sale_payment_amount,
SUM(CASE WHEN payments.cash_adjustment = 1 THEN payments.payment_amount ELSE 0 END) AS sale_cash_adjustment,
SUM(payments.cash_refund) AS sale_cash_refund,
GROUP_CONCAT(CONCAT(payments.payment_type, " ", (payments.payment_amount - payments.cash_refund)) SEPARATOR ", ") AS payment_type
FROM ' . $this->db->dbprefix('sales_payments') . ' AS payments
INNER JOIN ' . $this->db->dbprefix('sales') . ' AS sales
@@ -29,18 +31,23 @@ class Sale extends CI_Model
$sale_price = 'CASE WHEN sales_items.discount_type = ' . PERCENT . ' THEN sales_items.item_unit_price * sales_items.quantity_purchased * (1 - sales_items.discount / 100) ELSE sales_items.item_unit_price * sales_items.quantity_purchased - sales_items.discount END';
$sales_tax = 'ROUND(IFNULL(SUM(sales_items_taxes.sales_tax), 0), ' . $decimals . ')';
$internal_tax = 'ROUND(IFNULL(SUM(sales_items_taxes.internal_tax), 0), ' . $decimals . ')';
$sales_tax = "ROUND(IFNULL(SUM(sales_items_taxes.sales_tax), 0), $decimals)";
$internal_tax = "ROUND(IFNULL(SUM(sales_items_taxes.internal_tax), 0), $decimals)";
$cash_adjustment = 'IFNULL(SUM(payments.sale_cash_adjustment), 0)';
if($this->config->item('tax_included'))
{
$sale_total = 'ROUND(SUM(' . $sale_price . '),' . $decimals . ')';
$sale_total = "ROUND(SUM($sale_price), $decimals) + $cash_adjustment";
// $sale_subtotal = "$sale_total - $internal_tax";
}
else
{
$sale_total = 'ROUND(SUM(' . $sale_price . '),' . $decimals . ') + ' . $sales_tax;
// $sale_subtotal = "ROUND(SUM($sale_price), $decimals) - $internal_tax - $cash_adjustment";
$sale_total = "ROUND(SUM($sale_price), $decimals) + $sales_tax + $cash_adjustment";
}
// create a temporary table to contain all the sum of taxes per sale item
$this->db->query('CREATE TEMPORARY TABLE IF NOT EXISTS ' . $this->db->dbprefix('sales_items_taxes_temp') .
' (INDEX(sale_id), INDEX(item_id)) ENGINE=MEMORY
@@ -75,10 +82,12 @@ class Sale extends CI_Model
MAX(customer_p.last_name) AS last_name,
MAX(customer_p.email) AS email,
MAX(customer_p.comments) AS comments,
MAX(IFNULL(payments.sale_cash_adjustment, 0)) AS cash_adjustment,
MAX(IFNULL(payments.sale_cash_refund, 0)) AS cash_refund,
' . "
$sale_total AS amount_due,
MAX(IFNULL(payments.sale_payment_amount, 0)) AS amount_tendered,
MAX(IFNULL(payments.sale_payment_amount,0)) - $sale_total AS change_due,
(MAX(payments.sale_payment_amount)) - ($sale_total) AS change_due,
" . '
MAX(payments.payment_type) AS payment_type
');
@@ -131,7 +140,8 @@ class Sale extends CI_Model
' (PRIMARY KEY(sale_id), INDEX(sale_id))
(
SELECT payments.sale_id AS sale_id,
IFNULL(SUM(payments.payment_amount), 0) AS sale_payment_amount,
SUM(CASE WHEN payments.cash_adjustment = 0 THEN payments.payment_amount ELSE 0 END) AS sale_payment_amount,
SUM(CASE WHEN payments.cash_adjustment = 1 THEN payments.payment_amount ELSE 0 END) AS sale_cash_adjustment,
GROUP_CONCAT(CONCAT(payments.payment_type, " ", (payments.payment_amount - payments.cash_refund)) SEPARATOR ", ") AS payment_type
FROM ' . $this->db->dbprefix('sales_payments') . ' AS payments
INNER JOIN ' . $this->db->dbprefix('sales') . ' AS sales
@@ -149,9 +159,10 @@ class Sale extends CI_Model
$tax = 'IFNULL(SUM(sales_items_taxes.tax), 0)';
$sales_tax = 'IFNULL(SUM(sales_items_taxes.sales_tax), 0)';
$internal_tax = 'IFNULL(SUM(sales_items_taxes.internal_tax), 0)';
$cash_adjustment = 'IFNULL(SUM(payments.sale_cash_adjustment), 0)';
$sale_subtotal = 'ROUND(SUM(' . $sale_price . '), ' . $decimals . ') - ' . $internal_tax;
$sale_total = 'ROUND(SUM(' . $sale_price . '), ' . $decimals . ') + ' . $sales_tax;
$sale_subtotal = "ROUND(SUM($sale_price), $decimals) - $internal_tax";
$sale_total = "ROUND(SUM($sale_price), $decimals) + $sales_tax + $cash_adjustment";
// create a temporary table to contain all the sum of taxes per sale item
$this->db->query('CREATE TEMPORARY TABLE IF NOT EXISTS ' . $this->db->dbprefix('sales_items_taxes_temp') .
@@ -197,7 +208,7 @@ class Sale extends CI_Model
($sale_total - $sale_cost) AS profit,
$sale_total AS amount_due,
MAX(payments.sale_payment_amount) AS amount_tendered,
(MAX(payments.sale_payment_amount) - ($sale_total)) AS change_due,
(MAX(payments.sale_payment_amount)) - ($sale_total) AS change_due,
" . '
MAX(payments.payment_type) AS payment_type
');
@@ -550,17 +561,19 @@ class Sale extends CI_Model
$payment_type = $payment['payment_type'];
$payment_amount = $payment['payment_amount'];
$cash_refund = $payment['cash_refund'];
$cash_adjustment = $payment['cash_adjustment'];
$employee_id = $payment['employee_id'];
if($payment_id == -1 && $payment_amount != 0)
{
// Add a new payment transaction
$sales_payments_data = array(
'sale_id' => $sale_id,
'payment_type' => $payment_type,
'payment_amount' => $payment_amount,
'cash_refund' => $cash_refund,
'employee_id' => $employee_id
'sale_id' => $sale_id,
'payment_type' => $payment_type,
'payment_amount' => $payment_amount,
'cash_refund' => $cash_refund,
'cash_adjustment' => $cash_adjustment,
'employee_id' => $employee_id
);
$success = $this->db->insert('sales_payments', $sales_payments_data);
}
@@ -572,7 +585,8 @@ class Sale extends CI_Model
$sales_payments_data = array(
'payment_type' => $payment_type,
'payment_amount' => $payment_amount,
'cash_refund' => $cash_refund
'cash_refund' => $cash_refund,
'cash_adjustment' => $cash_adjustment
);
$this->db->where('payment_id', $payment_id);
$success = $this->db->update('sales_payments', $sales_payments_data);
@@ -589,7 +603,6 @@ class Sale extends CI_Model
$success &= $this->db->trans_status();
}
return $success;
}
@@ -658,11 +671,12 @@ class Sale extends CI_Model
}
$sales_payments_data = array(
'sale_id' => $sale_id,
'payment_type' => $payment['payment_type'],
'payment_amount' => $payment['payment_amount'],
'cash_refund' => $payment['cash_refund'],
'employee_id' => $employee_id
'sale_id' => $sale_id,
'payment_type' => $payment['payment_type'],
'payment_amount' => $payment['payment_amount'],
'cash_refund' => $payment['cash_refund'],
'cash_adjustment' => $payment['cash_adjustment'],
'employee_id' => $employee_id
);
$this->db->insert('sales_payments', $sales_payments_data);
@@ -1126,15 +1140,17 @@ class Sale extends CI_Model
$sales_tax = 'IFNULL(SUM(sales_items_taxes.sales_tax), 0)';
$internal_tax = 'IFNULL(SUM(sales_items_taxes.internal_tax), 0)';
$cash_adjustment = 'IFNULL(SUM(payments.sale_cash_adjustment), 0)';
if($this->config->item('tax_included'))
{
$sale_total = 'ROUND(SUM(' . $sale_price . '), ' . $decimals . ')';
$sale_subtotal = $sale_total . ' - ' . $internal_tax;
$sale_total = "ROUND(SUM($sale_price), $decimals) + $cash_adjustment";
$sale_subtotal = "$sale_total - $internal_tax";
}
else
{
$sale_subtotal = 'ROUND(SUM(' . $sale_price . '), ' . $decimals . ') - ' . $internal_tax;
$sale_total = 'ROUND(SUM(' . $sale_price . '), ' . $decimals . ') + ' . $sales_tax;
$sale_subtotal = "ROUND(SUM($sale_price), $decimals) - $internal_tax + $cash_adjustment";
$sale_total = "ROUND(SUM($sale_price), $decimals) + $sales_tax + $cash_adjustment";
}
// create a temporary table to contain all the sum of taxes per sale item
@@ -1162,7 +1178,8 @@ class Sale extends CI_Model
' (PRIMARY KEY(sale_id), INDEX(sale_id))
(
SELECT payments.sale_id AS sale_id,
IFNULL(SUM(payments.payment_amount), 0) AS sale_payment_amount,
SUM(CASE WHEN payments.cash_adjustment = 0 THEN payments.payment_amount ELSE 0 END) AS sale_payment_amount,
SUM(CASE WHEN payments.cash_adjustment = 1 THEN payments.payment_amount ELSE 0 END) AS sale_cash_adjustment,
GROUP_CONCAT(CONCAT(payments.payment_type, " ", (payments.payment_amount - payments.cash_refund)) SEPARATOR ", ") AS payment_type
FROM ' . $this->db->dbprefix('sales_payments') . ' AS payments
INNER JOIN ' . $this->db->dbprefix('sales') . ' AS sales
@@ -157,7 +157,9 @@ class Summary_payments extends Summary_report
$this->db->query('CREATE TEMPORARY TABLE IF NOT EXISTS ' . $this->db->dbprefix('sumpay_payments_temp') .
' (INDEX(sale_id)) ENGINE=MEMORY
(
SELECT sales.sale_id, COUNT(sales.sale_id) AS number_payments, SUM(sales_payments.payment_amount) AS total_payments,
SELECT sales.sale_id, COUNT(sales.sale_id) AS number_payments,
SUM(CASE WHEN sales_payments.cash_adjustment = 0 THEN sales_payments.payment_amount ELSE 0 END) AS total_payments,
SUM(CASE WHEN sales_payments.cash_adjustment = 1 THEN sales_payments.payment_amount ELSE 0 END) AS total_cash_adjustment,
SUM(sales_payments.cash_refund) AS total_cash_refund
FROM ' . $this->db->dbprefix('sales') . ' AS sales
LEFT OUTER JOIN ' . $this->db->dbprefix('sales_payments') . ' AS sales_payments
+7 -6
View File
@@ -891,8 +891,9 @@ $(document).ready(function()
});
});
function check_payment_type() {
var cash_rounding = <?php echo json_encode($cash_rounding); ?>;
function check_payment_type()
{
var cash_mode = <?php echo json_encode($cash_mode); ?>;
if($("#payment_types").val() == "<?php echo $this->lang->line('sales_giftcard'); ?>")
{
@@ -904,9 +905,9 @@ function check_payment_type() {
$(".non-giftcard-input").attr('disabled', true);
$(".giftcard-input:enabled").val('').focus();
}
else if($("#payment_types").val() == "<?php echo $this->lang->line('sales_cash'); ?>" && cash_rounding)
else if(($("#payment_types").val() == "<?php echo $this->lang->line('sales_cash'); ?>" && cash_mode == '1'))
{
$("#sale_total").html("<?php echo to_currency($cash_total); ?>");
$("#sale_total").html("<?php echo to_currency($non_cash_total); ?>");
$("#sale_amount_due").html("<?php echo to_currency($cash_amount_due); ?>");
$("#amount_tendered_label").html("<?php echo $this->lang->line('sales_amount_tendered'); ?>");
$("#amount_tendered:enabled").val("<?php echo to_currency_no_money($cash_amount_due); ?>");
@@ -916,9 +917,9 @@ function check_payment_type() {
else
{
$("#sale_total").html("<?php echo to_currency($non_cash_total); ?>");
$("#sale_amount_due").html("<?php echo to_currency($non_cash_amount_due); ?>");
$("#sale_amount_due").html("<?php echo to_currency($amount_due); ?>");
$("#amount_tendered_label").html("<?php echo $this->lang->line('sales_amount_tendered'); ?>");
$("#amount_tendered:enabled").val("<?php echo to_currency_no_money($non_cash_amount_due); ?>");
$("#amount_tendered:enabled").val("<?php echo to_currency_no_money($amount_due); ?>");
$(".giftcard-input").attr('disabled', true);
$(".non-giftcard-input").attr('disabled', false);
}