From ff79b73e340c6ed6d9e558241aecd423ec1cf841 Mon Sep 17 00:00:00 2001 From: objecttothis Date: Tue, 25 Feb 2020 15:44:49 +0400 Subject: [PATCH 1/9] Implement CHECKBOX attribute type Attribute Configuration view Attributes section of item management view Attributes section of CSV item import --- application/controllers/Attributes.php | 84 +++---- application/controllers/Items.php | 328 +++++++++++++------------ application/models/Attribute.php | 211 ++++++++-------- application/views/attributes/form.php | 14 +- application/views/attributes/item.php | 68 ++--- 5 files changed, 362 insertions(+), 343 deletions(-) diff --git a/application/controllers/Attributes.php b/application/controllers/Attributes.php index 440da8ca9..322af867c 100644 --- a/application/controllers/Attributes.php +++ b/application/controllers/Attributes.php @@ -8,17 +8,17 @@ class Attributes extends Secure_Controller { parent::__construct('attributes'); } - + public function index() { $data['table_headers'] = $this->xss_clean(get_attribute_definition_manage_table_headers()); - + $this->load->view('attributes/manage', $data); } - + /* - Returns customer table data rows. This will be called with AJAX. - */ + Returns customer table data rows. This will be called with AJAX. + */ public function search() { $search = $this->input->get('search'); @@ -26,48 +26,48 @@ class Attributes extends Secure_Controller $offset = $this->input->get('offset'); $sort = $this->input->get('sort'); $order = $this->input->get('order'); - + $attributes = $this->Attribute->search($search, $limit, $offset, $sort, $order); $total_rows = $this->Attribute->get_found_rows($search); - + $data_rows = array(); foreach($attributes->result() as $attribute) { $attribute->definition_flags = $this->_get_attributes($attribute->definition_flags); $data_rows[] = get_attribute_definition_data_row($attribute, $this); } - + $data_rows = $this->xss_clean($data_rows); - + echo json_encode(array('total' => $total_rows, 'rows' => $data_rows)); } - + public function save_attribute_value($attribute_value) { - $success = $this->Attribute->save_value(urldecode($attribute_value), $this->input->post('definition_id'), $this->input->post('item_id'), $this->input->post('attribute_id')); - + $success = $this->Attribute->save_value(urldecode($attribute_value), $this->input->post('definition_id'), $this->input->post('item_id'), $this->input->post('attribute_id')); + echo json_encode(array('success' => $success != 0)); } - + public function delete_attribute_value($attribute_value) { $success = $this->Attribute->delete_value($attribute_value, $this->input->post('definition_id')); - + echo json_encode(array('success' => $success)); } - + public function save_definition($definition_id = -1) { - + $definition_flags = 0; - + $flags = (empty($this->input->post('definition_flags'))) ? array() : $this->input->post('definition_flags'); - + foreach($flags as $flag) { $definition_flags |= $flag; } - + //Save definition data $definition_data = array( 'definition_name' => $this->input->post('definition_name'), @@ -75,57 +75,59 @@ class Attributes extends Secure_Controller 'definition_flags' => $definition_flags, 'definition_fk' => $this->input->post('definition_group') != '' ? $this->input->post('definition_group') : NULL ); - + if ($this->input->post('definition_type') != null) { $definition_data['definition_type'] = DEFINITION_TYPES[$this->input->post('definition_type')]; } - + $definition_name = $this->xss_clean($definition_data['definition_name']); - + if($this->Attribute->save_definition($definition_data, $definition_id)) { //New definition if($definition_id == -1) { $definition_values = json_decode($this->input->post('definition_values')); - + foreach($definition_values as $definition_value) { $this->Attribute->save_value($definition_value, $definition_data['definition_id']); } - + echo json_encode(array('success' => TRUE, 'message' => $this->lang->line('attributes_definition_successful_adding').' '. - $definition_name, 'id' => $definition_data['definition_id'])); + $definition_name, 'id' => $definition_data['definition_id'])); } - else //Existing definition + //Existing definition + else { echo json_encode(array('success' => TRUE, 'message' => $this->lang->line('attributes_definition_successful_updating').' '. - $definition_name, 'id' => $definition_id)); + $definition_name, 'id' => $definition_id)); } } - else//failure + //Failure + else { echo json_encode(array('success' => FALSE, 'message' => $this->lang->line('attributes_definition_error_adding_updating', $definition_name), 'id' => -1)); } } - + public function suggest_attribute($definition_id) { $suggestions = $this->xss_clean($this->Attribute->get_suggestions($definition_id, $this->input->get('term'))); - + echo json_encode($suggestions); } - + public function get_row($row_id) { $attribute_definition_info = $this->Attribute->get_info($row_id); $attribute_definition_info->definition_flags = $this->_get_attributes($attribute_definition_info->definition_flags); $data_row = $this->xss_clean(get_attribute_definition_data_row($attribute_definition_info)); - + echo json_encode($data_row); } - + private function _get_attributes($definition_flags = 0) { $definition_flag_names = array(); @@ -138,7 +140,7 @@ class Attributes extends Secure_Controller } return $definition_flag_names; } - + public function view($definition_id = -1) { $info = $this->Attribute->get_info($definition_id); @@ -146,30 +148,30 @@ class Attributes extends Secure_Controller { $info->$property = $this->xss_clean($value); } - + $data['definition_id'] = $definition_id; $data['definition_values'] = $this->Attribute->get_definition_values($definition_id); $data['definition_group'] = $this->Attribute->get_definitions_by_type(GROUP, $definition_id); $data['definition_group'][''] = $this->lang->line('common_none_selected_text'); $data['definition_info'] = $info; - + $show_all = Attribute::SHOW_IN_ITEMS | Attribute::SHOW_IN_RECEIVINGS | Attribute::SHOW_IN_SALES; $data['definition_flags'] = $this->_get_attributes($show_all); $selected_flags = $info->definition_flags === '' ? $show_all : $info->definition_flags; $data['selected_definition_flags'] = $this->_get_attributes($selected_flags); - + $this->load->view("attributes/form", $data); } - + public function delete_value($attribute_id) { return $this->Attribute->delete_value($attribute_id); } - + public function delete() { $attributes_to_delete = $this->input->post('ids'); - + if($this->Attribute->delete_definition_list($attributes_to_delete)) { $message = $this->lang->line('attributes_definition_successful_deleted') . ' ' . count($attributes_to_delete) . ' ' . $this->lang->line('attributes_definition_one_or_multiple'); @@ -180,5 +182,5 @@ class Attributes extends Secure_Controller echo json_encode(array('success' => FALSE, 'message' => $this->lang->line('attributes_definition_cannot_be_deleted'))); } } - + } diff --git a/application/controllers/Items.php b/application/controllers/Items.php index d5ca2d2cc..e55ed851a 100644 --- a/application/controllers/Items.php +++ b/application/controllers/Items.php @@ -7,19 +7,19 @@ class Items extends Secure_Controller public function __construct() { parent::__construct('items'); - + $this->load->library('item_lib'); } - + 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()); $data['stock_locations'] = $this->xss_clean($this->Stock_location->get_allowed_locations()); - + // filters that will be loaded in the multiselect dropdown $data['filters'] = array('empty_upc' => $this->lang->line('items_empty_upc_items'), 'low_inventory' => $this->lang->line('items_low_inventory_items'), @@ -28,10 +28,10 @@ class Items extends Secure_Controller 'search_custom' => $this->lang->line('items_search_attributes'), 'is_deleted' => $this->lang->line('items_is_deleted'), 'temporary' => $this->lang->line('items_temp')); - + $this->load->view('items/manage', $data); } - + /* Returns Items table data rows. This will be called with AJAX. */ @@ -42,11 +42,11 @@ class Items extends Secure_Controller $offset = $this->input->get('offset'); $sort = $this->input->get('sort'); $order = $this->input->get('order'); - + $this->item_lib->set_item_location($this->input->get('stock_location')); - + $definition_names = $this->Attribute->get_definitions_by_flags(Attribute::SHOW_IN_ITEMS); - + $filters = array('start_date' => $this->input->get('start_date'), 'end_date' => $this->input->get('end_date'), 'stock_location_id' => $this->item_lib->get_item_location(), @@ -58,15 +58,15 @@ class Items extends Secure_Controller 'is_deleted' => FALSE, 'temporary' => FALSE, 'definition_ids' => array_keys($definition_names)); - + // check if any filter is set in the multiselect dropdown $filledup = array_fill_keys($this->input->get('filters'), TRUE); $filters = array_merge($filters, $filledup); - + $items = $this->Item->search($search, $filters, $limit, $offset, $sort, $order); - + $total_rows = $this->Item->get_found_rows($search, $filters); - + $data_rows = array(); foreach($items->result() as $item) { @@ -76,19 +76,19 @@ class Items extends Secure_Controller $this->_update_pic_filename($item); } } - + echo json_encode(array('total' => $total_rows, 'rows' => $data_rows)); } - + public function pic_thumb($pic_filename) { $this->load->helper('file'); $this->load->library('image_lib'); - + // in this context, $pic_filename always has .ext $ext = pathinfo($pic_filename, PATHINFO_EXTENSION); $images = glob('./uploads/item_pics/' . $pic_filename); - + // make sure we pick only the file name, without extension $base_path = './uploads/item_pics/' . pathinfo($pic_filename, PATHINFO_FILENAME); if(sizeof($images) > 0) @@ -111,7 +111,7 @@ class Items extends Secure_Controller $this->output->set_output(file_get_contents($thumb_path)); } } - + /* Gives search suggestions based on what is being searched for */ @@ -119,75 +119,75 @@ class Items extends Secure_Controller { $suggestions = $this->xss_clean($this->Item->get_search_suggestions($this->input->post_get('term'), array('search_custom' => $this->input->post('search_custom'), 'is_deleted' => $this->input->post('is_deleted') != NULL), FALSE)); - + echo json_encode($suggestions); } - + public function suggest() { $suggestions = $this->xss_clean($this->Item->get_search_suggestions($this->input->post_get('term'), array('search_custom' => FALSE, 'is_deleted' => FALSE), TRUE)); - + echo json_encode($suggestions); } - - + + public function suggest_low_sell() { $suggestions = $this->xss_clean($this->Item->get_low_sell_suggestions($this->input->post_get('name'))); - + echo json_encode($suggestions); } - - + + public function suggest_kits() { $suggestions = $this->xss_clean($this->Item->get_kit_search_suggestions($this->input->post_get('term'), array('search_custom' => FALSE, 'is_deleted' => FALSE), TRUE)); - + echo json_encode($suggestions); } - + /* Gives search suggestions based on what is being searched for */ public function suggest_category() { $suggestions = $this->xss_clean($this->Item->get_category_suggestions($this->input->get('term'))); - + echo json_encode($suggestions); } - + /* Gives search suggestions based on what is being searched for */ public function suggest_location() { $suggestions = $this->xss_clean($this->Item->get_location_suggestions($this->input->get('term'))); - + echo json_encode($suggestions); } - + public function get_row($item_ids) { $item_infos = $this->Item->get_multiple_info(explode(":", $item_ids), $this->item_lib->get_item_location()); - + $result = array(); foreach($item_infos->result() as $item_info) { $result[$item_info->item_id] = $this->xss_clean(get_item_data_row($item_info)); } - + echo json_encode($result); } - + public function view($item_id = -1) { if($item_id == -1) { $data = array(); } - + // 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)); @@ -196,19 +196,19 @@ class Items extends Secure_Controller $data['item_kit_disabled'] = !$this->Employee->has_grant('item_kits', $this->Employee->get_logged_in_employee_info()->person_id); $data['definition_values'] = $this->Attribute->get_attributes_by_item($item_id); $data['definition_names'] = $this->Attribute->get_definition_names(); - + foreach($data['definition_values'] as $definition_id => $definition) { unset($data['definition_names'][$definition_id]); } - + $item_info = $this->Item->get_info($item_id); - + foreach(get_object_vars($item_info) as $property => $value) { $item_info->$property = $this->xss_clean($value); } - + if($data['allow_temp_item'] == 1) { if($item_id != -1) @@ -226,15 +226,15 @@ class Items extends Secure_Controller $data['allow_temp_item'] = 1; } } - + $use_destination_based_tax = (boolean)$this->config->item('use_destination_based_tax'); $data['include_hsn'] = $this->config->item('include_hsn') == '1'; - + if($item_id == -1) { $data['default_tax_1_rate'] = $this->config->item('default_tax_1_rate'); $data['default_tax_2_rate'] = $this->config->item('default_tax_2_rate'); - + $item_info->receiving_quantity = 1; $item_info->reorder_level = 1; $item_info->item_type = ITEM; // standard @@ -249,13 +249,13 @@ class Items extends Secure_Controller $item_info->tax_category_id = $this->config->item('default_tax_category'); } } - + $data['standard_item_locked'] = ($data['item_kit_disabled'] && $item_info->item_type == ITEM_KIT - && !$data['allow_temp_item'] - && !($this->config->item('derive_sale_quantity') == '1')); - + && !$data['allow_temp_item'] + && !($this->config->item('derive_sale_quantity') == '1')); + $data['item_info'] = $item_info; - + $suppliers = array('' => $this->lang->line('items_none')); foreach($this->Supplier->get_all()->result_array() as $row) { @@ -263,7 +263,7 @@ class Items extends Secure_Controller } $data['suppliers'] = $suppliers; $data['selected_supplier'] = $item_info->supplier_id; - + if($data['include_hsn']) { $data['hsn_code'] = $item_info->hsn_code; @@ -272,7 +272,7 @@ class Items extends Secure_Controller { $data['hsn_code'] = ''; } - + if($use_destination_based_tax) { $data['use_destination_based_tax'] = TRUE; @@ -297,7 +297,7 @@ class Items extends Secure_Controller $data['tax_categories'] = array(); $data['tax_category'] = ''; } - + $data['logo_exists'] = $item_info->pic_filename != ''; $ext = pathinfo($item_info->pic_filename, PATHINFO_EXTENSION); if($ext == '') @@ -315,15 +315,15 @@ class Items extends Secure_Controller foreach($stock_locations as $location) { $location = $this->xss_clean($location); - + $quantity = $this->xss_clean($this->Item_quantity->get_item_quantity($item_id, $location['location_id'])->quantity); $quantity = ($item_id == -1) ? 0 : $quantity; $location_array[$location['location_id']] = array('location_name' => $location['location_name'], 'quantity' => $quantity); $data['stock_locations'] = $location_array; } - + $data['selected_low_sell_item_id'] = $item_info->low_sell_item_id; - + if($item_id != -1 && $item_info->item_id != $item_info->low_sell_item_id) { $low_sell_item_info = $this->Item->get_info($item_info->low_sell_item_id); @@ -333,10 +333,10 @@ class Items extends Secure_Controller { $data['selected_low_sell_item'] = ''; } - + $this->load->view('items/form', $data); } - + public function inventory($item_id = -1) { $item_info = $this->Item->get_info($item_id); @@ -345,21 +345,21 @@ class Items extends Secure_Controller $item_info->$property = $this->xss_clean($value); } $data['item_info'] = $item_info; - + $data['stock_locations'] = array(); $stock_locations = $this->Stock_location->get_undeleted_all()->result_array(); foreach($stock_locations as $location) { $location = $this->xss_clean($location); $quantity = $this->xss_clean($this->Item_quantity->get_item_quantity($item_id, $location['location_id'])->quantity); - + $data['stock_locations'][$location['location_id']] = $location['location_name']; $data['item_quantities'][$location['location_id']] = $quantity; } - + $this->load->view('items/form_inventory', $data); } - + public function count_details($item_id = -1) { $item_info = $this->Item->get_info($item_id); @@ -368,62 +368,62 @@ class Items extends Secure_Controller $item_info->$property = $this->xss_clean($value); } $data['item_info'] = $item_info; - + $data['stock_locations'] = array(); $stock_locations = $this->Stock_location->get_undeleted_all()->result_array(); foreach($stock_locations as $location) { $location = $this->xss_clean($location); $quantity = $this->xss_clean($this->Item_quantity->get_item_quantity($item_id, $location['location_id'])->quantity); - + $data['stock_locations'][$location['location_id']] = $location['location_name']; $data['item_quantities'][$location['location_id']] = $quantity; } - + $this->load->view('items/form_count_details', $data); } - + public function generate_barcodes($item_ids) { $this->load->library('barcode_lib'); - + $item_ids = explode(':', $item_ids); $result = $this->Item->get_multiple_info($item_ids, $this->item_lib->get_item_location())->result_array(); $config = $this->barcode_lib->get_barcode_config(); - + $data['barcode_config'] = $config; - + // check the list of items to see if any item_number field is empty foreach($result as &$item) { $item = $this->xss_clean($item); - + // update the barcode field if empty / NULL with the newly generated barcode if(empty($item['item_number']) && $this->config->item('barcode_generate_if_empty')) { // get the newly generated barcode $barcode_instance = Barcode_lib::barcode_instance($item, $config); $item['item_number'] = $barcode_instance->getData(); - + $save_item = array('item_number' => $item['item_number']); - + // update the item in the database in order to save the barcode field $this->Item->save($save_item, $item['item_id']); } } $data['items'] = $result; - + // display barcodes $this->load->view('barcodes/barcode_sheet', $data); } - + public function attributes($item_id) { $data['item_id'] = $item_id; $definition_ids = json_decode($this->input->post('definition_ids'), TRUE); $data['definition_values'] = $this->Attribute->get_attributes_by_item($item_id) + $this->Attribute->get_values_by_definitions($definition_ids); $data['definition_names'] = $this->Attribute->get_definition_names(); - + foreach($data['definition_values'] as $definition_id => $definition_value) { $attribute_value = $this->Attribute->get_attribute_value($item_id, $definition_id); @@ -432,32 +432,32 @@ class Items extends Secure_Controller $values['attribute_id'] = $attribute_id; $values['attribute_value'] = $attribute_value; $values['selected_value'] = ''; - + if ($definition_value['definition_type'] == DROPDOWN) { $values['values'] = $this->Attribute->get_definition_values($definition_id); $link_value = $this->Attribute->get_link_value($item_id, $definition_id); $values['selected_value'] = (empty($link_value)) ? '' : $link_value->attribute_id; } - + if (!empty($definition_ids[$definition_id])) { $values['selected_value'] = $definition_ids[$definition_id]; } - + unset($data['definition_names'][$definition_id]); } - + $this->load->view('attributes/item', $data); } - + public function bulk_edit() { $suppliers = array('' => $this->lang->line('items_none')); foreach($this->Supplier->get_all()->result_array() as $row) { $row = $this->xss_clean($row); - + $suppliers[$row['person_id']] = $row['company_name']; } $data['suppliers'] = $suppliers; @@ -465,29 +465,29 @@ class Items extends Secure_Controller '' => $this->lang->line('items_do_nothing'), 1 => $this->lang->line('items_change_all_to_allow_alt_desc'), 0 => $this->lang->line('items_change_all_to_not_allow_allow_desc')); - + $data['serialization_choices'] = array( '' => $this->lang->line('items_do_nothing'), 1 => $this->lang->line('items_change_all_to_serialized'), 0 => $this->lang->line('items_change_all_to_unserialized')); - + $this->load->view('items/form_bulk', $data); } - + public function save($item_id = -1) { $upload_success = $this->_handle_image_upload(); $upload_data = $this->upload->data(); - + $receiving_quantity = parse_quantity($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'; } $default_pack_name = $this->lang->line('items_default_pack_name'); - + //Save item data $item_data = array( 'name' => $this->input->post('name'), @@ -509,14 +509,14 @@ class Items extends Secure_Controller 'deleted' => $this->input->post('is_deleted') != NULL, 'hsn_code' => $this->input->post('hsn_code') == NULL ? '' : $this->input->post('hsn_code') ); - + 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)) { @@ -526,7 +526,7 @@ class Items extends Secure_Controller { $item_data['tax_category_id'] = $this->input->post('tax_category_id') == '' ? NULL : $this->input->post('tax_category_id'); } - + if(!empty($upload_data['orig_name'])) { // XSS file image sanity check @@ -535,9 +535,9 @@ class Items extends Secure_Controller $item_data['pic_filename'] = $upload_data['raw_name']; } } - + $employee_id = $this->Employee->get_logged_in_employee_info()->person_id; - + if($this->Item->save($item_data, $item_id)) { $success = TRUE; @@ -548,9 +548,9 @@ class Items extends Secure_Controller $item_id = $item_data['item_id']; $new_item = TRUE; } - + $use_destination_based_tax = (boolean)$this->config->item('use_destination_based_tax'); - + if(!$use_destination_based_tax) { $items_taxes_data = array(); @@ -567,7 +567,7 @@ class Items extends Secure_Controller } $success &= $this->Item_taxes->save($items_taxes_data, $item_id); } - + //Save item quantity $stock_locations = $this->Stock_location->get_undeleted_all()->result_array(); foreach($stock_locations as $location) @@ -580,13 +580,13 @@ class Items extends Secure_Controller $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) { $success &= $this->Item_quantity->save($location_detail, $item_id, $location['location_id']); - + $inv_data = array( 'trans_date' => date('Y-m-d H:i:s'), 'trans_items' => $item_id, @@ -595,11 +595,11 @@ class Items extends Secure_Controller 'trans_comment' => $this->lang->line('items_manually_editing_of_quantity'), 'trans_inventory' => $updated_quantity - $item_quantity->quantity ); - + $success &= $this->Inventory->insert($inv_data); } } - + // Save item attributes $attribute_links = $this->input->post('attribute_links') != NULL ? $this->input->post('attribute_links') : array(); $attribute_ids = $this->input->post('attribute_ids'); @@ -613,34 +613,34 @@ class Items extends Secure_Controller } $this->Attribute->save_link($item_id, $definition_id, $attribute_id); } - + if($success && $upload_success) { $message = $this->xss_clean($this->lang->line('items_successful_' . ($new_item ? 'adding' : 'updating')) . ' ' . $item_data['name']); - + echo json_encode(array('success' => TRUE, 'message' => $message, 'id' => $item_id)); } else { $message = $this->xss_clean($upload_success ? $this->lang->line('items_error_adding_updating') . ' ' . $item_data['name'] : strip_tags($this->upload->display_errors())); - + echo json_encode(array('success' => FALSE, 'message' => $message, 'id' => $item_id)); } } else // failure { $message = $this->xss_clean($this->lang->line('items_error_adding_updating') . ' ' . $item_data['name']); - + echo json_encode(array('success' => FALSE, 'message' => $message, 'id' => -1)); } } - + public function check_item_number() { $exists = $this->Item->item_number_exists($this->input->post('item_number'), $this->input->post('item_id')); echo !$exists ? 'true' : 'false'; } - + /* If adding a new item check to see if an item kit with the same name as the item already exists. */ @@ -656,11 +656,11 @@ class Items extends Secure_Controller } echo !$exists ? 'true' : 'false'; } - + private function _handle_image_upload() { /* Let files be uploaded with their original name */ - + // load upload library $config = array('upload_path' => './uploads/item_pics/', 'allowed_types' => 'gif|jpg|png', @@ -670,18 +670,18 @@ class Items extends Secure_Controller ); $this->load->library('upload', $config); $this->upload->do_upload('item_image'); - + return strlen($this->upload->display_errors()) == 0 || !strcmp($this->upload->display_errors(), '

'.$this->lang->line('upload_no_file_selected').'

'); } - + public function remove_logo($item_id) { $item_data = array('pic_filename' => NULL); $result = $this->Item->save($item_data, $item_id); - + echo json_encode(array('success' => $result)); } - + public function save_inventory($item_id = -1) { $employee_id = $this->Employee->get_logged_in_employee_info()->person_id; @@ -695,9 +695,9 @@ class Items extends Secure_Controller 'trans_comment' => $this->input->post('trans_comment'), 'trans_inventory' => parse_quantity($this->input->post('newquantity')) ); - + $this->Inventory->insert($inv_data); - + //Update stock quantity $item_quantity = $this->Item_quantity->get_item_quantity($item_id, $location_id); $item_quantity_data = array( @@ -705,26 +705,26 @@ class Items extends Secure_Controller 'location_id' => $location_id, 'quantity' => $item_quantity->quantity + parse_quantity($this->input->post('newquantity')) ); - + if($this->Item_quantity->save($item_quantity_data, $item_id, $location_id)) { $message = $this->xss_clean($this->lang->line('items_successful_updating') . ' ' . $cur_item_info->name); - + echo json_encode(array('success' => TRUE, 'message' => $message, 'id' => $item_id)); } else//failure { $message = $this->xss_clean($this->lang->line('items_error_adding_updating') . ' ' . $cur_item_info->name); - + echo json_encode(array('success' => FALSE, 'message' => $message, 'id' => -1)); } } - + public function bulk_update() { $items_to_update = $this->input->post('item_ids'); $item_data = array(); - + foreach($_POST as $key => $value) { //This field is nullable, so treat it differently @@ -737,7 +737,7 @@ class Items extends Secure_Controller $item_data["$key"] = $value; } } - + //Item data could be empty if tax information is being updated if(empty($item_data) || $this->Item->update_multiple($item_data, $items_to_update)) { @@ -751,16 +751,16 @@ class Items extends Secure_Controller if(!empty($tax_names[$k]) && is_numeric($tax_percents[$k])) { $tax_updated = TRUE; - + $items_taxes_data[] = array('name' => $tax_names[$k], 'percent' => $tax_percents[$k]); } } - + if($tax_updated) { $this->Item_taxes->save_multiple($items_taxes_data, $items_to_update); } - + echo json_encode(array('success' => TRUE, 'message' => $this->lang->line('items_successful_bulk_edit'), 'id' => $this->xss_clean($items_to_update))); } else @@ -768,11 +768,11 @@ class Items extends Secure_Controller echo json_encode(array('success' => FALSE, 'message' => $this->lang->line('items_error_updating_multiple'))); } } - + public function delete() { $items_to_delete = $this->input->post('ids'); - + if($this->Item->delete_list($items_to_delete)) { $message = $this->lang->line('items_successful_deleted') . ' ' . count($items_to_delete) . ' ' . $this->lang->line('items_one_or_multiple'); @@ -783,7 +783,7 @@ class Items extends Secure_Controller echo json_encode(array('success' => FALSE, 'message' => $this->lang->line('items_cannot_be_deleted'))); } } - + /* Items import from csv spreadsheet */ @@ -795,12 +795,12 @@ class Items extends Secure_Controller $data = generate_import_items_csv($allowed_locations,$allowed_attributes); force_download($name, $data, TRUE); } - + public function csv_import() { $this->load->view('items/form_csv_import', NULL); } - + /** * Imports items from CSV formatted file. */ @@ -817,13 +817,13 @@ class Items extends Secure_Controller $line_array = get_csv_file($_FILES['file_path']['tmp_name']); $failCodes = array(); $keys = $line_array[0]; - + $this->db->trans_begin(); for($i = 1; $i < count($line_array); $i++) { $invalidated = FALSE; $line = array_combine($keys,$this->xss_clean($line_array[$i])); //Build a XSS-cleaned associative array with the row to use to assign values - + if(!empty($line)) { $item_data = array( @@ -839,15 +839,15 @@ class Items extends Secure_Controller 'hsn_code' => $line['HSN'], 'pic_filename' => $line['item_image'] ); - + $item_number = $line['Barcode']; - + if($item_number != '') { $item_data['item_number'] = $item_number; $invalidated = $this->Item->item_number_exists($item_number); } - + //Sanity check of data if(!$invalidated) { @@ -858,7 +858,7 @@ class Items extends Secure_Controller { $invalidated = TRUE; } - + //Save to database if(!$invalidated && $this->Item->save($item_data)) { @@ -873,7 +873,7 @@ class Items extends Secure_Controller log_message("ERROR","CSV Item import failed on line ". $failed_row .". This item was not imported."); } } - + if(count($failCodes) > 0) { $message = $this->lang->line('items_csv_import_partially_failed', count($failCodes), implode(', ', $failCodes)); @@ -892,9 +892,9 @@ class Items extends Secure_Controller } } } - + /** - * Checks the entire line of data for errors + * Checks the entire line of data in an import file for errors * * @param array $line * @param array $item_data @@ -910,13 +910,13 @@ class Items extends Secure_Controller $item_data['cost_price'], $item_data['unit_price'] ); - + if(in_array('',$check_for_empty,true)) { log_message("ERROR","Empty required value"); return TRUE; //Return fail on empty required fields } - + //Build array of fields to check for numerics $check_for_numeric_values = array( $item_data['cost_price'], @@ -926,15 +926,15 @@ class Items extends Secure_Controller $line['Tax 1 Percent'], $line['Tax 2 Percent'] ); - + //Add in Stock Location values to check for numeric $allowed_locations = $this->Stock_location->get_allowed_locations(); - + foreach($allowed_locations as $location_id => $location_name) { $check_for_numeric_values[] = $line['location_'. $location_name]; } - + //Check for non-numeric values which require numeric foreach($check_for_numeric_values as $value) { @@ -944,10 +944,10 @@ class Items extends Secure_Controller return TRUE; } } - + //Check Attribute Data $definition_names = $this->Attribute->get_definition_names(); - + foreach($definition_names as $definition_name) { if(!empty($line['attribute_' . $definition_name])) @@ -955,12 +955,12 @@ class Items extends Secure_Controller $attribute_data = $this->Attribute->get_definition_by_name($definition_name)[0]; $attribute_type = $attribute_data['definition_type']; $attribute_value = $line['attribute_' . $definition_name]; - + if($attribute_type == 'DROPDOWN') { $dropdown_values = $this->Attribute->get_definition_values($attribute_data['definition_id']); $dropdown_values[] = ''; - + if(in_array($attribute_value, $dropdown_values) === FALSE) { log_message("ERROR","Value: '$attribute_value' is not an acceptable DROPDOWN value"); @@ -985,11 +985,13 @@ class Items extends Secure_Controller } } } - + return FALSE; } - + //TODO: Figure out if I need to have line 1003 be isset or empty. If zero is a possible answer, then empty will return false negatives. /** + * Saves attribute data found in the CSV import. + * * @param line * @param failCodes * @param attribute_data @@ -997,15 +999,15 @@ class Items extends Secure_Controller private function save_attribute_data($line, $item_data) { $definition_names = $this->Attribute->get_definition_names(); - + foreach($definition_names as $definition_name) { - if(!empty($line['attribute_' . $definition_name])) + if(!isset($line['attribute_' . $definition_name])) { //Create attribute value $attribute_data = $this->Attribute->get_definition_by_name($definition_name)[0]; $status = $this->Attribute->save_value($line['attribute_' . $definition_name], $attribute_data['definition_id'], $item_data['item_id'], FALSE, $attribute_data['definition_type']); - + if($status === FALSE) { return FALSE; @@ -1013,7 +1015,7 @@ class Items extends Secure_Controller } } } - + /** * Saves inventory quantities for the row in the appropriate stock locations. * @@ -1027,26 +1029,26 @@ class Items extends Secure_Controller $emp_info = $this->Employee->get_info($employee_id); $comment = $this->lang->line('items_inventory_CSV_import_quantity'); $allowed_locations = $this->Stock_location->get_allowed_locations(); - + foreach($allowed_locations as $location_id => $location_name) { $item_quantity_data = array( 'item_id' => $item_data['item_id'], 'location_id' => $location_id ); - + $csv_data = array( 'trans_items' => $item_data['item_id'], 'trans_user' => $employee_id, 'trans_comment' => $comment, 'trans_location' => $location_id, ); - + if(!empty($line['location_' . $location_name])) { $item_quantity_data['quantity'] = $line['location_' . $location_name]; $this->Item_quantity->save($item_quantity_data, $item_data['item_id'], $location_id); - + $csv_data['trans_inventory'] = $line['location_' . $location_name]; $this->Inventory->insert($csv_data); } @@ -1054,13 +1056,13 @@ class Items extends Secure_Controller { $item_quantity_data['quantity'] = 0; $this->Item_quantity->save($item_quantity_data, $item_data['item_id'], $line[$col]); - + $csv_data['trans_inventory'] = 0; $this->Inventory->insert($csv_data); } } } - + /** * Saves the tax data found in the line of the CSV items import file * @@ -1069,24 +1071,24 @@ class Items extends Secure_Controller private function save_tax_data($line, $item_data) { $items_taxes_data = array(); - + if(is_numeric($line['Tax 1 Percent']) && $line['Tax 1 Name'] != '') { $items_taxes_data[] = array('name' => $line['Tax 1 Name'], 'percent' => $line['Tax 1 Percent'] ); } - + if(is_numeric($line['Tax 2 Percent']) && $line['Tax 2 Name'] != '') { $items_taxes_data[] = array('name' => $line['Tax 2 Name'], 'percent' => $line['Tax 2 Percent'] ); } - + if(count($items_taxes_data) > 0) { $this->Item_taxes->save($items_taxes_data, $item_data['item_id']); } } - - + + /** * Guess whether file extension is not in the table field, if it isn't, then it's an old-format (formerly pic_id) field, so we guess the right filename and update the table * @@ -1095,7 +1097,7 @@ class Items extends Secure_Controller private function _update_pic_filename($item) { $filename = pathinfo($item->pic_filename, PATHINFO_FILENAME); - + // if the field is empty there's nothing to check if(!empty($filename)) { diff --git a/application/models/Attribute.php b/application/models/Attribute.php index cc595b9a1..651f4b045 100644 --- a/application/models/Attribute.php +++ b/application/models/Attribute.php @@ -5,8 +5,9 @@ define('DROPDOWN', 'DROPDOWN'); define('DECIMAL', 'DECIMAL'); define('DATE', 'DATE'); define('TEXT', 'TEXT'); +define('CHECKBOX', 'CHECKBOX'); -const DEFINITION_TYPES = [GROUP, DROPDOWN, DECIMAL, TEXT, DATE]; +const DEFINITION_TYPES = [GROUP, DROPDOWN, DECIMAL, TEXT, DATE, CHECKBOX]; /** * Attribute class @@ -17,14 +18,14 @@ class Attribute extends CI_Model const SHOW_IN_ITEMS = 1; const SHOW_IN_SALES = 2; const SHOW_IN_RECEIVINGS = 4; - + public static function get_definition_flags() { $class = new ReflectionClass(__CLASS__); - + return array_flip($class->getConstants()); } - + /* Determines if a given definition_id is an attribute */ @@ -33,10 +34,10 @@ class Attribute extends CI_Model $this->db->from('attribute_definitions'); $this->db->where('definition_id', $definition_id); $this->db->where('deleted', $deleted); - + return ($this->db->get()->num_rows() == 1); } - + public function link_exists($item_id, $definition_id = FALSE) { $this->db->where('sale_id'); @@ -50,13 +51,13 @@ class Attribute extends CI_Model else { $this->db->where('definition_id', $definition_id); - + } $this->db->where('item_id', $item_id); - + return ($this->db->get()->num_rows() > 0); } - + /* Determines if a given attribute_value exists in the attribute_values table and returns the attribute_id if it does */ @@ -65,7 +66,7 @@ class Attribute extends CI_Model $this->db->distinct('attribute_id'); $this->db->from('attribute_values'); $this->db->where('attribute_value', $attribute_value); - + $query = $this->db->get(); if ($query->num_rows() > 0) { @@ -73,7 +74,7 @@ class Attribute extends CI_Model } return FALSE; } - + /* Gets information about a particular attribute definition */ @@ -83,9 +84,9 @@ class Attribute extends CI_Model $this->db->from('attribute_definitions AS definition'); $this->db->join('attribute_definitions AS parent_definition', 'parent_definition.definition_id = definition.definition_fk', 'left'); $this->db->where('definition.definition_id', $definition_id); - + $query = $this->db->get(); - + if($query->num_rows() == 1) { return $query->row(); @@ -94,17 +95,17 @@ class Attribute extends CI_Model { //Get empty base parent object, as $item_id is NOT an item $item_obj = new stdClass(); - + //Get all the fields from items table foreach($this->db->list_fields('attribute_definitions') as $field) { $item_obj->$field = ''; } - + return $item_obj; } } - + /* Performs a search on attribute definitions */ @@ -113,22 +114,22 @@ class Attribute extends CI_Model $this->db->select('parent_definition.definition_name AS definition_group, definition.*'); $this->db->from('attribute_definitions AS definition'); $this->db->join('attribute_definitions AS parent_definition', 'parent_definition.definition_id = definition.definition_fk', 'left'); - + $this->db->group_start(); $this->db->like('definition.definition_name', $search); $this->db->or_like('definition.definition_type', $search); $this->db->group_end(); $this->db->where('definition.deleted', 0); $this->db->order_by($sort, $order); - + if($rows > 0) { $this->db->limit($rows, $limit_from); } - + return $this->db->get(); } - + public function get_attributes_by_item($item_id) { $this->db->from('attribute_definitions'); @@ -137,51 +138,51 @@ class Attribute extends CI_Model $this->db->where('receiving_id'); $this->db->where('sale_id'); $this->db->where('deleted', 0); - + $results = $this->db->get()->result_array(); - + return $this->_to_array($results, 'definition_id'); } - + public function get_values_by_definitions($definition_ids) { if(count($definition_ids ? : [])) { $this->db->from('attribute_definitions'); - + $this->db->group_start(); $this->db->where_in('definition_fk', array_keys($definition_ids)); $this->db->or_where_in('definition_id', array_keys($definition_ids)); $this->db->where('definition_type !=', GROUP); $this->db->group_end(); - + $this->db->where('deleted', 0); - + $results = $this->db->get()->result_array(); - + return $this->_to_array($results, 'definition_id'); } - + return array(); } - + public function get_definitions_by_type($attribute_type, $definition_id = -1) { $this->db->from('attribute_definitions'); $this->db->where('definition_type', $attribute_type); $this->db->where('deleted', 0); - + if($definition_id != -1) { $this->db->where('definition_id != ', $definition_id); } - + $this->db->where('definition_fk'); $results = $this->db->get()->result_array(); - + return $this->_to_array($results, 'definition_id', 'definition_name'); } - + public function get_definitions_by_flags($definition_flags) { $this->db->from('attribute_definitions'); @@ -190,11 +191,11 @@ class Attribute extends CI_Model $this->db->where('definition_type <>', GROUP); $this->db->order_by('definition_id'); $results = $this->db->get()->result_array(); - + return $this->_to_array($results, 'definition_id', 'definition_name'); } - - + + /** * Returns an array of attribute definition names and IDs * @@ -205,45 +206,45 @@ class Attribute extends CI_Model { $this->db->from('attribute_definitions'); $this->db->where('deleted', 0); - + if($groups === FALSE) { $this->db->where_not_in('definition_type',GROUP); } - + $results = $this->db->get()->result_array(); - + $definition_name = array(-1 => $this->lang->line('common_none_selected_text')); - + return $definition_name + $this->_to_array($results, 'definition_id', 'definition_name'); } - + public function get_definition_values($definition_id) { $attribute_values = []; - + if($definition_id > -1) { $this->db->from('attribute_links'); $this->db->join('attribute_values', 'attribute_values.attribute_id = attribute_links.attribute_id'); $this->db->where('definition_id', $definition_id); $this->db->where('item_id'); - + $results = $this->db->get()->result_array(); - + return $this->_to_array($results, 'attribute_id', 'attribute_value'); } - + return $attribute_values; } - + private function _to_array($results, $key, $value = '') { return array_column(array_map(function($result) use ($key, $value) { return [$result[$key], empty($value) ? $result : $result[$value]]; }, $results), 1, 0); } - + /* Gets total of rows */ @@ -251,10 +252,10 @@ class Attribute extends CI_Model { $this->db->from('attribute_definitions'); $this->db->where('deleted', 0); - + return $this->db->count_all_results(); } - + /* Get number of rows */ @@ -262,11 +263,11 @@ class Attribute extends CI_Model { return $this->search($search)->num_rows(); } - + private function check_data_validity($definition, $from, $to) { $success = FALSE; - + if($from === TEXT) { $this->db->select('item_id,attribute_value'); @@ -274,7 +275,7 @@ class Attribute extends CI_Model $this->db->join('attribute_links', 'attribute_values.attribute_id = attribute_links.attribute_id'); $this->db->where('definition_id',$definition); $success = TRUE; - + if($to === DATE) { foreach($this->db->get()->result_array() as $row) @@ -300,22 +301,22 @@ class Attribute extends CI_Model } return $success; } - + private function convert_definition_type($definition_id, $from_type, $to_type) { $success = FALSE; - + //From TEXT to DATETIME if($from_type === TEXT) { - if($to_type === DATE || $to_type === DECIMAL) + if(in_array($to_type, [DATE, DECIMAL], TRUE)) { $field = ($to_type === DATE ? 'attribute_date' : 'attribute_decimal'); - + if($this->check_data_validity($definition_id, $from_type, $to_type)) { $this->db->trans_start(); - + $query = 'UPDATE ospos_attribute_values '; $query .= 'INNER JOIN ospos_attribute_links '; $query .= 'ON ospos_attribute_values.attribute_id = ospos_attribute_links.attribute_id '; @@ -323,39 +324,39 @@ class Attribute extends CI_Model $query .= 'attribute_value = NULL '; $query .= 'WHERE definition_id = ' . $this->db->escape($definition_id); $success = $this->db->query($query); - + $this->db->trans_complete(); } } - else if($to_type === DROPDOWN) + else if(in_array($to_type, [DROPDOWN, CHECKBOX], TRUE)) { $success = TRUE; } } - + //From DROPDOWN to TEXT else if($from_type === DROPDOWN) { //From DROPDOWN to TEXT $this->db->trans_start(); - + $this->db->from('ospos_attribute_links'); $this->db->where('definition_id',$definition_id); $this->db->where('item_id', NULL); $success = $this->db->delete(); - + $this->db->trans_complete(); } - + //Any other allowed conversion does not get checked here else { $success = TRUE; } - + return $success; } - + /* Inserts or updates a definition */ @@ -363,26 +364,26 @@ class Attribute extends CI_Model { //Run these queries as a transaction, we want to make sure we do all or nothing $this->db->trans_start(); - + //Definition doesn't exist if($definition_id === -1 || !$this->exists($definition_id)) { $success = $this->db->insert('attribute_definitions', $definition_data); $definition_data['definition_id'] = $this->db->insert_id(); } - + //Definition already exists else { $this->db->select('definition_type, definition_name'); $this->db->from('attribute_definitions'); $this->db->where('definition_id', $definition_id); - + $row = $this->db->get()->row(); $from_definition_type = $row->definition_type; $from_definition_name = $row->definition_name; $to_definition_type = $definition_data['definition_type']; - + if($from_definition_type !== $to_definition_type) { if(!$this->convert_definition_type($definition_id,$from_definition_type,$to_definition_type)) @@ -390,19 +391,19 @@ class Attribute extends CI_Model return FALSE; } } - + $this->db->where('definition_id', $definition_id); $success = $this->db->update('attribute_definitions', $definition_data); $definition_data['definition_id'] = $definition_id; } - + $this->db->trans_complete(); - + $success &= $this->db->trans_status(); - + return $success; } - + public function get_definition_by_name($definition_name, $definition_type = FALSE) { $this->db->from('attribute_definitions'); @@ -411,14 +412,14 @@ class Attribute extends CI_Model { $this->db->where('definition_type', $definition_type); } - + return $this->db->get()->result_array(); } - + public function save_link($item_id, $definition_id, $attribute_id) { $this->db->trans_start(); - + if($this->link_exists($item_id, $definition_id)) { $this->db->where('definition_id', $definition_id); @@ -431,30 +432,30 @@ class Attribute extends CI_Model { $this->db->insert('attribute_links', array('attribute_id' => $attribute_id, 'item_id' => $item_id, 'definition_id' => $definition_id)); } - + $this->db->trans_complete(); - + return $this->db->trans_status(); } - + public function delete_link($item_id) { $this->db->where('sale_id'); $this->db->where('receiving_id'); - + return $this->db->delete('attribute_links', array('item_id' => $item_id)); } - + public function get_link_value($item_id, $definition_id) { $this->db->where('item_id', $item_id); $this->db->where('definition_id', $definition_id); $this->db->where('sale_id'); $this->db->where('receiving_id'); - + return $this->db->get('attribute_links')->row_object(); } - + public function get_link_values($item_id, $sale_receiving_fk, $id, $definition_flags) { $format = $this->db->escape(dateformat_mysql()); @@ -465,7 +466,7 @@ class Attribute extends CI_Model $this->db->join('attribute_definitions', 'attribute_definitions.definition_id = attribute_links.definition_id'); $this->db->where('definition_type <>', GROUP); $this->db->where('deleted', 0); - + if(!empty($id)) { $this->db->where($sale_receiving_fk, $id); @@ -477,10 +478,10 @@ class Attribute extends CI_Model } $this->db->where('item_id', (int) $item_id); $this->db->where('definition_flags & ', $definition_flags); - + return $this->db->get(); } - + public function get_attribute_value($item_id, $definition_id) { $this->db->from('attribute_values'); @@ -489,10 +490,10 @@ class Attribute extends CI_Model $this->db->where('sale_id'); $this->db->where('receiving_id'); $this->db->where('item_id', (int) $item_id); - + return $this->db->get()->row_object(); } - + public function copy_attribute_links($item_id, $sale_receiving_fk, $id) { $this->db->query( @@ -502,7 +503,7 @@ class Attribute extends CI_Model WHERE item_id = ' . $this->db->escape($item_id) . ' AND sale_id IS NULL AND receiving_id IS NULL' ); } - + public function get_suggestions($definition_id, $term) { $suggestions = array(); @@ -520,20 +521,22 @@ class Attribute extends CI_Model $row_array = (array) $row; $suggestions[] = array('value' => $row_array['attribute_id'], 'label' => $row_array['attribute_value']); } - + return $suggestions; } - + public function save_value($attribute_value, $definition_id, $item_id = FALSE, $attribute_id = FALSE, $definition_type = DROPDOWN) { + //TODO: Right now when you uncheck the checkbox type it should be sending 0 but that's being interpreted funny and erasing the attribute_link altogether for that item. $this->db->trans_start(); - + + //New Attribute if(empty($attribute_id) || empty($item_id)) { - if($definition_type == TEXT || $definition_type == DROPDOWN) + if(in_array($definition_type, [TEXT, DROPDOWN, CHECKBOX], TRUE)) { $attribute_id = $this->value_exists($attribute_value); - + if(empty($attribute_id)) { $this->db->insert('attribute_values', array('attribute_value' => $attribute_value)); @@ -547,7 +550,7 @@ class Attribute extends CI_Model { $this->db->insert('attribute_values', array('attribute_date' => date('Y-m-d', strtotime($attribute_value)))); } - + $attribute_id = $attribute_id ? $attribute_id : $this->db->insert_id(); $this->db->insert('attribute_links', array( @@ -555,23 +558,25 @@ class Attribute extends CI_Model 'item_id' => empty($item_id) ? NULL : $item_id, 'definition_id' => $definition_id)); } + + //Existing Attribute else { $this->db->where('attribute_id', $attribute_id); $this->db->update('attribute_values', array('attribute_value' => $attribute_value)); } - + $this->db->trans_complete(); - + return $attribute_id; } - + public function delete_value($attribute_value, $definition_id) { return $this->db->query("DELETE atrv, atrl FROM " . $this->db->dbprefix('attribute_values') . " atrv, " . $this->db->dbprefix('attribute_links') . " atrl " . "WHERE atrl.attribute_id = atrv.attribute_id AND atrv.attribute_value = " . $this->db->escape($attribute_value) . " AND atrl.definition_id = " . $this->db->escape($definition_id)); } - + /** * Deletes an Attribute definition from the database and associated column in the items_import.csv * @@ -581,14 +586,14 @@ class Attribute extends CI_Model public function delete_definition($definition_id) { $this->db->where('definition_id', $definition_id); - + return $this->db->update('attribute_definitions', array('deleted' => 1)); } - + public function delete_definition_list($definition_ids) { $this->db->where_in('definition_id', $definition_ids); - + return $this->db->update('attribute_definitions', array('deleted' => 1)); } } diff --git a/application/views/attributes/form.php b/application/views/attributes/form.php index bbd7fc4b9..349048ce8 100644 --- a/application/views/attributes/form.php +++ b/application/views/attributes/form.php @@ -6,7 +6,7 @@
- lang->line('attributes_definition_name'), 'definition_name', array('class' => 'control-label col-xs-3')); ?> + lang->line('attributes_definition_name'), 'definition_name', array('class'=>'required control-label col-xs-3')); ?>
'definition_name', @@ -17,7 +17,7 @@
- lang->line('attributes_definition_type'), 'definition_type', array('class'=>'control-label col-xs-3')); ?> + lang->line('attributes_definition_type'), 'definition_type', array('class'=>'required control-label col-xs-3')); ?>
definition_type, DEFINITION_TYPES), 'id="definition_type" class="form-control"');?>
@@ -83,10 +83,10 @@ $(document).ready(function() var definition_type = $("#definition_type option:selected").text(); if(definition_type == "DATE" || (definition_type == "GROUP" && !is_new) || definition_type == "DECIMAL") - { - $('#definition_type').prop("disabled",true); - } - else if(definition_type == "DROPDOWN") + { + $('#definition_type').prop("disabled",true); + } + else if(definition_type == "DROPDOWN" || definition_type == "CHECKBOX") { $("#definition_type option:contains('GROUP')").hide(); $("#definition_type option:contains('DATE')").hide(); @@ -98,7 +98,7 @@ $(document).ready(function() } } disable_definition_types(); - + var show_hide_fields = function(event) { var is_dropdown = $('#definition_type').val() !== '1'; diff --git a/application/views/attributes/item.php b/application/views/attributes/item.php index 581741808..12f60e4c9 100644 --- a/application/views/attributes/item.php +++ b/application/views/attributes/item.php @@ -16,37 +16,47 @@ foreach($definition_values as $definition_id => $definition_value) 'control-label col-xs-3')); ?>
- attribute_date)) ? NOW : strtotime($attribute_value->attribute_date); - echo form_input(array( - 'name' => "attribute_links[$definition_id]", - 'value' => to_date($value), - 'class' => 'form-control input-sm datetime', - 'data-definition-id' => $definition_id, - 'readonly' => 'true')); - } - else if ($definition_value['definition_type'] == DROPDOWN) - { - $selected_value = $definition_value['selected_value']; - echo form_dropdown("attribute_links[$definition_id]", $definition_value['values'], $selected_value, "class='form-control' data-definition-id='$definition_id'"); - } - else if ($definition_value['definition_type'] == TEXT) - { - $value = (empty($attribute_value) || empty($attribute_value->attribute_value)) ? $definition_value['selected_value'] : $attribute_value->attribute_value; - echo form_input("attribute_links[$definition_id]", $value, "class='form-control valid_chars' data-definition-id='$definition_id'"); - } - else if ($definition_value['definition_type'] == DECIMAL) - { - $value = (empty($attribute_value) || empty($attribute_value->attribute_decimal)) ? $definition_value['selected_value'] : $attribute_value->attribute_decimal; - echo form_input("attribute_links[$definition_id]", $value, "class='form-control valid_chars' data-definition-id='$definition_id'"); - } + if ($definition_value['definition_type'] == DATE) + { + $value = (empty($attribute_value) || empty($attribute_value->attribute_date)) ? NOW : strtotime($attribute_value->attribute_date); + echo form_input(array( + 'name' => "attribute_links[$definition_id]", + 'value' => to_date($value), + 'class' => 'form-control input-sm datetime', + 'data-definition-id' => $definition_id, + 'readonly' => 'true')); + } + else if ($definition_value['definition_type'] == DROPDOWN) + { + $selected_value = $definition_value['selected_value']; + echo form_dropdown("attribute_links[$definition_id]", $definition_value['values'], $selected_value, "class='form-control' data-definition-id='$definition_id'"); + } + else if ($definition_value['definition_type'] == TEXT) + { + $value = (empty($attribute_value) || empty($attribute_value->attribute_value)) ? $definition_value['selected_value'] : $attribute_value->attribute_value; + echo form_input("attribute_links[$definition_id]", $value, "class='form-control valid_chars' data-definition-id='$definition_id'"); + } + else if ($definition_value['definition_type'] == DECIMAL) + { + $value = (empty($attribute_value) || empty($attribute_value->attribute_decimal)) ? $definition_value['selected_value'] : $attribute_value->attribute_decimal; + echo form_input("attribute_links[$definition_id]", $value, "class='form-control valid_chars' data-definition-id='$definition_id'"); + } + else if ($definition_value['definition_type'] == CHECKBOX) + { + $value = (empty($attribute_value) || empty($attribute_value->attribute_value)) ? $definition_value['selected_value'] : $attribute_value->attribute_value; + echo form_checkbox(array( + 'name' => "attribute_links[$definition_id]", + 'id' => "attribute_links[$definition_id]", + 'value' => 1, + 'checked' => ($value ? 1 : 0), + 'class' => 'checkbox-inline', + 'data-definition-id' => $definition_id + )); + } ?>
From d7a59221fcf053388a813b59132790d731b5aa12 Mon Sep 17 00:00:00 2001 From: objecttothis Date: Thu, 27 Feb 2020 12:24:04 +0400 Subject: [PATCH 2/9] Fix problem with unchecked attributes Previously, if the attribute was unchecked, the form wouldn't submit the attribute and the model/controller would delete the attribute_link from the item. A hidden input type with value 0 occuring before the checkbox fixes this problem. --- application/views/attributes/item.php | 11 ++++++++++- 1 file changed, 10 insertions(+), 1 deletion(-) diff --git a/application/views/attributes/item.php b/application/views/attributes/item.php index 12f60e4c9..5d3d41b9a 100644 --- a/application/views/attributes/item.php +++ b/application/views/attributes/item.php @@ -48,6 +48,15 @@ foreach($definition_values as $definition_id => $definition_value) else if ($definition_value['definition_type'] == CHECKBOX) { $value = (empty($attribute_value) || empty($attribute_value->attribute_value)) ? $definition_value['selected_value'] : $attribute_value->attribute_value; + + //Sends 0 if the box is unchecked instead of not sending anything. + echo form_input(array( + 'type' => 'hidden', + 'name' => "attribute_links[$definition_id]", + 'id' => "attribute_links[$definition_id]", + 'value' => 0, + 'data-definition-id' => $definition_id + )); echo form_checkbox(array( 'name' => "attribute_links[$definition_id]", 'id' => "attribute_links[$definition_id]", @@ -68,7 +77,7 @@ foreach($definition_values as $definition_id => $definition_value) ?> + \ No newline at end of file From c4c475b51f9e9590176b37a213b8bb787aad7de0 Mon Sep 17 00:00:00 2001 From: objecttothis Date: Wed, 18 Mar 2020 15:49:49 +0400 Subject: [PATCH 4/9] Updated CSV import to handle checkboxes 0, FALSE values create attributes marked as "unchecked" NULL, "" and spaces do not create an attribute 1, TRUE and ANY other value creates an attribute and marks as checked. Blank lines in CSV files are skipped with no error. --- application/controllers/Items.php | 111 +++++++++++++--------- application/helpers/importfile_helper.php | 6 +- 2 files changed, 71 insertions(+), 46 deletions(-) diff --git a/application/controllers/Items.php b/application/controllers/Items.php index f31f8bafb..4904040ae 100644 --- a/application/controllers/Items.php +++ b/application/controllers/Items.php @@ -822,41 +822,35 @@ class Items extends Secure_Controller for($i = 1; $i < count($line_array); $i++) { $invalidated = FALSE; - $line = array_combine($keys,$this->xss_clean($line_array[$i])); //Build a XSS-cleaned associative array with the row to use to assign values - if(!empty($line)) + $line = array_combine($keys,$this->xss_clean($line_array[$i])); //Build a XSS-cleaned associative array with the row to use to assign values + + $item_data = array( + 'name' => $line['Item Name'], + 'description' => $line['Description'], + 'category' => $line['Category'], + 'cost_price' => $line['Cost Price'], + 'unit_price' => $line['Unit Price'], + 'reorder_level' => $line['Reorder Level'], + 'supplier_id' => $this->Supplier->exists($line['Supplier ID']) ? $line['Supplier ID'] : NULL, + 'allow_alt_description' => empty($line['Allow Alt Description'])? '0' : '1', + 'is_serialized' => empty($line['Item has Serial Number'])? '0' : '1', + 'hsn_code' => $line['HSN'], + 'pic_filename' => $line['item_image'] + ); + + $item_number = $line['Barcode']; + + if(!empty($item_number)) { - $item_data = array( - 'name' => $line['Item Name'], - 'description' => $line['Description'], - 'category' => $line['Category'], - 'cost_price' => $line['Cost Price'], - 'unit_price' => $line['Unit Price'], - 'reorder_level' => $line['Reorder Level'], - 'supplier_id' => $this->Supplier->exists($line['Supplier ID']) ? $line['Supplier ID'] : NULL, - 'allow_alt_description' => $line['Allow Alt Description'] != '' ? '1' : '0', - 'is_serialized' => $line['Item has Serial Number'] != '' ? '1' : '0', - 'hsn_code' => $line['HSN'], - 'pic_filename' => $line['item_image'] - ); - - $item_number = $line['Barcode']; - - if($item_number != '') - { - $item_data['item_number'] = $item_number; - $invalidated = $this->Item->item_number_exists($item_number); - } - - //Sanity check of data - if(!$invalidated) - { - $invalidated = $this->data_error_check($line, $item_data); - } + $item_data['item_number'] = $item_number; + $invalidated = $this->Item->item_number_exists($item_number); } - else + + //Sanity check of data + if(!$invalidated) { - $invalidated = TRUE; + $invalidated = $this->data_error_check($line, $item_data); } //Save to database @@ -866,7 +860,8 @@ class Items extends Secure_Controller $this->save_inventory_quantities($line, $item_data); $this->save_attribute_data($line, $item_data); } - else //insert or update item failure + //Insert or update item failure + else { $failed_row = $i+1; $failCodes[] = $failed_row; @@ -907,16 +902,20 @@ class Items extends Secure_Controller $check_for_empty = array( $item_data['name'], $item_data['category'], - $item_data['cost_price'], $item_data['unit_price'] ); - if(in_array('',$check_for_empty,true)) + foreach($check_for_empty as $key => $val) { - log_message("ERROR","Empty required value"); - return TRUE; //Return fail on empty required fields + if (empty($val)) + { + log_message("ERROR","Empty required value"); + return TRUE; //Return fail on empty required fields + } } + $item_data['cost_price'] = empty($item_data['cost_price']) ? 0 : 1; //Allow for zero wholesale price + //Build array of fields to check for numerics $check_for_numeric_values = array( $item_data['cost_price'], @@ -947,6 +946,7 @@ class Items extends Secure_Controller //Check Attribute Data $definition_names = $this->Attribute->get_definition_names(); + unset($definition_names[-1]); foreach($definition_names as $definition_name) { @@ -961,7 +961,7 @@ class Items extends Secure_Controller $dropdown_values = $this->Attribute->get_definition_values($attribute_data['definition_id']); $dropdown_values[] = ''; - if(in_array($attribute_value, $dropdown_values) === FALSE) + if(in_array($attribute_value, $dropdown_values) === FALSE && !empty($attribute_value)) { log_message("ERROR","Value: '$attribute_value' is not an acceptable DROPDOWN value"); return TRUE; @@ -969,17 +969,17 @@ class Items extends Secure_Controller } else if($attribute_type == 'DECIMAL') { - if(!is_numeric($attribute_value) && $attribute_value != '') + if(!is_numeric($attribute_value) && !empty($attribute_value)) { - log_message("ERROR","Decimal required: '$attribute_value' is not an acceptable DECIMAL value"); + log_message("ERROR","'$attribute_value' is not an acceptable DECIMAL value"); return TRUE; } } else if($attribute_type == 'DATETIME') { - if(strtotime($attribute_value) === FALSE) + if(strtotime($attribute_value) === FALSE && !empty($attribute_value)) { - log_message("ERROR","Datetime required: '$attribute_value' is not an acceptable DATETIME value"); + log_message("ERROR","'$attribute_value' is not an acceptable DATETIME value."); return TRUE; } } @@ -988,7 +988,7 @@ class Items extends Secure_Controller return FALSE; } - //TODO: Figure out if I need to have line 1003 be isset or empty. If zero is a possible answer, then empty will return false negatives. + /** * Saves attribute data found in the CSV import. * @@ -999,14 +999,35 @@ class Items extends Secure_Controller private function save_attribute_data($line, $item_data) { $definition_names = $this->Attribute->get_definition_names(); + unset($definition_names[-1]); foreach($definition_names as $definition_name) { - if(!isset($line['attribute_' . $definition_name])) + //Create attribute value + if(!empty($line['attribute_' . $definition_name]) || $line['attribute_' . $definition_name] == '0') { - //Create attribute value $attribute_data = $this->Attribute->get_definition_by_name($definition_name)[0]; - $status = $this->Attribute->save_value($line['attribute_' . $definition_name], $attribute_data['definition_id'], $item_data['item_id'], FALSE, $attribute_data['definition_type']); + + //CHECKBOX Attribute types (zero value creates attribute and marks it as unchecked) + if($attribute_data['definition_type'] == 'CHECKBOX') + { + //FALSE and '0' value creates checkbox and marks it as unchecked. + if(strcasecmp($line['attribute_' . $definition_name],'FALSE') == 0 || $line['attribute_' . $definition_name] == '0') + { + $line['attribute_' . $definition_name] = '0'; + } + else + { + $line['attribute_' . $definition_name] = '1'; + } + + $status = $this->Attribute->save_value($line['attribute_' . $definition_name], $attribute_data['definition_id'], $item_data['item_id'], FALSE, $attribute_data['definition_type']); + } + //All other Attribute types (0 value means attribute not created) + elseif(!empty($line['attribute_' . $definition_name])) + { + $status = $this->Attribute->save_value($line['attribute_' . $definition_name], $attribute_data['definition_id'], $item_data['item_id'], FALSE, $attribute_data['definition_type']); + } if($status === FALSE) { diff --git a/application/helpers/importfile_helper.php b/application/helpers/importfile_helper.php index ff2dd878e..ad5411e6c 100644 --- a/application/helpers/importfile_helper.php +++ b/application/helpers/importfile_helper.php @@ -70,7 +70,11 @@ function get_csv_file($file_name) while (($data = fgetcsv($csv_file)) !== FALSE) { - $line_array[] = $data; + //Skip empty lines + if(array(null) !== $data) + { + $line_array[] = $data; + } } } else From 971ae5ec199729ffbb24044873ffe78b074c7d02 Mon Sep 17 00:00:00 2001 From: objecttothis Date: Tue, 24 Mar 2020 13:18:35 +0400 Subject: [PATCH 5/9] Correcting indentation problems --- application/controllers/Attributes.php | 74 +++++++++++++------------- 1 file changed, 36 insertions(+), 38 deletions(-) diff --git a/application/controllers/Attributes.php b/application/controllers/Attributes.php index f190c5c3e..b07abbd1f 100644 --- a/application/controllers/Attributes.php +++ b/application/controllers/Attributes.php @@ -8,14 +8,14 @@ class Attributes extends Secure_Controller { parent::__construct('attributes'); } - + public function index() { $data['table_headers'] = $this->xss_clean(get_attribute_definition_manage_table_headers()); - + $this->load->view('attributes/manage', $data); } - + /* Returns customer table data rows. This will be called with AJAX. */ @@ -26,108 +26,107 @@ class Attributes extends Secure_Controller $offset = $this->input->get('offset'); $sort = $this->input->get('sort'); $order = $this->input->get('order'); - + $attributes = $this->Attribute->search($search, $limit, $offset, $sort, $order); $total_rows = $this->Attribute->get_found_rows($search); - + $data_rows = array(); foreach($attributes->result() as $attribute) { $attribute->definition_flags = $this->_get_attributes($attribute->definition_flags); $data_rows[] = get_attribute_definition_data_row($attribute, $this); } - + $data_rows = $this->xss_clean($data_rows); - + echo json_encode(array('total' => $total_rows, 'rows' => $data_rows)); } - + public function save_attribute_value($attribute_value) { $success = $this->Attribute->save_value(urldecode($attribute_value), $this->input->post('definition_id'), $this->input->post('item_id'), $this->input->post('attribute_id')); - + echo json_encode(array('success' => $success != 0)); } - + public function delete_attribute_value($attribute_value) { $success = $this->Attribute->delete_value($attribute_value, $this->input->post('definition_id')); - + echo json_encode(array('success' => $success)); } - + public function save_definition($definition_id = -1) { - $definition_flags = 0; - + $flags = (empty($this->input->post('definition_flags'))) ? array() : $this->input->post('definition_flags'); - + foreach($flags as $flag) { $definition_flags |= $flag; } - - //Save definition data + + //Save definition data $definition_data = array( 'definition_name' => $this->input->post('definition_name'), 'definition_unit' => $this->input->post('definition_unit') != '' ? $this->input->post('definition_unit') : NULL, 'definition_flags' => $definition_flags, 'definition_fk' => $this->input->post('definition_group') != '' ? $this->input->post('definition_group') : NULL ); - + if ($this->input->post('definition_type') != null) { $definition_data['definition_type'] = DEFINITION_TYPES[$this->input->post('definition_type')]; } - + $definition_name = $this->xss_clean($definition_data['definition_name']); - + if($this->Attribute->save_definition($definition_data, $definition_id)) { - //New definition + //New definition if($definition_id == -1) { $definition_values = json_decode($this->input->post('definition_values')); - + foreach($definition_values as $definition_value) { $this->Attribute->save_value($definition_value, $definition_data['definition_id']); } - + echo json_encode(array('success' => TRUE, 'message' => $this->lang->line('attributes_definition_successful_adding').' '. $definition_name, 'id' => $definition_data['definition_id'])); } - //Existing definition + //Existing definition else { echo json_encode(array('success' => TRUE, 'message' => $this->lang->line('attributes_definition_successful_updating').' '. $definition_name, 'id' => $definition_id)); } } - //Failure + //Failure else { echo json_encode(array('success' => FALSE, 'message' => $this->lang->line('attributes_definition_error_adding_updating', $definition_name), 'id' => -1)); } } - + public function suggest_attribute($definition_id) { $suggestions = $this->xss_clean($this->Attribute->get_suggestions($definition_id, $this->input->get('term'))); - + echo json_encode($suggestions); } - + public function get_row($row_id) { $attribute_definition_info = $this->Attribute->get_info($row_id); $attribute_definition_info->definition_flags = $this->_get_attributes($attribute_definition_info->definition_flags); $data_row = $this->xss_clean(get_attribute_definition_data_row($attribute_definition_info)); - + echo json_encode($data_row); } - + private function _get_attributes($definition_flags = 0) { $definition_flag_names = array(); @@ -140,7 +139,7 @@ class Attributes extends Secure_Controller } return $definition_flag_names; } - + public function view($definition_id = -1) { $info = $this->Attribute->get_info($definition_id); @@ -148,30 +147,30 @@ class Attributes extends Secure_Controller { $info->$property = $this->xss_clean($value); } - + $data['definition_id'] = $definition_id; $data['definition_values'] = $this->Attribute->get_definition_values($definition_id); $data['definition_group'] = $this->Attribute->get_definitions_by_type(GROUP, $definition_id); $data['definition_group'][''] = $this->lang->line('common_none_selected_text'); $data['definition_info'] = $info; - + $show_all = Attribute::SHOW_IN_ITEMS | Attribute::SHOW_IN_RECEIVINGS | Attribute::SHOW_IN_SALES; $data['definition_flags'] = $this->_get_attributes($show_all); $selected_flags = $info->definition_flags === '' ? $show_all : $info->definition_flags; $data['selected_definition_flags'] = $this->_get_attributes($selected_flags); - + $this->load->view("attributes/form", $data); } - + public function delete_value($attribute_id) { return $this->Attribute->delete_value($attribute_id); } - + public function delete() { $attributes_to_delete = $this->input->post('ids'); - + if($this->Attribute->delete_definition_list($attributes_to_delete)) { $message = $this->lang->line('attributes_definition_successful_deleted') . ' ' . count($attributes_to_delete) . ' ' . $this->lang->line('attributes_definition_one_or_multiple'); @@ -182,5 +181,4 @@ class Attributes extends Secure_Controller echo json_encode(array('success' => FALSE, 'message' => $this->lang->line('attributes_definition_cannot_be_deleted'))); } } - } \ No newline at end of file From 3281fc9bb0bee678a2b20a20a26419d81f03c136 Mon Sep 17 00:00:00 2001 From: objecttothis Date: Tue, 24 Mar 2020 14:04:04 +0400 Subject: [PATCH 6/9] Correct indentation problems --- application/controllers/Items.php | 410 +++++++++++----------- application/helpers/importfile_helper.php | 20 +- application/models/Attribute.php | 249 ++++++------- application/views/attributes/form.php | 4 +- application/views/attributes/item.php | 194 +++++----- 5 files changed, 442 insertions(+), 435 deletions(-) diff --git a/application/controllers/Items.php b/application/controllers/Items.php index 4904040ae..a51afc4d2 100644 --- a/application/controllers/Items.php +++ b/application/controllers/Items.php @@ -10,17 +10,16 @@ class Items extends Secure_Controller $this->load->library('item_lib'); } - + 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()); $data['stock_locations'] = $this->xss_clean($this->Stock_location->get_allowed_locations()); - - // filters that will be loaded in the multiselect dropdown + + //Filters that will be loaded in the multiselect dropdown $data['filters'] = array('empty_upc' => $this->lang->line('items_empty_upc_items'), 'low_inventory' => $this->lang->line('items_low_inventory_items'), 'is_serialized' => $this->lang->line('items_serialized_items'), @@ -28,10 +27,10 @@ class Items extends Secure_Controller 'search_custom' => $this->lang->line('items_search_attributes'), 'is_deleted' => $this->lang->line('items_is_deleted'), 'temporary' => $this->lang->line('items_temp')); - + $this->load->view('items/manage', $data); } - + /* Returns Items table data rows. This will be called with AJAX. */ @@ -42,11 +41,11 @@ class Items extends Secure_Controller $offset = $this->input->get('offset'); $sort = $this->input->get('sort'); $order = $this->input->get('order'); - + $this->item_lib->set_item_location($this->input->get('stock_location')); - + $definition_names = $this->Attribute->get_definitions_by_flags(Attribute::SHOW_IN_ITEMS); - + $filters = array('start_date' => $this->input->get('start_date'), 'end_date' => $this->input->get('end_date'), 'stock_location_id' => $this->item_lib->get_item_location(), @@ -58,15 +57,15 @@ class Items extends Secure_Controller 'is_deleted' => FALSE, 'temporary' => FALSE, 'definition_ids' => array_keys($definition_names)); - - // check if any filter is set in the multiselect dropdown + + //Check if any filter is set in the multiselect dropdown $filledup = array_fill_keys($this->input->get('filters'), TRUE); $filters = array_merge($filters, $filledup); - + $items = $this->Item->search($search, $filters, $limit, $offset, $sort, $order); - + $total_rows = $this->Item->get_found_rows($search, $filters); - + $data_rows = array(); foreach($items->result() as $item) { @@ -76,25 +75,26 @@ class Items extends Secure_Controller $this->_update_pic_filename($item); } } - + echo json_encode(array('total' => $total_rows, 'rows' => $data_rows)); } - + public function pic_thumb($pic_filename) { $this->load->helper('file'); $this->load->library('image_lib'); - - // in this context, $pic_filename always has .ext + + //In this context, $pic_filename always has .ext $ext = pathinfo($pic_filename, PATHINFO_EXTENSION); $images = glob('./uploads/item_pics/' . $pic_filename); - - // make sure we pick only the file name, without extension + + //Make sure we pick only the file name, without extension $base_path = './uploads/item_pics/' . pathinfo($pic_filename, PATHINFO_FILENAME); if(sizeof($images) > 0) { $image_path = $images[0]; $thumb_path = $base_path . $this->image_lib->thumb_marker . '.' . $ext; + if(sizeof($images) < 2) { $config['image_library'] = 'gd2'; @@ -111,7 +111,7 @@ class Items extends Secure_Controller $this->output->set_output(file_get_contents($thumb_path)); } } - + /* Gives search suggestions based on what is being searched for */ @@ -119,76 +119,74 @@ class Items extends Secure_Controller { $suggestions = $this->xss_clean($this->Item->get_search_suggestions($this->input->post_get('term'), array('search_custom' => $this->input->post('search_custom'), 'is_deleted' => $this->input->post('is_deleted') != NULL), FALSE)); - + echo json_encode($suggestions); } - + public function suggest() { $suggestions = $this->xss_clean($this->Item->get_search_suggestions($this->input->post_get('term'), array('search_custom' => FALSE, 'is_deleted' => FALSE), TRUE)); - + echo json_encode($suggestions); } - - + public function suggest_low_sell() { $suggestions = $this->xss_clean($this->Item->get_low_sell_suggestions($this->input->post_get('name'))); - + echo json_encode($suggestions); } - - + public function suggest_kits() { $suggestions = $this->xss_clean($this->Item->get_kit_search_suggestions($this->input->post_get('term'), array('search_custom' => FALSE, 'is_deleted' => FALSE), TRUE)); - + echo json_encode($suggestions); } - + /* Gives search suggestions based on what is being searched for */ public function suggest_category() { $suggestions = $this->xss_clean($this->Item->get_category_suggestions($this->input->get('term'))); - + echo json_encode($suggestions); } - + /* Gives search suggestions based on what is being searched for */ public function suggest_location() { $suggestions = $this->xss_clean($this->Item->get_location_suggestions($this->input->get('term'))); - + echo json_encode($suggestions); } - + public function get_row($item_ids) { $item_infos = $this->Item->get_multiple_info(explode(":", $item_ids), $this->item_lib->get_item_location()); - + $result = array(); foreach($item_infos->result() as $item_info) { $result[$item_info->item_id] = $this->xss_clean(get_item_data_row($item_info)); } - + echo json_encode($result); } - + public function view($item_id = -1) { if($item_id == -1) { $data = array(); } - - // allow_temp_items is set in the index function of items.php or sales.php + + //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'] = ''; @@ -196,19 +194,19 @@ class Items extends Secure_Controller $data['item_kit_disabled'] = !$this->Employee->has_grant('item_kits', $this->Employee->get_logged_in_employee_info()->person_id); $data['definition_values'] = $this->Attribute->get_attributes_by_item($item_id); $data['definition_names'] = $this->Attribute->get_definition_names(); - + foreach($data['definition_values'] as $definition_id => $definition) { unset($data['definition_names'][$definition_id]); } - + $item_info = $this->Item->get_info($item_id); - + foreach(get_object_vars($item_info) as $property => $value) { $item_info->$property = $this->xss_clean($value); } - + if($data['allow_temp_item'] == 1) { if($item_id != -1) @@ -226,44 +224,47 @@ class Items extends Secure_Controller $data['allow_temp_item'] = 1; } } - + $use_destination_based_tax = (boolean)$this->config->item('use_destination_based_tax'); $data['include_hsn'] = $this->config->item('include_hsn') == '1'; - + if($item_id == -1) { $data['default_tax_1_rate'] = $this->config->item('default_tax_1_rate'); $data['default_tax_2_rate'] = $this->config->item('default_tax_2_rate'); - + $item_info->receiving_quantity = 1; $item_info->reorder_level = 1; - $item_info->item_type = ITEM; // standard + $item_info->item_type = ITEM; //Standard $item_info->item_id = $item_id; $item_info->stock_type = HAS_STOCK; $item_info->tax_category_id = NULL; $item_info->qty_per_pack = 1; $item_info->pack_name = $this->lang->line('items_default_pack_name'); $data['hsn_code'] = ''; + if($use_destination_based_tax) { $item_info->tax_category_id = $this->config->item('default_tax_category'); } } - + $data['standard_item_locked'] = ($data['item_kit_disabled'] && $item_info->item_type == ITEM_KIT && !$data['allow_temp_item'] - && !($this->config->item('derive_sale_quantity') == '1')); - + & !($this->config->item('derive_sale_quantity') == '1')); + $data['item_info'] = $item_info; - + $suppliers = array('' => $this->lang->line('items_none')); + foreach($this->Supplier->get_all()->result_array() as $row) { $suppliers[$this->xss_clean($row['person_id'])] = $this->xss_clean($row['company_name']); } + $data['suppliers'] = $suppliers; $data['selected_supplier'] = $item_info->supplier_id; - + if($data['include_hsn']) { $data['hsn_code'] = $item_info->hsn_code; @@ -272,7 +273,7 @@ class Items extends Secure_Controller { $data['hsn_code'] = ''; } - + if($use_destination_based_tax) { $data['use_destination_based_tax'] = TRUE; @@ -297,33 +298,36 @@ class Items extends Secure_Controller $data['tax_categories'] = array(); $data['tax_category'] = ''; } - + $data['logo_exists'] = $item_info->pic_filename != ''; $ext = pathinfo($item_info->pic_filename, PATHINFO_EXTENSION); + if($ext == '') { - // if file extension is not found guess it (legacy) + //If file extension is not found guess it (legacy) $images = glob('./uploads/item_pics/' . $item_info->pic_filename . '.*'); } else { - // else just pick that file + //Else just pick that file $images = glob('./uploads/item_pics/' . $item_info->pic_filename); } - $data['image_path'] = sizeof($images) > 0 ? base_url($images[0]) : ''; - $stock_locations = $this->Stock_location->get_undeleted_all()->result_array(); + + $data['image_path'] = sizeof($images) > 0 ? base_url($images[0]) : ''; + $stock_locations = $this->Stock_location->get_undeleted_all()->result_array(); + foreach($stock_locations as $location) { $location = $this->xss_clean($location); - + $quantity = $this->xss_clean($this->Item_quantity->get_item_quantity($item_id, $location['location_id'])->quantity); $quantity = ($item_id == -1) ? 0 : $quantity; $location_array[$location['location_id']] = array('location_name' => $location['location_name'], 'quantity' => $quantity); $data['stock_locations'] = $location_array; } - + $data['selected_low_sell_item_id'] = $item_info->low_sell_item_id; - + if($item_id != -1 && $item_info->item_id != $item_info->low_sell_item_id) { $low_sell_item_info = $this->Item->get_info($item_info->low_sell_item_id); @@ -333,10 +337,10 @@ class Items extends Secure_Controller { $data['selected_low_sell_item'] = ''; } - + $this->load->view('items/form', $data); } - + public function inventory($item_id = -1) { $item_info = $this->Item->get_info($item_id); @@ -345,21 +349,21 @@ class Items extends Secure_Controller $item_info->$property = $this->xss_clean($value); } $data['item_info'] = $item_info; - + $data['stock_locations'] = array(); $stock_locations = $this->Stock_location->get_undeleted_all()->result_array(); foreach($stock_locations as $location) { $location = $this->xss_clean($location); $quantity = $this->xss_clean($this->Item_quantity->get_item_quantity($item_id, $location['location_id'])->quantity); - + $data['stock_locations'][$location['location_id']] = $location['location_name']; $data['item_quantities'][$location['location_id']] = $quantity; } - + $this->load->view('items/form_inventory', $data); } - + public function count_details($item_id = -1) { $item_info = $this->Item->get_info($item_id); @@ -368,62 +372,60 @@ class Items extends Secure_Controller $item_info->$property = $this->xss_clean($value); } $data['item_info'] = $item_info; - + $data['stock_locations'] = array(); $stock_locations = $this->Stock_location->get_undeleted_all()->result_array(); foreach($stock_locations as $location) { $location = $this->xss_clean($location); $quantity = $this->xss_clean($this->Item_quantity->get_item_quantity($item_id, $location['location_id'])->quantity); - + $data['stock_locations'][$location['location_id']] = $location['location_name']; $data['item_quantities'][$location['location_id']] = $quantity; } - + $this->load->view('items/form_count_details', $data); } - + public function generate_barcodes($item_ids) { $this->load->library('barcode_lib'); - + $item_ids = explode(':', $item_ids); $result = $this->Item->get_multiple_info($item_ids, $this->item_lib->get_item_location())->result_array(); $config = $this->barcode_lib->get_barcode_config(); - + $data['barcode_config'] = $config; - - // check the list of items to see if any item_number field is empty + + //Check the list of items to see if any item_number field is empty foreach($result as &$item) { $item = $this->xss_clean($item); - - // update the barcode field if empty / NULL with the newly generated barcode + + //Update the barcode field if empty / NULL with the newly generated barcode if(empty($item['item_number']) && $this->config->item('barcode_generate_if_empty')) { - // get the newly generated barcode + // get the newly generated barcode $barcode_instance = Barcode_lib::barcode_instance($item, $config); $item['item_number'] = $barcode_instance->getData(); - + $save_item = array('item_number' => $item['item_number']); - - // update the item in the database in order to save the barcode field - $this->Item->save($save_item, $item['item_id']); + + $this->Item->save($save_item, $item['item_id']); // update the item in the database in order to save the barcode field } } $data['items'] = $result; - - // display barcodes - $this->load->view('barcodes/barcode_sheet', $data); + + $this->load->view('barcodes/barcode_sheet', $data); // display barcodes } - + public function attributes($item_id) { $data['item_id'] = $item_id; $definition_ids = json_decode($this->input->post('definition_ids'), TRUE); $data['definition_values'] = $this->Attribute->get_attributes_by_item($item_id) + $this->Attribute->get_values_by_definitions($definition_ids); $data['definition_names'] = $this->Attribute->get_definition_names(); - + foreach($data['definition_values'] as $definition_id => $definition_value) { $attribute_value = $this->Attribute->get_attribute_value($item_id, $definition_id); @@ -432,22 +434,22 @@ class Items extends Secure_Controller $values['attribute_id'] = $attribute_id; $values['attribute_value'] = $attribute_value; $values['selected_value'] = ''; - + if ($definition_value['definition_type'] == DROPDOWN) { $values['values'] = $this->Attribute->get_definition_values($definition_id); $link_value = $this->Attribute->get_link_value($item_id, $definition_id); $values['selected_value'] = (empty($link_value)) ? '' : $link_value->attribute_id; } - + if (!empty($definition_ids[$definition_id])) { $values['selected_value'] = $definition_ids[$definition_id]; } - + unset($data['definition_names'][$definition_id]); } - + $this->load->view('attributes/item', $data); } @@ -457,7 +459,7 @@ class Items extends Secure_Controller foreach($this->Supplier->get_all()->result_array() as $row) { $row = $this->xss_clean($row); - + $suppliers[$row['person_id']] = $row['company_name']; } $data['suppliers'] = $suppliers; @@ -465,30 +467,30 @@ class Items extends Secure_Controller '' => $this->lang->line('items_do_nothing'), 1 => $this->lang->line('items_change_all_to_allow_alt_desc'), 0 => $this->lang->line('items_change_all_to_not_allow_allow_desc')); - + $data['serialization_choices'] = array( '' => $this->lang->line('items_do_nothing'), 1 => $this->lang->line('items_change_all_to_serialized'), 0 => $this->lang->line('items_change_all_to_unserialized')); - + $this->load->view('items/form_bulk', $data); } - + public function save($item_id = -1) { $upload_success = $this->_handle_image_upload(); $upload_data = $this->upload->data(); - + $receiving_quantity = parse_quantity($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'; } $default_pack_name = $this->lang->line('items_default_pack_name'); - - //Save item data + + //Save item data $item_data = array( 'name' => $this->input->post('name'), 'description' => $this->input->post('description'), @@ -509,15 +511,16 @@ class Items extends Secure_Controller 'deleted' => $this->input->post('is_deleted') != NULL, 'hsn_code' => $this->input->post('hsn_code') == NULL ? '' : $this->input->post('hsn_code') ); - + 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)) { $item_data['tax_category_id'] = ''; @@ -526,31 +529,32 @@ class Items extends Secure_Controller { $item_data['tax_category_id'] = $this->input->post('tax_category_id') == '' ? NULL : $this->input->post('tax_category_id'); } - + if(!empty($upload_data['orig_name'])) { - // XSS file image sanity check + // XSS file image sanity check if($this->xss_clean($upload_data['raw_name'], TRUE) === TRUE) { $item_data['pic_filename'] = $upload_data['raw_name']; } } - + $employee_id = $this->Employee->get_logged_in_employee_info()->person_id; - + if($this->Item->save($item_data, $item_id)) { $success = TRUE; $new_item = FALSE; - //New item + + //New item if($item_id == -1) { $item_id = $item_data['item_id']; $new_item = TRUE; } - + $use_destination_based_tax = (boolean)$this->config->item('use_destination_based_tax'); - + if(!$use_destination_based_tax) { $items_taxes_data = array(); @@ -567,8 +571,8 @@ class Items extends Secure_Controller } $success &= $this->Item_taxes->save($items_taxes_data, $item_id); } - - //Save item quantity + + //Save item quantity $stock_locations = $this->Stock_location->get_undeleted_all()->result_array(); foreach($stock_locations as $location) { @@ -580,13 +584,13 @@ class Items extends Secure_Controller $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) { $success &= $this->Item_quantity->save($location_detail, $item_id, $location['location_id']); - + $inv_data = array( 'trans_date' => date('Y-m-d H:i:s'), 'trans_items' => $item_id, @@ -595,15 +599,16 @@ class Items extends Secure_Controller 'trans_comment' => $this->lang->line('items_manually_editing_of_quantity'), 'trans_inventory' => $updated_quantity - $item_quantity->quantity ); - + $success &= $this->Inventory->insert($inv_data); } } - - // Save item attributes + + // Save item attributes $attribute_links = $this->input->post('attribute_links') != NULL ? $this->input->post('attribute_links') : array(); $attribute_ids = $this->input->post('attribute_ids'); $this->Attribute->delete_link($item_id); + foreach($attribute_links as $definition_id => $attribute_id) { $definition_type = $this->Attribute->get_info($definition_id)->definition_type; @@ -613,34 +618,34 @@ class Items extends Secure_Controller } $this->Attribute->save_link($item_id, $definition_id, $attribute_id); } - + if($success && $upload_success) { $message = $this->xss_clean($this->lang->line('items_successful_' . ($new_item ? 'adding' : 'updating')) . ' ' . $item_data['name']); - + echo json_encode(array('success' => TRUE, 'message' => $message, 'id' => $item_id)); } else { $message = $this->xss_clean($upload_success ? $this->lang->line('items_error_adding_updating') . ' ' . $item_data['name'] : strip_tags($this->upload->display_errors())); - + echo json_encode(array('success' => FALSE, 'message' => $message, 'id' => $item_id)); } } - else // failure + else //Failure { $message = $this->xss_clean($this->lang->line('items_error_adding_updating') . ' ' . $item_data['name']); - + echo json_encode(array('success' => FALSE, 'message' => $message, 'id' => -1)); } } - + public function check_item_number() { $exists = $this->Item->item_number_exists($this->input->post('item_number'), $this->input->post('item_id')); echo !$exists ? 'true' : 'false'; } - + /* If adding a new item check to see if an item kit with the same name as the item already exists. */ @@ -656,32 +661,34 @@ class Items extends Secure_Controller } echo !$exists ? 'true' : 'false'; } - + + /* + * Let files be uploaded with their original name + */ private function _handle_image_upload() { - /* Let files be uploaded with their original name */ - - // load upload library + //Load upload library $config = array('upload_path' => './uploads/item_pics/', 'allowed_types' => 'gif|jpg|png', 'max_size' => '100', 'max_width' => '640', 'max_height' => '480' ); + $this->load->library('upload', $config); $this->upload->do_upload('item_image'); - + return strlen($this->upload->display_errors()) == 0 || !strcmp($this->upload->display_errors(), '

'.$this->lang->line('upload_no_file_selected').'

'); } - + public function remove_logo($item_id) { $item_data = array('pic_filename' => NULL); $result = $this->Item->save($item_data, $item_id); - + echo json_encode(array('success' => $result)); } - + public function save_inventory($item_id = -1) { $employee_id = $this->Employee->get_logged_in_employee_info()->person_id; @@ -695,39 +702,39 @@ class Items extends Secure_Controller 'trans_comment' => $this->input->post('trans_comment'), 'trans_inventory' => parse_quantity($this->input->post('newquantity')) ); - + $this->Inventory->insert($inv_data); - - //Update stock quantity + + //Update stock quantity $item_quantity = $this->Item_quantity->get_item_quantity($item_id, $location_id); $item_quantity_data = array( 'item_id' => $item_id, 'location_id' => $location_id, 'quantity' => $item_quantity->quantity + parse_quantity($this->input->post('newquantity')) ); - + if($this->Item_quantity->save($item_quantity_data, $item_id, $location_id)) { $message = $this->xss_clean($this->lang->line('items_successful_updating') . ' ' . $cur_item_info->name); - + echo json_encode(array('success' => TRUE, 'message' => $message, 'id' => $item_id)); } - else//failure + else //failure { $message = $this->xss_clean($this->lang->line('items_error_adding_updating') . ' ' . $cur_item_info->name); - + echo json_encode(array('success' => FALSE, 'message' => $message, 'id' => -1)); } } - + public function bulk_update() { $items_to_update = $this->input->post('item_ids'); $item_data = array(); - + foreach($_POST as $key => $value) { - //This field is nullable, so treat it differently + //This field is nullable, so treat it differently if($key == 'supplier_id' && $value != '') { $item_data["$key"] = $value; @@ -737,7 +744,7 @@ class Items extends Secure_Controller $item_data["$key"] = $value; } } - + //Item data could be empty if tax information is being updated if(empty($item_data) || $this->Item->update_multiple($item_data, $items_to_update)) { @@ -751,16 +758,16 @@ class Items extends Secure_Controller if(!empty($tax_names[$k]) && is_numeric($tax_percents[$k])) { $tax_updated = TRUE; - + $items_taxes_data[] = array('name' => $tax_names[$k], 'percent' => $tax_percents[$k]); } } - + if($tax_updated) { $this->Item_taxes->save_multiple($items_taxes_data, $items_to_update); } - + echo json_encode(array('success' => TRUE, 'message' => $this->lang->line('items_successful_bulk_edit'), 'id' => $this->xss_clean($items_to_update))); } else @@ -768,11 +775,11 @@ class Items extends Secure_Controller echo json_encode(array('success' => FALSE, 'message' => $this->lang->line('items_error_updating_multiple'))); } } - + public function delete() { $items_to_delete = $this->input->post('ids'); - + if($this->Item->delete_list($items_to_delete)) { $message = $this->lang->line('items_successful_deleted') . ' ' . count($items_to_delete) . ' ' . $this->lang->line('items_one_or_multiple'); @@ -783,7 +790,7 @@ class Items extends Secure_Controller echo json_encode(array('success' => FALSE, 'message' => $this->lang->line('items_cannot_be_deleted'))); } } - + /* Items import from csv spreadsheet */ @@ -795,12 +802,12 @@ class Items extends Secure_Controller $data = generate_import_items_csv($allowed_locations,$allowed_attributes); force_download($name, $data, TRUE); } - + public function csv_import() { $this->load->view('items/form_csv_import', NULL); } - + /** * Imports items from CSV formatted file. */ @@ -817,12 +824,12 @@ class Items extends Secure_Controller $line_array = get_csv_file($_FILES['file_path']['tmp_name']); $failCodes = array(); $keys = $line_array[0]; - + $this->db->trans_begin(); for($i = 1; $i < count($line_array); $i++) { $invalidated = FALSE; - + $line = array_combine($keys,$this->xss_clean($line_array[$i])); //Build a XSS-cleaned associative array with the row to use to assign values $item_data = array( @@ -838,7 +845,7 @@ class Items extends Secure_Controller 'hsn_code' => $line['HSN'], 'pic_filename' => $line['item_image'] ); - + $item_number = $line['Barcode']; if(!empty($item_number)) @@ -846,21 +853,22 @@ class Items extends Secure_Controller $item_data['item_number'] = $item_number; $invalidated = $this->Item->item_number_exists($item_number); } - - //Sanity check of data + + //Sanity check of data if(!$invalidated) { $invalidated = $this->data_error_check($line, $item_data); } - - //Save to database + + //Save to database if(!$invalidated && $this->Item->save($item_data)) { $this->save_tax_data($line, $item_data); $this->save_inventory_quantities($line, $item_data); $this->save_attribute_data($line, $item_data); } - //Insert or update item failure + + //Insert or update item failure else { $failed_row = $i+1; @@ -868,7 +876,7 @@ class Items extends Secure_Controller log_message("ERROR","CSV Item import failed on line ". $failed_row .". This item was not imported."); } } - + if(count($failCodes) > 0) { $message = $this->lang->line('items_csv_import_partially_failed', count($failCodes), implode(', ', $failCodes)); @@ -887,7 +895,7 @@ class Items extends Secure_Controller } } } - + /** * Checks the entire line of data in an import file for errors * @@ -898,13 +906,13 @@ class Items extends Secure_Controller */ private function data_error_check($line, $item_data) { - //Check for empty required fields + //Check for empty required fields $check_for_empty = array( $item_data['name'], $item_data['category'], $item_data['unit_price'] ); - + foreach($check_for_empty as $key => $val) { if (empty($val)) @@ -913,10 +921,10 @@ class Items extends Secure_Controller return TRUE; //Return fail on empty required fields } } - + $item_data['cost_price'] = empty($item_data['cost_price']) ? 0 : 1; //Allow for zero wholesale price - - //Build array of fields to check for numerics + + //Build array of fields to check for numerics $check_for_numeric_values = array( $item_data['cost_price'], $item_data['unit_price'], @@ -925,16 +933,16 @@ class Items extends Secure_Controller $line['Tax 1 Percent'], $line['Tax 2 Percent'] ); - - //Add in Stock Location values to check for numeric + + //Add in Stock Location values to check for numeric $allowed_locations = $this->Stock_location->get_allowed_locations(); - + foreach($allowed_locations as $location_id => $location_name) { $check_for_numeric_values[] = $line['location_'. $location_name]; } - - //Check for non-numeric values which require numeric + + //Check for non-numeric values which require numeric foreach($check_for_numeric_values as $value) { if(!is_numeric($value) && $value != '') @@ -943,11 +951,11 @@ class Items extends Secure_Controller return TRUE; } } - - //Check Attribute Data + + //Check Attribute Data $definition_names = $this->Attribute->get_definition_names(); unset($definition_names[-1]); - + foreach($definition_names as $definition_name) { if(!empty($line['attribute_' . $definition_name])) @@ -955,12 +963,12 @@ class Items extends Secure_Controller $attribute_data = $this->Attribute->get_definition_by_name($definition_name)[0]; $attribute_type = $attribute_data['definition_type']; $attribute_value = $line['attribute_' . $definition_name]; - + if($attribute_type == 'DROPDOWN') { $dropdown_values = $this->Attribute->get_definition_values($attribute_data['definition_id']); $dropdown_values[] = ''; - + if(in_array($attribute_value, $dropdown_values) === FALSE && !empty($attribute_value)) { log_message("ERROR","Value: '$attribute_value' is not an acceptable DROPDOWN value"); @@ -985,10 +993,10 @@ class Items extends Secure_Controller } } } - + return FALSE; } - + /** * Saves attribute data found in the CSV import. * @@ -1000,18 +1008,18 @@ class Items extends Secure_Controller { $definition_names = $this->Attribute->get_definition_names(); unset($definition_names[-1]); - + foreach($definition_names as $definition_name) { - //Create attribute value + //Create attribute value if(!empty($line['attribute_' . $definition_name]) || $line['attribute_' . $definition_name] == '0') { $attribute_data = $this->Attribute->get_definition_by_name($definition_name)[0]; - - //CHECKBOX Attribute types (zero value creates attribute and marks it as unchecked) + + //CHECKBOX Attribute types (zero value creates attribute and marks it as unchecked) if($attribute_data['definition_type'] == 'CHECKBOX') { - //FALSE and '0' value creates checkbox and marks it as unchecked. + //FALSE and '0' value creates checkbox and marks it as unchecked. if(strcasecmp($line['attribute_' . $definition_name],'FALSE') == 0 || $line['attribute_' . $definition_name] == '0') { $line['attribute_' . $definition_name] = '0'; @@ -1020,15 +1028,16 @@ class Items extends Secure_Controller { $line['attribute_' . $definition_name] = '1'; } - + $status = $this->Attribute->save_value($line['attribute_' . $definition_name], $attribute_data['definition_id'], $item_data['item_id'], FALSE, $attribute_data['definition_type']); } - //All other Attribute types (0 value means attribute not created) + + //All other Attribute types (0 value means attribute not created) elseif(!empty($line['attribute_' . $definition_name])) { $status = $this->Attribute->save_value($line['attribute_' . $definition_name], $attribute_data['definition_id'], $item_data['item_id'], FALSE, $attribute_data['definition_type']); } - + if($status === FALSE) { return FALSE; @@ -1036,7 +1045,7 @@ class Items extends Secure_Controller } } } - + /** * Saves inventory quantities for the row in the appropriate stock locations. * @@ -1045,31 +1054,31 @@ class Items extends Secure_Controller */ private function save_inventory_quantities($line, $item_data) { - //Quantities & Inventory Section + //Quantities & Inventory Section $employee_id = $this->Employee->get_logged_in_employee_info()->person_id; $emp_info = $this->Employee->get_info($employee_id); $comment = $this->lang->line('items_inventory_CSV_import_quantity'); $allowed_locations = $this->Stock_location->get_allowed_locations(); - + foreach($allowed_locations as $location_id => $location_name) { $item_quantity_data = array( 'item_id' => $item_data['item_id'], 'location_id' => $location_id ); - + $csv_data = array( 'trans_items' => $item_data['item_id'], 'trans_user' => $employee_id, 'trans_comment' => $comment, 'trans_location' => $location_id, ); - + if(!empty($line['location_' . $location_name])) { $item_quantity_data['quantity'] = $line['location_' . $location_name]; $this->Item_quantity->save($item_quantity_data, $item_data['item_id'], $location_id); - + $csv_data['trans_inventory'] = $line['location_' . $location_name]; $this->Inventory->insert($csv_data); } @@ -1077,13 +1086,13 @@ class Items extends Secure_Controller { $item_quantity_data['quantity'] = 0; $this->Item_quantity->save($item_quantity_data, $item_data['item_id'], $line[$col]); - + $csv_data['trans_inventory'] = 0; $this->Inventory->insert($csv_data); } } } - + /** * Saves the tax data found in the line of the CSV items import file * @@ -1092,24 +1101,23 @@ class Items extends Secure_Controller private function save_tax_data($line, $item_data) { $items_taxes_data = array(); - + if(is_numeric($line['Tax 1 Percent']) && $line['Tax 1 Name'] != '') { $items_taxes_data[] = array('name' => $line['Tax 1 Name'], 'percent' => $line['Tax 1 Percent'] ); } - + if(is_numeric($line['Tax 2 Percent']) && $line['Tax 2 Name'] != '') { $items_taxes_data[] = array('name' => $line['Tax 2 Name'], 'percent' => $line['Tax 2 Percent'] ); } - + if(count($items_taxes_data) > 0) { $this->Item_taxes->save($items_taxes_data, $item_data['item_id']); } } - - + /** * Guess whether file extension is not in the table field, if it isn't, then it's an old-format (formerly pic_id) field, so we guess the right filename and update the table * @@ -1118,8 +1126,8 @@ class Items extends Secure_Controller private function _update_pic_filename($item) { $filename = pathinfo($item->pic_filename, PATHINFO_FILENAME); - - // if the field is empty there's nothing to check + + // if the field is empty there's nothing to check if(!empty($filename)) { $ext = pathinfo($item->pic_filename, PATHINFO_EXTENSION); diff --git a/application/helpers/importfile_helper.php b/application/helpers/importfile_helper.php index ad5411e6c..97da2baba 100644 --- a/application/helpers/importfile_helper.php +++ b/application/helpers/importfile_helper.php @@ -11,7 +11,7 @@ function generate_import_items_csv($stock_locations,$attributes) $csv_headers .= 'Barcode,"Item Name",Category,"Supplier ID","Cost Price","Unit Price","Tax 1 Name","Tax 1 Percent","Tax 2 Name","Tax 2 Percent","Reorder Level",Description,"Allow Alt Description","Item has Serial Number",item_image,HSN'; $csv_headers .= generate_stock_location_headers($stock_locations); $csv_headers .= generate_attribute_headers($attributes); - + return $csv_headers; } @@ -23,12 +23,12 @@ function generate_import_items_csv($stock_locations,$attributes) function generate_stock_location_headers($locations) { $location_headers = ""; - + foreach($locations as $location_id => $location_name) { $location_headers .= ',"location_' . $location_name . '"'; } - + return $location_headers; } @@ -41,12 +41,12 @@ function generate_attribute_headers($attribute_names) { $attribute_headers = ""; unset($attribute_names[-1]); - + foreach($attribute_names as $attribute_name) { $attribute_headers .= ',"attribute_' . $attribute_name . '"'; } - + return $attribute_headers; } @@ -59,7 +59,7 @@ function generate_attribute_headers($attribute_names) function get_csv_file($file_name) { ini_set("auto_detect_line_endings", true); - + if(($csv_file = fopen($file_name,'r')) !== FALSE) { //Skip Byte-Order Mark @@ -67,7 +67,7 @@ function get_csv_file($file_name) { fseek($csv_file, 3); } - + while (($data = fgetcsv($csv_file)) !== FALSE) { //Skip empty lines @@ -81,7 +81,7 @@ function get_csv_file($file_name) { return FALSE; } - + return $line_array; } @@ -95,9 +95,9 @@ function bom_exists(&$file_handle) { $str = fread($file_handle,3); rewind($file_handle); - + $bom = pack("CCC", 0xef, 0xbb, 0xbf); - + if (0 === strncmp($str, $bom, 3)) { return TRUE; diff --git a/application/models/Attribute.php b/application/models/Attribute.php index 7340a39ff..ab585bf37 100644 --- a/application/models/Attribute.php +++ b/application/models/Attribute.php @@ -18,14 +18,14 @@ class Attribute extends CI_Model const SHOW_IN_ITEMS = 1; const SHOW_IN_SALES = 2; const SHOW_IN_RECEIVINGS = 4; - + public static function get_definition_flags() { $class = new ReflectionClass(__CLASS__); - + return array_flip($class->getConstants()); } - + /* Determines if a given definition_id is an attribute */ @@ -34,10 +34,10 @@ class Attribute extends CI_Model $this->db->from('attribute_definitions'); $this->db->where('definition_id', $definition_id); $this->db->where('deleted', $deleted); - + return ($this->db->get()->num_rows() == 1); } - + public function link_exists($item_id, $definition_id = FALSE) { $this->db->where('sale_id'); @@ -51,13 +51,13 @@ class Attribute extends CI_Model else { $this->db->where('definition_id', $definition_id); - } + $this->db->where('item_id', $item_id); - + return ($this->db->get()->num_rows() > 0); } - + /* Determines if a given attribute_value exists in the attribute_values table and returns the attribute_id if it does */ @@ -66,7 +66,7 @@ class Attribute extends CI_Model $this->db->distinct('attribute_id'); $this->db->from('attribute_values'); $this->db->where('attribute_value', $attribute_value); - + $query = $this->db->get(); if ($query->num_rows() > 0) { @@ -74,7 +74,7 @@ class Attribute extends CI_Model } return FALSE; } - + /* Gets information about a particular attribute definition */ @@ -84,28 +84,28 @@ class Attribute extends CI_Model $this->db->from('attribute_definitions AS definition'); $this->db->join('attribute_definitions AS parent_definition', 'parent_definition.definition_id = definition.definition_fk', 'left'); $this->db->where('definition.definition_id', $definition_id); - + $query = $this->db->get(); - + if($query->num_rows() == 1) { return $query->row(); } else { - //Get empty base parent object, as $item_id is NOT an item + //Get empty base parent object, as $item_id is NOT an item $item_obj = new stdClass(); - - //Get all the fields from items table + + //Get all the fields from items table foreach($this->db->list_fields('attribute_definitions') as $field) { $item_obj->$field = ''; } - + return $item_obj; } } - + /* Performs a search on attribute definitions */ @@ -114,22 +114,22 @@ class Attribute extends CI_Model $this->db->select('parent_definition.definition_name AS definition_group, definition.*'); $this->db->from('attribute_definitions AS definition'); $this->db->join('attribute_definitions AS parent_definition', 'parent_definition.definition_id = definition.definition_fk', 'left'); - + $this->db->group_start(); $this->db->like('definition.definition_name', $search); $this->db->or_like('definition.definition_type', $search); $this->db->group_end(); $this->db->where('definition.deleted', 0); $this->db->order_by($sort, $order); - + if($rows > 0) { $this->db->limit($rows, $limit_from); } - + return $this->db->get(); } - + public function get_attributes_by_item($item_id) { $this->db->from('attribute_definitions'); @@ -138,51 +138,51 @@ class Attribute extends CI_Model $this->db->where('receiving_id'); $this->db->where('sale_id'); $this->db->where('deleted', 0); - + $results = $this->db->get()->result_array(); - + return $this->_to_array($results, 'definition_id'); } - + public function get_values_by_definitions($definition_ids) { if(count($definition_ids ? : [])) { $this->db->from('attribute_definitions'); - + $this->db->group_start(); $this->db->where_in('definition_fk', array_keys($definition_ids)); $this->db->or_where_in('definition_id', array_keys($definition_ids)); $this->db->where('definition_type !=', GROUP); $this->db->group_end(); - + $this->db->where('deleted', 0); - + $results = $this->db->get()->result_array(); - + return $this->_to_array($results, 'definition_id'); } - + return array(); } - + public function get_definitions_by_type($attribute_type, $definition_id = -1) { $this->db->from('attribute_definitions'); $this->db->where('definition_type', $attribute_type); $this->db->where('deleted', 0); - + if($definition_id != -1) { $this->db->where('definition_id != ', $definition_id); } - + $this->db->where('definition_fk'); $results = $this->db->get()->result_array(); - + return $this->_to_array($results, 'definition_id', 'definition_name'); } - + public function get_definitions_by_flags($definition_flags) { $this->db->from('attribute_definitions'); @@ -191,11 +191,10 @@ class Attribute extends CI_Model $this->db->where('definition_type <>', GROUP); $this->db->order_by('definition_id'); $results = $this->db->get()->result_array(); - + return $this->_to_array($results, 'definition_id', 'definition_name'); } - - + /** * Returns an array of attribute definition names and IDs * @@ -206,45 +205,45 @@ class Attribute extends CI_Model { $this->db->from('attribute_definitions'); $this->db->where('deleted', 0); - + if($groups === FALSE) { $this->db->where_not_in('definition_type',GROUP); } - + $results = $this->db->get()->result_array(); - + $definition_name = array(-1 => $this->lang->line('common_none_selected_text')); - + return $definition_name + $this->_to_array($results, 'definition_id', 'definition_name'); } public function get_definition_values($definition_id) { $attribute_values = []; - + if($definition_id > -1) { $this->db->from('attribute_links'); $this->db->join('attribute_values', 'attribute_values.attribute_id = attribute_links.attribute_id'); $this->db->where('definition_id', $definition_id); $this->db->where('item_id'); - + $results = $this->db->get()->result_array(); - + return $this->_to_array($results, 'attribute_id', 'attribute_value'); } - + return $attribute_values; } - + private function _to_array($results, $key, $value = '') { return array_column(array_map(function($result) use ($key, $value) { return [$result[$key], empty($value) ? $result : $result[$value]]; }, $results), 1, 0); } - + /* Gets total of rows */ @@ -252,10 +251,10 @@ class Attribute extends CI_Model { $this->db->from('attribute_definitions'); $this->db->where('deleted', 0); - + return $this->db->count_all_results(); } - + /* Get number of rows */ @@ -263,11 +262,11 @@ class Attribute extends CI_Model { return $this->search($search)->num_rows(); } - + private function check_data_validity($definition, $from, $to) { $success = FALSE; - + if($from === TEXT) { $this->db->select('item_id,attribute_value'); @@ -275,7 +274,7 @@ class Attribute extends CI_Model $this->db->join('attribute_links', 'attribute_values.attribute_id = attribute_links.attribute_id'); $this->db->where('definition_id',$definition); $success = TRUE; - + if($to === DATE) { foreach($this->db->get()->result_array() as $row) @@ -301,23 +300,23 @@ class Attribute extends CI_Model } return $success; } - + private function convert_definition_type($definition_id, $from_type, $to_type) { $success = FALSE; - - //From TEXT + + //From TEXT if($from_type === TEXT) { - //To DATETIME or DECIMAL + //To DATETIME or DECIMAL if(in_array($to_type, [DATE, DECIMAL], TRUE)) { $field = ($to_type === DATE ? 'attribute_date' : 'attribute_decimal'); - + if($this->check_data_validity($definition_id, $from_type, $to_type)) { $this->db->trans_start(); - + $query = 'UPDATE ospos_attribute_values '; $query .= 'INNER JOIN ospos_attribute_links '; $query .= 'ON ospos_attribute_values.attribute_id = ospos_attribute_links.attribute_id '; @@ -325,11 +324,12 @@ class Attribute extends CI_Model $query .= 'attribute_value = NULL '; $query .= 'WHERE definition_id = ' . $this->db->escape($definition_id); $success = $this->db->query($query); - + $this->db->trans_complete(); } } - //To DROPDOWN or CHECKBOX + + //To DROPDOWN or CHECKBOX else if($to_type === DROPDOWN) { $success = TRUE; @@ -337,109 +337,108 @@ class Attribute extends CI_Model else if($to_type === CHECKBOX) { $checkbox_attribute_values = $this->checkbox_attribute_values($definition_id); - + $this->db->trans_start(); - + $query = 'UPDATE ospos_attribute_values a '; $query .= 'INNER JOIN ospos_attribute_links b '; $query .= 'ON a.attribute_id = b.attribute_id '; $query .= "SET b.attribute_id = IF((a.attribute_value IN('FALSE','0','') OR (a.attribute_value IS NULL)), $checkbox_attribute_values[0], $checkbox_attribute_values[1]) "; $query .= 'WHERE definition_id = ' . $this->db->escape($definition_id); $success = $this->db->query($query); - + $this->db->trans_complete(); } } - - //From DROPDOWN + + //From DROPDOWN else if($from_type === DROPDOWN) { - //To TEXT + //To TEXT if(in_array($to_type, [TEXT, CHECKBOX], TRUE)) { $this->db->trans_start(); - + $this->db->from('ospos_attribute_links'); $this->db->where('definition_id',$definition_id); $this->db->where('item_id', NULL); $success = $this->db->delete(); - + $this->db->trans_complete(); - - //To CHECKBOX + + //To CHECKBOX if($to_type === CHECKBOX) { $checkbox_attribute_values = $this->checkbox_attribute_values($definition_id); - + $this->db->trans_start(); - + $query = 'UPDATE ospos_attribute_values a '; $query .= 'INNER JOIN ospos_attribute_links b '; $query .= 'ON a.attribute_id = b.attribute_id '; $query .= "SET b.attribute_id = IF((a.attribute_value IN('FALSE','0','') OR (a.attribute_value IS NULL)), $checkbox_attribute_values[0], $checkbox_attribute_values[1]) "; $query .= 'WHERE definition_id = ' . $this->db->escape($definition_id); $success = $this->db->query($query); - + $this->db->trans_complete(); } - } } - - //From any other type + + //From any other type else { $success = TRUE; } - + return $success; } - + private function checkbox_attribute_values($definition_id) { $zero_attribute_id = $this->value_exists('0'); $one_attribute_id = $this->value_exists('1'); - + if($zero_attribute_id === FALSE) { $zero_attribute_id = $this->save_value('0', $definition_id, FALSE, FALSE, CHECKBOX); } - + if($one_attribute_id === FALSE) { $one_attribute_id = $this->save_value('1', $definition_id, FALSE, FALSE, CHECKBOX); } - + return array($zero_attribute_id, $one_attribute_id); } - + /* Inserts or updates a definition */ public function save_definition(&$definition_data, $definition_id = -1) { - //Run these queries as a transaction, we want to make sure we do all or nothing + //Run these queries as a transaction, we want to make sure we do all or nothing $this->db->trans_start(); - - //Definition doesn't exist + + //Definition doesn't exist if($definition_id === -1 || !$this->exists($definition_id)) { $success = $this->db->insert('attribute_definitions', $definition_data); $definition_data['definition_id'] = $this->db->insert_id(); } - - //Definition already exists + + //Definition already exists else { $this->db->select('definition_type, definition_name'); $this->db->from('attribute_definitions'); $this->db->where('definition_id', $definition_id); - + $row = $this->db->get()->row(); $from_definition_type = $row->definition_type; $from_definition_name = $row->definition_name; $to_definition_type = $definition_data['definition_type']; - + if($from_definition_type !== $to_definition_type) { if(!$this->convert_definition_type($definition_id,$from_definition_type,$to_definition_type)) @@ -447,19 +446,19 @@ class Attribute extends CI_Model return FALSE; } } - + $this->db->where('definition_id', $definition_id); $success = $this->db->update('attribute_definitions', $definition_data); $definition_data['definition_id'] = $definition_id; } - + $this->db->trans_complete(); - + $success &= $this->db->trans_status(); - + return $success; } - + public function get_definition_by_name($definition_name, $definition_type = FALSE) { $this->db->from('attribute_definitions'); @@ -468,14 +467,14 @@ class Attribute extends CI_Model { $this->db->where('definition_type', $definition_type); } - + return $this->db->get()->result_array(); } - + public function save_link($item_id, $definition_id, $attribute_id) { $this->db->trans_start(); - + if($this->link_exists($item_id, $definition_id)) { $this->db->where('definition_id', $definition_id); @@ -488,30 +487,30 @@ class Attribute extends CI_Model { $this->db->insert('attribute_links', array('attribute_id' => $attribute_id, 'item_id' => $item_id, 'definition_id' => $definition_id)); } - + $this->db->trans_complete(); - + return $this->db->trans_status(); } - + public function delete_link($item_id) { $this->db->where('sale_id'); $this->db->where('receiving_id'); - + return $this->db->delete('attribute_links', array('item_id' => $item_id)); } - + public function get_link_value($item_id, $definition_id) { $this->db->where('item_id', $item_id); $this->db->where('definition_id', $definition_id); $this->db->where('sale_id'); $this->db->where('receiving_id'); - + return $this->db->get('attribute_links')->row_object(); } - + public function get_link_values($item_id, $sale_receiving_fk, $id, $definition_flags) { $format = $this->db->escape(dateformat_mysql()); @@ -522,7 +521,7 @@ class Attribute extends CI_Model $this->db->join('attribute_definitions', 'attribute_definitions.definition_id = attribute_links.definition_id'); $this->db->where('definition_type <>', GROUP); $this->db->where('deleted', 0); - + if(!empty($id)) { $this->db->where($sale_receiving_fk, $id); @@ -532,12 +531,13 @@ class Attribute extends CI_Model $this->db->where('sale_id'); $this->db->where('receiving_id'); } + $this->db->where('item_id', (int) $item_id); $this->db->where('definition_flags & ', $definition_flags); - + return $this->db->get(); } - + public function get_attribute_value($item_id, $definition_id) { $this->db->from('attribute_values'); @@ -546,7 +546,7 @@ class Attribute extends CI_Model $this->db->where('sale_id'); $this->db->where('receiving_id'); $this->db->where('item_id', (int) $item_id); - + return $this->db->get()->row_object(); } @@ -559,7 +559,7 @@ class Attribute extends CI_Model WHERE item_id = ' . $this->db->escape($item_id) . ' AND sale_id IS NULL AND receiving_id IS NULL' ); } - + public function get_suggestions($definition_id, $term) { $suggestions = array(); @@ -572,26 +572,27 @@ class Attribute extends CI_Model $this->db->where('deleted', 0); $this->db->where('definition.definition_id', $definition_id); $this->db->order_by('attribute_value'); + foreach($this->db->get()->result() as $row) { $row_array = (array) $row; $suggestions[] = array('value' => $row_array['attribute_id'], 'label' => $row_array['attribute_value']); } - + return $suggestions; } - + public function save_value($attribute_value, $definition_id, $item_id = FALSE, $attribute_id = FALSE, $definition_type = DROPDOWN) { $this->db->trans_start(); - - //New Attribute + + //New Attribute if(empty($attribute_id) || empty($item_id)) { if(in_array($definition_type, [TEXT, DROPDOWN, CHECKBOX], TRUE)) { $attribute_id = $this->value_exists($attribute_value); - + if(empty($attribute_id)) { $this->db->insert('attribute_values', array('attribute_value' => $attribute_value)); @@ -605,16 +606,16 @@ class Attribute extends CI_Model { $this->db->insert('attribute_values', array('attribute_date' => date('Y-m-d', strtotime($attribute_value)))); } - + $attribute_id = $attribute_id ? $attribute_id : $this->db->insert_id(); - + $this->db->insert('attribute_links', array( 'attribute_id' => empty($attribute_id) ? NULL : $attribute_id, 'item_id' => empty($item_id) ? NULL : $item_id, 'definition_id' => $definition_id)); } - - //Existing Attribute + + //Existing Attribute else { $this->db->where('attribute_id', $attribute_id); @@ -632,18 +633,18 @@ class Attribute extends CI_Model $this->db->update('attribute_values', array('attribute_date' => date('Y-m-d', strtotime($attribute_value)))); } } - + $this->db->trans_complete(); - + return $attribute_id; } - + public function delete_value($attribute_value, $definition_id) { return $this->db->query("DELETE atrv, atrl FROM " . $this->db->dbprefix('attribute_values') . " atrv, " . $this->db->dbprefix('attribute_links') . " atrl " . "WHERE atrl.attribute_id = atrv.attribute_id AND atrv.attribute_value = " . $this->db->escape($attribute_value) . " AND atrl.definition_id = " . $this->db->escape($definition_id)); } - + /** * Deletes an Attribute definition from the database and associated column in the items_import.csv * @@ -653,14 +654,14 @@ class Attribute extends CI_Model public function delete_definition($definition_id) { $this->db->where('definition_id', $definition_id); - + return $this->db->update('attribute_definitions', array('deleted' => 1)); } public function delete_definition_list($definition_ids) { $this->db->where_in('definition_id', $definition_ids); - + return $this->db->update('attribute_definitions', array('deleted' => 1)); } } \ No newline at end of file diff --git a/application/views/attributes/form.php b/application/views/attributes/form.php index 2a3e1ed71..465154be1 100644 --- a/application/views/attributes/form.php +++ b/application/views/attributes/form.php @@ -54,8 +54,8 @@
'definition_value', 'class'=>'form-control input-sm', 'id' => 'definition_value'));?> - - + +
diff --git a/application/views/attributes/item.php b/application/views/attributes/item.php index 5d3d41b9a..9919d4a4e 100644 --- a/application/views/attributes/item.php +++ b/application/views/attributes/item.php @@ -1,9 +1,8 @@ -
lang->line("attributes_definition_name"), "definition_name_label", array('class' => 'control-label col-xs-3')); ?> -
+
'definition_name', 'class' => 'form-control')); ?> -
+
@@ -13,63 +12,63 @@ foreach($definition_values as $definition_id => $definition_value) ?>
- 'control-label col-xs-3')); ?> -
-
- 'control-label col-xs-3')); ?> +
+
+ attribute_date)) ? NOW : strtotime($attribute_value->attribute_date); - echo form_input(array( - 'name' => "attribute_links[$definition_id]", - 'value' => to_date($value), - 'class' => 'form-control input-sm datetime', - 'data-definition-id' => $definition_id, - 'readonly' => 'true')); - } - else if ($definition_value['definition_type'] == DROPDOWN) - { - $selected_value = $definition_value['selected_value']; - echo form_dropdown("attribute_links[$definition_id]", $definition_value['values'], $selected_value, "class='form-control' data-definition-id='$definition_id'"); - } - else if ($definition_value['definition_type'] == TEXT) - { - $value = (empty($attribute_value) || empty($attribute_value->attribute_value)) ? $definition_value['selected_value'] : $attribute_value->attribute_value; - echo form_input("attribute_links[$definition_id]", $value, "class='form-control valid_chars' data-definition-id='$definition_id'"); - } - else if ($definition_value['definition_type'] == DECIMAL) - { + if ($definition_value['definition_type'] == DATE) + { + $value = (empty($attribute_value) || empty($attribute_value->attribute_date)) ? NOW : strtotime($attribute_value->attribute_date); + echo form_input(array( + 'name' => "attribute_links[$definition_id]", + 'value' => to_date($value), + 'class' => 'form-control input-sm datetime', + 'data-definition-id' => $definition_id, + 'readonly' => 'true')); + } + else if ($definition_value['definition_type'] == DROPDOWN) + { + $selected_value = $definition_value['selected_value']; + echo form_dropdown("attribute_links[$definition_id]", $definition_value['values'], $selected_value, "class='form-control' data-definition-id='$definition_id'"); + } + else if ($definition_value['definition_type'] == TEXT) + { + $value = (empty($attribute_value) || empty($attribute_value->attribute_value)) ? $definition_value['selected_value'] : $attribute_value->attribute_value; + echo form_input("attribute_links[$definition_id]", $value, "class='form-control valid_chars' data-definition-id='$definition_id'"); + } + else if ($definition_value['definition_type'] == DECIMAL) + { $value = (empty($attribute_value) || empty($attribute_value->attribute_decimal)) ? $definition_value['selected_value'] : $attribute_value->attribute_decimal; echo form_input("attribute_links[$definition_id]", $value, "class='form-control valid_chars' data-definition-id='$definition_id'"); - } - else if ($definition_value['definition_type'] == CHECKBOX) - { - $value = (empty($attribute_value) || empty($attribute_value->attribute_value)) ? $definition_value['selected_value'] : $attribute_value->attribute_value; + } + else if ($definition_value['definition_type'] == CHECKBOX) + { + $value = (empty($attribute_value) || empty($attribute_value->attribute_value)) ? $definition_value['selected_value'] : $attribute_value->attribute_value; //Sends 0 if the box is unchecked instead of not sending anything. - echo form_input(array( - 'type' => 'hidden', + echo form_input(array( + 'type' => 'hidden', 'name' => "attribute_links[$definition_id]", - 'id' => "attribute_links[$definition_id]", - 'value' => 0, - 'data-definition-id' => $definition_id - )); - echo form_checkbox(array( - 'name' => "attribute_links[$definition_id]", - 'id' => "attribute_links[$definition_id]", - 'value' => 1, - 'checked' => ($value ? 1 : 0), - 'class' => 'checkbox-inline', - 'data-definition-id' => $definition_id - )); - } - ?> - -
-
+ 'id' => "attribute_links[$definition_id]", + 'value' => 0, + 'data-definition-id' => $definition_id + )); + echo form_checkbox(array( + 'name' => "attribute_links[$definition_id]", + 'id' => "attribute_links[$definition_id]", + 'value' => 1, + 'checked' => ($value ? 1 : 0), + 'class' => 'checkbox-inline', + 'data-definition-id' => $definition_id + )); + } + ?> + +
+
$definition_value) \ No newline at end of file From 8a0c88b11c2e058bd5b8fe52b2acc38ff4f798aa Mon Sep 17 00:00:00 2001 From: objecttothis Date: Tue, 24 Mar 2020 14:13:08 +0400 Subject: [PATCH 7/9] More indentation corrections --- application/controllers/Items.php | 6 +++--- application/models/Attribute.php | 6 +++--- 2 files changed, 6 insertions(+), 6 deletions(-) diff --git a/application/controllers/Items.php b/application/controllers/Items.php index a51afc4d2..4ae98f918 100644 --- a/application/controllers/Items.php +++ b/application/controllers/Items.php @@ -7,14 +7,14 @@ class Items extends Secure_Controller public function __construct() { parent::__construct('items'); - + $this->load->library('item_lib'); } 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()); $data['stock_locations'] = $this->xss_clean($this->Stock_location->get_allowed_locations()); @@ -452,7 +452,7 @@ class Items extends Secure_Controller $this->load->view('attributes/item', $data); } - + public function bulk_edit() { $suppliers = array('' => $this->lang->line('items_none')); diff --git a/application/models/Attribute.php b/application/models/Attribute.php index ab585bf37..9f0e02662 100644 --- a/application/models/Attribute.php +++ b/application/models/Attribute.php @@ -217,7 +217,7 @@ class Attribute extends CI_Model return $definition_name + $this->_to_array($results, 'definition_id', 'definition_name'); } - + public function get_definition_values($definition_id) { $attribute_values = []; @@ -549,7 +549,7 @@ class Attribute extends CI_Model return $this->db->get()->row_object(); } - + public function copy_attribute_links($item_id, $sale_receiving_fk, $id) { $this->db->query( @@ -657,7 +657,7 @@ class Attribute extends CI_Model return $this->db->update('attribute_definitions', array('deleted' => 1)); } - + public function delete_definition_list($definition_ids) { $this->db->where_in('definition_id', $definition_ids); From 4584b7eace98f7cd2c492333202784d0158807a7 Mon Sep 17 00:00:00 2001 From: objecttothis Date: Tue, 24 Mar 2020 14:17:36 +0400 Subject: [PATCH 8/9] Final indentation and formatting fixes --- application/controllers/Attributes.php | 4 ++-- application/views/attributes/form.php | 2 +- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/application/controllers/Attributes.php b/application/controllers/Attributes.php index b07abbd1f..a48218233 100644 --- a/application/controllers/Attributes.php +++ b/application/controllers/Attributes.php @@ -16,8 +16,8 @@ class Attributes extends Secure_Controller $this->load->view('attributes/manage', $data); } - /* - Returns customer table data rows. This will be called with AJAX. + /** + * Returns customer table data rows. This will be called with AJAX. */ public function search() { diff --git a/application/views/attributes/form.php b/application/views/attributes/form.php index 465154be1..8b3d8f3a3 100644 --- a/application/views/attributes/form.php +++ b/application/views/attributes/form.php @@ -54,7 +54,7 @@
'definition_value', 'class'=>'form-control input-sm', 'id' => 'definition_value'));?> - +
From b5265870be57f740cd210e327c8b78ae324a2156 Mon Sep 17 00:00:00 2001 From: objecttothis Date: Tue, 24 Mar 2020 14:21:57 +0400 Subject: [PATCH 9/9] More descriptive alias --- application/models/Attribute.php | 16 ++++++++-------- 1 file changed, 8 insertions(+), 8 deletions(-) diff --git a/application/models/Attribute.php b/application/models/Attribute.php index 9f0e02662..64f15f189 100644 --- a/application/models/Attribute.php +++ b/application/models/Attribute.php @@ -340,10 +340,10 @@ class Attribute extends CI_Model $this->db->trans_start(); - $query = 'UPDATE ospos_attribute_values a '; - $query .= 'INNER JOIN ospos_attribute_links b '; - $query .= 'ON a.attribute_id = b.attribute_id '; - $query .= "SET b.attribute_id = IF((a.attribute_value IN('FALSE','0','') OR (a.attribute_value IS NULL)), $checkbox_attribute_values[0], $checkbox_attribute_values[1]) "; + $query = 'UPDATE ospos_attribute_values values '; + $query .= 'INNER JOIN ospos_attribute_links links '; + $query .= 'ON values.attribute_id = links.attribute_id '; + $query .= "SET links.attribute_id = IF((values.attribute_value IN('FALSE','0','') OR (values.attribute_value IS NULL)), $checkbox_attribute_values[0], $checkbox_attribute_values[1]) "; $query .= 'WHERE definition_id = ' . $this->db->escape($definition_id); $success = $this->db->query($query); @@ -373,10 +373,10 @@ class Attribute extends CI_Model $this->db->trans_start(); - $query = 'UPDATE ospos_attribute_values a '; - $query .= 'INNER JOIN ospos_attribute_links b '; - $query .= 'ON a.attribute_id = b.attribute_id '; - $query .= "SET b.attribute_id = IF((a.attribute_value IN('FALSE','0','') OR (a.attribute_value IS NULL)), $checkbox_attribute_values[0], $checkbox_attribute_values[1]) "; + $query = 'UPDATE ospos_attribute_values values '; + $query .= 'INNER JOIN ospos_attribute_links links '; + $query .= 'ON values.attribute_id = links.attribute_id '; + $query .= "SET links.attribute_id = IF((values.attribute_value IN('FALSE','0','') OR (values.attribute_value IS NULL)), $checkbox_attribute_values[0], $checkbox_attribute_values[1]) "; $query .= 'WHERE definition_id = ' . $this->db->escape($definition_id); $success = $this->db->query($query);