Fix DECIMAL attribute not respecting locale format (#4422)

* Fix DECIMAL attribute not respecting locale format

Issue: DECIMAL attribute values were displayed as raw database values
instead of being formatted according to the user's locale settings.

Fix:
1. Modified Attribute::get_definitions_by_flags() to optionally return
   definition types along with names (new $include_types parameter)
2. Updated expand_attribute_values() in tabular_helper.php to detect
   DECIMAL attributes and apply to_decimals() locale formatting
3. Updated callers (Reports, Items table) to pass include_types=true
   where attributes are displayed

The DECIMAL values in table views (items, sales reports, receiving reports)
now respect the configured locale number format, matching DATE attributes
which already use locale-based formatting.

* Apply PSR-12 camelCase naming to new variables

Response to PR review comments:
- Rename  to
- Rename  to
- Rename  to

---------

Co-authored-by: Ollama <ollama@steganos.dev>
This commit is contained in:
jekkos
2026-03-13 21:23:52 +00:00
committed by GitHub
parent afc2f82dc6
commit c482e75304
3 changed files with 41 additions and 13 deletions

View File

@@ -1776,7 +1776,7 @@ class Reports extends Secure_Controller
{
$this->clearCache();
$definition_names = $this->attribute->get_definitions_by_flags(attribute::SHOW_IN_SALES);
$definition_names = $this->attribute->get_definitions_by_flags(attribute::SHOW_IN_SALES, true);
$inputs = [
'start_date' => $start_date,
@@ -1789,7 +1789,12 @@ class Reports extends Secure_Controller
$this->detailed_sales->create($inputs);
$columns = $this->detailed_sales->getDataColumns();
$columns['details'] = array_merge($columns['details'], $definition_names);
// Extract just names for column headers
$definitionHeaders = [];
foreach ($definition_names as $definition_id => $definitionInfo) {
$definitionHeaders[$definition_id] = $definitionInfo['name'];
}
$columns['details'] = array_merge($columns['details'], $definitionHeaders);
$headers = $columns;
@@ -1930,14 +1935,19 @@ class Reports extends Secure_Controller
{
$this->clearCache();
$definition_names = $this->attribute->get_definitions_by_flags(attribute::SHOW_IN_RECEIVINGS);
$definition_names = $this->attribute->get_definitions_by_flags(attribute::SHOW_IN_RECEIVINGS, true);
$inputs = ['start_date' => $start_date, 'end_date' => $end_date, 'receiving_type' => $receiving_type, 'location_id' => $location_id, 'definition_ids' => array_keys($definition_names)];
$this->detailed_receivings->create($inputs);
$columns = $this->detailed_receivings->getDataColumns();
$columns['details'] = array_merge($columns['details'], $definition_names);
// Extract just names for column headers
$definitionHeaders = [];
foreach ($definition_names as $definition_id => $definitionInfo) {
$definitionHeaders[$definition_id] = $definitionInfo['name'];
}
$columns['details'] = array_merge($columns['details'], $definitionHeaders);
$headers = $columns;
$report_data = $this->detailed_receivings->getData($inputs);

View File

@@ -408,7 +408,7 @@ function get_items_manage_table_headers(): string
{
$attribute = model(Attribute::class);
$config = config(OSPOS::class)->settings;
$definition_names = $attribute->get_definitions_by_flags($attribute::SHOW_IN_ITEMS); // TODO: this should be made into a constant in constants.php
$definitionsWithTypes = $attribute->get_definitions_by_flags($attribute::SHOW_IN_ITEMS, true);
$headers = item_headers();
@@ -420,8 +420,8 @@ function get_items_manage_table_headers(): string
$headers[] = ['item_pic' => lang('Items.image'), 'sortable' => false];
foreach ($definition_names as $definition_id => $definition_name) {
$headers[] = [$definition_id => $definition_name, 'sortable' => false];
foreach ($definitionsWithTypes as $definition_id => $definitionInfo) {
$headers[] = [$definition_id => $definitionInfo['name'], 'sortable' => false];
}
$headers[] = ['inventory' => '', 'escape' => false];
@@ -479,7 +479,7 @@ function get_item_data_row(object $item): array
$item->name .= NAME_SEPARATOR . $item->pack_name;
}
$definition_names = $attribute->get_definitions_by_flags($attribute::SHOW_IN_ITEMS);
$definition_names = $attribute->get_definitions_by_flags($attribute::SHOW_IN_ITEMS, true);
$columns = [
'items.item_id' => $item->item_id,
@@ -634,7 +634,7 @@ function parse_attribute_values(array $columns, array $row): array
}
/**
* @param array $definition_names
* @param array $definition_names Array of definition_id => ['name' => name, 'type' => type] or definition_id => name
* @param array $row
* @return array
*/
@@ -651,10 +651,16 @@ function expand_attribute_values(array $definition_names, array $row): array
}
$attribute_values = [];
foreach ($definition_names as $definition_id => $definition_name) {
foreach ($definition_names as $definition_id => $definitionInfo) {
if (isset($indexed_values[$definition_id])) {
$attribute_value = $indexed_values[$definition_id];
$attribute_values["$definition_id"] = $attribute_value;
$raw_value = $indexed_values[$definition_id];
// Format DECIMAL attributes according to locale
if (is_array($definitionInfo) && isset($definitionInfo['type']) && $definitionInfo['type'] === DECIMAL) {
$attribute_values["$definition_id"] = to_decimals($raw_value);
} else {
$attribute_values["$definition_id"] = $raw_value;
}
} else {
$attribute_values["$definition_id"] = "";
}

View File

@@ -262,9 +262,10 @@ class Attribute extends Model
/**
* @param int $definition_flags
* @param bool $include_types If true, returns array with definition_id => ['name' => name, 'type' => type]
* @return array
*/
public function get_definitions_by_flags(int $definition_flags): array
public function get_definitions_by_flags(int $definition_flags, bool $include_types = false): array
{
$builder = $this->db->table('attribute_definitions');
$builder->where(new RawSql("definition_flags & $definition_flags")); // TODO: we need to heed CI warnings to escape properly
@@ -274,6 +275,17 @@ class Attribute extends Model
$results = $builder->get()->getResultArray();
if ($include_types) {
$definitions = [];
foreach ($results as $result) {
$definitions[$result['definition_id']] = [
'name' => $result['definition_name'],
'type' => $result['definition_type']
];
}
return $definitions;
}
return $this->to_array($results, 'definition_id', 'definition_name');
}