Skip to content

Commit

Permalink
Fix update row on xlsx import do not work as csv import
Browse files Browse the repository at this point in the history
  • Loading branch information
phf committed Jul 4, 2017
1 parent 77f5952 commit 3892da7
Showing 1 changed file with 152 additions and 61 deletions.
213 changes: 152 additions & 61 deletions htdocs/core/modules/import/import_xlsx.modules.php
Expand Up @@ -292,10 +292,11 @@ function import_close_file()
* @param Object $objimport Object import (contains objimport->array_import_tables, objimport->array_import_fields, objimport->array_import_convertvalue, ...)
* @param int $maxfields Max number of fields to use
* @param string $importid Import key
* @param array $updatekeys Array of keys to use to try to do update
* @return int <0 if KO, >0 if OK
*/
// What is this doing here ? it is common to all imports, is should be in the parent class
function import_insert($arrayrecord,$array_match_file_to_database,$objimport,$maxfields,$importid)
function import_insert($arrayrecord,$array_match_file_to_database,$objimport,$maxfields,$importid,$updatekeys)
{
global $langs,$conf,$user;
global $thirdparty_static; // Specific to thirdparty import
Expand Down Expand Up @@ -326,13 +327,15 @@ function import_insert($arrayrecord,$array_match_file_to_database,$objimport,$ma
else
{
$last_insert_id_array = array(); // store the last inserted auto_increment id for each table, so that dependent tables can be inserted with the appropriate id (eg: extrafields fk_object will be set with the last inserted object's id)
$updatedone = false;
$insertdone = false;
// For each table to insert, me make a separate insert
foreach($objimport->array_import_tables[0] as $alias => $tablename)
{
// Build sql request
$sql='';
$listfields='';
$listvalues='';
$listfields=array();
$listvalues=array();
$i=0;
$errorforthistable=0;

Expand Down Expand Up @@ -372,7 +375,7 @@ function import_insert($arrayrecord,$array_match_file_to_database,$objimport,$ma
// Make some tests on $newval

// Is it a required field ?
if (preg_match('/\*/',$objimport->array_import_fields[0][$val]) && ((string) $newval == ''))
if (preg_match('/\*/',$objimport->array_import_fields[0][$val]) && ((string) $newval==''))
{
$this->errors[$error]['lib']=$langs->trans('ErrorMissingMandatoryValue',$key);
$this->errors[$error]['type']='NOTNULL';
Expand All @@ -399,7 +402,7 @@ function import_insert($arrayrecord,$array_match_file_to_database,$objimport,$ma

if ($isidorref == 'ref') // If value into input import file is a ref, we apply the function defined into descriptor
{
$file=$objimport->array_import_convertvalue[0][$val]['classfile'];
$file=(empty($objimport->array_import_convertvalue[0][$val]['classfile'])?$objimport->array_import_convertvalue[0][$val]['file']:$objimport->array_import_convertvalue[0][$val]['classfile']);
$class=$objimport->array_import_convertvalue[0][$val]['class'];
$method=$objimport->array_import_convertvalue[0][$val]['method'];
if ($this->cacheconvert[$file.'_'.$class.'_'.$method.'_'][$newval] != '')
Expand All @@ -408,7 +411,12 @@ function import_insert($arrayrecord,$array_match_file_to_database,$objimport,$ma
}
else
{
dol_include_once($file);
$resultload = dol_include_once($file);
if (empty($resultload))
{
dol_print_error('', 'Error trying to call file='.$file.', class='.$class.', method='.$method);
break;
}
$classinstance=new $class($this->db);
// Try the fetch from code or ref
call_user_func_array(array($classinstance, $method),array('', $newval));
Expand Down Expand Up @@ -481,6 +489,26 @@ function import_insert($arrayrecord,$array_match_file_to_database,$objimport,$ma
}
if (empty($newval)) $arrayrecord[($key-1)]['type']=-1; // If we get empty value, we will use "null"
}
elseif ($objimport->array_import_convertvalue[0][$val]['rule']=='getrefifauto')
{
$defaultref='';
// TODO provide the $modTask (module of generation of ref) as parameter of import_insert function
$obj = empty($conf->global->PROJECT_TASK_ADDON)?'mod_task_simple':$conf->global->PROJECT_TASK_ADDON;
if (! empty($conf->global->PROJECT_TASK_ADDON) && is_readable(DOL_DOCUMENT_ROOT ."/core/modules/project/task/".$conf->global->PROJECT_TASK_ADDON.".php"))
{
require_once DOL_DOCUMENT_ROOT ."/core/modules/project/task/".$conf->global->PROJECT_TASK_ADDON.'.php';
$modTask = new $obj;
$defaultref = $modTask->getNextValue(null,null);
}
if (is_numeric($defaultref) && $defaultref <= 0) $defaultref='';
$newval=$defaultref;
}


elseif ($objimport->array_import_convertvalue[0][$val]['rule']=='numeric')
{
$newval = price2num($newval);
}

//print 'Val to use as insert is '.$newval.'<br>';
}
Expand Down Expand Up @@ -541,92 +569,152 @@ function import_insert($arrayrecord,$array_match_file_to_database,$objimport,$ma
}

// Define $listfields and $listvalues to build SQL request
if ($listfields) { $listfields.=', '; $listvalues.=', '; }
$listfields.=$fieldname;
$listfields[] = $fieldname;

// Note: arrayrecord (and 'type') is filled with ->import_read_record called by import.php page before calling import_insert
if (empty($newval) && $arrayrecord[($key-1)]['type'] < 0) $listvalues.=($newval=='0'?$newval:"null");
elseif (empty($newval) && $arrayrecord[($key-1)]['type'] == 0) $listvalues.="''";
else $listvalues.="'".$this->db->escape($newval)."'";
if (empty($newval) && $arrayrecord[($key-1)]['type'] < 0) $listvalues[] = ($newval=='0'?$newval:"null");
elseif (empty($newval) && $arrayrecord[($key-1)]['type'] == 0) $listvalues[] = "''";
else $listvalues[] = "'".$this->db->escape($newval)."'";
}
$i++;
}

// We add hidden fields (but only if there is at least one field to add into table)
if ($listfields && is_array($objimport->array_import_fieldshidden[0]))
if (!empty($listfields) && is_array($objimport->array_import_fieldshidden[0]))
{
// Loop on each hidden fields to add them into listfields/listvalues
foreach($objimport->array_import_fieldshidden[0] as $key => $val)
{
if (! preg_match('/^'.preg_quote($alias).'\./', $key)) continue; // Not a field of current table
if ($listfields) { $listfields.=', '; $listvalues.=', '; }
if ($val == 'user->id')
{
$listfields.=preg_replace('/^'.preg_quote($alias).'\./','',$key);
$listvalues.=$user->id;
$listfields[] = preg_replace('/^'.preg_quote($alias).'\./','',$key);
$listvalues[] = $user->id;
}
elseif (preg_match('/^lastrowid-/',$val))
{
$tmp=explode('-',$val);
$lastinsertid=(isset($last_insert_id_array[$tmp[1]]))?$last_insert_id_array[$tmp[1]]:0;
$listfields.=preg_replace('/^'.preg_quote($alias).'\./','',$key);
$listvalues.=$lastinsertid;
$keyfield = preg_replace('/^'.preg_quote($alias).'\./','',$key);
$listfields[] = $keyfield;
$listvalues[] = $lastinsertid;
//print $key."-".$val."-".$listfields."-".$listvalues."<br>";exit;
} else
{
$listfields.=preg_replace('/^'.preg_quote($alias).'\./','',$key);
$listvalues.=$val;
}
}
}
}
//print 'listfields='.$listfields.'<br>listvalues='.$listvalues.'<br>';

// If no error for this $alias/$tablename, we have a complete $listfields and $listvalues that are defined
if (! $errorforthistable)
{
//print "$alias/$tablename/$listfields/$listvalues<br>";
if ($listfields)
//print "$alias/$tablename/$listfields/$listvalues<br>";
if (!empty($listfields))
{
//var_dump($objimport->array_import_convertvalue); exit;

// Build SQL request
if (empty($tablewithentity_cache[$tablename]))
{
$sql ='INSERT INTO '.$tablename.'('.$listfields.', import_key';
if (! empty($objimport->array_import_tables_creator[0][$alias])) $sql.=', '.$objimport->array_import_tables_creator[0][$alias];
$sql.=') VALUES('.$listvalues.", '".$importid."'";
}
else
{
$sql ='INSERT INTO '.$tablename.'('.$listfields.', import_key, entity';
if (! empty($objimport->array_import_tables_creator[0][$alias])) $sql.=', '.$objimport->array_import_tables_creator[0][$alias];
$sql.=') VALUES('.$listvalues.", '".$importid."', ".$conf->entity ;
$updatedone = false;
$insertdone = false;
if (!empty($updatekeys)) {
// We do SELECT to get the rowid, if we already have the rowid, it's to be used below for related tables (extrafields)
if (empty($lastinsertid)) {
$sqlSelect = 'SELECT rowid FROM '.$tablename;

$data = array_combine($listfields, $listvalues);
$where = array();
$filters = array();
foreach ($updatekeys as $key) {
$col = $objimport->array_import_updatekeys[0][$key];
$key=preg_replace('/^.*\./i','',$key);
$where[] = $key.' = '.$data[$key];
$filters[] = $col.' = '.$data[$key];
}
$sqlSelect.= ' WHERE '.implode(' AND ', $where);

$resql=$this->db->query($sqlSelect);
if($resql) {
$res = $this->db->fetch_object($resql);
if($resql->num_rows == 1) {
$lastinsertid = $res->rowid;
$last_insert_id_array[$tablename] = $lastinsertid;
} else if($resql->num_rows > 1) {
$this->errors[$error]['lib']=$langs->trans('MultipleRecordFoundWithTheseFilters', implode($filters, ', '));
$this->errors[$error]['type']='SQL';
$error++;
} else {
// No record found with filters, insert will be tried below
}
}
else
{
//print 'E';
$this->errors[$error]['lib']=$this->db->lasterror();
$this->errors[$error]['type']='SQL';
$error++;
}
}

if (!empty($lastinsertid)) {
// Build SQL UPDATE request
$sqlstart = 'UPDATE '.$tablename;

$data = array_combine($listfields, $listvalues);
$set = array();
foreach ($data as $key => $val) {
$set[] = $key.' = '.$val;
}
$sqlstart.= ' SET '.implode(', ', $set);

if(empty($keyfield)) $keyfield = 'rowid';
$sqlend = ' WHERE '.$keyfield.' = '.$lastinsertid;

$sql = $sqlstart.$sqlend;

// Run update request
$resql=$this->db->query($sql);
if($resql) {
// No error, update has been done. $this->db->db->affected_rows can be 0 if data hasn't changed
$updatedone = true;
}
else
{
//print 'E';
$this->errors[$error]['lib']=$this->db->lasterror();
$this->errors[$error]['type']='SQL';
$error++;
}
}
}
if (! empty($objimport->array_import_tables_creator[0][$alias])) $sql.=', '.$user->id;
$sql.=')';

//print($sql).'<br>';
dol_syslog("import_csv.modules", LOG_DEBUG);

//print '> '.join(',',$arrayrecord);
//print 'sql='.$sql;
//print '<br>'."\n";

// Run insert request
if ($sql)
{
$resql=$this->db->query($sql);
$last_insert_id_array[$tablename] = $this->db->last_insert_id($tablename); // store the last inserted auto_increment id for each table, so that dependent tables can be inserted with the appropriate id. This must be done just after the INSERT request, else we risk losing the id (because another sql query will be issued somewhere in Dolibarr).
if ($resql)
{
//print '.';

// Update not done, we do insert
if (!$error && !$updatedone) {
// Build SQL INSERT request
$sqlstart = 'INSERT INTO '.$tablename.'('.implode(', ', $listfields).', import_key';
$sqlend = ') VALUES('.implode(', ', $listvalues).", '".$importid."'";
if (! empty($tablewithentity_cache[$tablename])) {
$sqlstart.= ', entity';
$sqlend.= ', '.$conf->entity;
}
if (! empty($objimport->array_import_tables_creator[0][$alias])) {
$sqlstart.= ', '.$objimport->array_import_tables_creator[0][$alias];
$sqlend.=', '.$user->id;
}
else
$sql = $sqlstart.$sqlend.')';
dol_syslog("import_xlsx.modules", LOG_DEBUG);

// Run insert request
if ($sql)
{
//print 'E';
$this->errors[$error]['lib']=$this->db->lasterror();
$this->errors[$error]['type']='SQL';
$error++;
$resql=$this->db->query($sql);
if ($resql)
{
$last_insert_id_array[$tablename] = $this->db->last_insert_id($tablename); // store the last inserted auto_increment id for each table, so that child tables can be inserted with the appropriate id. This must be done just after the INSERT request, else we risk losing the id (because another sql query will be issued somewhere in Dolibarr).
$insertdone = true;
}
else
{
//print 'E';
$this->errors[$error]['lib']=$this->db->lasterror();
$this->errors[$error]['type']='SQL';
$error++;
}
}
}
}
Expand All @@ -638,6 +726,9 @@ function import_insert($arrayrecord,$array_match_file_to_database,$objimport,$ma

if ($error) break;
}

if($updatedone) $this->nbupdate++;
if($insertdone) $this->nbinsert++;
}

return 1;
Expand Down

0 comments on commit 3892da7

Please sign in to comment.