diff --git a/application/controllers/Config.php b/application/controllers/Config.php index e7a2cf7ac..f981e6643 100644 --- a/application/controllers/Config.php +++ b/application/controllers/Config.php @@ -9,6 +9,7 @@ class Config extends Secure_Controller parent::__construct('config'); $this->load->library('barcode_lib'); + $this->load->library('Sale_lib'); } /* @@ -194,7 +195,8 @@ class Config extends Secure_Controller $data['stock_locations'] = $this->Stock_location->get_all()->result_array(); $data['support_barcode'] = $this->barcode_lib->get_list_barcodes(); $data['logo_exists'] = $this->config->item('company_logo') != ''; - + $data['line_sequence_options'] = $this->sale_lib->get_line_sequence_options(); + $data = $this->xss_clean($data); // load all the license statements, they are already XSS cleaned in the private function @@ -372,7 +374,6 @@ class Config extends Secure_Controller private function _clear_session_state() { - $this->load->library('sale_lib'); $this->sale_lib->clear_sale_location(); $this->sale_lib->clear_all(); $this->load->library('receiving_lib'); @@ -414,9 +415,9 @@ class Config extends Secure_Controller echo json_encode(array('success' => $success, 'message' => $this->lang->line('config_saved_' . ($success ? '' : 'un') . 'successfully'))); } - public function save_barcode() - { - $batch_save_data = array( + public function save_barcode() + { + $batch_save_data = array( 'barcode_type' => $this->input->post('barcode_type'), 'barcode_quality' => $this->input->post('barcode_quality'), 'barcode_width' => $this->input->post('barcode_width'), @@ -431,17 +432,17 @@ class Config extends Secure_Controller 'barcode_page_cellspacing' => $this->input->post('barcode_page_cellspacing'), 'barcode_generate_if_empty' => $this->input->post('barcode_generate_if_empty') != NULL, 'barcode_content' => $this->input->post('barcode_content') - ); - - $result = $this->Appconfig->batch_save($batch_save_data); - $success = $result ? TRUE : FALSE; + ); + + $result = $this->Appconfig->batch_save($batch_save_data); + $success = $result ? TRUE : FALSE; - echo json_encode(array('success' => $success, 'message' => $this->lang->line('config_saved_' . ($success ? '' : 'un') . 'successfully'))); - } - - public function save_receipt() - { - $batch_save_data = array ( + echo json_encode(array('success' => $success, 'message' => $this->lang->line('config_saved_' . ($success ? '' : 'un') . 'successfully'))); + } + + public function save_receipt() + { + $batch_save_data = array ( 'receipt_template' => $this->input->post('receipt_template'), 'receipt_show_taxes' => $this->input->post('receipt_show_taxes') != NULL, 'receipt_show_total_discount' => $this->input->post('receipt_show_total_discount') != NULL, @@ -456,27 +457,28 @@ class Config extends Secure_Controller 'print_right_margin' => $this->input->post('print_right_margin') ); - $result = $this->Appconfig->batch_save($batch_save_data); - $success = $result ? TRUE : FALSE; + $result = $this->Appconfig->batch_save($batch_save_data); + $success = $result ? TRUE : FALSE; - echo json_encode(array('success' => $success, 'message' => $this->lang->line('config_saved_' . ($success ? '' : 'un') . 'successfully'))); - } + echo json_encode(array('success' => $success, 'message' => $this->lang->line('config_saved_' . ($success ? '' : 'un') . 'successfully'))); + } - public function save_invoice() - { - $batch_save_data = array ( + public function save_invoice() + { + $batch_save_data = array ( 'invoice_enable' => $this->input->post('invoice_enable') != NULL, 'sales_invoice_format' => $this->input->post('sales_invoice_format'), 'recv_invoice_format' => $this->input->post('recv_invoice_format'), 'invoice_default_comments' => $this->input->post('invoice_default_comments'), - 'invoice_email_message' => $this->input->post('invoice_email_message') + 'invoice_email_message' => $this->input->post('invoice_email_message'), + 'line_sequence' => $this->input->post('line_sequence') ); - $result = $this->Appconfig->batch_save($batch_save_data); - $success = $result ? TRUE : FALSE; + $result = $this->Appconfig->batch_save($batch_save_data); + $success = $result ? TRUE : FALSE; - echo json_encode(array('success' => $success, 'message' => $this->lang->line('config_saved_' . ($success ? '' : 'un') . 'successfully'))); - } + echo json_encode(array('success' => $success, 'message' => $this->lang->line('config_saved_' . ($success ? '' : 'un') . 'successfully'))); + } public function remove_logo() { @@ -484,22 +486,22 @@ class Config extends Secure_Controller echo json_encode(array('success' => $result)); } - - private function _handle_logo_upload() - { - $this->load->helper('directory'); - // load upload library - $config = array('upload_path' => './uploads/', - 'allowed_types' => 'gif|jpg|png', - 'max_size' => '1024', - 'max_width' => '800', - 'max_height' => '680', - 'file_name' => 'company_logo'); - $this->load->library('upload', $config); - $this->upload->do_upload('company_logo'); + private function _handle_logo_upload() + { + $this->load->helper('directory'); - return strlen($this->upload->display_errors()) == 0 || !strcmp($this->upload->display_errors(), '
'.$this->lang->line('upload_no_file_selected').'
'); + // load upload library + $config = array('upload_path' => './uploads/', + 'allowed_types' => 'gif|jpg|png', + 'max_size' => '1024', + 'max_width' => '800', + 'max_height' => '680', + 'file_name' => 'company_logo'); + $this->load->library('upload', $config); + $this->upload->do_upload('company_logo'); + + return strlen($this->upload->display_errors()) == 0 || !strcmp($this->upload->display_errors(), ''.$this->lang->line('upload_no_file_selected').'
'); } private function _check_encryption() @@ -556,35 +558,35 @@ class Config extends Secure_Controller return TRUE; } - - public function backup_db() - { - $employee_id = $this->Employee->get_logged_in_employee_info()->person_id; - if($this->Employee->has_module_grant('config', $employee_id)) - { - $this->load->dbutil(); - $prefs = array( + public function backup_db() + { + $employee_id = $this->Employee->get_logged_in_employee_info()->person_id; + if($this->Employee->has_module_grant('config', $employee_id)) + { + $this->load->dbutil(); + + $prefs = array( 'format' => 'zip', 'filename' => 'ospos.sql' - ); - - $backup = $this->dbutil->backup($prefs); - - $file_name = 'ospos-' . date("Y-m-d-H-i-s") .'.zip'; - $save = 'uploads/' . $file_name; - $this->load->helper('download'); - while(ob_get_level()) - { - ob_end_clean(); - } + ); - force_download($file_name, $backup); - } - else - { - redirect('no_access/config'); - } - } + $backup = $this->dbutil->backup($prefs); + + $file_name = 'ospos-' . date("Y-m-d-H-i-s") .'.zip'; + $save = 'uploads/' . $file_name; + $this->load->helper('download'); + while(ob_get_level()) + { + ob_end_clean(); + } + + force_download($file_name, $backup); + } + else + { + redirect('no_access/config'); + } + } } ?> diff --git a/application/controllers/Item_kits.php b/application/controllers/Item_kits.php index 07498a20f..4b6149f33 100644 --- a/application/controllers/Item_kits.php +++ b/application/controllers/Item_kits.php @@ -84,23 +84,35 @@ class Item_kits extends Secure_Controller public function view($item_kit_id = -1) { $info = $this->Item_kit->get_info($item_kit_id); + + if($item_kit_id == -1) + { + $info->price_option = '0'; + $info->print_option = '0'; + } foreach(get_object_vars($info) as $property => $value) { $info->$property = $this->xss_clean($value); } + $data['item_kit_info'] = $info; - + $items = array(); foreach($this->Item_kit_items->get_info($item_kit_id) as $item_kit_item) { + $item['kit_sequence'] = $this->xss_clean($item_kit_item['kit_sequence']); $item['name'] = $this->xss_clean($this->Item->get_info($item_kit_item['item_id'])->name); $item['item_id'] = $this->xss_clean($item_kit_item['item_id']); $item['quantity'] = $this->xss_clean($item_kit_item['quantity']); - + $items[] = $item; } + $data['item_kit_items'] = $items; + $data['selected_kit_item_id'] = $info->kit_item_id; + $data['selected_kit_item'] = ($item_kit_id > 0 && isset($info->kit_item_id)) ? $info->item_name : ''; + $this->load->view("item_kits/form", $data); } @@ -108,36 +120,51 @@ class Item_kits extends Secure_Controller { $item_kit_data = array( 'name' => $this->input->post('name'), + 'item_id' => $this->input->post('kit_item_id'), + 'kit_discount_percent' => $this->input->post('kit_discount_percent'), + 'price_option' => $this->input->post('price_option'), + 'print_option' => $this->input->post('print_option'), 'description' => $this->input->post('description') ); if($this->Item_kit->save($item_kit_data, $item_kit_id)) { $success = TRUE; + $new_item = FALSE; //New item kit if ($item_kit_id == -1) { $item_kit_id = $item_kit_data['item_kit_id']; + $new_item = TRUE; } - if($this->input->post('item_kit_item') != NULL) + if($this->input->post('item_kit_qty') != NULL) { $item_kit_items = array(); - foreach($this->input->post('item_kit_item') as $item_id => $quantity) + foreach($this->input->post('item_kit_qty') as $item_id => $quantity) { + $seq = $this->input->post('item_kit_seq[' . $item_id . ']'); $item_kit_items[] = array( 'item_id' => $item_id, - 'quantity' => $quantity + 'quantity' => $quantity, + 'kit_sequence' => $seq ); } - $success = $this->Item_kit_items->save($item_kit_items, $item_kit_id); } + $success = $this->Item_kit_items->save($item_kit_items, $item_kit_id); + $item_kit_data = $this->xss_clean($item_kit_data); - echo json_encode(array('success' => $success, - 'message' => $this->lang->line('item_kits_successful_adding').' '.$item_kit_data['name'], 'id' => $item_kit_id)); + if($new_item) { + echo json_encode(array('success' => $success, + 'message' => $this->lang->line('item_kits_successful_adding').' '.$item_kit_data['name'], 'id' => $item_kit_id)); + + } else { + echo json_encode(array('success' => $success, + 'message' => $this->lang->line('item_kits_successful_updating').' '.$item_kit_data['name'], 'id' => $item_kit_id)); + } } else//failure { @@ -182,7 +209,7 @@ class Item_kits extends Secure_Controller } $data['items'] = $result; - $barcode_config = $this->barcode_lib->get_barcode_config(); + $barcode_config = $this->barcode_lib->get_barcode_config(); // in case the selected barcode type is not Code39 or Code128 we set by default Code128 // the rationale for this is that EAN codes cannot have strings as seed, so 'KIT ' is not allowed if($barcode_config['barcode_type'] != 'Code39' && $barcode_config['barcode_type'] != 'Code128') diff --git a/application/controllers/Items.php b/application/controllers/Items.php index 39c93e5f6..534166026 100644 --- a/application/controllers/Items.php +++ b/application/controllers/Items.php @@ -87,8 +87,8 @@ class Items extends Secure_Controller $config['create_thumb'] = TRUE; $config['width'] = 52; $config['height'] = 32; - $this->image_lib->initialize($config); - $image = $this->image_lib->resize(); + $this->image_lib->initialize($config); + $image = $this->image_lib->resize(); $thumb_path = $this->image_lib->full_dst_path; } $this->output->set_content_type(get_mime_by_extension($thumb_path)); @@ -174,9 +174,11 @@ class Items extends Secure_Controller { $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 = 0; $item_info->reorder_level = 0; + $item_info->item_type = '0'; // standard + $item_info->stock_type = '0'; // stock } $data['item_info'] = $item_info; @@ -197,19 +199,19 @@ class Items extends Secure_Controller } $stock_locations = $this->Stock_location->get_undeleted_all()->result_array(); - foreach($stock_locations as $location) - { + 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; - } + } $this->load->view('items/form', $data); } - + public function inventory($item_id = -1) { $item_info = $this->Item->get_info($item_id); @@ -219,16 +221,16 @@ class Items extends Secure_Controller } $data['item_info'] = $item_info; - $data['stock_locations'] = array(); - $stock_locations = $this->Stock_location->get_undeleted_all()->result_array(); - foreach($stock_locations as $location) - { + $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; - } + $data['stock_locations'][$location['location_id']] = $location['location_name']; + $data['item_quantities'][$location['location_id']] = $quantity; + } $this->load->view('items/form_inventory', $data); } @@ -242,16 +244,16 @@ class Items extends Secure_Controller } $data['item_info'] = $item_info; - $data['stock_locations'] = array(); - $stock_locations = $this->Stock_location->get_undeleted_all()->result_array(); - foreach($stock_locations as $location) - { + $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; - } + $data['stock_locations'][$location['location_id']] = $location['location_name']; + $data['item_quantities'][$location['location_id']] = $quantity; + } $this->load->view('items/form_count_details', $data); } @@ -323,6 +325,8 @@ class Items extends Secure_Controller 'name' => $this->input->post('name'), 'description' => $this->input->post('description'), 'category' => $this->input->post('category'), + 'item_type' => $this->input->post('item_type'), + 'stock_type' => $this->input->post('stock_type'), 'supplier_id' => $this->input->post('supplier_id') == '' ? NULL : $this->input->post('supplier_id'), 'item_number' => $this->input->post('item_number') == '' ? NULL : $this->input->post('item_number'), 'cost_price' => parse_decimals($this->input->post('cost_price')), @@ -380,45 +384,45 @@ 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) - { - $updated_quantity = parse_decimals($this->input->post('quantity_' . $location['location_id'])); - $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, - 'trans_user' => $employee_id, - 'trans_location' => $location['location_id'], - '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 quantity + $stock_locations = $this->Stock_location->get_undeleted_all()->result_array(); + foreach($stock_locations as $location) + { + $updated_quantity = parse_decimals($this->input->post('quantity_' . $location['location_id'])); + $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, + 'trans_user' => $employee_id, + 'trans_location' => $location['location_id'], + 'trans_comment' => $this->lang->line('items_manually_editing_of_quantity'), + 'trans_inventory' => $updated_quantity - $item_quantity->quantity + ); + + $success &= $this->Inventory->insert($inv_data); + } + } if($success && $upload_success) - { - $message = $this->xss_clean($this->lang->line('items_successful_' . ($new_item ? 'adding' : 'updating')) . ' ' . $item_data['name']); + { + $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' => 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)); - } + echo json_encode(array('success' => FALSE, 'message' => $message, 'id' => $item_id)); + } } else//failure { @@ -433,7 +437,23 @@ class Items extends Secure_Controller $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. + */ + public function check_kit_exists() + { + if ($this->input->post('item_number') === -1) + { + $exists = $this->Item_kit->item_kit_exists_for_name($this->input->post('name')); + } + else + { + $exists = false; + } + echo !$exists ? 'true' : 'false'; + } + private function _handle_image_upload() { $this->load->helper('directory'); @@ -466,7 +486,7 @@ class Items extends Secure_Controller { $employee_id = $this->Employee->get_logged_in_employee_info()->person_id; $cur_item_info = $this->Item->get_info($item_id); - $location_id = $this->input->post('stock_location'); + $location_id = $this->input->post('stock_location'); $inv_data = array( 'trans_date' => date('Y-m-d H:i:s'), 'trans_items' => $item_id, @@ -579,133 +599,133 @@ class Items extends Secure_Controller $this->load->view('items/form_excel_import', NULL); } - public function do_excel_import() - { - if($_FILES['file_path']['error'] != UPLOAD_ERR_OK) - { - echo json_encode(array('success' => FALSE, 'message' => $this->lang->line('items_excel_import_failed'))); - } - else + public function do_excel_import() + { + if($_FILES['file_path']['error'] != UPLOAD_ERR_OK) { - if(($handle = fopen($_FILES['file_path']['tmp_name'], 'r')) !== FALSE) - { - // Skip the first row as it's the table description - fgetcsv($handle); - $i = 1; + echo json_encode(array('success' => FALSE, 'message' => $this->lang->line('items_excel_import_failed'))); + } + else + { + if(($handle = fopen($_FILES['file_path']['tmp_name'], 'r')) !== FALSE) + { + // Skip the first row as it's the table description + fgetcsv($handle); + $i = 1; $failCodes = array(); - while(($data = fgetcsv($handle)) !== FALSE) - { + while(($data = fgetcsv($handle)) !== FALSE) + { // XSS file data sanity check $data = $this->xss_clean($data); if(sizeof($data) >= 23) { - $item_data = array( - 'name' => $data[1], - 'description' => $data[11], - 'category' => $data[2], - 'cost_price' => $data[4], - 'unit_price' => $data[5], - 'reorder_level' => $data[10], - 'supplier_id' => $this->Supplier->exists($data[3]) ? $data[3] : NULL, - 'allow_alt_description' => $data[12] != '' ? '1' : '0', - 'is_serialized' => $data[13] != '' ? '1' : '0', - 'custom1' => $data[14], - 'custom2' => $data[15], - 'custom3' => $data[16], - 'custom4' => $data[17], - 'custom5' => $data[18], - 'custom6' => $data[19], - 'custom7' => $data[20], - 'custom8' => $data[21], - 'custom9' => $data[22], - 'custom10' => $data[23] - ); - $item_number = $data[0]; - $invalidated = FALSE; - if($item_number != '') - { - $item_data['item_number'] = $item_number; - $invalidated = $this->Item->item_number_exists($item_number); - } + $item_data = array( + 'name' => $data[1], + 'description' => $data[11], + 'category' => $data[2], + 'cost_price' => $data[4], + 'unit_price' => $data[5], + 'reorder_level' => $data[10], + 'supplier_id' => $this->Supplier->exists($data[3]) ? $data[3] : NULL, + 'allow_alt_description' => $data[12] != '' ? '1' : '0', + 'is_serialized' => $data[13] != '' ? '1' : '0', + 'custom1' => $data[14], + 'custom2' => $data[15], + 'custom3' => $data[16], + 'custom4' => $data[17], + 'custom5' => $data[18], + 'custom6' => $data[19], + 'custom7' => $data[20], + 'custom8' => $data[21], + 'custom9' => $data[22], + 'custom10' => $data[23] + ); + $item_number = $data[0]; + $invalidated = FALSE; + if($item_number != '') + { + $item_data['item_number'] = $item_number; + $invalidated = $this->Item->item_number_exists($item_number); + } } else { $invalidated = TRUE; } - if(!$invalidated && $this->Item->save($item_data)) - { - $items_taxes_data = NULL; - //tax 1 - if(is_numeric($data[7]) && $data[6] != '') - { - $items_taxes_data[] = array('name' => $data[6], 'percent' => $data[7] ); - } + if(!$invalidated && $this->Item->save($item_data)) + { + $items_taxes_data = NULL; + //tax 1 + if(is_numeric($data[7]) && $data[6] != '') + { + $items_taxes_data[] = array('name' => $data[6], 'percent' => $data[7] ); + } - //tax 2 - if(is_numeric($data[9]) && $data[8] != '') - { - $items_taxes_data[] = array('name' => $data[8], 'percent' => $data[9] ); - } + //tax 2 + if(is_numeric($data[9]) && $data[8] != '') + { + $items_taxes_data[] = array('name' => $data[8], 'percent' => $data[9] ); + } - // save tax values - if(count($items_taxes_data) > 0) - { - $this->Item_taxes->save($items_taxes_data, $item_data['item_id']); - } + // save tax values + if(count($items_taxes_data) > 0) + { + $this->Item_taxes->save($items_taxes_data, $item_data['item_id']); + } - // quantities & inventory Info - $employee_id = $this->Employee->get_logged_in_employee_info()->person_id; - $emp_info = $this->Employee->get_info($employee_id); - $comment ='Qty CSV Imported'; + // quantities & inventory Info + $employee_id = $this->Employee->get_logged_in_employee_info()->person_id; + $emp_info = $this->Employee->get_info($employee_id); + $comment ='Qty CSV Imported'; - $cols = count($data); + $cols = count($data); - // array to store information if location got a quantity - $allowed_locations = $this->Stock_location->get_allowed_locations(); - for ($col = 24; $col < $cols; $col = $col + 2) - { - $location_id = $data[$col]; - if(array_key_exists($location_id, $allowed_locations)) - { - $item_quantity_data = array( - 'item_id' => $item_data['item_id'], - 'location_id' => $location_id, - 'quantity' => $data[$col + 1], - ); - $this->Item_quantity->save($item_quantity_data, $item_data['item_id'], $location_id); + // array to store information if location got a quantity + $allowed_locations = $this->Stock_location->get_allowed_locations(); + for ($col = 24; $col < $cols; $col = $col + 2) + { + $location_id = $data[$col]; + if(array_key_exists($location_id, $allowed_locations)) + { + $item_quantity_data = array( + 'item_id' => $item_data['item_id'], + 'location_id' => $location_id, + 'quantity' => $data[$col + 1], + ); + $this->Item_quantity->save($item_quantity_data, $item_data['item_id'], $location_id); - $excel_data = array( - 'trans_items' => $item_data['item_id'], - 'trans_user' => $employee_id, - 'trans_comment' => $comment, - 'trans_location' => $data[$col], - 'trans_inventory' => $data[$col + 1] - ); + $excel_data = array( + 'trans_items' => $item_data['item_id'], + 'trans_user' => $employee_id, + 'trans_comment' => $comment, + 'trans_location' => $data[$col], + 'trans_inventory' => $data[$col + 1] + ); - $this->Inventory->insert($excel_data); - unset($allowed_locations[$location_id]); - } - } + $this->Inventory->insert($excel_data); + unset($allowed_locations[$location_id]); + } + } - /* - * now iterate through the array and check for which location_id no entry into item_quantities was made yet - * those get an entry with quantity as 0. - * unfortunately a bit duplicate code from above... - */ - foreach($allowed_locations as $location_id => $location_name) - { - $item_quantity_data = array( - 'item_id' => $item_data['item_id'], - 'location_id' => $location_id, - 'quantity' => 0, - ); - $this->Item_quantity->save($item_quantity_data, $item_data['item_id'], $data[$col]); + /* + * now iterate through the array and check for which location_id no entry into item_quantities was made yet + * those get an entry with quantity as 0. + * unfortunately a bit duplicate code from above... + */ + foreach($allowed_locations as $location_id => $location_name) + { + $item_quantity_data = array( + 'item_id' => $item_data['item_id'], + 'location_id' => $location_id, + 'quantity' => 0, + ); + $this->Item_quantity->save($item_quantity_data, $item_data['item_id'], $data[$col]); - $excel_data = array( + $excel_data = array( 'trans_items' => $item_data['item_id'], 'trans_user' => $employee_id, 'trans_comment' => $comment, @@ -713,16 +733,16 @@ class Items extends Secure_Controller 'trans_inventory' => 0 ); - $this->Inventory->insert($excel_data); - } - } - else //insert or update item failure - { - $failCodes[] = $i; - } + $this->Inventory->insert($excel_data); + } + } + else //insert or update item failure + { + $failCodes[] = $i; + } ++$i; - } + } if(count($failCodes) > 0) { @@ -737,9 +757,9 @@ class Items extends Secure_Controller } else { - echo json_encode(array('success' => FALSE, 'message' => $this->lang->line('items_excel_import_nodata_wrongformat'))); + echo json_encode(array('success' => FALSE, 'message' => $this->lang->line('items_excel_import_nodata_wrongformat'))); } - } + } } } ?> diff --git a/application/controllers/Reports.php b/application/controllers/Reports.php index 6b6f4724d..9c19430f8 100644 --- a/application/controllers/Reports.php +++ b/application/controllers/Reports.php @@ -369,21 +369,21 @@ class Reports extends Secure_Controller $stock_locations = $data = $this->xss_clean($this->Stock_location->get_allowed_locations('sales')); $stock_locations['all'] = $this->lang->line('reports_all'); $data['stock_locations'] = array_reverse($stock_locations, TRUE); - $data['mode'] = 'sale'; + $data['mode'] = 'sale'; $this->load->view('reports/date_input', $data); } - public function date_input_recv() - { - $data = array(); + public function date_input_recv() + { + $data = array(); $stock_locations = $data = $this->xss_clean($this->Stock_location->get_allowed_locations('receivings')); $stock_locations['all'] = $this->lang->line('reports_all'); $data['stock_locations'] = array_reverse($stock_locations, TRUE); - $data['mode'] = 'receiving'; + $data['mode'] = 'receiving'; - $this->load->view('reports/date_input', $data); - } + $this->load->view('reports/date_input', $data); + } //Graphical summary sales report public function graphical_summary_sales($start_date, $end_date, $sale_type, $location_id = 'all') @@ -893,7 +893,7 @@ class Reports extends Secure_Controller $this->load->view('reports/tabular_details', $data); } - public function get_detailed_sales_row($sale_id) + public function get_detailed_sales_row($sale_id) { $inputs = array('sale_id' => $sale_id); @@ -931,10 +931,11 @@ class Reports extends Secure_Controller $this->load->model('reports/Detailed_sales'); $model = $this->Detailed_sales; - + $model->create($inputs); $headers = $this->xss_clean($model->getDataColumns()); + $report_data = $model->getData($inputs); $summary_data = array(); @@ -1041,6 +1042,7 @@ class Reports extends Secure_Controller 'employee_name' => $row['employee_name'], 'supplier_name' => $row['supplier_name'], 'total' => to_currency($row['total']), + 'profit' => to_currency($row['profit']), 'payment_type' => $row['payment_type'], 'reference' => $row['reference'], 'comment' => $row['comment'], diff --git a/application/controllers/Sales.php b/application/controllers/Sales.php index 8c0650524..e3bd75237 100644 --- a/application/controllers/Sales.php +++ b/application/controllers/Sales.php @@ -176,7 +176,7 @@ class Sales extends Secure_Controller public function set_email_receipt() { - $this->sale_lib->set_email_receipt($this->input->post('email_receipt')); + $this->sale_lib->set_email_receipt($this->input->post('email_receipt')); } // Multiple Payments @@ -248,7 +248,7 @@ class Sales extends Secure_Controller public function add() { $data = array(); - + $discount = 0; // check if any discount is assigned to the selected customer @@ -280,10 +280,36 @@ class Sales extends Secure_Controller } elseif($this->Item_kit->is_valid_item_kit($item_id_or_number_or_item_kit_or_receipt)) { + + // Add kit item to order if one is assigned + $pieces = explode(' ', $item_id_or_number_or_item_kit_or_receipt); + $item_kit_id = $pieces[1]; + $item_kit_info = $this->Item_kit->get_info($item_kit_id); + $kit_item_id = $item_kit_info->kit_item_id; + + if ($kit_item_id !== '' && $kit_item_id != 0) + { + if ($item_kit_info->kit_discount_percent != 0 && $item_kit_info->kit_discount_percent > $discount) + { + $discount = $item_kit_info->kit_discount_percent; + } + if(!$this->sale_lib->add_item($kit_item_id, $quantity, $item_location, $discount)) + { + $data['error'] = $this->lang->line('sales_unable_to_add_item'); + } + else + { + $data['warning'] = $this->sale_lib->out_of_stock($item_id_or_number_or_item_kit_or_receipt, $item_location); + } + } + + // Add kit items to order if(!$this->sale_lib->add_item_kit($item_id_or_number_or_item_kit_or_receipt, $item_location, $discount)) { $data['error'] = $this->lang->line('sales_unable_to_add_item'); } + + } else { diff --git a/application/language/en/config_lang.php b/application/language/en/config_lang.php index 0cc0afd67..bcbf18f26 100644 --- a/application/language/en/config_lang.php +++ b/application/language/en/config_lang.php @@ -103,6 +103,7 @@ $lang["config_language"] = "Language"; $lang["config_left"] = "Left"; $lang["config_license"] = "License"; $lang["config_license_configuration"] = "License Statement"; +$lang["config_line_sequence"] = "Line Sequence"; $lang["config_lines_per_page"] = "Lines Per Page"; $lang["config_lines_per_page_number"] = ""; $lang["config_lines_per_page_required"] = "The lines per page is a required field"; diff --git a/application/language/en/item_kits_lang.php b/application/language/en/item_kits_lang.php index 353c0b7c2..2afd43378 100644 --- a/application/language/en/item_kits_lang.php +++ b/application/language/en/item_kits_lang.php @@ -1,21 +1,31 @@ 'Standard', '1' => 'Entry', '2' => 'Group by Type', '3' => 'Group by Category'); - public function __construct() + public function __construct() { $this->CI =& get_instance(); } + public function get_line_sequence_options() + { + return $this->line_sequence_options; + } + + public function get_cart() { if(!$this->CI->session->userdata('sales_cart')) @@ -34,7 +41,7 @@ class Sale_lib // avoid returning a NULL that results in a 0 in the comment if nothing is set/available $comment = $this->CI->session->userdata('sales_comment'); - return empty($comment) ? '' : $comment; + return empty($comment) ? '' : $comment; } public function set_comment($comment) @@ -177,7 +184,7 @@ class Sale_lib $subtotal = 0; foreach($this->get_payments() as $payments) { - $subtotal = bcadd($payments['payment_amount'], $subtotal); + $subtotal = bcadd($payments['payment_amount'], $subtotal); } return $subtotal; @@ -192,7 +199,7 @@ class Sale_lib $precision = $this->CI->config->item('currency_decimals'); $rounded_due = bccomp(round($amount_due, $precision, PHP_ROUND_HALF_EVEN), 0, $precision); // take care of rounding error introduced by round tripping payment amount to the browser - return $rounded_due == 0 ? 0 : $amount_due; + return $rounded_due == 0 ? 0 : $amount_due; } public function get_customer() @@ -255,40 +262,40 @@ class Sale_lib $this->CI->session->unset_userdata('sales_mode'); } - public function get_sale_location() - { - if(!$this->CI->session->userdata('sales_location')) - { + public function get_sale_location() + { + if(!$this->CI->session->userdata('sales_location')) + { $this->set_sale_location($this->CI->Stock_location->get_default_location_id()); - } + } - return $this->CI->session->userdata('sales_location'); - } + return $this->CI->session->userdata('sales_location'); + } - public function set_sale_location($location) - { - $this->CI->session->set_userdata('sales_location', $location); - } - - public function clear_sale_location() - { - $this->CI->session->unset_userdata('sales_location'); - } - - public function set_giftcard_remainder($value) - { - $this->CI->session->set_userdata('sales_giftcard_remainder', $value); - } - - public function get_giftcard_remainder() - { - return $this->CI->session->userdata('sales_giftcard_remainder'); - } - - public function clear_giftcard_remainder() - { - $this->CI->session->unset_userdata('sales_giftcard_remainder'); - } + public function set_sale_location($location) + { + $this->CI->session->set_userdata('sales_location', $location); + } + + public function clear_sale_location() + { + $this->CI->session->unset_userdata('sales_location'); + } + + public function set_giftcard_remainder($value) + { + $this->CI->session->set_userdata('sales_giftcard_remainder', $value); + } + + public function get_giftcard_remainder() + { + return $this->CI->session->userdata('sales_giftcard_remainder'); + } + + public function clear_giftcard_remainder() + { + $this->CI->session->unset_userdata('sales_giftcard_remainder'); + } public function add_item(&$item_id, $quantity = 1, $item_location, $discount = 0, $price = NULL, $description = NULL, $serialnumber = NULL, $include_deleted = FALSE) { @@ -298,7 +305,7 @@ class Sale_lib if(empty($item_info)) { $item_id = -1; - return FALSE; + return FALSE; } $item_id = $item_info->item_id; @@ -308,20 +315,20 @@ class Sale_lib //Get all items in the cart so far... $items = $this->get_cart(); - //We need to loop through all items in the cart. - //If the item is already there, get it's key($updatekey). - //We also need to get the next key that we are going to use in case we need to add the - //item to the cart. Since items can be deleted, we can't use a count. we use the highest key + 1. + //We need to loop through all items in the cart. + //If the item is already there, get it's key($updatekey). + //We also need to get the next key that we are going to use in case we need to add the + //item to the cart. Since items can be deleted, we can't use a count. we use the highest key + 1. - $maxkey = 0; //Highest key so far - $itemalreadyinsale = FALSE; //We did not find the item yet. + $maxkey = 0; //Highest key so far + $itemalreadyinsale = FALSE; //We did not find the item yet. $insertkey = 0; //Key to use for new entry. $updatekey = 0; //Key to use to update(quantity) foreach($items as $item) { - //We primed the loop so maxkey is 0 the first time. - //Also, we have stored the key in the element itself so we can compare. + //We primed the loop so maxkey is 0 the first time. + //Also, we have stored the key in the element itself so we can compare. if($maxkey <= $item['line']) { @@ -332,10 +339,10 @@ class Sale_lib { $itemalreadyinsale = TRUE; $updatekey = $item['line']; - if(!$item_info->is_serialized) - { - $quantity = bcadd($quantity, $items[$updatekey]['quantity']); - } + if(!$item_info->is_serialized) + { + $quantity = bcadd($quantity, $items[$updatekey]['quantity']); + } } } @@ -343,39 +350,39 @@ class Sale_lib //array/cart records are identified by $insertkey and item_id is just another field. $price = $price != NULL ? $price : $item_info->unit_price; $total = $this->get_item_total($quantity, $price, $discount); - $discounted_total = $this->get_item_total($quantity, $price, $discount, TRUE); + $discounted_total = $this->get_item_total($quantity, $price, $discount, TRUE); //Item already exists and is not serialized, add to quantity if(!$itemalreadyinsale || $item_info->is_serialized) { - $item = array($insertkey => array( - 'item_id' => $item_id, - 'item_location' => $item_location, - 'stock_name' => $this->CI->Stock_location->get_location_name($item_location), - 'line' => $insertkey, - 'name' => $item_info->name, - 'item_number' => $item_info->item_number, - 'description' => $description != NULL ? $description : $item_info->description, - 'serialnumber' => $serialnumber != NULL ? $serialnumber : '', - 'allow_alt_description' => $item_info->allow_alt_description, - 'is_serialized' => $item_info->is_serialized, - 'quantity' => $quantity, - 'discount' => $discount, - 'in_stock' => $this->CI->Item_quantity->get_item_quantity($item_id, $item_location)->quantity, - 'price' => $price, - 'total' => $total, - 'discounted_total' => $discounted_total, - ) - ); + $item = array($insertkey => array( + 'item_id' => $item_id, + 'item_location' => $item_location, + 'stock_name' => $this->CI->Stock_location->get_location_name($item_location), + 'line' => $insertkey, + 'name' => $item_info->name, + 'item_number' => $item_info->item_number, + 'description' => $description != NULL ? $description : $item_info->description, + 'serialnumber' => $serialnumber != NULL ? $serialnumber : '', + 'allow_alt_description' => $item_info->allow_alt_description, + 'is_serialized' => $item_info->is_serialized, + 'quantity' => $quantity, + 'discount' => $discount, + 'in_stock' => $this->CI->Item_quantity->get_item_quantity($item_id, $item_location)->quantity, + 'price' => $price, + 'total' => $total, + 'discounted_total' => $discounted_total, + ) + ); //add to existing array $items += $item; } - else - { - $line = &$items[$updatekey]; - $line['quantity'] = $quantity; - $line['total'] = $total; - $line['discounted_total'] = $discounted_total; - } + else + { + $line = &$items[$updatekey]; + $line['quantity'] = $quantity; + $line['total'] = $total; + $line['discounted_total'] = $discounted_total; + } $this->set_cart($items); @@ -387,16 +394,20 @@ class Sale_lib //make sure item exists if($item_id != -1) { - $item_quantity = $this->CI->Item_quantity->get_item_quantity($item_id, $item_location)->quantity; - $quantity_added = $this->get_quantity_already_added($item_id, $item_location); + $item_info = $this->CI->Item->get_info_by_id_or_number($item_id); - if($item_quantity - $quantity_added < 0) - { - return $this->CI->lang->line('sales_quantity_less_than_zero'); - } - elseif($item_quantity - $quantity_added < $this->CI->Item->get_info_by_id_or_number($item_id)->reorder_level) - { - return $this->CI->lang->line('sales_quantity_less_than_reorder_level'); + if ($item_info->stock_type === 0) { + $item_quantity = $this->CI->Item_quantity->get_item_quantity($item_id, $item_location)->quantity; + $quantity_added = $this->get_quantity_already_added($item_id, $item_location); + + if($item_quantity - $quantity_added < 0) + { + return $this->CI->lang->line('sales_quantity_less_than_zero'); + } + elseif($item_quantity - $quantity_added < $item_info->reorder_level) + { + return $this->CI->lang->line('sales_quantity_less_than_reorder_level'); + } } } @@ -468,7 +479,7 @@ class Sale_lib $this->empty_cart(); $this->remove_customer(); - foreach($this->CI->Sale->get_sale_items($sale_id)->result() as $row) + foreach($this->CI->Sale->get_sale_items_ordered($sale_id)->result() as $row) { $this->add_item($row->item_id, -$row->quantity_purchased, $row->item_location, $row->discount_percent, $row->item_unit_price, $row->description, $row->serialnumber, TRUE); } @@ -496,7 +507,7 @@ class Sale_lib $this->empty_cart(); $this->remove_customer(); - foreach($this->CI->Sale->get_sale_items($sale_id)->result() as $row) + foreach($this->CI->Sale->get_sale_items_ordered($sale_id)->result() as $row) { $this->add_item($row->item_id, $row->quantity_purchased, $row->item_location, $row->discount_percent, $row->item_unit_price, $row->description, $row->serialnumber, TRUE); } @@ -704,7 +715,6 @@ class Sale_lib return $total; } - } ?> diff --git a/application/models/Item.php b/application/models/Item.php index eb13a5842..46de993c4 100644 --- a/application/models/Item.php +++ b/application/models/Item.php @@ -60,13 +60,58 @@ class Item extends CI_Model */ public function search($search, $filters, $rows = 0, $limit_from = 0, $sort = 'items.name', $order = 'asc') { - $this->db->from('items'); - $this->db->join('suppliers', 'suppliers.person_id = items.supplier_id', 'left'); - $this->db->join('inventory', 'inventory.trans_items = items.item_id'); + $this->db->select('max(items.name) as name'); + $this->db->select('max(items.category) as category'); + $this->db->select('max(items.supplier_id) as supplier_id'); + $this->db->select('max(items.item_number) as item_number'); + $this->db->select('max(items.description) as description'); + $this->db->select('max(items.cost_price) as cost_price'); + $this->db->select('max(items.unit_price) as unit_price'); + $this->db->select('max(items.reorder_level) as reorder_level'); + $this->db->select('max(items.receiving_quantity) as receiving_quantity'); + $this->db->select('items.item_id as item_id'); + $this->db->select('max(items.pic_id) as pic_id'); + $this->db->select('max(items.allow_alt_description) as allow_alt_description'); + $this->db->select('max(items.is_serialized) as is_serialized'); + $this->db->select('max(items.deleted) as deleted'); + $this->db->select('max(items.custom1) as custom1'); + $this->db->select('max(items.custom2) as custom2'); + $this->db->select('max(items.custom3) as custom3'); + $this->db->select('max(items.custom4) as custom4'); + $this->db->select('max(items.custom5) as custom5'); + $this->db->select('max(items.custom6) as custom6'); + $this->db->select('max(items.custom7) as custom7'); + $this->db->select('max(items.custom8) as custom8'); + $this->db->select('max(items.custom9) as custom9'); + $this->db->select('max(items.custom10) as custom10'); + + $this->db->select('max(suppliers.person_id) as person_id'); + $this->db->select('max(suppliers.company_name) as company_name'); + $this->db->select('max(suppliers.agency_name) as agency_name'); + $this->db->select('max(suppliers.account_number) as account_number'); + $this->db->select('max(suppliers.deleted) as deleted'); + + $this->db->select('max(inventory.trans_id) as trans_id'); + $this->db->select('max(inventory.trans_items) as trans_items'); + $this->db->select('max(inventory.trans_user) as trans_user'); + $this->db->select('max(inventory.trans_date) as trans_date'); + $this->db->select('max(inventory.trans_comment) as trans_comment'); + $this->db->select('max(inventory.trans_location) as trans_location'); + $this->db->select('max(inventory.trans_inventory) as trans_inventory'); + + if($filters['stock_location_id'] > -1) { + $this->db->select('max(item_quantities.item_id) as qty_item_id'); + $this->db->select('max(item_quantities.location_id) as location_id'); + $this->db->select('sum(item_quantities.quantity) as quantity'); + } + + $this->db->from('items as items'); + $this->db->join('suppliers as suppliers', 'suppliers.person_id = items.supplier_id', 'left'); + $this->db->join('inventory as inventory', 'inventory.trans_items = items.item_id'); if($filters['stock_location_id'] > -1) { - $this->db->join('item_quantities', 'item_quantities.item_id = items.item_id'); + $this->db->join('item_quantities as item_quantities', 'item_quantities.item_id = items.item_id'); $this->db->where('location_id', $filters['stock_location_id']); } @@ -122,18 +167,18 @@ class Item extends CI_Model // avoid duplicated entries with same name because of inventory reporting multiple changes on the same item in the same date range $this->db->group_by('items.item_id'); - + // order by name of item $this->db->order_by($sort, $order); - if($rows > 0) - { + if($rows > 0) + { $this->db->limit($rows, $limit_from); } return $this->db->get(); } - + /* Returns all the items */ @@ -192,7 +237,7 @@ class Item extends CI_Model return $item_obj; } } - + /* Gets information about a particular item by item id or number */ @@ -200,17 +245,17 @@ class Item extends CI_Model { $this->db->from('items'); - if (ctype_digit($item_id)) - { - $this->db->group_start(); - $this->db->where('item_id', (int) $item_id); - $this->db->or_where('items.item_number', $item_id); - $this->db->group_end(); - } - else - { - $this->db->where('item_number', $item_id); - } + if (ctype_digit($item_id)) + { + $this->db->group_start(); + $this->db->where('item_id', (int) $item_id); + $this->db->or_where('items.item_number', $item_id); + $this->db->group_end(); + } + else + { + $this->db->where('item_number', $item_id); + } $this->db->where('items.deleted', 0); @@ -236,7 +281,7 @@ class Item extends CI_Model { $this->db->where('items.deleted', $deleted); } - + $query = $this->db->get(); if($query->num_rows() == 1) @@ -277,7 +322,7 @@ class Item extends CI_Model return FALSE; } - + $this->db->where('item_id', $item_id); return $this->db->update('items', $item_data); @@ -305,14 +350,14 @@ class Item extends CI_Model $this->Item_quantity->reset_quantity($item_id); $this->db->where('item_id', $item_id); $success = $this->db->update('items', array('deleted'=>1)); - + $this->db->trans_complete(); - + $success &= $this->db->trans_status(); return $success; } - + /* Undeletes one item */ @@ -335,13 +380,13 @@ class Item extends CI_Model $this->Item_quantity->reset_quantity_list($item_ids); $this->db->where_in('item_id', $item_ids); $success = $this->db->update('items', array('deleted'=>1)); - + $this->db->trans_complete(); - + $success &= $this->db->trans_status(); return $success; - } + } public function get_search_suggestions($search, $filters = array('is_deleted' => FALSE, 'search_custom' => FALSE), $unique = FALSE, $limit = 25) { @@ -350,6 +395,7 @@ class Item extends CI_Model $this->db->select('item_id, name'); $this->db->from('items'); $this->db->where('deleted', $filters['is_deleted']); + $this->db->where("item_type = '0'"); // standard, exclude kit items since kits will be picked up later $this->db->like('name', $search); $this->db->order_by('name', 'asc'); foreach($this->db->get()->result() as $row) @@ -458,7 +504,7 @@ class Item extends CI_Model return $suggestions; } - + public function get_location_suggestions($search) { $suggestions = array(); @@ -472,7 +518,7 @@ class Item extends CI_Model { $suggestions[] = array('label' => $row->location); } - + return $suggestions; } @@ -490,7 +536,7 @@ class Item extends CI_Model $row_array = (array) $row; $suggestions[] = array('label' => $row_array['custom'.$field_no]); } - + return $suggestions; } diff --git a/application/models/Item_kit.php b/application/models/Item_kit.php index 91a673781..ba07e7dd4 100644 --- a/application/models/Item_kit.php +++ b/application/models/Item_kit.php @@ -46,7 +46,41 @@ class Item_kit extends CI_Model */ public function get_info($item_kit_id) { - $this->db->from('item_kits'); + $this->db->select(' + item_kit_id, + item_kits.name as name, + items.name as item_name, + item_kits.description, + items.description as item_description, + item_kits.item_id as kit_item_id, + kit_discount_percent, + price_option, + print_option, + category, + supplier_id, + item_number, + cost_price, + unit_price, + reorder_level, + receiving_quantity, + pic_id, + allow_alt_description, + is_serialized, + deleted, + custom1, + custom2, + custom3, + custom4, + custom5, + custom6, + custom7, + custom8, + custom9, + custom10, + item_type'); + + $this->db->from('item_kits'); + $this->db->join('items', 'item_kits.item_id = items.item_id', 'left'); $this->db->where('item_kit_id', $item_kit_id); $query = $this->db->get(); @@ -120,7 +154,7 @@ class Item_kit extends CI_Model $this->db->where_in('item_kit_id', $item_kit_ids); return $this->db->delete('item_kits'); - } + } public function get_search_suggestions($search, $limit = 25) { diff --git a/application/models/Item_kit_items.php b/application/models/Item_kit_items.php index ab4e0b3fa..067bb891b 100644 --- a/application/models/Item_kit_items.php +++ b/application/models/Item_kit_items.php @@ -8,29 +8,44 @@ class Item_kit_items extends CI_Model { $this->db->from('item_kit_items'); $this->db->where('item_kit_id', $item_kit_id); - + $this->db->order_by('kit_sequence', 'asc'); + + //return an array of item kit items for an item + return $this->db->get()->result_array(); + } + + /* + Gets item kit items for a particular item kit + */ + public function get_info_for_sale($item_kit_id) + { + $this->db->from('item_kit_items'); + $this->db->where('item_kit_id', $item_kit_id); + $this->db->order_by('kit_sequence', 'desc'); + //return an array of item kit items for an item return $this->db->get()->result_array(); } - /* Inserts or updates an item kit's items */ public function save(&$item_kit_items_data, $item_kit_id) { $success = TRUE; - + //Run these queries as a transaction, we want to make sure we do all or nothing + $this->db->trans_start(); $this->delete($item_kit_id); - - foreach($item_kit_items_data as $row) - { - $row['item_kit_id'] = $item_kit_id; - $success &= $this->db->insert('item_kit_items', $row); + + if ($item_kit_items_data != NULL) { + foreach ($item_kit_items_data as $row) { + $row['item_kit_id'] = $item_kit_id; + $success &= $this->db->insert('item_kit_items', $row); + } } - + $this->db->trans_complete(); $success &= $this->db->trans_status(); diff --git a/application/models/Receiving.php b/application/models/Receiving.php index 4b8b9145e..a4bf6fa8a 100644 --- a/application/models/Receiving.php +++ b/application/models/Receiving.php @@ -2,7 +2,7 @@ class Receiving extends CI_Model { public function get_info($receiving_id) - { + { $this->db->from('receivings'); $this->db->join('people', 'people.person_id = receivings.supplier_id', 'LEFT'); $this->db->join('suppliers', 'suppliers.person_id = receivings.supplier_id', 'LEFT'); @@ -30,7 +30,7 @@ class Receiving extends CI_Model { return $this->exists($pieces[1]); } - else + else { return $this->get_receiving_by_reference($receipt_receiving_id)->num_rows() > 0; } @@ -46,7 +46,7 @@ class Receiving extends CI_Model return ($this->db->get()->num_rows() == 1); } - + public function update($receiving_data, $receiving_id) { $this->db->where('receiving_id', $receiving_id); @@ -106,8 +106,8 @@ class Receiving extends CI_Model //Update stock quantity $item_quantity = $this->Item_quantity->get_item_quantity($item['item_id'], $item['item_location']); - $this->Item_quantity->save(array('quantity' => $item_quantity->quantity + $items_received, 'item_id' => $item['item_id'], - 'location_id' => $item['item_location']), $item['item_id'], $item['item_location']); + $this->Item_quantity->save(array('quantity' => $item_quantity->quantity + $items_received, 'item_id' => $item['item_id'], + 'location_id' => $item['item_location']), $item['item_id'], $item['item_location']); $recv_remarks = 'RECV ' . $receiving_id; $inv_data = array( @@ -125,7 +125,7 @@ class Receiving extends CI_Model } $this->db->trans_complete(); - + if($this->db->trans_status() === FALSE) { return -1; @@ -133,7 +133,7 @@ class Receiving extends CI_Model return $receiving_id; } - + public function delete_list($receiving_ids, $employee_id, $update_inventory = TRUE) { $success = TRUE; @@ -153,7 +153,7 @@ class Receiving extends CI_Model return $success; } - + public function delete($receiving_id, $employee_id, $update_inventory = TRUE) { // start a transaction to assure data integrity @@ -233,33 +233,32 @@ class Receiving extends CI_Model { $where = 'WHERE receivings_items.receiving_id = ' . $this->db->escape($inputs['receiving_id']); } - - $this->db->query('CREATE TEMPORARY TABLE IF NOT EXISTS ' . $this->db->dbprefix('receivings_items_temp') . + + $this->db->query('CREATE TEMPORARY TABLE IF NOT EXISTS ' . $this->db->dbprefix('receivings_items_temp') . ' (INDEX(receiving_date), INDEX(receiving_id)) - ( - SELECT - DATE(receiving_time) AS receiving_date, - receiving_time, + ( SELECT + MAX(DATE(receiving_time)) AS receiving_date, + MAX(receiving_time) AS receiving_time, receivings_items.receiving_id, - comment, - item_location, - reference, - payment_type, - employee_id, + MAX(comment) AS comment, + MAX(item_location) AS item_location, + MAX(reference) AS reference, + MAX(payment_type) AS payment_type, + MAX(employee_id) AS employee_id, items.item_id, - receivings.supplier_id, - quantity_purchased, - receivings_items.receiving_quantity, - item_cost_price, - item_unit_price, - discount_percent, + MAX(receivings.supplier_id) AS supplier_id, + SUM(quantity_purchased) AS quantity_purchased, + SUM(receivings_items.receiving_quantity) AS receiving_quantity, + MAX(item_cost_price) AS item_cost_price, + MAX(item_unit_price) AS item_unit_price, + MAX(discount_percent) AS discount_percent, receivings_items.line, - serialnumber, - receivings_items.description, - (item_unit_price * quantity_purchased - item_unit_price * quantity_purchased * discount_percent / 100) AS subtotal, - (item_unit_price * quantity_purchased - item_unit_price * quantity_purchased * discount_percent / 100) AS total, - (item_unit_price * quantity_purchased - item_unit_price * quantity_purchased * discount_percent / 100) - (item_cost_price * quantity_purchased) AS profit, - (item_cost_price * quantity_purchased) AS cost + MAX(serialnumber) AS serialnumber, + MAX(receivings_items.description) AS description, + SUM(item_unit_price * quantity_purchased - item_unit_price * quantity_purchased * discount_percent / 100) AS subtotal, + SUM(item_unit_price * quantity_purchased - item_unit_price * quantity_purchased * discount_percent / 100) AS total, + SUM((item_unit_price * quantity_purchased - item_unit_price * quantity_purchased * discount_percent / 100) - (item_cost_price * quantity_purchased)) AS profit, + SUM(item_cost_price * quantity_purchased) AS cost FROM ' . $this->db->dbprefix('receivings_items') . ' AS receivings_items INNER JOIN ' . $this->db->dbprefix('receivings') . ' AS receivings ON receivings_items.receiving_id = receivings.receiving_id diff --git a/application/models/Sale.php b/application/models/Sale.php index 581941ecd..5bc2b0a62 100644 --- a/application/models/Sale.php +++ b/application/models/Sale.php @@ -5,7 +5,7 @@ class Sale extends CI_Model { // NOTE: temporary tables are created to speed up searches due to the fact that are ortogonal to the main query // create a temporary table to contain all the payments per sale item - $this->db->query('CREATE TEMPORARY TABLE IF NOT EXISTS ' . $this->db->dbprefix('sales_payments_temp') . + $this->db->query('CREATE TEMPORARY TABLE IF NOT EXISTS ' . $this->db->dbprefix('sales_payments_temp') . '( SELECT payments.sale_id AS sale_id, IFNULL(SUM(payments.payment_amount), 0) AS sale_payment_amount, @@ -19,7 +19,7 @@ class Sale extends CI_Model ); // create a temporary table to contain all the sum of taxes per sale item - $this->db->query('CREATE TEMPORARY TABLE IF NOT EXISTS ' . $this->db->dbprefix('sales_items_taxes_temp') . + $this->db->query('CREATE TEMPORARY TABLE IF NOT EXISTS ' . $this->db->dbprefix('sales_items_taxes_temp') . '( SELECT sales_items_taxes.sale_id AS sale_id, sales_items_taxes.item_id AS item_id, @@ -51,23 +51,23 @@ class Sale extends CI_Model $this->db->select(' sales.sale_id AS sale_id, - DATE(sales.sale_time) AS sale_date, - sales.sale_time AS sale_time, - sales.comment AS comment, - sales.invoice_number AS invoice_number, - sales.employee_id AS employee_id, - sales.customer_id AS customer_id, - CONCAT(customer_p.first_name, " ", customer_p.last_name) AS customer_name, - customer_p.first_name AS first_name, - customer_p.last_name AS last_name, - customer_p.email AS email, - customer_p.comments AS comments, + MAX(DATE(sales.sale_time)) AS sale_date, + MAX(sales.sale_time) AS sale_time, + MAX(sales.comment) AS comment, + MAX(sales.invoice_number) AS invoice_number, + MAX(sales.employee_id) AS employee_id, + MAX(sales.customer_id) AS customer_id, + MAX(CONCAT(customer_p.first_name, " ", customer_p.last_name)) AS customer_name, + MAX(customer_p.first_name) AS first_name, + MAX(customer_p.last_name) AS last_name, + MAX(customer_p.email) AS email, + MAX(customer_p.comments) AS comments, ' . " IFNULL(ROUND($sale_total, $decimals), ROUND($sale_subtotal, $decimals)) AS amount_due, - payments.sale_payment_amount AS amount_tendered, - (payments.sale_payment_amount - IFNULL(ROUND($sale_total, $decimals), ROUND($sale_subtotal, $decimals))) AS change_due, + SUM(payments.sale_payment_amount) AS amount_tendered, + (SUM(payments.sale_payment_amount) - IFNULL(ROUND($sale_total, $decimals), ROUND($sale_subtotal, $decimals))) AS change_due, " . ' - payments.payment_type AS payment_type + MAX(payments.payment_type) AS payment_type '); $this->db->from('sales_items AS sales_items'); @@ -100,7 +100,7 @@ class Sale extends CI_Model { // NOTE: temporary tables are created to speed up searches due to the fact that are ortogonal to the main query // create a temporary table to contain all the payments per sale item - $this->db->query('CREATE TEMPORARY TABLE IF NOT EXISTS ' . $this->db->dbprefix('sales_payments_temp') . + $this->db->query('CREATE TEMPORARY TABLE IF NOT EXISTS ' . $this->db->dbprefix('sales_payments_temp') . ' (PRIMARY KEY(sale_id), INDEX(sale_id)) ( SELECT payments.sale_id AS sale_id, @@ -115,7 +115,7 @@ class Sale extends CI_Model ); // create a temporary table to contain all the sum of taxes per sale item - $this->db->query('CREATE TEMPORARY TABLE IF NOT EXISTS ' . $this->db->dbprefix('sales_items_taxes_temp') . + $this->db->query('CREATE TEMPORARY TABLE IF NOT EXISTS ' . $this->db->dbprefix('sales_items_taxes_temp') . ' (INDEX(sale_id), INDEX(item_id)) ( SELECT sales_items_taxes.sale_id AS sale_id, @@ -150,12 +150,12 @@ class Sale extends CI_Model $this->db->select(' sales.sale_id AS sale_id, - DATE(sales.sale_time) AS sale_date, - sales.sale_time AS sale_time, - sales.invoice_number AS invoice_number, + MAX(DATE(sales.sale_time)) AS sale_date, + MAX(sales.sale_time) AS sale_time, + MAX(sales.invoice_number) AS invoice_number, SUM(sales_items.quantity_purchased) AS items_purchased, - CONCAT(customer_p.first_name, " ", customer_p.last_name) AS customer_name, - customer.company_name AS company_name, + MAX(CONCAT(customer_p.first_name, " ", customer_p.last_name)) as customer_name, + MAX(customer.company_name) AS company_name, ' . " ROUND($sale_subtotal, $decimals) AS subtotal, IFNULL(ROUND($sale_tax, $decimals), 0) AS tax, @@ -163,10 +163,10 @@ class Sale extends CI_Model ROUND($sale_cost, $decimals) AS cost, ROUND($sale_total - IFNULL($sale_tax, 0) - $sale_cost, $decimals) AS profit, IFNULL(ROUND($sale_total, $decimals), ROUND($sale_subtotal, $decimals)) AS amount_due, - payments.sale_payment_amount AS amount_tendered, - (payments.sale_payment_amount - IFNULL(ROUND($sale_total, $decimals), ROUND($sale_subtotal, $decimals))) AS change_due, + SUM(payments.sale_payment_amount) AS amount_tendered, + (SUM(payments.sale_payment_amount) - IFNULL(ROUND($sale_total, $decimals), ROUND($sale_subtotal, $decimals))) AS change_due, " . ' - payments.payment_type AS payment_type + MAX(payments.payment_type) AS payment_type '); $this->db->from('sales_items AS sales_items'); @@ -186,7 +186,7 @@ class Sale extends CI_Model $this->db->where('sales.sale_id', $pieces[1]); } else - { + { $this->db->group_start(); // customer last name $this->db->like('customer_p.last_name', $search); @@ -206,13 +206,13 @@ class Sale extends CI_Model } if($filters['sale_type'] == 'sales') - { - $this->db->where('sales_items.quantity_purchased > 0'); - } - elseif($filters['sale_type'] == 'returns') - { - $this->db->where('sales_items.quantity_purchased < 0'); - } + { + $this->db->where('sales_items.quantity_purchased > 0'); + } + elseif($filters['sale_type'] == 'returns') + { + $this->db->where('sales_items.quantity_purchased < 0'); + } if($filters['only_invoices'] != FALSE) { @@ -287,7 +287,7 @@ class Sale extends CI_Model { $this->db->where('invoice_number IS NOT NULL'); } - + if($filters['only_cash'] != FALSE) { $this->db->like('payment_type', $this->lang->line('sales_cash'), 'after'); @@ -378,7 +378,7 @@ class Sale extends CI_Model return $this->db->get(); } - public function get_invoice_number_for_year($year = '', $start_from = 0) + public function get_invoice_number_for_year($year = '', $start_from = 0) { $year = $year == '' ? date('Y') : $year; $this->db->select('COUNT( 1 ) AS invoice_number_year'); @@ -389,7 +389,7 @@ class Sale extends CI_Model return ($start_from + $result['invoice_number_year']); } - + public function is_valid_receipt(&$receipt_sale_id) { if(!empty($receipt_sale_id)) @@ -434,7 +434,7 @@ class Sale extends CI_Model { //Run these queries as a transaction, we want to make sure we do all or nothing $this->db->trans_start(); - + // first delete all payments $this->db->delete('sales_payments', array('sale_id' => $sale_id)); @@ -449,12 +449,12 @@ class Sale extends CI_Model $success = $this->db->insert('sales_payments', $sales_payments_data); } - + $this->db->trans_complete(); - + $success &= $this->db->trans_status(); } - + return $success; } @@ -516,33 +516,40 @@ class Sale extends CI_Model $this->db->insert('sales_items', $sales_items_data); - // Update stock quantity - $item_quantity = $this->Item_quantity->get_item_quantity($item['item_id'], $item['item_location']); - $this->Item_quantity->save(array('quantity' => $item_quantity->quantity - $item['quantity'], - 'item_id' => $item['item_id'], - 'location_id' => $item['item_location']), $item['item_id'], $item['item_location']); + if ($cur_item_info->stock_type === '0') + { + // Update stock quantity if item type is not non-stock + $item_quantity = $this->Item_quantity->get_item_quantity($item['item_id'], $item['item_location']); + $this->Item_quantity->save(array('quantity' => $item_quantity->quantity - $item['quantity'], + 'item_id' => $item['item_id'], + 'location_id' => $item['item_location']), $item['item_id'], $item['item_location']); + } // if an items was deleted but later returned it's restored with this rule + if($item['quantity'] < 0) { $this->Item->undelete($item['item_id']); } - - // Inventory Count Details - $sale_remarks = 'POS '.$sale_id; - $inv_data = array( - 'trans_date' => date('Y-m-d H:i:s'), - 'trans_items' => $item['item_id'], - 'trans_user' => $employee_id, - 'trans_location' => $item['item_location'], - 'trans_comment' => $sale_remarks, - 'trans_inventory' => -$item['quantity'] - ); - $this->Inventory->insert($inv_data); + + if ($cur_item_info->stock_type === '0') + { + // Inventory Count Details + $sale_remarks = 'POS ' . $sale_id; + $inv_data = array( + 'trans_date' => date('Y-m-d H:i:s'), + 'trans_items' => $item['item_id'], + 'trans_user' => $employee_id, + 'trans_location' => $item['item_location'], + 'trans_comment' => $sale_remarks, + 'trans_inventory' => -$item['quantity'] + ); + $this->Inventory->insert($inv_data); + } $customer = $this->Customer->get_info($customer_id); - if($customer_id == -1 || $customer->taxable) - { + if($customer_id == -1 || $customer->taxable) + { foreach($this->Item_taxes->get_info($item['item_id']) as $row) { $this->db->insert('sales_items_taxes', array( @@ -557,16 +564,16 @@ class Sale extends CI_Model } $this->db->trans_complete(); - + if($this->db->trans_status() === FALSE) { return -1; } - + return $sale_id; } - public function delete_list($sale_ids, $employee_id, $update_inventory = TRUE) + public function delete_list($sale_ids, $employee_id, $update_inventory = TRUE) { $result = TRUE; @@ -578,7 +585,7 @@ class Sale extends CI_Model return $result; } - public function delete($sale_id, $employee_id, $update_inventory = TRUE) + public function delete($sale_id, $employee_id, $update_inventory = TRUE) { // start a transaction to assure data integrity $this->db->trans_start(); @@ -595,20 +602,24 @@ class Sale extends CI_Model $items = $this->get_sale_items($sale_id)->result_array(); foreach($items as $item) { - // create query to update inventory tracking - $inv_data = array( - 'trans_date' => date('Y-m-d H:i:s'), - 'trans_items' => $item['item_id'], - 'trans_user' => $employee_id, - 'trans_comment' => 'Deleting sale ' . $sale_id, - 'trans_location' => $item['item_location'], - 'trans_inventory' => $item['quantity_purchased'] - ); - // update inventory - $this->Inventory->insert($inv_data); + $cur_item_info = $this->Item->get_info($item['item_id']); - // update quantities - $this->Item_quantity->change_quantity($item['item_id'], $item['item_location'], $item['quantity_purchased']); + if ($cur_item_info->stock_type === '0') { + // create query to update inventory tracking + $inv_data = array( + 'trans_date' => date('Y-m-d H:i:s'), + 'trans_items' => $item['item_id'], + 'trans_user' => $employee_id, + 'trans_comment' => 'Deleting sale ' . $sale_id, + 'trans_location' => $item['item_location'], + 'trans_inventory' => $item['quantity_purchased'] + ); + // update inventory + $this->Inventory->insert($inv_data); + + // update quantities + $this->Item_quantity->change_quantity($item['item_id'], $item['item_location'], $item['quantity_purchased']); + } } } @@ -619,7 +630,7 @@ class Sale extends CI_Model // execute transaction $this->db->trans_complete(); - + return $this->db->trans_status(); } @@ -631,6 +642,59 @@ class Sale extends CI_Model return $this->db->get(); } + /* + * Used by the invoice and receipt programs + */ + public function get_sale_items_ordered($sale_id) + { + $this->db->select(' + sale_id, + sales_items.item_id, + sales_items.description, + serialnumber, + line, + quantity_purchased, + item_cost_price, + item_unit_price, + discount_percent, + item_location, + items.name as name, + category, + item_type'); + $this->db->from('sales_items as sales_items'); + $this->db->join('items as items', 'sales_items.item_id = items.item_id'); + $this->db->where('sale_id', $sale_id); + + // Entry sequence (this will render kits in the expected sequence) + if($this->config->item('line_sequence') == '1') + { + $this->db->order_by('line', 'asc'); + } + // Group by Stock Type (nonstock first - type 1, stock next - type 0) + elseif($this->config->item('line_sequence') == '2') + { + $this->db->order_by('stock_type', 'desc'); + $this->db->order_by('sales_items.description', 'asc'); + $this->db->order_by('items.name', 'asc'); + } + + // Group by Item Category + elseif($this->config->item('line_sequence') == '3') + { + $this->db->order_by('category', 'asc'); + $this->db->order_by('sales_items.description', 'asc'); + $this->db->order_by('items.name', 'asc'); + } + + // Group by entry sequence in descending sequence (the Standard) + else + { + $this->db->order_by('line', 'desc'); + } + + return $this->db->get(); + } + public function get_sale_payments($sale_id) { $this->db->from('sales_payments'); @@ -642,7 +706,7 @@ class Sale extends CI_Model public function get_payment_options($giftcard = TRUE) { $payments = array(); - + if($this->config->item('payment_options_order') == 'debitcreditcash') { $payments[$this->lang->line('sales_debit')] = $this->lang->line('sales_debit'); @@ -696,7 +760,7 @@ class Sale extends CI_Model { $this->db->where('sale_id !=', $sale_id); } - + return ($this->db->get()->num_rows() == 1); } @@ -706,7 +770,7 @@ class Sale extends CI_Model { return 0; } - + $this->db->from('giftcards'); $this->db->where('giftcard_number', $giftcardNumber); @@ -743,7 +807,7 @@ class Sale extends CI_Model } // create a temporary table to contain all the payment types and amount - $this->db->query('CREATE TEMPORARY TABLE IF NOT EXISTS ' . $this->db->dbprefix('sales_payments_temp') . + $this->db->query('CREATE TEMPORARY TABLE IF NOT EXISTS ' . $this->db->dbprefix('sales_payments_temp') . ' (PRIMARY KEY(sale_id), INDEX(sale_id)) ( SELECT payments.sale_id AS sale_id, @@ -759,38 +823,38 @@ class Sale extends CI_Model )' ); - $this->db->query('CREATE TEMPORARY TABLE IF NOT EXISTS ' . $this->db->dbprefix('sales_items_temp') . + $this->db->query('CREATE TEMPORARY TABLE IF NOT EXISTS ' . $this->db->dbprefix('sales_items_temp') . ' (INDEX(sale_date), INDEX(sale_id)) ( SELECT - DATE(sales.sale_time) AS sale_date, - sales.sale_time, + MAX(DATE(sales.sale_time)) AS sale_date, + MAX(sales.sale_time) AS sale_time, sales.sale_id, - sales.comment, - sales.invoice_number, - sales.customer_id, - CONCAT(customer_p.first_name, " ", customer_p.last_name) AS customer_name, - customer_p.first_name AS customer_first_name, - customer_p.last_name AS customer_last_name, - customer_p.email AS customer_email, - customer_p.comments AS customer_comments, - customer.company_name AS customer_company_name, - sales.employee_id, - CONCAT(employee.first_name, " ", employee.last_name) AS employee_name, + MAX(sales.comment) AS comment, + MAX(sales.invoice_number) AS invoice_number, + MAX(sales.customer_id) AS customer_id, + MAX(CONCAT(customer_p.first_name, " ", customer_p.last_name)) AS customer_name, + MAX(customer_p.first_name) AS customer_first_name, + MAX(customer_p.last_name) AS customer_last_name, + MAX(customer_p.email) AS customer_email, + MAX(customer_p.comments) AS customer_comments, + MAX(customer.company_name) AS customer_company_name, + MAX(sales.employee_id) AS employee_id, + MAX(CONCAT(employee.first_name, " ", employee.last_name)) AS employee_name, items.item_id, - items.name, - items.category, - items.supplier_id, - sales_items.quantity_purchased, - sales_items.item_cost_price, - sales_items.item_unit_price, - sales_items.discount_percent, + MAX(items.name) AS name, + MAX(items.category) AS category, + MAX(items.supplier_id) AS supplier_id, + SUM(sales_items.quantity_purchased) AS quantity_purchased, + MAX(sales_items.item_cost_price) AS item_cost_price, + MAX(sales_items.item_unit_price) AS item_unit_price, + MAX(sales_items.discount_percent) AS discount_percent, sales_items.line, - sales_items.serialnumber, - sales_items.item_location, - sales_items.description, - payments.payment_type, - payments.sale_payment_amount, + MAX(sales_items.serialnumber) AS serialnumber, + MAX(sales_items.item_location) AS item_location, + MAX(sales_items.description) AS description, + MAX(payments.payment_type) AS payment_type, + SUM(payments.sale_payment_amount) AS sale_payment_amount, IFNULL(SUM(sales_items_taxes.percent), 0) AS item_tax_percent, ' . " ROUND($sale_subtotal, $decimals) AS subtotal, diff --git a/application/models/reports/Detailed_receivings.php b/application/models/reports/Detailed_receivings.php index 8c521780c..83904400c 100644 --- a/application/models/reports/Detailed_receivings.php +++ b/application/models/reports/Detailed_receivings.php @@ -14,7 +14,7 @@ class Detailed_receivings extends Report //Create our temp tables to work with the data in our report $this->Receiving->create_temp_table($inputs); } - + public function getDataColumns() { $columns = array( @@ -26,8 +26,8 @@ class Detailed_receivings extends Report array('supplier' => $this->lang->line('reports_supplied_by')), array('total' => $this->lang->line('reports_total'), 'sorter' => 'number_sorter'), array('payment_type' => $this->lang->line('reports_payment_type')), - array('reference' => $this->lang->line('receivings_reference')), - array('comment' => $this->lang->line('reports_comments'))), + array('comment' => $this->lang->line('reports_comments')), + array('reference' => $this->lang->line('receivings_reference'))), 'details' => array( $this->lang->line('reports_item_number'), $this->lang->line('reports_name'), @@ -39,24 +39,45 @@ class Detailed_receivings extends Report return $columns; } - + public function getDataByReceivingId($receiving_id) { - $this->db->select('receiving_id, receiving_date, SUM(quantity_purchased) AS items_purchased, CONCAT(employee.first_name, " ", employee.last_name) AS employee_name, supplier.company_name AS supplier_name, SUM(subtotal) AS subtotal, SUM(total) AS total, SUM(profit) AS profit, payment_type, comment, reference'); + $this->db->select('receiving_id, + MAX(receiving_date) as receiving_date, + SUM(quantity_purchased) AS items_purchased, + MAX(CONCAT(employee.first_name, " ", employee.last_name)) AS employee_name, + MAX(supplier.company_name) AS supplier_name, + SUM(subtotal) AS subtotal, + SUM(total) AS total, + SUM(profit) AS profit, + MAX(payment_type) as payment_type, + MAX(comment) as comment, + MAX(reference) as reference'); $this->db->from('receivings_items_temp'); $this->db->join('people AS employee', 'receivings_items_temp.employee_id = employee.person_id'); $this->db->join('suppliers AS supplier', 'receivings_items_temp.supplier_id = supplier.person_id', 'left'); $this->db->where('receiving_id', $receiving_id); + $this->db->group_by('receiving_id'); - return $this->db->get()->row_array(); - } - - public function getData(array $inputs) - { - $this->db->select('receiving_id, receiving_date, SUM(quantity_purchased) AS items_purchased, CONCAT(employee.first_name," ",employee.last_name) AS employee_name, supplier.company_name AS supplier_name, SUM(total) AS total, SUM(profit) AS profit, payment_type, comment, reference'); - $this->db->from('receivings_items_temp'); - $this->db->join('people AS employee', 'receivings_items_temp.employee_id = employee.person_id'); - $this->db->join('suppliers AS supplier', 'receivings_items_temp.supplier_id = supplier.person_id', 'left'); + return $this->db->get()->row_array(); + } + + public function getData(array $inputs) + { + + $this->db->select('receiving_id, + MAX(receiving_date) as receiving_date, + SUM(quantity_purchased) AS items_purchased, + MAX(CONCAT(employee.first_name," ",employee.last_name)) AS employee_name, + MAX(supplier.company_name) AS supplier_name, + SUM(total) AS total, + SUM(profit) AS profit, + MAX(payment_type) AS payment_type, + MAX(comment) AS comment, + MAX(reference) AS reference'); + $this->db->from('receivings_items_temp AS receivings_items_temp'); + $this->db->join('people AS employee', 'receivings_items_temp.employee_id = employee.person_id'); + $this->db->join('suppliers AS supplier', 'receivings_items_temp.supplier_id = supplier.person_id', 'left'); if($inputs['location_id'] != 'all') { @@ -74,13 +95,13 @@ class Detailed_receivings extends Report { $this->db->having('items_purchased = 0'); } - $this->db->group_by('receiving_id'); - $this->db->order_by('receiving_date'); + $this->db->group_by('receiving_id', 'receiving_date'); + $this->db->order_by('receiving_id'); $data = array(); $data['summary'] = $this->db->get()->result_array(); $data['details'] = array(); - + foreach($data['summary'] as $key=>$value) { $this->db->select('name, item_number, category, quantity_purchased, serialnumber,total, discount_percent, item_location, receivings_items_temp.receiving_quantity'); @@ -89,10 +110,10 @@ class Detailed_receivings extends Report $this->db->where('receiving_id = '.$value['receiving_id']); $data['details'][$key] = $this->db->get()->result_array(); } - + return $data; } - + public function getSummaryData(array $inputs) { $this->db->select('SUM(total) AS total'); diff --git a/application/models/reports/Detailed_sales.php b/application/models/reports/Detailed_sales.php index 2996a04be..8303921a1 100644 --- a/application/models/reports/Detailed_sales.php +++ b/application/models/reports/Detailed_sales.php @@ -25,8 +25,8 @@ class Detailed_sales extends Report array('employee_name' => $this->lang->line('reports_sold_by')), array('customer_name' => $this->lang->line('reports_sold_to')), array('subtotal' => $this->lang->line('reports_subtotal'), 'sorter' => 'number_sorter'), - array('total' => $this->lang->line('reports_total'), 'sorter' => 'number_sorter'), array('tax' => $this->lang->line('reports_tax'), 'sorter' => 'number_sorter'), + array('total' => $this->lang->line('reports_total'), 'sorter' => 'number_sorter'), array('cost' => $this->lang->line('reports_cost'), 'sorter' => 'number_sorter'), array('profit' => $this->lang->line('reports_profit'), 'sorter' => 'number_sorter'), array('payment_type' => $this->lang->line('sales_amount_tendered')), @@ -43,7 +43,7 @@ class Detailed_sales extends Report $this->lang->line('reports_cost'), $this->lang->line('reports_profit'), $this->lang->line('reports_discount')) - ); + ); } public function getDataBySaleId($sale_id) @@ -57,7 +57,18 @@ class Detailed_sales extends Report public function getData(array $inputs) { - $this->db->select('sale_id, sale_date, SUM(quantity_purchased) AS items_purchased, employee_name, customer_name, SUM(subtotal) AS subtotal, SUM(tax) AS tax, SUM(total) AS total, SUM(cost) AS cost, SUM(profit) AS profit, payment_type, comment'); + $this->db->select('sale_id, + MAX(sale_date) AS sale_date, + SUM(quantity_purchased) AS items_purchased, + MAX(employee_name) AS employee_name, + MAX(customer_name) AS customer_name, + SUM(subtotal) AS subtotal, + SUM(tax) AS tax, + SUM(total) AS total, + SUM(cost) AS cost, + SUM(profit) AS profit, + MAX(payment_type) AS payment_type, + MAX(comment) AS comment'); $this->db->from('sales_items_temp'); if($inputs['location_id'] != 'all') @@ -66,16 +77,16 @@ class Detailed_sales extends Report } if($inputs['sale_type'] == 'sales') - { - $this->db->where('quantity_purchased > 0'); - } - elseif($inputs['sale_type'] == 'returns') - { - $this->db->where('quantity_purchased < 0'); - } + { + $this->db->where('quantity_purchased > 0'); + } + elseif($inputs['sale_type'] == 'returns') + { + $this->db->where('quantity_purchased < 0'); + } $this->db->group_by('sale_id'); - $this->db->order_by('sale_date'); + $this->db->order_by('MAX(sale_date)'); $data = array(); $data['summary'] = $this->db->get()->result_array(); @@ -99,17 +110,17 @@ class Detailed_sales extends Report if($inputs['location_id'] != 'all') { - $this->db->where('item_location', $inputs['location_id']); + $this->db->where('item_location', $inputs['location_id']); } if($inputs['sale_type'] == 'sales') - { - $this->db->where('quantity_purchased > 0'); - } - elseif($inputs['sale_type'] == 'returns') - { - $this->db->where('quantity_purchased < 0'); - } + { + $this->db->where('quantity_purchased > 0'); + } + elseif($inputs['sale_type'] == 'returns') + { + $this->db->where('quantity_purchased < 0'); + } return $this->db->get()->row_array(); } diff --git a/application/models/reports/Specific_customer.php b/application/models/reports/Specific_customer.php index 71ce181ca..f04abec55 100644 --- a/application/models/reports/Specific_customer.php +++ b/application/models/reports/Specific_customer.php @@ -8,13 +8,13 @@ class Specific_customer extends Report { parent::__construct(); } - + public function create(array $inputs) { //Create our temp tables to work with the data in our report $this->Sale->create_temp_table($inputs); } - + public function getDataColumns() { return array( @@ -44,29 +44,29 @@ class Specific_customer extends Report $this->lang->line('reports_discount')) ); } - + public function getData(array $inputs) { - $this->db->select('sale_id, sale_date, SUM(quantity_purchased) AS items_purchased, employee_name, SUM(subtotal) AS subtotal, SUM(tax) AS tax, SUM(total) AS total, SUM(cost) AS cost, SUM(profit) AS profit, payment_type, comment'); + $this->db->select('sale_id, MAX(sale_date) AS sale_date, SUM(quantity_purchased) AS items_purchased, MAX(employee_name) AS employee_name, SUM(subtotal) AS subtotal, SUM(tax) AS tax, SUM(total) AS total, SUM(cost) AS cost, SUM(profit) AS profit, MAX(payment_type) AS payment_type, MAX(comment) AS comment'); $this->db->from('sales_items_temp'); $this->db->where('customer_id', $inputs['customer_id']); if ($inputs['sale_type'] == 'sales') - { - $this->db->where('quantity_purchased > 0'); - } - elseif ($inputs['sale_type'] == 'returns') - { - $this->db->where('quantity_purchased < 0'); - } + { + $this->db->where('quantity_purchased > 0'); + } + elseif ($inputs['sale_type'] == 'returns') + { + $this->db->where('quantity_purchased < 0'); + } $this->db->group_by('sale_id'); - $this->db->order_by('sale_date'); + $this->db->order_by('MAX(sale_date)'); $data = array(); $data['summary'] = $this->db->get()->result_array(); $data['details'] = array(); - + foreach($data['summary'] as $key=>$value) { $this->db->select('name, category, serialnumber, description, quantity_purchased, subtotal, tax, total, cost, profit, discount_percent'); @@ -77,7 +77,7 @@ class Specific_customer extends Report return $data; } - + public function getSummaryData(array $inputs) { $this->db->select('SUM(subtotal) AS subtotal, SUM(tax) AS tax, SUM(total) AS total, SUM(cost) AS cost, SUM(profit) AS profit'); @@ -85,13 +85,13 @@ class Specific_customer extends Report $this->db->where('customer_id', $inputs['customer_id']); if ($inputs['sale_type'] == 'sales') - { - $this->db->where('quantity_purchased > 0'); - } - elseif ($inputs['sale_type'] == 'returns') - { - $this->db->where('quantity_purchased < 0'); - } + { + $this->db->where('quantity_purchased > 0'); + } + elseif ($inputs['sale_type'] == 'returns') + { + $this->db->where('quantity_purchased < 0'); + } return $this->db->get()->row_array(); } diff --git a/application/models/reports/Specific_discount.php b/application/models/reports/Specific_discount.php index 2ae0cfc11..609e7b7ce 100755 --- a/application/models/reports/Specific_discount.php +++ b/application/models/reports/Specific_discount.php @@ -8,13 +8,13 @@ class Specific_discount extends Report { parent::__construct(); } - + public function create(array $inputs) { //Create our temp tables to work with the data in our report $this->Sale->create_temp_table($inputs); } - + public function getDataColumns() { return array( @@ -40,12 +40,12 @@ class Specific_discount extends Report $this->lang->line('reports_tax'), $this->lang->line('reports_profit'), $this->lang->line('reports_discount')) - ); + ); } - + public function getData(array $inputs) { - $this->db->select('sale_id, sale_date, SUM(quantity_purchased) AS items_purchased, customer_name, SUM(subtotal) AS subtotal, SUM(tax) AS tax, SUM(total) AS total, SUM(cost) AS cost, SUM(profit) AS profit, payment_type, comment'); + $this->db->select('sale_id, MAX(sale_date) AS sales_date, SUM(quantity_purchased) AS items_purchased, MAX(customer_name) AS customer_name, SUM(subtotal) AS subtotal, SUM(tax) AS tax, SUM(total) AS total, SUM(cost) AS cost, SUM(profit) AS profit, MAX(payment_type) AS payment_type, MAX(comment) AS comment'); $this->db->from('sales_items_temp'); $this->db->where('discount_percent >=', $inputs['discount']); @@ -59,12 +59,12 @@ class Specific_discount extends Report } $this->db->group_by('sale_id'); - $this->db->order_by('sale_date'); + $this->db->order_by('MAX(sale_date)'); $data = array(); $data['summary'] = $this->db->get()->result_array(); $data['details'] = array(); - + foreach($data['summary'] as $key=>$value) { $this->db->select('name, serialnumber, category, description, quantity_purchased, subtotal, tax, total, cost, profit, discount_percent'); @@ -75,13 +75,13 @@ class Specific_discount extends Report return $data; } - + public function getSummaryData(array $inputs) { $this->db->select('SUM(subtotal) AS subtotal, SUM(tax) AS tax, SUM(total) AS total, SUM(cost) AS cost, SUM(profit) AS profit'); $this->db->from('sales_items_temp'); $this->db->where('discount_percent >=', $inputs['discount']); - + if ($inputs['sale_type'] == 'sales') { $this->db->where('quantity_purchased > 0'); diff --git a/application/models/reports/Specific_employee.php b/application/models/reports/Specific_employee.php index 2ba300d0b..8f8d489f6 100644 --- a/application/models/reports/Specific_employee.php +++ b/application/models/reports/Specific_employee.php @@ -8,13 +8,13 @@ class Specific_employee extends Report { parent::__construct(); } - + public function create(array $inputs) { //Create our temp tables to work with the data in our report $this->Sale->create_temp_table($inputs); } - + public function getDataColumns() { return array( @@ -42,31 +42,31 @@ class Specific_employee extends Report $this->lang->line('reports_cost'), $this->lang->line('reports_profit'), $this->lang->line('reports_discount')) - ); + ); } - + public function getData(array $inputs) { - $this->db->select('sale_id, sale_date, SUM(quantity_purchased) AS items_purchased, customer_name, SUM(subtotal) AS subtotal, SUM(tax) AS tax, SUM(total) AS total, SUM(cost) AS cost, SUM(profit) AS profit, payment_type, comment'); + $this->db->select('sale_id, MAX(sale_date) AS sale_date, SUM(quantity_purchased) AS items_purchased, MAX(customer_name) AS customer_name, SUM(subtotal) AS subtotal, SUM(tax) AS tax, SUM(total) AS total, SUM(cost) AS cost, SUM(profit) AS profit, MAX(payment_type) AS payment_type, MAX(comment) AS comment'); $this->db->from('sales_items_temp'); $this->db->where('employee_id', $inputs['employee_id']); - + if ($inputs['sale_type'] == 'sales') - { - $this->db->where('quantity_purchased > 0'); - } - elseif ($inputs['sale_type'] == 'returns') - { - $this->db->where('quantity_purchased < 0'); - } - + { + $this->db->where('quantity_purchased > 0'); + } + elseif ($inputs['sale_type'] == 'returns') + { + $this->db->where('quantity_purchased < 0'); + } + $this->db->group_by('sale_id'); - $this->db->order_by('sale_date'); + $this->db->order_by('MAX(sale_date)'); $data = array(); $data['summary'] = $this->db->get()->result_array(); $data['details'] = array(); - + foreach($data['summary'] as $key=>$value) { $this->db->select('name, category, serialnumber, description, quantity_purchased, subtotal, tax, total, cost, profit, discount_percent'); @@ -74,10 +74,10 @@ class Specific_employee extends Report $this->db->where('sale_id', $value['sale_id']); $data['details'][$key] = $this->db->get()->result_array(); } - + return $data; } - + public function getSummaryData(array $inputs) { $this->db->select('SUM(subtotal) AS subtotal, SUM(tax) AS tax, SUM(total) AS total, SUM(cost) AS cost, SUM(profit) AS profit'); @@ -85,13 +85,13 @@ class Specific_employee extends Report $this->db->where('employee_id', $inputs['employee_id']); if ($inputs['sale_type'] == 'sales') - { - $this->db->where('quantity_purchased > 0'); - } - elseif ($inputs['sale_type'] == 'returns') - { - $this->db->where('quantity_purchased < 0'); - } + { + $this->db->where('quantity_purchased > 0'); + } + elseif ($inputs['sale_type'] == 'returns') + { + $this->db->where('quantity_purchased < 0'); + } return $this->db->get()->row_array(); } diff --git a/application/models/reports/Summary_discounts.php b/application/models/reports/Summary_discounts.php index 338fec5b7..80a279e8b 100644 --- a/application/models/reports/Summary_discounts.php +++ b/application/models/reports/Summary_discounts.php @@ -8,7 +8,7 @@ class Summary_discounts extends Summary_report { parent::__construct(); } - + protected function _get_data_columns() { return array( @@ -18,18 +18,18 @@ class Summary_discounts extends Summary_report public function getData(array $inputs) { - $this->db->select('CONCAT(sales_items.discount_percent, "%") AS discount_percent, count(*) AS count'); + $this->db->select('MAX(CONCAT(sales_items.discount_percent, "%")) AS discount_percent, count(*) AS count'); $this->db->from('sales_items AS sales_items'); $this->db->join('sales AS sales', 'sales_items.sale_id = sales.sale_id', 'inner'); $this->db->where('discount_percent > 0'); $this->_where($inputs); - + $this->db->group_by('sales_items.discount_percent'); $this->db->order_by('sales_items.discount_percent'); - return $this->db->get()->result_array(); + return $this->db->get()->result_array(); } } ?> diff --git a/application/models/reports/Summary_employees.php b/application/models/reports/Summary_employees.php index 2e3997a1b..2824911ec 100644 --- a/application/models/reports/Summary_employees.php +++ b/application/models/reports/Summary_employees.php @@ -8,7 +8,7 @@ class Summary_employees extends Summary_report { parent::__construct(); } - + protected function _get_data_columns() { return array( @@ -26,7 +26,7 @@ class Summary_employees extends Summary_report parent::_select($inputs); $this->db->select(' - CONCAT(employee_p.first_name, " ", employee_p.last_name) AS employee, + MAX(CONCAT(employee_p.first_name, " ", employee_p.last_name)) AS employee, SUM(sales_items.quantity_purchased) AS quantity_purchased '); } diff --git a/application/models/reports/Summary_items.php b/application/models/reports/Summary_items.php index 30a57039f..515e0f636 100644 --- a/application/models/reports/Summary_items.php +++ b/application/models/reports/Summary_items.php @@ -26,7 +26,7 @@ class Summary_items extends Summary_report parent::_select($inputs); $this->db->select(' - items.name AS name, + MAX(items.name) AS name, SUM(sales_items.quantity_purchased) AS quantity_purchased '); } @@ -41,7 +41,7 @@ class Summary_items extends Summary_report protected function _group_order() { $this->db->group_by('items.item_id'); - $this->db->order_by('items.name'); + $this->db->order_by('name'); } } ?> diff --git a/application/models/reports/Summary_sales.php b/application/models/reports/Summary_sales.php index 692df096d..2c174fa76 100644 --- a/application/models/reports/Summary_sales.php +++ b/application/models/reports/Summary_sales.php @@ -26,11 +26,11 @@ class Summary_sales extends Summary_report parent::_select($inputs); $this->db->select(' - DATE(sales.sale_time) AS sale_date, + DATE(sales.sale_time) AS sale_date, SUM(sales_items.quantity_purchased) AS quantity_purchased '); } - + protected function _group_order() { $this->db->group_by('sale_date'); diff --git a/application/models/reports/Summary_suppliers.php b/application/models/reports/Summary_suppliers.php index 97b478c51..0aad9c808 100644 --- a/application/models/reports/Summary_suppliers.php +++ b/application/models/reports/Summary_suppliers.php @@ -26,7 +26,7 @@ class Summary_suppliers extends Summary_report parent::_select($inputs); $this->db->select(' - CONCAT(supplier_c.company_name, " (", supplier_p.first_name, " ", supplier_p.last_name, ")") AS supplier, + MAX(CONCAT(supplier_c.company_name, " (", supplier_p.first_name, " ", supplier_p.last_name, ")")) AS supplier, SUM(sales_items.quantity_purchased) AS quantity_purchased '); } @@ -35,15 +35,15 @@ class Summary_suppliers extends Summary_report { parent::_from(); - $this->db->join('items AS items', 'sales_items.item_id = items.item_id', 'inner'); - $this->db->join('suppliers AS supplier_c', 'supplier_c.person_id = items.supplier_id'); - $this->db->join('people AS supplier_p', 'supplier_c.person_id = supplier_p.person_id'); + $this->db->join('items AS items', 'sales_items.item_id = items.item_id'); + $this->db->join('suppliers AS supplier_c', 'items.supplier_id = supplier_c.person_id '); + $this->db->join('people AS supplier_p', 'items.supplier_id = supplier_p.person_id'); } protected function _group_order() { $this->db->group_by('items.supplier_id'); - $this->db->order_by('supplier_p.last_name'); + $this->db->order_by('MAX(CONCAT(supplier_c.company_name, " (", supplier_p.first_name, " ", supplier_p.last_name, ")"))'); } } ?> diff --git a/application/views/configs/invoice_config.php b/application/views/configs/invoice_config.php index ad5de429d..b6717b5ed 100644 --- a/application/views/configs/invoice_config.php +++ b/application/views/configs/invoice_config.php @@ -59,6 +59,13 @@ +