diff --git a/application/helpers/locale_helper.php b/application/helpers/locale_helper.php index b8275e38f..9dba8b498 100644 --- a/application/helpers/locale_helper.php +++ b/application/helpers/locale_helper.php @@ -12,18 +12,18 @@ define('DEFAULT_DATETIME', mktime(0, 0, 0, 1, 1, 2010)); function current_language_code($load_system_language = FALSE) { $employee = get_instance()->Employee; - + // Returns the language code of the employee if set or system language code if not if($employee->is_logged_in() && $load_system_language != TRUE) { $employee_info = $employee->get_logged_in_employee_info(); - + if(property_exists($employee_info, 'language_code') && !empty($employee_info->language_code)) { return $employee_info->language_code; } } - + $language_code = get_instance()->config->item('language_code'); return empty($language_code) ? DEFAULT_LANGUAGE_CODE : $language_code; } @@ -31,7 +31,7 @@ function current_language_code($load_system_language = FALSE) function current_language($load_system_language = FALSE) { $employee = get_instance()->Employee; - + // Returns the language of the employee if set or system language if not if($employee->is_logged_in() && $load_system_language != TRUE) { @@ -41,7 +41,7 @@ function current_language($load_system_language = FALSE) return $employee_info->language; } } - + $language = get_instance()->config->item('language'); return empty($language) ? DEFAULT_LANGUAGE : $language; } @@ -79,7 +79,7 @@ function get_languages() function load_language($load_system_language = FALSE, array $lang_array) { $lang = get_instance()->lang; - + if($load_system_language = TRUE) { foreach($lang_array as $language_file) @@ -218,16 +218,16 @@ function get_timeformats() /* -Gets the payment options -*/ + Gets the payment options + */ function get_payment_options() { $config = get_instance()->config; $lang = get_instance()->lang; - + $payments = array(); - - + + if($config->item('payment_options_order') == 'debitcreditcash') { $payments[$lang->line('sales_debit')] = $lang->line('sales_debit'); @@ -258,62 +258,62 @@ function get_payment_options() $payments[$lang->line('sales_debit')] = $lang->line('sales_debit'); $payments[$lang->line('sales_credit')] = $lang->line('sales_credit'); } - + $payments[$lang->line('sales_due')] = $lang->line('sales_due'); $payments[$lang->line('sales_check')] = $lang->line('sales_check'); - + // If India (list of country codes include India) then include Unified Payment Interface if (stripos(get_instance()->config->item('country_codes'), 'IN') !== false) { $payments[$lang->line('sales_upi')] = $lang->line('sales_upi'); } - - + + return $payments; } function currency_side() { $config = get_instance()->config; - + $fmt = new \NumberFormatter($config->item('number_locale'), \NumberFormatter::CURRENCY); $fmt->setSymbol(\NumberFormatter::CURRENCY_SYMBOL, $config->item('currency_symbol')); - + return !preg_match('/^ยค/', $fmt->getPattern()); } function quantity_decimals() { $config = get_instance()->config; - + return $config->item('quantity_decimals') ? $config->item('quantity_decimals') : 0; } function totals_decimals() { $config = get_instance()->config; - + return $config->item('currency_decimals') ? $config->item('currency_decimals') : 0; } function cash_decimals() { $config = get_instance()->config; - + return $config->item('cash_decimals') ? $config->item('cash_decimals') : 0; } function tax_decimals() { $config = get_instance()->config; - + return $config->item('tax_decimals') ? $config->item('tax_decimals') : 0; } function to_datetime($datetime) { $config = get_instance()->config; - + return date($config->item('dateformat') . ' ' . $config->item('timeformat'), $datetime); } @@ -330,7 +330,7 @@ function to_currency_no_money($number) function to_currency_tax($number) { $config = get_instance()->config; - + if($config->item('tax_included') == '1') { return to_decimals($number, 'tax_decimals', \NumberFormatter::CURRENCY); @@ -349,7 +349,7 @@ function to_tax_decimals($number) { return $number; } - + return to_decimals($number, 'tax_decimals'); } @@ -366,7 +366,7 @@ function to_decimals($number, $decimals, $type=\NumberFormatter::DECIMAL) { return $number; } - + $config = get_instance()->config; $fmt = new \NumberFormatter($config->item('number_locale'), $type); $fmt->setAttribute(\NumberFormatter::MIN_FRACTION_DIGITS, $config->item($decimals)); @@ -376,7 +376,7 @@ function to_decimals($number, $decimals, $type=\NumberFormatter::DECIMAL) $fmt->setAttribute(\NumberFormatter::GROUPING_SEPARATOR_SYMBOL, ''); } $fmt->setSymbol(\NumberFormatter::CURRENCY_SYMBOL, $config->item('currency_symbol')); - + return $fmt->format($number); } @@ -387,17 +387,17 @@ function parse_decimals($number) { return $number; } - + $config = get_instance()->config; $fmt = new \NumberFormatter($config->item('number_locale'), \NumberFormatter::DECIMAL); - + $fmt->setAttribute(\NumberFormatter::FRACTION_DIGITS, $config->item('currency_decimals')); - + if(empty($config->item('thousands_separator'))) { $fmt->setAttribute(\NumberFormatter::GROUPING_SEPARATOR_SYMBOL, ''); } - + try { return $fmt->parse($number); @@ -453,7 +453,7 @@ function dateformat_momentjs($php_format) 'r' => '', // no equivalent 'U' => 'X' ); - + return strtr($php_format, $SYMBOLS_MATCHING); } @@ -494,7 +494,7 @@ function dateformat_bootstrap($php_format) 's' => 'ss', 'u' => '' ); - + return strtr($php_format, $SYMBOLS_MATCHING); } @@ -502,4 +502,10 @@ function valid_datetime($datetime) { return preg_match('/^([0-9]{2,4})-([0-1][0-9])-([0-3][0-9])(?:( [0-2][0-9]):([0-5][0-9]):([0-5][0-9]))?$/', $datetime); } + +function valid_decimal($decimal) +{ + return preg_match('/^(\d*\.)?\d+$/', $decimal); +} + ?> \ No newline at end of file diff --git a/application/models/Attribute.php b/application/models/Attribute.php index aa8ed0342..d34c725f7 100644 --- a/application/models/Attribute.php +++ b/application/models/Attribute.php @@ -2,10 +2,11 @@ define('GROUP', 'GROUP'); define('DROPDOWN', 'DROPDOWN'); +define('DECIMAL', 'DECIMAL'); define('DATETIME', 'DATETIME'); define('TEXT', 'TEXT'); -const DEFINITION_TYPES = [GROUP, DROPDOWN, TEXT, DATETIME]; +const DEFINITION_TYPES = [GROUP, DROPDOWN, DECIMAL, TEXT, DATETIME]; /** * Attribute class @@ -16,26 +17,26 @@ 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 - */ + Determines if a given definition_id is an attribute + */ public function exists($definition_id, $deleted = FALSE) { $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'); @@ -49,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 */ @@ -67,19 +68,19 @@ class Attribute extends CI_Model return $this->db->get()->row()->attribute_id; } - + /* - Gets information about a particular attribute definition - */ + Gets information about a particular attribute definition + */ public function get_info($definition_id) { $this->db->select('parent_definition.definition_name AS definition_group, definition.*'); $this->db->from('attribute_definitions AS definition'); $this->db->join('attribute_definitions AS parent_definition', 'parent_definition.definition_id = definition.definition_fk', 'left'); $this->db->where('definition.definition_id', $definition_id); - + $query = $this->db->get(); - + if($query->num_rows() == 1) { return $query->row(); @@ -88,41 +89,41 @@ 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 - */ + Performs a search on attribute definitions + */ public function search($search, $rows = 0, $limit_from = 0, $sort = 'definition.definition_name', $order = 'asc') { $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'); @@ -131,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'); @@ -184,71 +185,71 @@ 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() { $this->db->from('attribute_definitions'); $this->db->where('deleted', 0); $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 - */ + Gets total of rows + */ public function get_total_rows() { $this->db->from('attribute_definitions'); $this->db->where('deleted', 0); - + return $this->db->count_all_results(); } - + /* - Get number of rows - */ + Get number of rows + */ public function get_found_rows($search) { return $this->search($search)->num_rows(); } - + private function check_data_validity($definition, $from, $to) { $success = FALSE; - - if($from === TEXT && $to === DATETIME) + + if($from === TEXT) { $this->db->select('item_id,attribute_value'); $this->db->from('attribute_values'); @@ -256,12 +257,26 @@ class Attribute extends CI_Model $this->db->where('definition_id',$definition); $success = TRUE; - foreach($this->db->get()->result_array() as $row) + if($to === DATETIME) { - if(valid_datetime($row['attribute_value']) === FALSE) + foreach($this->db->get()->result_array() as $row) { - log_message('ERROR', 'item_id: ' . $row['item_id'] . ' with attribute_value: ' . $row['attribute_value'] . ' cannot be converted to datetime'); - $success = FALSE; + if(valid_datetime($row['attribute_value']) === FALSE) + { + log_message('ERROR', 'item_id: ' . $row['item_id'] . ' with attribute_value: ' . $row['attribute_value'] . ' cannot be converted to datetime'); + $success = FALSE; + } + } + } + else if($to === DECIMAL) + { + foreach($this->db->get()->result_array() as $row) + { + if(valid_decimal($row['attribute_value']) === FALSE) + { + log_message('ERROR', 'item_id: ' . $row['item_id'] . ' with attribute_value: ' . $row['attribute_value'] . ' cannot be converted to decimal'); + $success = FALSE; + } } } } @@ -273,23 +288,30 @@ class Attribute extends CI_Model $success = FALSE; //From TEXT to DATETIME - if($from_type === TEXT && $to_type === DATETIME) + if($from_type === TEXT) { - if($this->check_data_validity($definition_id, $from_type, $to_type)) + if($to_type === DATETIME || $to_type === DECIMAL) { - $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 '; - $query .= 'SET attribute_datetime = attribute_value, '; - $query .= 'attribute_value = NULL '; - $query .= 'WHERE definition_id = ' . $this->db->escape($definition_id); - $success = $this->db->query($query); - - $this->db->trans_complete(); + $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 '; + $query .= 'SET '. $field .'= attribute_value, '; + $query .= 'attribute_value = NULL '; + $query .= 'WHERE definition_id = ' . $this->db->escape($definition_id); + $success = $this->db->query($query); + + $this->db->trans_complete(); + } } } + + //From DROPDOWN to TEXT else if($from_type === DROPDOWN) { //From DROPDOWN to TEXT @@ -308,13 +330,13 @@ class Attribute extends CI_Model { $success = TRUE; } - + return $success; } /* - Inserts or updates a definition - */ + Inserts or updates a definition + */ public function save_definition(&$definition_data, $definition_id = -1) { //Run these queries as a transaction, we want to make sure we do all or nothing @@ -348,27 +370,27 @@ class Attribute extends CI_Model $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) { $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(); } - + 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); @@ -381,39 +403,39 @@ 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'); + $this->db->select('GROUP_CONCAT(attribute_value SEPARATOR ", ") AS attribute_values, GROUP_CONCAT(attribute_datetime SEPARATOR ", ") AS attribute_datetimevalues'); $this->db->from('attribute_links'); $this->db->join('attribute_values', 'attribute_values.attribute_id = attribute_links.attribute_id'); $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); @@ -423,28 +445,28 @@ class Attribute extends CI_Model $this->db->where('sale_id'); $this->db->where('receiving_id'); } - $this->db->where('item_id', (int) $item_id); + $this->db->where('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'); @@ -453,20 +475,20 @@ 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( - 'INSERT INTO ospos_attribute_links (item_id, definition_id, attribute_id, ' . $sale_receiving_fk . ') + 'INSERT INTO ospos_attribute_links (item_id, definition_id, attribute_id, ' . $sale_receiving_fk . ') SELECT ' . $this->db->escape($item_id) . ', definition_id, attribute_id, ' . $this->db->escape($id) . ' - FROM ' . $this->db->dbprefix('attribute_links') . ' + FROM ' . $this->db->dbprefix('attribute_links') . ' 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(); @@ -484,17 +506,17 @@ 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 != DATETIME) + if($definition_type == TEXT || $definition_type == DROPDOWN) { $attribute_id_check = $this->value_exists($attribute_value); if(empty($attribute_id_check)) @@ -507,6 +529,11 @@ class Attribute extends CI_Model $attribute_id = $attribute_id_check; } } + else if($definition_type == DECIMAL) + { + $this->db->insert('attribute_values', array('attribute_decimal' => $attribute_value)); + $attribute_id = $this->db->insert_id(); + } else { $this->db->insert('attribute_values', array('attribute_datetime' => date('Y-m-d H:i:s', strtotime($attribute_value)))); @@ -532,20 +559,20 @@ class Attribute extends CI_Model 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)); + "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)); } - + public function delete_definition($definition_id) { $this->db->where('definition_id', $definition_id); - + return $this->db->update('attribute_definitions', array('deleted' => 1)); } - + public function delete_definition_list($definition_ids) { $this->db->where_in('definition_id', $definition_ids); - + return $this->db->update('attribute_definitions', array('deleted' => 1)); } -} +} \ No newline at end of file diff --git a/application/views/attributes/form.php b/application/views/attributes/form.php index 38842cf36..b370ac9f2 100644 --- a/application/views/attributes/form.php +++ b/application/views/attributes/form.php @@ -73,7 +73,7 @@ $(document).ready(function() { var definition_type = $("#definition_type option:selected").text(); - if(definition_type == "DATETIME" || (definition_type == "GROUP" && !is_new)) + if(definition_type == "DATETIME" || (definition_type == "GROUP" && !is_new) || definition_type == "DECIMAL") { $('#definition_type').prop("disabled",true); } @@ -81,6 +81,7 @@ $(document).ready(function() { $("#definition_type option:contains('GROUP')").hide(); $("#definition_type option:contains('DATETIME')").hide(); + $("#definition_type option:contains('DECIMAL')").hide(); } else { @@ -205,4 +206,4 @@ $(document).ready(function() } }, form_support.error)); }); - + \ No newline at end of file diff --git a/application/views/attributes/item.php b/application/views/attributes/item.php index 7d42fff7f..97e6aabd3 100644 --- a/application/views/attributes/item.php +++ b/application/views/attributes/item.php @@ -41,6 +41,11 @@ foreach($definition_values as $definition_id => $definition_value) $value = (empty($attribute_value) || empty($attribute_value->attribute_value)) ? $definition_value['selected_value'] : $attribute_value->attribute_value; echo form_input("attribute_links[$definition_id]", $value, "class='form-control valid_chars' data-definition-id='$definition_id'"); } + else if ($definition_value['definition_type'] == DECIMAL) + { + $value = (empty($attribute_value) || empty($attribute_value->attribute_decimal)) ? $definition_value['selected_value'] : $attribute_value->attribute_decimal; + echo form_input("attribute_links[$definition_id]", $value, "class='form-control valid_chars' data-definition-id='$definition_id'"); + } ?> @@ -103,4 +108,4 @@ foreach($definition_values as $definition_id => $definition_value) refresh(); }); })(); - + \ No newline at end of file