Szatuna/managers/statistics.php
2026-02-26 14:35:27 +01:00

537 lines
18 KiB
PHP
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

<?php
include 'dbconn.php';
setlocale(LC_COLLATE, 'hu_HU.UTF-8');
date_default_timezone_set('Europe/Budapest');
if (!function_exists('parseCode')) {
function parseCode(string $str): ?array {
$str = trim($str);
if (!preg_match('/^(?:(\p{L}{1,2}))?(\d+)$/u', $str, $m)) {
return null;
}
$prefix = isset($m[1]) && $m[1] !== '' ? $m[1] : null;
$number = str_pad($m[2], 4, '0', STR_PAD_LEFT);
return [
'prefix' => $prefix,
'number' => $number
];
}
}
if (isset($_GET['type'])) {
$statistics_type = htmlspecialchars($_GET['type']);
if ($statistics_type == "daily") {
// Default értékek lekérése a system_params táblából
$sql = mysqli_query($conn,"SELECT * FROM system_params");
$system_params = [];
while ($row = mysqli_fetch_assoc($sql)) {
$system_params[$row['param_key']] = $row['param_value'];
}
$current_timestamp = time();
$item_query = "SELECT item_id, data_status, CASE WHEN item_id LIKE '%+%' THEN true ELSE false END AS isakit, CASE WHEN front_and_rear LIKE 'hátsó' THEN true ELSE false END AS isarear, CASE WHEN category = 'ClimAir' THEN true ELSE false END AS isacl FROM pr_parameters";
if (isset($_GET['item_id'])) {
$get_item_id = htmlspecialchars(str_replace(' ', '+', $_GET['item_id']));
$item_id_query = mysqli_query($conn, "SELECT item_id FROM pr_parameters WHERE item_id = '$get_item_id'");
$item_id_result = mysqli_fetch_assoc($item_id_query);
if ($item_id_result != null) {
$valid_get_item_id = $item_id_result["item_id"];
$item_query .= " WHERE item_id = '$valid_get_item_id'";
} else {
die("ItemID is invalid!");
}
}
$item_query .= ' ORDER BY isakit DESC';
$item_result = mysqli_query($conn, $item_query);
$path = realpath($_SERVER['DOCUMENT_ROOT']) . '/managers/prdb.json';
$PRDB_data = json_decode(file_get_contents($path), true);
while ($item_row = mysqli_fetch_assoc($item_result)) {
$item_id = $item_row['item_id'];
// Legújabb év adatainak lekérése cikkszámonként
$annual_query = "SELECT item_id, total_consumption, average_production, year
FROM statistics_annual
WHERE item_id = '$item_id'
AND year = (SELECT MAX(year) FROM statistics_annual WHERE item_id = '$item_id')
LIMIT 1";
$annual_result = mysqli_query($conn, $annual_query);
$annual_data = mysqli_fetch_assoc($annual_result);
if ($annual_data) {
if ($annual_data['total_consumption'] == null || intval($annual_data['total_consumption']) < 1) {
$total_consumption = $system_params['default_total_consumption'];
} else {
$total_consumption = $annual_data['total_consumption'];
}
if ($annual_data['average_production'] == null || intval($annual_data['average_production']) < 1) {
$average_production = $system_params['default_average_production'];
} else {
$average_production = $annual_data['average_production'];
}
} else {
$total_consumption = $system_params['default_total_consumption'];
$average_production = $system_params['default_average_production'];
}
// Dobozos raktárkészlet (warehouse tábla)
$warehouse_query = "SELECT SUM(amount) AS warehouse_total FROM warehouse WHERE item_id = '$item_id'";
$warehouse_result = mysqli_query($conn, $warehouse_query);
$warehouse_data = mysqli_fetch_assoc($warehouse_result);
$warehouse_total = $warehouse_data['warehouse_total'] ?? 0;
// Fóliás készlet (kisebbik érték a right_db és left_db közül)
$pair_stock = 0;
// Ellenőrizni, hogy szett-e az item_id
$part1_id = '';
$stock2 = 0;
if ( (bool)$item_row['isakit'] ) {
$parts = explode('+', $item_id, 2);
$first = trim($parts[0]);
$second = trim($parts[1]);
// Prefix keresése (1-2 nem számjegyű karakter az elején)
$prefix = '';
$first_numeric = $first;
if (preg_match('/^([^0-9]{1,2})(.*)$/', $first, $matches)) {
$prefix = $matches[1];
$first_numeric = $matches[2];
} else {
// Nincs prefix, vezető nullákat törlünk
$first_numeric = (string)intval($first);
}
$item1 = $prefix . $first_numeric;
// Második komponens feldolgozása
$second_numeric = $second;
if ($prefix === '') {
$second_numeric = (string)intval($second);
}
$item2 = $prefix . $second_numeric;
$part1_id = $item1;
$part2_id = $item2;
// Készlet lekérése mindkét komponensből
$pair_query1 = "SELECT SUM(right_db) as right_db, SUM(left_db) as left_db FROM warehouse_foil WHERE item_id = '$item1'";
$pair_result1 = mysqli_query($conn, $pair_query1);
$pair_data1 = mysqli_fetch_assoc($pair_result1);
$pair_query2 = "SELECT SUM(right_db) as right_db, SUM(left_db) as left_db FROM warehouse_foil WHERE item_id = '$item2'";
$pair_result2 = mysqli_query($conn, $pair_query2);
$pair_data2 = mysqli_fetch_assoc($pair_result2);
$stock1 = 0;
if ($pair_data1 && ($pair_data1['right_db'] > 0 || $pair_data1['left_db'] > 0)) {
$stock1 = min($pair_data1['right_db'], $pair_data1['left_db']);
}
if ($pair_data2 && ($pair_data2['right_db'] > 0 || $pair_data2['left_db'] > 0)) {
$stock2 = min($pair_data2['right_db'], $pair_data2['left_db']);
}
// A szett fóliás készlete: mindkét komponensből az elérhető pár mennyiség minimuma
$pair_stock = min($stock1, $stock2);
} else {
// Nem szett, normál lekérdezés
$pair_query = "SELECT item_id, SUM(right_db) as right_db, SUM(left_db) as left_db FROM warehouse_foil WHERE item_id = '$item_id'";
$pair_result = mysqli_query($conn, $pair_query);
$pair_data = mysqli_fetch_assoc($pair_result);
if ($pair_data) {
$pair_stock = min($pair_data['right_db'], $pair_data['left_db']);
}
}
// Teljes raktárkészlet
$total_stock = $warehouse_total + $pair_stock;
// Dobozos raktár kitartás
$warehouse_endurance = 0;
if ($total_consumption > 0) {
$warehouse_endurance = $warehouse_total / ($total_consumption / 365);
}
// Eladható mennyiség számítás
$saleable_quantity = $total_stock;
if ( (bool)$item_row['isakit'] ) {
$wh_query_kit = "SELECT SUM(amount) AS warehouse_total FROM warehouse WHERE item_id = '$part1_id'";
$wh_result_kit = mysqli_query($conn, $wh_query_kit);
$wh_data_kit = mysqli_fetch_assoc($wh_result_kit);
$wh_total_kit = $wh_data_kit['warehouse_total'] ?? 0;
$saleable_quantity += min($wh_total_kit, $stock2);
}
// Függő rendelések
$pending_demand_query = "SELECT COALESCE(SUM(amount - taken_out), 0) as pending_demand FROM warehouse_reservation WHERE item_id = '$item_id' AND is_active = 1";
$pending_demand_result = mysqli_query($conn, $pending_demand_query);
$pending_demand_data = mysqli_fetch_assoc($pending_demand_result);
$pending_demand = $pending_demand_data['pending_demand'];
//Szabad raktárkészlet számolás
$free_stock = intval($total_stock) - intval($pending_demand);
$sql_wh = mysqli_query($conn,"SELECT front_and_rear FROM pr_parameters WHERE item_id = '$item_id'");
$pr_param = mysqli_fetch_array($sql_wh);
if ($pr_param['front_and_rear'] == "hátsó") {
$parseCode = parseCode($item_id);
$searchItem_ID = $parseCode['prefix'] . '____+'.$parseCode['number'];
$sql_wh = mysqli_query($conn,"SELECT SUM(warehouse_box) as set_box_count FROM statistics_daily WHERE item_id LIKE '$searchItem_ID'");
$set_box_count = mysqli_fetch_array($sql_wh);
if ($set_box_count != null) {
$free_stock += intval($set_box_count['set_box_count']);
}
$sql_wh = mysqli_query($conn,"SELECT SUM(under_sales) as under_sales FROM statistics_daily WHERE item_id LIKE '$searchItem_ID'");
$set_box_count = mysqli_fetch_array($sql_wh);
if ($set_box_count != null) {
$free_stock -= intval($set_box_count['under_sales']);
}
}
if ($pr_param['front_and_rear'] == "első") {
$searchItem_ID = $item_id.'+____';
$sql_wh = mysqli_query($conn,"SELECT SUM(under_sales) as under_sales FROM statistics_daily WHERE item_id LIKE '$searchItem_ID'");
$set_box_count = mysqli_fetch_array($sql_wh);
if ($set_box_count != null) {
$free_stock -= intval($set_box_count['under_sales']);
}
}
// Készlet kitartás számítása (stock_endurance)
$stock_endurance = 0;
if ($total_consumption > 0) {
$stock_endurance = $free_stock / ($total_consumption / 365);
}
// Priority score
$net_shortage = max(0, $pending_demand - $total_stock);
$priority_score = 0;
if ($average_production > 0) {
$priority_score = (($pending_demand * 1) + ($total_consumption * 1) - ($total_stock * 1)) * MAX(0, (1 - ($stock_endurance / 365)));
// Prioritás = ((Aktív_rendelések × Súly_rendelés) + (Éves_fogyás × Súly_fogyás) (Raktáron × Súly_készlet)) × (1 Készlet kitartás)
$priority_score = -$priority_score;
}
// Boxing score
$net_shortage_box = max(0, $pending_demand - $warehouse_total);
$boxing_score = 0;
if ($total_consumption > 0) {
$boxing_score = (($pending_demand * 1) + ($total_consumption * 1) - ($warehouse_total * 1)) * MAX(0, (1 - ($warehouse_endurance / 365)));
// Prioritás = ((Aktív_rendelések × Súly_rendelés) + (Éves_fogyás × Súly_fogyás) (Dobozban × Súly_készlet)) × (1 Dobozos készlet kitartás)
if ($pair_stock <= 0) {
$boxing_score = $boxing_score - 500;
}
$boxing_score = -$boxing_score;
}
// Gyártás alatt van e
$is_in_production = 0;
$check_production = "SELECT DISTINCT item_id FROM ( SELECT item_id FROM production_classic WHERE stage <> 0 and item_id = '$item_id' UNION SELECT item_id FROM production_injmold WHERE stage <> 0 and item_id = '$item_id' UNION SELECT item_id FROM production_sporty WHERE stage <> 0 and item_id = '$item_id' ) AS combined";
$check_production_Result = mysqli_query($conn, $check_production);
if (mysqli_num_rows($check_production_Result) > 0) {
$is_in_production = 1;
}
// Dobozolás alatt van e
$is_in_boxing = 0;
$check_boxing_query = "SELECT DISTINCT item_id FROM production_boxing WHERE stage <> 0 and item_id = '$item_id'";
$check_boxing_result = mysqli_query($conn, $check_boxing_query);
if (mysqli_num_rows($check_boxing_result) > 0) {
$is_in_boxing = 1;
}
// Gyártás elrejtésre vonatkozó paraméterek
$isPriorityScore = false;
if ( (bool)$item_row["isakit"] || intval($item_row["data_status"]) !== 1 || (bool)$item_row["isacl"] ) {
$isPriorityScore = true;
}
// Dobozolás elrejtésre vonatkozó paraméterek
$isBoxingScore = false;
if ( (bool)$item_row["isarear"] || !(intval($item_row["data_status"]) == 1 || intval($item_row["data_status"]) == -1) || (bool)$item_row["isacl"]) {
$isBoxingScore = true;
}
// Manuálisan elrejtett cikksszámok
$HidedProdStatItemID = ["FR4502"];
$HidedBoxingStatItemID = ["FR4502", "1722", "4504", "2022", "FR4502", "1722+1723"];
if (in_array(strtoupper($item_id), $HidedProdStatItemID)) { $isPriorityScore = true; }
if (in_array(strtoupper($item_id), $HidedBoxingStatItemID)) { $isBoxingScore = true; }
$new_data_status = $item_row["data_status"];
if (intval($item_row["data_status"]) == -1 || intval($item_row["data_status"]) == -2) {
$new_data_status = -1;
if ($is_in_production == 0 && $is_in_boxing == 0 && $pending_demand == 0 && $warehouse_total == 0) {
$new_data_status = -2;
}
}
foreach ($PRDB_data["DBList"] as $table) {
$c_table_id = $table["ID"];
$update_query = "UPDATE $c_table_id SET data_status = '$new_data_status' WHERE item_id = '$item_id'";
$update_result = mysqli_query($conn, $update_query);
}
// Ellenőrzés, hogy létezik-e már az item_id
$check_query = "SELECT item_id FROM statistics_daily WHERE item_id = '$item_id'";
$check_result = mysqli_query($conn, $check_query);
if (mysqli_num_rows($check_result) > 0) {
$update_query = "UPDATE statistics_daily SET
day_date = '$current_timestamp',
warehouse_box = '$warehouse_total',
warehouse_total = '$total_stock',
stock_endurance = '$stock_endurance',
stock_box_endurance = '$warehouse_endurance',
under_production = '$is_in_production',
under_boxing = '$is_in_boxing',
under_sales = '$pending_demand',
saleable_quantity = '$saleable_quantity'";
if ($isPriorityScore) {
$update_query .= ", priority_score = NULL";
} else {
$update_query .= ", priority_score = '$priority_score'";
}
if ($isBoxingScore) {
$update_query .= ", boxing_score = NULL";
} else {
$update_query .= ", boxing_score = '$boxing_score'";
}
if ($new_data_status == -2) {
$update_query .= ", free_stock = NULL";
} else {
$update_query .= ", free_stock = '$free_stock'";
}
$update_query .= " WHERE item_id = '$item_id'";
mysqli_query($conn, $update_query);
} else {
$insert_query = "INSERT INTO statistics_daily ";
$params = "item_id, day_date, warehouse_box, warehouse_total, stock_endurance, stock_box_endurance, under_production, under_boxing, under_sales, saleable_quantity";
$values = "'$item_id', '$current_timestamp', '$warehouse_total', '$total_stock', '$stock_endurance', '$warehouse_endurance', '$is_in_production', '$is_in_boxing', '$pending_demand', '$saleable_quantity'";
if (!$isPriorityScore) {
$params .= ", priority_score";
$values .= ", '$priority_score'";
}
if (!$isBoxingScore) {
$params .= ", boxing_score";
$values .= ", '$boxing_score'";
}
if ($new_data_status != -2) {
$params .= ", free_stock";
$values .= ", '$free_stock'";
}
$insert_query = $insert_query . "(" . $params . ") VALUES (" . $values .")";
mysqli_query($conn, $insert_query);
}
}
if (!isset($_GET['silent'])) echo "Napi statisztika sikeresen frissítve.";
} else if($statistics_type == "backup") {
$backupDir = './backup';
$retentionHours = 24;
$preserveHour = 3; // 03:00 körüli backup megtartása
$force_save = htmlspecialchars($_GET['forcesave']);
// Backup mappa létrehozása ha nem létezik
if (!is_dir($backupDir)) {
mkdir($backupDir, 0755, true);
}
// Adatbázis dump készítés
function createDatabaseDump($conn, $database) {
$tables = array();
$result = $conn->query("SHOW TABLES");
while ($row = $result->fetch_row()) {
$tables[] = $row[0];
}
$dump = "";
foreach ($tables as $table) {
$dump .= "DROP TABLE IF EXISTS `" . $table . "`;\n";
// Tábla szerkezet
$result = $conn->query("SHOW CREATE TABLE `" . $table . "`");
$row = $result->fetch_row();
$dump .= $row[1] . ";\n\n";
// Tábla adatok
$result = $conn->query("SELECT * FROM `" . $table . "`");
while ($row = $result->fetch_assoc()) {
$columns = implode("`, `", array_keys($row));
$values = array();
foreach ($row as $value) {
$values[] = "'" . $conn->real_escape_string($value) . "'";
}
$dump .= "INSERT INTO `" . $table . "` (`" . $columns . "`) VALUES (" . implode(", ", $values) . ");\n";
}
$dump .= "\n";
}
return $dump;
}
// Dump fájl létrehozása
$dumpContent = createDatabaseDump($conn, $servername);
$dumpHash = hash('sha256', $dumpContent);
$dumpFile = $backupDir . '/dump_' . date('Y-m-d_H-i-s') . '.sql';
// Előző mentés hash ellenőrzése
$lastHashFile = $backupDir . '/.last_hash';
$lastHash = file_exists($lastHashFile) ? file_get_contents($lastHashFile) : '';
$currentHour = (int)date('H');
if ($dumpHash === $lastHash && $currentHour != $preserveHour && $force_save != "1") {
exit(0);
}
if (!file_put_contents($dumpFile, $dumpContent)) {
exit(1);
}
file_put_contents($lastHashFile, $dumpHash);
// ZIP létrehozása
$zipFilename = 'SZATURNUSZ_DB_'.date('Y-m-d_H-i') . '.zip';
$zipPath = $backupDir . '/' . $zipFilename;
$zip = new ZipArchive();
if ($zip->open($zipPath, ZipArchive::CREATE) !== TRUE) {
unlink($dumpFile);
exit(1);
}
$zip->addFile($dumpFile, basename($dumpFile));
$zip->close();
// Dump fájl törlése (már ZIP-ben van)
unlink($dumpFile);
// FTP Save
$localIP = trim(shell_exec('hostname -I | cut -d" " -f1'));
if (($currentHour == $preserveHour || $force_save == "1") && $localIP == '192.168.15.10') {
$ftp_server = '192.168.14.91';
$ftp_user = 'Szaturnusz';
$ftp_pass = 'Szat.Ftp.26';
$remote_dir = '/Szaturnusz/';
$conn = ftp_connect($ftp_server, 21);
if (!$conn || !ftp_login($conn, $ftp_user, $ftp_pass)) {
exit('FTP kapcsolat hiba');
}
ftp_chdir($conn, $remote_dir);
$remote_filename = basename($zipPath);
ftp_pasv($conn, true);
ftp_put($conn, $remote_filename, $zipPath, FTP_BINARY);
ftp_close($conn);
} else if ($localIP != '192.168.15.10') {
if (!isset($_GET['silent'])) echo "TEST ENVIROMENT!";
}
// Régi biztonsági mentések törlése
$files = scandir($backupDir);
$backupFiles = array();
foreach ($files as $file) {
if (pathinfo($file, PATHINFO_EXTENSION) === 'zip') {
$filePath = $backupDir . '/' . $file;
$fileTime = filemtime($filePath);
$backupFiles[] = array(
'name' => $file,
'path' => $filePath,
'time' => $fileTime,
'hour' => date('H', $fileTime)
);
}
}
// Idő szerinti rendezés (legöregebbi először)
usort($backupFiles, function($a, $b) {
return $a['time'] - $b['time'];
});
// Törlési logika
$now = time();
$cutoffTime = $now - ($retentionHours * 3600);
$sevenDaysCutoff = $now - (7 * 24 * 3600);
$threeMonthsCutoff = $now - (90 * 24 * 3600);
foreach ($backupFiles as $backup) {
// 3 hónapnál régebbi - egyenesen törlés
if ($backup['time'] < $threeMonthsCutoff) {
unlink($backup['path']);
}
// 24 óránál régebbi
elseif ($backup['time'] < $cutoffTime) {
// 03:00 körüli backupot NE töröljük
if ($backup['hour'] == $preserveHour) {
continue;
}
unlink($backup['path']);
}
// 7 napnál régebbi
elseif ($backup['time'] < $sevenDaysCutoff) {
// Pénteki napokat megtartjuk
$dayOfWeek = date('w', $backup['time']);
if ($dayOfWeek == 5) {
continue;
}
unlink($backup['path']);
}
}
}
if (!isset($_GET['silent'])) exit();
} else {
die("Type is not specified!");
}
?>