Separates Logging für die Console.
[kivitendo-erp.git] / lxo-import / parts_import.php
1 <?php
2 //Henry Margies <h.margies@maxina.de>
3 //Holger Lindemann <hli@lx-system.de>
4
5 /**
6  * Returns ID of a partgroup (or adds a new partgroup entry)
7  * \db is the database
8  * \value is the partgroup name
9  * \add if true and partgroup does not exist yet, we will add it automatically
10  * \returns partgroup id or "" in case of an error
11  */
12 function getPartsgroupId($db, $value, $add) {
13     $sql="select id from partsgroup where partsgroup = '$value'";
14     $rs=$db->getAll($sql);
15     if (empty($rs[0]["id"]) && $add) {
16         $sql="insert into partsgroup (partsgroup) values ('$value')";
17         $rc=$db->query($sql);
18         if (!$rc)
19             return "";
20         return getPartsgroupId($db, $value, 0);
21     }
22     return $rs[0]["id"];
23 }
24 function getPricegroup($db) {
25     $sql="SELECT * from pricegroup";
26     $rs=$db->getAll($sql);
27     $data = false;
28     if ($rs) foreach ($rs as $row) {
29         $data["pg_".strtolower($row["pricegroup"])]=$row["id"];
30     };
31     return $data;       
32 }
33 function insertParts($db,$insert,$show,$data,$pricegroup) {
34     if ($show) {
35         show('<tr>',false);
36         show($data["partnumber"]);        show($data["lastcost"]);          show($data["sellprice"]);   show($data["listprice"]);
37         show($data["description"]);       show(substr($data["notes"],0,25));show($data["ean"]);
38         show($data["weight"]);            show($data["image"]);             show($data["partsgroup_id"]);
39         show($data["buchungsgruppen_id"]);show($data["income_accno"]);      show($data["expense_accno"]);
40         show($data["inventory_accno"]);   show($data["microfiche"]);        show($data["drawing"]);
41         show($data["rop"]);               show($data["assembly"]);          show($data["makemodel"]);
42         show($data["shop"]);
43     }
44
45     /*foreach ($data as $key=>$val) {
46         echo $key.":".gettype($val).":".gettype($data[$key]).":".$val."<br>";
47     }*/
48     if ($insert) {
49         $data["import"]=time();
50         $sqlIa  = 'INSERT INTO parts (';
51         $sqlIa .= 'partnumber,description,notes,ean,unit,';
52         $sqlIa .= 'weight,image,sellprice,listprice,lastcost,partsgroup_id,';
53         $sqlIa .= 'buchungsgruppen_id,income_accno_id,expense_accno_id,inventory_accno_id,';
54         $sqlIa .= 'microfiche,drawing,rop,assembly,shop,makemodel,import) ';
55         //$sqlIa .= 'VALUES (?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?)';
56         //$rc=$db->execute($sqlIa,$data);
57         $sqlIa .= "VALUES ('%s','%s','%s','%s','%s',%0.5f,'%s',%0.5f,%0.5f,%0.5f,%d,%d,%d,%d,%d,'%s','%s',%.0f,'%s','%s','%s',%s)";
58         $sql = sprintf($sqlIa,$data['partnumber'],$data['description'],$data['notes'],$data['ean'],
59                                 $data['unit'],$data['weight'],$data['image'],$data['sellprice'],
60                                 $data['listprice'],$data['lastcost'],$data['partsgroup_id'],
61                                 $data['buchungsgruppen_id'],$data['income_accno_id'],$data['expense_accno_id'],
62                                 $data['inventory_accno_id'],$data['microfiche'],$data['drawing'],$data['rop'],
63                                 $data['assembly'],$data['shop'],$data['makemodel'],$data['import']);
64         $rc = $db->query($sql);
65     } else {
66         $rc = true;
67     }
68     if ($pricegroup) $ok = insPrices($db,$data["partnumber"],$pricegroup);
69     if ($show) {
70         if ($rc) 
71             show('<b>ok</b>');
72         else
73             show('<font color="red">error</font>');
74         show('</tr>'."\n",false);
75     }
76     return $rc;
77 }
78 function updPrice($db,$insert,$show,$partnumber,$lastcost,$sellprice,$listprice,$pricegroup,$shop) {
79     if ($show) {
80         show('<tr>',false);
81         show($partnumber); show($lastcost); show($sellprice); show($listprice);
82     }
83     if ($insert) {
84         $sqlPr  = 'UPDATE PARTS SET ';
85         $sqlPr .= 'sellprice = ?, listprice = ?, lastcost = ?, shop = ? ';
86         $sqlPr .= 'WHERE  partnumber = ?';
87         $rc=$db->execute($sqlPr,array("sellprice"=>$sellprice,"listprice"=>$listprice,"lastcost"=>$lastcost,"shop"=>$shop,"partnumber"=>$partnumber));
88     } else {
89         $rc = true;
90     }
91     if ($pricegroup) $ok = insPrices($db,$partnumber,$pricegroup);
92     if ($show) {
93         if ($rc) 
94             show('<b>ok</b>');
95         else
96             show('<font color="red">error</font>');
97         show('</tr>'."\n",false);
98     }
99     return $rc;
100 }
101 function updParts($db,$insert,$show,$partnumber,$lastcost,$sellprice,$listprice,
102                     $description,$notes,$ean,$weight,$image,
103                     $partsgroup_id,$pricegroup, $shop) {
104     if ($show) {
105         show('<tr>',false);
106         show($partnumber);      show($lastcost);          show($sellprice);     show($listprice);
107         show($description);     show(substr($notes,0,25));show($ean);
108         show($weight);          show($image);             show($partsgroup_id);
109     }
110     if ($insert) {
111         $sqlUa  = 'UPDATE PARTS SET ';
112         $sqlUa .= 'description = ?, notes = ?, ean = ?, weight = ?, image = ?, ';
113         $sqlUa .= 'sellprice = ?, listprice = ?, lastcost = ?, partsgroup_id = ?, shop = ? ';
114         $sqlUa .= 'WHERE  partnumber = ?';
115         $rc=$db->execute($sqlUa,array($description,$notes,$ean,$weight,$image,
116                                 $sellprice,$listprice,$lastcost,$partsgroup_id,$shop,$partnumber));
117     } else {
118         $rc = true;
119     }
120     if ($pricegroup) $ok = insPrices($db,$partnumber,$pricegroup);
121     if ($show) {
122         if ($rc) 
123             show('<b>ok</b>');
124         else
125             show('<font color="red">error</font>');
126         show('</tr>'."\n",false);
127     }
128     return $rc;
129 }
130
131 function getMakemodel($db,$check,$hersteller,$model,$partsid,$lastcost,$add=true) {
132     $sql="select * from makemodel where make = $hersteller and model = '$model' and parts_id = $partsid";
133     $rs=$db->getAll($sql);
134     if (empty($rs[0]["id"]) && $add) {
135         if (!$lastcost) $lastcost=0.00;
136         $sql="insert into makemodel (parts_id,make,model,lastcost,lastupdate,sortorder) ";
137         $sql.="values ($partsid,'$hersteller','$model',$lastcost,now(),1)";    
138         $rc=$db->query($sql);
139     }
140 }
141
142 function getAccnoId($db, $accno) {
143     $sql = "select id from chart where accno='$accno'";
144     $rs=$db->getAll($sql);
145     return $rs[0]["id"];
146 }
147
148 function getPartsid($db,$number) {
149     $sql = "select id from parts where partnumber = '$number'";
150     $rs=$db->getAll($sql);
151     if ($rs[0]["id"]>0) {
152         return $rs[0]["id"];
153     } else { 
154         return false;
155     }
156 }
157
158 function newPartNumber($db,$check) {
159     if ($check) return "check";
160     $rc=$db->query("BEGIN");
161     $sql = "select  articlenumber from defaults";
162     $rs=$db->getAll($sql);
163     if ($rs[0]["articlenumber"]) {
164         preg_match("/([^0-9]+)?([0-9]+)([^0-9]+)?/", $rs[0]["articlenumber"] , $regs);
165         $number=$regs[1].($regs[2]+1).$regs[3];
166     }
167     $sql = "update defaults set articlenumber = '$number'";
168     $rc=$db->query($sql);
169     $rc=$db->query("COMMIT");
170     //Prüfen ob die Nummer nicht doch schon vergeben ist.
171     $sql = "select * from parts where partnumber = '$number'";
172     $rs=$db->getAll($sql);
173     if ($rs[0]["id"]>0) return "";
174     return $number;
175 }
176
177 function getBuchungsgruppe($db, $income, $expense) {
178     $income_id = getAccnoId($db, $income);
179     $expense_id = getAccnoId($db, $expense);
180     $sql  = "select id from buchungsgruppen where ";
181     $sql .= "income_accno_id_0 = $income and ";
182     $sql .= "expense_accno_id_0 = $expense ";
183     $sql .= "order by sortkey";
184     $rs=$db->getAll($sql);
185     return $rs[0]["id"];
186 }
187
188 function getFromBG($db, $bg_id, $name) {
189     $sql  = "select $name from buchungsgruppen where id='$bg_id'";
190     $rs=$db->getAll($sql);
191     return 1*$rs[0][$name];
192 }
193
194 function existUnit($db, $value) {
195     $sql="select name from units where name = '$value'";
196     $rs=$db->getAll($sql);
197     if (empty($rs[0]["name"]))
198         return FALSE;
199     return TRUE;
200 }
201
202 function show($things,$td=true) {
203         if ($td) 
204             echo '<td>'.$things.'</td>';
205         else
206             echo $things;
207 }
208
209 function getStdUnit($db,$type) {
210     $sql="select * from units where type='$type' order by sortkey limit 1";
211     $rs=$db->getAll($sql);
212     return $rs[0]["name"];
213 }
214
215 function insPrices($db,$pid,$prices) {
216     $rc = $db->query("BEGIN");
217     $sql="delete from prices where parts_id = (select id from parts where partnumber = '$pid')";
218     $rc = $db->query($sql);
219     $sql = "insert into prices (parts_id,pricegroup_id,price) values ((select id from parts where partnumber = '%s'),%d,%0.5f)";
220     foreach ($prices as $key => $val) {
221         $rc = $db->query(sprintf($sql,$pid,$key,$val));
222         if (!$rc) {
223             $db->query("ROLLBACK");
224             return false;
225         }
226     }
227     $db->query("COMMIT");
228     return true;
229 }
230
231 /**
232  * TODO: short description.
233  * 
234  * @param double $db     
235  * @param mixed  $file   
236  * @param mixed  $fields 
237  * @param mixed  $check  
238  * @param int    $insert 
239  * @param string $show   
240  * @param mixed  $maske  
241  * 
242  * @return TODO
243  */
244 function import_parts($db, $file, $fields, $check, $maske) {
245     $insert = !$maske["test"];
246     $show = $maske["show"];
247     $trennzeichen = ($maske["trennzeichen"])?$maske["trennzeichen"]:"";
248     $trenner = ($maske["trenner"])?$maske["trenner"]:",";
249     $precision=$maske["precision"];
250     $quotation=$maske["quotation"];
251     $quottype=$maske["quottype"];
252     $shop=$maske["shop"];
253     $wgtrenner=$maske["wgtrenner"];
254     $Update=($maske["update"]=="U")?true:false;
255     $UpdText=($maske["TextUpd"]=="1")?true:false;
256     $vendnr=($maske["vendnr"]=="t")?true:false;
257     $modnr=($maske["modnr"]=="t")?true:false;
258
259     //$stdunitW=getStdUnit($db,"dimension");
260     //$stdunitD=getStdUnit($db,"service");
261     $stdunitW=$maske["dimensionunit"];
262     $stdunitD=$maske["serviceunit"];
263     if ($quottype=="P") $quotation=($quotation+100)/100;
264
265     if ($show && !$insert) show("<b>Testimport</b>",false);
266     if ($show) show("<table border='1'>\n",false);
267
268     /* field description */
269     $prices = getPricegroup($db);
270     if ($prices) {
271         $priceskey = array_keys($prices);
272         $parts_fld = array_merge(array_keys($fields),$priceskey);
273     } else {
274         $parts_fld = array_keys($fields);
275     }
276
277     if ($trenner=="other") $trenner=trim($trennzeichen);
278     if (substr($trenner,0,1)=="#") if (strlen($trenner)>1) $trenner=chr(substr($trenner,1));
279
280     /* open csv file */
281     if (file_exists($file."head.csv")) {
282         $fh=fopen($file.'head.csv',"r");
283         // Erst einmal die erste Zeile mit den richtigen Feldbezeichnungen einlesen. 
284         $infld=fgetcsv($fh,1200,$trenner);
285         fclose($fh);
286         $f=fopen($file.'.csv',"r");
287         // Erst einmal die erste Zeile mit den falschen Feldbezeichnungen einlesen. 
288         $tmp=fgetcsv($f,1200,$trenner);
289     } else {
290         $f=fopen($file.'.csv',"r");
291         // Erst einmal die erste Zeile mit den Feldbezeichnungen einlesen. 
292         $infld=fgetcsv($f,1200,$trenner);
293     }
294
295     /*
296      * read first line with table descriptions
297      */
298     if ($show) {
299         show('<tr>',false);
300         show("partnumber");     show("lastcost");       show("sellprice");      show("listprice");
301         show("description");    show("notes");          show("ean");
302         show("weight");         show("image");          show("partsgroup_id");
303         show("bg");             show("income_accno");   show("expense_accno");
304         show("inventory_accno"); show("microfiche");    show("drawing");
305         show("rop");            show("assembly");       show("makemodel");  show("shop"); show("");
306         show("</tr>\n",false);
307     }
308
309    
310     $p=0;
311     foreach ($infld as $fld) {
312         $fld = strtolower(trim(strtr($fld,array("\""=>"","'"=>""))));
313         if (in_array($fld,$parts_fld)) {
314             $fldpos[$fld]=$p;
315         }
316         $p++;
317     }
318     $i=0;
319     $u=0;
320     $m=0;        /* line */
321     $errors=0;    /* number of errors detected */
322     $income_accno = "";
323     $expense_accno = "";
324     $assembly = 'f';
325
326     while ( ($zeile=fgetcsv($f,120000,$trenner)) != FALSE) {
327         $m++;    /* increase line */
328         $unit=false;
329         unset($pgroup); 
330         unset($partsgroup_id); 
331         unset($notes); 
332         unset($rop);
333         unset($weight);
334         unset($inventory_accno);
335         unset($income_accno);
336         unset($expense_accno);
337         unset($model);
338         unset($makemodel);
339         unset($hersteller);
340
341         /* VK-Preis bilden */
342         $sellprice = str_replace(",", ".", $zeile[$fldpos["sellprice"]]);
343         $listprice = str_replace(",", ".", $zeile[$fldpos["listprice"]]);
344         $lastcost = str_replace(",", ".", $zeile[$fldpos["lastcost"]]);
345         if ($prices) {
346                 foreach ($prices as $pkey=>$val) {
347                 if (array_key_exists($pkey,$fldpos))  
348                         $pricegroup[$val] = str_replace(",", ".", $zeile[$fldpos[$pkey]]);
349             }
350         }
351         if ($quotation<>0) {
352             if ($quottype=="A") { $sellprice += $quotation; }
353             else { $sellprice = $sellprice * $quotation; }
354         };
355         if ($lastcost=="") unset($lastcost);
356         if ($sellprice=="") unset($sellprice);
357         if ($listprice=="") unset($listprice);
358
359         /* Langtext zusammenbauen */
360         if ($zeile[$fldpos["notes"]]) {
361             //Kundenspezifisch:
362             //$notes = preg_replace('/""[^ ]/','"',$zeile[$fldpos["notes"]]);
363             $notes = addslashes($zeile[$fldpos["notes"]]);
364             if (Translate) translate($notes);
365         }
366         if ($zeile[$fldpos["notes1"]]) {
367             //Kundenspezifisch:
368             //$notes1 = preg_replace('/""[^ ]/','"',$zeile[$fldpos["notes1"]]);
369             $notes1 = addslashes($zeile[$fldpos["notes1"]]);
370             if (Translate) translate($notes1);
371             if ($notes) {
372                 $notes .= "\n".$notes1;
373             } else {
374                 $notes = $notes1;
375             }
376         }
377
378         /* Warengruppe bilden */
379         if ($fldpos["partsgroup"]>0  and $zeile[$fldpos["partsgroup"]])  $pgroup[]=$zeile[$fldpos["partsgroup"]];
380         if ($fldpos["partsgroup1"]>0 and $zeile[$fldpos["partsgroup1"]]) $pgroup[]=$zeile[$fldpos["partsgroup1"]];
381         if ($fldpos["partsgroup2"]>0 and $zeile[$fldpos["partsgroup2"]]) $pgroup[]=$zeile[$fldpos["partsgroup2"]];
382         if ($fldpos["partsgroup3"]>0 and $zeile[$fldpos["partsgroup3"]]) $pgroup[]=$zeile[$fldpos["partsgroup3"]];
383         if ($fldpos["partsgroup4"]>0 and $zeile[$fldpos["partsgroup4"]]) $pgroup[]=$zeile[$fldpos["partsgroup4"]];
384         if (count($pgroup)>0) {
385                 $pgname = implode($wgtrenner,$pgroup);
386                 if (Translate) translate($pgname);
387                 $partsgroup_id = getPartsgroupId($db, $pgname, $insert);
388         }
389
390         /* Ware oder Dienstleistung */
391         if (($maske["ware"]=="G" and strtoupper($zeile[$fldpos["art"]])=="D") or $maske["ware"]=="D") { 
392             $artikel = false; 
393         } else if (($maske["ware"]=="G" and strtoupper($zeile[$fldpos["art"]])=="W") or $maske["ware"]=="W") { 
394             $artikel = true;
395         }
396
397         /* sind Hersteller und Modelnummer hinterlegt 
398             wenn ja, erfolgt er insert später */
399         $makemodel = 'f';
400         if (!empty($zeile[$fldpos["makemodel"]]) and $artikel) { 
401             $mm = $zeile[$fldpos["makemodel"]];
402             if (Translate) translate($mm);
403             if ($vendnr) {
404                 $hersteller=getFirma($mm,"vendor");
405             } else {
406                 $hersteller=suchFirma("vendor",$mm);
407                 $hersteller=$hersteller["cp_cv_id"];
408             }
409             if (!empty($zeile[$fldpos["model"]]) and $hersteller>0) {
410                 $mo = $zeile[$fldpos["model"]];
411                 if (Translate) translate($mo);
412                 $model = $mo;
413                 $makemodel = 't';
414             } else if ($modnr and $hersteller>0) { 
415                 $model = ''; 
416                 $makemodel = 't';
417             } else {
418                 unset($hersteller);
419                 $makemodel = 'f';
420             }
421         }
422
423         /* Einheit ermitteln */
424         if ($zeile[$fldpos["unit"]]=="") {
425             //Keine Einheit mitgegeben
426             if ($maske["ware"]=="G") { 
427                 if ($artikel) {
428                     $unit = $stdunitD;
429                 } else {
430                     $unit = $stdunitW; 
431                 }
432             } else if ($maske["ware"]=="D") { $unit = $stdunitD; }
433             else { $unit = $stdunitW; };
434         } else {
435             if (existUnit($db,$zeile[$fldpos["unit"]])) {
436                 $unit = $zeile[$fldpos["unit"]];
437             } else {
438                 $unit = ($artikel)?$stdunitD:$stdunitW;
439             }
440         }
441
442         /* Buchungsgruppe ermitteln */
443         if ($maske["bugrufix"]==1) {
444             $bg = $maske["bugru"];
445         } else {
446             if ($zeile[$fldpos["income_accno"]]<>"" and $zeile[$fldpos["expense_accno"]]<>"") {
447                 /* search for buchungsgruppe */
448                 $bg = getBuchungsgruppe($db, $zeile[$fldpos["income_accno"]],$zeile[$fldpos["expense_accno"]]);
449                 if ($bg == "" and $maske["bugrufix"]==2 and $maske["bugru"]<>"") {
450                     $bg = $maske["bugru"];
451                 }
452             } else if ($maske["bugru"]<>"" and $maske["bugrufix"]==2) {
453                 $bg = $maske["bugru"];
454             } else {
455                 /* nothing found? user must create one */
456                 echo "Error in line $m: ";
457                 echo "Keine Buchungsgruppe gefunden f&uuml;r <br>";
458                 echo "Erl&ouml;se Inland: ".$zeile[$fldpos["income_accno"]]."<br>";
459                 echo "Aufwand Inland: ".$zeile[$fldpos["expense_accno"]]."<br>";
460                 echo "Bitte legen Sie eine an oder geben Sie eine vor.<br>";
461                 echo "<br>";
462                 $errors++;
463             }
464         }
465         if ($bg > 0) {
466             /* found one, add income_accno_id etc from buchungsgr. */
467             /* XXX nur bei artikel!!! */
468             if ($artikel) {
469                 $inventory_accno = getFromBG($db, $bg, "inventory_accno_id");
470             };
471             $income_accno = getFromBG($db, $bg, "income_accno_id_0");
472             $expense_accno = getFromBG($db, $bg, "expense_accno_id_0");
473             $bg = $bg * 1;
474         } else {
475             echo "Error in line $m: ";
476             echo "Keine Buchungsgruppe angegeben/gefunden<br>";
477             $errors++;
478             continue;
479         }
480
481         $description = preg_replace('/""[^ ]/','"',$zeile[$fldpos["description"]]);
482         $description = addslashes($description);
483         if (Translate) translate($description);
484
485         // rop und weight müssen null oder Zahl sein
486         if ($zeile[$fldpos["rop"]]) $rop = 1 * str_replace(",", ".",$zeile[$fldpos["rop"]]);
487         if ($zeile[$fldpos["weight"]]) $weight = 1 * str_replace(",", ".", $zeile[$fldpos["weight"]]);
488
489         // Shop-Artikel
490         if ($zeile[$fldpos["shop"]]) {
491                 $shop = (strtolower($zeile[$fldpos["shop"]]=='t'))?'t':'f';
492         } else {
493                 $shop = $maske["shop"];
494         }
495         // Artikel updaten
496
497         if (getPartsid($db,trim($zeile[$fldpos["partnumber"]]))) {
498             /* es gibt die Artikelnummer */
499             if ($Update) {
500                 /* Updates durchführen */
501                 if ($UpdText=='1') {
502                     $u += updParts($db,$insert,$show,$zeile[$fldpos["partnumber"]],$lastcost,$sellprice,$listprice,
503                     $description,$notes,$zeile[$fldpos["ean"]],$weight,
504                     $zeile[$fldpos["image"]],$partsgroup_id,$pricegroup, $shop);
505                 } else {
506                     $u += updPrice($db,$insert,$show,$zeile[$fldpos["partnumber"]],$lastcost,$sellprice,$listprice,$pricegroup,$shop);
507                 }
508                 continue;
509                 // nächste Zeile
510             } 
511         }
512
513         // Neuen Artikel einfügen
514
515         if ($zeile[$fldpos["partnumber"]] == "") {
516             $zeile[$fldpos["partnumber"]] = newPartNumber($db,$check);
517             //Keine Artikelnummer bekommen
518             if ($zeile[$fldpos["partnumber"]] == "") {
519                 continue;
520             }
521         }
522         $i += insertParts($db,$insert,$show,array(
523                     "partnumber"=>$zeile[$fldpos["partnumber"]],
524                     "description"=>$description,"notes"=>$notes,
525                     "ean"=>$zeile[$fldpos["ean"]],"unit"=>$unit,
526                     "weight"=>$weight,"image"=>$zeile[$fldpos["image"]],
527                     "sellprice"=>$sellprice,
528                     "lastcost"=>$lastcost,
529                     "listprice"=>$listprice,
530                     "partsgroup_id"=>$partsgroup_id,
531                     "buchungsgruppen_id"=>$bg,"income_accno_id"=>$income_accno,
532                     "expense_accno_id"=>$expense_accno,"inventory_accno_id"=>$inventory_accno,
533                     "microfiche"=>$zeile[$fldpos["microfiche"]],"drawing"=>$zeile[$fldpos["drawing"]],
534                     "rop"=>$rop,"assembly"=>$assembly,
535                     "shop"=>$shop,"makemodel"=>$makemodel),$pricegroup
536                 );
537         if ($hersteller>0 ) { // && $model) {
538             $partsid=getPartsid($db,$zeile[$fldpos["partnumber"]]);
539             if ($partsid) { 
540                 getMakemodel($db,$check,$hersteller,$model,$partsid,$lastcost,true);
541             }
542         }
543         unset($zeile);
544     }
545
546     if ($show) show("</table>",false);
547     fclose($f);
548     echo "$m Zeilen bearbeitet. Importiert: $i Update: $u (".($m-$u-$i+$errors)." : Fehler) ";
549 }
550 ?>