From 5ef8a88000b6410529ce2d73092823d7bec4bcd4 Mon Sep 17 00:00:00 2001 From: Steve Ireland Date: Thu, 3 May 2018 21:39:23 -0400 Subject: [PATCH] Add support for temporary items. --- application/controllers/Items.php | 59 ++++++- application/controllers/Sales.php | 59 ++++++- application/language/en-GB/items_lang.php | 1 + application/language/en-US/items_lang.php | 1 + application/libraries/Sale_lib.php | 35 ++++- application/models/Item.php | 53 ++++++- application/models/Sale.php | 1 - application/views/items/form.php | 16 +- application/views/sales/register.php | 182 ++++++++++++++++------ 9 files changed, 337 insertions(+), 70 deletions(-) diff --git a/application/controllers/Items.php b/application/controllers/Items.php index f6f7991bc..2e6d2a3a8 100644 --- a/application/controllers/Items.php +++ b/application/controllers/Items.php @@ -13,6 +13,8 @@ class Items extends Secure_Controller public function index() { + $this->session->set_userdata('allow_temp_items', 0); + $data['table_headers'] = $this->xss_clean(get_items_manage_table_headers()); $data['stock_location'] = $this->xss_clean($this->item_lib->get_item_location()); @@ -24,7 +26,8 @@ class Items extends Secure_Controller 'is_serialized' => $this->lang->line('items_serialized_items'), 'no_description' => $this->lang->line('items_no_description_items'), 'search_custom' => $this->lang->line('items_search_custom_items'), - 'is_deleted' => $this->lang->line('items_is_deleted')); + 'is_deleted' => $this->lang->line('items_is_deleted'), + 'temporary' => $this->lang->line('items_temp')); $this->load->view('items/manage', $data); } @@ -50,7 +53,8 @@ class Items extends Secure_Controller 'is_serialized' => FALSE, 'no_description' => FALSE, 'search_custom' => FALSE, - 'is_deleted' => FALSE); + 'is_deleted' => FALSE, + 'temporary' => FALSE); // check if any filter is set in the multiselect dropdown $filledup = array_fill_keys($this->input->get('filters'), TRUE); @@ -177,6 +181,9 @@ class Items extends Secure_Controller public function view($item_id = -1) { + // allow_temp_items is set in the index function of items.php or sales.php + $data['allow_temp_item'] = $this->session->userdata('allow_temp_items'); + $data['item_tax_info'] = $this->xss_clean($this->Item_taxes->get_info($item_id)); $data['default_tax_1_rate'] = ''; $data['default_tax_2_rate'] = ''; @@ -188,6 +195,25 @@ class Items extends Secure_Controller $item_info->$property = $this->xss_clean($value); } + if($data['allow_temp_item'] == 1) + { + if($item_id != -1) + { + if($item_info->item_type != ITEM_TEMP) + { + $data['allow_temp_item'] = 0; + } + } + } + else + { + if($item_info->item_type == ITEM_TEMP) + { + $data['allow_temp_item'] = 1; + } + } + + if($item_id == -1) { $data['default_tax_1_rate'] = $this->config->item('default_tax_1_rate'); @@ -364,19 +390,26 @@ class Items extends Secure_Controller $upload_success = $this->_handle_image_upload(); $upload_data = $this->upload->data(); + $receiving_quantity = parse_decimals($this->input->post('receiving_quantity')); + $item_type = $this->input->post('item_type') == NULL ? ITEM : $this->input->post('item_type'); + + if($receiving_quantity == '0' && $item_type!= ITEM_TEMP) + { + $receiving_quantity = '1'; + } //Save item data $item_data = array( 'name' => $this->input->post('name'), 'description' => $this->input->post('description'), 'category' => $this->input->post('category'), - 'item_type' => $this->input->post('item_type') == NULL ? ITEM : $this->input->post('item_type'), + 'item_type' => $item_type, 'stock_type' => $this->input->post('stock_type') == NULL ? HAS_STOCK : $this->input->post('stock_type'), 'supplier_id' => $this->input->post('supplier_id') == '' ? NULL : $this->input->post('supplier_id'), 'item_number' => $this->input->post('item_number') == '' ? NULL : $this->input->post('item_number'), 'cost_price' => parse_decimals($this->input->post('cost_price')), 'unit_price' => parse_decimals($this->input->post('unit_price')), 'reorder_level' => parse_decimals($this->input->post('reorder_level')), - 'receiving_quantity' => parse_decimals($this->input->post('receiving_quantity')), + 'receiving_quantity' => $receiving_quantity, 'allow_alt_description' => $this->input->post('allow_alt_description') != NULL, 'is_serialized' => $this->input->post('is_serialized') != NULL, 'deleted' => $this->input->post('is_deleted') != NULL, @@ -392,6 +425,13 @@ class Items extends Secure_Controller 'custom10' => $this->input->post('custom10') == NULL ? '' : $this->input->post('custom10') ); + if($item_data['item_type'] == ITEM_TEMP) + { + $item_data['stock_type'] = HAS_NO_STOCK; + $item_data['receiving_quantity'] = 0; + $item_data['reorder_level'] = 0; + } + $x = $this->input->post('tax_category_id'); if(!isset($x)) { @@ -412,8 +452,7 @@ class Items extends Secure_Controller } $employee_id = $this->Employee->get_logged_in_employee_info()->person_id; - $cur_item_info = $this->Item->get_info($item_id); - + if($this->Item->save($item_data, $item_id)) { $success = TRUE; @@ -424,7 +463,7 @@ class Items extends Secure_Controller $item_id = $item_data['item_id']; $new_item = TRUE; } - + $items_taxes_data = array(); $tax_names = $this->input->post('tax_names'); $tax_percents = $this->input->post('tax_percents'); @@ -444,9 +483,15 @@ class Items extends Secure_Controller foreach($stock_locations as $location) { $updated_quantity = parse_decimals($this->input->post('quantity_' . $location['location_id'])); + if($item_data['item_type'] == ITEM_TEMP) + { + $updated_quantity = 0; + } $location_detail = array('item_id' => $item_id, 'location_id' => $location['location_id'], 'quantity' => $updated_quantity); + + $item_quantity = $this->Item_quantity->get_item_quantity($item_id, $location['location_id']); if($item_quantity->quantity != $updated_quantity || $new_item) { diff --git a/application/controllers/Sales.php b/application/controllers/Sales.php index 01388f403..556aabc50 100644 --- a/application/controllers/Sales.php +++ b/application/controllers/Sales.php @@ -19,6 +19,7 @@ class Sales extends Secure_Controller public function index() { + $this->session->set_userdata('allow_temp_items', 1); $this->_reload(); } @@ -1274,6 +1275,10 @@ class Sales extends Secure_Controller $this->session->set_userdata('sale_id', -1); } } + else + { + $this->sale_lib->remove_temp_items(); + } $this->sale_lib->clear_all(); $this->_reload(); @@ -1387,6 +1392,58 @@ class Sales extends Secure_Controller return $filtered_cart; } -} + public function change_item_number() + { + $item_id = $this->input->post('item_id'); + $item_number = $this->input->post('item_number'); + $this->Item->update_item_number($item_id, $item_number); + $cart = $this->sale_lib->get_cart(); + $x = $this->search_cart_for_item_id($item_id, $cart); + if($x != NULL) + { + $cart[$x]['item_number'] = $item_number; + } + $this->sale_lib->set_cart($cart); + } + + public function change_item_name() + { + $item_id = $this->input->post('item_id'); + $name = $this->input->post('item_name'); + $this->Item->update_item_name($item_id, $name); + $cart = $this->sale_lib->get_cart(); + $x = $this->search_cart_for_item_id($item_id, $cart); + if($x != NULL) { + $cart[$x]['name'] = $name; + } + $this->sale_lib->set_cart($cart); + } + + public function change_item_description() + { + $item_id = $this->input->post('item_id'); + $description = $this->input->post('item_description'); + $this->Item->update_item_description($item_id, $description); + $cart = $this->sale_lib->get_cart(); + $x = $this->search_cart_for_item_id($item_id, $cart); + if($x != NULL) + { + $cart[$x]['description'] = $description; + } + $this->sale_lib->set_cart($cart); + } + + function search_cart_for_item_id($id, $array) + { + foreach($array as $key => $val) + { + if ($val['item_id'] === $id) + { + return $key; + } + } + return NULL; + } +} ?> diff --git a/application/language/en-GB/items_lang.php b/application/language/en-GB/items_lang.php index 9c116f555..f993612c0 100644 --- a/application/language/en-GB/items_lang.php +++ b/application/language/en-GB/items_lang.php @@ -97,6 +97,7 @@ $lang["items_tax_percent"] = "Tax Percent"; $lang["items_tax_percent_number"] = "Tax Percent must be a numeric value"; $lang["items_tax_percent_required"] = "Tax Percent is a required field"; $lang["items_tax_percents"] = "Tax Percent(s)"; +$lang["items_temp"] = "Temporary"; $lang["items_type"] = "Item Type"; $lang["items_unit_price"] = "Sell Price"; $lang["items_unit_price_number"] = "Sell Price must be a number"; diff --git a/application/language/en-US/items_lang.php b/application/language/en-US/items_lang.php index bb5928912..bf8527123 100644 --- a/application/language/en-US/items_lang.php +++ b/application/language/en-US/items_lang.php @@ -97,6 +97,7 @@ $lang["items_tax_percent"] = "Tax Percent"; $lang["items_tax_percent_number"] = "Tax Percent must be a numeric value"; $lang["items_tax_percent_required"] = "Tax Percent is a required field."; $lang["items_tax_percents"] = "Tax Percent(s)"; +$lang["items_temp"] = "Temporary"; $lang["items_type"] = "Item Type"; $lang["items_unit_price"] = "Retail Price"; $lang["items_unit_price_number"] = "Unit price must be a number."; diff --git a/application/libraries/Sale_lib.php b/application/libraries/Sale_lib.php index 61ca5d259..4c90e2612 100644 --- a/application/libraries/Sale_lib.php +++ b/application/libraries/Sale_lib.php @@ -66,7 +66,7 @@ class Sale_lib $filtered_cart = array(); - foreach($cart as $k=>$v) + foreach($cart as $k => $v) { if($v['print_option'] == PRINT_YES) { @@ -78,7 +78,7 @@ class Sale_lib if($this->CI->config->item('line_sequence') == '0') { $sort = array(); - foreach($filtered_cart as $k=>$v) + foreach($filtered_cart as $k => $v) { $sort['line'][$k] = $v['line']; } @@ -88,19 +88,19 @@ class Sale_lib elseif($this->CI->config->item('line_sequence') == '1') { $sort = array(); - foreach($filtered_cart as $k=>$v) + foreach($filtered_cart as $k => $v) { $sort['stock_type'][$k] = $v['stock_type']; $sort['description'][$k] = $v['description']; $sort['name'][$k] = $v['name']; } - array_multisort($sort['stock_type'], SORT_DESC, $sort['description'], SORT_ASC, $sort['name'], SORT_ASC. $filtered_cart); + array_multisort($sort['stock_type'], SORT_DESC, $sort['description'], SORT_ASC, $sort['name'], SORT_ASC . $filtered_cart); } // Group by Item Category elseif($this->CI->config->item('line_sequence') == '2') { $sort = array(); - foreach($filtered_cart as $k=>$v) + foreach($filtered_cart as $k => $v) { $sort['category'][$k] = $v['stock_type']; $sort['description'][$k] = $v['description']; @@ -112,7 +112,7 @@ class Sale_lib else { $sort = array(); - foreach($filtered_cart as $k=>$v) + foreach($filtered_cart as $k => $v) { $sort['line'][$k] = $v['line']; } @@ -132,6 +132,19 @@ class Sale_lib $this->CI->session->unset_userdata('sales_cart'); } + public function remove_temp_items() + { + // Loop through the cart items and delete temporary items specific to this sale + $cart = $this->get_cart(); + foreach($cart as $line=>$item) + { + if($item['item_type'] == ITEM_TEMP) + { + $this->CI->Item->delete($item['item_id']); + } + } + } + public function get_comment() { // avoid returning a NULL that results in a 0 in the comment if nothing is set/available @@ -685,7 +698,7 @@ class Sale_lib public function add_item(&$item_id, $quantity = 1, $item_location, $discount = 0, $price_mode = PRICE_MODE_STANDARD, $kit_price_option = NULL, $kit_print_option = NULL, $price_override = NULL, $description = NULL, $serialnumber = NULL, $include_deleted = FALSE, $print_option = NULL ) { - $item_info = $this->CI->Item->get_info_by_id_or_number($item_id); + $item_info = $this->CI->Item->get_info_by_id($item_id); //make sure item exists if(empty($item_info)) @@ -862,7 +875,7 @@ class Sale_lib //make sure item exists if($item_id != -1) { - $item_info = $this->CI->Item->get_info_by_id_or_number($item_id); + $item_info = $this->CI->Item->get_info_by_id($item_id); if($item_info->stock_type == HAS_STOCK) { @@ -940,6 +953,12 @@ class Sale_lib public function delete_item($line) { $items = $this->get_cart(); + $item_type = $items[$line]['item_type']; + if($item_type == ITEM_TEMP) + { + $item_id = $items[$line]['item_id']; + $this->CI->Item->delete($item_id); + } unset($items[$line]); $this->set_cart($items); } diff --git a/application/models/Item.php b/application/models/Item.php index 48589a28d..5a085aecc 100644 --- a/application/models/Item.php +++ b/application/models/Item.php @@ -6,6 +6,7 @@ define('HAS_NO_STOCK', 1); define('ITEM', 0); define('ITEM_KIT', 1); define('ITEM_AMOUNT_ENTRY', 2); +define('ITEM_TEMP', 3); define('PRINT_ALL', 0); define('PRINT_PRICED', 1); @@ -65,7 +66,7 @@ class Item extends CI_Model $this->db->where('item_number', (string) $item_number); // check if $item_id is a number and not a string starting with 0 // because cases like 00012345 will be seen as a number where it is a barcode - if(ctype_digit($item_id) && substr($item_id, 0, 1) != '0') + if(is_numeric($item_id) && substr($item_id, 0, 1) != '0') { $this->db->where('item_id !=', (int) $item_id); } @@ -225,6 +226,15 @@ class Item extends CI_Model { $this->db->where('items.description', ''); } + if($filters['temporary'] != FALSE) + { + $this->db->where('items.item_type', ITEM_TEMP); + } + else + { + $non_temp = array(ITEM, ITEM_KIT, ITEM_AMOUNT_ENTRY); + $this->db->where_in('items.item_type', $non_temp); + } // get_found_rows case if($count_only == TRUE) @@ -341,6 +351,26 @@ class Item extends CI_Model return ''; } + /* + * Gets information about a particular active item by item id + */ + public function get_info_by_id($item_id) + { + $this->db->from('items'); + + $this->db->where('items.item_id', (int) $item_id); + + $this->db->where('items.deleted', 0); + + $query = $this->db->get(); + + if($query->num_rows() == 1) + { + return $query->row(); + } + + return ''; + } /* Get an item id given an item number */ @@ -388,10 +418,8 @@ class Item extends CI_Model if($this->db->insert('items', $item_data)) { $item_data['item_id'] = $this->db->insert_id(); - return TRUE; } - return FALSE; } @@ -923,5 +951,24 @@ class Item extends CI_Model return $this->save($data, $item_id); } + + public function update_item_number($item_id, $item_number) + { + $this->db->where('item_id', $item_id); + $this->db->update('items', array('item_number'=>$item_number)); + } + + public function update_item_name($item_id, $item_name) + { + $this->db->where('item_id', $item_id); + $this->db->update('items', array('name'=>$item_name)); + } + + public function update_item_description($item_id, $item_description) + { + $this->db->where('item_id', $item_id); + $this->db->update('items', array('description'=>$item_description)); + } + } ?> diff --git a/application/models/Sale.php b/application/models/Sale.php index c4b3bfe2f..9c1cba3ce 100644 --- a/application/models/Sale.php +++ b/application/models/Sale.php @@ -1292,7 +1292,6 @@ class Sale extends CI_Model $this->db->update('sales', array('sale_status'=>$sale_status)); } - /** * Gets the quote_number for the selected sale */ diff --git a/application/views/items/form.php b/application/views/items/form.php index 637ee9056..08bae1e5a 100644 --- a/application/views/items/form.php +++ b/application/views/items/form.php @@ -107,7 +107,21 @@ - + + + diff --git a/application/views/sales/register.php b/application/views/sales/register.php index 734259d80..3762dd06e 100644 --- a/application/views/sales/register.php +++ b/application/views/sales/register.php @@ -135,13 +135,33 @@ if(isset($success)) ?> 'form-horizontal', 'id'=>'cart_'.$line)); ?> - ');?> - - -
+ + '); ?> + 'hidden', 'name'=>'item_id', 'value'=>$item['item_id'])); ?> - + + 'item_number', 'id'=>'item_number','class'=>'form-control input-sm', 'value'=>$item['item_number'], 'tabindex'=>++$tabindex));?> + + 'name','id'=>'name', 'class'=>'form-control input-sm', 'value'=>$item['name'], 'tabindex'=>++$tabindex));?> + + + + + +
+ + + - lang->line('sales_description_abbrv');?> + 'hidden', 'name'=>'item_id', 'value'=>$item['item_id'])); ?> + + 'item_description', 'id'=>'item_description', 'class'=>'form-control input-sm', 'value'=>$item['description'], 'tabindex'=>++$tabindex));?> + + + + + + lang->line('sales_description_abbrv');?> + + + + 'description', 'class'=>'form-control input-sm', 'value'=>$item['description'], 'onClick'=>'this.select();')); + } + else + { + if($item['description']!='') + { + echo $item['description']; + echo form_hidden('description', $item['description']); + } + else + { + echo $this->lang->line('sales_no_description'); + echo form_hidden('description',''); + } + } + ?> + +   + + lang->line('sales_serial'); + } + ?> + + + 'serialnumber', 'class'=>'form-control input-sm', 'value'=>$item['serialnumber'], 'onClick'=>'this.select();')); + } + else + { + echo form_hidden('serialnumber', ''); + } + ?> + - - 'description', 'class'=>'form-control input-sm', 'value'=>$item['description'], 'onClick'=>'this.select();')); - } - else - { - if($item['description']!='') - { - echo $item['description']; - echo form_hidden('description', $item['description']); - } - else - { - echo $this->lang->line('sales_no_description'); - echo form_hidden('description',''); - } - } - ?> - -   - - lang->line('sales_serial'); - } - ?> - - - 'serialnumber', 'class'=>'form-control input-sm', 'value'=>$item['serialnumber'], 'onClick'=>'this.select();')); - } - else - { - echo form_hidden('serialnumber', ''); - } - ?> - $(document).ready(function() { + $("input[name='item_number']").change(function(){ + var item_id = $(this).parents("tr").find("input[name='item_id']").val(); + var item_number = $(this).val(); + $.ajax({ + url: "", + method: 'post', + data: $.extend(csrf_form_base(), + { + "item_id" : item_id, + "item_number" : item_number, + }), + dataType: 'json' + }); + }); + + $("input[name='name']").change(function(){ + var item_id = $(this).parents("tr").find("input[name='item_id']").val(); + var item_name = $(this).val(); + $.ajax({ + url: "", + method: 'post', + data: $.extend(csrf_form_base(), + { + "item_id" : item_id, + "item_name" : item_name, + }), + dataType: 'json' + }); + }); + + $("input[name='item_description']").change(function(){ + var item_id = $(this).parents("tr").find("input[name='item_id']").val(); + var item_description = $(this).val(); + $.ajax({ + url: "", + method: 'post', + data: $.extend(csrf_form_base(), + { + "item_id" : item_id, + "item_description" : item_description, + }), + dataType: 'json' + }); + }); + $('#item').focus(); $('#item').blur(function()