Teren-app/app/Services/Import/DecimalNormalizer.php
Simon Pocrnjič 36b63a180d fixed import
2025-12-28 13:55:09 +01:00

84 lines
2.4 KiB
PHP

<?php
namespace App\Services\Import;
class DecimalNormalizer
{
/**
* Normalize a raw decimal string to a standard format (period as decimal separator).
* Handles European format (comma as decimal) and American format (period as decimal).
*
* Examples:
* - "958,31" => "958.31"
* - "1.234,56" => "1234.56"
* - "1,234.56" => "1234.56"
* - "1234" => "1234"
*
* Based on ImportProcessor::normalizeDecimal()
*/
public static function normalize(?string $raw): ?string
{
if ($raw === null) {
return null;
}
// Keep digits, comma, dot, and minus to detect separators
$s = preg_replace('/[^0-9,\.-]/', '', $raw) ?? '';
$s = trim($s);
if ($s === '') {
return null;
}
$lastComma = strrpos($s, ',');
$lastDot = strrpos($s, '.');
// Determine decimal separator by last occurrence
$decimalSep = null;
if ($lastComma !== false || $lastDot !== false) {
if ($lastComma === false) {
$decimalSep = '.';
} elseif ($lastDot === false) {
$decimalSep = ',';
} else {
$decimalSep = $lastComma > $lastDot ? ',' : '.';
}
}
// Remove all thousand separators and unify decimal to '.'
if ($decimalSep === ',') {
// Remove all dots (thousand separators)
$s = str_replace('.', '', $s);
// Replace last comma with dot
$pos = strrpos($s, ',');
if ($pos !== false) {
$s[$pos] = '.';
}
// Remove any remaining commas (unlikely)
$s = str_replace(',', '', $s);
} elseif ($decimalSep === '.') {
// Remove all commas (thousand separators)
$s = str_replace(',', '', $s);
// Dot is already decimal separator
} else {
// No decimal separator: remove commas/dots entirely
$s = str_replace([',', '.'], '', $s);
}
// Handle negative numbers
$s = ltrim($s, '+');
$neg = false;
if (str_starts_with($s, '-')) {
$neg = true;
$s = ltrim($s, '-');
}
// Remove any stray minus signs
$s = str_replace('-', '', $s);
if ($neg) {
$s = '-' . $s;
}
return $s;
}
}