- Neue Funktion idsconnect_notify() für GlobalNotify-Benachrichtigungen mit Fallback auf dol_syslog falls Modul nicht installiert - Neue Funktion idsconnect_validateSupplierConfig() prüft Supplier- Konfiguration vor dem Launch auf Vollständigkeit - launch.php: Validierung vor Formular-Submit - Fehler (leeres Passwort): blockiert Launch, Redirect zur Konfiguration - Warnung (leerer Username): erlaubt Launch aber warnt User + Admin - Löst Problem: Klux "Weiter"-Button fehlte weil ids_username leer war, Login schlug still fehl ohne jede Fehlermeldung Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
320 lines
11 KiB
PHP
Executable file
320 lines
11 KiB
PHP
Executable file
<?php
|
|
/* Copyright (C) 2026 Eduard Wisch <data@data-it-solution.de>
|
|
*
|
|
* 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/launch.php
|
|
* \ingroup idsconnect
|
|
* \brief Launcher - generiert und sendet IDS Connect Formular zum Großhandels-Shop
|
|
*/
|
|
|
|
// 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");
|
|
}
|
|
|
|
dol_include_once('/idsconnect/class/idsconnect.class.php');
|
|
dol_include_once('/idsconnect/class/idssupplier.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"));
|
|
|
|
// Berechtigungsprüfung
|
|
if (!$user->hasRight('idsconnect', 'use')) {
|
|
accessforbidden();
|
|
}
|
|
|
|
// Parameter
|
|
$supplier_id = GETPOSTINT('supplier_id');
|
|
$action = GETPOST('ids_action', 'alpha');
|
|
$confirm = GETPOST('confirm', 'alpha');
|
|
$confirm_wks = GETPOST('confirm_wks', 'alpha');
|
|
$fk_commande = GETPOSTINT('fk_commande');
|
|
|
|
// Validierung
|
|
if (empty($supplier_id) || empty($action)) {
|
|
setEventMessages($langs->trans("IdsconnectMissingParams"), null, 'errors');
|
|
header('Location: '.DOL_URL_ROOT.'/custom/idsconnect/idsconnectindex.php');
|
|
exit;
|
|
}
|
|
|
|
// CSRF-Schutz für den Launch
|
|
if (!verifCond(GETPOST('token', 'alpha') == newToken())) {
|
|
accessforbidden('Bad CSRF token');
|
|
}
|
|
|
|
// Großhändler laden
|
|
$supplier = new IdsSupplier($db);
|
|
$result = $supplier->fetch($supplier_id);
|
|
if ($result <= 0) {
|
|
setEventMessages($langs->trans("IdsconnectSupplierNotFound"), null, 'errors');
|
|
header('Location: '.DOL_URL_ROOT.'/custom/idsconnect/idsconnectindex.php');
|
|
exit;
|
|
}
|
|
|
|
// Prüfen ob der Großhändler aktiv ist
|
|
if (!$supplier->active) {
|
|
setEventMessages($langs->trans("IdsconnectSupplierInactive"), null, 'errors');
|
|
header('Location: '.DOL_URL_ROOT.'/custom/idsconnect/idsconnectindex.php');
|
|
exit;
|
|
}
|
|
|
|
// Supplier-Konfiguration auf Vollständigkeit prüfen
|
|
$config_issues = idsconnect_validateSupplierConfig($supplier);
|
|
$supplier_config_url = dol_buildpath('/idsconnect/supplier_card.php?id='.$supplier_id, 1);
|
|
|
|
foreach ($config_issues['errors'] as $err) {
|
|
setEventMessages($err, null, 'errors');
|
|
idsconnect_notify('action', 'IDS Connect: Konfigurationsfehler', $err, $supplier_config_url, 'Konfiguration öffnen');
|
|
}
|
|
foreach ($config_issues['warnings'] as $warn) {
|
|
setEventMessages($warn, null, 'warnings');
|
|
idsconnect_notify('warning', 'IDS Connect: Konfiguration unvollständig', $warn, $supplier_config_url, 'Konfiguration öffnen');
|
|
}
|
|
if (!empty($config_issues['errors'])) {
|
|
header('Location: '.$supplier_config_url);
|
|
exit;
|
|
}
|
|
|
|
// IDS Connect initialisieren
|
|
$idsconnect = new IdsConnect($db);
|
|
$testmode = $idsconnect->isTestMode($supplier);
|
|
|
|
// Bestätigungsseite bei Live-Modus (extra Sicherheit)
|
|
if (!$testmode && $confirm !== 'yes') {
|
|
llxHeader('', $langs->trans("IdsconnectLaunchConfirm"));
|
|
|
|
print '<div class="confirmmessage">';
|
|
print '<h2>'.$langs->trans("IdsconnectLaunchConfirmTitle").'</h2>';
|
|
print '<p><strong>'.$langs->trans("IdsconnectLaunchConfirmWarning").'</strong></p>';
|
|
print '<p>'.$langs->trans("IdsconnectLaunchConfirmText", $supplier->label, $action).'</p>';
|
|
print '<br>';
|
|
$confirm_url = $_SERVER['PHP_SELF'].'?supplier_id='.$supplier_id.'&ids_action='.urlencode($action).'&confirm=yes&token='.newToken();
|
|
if ($fk_commande > 0) {
|
|
$confirm_url .= '&fk_commande='.$fk_commande;
|
|
}
|
|
print '<a class="butAction" href="'.$confirm_url.'">'.$langs->trans("Confirm").'</a>';
|
|
print ' ';
|
|
print '<a class="butActionDelete" href="'.DOL_URL_ROOT.'/custom/idsconnect/idsconnectindex.php">'.$langs->trans("Cancel").'</a>';
|
|
print '</div>';
|
|
|
|
llxFooter();
|
|
$db->close();
|
|
exit;
|
|
}
|
|
|
|
// Zusätzliche Parameter sammeln
|
|
$extra = array();
|
|
if (!empty(GETPOST('artikelnr', 'alphanohtml'))) {
|
|
$extra['artikelnr'] = GETPOST('artikelnr', 'alphanohtml');
|
|
}
|
|
if (!empty(GETPOST('target', 'alpha'))) {
|
|
$extra['target'] = GETPOST('target', 'alpha');
|
|
}
|
|
|
|
// Bei WKS: Bestellpositionen aus Dolibarr-Bestellung als Warenkorb-XML generieren
|
|
$cart_lines = array();
|
|
if ($action === 'WKS' && $fk_commande > 0) {
|
|
require_once DOL_DOCUMENT_ROOT.'/fourn/class/fournisseur.commande.class.php';
|
|
$order = new CommandeFournisseur($db);
|
|
$order->fetch($fk_commande);
|
|
$order->fetch_lines();
|
|
|
|
if (count($order->lines) > 0) {
|
|
$cart_lines = array();
|
|
foreach ($order->lines as $line) {
|
|
$cart_lines[] = array(
|
|
'artikelnr' => $line->ref_supplier ?: ($line->product_ref ?: ''),
|
|
'bezeichnung' => $line->desc ?: ($line->product_label ?: ''),
|
|
'menge' => $line->qty,
|
|
'einheit' => 'PCE',
|
|
'einzelpreis' => $line->subprice,
|
|
'mwst_satz' => $line->tva_tx,
|
|
);
|
|
}
|
|
$extra['warenkorb'] = $idsconnect->buildCartXml($cart_lines);
|
|
} else {
|
|
setEventMessages('Bestellung hat keine Positionen', null, 'errors');
|
|
header('Location: '.DOL_URL_ROOT.'/fourn/commande/card.php?id='.$fk_commande);
|
|
exit;
|
|
}
|
|
} elseif (!empty(GETPOST('warenkorb', 'none'))) {
|
|
$extra['warenkorb'] = GETPOST('warenkorb', 'none');
|
|
}
|
|
|
|
// WKS-PIN prüfen wenn Bestätigung kommt
|
|
if ($action === 'WKS' && $confirm_wks === 'yes') {
|
|
$stored_hash = getDolGlobalString('IDSCONNECT_WKS_PIN');
|
|
if (!empty($stored_hash)) {
|
|
$pin = GETPOST('wks_pin', 'none');
|
|
if (empty($pin) || !password_verify($pin, $stored_hash)) {
|
|
setEventMessages($langs->trans("IdsconnectWksPinWrong"), null, 'errors');
|
|
$confirm_wks = ''; // Bestätigungsseite erneut zeigen
|
|
}
|
|
}
|
|
}
|
|
|
|
// WKS-Bestätigung: Bestellinhalt prüfen bevor gesendet wird
|
|
if ($action === 'WKS' && !empty($cart_lines) && $confirm_wks !== 'yes') {
|
|
$wks_warn_qty = getDolGlobalInt('IDSCONNECT_WKS_WARN_QTY', 100);
|
|
$wks_warn_value = (float) getDolGlobalString('IDSCONNECT_WKS_WARN_VALUE', '10000');
|
|
|
|
llxHeader('', $langs->trans("IdsconnectWksConfirmTitle"), '', '', 0, 0, '', '', '', 'mod-idsconnect page-wks_confirm');
|
|
|
|
print load_fiche_titre($langs->trans("IdsconnectWksConfirmTitle"), '', 'fa-paper-plane');
|
|
|
|
idsconnectShowTestModeBanner();
|
|
|
|
// Info-Box
|
|
print '<div class="info">';
|
|
print '<strong>'.$langs->trans("IdsconnectWksConfirmInfo", $supplier->label).'</strong>';
|
|
print '</div>';
|
|
|
|
// Artikeltabelle
|
|
print '<table class="noborder centpercent">';
|
|
print '<tr class="liste_titre">';
|
|
print '<th>'.$langs->trans("IdsconnectCartArticleNr").'</th>';
|
|
print '<th>'.$langs->trans("IdsconnectCartDescription").'</th>';
|
|
print '<th class="right">'.$langs->trans("IdsconnectCartQty").'</th>';
|
|
print '<th>'.$langs->trans("IdsconnectCartUnit").'</th>';
|
|
print '<th class="right">'.$langs->trans("IdsconnectCartUnitPrice").'</th>';
|
|
print '<th class="right">'.$langs->trans("IdsconnectCartTotalPrice").'</th>';
|
|
print '</tr>';
|
|
|
|
$total = 0;
|
|
$warnings = array();
|
|
foreach ($cart_lines as $item) {
|
|
$line_total = (float) $item['menge'] * (float) $item['einzelpreis'];
|
|
$total += $line_total;
|
|
$qty_warn = ((float) $item['menge'] > $wks_warn_qty);
|
|
|
|
if ($qty_warn) {
|
|
$warnings[] = $langs->trans("IdsconnectWksWarnQtyLine", $item['artikelnr'], (float) $item['menge'], $wks_warn_qty);
|
|
}
|
|
|
|
print '<tr class="oddeven'.($qty_warn ? ' idsconnect-warn-row' : '').'">';
|
|
print '<td><code>'.htmlspecialchars($item['artikelnr']).'</code></td>';
|
|
print '<td>'.htmlspecialchars($item['bezeichnung']).'</td>';
|
|
print '<td class="right">'.($qty_warn ? '<strong class="idsconnect-warn-text">' : '').((float) $item['menge']).($qty_warn ? '</strong>' : '').'</td>';
|
|
print '<td>'.htmlspecialchars($item['einheit']).'</td>';
|
|
print '<td class="right">'.price($item['einzelpreis']).'</td>';
|
|
print '<td class="right">'.price($line_total).'</td>';
|
|
print '</tr>';
|
|
}
|
|
|
|
print '<tr class="liste_total">';
|
|
print '<td colspan="5" class="right"><strong>'.$langs->trans("Total").'</strong></td>';
|
|
print '<td class="right"><strong>'.price($total).'</strong></td>';
|
|
print '</tr>';
|
|
print '</table>';
|
|
|
|
// Wertwarnung
|
|
if ($total > $wks_warn_value) {
|
|
$warnings[] = $langs->trans("IdsconnectWksWarnValue", price($total), price($wks_warn_value));
|
|
}
|
|
|
|
// Warnungen anzeigen
|
|
if (!empty($warnings)) {
|
|
print '<div class="idsconnect-wks-warning">';
|
|
print '<strong>'.$langs->trans("IdsconnectWksWarningTitle").'</strong><br>';
|
|
foreach ($warnings as $w) {
|
|
print '- '.$w.'<br>';
|
|
}
|
|
print '</div>';
|
|
}
|
|
|
|
// Formular mit PIN-Eingabe und Absenden
|
|
print '<form method="POST" action="'.$_SERVER['PHP_SELF'].'">';
|
|
print '<input type="hidden" name="token" value="'.newToken().'">';
|
|
print '<input type="hidden" name="supplier_id" value="'.$supplier_id.'">';
|
|
print '<input type="hidden" name="ids_action" value="WKS">';
|
|
print '<input type="hidden" name="fk_commande" value="'.$fk_commande.'">';
|
|
print '<input type="hidden" name="confirm_wks" value="yes">';
|
|
if (!$testmode) {
|
|
print '<input type="hidden" name="confirm" value="yes">';
|
|
}
|
|
|
|
// PIN-Eingabe (wenn konfiguriert)
|
|
$has_pin = !empty(getDolGlobalString('IDSCONNECT_WKS_PIN'));
|
|
if ($has_pin) {
|
|
print '<div class="idsconnect-pin-box">';
|
|
print '<label><strong>'.$langs->trans("IdsconnectWksPin").':</strong></label> ';
|
|
print '<input type="password" name="wks_pin" required autocomplete="off" class="width100" placeholder="****">';
|
|
print ' <span class="opacitymedium">'.$langs->trans("IdsconnectWksPinInfo").'</span>';
|
|
print '</div>';
|
|
}
|
|
|
|
print '<div class="tabsAction">';
|
|
print '<input type="submit" class="butAction" value="'.$langs->trans("IdsconnectWksConfirmSend").'">';
|
|
print ' ';
|
|
print '<a class="butActionDelete" href="'.DOL_URL_ROOT.'/fourn/commande/card.php?id='.$fk_commande.'">'.$langs->trans("Cancel").'</a>';
|
|
print '</div>';
|
|
print '</form>';
|
|
|
|
llxFooter();
|
|
$db->close();
|
|
exit;
|
|
}
|
|
|
|
// Bei WKS: Bestellstatus auf "Bestellt" setzen
|
|
if ($action === 'WKS' && $fk_commande > 0 && isset($order) && $order->id > 0) {
|
|
if ($order->statut == CommandeFournisseur::STATUS_ACCEPTED) {
|
|
$order->commande($user, dol_now(), 0);
|
|
dol_syslog("IDS Connect: Bestellstatus auf 'Bestellt' gesetzt für Bestellung #".$order->id, LOG_INFO);
|
|
}
|
|
}
|
|
|
|
// Formular generieren
|
|
$result = $idsconnect->buildLaunchForm($supplier, $action, $user, $extra);
|
|
|
|
if ($result === false) {
|
|
setEventMessages($idsconnect->error, null, 'errors');
|
|
header('Location: '.DOL_URL_ROOT.'/custom/idsconnect/idsconnectindex.php');
|
|
exit;
|
|
}
|
|
|
|
// Testmodus-Hinweis loggen
|
|
if ($result['testmode']) {
|
|
dol_syslog("IDS Connect Launch: TESTMODUS aktiv - Verbindung geht zum Mock-Server", LOG_INFO);
|
|
}
|
|
|
|
// HTML-Formular direkt ausgeben (leitet zum Shop weiter)
|
|
header('Content-Type: text/html; charset=UTF-8');
|
|
echo $result['html'];
|
|
exit;
|