From dbaae5b1e3ed52e08f6e9be834179d14ed8f2312 Mon Sep 17 00:00:00 2001 From: Laurent Destailleur Date: Thu, 9 Jun 2022 17:44:32 +0200 Subject: [PATCH] Fix autodetect csv separator --- htdocs/imports/import.php | 120 ++++++++++++++++++++------------ htdocs/langs/en_US/exports.lang | 3 + 2 files changed, 78 insertions(+), 45 deletions(-) diff --git a/htdocs/imports/import.php b/htdocs/imports/import.php index 05d1dd89a88..1fd9794581a 100644 --- a/htdocs/imports/import.php +++ b/htdocs/imports/import.php @@ -135,11 +135,11 @@ $confirm = GETPOST('confirm', 'alpha'); $step = (GETPOST('step') ? GETPOST('step') : 1); $import_name = GETPOST('import_name'); $hexa = GETPOST('hexa'); -$importmodelid = GETPOST('importmodelid'); +$importmodelid = GETPOST('importmodelid', 'int'); $excludefirstline = (GETPOST('excludefirstline') ? GETPOST('excludefirstline') : 2); $endatlinenb = (GETPOST('endatlinenb') ? GETPOST('endatlinenb') : ''); $updatekeys = (GETPOST('updatekeys', 'array') ? GETPOST('updatekeys', 'array') : array()); -$separator = (GETPOST('separator', 'nohtml') ? GETPOST('separator', 'nohtml') : (!empty($conf->global->IMPORT_CSV_SEPARATOR_TO_USE) ? $conf->global->IMPORT_CSV_SEPARATOR_TO_USE : ',')); +$separator = (GETPOST('separator', 'nohtml') ? GETPOST('separator', 'nohtml', 3) : ''); $enclosure = (GETPOST('enclosure', 'nohtml') ? GETPOST('enclosure', 'nohtml') : '"'); $separator_used = str_replace('\t', "\t", $separator); @@ -753,6 +753,34 @@ if ($step == 4 && $datatoimport) { $model = $format; $list = $objmodelimport->liste_modeles($db); + if (empty($separator)) { + $separator = (empty($conf->global->IMPORT_CSV_SEPARATOR_TO_USE) ? ',' : $conf->global->IMPORT_CSV_SEPARATOR_TO_USE); + } + + // The separator has been defined, if it is a unique char, we check it is valid by reading the source file + if ($model == 'csv' && strlen($separator) == 1 && !GETPOSTISSET('separator')) { + // Count the char in first line of file. + $fh = fopen($conf->import->dir_temp.'/'.$filetoimport, 'r'); + if ($fh) { + $sline = fgets($fh, 1000000); + fclose($fh); + $nboccurence = substr_count($sline, $separator); + $nboccurencea = substr_count($sline, ','); + $nboccurenceb = substr_count($sline, ';'); + //var_dump($nboccurence." ".$nboccurencea." ".$nboccurenceb);exit; + if ($nboccurence == 0) { + if ($nboccurencea > 2) { + $separator = ','; + } elseif ($nboccurenceb > 2) { + $separator = ';'; + } + } + } + } + + // The value to use + $separator_used = str_replace('\t', "\t", $separator); + // Create classe to use for import $dir = DOL_DOCUMENT_ROOT."/core/modules/import/"; $file = "import_".$model.".modules.php"; @@ -947,7 +975,7 @@ if ($step == 4 && $datatoimport) { if ($model == 'csv') { print ''.$langs->trans("CsvOptions").''; print ''; - print '
'; + print ''; print ''; print ''; print ''; @@ -998,6 +1026,7 @@ if ($step == 4 && $datatoimport) { print ''; print ''; + // Import profile to use/load print '
'; print ''; $s = $langs->trans("SelectImportFieldsSource", '{s1}'); @@ -1240,47 +1269,9 @@ if ($step == 4 && $datatoimport) { print ''; - // List of not imported fields - /* - print ''.$langs->trans("NotUsedFields").''; - - print ''; - - print "\n\n"; - print '\n"; - print "\n"; - - print ''; - print ''; - $i = 0; - while ($i < $nbofnotimportedfields) { - // Print empty cells - show_elem('', '', 'none', $var, 'nostyle'); - $i++; - } - print ''; - */ + // Lines for remark + print ''.$langs->trans("Remark").''; + print '
'; print ''; print '
'; @@ -1291,6 +1282,19 @@ if ($step == 4 && $datatoimport) { print 'var previousselectedvalueimport = "0";'."\n"; print 'var previousselectedlabelimport = "0";'."\n"; print 'var arrayofselectedvalues = [];'."\n"; + print 'var arrayoftargetfields = [];'."\n"; + print 'var arrayoftargetmandatoryfields = [];'."\n"; + + // Loop on $fieldstarget (seems sorted by 'position') to store php array into javascript array + $tmpi = 0; + foreach ($fieldstarget as $key => $val) { + print "arrayoftargetfields[".$tmpi."] = '".dol_escape_js($langs->trans($val['label']))."'; "; + if ($val['required']) { + print "arrayoftargetmandatoryfields[".$tmpi."] = '".dol_escape_js($key)."'; "; + } + $tmpi++; + } + print "\n"; print '$(document).ready(function () {'."\n"; @@ -1350,6 +1354,27 @@ if ($step == 4 && $datatoimport) { print " console.log('Select order saved');\n"; print " },\n"; print ' });'."\n"; + + // Now we loop on all target fields that are mandatory to show if they are not mapped yet. + print ' console.log(arrayselectedfields);'; + print ' console.log(arrayoftargetmandatoryfields);'; + print " listtoshow = '';"; + print " nbelement = arrayoftargetmandatoryfields.length + for (let i = 0; i < nbelement; i++) { + if (arrayoftargetmandatoryfields[i] && ! arrayselectedfields.includes(arrayoftargetmandatoryfields[i])) { + console.log(arrayoftargetmandatoryfields[i]+' not mapped'); + listtoshow = listtoshow + (listtoshow ? ', ' : '') + '' + arrayoftargetfields[i] + '*'; + } + } + console.log(listtoshow); + if (listtoshow) { + listtoshow = '".dol_escape_js(img_warning($langs->trans("MandatoryTargetFieldsNotMapped")).' '.$langs->trans("MandatoryTargetFieldsNotMapped")).": ' + listtoshow; + $('#div-mandatory-target-fields-not-mapped').html(listtoshow); + } else { + $('#div-mandatory-target-fields-not-mapped').html('".dol_escape_js($langs->trans("AllTargetMandatoryFieldsAreMapped"))."'); + } + "; + print '};'."\n"; // If we make a change on a selectbox @@ -1422,8 +1447,13 @@ if ($step == 4 && $datatoimport) { print ''; print ''; + $nameofimportprofile = str_replace(' ', '-', $langs->trans("ImportProfile").' '.$titleofmodule.' '.dol_print_date(dol_now('gmt'), 'dayxcard')); + if (is_object($objimport)) { + $nameofimportprofile = $objimport->model_name; + } + print ''; - print ''; + print ''; print ''; $arrayvisibility = array('private'=>$langs->trans("Private"), 'all'=>$langs->trans("Everybody")); print $form->selectarray('visibility', $arrayvisibility, 'private'); diff --git a/htdocs/langs/en_US/exports.lang b/htdocs/langs/en_US/exports.lang index c6dd04fd488..f9b30ab0131 100644 --- a/htdocs/langs/en_US/exports.lang +++ b/htdocs/langs/en_US/exports.lang @@ -18,6 +18,7 @@ ExportableFields=Exportable fields ExportedFields=Exported fields ImportModelName=Import profile name ImportModelSaved=Import profile saved as %s. +ImportProfile=Import profile DatasetToExport=Dataset to export DatasetToImport=Import file into dataset ChooseFieldsOrdersAndTitle=Choose fields order... @@ -138,3 +139,5 @@ StocksWithBatch=Stocks and location (warehouse) of products with batch/serial nu WarningFirstImportedLine=The first line(s) will not be imported with the current selection NotUsedFields=Fields of database not used SelectImportFieldsSource = Choose the source file fields you want to import and their target field in database by choosing the fields in each select boxes, or select a predefined import profile: +MandatoryTargetFieldsNotMapped=Some mandatory target fields are not mapped +AllTargetMandatoryFieldsAreMapped=All target fields that need a mandatory value are mapped \ No newline at end of file