diff --git a/class/preisbot.class.php b/class/preisbot.class.php old mode 100644 new mode 100755 index 25a4fdf..03adf1f --- a/class/preisbot.class.php +++ b/class/preisbot.class.php @@ -54,117 +54,129 @@ class PreisBot { global $conf, $user, $langs; - require_once DOL_DOCUMENT_ROOT.'/product/class/product.class.php'; + try { + require_once DOL_DOCUMENT_ROOT.'/product/class/product.class.php'; - $priceSource = getDolGlobalString('PREISBOT_PRICE_SOURCE', 'cheapest'); - $priceDirection = getDolGlobalString('PREISBOT_PRICE_DIRECTION', 'up_only'); - $minMargin = (float) getDolGlobalString('PREISBOT_MIN_MARGIN', 20); + $priceSource = getDolGlobalString('PREISBOT_PRICE_SOURCE', 'cheapest'); + $priceDirection = getDolGlobalString('PREISBOT_PRICE_DIRECTION', 'up_only'); + $minMargin = (float) getDolGlobalString('PREISBOT_MIN_MARGIN', 20); - $updated = 0; - $skipped = 0; - $errors = 0; - $priceChanges = array(); // Für Mail-Bericht + $updated = 0; + $skipped = 0; + $errors = 0; + $priceChanges = array(); - // Hole alle Produkte mit gesetztem Gewinnaufschlag (nur zum Verkauf stehende) - $sql = "SELECT p.rowid, p.ref, p.label, p.price, pe.preisbot_margin"; - $sql .= " FROM ".$this->db->prefix()."product as p"; - $sql .= " LEFT JOIN ".$this->db->prefix()."product_extrafields as pe ON pe.fk_object = p.rowid"; - $sql .= " WHERE pe.preisbot_margin IS NOT NULL"; - $sql .= " AND pe.preisbot_margin >= ".((float) $minMargin); - $sql .= " AND p.tosell = 1"; // Nur Produkte die zum Verkauf stehen - $sql .= " AND p.entity IN (".getEntity('product').")"; + // Hole alle Produkte mit gesetztem Gewinnaufschlag (nur zum Verkauf stehende) + $sql = "SELECT p.rowid, p.ref, p.label, p.price, pe.preisbot_margin"; + $sql .= " FROM ".$this->db->prefix()."product as p"; + $sql .= " LEFT JOIN ".$this->db->prefix()."product_extrafields as pe ON pe.fk_object = p.rowid"; + $sql .= " WHERE pe.preisbot_margin IS NOT NULL"; + $sql .= " AND pe.preisbot_margin >= ".((float) $minMargin); + $sql .= " AND p.tosell = 1"; + $sql .= " AND p.entity IN (".getEntity('product').")"; - $resql = $this->db->query($sql); - if (!$resql) { - $this->error = $this->db->lasterror(); - return -1; - } - - while ($obj = $this->db->fetch_object($resql)) { - $productId = $obj->rowid; - $currentPrice = (float) $obj->price; - $margin = (float) $obj->preisbot_margin; - - // Hole Einkaufspreis basierend auf Einstellung - $buyPrice = $this->getSupplierPrice($productId, $priceSource); - - if ($buyPrice <= 0) { - $skipped++; - continue; + $resql = $this->db->query($sql); + if (!$resql) { + $this->error = $this->db->lasterror(); + return -1; } - // Berechne neuen Verkaufspreis - $newPrice = $buyPrice * (1 + ($margin / 100)); - $newPrice = round($newPrice, 2); + while ($obj = $this->db->fetch_object($resql)) { + $productId = $obj->rowid; + $currentPrice = (float) $obj->price; + $margin = (float) $obj->preisbot_margin; - // Prüfe Preisrichtung - if ($priceDirection === 'up_only' && $newPrice < $currentPrice) { - $skipped++; - continue; - } + // Hole Einkaufspreis basierend auf Einstellung + $buyPrice = $this->getSupplierPrice($productId, $priceSource); - // Nur aktualisieren wenn Preis sich ändert - if (abs($newPrice - $currentPrice) < 0.01) { - $skipped++; - continue; - } + if ($buyPrice <= 0) { + $skipped++; + continue; + } - // Preis aktualisieren - $product = new Product($this->db); - $product->fetch($productId); + // Berechne neuen Verkaufspreis + $newPrice = $buyPrice * (1 + ($margin / 100)); + $newPrice = round($newPrice, 2); - // updatePrice($newprice, $newpricebase, $user, $newvat, $newminprice, $level, $newnpr, $newpbq, $ignore_autogen, $localtaxes_array, $newdefaultvatcode, $price_label, $notrigger) - // Wir aktualisieren NUR den Preis, behalten aber alle anderen Werte bei - $result = $product->updatePrice( - $newPrice, // neuer Preis - $product->price_base_type, // HT oder TTC - BEIBEHALTEN - $user, // User - $product->tva_tx, // MwSt-Satz - BEIBEHALTEN - $product->price_min, // Mindestpreis - BEIBEHALTEN - 0, // Level (Preisstufe) - $product->tva_npr, // NPR - BEIBEHALTEN - 0, // price by quantity - 0, // ignore autogen - array(), // localtaxes - $product->default_vat_code, // default vat code - BEIBEHALTEN - 'Preisbot' // price_label - Bezeichnung der Preisänderung - ); + // Prüfe Preisrichtung + if ($priceDirection === 'up_only' && $newPrice < $currentPrice) { + $skipped++; + continue; + } - if ($result > 0) { - $updated++; - $diff = $newPrice - $currentPrice; - $diffPercent = $currentPrice > 0 ? round(($diff / $currentPrice) * 100, 2) : 0; + // Nur aktualisieren wenn Preis sich ändert + if (abs($newPrice - $currentPrice) < 0.01) { + $skipped++; + continue; + } - $priceChanges[] = array( - 'ref' => $obj->ref, - 'label' => $obj->label, - 'old_price' => $currentPrice, - 'new_price' => $newPrice, - 'diff' => $diff, - 'diff_percent' => $diffPercent, - 'margin' => $margin, - 'buy_price' => $buyPrice + // Preis aktualisieren + $product = new Product($this->db); + $product->fetch($productId); + + $result = $product->updatePrice( + $newPrice, + $product->price_base_type, + $user, + $product->tva_tx, + $product->price_min, + 0, + $product->tva_npr, + 0, + 0, + array(), + $product->default_vat_code, + 'Preisbot' ); - $this->output .= "Produkt ".$obj->ref.": ".$currentPrice." -> ".$newPrice." EUR (Aufschlag: ".$margin."%)\n"; - } else { - $errors++; - $this->errors[] = "Fehler bei Produkt ".$obj->ref.": ".$product->error; + if ($result > 0) { + $updated++; + $diff = $newPrice - $currentPrice; + $diffPercent = $currentPrice > 0 ? round(($diff / $currentPrice) * 100, 2) : 0; + + $priceChanges[] = array( + 'ref' => $obj->ref, + 'label' => $obj->label, + 'old_price' => $currentPrice, + 'new_price' => $newPrice, + 'diff' => $diff, + 'diff_percent' => $diffPercent, + 'margin' => $margin, + 'buy_price' => $buyPrice + ); + + $this->output .= "Produkt ".$obj->ref.": ".$currentPrice." -> ".$newPrice." EUR (Aufschlag: ".$margin."%)\n"; + } else { + $errors++; + $this->errors[] = "Fehler bei Produkt ".$obj->ref.": ".$product->error; + } } + + $this->output .= "\n--- Zusammenfassung ---\n"; + $this->output .= "Aktualisiert: ".$updated."\n"; + $this->output .= "Übersprungen: ".$skipped."\n"; + $this->output .= "Fehler: ".$errors."\n"; + + // Benachrichtigung und Mail nur wenn es Änderungen gab + if ($updated > 0) { + try { + $this->sendNotification($priceChanges, $updated, $errors); + } catch (Exception $e) { + $this->output .= "Warnung: GlobalNotify fehlgeschlagen: ".$e->getMessage()."\n"; + } + try { + $this->sendMailReport($priceChanges, $updated, $skipped, $errors); + } catch (Exception $e) { + $this->output .= "Warnung: Mail-Versand fehlgeschlagen: ".$e->getMessage()."\n"; + } + } + + return ($errors > 0) ? -1 : 0; + } catch (Exception $e) { + $this->error = 'PreisBot Exception: '.$e->getMessage(); + $this->output .= 'FEHLER: '.$e->getMessage()."\n"; + return -1; } - - $this->output .= "\n--- Zusammenfassung ---\n"; - $this->output .= "Aktualisiert: ".$updated."\n"; - $this->output .= "Übersprungen: ".$skipped."\n"; - $this->output .= "Fehler: ".$errors."\n"; - - // Benachrichtigung und Mail nur wenn es Änderungen gab - if ($updated > 0) { - $this->sendNotification($priceChanges, $updated, $errors); - $this->sendMailReport($priceChanges, $updated, $skipped, $errors); - } - - return ($errors > 0) ? -1 : 0; } /**