Add support for customer balance due tracking.

This commit is contained in:
Steve Ireland
2021-02-27 18:25:18 -05:00
parent 23f720ba40
commit 46ef36ced9
13 changed files with 132 additions and 12 deletions

View File

@@ -38,6 +38,7 @@ class Customers extends Persons
//create object with empty properties.
$stats = new stdClass;
$stats->total = 0;
$stats->balance_due = 0;
$stats->min = 0;
$stats->max = 0;
$stats->average = 0;
@@ -74,6 +75,7 @@ class Customers extends Persons
//create object with empty properties.
$stats = new stdClass;
$stats->total = 0;
$stats->balance_due = 0;
$stats->min = 0;
$stats->max = 0;
$stats->average = 0;
@@ -260,6 +262,7 @@ class Customers extends Persons
'company_name' => $this->input->post('company_name') == '' ? NULL : $this->input->post('company_name'),
'discount' => $this->input->post('discount') == '' ? 0.00 : $this->input->post('discount'),
'discount_type' => $this->input->post('discount_type') == NULL ? PERCENT : $this->input->post('discount_type'),
'credit_limit' => $this->input->post('credit_limit') == '' ? 0.00 : $this->input->post('credit_limit'),
'package_id' => $this->input->post('package_id') == '' ? NULL : $this->input->post('package_id'),
'taxable' => $this->input->post('taxable') != NULL,
'date' => $date_formatter->format('Y-m-d H:i:s'),

View File

@@ -1347,6 +1347,7 @@ class Reports extends Secure_Controller
}
$sale_type_options['canceled'] = $this->lang->line('reports_canceled');
$sale_type_options['returns'] = $this->lang->line('reports_returns');
$sale_type_options['due'] = $this->lang->line('reports_balance_due');
return $sale_type_options;
}
@@ -1387,6 +1388,16 @@ class Reports extends Secure_Controller
$button_label = $this->lang->line('common_delete');
}
$payments = $row['payment_type'];
if($row['due'] > 0)
{
if($row['payment_type'] != "")
{
$payments .= ', ';
}
$payments .= 'Balance ' . to_currency($row['due']);
}
$summary_data[] = $this->xss_clean(array(
'id' => $row['sale_id'],
'type_code' => $row['type_code'],
@@ -1399,7 +1410,7 @@ class Reports extends Secure_Controller
'total' => to_currency($row['total']),
'cost' => to_currency($row['cost']),
'profit' => to_currency($row['profit']),
'payment_type' => $row['payment_type'],
'payment_type' => $payments,
'comment' => $row['comment'],
'edit' => anchor('sales/edit/'.$row['sale_id'], '<span class="glyphicon glyphicon-edit"></span>',
array('class' => 'modal-dlg print_hide', $button_key => $button_label, 'data-btn-submit' => $this->lang->line('common_submit'), 'title' => $this->lang->line('sales_update')))

View File

@@ -12,6 +12,7 @@ $lang["customers_confirm_delete"] = "Are you sure you want to delete the selecte
$lang["customers_confirm_restore"] = "Are you sure you want to restore the selected Customers(s)?";
$lang["customers_consent"] = "Registration consent";
$lang["customers_consent_required"] = "Registration consent is a required field";
$lang["customers_credit_limit"] = "Credit Limit";
$lang["customers_csv_import_failed"] = "The csv import failed";
$lang["customers_csv_import_nodata_wrongformat"] = "The uploaded file has no data or is incorrectly formatted";
$lang["customers_csv_import_partially_failed"] = "Customer import successful with some failures:";

View File

@@ -2,6 +2,7 @@
$lang["reports_all"] = "All";
$lang["reports_authority"] = "Authority";
$lang["reports_balance_due"] = "Balance Due";
$lang["reports_canceled"] = "Cancelled";
$lang["reports_categories"] = "Categories";
$lang["reports_categories_summary_report"] = "Categories Summary Report";

View File

@@ -12,6 +12,7 @@ $lang["customers_confirm_delete"] = "Are you sure you want to delete the selecte
$lang["customers_confirm_restore"] = "Are you sure you want to restore selected customers(s)?";
$lang["customers_consent"] = "Registration consent";
$lang["customers_consent_required"] = "Registration consent is a required field.";
$lang["customers_credit_limit"] = "Credit Limit";
$lang["customers_csv_import_failed"] = "CSV import failed";
$lang["customers_csv_import_nodata_wrongformat"] = "The uploaded file has no data or is incorrectly formatted.";
$lang["customers_csv_import_partially_failed"] = "Customer import successful with some failures:";

View File

@@ -2,6 +2,7 @@
$lang["reports_all"] = "All";
$lang["reports_authority"] = "Authority";
$lang["reports_balance_due"] = "Balance Due";
$lang["reports_canceled"] = "Canceled";
$lang["reports_categories"] = "Categories";
$lang["reports_categories_summary_report"] = "Categories Summary Report";

View File

@@ -0,0 +1,20 @@
<?php if (!defined('BASEPATH')) exit('No direct script access allowed');
class Migration_customerduetracking extends CI_Migration
{
public function __construct()
{
parent::__construct();
}
public function up()
{
$this->db->query('ALTER TABLE ' . $this->db->dbprefix('customers') . ' ADD COLUMN `credit_limit` decimal(15,2) NOT NULL DEFAULT 0 AFTER `discount_type`');
}
public function down()
{
$this->db->query('ALTER TABLE ' . $this->db->dbprefix('customers') . ' DROP COLUMN `credit_limit`');
}
}
?>

View File

@@ -98,6 +98,7 @@ class Customer extends Person
*/
public function get_stats($customer_id)
{
// TODO Rework this
// create a temporary table to contain all the sum and average of items
$this->db->query('CREATE TEMPORARY TABLE IF NOT EXISTS ' . $this->db->dbprefix('sales_items_temp') .
' (INDEX(sale_id)) ENGINE=MEMORY
@@ -255,6 +256,7 @@ class Customer extends Person
'taxable' => 0,
'discount' => 0.00,
'discount_type' => 0,
'credit_limit' => 0,
'package_id' => NULL,
'points' => NULL,
'sales_tax_code_id' => NULL,

View File

@@ -1115,7 +1115,7 @@ class Sale extends CI_Model
}
/**
* Creates sales temporary dimentional table
* Creates sales temporary dimensional table
* We create a temp table that allows us to do easy report/sales queries
*/
public function create_temp_table(array $inputs)

View File

@@ -86,6 +86,7 @@ class Detailed_sales extends Report
SUM(subtotal) AS subtotal,
SUM(tax) AS tax,
SUM(total) AS total,
SUM(CASE WHEN (total - sale_payment_amount) > 0 THEN (total - sale_payment_amount) ELSE 0 END) AS due,
SUM(cost) AS cost,
SUM(profit) AS profit,
MAX(payment_type) AS payment_type,
@@ -114,6 +115,14 @@ class Detailed_sales extends Report
$this->db->or_where('sale_type', SALE_TYPE_INVOICE);
$this->db->group_end();
}
elseif($inputs['sale_type'] == 'due')
{
$this->db->where('sale_status', COMPLETED);
$this->db->group_start();
$this->db->where('sale_type', SALE_TYPE_POS);
$this->db->or_where('sale_type', SALE_TYPE_INVOICE);
$this->db->group_end();
}
elseif($inputs['sale_type'] == 'quotes')
{
$this->db->where('sale_status', SUSPENDED);
@@ -135,6 +144,10 @@ class Detailed_sales extends Report
}
$this->db->group_by('sale_id');
if($inputs['sale_type'] == 'due')
{
$this->db->having('due > 0');
}
$this->db->order_by('MAX(sale_date)');
$data = array();

View File

@@ -121,9 +121,15 @@ class Summary_payments extends Summary_report
{
$decimals = totals_decimals();
$trans_amount = 'ROUND(SUM(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), ' . $decimals . ') AS trans_amount';
// Replace the following
// $trans_amount = 'ROUND(SUM(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), ' . $decimals . ') AS trans_amount';
// With the following
$trans_amount = 'SUM(CASE WHEN sales_items.discount_type = ' . PERCENT
. " THEN sales_items.quantity_purchased * sales_items.item_unit_price - ROUND(sales_items.quantity_purchased * sales_items.item_unit_price * sales_items.discount / 100, $decimals) "
. 'ELSE sales_items.quantity_purchased * (sales_items.item_unit_price - sales_items.discount) END) AS trans_amount';
$this->db->query('CREATE TEMPORARY TABLE IF NOT EXISTS ' . $this->db->dbprefix('sumpay_taxes_temp') .
' (INDEX(sale_id)) ENGINE=MEMORY

View File

@@ -40,19 +40,44 @@ class Summary_taxes extends Summary_report
{
$where .= 'AND sale_time BETWEEN ' . $this->db->escape(rawurldecode($inputs['start_date'])) . ' AND ' . $this->db->escape(rawurldecode($inputs['end_date']));
}
// Replace the following
// if($this->config->item('tax_included'))
// {
// $sale_total = '(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)';
// $sale_subtotal = '(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 * (100 / (100 + sales_items_taxes.percent)))';
// }
// else
// {
// $sale_total = '(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 * (1 + (sales_items_taxes.percent / 100)))';
// $sale_subtotal = '(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)';
// }
//
// $decimals = totals_decimals();
// With the following
$decimals = totals_decimals();
if($this->config->item('tax_included'))
{
$sale_total = '(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)';
$sale_subtotal = '(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 * (100 / (100 + sales_items_taxes.percent)))';
$sale_total = '(CASE WHEN sales_items.discount_type = ' . PERCENT
. " THEN sales_items.quantity_purchased * sales_items.item_unit_price - ROUND(sales_items.quantity_purchased * sales_items.item_unit_price * sales_items.discount / 100, $decimals) "
. 'ELSE sales_items.quantity_purchased * (sales_items.item_unit_price - sales_items.discount) END)';
$sale_subtotal = '(CASE WHEN sales_items.discount_type = ' . PERCENT
. " THEN sales_items.quantity_purchased * sales_items.item_unit_price - ROUND(sales_items.quantity_purchased * sales_items.item_unit_price * sales_items.discount / 100, $decimals) "
. 'ELSE sales_items.quantity_purchased * (sales_items.item_unit_price - sales_items.discount) END * (100 / (100 + sales_items_taxes.percent)))';
}
else
{
$sale_total = '(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 * (1 + (sales_items_taxes.percent / 100)))';
$sale_subtotal = '(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)';
}
$sale_total = '(CASE WHEN sales_items.discount_type = ' . PERCENT
. " THEN sales_items.quantity_purchased * sales_items.item_unit_price - ROUND(sales_items.quantity_purchased * sales_items.item_unit_price * sales_items.discount / 100, $decimals) "
. 'ELSE sales_items.quantity_purchased * (sales_items.item_unit_price - sales_items.discount) END * (100 / (100 + sales_items_taxes.percent)) * (1 + (sales_items_taxes.percent / 100)))';
$decimals = totals_decimals();
$sale_subtotal = '(CASE WHEN sales_items.discount_type = ' . PERCENT
. " THEN sales_items.quantity_purchased * sales_items.item_unit_price - ROUND(sales_items.quantity_purchased * sales_items.item_unit_price * sales_items.discount / 100, $decimals) "
. 'ELSE sales_items.quantity_purchased * (sales_items.item_unit_price - sales_items.discount) END)';
}
// End of "with the following"
$query = $this->db->query("SELECT percent, count(*) AS count, ROUND(SUM(subtotal), $decimals) AS subtotal, ROUND(SUM(tax), $decimals) AS tax, ROUND(SUM(total), $decimals) AS total
FROM (

View File

@@ -80,6 +80,21 @@
</div>
</div>
<div class="form-group form-group-sm">
<?php echo form_label($this->lang->line('customers_credit_limit'), 'credit_limit', array('class' => 'control-label col-xs-3')); ?>
<div class='col-xs-4'>
<div class="input-group input-group-sm">
<?php echo form_input(array(
'name'=>'credit_limit',
'id'=>'credit_limit',
'class'=>'form-control input-sm',
'onClick'=>'this.select();',
'value'=>$person_info->credit_limit)
); ?>
</div>
</div>
</div>
<div class="form-group form-group-sm">
<?php echo form_label($this->lang->line('customers_company_name'), 'company_name', array('class' => 'control-label col-xs-3')); ?>
<div class='col-xs-8'>
@@ -227,7 +242,28 @@
</div>
</div>
</div>
<div class="form-group form-group-sm">
<?php echo form_label($this->lang->line('customers_balance_due'), 'total', array('class' => 'control-label col-xs-3')); ?>
<div class="col-xs-4">
<div class="input-group input-group-sm">
<?php if (!currency_side()): ?>
<span class="input-group-addon input-sm"><b><?php echo $this->config->item('currency_symbol'); ?></b></span>
<?php endif; ?>
<?php echo form_input(array(
'name'=>'balance_due',
'id'=>'balance_due',
'class'=>'form-control input-sm',
'value'=>to_currency_no_money($stats->balance_due),
'disabled'=>'')
); ?>
<?php if (currency_side()): ?>
<span class="input-group-addon input-sm"><b><?php echo $this->config->item('currency_symbol'); ?></b></span>
<?php endif; ?>
</div>
</div>
</div>
<div class="form-group form-group-sm">
<?php echo form_label($this->lang->line('customers_max'), 'max', array('class' => 'control-label col-xs-3')); ?>
<div class="col-xs-4">