*
* 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 preisbot/admin/history.php
* \ingroup preisbot
* \brief History page: cronjob runs and price changes
*/
$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.'/core/lib/admin.lib.php';
require_once '../lib/preisbot.lib.php';
$langs->loadLangs(array("admin", "preisbot@preisbot"));
if (!$user->admin) {
accessforbidden();
}
$filter = GETPOST('filter', 'aZ09');
if (empty($filter)) {
$filter = '30';
}
/*
* View
*/
$form = new Form($db);
$title = $langs->trans("PreisBotSetup");
llxHeader('', $title, '', '', 0, 0, '', '', '', 'mod-preisbot page-admin_history');
$linkback = ''.$langs->trans("BackToModuleList").'';
print load_fiche_titre($title, $linkback, 'title_setup');
$head = preisbotAdminPrepareHead();
print dol_get_fiche_head($head, 'history', $title, -1, 'preisbot@preisbot');
// ─── Sektion 1: Cronjob-Läufe ────────────────────────────────────────────────
print '
';
print '
'.$langs->trans("PreisBotCronRuns").'
';
$sql = "SELECT rowid, label, status, processing, datelastrun, datelastresult, lastresult, lastoutput, datenextrun";
$sql .= " FROM ".MAIN_DB_PREFIX."cronjob";
$sql .= " WHERE module_name = 'preisbot'";
$sql .= " ORDER BY datelastrun DESC";
$resql = $db->query($sql);
if ($resql && $db->num_rows($resql) > 0) {
print '
';
print '';
print '| '.$langs->trans("Date").' | ';
print ''.$langs->trans("Status").' | ';
print ''.$langs->trans("PreisBotUpdated").' | ';
print ''.$langs->trans("PreisBotSkipped").' | ';
print ''.$langs->trans("Errors").' | ';
print ''.$langs->trans("PreisBotLastOutput").' | ';
print '
';
while ($obj = $db->fetch_object($resql)) {
// Parse Zusammenfassung aus lastoutput
$updated = '-';
$skipped = '-';
$errors = '-';
if (!empty($obj->lastoutput)) {
if (preg_match('/Aktualisiert:\s*(\d+)/u', $obj->lastoutput, $m)) {
$updated = $m[1];
}
if (preg_match('/Übersprungen:\s*(\d+)/u', $obj->lastoutput, $m)) {
$skipped = $m[1];
}
if (preg_match('/Fehler:\s*(\d+)/u', $obj->lastoutput, $m)) {
$errors = $m[1];
}
}
// Status-Badge
if (!empty($obj->processing)) {
$statusLabel = ''.$langs->trans("Running").'';
} elseif (is_null($obj->datelastresult)) {
$statusLabel = ''.$langs->trans("Error").'';
} elseif ($obj->lastresult == 0) {
$statusLabel = ''.$langs->trans("OK").'';
} else {
$statusLabel = ''.$langs->trans("Error").'';
}
// Kurzausgabe (erste 3 Zeilen)
$shortOutput = '';
if (!empty($obj->lastoutput)) {
$lines = array_filter(explode("\n", trim($obj->lastoutput)));
$preview = array_slice(array_values($lines), 0, 3);
$shortOutput = ''.nl2br(dol_htmlentities(implode("\n", $preview))).'';
}
$errorClass = ($errors !== '-' && $errors > 0) ? ' class="error"' : '';
print '';
print '| '.dol_print_date($db->jdate($obj->datelastrun), 'dayhour').' | ';
print ''.$statusLabel.' | ';
print ''.($updated !== '-' ? $updated : '-').' | ';
print ''.$skipped.' | ';
print ''.$errors.' | ';
print ''.$shortOutput.' | ';
print '
';
}
print '
';
} else {
print '
'.$langs->trans("PreisBotNoCronRuns").'
';
}
print '
';
print '
';
// ─── Sektion 2: Preisänderungen ───────────────────────────────────────────────
print '';
print '
'.$langs->trans("PreisBotPriceChanges").'
';
// Filter-Auswahl
print '
';
$sqlFilter = '';
if ($filter > 0) {
$sqlFilter = " AND pp.date_price > DATE_SUB(NOW(), INTERVAL ".(int)$filter." DAY)";
}
$sql = "SELECT pp.rowid, pp.fk_product, pp.date_price, pp.price, pp.price_ttc, pp.tva_tx, pp.price_base_type,";
$sql .= " p.ref, p.label as product_label, pe.preisbot_margin,";
$sql .= " (SELECT pp2.price FROM ".MAIN_DB_PREFIX."product_price pp2";
$sql .= " WHERE pp2.fk_product = pp.fk_product AND pp2.date_price < pp.date_price";
$sql .= " ORDER BY pp2.date_price DESC LIMIT 1) as old_price";
$sql .= " FROM ".MAIN_DB_PREFIX."product_price pp";
$sql .= " LEFT JOIN ".MAIN_DB_PREFIX."product p ON p.rowid = pp.fk_product";
$sql .= " LEFT JOIN ".MAIN_DB_PREFIX."product_extrafields pe ON pe.fk_object = pp.fk_product";
$sql .= " WHERE pp.price_label = 'Preisbot'";
$sql .= $sqlFilter;
$sql .= " ORDER BY pp.date_price DESC";
$sql .= " LIMIT 200";
$resql = $db->query($sql);
if ($resql && $db->num_rows($resql) > 0) {
print '
';
print '';
print '| '.$langs->trans("Date").' | ';
print ''.$langs->trans("Ref").' | ';
print ''.$langs->trans("Label").' | ';
print ''.$langs->trans("PreviousPrice").' | ';
print ''.$langs->trans("NewPrice").' | ';
print ''.$langs->trans("Diff").' | ';
print ''.$langs->trans("PreisBotMinMargin").' | ';
print ''.$langs->trans("VAT").' | ';
print '
';
while ($obj = $db->fetch_object($resql)) {
$newPrice = (float) $obj->price;
$oldPrice = !is_null($obj->old_price) ? (float) $obj->old_price : null;
$diff = !is_null($oldPrice) ? $newPrice - $oldPrice : null;
if (!is_null($diff)) {
$diffStr = ($diff >= 0 ? '+' : '').number_format($diff, 2, ',', '.').' €';
$diffClass = $diff > 0 ? ' style="color:green"' : ($diff < 0 ? ' style="color:red"' : '');
} else {
$diffStr = '-';
$diffClass = '';
}
$productLink = ''.$obj->ref.'';
print '';
print '| '.dol_print_date($db->jdate($obj->date_price), 'dayhour').' | ';
print ''.$productLink.' | ';
print ''.dol_trunc($obj->product_label, 40).' | ';
print ''.(!is_null($oldPrice) ? number_format($oldPrice, 2, ',', '.').' €' : '-').' | ';
print ''.number_format($newPrice, 2, ',', '.').' € | ';
print ''.$diffStr.' | ';
print ''.(!is_null($obj->preisbot_margin) ? number_format((float)$obj->preisbot_margin, 0).' %' : '-').' | ';
print ''.number_format((float)$obj->tva_tx, 0).' % | ';
print '
';
}
print '
';
} else {
print '
'.$langs->trans("PreisBotNoPriceChanges").'
';
}
print '
';
print dol_get_fiche_end();
llxFooter();
$db->close();