*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation; either version 3 of the License, or
* (at your option) any later version.
*/
/**
* \file idsconnect/tab_supplierorder.php
* \ingroup idsconnect
* \brief IDS Connect Tab in Lieferantenbestellungen
*/
// Dolibarr laden
$res = 0;
if (!$res && !empty($_SERVER["CONTEXT_DOCUMENT_ROOT"])) {
$res = @include $_SERVER["CONTEXT_DOCUMENT_ROOT"]."/main.inc.php";
}
$tmp = empty($_SERVER['SCRIPT_FILENAME']) ? '' : $_SERVER['SCRIPT_FILENAME'];
$tmp2 = realpath(__FILE__);
$i = strlen($tmp) - 1;
$j = strlen($tmp2) - 1;
while ($i > 0 && $j > 0 && isset($tmp[$i]) && isset($tmp2[$j]) && $tmp[$i] == $tmp2[$j]) {
$i--;
$j--;
}
if (!$res && $i > 0 && file_exists(substr($tmp, 0, ($i + 1))."/main.inc.php")) {
$res = @include substr($tmp, 0, ($i + 1))."/main.inc.php";
}
if (!$res && $i > 0 && file_exists(dirname(substr($tmp, 0, ($i + 1)))."/main.inc.php")) {
$res = @include dirname(substr($tmp, 0, ($i + 1)))."/main.inc.php";
}
if (!$res && file_exists("../main.inc.php")) {
$res = @include "../main.inc.php";
}
if (!$res && file_exists("../../main.inc.php")) {
$res = @include "../../main.inc.php";
}
if (!$res) {
die("Include of main fails");
}
require_once DOL_DOCUMENT_ROOT.'/fourn/class/fournisseur.commande.class.php';
require_once DOL_DOCUMENT_ROOT.'/core/lib/fourn.lib.php';
dol_include_once('/idsconnect/class/idssupplier.class.php');
dol_include_once('/idsconnect/class/idsconnect.class.php');
dol_include_once('/idsconnect/lib/idsconnect.lib.php');
/**
* @var Conf $conf
* @var DoliDB $db
* @var Translate $langs
* @var User $user
*/
$langs->loadLangs(array("idsconnect@idsconnect", "orders"));
if (!$user->hasRight('idsconnect', 'use')) {
accessforbidden();
}
$id = GETPOSTINT('id');
// Bestellung laden
$object = new CommandeFournisseur($db);
$object->fetch($id);
$object->fetch_thirdparty();
/*
* View
*/
llxHeader('', $langs->trans("IdsConnectTab"), '', '', 0, 0, '', '', '', 'mod-idsconnect page-tab_supplierorder');
// Tabs der Lieferantenbestellung
$head = ordersupplier_prepare_head($object);
print dol_get_fiche_head($head, 'idsconnect', $langs->trans("SupplierOrder"), -1, 'order');
// Bestellungs-Info
print '
';
print '| '.$langs->trans("Ref").' | '.$object->getNomUrl(1).' |
';
print '| '.$langs->trans("Supplier").' | '.$object->thirdparty->getNomUrl(1).' |
';
print '
';
print '
';
idsconnectShowTestModeBanner();
// Passende Großhändler für diesen Lieferanten finden
$supplierObj = new IdsSupplier($db);
$allSuppliers = $supplierObj->fetchAll(1);
$matchingSuppliers = array();
if (is_array($allSuppliers)) {
foreach ($allSuppliers as $sup) {
// Großhändler die mit diesem Dolibarr-Lieferanten verknüpft sind
if ($sup->fk_soc == $object->socid) {
$matchingSuppliers[] = $sup;
}
}
}
if (!empty($matchingSuppliers)) {
print ''.$langs->trans("IdsconnectSuppliers").'
';
foreach ($matchingSuppliers as $sup) {
print '';
print '
'.htmlspecialchars($sup->label).' ('.htmlspecialchars($sup->ref).')
';
print '
'.htmlspecialchars($sup->ids_url).' | IDS '.htmlspecialchars($sup->ids_version).'
';
if ($sup->testmode) {
print '
Testmodus';
}
print '
';
}
} else {
print '';
}
// Preis-Vergleich für Bestellpositionen
if (!empty($matchingSuppliers) && count($object->lines) > 0 && getDolGlobalInt('IDSCONNECT_PRICE_UPDATE_ENABLED')) {
print '
';
print ''.$langs->trans("IdsconnectPriceManagement").'
';
// Aktuelle Preise aus product_fournisseur_price laden
$price_data = array();
foreach ($object->lines as $line) {
if ($line->fk_product > 0) {
// Produkt ist verknüpft → Preis aus product_fournisseur_price holen
$sql = "SELECT pfp.price, pfp.quantity, pfp.ref_fourn";
$sql .= " FROM ".$db->prefix()."product_fournisseur_price pfp";
$sql .= " WHERE pfp.fk_product = ".((int) $line->fk_product);
$sql .= " AND pfp.fk_soc = ".((int) $object->socid);
$sql .= " ORDER BY pfp.tms DESC LIMIT 1"; // Neuesten Preis
$resql = $db->query($sql);
if ($resql && $obj = $db->fetch_object($resql)) {
// Stückpreis berechnen (price / qty)
$price_qty = (float) $obj->quantity;
if ($price_qty <= 0) $price_qty = 1;
$unit_price = (float) $obj->price / $price_qty;
$price_data[$line->id] = array(
'current_price' => $unit_price, // Stückpreis statt Gesamtpreis
'ref_fourn' => $obj->ref_fourn,
'order_price' => (float) $line->subprice,
'qty' => $line->qty,
'fk_product' => $line->fk_product
);
}
} elseif (!empty($line->ref_supplier)) {
// Freitext → Preis über ref_supplier suchen
$sql = "SELECT pfp.price, pfp.quantity, pfp.fk_product, p.ref, p.label";
$sql .= " FROM ".$db->prefix()."product_fournisseur_price pfp";
$sql .= " JOIN ".$db->prefix()."product p ON p.rowid = pfp.fk_product";
$sql .= " WHERE pfp.ref_fourn = '".$db->escape($line->ref_supplier)."'";
$sql .= " AND pfp.fk_soc = ".((int) $object->socid);
$sql .= " AND p.tosell = 1";
$sql .= " ORDER BY pfp.tms DESC LIMIT 1";
$resql = $db->query($sql);
if ($resql && $obj = $db->fetch_object($resql)) {
// Stückpreis berechnen (price / qty)
$price_qty = (float) $obj->quantity;
if ($price_qty <= 0) $price_qty = 1;
$unit_price = (float) $obj->price / $price_qty;
$price_data[$line->id] = array(
'current_price' => $unit_price, // Stückpreis statt Gesamtpreis
'ref_fourn' => $line->ref_supplier,
'order_price' => (float) $line->subprice,
'qty' => $line->qty,
'fk_product' => (int) $obj->fk_product,
'product_ref' => $obj->ref,
'product_label' => $obj->label,
'is_freetext' => true
);
}
}
}
// Nur Positionen mit Abweichungen anzeigen
$threshold = (float) getDolGlobalString('IDSCONNECT_PRICE_UPDATE_THRESHOLD', '5');
$deviations = array();
foreach ($price_data as $line_id => $data) {
if ($data['current_price'] > 0 && $data['order_price'] > 0) {
$deviation = (($data['order_price'] - $data['current_price']) / $data['current_price']) * 100;
if (abs($deviation) > $threshold) {
$deviations[$line_id] = array_merge($data, array('deviation' => $deviation));
}
}
}
if (!empty($deviations)) {
print '';
print ''.count($deviations).' Position(en) mit Preisabweichung > '.$threshold.'%';
print '
';
print '';
print '';
print '| '.$langs->trans("IdsconnectCartArticleNr").' | ';
print ''.$langs->trans("IdsconnectCartDescription").' | ';
print ''.$langs->trans("Qty").' | ';
print ''.$langs->trans("IdsconnectCartUnitPrice").' (Bestellung) | ';
print ''.$langs->trans("IdsconnectCartUnitPrice").' (Aktuell) | ';
print ''.$langs->trans("IdsconnectPriceDeviation").' | ';
print ' | ';
print '
';
foreach ($deviations as $line_id => $data) {
// Zeile finden
$line = null;
foreach ($object->lines as $l) {
if ($l->id == $line_id) {
$line = $l;
break;
}
}
if (!$line) continue;
print '';
print '| '.$data['ref_fourn'].' | ';
print '';
if (!empty($data['is_freetext'])) {
print '! ';
}
print $line->desc;
if (!empty($data['product_ref'])) {
print ' '.$data['product_ref'].' - '.$data['product_label'].'';
}
print ' | ';
print ''.$line->qty.' | ';
print ''.price($data['order_price']).' | ';
print ''.price($data['current_price']).' | ';
print '';
$abs_deviation = abs($data['deviation']);
if ($abs_deviation <= 2) {
$color = '#28a745';
} elseif ($abs_deviation <= 10) {
$color = '#ffc107';
} else {
$color = '#dc3545';
}
print ''.sprintf('%+.1f%%', $data['deviation']).'';
print ' | ';
print '';
if (!empty($data['is_freetext']) && $user->hasRight('produit', 'creer')) {
print 'Freitext';
}
print ' | ';
print '
';
}
print '
';
if (!empty($deviations)) {
$has_freetext = false;
foreach ($deviations as $data) {
if (!empty($data['is_freetext'])) {
$has_freetext = true;
break;
}
}
if ($has_freetext) {
print '
';
print 'Hinweis: Freitext-Positionen können nicht automatisch aktualisiert werden. ';
print 'Bitte verknüpfen Sie diese Artikel zuerst mit Dolibarr-Produkten.';
print '
';
}
}
} else {
print 'Keine signifikanten Preisabweichungen gefunden (Schwellwert: '.$threshold.'%)
';
}
}
print dol_get_fiche_end();
llxFooter();
$db->close();