mirror of
https://github.com/opensourcepos/opensourcepos.git
synced 2026-02-25 11:27:21 -05:00
Merge pull request #2431 from opensourcepos/attributes_csv_import_integration
Attributes csv import integration
This commit is contained in:
@@ -89,7 +89,7 @@ $autoload['drivers'] = array();
|
||||
|
|
||||
| $autoload['helper'] = array('url', 'file');
|
||||
*/
|
||||
$autoload['helper'] = array('form', 'url', 'tabular', 'text', 'locale', 'html', 'download', 'directory', 'migration');
|
||||
$autoload['helper'] = array('form', 'url', 'tabular', 'text', 'locale', 'html', 'download', 'directory', 'migration', 'importfile');
|
||||
|
||||
/*
|
||||
| -------------------------------------------------------------------
|
||||
|
||||
@@ -10,13 +10,13 @@ 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());
|
||||
|
||||
@@ -33,8 +33,8 @@ class Items extends Secure_Controller
|
||||
}
|
||||
|
||||
/*
|
||||
Returns Items table data rows. This will be called with AJAX.
|
||||
*/
|
||||
Returns Items table data rows. This will be called with AJAX.
|
||||
*/
|
||||
public function search()
|
||||
{
|
||||
$search = $this->input->get('search');
|
||||
@@ -48,17 +48,17 @@ class Items extends Secure_Controller
|
||||
$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(),
|
||||
'empty_upc' => FALSE,
|
||||
'low_inventory' => FALSE,
|
||||
'is_serialized' => FALSE,
|
||||
'no_description' => FALSE,
|
||||
'search_custom' => FALSE,
|
||||
'is_deleted' => FALSE,
|
||||
'temporary' => FALSE,
|
||||
'definition_ids' => array_keys($definition_names));
|
||||
|
||||
'end_date' => $this->input->get('end_date'),
|
||||
'stock_location_id' => $this->item_lib->get_item_location(),
|
||||
'empty_upc' => FALSE,
|
||||
'low_inventory' => FALSE,
|
||||
'is_serialized' => FALSE,
|
||||
'no_description' => FALSE,
|
||||
'search_custom' => FALSE,
|
||||
'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);
|
||||
@@ -79,7 +79,7 @@ class Items extends Secure_Controller
|
||||
|
||||
echo json_encode(array('total' => $total_rows, 'rows' => $data_rows));
|
||||
}
|
||||
|
||||
|
||||
public function pic_thumb($pic_filename)
|
||||
{
|
||||
$this->load->helper('file');
|
||||
@@ -113,8 +113,8 @@ class Items extends Secure_Controller
|
||||
}
|
||||
|
||||
/*
|
||||
Gives search suggestions based on what is being searched for
|
||||
*/
|
||||
Gives search suggestions based on what is being searched for
|
||||
*/
|
||||
public function suggest_search()
|
||||
{
|
||||
$suggestions = $this->xss_clean($this->Item->get_search_suggestions($this->input->post_get('term'),
|
||||
@@ -149,8 +149,8 @@ class Items extends Secure_Controller
|
||||
}
|
||||
|
||||
/*
|
||||
Gives search suggestions based on what is being searched for
|
||||
*/
|
||||
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')));
|
||||
@@ -160,7 +160,7 @@ class Items extends Secure_Controller
|
||||
|
||||
/*
|
||||
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')));
|
||||
@@ -348,14 +348,14 @@ class Items extends Secure_Controller
|
||||
{
|
||||
$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);
|
||||
@@ -371,7 +371,7 @@ class Items extends Secure_Controller
|
||||
{
|
||||
$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;
|
||||
}
|
||||
@@ -393,14 +393,14 @@ class Items extends Secure_Controller
|
||||
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
|
||||
@@ -428,7 +428,7 @@ 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);
|
||||
@@ -444,7 +444,7 @@ class Items extends Secure_Controller
|
||||
unset($data['definition_names'][$definition_id]);
|
||||
}
|
||||
|
||||
$this->load->view('attributes/item', $data);
|
||||
$this->load->view('attributes/item', $data);
|
||||
}
|
||||
|
||||
public function bulk_edit()
|
||||
@@ -458,12 +458,12 @@ class Items extends Secure_Controller
|
||||
}
|
||||
$data['suppliers'] = $suppliers;
|
||||
$data['allow_alt_description_choices'] = array(
|
||||
'' => $this->lang->line('items_do_nothing'),
|
||||
'' => $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'),
|
||||
'' => $this->lang->line('items_do_nothing'),
|
||||
1 => $this->lang->line('items_change_all_to_serialized'),
|
||||
0 => $this->lang->line('items_change_all_to_unserialized'));
|
||||
|
||||
@@ -535,7 +535,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
|
||||
@@ -544,7 +544,7 @@ 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))
|
||||
@@ -587,8 +587,8 @@ class Items extends Secure_Controller
|
||||
$updated_quantity = 0;
|
||||
}
|
||||
$location_detail = array('item_id' => $item_id,
|
||||
'location_id' => $location['location_id'],
|
||||
'quantity' => $updated_quantity);
|
||||
'location_id' => $location['location_id'],
|
||||
'quantity' => $updated_quantity);
|
||||
|
||||
|
||||
$item_quantity = $this->Item_quantity->get_item_quantity($item_id, $location['location_id']);
|
||||
@@ -639,11 +639,11 @@ class Items extends Secure_Controller
|
||||
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'));
|
||||
@@ -651,8 +651,8 @@ class Items extends Secure_Controller
|
||||
}
|
||||
|
||||
/*
|
||||
If adding a new item check to see if an item kit with the same name as the item already exists.
|
||||
*/
|
||||
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)
|
||||
@@ -669,7 +669,7 @@ class Items extends Secure_Controller
|
||||
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',
|
||||
@@ -679,7 +679,7 @@ 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(), '<p>'.$this->lang->line('upload_no_file_selected').'</p>');
|
||||
}
|
||||
|
||||
@@ -692,7 +692,7 @@ class Items extends Secure_Controller
|
||||
}
|
||||
|
||||
public function save_inventory($item_id = -1)
|
||||
{
|
||||
{
|
||||
$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');
|
||||
@@ -704,9 +704,9 @@ class Items extends Secure_Controller
|
||||
'trans_comment' => $this->input->post('trans_comment'),
|
||||
'trans_inventory' => parse_decimals($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(
|
||||
@@ -718,13 +718,13 @@ class Items extends Secure_Controller
|
||||
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));
|
||||
}
|
||||
}
|
||||
@@ -735,10 +735,10 @@ class Items extends Secure_Controller
|
||||
$item_data = array();
|
||||
|
||||
foreach($_POST as $key => $value)
|
||||
{
|
||||
{
|
||||
//This field is nullable, so treat it differently
|
||||
if($key == 'supplier_id' && $value != '')
|
||||
{
|
||||
{
|
||||
$item_data["$key"] = $value;
|
||||
}
|
||||
elseif($value != '' && !(in_array($key, array('item_ids', 'tax_names', 'tax_percents'))))
|
||||
@@ -756,15 +756,15 @@ class Items extends Secure_Controller
|
||||
$tax_updated = FALSE;
|
||||
$count = count($tax_percents);
|
||||
for($k = 0; $k < $count; ++$k)
|
||||
{
|
||||
{
|
||||
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);
|
||||
@@ -794,183 +794,108 @@ class Items extends Secure_Controller
|
||||
}
|
||||
|
||||
/*
|
||||
Items import from excel spreadsheet
|
||||
*/
|
||||
Items import from excel spreadsheet
|
||||
*/
|
||||
public function excel()
|
||||
{
|
||||
$name = 'import_items.csv';
|
||||
$data = file_get_contents('../' . $name);
|
||||
force_download($name, $data);
|
||||
$allowed_locations = $this->Stock_location->get_allowed_locations();
|
||||
$allowed_attributes = $this->Attribute->get_definition_names(FALSE);
|
||||
$data = generate_import_items_csv($allowed_locations,$allowed_attributes);
|
||||
force_download($name, $data, TRUE);
|
||||
}
|
||||
|
||||
|
||||
public function excel_import()
|
||||
{
|
||||
$this->load->view('items/form_excel_import', NULL);
|
||||
}
|
||||
|
||||
/**
|
||||
* Imports items from CSV formatted file.
|
||||
*/
|
||||
public function do_excel_import()
|
||||
{
|
||||
$non_repeating_element_count = 18;
|
||||
|
||||
if($_FILES['file_path']['error'] != UPLOAD_ERR_OK)
|
||||
{
|
||||
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)
|
||||
if(file_exists($_FILES['file_path']['tmp_name']))
|
||||
{
|
||||
// Skip the first row as it's the table description
|
||||
fgetcsv($handle);
|
||||
$i = 1;
|
||||
|
||||
$failCodes = array();
|
||||
$line_array = get_csv_file($_FILES['file_path']['tmp_name']);
|
||||
$failCodes = array();
|
||||
$keys = $line_array[0];
|
||||
|
||||
while(($data = fgetcsv($handle)) !== FALSE)
|
||||
$this->db->trans_begin();
|
||||
for($i = 1; $i < count($line_array); $i++)
|
||||
{
|
||||
// XSS file data sanity check
|
||||
$data = $this->xss_clean($data);
|
||||
|
||||
if(sizeof($data) >= $non_repeating_element_count)
|
||||
$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(
|
||||
'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',
|
||||
'hsn_code' => $data[15]
|
||||
'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']
|
||||
);
|
||||
|
||||
/* we could do something like this, however, the effectiveness of
|
||||
this is rather limited, since for now, you have to upload files manually
|
||||
into that directory, so you really can do whatever you want, this probably
|
||||
needs further discussion */
|
||||
$item_number = $line['Barcode'];
|
||||
|
||||
$pic_file = $data[14];
|
||||
/*if(strcmp('.htaccess', $pic_file)==0)
|
||||
{
|
||||
$pic_file='';
|
||||
}*/
|
||||
$item_data['pic_filename'] = $pic_file;
|
||||
|
||||
$item_number = $data[0];
|
||||
$invalidated = FALSE;
|
||||
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);
|
||||
}
|
||||
}
|
||||
else
|
||||
else
|
||||
{
|
||||
$invalidated = TRUE;
|
||||
}
|
||||
|
||||
//Save to database
|
||||
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] );
|
||||
}
|
||||
|
||||
// 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';
|
||||
|
||||
$cols = count($data);
|
||||
|
||||
// array to store information if location got a quantity
|
||||
$allowed_locations = $this->Stock_location->get_allowed_locations();
|
||||
for($col = 16; $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]
|
||||
);
|
||||
|
||||
$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]);
|
||||
|
||||
$excel_data = array(
|
||||
'trans_items' => $item_data['item_id'],
|
||||
'trans_user' => $employee_id,
|
||||
'trans_comment' => $comment,
|
||||
'trans_location' => $location_id,
|
||||
'trans_inventory' => 0
|
||||
);
|
||||
|
||||
$this->Inventory->insert($excel_data);
|
||||
}
|
||||
$this->save_tax_data($line, $item_data);
|
||||
$this->save_inventory_quantities($line, $item_data);
|
||||
$this->save_attribute_data($line, $item_data);
|
||||
}
|
||||
else //insert or update item failure
|
||||
{
|
||||
$failCodes[] = $i;
|
||||
$failed_row = $i+1;
|
||||
$failCodes[] = $failed_row;
|
||||
log_message("ERROR","CSV Item import failed on line ". $failed_row .". This item was not imported.");
|
||||
}
|
||||
|
||||
++$i;
|
||||
}
|
||||
|
||||
if(count($failCodes) > 0)
|
||||
{
|
||||
$message = $this->lang->line('items_excel_import_partially_failed') . ' (' . count($failCodes) . '): ' . implode(', ', $failCodes);
|
||||
|
||||
$message = $this->lang->line('items_excel_import_partially_failed', count($failCodes), implode(', ', $failCodes));
|
||||
$this->db->trans_rollback();
|
||||
echo json_encode(array('success' => FALSE, 'message' => $message));
|
||||
}
|
||||
else
|
||||
{
|
||||
$this->db->trans_commit();
|
||||
echo json_encode(array('success' => TRUE, 'message' => $this->lang->line('items_excel_import_success')));
|
||||
}
|
||||
}
|
||||
else
|
||||
else
|
||||
{
|
||||
echo json_encode(array('success' => FALSE, 'message' => $this->lang->line('items_excel_import_nodata_wrongformat')));
|
||||
}
|
||||
@@ -978,9 +903,202 @@ class Items extends Secure_Controller
|
||||
}
|
||||
|
||||
/**
|
||||
* 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
|
||||
* Checks the entire line of data for errors
|
||||
*
|
||||
* @param array $line
|
||||
* @param array $item_data
|
||||
*
|
||||
* @return bool Returns FALSE if all data checks out and TRUE when there is an error in the data
|
||||
*/
|
||||
private function data_error_check($line, $item_data)
|
||||
{
|
||||
//Check for empty required fields
|
||||
$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))
|
||||
{
|
||||
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'],
|
||||
$item_data['unit_price'],
|
||||
$item_data['reorder_level'],
|
||||
$item_data['supplier_id'],
|
||||
$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)
|
||||
{
|
||||
if(!is_numeric($value) && $value != '')
|
||||
{
|
||||
log_message("ERROR","non-numeric: '$value' when numeric is required");
|
||||
return TRUE;
|
||||
}
|
||||
}
|
||||
|
||||
//Check Attribute Data
|
||||
$definition_names = $this->Attribute->get_definition_names();
|
||||
|
||||
foreach($definition_names as $definition_name)
|
||||
{
|
||||
if(!empty($line['attribute_' . $definition_name]))
|
||||
{
|
||||
$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");
|
||||
return TRUE;
|
||||
}
|
||||
}
|
||||
else if($attribute_type == 'DECIMAL')
|
||||
{
|
||||
if(!is_numeric($attribute_value) && $attribute_value != '')
|
||||
{
|
||||
log_message("ERROR","Decimal required: '$attribute_value' is not an acceptable DECIMAL value");
|
||||
return TRUE;
|
||||
}
|
||||
}
|
||||
else if($attribute_type == 'DATETIME')
|
||||
{
|
||||
if(strtotime($attribute_value) === FALSE)
|
||||
{
|
||||
log_message("ERROR","Datetime required: '$attribute_value' is not an acceptable DATETIME value");
|
||||
return TRUE;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param line
|
||||
* @param failCodes
|
||||
* @param attribute_data
|
||||
*/
|
||||
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]))
|
||||
{
|
||||
//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;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Saves inventory quantities for the row in the appropriate stock locations.
|
||||
*
|
||||
* @param array line
|
||||
* @param item_data
|
||||
*/
|
||||
private function save_inventory_quantities($line, $item_data)
|
||||
{
|
||||
//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
|
||||
);
|
||||
|
||||
$excel_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);
|
||||
|
||||
$excel_data['trans_inventory'] = $line['location_' . $location_name];
|
||||
$this->Inventory->insert($excel_data);
|
||||
}
|
||||
else
|
||||
{
|
||||
$item_quantity_data['quantity'] = 0;
|
||||
$this->Item_quantity->save($item_quantity_data, $item_data['item_id'], $line[$col]);
|
||||
|
||||
$excel_data['trans_inventory'] = 0;
|
||||
$this->Inventory->insert($excel_data);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Saves the tax data found in the line of the CSV items import file
|
||||
*
|
||||
* @param array line
|
||||
*/
|
||||
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
|
||||
*
|
||||
* @param $item the item to update
|
||||
*/
|
||||
private function _update_pic_filename($item)
|
||||
|
||||
80
application/helpers/importfile_helper.php
Normal file
80
application/helpers/importfile_helper.php
Normal file
@@ -0,0 +1,80 @@
|
||||
<?php if (!defined('BASEPATH')) exit('No direct script access allowed');
|
||||
|
||||
/**
|
||||
* Generates the header content for the import_items.csv file
|
||||
*
|
||||
* @return string Comma separated headers for the CSV file
|
||||
*/
|
||||
function generate_import_items_csv($stock_locations,$attributes)
|
||||
{
|
||||
$csv_headers = pack("CCC",0xef,0xbb,0xbf); //Encode the Byte-Order Mark (BOM) so that UTF-8 File headers display properly in Microsoft Excel
|
||||
$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;
|
||||
}
|
||||
|
||||
/**
|
||||
* Generates a list of stock location names as a string
|
||||
*
|
||||
* @return string Comma-separated list of stock location names
|
||||
*/
|
||||
function generate_stock_location_headers($locations)
|
||||
{
|
||||
$location_headers = "";
|
||||
|
||||
foreach($locations as $location_id => $location_name)
|
||||
{
|
||||
$location_headers .= ',"location_' . $location_name . '"';
|
||||
}
|
||||
|
||||
return $location_headers;
|
||||
}
|
||||
|
||||
/**
|
||||
* Generates a list of attribute names as a string
|
||||
*
|
||||
* @return string Comma-separated list of attribute names
|
||||
*/
|
||||
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;
|
||||
}
|
||||
|
||||
/**
|
||||
* Read the contents of a given CSV formatted file into a two-dimensional array
|
||||
*
|
||||
* @param string $file_name Name of the file to read.
|
||||
* @return boolean|array[][] two-dimensional array with the file contents or FALSE on failure.
|
||||
*/
|
||||
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
|
||||
fseek($csv_file, 3);
|
||||
|
||||
while (($data = fgetcsv($csv_file)) !== FALSE)
|
||||
{
|
||||
$line_array[] = $data;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
return $line_array;
|
||||
}
|
||||
?>
|
||||
@@ -34,7 +34,7 @@ $lang["items_error_adding_updating"] = "Error adding/updating item";
|
||||
$lang["items_error_updating_multiple"] = "Error updating items";
|
||||
$lang["items_excel_import_failed"] = "The excel import failed";
|
||||
$lang["items_excel_import_nodata_wrongformat"] = "The uploaded file has no data or is formatted incorrectly";
|
||||
$lang["items_excel_import_partially_failed"] = "Item import successful with some failures:";
|
||||
$lang["items_excel_import_partially_failed"] = "There were %1 item import failure(s) on line(s): %2. No rows were imported";
|
||||
$lang["items_excel_import_success"] = "Item import successful";
|
||||
$lang["items_generate_barcodes"] = "Generate Barcodes";
|
||||
$lang["items_hsn_code"] = "Harmonised System Nomenclature";
|
||||
@@ -43,6 +43,7 @@ $lang["items_import_items_excel"] = "Item Import from Excel";
|
||||
$lang["items_info_provided_by"] = "Information provided by";
|
||||
$lang["items_inventory"] = "Inventory";
|
||||
$lang["items_inventory_comments"] = "Comments";
|
||||
$lang["items_inventory_CSV_import_quantity"] = "Quantity Imported from CSV";
|
||||
$lang["items_inventory_data_tracking"] = "Inventory Data Tracking";
|
||||
$lang["items_inventory_date"] = "Date";
|
||||
$lang["items_inventory_employee"] = "Employee";
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
<?php
|
||||
<?php
|
||||
|
||||
$lang["items_add_minus"] = "Inventory to add or subtract.";
|
||||
$lang["items_allow_alt_description"] = "Allow Alternate Description";
|
||||
@@ -34,7 +34,7 @@ $lang["items_error_adding_updating"] = "Error adding/updating item";
|
||||
$lang["items_error_updating_multiple"] = "Error updating items";
|
||||
$lang["items_excel_import_failed"] = "Excel import failed";
|
||||
$lang["items_excel_import_nodata_wrongformat"] = "The uploaded file has no data or is formatted incorrectly.";
|
||||
$lang["items_excel_import_partially_failed"] = "Item import successful with some failures:";
|
||||
$lang["items_excel_import_partially_failed"] = "There were %1 item import failure(s) on line(s): %2. No rows were imported.";
|
||||
$lang["items_excel_import_success"] = "Item import successful.";
|
||||
$lang["items_generate_barcodes"] = "Generate Barcodes";
|
||||
$lang["items_hsn_code"] = "Harmonized System Nomenclature";
|
||||
@@ -43,6 +43,7 @@ $lang["items_import_items_excel"] = "Item Import from Excel";
|
||||
$lang["items_info_provided_by"] = "Information provided by";
|
||||
$lang["items_inventory"] = "Inventory";
|
||||
$lang["items_inventory_comments"] = "Comments";
|
||||
$lang["items_inventory_CSV_import_quantity"] = "Quantity Imported from CSV";
|
||||
$lang["items_inventory_data_tracking"] = "Inventory Data Tracking";
|
||||
$lang["items_inventory_date"] = "Date";
|
||||
$lang["items_inventory_employee"] = "Employee";
|
||||
|
||||
@@ -17,14 +17,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 +33,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 +50,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,10 +65,10 @@ class Attribute extends CI_Model
|
||||
$this->db->distinct('attribute_id');
|
||||
$this->db->from('attribute_values');
|
||||
$this->db->where('attribute_value', $attribute_value);
|
||||
|
||||
|
||||
return $this->db->get()->row()->attribute_id;
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
Gets information about a particular attribute definition
|
||||
*/
|
||||
@@ -78,9 +78,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();
|
||||
@@ -89,17 +89,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
|
||||
*/
|
||||
@@ -108,22 +108,22 @@ class Attribute extends CI_Model
|
||||
$this->db->select('definition_group.definition_name AS definition_group, definition.*');
|
||||
$this->db->from('attribute_definitions AS definition');
|
||||
$this->db->join('attribute_definitions AS definition_group', 'definition_group.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');
|
||||
@@ -132,51 +132,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');
|
||||
@@ -185,47 +185,60 @@ 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');
|
||||
}
|
||||
|
||||
public function get_definition_names()
|
||||
|
||||
|
||||
/**
|
||||
* Returns an array of attribute definition names and IDs
|
||||
*
|
||||
* @param boolean $groups If FALSE does not return GROUP type attributes in the array
|
||||
* @return array Array containing definition IDs, attribute names and -1 index with the local language '[SELECT]' line.
|
||||
*/
|
||||
public function get_definition_names($groups = TRUE)
|
||||
{
|
||||
$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
|
||||
*/
|
||||
@@ -233,10 +246,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
|
||||
*/
|
||||
@@ -244,11 +257,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');
|
||||
@@ -256,7 +269,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 === DATETIME)
|
||||
{
|
||||
foreach($this->db->get()->result_array() as $row)
|
||||
@@ -282,22 +295,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 === DATETIME || $to_type === DECIMAL)
|
||||
{
|
||||
$field = ($to_type === DATETIME ? 'attribute_datetime' : '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 ';
|
||||
@@ -305,7 +318,7 @@ 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();
|
||||
}
|
||||
}
|
||||
@@ -314,30 +327,30 @@ class Attribute extends CI_Model
|
||||
$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
|
||||
*/
|
||||
@@ -345,23 +358,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');
|
||||
$this->db->select('definition_type, definition_name');
|
||||
$this->db->from('attribute_definitions');
|
||||
$this->db->where('definition_id',$definition_id);
|
||||
|
||||
$from_definition_type = $this->db->get()->row()->definition_type;
|
||||
|
||||
$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))
|
||||
@@ -369,32 +385,35 @@ 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)
|
||||
|
||||
public function get_definition_by_name($definition_name, $definition_type = FALSE)
|
||||
{
|
||||
$this->db->from('attribute_definitions');
|
||||
$this->db->where('definition_name', $definition_name);
|
||||
$this->db->where('definition_type', $definition_type);
|
||||
|
||||
return $this->db->get()->row_object();
|
||||
if($definition_type != FALSE)
|
||||
{
|
||||
$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);
|
||||
@@ -407,30 +426,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)
|
||||
{
|
||||
$this->db->select('GROUP_CONCAT(attribute_value SEPARATOR ", ") AS attribute_values, GROUP_CONCAT(attribute_datetime SEPARATOR ", ") AS attribute_datetimevalues');
|
||||
@@ -439,7 +458,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);
|
||||
@@ -451,26 +470,26 @@ class Attribute extends CI_Model
|
||||
}
|
||||
$this->db->where('item_id', (int) $item_id);
|
||||
$this->db->where('definition_flags & ', $definition_flags);
|
||||
|
||||
|
||||
$results = $this->db->get();
|
||||
|
||||
|
||||
if ($results->num_rows() > 0)
|
||||
{
|
||||
$row_object = $results->row_object();
|
||||
|
||||
|
||||
$datetime_values = explode(', ', $row_object->attribute_datetimevalues);
|
||||
$attribute_values = array();
|
||||
|
||||
|
||||
foreach (array_filter($datetime_values) as $datetime_value)
|
||||
{
|
||||
$attribute_values[] = to_datetime(strtotime($datetime_value));
|
||||
}
|
||||
|
||||
|
||||
return implode(',', $attribute_values) . $row_object->attribute_values;
|
||||
}
|
||||
return "";
|
||||
}
|
||||
|
||||
|
||||
public function get_attribute_value($item_id, $definition_id)
|
||||
{
|
||||
$this->db->from('attribute_values');
|
||||
@@ -479,10 +498,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(
|
||||
@@ -492,7 +511,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();
|
||||
@@ -510,14 +529,14 @@ 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)
|
||||
{
|
||||
$this->db->trans_start();
|
||||
|
||||
|
||||
if(empty($attribute_id) || empty($item_id))
|
||||
{
|
||||
if($definition_type == TEXT || $definition_type == DROPDOWN)
|
||||
@@ -543,7 +562,7 @@ class Attribute extends CI_Model
|
||||
$this->db->insert('attribute_values', array('attribute_datetime' => date('Y-m-d H:i:s', strtotime($attribute_value))));
|
||||
$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,
|
||||
@@ -554,29 +573,35 @@ class Attribute extends CI_Model
|
||||
$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
|
||||
*
|
||||
* @param unknown $definition_id Attribute definition ID to remove.
|
||||
* @return boolean TRUE if successful and FALSE if there is a failure
|
||||
*/
|
||||
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));
|
||||
}
|
||||
}
|
||||
|
||||
@@ -109,27 +109,27 @@ class Stock_location extends CI_Model
|
||||
{
|
||||
$this->db->trans_start();
|
||||
|
||||
$this->db->insert('stock_locations', $location_data_to_save);
|
||||
$location_id = $this->db->insert_id();
|
||||
$this->db->insert('stock_locations', $location_data_to_save);
|
||||
$location_id = $this->db->insert_id();
|
||||
|
||||
$this->_insert_new_permission('items', $location_id, $location_name);
|
||||
$this->_insert_new_permission('sales', $location_id, $location_name);
|
||||
$this->_insert_new_permission('receivings', $location_id, $location_name);
|
||||
$this->_insert_new_permission('items', $location_id, $location_name);
|
||||
$this->_insert_new_permission('sales', $location_id, $location_name);
|
||||
$this->_insert_new_permission('receivings', $location_id, $location_name);
|
||||
|
||||
// insert quantities for existing items
|
||||
$items = $this->Item->get_all();
|
||||
foreach($items->result_array() as $item)
|
||||
{
|
||||
$quantity_data = array('item_id' => $item['item_id'], 'location_id' => $location_id, 'quantity' => 0);
|
||||
$this->db->insert('item_quantities', $quantity_data);
|
||||
}
|
||||
// insert quantities for existing items
|
||||
$items = $this->Item->get_all();
|
||||
foreach($items->result_array() as $item)
|
||||
{
|
||||
$quantity_data = array('item_id' => $item['item_id'], 'location_id' => $location_id, 'quantity' => 0);
|
||||
$this->db->insert('item_quantities', $quantity_data);
|
||||
}
|
||||
|
||||
$this->db->trans_complete();
|
||||
$this->db->trans_complete();
|
||||
|
||||
return $this->db->trans_status();
|
||||
}
|
||||
}
|
||||
|
||||
$original_location_name = $this->get_location_name($location_id);
|
||||
$original_location_name = $this->get_location_name($location_id);
|
||||
|
||||
if($original_location_name != $location_name)
|
||||
{
|
||||
@@ -167,7 +167,7 @@ class Stock_location extends CI_Model
|
||||
|
||||
/*
|
||||
Deletes one item
|
||||
*/
|
||||
*/
|
||||
public function delete($location_id)
|
||||
{
|
||||
$this->db->trans_start();
|
||||
|
||||
@@ -1,2 +0,0 @@
|
||||
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,location_id,quantity
|
||||
33333334,Apple iMac,Computers,,800,1200,Tax 1,8,Tax 2,10,1,Best Computer ever,y,,item.jpg,,1,100
|
||||
|
Reference in New Issue
Block a user