35004-vm/mappings/mapping_1760650510.php
2025-10-16 21:35:54 +00:00

156 lines
5.0 KiB
PHP

<?php
function convert_csv($inputPath, $outputPath) {
if (!is_readable($inputPath)) {
throw new RuntimeException("Input file not readable: $inputPath");
}
$in = fopen($inputPath, 'rb');
if ($in === false) {
throw new RuntimeException("Failed to open input file: $inputPath");
}
$out = fopen($outputPath, 'wb');
if ($out === false) {
fclose($in);
throw new RuntimeException("Failed to open output file: $outputPath");
}
// Read header and build index map
$headers = fgetcsv($in);
if ($headers === false) {
fclose($in);
fclose($out);
throw new RuntimeException("Input CSV appears to be empty.");
}
// Handle potential BOM
if (isset($headers[0])) {
$headers[0] = preg_replace('/^\xEF\xBB\xBF/', '', $headers[0]);
}
// Build a map of header name (trimmed) to index
$idx = [];
foreach ($headers as $i => $name) {
$norm = trim($name);
$idx[$norm] = $i;
}
// Helper to fetch a cell by header name, with fallbacks
$get = function(array $row, array $candidates) use ($idx) {
foreach ($candidates as $cand) {
if (isset($idx[$cand])) {
$val = isset($row[$idx[$cand]]) ? $row[$idx[$cand]] : '';
$val = is_string($val) ? trim($val) : $val;
if ($val !== '' && $val !== null) {
return $val;
}
}
}
return '';
};
// Helper to normalize date to YYYY-MM-DD
$normDate = function($s) {
$s = trim($s);
if ($s === '') {
return '';
}
// Try to extract date part
// Accept formats: YYYY-MM-DD, YYYY-MM-DDTHH:MM:SSZ, etc.
if (preg_match('/^\d{4}-\d{2}-\d{2}/', $s, $m)) {
return $m[0];
}
// Try strtotime
$ts = strtotime($s);
if ($ts !== false) {
return date('Y-m-d', $ts);
}
return $s;
};
// Helper to normalize amount (use dot as decimal separator, keep sign)
$normAmount = function($s) {
$s = trim((string)$s);
if ($s === '') return '0';
// Replace comma decimal to dot, remove spaces
$s = str_replace([' ', ','], ['', '.'], $s);
// If it's a plain numeric string, keep as-is
if (is_numeric($s)) {
// Keep as minimally formatted string
// Avoid scientific notation
$f = (float)$s;
// Preserve sign and decimals without trailing zeros if possible
// Format with high precision then trim
$str = rtrim(rtrim(number_format($f, 8, '.', ''), '0'), '.');
return $str === '' ? '0' : $str;
}
return $s;
};
// Write output header (semicolon-separated)
$outputHeader = [
'Data księgowania',
'Nadawca / Odbiorca',
'Adres nadawcy / odbiorcy',
'Rachunek źródłowy',
'Rachunek docelowy',
'Tytuł',
'Kwota',
];
// Use fputcsv with semicolon delimiter
fputcsv($out, $outputHeader, ';');
while (($row = fgetcsv($in)) !== false) {
// Skip entirely empty rows
if (count($row) === 1 && trim((string)$row[0]) === '') {
continue;
}
// Extract fields using common header names
$date = $get($row, ['Date completed (UTC)', 'Date started (UTC)', 'Date', 'Completed Date']);
$date = $normDate($date);
$description = $get($row, ['Description', 'Narrative', 'Details']);
$payer = $get($row, ['Payer', 'Counterparty', 'Merchant']);
$account = $get($row, ['Account', 'From', 'Source account']);
$benefIban = $get($row, ['Beneficiary IBAN', 'Beneficiary account IBAN', 'IBAN']);
$benefAccNo = $get($row, ['Beneficiary account number', 'Beneficiary account', 'Account number']);
$benefRouting = $get($row, ['Beneficiary sort code or routing number', 'Routing number', 'Sort code']);
$amount = $get($row, ['Amount', 'Total amount', 'Payment amount', 'Paid amount', 'Value']);
if ($amount === '') {
// Fallback to original amount if needed
$amount = $get($row, ['Orig amount', 'Original amount']);
}
$amount = $normAmount($amount);
$counterparty = $description !== '' ? $description : ($payer !== '' ? $payer : '');
$title = $description !== '' ? $description : ($counterparty !== '' ? $counterparty : '');
$destAccount = '';
if ($benefIban !== '') {
$destAccount = $benefIban;
} elseif ($benefAccNo !== '') {
$destAccount = $benefAccNo;
} elseif ($benefRouting !== '') {
$destAccount = $benefRouting;
}
$outRow = [
$date,
$counterparty,
'', // Adres nadawcy / odbiorcy (not provided in input)
$account,
$destAccount,
$title,
$amount,
];
fputcsv($out, $outRow, ';');
}
fclose($in);
fclose($out);
}
?>