Inicial commit

This commit is contained in:
Sperg Tamás 2026-02-26 14:35:27 +01:00
commit 95350b8d05
77 changed files with 57202 additions and 0 deletions

44
.htaccess Normal file
View File

@ -0,0 +1,44 @@
<IfModule mod_headers.c>
Header always set X-Content-Type-Options "nosniff"
Header always set X-XSS-Protection "1; mode=block"
Header always set X-Frame-Options "deny"
# Belső hálózat - cache OK
Header set Cache-Control "private, max-age=3600"
</IfModule>
<FilesMatch "\.(css|gif|ico|jpe|jpeg|jpg|png|pdf)$">
<IfModule mod_expires.c>
ExpiresActive On
ExpiresDefault "access plus 1 hour"
</IfModule>
</FilesMatch>
RewriteEngine on
# HTTPS erőltetés (opcionális belső hálózaton)
# RewriteCond %{HTTPS} off
# RewriteRule ^ https://%{HTTP_HOST}%{REQUEST_URI} [L,R=301]
# PHP rewrite
RewriteCond %{REQUEST_FILENAME} !-d
RewriteCond %{REQUEST_FILENAME}.php -f
RewriteRule ^(.*)$ $1.php [L]
DirectoryIndex index.html index.php
# CSAK külső hotlink ellen (JSON/PHP kivéve)
RewriteCond %{REQUEST_URI} !\.(php|json)$
RewriteCond %{HTTP_REFERER} !^$
RewriteCond %{HTTP_REFERER} !^https?://szaturnusz\.szatuna\.hu [NC]
RewriteRule \.(jpg|jpeg|png|gif|css)$ - [NC,F,L]
# CSAK VALÓDI hibákra ErrorDocument
ErrorDocument 400 /error.php
ErrorDocument 401 /error.php
ErrorDocument 403 /error.php
ErrorDocument 404 /error.php
ErrorDocument 500 /error.php
ErrorDocument 502 /error.php
ErrorDocument 503 /error.php
IndexIgnore *.png *.jpg *.jpeg *.json

52
api/.htaccess Normal file
View File

@ -0,0 +1,52 @@
<IfModule mod_headers.c>
Header always set X-Content-Type-Options "nosniff"
Header always set X-XSS-Protection "1; mode=block"
Header always set X-Frame-Options "deny"
Header set Cache-Control "no-cache, no-store, must-revalidate"
Header set Pragma "no-cache"
Header set Expires 0
</IfModule>
<FilesMatch "\.(css|flv|gif|htm|html|ico|jpe|jpeg|jpg|js|mp3|mp4|png|pdf|swf|txt)$">
<IfModule mod_expires.c>
ExpiresActive Off
</IfModule>
<IfModule mod_headers.c>
FileETag None
Header unset ETag
Header unset Pragma
Header unset Cache-Control
Header unset Last-Modified
Header set Pragma "no-cache"
Header set Cache-Control "max-age=0, no-cache, no-store, must-revalidate"
Header set Expires "Thu, 1 Jan 1970 00:00:00 GMT"
</IfModule>
</FilesMatch>
RewriteEngine on
# PATH TRAVERSAL VÉDELEM
RewriteCond %{REQUEST_URI} (\.\./|/\.\.|\\|\0|%2e%2e) [NC]
RewriteRule .* - [F,L]
# SENSITIVE FILES VÉDELEM (kivéve stock.php és index.php)
RewriteRule ^(wp-config\.php|\.env)$ - [F,L]
# HTTPS erőltetés
RewriteCond %{HTTPS} off
RewriteRule ^ https://%{HTTP_HOST}%{REQUEST_URI} [L,R=301]
# PHP rewrite
RewriteCond %{REQUEST_FILENAME} !-d
RewriteCond %{REQUEST_FILENAME}.php -f
RewriteRule ^(.*)$ $1.php [L]
DirectoryIndex index.html index.php
# Hotlink védelem - CSAK statikus fájlok
RewriteCond %{REQUEST_URI} !\.(php|json)$
RewriteCond %{HTTP_REFERER} !^$
RewriteCond %{HTTP_REFERER} !^https?://(?:www\.)?zimbra\.szatuna\.hu:18821 [NC]
RewriteRule \.(jpg|jpeg|png|gif|css)$ - [NC,F,L]
IndexIgnore *.png *.jpg *.jpeg *.json

BIN
api/favicon.ico Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 4.2 KiB

629
api/index.php Normal file
View File

@ -0,0 +1,629 @@
<!DOCTYPE html>
<html lang="hu">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>API Dokumentáció</title>
<style>
:root {
--color-bg-primary: #f5f5f5;
--color-bg-secondary: #ffffff;
--color-text-primary: #1a1a1a;
--color-text-secondary: #666666;
--color-border: #e0e0e0;
--color-primary: #2563eb;
--color-primary-hover: #1d4ed8;
--color-success: #059669;
--color-warning: #d97706;
--color-error: #dc2626;
--color-code-bg: #f3f4f6;
--sidebar-width: 250px;
}
* {
margin: 0;
padding: 0;
box-sizing: border-box;
}
html {
scroll-behavior: smooth;
}
body {
font-family: -apple-system, BlinkMacSystemFont, 'Segoe UI', Roboto, sans-serif;
background-color: var(--color-bg-primary);
color: var(--color-text-primary);
line-height: 1.6;
}
header {
background-color: var(--color-bg-secondary);
border-bottom: 1px solid var(--color-border);
padding: 20px 0;
position: sticky;
top: 0;
z-index: 100;
box-shadow: 0 1px 3px rgba(0,0,0,0.05);
}
.header-container {
max-width: 1400px;
margin: 0 auto;
padding: 0 20px;
}
h1 {
font-size: 24px;
font-weight: 600;
margin-bottom: 5px;
}
.header-subtitle {
color: var(--color-text-secondary);
font-size: 14px;
}
.container {
max-width: 1400px;
margin: 0 auto;
display: grid;
grid-template-columns: var(--sidebar-width) 1fr;
gap: 0;
min-height: calc(100vh - 80px);
}
aside {
background-color: var(--color-bg-secondary);
border-right: 1px solid var(--color-border);
padding: 20px;
position: sticky;
top: 80px;
height: calc(100vh - 80px);
overflow-y: auto;
}
.nav-section {
margin-bottom: 25px;
}
.nav-section-title {
font-size: 12px;
font-weight: 600;
text-transform: uppercase;
color: var(--color-text-secondary);
margin-bottom: 10px;
letter-spacing: 0.5px;
}
.nav-link {
display: block;
padding: 8px 12px;
margin-bottom: 5px;
color: var(--color-text-secondary);
text-decoration: none;
border-radius: 4px;
transition: all 0.2s ease;
font-size: 14px;
}
.nav-link:hover {
background-color: var(--color-bg-primary);
color: var(--color-primary);
}
.nav-link.active {
background-color: rgba(37, 99, 235, 0.1);
color: var(--color-primary);
font-weight: 500;
}
main {
padding: 40px;
overflow-y: auto;
}
section {
margin-bottom: 50px;
scroll-margin-top: 100px;
}
section:first-child {
margin-top: 0;
}
h2 {
font-size: 28px;
font-weight: 600;
margin-bottom: 15px;
padding-bottom: 10px;
border-bottom: 2px solid var(--color-border);
}
h3 {
font-size: 18px;
font-weight: 600;
margin-top: 20px;
margin-bottom: 12px;
color: var(--color-primary);
}
p {
margin-bottom: 12px;
color: var(--color-text-secondary);
}
.endpoint-block {
background-color: var(--color-bg-secondary);
border: 1px solid var(--color-border);
border-radius: 6px;
padding: 20px;
margin-bottom: 20px;
margin-top: 15px;
}
.endpoint-header {
display: flex;
align-items: center;
gap: 12px;
margin-bottom: 15px;
flex-wrap: wrap;
}
.method-badge {
display: inline-block;
padding: 4px 10px;
border-radius: 4px;
font-size: 12px;
font-weight: 600;
text-transform: uppercase;
letter-spacing: 0.5px;
}
.method-get {
background-color: #dbeafe;
color: #1e40af;
}
.method-post {
background-color: #dcfce7;
color: #166534;
}
.method-put {
background-color: #fed7aa;
color: #92400e;
}
.method-delete {
background-color: #fee2e2;
color: #991b1b;
}
.endpoint-url {
font-family: 'Monaco', 'Menlo', monospace;
background-color: var(--color-code-bg);
padding: 8px 12px;
border-radius: 4px;
font-size: 13px;
word-break: break-all;
flex: 1;
min-width: 200px;
}
.description {
margin-bottom: 15px;
padding: 12px;
background-color: var(--color-bg-primary);
border-left: 3px solid var(--color-primary);
border-radius: 0 4px 4px 0;
}
.param-table {
width: 100%;
border-collapse: collapse;
margin: 15px 0;
font-size: 14px;
}
.param-table th {
background-color: var(--color-code-bg);
padding: 12px;
text-align: left;
font-weight: 600;
border-bottom: 2px solid var(--color-border);
}
.param-table td {
padding: 10px 12px;
border-bottom: 1px solid var(--color-border);
}
.param-table tr:hover {
background-color: var(--color-bg-primary);
}
.param-name {
font-family: 'Monaco', 'Menlo', monospace;
font-weight: 600;
color: var(--color-primary);
}
.param-type {
background-color: var(--color-code-bg);
padding: 2px 6px;
border-radius: 3px;
font-family: 'Monaco', 'Menlo', monospace;
font-size: 12px;
color: var(--color-text-secondary);
}
.required {
background-color: #fee2e2;
color: #991b1b;
padding: 2px 6px;
border-radius: 3px;
font-size: 11px;
font-weight: 600;
}
.optional {
background-color: #fef3c7;
color: #92400e;
padding: 2px 6px;
border-radius: 3px;
font-size: 11px;
font-weight: 600;
}
.code-block {
background-color: #1f2937;
color: #e5e7eb;
padding: 15px;
border-radius: 6px;
overflow-x: auto;
margin: 15px 0;
font-family: 'Monaco', 'Menlo', monospace;
font-size: 13px;
line-height: 1.5;
}
.code-label {
font-size: 12px;
font-weight: 600;
text-transform: uppercase;
color: var(--color-text-secondary);
margin-bottom: 8px;
letter-spacing: 0.5px;
}
.response-example {
margin-top: 15px;
}
.status-code {
display: inline-block;
padding: 6px 12px;
border-radius: 4px;
font-weight: 600;
font-size: 13px;
margin-bottom: 8px;
font-family: 'Monaco', 'Menlo', monospace;
}
.status-200 {
background-color: #dcfce7;
color: #166534;
}
.status-400 {
background-color: #fecaca;
color: #7c2d12;
}
.status-401 {
background-color: #fecaca;
color: #7c2d12;
}
.status-404 {
background-color: #fecaca;
color: #7c2d12;
}
.status-500 {
background-color: #fee2e2;
color: #7f1d1d;
}
.key-value {
display: grid;
grid-template-columns: auto 1fr;
gap: 15px;
margin: 10px 0;
}
.key-value dt {
font-weight: 600;
color: var(--color-primary);
}
.key-value dd {
margin: 0;
color: var(--color-text-secondary);
}
.note-box {
background-color: #eff6ff;
border-left: 4px solid var(--color-primary);
padding: 15px;
border-radius: 4px;
margin: 15px 0;
}
.note-box strong {
color: var(--color-primary);
}
.error-codes {
margin-top: 20px;
}
.error-item {
display: grid;
grid-template-columns: 100px 1fr;
gap: 15px;
padding: 12px 0;
border-bottom: 1px solid var(--color-border);
}
.error-code {
font-family: 'Monaco', 'Menlo', monospace;
font-weight: 600;
color: var(--color-error);
}
@media (max-width: 768px) {
.container {
grid-template-columns: 1fr;
}
aside {
display: none;
}
main {
padding: 20px;
}
h2 {
font-size: 22px;
}
.endpoint-header {
flex-direction: column;
align-items: flex-start;
}
.endpoint-url {
width: 100%;
}
}
::-webkit-scrollbar {
width: 8px;
height: 8px;
}
::-webkit-scrollbar-track {
background: transparent;
}
::-webkit-scrollbar-thumb {
background: #ccc;
border-radius: 4px;
}
::-webkit-scrollbar-thumb:hover {
background: #999;
}
</style>
</head>
<body>
<header>
<div class="header-container">
<h1>API Dokumentáció</h1>
<p class="header-subtitle">Verzió 1.0.0 | Utolsó frissítés: 2025. december 29.</p>
</div>
</header>
<div class="container">
<aside>
<div class="nav-section">
<div class="nav-section-title">Bevezetés</div>
<a href="#overview" class="nav-link active">Áttekintés</a>
<a href="#authentication" class="nav-link">Hitelesítés</a>
</div>
<div class="nav-section">
<div class="nav-section-title">GET Végpontok</div>
<a href="#get-stock" class="nav-link">Raktárkészlet</a>
</div>
<div class="nav-section">
<div class="nav-section-title">Teknikai adatok</div>
<a href="#formats" class="nav-link">Válasz formátumok</a>
<a href="#error-codes" class="nav-link">Hibakódok</a>
</div>
</aside>
<main>
<!-- OVERVIEW -->
<section id="overview">
<h2>Áttekintés</h2>
<p>A Szaturnusz rendszerhez tartozó Web API-k leírását tekintheti meg.</p>
<div class="note-box">
<strong>Alap URL:</strong> https://zimbra.szatuna.hu:18821
</div>
</section>
<!-- AUTHENTICATION -->
<section id="authentication">
<h2>Hitelesítés</h2>
<p>Az API-k jelenleg nem igényelnek hitelesítést. Az összes végpont nyilvánosan elérhető.</p>
</section>
<!-- GET USERS -->
<section id="get-stock">
<h2>GET Végpontok</h2>
<h3>Teljes raktárkészlet lekérdezése</h3>
<div class="endpoint-block">
<div class="endpoint-header">
<span class="method-badge method-get">GET</span>
<span class="endpoint-url">/stock.php</span>
</div>
<div class="description">Az összes raktárban rendelkezésre álló cikkszám lekérdezése. Tartalmazza a szokványos raktárat, a fóliás raktárat és a szett cikkszámokat. Csak pozitív készletű cikkszámok kerülnek visszaadásra.</div>
<h4 style="margin-top: 20px; font-size: 14px; font-weight: 600;">Lekérdezési paraméterek</h4>
<table class="param-table">
<thead>
<tr>
<th>Paraméter</th>
<th>Típus</th>
<th>Státusz</th>
<th>Leírás</th>
</tr>
</thead>
<tbody>
<tr>
<td class="param-name">format</td>
<td><span class="param-type">string</span></td>
<td><span class="optional">opcionális</span></td>
<td>Válasz formátuma: json, csv, xml. Alapértelmezett: json</td>
</tr>
<tr>
<td class="param-name">item_id</td>
<td><span class="param-type">string</span></td>
<td><span class="optional">opcionális</span></td>
<td>Szűrés egy konkrét cikkszámra. Pontos egyezés szükséges</td>
</tr>
</tbody>
</table>
<div class="response-example">
<div class="code-label">Sikeres válasz (JSON)</div>
<span class="status-code status-200">200 OK</span>
<div class="code-block">[
{
"item_id": "PART001",
"total_amount": 42
},
{
"item_id": "PART002",
"total_amount": 15
},
{
"item_id": "PART003+PART004",
"total_amount": 8
}
]</div>
</div>
</div>
</section>
<!-- FORMATS -->
<section id="formats">
<h2>Válasz formátumok</h2>
<p>Az API-k támogatják a JSON, CSV és XML kimeneti formátumokat. Válassz a <code>format</code> paraméterrel.</p>
<h3>JSON formátum (alapértelmezett)</h3>
<div class="endpoint-block">
<div class="code-label">Kérés</div>
<div class="code-block">/stock.php?format=json</div>
<div class="code-label" style="margin-top: 15px;">Válasz</div>
<div class="code-block">[
{
"item_id": "PART001",
"total_amount": 42
}
]</div>
</div>
<h3>CSV formátum</h3>
<div class="endpoint-block">
<div class="code-label">Kérés</div>
<div class="code-block">/stock.php?format=csv</div>
<div class="code-label" style="margin-top: 15px;">Válasz</div>
<div class="code-block">item_id,total_amount
PART001,42
PART002,15
PART003+PART004,8</div>
</div>
<h3>XML formátum</h3>
<div class="endpoint-block">
<div class="code-label">Kérés</div>
<div class="code-block">/stock.php?format=xml</div>
<div class="code-label" style="margin-top: 15px;">Válasz</div>
<div class="code-block">&lt;?xml version="1.0"?&gt;
&lt;root&gt;
&lt;item&gt;
&lt;item_id&gt;PART001&lt;/item_id&gt;
&lt;total_amount&gt;42&lt;/total_amount&gt;
&lt;/item&gt;
&lt;/root&gt;</div>
</div>
</section>
<!-- ERROR CODES -->
<section id="error-codes">
<h2>Hibák és státuszkódok</h2>
<p>Az API-k lekérdezési hibái közvetlenül a kimenetre íródnak. Az alábbi HTTP státuszkódok lehetségesek:</p>
<div class="error-codes">
<div class="error-item">
<div class="error-code">200 OK</div>
<div>A kérés sikeres. Az eredmények JSON/CSV/XML formátumban kerülnek visszaadásra</div>
</div>
<div class="error-item">
<div class="error-code">500 Internal Server Error</div>
<div>Adatbázis kapcsolat vagy lekérdezési hiba. Az error üzenet az stdout-ra íródik</div>
</div>
</div>
<h3>Paraméter validáció</h3>
<p>Az API alapértelmezés szerint figyelmen kívül hagyja az érvénytelen paramétereket:</p>
<ul style="margin-top: 12px; margin-left: 20px;">
<li><code>format</code> Érvénytelen érték esetén JSON alapértelmezett</li>
<li><code>item_id</code> Nem tárolt item_id esetén üres tömb kerül visszaadásra</li>
</ul>
</section>
</main>
</div>
<script type="text/javascript">
const sections = document.querySelectorAll('section');
const navLinks = document.querySelectorAll('.nav-link');
window.addEventListener('scroll', () => {
let currentSection = '';
sections.forEach(section => {
const sectionTop = section.offsetTop;
const sectionHeight = section.clientHeight;
if (pageYOffset >= sectionTop - 200) {
currentSection = section.getAttribute('id');
}
});
navLinks.forEach(link => {
link.classList.remove('active');
if (link.getAttribute('href') === `#${currentSection}`) {
link.classList.add('active');
}
});
});
</script>
</body>
</html>

97
api/stock.php Normal file
View File

@ -0,0 +1,97 @@
<?php
include '../managers/dbconn.php';
function splitSetitem_id($item_id) {
if (strpos($item_id, '+') === false) {
return null;
}
$parts = explode('+', $item_id, 2);
$first = trim($parts[0]);
$second = trim($parts[1]);
$prefix = '';
$first_numeric = $first;
if (preg_match('/^([^0-9]{1,2})(.*)$/', $first, $matches)) {
$prefix = $matches[1];
$first_numeric = $matches[2];
} else {
$first_numeric = (string)intval($first);
}
$item1 = $prefix . $first_numeric;
$second_numeric = $second;
if ($prefix === '') {
$second_numeric = (string)intval($second);
}
$item2 = $prefix . $second_numeric;
return ['item1' => $item1, 'item2' => $item2];
}
$format = isset($_GET['format']) ? strtolower($_GET['format']) : 'json';
$itemIdFilter = isset($_GET['item_id']) ? trim($_GET['item_id']) : null;
$sql = "SELECT s.item_id, s.saleable_quantity
FROM statistics_daily s
INNER JOIN pr_parameters p ON s.item_id = p.item_id
WHERE p.data_status IN (1, -1)
";
$result = $conn->query($sql);
if (!$result) {
die('Lekérdezési hiba: ' . $conn->error);
}
$data = [];
$dataMap = [];
while ($row = $result->fetch_assoc()) {
$data[] = $row;
$dataMap[$row['item_id']] = $row['saleable_quantity'];
}
if ($itemIdFilter !== null) {
$data = array_filter($data, function($row) use ($itemIdFilter) {
return $row['item_id'] === $itemIdFilter;
});
$data = array_values($data);
}
switch ($format) {
case 'csv':
header('Content-Type: text/csv; charset=utf-8');
header('Content-Disposition: attachment; filename="export.csv"');
$output = fopen('php://output', 'w');
if (!empty($data)) {
fputcsv($output, array_keys($data[0]));
foreach ($data as $row) {
fputcsv($output, $row);
}
}
fclose($output);
break;
case 'xml':
header('Content-Type: application/xml; charset=utf-8');
$xml = new SimpleXMLElement('<?xml version="1.0" encoding="UTF-8"?><items/>');
foreach ($data as $row) {
$item = $xml->addChild('item');
foreach ($row as $key => $value) {
$item->addChild($key, htmlspecialchars($value));
}
}
echo $xml->asXML();
break;
case 'json':
default:
header('Content-Type: application/json; charset=utf-8');
echo json_encode($data, JSON_UNESCAPED_UNICODE | JSON_PRETTY_PRINT);
break;
}
$conn->close();
?>

BIN
cloc.exe Normal file

Binary file not shown.

36
css/aszf.css Normal file
View File

@ -0,0 +1,36 @@
body {
width: 100%;
height: 100%;
margin: 0px;
background: #111;
}
::-webkit-scrollbar-track
{
-webkit-box-shadow: inset 0 0 6px rgba(0,0,0,0.3);
background-color: #ecf0f1;
}
::-webkit-scrollbar
{
width: 5px;
background-color: #ecf0f1;
}
::-webkit-scrollbar-thumb
{
background-color: #7f8c8d;
border-radius: 20px;
}
.content {
font-family: monospace;
padding: 30px;
color: #95a5a6;
}
.content p {
color: #7f8c8d;
}
strong {
font-size: 16px;
color: #95a5a6;
font-weight: bold;
}

546
css/custom_panel.css Normal file
View File

@ -0,0 +1,546 @@
/*--- Custom CSS ---*/
.menu .menubtn.exit:hover {
background: #c0392b;
}
.loadingBG img.svg {
width: 400px;
height: 400px;
animation: float 3s ease-in-out infinite;
}
.menubtn p {
font-size: 14px;
}
@keyframes float {
0% { transform: translateY(0); }
50% { transform: translateY(-10px); }
100% { transform: translateY(0); }
}
.redtext {
background: linear-gradient(90deg, #ff0000, #910101, #ff0000);
background-size: 200% 100%;
-webkit-background-clip: text;
-webkit-text-fill-color: transparent;
text-shadow: 0px 0px 20px rgba(206, 0, 0, 0.4);
animation: wave 2s linear infinite;
}
@keyframes wave {
0% { background-position: 200% 50%; }
100% { background-position: 0% 50%; }
}
p.label {
margin: 5px 0px;
font-weight: bold;
}
.wapp input.nameInput {
width: calc(100% - 16px);
max-width: unset;
margin-top: 0px;
margin-bottom: 15px;
font-size: 16px;
font-weight: normal;
}
.window .wapp {
padding-left: 23px;
padding-right: 23px;
width: calc(100% - 46px);
}
div#qrcode {
-webkit-user-drag: none;
user-drag: none;
-webkit-user-select: none;
-moz-user-select: none;
-ms-user-select: none;
user-select: none;
pointer-events: none;
}
select {
max-width: 165px;
}
button {
color: var(--bgcolor);
background: var(--panelcolor);
border: 0px;
}
.boxpc button, .box2 button, .box3 button, .box4 button {
color: var(--panelcolor);
background: var(--bgcolor);
}
/* Products */
.productbox {
display: block;
padding: 3px 20px;
}
.productbox p:first-of-type {
display: inline-block;
font-weight: bold;
float: left;
margin: 0px;
}
.productbox p:first-of-type::after {
content: ":";
}
.productbox p:last-of-type {
color: var(--panelcolor);
display: inline-block;
min-width: 50px;
margin: 0px 0px 0px 6px;
}
.productbox p:last-of-type:focus {
outline: none;
transition: 0.2s;
box-shadow: 0px 1px 1px var(--panelcolor) !important;
background-color: color-mix(in srgb, var(--panelcolor) 8%, #ffffff 90%);
border-radius: 6px 6px 0px 0px;
}
.productbox p:last-of-type:empty {
opacity: 0.2;
outline: none;
box-shadow: 0px 1px 0px var(--panelcolor);
}
/* Helpcursor */
.helpcursor .helptext {
width: 350px;
text-align: left;
left: unset;
right: 0;
margin-right: 30px;
}
/* Version info */
.VersionData {
z-index: 9999;
position: fixed;
left: 5px;
bottom: 5px;
-webkit-user-select: none;
-moz-user-select: none;
-ms-user-select: none;
user-select: none;
}
.VersionData a {
opacity: 0.4;
margin: 0px;
font-size: 12px;
cursor: pointer;
color: #333333;
}
.VersionData a:hover {
opacity: 0.8;
}
/* Category TAB */
.category-tabs {
display: grid;
grid-template-columns: repeat(3, 1fr);
gap: 15px;
margin-top: 30px;
margin-bottom: 30px;
}
.category-tab {
background: white;
border: 2px solid #ddd;
border-radius: 5px;
padding: 20px;
cursor: pointer;
transition: all 0.3s ease;
text-align: center;
}
.category-tab:hover {
border-color: var(--panelcolor);
}
.category-tab.active {
border-color: var(--panelcolor);
background-color: color-mix(in srgb, var(--panelcolor) 10%, #ffffff 90%);;
}
.category-tab-icon {
position: absolute;
}
.category-tab-icon img {
width: 44px;
height: 44px;
}
.category-tab-desc {
font-size: 12px;
opacity: 0.6;
margin-top: 5px;
}
.cat-tab.form-section {
background: white;
border-radius: 5px;
padding: 30px;
display: none;
}
.cat-tab.form-section.active {
display: block;
}
.cat-tab .form-title {
font-size: 18px;
font-weight: 600;
color: var(--panelcolor);
margin-bottom: 5px;
}
.cat-tab .form-desc {
font-size: 13px;
margin-bottom: 25px;
padding-bottom: 15px;
border-bottom: 1px solid #eee;
opacity: 0.6;
}
.cat-tab .form-row {
min-height: 80px;
display: grid;
grid-template-columns: 1fr 1fr 1fr;
gap: 20px;
margin-bottom: 20px;
}
.cat-tab .form-row.full {
grid-template-columns: 1fr;
}
.cat-tab .form-group {
display: flex;
flex-direction: column;
}
.cat-tab label {
font-weight: 600;
font-size: 13px;
margin-bottom: 8px;
color: #333;
}
.cat-tab .required::after {
content: "*";
color: #c0392b;
margin-left: 3px;
}
.cat-tab textarea {
resize: vertical;
min-height: 80px;
}
.cat-tab select {
max-width: 218px;
}
.cat-tab .form-hint {
font-size: 11px;
opacity: 0.5;
margin-top: 4px;
}
.cat-tab .form-actions {
display: flex;
gap: 10px;
margin-top: 25px;
justify-content: flex-end;
}
.cat-tab .info-banner {
background-color: color-mix(in srgb, var(--panelcolor) 10%, #ffffff 90%);;
border-left: 4px solid var(--panelcolor);
padding: 12px 15px;
border-radius: 4px;
margin-bottom: 20px;
font-size: 12px;
color: var(--panelcolor);
}
.cat-tab .info-banner strong {
display: block;
margin-bottom: 3px;
}
@media (max-width: 992px) {
.category-tabs {
grid-template-columns: 1fr;
}
.cat-tab .form-row {
grid-template-columns: 1fr 1fr;
}
}
/* Stat Style */
.statistics {
padding: 16px;
}
.statistics .container {
max-width: 1400px;
margin: 0 auto;
}
.statistics .header {
margin-bottom: 24px;
}
.statistics .header h1 {
margin: 0 0 5px 0;
font-size: 24px;
font-weight: 600;
}
.statistics .header p {
margin: 0;
opacity: 0.8;
font-size: 14px;
}
.statistics .sections {
display: grid;
grid-template-columns: repeat(auto-fit, minmax(380px, 1fr));
gap: 16px;
}
.statistics .section-group {
background: var(--toppanel);
border-radius: 5px;
overflow: hidden;
}
.statistics .section-group-title {
font-family: Arial, Helvetica, sans-serif;
background: var(--panelcolor);
color: var(--bgcolor);
padding: 12px 16px;
font-size: 16px;
font-weight: bold;
margin: 0;
}
.statistics .section {
padding: 12px 16px;
border-bottom: 1px solid rgb(211, 220, 228);
}
.statistics .section:last-child {
border-bottom: none;
}
.statistics .section-name {
font-family: Arial, Helvetica, sans-serif;
font-size: 13px;
font-weight: bold;
margin: 0 0 12px 0;
}
.statistics .article-row {
display: grid;
grid-template-columns: 70px 1fr;
gap: 12px;
align-items: center;
margin-bottom: 5px;
font-size: 13px;
}
.statistics .article-row:last-child {
margin-bottom: 0;
}
.statistics .article-stats {
display: grid;
grid-template-columns: 1fr 1fr;
gap: 5px;
}
.statistics .stat-block {
display: flex;
align-items: baseline;
gap: 4px;
}
.statistics .stat-label {
font-size: 11px;
opacity: 0.8;
min-width: 18px;
}
.statistics .stat-value {
font-weight: 600;
font-size: 14px;
}
.statistics .stat-value.right {
color: var(--panelcolor);
}
.statistics .stat-value.left {
color: var(--panelcolor);
}
.statistics .boxing-row {
display: flex;
flex-direction: column;
gap: 5px;
margin-bottom: 5px;
padding: 5px;
background: var(--bgcolor);
border-radius: 5px;
}
.statistics .boxing-row:last-child {
margin-bottom: 0;
}
.statistics .boxing-header {
display: grid;
grid-template-columns: 70px 1fr;
gap: 12px;
align-items: center;
}
.statistics .boxing-header .article-code {
font-weight: bold;
}
.statistics .boxing-progress {
display: flex;
align-items: center;
gap: 5px;
}
.statistics .progress-bar {
flex: 1;
height: 6px;
background-color: rgb(211, 220, 228);
border-radius: 3px;
overflow: hidden;
}
.statistics .progress-fill {
height: 100%;
background: var(--panelcolor);
transition: width 0.3s ease;
}
.statistics .progress-text {
font-size: 11px;
opacity: 0.8;
}
.statistics .boxing-label {
font-size: 11px;
opacity: 0.8;
}
.statistics .separator {
color: rgb(211, 220, 228);
font-weight: 300;
}
.statistics .section-articles {
display: grid;
grid-template-columns: repeat(auto-fit, minmax(140px, 1fr));
gap: 12px;
}
.statistics .article-card {
background: var(--bgcolor);
border: 1px solid rgb(211, 220, 228);
border-radius: 5px;
padding: 12px;
text-align: center;
display: flex;
flex-direction: column;
gap: 5px;
}
.statistics .article-card-code {
font-weight: bold;
}
.statistics .article-card-stats {
display: flex;
justify-content: center;
gap: 12px;
font-size: 12px;
}
.statistics .article-card-stat {
display: flex;
align-items: center;
gap: 3px;
}
.statistics .article-card-value {
font-size: 13px;
opacity: 0.8;
}
.statistics .article-card-value.right {
color: var(--panelcolor);
opacity: 1;
}
.statistics .article-card-value.left {
color: var(--panelcolor);
opacity: 1;
}
/* Production */
.kanban-card {
display: grid;
grid-template-columns: 1fr auto;
align-items: center;
}
.kanban-card .card-title {
grid-column: 1;
align-items: center;
justify-content: flex-start;
display: flex;
margin-bottom: 8px;
font-size: 16px;
}
.kanban-card .card-subtitle {
font-size: 14px;
grid-column: 1;
display: flex;
justify-content: space-between;
align-items: center;
margin-bottom: 0;
}
.kanban-card .card-button {
grid-column: 2;
grid-row: 1 / 3;
display: flex;
align-items: center;
justify-content: center;
flex-shrink: 0;
margin-left: 12px;
}

64
css/error.css Normal file
View File

@ -0,0 +1,64 @@
@import url('https://fonts.googleapis.com/css?family=Poppins:100,200,300,400,500,600,700,800,900');
*
{
margin: 0;
padding: 0;
box-sizing: border-box;
font-family: 'Poppins', sans-serif;
}
body
{
background: linear-gradient(45deg, #8500ff, #5acaff);
height: 100vh;
}
#container
{
position: absolute;
width: 100%;
height: 100%;
display: flex;
justify-content: center;
align-items: center;
background: url('https://image.kjokmjnoi.hu/image.php?path=/p404'), #151729;
box-shadow: 0 15px 30px rgba(0, 0, 0, .5);
}
#container .content
{
max-width: 600px;
text-align: center;
}
#container .content h2
{
font-size: 18vw;
color: #fff;
line-height: 1em;
}
#container .content h4
{
position: relative;
font-size: 1.5em;
margin-bottom: 20px;
color: #111;
background: #fff;
font-weight: 300;
padding: 10px 20px;
display: inline-block;
}
#container .content p
{
color: #fff;
font-size: 1.2em;
}
#container .content a
{
cursor: pointer;
position: relative;
display: inline-block;
padding: 10px 25px;
background: #2ecc71;
color: #fff;
text-decoration: none;
margin-top: 25px;
border-radius: 25px;
border-bottom: 4px solid #27ae60;
}

405
css/login.css Normal file

File diff suppressed because one or more lines are too long

0
css/panel.css Normal file
View File

99
css/panelupdater.php Normal file
View File

@ -0,0 +1,99 @@
<?php
header('X-Content-Type-Options: nosniff');
header('X-Frame-Options: deny');
header("Cache-Control: no-store, no-cache, must-revalidate, max-age=0");
header("Cache-Control: post-check=0, pre-check=0", false);
header("Pragma: no-cache");
header('X-Powered-By: kbsz');
/*
=============================================
kjokmjnoi API menu design updater
=============================================
This file checks and, if necessary, updates the design of the admin panel.
Panel created by: kjokmjnoi (https://api.kjokmjnoi.hu)
If you have some question please send me an email: sperg.tamas@kjokmjnoi.hu
This file version is: 2.1
============================================
SETTINGS
============================================
*/
$localfile = "panel.css"; // Define where is the style (.css) file.
//Cusom colors
//Be informed about the possible color settings before editing
$ColorSettings = [
"panelcolor" => "#2980b9", //Default: #2980b9
"bgcolor" => "#f5f5f5", //Default: #f5f5f5
"toppanel" => "#ffffff" //Default: #ffffff
];
//Custom CSS
$CustomCSS = file_get_contents("custom_panel.css");
/*
==== End Settings ====
--- Check and update ---
*/
$newestversion = file_get_contents("https://api.kjokmjnoi.hu/css/panel.css").$CustomCSS;
$currentversion = file_get_contents($localfile);
$version = substr($newestversion, 70, 14);
foreach ($ColorSettings as $name => $value) {
$rootcolorname = "--".$name.": ";
$rootcolorname_pos = strpos($newestversion, $rootcolorname);
$rootvalue = "";
if ($rootcolorname_pos !== false) {
$colorvalue_pos = strpos($newestversion, ";", $rootcolorname_pos);
if ($colorvalue_pos !== false) {
$rootvalue = substr($newestversion, $rootcolorname_pos, $colorvalue_pos - $rootcolorname_pos + 1);
} else {
$rootvalue = substr($newestversion, $rootcolorname_pos);
}
}
if ($rootvalue == "") {
echo "Error, There is no color value under the name '".$name."'<br>";
} else {
$newrootvalue = $rootcolorname.$value.";";
if ($newrootvalue != $rootvalue) {
$newestversion = str_replace($rootvalue, $newrootvalue, $newestversion);
echo "Color Setting: ".$rootvalue." -> ".$newrootvalue."<br>";
}
}
}
if ($newestversion != $currentversion) {
if (substr($newestversion, 7, 22) == "@license kjokmjnoi API") {
echo "Update design....";
$designfile = fopen($localfile, "w") or die("Unable to open css file!");
fwrite($designfile, $newestversion);
fclose($designfile);
echo "<br><br>Update finised!<br>";
print_r($version);
} else {
$version = substr($currentversion, 70, 14);
echo "The Design was been removed or temporarily unavailable.<br><br>Update failed!";
print_r($version);
echo " (Not synced)";
}
} else {
echo "The Design is on newest version.<br><br>";
print_r($version);
}
?>

182
dashboard/addperm.php Normal file
View File

@ -0,0 +1,182 @@
<?php
include '../managers/menu.php';
if (!(UserHasPerm("god_profile") && $userID == 1)) {
StopAndDie();
}
if ($_SERVER['REQUEST_METHOD'] === 'POST' && UserHasPerm("god_profile") && $userID = 1 && isset($_POST['anticsrfid']) && $_POST['anticsrfid'] == $_SESSION["anticsrfid"]) {
$perm_id = $_POST['perm_id'] ?? '';
$short_name = $coderclass->encode($_POST['short_name'] ?? '', 'HA98');
$perm_desc = $coderclass->encode($_POST['perm_desc'] ?? '', 'H3AH');
$perm_status = $_POST['perm_status'] ?? '';
$perm_category = $_POST['perm_category'] ?? '';
$risk_factor = $_POST['risk_factor'] ?? '';
$sql = mysqli_query($conn,"SELECT perm_id FROM perm_database WHERE perm_id = '".$perm_id."'");
if(!mysqli_fetch_array($sql)) {
$sql = mysqli_query($conn,"INSERT INTO perm_database (perm_id, short_name, perm_desc, perm_status, perm_category, risk_factor) VALUES ('$perm_id', '$short_name', '$perm_desc', '$perm_status', '$perm_category', '$risk_factor')");
echo "<script>alert('Jog sikeresen létrehozva!');</script>";
} else {
$sql = mysqli_query($conn,"UPDATE perm_database SET short_name='$short_name', perm_desc='$perm_desc', perm_status='$perm_status', perm_category='$perm_category', risk_factor='$risk_factor' WHERE perm_id = '$perm_id'");
echo "<script>alert('Jog sikeresen módosítva!');</script>";
}
}
$anticsrfid = bin2hex(random_bytes(24));
$_SESSION["anticsrfid"] = $anticsrfid;
?>
<!DOCTYPE html>
<html lang="hu" dir="ltr">
<head>
<meta charset="utf-8">
<title>Jog hozzáadása</title>
</head>
<style>
body {
font-family: Arial, sans-serif;
background: #f2f2f2;
display: flex;
justify-content: center;
padding: 50px;
}
form {
background: white;
padding: 30px;
border-radius: 10px;
width: 100%;
max-width: 400px;
box-shadow: 0 4px 10px rgba(0, 0, 0, 0.1);
display: flex;
flex-direction: column;
}
h2 {
text-align: center;
margin-bottom: 30px;
}
.form-group {
position: relative;
margin-bottom: 30px;
}
input {
width: calc(100% - 30px);
padding: 12px 10px;
font-size: 16px;
border: 1px solid #ccc;
border-radius: 5px;
background: none;
outline: none;
}
label {
position: absolute;
top: 12px;
left: 10px;
color: #aaa;
font-size: 16px;
pointer-events: none;
transition: 0.2s ease all;
background-color: white;
padding: 0 5px;
}
input:focus + label,
input:not(:placeholder-shown) + label {
top: -10px;
left: 8px;
font-size: 12px;
color: #48a14d;
}
button {
padding: 12px;
font-size: 16px;
background-color: #48a14d;
color: white;
border: none;
border-radius: 5px;
cursor: pointer;
margin-top: 10px;
}
button:hover {
opacity: 0.8;
}
</style>
<body>
<form action="addperm.php" method="post">
<h2>Jogosultság hozzáadása</h2>
<div class="form-group">
<input type="text" required placeholder=" " id="perm_id" name="perm_id" autocomplete="off" autocapitalize="off" spellcheck="false" autocorrect="off">
<label for="perm_id">Jog ID</label>
</div>
<div class="form-group">
<input type="text" required placeholder=" " id="short_name" name="short_name" autocomplete="off" autocapitalize="off" spellcheck="false" autocorrect="off">
<label for="short_name">Rövid neve</label>
</div>
<div class="form-group">
<input type="text" required placeholder=" " id="perm_desc" name="perm_desc" autocomplete="off" autocapitalize="off" spellcheck="false" autocorrect="off">
<label for="perm_desc">Leírása</label>
</div>
<div class="form-group">
<input type="number" required placeholder=" " id="perm_status" name="perm_status" value="1" min="0" max="2" autocomplete="off" autocapitalize="off" spellcheck="false" autocorrect="off">
<label for="perm_status">Státusza</label>
</div>
<div class="form-group">
<input type="text" required placeholder=" " id="perm_category" name="perm_category" autocomplete="off" autocapitalize="off" spellcheck="false" autocorrect="off" list="category">
<label for="perm_category">Kategória</label>
<datalist id="category">
<?php
$query = "SELECT DISTINCT perm_category FROM perm_database ORDER BY perm_category ASC";
if ($result = $conn->query($query)) {
while ($warehouse = $result->fetch_assoc()) {
echo '<option value="'.$warehouse['perm_category'].'">';
}
}
?>
</datalist>
</div>
<div class="form-group">
<input type="text" required placeholder=" " id="risk_factor" name="risk_factor" autocomplete="off" autocapitalize="off" spellcheck="false" autocorrect="off">
<label for="risk_factor">Rizikófaktor</label>
</div>
<input type="hidden" name="anticsrfid" value="<?php echo $anticsrfid; ?>">
<button type="submit">Hozzáadás</button>
</form>
<script src="../js/default.js" type="text/javascript"></script>
<script type="text/javascript">
document.querySelector("form").addEventListener("submit", function(e) {
const inputs = this.querySelectorAll("input");
let allFilled = true;
inputs.forEach(input => {
if (input.value.trim() === "") {
allFilled = false;
}
});
if (!allFilled) {
e.preventDefault();
alert("Tölts ki minden mezőt!");
}
});
</script>
</body>
</html>

1242
dashboard/boxing.php Normal file

File diff suppressed because it is too large Load Diff

475
dashboard/devplan.php Normal file
View File

@ -0,0 +1,475 @@
<?php
include '../managers/cookie.php';
if (isset($_GET['api']) && $_GET['api'] === '1') {
header('Content-Type: application/json');
$jsonFile = __DIR__ . '/../managers/devplan.json';
function ensureDirectory($file) {
$dir = dirname($file);
if (!is_dir($dir)) {
mkdir($dir, 0755, true);
}
}
if ($_SERVER['REQUEST_METHOD'] === 'GET' && isset($_GET['action']) && $_GET['action'] === 'load') {
ensureDirectory($jsonFile);
if (file_exists($jsonFile)) {
$content = file_get_contents($jsonFile);
echo $content;
} else {
echo json_encode(['plans' => []]);
}
exit;
}
if ($_SERVER['REQUEST_METHOD'] === 'POST' && isset($_GET['action']) && $_GET['action'] === 'save') {
ensureDirectory($jsonFile);
$input = file_get_contents('php://input');
$data = json_decode($input, true);
if (json_last_error() === JSON_ERROR_NONE) {
file_put_contents($jsonFile, json_encode($data, JSON_PRETTY_PRINT | JSON_UNESCAPED_UNICODE));
echo json_encode(['success' => true]);
} else {
http_response_code(400);
echo json_encode(['success' => false, 'error' => 'Hibás JSON formátum']);
}
exit;
}
if ($_SERVER['REQUEST_METHOD'] === 'POST' && isset($_GET['action']) && $_GET['action'] === 'complete') {
$input = file_get_contents('php://input');
$data = json_decode($input, true);
if (json_last_error() !== JSON_ERROR_NONE || !isset($data['index'])) {
http_response_code(400);
echo json_encode(['success' => false, 'error' => 'Hibás JSON formátum']);
exit;
}
$index = (int)$data['index'];
// Devplan betöltése
ensureDirectory($jsonFile);
$devplanData = ['plans' => []];
if (file_exists($jsonFile)) {
$content = file_get_contents($jsonFile);
$devplanData = json_decode($content, true);
if (!is_array($devplanData) || !isset($devplanData['plans'])) {
$devplanData = ['plans' => []];
}
}
if (!isset($devplanData['plans'][$index])) {
http_response_code(400);
echo json_encode(['success' => false, 'error' => 'Érvénytelen index']);
exit;
}
$planName = $devplanData['plans'][$index];
// Version.json betöltése
$versionFile = __DIR__ . '/../managers/version.json';
$versionData = ['updates' => []];
if (file_exists($versionFile)) {
$versionContent = file_get_contents($versionFile);
$versionData = json_decode($versionContent, true);
if (!is_array($versionData) || !isset($versionData['updates'])) {
$versionData = ['updates' => []];
}
}
// Legutóbbi build szám használata
if (empty($versionData['updates'])) {
http_response_code(400);
echo json_encode(['success' => false, 'error' => 'Nincs meglévő build szám']);
exit;
}
$build = $versionData['updates'][0]['build'];
// Changelog bejegyzés hozzáadása a legutóbbi buildhez
if (!in_array($planName, $versionData['updates'][0]['changes'], true)) {
array_unshift($versionData['updates'][0]['changes'], $planName);
}
// Version.json mentése
file_put_contents($versionFile, json_encode($versionData, JSON_UNESCAPED_UNICODE | JSON_PRETTY_PRINT));
// Terv törlése a devplan.json-ból
array_splice($devplanData['plans'], $index, 1);
file_put_contents($jsonFile, json_encode($devplanData, JSON_PRETTY_PRINT | JSON_UNESCAPED_UNICODE));
echo json_encode(['success' => true, 'build' => $build]);
exit;
}
http_response_code(400);
echo json_encode(['success' => false, 'error' => 'Hibás kérés']);
exit;
} else {
$CanEdit = false;
$localIP = trim(shell_exec('hostname -I | cut -d" " -f1'));
if (UserHasPerm("god_profile") && $userID == 1 && $localIP == '192.168.15.10') {
$CanEdit = true;
}
}
?>
<!DOCTYPE html>
<html lang="hu">
<head>
<meta charset="UTF-8">
<link rel="stylesheet" href="../css/login.css">
<title>Fejlesztési Tervek</title>
<style>
* {
margin: 0;
padding: 0;
box-sizing: border-box;
}
body {
background: linear-gradient(135deg, var(--bgcolorlight) 0%, var(--bgcolordark) 100%);
padding: 20px;
}
.Background {
z-index: 0;
position: fixed;
top: 0px;
left: 0px;
width: 100%;
height: 100%;
background: linear-gradient(135deg, var(--bgcolorlight) 0%, var(--bgcolordark) 100%);
}
.devplanContainer {
z-index: 1;
position: relative;
max-width: 700px;
margin: 0 auto;
background: white;
border-radius: 8px;
box-shadow: 0 2px 10px rgba(0,0,0,0.1);
padding: 30px;
}
h1 {
color: #2980b9;
margin-bottom: 30px;
text-align: center;
}
.plan-list {
list-style: none;
margin-bottom: 30px;
}
.plan-item {
background: #f8f9fa;
border-left: 4px solid #2980b9;
padding: 15px;
margin-bottom: 10px;
border-radius: 4px;
display: flex;
align-items: center;
justify-content: space-between;
transition: all 0.2s;
}
.plan-item:hover {
box-shadow: 0 2px 8px rgba(41, 128, 185, 0.2);
}
.plan-item.dragging {
opacity: 0.5;
}
.plan-content {
flex: 1;
color: #333;
}
.plan-controls {
display: flex;
gap: 8px;
}
.devplanBtn {
background: #2980b9;
color: white;
border: none;
padding: 8px 12px;
border-radius: 4px;
cursor: pointer;
font-size: 14px;
transition: background 0.2s;
}
.devplanBtn:hover {
background: #1f6391;
}
.devplanBtn-complete {
background: #27ae60;
}
.devplanBtn-complete:hover {
background: #1e8449;
}
.devplanBtn-delete {
background: #e74c3c;
}
.devplanBtn-delete:hover {
background: #c0392b;
}
.devplanBtn:disabled {
background: #95a5a6;
cursor: not-allowed;
}
.add-section {
border-top: 2px solid #ecf0f1;
padding-top: 20px;
}
.input-group {
display: flex;
gap: 10px;
}
.input-group input {
flex: 1;
padding: 12px;
border: 2px solid #2980b9;
border-radius: 4px;
font-size: 14px;
margin: unset;
background: unset;
color: #333;
}
.input-group input:focus {
outline: none;
border-color: #1f6391;
}
.empty-state {
text-align: center;
color: #95a5a6;
padding: 40px;
font-style: italic;
}
.drag-handle {
cursor: grab;
color: #2980b9;
margin-right: 10px;
font-size: 18px;
}
.drag-handle:active {
cursor: grabbing;
}
</style>
</head>
<body>
<div class="Background"></div>
<div class="devplanContainer">
<h1>Fejlesztési Tervek</h1>
<ul class="plan-list" id="planList"></ul>
<div class="add-section" id="addSection">
<div class="input-group">
<input type="text" id="newPlanInput" placeholder="Új fejlesztési terv hozzáadása...">
<button class="devplanBtn" onclick="addPlan()">Hozzáadás</button>
</div>
</div>
</div>
<script>
const canEdit = <?= $CanEdit ? 'true' : 'false' ?>;
let plans = [];
let draggedElement = null;
async function loadPlans() {
try {
const response = await fetch('devplan.php?action=load&api=1');
const data = await response.json();
plans = data.plans || [];
renderPlans();
} catch (error) {
console.error('Hiba a tervek betöltésekor:', error);
}
}
async function savePlans() {
try {
await fetch('devplan.php?action=save&api=1', {
method: 'POST',
headers: {
'Content-Type': 'application/json'
},
body: JSON.stringify({ plans: plans })
});
} catch (error) {
console.error('Hiba a mentés során:', error);
}
}
function renderPlans() {
const listElement = document.getElementById('planList');
listElement.innerHTML = '';
if (!canEdit) {
document.getElementById("addSection").style.display = 'none';
}
if (plans.length === 0) {
listElement.innerHTML = '<div class="empty-state">Még nincsenek fejlesztési tervek</div>';
return;
}
plans.forEach((plan, index) => {
const li = document.createElement('li');
li.className = 'plan-item';
li.draggable = canEdit;
li.dataset.index = index;
li.innerHTML = `
${canEdit ? '<span class="drag-handle">☰</span>' : ''}
<div class="plan-content">${escapeHtml(plan)}</div>
<div class="plan-controls">
${canEdit ? `<button class="devplanBtn devplanBtn-complete" onclick="completePlan(${index})" title="Kész, áthelyezés a changelogba">✓</button>` : ''}
${canEdit ? `<button class="devplanBtn devplanBtn-delete" onclick="deletePlan(${index})">Törlés</button>` : ''}
</div>
`;
if (canEdit) {
li.addEventListener('dragstart', handleDragStart);
li.addEventListener('dragend', handleDragEnd);
li.addEventListener('dragover', handleDragOver);
li.addEventListener('drop', handleDrop);
}
listElement.appendChild(li);
});
}
function handleDragStart(e) {
draggedElement = this;
this.classList.add('dragging');
e.dataTransfer.effectAllowed = 'move';
}
function handleDragEnd(e) {
this.classList.remove('dragging');
draggedElement = null;
}
function handleDragOver(e) {
if (e.preventDefault) {
e.preventDefault();
}
e.dataTransfer.dropEffect = 'move';
return false;
}
function handleDrop(e) {
if (e.stopPropagation) {
e.stopPropagation();
}
if (draggedElement !== this) {
const draggedIndex = parseInt(draggedElement.dataset.index);
const targetIndex = parseInt(this.dataset.index);
const draggedPlan = plans[draggedIndex];
plans.splice(draggedIndex, 1);
plans.splice(targetIndex, 0, draggedPlan);
savePlans();
renderPlans();
}
return false;
}
async function addPlan() {
if (!canEdit) return;
const input = document.getElementById('newPlanInput');
const value = input.value.trim();
if (value === '') {
alert('Kérlek, adj meg egy fejlesztési tervet!');
return;
}
plans.push(value);
input.value = '';
await savePlans();
renderPlans();
}
async function deletePlan(index) {
if (!canEdit) return;
if (confirm('Biztosan törölni szeretnéd ezt a tervet?')) {
plans.splice(index, 1);
await savePlans();
renderPlans();
}
}
async function completePlan(index) {
if (!canEdit) return;
if (confirm('A terv kész? Áthelyezed a changelogba?')) {
try {
const response = await fetch('devplan.php?action=complete&api=1', {
method: 'POST',
headers: {
'Content-Type': 'application/json'
},
body: JSON.stringify({ index: index })
});
const result = await response.json();
if (result.success) {
await loadPlans();
alert('A terv sikeresen áthelyezve a changelogba!\nBuild szám: ' + result.build);
} else {
alert('Hiba történt: ' + (result.error || 'Ismeretlen hiba'));
}
} catch (error) {
console.error('Hiba a terv befejezésekor:', error);
alert('Hiba történt a művelet során.');
}
}
}
function escapeHtml(text) {
const div = document.createElement('div');
div.textContent = text;
return div.innerHTML;
}
document.getElementById('newPlanInput').addEventListener('keypress', function(e) {
if (e.key === 'Enter') {
addPlan();
}
});
loadPlans();
</script>
</body>
</html>

139
dashboard/index.php Normal file
View File

@ -0,0 +1,139 @@
<?php
include '../managers/menu.php';
$IsGlobalError = false;
$GlobalErrorText = "";
if (isset($_SESSION['error_message']) && $_SESSION['error_message'] != "") {
$IsGlobalError = true;
$GlobalErrorText = $_SESSION['error_message'];
$_SESSION['error_message'] = '';
}
$sql = mysqli_query($conn,"SELECT otptype, otphash FROM users WHERE uid = '$userID'");
$user2Fa = mysqli_fetch_array($sql);
$Need2FAActivation = false;
$totpKey = '';
$totpQRCode = '';
$anticsrfid = '';
if (($user2Fa['otptype'] == 2 || $user2Fa['otptype'] == 3) && $user2Fa['otphash'] == "") {
$Need2FAActivation = true;
$totp = new TOTP();
$totpKey = $totp->generateKey();
$totpQRCode = 'otpauth://totp/Szaturnusz?secret='.$totpKey.'&issuer=saturn&algorithm=SHA1&digits=6&period=30';
$anticsrfid = bin2hex(random_bytes(24));
$_SESSION["anticsrfid"] = $anticsrfid;
$menuhtml = str_replace('<script src="../js/bug_report.js"></script>', '', $menuhtml);
}
?>
<!DOCTYPE html>
<html lang="hu" dir="ltr">
<head>
<meta charset="utf-8">
<link rel="stylesheet" href="../css/panel.css">
<title>Kezelőfelület</title>
</head>
<body>
<?php echo $menuhtml;?>
<div class="window closed" id="win">
<div class="topbar">
<p id="wintitle">Title</p>
<div class="btn fullscrn" onclick="fullscrn();" id="fullscrnbtn"></div>
<div class="btn close" onclick="closewin();"></div>
</div>
<div class="wapp" id="winapp"><div id="errorDIV"></div></div>
<div class="loading" id="winloading"></div>
</div>
<div class="loadingBG" id="loadingBG"><img src="../img/loading.gif"></div>
<div class="content">
<div id="errorDIV" style="z-index: 100; top: 50px; position: fixed; width: calc(100% - 260px);"></div>
<!-- Tartalmi rész kezdete -->
<!--
<div class="box">
<p class="strong">Tervezett leállás!</p>
<p><span style="color: var(--panelcolor);">2026.01.13. 22:00</span>-tól tervezett leállás várható rendszerkarbantartás miatt!</p>
</div>
-->
<!-- Tartalmi rész vége -->
</div>
<script src="../js/default.js" type="text/javascript"></script>
<?php if ($Need2FAActivation) {echo '<script src="../js/qrcode.js" type="text/javascript"></script>';}?>
<script type="text/javascript">
var GlobalAntiCSRFId = "<?php echo $anticsrfid;?>";
if (<?php if ($IsGlobalError) {echo 'true';} else {echo 'false';}?>) {
GenerateAlerts('error', '<?php echo $GlobalErrorText;?>', false);
}
if (<?php if ($Need2FAActivation) {echo 'true';} else {echo 'false';}?>) {
html = `<?php
echo '<p><b>Fiók aktiválás!</b></p><p>Scannelje be a QR kódot hitelesítő alkalmazásában,<br><i style="opacity: 0.8;">(pl: Google Authenticator, Authy, Microsoft Authenticator)</i><br>majd írja be a kapott kódot, hogy elkezdhesse használni fiókját.</p><br>';
echo '<div style="display: flex; justify-content: center; align-items: center; height: 160px;"><div id="qrcode" style="width: 160px; height: 160px;"></div></div>';
echo '<p style="text-align: center;">'.$totpKey.'</p>';
echo '<input style="margin: auto;" type="text" id="otc" class="otc" maxlength="6" autocomplete="off">
<div style="display: flex; justify-content: center; align-items: center; margin-top: 15px;">
<input type="password" id="pass" placeholder="Jelenlegi jelszó..." autocomplete="off">
<input type="hidden" id="otckey" value="'.$totpKey.'">
<button style="margin-left: 15px;" onclick="Activate2fa();">Aktiválás</button></div>';
?>`;
CreateAlertBox("Kétlépcsős hitelesítés", html, false);
}
function Activate2fa() {
Loading();
var otc = document.getElementById("otc").value;
var otckey = document.getElementById("otckey").value;
var pass = document.getElementById("pass").value;
const body = 'f=Activate2fa&otc=' + encodeURIComponent(otc).replace(/%20/g, '+') + '&otckey=' + encodeURIComponent(otckey).replace(/%20/g, '+') + '&pass=' + encodeURIComponent(pass).replace(/%20/g, '+') + '&anticsrfid=' + GlobalAntiCSRFId;
get_POST_information("profile.php", body, function(text) {
Loading(false);
if (text == "ok") {
html = `<p><b>Sikeresen aktiválta a kétlépcsős hitelesítést!</b> Mostmár használhatja fiókját.</p>`;
CreateAlertBox("Kétlépcsős hitelesítés", html, false);
setTimeout(() => {window.location.reload();}, 2000);
} else {
html = `<p style="color: red;"><b>${text}</b></p>`;
CreateAlertBox("HIBA", html);
}
}, function() {
html = `<p style="color: red;"><b>Hálózati hiba történt, próbálja újra!</b></p>`;
CreateAlertBox("HIBA", html);
Loading(false);
});
}
if (document.getElementById('qrcode')) {
new QRCode(document.getElementById("qrcode"), {
text: "<?php echo $totpQRCode;?>",
width: 160,
height: 160,
colorDark : "#000000",
colorLight : "#ffffff",
correctLevel : QRCode.CorrectLevel.H
});
}
</script>
</body>
</html>

1967
dashboard/itemcreator.php Normal file

File diff suppressed because it is too large Load Diff

758
dashboard/labelmaker.php Normal file
View File

@ -0,0 +1,758 @@
<?php
include '../managers/menu.php';
$warehouses = [];
$foil_warehouse = null;
$query = "SELECT * FROM warehouse_structure ORDER BY warehouse_id ASC";
if ($result = $conn->query($query)) {
while ($row = $result->fetch_assoc()) {
$warehouses[] = $row;
}
}
// Fóliás helyeket lekérése
$foil_places = [];
$foil_query = "SELECT foil_product_place FROM pr_warehouse_parameters WHERE foil_product_place IS NOT NULL AND foil_product_place != ''";
if ($result_foil = $conn->query($foil_query)) {
while ($row = $result_foil->fetch_assoc()) {
// Vesszővel elválasztott helyeket fel bontjuk
$places = array_map('trim', explode(',', $row['foil_product_place']));
$foil_places = array_merge($foil_places, $places);
}
}
// Duplikátumok eltávolítása, rendezés
$foil_places = array_unique($foil_places);
$foil_places = array_values($foil_places);
function mixed_compare($a, $b) {
preg_match_all('/(\D+|\d+)/', $a, $a_parts);
preg_match_all('/(\D+|\d+)/', $b, $b_parts);
$a_parts = $a_parts[0];
$b_parts = $b_parts[0];
$i = 0;
while (isset($a_parts[$i]) && isset($b_parts[$i])) {
if (ctype_digit($a_parts[$i]) && ctype_digit($b_parts[$i])) {
$diff = intval($a_parts[$i]) - intval($b_parts[$i]);
if ($diff !== 0) {
return $diff;
}
} else {
$diff = strcmp($a_parts[$i], $b_parts[$i]);
if ($diff !== 0) {
return $diff;
}
}
$i++;
}
return count($a_parts) - count($b_parts);
}
// Használat usort-tal
usort($foil_places, 'mixed_compare');
?>
<!DOCTYPE html>
<html lang="hu">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Raktár Címke Generátor</title>
<script src="../js/qrcode.js" type="text/javascript"></script>
<style>
:root {
--label-width: 8.6cm;
--label-height: 4.2cm;
--qr-size: 140;
}
:root {
--color-primary: #208091;
--color-bg: #fcfcf9;
--color-surface: #fffffe;
--color-text: #134252;
--color-border: #5e5240;
}
* {
box-sizing: border-box;
}
body {
font-family: "Source Sans Pro", sans-serif;
margin: 0;
padding: 20px;
background: var(--color-bg);
color: #333333;
}
.size-settings {
display: grid;
grid-template-columns: repeat(3, 1fr);
gap: 16px;
margin-bottom: 20px;
}
.size-input-group {
display: flex;
gap: 12px;
align-items: flex-end;
}
.size-input-group input {
width: 100px;
padding: 8px 12px;
border: 1px solid rgba(94, 82, 64, 0.2);
border-radius: 8px;
font-size: 14px;
}
.size-input-group label {
margin-bottom: 0;
}
.container {
max-width: 1200px;
margin: 0 auto;
}
h1 {
font-size: 28px;
margin: 0 0 24px 0;
font-weight: 600;
}
.selector-section {
background: var(--color-surface);
border: 1px solid rgba(94, 82, 64, 0.2);
border-radius: 8px;
padding: 20px;
margin-bottom: 24px;
}
.selector-row {
display: flex;
gap: 16px;
align-items: flex-end;
margin-bottom: 16px;
}
.selector-row:last-child {
margin-bottom: 0;
}
.form-group {
flex: 1;
min-width: 200px;
}
label {
display: block;
font-size: 12px;
font-weight: 500;
margin-bottom: 8px;
color: var(--color-text);
}
select {
width: 100%;
padding: 8px 12px;
border: 1px solid rgba(94, 82, 64, 0.2);
border-radius: 8px;
font-size: 14px;
background: var(--color-surface);
color: var(--color-text);
-webkit-appearance: none;
-moz-appearance: none;
appearance: none;
background-image: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' width='16' height='16' viewBox='0 0 24 24' fill='none' stroke='%23134252' stroke-width='2' stroke-linecap='round' stroke-linejoin='round'%3E%3Cpolyline points='6 9 12 15 18 9'%3E%3C/polyline%3E%3C/svg%3E");
background-repeat: no-repeat;
background-position: right 12px center;
background-size: 16px;
padding-right: 32px;
cursor: pointer;
}
select:focus {
outline: 2px solid var(--color-primary);
outline-offset: 2px;
}
button {
padding: 8px 20px;
background: var(--color-primary);
color: #fcfcf9;
border: none;
border-radius: 8px;
font-size: 14px;
font-weight: 500;
cursor: pointer;
transition: background 150ms ease;
}
button:hover {
background: #1a7480;
}
button:active {
background: #1a6873;
}
button:focus-visible {
outline: 2px solid var(--color-primary);
outline-offset: 2px;
}
.print-section {
display: none;
}
.print-section.active {
display: block;
}
.print-controls {
margin-bottom: 20px;
text-align: right;
}
.print-controls button {
margin-left: 12px;
}
.labels-grid {
display: grid;
grid-template-columns: repeat(auto-fill, minmax(var(--label-width), 1fr));
gap: 20px;
margin-bottom: 20px;
}
.label-card {
background: var(--color-surface);
border: 1px solid rgba(94, 82, 64, 0.2);
border-radius: 8px;
padding: 16px;
display: flex;
flex-direction: row;
justify-content: space-between;
align-items: center;
width: var(--label-width);
height: var(--label-height);
box-sizing: border-box;
overflow: hidden;
gap: 8px;
}
.label-content {
flex: 1;
display: flex;
flex-direction: column;
justify-content: center;
}
.label-code {
font-size: 55px;
font-weight: 600;
color: var(--color-text);
white-space: nowrap;
line-height: 1.2;
margin: 0 0 8px 0;
flex: 1;
min-width: 0;
overflow: hidden;
text-overflow: ellipsis;
}
.qrcode-container {
flex-shrink: 0;
align-self: center;
margin-left: 12px;
width: var(--qr-size);
height: var(--qr-size);
min-width: var(--qr-size);
min-height: var(--qr-size);
}
.qrcode-container img {
width: var(--qr-size) !important;
height: var(--qr-size) !important;
max-width: var(--qr-size) !important;
max-height: var(--qr-size) !important;
display: block;
}
@media print {
body {
background: white;
padding: 0;
}
.selector-section,
.print-controls,
.size-settings,
h1 {
display: none;
}
.labels-grid {
grid-template-columns: repeat(auto-fill, minmax(var(--label-width), 1fr));
gap: 16px;
margin: 0;
}
.label-card {
page-break-inside: avoid;
width: var(--label-width);
height: var(--label-height);
box-sizing: border-box;
overflow: hidden;
}
.qrcode-container {
width: var(--qr-size);
height: var(--qr-size);
min-width: var(--qr-size);
min-height: var(--qr-size);
}
}
.loading-overlay {
position: fixed;
top: 0;
left: 0;
width: 100%;
height: 100%;
background: rgba(0, 0, 0, 0.5);
display: flex;
align-items: center;
justify-content: center;
z-index: 9999;
}
.loading-overlay.hidden {
display: none;
}
.loading-spinner {
text-align: center;
background: var(--color-surface);
padding: 40px;
border-radius: 12px;
box-shadow: 0 10px 40px rgba(0, 0, 0, 0.2);
}
.spinner {
width: 50px;
height: 50px;
margin: 0 auto 20px;
border: 4px solid rgba(94, 82, 64, 0.2);
border-top: 4px solid var(--color-primary);
border-radius: 50%;
animation: spin 1s linear infinite;
}
@keyframes spin {
0% { transform: rotate(0deg); }
100% { transform: rotate(360deg); }
}
.loading-spinner p {
color: var(--color-text);
margin: 0;
font-size: 16px;
font-weight: 500;
}
.loading-counter {
color: var(--color-text-secondary);
margin: 12px 0 0 0;
font-size: 16px;
}
</style>
</head>
<body>
<div id="loading-overlay" class="loading-overlay hidden">
<div class="loading-spinner">
<div class="spinner"></div>
<p class="loading-counter"><span id="qr-total">0</span> címke generálása...</p>
</div>
</div>
<div class="container">
<h1>Raktárhely Címke Generátor</h1>
<div class="selector-section">
<div class="selector-row">
<div class="form-group" style="flex: 2;">
<label for="warehouse-select">Raktár kiválasztása:</label>
<select id="warehouse-select">
<option value="">-- Válassz raktárt --</option>
</select>
</div>
<button onclick="generateLabels()">Címkék generálása</button>
<button onclick="generateAllLabels()" style="background: #1a7480;">Összes generálása</button>
</div>
<div class="size-settings">
<div class="size-input-group">
<label for="label-width">Szélesség (cm):</label>
<input type="number" id="label-width" value="9" min="1" max="30" step="0.1">
</div>
<div class="size-input-group">
<label for="label-height">Magasság (cm):</label>
<input type="number" id="label-height" value="3" min="1" max="30" step="0.1">
</div>
<div class="size-input-group">
<label for="qr-size">QR méret (px):</label>
<input type="number" id="qr-size" value="80" min="40" max="300" step="5">
</div>
</div>
</div>
<div class="print-section" id="print-section">
<div class="print-controls">
<button onclick="window.print()">🖨 Nyomtatás</button>
<button onclick="resetView()"> Újra</button>
</div>
<div class="labels-grid" id="labels-grid"></div>
</div>
</div>
<script>
function NumberToABC(n) {
const abc = 'ABCDEFGHIJKLMNOPQRSTUVWXYZ';
if (typeof n === 'string') {
const num = parseInt(n, 10);
if (isNaN(num) || num < 1 || num > 26) return null;
return abc.charAt(num - 1);
}
if (typeof n !== 'number' || n < 1 || n > 26) return null;
return abc.charAt(n - 1);
}
function padWithZero(str) {
if (str.length === 2) return str;
return str.toString().padStart(2, '0');
}
// Raktárak adatai PHP-ből
const warehouses = <?php echo json_encode($warehouses); ?>;
const foilPlaces = <?php echo json_encode($foil_places); ?>;
// Dropdown feltöltése
function initializeSelect() {
const select = document.getElementById('warehouse-select');
// Normál raktárak
warehouses.forEach(warehouse => {
const option = document.createElement('option');
option.value = JSON.stringify(warehouse);
option.textContent = warehouse.name;
select.appendChild(option);
});
// Fóliás raktár hozzáadása
if (foilPlaces && foilPlaces.length > 0) {
const option = document.createElement('option');
const foilData = {
is_foil: true,
foil_places: foilPlaces
};
option.value = JSON.stringify(foilData);
option.textContent = 'Fóliás raktár';
select.appendChild(option);
}
}
// Méret beállítások frissítése
function updateSizeSettings() {
const width = document.getElementById('label-width').value;
const height = document.getElementById('label-height').value;
const qrSize = document.getElementById('qr-size').value;
document.documentElement.style.setProperty('--label-width', width + 'cm');
document.documentElement.style.setProperty('--label-height', height + 'cm');
document.documentElement.style.setProperty('--qr-size', qrSize);
}
// Címkék generálása
function generateLabels() {
const select = document.getElementById('warehouse-select');
if (!select.value) {
alert('Kérjük válassz raktárt!');
return;
}
// Loading overlay megjelenítése
document.getElementById('loading-overlay').classList.remove('hidden');
updateSizeSettings();
const warehouse = JSON.parse(select.value);
const grid = document.getElementById('labels-grid');
grid.innerHTML = '';
let labelIndex = 0;
const qrSize = parseInt(document.getElementById('qr-size').value);
let qrGeneratedCount = 0;
let totalQRCodes = 0;
if (warehouse.is_foil) {
totalQRCodes = warehouse.foil_places.filter(place => place.length <= 7).length;
const invalidPlaces = [];
document.getElementById('qr-total').textContent = totalQRCodes;
warehouse.foil_places.forEach((place, index) => {
if (place.length > 7) {
invalidPlaces.push(place);
return;
}
const labelCode = place;
const qrcodeId = `qrcode-${labelIndex}`;
const card = document.createElement('div');
card.className = 'label-card';
card.innerHTML = `
<div class="label-content">
<p class="label-code">${labelCode}</p>
</div>
<div class="qrcode-container" id="${qrcodeId}"></div>
`;
grid.appendChild(card);
setTimeout(() => {
new QRCode(document.getElementById(qrcodeId), {
text: labelCode,
width: qrSize,
height: qrSize,
colorDark: '#000000',
colorLight: '#ffffff',
correctLevel: QRCode.CorrectLevel.H,
callback: function() {
qrGeneratedCount++;
if (qrGeneratedCount === totalQRCodes) {
document.getElementById('loading-overlay').classList.add('hidden');
}
}
});
}, 0);
labelIndex++;
});
if (invalidPlaces.length > 0) {
alert('Az alábbi helyek 7 karakternél hosszabbak, ezért nem voltak generálva:\n\n' + invalidPlaces.join('\n'));
}
} else {
totalQRCodes = warehouse.row * warehouse.columns;
document.getElementById('qr-total').textContent = totalQRCodes;
for (let row = 1; row <= warehouse.row; row++) {
for (let col = 1; col <= warehouse.columns; col++) {
const labelCode = warehouse.code + NumberToABC(row) + padWithZero(col);
const qrcodeId = `qrcode-${labelIndex}`;
const card = document.createElement('div');
card.className = 'label-card';
card.innerHTML = `
<div class="label-content">
<p class="label-code">${labelCode}</p>
</div>
<div class="qrcode-container" id="${qrcodeId}"></div>
`;
grid.appendChild(card);
setTimeout(() => {
new QRCode(document.getElementById(qrcodeId), {
text: labelCode,
width: qrSize,
height: qrSize,
colorDark: '#000000',
colorLight: '#ffffff',
correctLevel: QRCode.CorrectLevel.H
});
}, 0);
labelIndex++;
}
}
}
document.getElementById('print-section').classList.add('active');
monitorQRCodeLoading(totalQRCodes);
}
// Összes raktár címkéinek generálása
function generateAllLabels() {
// Loading overlay megjelenítése
document.getElementById('loading-overlay').classList.remove('hidden');
updateSizeSettings();
const grid = document.getElementById('labels-grid');
grid.innerHTML = '';
let labelIndex = 0;
const qrSize = parseInt(document.getElementById('qr-size').value);
let qrGeneratedCount = 0;
let totalQRCodes = 0;
const foilWarehouseObject = foilPlaces && foilPlaces.length > 0 ? {
is_foil: true,
foil_places: foilPlaces
} : null;
const allWarehouses = foilWarehouseObject ? [...warehouses, foilWarehouseObject] : warehouses;
// Először számold meg az összes QR kódot
allWarehouses.forEach(warehouse => {
if (warehouse.is_foil) {
totalQRCodes += warehouse.foil_places.filter(place => place.length <= 7).length;
} else {
totalQRCodes += warehouse.row * warehouse.columns;
}
});
document.getElementById('qr-total').textContent = totalQRCodes;
allWarehouses.forEach(warehouse => {
if (warehouse.is_foil) {
const invalidPlaces = [];
warehouse.foil_places.forEach((place, index) => {
if (place.length > 7) {
invalidPlaces.push(place);
return;
}
const labelCode = place;
const qrcodeId = `qrcode-${labelIndex}`;
const card = document.createElement('div');
card.className = 'label-card';
card.innerHTML = `
<div class="label-content">
<p class="label-code">${labelCode}</p>
</div>
<div class="qrcode-container" id="${qrcodeId}"></div>
`;
grid.appendChild(card);
setTimeout(() => {
new QRCode(document.getElementById(qrcodeId), {
text: labelCode,
width: qrSize,
height: qrSize,
colorDark: '#000000',
colorLight: '#ffffff',
correctLevel: QRCode.CorrectLevel.H
});
}, 0);
labelIndex++;
});
if (invalidPlaces.length > 0) {
alert('Az alábbi helyek 7 karakternél hosszabbak, ezért nem voltak generálva:\n\n' + invalidPlaces.join('\n'));
}
} else {
for (let row = 1; row <= warehouse.row; row++) {
for (let col = 1; col <= warehouse.columns; col++) {
const labelCode = warehouse.code + NumberToABC(row) + padWithZero(col);
const qrcodeId = `qrcode-${labelIndex}`;
const card = document.createElement('div');
card.className = 'label-card';
card.innerHTML = `
<div class="label-content">
<p class="label-code">${labelCode}</p>
</div>
<div class="qrcode-container" id="${qrcodeId}"></div>
`;
grid.appendChild(card);
setTimeout(() => {
new QRCode(document.getElementById(qrcodeId), {
text: labelCode,
width: qrSize,
height: qrSize,
colorDark: '#000000',
colorLight: '#ffffff',
correctLevel: QRCode.CorrectLevel.H,
callback: function() {
qrGeneratedCount++;
if (qrGeneratedCount === totalQRCodes) {
document.getElementById('loading-overlay').classList.add('hidden');
}
}
});
}, 0);
labelIndex++;
}
}
}
});
document.getElementById('print-section').classList.add('active');
monitorQRCodeLoading(totalQRCodes);
}
function monitorQRCodeLoading(total) {
document.getElementById('qr-total').textContent = total;
const checkInterval = setInterval(() => {
const grid = document.getElementById('labels-grid');
const imgElements = grid.querySelectorAll('img').length;
if (imgElements === total) {
clearInterval(checkInterval);
setTimeout(() => {
document.getElementById('loading-overlay').classList.add('hidden');
}, 300);
}
}, 10);
}
// Vissza az alapértelmezett nézetre
function resetView() {
document.getElementById('warehouse-select').value = '';
document.getElementById('print-section').classList.remove('active');
document.getElementById('labels-grid').innerHTML = '';
}
// Méret inputok figyelése
document.getElementById('label-width').addEventListener('change', updateSizeSettings);
document.getElementById('label-height').addEventListener('change', updateSizeSettings);
document.getElementById('qr-size').addEventListener('change', updateSizeSettings);
// Inicializálás
initializeSelect();
updateSizeSettings();
</script>
</body>
</html>

2622
dashboard/monthlystat.php Normal file

File diff suppressed because it is too large Load Diff

183
dashboard/permlist.php Normal file
View File

@ -0,0 +1,183 @@
<?php
include '../managers/menu.php';
if (!UserHasPerm('perm_read')) {
StopAndDie();
}
if (isset($_POST['func'])) {
if (htmlspecialchars($_POST["func"]) == "savestatus") {
$perm_id = htmlspecialchars($_POST["permid"]);
$status = intval(htmlspecialchars($_POST["status"]));
if ($perm_id == "perm_read") {
$json = json_encode(array(
'result' => 'A "perm_read" jogosultság nem állítható!'
));
echo $json;
} else if ($status == 1 || $status == 0) {
$sql = mysqli_query($conn,"UPDATE perm_database SET perm_status=$status WHERE perm_id = '$perm_id'");
$json = json_encode(array(
'result' => 'ok'
));
echo $json;
} else {
$json = json_encode(array(
'result' => 'Hibás státusz kód! Próbálja újra!'
));
echo $json;
}
}
exit();
}
$permlist = array();
$query = "SELECT * FROM perm_database WHERE perm_status != 2 ORDER BY perm_category ASC";
if ($result = $conn->query($query)) {
while ($cperm = $result->fetch_assoc()) {
$desc = $coderclass->decode($cperm['perm_desc'], 'H3AH');
$name = $coderclass->decode($cperm['short_name'], 'HA98');
array_push($permlist, $cperm['perm_category']."|".$cperm['risk_factor']."|".$desc."|".$cperm['perm_id']."|".$cperm['perm_status']."|".$name);
}
}
sort($permlist);
$printedCat = array();
$printingTable = '';
for ($i=0; $i < count($permlist); $i++) {
$TempArr = explode("|", $permlist[$i]);
if (!in_array($TempArr[0], $printedCat)) {
array_push($printedCat, $TempArr[0]);
$printingTable .= "<tr><td style='font-weight: bold; text-align: center;' colspan='4'>".$TempArr[0]."</td></tr>";
}
if ($TempArr[3] != "perm_read") {
$status = "<select style='background: transparent; width: -webkit-fill-available; font-size: 14px;' onchange='SaveStatus(\"".$TempArr[3]."\", this.value);'>";
if ($TempArr[4] == "1") {
$status .= "<option value='0'>Inaktív</option>
<option value='1' selected>Aktív</option>";
} else {
$status .= "<option value='0' selected>Inaktív</option>
<option value='1'>Aktív</option>";
}
$status .= "/select>";
} else {
$status = "<span style='color: var(--panelcolor); font-size: 14px; margin-left: 12px;'>Aktív</span>";
}
$printingTable .= "<tr><td>".$TempArr[5]." <span style='opacity: 0.6; font-size: 14px;'> - ".$TempArr[3]."</span></td><td>".$TempArr[2]."</td><td style='padding: 0px;'>".$status."</td><td>".$TempArr[1].". oszály</td></tr>";
}
?>
<!DOCTYPE html>
<html lang="hu" dir="ltr">
<head>
<meta charset="utf-8">
<link rel="stylesheet" href="../css/panel.css">
<title>Kezelőfelület</title>
</head>
<body>
<?php echo $menuhtml;?>
<div class="window closed" id="win">
<div class="topbar">
<p id="wintitle">Title</p>
<div class="btn fullscrn" onclick="fullscrn();" id="fullscrnbtn"></div>
<div class="btn close" onclick="closewin();"></div>
</div>
<div class="wapp" id="winapp"><div id="errorDIV"></div></div>
<div class="loading" id="winloading"></div>
</div>
<div class="loadingBG" id="loadingBG"><img src="../img/loading.gif"></div>
<div class="content">
<div id="errorDIV" style="z-index: 100; top: 50px; position: fixed; width: calc(100% - 260px);"></div>
<!-- Tartalmi rész kezdete -->
<h1>Jogosultságok listája</h1>
<?php
if (UserHasPerm('god_profile') && $userID == 1) {
echo '<a href="#" onclick="OpenEditor()" style="position: absolute; right: 30px; top: 80px;">Jog hozzáadása</a>';
}
?>
<div style="width: 100%; margin-left: 10px; margin-top: 10px; display: inline; float: left;">
<div class="tables" style="width: 100%">
<table id="drugstable">
<thead>
<tr style="top: 0px; position: sticky; z-index: 1;">
<th>Megnevezés</th>
<th>Leírás</th>
<th>Állapot</th>
<th>Kockázati tényező</th>
</tr>
</thead>
<tbody>
<?php echo $printingTable;?>
</tbody>
</table>
</div>
</div>
<br clear="all"><br><br>
<!-- Tartalmi rész vége -->
</div>
<script src="../js/default.js" type="text/javascript"></script>
<script type="text/javascript">
function SaveStatus(perm_id, status) {
Loading();
const body = 'func=savestatus&permid='+ encodeURIComponent(perm_id).replace(/%20/g, '+') + '&status=' + status;
get_POST_information("permlist.php", body, function(text) {
let response = JSON.parse(text);
Loading(false);
if (response.result == "ok") {
GenerateAlerts("success", "Sikeresen módosította a jog státuszát!");
} else {
GenerateAlerts("error", response.result);
}
}, function() {
Loading(false);
GenerateAlerts("error", "Hálózati hiba!");
});
}
function OpenEditor() {
const popup = window.open('./addperm', 'Jog hozzáadása', 'width=610,height=860');
const timer = setInterval(() => {
if (popup == null) {
clearInterval(timer);
console.log("Nem lehet elérni a megnyílt oldalt");
} else if (popup.closed) {
clearInterval(timer);
location.reload();
}
}, 500);
}
</script>
</body>
</html>

438
dashboard/pricing.php Normal file

File diff suppressed because one or more lines are too long

1874
dashboard/production.php Normal file

File diff suppressed because it is too large Load Diff

1162
dashboard/productionstat.php Normal file

File diff suppressed because it is too large Load Diff

1078
dashboard/products.php Normal file

File diff suppressed because it is too large Load Diff

353
dashboard/profile.php Normal file
View File

@ -0,0 +1,353 @@
<?php
include '../managers/menu.php';
$totp = new TOTP();
$sql = mysqli_query($conn,"SELECT * FROM users WHERE uid = '$userID'");
$userDataSQL = mysqli_fetch_array($sql);
if ($userDataSQL == null) {
StopAndDie("Váratlan hiba lépett fel a fiók adatainak lekérésekor! Próbálja újra!");
}
if (isset($_POST['f']) && isset($_POST['anticsrfid']) && $_POST['anticsrfid'] == $_SESSION["anticsrfid"]) {
if (htmlspecialchars($_POST['f']) == 'SavePass') {
$oldpass = md5($_POST['oldpass']);
$pass = md5($_POST['pass']);
$realoldpass = $userDataSQL["upass"];
if (md5($_POST['repass']) != $pass) {
echo "A két jelszó nem egyezik!";
} else if (strlen(htmlspecialchars($_POST['repass'])) < 6) {
echo "A jelszónak minimum 6 karakter hosszúnak kell lennie!";
} else if (!(preg_match('/[a-z]/', $_POST['repass']) && preg_match('/[A-Z]/', $_POST['repass']) && preg_match('/[0-9]/', $_POST['repass']))) {
echo "A jelszónak tartamaznia kell egy kis és nagy karaktert, és legalább egy számot!";
} else if ($realoldpass != $oldpass) {
echo "A régi jelszó helytelen!";
} else {
mysqli_query($conn,"UPDATE users SET upass='$pass' WHERE uid = ".$userID);
echo "ok";
}
} elseif (htmlspecialchars($_POST['f']) == 'Activate2fa') {
$otckey = $_POST['otckey'];
$otc = $_POST['otc'];
$pass = md5($_POST['pass']);
if ($pass != $userDataSQL["upass"]) {
echo "A jelszó helytelen!";
} else if($totp->isValidKey($otckey) == false) {
echo "Váratlan hiba történt az egyedik kód generálásában, kérem vegye fel újra a kódot a hitelesítő alkalmazásába, és frissítse az oldalt!";
} else if($totp->getOtp($otckey) == $otc) {
$hashto2fa = $coderclass->encode($otckey, "J57A");
$sql = mysqli_query($conn,"UPDATE users SET otphash = '$hashto2fa' WHERE uid = '$userID'");
echo "ok";
} else {
echo "A hitelesítő kód nem egyezik!";
}
} else if (htmlspecialchars($_POST['f']) == 'Settings2fa') {
$type = '<option value="0">Új eszköz esetén, vagy 1 hét inaktivitás után</option>';
$type .= '<option value="1">Minden belépés esetén</option>';
$type = str_replace('value="'.$userDataSQL["otptype"].'"', 'value="'.$userDataSQL["otptype"].'" selected', $type);
if ($userDataSQL["otptype"] == 2) {$type = "NOEDIT 1";} else if ($userDataSQL["otptype"] == 3) {$type = "NOEDIT 2";}
echo json_encode(["status" => "ok", "type" => $type]);
} else if (htmlspecialchars($_POST['f']) == 'Delete2fa') {
$pass = md5($_POST['pass']);
if ($pass != $userDataSQL["upass"]) {
echo "A jelszó helytelen!";
} else if ($type == 2 || $type == 3) {
echo "A fiók valamilyen ok miatt megköveteli a kétfaktoros hitelesítést, ezért nem deaktiválható!";
} else {
$sql = mysqli_query($conn,"UPDATE users SET otphash = '' WHERE uid = '$userID'");
echo 'ok';
}
} else if (htmlspecialchars($_POST['f']) == 'Save2fa') {
$pass = md5($_POST['pass']);
$type = $_POST['type'];
if ($pass != $userDataSQL["upass"]) {
echo "A jelszó helytelen!";
} else if ($type != 0 && $type != 1) {
echo "Váratlan hiba történt, töltse újra az oldalt, és próbálja újra!";
}else {
$sql = mysqli_query($conn,"UPDATE users SET otptype = $type WHERE uid = '$userID'");
setcookie("otpauth", "", time() - 3600, "/");
echo 'ok';
}
}
die();
} else if (isset($_POST['f'])) {
echo "Titkos token hiba! Frissítse az oldalt, és próbálja újra!";
die();
}
$usermail = $coderclass->decode($userDataSQL["mail"], "A7SO");
$userPosition = $coderclass->decode($userDataSQL["position"], "SWI2");
$userPerms = "<ul>";
$userPermListArr = explode(", ", $userPermsList);
$CurrentUserPermList = array();
for ($i=0; $i < count($userPermListArr); $i++) {
$cpid = $userPermListArr[$i];
$sql = mysqli_query($conn,"SELECT short_name, risk_factor, perm_status FROM perm_database WHERE perm_id = '$cpid'");
$tempSQL = mysqli_fetch_array($sql);
$name = $coderclass->decode($tempSQL[0], "HA98");
array_push($CurrentUserPermList, $tempSQL[1]."|".$name."|".$tempSQL[2]);
}
sort($CurrentUserPermList);
//$CurrentUserPermList = array_values(array_reverse($CurrentUserPermList));
$CurrentUserPermListSliced = array_slice($CurrentUserPermList, 0, 12);
for ($x=0; $x < count($CurrentUserPermListSliced); $x++) {
$templist = explode("|", $CurrentUserPermListSliced[$x]);
if ($templist[2] == "1") {
$userPerms .= '<li><span style="color: var(--panelcolor);">'.$templist[1].'</span></li>';
} else if ($templist[0] == "0") {
$userPerms .= '<li><span class="redtext">'.$templist[1].'</span></li>';
} else {
$userPerms .= '<li><span style="opacity: 0.8;">'.$templist[1].'</span></li>';
}
}
$userPerms .= "</ul>";
$anticsrfid = bin2hex(random_bytes(24));
$_SESSION["anticsrfid"] = $anticsrfid;
?>
<!DOCTYPE html>
<html lang="hu" dir="ltr">
<head>
<meta charset="utf-8">
<link rel="stylesheet" href="../css/panel.css">
<title>Kezelőfelület</title>
</head>
<body>
<?php echo $menuhtml;?>
<div class="window closed" id="win">
<div class="topbar">
<p id="wintitle">Title</p>
<div class="btn fullscrn" onclick="fullscrn();" id="fullscrnbtn"></div>
<div class="btn close" onclick="closewin();"></div>
</div>
<div class="wapp" id="winapp"><div id="errorDIV"></div></div>
<div class="loading" id="winloading"></div>
</div>
<div class="loadingBG" id="loadingBG"><img class="svg" src="../img/Saturnus.svg"></div>
<div class="content">
<div id="errorDIV" style="z-index: 100; top: 50px; position: fixed; width: calc(100% - 260px);"></div>
<!-- Tartalmi rész kezdete -->
<div class="box">
<h2>Fiókom adatlapja</h2>
<p style="margin-bottom: 0px;"><b>Felhasználó neve:</b><span style="color: var(--panelcolor);"> <?php echo $userName;?></span></p>
<p style="margin-bottom: 0px; margin-top: 0px;"><b>Felhasználó email címe:</b><span style="color: var(--panelcolor);"> <?php echo $usermail;?></span></p>
<p style="margin-bottom: 0px; margin-top: 0px;"><b>Beosztása:</b><span style="color: var(--panelcolor);"> <?php echo $userPosition;?></span></p>
<p style="margin-top: 0px;"><b>Jelszó módosítása:</b></p>
<input type="password" id="oldpsw" placeholder="Jelenlegi jelszó" autocomplete="off" spellcheck="false" class="pass" autocapitalize="off" autocorrect="off"><br><br>
<input type="password" id="psw" placeholder="Új jelszó" autocomplete="off" spellcheck="false" class="pass" autocapitalize="off" autocorrect="off"><br><br>
<input type="password" id="repsw" placeholder="Új jelszó ismét" autocomplete="off" spellcheck="false" class="pass" autocapitalize="off" autocorrect="off"><br><br>
<button onclick="SaveNewPass();">Mentés</button><button onclick="window.location='../managers/logout.php';" style="position: absolute; right: 15px; background-color: #c0392b;">Kijelentkezés</button>
</div>
<div class="box">
<h2>Fiókomhoz társított jogok</h2>
<p style="opacity: 0.6;"><?php if (count($CurrentUserPermList) > 13) {echo "Az első 12 legfontosabb jog";}?></p>
<?php echo $userPerms;?>
</div>
<div class="box">
<h2>Kétlépcsős hitelesítés</h2>
<?php
$totpQRCode = "";
if ($userDataSQL["otphash"] != "") {
echo "<p style='color: #66A182;'><b>Aktív!</b> <a style='color: var(--panelcolor); padding-left: 15px;' onclick='Settings2fa();'>Módosítás</a></p>";
} else {
$totpKey = $totp->generateKey();
$totpQRCode = 'otpauth://totp/Szaturnusz?secret='.$totpKey.'&issuer=saturn&algorithm=SHA1&digits=6&period=30';
echo '<p>Scannelje be a QR kódot hitelesítő alkalmazásában,<br><i style="opacity: 0.8;">(pl: Google Authenticator, Authy, Microsoft Authenticator)</i><br>majd írja be a kapott kódot.</p><br>';
echo '<div style="display: flex; justify-content: center; align-items: center; height: 160px;"><div id="qrcode" style="width: 160px; height: 160px;"></div></div>';
echo '<p style="text-align: center;">'.$totpKey.'</p>';
echo '<input style="margin: auto;" type="text" id="otc" class="otc" maxlength="6" autocomplete="off">
<div style="display: flex; justify-content: center; align-items: center; margin-top: 15px;">
<input type="password" id="pass" placeholder="Jelenlegi jelszó..." autocomplete="off">
<input type="hidden" id="otckey" value="'.$totpKey.'">
<button style="margin-left: 15px;" onclick="Activate2fa();">Aktiválás</button></div>';
}
?>
</div>
<!-- Tartalmi rész vége -->
</div>
<script src="../js/default.js" type="text/javascript"></script>
<script src="../js/qrcode.js" type="text/javascript"></script>
<script type="text/javascript">
var GlobalAntiCSRFId = "<?php echo $anticsrfid;?>";
function SaveNewPass() {
Loading();
var oldpass = document.getElementById("oldpsw").value;
var pass = document.getElementById("psw").value;
var repass = document.getElementById("repsw").value;
const body = 'f=SavePass&oldpass=' + encodeURIComponent(oldpass).replace(/%20/g, '+') + '&pass=' + encodeURIComponent(pass).replace(/%20/g, '+') + '&repass=' + encodeURIComponent(repass).replace(/%20/g, '+') + '&anticsrfid=' + GlobalAntiCSRFId;
get_POST_information("profile.php", body, function(text) {
Loading(false);
if (text == "ok") {
GenerateAlerts("success", "Sikeresen frissítette a jelszavát!");
document.getElementById("oldpsw").value = "";
document.getElementById("psw").value = "";
document.getElementById("repsw").value = "";
} else {
GenerateAlerts("error", text);
}
}, function() {
GenerateAlerts("error", "Hálózati hiba történt, próbálja újra!");
Loading(false);
});
}
function Activate2fa() {
Loading();
var otc = document.getElementById("otc").value;
var otckey = document.getElementById("otckey").value;
var pass = document.getElementById("pass").value;
const body = 'f=Activate2fa&otc=' + encodeURIComponent(otc).replace(/%20/g, '+') + '&otckey=' + encodeURIComponent(otckey).replace(/%20/g, '+') + '&pass=' + encodeURIComponent(pass).replace(/%20/g, '+') + '&anticsrfid=' + GlobalAntiCSRFId;
get_POST_information("profile.php", body, function(text) {
Loading(false);
if (text == "ok") {
GenerateAlerts("success", "Sikeresen aktiválta a kétlépcsős hitelesítést!");
setTimeout(() => {window.location.reload();}, 2000);
} else {
GenerateAlerts("error", text);
}
}, function() {
GenerateAlerts("error", "Hálózati hiba történt, próbálja újra!");
Loading(false);
});
}
if (document.getElementById('qrcode')) {
new QRCode(document.getElementById("qrcode"), {
text: "<?php echo $totpQRCode;?>",
width: 160,
height: 160,
colorDark : "#000000",
colorLight : "#ffffff",
correctLevel : QRCode.CorrectLevel.H
});
}
function Settings2fa() {
Loading();
openwin();
wintitle.innerHTML = "Kétlépcsős hitelesítés - Beállítások";
const body = 'f=Settings2fa&anticsrfid=' + GlobalAntiCSRFId;
get_POST_information("profile.php", body, function(text) {
Loading(false);
winapp.innerHTML = '<div id="errorDIV"></div>';
let response = JSON.parse(text);
if (response.status == "ok") {
winapp.innerHTML += '<h1>Kétlépcsős hitelesítés beállításai</h1>';
winapp.innerHTML += '<p style="width: calc(100% - 35px); border-bottom: 1px solid #bdc3c7; display: inline-block; margin-right: 15px; "></p>';
winapp.innerHTML += '<p style="font-weight: bold;">Mikor kérje a 6 számjegyű kódot:</p>';
var CanDelete = true;
if (response.type != "NOEDIT 1" && response.type != "NOEDIT 2") {
winapp.innerHTML += '<select id="type">'+response.type+'</select>';
winapp.innerHTML += '<br><br><input type="password" id="settingspass" placeholder="Jelenlegi jelszó..." autocomplete="off" style="height: 17px;">';
winapp.innerHTML += '<button onclick="Save2fa();" style="margin-left: 19px;">Mentés</button>';
} else if (response.type == "NOEDIT 1") {
winapp.innerHTML += '<p style="color: var(--panelcolor);">Új eszköz esetén, vagy 1 hét inaktivitás után - <span style="opacity: 0.7; font-style: italic; color: #333;">Nem módosítható</span></p><br><br>';
CanDelete = false;
} else {
winapp.innerHTML += '<p style="color: var(--panelcolor);">Minden belépés esetén - <span style="opacity: 0.7; font-style: italic; color: #333;">Nem módosítható</span></p><br><br>';
CanDelete = false;
}
winapp.innerHTML += '<button onclick="Delete2fa('+CanDelete+');" style="position: absolute; right: 50px; background-color: #c0392b; color: #f5f5f5;">Deaktiválás</button>';
} else {
GenerateAlerts("error", response.message);
}
}, function() {
GenerateAlerts("error", "Hálózati hiba történt, próbálja újra!");
Loading(false);
});
}
function Save2fa() {
Loading();
var pass = document.getElementById("settingspass").value; document.getElementById("settingspass").value = "";
var type = document.getElementById("type").value;
const body = 'f=Save2fa&anticsrfid=' + GlobalAntiCSRFId + '&pass=' + encodeURIComponent(pass).replace(/%20/g, '+') + '&type=' + type;
get_POST_information("profile.php", body, function(text) {
Loading(false);
if (text == "ok") {
GenerateAlerts("success", "Sikeresen elmentette a változásokat!");
} else {
GenerateAlerts("error", text);
}
}, function() {
GenerateAlerts("error", "Hálózati hiba történt, próbálja újra!");
Loading(false);
});
}
function Delete2fa(CanDelete, text = 'DefaultText') {
if (!CanDelete) {
GenerateAlerts('warning', 'A fiók valamilyen ok miatt megköveteli a kétfaktoros hitelesítést, ezért nem deaktiválható!');
} else if (text == "igen") {
var pass = document.getElementById("settingspass").value; document.getElementById("settingspass").value = "";
const body = 'f=Delete2fa&anticsrfid=' + GlobalAntiCSRFId + '&pass=' + encodeURIComponent(pass).replace(/%20/g, '+');
Loading();
get_POST_information("profile.php", body, function(text) {
Loading(false);
if (text == "ok") {
GenerateAlerts("success", "Sikeresen deaktiválta a kétlépcsős hitelesítést!");
setTimeout(() => {window.location.reload();}, 2000);
} else {
GenerateAlerts("error", text);
}
}, function() {
GenerateAlerts("error", "Hálózati hiba történt, próbálja újra!");
Loading(false);
});
} else if (text == 'DefaultText') {
var html = `
<p><b>Kérjük, amennyiben biztos abban, hogy deaktiválni szeretné a kétlépcsős hitelesítést, írja be, hogy 'igen'</b><br><br>Bármikor visszakapcsolhatja ezt a szolgáltatást!</p><br>
<input type="text" id="AlertTextInput" placeholder="Indoklás..." autocomplete="off" autocapitalize="off" spellcheck="false" autocorrect="off">
<br clear="all"><br>
<button id="AlertBtnNo" style="float: right; margin-left: 15px; width: 80;">Mégsem</button>
<button id="AlertBtnYes" style="float: right; width: 60px; background: var(--panelcolor); color: #f5f5f5; border: unset;">Mentés</button>
`;
const overlay = CreateAlertBox('Kétlépcsős hitelesítő!', html, false);
document.getElementById('AlertBtnYes').onclick = function () { Delete2fa(CanDelete, (document.getElementById("AlertTextInput").value).toLowerCase()); CloseAlertBox(overlay); };
document.getElementById('AlertBtnNo').onclick = function () { CloseAlertBox(overlay); FeedbackButtonStatus('failed', Statement_id + '_button'); };
return;
}
}
</script>
</body>
</html>

850
dashboard/return_goods.php Normal file
View File

@ -0,0 +1,850 @@
<?php
include '../managers/menu.php';
if (!(UserHasPerm('return_goods'))) {
StopAndDie();
}
if (isset($_POST["func"])) {
if (htmlspecialchars($_POST["func"]) == "filter") {
if (!isset($_COOKIE['maxperpage'])) {
setcookie("maxperpage", "25", time() + (86400 * 90), "/");
$maxperpage = "25";
} else {
$maxperpage = $_COOKIE['maxperpage'];
}
setcookie("maxperpage", strval($maxperpage), time() + (86400 * 90), "/");
$perpageselect = "<option value='25'>25 db / oldal</option>
<option value='50'>50 db / oldal</option>
<option value='100'>100 db / oldal</option>
<option value='250'>250 db / oldal</option>
<option value='500'>500 db / oldal</option>
<option value='1000'>1000 db / oldal</option>";
$perpageselect = str_replace("value='".$maxperpage."'", "value='".$maxperpage."' selected", $perpageselect);
$json = json_encode(array(
'perpage' => $perpageselect,
'result' => 'ok'
));
echo $json;
} else if (htmlspecialchars($_POST["func"]) == "LoadTable") {
$maxperpage = intval(htmlspecialchars($_POST["perpage"]));
$cpage = intval(htmlspecialchars($_POST["cpage"]));
$name = htmlspecialchars($_POST["name"]);
$track_id = htmlspecialchars($_POST["track_id"]);
$item_id = htmlspecialchars(str_replace(' ', '+', $_POST['item_id']));
$date = htmlspecialchars($_POST["date"]);
$is_saved = htmlspecialchars($_POST["is_saved"]);
$addquery = "";
$isfirst = true;
if ($cpage == 0) {
$cpage = 1;
}
setcookie("maxperpage", $maxperpage, time() + (86400 * 90), "/");
if ($name != "") {
if ($isfirst) {
$addquery = $addquery." WHERE name LIKE '%".$name."%'";
$isfirst = false;
} else {
$addquery = $addquery." and item_id LIKE '%".$name."%'";
}
}
if ($track_id != "") {
if ($isfirst) {
$addquery = $addquery." WHERE (pack_id LIKE '%$track_id%' OR order_id LIKE '%$track_id%')";
$isfirst = false;
} else {
$addquery = $addquery." and (pack_id LIKE '%$track_id%' OR order_id LIKE '%$track_id%')";
}
}
if ($item_id != "") {
if ($isfirst) {
$addquery = $addquery." WHERE item_id LIKE '%".$item_id."%'";
$isfirst = false;
} else {
$addquery = $addquery." and item_id LIKE '%".$item_id."%'";
}
}
if ($date != "") {
if ($isfirst) {
$addquery = $addquery." WHERE DATE(FROM_UNIXTIME(return_date)) = '".$date."'";
$isfirst = false;
} else {
$addquery = $addquery." and DATE(FROM_UNIXTIME(return_date)) = '".$date."'";
}
}
if ($is_saved != "") {
if ($is_saved == "1") {
if ($isfirst) {
$addquery = $addquery." WHERE is_saved = '1'";
$isfirst = false;
} else {
$addquery = $addquery." and is_saved = '1'";
}
} else {
if ($isfirst) {
$addquery = $addquery." WHERE COALESCE(is_saved, 0) != 1";
$isfirst = false;
} else {
$addquery = $addquery." and COALESCE(is_saved, 0) != 1";
}
}
}
$sql = mysqli_query($conn,"SELECT COUNT(*) FROM return_goods".$addquery);
$count = mysqli_fetch_array($sql)[0];
$addquery = $addquery." ORDER BY return_date DESC";
$maxpage = ceil($count / $maxperpage);
if (!($cpage >= 1 && $cpage <= $maxpage)) {
$cpage = 1;
}
$limit = ($cpage - 1) * $maxperpage;
$responseStr = '';
$query = "SELECT return_id, name, COALESCE(NULLIF(order_id,''), pack_id) as the_id, item_id, return_date, is_saved FROM return_goods".$addquery." LIMIT $limit, $maxperpage";
if ($result = $conn->query($query)) {
while ($c_prod = $result->fetch_assoc()) {
if ($responseStr != "") {
$responseStr .= "|%|";
}
$responseStr .= $c_prod['return_id'].'/!/'.$c_prod['name'].'/!/'.$c_prod['the_id'].'/!/'.$c_prod['item_id'].'/!/'.date("Y. m. d.", $c_prod['return_date']).'/!/'.$c_prod['is_saved'];
}
}
echo '{"result": "ok", "data": "'.$responseStr.'", "maxpage": "'.$maxpage.'", "cpage": "'.$cpage.'"}';
} else if (htmlspecialchars($_POST["func"]) == "CreateReturn") {
$name = 'temp_'.bin2hex(random_bytes(24));
$sql = mysqli_query($conn,"INSERT INTO return_goods(name) VALUES ('$name')");
$rid = mysqli_insert_id($conn);
$json = json_encode(array(
'return_id' => $rid,
'result' => 'ok'
));
echo $json;
} else if (htmlspecialchars($_POST["func"]) == "OpenRetun") {
$rid = htmlspecialchars($_POST["return_id"]);
$sql = mysqli_query($conn,"SELECT * FROM return_goods WHERE return_id = '$rid'");
$data = mysqli_fetch_array($sql);
$json = json_encode(array(
'data' => $data,
'result' => 'ok'
));
echo $json;
} else if (htmlspecialchars($_POST["func"]) == "AutoSaveReturn") {
$return_id = htmlspecialchars($_POST["return_id"]);
$param = htmlspecialchars($_POST["param"]);
$value = htmlspecialchars($_POST["value"]);
$params = ['name', 'item_id', 'pack_id', 'order_id', 'return_reason', 'is_withdraw', 'cancellation_invoice', 'is_scrap', 'is_warehoused', 'reason', 'note', 'return_date', 'is_saved'];
if (!(!empty($param) && in_array($param,$params))) {
echo json_encode(array('result' => 'Hibás paraméter lett megadva!'));
exit();
}
if ($param == "return_date" && $value != "") {
$value = strtotime($value);
}
if ($param == "item_id" && $value != "") {
$sql = mysqli_query($conn,"SELECT item_id FROM pr_parameters WHERE item_id = '$value'");
$data = mysqli_fetch_array($sql);
if ($data != null) {
$value = $data['item_id'];
} else {
echo json_encode(array('result' => 'Nem létező cikkszámot adott meg!'));
exit();
}
}
if ($return_id != "") {
$sql = mysqli_query($conn,"UPDATE return_goods SET $param='$value' WHERE return_id = '$return_id'");
} else {
$sql = mysqli_query($conn, "INSERT INTO return_goods($param) VALUES ('$value')");
$return_id = mysqli_insert_id($conn);
}
echo json_encode(array('result' => 'ok', 'return_id' => $return_id));
} else if (htmlspecialchars($_POST["func"]) == "SaveReturn") {
$return_id = htmlspecialchars($_POST["return_id"]);
$name = htmlspecialchars($_POST["name"]);
$return_date = htmlspecialchars($_POST["return_date"]);
$item_id = htmlspecialchars($_POST["item_id"]);
$pack_id = htmlspecialchars($_POST["pack_id"]);
$order_id = htmlspecialchars($_POST["order_id"]);
$return_reason = htmlspecialchars($_POST["return_reason"]);
$is_withdraw = htmlspecialchars($_POST["is_withdraw"]);
$cancellation_invoice = htmlspecialchars($_POST["cancellation_invoice"]);
$is_scrap = htmlspecialchars($_POST["is_scrap"]);
$is_warehoused = htmlspecialchars($_POST["is_warehoused"]);
$reason = htmlspecialchars($_POST["reason"]);
$note = htmlspecialchars($_POST["note"]);
if ($return_date != "") {
$return_date = strtotime($return_date);
}
if ($item_id != "") {
$sql = mysqli_query($conn,"SELECT item_id FROM pr_parameters WHERE item_id = '$item_id'");
$data = mysqli_fetch_array($sql);
if ($data != null) {
$item_id = $data['item_id'];
} else {
echo json_encode(array('result' => 'Nem létező cikkszámot adott meg!'));
exit();
}
}
if ($return_id == "") {
$sql = mysqli_query($conn, "INSERT INTO return_goods(name) VALUES ('$name')");
$return_id = mysqli_insert_id($conn);
}
$sql = mysqli_query($conn,"UPDATE return_goods SET
name = '$name',
item_id = '$item_id',
pack_id = '$pack_id',
order_id = '$order_id',
return_reason = '$return_reason',
is_withdraw = '$is_withdraw',
cancellation_invoice = '$cancellation_invoice',
is_scrap = '$is_scrap',
is_warehoused = '$is_warehoused',
reason = '$reason',
note = '$note'
WHERE return_id = '$return_id'");
if ($return_date != "") {
$sql = mysqli_query($conn,"UPDATE return_goods SET return_date = $return_date WHERE return_id = '$return_id'");
} else {
$sql = mysqli_query($conn,"UPDATE return_goods SET return_date = NULL WHERE return_id = '$return_id'");
}
echo json_encode(array('result' => 'ok', 'return_id' => $return_id));
}
exit();
}
?>
<!DOCTYPE html>
<html lang="hu" dir="ltr">
<head>
<meta charset="utf-8">
<link rel="stylesheet" href="../css/panel.css">
<title>Kezelőfelület</title>
</head>
<style>
details .arrow {
margin-right: 8px;
display:inline-block;
width:11px;
transition:transform 0.3s;
transform:rotate(90deg);
}
details[open] .arrow {
transform:rotate(180deg);
}
</style>
<body>
<?php echo $menuhtml;?>
<div class="window closed" id="win">
<div class="topbar">
<p id="wintitle">Title</p>
<div class="btn fullscrn" onclick="fullscrn();" id="fullscrnbtn"></div>
<div class="btn close" onclick="closewin();"></div>
</div>
<div class="wapp" id="winapp"><div id="errorDIV"></div></div>
<div class="loading" id="winloading"></div>
</div>
<div class="loadingBG" id="loadingBG"><img src="../img/loading.gif"></div>
<div class="content">
<div id="errorDIV" style="z-index: 100; top: 50px; position: fixed; width: calc(100% - 260px);"></div>
<!-- Tartalmi rész kezdete -->
<h1>Visszáru</h1>
<div style="width: 100%; min-height: 85px;">
<div style="display: inline; float: left;">
<p>Neve: </p>
<input type="text" id="filter-name" placeholder="Neve..." onkeydown="if (event.keyCode == 13) {SendFilter();}" autocomplete="off" style="width: 147px; height: 17px;">
</div><div style="display: inline; float: left; padding-left: 15px;">
<p>Csomag / Rendelés szám</p>
<input type="text" id="filter-track_id" placeholder="Csomag / Rendelés szám..." onkeydown="if (event.keyCode == 13) {SendFilter();}" autocomplete="off" style="width: 147px; height: 17px;">
</div><div style="display: inline; float: left; padding-left: 15px;">
<p>Cikkszám</p>
<input type="text" id="filter-item_id" placeholder="Cikkszám..." onkeydown="if (event.keyCode == 13) {SendFilter();}" autocomplete="off" style="width: 147px; height: 17px;">
</div><div style="display: inline; float: left; padding-left: 15px;">
<p>Dátum kiválasztása: </p>
<input type="date" id="filter-date" style="height: 17px" onchange="SendFilter();">
</div><div style="display: inline; float: left; padding-left: 15px;">
<p>Lezárt elemek: </p>
<select id="filter-is_saved" onchange="SendFilter();">
<option value="0">Elrejtése</option>
<option value="">Megjelenítése</option>
<option value="1">Csak lezártak</option>
</select>
</div><div style="display: inline; float: left; padding-left: 15px;">
<p>Oldalanként: </p>
<select id="filter-perpage" onchange="SendFilter();"><option value="25">25 db / oldal</option></select>
</div><div style="display: inline; float: left; padding-left: 15px;">
<p style="color: #f5f5f5;">: </p>
<button onclick="SendFilter();">Szűrés</button>
</div>
<div style="display: inline; float: right; padding-right: 15px;">
<p style="color: #f5f5f5;">: </p>
<button onclick="CreateReturn();">Új visszáru</button>
</div>
</div>
<br clear="all">
<div style="border-top: solid 1px rgb(211,220,228); width: calc(100% - 15px); height: 0px; margin-top: 15px;"></div>
<br clear="all">
<div style="width: calc(100% - 6px); margin-left: 11px; margin-top: 2px; display: inline; float: left;">
<div class="tables" style="width: 100%">
<table id="table">
<thead>
<tr style="top: 0px; position: sticky; z-index: 1;">
<th>Neve</th>
<th>Rendelés / Csomag szám</th>
<th>Cikkszám</th>
<th>Dátum</th>
<th style="width: 150px;">Megnyitás</th>
</tr>
</thead>
<tbody></tbody>
</table>
</div>
</div>
<br clear="all">
<div>
<p style="text-align: center; padding-bottom: 50px; color: #333333;"><span onclick="left();" style="cursor: pointer;"><&nbsp;&nbsp;&nbsp;&nbsp;</span><span id="cpage">0</span> / <span id="maxpage">0</span><span onclick="right();" style="cursor: pointer;">&nbsp;&nbsp;&nbsp;&nbsp;></span></p>
</div>
<br clear="all"><br><br>
<!-- Tartalmi rész vége -->
</div>
<script src="../js/default.js" type="text/javascript"></script>
<script type="text/javascript">
function LoadFilter() {
const body = 'func=filter';
get_POST_information("return_goods.php", body, function(text) {
let response = JSON.parse(text);
if (response.result == "ok") {
document.getElementById('filter-perpage').innerHTML = response.perpage;
LoadTable();
} else {
GenerateAlerts("error", response.result);
}
}, function() {
GenerateAlerts("error", "Hálózati hiba!");
});
}
function SendFilter() {
document.getElementById('cpage').innerHTML = '1';
LoadTable();
}
function left() {
var cpage = document.getElementById("cpage").innerHTML;
if ((parseInt(cpage) - 1) >= 1) {
document.getElementById("cpage").innerHTML = parseInt(cpage) - 1;
LoadTable();
}
}
function right() {
var cpage = document.getElementById("cpage").innerHTML;
var maxpage = document.getElementById("maxpage").innerHTML;
if ((parseInt(cpage) + 1) <= parseInt(maxpage)) {
document.getElementById("cpage").innerHTML = parseInt(cpage) + 1;
LoadTable();
}
}
LoadFilter();
function LoadTable(silent = false) {
if (!silent) Loading();
var name = document.getElementById("filter-name").value;
var track_id = document.getElementById("filter-track_id").value;
var item_id = document.getElementById("filter-item_id").value;
var date = document.getElementById("filter-date").value;
var is_saved = document.getElementById("filter-is_saved").value;
var perpage = document.getElementById("filter-perpage").value;
var cpage = document.getElementById("cpage").innerHTML;
const body = 'func=LoadTable&perpage=' + perpage + '&cpage=' + cpage + '&name=' + encodeURIComponent(name).replace(/%20/g, '+') + '&track_id=' + encodeURIComponent(track_id).replace(/%20/g, '+') +'&item_id=' + encodeURIComponent(item_id).replace(/%20/g, '+') + '&date=' + date + '&is_saved=' + is_saved;
get_POST_information("return_goods.php", body, function(text) {
if (!silent) Loading(false);
let response = JSON.parse(text);
if (response.result == "ok") {
var table = document.getElementById('table').getElementsByTagName('tbody')[0];
table.innerHTML = "";
document.getElementById("cpage").innerHTML = response.cpage;
document.getElementById("maxpage").innerHTML = response.maxpage;
var tableresponse = response.data;
if (tableresponse != "") {
if (tableresponse.includes("|%|")) {
var tablearr = tableresponse.split("|%|");
} else {
var tablearr = [tableresponse];
}
for (var i = 0; i < tablearr.length; i++) {
var datas = tablearr[i].split("/!/");
var newRow = table.insertRow();
var newCell_1 = newRow.insertCell(0);
var newCell_2 = newRow.insertCell(1);
var newCell_3 = newRow.insertCell(2);
var newCell_4 = newRow.insertCell(3);
var newCell_5 = newRow.insertCell(4);
newCell_1.innerHTML = datas[1];
newCell_2.innerHTML = datas[2];
newCell_3.innerHTML = datas[3];
newCell_4.innerHTML = datas[4];
newCell_5.innerHTML = '<a style="cursor: pointer;" onclick="OpenRetun(\''+datas[0]+'\')">Részletek</button>';
if (datas[5] != '1') {
newCell_1.innerHTML += `<img style="margin-left: 10px; height: 20px; position: absolute;" title="Folyamatban van" src="data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAADAAAAAwCAYAAABXAvmHAAAACXBIWXMAAAsTAAALEwEAmpwYAAAEiklEQVR4nNVZS6gbVRg+txWfdSFY66NSF2nnnIlWsIsKinXloyKIiIqgu9qnVRe6Ufj/pL2IiGBBxasbUVwYBIteM/8/LQRFBBeFtvahIL6Wor2P+ijWGvkniTdzMpPMTCaZ+MGBXObMme8753+eq1TuaE4ZoFc18I585o0VzSmD9JpBbhqgf+LJJZ03VnSR6oxIcknnjRURpCLJJZ2XEXqvd1Xk4sEH+OfSvvoFapJx/fTBVbECkJsO0CNqkrEe+Ip+AgzQ52qSUZqur+wrALmpwbtJ/Z+gkQ8MEjWOoYGP6SpvSC3AAN1XNHmzJOKz1AI2QeM8DfzTRAhA/jK1gOAUkJ4rmrwJBj2U3bmBzxS/+82pTAJap8DvFSnAhQO3qmGwrsK3FCYA+IOhyHedwqGxmw7QX6bqr81FgEbaUoCAV1Re2AAfXayBT42NPNLcOmhcrvKE7MgYT+AZlTdcoJJBPjcG8t+vgcaFahQwwH4OBBc0UE0DP24qvFFyjfQbYqYOeNeV99C1IyE/bH2kgb8V0kJUFYZabblG+jEVecnkwM+6UDtfTQI0EiQnT9+Vq3SjmhgALJPuLKGAIy7MXhm1TAnqqzXyTo3sGeSTGug3Ge3fdWnyZU7u/F3krUl3Poq8A/7VBnlGI51NsM45DfyOXDjk1vjbyUwD70/6vlPhew3wYqaoVfHuGVqARno3RB7pdNKQp4F2DZVDgP8e6u7I7JldI4uEBfDTiXc+grwGPuwiPVGu+mb9S3yJDBfqrgHeLf4TKSLrSbjAD1jkj0tIHUhebL7HbOhPKQ4lIMS+CLAs8De7mQKaz+QTBvzNCRz3DxcaK0LvIb1lkzfAt8V+p8IbNfg3d/7WFX+TLUIDvZFagBATZ0rTfEgY7DU72tLvEsEgfSV3pQbo7a5N2G6tcXbt3oPXpBahgR4LFo8tFWhXhOOGbL6f2ZiW7Xc243kr9xy11srm0Br4Do30qUb+3RYgracloN79XBw2bt3SdH2l9ABtcj+sfvmLi0Li0H/SOu1ZNWoYpG+6PyrRJnYu8Jtdu/uw/TyITuENOzl6AVb0sR28A7k27Aqzh6KuUJwX919qncCiygJJXOKsATngRY38oVP1nGEEGPA3Bw1820ENeo+ORICQ18i/RiSkU1EZ2QB/ndSENHj3d0RIoLD9xVS98tAmFOx8fASq9ZBC+sTatd391tfdIoL53oNLz+gp65sfZxHQrxBb6BXAO605R/pmX7UkQm6j/+uLa7XlQX4IJ8Tt+QoAmo+u+cNls5QHg77jVPw7b3hh9rIlUbzDTmRSoqQWIA4ba0LI70eKRp6xzOiMlAcqIRzwbu8tJfj11OSDxaqeE3m5BfRLXPcU/PcTaN4WYcQE+pmT9N6y8zZ5pDnpS1RWBJEIqNauixZk5we1flIC2zWRaQk/GmTYqlduldKNFfK75bC2zbfKaVPhu1URaO9mrwhMOORd8LYVQj50EoMqWozyL5pzge5SkwC5sNVI+5I09e05M3E3G4VC6nlxZEl2GuiE9NfBADohlaaYy6BQ+S+XsS2DTwGeaQAAAABJRU5ErkJggg==" alt="procurement">`;
}
}
}
} else {
GenerateAlerts("error", response.result);
}
}, function() {
if (!silent) Loading(false);
GenerateAlerts("error", "Hálózati hiba!");
});
}
var global_return_id = "";
function CreateReturn() {
openwin();
wintitle.innerHTML = "Visszáru";
winapp.innerHTML = '<div id="errorDIV"></div>';
InitReturnEditor();
global_return_id = "";
if (<?php echo UserHasPerm('warehouse_add') ? 'true' : 'false'; ?>) {
const container = document.getElementById('WarehouseAdd');
container.innerHTML = ``;
const iframe = document.createElement('iframe');
iframe.src = './wh_add?iframe=1&reason=' + encodeURIComponent('Manual#<?php echo $userName; ?>').replace(/%20/g, '+') + '&functions=' + encodeURIComponent("box,foil").replace(/%20/g, '+');
iframe.style.width = "100%";
iframe.style.height = "500px";
iframe.style.border = "0px";
iframe.id = "WarehouseIframe";
container.appendChild(iframe);
}
}
function OpenRetun(return_id) {
openwin();
Loading();
global_return_id = return_id;
wintitle.innerHTML = "Visszáru";
winapp.innerHTML = '<div id="errorDIV"></div>';
const body = 'func=OpenRetun&return_id=' + return_id;
get_POST_information("return_goods.php", body, function(text) {
let response = JSON.parse(text);
Loading(false);
if (response.result == "ok") {
var ElemStyle = `flex: 1 1 calc(33.333% - 10px); min-width: 250px; box-sizing: border-box;`;
var date = new Date(response.data.return_date * 1000).toLocaleDateString('hu-HU', { year: 'numeric', month: '2-digit', day: '2-digit' }).replace(/(\d{4})-(\d{2})-(\d{2})/, '$1. $2. $3.');
if (response.data.is_saved && response.data.is_saved == 1) {
winapp.innerHTML += `<p style="color: #333333; margin-bottom: 0px; margin-left: 0px; font-size: 23px; font-weight: bold;">Vissszárú kezelés</p><br>
<p style="font-weight: bold; font-size: 18px; margin-bottom: 0px;">Megtekintés:</p><p style="width: calc(100% - 35px); border-bottom: 1px solid #bdc3c7; margin-top: 5px;"></p>
<div style="display: flex; flex-wrap: wrap; width: calc(100% - 35px); gap: 15px;">
<div style="${ElemStyle}">
<p class="label" style="margin-bottom: 5px;">Név:</p>
<p style="color: var(--panelcolor);">${response.data.name}</p>
</div>
<div style="${ElemStyle}">
<p class="label" style="margin-bottom: 5px;">Dátum:</p>
<p style="color: var(--panelcolor);">${date}</p>
</div>
<div style="${ElemStyle}">
<p class="label" style="margin-bottom: 5px;">Cikkszám:</p>
<p style="color: var(--panelcolor);">${response.data.item_id}</p>
</div>
<div style="${ElemStyle}">
<p class="label" style="margin-bottom: 5px;">Csomagszám:</p>
<p style="color: var(--panelcolor);">${response.data.pack_id}</p>
</div>
<div style="${ElemStyle}">
<p class="label" style="margin-bottom: 5px;">Rendelés szám:</p>
<p style="color: var(--panelcolor);">${response.data.order_id}</p>
</div>
<div style="${ElemStyle}">
<p class="label" style="margin-bottom: 5px;">Visszaküldés oka:</p>
<p style="color: var(--panelcolor);">${response.data.return_reason}</p>
</div>
<div style="${ElemStyle}">
<p class="label" style="margin-bottom: 5px;">Elállási nyilatkozat:</p>
<p style="color: var(--panelcolor);">${response.data.is_withdraw}</p>
</div>
<div style="${ElemStyle}">
<p class="label" style="margin-bottom: 5px;">Sztornó számla készült:</p>
<p style="color: var(--panelcolor);">${response.data.cancellation_invoice}</p>
</div>
<div style="${ElemStyle}">
<p class="label" style="margin-bottom: 5px;">Selejt:</p>
<p style="color: var(--panelcolor);">${response.data.is_scrap}</p>
</div>
<div style="${ElemStyle}">
<p class="label" style="margin-bottom: 5px;">Visszaraktam polcra:</p>
<p style="color: var(--panelcolor);">${response.data.is_warehoused}</p>
</div>
<div style="${ElemStyle}">
<p class="label" style="margin-bottom: 5px;">Elállás oka: </p>
<p style="color: var(--panelcolor);">${response.data.reason}</p>
</div>
<div style="${ElemStyle}">
<p class="label" style="margin-bottom: 5px;">Megjegyzés: </p>
<p style="color: var(--panelcolor);">${response.data.note}</p>
</div>
</div>
`;
} else {
InitReturnEditor();
document.getElementById('winapp_name').value = response.data.name ?? '';
if (response.data.return_date) document.getElementById('winapp_return_date').value = new Date(response.data.return_date * 1000).toLocaleDateString('sv').replace(/\//g,'-');
document.getElementById('winapp_item_id').value = response.data.item_id ?? '';
document.getElementById('winapp_pack_id').value = response.data.pack_id ?? '';
document.getElementById('winapp_order_id').value = response.data.order_id ?? '';
document.getElementById('winapp_return_reason').value = response.data.return_reason;
document.getElementById('winapp_is_withdraw').value = response.data.is_withdraw;
document.getElementById('winapp_cancellation_invoice').value = response.data.cancellation_invoice;
document.getElementById('winapp_is_scrap').value = response.data.is_scrap;
document.getElementById('winapp_is_warehoused').value = response.data.is_warehoused;
document.getElementById('winapp_reason').innerHTML = response.data.reason ?? '';
document.getElementById('winapp_note').innerHTML = response.data.note ?? '';
if (<?php echo UserHasPerm('warehouse_add') ? 'true' : 'false'; ?>) {
const container = document.getElementById('WarehouseAdd');
container.innerHTML = ``;
const iframe = document.createElement('iframe');
iframe.src = './wh_add?iframe=1&reason=' + encodeURIComponent('Manual#<?php echo $userName; ?>').replace(/%20/g, '+') + '&functions=' + encodeURIComponent("box,foil").replace(/%20/g, '+');
iframe.style.width = "100%";
iframe.style.height = "500px";
iframe.style.border = "0px";
iframe.id = "WarehouseIframe";
container.appendChild(iframe);
}
}
} else {
GenerateAlerts("error", response.result);
}
}, function() {
Loading(false);
GenerateAlerts("error", "Hálózati hiba!");
});
}
function InitReturnEditor() {
var ElemStyle = `flex: 1 1 calc(33.333% - 10px); min-width: 250px; box-sizing: border-box;`;
winapp.innerHTML += `<p style="color: #333333; margin-bottom: 0px; margin-left: 0px; font-size: 23px; font-weight: bold;">Vissszárú kezelés</p><br>
<p style="font-weight: bold; font-size: 18px; margin-bottom: 0px;">Töltse ki az alábbiakat:</p><p style="width: calc(100% - 35px); border-bottom: 1px solid #bdc3c7; margin-top: 5px;"></p>
<div style="display: flex; flex-wrap: wrap; width: calc(100% - 35px); gap: 15px;">
<div style="${ElemStyle}">
<p class="label" style="margin-bottom: 5px;">Név: <span style="color: red;">*</span></p>
<input id="winapp_name" type="text" autocomplete="off" spellcheck="false" placeholder="Név..." oninput="this.modified=true;" onblur="if(this.modified) {AutoSaveReturn(this.id, this.value); this.modified=false;}">
</div>
<div style="${ElemStyle}">
<p class="label" style="margin-bottom: 5px;">Dátum: <span style="color: red;">*</span></p>
<input id="winapp_return_date" type="date" autocomplete="off" spellcheck="false" placeholder="Dátum..." oninput="this.modified=true;" onblur="if(this.modified) {AutoSaveReturn(this.id, this.value); this.modified=false;}">
</div>
<div style="${ElemStyle}">
<p class="label" style="margin-bottom: 5px;">Cikkszám: <span style="color: red;">*</span></p>
<input id="winapp_item_id" type="text" autocomplete="off" spellcheck="false" placeholder="Cikkszám..." oninput="this.modified=true;" onblur="if(this.modified) {AutoSaveReturn(this.id, this.value); this.modified=false;}">
</div>
<div style="${ElemStyle}">
<p class="label" style="margin-bottom: 5px;">Csomagszám: <span style="color: red;">*</span></p>
<input id="winapp_pack_id" type="text" autocomplete="off" spellcheck="false" placeholder="Csomagszám..." oninput="this.modified=true;" onblur="if(this.modified) {AutoSaveReturn(this.id, this.value); this.modified=false;}">
</div>
<div style="${ElemStyle}">
<p class="label" style="margin-bottom: 5px;">Rendelés szám: <span style="color: red;">*</span></p>
<input id="winapp_order_id" type="text" autocomplete="off" spellcheck="false" placeholder="Rendelés szám..." oninput="this.modified=true;" onblur="if(this.modified) {AutoSaveReturn(this.id, this.value); this.modified=false;}">
</div>
<div style="${ElemStyle}">
<p class="label" style="margin-bottom: 5px;">Visszaküldés oka: <span style="color: red;">*</span></p>
<select id="winapp_return_reason" style="max-width: unset; width: 218px;" oninput="this.modified=true;" onblur="if(this.modified) {AutoSaveReturn(this.id, this.value); this.modified=false;}">
<option value="Nem vette át">Nem vette át</option>
<option value="Téves rendelés csere">Téves rendelés csere</option>
<option value="Csomagolási hiba csere">Csomagolási hiba csere</option>
<option value="Hibás címzett">Hibás címzett</option>
<option value="Elállási visszaküldés">Elállási visszaküldés</option>
<option value="Kiszállítás előtt sérült">Kiszállítás előtt sérült</option>
</select>
</div>
<div style="${ElemStyle}">
<p class="label" style="margin-bottom: 5px;">Elállási nyilatkozat:</p>
<select id="winapp_is_withdraw" style="max-width: unset; width: 218px;" oninput="this.modified=true;" onblur="if(this.modified) {AutoSaveReturn(this.id, this.value); this.modified=false;}">
<option value="Volt">Volt</option>
<option value="Nem volt">Nem volt</option>
<option value="Nem kell">Nem kell</option>
</select>
</div>
<div style="${ElemStyle}">
<p class="label" style="margin-bottom: 5px;">Sztornó számla készült:</p>
<select id="winapp_cancellation_invoice" style="max-width: unset; width: 218px;" oninput="this.modified=true;" onblur="if(this.modified) {AutoSaveReturn(this.id, this.value); this.modified=false;}">
<option value="Igen">Igen</option>
<option value="Nem">Nem</option>
<option value="Nem kell">Nem kell</option>
</select>
</div>
<div style="${ElemStyle}">
<p class="label" style="margin-bottom: 5px;">Selejt: <span style="color: red;">*</span></p>
<select id="winapp_is_scrap" style="max-width: unset; width: 218px;" oninput="this.modified=true;" onblur="if(this.modified) {AutoSaveReturn(this.id, this.value); this.modified=false;}">
<option value="Igen">Igen</option>
<option value="Nem">Nem</option>
<option value="Részben">Részben</option>
</select>
</div>
<div style="${ElemStyle}">
<p class="label" style="margin-bottom: 5px;">Visszaraktam polcra: <span style="color: red;">*</span></p>
<select id="winapp_is_warehoused" style="max-width: unset; width: 218px;" oninput="this.modified=true;" onblur="if(this.modified) {AutoSaveReturn(this.id, this.value); this.modified=false;}">
<option value="Igen">Igen</option>
<option value="Nem">Nem</option>
<option value="Selejt">Selejt</option>
</select>
</div>
<div style="${ElemStyle}">
<p class="label" style="margin-bottom: 5px;">Elállás oka: </p>
<textarea style="resize: vertical; min-height: 80px; width: 200px;" id="winapp_reason" placeholder="Elállás oka..." autocomplete="off" oninput="this.modified=true;" onblur="if(this.modified) {AutoSaveReturn(this.id, this.value); this.modified=false;}"></textarea>
</div>
<div style="${ElemStyle}">
<p class="label" style="margin-bottom: 5px;">Megjegyzés: </p>
<textarea style="resize: vertical; min-height: 80px; width: 200px;" id="winapp_note" placeholder="Megjegyzés..." autocomplete="off" oninput="this.modified=true;" onblur="if(this.modified) {AutoSaveReturn(this.id, this.value); this.modified=false;}"></textarea>
</div>
<div style="flex: 1 1 calc(50% - 10px); margin: 20px 0px; min-width: 250px; box-sizing: border-box;">
<button onclick="SaveReturn();" style="width: 100%;">Mentés</button>
</div>
<div style="flex: 1 1 calc(50% - 10px); margin: 20px 0px; min-width: 250px; box-sizing: border-box;">
<button onclick="EndReturn();" style="width: 100%;">Lezárás</button>
</div>
</div>
<br clear="all">
<details>
<summary style="width: calc(100% - 15px); border-bottom: solid 1px rgb(211,220,228); display: inline-block; color: var(--panelcolor); cursor: pointer;"><span class="arrow"><svg role="graphics-symbol" viewBox="0 0 100 100" class=""><polygon points="5.9,88.2 50,11.8 94.1,88.2" fill="var(--panelcolor)"></polygon></svg></span> Raktározási program</summary>
<div id="WarehouseAdd"></div>
</details>
<br clear="all">
`;
document.getElementById('winapp_return_reason').value = '';
document.getElementById('winapp_is_withdraw').value = '';
document.getElementById('winapp_cancellation_invoice').value = '';
document.getElementById('winapp_is_scrap').value = '';
document.getElementById('winapp_is_warehoused').value = '';
}
window.addEventListener('message', function(event) {
if (event.origin === 'https://szaturnusz.szatuna.hu') {
if (event.data.iframeHeight) {
setTimeout(() => {
const iframe = document.getElementById("WarehouseIframe");
iframe.style.height = event.data.iframeHeight + 'px';
console.log(event.data.iframeHeight);
//document.getElementById('WarehouseSection').style.maxHeight = document.getElementById('WarehouseSection').scrollHeight + 'px';
}, 50);
}
}
});
function AutoSaveReturn(winapp_param, value) {
if (document.getElementById("winapp_name").value != '') {
var param = winapp_param.replace(/^winapp_/, '');
const body = 'func=AutoSaveReturn&param=' + param + '&value=' + encodeURIComponent(value).replace(/%20/g, '+') + '&return_id=' + global_return_id;
get_POST_information("return_goods.php", body, function(text) {
let response = JSON.parse(text);
if (response.result == "ok") {
global_return_id = response.return_id;
if (param == "name" || param == "return_date" || param == "item_id" || param == "pack_id" || param == "order_id") {
LoadTable(true);
}
if (param == "is_saved") {
OpenRetun(global_return_id);
}
} else {
GenerateAlerts("error", response.result);
}
}, function() {
Loading(false);
GenerateAlerts("error", "Hálózati hiba!");
});
}
}
function SaveReturn() {
var name = document.getElementById("winapp_name").value;
var return_date = document.getElementById("winapp_return_date").value;
var item_id = document.getElementById("winapp_item_id").value;
var pack_id = document.getElementById("winapp_pack_id").value;
var order_id = document.getElementById("winapp_order_id").value;
var return_reason = document.getElementById("winapp_return_reason").value;
var is_withdraw = document.getElementById("winapp_is_withdraw").value;
var cancellation_invoice = document.getElementById("winapp_cancellation_invoice").value;
var is_scrap = document.getElementById("winapp_is_scrap").value;
var is_warehoused = document.getElementById("winapp_is_warehoused").value;
var reason = document.getElementById("winapp_reason").value;
var note = document.getElementById("winapp_note").value;
const body = 'func=SaveReturn&return_id=' + global_return_id
+ '&name=' + encodeURIComponent(name).replace(/%20/g, '+')
+ '&return_date=' + encodeURIComponent(return_date).replace(/%20/g, '+')
+ '&item_id=' + encodeURIComponent(item_id).replace(/%20/g, '+')
+ '&pack_id=' + encodeURIComponent(pack_id).replace(/%20/g, '+')
+ '&order_id=' + encodeURIComponent(order_id).replace(/%20/g, '+')
+ '&return_reason=' + encodeURIComponent(return_reason).replace(/%20/g, '+')
+ '&is_withdraw=' + encodeURIComponent(is_withdraw).replace(/%20/g, '+')
+ '&cancellation_invoice=' + encodeURIComponent(cancellation_invoice).replace(/%20/g, '+')
+ '&is_scrap=' + encodeURIComponent(is_scrap).replace(/%20/g, '+')
+ '&is_warehoused=' + encodeURIComponent(is_warehoused).replace(/%20/g, '+')
+ '&reason=' + encodeURIComponent(reason).replace(/%20/g, '+')
+ '&note=' + encodeURIComponent(note).replace(/%20/g, '+');
Loading();
get_POST_information("return_goods.php", body, function(text) {
let response = JSON.parse(text);
Loading(false);
if (response.result == "ok") {
global_return_id = response.return_id;
LoadTable(true);
} else {
GenerateAlerts("error", response.result);
}
}, function() {
Loading(false);
GenerateAlerts("error", "Hálózati hiba!");
});
}
function EndReturn(isVerified = false) {
const fields = {
winapp_name: "Kérem, töltse ki ezt a mezőt!",
winapp_return_date: "Kérem, töltse ki ezt a mezőt!",
winapp_item_id: "Kérem, töltse ki ezt a mezőt!",
winapp_return_reason: "Kérem, töltse ki ezt a mezőt!",
winapp_is_scrap: "Kérem, töltse ki ezt a mezőt!",
winapp_is_warehoused: "Kérem, töltse ki ezt a mezőt!"
};
const packOrOrder = document.getElementById("winapp_pack_id").value.trim() ||
document.getElementById("winapp_order_id").value.trim();
let allFieldsValid = true;
Object.entries(fields).forEach(([id, msg]) => {
const elem = document.getElementById(id);
if (!elem.value.trim()) {
elem.setCustomValidity(msg);
elem.reportValidity();
allFieldsValid = false;
} else {
elem.setCustomValidity('');
}
});
if (!packOrOrder) {
document.getElementById("winapp_pack_id").setCustomValidity("Csomagszám vagy rendelés szám megadása kötelező!");
document.getElementById("winapp_order_id").setCustomValidity("Csomagszám vagy rendelés szám megadása kötelező!");
document.getElementById("winapp_pack_id").reportValidity();
allFieldsValid = false;
} else {
document.getElementById("winapp_pack_id").setCustomValidity('');
document.getElementById("winapp_order_id").setCustomValidity('');
}
if (isVerified) {
AutoSaveReturn('is_saved', 1);
} else if (allFieldsValid) {
var html = `
<p><strong>Biztos benne, hogy le szeretné zárni ezt a visszárú kezelést?</strong></p>
<br clear="all"><br>
<button id="AlertBtnNo" style="float: right; margin-left: 15px; width: 80px;">Mégsem</button>
<button id="AlertBtnYes" style="float: right; width: 95px; background: var(--panelcolor); color: #f5f5f5; border: unset;">Lezárás</button>
`;
const overlay = CreateAlertBox('Lezárás', html);
document.getElementById('AlertBtnYes').onclick = function () {
EndReturn(true);
CloseAlertBox(overlay);
};
document.getElementById('AlertBtnNo').onclick = function () {
CloseAlertBox(overlay);
};
SaveReturn();
}
}
</script>
</body>
</html>

764
dashboard/usereditor.php Normal file
View File

@ -0,0 +1,764 @@
<?php
include '../managers/menu.php';
if (!(UserHasPerm('user_read_perm') || UserHasPerm('user_edit_perm'))) {
StopAndDie();
}
if (isset($_POST["func"])) {
if (htmlspecialchars($_POST["func"]) == "table") {
$maxperpage = intval(htmlspecialchars($_POST["perpage"]));
$cpage = intval(htmlspecialchars($_POST["cpage"]));
$orderby = htmlspecialchars($_POST["orderby"]);
$name = htmlspecialchars($_POST["name"]);
$addquery = "";
$isfirst = true;
if ($cpage == 0) {
$cpage = 1;
}
setcookie("maxperpage", $maxperpage, time() + (86400 * 90), "/");
if ($name != "") {
$namelength = strlen($name);
$newNameLength = $namelength - ($namelength % 3);
$name = substr($name, 0, $newNameLength);
$name = $coderclass->encode($name, 'S1TU');
$addquery = $addquery." WHERE uname LIKE '%".$name."%'";
$isfirst = false;
}
$sql = mysqli_query($conn,"SELECT COUNT(*) FROM users".$addquery);
$count = mysqli_fetch_array($sql)[0];
$maxpage = ceil($count / $maxperpage);
if (!($cpage >= 1 && $cpage <= $maxpage)) {$cpage = 1;}
$UserItems = [];
$query = "SELECT * FROM users".$addquery;
if ($result = $conn->query($query)) {
while ($cuser = $result->fetch_assoc()) {
$Current_full_name = $coderclass->decode($cuser['full_name'], 'TIT4');
$Current_position = $coderclass->decode($cuser['position'], 'SWI2');
$Current_perms = $coderclass->decode($cuser['perms'], 'AFDG');
$Current_perms_List = explode(', ', $Current_perms);
$CurrentUserPermList = array();
for ($i=0; $i < count($Current_perms_List); $i++) {
$cpid = $Current_perms_List[$i];
$sql = mysqli_query($conn,"SELECT risk_factor, perm_status FROM perm_database WHERE perm_id = '$cpid'");
$tempSQL = mysqli_fetch_array($sql);
if ($tempSQL != null) {
if ($tempSQL[1] != "0") {
array_push($CurrentUserPermList, $tempSQL[0]);
}
}
}
sort($CurrentUserPermList);
if (empty($CurrentUserPermList)) {
array_push($CurrentUserPermList, null);
}
if (!($CurrentUserPermList[0] == 0 && !UserHasPerm('god_profile')) || $Current_perms == "") {
$UserItems[] = [
'uid' => $cuser['uid'],
'full_name' => $Current_full_name,
'position' => $Current_position,
'risk_factor' => $CurrentUserPermList[0]
];
}
}
}
if ($orderby != "") {
usort($UserItems, function ($a, $b) {
global $orderby;
return strcoll($a[$orderby], $b[$orderby]);
});
} else {
usort($UserItems, function ($a, $b) {
return strcoll($a['full_name'], $b['full_name']);
});
}
$PrintableUserItems = getItemsSlice($UserItems, $cpage, $maxperpage);
$responseStr = '';
for ($i=0; $i < count($PrintableUserItems); $i++) {
if ($responseStr != "") {
$responseStr = $responseStr."%";
}
$responseStr = $responseStr.$PrintableUserItems[$i]['uid'].'|'.$PrintableUserItems[$i]['full_name'].'|'.$PrintableUserItems[$i]['position'].'|'.$PrintableUserItems[$i]['risk_factor'];
}
echo '{"result": "ok", "data": "'.$responseStr.'", "maxpage": "'.$maxpage.'", "cpage": "'.$cpage.'"}';
} else if (htmlspecialchars($_POST["func"]) == "filter") {
$name = array();
$query = "SELECT uname FROM users";
if ($result = $conn->query($query)) {
while ($cuser = $result->fetch_assoc()) {
array_push($name, $coderclass->decode($cuser['uname'], "S1TU"));
}
}
sort($name);
$names = "";
for ($i=0; $i < count($name); $i++) {
$names = $names."<option>".$name[$i]."</option>";
}
if (!isset($_COOKIE['maxperpage'])) {
setcookie("maxperpage", "25", time() + (86400 * 90), "/");
$maxperpage = "25";
} else {
$maxperpage = $_COOKIE['maxperpage'];
}
setcookie("maxperpage", strval($maxperpage), time() + (86400 * 90), "/");
$perpageselect = "<option value='25'>25 db / oldal</option>
<option value='50'>50 db / oldal</option>
<option value='100'>100 db / oldal</option>
<option value='250'>250 db / oldal</option>
<option value='500'>500 db / oldal</option>
<option value='1000'>1000 db / oldal</option>";
$perpageselect = str_replace("value='".$maxperpage."'", "value='".$maxperpage."' selected", $perpageselect);
$json = json_encode(array(
'name' => $names,
'perpage' => $perpageselect,
'result' => 'ok'
));
echo $json;
} else if (htmlspecialchars($_POST["func"]) == "createuser") {
if (UserHasPerm('user_edit_perm')) {
$tempID = bin2hex(random_bytes(24));
$sql = mysqli_query($conn,"INSERT INTO users(full_name, perms, status) VALUES ('564946704637584974726d6975623239564c7179462b652f61594655', '$tempID', -1)");
$sql = mysqli_query($conn,"SELECT uid FROM users WHERE perms = '$tempID' and status = -1");
$user = mysqli_fetch_array($sql);
$CreatedUserID = $user[0];
$json = json_encode(array(
'uid' => $CreatedUserID,
'result' => 'ok'
));
$sql = mysqli_query($conn,"UPDATE users SET perms='' WHERE uid = '$CreatedUserID'");
} else {
$json = json_encode(array(
'result' => 'Jogosultság megtagadva! Önnek nincsen joga felhasználót létrehozni!'
));
}
echo $json;
} else if (htmlspecialchars($_POST["func"]) == "openuser") {
$uid = intval(htmlspecialchars($_POST["uid"]));
$toedit = htmlspecialchars($_POST["toedit"]);
if ($toedit == "true") {
$toedit = true;
} else {
$toedit = false;
}
$sql = mysqli_query($conn,"SELECT * FROM users WHERE uid = $uid");
$user = mysqli_fetch_array($sql);
if ($user == null) {
echo json_encode(array('result' => 'Ilyen felhasználói azonosítóval nem létezik fiók! Próbálja újra!'));
exit();
}
$PermsList = $coderclass->decode($user["perms"], 'AFDG');
$PermListArr = explode(", ", $PermsList);
$CurrentPermList = array();
$CurrentPermRisk = array();
for ($i=0; $i < count($PermListArr); $i++) {
$cpid = $PermListArr[$i];
$sql = mysqli_query($conn,"SELECT short_name, risk_factor, perm_status FROM perm_database WHERE perm_id = '$cpid'");
$tempSQL = mysqli_fetch_array($sql);
$name = $coderclass->decode($tempSQL['short_name'] ?? '', "HA98");
array_push($CurrentPermList, $tempSQL[1]."|".$name."|".$tempSQL[2]);
array_push($CurrentPermRisk, $tempSQL[1]);
}
sort($CurrentPermList);
sort($CurrentPermRisk);
$Perms = '';
$PermListToJS = $PermsList;
if ($toedit && UserHasPerm('user_edit_perm')) {
$Perms = "<tbody>";
$permlist = array();
$query = "SELECT perm_category, perm_id, short_name FROM perm_database WHERE perm_status != 2";
if ($result = $conn->query($query)) {
while ($cperm = $result->fetch_assoc()) {
$name = $coderclass->decode($cperm['short_name'], 'HA98');
array_push($permlist, $cperm['perm_category']."|".$cperm['perm_id']."|".$name);
}
}
sort($permlist);
$printedCat = array();
for ($i=0; $i < count($permlist); $i++) {
$TempArr = explode("|", $permlist[$i]);
if (!in_array($TempArr[0], $printedCat)) {
array_push($printedCat, $TempArr[0]);
$Perms .= "<tr><td style='font-weight: bold; text-align: center;' colspan='2'>".$TempArr[0]."</td></tr>";
}
if (str_contains($PermsList, $TempArr[1])) {
$Perms .= "<tr style='background-color: unset;'><td>".$TempArr[2]." <span style='opacity: 0.6; font-size: 14px;'> - ".$TempArr[1]."</span></td><td><div class='checkbox-wrapper'><input type='checkbox' id='".$TempArr[1]."_checkbox' checked><label onclick='EditUserPerm(\"".$TempArr[1]."\");' for='".$TempArr[1]."_checkbox' class='saved'>Igen</label></div></td></tr>";
} else {
$Perms .= "<tr style='background-color: unset;'><td>".$TempArr[2]." <span style='opacity: 0.6; font-size: 14px;'> - ".$TempArr[1]."</span></td><td><div class='checkbox-wrapper'><input type='checkbox' id='".$TempArr[1]."_checkbox'><label onclick='EditUserPerm(\"".$TempArr[1]."\");' for='".$TempArr[1]."_checkbox'>Igen</label></div></td></tr>";
}
}
$Perms .= "</tbody>";
} else {
$Perms = "<ul style='margin: 5px 0px;'>";
for ($x=0; $x < count($CurrentPermList); $x++) {
$templist = explode("|", $CurrentPermList[$x]);
if ($templist[2] == "1") {
$Perms .= '<li><span style="color: var(--panelcolor);">'.$templist[1].'</span> <span style="opacity: 0.5;">- '.$templist[0].'. oszt</span></li>';
} else if ($templist[0] == "0") {
$Perms .= '<li><span class="redtext">'.$templist[1].'</span> <span style="opacity: 0.5;">- '.$templist[0].'. oszt</span></li>';
} else {
$Perms .= '<li><span style="opacity: 0.8;">'.$templist[1].'</span> <span style="opacity: 0.5;">- '.$templist[0].'. oszt</span></li>';
}
}
$Perms .= "</ul>";
}
$can_edit = false;
if (UserHasPerm('user_edit_perm') && ($CurrentPermRisk[0] != 0 || $PermsList == "")) {
$can_edit = true;
} else if (UserHasPerm('god_profile')) {
$can_edit = true;
}
if ($user != null) {
$otp = "";
if ($user["otphash"] != "") {
$otp = $user["otptype"];
}
$json = json_encode(array(
'uname' => $coderclass->decode($user["uname"], 'S1TU'),
'full_name' => $coderclass->decode($user["full_name"], 'TIT4'),
'mail' => $coderclass->decode($user["mail"], 'A7SO'),
'position' => $coderclass->decode($user["position"], 'SWI2'),
'note' => $coderclass->decode($user["note"], 'AH1K'),
'perms' => $Perms,
'PermListToJS' => $PermListToJS,
'status' => $user["status"],
'can_edit' => $can_edit,
'otp' => $otp,
'result' => 'ok'
));
} else {
$json = json_encode(array('result' => 'A felhasználó azonosítója hibás! Próbálja újra.'));
}
echo $json;
} else if (htmlspecialchars($_POST["func"]) == "saveuser") {
$uid = intval(htmlspecialchars($_POST["uid"]));
if (htmlspecialchars($_POST["status"]) == "true") {$status = "1";} else {$status = "0";}
if ($status == "0" && $uid == $userID) {
echo json_encode(array('result' => 'A saját fiókodat nem tudod deaktiválni!'));
exit();
}
$uname = $coderclass->encode(htmlspecialchars($_POST["uname"]), "S1TU");
if ($uname == "") {
echo json_encode(array('result' => 'Kötelező megadni egy felhasználó nevet!'));
exit();
}
$sql = mysqli_query($conn,"SELECT uid FROM users WHERE uname = '$uname'");
$tempSQL = mysqli_fetch_array($sql);
if ($tempSQL != null && $tempSQL[0] != $uid) {
echo json_encode(array('result' => 'Ilyen felhasználónévvel már létezik fiók! Adjon meg mást!'));
exit();
}
$full_name = $coderclass->encode(htmlspecialchars($_POST["full_name"]), "TIT4");
if (filter_var(htmlspecialchars($_POST["mail"]), FILTER_VALIDATE_EMAIL) !== false) {
$mail = $coderclass->encode(htmlspecialchars($_POST["mail"]), "A7SO");
} else if($_POST["mail"] == "") {
$mail = "";
} else {
echo json_encode(array('result' => 'Az email cím nem felel meg a formai követelményeknek!'));
exit();
}
$position = $coderclass->encode(htmlspecialchars($_POST["position"]), "SWI2");
$note = $coderclass->encode(htmlspecialchars($_POST["note"]), "AH1K");
if (!UserHasPerm('god_profile')) {
$perms = $coderclass->encode(str_replace('god_profile', '', str_replace(', god_profile', '', htmlspecialchars($_POST["perms"]))), "AFDG");
} else {
$perms = $coderclass->encode(htmlspecialchars($_POST["perms"]), "AFDG");
}
$userpass = htmlspecialchars($_POST["upass"]);
if (!(strlen($userpass) >= 6 && preg_match('/[a-z]/', $userpass) && preg_match('/[A-Z]/', $userpass) && preg_match('/[0-9]/', $userpass)) && $userpass != "") {
echo json_encode(array('result' => 'A megadott jelszó nem felel meg a formai követelményeknek!'));
exit();
} else if($userpass != "") {
$md5_userpass = md5($userpass);
}
if (UserHasPerm('user_edit_perm')) {
if ($userpass != "") {
$sql = mysqli_query($conn,"UPDATE users SET uname='$uname',upass='$md5_userpass',full_name='$full_name',mail='$mail',position='$position',note='$note',perms='$perms',status=$status WHERE uid = $uid");
} else {
$sql = mysqli_query($conn,"UPDATE users SET uname='$uname',full_name='$full_name',mail='$mail',position='$position',note='$note',perms='$perms',status=$status WHERE uid = $uid");
}
$json = json_encode(array('result' => 'ok'));
} else {
$json = json_encode(array('result' => 'Jogosultság megtagadva! Önnek nincsen joga felhasználót módosítani!'));
}
echo $json;
} else if (htmlspecialchars($_POST["func"]) == "DeactivateOTP") {
$uid = intval(htmlspecialchars($_POST["uid"]));
if (!UserHasPerm('user_edit_perm')) {
$json = json_encode(array('result' => 'Jogosultság megtagadva! Önnek nincsen joga felhasználót módosítani!'));
} else if ($uid == $userID) {
$json = json_encode(array('result' => 'A saját kétlépcsős hitelesítésének deaktiválását a fiók menupont alatt teheti meg!'));
} else {
$sql = mysqli_query($conn,"UPDATE users SET otphash = '' WHERE uid = '$uid'");
$json = json_encode(array('result' => 'ok'));
}
echo $json;
}
exit();
}
?>
<!DOCTYPE html>
<html lang="hu" dir="ltr">
<head>
<meta charset="utf-8">
<link rel="stylesheet" href="../css/panel.css">
<title>Kezelőfelület</title>
</head>
<body>
<?php echo $menuhtml;?>
<div class="window closed" id="win">
<div class="topbar">
<p id="wintitle">Title</p>
<div class="btn fullscrn" onclick="fullscrn();" id="fullscrnbtn"></div>
<div class="btn close" onclick="closewin();"></div>
</div>
<div class="wapp" id="winapp"><div id="errorDIV"></div></div>
<div class="loading" id="winloading"></div>
</div>
<div class="loadingBG" id="loadingBG"><img src="../img/loading.gif"></div>
<div class="content">
<div id="errorDIV" style="z-index: 100; top: 50px; position: fixed; width: calc(100% - 260px);"></div>
<!-- Tartalmi rész kezdete -->
<h1>Felhasználók</h1>
<div style="width: 100%; min-height: 85px;">
<div style="display: inline; float: left;">
<p>Felhasználónév: </p>
<input type="text" id="filter-name" placeholder="Felhasználónév..." onkeydown="if (event.keyCode == 13) {SendFilter();}" autocomplete="off" style="width: 147px; height: 17px;" list="namelist">
<datalist id="namelist" role="listbox">
</datalist>
</div><div style="display: inline; float: left; padding-left: 15px;">
<p>Oldalanként: </p>
<select id="filter-perpage" onchange="SendFilter();"><option value="25">25 db / oldal</option></select>
</div><div style="display: inline; float: left; padding-left: 15px;">
<p style="color: #f5f5f5;">: </p>
<button onclick="SendFilter();">Szűrés</button>
</div>
<?php if (UserHasPerm('user_edit_perm')) {echo '<div style="display: inline; float: right; padding-right: 15px;"><p style="color: #f5f5f5;">: </p><button onclick="CreateUser();">Hozzáadás</button></div>';}?>
</div>
<br clear="all">
<div style="border-top: solid 1px rgb(211,220,228); width: calc(100% - 15px); height: 0px; margin-top: 15px;"></div>
<br clear="all">
<div style="width: 100%; margin-left: 10px; margin-top: 10px; display: inline; float: left;">
<div class="tables" style="width: 100%">
<table id="table">
<thead>
<tr style="top: 0px; position: sticky; z-index: 1;">
<th id="table_head_name" onclick="orderby_filter('full_name');" style="cursor: pointer;">Teljes neve</th>
<th id="table_head_position" onclick="orderby_filter('position');" style="cursor: pointer;">Beosztása</th>
<th id="table_head_risk_factor" onclick="orderby_filter('risk_factor');" style="cursor: pointer;">Kockázati tényező</th>
<th style="width: 100px;">Adatlap</th>
</tr>
</thead>
<tbody>
</tbody>
</table>
</div>
</div>
<br clear="all">
<div>
<p style="text-align: center; padding-bottom: 50px; color: #333333;"><span onclick="left();" style="cursor: pointer;"><&nbsp;&nbsp;&nbsp;&nbsp;</span><span id="cpage">0</span> / <span id="maxpage">0</span><span onclick="right();" style="cursor: pointer;">&nbsp;&nbsp;&nbsp;&nbsp;></span></p>
</div>
<br clear="all"><br><br>
<!-- Tartalmi rész vége -->
</div>
<script src="../js/default.js" type="text/javascript"></script>
<script type="text/javascript">
Loading();
var orderby = 'full_name';
function LoadFilter() {
const body = 'func=filter';
get_POST_information("usereditor.php", body, function(text) {
let response = JSON.parse(text);
if (response.result == "ok") {
document.getElementById('namelist').innerHTML = response.name;
document.getElementById('filter-perpage').innerHTML = response.perpage;
orderby_filter();
} else {
GenerateAlerts("error", response.result);
}
}, function() {
GenerateAlerts("error", "Hálózati hiba!");
});
}
function SendFilter() {
document.getElementById('cpage').innerHTML = '1';
LoadTable();
}
function LoadTable() {
Loading();
var name = document.getElementById("filter-name").value;
var perpage = document.getElementById("filter-perpage").value;
var cpage = document.getElementById("cpage").innerHTML;
const body = 'func=table&perpage=' + perpage + '&cpage=' + cpage + '&name=' + encodeURIComponent(name).replace(/%20/g, '+') + '&orderby=' + orderby;
get_POST_information("usereditor.php", body, function(text) {
Loading(false);
let response = JSON.parse(text);
if (response.result == "ok") {
var table = document.getElementById('table').getElementsByTagName('tbody')[0];
table.innerHTML = "";
document.getElementById("cpage").innerHTML = response.cpage;
document.getElementById("maxpage").innerHTML = response.maxpage;
var tableresponse = response.data;
if (tableresponse != "") {
if (tableresponse.includes("%")) {
var tablearr = tableresponse.split("%");
} else {
var tablearr = [tableresponse];
}
for (var i = 0; i < tablearr.length; i++) {
var datas = tablearr[i].split("|");
var newRow = table.insertRow();
var newCell_1 = newRow.insertCell(0);
var newCell_2 = newRow.insertCell(1);
var newCell_3 = newRow.insertCell(2);
var newCell_4 = newRow.insertCell(3);
newCell_1.innerHTML = datas[1];
newCell_2.innerHTML = datas[2];
if (datas[3] == "0") {
newCell_3.innerHTML = '<span class="redtext">Kritikus</span>';
} else if (datas[3] == "") {
newCell_3.innerHTML = '<span style="color: #27ae60">Nincsen</span>';
} else {
newCell_3.innerHTML = datas[3] + '. osztály';
}
newCell_4.innerHTML = '<a style="cursor: pointer;" onclick="OpenUser(' + datas[0] + ')">Megnyitás</button>';
}
}
} else {
GenerateAlerts("error", response.result);
}
}, function() {
Loading(false);
GenerateAlerts("error", "Hálózati hiba!");
});
}
function left() {
var cpage = document.getElementById("cpage").innerHTML;
if ((parseInt(cpage) - 1) >= 1) {
document.getElementById("cpage").innerHTML = parseInt(cpage) - 1;
LoadTable();
}
}
function right() {
var cpage = document.getElementById("cpage").innerHTML;
var maxpage = document.getElementById("maxpage").innerHTML;
if ((parseInt(cpage) + 1) <= parseInt(maxpage)) {
document.getElementById("cpage").innerHTML = parseInt(cpage) + 1;
LoadTable();
}
}
function orderby_filter(by = 'full_name') {
orderby = by;
document.getElementById('cpage').innerHTML = '1';
document.getElementById('table_head_name').innerHTML = "Teljes neve";
document.getElementById('table_head_position').innerHTML = "Beosztása";
document.getElementById('table_head_risk_factor').innerHTML = "Kockázati tényező";
if (by == "position") {
document.getElementById('table_head_position').innerHTML = "Beosztása <small><small style='opacity: 0.6;'>(Rendezés eszerint)</small></small>";
} else if (by == "risk_factor") {
document.getElementById('table_head_risk_factor').innerHTML = "Kockázati tényező <small><small style='opacity: 0.6;'>(Rendezés eszerint)</small></small>";
} else {
document.getElementById('table_head_name').innerHTML = "Teljes neve <small><small style='opacity: 0.6;'>(Rendezés eszerint)</small></small>";
}
LoadTable();
}
LoadFilter();
function CreateUser() {
Loading();
const body = 'func=createuser';
get_POST_information("usereditor.php", body, function(text) {
let response = JSON.parse(text);
if (response.result == "ok") {
LoadFilter();
LoadTable();
OpenUser(response.uid);
} else {
Loading(false);
GenerateAlerts("error", response.result);
}
}, function() {
Loading(false);
GenerateAlerts("error", "Hálózati hiba!");
});
}
var OpenedUserPermList = '';
var editormode = false;
function OpenUser(uid, toedit = false) {
Loading();
openwin();
wintitle.innerHTML = "Adatlap";
const body = 'func=openuser&uid=' + uid + '&toedit=' + toedit;
get_POST_information("usereditor.php", body, function(text) {
winapp.innerHTML = '<div id="errorDIV"></div>';
let response = JSON.parse(text);
Loading(false);
if (response.result == "ok") {
if (response.can_edit) {
if (toedit) {
editormode = true;
winapp.innerHTML += '<div style="display: inline; float: right; padding-right: 10px;"><button onclick="SaveUser(\''+uid+'\');">Mentés</button></div>';
winapp.innerHTML += '<input type="hidden" id="winapp_uid" value="'+uid+'">';
} else {
winapp.innerHTML += '<div style="display: inline; float: right; padding-right: 10px;"><button onclick="OpenUser(\''+uid+'\', true);">Szerkesztés</button></div>';
}
}
if (response.can_edit && toedit) {
OpenedUserPermList = response.PermListToJS;
wintitle.innerHTML = "Szerkesztés";
winapp.innerHTML += '<p class="label">Felhasználó teljes neve:</p>';
winapp.innerHTML += '<input id="winapp_full_name" type="text" class="nameInput" autocomplete="off" spellcheck="false" placeholder="Felhasználó teljes neve..." value="'+response.full_name+'"><br>';
winapp.innerHTML += '<p class="label">Felhasználónév:</p>';
winapp.innerHTML += '<input id="winapp_uname" type="text" class="nameInput" autocomplete="off" spellcheck="false" placeholder="Felhasználónév..." value="'+response.uname+'"><br>';
winapp.innerHTML += '<p class="label" style="display: inline-block; margin-right: 15px;">Felhasználó jelszava:</p><div class="helpcursor"><span class="helptext" style="left: 0; right: unset;">Csak akkor töltse ki, ha módosítani szeretné!</span><span>&#9432;</span></div><br>';
winapp.innerHTML += '<input style="margin-right: 15px;" id="winapp_upass" type="password" autocomplete="off" spellcheck="false" placeholder="Jelszó..." >';
winapp.innerHTML += '<input id="winapp_upass2" type="password" autocomplete="off" spellcheck="false" placeholder="Jelszó ismét..." ><br><br>';
winapp.innerHTML += '<p class="label">Felhasználó email címe:</p>';
winapp.innerHTML += '<input id="winapp_mail" type="text" class="nameInput" autocomplete="off" spellcheck="false" placeholder="Email cím..." value="'+response.mail+'"><br>';
winapp.innerHTML += '<p class="label">Beosztása:</p>';
winapp.innerHTML += '<input id="winapp_position" type="text" class="nameInput" autocomplete="off" spellcheck="false" placeholder="Beosztása..." value="'+response.position+'"><br>';
winapp.innerHTML += '<p class="label">Megjegyzés:</p>';
winapp.innerHTML += '<textarea autocomplete="off" spellcheck="false" placeholder="Megjegyzés..." id="winapp_note" style="width: calc(100% - 16px); min-height: 60px; resize: vertical; margin-bottom: 15px;">'+response.note+'</textarea><br>';
winapp.innerHTML += '<p class="label">Jogai:</p>';
winapp.innerHTML += '<div style="width: 100%; margin-left: 10px; margin-top: 10px; display: inline; float: left;"><div class="tables" style="width: 100%"><table id="table"><thead><tr style="top: 0px; position: sticky; z-index: 1;"><th>Megnevezés</th><th style="width: 100px;">Hozzárendelés</th></tr></thead>'+response.perms+'</table></div></div>';
winapp.innerHTML += '<br clear="all"><br><p class="label">Fiók állapota:</p>';
if (response.status == "1") {winapp.innerHTML += '<div class="checkbox-wrapper"><input type="checkbox" id="winapp_status" checked><label for="winapp_status" class="saved">Aktív fiók</label></div>';
} else {winapp.innerHTML += '<div class="checkbox-wrapper"><input type="checkbox" id="winapp_status"><label for="winapp_status">Aktív fiók</label></div>';}
} else {
winapp.innerHTML += '<h1 style="margin-bottom: 0px;">'+response.full_name+'</h1>';
if (response.status == "1") {
winapp.innerHTML += '<p style="opacity: 0.8; margin-top: 0px;">'+response.uname+' - <span style="color: var(--panelcolor);">Aktív fiók</span></p>';
} else if (response.status == "-1") {
winapp.innerHTML += '<p style="opacity: 0.8; margin-top: 0px;">'+response.uname+' - <span style="color: var(--panelcolor);">Átmeneti fiók</span></p>';
} else {
winapp.innerHTML += '<p style="opacity: 0.8; margin-top: 0px;">'+response.uname+' - <span style="color: var(--panelcolor);">Inaktív fiók</span></p>';
}
winapp.innerHTML += '<p class="label">Email: <span style="color: var(--panelcolor); font-weight: normal;">'+response.mail+'</span></p>';
winapp.innerHTML += '<p class="label">Beosztása: <span style="color: var(--panelcolor); font-weight: normal;">'+response.position+'</span></p>';
if (response.otp == "") {
winapp.innerHTML += '<p class="label">Kétlépcsős hitelesítés: <span style="color: #c0392b; font-weight: normal;">Deaktiválva!</span></p>';
} else if (response.can_edit) {
winapp.innerHTML += '<p class="label">Kétlépcsős hitelesítés: <span style="color: #66A182; font-weight: normal;">Aktív!</span><span style="opacity: 0.7; font-style: italic; font-weight: normal; cursor: pointer;" onclick="DeactivateOTP('+uid+', \''+response.full_name+'\');"> - Deaktiválás</span></p>';
} else {
winapp.innerHTML += '<p class="label">Kétlépcsős hitelesítés: <span style="color: #66A182; font-weight: normal;">Aktív!</span></p>';
}
winapp.innerHTML += '<p class="label">Megjegyzés:</p><p class="label" style="color: var(--panelcolor); padding-left: 15px; border-left: 3px solid #80808052; font-weight: normal;">'+response.note+'</p>';
winapp.innerHTML += '<p class="label">Jogai:</p>' + response.perms;
}
} else {
GenerateAlerts("error", response.result);
}
}, function() {
Loading(false);
GenerateAlerts("error", "Hálózati hiba!");
});
}
function EditUserPerm(permid) {
var element = document.getElementById(permid+'_checkbox');
var UserPermList = OpenedUserPermList.split(', ');
if (!element.checked && !UserPermList.includes(permid)) {
UserPermList.push(permid);
} else if (element.checked && UserPermList.includes(permid)){
UserPermList = UserPermList.filter(elem => elem !== permid);
}
OpenedUserPermList = "";
for (var i = 0; i < UserPermList.length; i++) {
if (OpenedUserPermList != "") {
OpenedUserPermList += ", ";
}
OpenedUserPermList += UserPermList[i];
}
}
function DeactivateOTP(uid, name, text = 'DefaultText') {
if (text == "igen") {
Loading();
const body = 'func=DeactivateOTP&uid=' + uid;
get_POST_information("usereditor.php", body, function(text) {
let response = JSON.parse(text);
Loading(false);
if (response.result == "ok") {
OpenUser(uid);
GenerateAlerts("success", "Sikeresen deaktiválta a kétlépcsős hitelesítését a felhasználónak!");
} else {
GenerateAlerts("error", response.result);
}
}, function() {
Loading(false);
GenerateAlerts("error", "Hálózati hiba!");
});
} else if (text == 'DefaultText') {
var html = `
<p><b>Kérjük, amennyiben biztos abban, hogy deaktiválni szeretné '${name}' kétlépcsős hitelesítését, írja be, hogy 'igen'</b><br><br>Bármikor visszakapcsolhatja ezt a szolgáltatást a felhasználó a saját profiljában!</p><br>
<input type="text" id="AlertTextInput" placeholder="Indoklás..." autocomplete="off" autocapitalize="off" spellcheck="false" autocorrect="off">
<br clear="all"><br>
<button id="AlertBtnNo" style="float: right; margin-left: 15px; width: 80;">Mégsem</button>
<button id="AlertBtnYes" style="float: right; width: 60px; background: var(--panelcolor); color: #f5f5f5; border: unset;">Mentés</button>
`;
const overlay = CreateAlertBox('Kétlépcsős hitelesítés!', html, false);
document.getElementById('AlertBtnYes').onclick = function () { DeactivateOTP(uid, name, (document.getElementById("AlertTextInput").value).toLowerCase()); CloseAlertBox(overlay); };
document.getElementById('AlertBtnNo').onclick = function () { CloseAlertBox(overlay); FeedbackButtonStatus('failed', Statement_id + '_button'); };
return;
}
}
function SaveUser(uid) {
Loading();
var uname = document.getElementById('winapp_uname').value;
var full_name = document.getElementById('winapp_full_name').value;
var mail = document.getElementById('winapp_mail').value;
var position = document.getElementById('winapp_position').value;
var note = document.getElementById('winapp_note').value;
var perms = OpenedUserPermList;
var status = document.getElementById('winapp_status').checked;
var upass = document.getElementById('winapp_upass').value;
var upass2 = document.getElementById('winapp_upass2').value;
if (upass != "") {
if (upass !== upass2) {
GenerateAlerts("error", "A két megadott jelszó nem egyezik!");
Loading(false);
return;
} else if (upass.length < 6) {
GenerateAlerts("error", "A megadott jelszó nem lehet rövidebb 6 karakternél!");
Loading(false);
return;
} else if (!(/[a-z]/.test(upass) && /[A-Z]/.test(upass) && /[0-9]/.test(upass))) {
GenerateAlerts("error", "A megadott jelszónak tartamaznia kell egy kis és nagy karaktert, és legalább egy számot!");
Loading(false);
return;
}
}
const body = 'func=saveuser&uid=' + uid + '&status=' + status + '&uname=' + encodeURIComponent(uname).replace(/%20/g, '+') + '&full_name=' + encodeURIComponent(full_name).replace(/%20/g, '+') + '&mail=' + encodeURIComponent(mail).replace(/%20/g, '+') + '&position=' + encodeURIComponent(position).replace(/%20/g, '+') + '&note=' + encodeURIComponent(note).replace(/%20/g, '+') + '&perms=' + encodeURIComponent(perms).replace(/%20/g, '+') + '&upass=' + encodeURIComponent(upass).replace(/%20/g, '+');
get_POST_information("usereditor.php", body, function(text) {
let response = JSON.parse(text);
Loading(false);
if (response.result == "ok") {
LoadFilter();
LoadTable();
OpenUser(uid);
GenerateAlerts("success", "Sikeresen elmentve!");
} else {
GenerateAlerts("error", response.result);
}
}, function() {
Loading(false);
GenerateAlerts("error", "Hálózati hiba!");
});
}
isCtrl = false;
document.onkeydown=function(e){
if(e.keyCode == 17) isCtrl=true;
if(e.keyCode == 83 && isCtrl == true) {
if (!win.classList.contains("closed") && editormode) {
SaveUser(document.getElementById("winapp_uid").value);
return false;
}
}
}
document.onkeyup = function(e) {
if (e.keyCode == 17) isCtrl = false;
}
</script>
</body>
</html>

View File

@ -0,0 +1,282 @@
<?php
include '../managers/menu.php';
if (!(UserHasPerm("god_profile") && $userID == 1)) {
StopAndDie();
}
$jsonFile = __DIR__ . '/../managers/version.json';
if (isset($_POST['build'], $_POST['idx']) && file_exists($jsonFile)) {
$build = $_POST['build'];
$idx = (int)$_POST['idx'];
$versionData = json_decode(file_get_contents($jsonFile), true);
foreach ($versionData['updates'] as $uKey => &$update) {
if ($update['build'] === $build) {
if (isset($update['changes'][$idx])) {
array_splice($update['changes'], $idx, 1);
if (count($update['changes']) === 0) {
array_splice($versionData['updates'], $uKey, 1);
}
file_put_contents($jsonFile, json_encode($versionData, JSON_UNESCAPED_UNICODE | JSON_PRETTY_PRINT));
}
break;
}
}
}
if (isset($_POST['build'])) {
http_response_code(204);
exit();
}
$versionData = [];
if (file_exists($jsonFile)) {
$jsonContent = file_get_contents($jsonFile);
$versionData = json_decode($jsonContent, true);
if (!is_array($versionData)) {
$versionData = ['updates' => []];
}
} else {
$versionData = ['updates' => []];
}
// Alapértelmezett értékek a legutóbbi build alapján
$defaultEnv = 'l'; // Éles
$defaultStatus = 'a'; // Aktív
$defaultDateTime = date('Y-m-d\TH:i');
if (!empty($versionData['updates'])) {
$lastBuild = $versionData['updates'][0]['build'];
if (strlen($lastBuild) >= 2) {
$defaultEnv = substr($lastBuild, 0, 1);
$defaultStatus = substr($lastBuild, 1, 1);
$timestamp = (int) substr($lastBuild, 2);
$defaultDateTime = date('Y-m-d\TH:i', $timestamp);
}
}
$message = '';
if ($_SERVER['REQUEST_METHOD'] === 'POST' && isset($_POST['env']) && isset($_POST['status']) && isset($_POST['datetime']) && isset($_POST['change']) && isset($_POST['anticsrfid']) && $_POST['anticsrfid'] == $_SESSION["anticsrfid"]) {
$env = trim($_POST['env']);
$status = trim($_POST['status']);
$datetime = trim($_POST['datetime']);
$change = trim($_POST['change']);
if ($env !== '' && $status !== '' && $datetime !== '' && $change !== '') {
// Build szám generálása
$timestamp = strtotime($datetime);
$build = $env . $status . $timestamp;
$found = false;
foreach ($versionData['updates'] as &$update) {
if ($update['build'] === $build) {
if (!in_array($change, $update['changes'], true)) {
array_unshift($update['changes'], $change);
}
$found = true;
break;
}
}
unset($update);
if (!$found) {
array_unshift($versionData['updates'], [
'build' => $build,
'changes' => [$change]
]);
}
if (file_put_contents($jsonFile, json_encode($versionData, JSON_UNESCAPED_UNICODE | JSON_PRETTY_PRINT)) === false) {
$message = 'Mentés sikertelen: nem lehet írni a fájlt. Útvonal: ' . htmlspecialchars($jsonFile);
} else {
$message = 'A változtatás mentve lett. Build szám: ' . htmlspecialchars($build);
}
} else {
$message = 'Minden mező kitöltése kötelező.';
}
}
$anticsrfid = bin2hex(random_bytes(24));
$_SESSION["anticsrfid"] = $anticsrfid;
?>
<!DOCTYPE html>
<html lang="hu">
<head>
<meta charset="UTF-8" />
<meta name="viewport" content="width=device-width, initial-scale=1" />
<title>Verzió szerkesztő</title>
<style>
body {
font-family: 'Poppins', sans-serif;
font-size: 14px;
line-height: 1.7;
color: #333333;
background: #eef2f7;
display: flex;
justify-content: center;
align-items: flex-start;
min-height: 100vh;
padding: 2rem;
}
form {
background: white;
padding: 1.5rem 2rem;
border-radius: 10px;
box-shadow: 0 2px 8px rgba(0,0,0,0.1);
width: 100%;
max-width: 400px;
}
h2 {
margin-bottom: 1rem;
}
label {
display: block;
margin-bottom: 0.25rem;
font-weight: 600;
color: #555;
}
input[type="text"], input[type="datetime-local"], select {
width: 100%;
padding: 0.5rem 0.75rem;
margin-bottom: 1rem;
border: 1px solid #ccc;
border-radius: 6px;
font-size: 1rem;
box-sizing: border-box;
transition: border-color 0.2s ease;
}
input[type="text"]:focus, input[type="datetime-local"]:focus, select:focus {
border-color: #667eea;
outline: none;
}
select {
cursor: pointer;
}
button {
background: #48a14d;
color: white;
border: none;
border-radius: 6px;
padding: 0.6rem 1.2rem;
font-size: 1rem;
cursor: pointer;
font-weight: 600;
transition: 0.2s ease;
}
button:hover {
opacity: 0.8;
}
.message {
margin-top: 1rem;
padding: 0.75rem;
border-radius: 6px;
font-weight: 600;
color: #2a662a;
background-color: #d3f9d8;
}
.form-row {
display: flex;
gap: 1rem;
}
.form-row > div {
flex: 1;
}
.form-row label {
margin-bottom: 0.25rem;
}
li {
cursor: pointer;
transition: 0.2s ease;
}
li:hover {
color: #48a14d;
}
</style>
</head>
<body>
<div style="display: block;">
<form method="POST" novalidate>
<h2>Új frissítés hozzáadása</h2>
<label for="change">Frissítés leírása</label>
<input type="text" id="change" name="change" autocomplete="off" spellcheck="false" autocapitalize="off" autocorrect="off" required />
<input type="hidden" name="anticsrfid" value="<?php echo $anticsrfid;?>">
<div class="form-row">
<div>
<label for="env">Verzió környezete</label>
<select id="env" name="env" required>
<option value="l" <?= $defaultEnv === 'l' ? 'selected' : '' ?>>Éles</option>
<option value="t" <?= $defaultEnv === 't' ? 'selected' : '' ?>>Teszt</option>
</select>
</div>
<div>
<label for="status">Verzió státusza</label>
<select id="status" name="status" required>
<option value="a" <?= $defaultStatus === 'a' ? 'selected' : '' ?>>Aktív</option>
<option value="d" <?= $defaultStatus === 'd' ? 'selected' : '' ?>>Demó</option>
<option value="b" <?= $defaultStatus === 'b' ? 'selected' : '' ?>>Béta</option>
</select>
</div>
</div>
<label for="datetime">Dátum és idő</label>
<input type="datetime-local" id="datetime" name="datetime" value="<?= $defaultDateTime ?>" required />
<button type="submit">Mentés</button>
<?php if ($message !== ''): ?>
<div class="message"><?=htmlspecialchars($message)?></div>
<?php endif; ?>
</form>
<br clear="all"><br>
<?php
$jsonPath = __DIR__ . '/../managers/version.json';
$jsonData = file_get_contents($jsonPath);
$versionData = json_decode($jsonData, true);
if (!empty($versionData['updates'])) {
$updates = array_slice($versionData['updates'], 0, 5);
echo '<div style="background: white; padding: 1.5rem 2rem; border-radius: 10px; box-shadow: 0 2px 8px rgba(0, 0, 0, 0.1); width: 100%; max-width: 400px; overflow-y: auto; ">';
foreach ($updates as $update) {
echo '<div style="margin-bottom: 1rem;">';
$buildNumber = htmlspecialchars($update['build']);
// Build szám dekódolása
$envChar = substr($buildNumber, 0, 1);
$statusChar = substr($buildNumber, 1, 1);
$timestampPart = substr($buildNumber, 2);
$envLabel = ($envChar === 'l') ? 'Éles' : 'Teszt';
$statusLabel = ($statusChar === 'a') ? 'Aktív' : (($statusChar === 'd') ? 'Demó' : 'Béta');
echo '<strong>Build szám: #' . $buildNumber . '</strong>';
echo '<small style="opacity: 0.8;"> (' . $envLabel . ' / ' . $statusLabel . ' - ' . date('Y.m.d. H:i', intval($timestampPart)) . ')</small><br>';
echo '<ul style="margin: 0 0 0 1rem; padding: 0;">';
foreach ($update['changes'] as $idx => $change) {
echo '<li class="deletable" data-build="'.htmlspecialchars($buildNumber).'" data-idx="'.$idx.'">'
.htmlspecialchars($change).'</li>';
}
echo '</ul></div>';
}
echo '</div>';
}
?>
</div>
<script type="text/javascript">
document.addEventListener("DOMContentLoaded", function() {
document.querySelectorAll('.deletable').forEach(function(el) {
el.addEventListener('click', function() {
const build = this.dataset.build;
const idx = this.dataset.idx;
const text = this.textContent;
if (confirm(`Biztos törölni akarod a(z) ${build} buildszámú "${text}" bejegyzést?`)) {
fetch('version_controll.php', {
method: 'POST',
headers: { 'Content-Type': 'application/x-www-form-urlencoded' },
body: `build=${encodeURIComponent(build)}&idx=${encodeURIComponent(idx)}`
})
.then(response => location.reload());
}
});
});
});
</script>
</body>
</html>

2504
dashboard/warehouse.php Normal file

File diff suppressed because it is too large Load Diff

1008
dashboard/wh_add.php Normal file

File diff suppressed because it is too large Load Diff

2911
dashboard/wh_orders.php Normal file

File diff suppressed because it is too large Load Diff

991
dashboard/wh_remove.php Normal file
View File

@ -0,0 +1,991 @@
<?php
include '../managers/menu.php';
if (!UserHasPerm('removal_from_warehouse')) {
StopAndDie();
}
if (isset($_POST["func"])) {
if (htmlspecialchars($_POST["func"]) == "filter") {
if (!isset($_COOKIE['maxperpage'])) {
setcookie("maxperpage", "25", time() + (86400 * 90), "/");
$maxperpage = "25";
} else {
$maxperpage = $_COOKIE['maxperpage'];
}
setcookie("maxperpage", strval($maxperpage), time() + (86400 * 90), "/");
$perpageselect = "<option value='25'>25 db / oszlop</option>
<option value='50'>50 db / oszlop</option>
<option value='100'>100 db / oszlop</option>
<option value='250'>250 db / oszlop</option>
<option value='500'>500 db / oszlop</option>
<option value='1000'>1000 db / oszlop</option>";
$perpageselect = str_replace("value='".$maxperpage."'", "value='".$maxperpage."' selected", $perpageselect);
$UserItems = [];
$query = "SELECT full_name, uid FROM users";
if ($result = $conn->query($query)) {
while ($cuser = $result->fetch_assoc()) {
$Current_full_name = $coderclass->decode($cuser['full_name'], 'TIT4');
$UserItems[] = [ 'full_name' => $Current_full_name, 'uid' => $cuser['uid'] ];
}
}
usort($UserItems, function ($a, $b) {
return strcoll($a['full_name'], $b['full_name']);
});
$userselect = '';
for ($i=0; $i < count($UserItems); $i++) {
$cval = $UserItems[$i]['full_name'] . " - " . $coderclass->encode($UserItems[$i]['uid'], 'RM');
$userselect .= '<option value="'.$cval.'"></option>';
}
$json = json_encode(array(
'perpage' => $perpageselect,
'userselect' => $userselect,
'result' => 'ok'
));
echo $json;
} else if (htmlspecialchars($_POST["func"]) == 'CreateRemoval') {
$category = $_POST['category'] ?? '';
$rawData = $_POST['data'] ?? '';
$allowedCategories = ['warranty', 'scrap', 'employee'];
if (!in_array($category, $allowedCategories, true)) {
echo 'Érvénytelen kategória';
exit;
}
$jsonData = json_decode($rawData, true);
if (!is_array($jsonData)) {
echo 'Hibás adatstruktúra';
exit;
}
$itemIdValue = null;
foreach ($jsonData as $param) {
if ($param['name'] === 'item_id') {
$itemIdValue = $param['value'];
break;
}
}
if ($itemIdValue == null) {
echo 'Hibás adatstruktúra';
exit;
} else {
$sql = mysqli_query($conn,"SELECT name_in_db FROM pr_parameters WHERE item_id = '$itemIdValue'");
$pr_parameters = mysqli_fetch_array($sql);
if ($pr_parameters == null) {
echo 'Nem létező cikkszámot adott meg!';
exit;
}
}
$table = $conn->real_escape_string("{$category}_removal");
$time = time();
mysqli_query($conn, "INSERT INTO $table (date_create) VALUES ($time)");
$rid = mysqli_insert_id($conn);
foreach ($jsonData as $item) {
if (!isset($item['name'], $item['value'])) {
continue;
}
$paramName = $item['name'];
$paramValue = $item['value'];
if (!preg_match('/^[a-z_]+$/', $paramName)) {
continue;
}
if ($paramValue === '$[TIMESTAMP]') {
$paramValue = time();
$type = 'i';
} else {
$paramValue = htmlspecialchars($paramValue, ENT_QUOTES, 'UTF-8');
$type = 's';
}
if ($paramName === 'uid') {
$paramValue = $coderclass->decode($paramValue, "RM");
}
$column = $conn->real_escape_string($paramName);
$sql = "UPDATE `{$table}` SET `{$column}` = ? WHERE `{$category}_rid` = ?";
$stmt = $conn->prepare($sql);
if (!$stmt) {
continue;
}
$stmt->bind_param($type . 'i', $paramValue, $rid);
$stmt->execute();
$stmt->close();
}
echo 'ok';
} else if (htmlspecialchars($_POST["func"]) == "table") {
$category = $_POST['category'] ?? '';
$rawData = $_POST['data'] ?? '';
$allowedCategories = ['warranty', 'scrap', 'employee'];
if (!in_array($category, $allowedCategories, true)) {
echo '{"result": "Érvénytelen kategória"}';
exit;
}
$maxperpage = intval(htmlspecialchars($_POST["perpage"]));
$cpage = intval(htmlspecialchars($_POST["cpage"]));
$start_datetime = htmlspecialchars($_POST["start_datetime"]);
$end_datetime = htmlspecialchars($_POST["end_datetime"]);
$name = htmlspecialchars($_POST["name"]);
$item_id = htmlspecialchars(str_replace(' ', '+', $_POST['item_id']));
$addquery = "";
$isfirst = true;
if ($cpage == 0) {
$cpage = 1;
}
setcookie("maxperpage", $maxperpage, time() + (86400 * 90), "/");
if ($name != "" && $category != "scrap") {
$addquery = $addquery." WHERE name LIKE '%".$name."%'";
$isfirst = false;
} else if ($name != "") {
$addquery = $addquery." WHERE wh_id LIKE '%".$name."%'";
$isfirst = false;
}
if ($start_datetime != "") {
$timestamp = strtotime($start_datetime);
if ($isfirst) {
$addquery = $addquery." WHERE date_create > '".$timestamp."'";
$isfirst = false;
} else {
$addquery = $addquery." and date_create > '".$timestamp."'";
}
}
if ($end_datetime != "") {
$timestamp = strtotime($end_datetime);
if ($isfirst) {
$addquery = $addquery." WHERE date_create < '".$timestamp."'";
$isfirst = false;
} else {
$addquery = $addquery." and date_create < '".$timestamp."'";
}
}
if ($item_id != "") {
if ($isfirst) {
$addquery = $addquery." WHERE item_id LIKE '%".$item_id."%'";
$isfirst = false;
} else {
$addquery = $addquery." and item_id LIKE '%".$item_id."%'";
}
}
$table = $conn->real_escape_string("{$category}_removal");
$sql = mysqli_query($conn,"SELECT COUNT(*) FROM ".$table.$addquery);
$count = mysqli_fetch_array($sql)[0];
$addquery = $addquery." ORDER BY date_create DESC";
$maxpage = ceil($count / $maxperpage);
if (!($cpage >= 1 && $cpage <= $maxpage)) {
$cpage = 1;
}
$limit = ($cpage - 1) * $maxperpage;
$responseStr = '';
$isnamequery = ($category === "scrap") ? 'wh_id' : 'name';
$ridquery = $category."_rid";
$query = "SELECT $ridquery, $isnamequery, item_id, date_create, right_db, left_db FROM $table".$addquery." LIMIT $limit, $maxperpage";
if ($result = $conn->query($query)) {
while ($c_removal = $result->fetch_assoc()) {
if ($responseStr != "") {
$responseStr .= "|%|";
}
$responseStr .= $c_removal[$isnamequery].'/!/'.$c_removal['item_id'].'/!/'.date("Y. m. d.", $c_removal['date_create']).'/!/'.$c_removal['right_db'].'/!/'.$c_removal['left_db'].'/!/'.$c_removal[$ridquery];
}
}
echo '{"result": "ok", "data": "'.$responseStr.'", "maxpage": "'.$maxpage.'", "cpage": "'.$cpage.'"}';
} else if (htmlspecialchars($_POST["func"]) == "OpenInfo") {
$category = $_POST['category'] ?? '';
$allowedCategories = ['warranty', 'scrap', 'employee'];
$rid = intval(htmlspecialchars($_POST["rid"]));
if (!in_array($category, $allowedCategories, true)) {
echo '{"result": "Érvénytelen kategória"}';
exit;
}
$table = $conn->real_escape_string("{$category}_removal");
$NameTranslate = [
"warranty" => "Garanciális ügyintézés",
"scrap" => "Selejt kivét",
"employee" => "Dolgozói kivét",
"name" => "Ügyfél / Raktár / Dolgozó neve",
"mail" => "Email",
"order_id" => "Rendelés azonosító",
"item_id" => "Cikkszám",
"right_db" => "Jobb oldal db",
"left_db" => "Bal oldal db",
"reason" => "Kivét / Selejt oka",
"note" => "Megjegyzés",
"date_create" => "Dátum",
"wh_id" => "Raktárhely"
];
$sql = mysqli_query($conn,"SELECT * FROM $table WHERE ".$category."_rid = $rid");
$result = mysqli_fetch_array($sql);
$html = '<p><span style="font-size: 18px; font-weight: bold;">'.$NameTranslate[$category].'</span><br><br>';
if ($result != null) {
foreach ($result as $paramName => $value) {
if (array_key_exists($paramName, $NameTranslate)) {
$cvalue = $value;
if ($paramName == "date_create") {
$cvalue = date("Y. m. d. h:i:s", $value);
$html .= '<br><b>'.$NameTranslate[$paramName].':</b> '.$cvalue.'<br>';
continue;
}
$html .= '<b>'.$NameTranslate[$paramName].':</b> '.$cvalue.'<br>';
}
}
$html .= '</p>';
} else {
echo '{"result": "Érvénytelen azonosító"}';
exit;
}
echo json_encode(array(
'html' => $html,
'result' => 'ok'
));
} else if (htmlspecialchars($_POST["func"]) == "ScrapRemoval") {
$item_id = htmlspecialchars($_POST["item_id"]);
$left = intval(htmlspecialchars($_POST["left"]));
$right = intval(htmlspecialchars($_POST["right"]));
$warehouse_code = htmlspecialchars($_POST["warehouse_code"]);
$sql = mysqli_query($conn,"SELECT wid FROM warehouse_foil WHERE item_id = '$item_id' and place LIKE '%$warehouse_code%' AND is_active = 1");
$foil_warehouse = mysqli_fetch_array($sql);
if ($foil_warehouse != null) {
$left_db = -$left;
$right_db = -$right;
$wid = $foil_warehouse['wid'];
$sql = mysqli_query($conn,"UPDATE warehouse_foil SET left_db = CASE WHEN left_db + $left_db < 0 THEN 0 ELSE left_db + $left_db END, right_db = CASE WHEN right_db + $right_db < 0 THEN 0 ELSE right_db + $right_db END WHERE wid = '$wid'");
$loggerclass->writeLogWarehouse(['reason' => 'Kivét selejt miatt', 'reason_code' => 1,
'item_id' => $item_id,
'from_place' => $warehouse_code,
'to_place' => '',
'amount_left' => $left,
'amount_right' => $right
]);
} else {
$position = substr($warehouse_code, -3);
$wcode = substr($warehouse_code, 0, strlen($warehouse_code) - 3);
$letter = $position[0];
$numberFromLetter = ord(strtoupper($letter)) - ord('A') + 1;
$number = ltrim(substr($position, 1, 2), '0');
$position = $numberFromLetter . ':' . $number;
$sql = mysqli_query($conn,"SELECT warehouse_id FROM warehouse_structure WHERE code = '$wcode'");
$warehouse_structure = mysqli_fetch_array($sql);
if ($warehouse_structure != null) {
$warehouse_id = $warehouse_structure['warehouse_id'];
$sql = mysqli_query($conn,"SELECT wid FROM warehouse WHERE warehouse_id = '$warehouse_id' and item_id = '$item_id' and position = '$position'");
$warehouse_box = mysqli_fetch_array($sql);
if ($warehouse_box != null) {
$box_db = -max($left, $right);
$wid = $warehouse_box['wid'];
$sql = mysqli_query($conn,"UPDATE warehouse SET amount = CASE WHEN amount + $box_db < 0 THEN 0 ELSE amount + $box_db END WHERE wid = '$wid'");
$loggerclass->writeLogWarehouse(['reason' => 'Kivét selejt miatt', 'reason_code' => 1,
'item_id' => $item_id,
'from_place' => $warehouse_code,
'to_place' => '',
'amount_left' => $box_db,
'amount_right' => $box_db
]);
} else {
echo json_encode(array(
'result' => 'A cikkszám nem található meg ezen a raktárazonosítón!'
));
exit();
}
} else {
echo json_encode(array(
'result' => 'Nem létező raktár azonosítót adott meg!'
));
exit();
}
}
echo json_encode(array(
'result' => 'ok'
));
}
exit;
}
?>
<!DOCTYPE html>
<html lang="hu" dir="ltr">
<head>
<meta charset="utf-8">
<link rel="stylesheet" href="../css/panel.css">
<title>Kezelőfelület</title>
</head>
<body>
<?php echo $menuhtml;?>
<div class="window closed" id="win">
<div class="topbar">
<p id="wintitle">Title</p>
<div class="btn fullscrn" onclick="fullscrn();" id="fullscrnbtn"></div>
<div class="btn close" onclick="closewin();"></div>
</div>
<div class="wapp" id="winapp"><div id="errorDIV"></div></div>
<div class="loading" id="winloading"></div>
</div>
<div class="loadingBG" id="loadingBG"><img src="../img/loading.gif"></div>
<div class="content" style="margin-right: 30px;">
<div id="errorDIV" style="z-index: 100; top: 50px; position: fixed; width: calc(100% - 260px);"></div>
<!-- Tartalmi rész kezdete -->
<!-- KATEGÓRIA GOMBOK -->
<div class="category-tabs">
<div class="category-tab active" onclick="switchCategory(this, 'warranty')">
<div class="category-tab-icon">
<img src="data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAADAAAAAwCAYAAABXAvmHAAAACXBIWXMAAAsTAAALEwEAmpwYAAAEMUlEQVR4nO2ZXWgUVxTHT2PbF7ElraDZLBGhIKybbFAfBUNNK60PIiWYzEptSuiLoogfbGaloRQTlD4JhZZQmkVEjEZBnbmb3ZhAE41JNzGZySZ+RFAQ8iAmiD4EduYeubOTMLOzrZnNzCSBHPjDsjP37v83994z594FWI3VWA3HAwlsU0W4phCYYWKf2XewHANF8GcIVGUIVGdE+FolEFMIqCoBNEr/Lsbu0e4lUMXaLp3xm7BeJXBDEYHmml2olGzb65iEz7013w5rFAJ9hRrPMzq9rE/PAJQ4HMlrpguQ9gOqDwCpDEjHAZFpFJAOA9K72Xv+A+KwJ+YxAT6FwLTJQA+gykw+0vVQ1wQgMs2BpHUNA6rdFoBp1rd7xpugSBHge4XAS5P5FCB9Akgf2wAYy4r2WyBY1jqGPfChs+ZvwnrLnE8AqrJuvkAAZO3/BVQ786wJJxc2yzaWect+fHLxACgBYgpQjef0L0KHI+ZZrrakyiHdvFMAEiC9Z02xjqwJ9sLJXbD0qfMAOGrNUOy3nQDYYwIYcw+ADloA9iweQIRv5zvt1s27BIBsFJImgL2LBmD1y1yHdMB9APqPaRRiizKPt6HSVJiNeQAwaC4AUYAdhT99ETqMc1Iz5zIAspRqTtlXCwbQankjwFMPAB5YSwznACaXAECEVwUDsJ2UCeDhCptCuBSLeCBnEXfC9oIBtFEg0DY/AoMeAPSann4bOPoi61qBL7JMbikhr7RSguQp5iZXUDGHS1VOE1Ad22Kyow/LhkZyfUNzDZwKtr1j2zxPt5Rx+MwxAFc29bKHm/r3HqvcAVRHFg5AU3ob4uGxyoIOtpL6Ux3Jc7A1pB9sGfK8apB0efOv4FWwY8DJjs1TeSEKUH8siJsOiq2eAQQbpQ27fu6bTV6sxgwpKth4hnyAt/7YiYH6DiwJJ2bLwqTEE4BQJN0S4tNYwadx9y89WH/ub2w434oNv7Xijdi+vFDM7JXfq7H25Fk8cKIZvzt+Hrc1XEIf14k+LoG+sKZm181vOTWxriKSnpkDYCrnxzQFo1nVtLRj58WvcObWJ5pI25f4zZEL6OdELOWIrrgmEwCXfF1ck/zUVYCKSPpkqDGN/wcQjMq4VVcgKuOmH7s08+8FCCdxI5c44Zr57T+lPqpoHH9uB2DLqaE3/jrBDsCLQE37x64AhPiJH0KN42gH4Iuj9y/YAShhEOHkIXcAIulRWwC8NLXh4Mhaf63wzCbAqCsAlZHxATsAAV5qYu38tcJpOwAlXFc/eBlBXtpfzsvUDCDNsvcFu17G3S721wlvzQCE+rj4AVguUc7LLUaAQFT+y3jdzwl/GgF8dXH3c76taMKirbwszI/AGTlkvFwWFgN+TqBZADEBNe3e/Su50CiPSMVBXh4ORqXL+a6X1omXSjkxxaaU9+5gecY7hGF4QgN8A1AAAAAASUVORK5CYII=" alt="warranty--v1">
</div>
<div class="category-tab-title">Garanciális ügyintézés</div>
<div class="category-tab-desc">Garancia szerinti csere</div>
</div>
<div class="category-tab" onclick="switchCategory(this, 'scrap')">
<div class="category-tab-icon">
<img src="data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAADAAAAAwCAYAAABXAvmHAAAACXBIWXMAAAsTAAALEwEAmpwYAAAJT0lEQVR4nO2Y20/jaRnHm032xjWaqIl6YaI3XnizN7rxYo0mJntn9NJEk/VGY6KJf8EuzAwzDJ0ZoJzLmUIptFB6oLSlLaUtPVBaej5COfX8+7XMMO5odtbla963Z6DQmezszibzJJ8QQkk/z/d93vd34HDe1Jt6/SqVOvsuwzA2hmGzLMv+jvN1qnQ6/Q2GYbcYhgUhn2fOGYa5D+AtzuteAN5mGFZdkb+AOJvNvsN5XQvAW/k8u9BEvoIvm83+hPM6Vj7P8m6QL8MUcjn2t5zXKXmGYTpbk6/ui+csy/7tKxE+O3uqfvbsP/jkk2cUtnCKo2QauTzTcgPJVBqyNd3zr0D+zNAgXyxi7/AEe4fHlGQqc1Py2Nn1Y1SwiP7xWXyp8qp14z+7R6ZA6BufpQKToiXI1XqYrE64vEEEY/uI7R/i+CSNVCqDQDgGu9ONNb0JYpkKo4IF+n8VOF9mzUpkp+RL7/eP4R5vBA+HJtA3JmgQaoXhKRG2HG4cJzNbkb2DrVgi8atXLq/Q6NsqAkT6Xi8fHT3D6OgdRtfAGHr50zeKCxZl8IdidM8Uio+RzuQykb0DlNFFIvs/Tybz72YymT+n0xluJpPVnpyk2HA8AUI0tnfo9Yb+7nK53n4heZ3L9e3xOcnzeple/gw6uocod8o8GJy4Uly5bsTRcZJKF08f05+F4ikSR8cI7x0gHCeUJPcSR0imUkinM0ilM0gcniAU26eQv3v9oc9cu37W5fH9teUGpMp1w1ViD4cncad7sMSjEtzBccwvK2Hf8eDwOAm2eIrT0ycoUmryDFOsSocIsURVlEAaOT5J0dUJRvfL7CEc24drNwCny/vvluTXdJb3ByeFTcfibu8wbj8arOJweZHN5uhpwzAFFApFKl6Tf4xC4RSpTK5BOEioE60QqBCpEYruYdcbvtNSAyKp6ui6ueYOjOH2wwHcejhA5c/OnlaXn5LK0N8zmSyyOQb5PAuGLSK+f9wgGrxSNk7x1xOOk4bZlsdnaFJ4fl0DvaMzmJXIqeyTs6cUcpGiJCukcFKGNHOSSl8pGrggWiMGXx2h6N4fWm7gOnlyMXK4PEgcndBxefLkKZ48OavKnpwQkqVNmcnSzzBsgabdiqgvVE8U3lAUwUjc17L8dQ1IV7XYSxxQ0cryR/cPkMnm6Wpkc3kqWyw+rm5isnnDsQQV9TcVjVHRKsEGzr3h8E9fuoFZsQx6kxXhSAzHJ8kSx8lLyx+I7NMxIZu1evoUThFPHDUXDTXKeoKRRgIRBEJx6QvJ1zegMZipbCJxhEAoih23DxbrNrQGM8Vo2YZ12w2n2wu3Nwivn3xhFPsHx8jlWRwcp5qIRi+JVtilhCmeQPTTYDD4zZdqYFYiQyJxCKvDBZXWCJXGiFXNRg31BpQUQ4k1AxQUfQmVHk6XryXRXYK/hruMLxS5xXmZGpoSwuMLQmfcuka0LKvSQ15FB/mqDrI6rA53U1l3lVAJXwmXLwSH2webc/fXL9WAwWT7H0m8uai+QdS2vYtMJkfvdwjkzCd3qlKFlrJhttcJX5Z1VQlSyDiKlhWw2t1zL9WAet24UZ9qfaKy1XWsKGvYHO6qOFsoIpcvIJ3J082rXNvAklyDJZkG6xuWOuFgCW+JnQvMSxSQKtRkvz1zOBzfeuEGFArj91ZW13P1ooRKohWW5Vp6fLJskaaeyeZoypVEdzx+SFbUkKysQbyyRkewUTiAHU8AzjrIiXe/dxhavRlmqxMWq/PlHkGXZdo/VkWprKYKSVWl2aR3m0S8Qii2dylRg9mORakKi8slpMr1S9JOjx/bu37YXV5w+/iUTYsdpq1tmCyOnZalPcHge/5QbMAbiAR3A6H/VpZ/SaamSAgranq65MjjIhUvIM8UkEpnr07VG8CSTAvR0ipES0qIJEqIV9TYdnupdAWH248xgYimPzIpxKbFUcVms33nRvl4PP5BKBL9nBxxlRGoX36xdI3O9CG5hWCLVLpCjimQy31Dos46Obtzl871vFgBYZl5iRJao4WeNoQpkRSjM/O0AaFEhk2zA8YyepPtvWvlvV7vO5FY/CASiyMSjSMYjtJTgy59efm3d7zI5dgGcTL/5PlXY7DA5vQ0JEopyxFI6nOL8hILMsyWkasNWJCpcL+Pj77RGdqAYk0Ho9lewmTHhsn2p2sbiETiA5FojN4uXCQQjNANddWXU0QyCEQyCMVymB07VeGLmGw7mBPJIRCt1JhfwdCEEJ28kSpD4wKsG7aIdBWDydreVD4cjv8yFI5+HopEEQo34vb46Ow3yjYKzFCkFDIWth1P0yZI2pXPTgul4E8t4D6Pj3u9I2WGMT63CMOmrQ4rDEZr8+tBMBQNkJEJhiJV/IEwjBY7TbwiWy9KEZYkSixTpuaWsazUNm2AnDJzYgX93Nj0Ijr7RnCvZ5hyt4zWYKLSemMNndHqaNqAfE2vuS7VSloXRWssYZIwu4QJgQS9I9P0gb5ZExtb25gQiOm43O0ZKtFdYkq4VJbeopBbGd0GwZK/dg+s6TY+FEkUzy+JNsgulWRnG5mYlVBxMstdfaN0DLj9Y9i0Oq9swOxwo3tkuvp2o6N7kEJWoSZcg1zBtQaLnnNT6e327y/L1fGLqV4UrWdcIKaj0D00WR6BcqI9Q+gfE9CRaZC3u+i7pI7y24waA5Culm431g2NaPWWz3Q6y/ucVkuq0OiuEh2fqTFGWcTg2Cw6e0fo8l9MlCBcUtQlv4OekSkqe4fwcIC+GCDw+NNE9pwKU2nTkUZvntbqTX/RaEw/4rxoSeRrugbZ6cUqo2UGx+Zqso8Gr0yV/E2hMcBgcdBXkhXh2w/7KbcelFBq9Bmt3ryo1Zk+VBuNP+Z8ESWWqjRUdmqhCjn2+JMEEbp4o1XRCjXBgStluf2j9MFIqzdTVNrN89mFFT7nVdXiyqqWyI5UmBChny/A/d6Ra0Uv00eZWZBCozNRpErts3GR9APOq65lhfofM/PLp/yphXMy762ItnMvc+dRP1a1G1DrTFiQqhKPxOKbb9C+yGp7wPtZO7evrZ3bv3uL28e2c3netq4+WRuX19ve1f+vW1ze72939r3b0d39w7YHPb/5uIsn/LiL92lbFw+EoYk58jh6PiNa7uJ8XaqNO/CDjzp72j/q7ElOz0uP+JMLv/iqnd7Um+KU6v/c9rF3BDVaCQAAAABJRU5ErkJggg==" alt="paper-waste">
</div>
<div class="category-tab-title">Selejt kivét</div>
<div class="category-tab-desc">Selejtből raktári kivét</div>
</div>
<div class="category-tab" onclick="switchCategory(this, 'employee')">
<div class="category-tab-icon">
<img src="data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAADAAAAAwCAYAAABXAvmHAAAACXBIWXMAAAsTAAALEwEAmpwYAAAFgklEQVR4nO2YbUyTVxTHr73RT5tsn3RkmVRRBKYuOnEbUhBkvDid2UuWOfcFVPrw0ha/bFEznJosmcuyL3PTbTGbS8yIGTjKm7yUUvrABIxTJ8pMmPptUVpAWmxL/8u5TyG0FoVQWkw4yT+5uefc2//vPKdPkzI2H/MxH7MSntIoq2d/FIRKF1vY0xBuib3pltgPbondGDfvk1tiPW4tO+UuYJlsrgW0LM4jsVaPxDCuAAC/nJaZUcRWsbkQLomlurXM5mfwSQASoyfS7ypkmoh3Pqj5KQCMQaCArYwYgEdipqDmpwjg8Y1TRMzTl3FSU9MBkBjchSwj/ABa9mPIACR2MvwA9KoMHUBP+AG0bChkAFo2FHaAx5qfJoBHYgireZeWpYQawFXINofFPI4m3sfRRMyKjiTem32AI4n3nmoAin/LYxM6Di7pl0uWwmFKwkjrZjxsS4O7PROeP3Mx2rkD3u6dwKV3hWhNe5SjGqqlMw5TEsz5L6KleEl/39ll8Sxc0Veu3t/9xVJc+XyZMOH0AbgEQA5GO7cL095L7ygSANtFjmqols44TEm4UqZGx6EXQHeGD+Ds8pzL30Sj7/uVcDRvhNOcjIdtqXDJW+HuyMboxbcw2rUD3q63hWhNe5SjGqqlM47mjbh9Kg7dX0ajr3xFdtgAes/ELr52Mrr3fkUChps2wNnyOkYsKXho3eIboxx4Lm4TXRedv7hN7InxsW4RtXRmuGkD7lck4uqJ6F66k4U7huoT8KDxFWWMzMkYsaTCZU0XY+LuyBIdV5Ql9ihHNaL7piRxlu5gkYqB2tWOoQtrMNy0Ho6WTXC2EoRGdNklZ4hxUZTh67xG1FAtnRm6sAZ0R8QA7NUr2gfr4vGgYa0YB4dpk/IkWlMUkLZUIVrTntJ5Mr9BnBmsi4e9OlaOGMCAUb17oGYlBmmUBMR68cV0tLwGp/kNP9Ee5ahGmK9PAJ21G5d/GDEAlDGVzRhTLSDq4jF04WU8aFgnTFKXh5tfVURrYXydqKFaOmOriqmiO1gkw2586Xm7MaZroDoWg7VxCkh9ophv6jSJ1rRHOaqhWltVTKetYtlzbC5Ef8PyKFuVusZuVGOgeoXoroCZINqjHNXQU7tXE4HX5uMCYAtu/6ZGf5VamAwmylEN1bK5GNd/VqPnjGLyv0rFMInWd8rV6PlFDaphcymOn9ulURk6DqgM7Y1kbipS6awNKp184OuzH6REzPiJ398r67Am2EZvLQA3tAvJP619onmq4XpZaPTmAnRY4m0nzu0sC5vxhbr2tZ3tcTbvLYYxjQEc/Ep6IsCB49I4gPcmG1dn2yrbwlJ5zayaVxnkj7hBHvb+wzBRYwDP7jfh12+zJzVPuWdKm8D1ViHvDeYnrrM4VSWWvNkxr28/OGbU28v8NNZR0iJDGz4+dhjl321F9+l4dJ9eLda7jx3GIoPFZ74NXNcGbw8Tgk+8xAxebIaq2PRpSM1zvfw+N8heARDw6EkTARRZg0gxzXUWRSWtwHXmJ17cAl5kAi9q9qqKmnaFxv0nXVFcJ9smGszNzUV2djaysrKQmZk5iWGrz7DPdIliWpHS6dzAe4qawQtJTeBSo53pTTP/pVbp5c8CO0wflpGRgfT0dKSlpT22yxMNiw6Pd9n06D1SI7i2AVxbD15QB9W+2kMzB9DJ1wLHgj5Mo9EgJSUFycnJ0zI9sctpgfcU1IHvqwXfVwO+txqqPcarMwbgeutI4Czjb/aork2iq0F0Jbj4XiP4nirw/D/A88+D51U4QwHgP8s6y9SNTmb2r+DieWS60k8zB9BZ7gaOxXS6GtTs5eDiAeZ5XuWdmQMUt+TwIvPdibM8na5OZnYKAHd4/vnw/dUyH/PBns74H103Ro9XlAz1AAAAAElFTkSuQmCC" alt="worker-male">
</div>
<div class="category-tab-title">Dolgozói kivét</div>
<div class="category-tab-desc">Dolgozó által kivett</div>
</div>
</div>
<!-- GARANCIÁLIS -->
<div id="warranty" class="cat-tab form-section active">
<div class="form-title">Garanciális ügyintézés</div>
<div class="form-desc">Ügyfél garanciális igénye alapján töltse ki az adatokat</div>
<form onsubmit="handleSubmit(event, 'warranty')">
<div class="form-row">
<div class="form-group">
<label class="required">Ügyfél neve</label>
<input id="warranty" name="name" type="text" placeholder="Ügyfél neve" autocomplete="off" required>
</div>
<div class="form-group">
<label class="required">E-mail cím</label>
<input id="warranty" name="mail" type="email" placeholder="E-mail cím" autocomplete="off" required>
</div>
<div class="form-group">
<label>Rendelés azonosító</label>
<input id="warranty" name="order_id" type="text" placeholder="Rendelés azonosító" autocomplete="off">
<div class="form-hint">Nem kötelező</div>
</div>
</div>
<div class="form-row">
<div class="form-group">
<label class="required">Cikkszám</label>
<input id="warranty" name="item_id" onkeyup="CopyData(this.name, this.value)" type="text" placeholder="Cikkszám" autocomplete="off" required>
</div>
<div class="form-group">
<label class="required">Bal oldal darabszám</label>
<input id="warranty" name="left_db" value="0" onkeyup="CopyData(this.name, this.value)" type="number" min="0" placeholder="Bal oldal darabszám" autocomplete="off"required>
</div>
<div class="form-group">
<label class="required">Jobb oldal darabszám</label>
<input id="warranty" name="right_db" value="0" onkeyup="CopyData(this.name, this.value)" type="number" min="0" placeholder="Jobb oldal darabszám" autocomplete="off" required>
</div>
</div>
<div class="form-row">
<div class="form-group">
<label class="required">Garancia típusa</label>
<select id="warranty" name="reason" required>
<option value="">-- Válassz --</option>
<option value="Felszerelési törés garancia">Felszerelési törés garancia</option>
<option value="Szállítási törés garancia">Szállítási törés garancia</option>
<option value="Téves rendelés garancia">Téves rendelés garancia</option>
<option value="Csomagolási hiba garancia">Csomagolási hiba garancia</option>
<option value="Export partner garancia">Export partner garancia</option>
<option value="Nagyker partner garancia">Nagyker partner garancia</option>
<option value="1 éves vásárolt garancia">1 éves vásárolt garancia</option>
<option value="2 éves vásárolt garancia">2 éves vásárolt garancia</option>
</select>
</div>
</div>
<div class="form-row full">
<div class="form-group">
<label>Megjegyzés</label>
<textarea id="warranty" name="note" placeholder="Megjegyzés a kiszedéshez..." autocomplete="off"></textarea>
<div class="form-hint">Nem kötelező</div>
</div>
</div>
<div class="form-actions">
<button type="submit" class="btn-primary">Rögzítés</button>
</div>
</form>
</div>
<!-- SELEJT -->
<div id="scrap" class="cat-tab form-section">
<div class="form-title">Selejt kivét</div>
<div class="form-desc">Raktári selejt adatait rögzítse az alábbi űrlapon</div>
<form onsubmit="handleSubmit(event, 'scrap')">
<div class="form-row">
<div class="form-group">
<label class="required">Raktárhely</label>
<input id="scrap" name="wh_id" type="text" placeholder="Raktárhely" autocomplete="off" required>
</div>
</div>
<div class="form-row">
<div class="form-group">
<label class="required">Cikkszám</label>
<input id="scrap" name="item_id" onkeyup="CopyData(this.name, this.value)" type="text" placeholder="Cikkszám" autocomplete="off" required>
</div>
<div class="form-group">
<label class="required">Bal oldal darabszám</label>
<input id="scrap" name="left_db" value="0" onkeyup="CopyData(this.name, this.value)" type="number" min="0" placeholder="Bal oldal darabszám" autocomplete="off" required>
</div>
<div class="form-group">
<label class="required">Jobb oldal darabszám</label>
<input id="scrap" name="right_db" value="0" onkeyup="CopyData(this.name, this.value)" type="number" min="0" placeholder="Jobb oldal darabszám" autocomplete="off" required>
</div>
</div>
<div class="form-row full">
<div class="form-group">
<label class="required">Selejt oka</label>
<textarea id="scrap" name="reason" placeholder="Részletes leírás a selejt okáról..." autocomplete="off" required></textarea>
</div>
</div>
<div class="form-actions">
<button type="submit" class="btn-primary">Rögzítés</button>
</div>
</form>
</div>
<!-- DOLGOZÓI -->
<div id="employee" class="cat-tab form-section">
<div class="form-title">Dolgozói kivét</div>
<div class="form-desc">Dolgozó által kivett terméket rögzítse itt</div>
<div class="info-banner">
<strong>Infó:</strong> A dolgozó ID nem kötelező mező! A szaturnusz rendszerben létező fiókokhoz való társításra szolgál.
</div>
<form onsubmit="handleSubmit(event, 'employee')">
<div class="form-row">
<div class="form-group">
<label class="required">Dolgozó neve</label>
<input id="employee" name="name"type="text" placeholder="Dolgozó neve" list="employee_list" oninput="EmployeeName(this.value);" autocomplete="off" required>
<datalist id="employee_list" role="listbox"></datalist>
</div>
<div class="form-group">
<label>Dolgozó ID</label>
<input id="employee" title="Válasszon a névlistából" name="uid" type="text" placeholder="Dolgozó ID" autocomplete="off" disabled>
<div class="form-hint">Válasszon a névlistából</div>
</div>
</div>
<div class="form-row">
<div class="form-group">
<label class="required">Cikkszám</label>
<input id="employee" name="item_id" onkeyup="CopyData(this.name, this.value)" type="text" placeholder="Cikkszám" autocomplete="off" required>
</div>
<div class="form-group">
<label class="required">Bal oldal darabszám</label>
<input id="employee" name="left_db" value="0" onkeyup="CopyData(this.name, this.value)" type="number" min="0" placeholder="Bal oldal darabszám" autocomplete="off" required>
</div>
<div class="form-group">
<label class="required">Jobb oldal darabszám</label>
<input id="employee" name="right_db" value="0" onkeyup="CopyData(this.name, this.value)" type="number" min="0" placeholder="Jobb oldal darabszám" autocomplete="off" required>
</div>
</div>
<div class="form-actions">
<button type="submit" class="btn-primary">Rögzítés</button>
</div>
</form>
</div>
<br clear="all">
<br clear="all">
<div style="width: 100%; min-height: 85px;">
<div style="display: inline; float: left;">
<p>Cikkszám: </p>
<input type="text" id="filter-item_id" placeholder="Cikkszám..." onkeydown="if (event.keyCode == 13) {SendFilter();}" autocomplete="off" style="width: 147px; height: 17px;">
</div><div style="display: inline; float: left; padding-left: 15px;">
<p>Ügyfél / Raktár / Dolgozó neve: </p>
<input type="text" id="filter-name" placeholder="Ügyfél / Raktár / Dolgozó neve..." onkeydown="if (event.keyCode == 13) {SendFilter();}" autocomplete="off" style="width: 147px; height: 17px;">
</div><div style="display: inline; float: left; padding-left: 15px;">
<p>Időtartam kezdet: </p>
<input type="datetime-local" id="filter-start_datetime" onchange="SendFilter();" >
</div><div style="display: inline; float: left; padding-left: 15px;">
<p>Időtartam vége: </p>
<input type="datetime-local" id="filter-end_datetime" onchange="SendFilter();">
</div><div style="display: inline; float: left; padding-left: 15px;">
<p>Oldalanként: </p>
<select id="filter-perpage" onchange="SendFilter();"><option value="25">25 db / oldal</option></select>
</div><div style="display: inline; float: left; padding-left: 15px;">
<p style="color: #f5f5f5;">: </p>
<button onclick="SendFilter();">Szűrés</button>
</div>
</div>
<br clear="all">
<div style="border-top: solid 1px rgb(211,220,228); width: 100%; height: 0px; margin-top: 15px;"></div>
<br clear="all">
<div style="width: 100%; margin-left: 10px; margin-top: 10px; display: inline; float: left;">
<div class="tables" style="width: 100%">
<table id="table">
<thead>
<tr style="top: 0px; position: sticky; z-index: 1;">
<th >Ügyfél / Raktár / Dolgozó neve</th>
<th >Cikkszám</th>
<th >Dátum</th>
<th style="width: 100px;">Jobb db</th>
<th style="width: 100px;">Bal db</th>
<th style="width: 100px;">Adatlap</th>
</tr>
</thead>
<tbody>
</tbody>
</table>
</div>
</div>
<br clear="all">
<div>
<p style="text-align: center; padding-bottom: 50px; color: #333333;"><span onclick="left();" style="cursor: pointer;"><&nbsp;&nbsp;&nbsp;&nbsp;</span><span id="cpage">0</span> / <span id="maxpage">0</span><span onclick="right();" style="cursor: pointer;">&nbsp;&nbsp;&nbsp;&nbsp;></span></p>
</div>
<br clear="all"><br><br>
<!-- Tartalmi rész vége -->
</div>
<script src="../js/default.js" type="text/javascript"></script>
<script type="text/javascript">
var ActiveCategory = "warranty";
function switchCategory(element, categoryId) {
document.querySelectorAll('.category-tab').forEach(tab => tab.classList.remove('active'));
element.classList.add('active');
document.querySelectorAll('.form-section').forEach(section => section.classList.remove('active'));
document.getElementById(categoryId).classList.add('active');
ActiveCategory = categoryId;
LoadTable();
}
/* Kereső */
function LoadFilter() {
const body = 'func=filter';
get_POST_information("wh_remove.php", body, function(text) {
let response = JSON.parse(text);
if (response.result == "ok") {
document.getElementById('filter-perpage').innerHTML = response.perpage;
document.getElementById('employee_list').innerHTML = response.userselect;
LoadTable();
} else {
GenerateAlerts("error", response.result);
}
}, function() {
GenerateAlerts("error", "Hálózati hiba!");
});
}
function SendFilter() {
document.getElementById('cpage').innerHTML = '1';
LoadTable();
}
function left() {
var cpage = document.getElementById("cpage").innerHTML;
if ((parseInt(cpage) - 1) >= 1) {
document.getElementById("cpage").innerHTML = parseInt(cpage) - 1;
LoadTable();
}
}
function right() {
var cpage = document.getElementById("cpage").innerHTML;
var maxpage = document.getElementById("maxpage").innerHTML;
if ((parseInt(cpage) + 1) <= parseInt(maxpage)) {
document.getElementById("cpage").innerHTML = parseInt(cpage) + 1;
LoadTable();
}
}
function LoadTable() {
Loading();
var item_id = document.getElementById("filter-item_id").value;
var name = document.getElementById("filter-name").value;
var start_datetime = document.getElementById("filter-start_datetime").value;
var end_datetime = document.getElementById("filter-end_datetime").value;
var perpage = document.getElementById("filter-perpage").value;
var cpage = document.getElementById("cpage").innerHTML;
const body = 'func=table&perpage=' + perpage + '&cpage=' + cpage + '&category=' + ActiveCategory + '&item_id=' + encodeURIComponent(item_id).replace(/%20/g, '+') + '&start_datetime=' + encodeURIComponent(start_datetime).replace(/%20/g, '+') +'&end_datetime=' + encodeURIComponent(end_datetime).replace(/%20/g, '+') + '&name=' + encodeURIComponent(name).replace(/%20/g, '+');
get_POST_information("wh_remove.php", body, function(text) {
Loading(false);
let response = JSON.parse(text);
if (response.result == "ok") {
var table = document.getElementById('table').getElementsByTagName('tbody')[0];
table.innerHTML = "";
document.getElementById("cpage").innerHTML = response.cpage;
document.getElementById("maxpage").innerHTML = response.maxpage;
var tableresponse = response.data;
if (tableresponse != "") {
if (tableresponse.includes("|%|")) {
var tablearr = tableresponse.split("|%|");
} else {
var tablearr = [tableresponse];
}
for (var i = 0; i < tablearr.length; i++) {
var datas = tablearr[i].split("/!/");
var newRow = table.insertRow();
var newCell_1 = newRow.insertCell(0);
var newCell_2 = newRow.insertCell(1);
var newCell_3 = newRow.insertCell(2);
var newCell_4 = newRow.insertCell(3);
var newCell_5 = newRow.insertCell(4);
var newCell_6 = newRow.insertCell(5);
newCell_1.innerHTML = datas[0];
newCell_2.innerHTML = datas[1];
newCell_3.innerHTML = datas[2];
newCell_4.innerHTML = datas[3];
newCell_5.innerHTML = datas[4];
newCell_6.innerHTML = '<a style="cursor: pointer;" onclick="OpenInfo(\'' + ActiveCategory + '\', \'' + datas[5] + '\')">Megnyitás</button>';
}
}
} else {
GenerateAlerts("error", response.result);
}
}, function() {
Loading(false);
GenerateAlerts("error", "Hálózati hiba!");
});
}
LoadFilter();
function OpenInfo(category, rid) {
Loading();
const body = 'func=OpenInfo&category=' + category + "&rid=" + rid;
get_POST_information("wh_remove.php", body, function(text) {
Loading(false);
let response = JSON.parse(text);
if (response.result == "ok") {
CreateAlertBox("Adatlap", response.html);
} else {
GenerateAlerts("error", response.result);
}
}, function() {
Loading(false);
GenerateAlerts("error", "Hálózati hiba!");
});
}
/* Kiszedés létrehozás */
async function SendCreateRemoval(json, category) {
try {
const formData = new FormData();
formData.append('func', 'CreateRemoval');
formData.append('category', category);
formData.append('data', JSON.stringify(json));
const response = await fetch('wh_remove.php', {
method: 'POST',
body: formData
});
const result = await response.text();
return result;
} catch (error) {
console.error('Hiba:', error);
return null;
}
}
function handleSubmit(event, type) {
event.preventDefault();
Loading();
document.querySelector('input#employee[name="uid"]').disabled = false;
const formData = new FormData(event.target);
const data = Object.fromEntries(formData);
document.querySelector('input#employee[name="uid"]').disabled = true;
const dataArray = [];
Object.entries(data).forEach(([paramName, paramValue]) => { dataArray.push({ name: paramName, value: paramValue }); });
if (type == "scrap") {
ScrapRemoval(
document.querySelector('input#scrap[name="item_id"]').value,
parseInt(document.querySelector('input#scrap[name="right_db"]').value),
parseInt(document.querySelector('input#scrap[name="left_db"]').value),
document.querySelector('input#scrap[name="wh_id"]').value,
dataArray
);
return;
}
SendCreateRemoval(dataArray, type).then(result => {
Loading(false);
if (!(result == "ok" || result == "reload - ok")) {
GenerateAlerts("error", result);
} else {
GenerateAlerts("success", "Sikeresen regisztrálta a kivétet!");
if (type == "warranty") {
var amount = Math.min(
parseInt(document.querySelector('input#warranty[name="right_db"]').value),
parseInt(document.querySelector('input#warranty[name="left_db"]').value)
);
ReservItem(
document.querySelector('input#warranty[name="item_id"]').value,
amount,
"Garanciális - " + document.querySelector('input#warranty[name="name"]').value,
document.querySelector('input#warranty[name="order_id"]').value,
document.querySelector('input#warranty[name="name"]').value,
document.querySelector('input#warranty[name="mail"]').value,
document.querySelector('textarea#warranty[name="note"]').value, 0
);
var difference = Math.abs(
parseInt(document.querySelector('input#warranty[name="right_db"]').value) -
parseInt(document.querySelector('input#warranty[name="left_db"]').value)
);
if (parseInt(document.querySelector('input#warranty[name="right_db"]').value) > parseInt(document.querySelector('input#warranty[name="left_db"]').value)) {
ReservItem(
document.querySelector('input#warranty[name="item_id"]').value,
difference,
"Garanciális - " + document.querySelector('input#warranty[name="name"]').value,
document.querySelector('input#warranty[name="order_id"]').value,
document.querySelector('input#warranty[name="name"]').value,
document.querySelector('input#warranty[name="mail"]').value,
document.querySelector('textarea#warranty[name="note"]').value, 1
);
} else if (parseInt(document.querySelector('input#warranty[name="right_db"]').value) < parseInt(document.querySelector('input#warranty[name="left_db"]').value)) {
ReservItem(
document.querySelector('input#warranty[name="item_id"]').value,
difference,
"Garanciális - " + document.querySelector('input#warranty[name="name"]').value,
document.querySelector('input#warranty[name="order_id"]').value,
document.querySelector('input#warranty[name="name"]').value,
document.querySelector('input#warranty[name="mail"]').value,
document.querySelector('textarea#warranty[name="note"]').value, 2
);
}
} else if (type == "employee") {
var amount = Math.min(
parseInt(document.querySelector('input#employee[name="right_db"]').value),
parseInt(document.querySelector('input#employee[name="left_db"]').value)
);
ReservItem(
document.querySelector('input#employee[name="item_id"]').value,
amount,
"Dolgozói - " + document.querySelector('input#employee[name="name"]').value,
document.querySelector('input#employee[name="uid"]').value,
document.querySelector('input#employee[name="name"]').value,
"", "", 0
);
var difference = Math.abs(
parseInt(document.querySelector('input#employee[name="right_db"]').value) -
parseInt(document.querySelector('input#employee[name="left_db"]').value)
);
if (parseInt(document.querySelector('input#employee[name="right_db"]').value) > parseInt(document.querySelector('input#employee[name="left_db"]').value)) {
ReservItem(
document.querySelector('input#employee[name="item_id"]').value,
difference,
"Dolgozói - " + document.querySelector('input#employee[name="name"]').value,
document.querySelector('input#employee[name="uid"]').value,
document.querySelector('input#employee[name="name"]').value,
"", "", 1
);
} else if (parseInt(document.querySelector('input#employee[name="right_db"]').value) < parseInt(document.querySelector('input#employee[name="left_db"]').value)) {
ReservItem(
document.querySelector('input#employee[name="item_id"]').value,
difference,
"Dolgozói - " + document.querySelector('input#employee[name="name"]').value,
document.querySelector('input#employee[name="uid"]').value,
document.querySelector('input#employee[name="name"]').value,
"", "", 2
);
}
}
LoadTable();
}
const inputs = document.querySelectorAll('input[name="right_db"], input[name="left_db"]');
inputs.forEach(input => {
input.value = '0';
});
const inputs2 = document.querySelectorAll('input[name="item_id"]');
inputs2.forEach(input => {
input.value = '';
});
});
}
function ReservItem(item_id, amount, reason, order_id, order_name, order_mail, note, amount_type, order_primary_source_input = null) {
if (Number(amount) <= 0 || isNaN(Number(amount))) return;
if (order_primary_source_input != null || Number(amount_type) != 0) {
if (Number(amount_type) != 0) {
order_primary_source = 0;
} else {
order_primary_source = order_primary_source_input;
}
Loading();
const body = 'func=reservitem&item_id=' + encodeURIComponent(item_id).replace(/%20/g, '+') + '&primary_source=' + order_primary_source + '&amount_type=' + amount_type + '&reason=' + encodeURIComponent(reason).replace(/%20/g, '+') + '&amount=' + amount + '&order_id=' + encodeURIComponent(order_id).replace(/%20/g, '+') + '&order_name=' + encodeURIComponent(order_name).replace(/%20/g, '+') + '&order_mail=' + encodeURIComponent(order_mail).replace(/%20/g, '+') + '&note=' + encodeURIComponent(note).replace(/%20/g, '+');
get_POST_information("wh_orders.php", body, function(text) {
let response = JSON.parse(text);
Loading(false);
if (response.result == "ok") {
LoadTable();
} else {
GenerateAlerts("error", response.result);
}
}, function() {
Loading(false);
GenerateAlerts("error", "Hálózati hiba!");
});
return;
} else {
var html = `
<p><b>Válassza ki, hogy elsődlegesen honnan legyen kiszedve az alábbi rendelés:</b><br>
${reason}</p>
<button id="AlertBtnFoil" style="float: right; margin-left: 15px;">Fóliás</button>
<button id="AlertBtnBox" style="float: right;">Dobozos</button>
`;
const overlay = CreateAlertBox('Elsődleges forrás', html, false);
document.getElementById('AlertBtnFoil').onclick = function () { ReservItem(item_id, amount, reason, order_id, order_name, order_mail, note, amount_type, 1), CloseAlertBox(overlay); };
document.getElementById('AlertBtnBox').onclick = function () { ReservItem(item_id, amount, reason, order_id, order_name, order_mail, note, amount_type, 0), CloseAlertBox(overlay); };
return;
}
}
function ScrapRemoval(item_id, right, left, warehouse_code, dataArray) {
Loading();
const body = 'func=ScrapRemoval&item_id=' + encodeURIComponent(item_id).replace(/%20/g, '+') + '&left=' + left + '&right=' + right + '&warehouse_code=' + encodeURIComponent(warehouse_code).replace(/%20/g, '+');
get_POST_information("wh_remove.php", body, function(text) {
let response = JSON.parse(text);
Loading(false);
if (response.result == "ok") {
GenerateAlerts("success", "Sikeresen törölte a raktárból");
var type = "scrap"
SendCreateRemoval(dataArray, type).then(result => {
Loading(false);
if (!(result == "ok" || result == "reload - ok")) {
GenerateAlerts("error", result);
} else {
GenerateAlerts("success", "Sikeresen regisztrálta a kivétet!");
LoadTable();
}
const inputs = document.querySelectorAll('input[name="right_db"], input[name="left_db"]');
inputs.forEach(input => {
input.value = '0';
});
const inputs2 = document.querySelectorAll('input[name="item_id"]');
inputs2.forEach(input => {
input.value = '';
});
});
LoadTable();
} else {
GenerateAlerts("error", response.result);
}
}, function() {
Loading(false);
GenerateAlerts("error", "Hálózati hiba!");
});
}
/* Egyéb */
function CopyData(name, value) {
const inputs = document.querySelectorAll(`input[name="${name}"]`);
inputs.forEach(input => {
input.value = value;
});
}
function EmployeeName(name) {
document.querySelector('input#employee[name="uid"]').value = name.includes(" - ") ? name.split(" - ")[1] : "";
document.querySelector('input#employee[name="name"]').value = name.includes(" - ") ? name.split(" - ")[0] : name;
}
</script>
</body>
</html>

34
error.php Normal file
View File

@ -0,0 +1,34 @@
<?php
$protocol = (!empty($_SERVER['HTTPS']) && $_SERVER['HTTPS'] !== 'off') ? "https://" : "http://";
$host = $_SERVER['HTTP_HOST'];
$currentUrl = $protocol . $host;
?>
<!DOCTYPE html>
<html lang="hu" dir="ltr">
<head>
<meta charset="utf-8">
<title>Error</title>
<link rel="stylesheet" href="<?php echo $currentUrl;?>/css/error.css">
</head>
<body>
<div id="container">
<div class="content">
<h2>HIBA</h2>
<h4>Hoppá! Az oldal nem található</h4>
<p>Az oldal amit meg szerettél volna látogatni nem létezik vagy nincsen jogod megtekinteni. Lépj vissza a oldalra.</p>
<a onclick="window.open(window.location.origin, '_self');">Vissza a oldalra</a>
</div>
</div>
<script type="text/javascript">
var container = document.getElementById('container');
window.onmousemove = function(e) {
var x = - e.clientX/5,
y = - e.clientY/5;
container.style.backgroundPositionX = x + 'px';
container.style.backgroundPositionY = y + 'px';
}
</script>
</body>
</html>

BIN
favicon.ico Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 4.2 KiB

BIN
img/CheckCircle.cur Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 4.2 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 32 MiB

BIN
img/Saturnus.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 162 KiB

676
img/Saturnus.svg Normal file

File diff suppressed because one or more lines are too long

After

Width:  |  Height:  |  Size: 1.6 MiB

BIN
img/loading.gif Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 82 KiB

BIN
img/protection.gif Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 410 KiB

BIN
img/shieldno.gif Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 242 KiB

BIN
img/shieldok.gif Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 245 KiB

BIN
img/success.gif Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 12 KiB

BIN
img/szatunalogo.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 16 KiB

398
index.php Normal file
View File

@ -0,0 +1,398 @@
<?php
setlocale(LC_COLLATE, 'hu_HU.UTF-8');
date_default_timezone_set('Europe/Budapest');
include 'managers/dbconn.php';
include 'managers/code.php';
$coderclass = new coder;
$totp = new TOTP();
ini_set('session.cookie_httponly', 1);
ini_set('session.cookie_secure', 1);
session_set_cookie_params([
'lifetime' => 0,
'path' => '/',
'domain' => $_SERVER['HTTP_HOST'],
'secure' => true,
'httponly' => true,
'samesite' => 'Strict'
]);
session_start();
$ServerLocalIP = trim(shell_exec('hostname -I | cut -d" " -f1'));
$userip = $_SERVER['REMOTE_ADDR'];
if (isset($_POST['login']) && $_POST['login'] == "islogin") {
$usr = htmlspecialchars($_POST['usr']);
$otc = htmlspecialchars($_POST['otc']);
$pass = md5(htmlspecialchars($_POST['psw']));
$anticsrf = htmlspecialchars($_POST['anticsrf']);
if ($otc == "UNSET") {
$otc = "";
}
$useragent = $_SERVER['HTTP_USER_AGENT'];
$protocol = (!empty($_SERVER['HTTPS']) && $_SERVER['HTTPS'] !== 'off') ? "https://" : "http://";
$host = $_SERVER['HTTP_HOST'];
$currentUrl = $protocol . $host;
$getagent = json_decode(file_get_contents($currentUrl."/js/bot.php?j=1&a=".urlencode($useragent)));
if ($anticsrf == $_SESSION['anticsrfid'] && $getagent->status == "ok") {
$uname = $coderclass->encode($usr, "S1TU");
$sql = mysqli_query($conn,"SELECT uid,upass,status,otphash,otptype FROM users WHERE uname = '$uname'");
$user = mysqli_fetch_array($sql);
if ($user != null && $user[2] < 1) {
echo '{"result":"A megadott fiók jelenleg nem tud bejelentkezni."}';
setcookie('auth_token', '', [ 'expires' => time() - 3600, 'path' => '/', 'domain' => $_SERVER['SERVER_NAME'], 'secure' => true, 'httponly' => true, 'samesite' => 'Strict']);
exit();
} else if ($user != null && $user[3] != "" && $otc == "" && ((!isset($_COOKIE['otpauth']) || $_COOKIE['otpauth'] != md5($user[3])) || ($user[4] == 1 || $user[4] == 3) )) {
echo '{"result":"otp"}';
setcookie('auth_token', '', [ 'expires' => time() - 3600, 'path' => '/', 'domain' => $_SERVER['SERVER_NAME'], 'secure' => true, 'httponly' => true, 'samesite' => 'Strict']);
exit();
} else if ($user[1] === $pass && $user != null) {
if ($user[3] != "") {
if ($totp->getOtp($coderclass->decode($user[3], "J57A")) == $otc || (isset($_COOKIE['otpauth']) && $_COOKIE['otpauth'] == md5($user[3]) && ($user[4] == 0 || $user[4] == 2))) {
if ($user[4] == 0 || $user[4] == 2) {
setcookie("otpauth", md5($user[3]), [
'expires' => time() + (86400 * 7),
'path' => "/",
'domain' => $_SERVER['SERVER_NAME'],
'secure' => true,
'httponly' => true,
'samesite' => 'Strict'
]);
}
echo '{"result":"ok"}';
$auth_token = $coderclass->encode($user[0], $coderclass->today_private_key());
setcookie("auth_token", $auth_token, [ 'expires' => time() + 3600, 'path' => "/", 'domain' => $_SERVER['SERVER_NAME'], 'secure' => true, 'httponly' => true, 'samesite' => 'Strict' ]);
setcookie('auth_timer', time() + 3600, ['expires' => time() + 3610, 'path' => '/', 'domain' => $_SERVER['SERVER_NAME'],'secure' => true,'httponly' => false, 'samesite' => 'Strict']);
} else {
echo '{"result":"Hibás kétlépcsős hitelesítés!"}';
setcookie('auth_token', '', [ 'expires' => time() - 3600, 'path' => '/', 'domain' => $_SERVER['SERVER_NAME'], 'secure' => true, 'httponly' => true, 'samesite' => 'Strict']);
}
} else {
echo '{"result":"ok"}';
$auth_token = $coderclass->encode($user[0], $coderclass->today_private_key());
setcookie("auth_token", $auth_token, [ 'expires' => time() + 3600, 'path' => "/", 'domain' => $_SERVER['SERVER_NAME'], 'secure' => true, 'httponly' => true, 'samesite' => 'Strict' ]);
setcookie('auth_timer', time() + 3600, ['expires' => time() + 3610, 'path' => '/', 'domain' => $_SERVER['SERVER_NAME'],'secure' => true,'httponly' => false, 'samesite' => 'Strict']);
}
exit();
} else {
echo '{"result":"A felhasználónév és a jelszó kombinációja helytelen."}';
setcookie('auth_token', '', [ 'expires' => time() - 3600, 'path' => '/', 'domain' => $_SERVER['SERVER_NAME'], 'secure' => true, 'httponly' => true, 'samesite' => 'Strict']);
exit();
}
} else {
echo '{"result":"Biztonsági titkos Token hiba! Töltse újra az oldalt."}';
setcookie('auth_token', '', [ 'expires' => time() - 3600, 'path' => '/', 'domain' => $_SERVER['SERVER_NAME'], 'secure' => true, 'httponly' => true, 'samesite' => 'Strict']);
exit();
}
} else if (!empty($_COOKIE['auth_token'] ?? '')) {
header("Location: dashboard/");
exit();
}
$anticsrfid = bin2hex(random_bytes(24));
$_SESSION["anticsrfid"] = $anticsrfid;
?>
<!DOCTYPE html>
<html lang="hu" dir="ltr">
<head>
<meta charset="utf-8">
<title>Szaturnusz</title>
<link rel="stylesheet" href="css/login.css">
<script src="js/feather-icons.js"></script>
</head>
<?php
if ($ServerLocalIP != '192.168.15.10') {
echo '<style>
:root {
--bgcolorlight: #008000;
--bgcolordark: #007a80;
}
</style>';
}
?>
<body>
<div class="otcdiv deactive" id="otcdiv">
<h1>Kétlépcsős hitelesítés</h1>
<p>Kérjük, adja meg a hitelesítő alkalmazása által generált 6 számjegyű kódot!</p>
<input type="text" id="otc" class="otc" name="otc" maxlength="6" autocomplete="off" oninput="this.value = this.value.replace(/[^0-9]/g, '');" onkeyup="checkLength(this);" onkeydown="if (event.key === 'Enter') {event.preventDefault(); document.getElementById('submit-otp').click();}">
<input type="submit" id="submit-otp" name="submit" value="Belépés" onclick="login();" disabled>
</div>
<div class="bg"></div>
<div class="protection" id="protection">
<p>Biztonsági ellenőrzés</p>
<img id="protection_img" src="img/protection.gif">
<p id="protection_text" class="result">A Javascript engedélyezése kötelező!</p>
<div class="hidden">
<img src="img/shieldok.gif">
<img src="img/shieldno.gif">
<img src="img/protection.gif">
</div>
<div class="hp">
<form id="hp">
<input type="text" placeholder="Enter Username" name="unamehp" id="unamehp">
<input type="password" placeholder="Enter Password" name="pswhp" id="pswhp">
<button type="submit">LogIn</button>
</form>
</div>
</div>
<div class="container">
<div class="login">
<div class="mobilelogin">
<h1>Szaturnusz</h1>
</div>
<div class="form">
<i class="icon"><i data-feather="user"></i></i><input type="text" id="usr" name="usr" placeholder="Felhasználónév" autocomplete="off" autocapitalize="off" spellcheck="false" autocorrect="off" onkeydown="if (event.keyCode == 13) {login()}">
<i class="icon"><i data-feather="key"></i></i><input type="password" id="psw" name="psw" placeholder="Jelszó" autocomplete="off" spellcheck="false" class="pass" autocapitalize="off" autocorrect="off" onkeydown="if (event.keyCode == 13) {login()}">
<input type="hidden" id="anticsrf" name="anticsrf" value="<?php echo $anticsrfid;?>">
<input type="submit" id="submit" name="submit" value="Belépés" onclick="login();">
</div>
<p class="errortext" id="errortext"></p>
</div>
<div class="info">
<br><br><br>
<h1>Szaturnusz</h1>
<p>Kezelőfelület</p>
<?php
if ($ServerLocalIP != '192.168.15.10') {
echo '<br><p>Teszt környezet</p>';
}
?>
</div>
<section>
<div class="wave wave1"></div>
<div class="wave wave2"></div>
<div class="wave wave3"></div>
<div class="wave wave4"></div>
</section>
</div>
<script type="text/javascript" src="js/default.js"></script>
<script type="text/javascript">
feather.replace();
const protection = document.getElementById("protection");
const protection_img = document.getElementById("protection_img");
const protection_text = document.getElementById("protection_text");
var TypingMax = 0;
var isTyping = false;
function getRandomNumber(min, max) { return Math.floor(Math.random() * (max - min + 1)) + min;}
function SimulateTypingProtector(text, elementId, isEnd) {
if (isTyping) {
setTimeout(function() {
if (isEnd) {protection_text.classList.add("result");} else {protection_text.classList.remove("result");}
protection_text.innerHTML = "";
SimulateTyping(text, elementId);
}, TypingMax);
} else {
if (isEnd) {protection_text.classList.add("result");} else {protection_text.classList.remove("result");}
protection_text.innerHTML = "";
SimulateTyping(text, elementId);
}
}
function SimulateTyping(text, elementId) {
var element = document.getElementById(elementId);
var delaymin = 20;
var delaymax = 40;
var index = 0;
TypingMax = text.length * delaymax;
isTyping = true;
var timer = setInterval(function() {
if (index < text.length) {
var char = text.charAt(index);
element.innerHTML += char;
index++;
} else {
clearInterval(timer);
element.innerHTML = text;
isTyping = false;
}
}, getRandomNumber(delaymin, delaymax));
}
function editProtectionStatus() {
BlockLogin();
}
function OpenOTP() {
BlockLogin();
}
var lastlength = 0;
function checkLength(input) {
const loginButton = document.getElementById('submit-otp');
if (input.value.length === 6) {
loginButton.disabled = false;
if (lastlength == 0) {
login();
}
} else {
loginButton.disabled = true;
}
lastlength = input.value.length;
}
var isSecure = false;
var TryedToLogin = false;
function CheckOutsideSec() {
if (!isSecure && !TryedToLogin) {
return true;
}
return false;
}
{
function editProtectionStatus(text, isEnd = false, isSuccess = false, toHide = false) {
if (isEnd && isSuccess) {
protection_img.src = "img/shieldok.gif";
if (toHide) { protection.classList.add("active"); setTimeout(function() {protection_img.src = "img/protection.gif";}, 2800); } else {protection.classList.remove("active"); }
SimulateTypingProtector("Siker! Hozzáférés megadva.", "protection_text", isEnd);
} else if (isEnd) {
protection_img.src = "img/shieldno.gif";
if (toHide) { protection.classList.add("active"); setTimeout(function() {protection_img.src = "img/protection.gif";}, 2800); } else {protection.classList.remove("active"); }
SimulateTypingProtector(text, "protection_text", isEnd);
} else {
protection_img.src = "img/protection.gif";
protection.classList.remove("active");
SimulateTypingProtector(text, "protection_text", isEnd);
}
}
editProtectionStatus("Böngésző ellenőrzése.");
function OpenOTP() {
editProtectionStatus("Kétlépcsős hitelesítés", false, false, false);
document.getElementById("otc").value = "";
document.getElementById('otcdiv').classList.remove("deactive");
lastlength = 0;
}
let isSecure = false;
let TryedToLogin = false;
function BlockLogin() {
isSecure = false;
TryedToLogin = true;
}
function ProtectionChek() {
let userAgent = navigator.userAgent;
let userAgentLower = userAgent.toLowerCase();
if (
userAgentLower.indexOf('/') === -1 ||
!/\d/.test(userAgentLower) ||
userAgentLower.trim().split(/\s+/).length === 1 ||
userAgentLower.includes('bot') ||
userAgentLower.includes('http')
) {
editProtectionStatus("BOT detektálva! Hozzáférés megtagadva!", true);
} else {
get_POST_information("js/bot.php?j=1", '', function(text) {
let response = JSON.parse(text);
if (response.status == "ok") {
editProtectionStatus("", true, true, true);
isSecure = true;
} else {
editProtectionStatus("BOT detektálva! Hozzáférés megtagadva!", true);
}
}, function() {
document.getElementById("errortext").innerHTML = "Hálózati hiba. Próbálja újra.";
editProtectionStatus("Hálózati hiba. Próbálja újra.", true, false, true);
setTimeout(function() {protection_img.src = "img/protection.gif";}, 2800);
});
}
}
setTimeout(ProtectionChek(), getRandomNumber(3000, 5000));
document.getElementById("hp").addEventListener("submit", function(event) {
event.preventDefault();
TryedToLogin = true;
editProtectionStatus("Jogtalan bejelentkezési kísérlet!", true);
});
function login() {
document.getElementById('otcdiv').classList.add("deactive");
if (isSecure && !TryedToLogin && CheckOutsideSec()) {
editProtectionStatus("Bejelentkezés folyamat.");
setTimeout(function () {
var usr = encodeURIComponent(document.getElementById("usr").value).replace(/%20/g, '+');
var psw = encodeURIComponent(document.getElementById("psw").value).replace(/%20/g, '+');
var anticsrf = encodeURIComponent(document.getElementById("anticsrf").value).replace(/%20/g, '+');
var otp = encodeURIComponent(document.getElementById("otc").value).replace(/%20/g, '+');
const body = 'login=islogin&anticsrf=' + anticsrf + '&psw=' + psw + '&usr=' + usr + '&otc=' + otp;
get_POST_information("index.php", body, function(text) {
document.getElementById("otc").value = "";
let response = JSON.parse(text);
if (response.result == "ok") {
editProtectionStatus("A bejelentkezés sikeres!", true, true, false);
setTimeout(function() {
if (<?php echo ($_GET['noredirect'] ?? '0') === '1' ? 'false' : 'true'; ?>) {
window.location.href = '<?php
$protocol = (!empty($_SERVER['HTTPS']) && $_SERVER['HTTPS'] !== 'off') ? "https://" : "http://";
$host = $_SERVER['HTTP_HOST'];
$currentUrl = $protocol . $host;
$current_domain = $_SERVER['HTTP_HOST'];
if (isset($_SERVER['HTTP_REFERER'])) {
$referer = $_SERVER['HTTP_REFERER'];
$referer_host = parse_url($referer, PHP_URL_HOST);
$referer_path = parse_url($referer, PHP_URL_PATH);
if ($referer_host === $current_domain && strpos($referer_path, 'profile') === false) {
echo str_replace($currentUrl, "", $referer);
} else {echo 'dashboard/';}
} else {echo 'dashboard/';}
?>';
}
}, 2500);
} else if (response.result == "otp") {
OpenOTP();
} else {
document.getElementById("errortext").innerHTML = response.result;
editProtectionStatus(response.result, true, false, true);
setTimeout(function() {protection_img.src = "img/protection.gif";}, 2800);
}
}, function() {
document.getElementById("errortext").innerHTML = "Hálózati hiba. Próbálja újra.";
editProtectionStatus("Hálózati hiba. Próbálja újra.", true, false, true);
setTimeout(function() {protection_img.src = "img/protection.gif";}, 2800);
});
}, getRandomNumber(1000, 3000));
} else {
TryedToLogin = true;
editProtectionStatus("Jogtalan bejelentkezési kísérlet!", true);
}
}
}
</script>
</body>
</html>

49
js/bot.php Normal file
View File

@ -0,0 +1,49 @@
<?php
header('Access-Control-Allow-Origin: *');
$testagent = isset($_GET['a']) ? $_GET['a'] : '#404?$';
$json = isset($_GET['j']) ? $_GET['j'] : '0';
$sleep = isset($_GET['s']) ? $_GET['s'] : '0';
if ($json == '1') {
header('Content-Type: application/json');
}
if ($testagent == "#404?$") {
$testagent = $_SERVER['HTTP_USER_AGENT'];
}
if (ellenorzes($testagent)) {
if ($json == '1') {
echo json_encode(["status" => "no", "agent" => htmlspecialchars($testagent)]);
} else {
echo "no";
}
} else {
if ($json == '1') {
echo json_encode(["status" => "ok", "agent" => htmlspecialchars($testagent)]);
} else {
echo "ok";
}
}
function ellenorzes($string) {
if ($string == null || $string == "") {
return true;
}
$botslist = file_get_contents('user-agents_bot-crawler.txt');
$botarray = explode("\n", $botslist);
for ($i=0; $i < count($botarray); $i++) {
if (strpos($botarray[$i], $string) !== false) {
return true;
}
}
return false;
}
sleep($sleep);
?>

723
js/bug_report.js Normal file
View File

@ -0,0 +1,723 @@
// Bug Report System - JavaScript rész
(function() {
const logs = [];
const origLog = console.log;
const origError = console.error;
const origWarn = console.warn;
console.log = function(...args) {
logs.push('[LOG] ' + args.join(' '));
origLog.apply(console, args);
};
console.error = function(...args) {
logs.push('[ERROR] ' + args.join(' '));
origError.apply(console, args);
};
console.warn = function(...args) {
logs.push('[WARN] ' + args.join(' '));
origWarn.apply(console, args);
};
const origXHROpen = XMLHttpRequest.prototype.open;
const origXHRSend = XMLHttpRequest.prototype.send;
XMLHttpRequest.prototype.open = function(method, url, async, user, password) {
this._method = method;
this._url = url;
return origXHROpen.apply(this, arguments);
};
XMLHttpRequest.prototype.send = function(data) {
const startTime = Date.now();
this._sendData = data;
this.addEventListener('load', function() {
const duration = Date.now() - startTime;
logs.push(`[NETWORK] ${this._method} ${this._url} - Status: ${this.status} (${duration}ms)`);
});
this.addEventListener('error', function() {
const duration = Date.now() - startTime;
let errorLog = `[NET ERROR] ${this._method} ${this._url} - Failed (${duration}ms)`;
if (this._sendData && (this._method === 'POST' || this._method === 'PUT' || this._method === 'PATCH')) {
let postData = 'Unknown';
try {
if (typeof this._sendData === 'string') {
postData = this._sendData;
} else if (this._sendData instanceof FormData) {
postData = 'FormData';
const formDataEntries = [];
for (let [key, value] of this._sendData.entries()) {
formDataEntries.push(`${key}=${value}`);
}
if (formDataEntries.length > 0) {
postData = formDataEntries.join('&');
}
} else {
postData = JSON.stringify(this._sendData);
}
} catch (e) {
postData = '[Cannot serialize data]';
}
errorLog += ` - POST Data: ${postData}`;
}
logs.push(errorLog);
});
this.addEventListener('timeout', function() {
const duration = Date.now() - startTime;
let timeoutLog = `[NET ERROR] ${this._method} ${this._url} - Timeout (${duration}ms)`;
if (this._sendData && (this._method === 'POST' || this._method === 'PUT' || this._method === 'PATCH')) {
let postData = 'Unknown';
try {
if (typeof this._sendData === 'string') {
postData = this._sendData;
} else if (this._sendData instanceof FormData) {
postData = 'FormData';
const formDataEntries = [];
for (let [key, value] of this._sendData.entries()) {
formDataEntries.push(`${key}=${value}`);
}
if (formDataEntries.length > 0) {
postData = formDataEntries.join('&');
}
} else {
postData = JSON.stringify(this._sendData);
}
} catch (e) {
postData = '[Cannot serialize data]';
}
timeoutLog += ` - POST Data: ${postData}`;
}
logs.push(timeoutLog);
});
return origXHRSend.apply(this, arguments);
};
window.addEventListener('unhandledrejection', event => {
logs.push('[UNHANDLED PROMISE REJECTION] ' + (event.reason?.message || event.reason));
});
window.onerror = function(message, source, lineno, colno, error) {
logs.push(`[GLOBAL ERROR] ${message} at ${source}:${lineno}:${colno}`);
};
window.addEventListener('error', event => {
if (event.target && (event.target.src || event.target.href)) {
logs.push(`[RESOURCE LOAD ERROR] ${event.target.tagName} on ${event.target.src || event.target.href}`);
}
}, true);
window.addEventListener('online', () => {
logs.push('[NETWORK STATUS] Back online');
});
window.addEventListener('offline', () => {
logs.push('[NETWORK STATUS] Offline');
});
const origFetch = window.fetch;
window.fetch = function(input, init) {
const startTime = Date.now();
const url = typeof input === 'string' ? input : input.url;
const method = (init && init.method) || 'GET';
const requestBody = init && init.body;
return origFetch.apply(this, arguments)
.then(response => {
const duration = Date.now() - startTime;
logs.push(`[NETWORK] ${method} ${url} - Status: ${response.status} (${duration}ms)`);
return response;
})
.catch(error => {
const duration = Date.now() - startTime;
let errorLog = `[NET ERROR] ${method} ${url} - ${error.message} (${duration}ms)`;
if (requestBody && (method === 'POST' || method === 'PUT' || method === 'PATCH')) {
let postData = 'Unknown';
try {
if (typeof requestBody === 'string') {
postData = requestBody;
} else if (requestBody instanceof FormData) {
postData = 'FormData';
const formDataEntries = [];
for (let [key, value] of requestBody.entries()) {
formDataEntries.push(`${key}=${value}`);
}
if (formDataEntries.length > 0) {
postData = formDataEntries.join('&');
}
} else {
postData = JSON.stringify(requestBody);
}
} catch (e) {
postData = '[Cannot serialize data]';
}
errorLog += ` - POST Data: ${postData}`;
}
logs.push(errorLog);
throw error;
});
};
const bugBtn = document.createElement('button');
bugBtn.innerHTML = 'Hibabejelentés 🐛';
Object.assign(bugBtn.style, {
position: 'fixed',
bottom: '30px',
left: '-97px',
zIndex: '99999',
backgroundColor: '#e74c3c',
color: 'white',
border: 'none',
borderRadius: '0px 8px 8px 0px',
cursor: 'pointer',
fontSize: '12px',
fontWeight: 'bold',
transition: 'all 0.3s ease',
width: '130px',
padding: '5px 10px',
overflow: 'hidden',
opacity: '1'
});
bugBtn.onmouseenter = () => {
bugBtn.style.left = '0px';
};
bugBtn.onmouseleave = () => {
bugBtn.style.left = '-97px';
};
document.body.appendChild(bugBtn);
bugBtn.onclick = async () => {
bugBtn.textContent = 'Küldés...';
bugBtn.disabled = true;
try {
let screenshotData = null;
let screenshotDataFull = null;
if (typeof html2canvas !== 'undefined') {
try {
const links = document.querySelectorAll('link[rel="stylesheet"]');
const filterPromises = Array.from(links).map(link => {
const href = link.href;
return fetch(href)
.then(r => r.text())
.then(css => {
css = css.replace(/color\s*\([^)]*\)/gi, '#000000');
css = css.replace(/color-mix\s*\([^()]*(?:\([^()]*\)[^()]*)*\)/gi, '#808080');
return css;
})
.catch(() => null);
});
const cssArrays = await Promise.all(filterPromises);
const combinedCss = cssArrays.filter(c => c).join('\n');
const filterUnsupported = (clonedDoc) => {
const clonedLinks = clonedDoc.querySelectorAll('link[rel="stylesheet"]');
clonedLinks.forEach(link => link.remove());
if (combinedCss) {
const style = clonedDoc.createElement('style');
style.textContent = combinedCss;
clonedDoc.head.appendChild(style);
}
clonedDoc.querySelectorAll('[style]').forEach(el => {
const style = el.getAttribute('style');
let newStyle = style;
newStyle = newStyle.replace(/color\s*\([^)]*\)/gi, '#000000');
newStyle = newStyle.replace(/color-mix\s*\([^()]*(?:\([^()]*\)[^()]*)*\)/gi, '#808080');
el.setAttribute('style', newStyle);
});
clonedDoc.querySelectorAll('style').forEach(styleEl => {
let css = styleEl.textContent;
css = css.replace(/color\s*\([^)]*\)/gi, '#000000');
css = css.replace(/color-mix\s*\([^()]*(?:\([^()]*\)[^()]*)*\)/gi, '#808080');
styleEl.textContent = css;
});
};
const canvas = await html2canvas(document.body, {
scale: window.devicePixelRatio || 1,
onclone: filterUnsupported
});
const canvasFull = await html2canvas(document.body, {
scrollX: 0,
scrollY: 0,
width: document.documentElement.scrollWidth,
height: document.documentElement.scrollHeight,
scale: window.devicePixelRatio || 1,
onclone: filterUnsupported
});
screenshotData = canvas.toDataURL('image/png');
screenshotDataFull = canvasFull.toDataURL('image/png');
} catch (e) {
console.error('Screenshot hiba:', e);
}
}
SendReport(screenshotData, screenshotDataFull);
} catch (error) {
console.error('Bug report küldési hiba:', error);
GenerateAlerts('error', 'Hiba történt a bejelentés küldése során.');
}
};
let currentImageMode = 'viewport';
let drawMode = 'pen';
let isDrawing = false;
let lastX = 0;
let lastY = 0;
let startX = 0;
let startY = 0;
let paintCanvas, paintCtx;
let baseImageViewport = new Image();
let baseImageFull = new Image();
let currentScreenshotData, currentScreenshotDataFull, currentText;
let savedImageData = null;
window.switchImage = function() {
currentImageMode = document.getElementById('BUGREPORT_imageSelector').value;
setupCanvas();
};
window.setDrawMode = function(mode) {
drawMode = mode;
document.getElementById('BUGREPORT_penBtn').style.background = mode === 'pen' ? '#c0392b' : '#e74c3c';
document.getElementById('BUGREPORT_rectBtn').style.background = mode === 'rect' ? '#2980b9' : '#3498db';
document.getElementById('BUGREPORT_textBtn').style.background = mode === 'text' ? '#d68910' : '#f39c12';
if (mode === 'text') {
paintCanvas.style.cursor = 'text';
} else {
paintCanvas.style.cursor = 'crosshair';
}
};
window.clearCanvas = function() {
setupCanvas();
};
window.skipPainting = function() {
const alertElement = document.querySelector('.custom-alert');
if (alertElement) {
alertElement.remove();
}
SendReport(currentScreenshotData, currentScreenshotDataFull, currentText, 'skipped');
};
window.savePaintedImage = function() {
const paintedImageData = paintCanvas.toDataURL('image/png');
const alertElement = document.querySelector('.custom-alert');
if (alertElement) {
alertElement.remove();
}
SendReport(currentScreenshotData, currentScreenshotDataFull, currentText, paintedImageData);
};
function setupCanvas() {
const img = currentImageMode === 'viewport' ? baseImageViewport : baseImageFull;
const maxWidth = window.innerWidth * 0.8;
const maxHeight = window.innerHeight * 0.6;
let displayWidth = img.naturalWidth;
let displayHeight = img.naturalHeight;
if (displayWidth > maxWidth) {
displayHeight = (displayHeight * maxWidth) / displayWidth;
displayWidth = maxWidth;
}
if (displayHeight > maxHeight) {
displayWidth = (displayWidth * maxHeight) / displayHeight;
displayHeight = maxHeight;
}
paintCanvas.width = displayWidth;
paintCanvas.height = displayHeight;
paintCtx.clearRect(0, 0, paintCanvas.width, paintCanvas.height);
paintCtx.drawImage(img, 0, 0, paintCanvas.width, paintCanvas.height);
}
function GetMouseX(e, canvas) {
const rect = paintCanvas.getBoundingClientRect();
return ((e.clientX - rect.left) * canvas.width) / rect.width;
}
function GetMouseY(e, canvas) {
const rect = paintCanvas.getBoundingClientRect();
return ((e.clientY - rect.top) * canvas.height) / rect.height;
}
function startDraw(e) {
if (drawMode === 'text') return;
isDrawing = true;
lastX = startX = GetMouseX(e, paintCanvas);
lastY = startY = GetMouseY(e, paintCanvas);
}
function draw(e) {
if (!isDrawing || drawMode === 'text') return;
const currentX = GetMouseX(e, paintCanvas);
const currentY = GetMouseY(e, paintCanvas);
paintCtx.strokeStyle = '#e74c3c';
paintCtx.lineWidth = 3;
paintCtx.lineCap = 'round';
if (drawMode === 'pen') {
paintCtx.beginPath();
paintCtx.moveTo(lastX, lastY);
paintCtx.lineTo(currentX, currentY);
paintCtx.stroke();
lastX = currentX;
lastY = currentY;
}
}
function stopDraw(e) {
if (!isDrawing) return;
isDrawing = false;
if (drawMode === 'rect') {
const endX = GetMouseX(e, paintCanvas);
const endY = GetMouseY(e, paintCanvas);
paintCtx.strokeStyle = '#e74c3c';
paintCtx.lineWidth = 3;
paintCtx.strokeRect(startX, startY, endX - startX, endY - startY);
}
}
function handleClick(e) {
if (drawMode !== 'text') return;
const x = GetMouseX(e, paintCanvas);
const y = GetMouseY(e, paintCanvas);
const text = prompt('Írja be a szöveget:');
if (text) {
paintCtx.fillStyle = '#e74c3c';
paintCtx.font = '16px Arial';
paintCtx.fillText(text, x, y);
}
}
function initializePaintCanvas() {
paintCanvas = document.getElementById('BUGREPORT_paintCanvas');
paintCtx = paintCanvas.getContext('2d');
paintCanvas.addEventListener('mousedown', startDraw);
paintCanvas.addEventListener('mousemove', draw);
paintCanvas.addEventListener('mouseup', stopDraw);
paintCanvas.addEventListener('click', handleClick);
baseImageViewport.onload = () => {
setupCanvas();
};
if (baseImageFull.complete || baseImageFull.naturalWidth > 0) {
setupCanvas();
} else {
baseImageFull.onload = () => {
if (currentImageMode === 'full') {
setupCanvas();
}
};
}
}
function BrowserData() {
const data = [];
// Document
[
{ k: 'URL', v: () => document.URL },
{ k: 'referrer', v: () => document.referrer },
{ k: 'characterSet', v: () => document.characterSet },
{ k: 'contentType', v: () => document.contentType },
{ k: 'visibilityState', v: () => document.visibilityState },
{ k: 'title', v: () => document.title },
{ k: 'domain', v: () => document.domain },
{ k: 'lastModified', v: () => document.lastModified },
{ k: 'readyState', v: () => document.readyState },
{ k: 'compatMode', v: () => document.compatMode },
{ k: 'dir', v: () => document.dir },
{ k: 'fullscreenEnabled', v: () => document.fullscreenEnabled },
{ k: 'hidden', v: () => document.hidden },
{ k: 'documentElement.lang', v: () => document.documentElement.lang }
].forEach(o => data.push(`document.${o.k} paraméter értéke: ${o.v()}`));
// Location
[
'href','protocol','host','hostname','port','pathname','search','hash','origin'
].forEach(p => data.push(`location.${p} paraméter értéke: ${location[p]}`));
if (location.ancestorOrigins) data.push(`location.ancestorOrigins paraméter értéke: ${[...location.ancestorOrigins].join(', ')}`);
// Navigator alap és kiterjesztett
[
'userAgent','platform','language','languages','onLine','maxTouchPoints','hardwareConcurrency','deviceMemory',
'cookieEnabled','doNotTrack','appCodeName','appName','appVersion','product','productSub','vendor','vendorSub',
'buildID','oscpu','appMinorVersion','pdfViewerEnabled','webdriver'
].forEach(p => {
const v = navigator[p];
if (v!==undefined) data.push(`navigator.${p} paraméter értéke: ${Array.isArray(v)?v.join(', '):v}`);
});
if (navigator.javaEnabled) data.push(`navigator.javaEnabled() paraméter értéke: ${navigator.javaEnabled()}`);
// Navigator.connection
if (navigator.connection) {
['type','downlink','rtt','effectiveType','saveData']
.forEach(k => data.push(`connection.${k} paraméter értéke: ${navigator.connection[k]}`));
}
// Navigator.userAgentData (Chrome)
if (navigator.userAgentData) {
data.push(`userAgentData.mobile paraméter értéke: ${navigator.userAgentData.mobile}`);
data.push(`userAgentData.brands paraméter értéke: ${navigator.userAgentData.brands.map(b=>b.brand+'('+b.version+')').join(', ')}`);
}
// Plugins & mimeTypes
if (navigator.plugins) data.push(`plugins paraméter értéke: ${Array.from(navigator.plugins).map(p=>p.name).join(', ')}`);
if (navigator.mimeTypes) data.push(`mimeTypes paraméter értéke: ${Array.from(navigator.mimeTypes).map(m=>m.type).join(', ')}`);
// Window & screen
[
'innerWidth','innerHeight','outerWidth','outerHeight','devicePixelRatio',
'scrollX','scrollY','name','length','screenLeft','screenTop'
].forEach(p => data.push(`window.${p} paraméter értéke: ${window[p]}`));
[
'width','height','availWidth','availHeight','colorDepth','pixelDepth',
'availLeft','availTop','isExtended'
].forEach(p => data.push(`screen.${p} paraméter értéke: ${screen[p]}`));
if (screen.orientation) {
data.push(`screen.orientation.type paraméter értéke: ${screen.orientation.type}`);
data.push(`screen.orientation.angle paraméter értéke: ${screen.orientation.angle}`);
}
// History
data.push(`history.length paraméter értéke: ${history.length}`);
data.push(`history.state paraméter értéke: ${JSON.stringify(history.state)}`);
// Timezone & Intl
try {
const intl = Intl.DateTimeFormat().resolvedOptions();
data.push(`timezone paraméter értéke: ${intl.timeZone}`);
data.push(`Intl.locale paraméter értéke: ${intl.locale}`);
data.push(`Intl.calendar paraméter értéke: ${intl.calendar}`);
data.push(`Intl.numberingSystem paraméter értéke: ${intl.numberingSystem}`);
} catch {}
// Performance
if (performance) {
['timeOrigin'].forEach(p => data.push(`performance.${p} paraméter értéke: ${performance[p]}`));
if (performance.navigation) ['type','redirectCount'].forEach(p=>data.push(`performance.navigation.${p} paraméter értéke: ${performance.navigation[p]}`));
if (performance.memory) ['totalJSHeapSize','usedJSHeapSize','jsHeapSizeLimit'].forEach(p=>data.push(`performance.memory.${p} paraméter értéke: ${performance.memory[p]}`));
data.push(`performance.getEntries().length paraméter értéke: ${performance.getEntries().length}`);
if (performance.timing) {
data.push(`performance.timing.loadEventEnd paraméter értéke: ${performance.timing.loadEventEnd}`);
data.push(`performance.timing.domContentLoadedEventEnd paraméter értéke: ${performance.timing.domContentLoadedEventEnd}`);
}
data.push(`performance.now() paraméter értéke: ${performance.now()}`);
}
// Storage & cookies
data.push(`document.cookie.length paraméter értéke: ${document.cookie.length}`);
try { data.push(`localStorage.length paraméter értéke: ${localStorage.length}`); } catch {}
try { data.push(`sessionStorage.length paraméter értéke: ${sessionStorage.length}`); } catch {}
data.push(`indexedDB elérhető: ${'indexedDB' in window}`);
data.push(`caches elérhető: ${'caches' in window}`);
// Battery
if (navigator.getBattery) {
navigator.getBattery().then(b=>{
['charging','level','chargingTime','dischargingTime']
.forEach(p=>data.push(`battery.${p} paraméter értéke: ${b[p]}`));
});
}
// Crypto
data.push(`crypto elérhető: ${'crypto' in window}`);
data.push(`crypto.subtle elérhető: ${!!(crypto && crypto.subtle)}`);
data.push(`crypto.randomUUID elérhető: ${typeof crypto.randomUUID === 'function'}`);
data.push(`crypto.getRandomValues elérhető: ${typeof crypto.getRandomValues === 'function'}`);
// Geolocation, clipboard, permissions, mediaDevices, usb, serial, bluetooth, xr, serviceWorker, sendBeacon, vibrate
[
'geolocation','clipboard','permissions','mediaDevices','usb','serial','bluetooth','xr','serviceWorker','sendBeacon','vibrate','keyboard','mediaCapabilities'
].forEach(api => data.push(`${api} elérhető: ${api in navigator || api in window}`));
// Permissions lekérés (state)
if (navigator.permissions) {
['geolocation','notifications','microphone','camera','clipboard-read','clipboard-write'].forEach(name => {
navigator.permissions.query({name}).then(res => {
data.push(`permissions.${name} paraméter értéke: ${res.state}`);
}).catch(()=>{});
});
}
// CSS / vizuális adatok
try {
data.push(`getComputedStyle(document.body).fontFamily paraméter értéke: ${getComputedStyle(document.body).fontFamily}`);
} catch {}
data.push(`matchMedia("(prefers-color-scheme: dark)").matches paraméter értéke: ${matchMedia("(prefers-color-scheme: dark)").matches}`);
// Dátum/idő
data.push(`Date.now() paraméter értéke: ${Date.now()}`);
data.push(`new Date().getTimezoneOffset() paraméter értéke: ${new Date().getTimezoneOffset()}`);
// Feature detect / Events
data.push(`draggable támogatás: ${'draggable' in document.createElement('span')}`);
data.push(`pointerEvents támogatás: ${'onpointerdown' in window}`);
data.push(`touchEvent támogatás: ${'ontouchstart' in window}`);
data.push(`fullscreen API: ${'fullscreenEnabled' in document}`);
data.push(`visibility API: ${typeof document.hidden !== 'undefined'}`);
return data;
}
function SendReport(screenshotData, screenshotDataFull, text = "%DefaultText%", paintedImage = null) {
if (text == "%DefaultText%") {
var html = `
<p><strong>Kérjük, írja le a hibát amit tapasztal minél pontosabban.</strong></p>
<textarea id="BUGREPORT_bugDescription" style="width: calc(100% - 20px); height: 150px; margin: 10px 0; padding: 10px; border: 1px solid #ccc; border-radius: 4px;" placeholder="Írja le itt a problémát..."></textarea>
<br clear="all"><br>
<button id="BUGREPORT_AlertBtnNo" style="float: right; margin-left: 15px; width: 80;">Mégsem</button>
<button id="BUGREPORT_AlertBtnYes" style="float: right; width: 60px; background: var(--panelcolor); color: #f5f5f5; border: unset;">Tovább</button>
`;
const overlay = CreateAlertBox('Hibabejelentés', html, false);
document.getElementById('BUGREPORT_AlertBtnYes').onclick = function () {
var reporttext = document.getElementById("BUGREPORT_bugDescription").value;
if (reporttext == "") {
html = `<p><b>Kérjük írja le mi történt!</b></p>`;
CreateAlertBox("Figyelem", html);
return;
}
SendReport(screenshotData, screenshotDataFull, reporttext);
CloseAlertBox(overlay);
};
document.getElementById('BUGREPORT_AlertBtnNo').onclick = function () {
CloseAlertBox(overlay);
bugBtn.textContent = 'Hibabejelentés 🐛';
bugBtn.disabled = false;
};
} else if (paintedImage === null && screenshotData != null) {
currentScreenshotData = screenshotData;
currentScreenshotDataFull = screenshotDataFull;
currentText = text;
baseImageViewport.src = screenshotData;
baseImageFull.src = screenshotDataFull;
var paintHtml = `
<p>Jelölje be a problémás területeket a képernyőn.</p>
<div style="margin: 10px 0;">
<label>Kép választása:</label>
<select id="BUGREPORT_imageSelector" onchange="switchImage()" style="margin-left: 10px; padding: 5px;">
<option value="viewport">Jelenlegi nézet</option>
<option value="full">Teljes oldal</option>
</select>
</div>
<div style="margin: 10px 0;">
<button onclick="setDrawMode('pen')" id="BUGREPORT_penBtn" style="padding: 8px 15px; margin: 5px; background: #e74c3c; color: white; border: none; border-radius: 4px; cursor: pointer;">Ceruza</button>
<button onclick="setDrawMode('rect')" id="BUGREPORT_rectBtn" style="padding: 8px 15px; margin: 5px; background: #3498db; color: white; border: none; border-radius: 4px; cursor: pointer;">Négyzet</button>
<button onclick="setDrawMode('text')" id="BUGREPORT_textBtn" style="padding: 8px 15px; margin: 5px; background: #f39c12; color: white; border: none; border-radius: 4px; cursor: pointer;">Szöveg</button>
<button onclick="clearCanvas()" style="padding: 8px 15px; margin: 5px; background: #95a5a6; color: white; border: none; border-radius: 4px; cursor: pointer;">Törlés</button>
</div>
<div style="border: 1px solid #ccc; margin: 10px 0; position: relative; overflow: auto; max-height: 60vh;">
<canvas id="BUGREPORT_paintCanvas" style="cursor: crosshair; display: block; max-width: 100%;"></canvas>
</div>
<br clear="all"><br>
<button id="BUGREPORT_AlertBtnNoPaint" style="float: right; margin-left: 15px; width: 80;">Kihagyás</button>
<button id="BUGREPORT_AlertBtnYesPaint" style="float: right; width: 60px; background: var(--panelcolor); color: #f5f5f5; border: unset;">Mentés</button>
<br clear="all">
`;
const overlay = CreateAlertBox('Hiba megjelölése (opcionális)', paintHtml, false);
document.getElementById('BUGREPORT_AlertBtnYesPaint').onclick = function () {
savePaintedImage();
CloseAlertBox(overlay);
bugBtn.textContent = 'Hibabejelentés 🐛';
bugBtn.disabled = false;
};
document.getElementById('BUGREPORT_AlertBtnNoPaint').onclick = function () {
skipPainting();
CloseAlertBox(overlay);
bugBtn.textContent = 'Hibabejelentés 🐛';
bugBtn.disabled = false;
};
setTimeout(() => {
initializePaintCanvas();
}, 100);
} else {
bugBtn.textContent = 'Küldés...';
bugBtn.disabled = true;
const reportData = {
userAgent: navigator.userAgent,
url: window.location.href,
timestamp: new Date().toISOString(),
viewport: {
width: window.innerWidth,
height: window.innerHeight
},
screen: {
width: screen.width,
height: screen.height
},
logs: logs,
description: text,
browserData: BrowserData(),
screenshot: screenshotData,
screenshotFull: screenshotDataFull,
screenshotPainted: paintedImage !== 'skipped' ? paintedImage : null
};
fetch('/managers/bug_report_handler.php', {
method: 'POST',
headers: {
'Content-Type': 'application/json',
},
body: JSON.stringify(reportData)
})
.then(response => response.json())
.then(result => {
if (result.success) {
GenerateAlerts('success', 'Hibabejelentés sikeresen elküldve! Köszönjük a visszajelzést.');
} else {
GenerateAlerts('error', 'Hiba történt a küldés során: ' + (result.error || 'Ismeretlen hiba'));
}
})
.catch(error => {
console.error('Bug report küldési hiba:', error);
GenerateAlerts('error', 'Hiba történt a bejelentés küldése során.');
})
.finally(() => {
bugBtn.textContent = 'Hibabejelentés 🐛';
bugBtn.disabled = false;
});
}
}
})();
function loadScript(url, callback) {
const script = document.createElement('script');
script.src = url;
script.onload = () => callback && callback();
document.head.appendChild(script);
}
loadScript('https://szaturnusz.szatuna.hu/js/html2canvas.min.js', () => {});

848
js/default.js Normal file
View File

@ -0,0 +1,848 @@
/*!
* @license kjokmjnoi API
* Website: https://api.kjokmjnoi.hu
* Ver: 1.0.4
*/
/* Link funkciók */
function get_information(link, callback) {
var xhr = new XMLHttpRequest();
xhr.open("GET", link, true);
xhr.onreadystatechange = function() {
if (xhr.status == 200) {
if (xhr.responseText.startsWith('|$6b4ea69e17243db95f7b46c384d40370$|!<script type="text/javascript">window.location=')) {
var url = xhr.responseText.split('window.location="')[1];
url = url.split('";</script>')[0];
window.location= url;
} else {
callback(xhr.responseText);
}
} else {
errorCallback();
}
};
xhr.send(null);
}
function get_POST_information(link, jsonBody, callback, errorCallback) {
var xhr = new XMLHttpRequest();
xhr.open("POST", link);
xhr.setRequestHeader("Content-Type", "application/x-www-form-urlencoded");
xhr.onreadystatechange = function() {
if (xhr.readyState == 4) {
if (xhr.status == 200) {
if (xhr.responseText.startsWith('|$6b4ea69e17243db95f7b46c384d40370$|!<script type="text/javascript">window.location=')) {
var url = xhr.responseText.split('window.location="')[1];
url = url.split('";</script>')[0];
window.location= url;
} else {
callback(xhr.responseText);
}
} else {
errorCallback();
}
}
};
xhr.send(jsonBody);
}
/* Kódolók */
function htmlspecialchar(text) {
return text.replace(/&/g, "&amp;").replace(/>/g, "&gt;").replace(/</g, "&lt;").replace(/"/g, "&quot;");
}
function htmlEncode(s) {
return s.replace(' ', '%20')
.replace('/', '%2F')
.replace('!', '%21')
.replace('"', '%22')
.replace('#', '%23')
.replace('$', '%24')
.replace('%', '%25')
.replace('&', '%26')
.replace("'", "%27")
.replace('.', '%2E')
.replace(',', '%2C')
.replace('+', '%2B')
.replace('*', '%2A')
.replace(';', '%3B')
.replace('?', '%3F')
.replace('@', '%40')
.replace(':', '%3A');
}
var sha256 = function sha256(ascii) {
function rightRotate(value, amount) {
return (value>>>amount) | (value<<(32 - amount));
};
var mathPow = Math.pow;
var maxWord = mathPow(2, 32);
var lengthProperty = 'length'
var i, j;
var result = ''
var words = [];
var asciiBitLength = ascii[lengthProperty]*8;
var hash = sha256.h = sha256.h || [];
var k = sha256.k = sha256.k || [];
var primeCounter = k[lengthProperty];
var isComposite = {};
for (var candidate = 2; primeCounter < 64; candidate++) {
if (!isComposite[candidate]) {
for (i = 0; i < 313; i += candidate) {
isComposite[i] = candidate;
}
hash[primeCounter] = (mathPow(candidate, .5)*maxWord)|0;
k[primeCounter++] = (mathPow(candidate, 1/3)*maxWord)|0;
}
}
ascii += '\x80'
while (ascii[lengthProperty]%64 - 56) ascii += '\x00'
for (i = 0; i < ascii[lengthProperty]; i++) {
j = ascii.charCodeAt(i);
if (j>>8) return;
words[i>>2] |= j << ((3 - i)%4)*8;
}
words[words[lengthProperty]] = ((asciiBitLength/maxWord)|0);
words[words[lengthProperty]] = (asciiBitLength)
for (j = 0; j < words[lengthProperty];) {
var w = words.slice(j, j += 16);
var oldHash = hash;
hash = hash.slice(0, 8);
for (i = 0; i < 64; i++) {
var i2 = i + j;
var w15 = w[i - 15], w2 = w[i - 2];
var a = hash[0], e = hash[4];
var temp1 = hash[7]
+ (rightRotate(e, 6) ^ rightRotate(e, 11) ^ rightRotate(e, 25))
+ ((e&hash[5])^((~e)&hash[6]))
+ k[i]
+ (w[i] = (i < 16) ? w[i] : (
w[i - 16]
+ (rightRotate(w15, 7) ^ rightRotate(w15, 18) ^ (w15>>>3))
+ w[i - 7]
+ (rightRotate(w2, 17) ^ rightRotate(w2, 19) ^ (w2>>>10))
)|0
);
var temp2 = (rightRotate(a, 2) ^ rightRotate(a, 13) ^ rightRotate(a, 22))
+ ((a&hash[1])^(a&hash[2])^(hash[1]&hash[2]));
hash = [(temp1 + temp2)|0].concat(hash);
hash[4] = (hash[4] + temp1)|0;
}
for (i = 0; i < 8; i++) {
hash[i] = (hash[i] + oldHash[i])|0;
}
}
for (i = 0; i < 8; i++) {
for (j = 3; j + 1; j--) {
var b = (hash[i]>>(j*8))&255;
result += ((b < 16) ? 0 : '') + b.toString(16);
}
}
return result;
};
var MD5 = function (string) {
function RotateLeft(lValue, iShiftBits) {
return (lValue<<iShiftBits) | (lValue>>>(32-iShiftBits));
}
function AddUnsigned(lX,lY) {
var lX4,lY4,lX8,lY8,lResult;
lX8 = (lX & 0x80000000);
lY8 = (lY & 0x80000000);
lX4 = (lX & 0x40000000);
lY4 = (lY & 0x40000000);
lResult = (lX & 0x3FFFFFFF)+(lY & 0x3FFFFFFF);
if (lX4 & lY4) {
return (lResult ^ 0x80000000 ^ lX8 ^ lY8);
}
if (lX4 | lY4) {
if (lResult & 0x40000000) {
return (lResult ^ 0xC0000000 ^ lX8 ^ lY8);
} else {
return (lResult ^ 0x40000000 ^ lX8 ^ lY8);
}
} else {
return (lResult ^ lX8 ^ lY8);
}
}
function F(x,y,z) { return (x & y) | ((~x) & z); }
function G(x,y,z) { return (x & z) | (y & (~z)); }
function H(x,y,z) { return (x ^ y ^ z); }
function I(x,y,z) { return (y ^ (x | (~z))); }
function FF(a,b,c,d,x,s,ac) {
a = AddUnsigned(a, AddUnsigned(AddUnsigned(F(b, c, d), x), ac));
return AddUnsigned(RotateLeft(a, s), b);
};
function GG(a,b,c,d,x,s,ac) {
a = AddUnsigned(a, AddUnsigned(AddUnsigned(G(b, c, d), x), ac));
return AddUnsigned(RotateLeft(a, s), b);
};
function HH(a,b,c,d,x,s,ac) {
a = AddUnsigned(a, AddUnsigned(AddUnsigned(H(b, c, d), x), ac));
return AddUnsigned(RotateLeft(a, s), b);
};
function II(a,b,c,d,x,s,ac) {
a = AddUnsigned(a, AddUnsigned(AddUnsigned(I(b, c, d), x), ac));
return AddUnsigned(RotateLeft(a, s), b);
};
function ConvertToWordArray(string) {
var lWordCount;
var lMessageLength = string.length;
var lNumberOfWords_temp1=lMessageLength + 8;
var lNumberOfWords_temp2=(lNumberOfWords_temp1-(lNumberOfWords_temp1 % 64))/64;
var lNumberOfWords = (lNumberOfWords_temp2+1)*16;
var lWordArray=Array(lNumberOfWords-1);
var lBytePosition = 0;
var lByteCount = 0;
while ( lByteCount < lMessageLength ) {
lWordCount = (lByteCount-(lByteCount % 4))/4;
lBytePosition = (lByteCount % 4)*8;
lWordArray[lWordCount] = (lWordArray[lWordCount] | (string.charCodeAt(lByteCount)<<lBytePosition));
lByteCount++;
}
lWordCount = (lByteCount-(lByteCount % 4))/4;
lBytePosition = (lByteCount % 4)*8;
lWordArray[lWordCount] = lWordArray[lWordCount] | (0x80<<lBytePosition);
lWordArray[lNumberOfWords-2] = lMessageLength<<3;
lWordArray[lNumberOfWords-1] = lMessageLength>>>29;
return lWordArray;
};
function WordToHex(lValue) {
var WordToHexValue="",WordToHexValue_temp="",lByte,lCount;
for (lCount = 0;lCount<=3;lCount++) {
lByte = (lValue>>>(lCount*8)) & 255;
WordToHexValue_temp = "0" + lByte.toString(16);
WordToHexValue = WordToHexValue + WordToHexValue_temp.substr(WordToHexValue_temp.length-2,2);
}
return WordToHexValue;
};
function Utf8Encode(string) {
string = string.replace(/\r\n/g,"\n");
var utftext = "";
for (var n = 0; n < string.length; n++) {
var c = string.charCodeAt(n);
if (c < 128) {
utftext += String.fromCharCode(c);
}
else if((c > 127) && (c < 2048)) {
utftext += String.fromCharCode((c >> 6) | 192);
utftext += String.fromCharCode((c & 63) | 128);
}
else {
utftext += String.fromCharCode((c >> 12) | 224);
utftext += String.fromCharCode(((c >> 6) & 63) | 128);
utftext += String.fromCharCode((c & 63) | 128);
}
}
return utftext;
};
var x=Array();
var k,AA,BB,CC,DD,a,b,c,d;
var S11=7, S12=12, S13=17, S14=22;
var S21=5, S22=9 , S23=14, S24=20;
var S31=4, S32=11, S33=16, S34=23;
var S41=6, S42=10, S43=15, S44=21;
string = Utf8Encode(string);
x = ConvertToWordArray(string);
a = 0x67452301; b = 0xEFCDAB89; c = 0x98BADCFE; d = 0x10325476;
for (k=0;k<x.length;k+=16) {
AA=a; BB=b; CC=c; DD=d;
a=FF(a,b,c,d,x[k+0], S11,0xD76AA478);
d=FF(d,a,b,c,x[k+1], S12,0xE8C7B756);
c=FF(c,d,a,b,x[k+2], S13,0x242070DB);
b=FF(b,c,d,a,x[k+3], S14,0xC1BDCEEE);
a=FF(a,b,c,d,x[k+4], S11,0xF57C0FAF);
d=FF(d,a,b,c,x[k+5], S12,0x4787C62A);
c=FF(c,d,a,b,x[k+6], S13,0xA8304613);
b=FF(b,c,d,a,x[k+7], S14,0xFD469501);
a=FF(a,b,c,d,x[k+8], S11,0x698098D8);
d=FF(d,a,b,c,x[k+9], S12,0x8B44F7AF);
c=FF(c,d,a,b,x[k+10],S13,0xFFFF5BB1);
b=FF(b,c,d,a,x[k+11],S14,0x895CD7BE);
a=FF(a,b,c,d,x[k+12],S11,0x6B901122);
d=FF(d,a,b,c,x[k+13],S12,0xFD987193);
c=FF(c,d,a,b,x[k+14],S13,0xA679438E);
b=FF(b,c,d,a,x[k+15],S14,0x49B40821);
a=GG(a,b,c,d,x[k+1], S21,0xF61E2562);
d=GG(d,a,b,c,x[k+6], S22,0xC040B340);
c=GG(c,d,a,b,x[k+11],S23,0x265E5A51);
b=GG(b,c,d,a,x[k+0], S24,0xE9B6C7AA);
a=GG(a,b,c,d,x[k+5], S21,0xD62F105D);
d=GG(d,a,b,c,x[k+10],S22,0x2441453);
c=GG(c,d,a,b,x[k+15],S23,0xD8A1E681);
b=GG(b,c,d,a,x[k+4], S24,0xE7D3FBC8);
a=GG(a,b,c,d,x[k+9], S21,0x21E1CDE6);
d=GG(d,a,b,c,x[k+14],S22,0xC33707D6);
c=GG(c,d,a,b,x[k+3], S23,0xF4D50D87);
b=GG(b,c,d,a,x[k+8], S24,0x455A14ED);
a=GG(a,b,c,d,x[k+13],S21,0xA9E3E905);
d=GG(d,a,b,c,x[k+2], S22,0xFCEFA3F8);
c=GG(c,d,a,b,x[k+7], S23,0x676F02D9);
b=GG(b,c,d,a,x[k+12],S24,0x8D2A4C8A);
a=HH(a,b,c,d,x[k+5], S31,0xFFFA3942);
d=HH(d,a,b,c,x[k+8], S32,0x8771F681);
c=HH(c,d,a,b,x[k+11],S33,0x6D9D6122);
b=HH(b,c,d,a,x[k+14],S34,0xFDE5380C);
a=HH(a,b,c,d,x[k+1], S31,0xA4BEEA44);
d=HH(d,a,b,c,x[k+4], S32,0x4BDECFA9);
c=HH(c,d,a,b,x[k+7], S33,0xF6BB4B60);
b=HH(b,c,d,a,x[k+10],S34,0xBEBFBC70);
a=HH(a,b,c,d,x[k+13],S31,0x289B7EC6);
d=HH(d,a,b,c,x[k+0], S32,0xEAA127FA);
c=HH(c,d,a,b,x[k+3], S33,0xD4EF3085);
b=HH(b,c,d,a,x[k+6], S34,0x4881D05);
a=HH(a,b,c,d,x[k+9], S31,0xD9D4D039);
d=HH(d,a,b,c,x[k+12],S32,0xE6DB99E5);
c=HH(c,d,a,b,x[k+15],S33,0x1FA27CF8);
b=HH(b,c,d,a,x[k+2], S34,0xC4AC5665);
a=II(a,b,c,d,x[k+0], S41,0xF4292244);
d=II(d,a,b,c,x[k+7], S42,0x432AFF97);
c=II(c,d,a,b,x[k+14],S43,0xAB9423A7);
b=II(b,c,d,a,x[k+5], S44,0xFC93A039);
a=II(a,b,c,d,x[k+12],S41,0x655B59C3);
d=II(d,a,b,c,x[k+3], S42,0x8F0CCC92);
c=II(c,d,a,b,x[k+10],S43,0xFFEFF47D);
b=II(b,c,d,a,x[k+1], S44,0x85845DD1);
a=II(a,b,c,d,x[k+8], S41,0x6FA87E4F);
d=II(d,a,b,c,x[k+15],S42,0xFE2CE6E0);
c=II(c,d,a,b,x[k+6], S43,0xA3014314);
b=II(b,c,d,a,x[k+13],S44,0x4E0811A1);
a=II(a,b,c,d,x[k+4], S41,0xF7537E82);
d=II(d,a,b,c,x[k+11],S42,0xBD3AF235);
c=II(c,d,a,b,x[k+2], S43,0x2AD7D2BB);
b=II(b,c,d,a,x[k+9], S44,0xEB86D391);
a=AddUnsigned(a,AA);
b=AddUnsigned(b,BB);
c=AddUnsigned(c,CC);
d=AddUnsigned(d,DD);
}
var temp = WordToHex(a)+WordToHex(b)+WordToHex(c)+WordToHex(d);
return temp.toLowerCase();
}
function jsonSafeEncode(str) {
return str
.replace(/\\/g, '\\\\')
.replace(/"/g, '\\"')
.replace(/'/g, "\\'")
.replace(/\n/g, '\\n')
.replace(/\r/g, '\\r')
.replace(/\t/g, '\\t')
.replace(/\f/g, '\\f')
.replace(/%/g, '\\%')
.replace(/_/g, '\\_')
.replace(/`/g, '\\`');
}
function jsonSafeDecode(str) {
return str
.replace(/\\`/g, '`')
.replace(/\\_/g, '_')
.replace(/\\%/g, '%')
.replace(/\\f/g, '\f')
.replace(/\\t/g, '\t')
.replace(/\\r/g, '\r')
.replace(/\\n/g, '\n')
.replace(/\\"/g, '"')
.replace(/\\'/g, "'")
.replace(/\\\\/g, '\\');
}
function NumberToABC(n) {
const abc = 'ABCDEFGHIJKLMNOPQRSTUVWXYZ';
if (typeof n === 'string') {
const num = parseInt(n, 10);
if (isNaN(num) || num < 1 || num > 26) return null;
return abc.charAt(num - 1);
}
if (typeof n !== 'number' || n < 1 || n > 26) return null;
return abc.charAt(n - 1);
}
function padWithZero(str) {
if (str.length === 2) return str;
return str.toString().padStart(2, '0');
}
/* Sütikezelés */
function setCookie(cname, cvalue, exdays) {
var d = new Date();
d.setTime(d.getTime() + (exdays*24*60*60*1000));
var expires = "expires="+ d.toUTCString();
document.cookie = cname + "=" + cvalue + ";" + expires + ";path=/";
}
function getCookie(cname) {
var name = cname + "=";
var decodedCookie = decodeURIComponent(document.cookie);
var ca = decodedCookie.split(';');
for(var i = 0; i <ca.length; i++) {
var c = ca[i];
while (c.charAt(0) == ' ') {
c = c.substring(1);
}
if (c.indexOf(name) == 0) {
return c.substring(name.length, c.length);
}
}
return "";
}
var isMobile = {
Android: function() {
return navigator.userAgent.match(/Android/i);
},
BlackBerry: function() {
return navigator.userAgent.match(/BlackBerry/i);
},
iOS: function() {
return navigator.userAgent.match(/iPhone|iPad|iPod/i);
},
Opera: function() {
return navigator.userAgent.match(/Opera Mini/i);
},
Windows: function() {
return navigator.userAgent.match(/IEMobile/i) || navigator.userAgent.match(/WPDesktop/i);
},
any: function() {
return (isMobile.Android() || isMobile.BlackBerry() || isMobile.iOS() || isMobile.Opera() || isMobile.Windows());
}
};
function isMobileDevice() {
return (
('ontouchstart' in window || navigator.maxTouchPoints > 0) &&
window.matchMedia("(max-width: 768px)").matches
);
}
var iscookie = getCookie("iscookie");
if (iscookie != "") {
} else {
var elementExists = document.getElementById("kjokmjnoi");
if (elementExists != null) {
document.getElementById('kjokmjnoi').style.visibility='visible';
style = "font-family: sans-serif; background-color: #2196F3; padding: 20px; color: white; opacity: 1; transition: opacity 0.6s; margin-bottom: 15px;";
stylebtn = "font-family: sans-serif; margin-left: 15px; color: white; font-weight: bold; float: right; font-size: 22px; line-height: 20px; cursor: pointer; transition: 0.3s;";
alert = "<div style='" + style + "'><span class='closebtn' style='" + stylebtn + "'>&times;</span><strong>Info!</strong> Az oldal mĹąkĂśdĂŠsĂŠhez szĂźksĂŠgesek a cookie-k! Az oldal hasznĂĄlatĂĄval elfogadja ezt!</div>";
var posts_div=document.getElementById('kjokmjnoi');
posts_div.innerHTML = alert;
setCookie("iscookie", "true", 365);
setTimeout(() => { window.scrollTo(0, 0); }, 10);
}
}
var close = document.getElementsByClassName("closebtn");
var i;
for (i = 0; i < close.length; i++) {
close[i].onclick = function(){
var div = this.parentElement;
div.style.opacity = "0";
setTimeout(function(){ div.style.display = "none"; }, 600);
}
}
/* Window Funkció */
const win = document.getElementById("win");
const wintitle = document.getElementById("wintitle");
const winapp = document.getElementById("winapp");
const winloading = document.getElementById("winloading");
function openwin() {
win.classList.remove("closed");
}
function closewin() {
win.classList.add("closed");
}
function fullscrn(isfull = null) {
if (isfull == null) {
if(document.getElementById("fullscrnbtn").classList.contains("close")) {
win.classList.remove("fullscrn");
document.getElementById("fullscrnbtn").classList.remove("close");
} else {
win.classList.add("fullscrn");
document.getElementById("fullscrnbtn").classList.add("close");
}
} else if (isfull) {
win.classList.add("fullscrn");
document.getElementById("fullscrnbtn").classList.add("close");
} else {
win.classList.remove("fullscrn");
document.getElementById("fullscrnbtn").classList.remove("close");
}
}
function Loading(isloading = true) {
if (isloading) {
document.getElementById("winloading").classList.remove("hidden");
document.getElementById("loadingBG").classList.add("active")
} else {
document.getElementById("winloading").classList.add("hidden")
document.getElementById("loadingBG").classList.remove("active")
}
}
/* Alert funkciók */
function GenerateID(length = 8) {
const characters = 'abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789';
let randomId = '';
for (let i = 0; i < length; i++) {
const randomIndex = Math.floor(Math.random() * characters.length);
randomId += characters[randomIndex];
}
return randomId;
}
function GenerateAlerts(type, message, disappearing = true) {
const errorElements = document.querySelectorAll('#errorDIV');
let spanstyle = "'none'";
errorElements.forEach(function(element) {
const randomId = type + GenerateID(16);
let alertHtml = '';
if (type == "error") {
alertHtml = '<div class="erroralert" id="'+randomId+'"><span class="closebtn" onclick="this.parentElement.style.display='+spanstyle+';">&times;</span><strong>Hiba!</strong> '+message+'</div>';
} else if (type == "success") {
alertHtml = '<div class="successalert" id="'+randomId+'"><span class="closebtn" onclick="this.parentElement.style.display='+spanstyle+';">&times;</span><strong>Siker!</strong> '+message+'</div>';
} else if (type == "info") {
alertHtml = '<div class="infoalert" id="'+randomId+'"><span class="closebtn" onclick="this.parentElement.style.display='+spanstyle+';">&times;</span><strong>Info!</strong> '+message+'</div>';
} else if (type == "warning") {
alertHtml = '<div class="warningalert" id="'+randomId+'"><span class="closebtn" onclick="this.parentElement.style.display='+spanstyle+';">&times;</span><strong>Figyelem!</strong> '+message+'</div>';
}
element.innerHTML += alertHtml;
if (disappearing) {
setTimeout(() => {
const alertElement = document.getElementById(randomId);
if (alertElement) {
alertElement.remove();
}
}, 10000);
}
});
}
/* Név korrektálás */
function adjustFontSize() {
const container = document.getElementById("userNameDiv");
const text = document.getElementById("userNameP");
let fontSize = 16;
text.style.fontSize = "16px";
while (text.scrollHeight > container.clientHeight || text.scrollWidth > container.clientWidth) {
fontSize--;
text.style.fontSize = fontSize + "px";
if (fontSize <= 8) {
break;
}
}
}
if (document.getElementById("userNameP") !== null && document.getElementById("userNameDiv") !== null) {
window.onload = adjustFontSize;
window.onresize = adjustFontSize;
}
/* LogOut timer és vissza LogIn */
let reLogInPopup;
function ReLogIn() {
reLogInPopup = window.open(window.location.origin + '?noredirect=1', 'Belépés', 'width=860,height=860');
}
function ReLogInClose() {
try {
reLogInPopup.location.href = window.location.origin + '/managers/template/loggedin.html';
reLogInPopup.close();
} catch (e) {
console.error('Close error:', e.message);
}
reLogInPopup = null;
}
if (document.getElementById("TimeBeforeLogOutSpan") !== null) {
const timerSpan = document.getElementById('TimeBeforeLogOutSpan');
var theAlertedSessionEnd = null;
const update = () => {
const authTimer = getCookie('auth_timer');
if (!authTimer || isNaN(authTimer)) {
return;
}
const expiry = parseInt(authTimer) * 1000;
const now = Date.now();
const remaining = Math.max(0, Math.floor((expiry - now) / 1000));
if (remaining <= 0) {
timerSpan.textContent = 'Lejárt munkamenet';
timerSpan.style.opacity = '1';
timerSpan.style.right = '210px';
timerSpan.style.color = 'red';
if (theAlertedSessionEnd == null) {
const html = `<p><b>Az ön munkamenete lejárt!</b><br>Kérjük, jelentkezzen be újra!</p>
<br clear='all'>
<button id="AlertBtnNo" style="float: right; margin-left: 15px; width: 80;" onclick="location.reload();">Mégsem</button>
<button style="float: right; width: 80;" onclick="ReLogIn()">Bejelentkezés</button>`;
theAlertedSessionEnd = CreateAlertBox('Lejárt munkamenet', html, false);
}
return;
}
if (theAlertedSessionEnd != null) {
CloseAlertBox(theAlertedSessionEnd);
theAlertedSessionEnd = null;
}
if (reLogInPopup != null && !reLogInPopup.closed) {
ReLogInClose();
}
const minutes = Math.floor(remaining / 60);
const seconds = remaining % 60;
timerSpan.textContent = `${minutes}:${seconds.toString().padStart(2, '0')}`;
timerSpan.style.opacity = '0.4';
timerSpan.style.right = '10px';
timerSpan.style.color = 'var(--panelcolor)';
};
update();
setInterval(update, 1000);
}
/* Feedback Státusz */
function FeedbackButtonStatus(status = "loading", id) {
var FeedbackButton = document.getElementById(id);
if (status == "loading") {
FeedbackButton.disabled = true;
FeedbackButton.classList.add('loading');
} else if (status == "complete") {
FeedbackButton.classList.add('complete');
setTimeout(() => {
FeedbackButton.classList.remove("loading");
FeedbackButton.classList.remove("complete");
FeedbackButton.disabled = false;
}, 6000);
} else {
FeedbackButton.classList.add('failed');
setTimeout(() => {
FeedbackButton.classList.remove("loading");
FeedbackButton.classList.remove("failed");
FeedbackButton.disabled = false;
}, 6000);
}
}
/* Typing szimuláció */
var TypingMax = 0;
var isSimulateTyping = false;
function getRandomNumber(min, max) { return Math.floor(Math.random() * (max - min + 1)) + min;}
function SimulateTypingProtector(text, elementId) {
if (isSimulateTyping) {
setTimeout(function() {
SimulateTyping(text, elementId);
}, TypingMax);
} else {
SimulateTyping(text, elementId);
}
}
function SimulateTyping(text, elementId) {
var element = document.getElementById(elementId);
var delaymin = 20;
var delaymax = 40;
var index = 0;
TypingMax = text.length * delaymax;
isSimulateTyping = true;
var timer = setInterval(function() {
if (index < text.length) {
var char = text.charAt(index);
element.innerHTML += char;
index++;
} else {
clearInterval(timer);
isSimulateTyping = false;
}
}, getRandomNumber(delaymin, delaymax));
}
/* Kanban board */
if (document.querySelector('.kanban-board') !== null) {
document.addEventListener('DOMContentLoaded', () => {
const board = document.querySelector('.kanban-board');
let isDown = false;
let startX;
let scrollLeft;
board.addEventListener('mousedown', (e) => {
isDown = true;
board.classList.add('active');
startX = e.pageX - board.offsetLeft;
scrollLeft = board.scrollLeft;
});
board.addEventListener('mouseleave', () => {
isDown = false;
board.classList.remove('active');
});
board.addEventListener('mouseup', () => {
isDown = false;
board.classList.remove('active');
});
board.addEventListener('mousemove', (e) => {
if (!isDown) return;
e.preventDefault();
const x = e.pageX - board.offsetLeft;
const walk = (x - startX) * 1.5;
board.scrollLeft = scrollLeft - walk;
});
});
}
/* AlertBox */
function CreateAlertBox(title, html, closeable = true) {
// Overlay létrehozása
const overlay = document.createElement('div');
overlay.className = 'alert-overlay';
overlay.style.cssText = `
position: fixed;
top: 0;
left: 0;
width: 100%;
height: 100%;
background: rgba(0, 0, 0, 0.5);
backdrop-filter: blur(3px);
display: flex;
justify-content: center;
align-items: center;
z-index: ${1000 + document.querySelectorAll('.alert-overlay').length};
`;
// AlertBox div létrehozása
const alertBox = document.createElement('div');
alertBox.className = 'alert-box';
alertBox.style.cssText = `
width: 25%;
min-width: 300px;
max-width: 600px;
max-height: 600px;
background: var(--toppanel);
border-radius: 4px;
box-shadow: 1 5px 10px #aaaaaa;
position: relative;
overflow: hidden;
display: flex;
flex-direction: column;
`;
// Header létrehozása
const header = document.createElement('div');
header.style.cssText = `
padding: 8px 20px;
border-bottom: 1px solid #bdc3c7;
display: flex;
justify-content: space-between;
align-items: center;
flex-shrink: 0;
background-color: var(--panelcolor);
`;
// Title h2 elem
const titleElement = document.createElement('h2');
titleElement.textContent = title;
titleElement.style.cssText = `
margin: 0;
font-size: 18px;
color: #f5f5f5;
`;
header.appendChild(titleElement);
// Close gomb ha closeable
if (closeable) {
const closeButton = document.createElement('button');
closeButton.innerHTML = '×';
closeButton.style.cssText = `
background: none;
border: none;
font-size: 24px;
color: #f5f5f5;
cursor: pointer;
padding: 0;
margin: 0;
width: 30px;
height: 30px;
display: flex;
align-items: center;
justify-content: center;
border-radius: 50%;
transition: background-color 0.2s;
`;
closeButton.onmouseover = () => closeButton.style.backgroundColor = '#f0f0f0';
closeButton.onmouseout = () => closeButton.style.backgroundColor = 'transparent';
closeButton.onclick = () => CloseAlertBox(overlay);
header.appendChild(closeButton);
}
// Content terület
const content = document.createElement('div');
content.innerHTML = html;
content.style.cssText = `
padding: 0px 20px 20px 20px;
overflow-y: auto;
flex-grow: 1;
text-align: justify;
`;
// Összeállítás
alertBox.appendChild(header);
alertBox.appendChild(content);
overlay.appendChild(alertBox);
// DOM-hoz hozzáadás
document.body.appendChild(overlay);
// Animáció
overlay.style.opacity = '0';
alertBox.style.transform = 'scale(0.8)';
requestAnimationFrame(() => {
overlay.style.transition = 'opacity 0.3s ease';
alertBox.style.transition = 'transform 0.3s ease';
overlay.style.opacity = '1';
alertBox.style.transform = 'scale(1)';
});
return overlay;
}
function CloseAlertBox(overlay) {
if (!overlay) return;
overlay.style.transition = 'opacity 0.3s ease';
overlay.querySelector('.alert-box').style.transition = 'transform 0.3s ease';
overlay.style.opacity = '0';
overlay.querySelector('.alert-box').style.transform = 'scale(0.8)';
setTimeout(() => {
if (overlay.parentNode) {
overlay.parentNode.removeChild(overlay);
}
}, 300);
}

13
js/feather-icons.js Normal file

File diff suppressed because one or more lines are too long

20
js/html2canvas.min.js vendored Normal file

File diff suppressed because one or more lines are too long

589
js/qrcode.js Normal file
View File

@ -0,0 +1,589 @@
var QRCode;
(function () {
function QR8bitByte(data) {
this.mode = QRMode.MODE_8BIT_BYTE;
this.data = data;
this.parsedData = [];
// Added to support UTF-8 Characters
for (var i = 0, l = this.data.length; i < l; i++) {
var byteArray = [];
var code = this.data.charCodeAt(i);
if (code > 0x10000) {
byteArray[0] = 0xF0 | ((code & 0x1C0000) >>> 18);
byteArray[1] = 0x80 | ((code & 0x3F000) >>> 12);
byteArray[2] = 0x80 | ((code & 0xFC0) >>> 6);
byteArray[3] = 0x80 | (code & 0x3F);
} else if (code > 0x800) {
byteArray[0] = 0xE0 | ((code & 0xF000) >>> 12);
byteArray[1] = 0x80 | ((code & 0xFC0) >>> 6);
byteArray[2] = 0x80 | (code & 0x3F);
} else if (code > 0x80) {
byteArray[0] = 0xC0 | ((code & 0x7C0) >>> 6);
byteArray[1] = 0x80 | (code & 0x3F);
} else {
byteArray[0] = code;
}
this.parsedData.push(byteArray);
}
this.parsedData = Array.prototype.concat.apply([], this.parsedData);
if (this.parsedData.length != this.data.length) {
this.parsedData.unshift(191);
this.parsedData.unshift(187);
this.parsedData.unshift(239);
}
}
QR8bitByte.prototype = {
getLength: function (buffer) {
return this.parsedData.length;
},
write: function (buffer) {
for (var i = 0, l = this.parsedData.length; i < l; i++) {
buffer.put(this.parsedData[i], 8);
}
}
};
function QRCodeModel(typeNumber, errorCorrectLevel) {
this.typeNumber = typeNumber;
this.errorCorrectLevel = errorCorrectLevel;
this.modules = null;
this.moduleCount = 0;
this.dataCache = null;
this.dataList = [];
}
QRCodeModel.prototype={addData:function(data){var newData=new QR8bitByte(data);this.dataList.push(newData);this.dataCache=null;},isDark:function(row,col){if(row<0||this.moduleCount<=row||col<0||this.moduleCount<=col){throw new Error(row+","+col);}
return this.modules[row][col];},getModuleCount:function(){return this.moduleCount;},make:function(){this.makeImpl(false,this.getBestMaskPattern());},makeImpl:function(test,maskPattern){this.moduleCount=this.typeNumber*4+17;this.modules=new Array(this.moduleCount);for(var row=0;row<this.moduleCount;row++){this.modules[row]=new Array(this.moduleCount);for(var col=0;col<this.moduleCount;col++){this.modules[row][col]=null;}}
this.setupPositionProbePattern(0,0);this.setupPositionProbePattern(this.moduleCount-7,0);this.setupPositionProbePattern(0,this.moduleCount-7);this.setupPositionAdjustPattern();this.setupTimingPattern();this.setupTypeInfo(test,maskPattern);if(this.typeNumber>=7){this.setupTypeNumber(test);}
if(this.dataCache==null){this.dataCache=QRCodeModel.createData(this.typeNumber,this.errorCorrectLevel,this.dataList);}
this.mapData(this.dataCache,maskPattern);},setupPositionProbePattern:function(row,col){for(var r=-1;r<=7;r++){if(row+r<=-1||this.moduleCount<=row+r)continue;for(var c=-1;c<=7;c++){if(col+c<=-1||this.moduleCount<=col+c)continue;if((0<=r&&r<=6&&(c==0||c==6))||(0<=c&&c<=6&&(r==0||r==6))||(2<=r&&r<=4&&2<=c&&c<=4)){this.modules[row+r][col+c]=true;}else{this.modules[row+r][col+c]=false;}}}},getBestMaskPattern:function(){var minLostPoint=0;var pattern=0;for(var i=0;i<8;i++){this.makeImpl(true,i);var lostPoint=QRUtil.getLostPoint(this);if(i==0||minLostPoint>lostPoint){minLostPoint=lostPoint;pattern=i;}}
return pattern;},createMovieClip:function(target_mc,instance_name,depth){var qr_mc=target_mc.createEmptyMovieClip(instance_name,depth);var cs=1;this.make();for(var row=0;row<this.modules.length;row++){var y=row*cs;for(var col=0;col<this.modules[row].length;col++){var x=col*cs;var dark=this.modules[row][col];if(dark){qr_mc.beginFill(0,100);qr_mc.moveTo(x,y);qr_mc.lineTo(x+cs,y);qr_mc.lineTo(x+cs,y+cs);qr_mc.lineTo(x,y+cs);qr_mc.endFill();}}}
return qr_mc;},setupTimingPattern:function(){for(var r=8;r<this.moduleCount-8;r++){if(this.modules[r][6]!=null){continue;}
this.modules[r][6]=(r%2==0);}
for(var c=8;c<this.moduleCount-8;c++){if(this.modules[6][c]!=null){continue;}
this.modules[6][c]=(c%2==0);}},setupPositionAdjustPattern:function(){var pos=QRUtil.getPatternPosition(this.typeNumber);for(var i=0;i<pos.length;i++){for(var j=0;j<pos.length;j++){var row=pos[i];var col=pos[j];if(this.modules[row][col]!=null){continue;}
for(var r=-2;r<=2;r++){for(var c=-2;c<=2;c++){if(r==-2||r==2||c==-2||c==2||(r==0&&c==0)){this.modules[row+r][col+c]=true;}else{this.modules[row+r][col+c]=false;}}}}}},setupTypeNumber:function(test){var bits=QRUtil.getBCHTypeNumber(this.typeNumber);for(var i=0;i<18;i++){var mod=(!test&&((bits>>i)&1)==1);this.modules[Math.floor(i/3)][i%3+this.moduleCount-8-3]=mod;}
for(var i=0;i<18;i++){var mod=(!test&&((bits>>i)&1)==1);this.modules[i%3+this.moduleCount-8-3][Math.floor(i/3)]=mod;}},setupTypeInfo:function(test,maskPattern){var data=(this.errorCorrectLevel<<3)|maskPattern;var bits=QRUtil.getBCHTypeInfo(data);for(var i=0;i<15;i++){var mod=(!test&&((bits>>i)&1)==1);if(i<6){this.modules[i][8]=mod;}else if(i<8){this.modules[i+1][8]=mod;}else{this.modules[this.moduleCount-15+i][8]=mod;}}
for(var i=0;i<15;i++){var mod=(!test&&((bits>>i)&1)==1);if(i<8){this.modules[8][this.moduleCount-i-1]=mod;}else if(i<9){this.modules[8][15-i-1+1]=mod;}else{this.modules[8][15-i-1]=mod;}}
this.modules[this.moduleCount-8][8]=(!test);},mapData:function(data,maskPattern){var inc=-1;var row=this.moduleCount-1;var bitIndex=7;var byteIndex=0;for(var col=this.moduleCount-1;col>0;col-=2){if(col==6)col--;while(true){for(var c=0;c<2;c++){if(this.modules[row][col-c]==null){var dark=false;if(byteIndex<data.length){dark=(((data[byteIndex]>>>bitIndex)&1)==1);}
var mask=QRUtil.getMask(maskPattern,row,col-c);if(mask){dark=!dark;}
this.modules[row][col-c]=dark;bitIndex--;if(bitIndex==-1){byteIndex++;bitIndex=7;}}}
row+=inc;if(row<0||this.moduleCount<=row){row-=inc;inc=-inc;break;}}}}};QRCodeModel.PAD0=0xEC;QRCodeModel.PAD1=0x11;QRCodeModel.createData=function(typeNumber,errorCorrectLevel,dataList){var rsBlocks=QRRSBlock.getRSBlocks(typeNumber,errorCorrectLevel);var buffer=new QRBitBuffer();for(var i=0;i<dataList.length;i++){var data=dataList[i];buffer.put(data.mode,4);buffer.put(data.getLength(),QRUtil.getLengthInBits(data.mode,typeNumber));data.write(buffer);}
var totalDataCount=0;for(var i=0;i<rsBlocks.length;i++){totalDataCount+=rsBlocks[i].dataCount;}
if(buffer.getLengthInBits()>totalDataCount*8){throw new Error("code length overflow. ("
+buffer.getLengthInBits()
+">"
+totalDataCount*8
+")");}
if(buffer.getLengthInBits()+4<=totalDataCount*8){buffer.put(0,4);}
while(buffer.getLengthInBits()%8!=0){buffer.putBit(false);}
while(true){if(buffer.getLengthInBits()>=totalDataCount*8){break;}
buffer.put(QRCodeModel.PAD0,8);if(buffer.getLengthInBits()>=totalDataCount*8){break;}
buffer.put(QRCodeModel.PAD1,8);}
return QRCodeModel.createBytes(buffer,rsBlocks);};QRCodeModel.createBytes=function(buffer,rsBlocks){var offset=0;var maxDcCount=0;var maxEcCount=0;var dcdata=new Array(rsBlocks.length);var ecdata=new Array(rsBlocks.length);for(var r=0;r<rsBlocks.length;r++){var dcCount=rsBlocks[r].dataCount;var ecCount=rsBlocks[r].totalCount-dcCount;maxDcCount=Math.max(maxDcCount,dcCount);maxEcCount=Math.max(maxEcCount,ecCount);dcdata[r]=new Array(dcCount);for(var i=0;i<dcdata[r].length;i++){dcdata[r][i]=0xff&buffer.buffer[i+offset];}
offset+=dcCount;var rsPoly=QRUtil.getErrorCorrectPolynomial(ecCount);var rawPoly=new QRPolynomial(dcdata[r],rsPoly.getLength()-1);var modPoly=rawPoly.mod(rsPoly);ecdata[r]=new Array(rsPoly.getLength()-1);for(var i=0;i<ecdata[r].length;i++){var modIndex=i+modPoly.getLength()-ecdata[r].length;ecdata[r][i]=(modIndex>=0)?modPoly.get(modIndex):0;}}
var totalCodeCount=0;for(var i=0;i<rsBlocks.length;i++){totalCodeCount+=rsBlocks[i].totalCount;}
var data=new Array(totalCodeCount);var index=0;for(var i=0;i<maxDcCount;i++){for(var r=0;r<rsBlocks.length;r++){if(i<dcdata[r].length){data[index++]=dcdata[r][i];}}}
for(var i=0;i<maxEcCount;i++){for(var r=0;r<rsBlocks.length;r++){if(i<ecdata[r].length){data[index++]=ecdata[r][i];}}}
return data;};var QRMode={MODE_NUMBER:1<<0,MODE_ALPHA_NUM:1<<1,MODE_8BIT_BYTE:1<<2,MODE_KANJI:1<<3};var QRErrorCorrectLevel={L:1,M:0,Q:3,H:2};var QRMaskPattern={PATTERN000:0,PATTERN001:1,PATTERN010:2,PATTERN011:3,PATTERN100:4,PATTERN101:5,PATTERN110:6,PATTERN111:7};var QRUtil={PATTERN_POSITION_TABLE:[[],[6,18],[6,22],[6,26],[6,30],[6,34],[6,22,38],[6,24,42],[6,26,46],[6,28,50],[6,30,54],[6,32,58],[6,34,62],[6,26,46,66],[6,26,48,70],[6,26,50,74],[6,30,54,78],[6,30,56,82],[6,30,58,86],[6,34,62,90],[6,28,50,72,94],[6,26,50,74,98],[6,30,54,78,102],[6,28,54,80,106],[6,32,58,84,110],[6,30,58,86,114],[6,34,62,90,118],[6,26,50,74,98,122],[6,30,54,78,102,126],[6,26,52,78,104,130],[6,30,56,82,108,134],[6,34,60,86,112,138],[6,30,58,86,114,142],[6,34,62,90,118,146],[6,30,54,78,102,126,150],[6,24,50,76,102,128,154],[6,28,54,80,106,132,158],[6,32,58,84,110,136,162],[6,26,54,82,110,138,166],[6,30,58,86,114,142,170]],G15:(1<<10)|(1<<8)|(1<<5)|(1<<4)|(1<<2)|(1<<1)|(1<<0),G18:(1<<12)|(1<<11)|(1<<10)|(1<<9)|(1<<8)|(1<<5)|(1<<2)|(1<<0),G15_MASK:(1<<14)|(1<<12)|(1<<10)|(1<<4)|(1<<1),getBCHTypeInfo:function(data){var d=data<<10;while(QRUtil.getBCHDigit(d)-QRUtil.getBCHDigit(QRUtil.G15)>=0){d^=(QRUtil.G15<<(QRUtil.getBCHDigit(d)-QRUtil.getBCHDigit(QRUtil.G15)));}
return((data<<10)|d)^QRUtil.G15_MASK;},getBCHTypeNumber:function(data){var d=data<<12;while(QRUtil.getBCHDigit(d)-QRUtil.getBCHDigit(QRUtil.G18)>=0){d^=(QRUtil.G18<<(QRUtil.getBCHDigit(d)-QRUtil.getBCHDigit(QRUtil.G18)));}
return(data<<12)|d;},getBCHDigit:function(data){var digit=0;while(data!=0){digit++;data>>>=1;}
return digit;},getPatternPosition:function(typeNumber){return QRUtil.PATTERN_POSITION_TABLE[typeNumber-1];},getMask:function(maskPattern,i,j){switch(maskPattern){case QRMaskPattern.PATTERN000:return(i+j)%2==0;case QRMaskPattern.PATTERN001:return i%2==0;case QRMaskPattern.PATTERN010:return j%3==0;case QRMaskPattern.PATTERN011:return(i+j)%3==0;case QRMaskPattern.PATTERN100:return(Math.floor(i/2)+Math.floor(j/3))%2==0;case QRMaskPattern.PATTERN101:return(i*j)%2+(i*j)%3==0;case QRMaskPattern.PATTERN110:return((i*j)%2+(i*j)%3)%2==0;case QRMaskPattern.PATTERN111:return((i*j)%3+(i+j)%2)%2==0;default:throw new Error("bad maskPattern:"+maskPattern);}},getErrorCorrectPolynomial:function(errorCorrectLength){var a=new QRPolynomial([1],0);for(var i=0;i<errorCorrectLength;i++){a=a.multiply(new QRPolynomial([1,QRMath.gexp(i)],0));}
return a;},getLengthInBits:function(mode,type){if(1<=type&&type<10){switch(mode){case QRMode.MODE_NUMBER:return 10;case QRMode.MODE_ALPHA_NUM:return 9;case QRMode.MODE_8BIT_BYTE:return 8;case QRMode.MODE_KANJI:return 8;default:throw new Error("mode:"+mode);}}else if(type<27){switch(mode){case QRMode.MODE_NUMBER:return 12;case QRMode.MODE_ALPHA_NUM:return 11;case QRMode.MODE_8BIT_BYTE:return 16;case QRMode.MODE_KANJI:return 10;default:throw new Error("mode:"+mode);}}else if(type<41){switch(mode){case QRMode.MODE_NUMBER:return 14;case QRMode.MODE_ALPHA_NUM:return 13;case QRMode.MODE_8BIT_BYTE:return 16;case QRMode.MODE_KANJI:return 12;default:throw new Error("mode:"+mode);}}else{throw new Error("type:"+type);}},getLostPoint:function(qrCode){var moduleCount=qrCode.getModuleCount();var lostPoint=0;for(var row=0;row<moduleCount;row++){for(var col=0;col<moduleCount;col++){var sameCount=0;var dark=qrCode.isDark(row,col);for(var r=-1;r<=1;r++){if(row+r<0||moduleCount<=row+r){continue;}
for(var c=-1;c<=1;c++){if(col+c<0||moduleCount<=col+c){continue;}
if(r==0&&c==0){continue;}
if(dark==qrCode.isDark(row+r,col+c)){sameCount++;}}}
if(sameCount>5){lostPoint+=(3+sameCount-5);}}}
for(var row=0;row<moduleCount-1;row++){for(var col=0;col<moduleCount-1;col++){var count=0;if(qrCode.isDark(row,col))count++;if(qrCode.isDark(row+1,col))count++;if(qrCode.isDark(row,col+1))count++;if(qrCode.isDark(row+1,col+1))count++;if(count==0||count==4){lostPoint+=3;}}}
for(var row=0;row<moduleCount;row++){for(var col=0;col<moduleCount-6;col++){if(qrCode.isDark(row,col)&&!qrCode.isDark(row,col+1)&&qrCode.isDark(row,col+2)&&qrCode.isDark(row,col+3)&&qrCode.isDark(row,col+4)&&!qrCode.isDark(row,col+5)&&qrCode.isDark(row,col+6)){lostPoint+=40;}}}
for(var col=0;col<moduleCount;col++){for(var row=0;row<moduleCount-6;row++){if(qrCode.isDark(row,col)&&!qrCode.isDark(row+1,col)&&qrCode.isDark(row+2,col)&&qrCode.isDark(row+3,col)&&qrCode.isDark(row+4,col)&&!qrCode.isDark(row+5,col)&&qrCode.isDark(row+6,col)){lostPoint+=40;}}}
var darkCount=0;for(var col=0;col<moduleCount;col++){for(var row=0;row<moduleCount;row++){if(qrCode.isDark(row,col)){darkCount++;}}}
var ratio=Math.abs(100*darkCount/moduleCount/moduleCount-50)/5;lostPoint+=ratio*10;return lostPoint;}};var QRMath={glog:function(n){if(n<1){throw new Error("glog("+n+")");}
return QRMath.LOG_TABLE[n];},gexp:function(n){while(n<0){n+=255;}
while(n>=256){n-=255;}
return QRMath.EXP_TABLE[n];},EXP_TABLE:new Array(256),LOG_TABLE:new Array(256)};for(var i=0;i<8;i++){QRMath.EXP_TABLE[i]=1<<i;}
for(var i=8;i<256;i++){QRMath.EXP_TABLE[i]=QRMath.EXP_TABLE[i-4]^QRMath.EXP_TABLE[i-5]^QRMath.EXP_TABLE[i-6]^QRMath.EXP_TABLE[i-8];}
for(var i=0;i<255;i++){QRMath.LOG_TABLE[QRMath.EXP_TABLE[i]]=i;}
function QRPolynomial(num,shift){if(num.length==undefined){throw new Error(num.length+"/"+shift);}
var offset=0;while(offset<num.length&&num[offset]==0){offset++;}
this.num=new Array(num.length-offset+shift);for(var i=0;i<num.length-offset;i++){this.num[i]=num[i+offset];}}
QRPolynomial.prototype={get:function(index){return this.num[index];},getLength:function(){return this.num.length;},multiply:function(e){var num=new Array(this.getLength()+e.getLength()-1);for(var i=0;i<this.getLength();i++){for(var j=0;j<e.getLength();j++){num[i+j]^=QRMath.gexp(QRMath.glog(this.get(i))+QRMath.glog(e.get(j)));}}
return new QRPolynomial(num,0);},mod:function(e){if(this.getLength()-e.getLength()<0){return this;}
var ratio=QRMath.glog(this.get(0))-QRMath.glog(e.get(0));var num=new Array(this.getLength());for(var i=0;i<this.getLength();i++){num[i]=this.get(i);}
for(var i=0;i<e.getLength();i++){num[i]^=QRMath.gexp(QRMath.glog(e.get(i))+ratio);}
return new QRPolynomial(num,0).mod(e);}};function QRRSBlock(totalCount,dataCount){this.totalCount=totalCount;this.dataCount=dataCount;}
QRRSBlock.RS_BLOCK_TABLE=[[1,26,19],[1,26,16],[1,26,13],[1,26,9],[1,44,34],[1,44,28],[1,44,22],[1,44,16],[1,70,55],[1,70,44],[2,35,17],[2,35,13],[1,100,80],[2,50,32],[2,50,24],[4,25,9],[1,134,108],[2,67,43],[2,33,15,2,34,16],[2,33,11,2,34,12],[2,86,68],[4,43,27],[4,43,19],[4,43,15],[2,98,78],[4,49,31],[2,32,14,4,33,15],[4,39,13,1,40,14],[2,121,97],[2,60,38,2,61,39],[4,40,18,2,41,19],[4,40,14,2,41,15],[2,146,116],[3,58,36,2,59,37],[4,36,16,4,37,17],[4,36,12,4,37,13],[2,86,68,2,87,69],[4,69,43,1,70,44],[6,43,19,2,44,20],[6,43,15,2,44,16],[4,101,81],[1,80,50,4,81,51],[4,50,22,4,51,23],[3,36,12,8,37,13],[2,116,92,2,117,93],[6,58,36,2,59,37],[4,46,20,6,47,21],[7,42,14,4,43,15],[4,133,107],[8,59,37,1,60,38],[8,44,20,4,45,21],[12,33,11,4,34,12],[3,145,115,1,146,116],[4,64,40,5,65,41],[11,36,16,5,37,17],[11,36,12,5,37,13],[5,109,87,1,110,88],[5,65,41,5,66,42],[5,54,24,7,55,25],[11,36,12],[5,122,98,1,123,99],[7,73,45,3,74,46],[15,43,19,2,44,20],[3,45,15,13,46,16],[1,135,107,5,136,108],[10,74,46,1,75,47],[1,50,22,15,51,23],[2,42,14,17,43,15],[5,150,120,1,151,121],[9,69,43,4,70,44],[17,50,22,1,51,23],[2,42,14,19,43,15],[3,141,113,4,142,114],[3,70,44,11,71,45],[17,47,21,4,48,22],[9,39,13,16,40,14],[3,135,107,5,136,108],[3,67,41,13,68,42],[15,54,24,5,55,25],[15,43,15,10,44,16],[4,144,116,4,145,117],[17,68,42],[17,50,22,6,51,23],[19,46,16,6,47,17],[2,139,111,7,140,112],[17,74,46],[7,54,24,16,55,25],[34,37,13],[4,151,121,5,152,122],[4,75,47,14,76,48],[11,54,24,14,55,25],[16,45,15,14,46,16],[6,147,117,4,148,118],[6,73,45,14,74,46],[11,54,24,16,55,25],[30,46,16,2,47,17],[8,132,106,4,133,107],[8,75,47,13,76,48],[7,54,24,22,55,25],[22,45,15,13,46,16],[10,142,114,2,143,115],[19,74,46,4,75,47],[28,50,22,6,51,23],[33,46,16,4,47,17],[8,152,122,4,153,123],[22,73,45,3,74,46],[8,53,23,26,54,24],[12,45,15,28,46,16],[3,147,117,10,148,118],[3,73,45,23,74,46],[4,54,24,31,55,25],[11,45,15,31,46,16],[7,146,116,7,147,117],[21,73,45,7,74,46],[1,53,23,37,54,24],[19,45,15,26,46,16],[5,145,115,10,146,116],[19,75,47,10,76,48],[15,54,24,25,55,25],[23,45,15,25,46,16],[13,145,115,3,146,116],[2,74,46,29,75,47],[42,54,24,1,55,25],[23,45,15,28,46,16],[17,145,115],[10,74,46,23,75,47],[10,54,24,35,55,25],[19,45,15,35,46,16],[17,145,115,1,146,116],[14,74,46,21,75,47],[29,54,24,19,55,25],[11,45,15,46,46,16],[13,145,115,6,146,116],[14,74,46,23,75,47],[44,54,24,7,55,25],[59,46,16,1,47,17],[12,151,121,7,152,122],[12,75,47,26,76,48],[39,54,24,14,55,25],[22,45,15,41,46,16],[6,151,121,14,152,122],[6,75,47,34,76,48],[46,54,24,10,55,25],[2,45,15,64,46,16],[17,152,122,4,153,123],[29,74,46,14,75,47],[49,54,24,10,55,25],[24,45,15,46,46,16],[4,152,122,18,153,123],[13,74,46,32,75,47],[48,54,24,14,55,25],[42,45,15,32,46,16],[20,147,117,4,148,118],[40,75,47,7,76,48],[43,54,24,22,55,25],[10,45,15,67,46,16],[19,148,118,6,149,119],[18,75,47,31,76,48],[34,54,24,34,55,25],[20,45,15,61,46,16]];QRRSBlock.getRSBlocks=function(typeNumber,errorCorrectLevel){var rsBlock=QRRSBlock.getRsBlockTable(typeNumber,errorCorrectLevel);if(rsBlock==undefined){throw new Error("bad rs block @ typeNumber:"+typeNumber+"/errorCorrectLevel:"+errorCorrectLevel);}
var length=rsBlock.length/3;var list=[];for(var i=0;i<length;i++){var count=rsBlock[i*3+0];var totalCount=rsBlock[i*3+1];var dataCount=rsBlock[i*3+2];for(var j=0;j<count;j++){list.push(new QRRSBlock(totalCount,dataCount));}}
return list;};QRRSBlock.getRsBlockTable=function(typeNumber,errorCorrectLevel){switch(errorCorrectLevel){case QRErrorCorrectLevel.L:return QRRSBlock.RS_BLOCK_TABLE[(typeNumber-1)*4+0];case QRErrorCorrectLevel.M:return QRRSBlock.RS_BLOCK_TABLE[(typeNumber-1)*4+1];case QRErrorCorrectLevel.Q:return QRRSBlock.RS_BLOCK_TABLE[(typeNumber-1)*4+2];case QRErrorCorrectLevel.H:return QRRSBlock.RS_BLOCK_TABLE[(typeNumber-1)*4+3];default:return undefined;}};function QRBitBuffer(){this.buffer=[];this.length=0;}
QRBitBuffer.prototype={get:function(index){var bufIndex=Math.floor(index/8);return((this.buffer[bufIndex]>>>(7-index%8))&1)==1;},put:function(num,length){for(var i=0;i<length;i++){this.putBit(((num>>>(length-i-1))&1)==1);}},getLengthInBits:function(){return this.length;},putBit:function(bit){var bufIndex=Math.floor(this.length/8);if(this.buffer.length<=bufIndex){this.buffer.push(0);}
if(bit){this.buffer[bufIndex]|=(0x80>>>(this.length%8));}
this.length++;}};var QRCodeLimitLength=[[17,14,11,7],[32,26,20,14],[53,42,32,24],[78,62,46,34],[106,84,60,44],[134,106,74,58],[154,122,86,64],[192,152,108,84],[230,180,130,98],[271,213,151,119],[321,251,177,137],[367,287,203,155],[425,331,241,177],[458,362,258,194],[520,412,292,220],[586,450,322,250],[644,504,364,280],[718,560,394,310],[792,624,442,338],[858,666,482,382],[929,711,509,403],[1003,779,565,439],[1091,857,611,461],[1171,911,661,511],[1273,997,715,535],[1367,1059,751,593],[1465,1125,805,625],[1528,1190,868,658],[1628,1264,908,698],[1732,1370,982,742],[1840,1452,1030,790],[1952,1538,1112,842],[2068,1628,1168,898],[2188,1722,1228,958],[2303,1809,1283,983],[2431,1911,1351,1051],[2563,1989,1423,1093],[2699,2099,1499,1139],[2809,2213,1579,1219],[2953,2331,1663,1273]];
function _isSupportCanvas() {
return typeof CanvasRenderingContext2D != "undefined";
}
// android 2.x doesn't support Data-URI spec
function _getAndroid() {
var android = false;
var sAgent = navigator.userAgent;
if (/android/i.test(sAgent)) { // android
android = true;
var aMat = sAgent.toString().match(/android ([0-9]\.[0-9])/i);
if (aMat && aMat[1]) {
android = parseFloat(aMat[1]);
}
}
return android;
}
var svgDrawer = (function() {
var Drawing = function (el, htOption) {
this._el = el;
this._htOption = htOption;
};
Drawing.prototype.draw = function (oQRCode) {
var _htOption = this._htOption;
var _el = this._el;
var nCount = oQRCode.getModuleCount();
var nWidth = Math.floor(_htOption.width / nCount);
var nHeight = Math.floor(_htOption.height / nCount);
this.clear();
function makeSVG(tag, attrs) {
var el = document.createElementNS('http://www.w3.org/2000/svg', tag);
for (var k in attrs)
if (attrs.hasOwnProperty(k)) el.setAttribute(k, attrs[k]);
return el;
}
var svg = makeSVG("svg" , {'viewBox': '0 0 ' + String(nCount) + " " + String(nCount), 'width': '100%', 'height': '100%', 'fill': _htOption.colorLight});
svg.setAttributeNS("http://www.w3.org/2000/xmlns/", "xmlns:xlink", "http://www.w3.org/1999/xlink");
_el.appendChild(svg);
svg.appendChild(makeSVG("rect", {"fill": _htOption.colorLight, "width": "100%", "height": "100%"}));
svg.appendChild(makeSVG("rect", {"fill": _htOption.colorDark, "width": "1", "height": "1", "id": "template"}));
for (var row = 0; row < nCount; row++) {
for (var col = 0; col < nCount; col++) {
if (oQRCode.isDark(row, col)) {
var child = makeSVG("use", {"x": String(col), "y": String(row)});
child.setAttributeNS("http://www.w3.org/1999/xlink", "href", "#template")
svg.appendChild(child);
}
}
}
};
Drawing.prototype.clear = function () {
while (this._el.hasChildNodes())
this._el.removeChild(this._el.lastChild);
};
return Drawing;
})();
var useSVG = document.documentElement.tagName.toLowerCase() === "svg";
// Drawing in DOM by using Table tag
var Drawing = useSVG ? svgDrawer : !_isSupportCanvas() ? (function () {
var Drawing = function (el, htOption) {
this._el = el;
this._htOption = htOption;
};
/**
* Draw the QRCode
*
* @param {QRCode} oQRCode
*/
Drawing.prototype.draw = function (oQRCode) {
var _htOption = this._htOption;
var _el = this._el;
var nCount = oQRCode.getModuleCount();
var nWidth = Math.floor(_htOption.width / nCount);
var nHeight = Math.floor(_htOption.height / nCount);
var aHTML = ['<table style="border:0;border-collapse:collapse;">'];
for (var row = 0; row < nCount; row++) {
aHTML.push('<tr>');
for (var col = 0; col < nCount; col++) {
aHTML.push('<td style="border:0;border-collapse:collapse;padding:0;margin:0;width:' + nWidth + 'px;height:' + nHeight + 'px;background-color:' + (oQRCode.isDark(row, col) ? _htOption.colorDark : _htOption.colorLight) + ';"></td>');
}
aHTML.push('</tr>');
}
aHTML.push('</table>');
_el.innerHTML = aHTML.join('');
// Fix the margin values as real size.
var elTable = _el.childNodes[0];
var nLeftMarginTable = (_htOption.width - elTable.offsetWidth) / 2;
var nTopMarginTable = (_htOption.height - elTable.offsetHeight) / 2;
if (nLeftMarginTable > 0 && nTopMarginTable > 0) {
elTable.style.margin = nTopMarginTable + "px " + nLeftMarginTable + "px";
}
};
/**
* Clear the QRCode
*/
Drawing.prototype.clear = function () {
this._el.innerHTML = '';
};
return Drawing;
})() : (function () { // Drawing in Canvas
function _onMakeImage() {
this._elImage.src = this._elCanvas.toDataURL("image/png");
this._elImage.style.display = "block";
this._elCanvas.style.display = "none";
}
// Android 2.1 bug workaround
// http://code.google.com/p/android/issues/detail?id=5141
if (this._android && this._android <= 2.1) {
var factor = 1 / window.devicePixelRatio;
var drawImage = CanvasRenderingContext2D.prototype.drawImage;
CanvasRenderingContext2D.prototype.drawImage = function (image, sx, sy, sw, sh, dx, dy, dw, dh) {
if (("nodeName" in image) && /img/i.test(image.nodeName)) {
for (var i = arguments.length - 1; i >= 1; i--) {
arguments[i] = arguments[i] * factor;
}
} else if (typeof dw == "undefined") {
arguments[1] *= factor;
arguments[2] *= factor;
arguments[3] *= factor;
arguments[4] *= factor;
}
drawImage.apply(this, arguments);
};
}
/**
* Check whether the user's browser supports Data URI or not
*
* @private
* @param {Function} fSuccess Occurs if it supports Data URI
* @param {Function} fFail Occurs if it doesn't support Data URI
*/
function _safeSetDataURI(fSuccess, fFail) {
var self = this;
self._fFail = fFail;
self._fSuccess = fSuccess;
// Check it just once
if (self._bSupportDataURI === null) {
var el = document.createElement("img");
var fOnError = function() {
self._bSupportDataURI = false;
if (self._fFail) {
self._fFail.call(self);
}
};
var fOnSuccess = function() {
self._bSupportDataURI = true;
if (self._fSuccess) {
self._fSuccess.call(self);
}
};
el.onabort = fOnError;
el.onerror = fOnError;
el.onload = fOnSuccess;
el.src = "data:image/gif;base64,iVBORw0KGgoAAAANSUhEUgAAAAUAAAAFCAYAAACNbyblAAAAHElEQVQI12P4//8/w38GIAXDIBKE0DHxgljNBAAO9TXL0Y4OHwAAAABJRU5ErkJggg=="; // the Image contains 1px data.
return;
} else if (self._bSupportDataURI === true && self._fSuccess) {
self._fSuccess.call(self);
} else if (self._bSupportDataURI === false && self._fFail) {
self._fFail.call(self);
}
};
/**
* Drawing QRCode by using canvas
*
* @constructor
* @param {HTMLElement} el
* @param {Object} htOption QRCode Options
*/
var Drawing = function (el, htOption) {
this._bIsPainted = false;
this._android = _getAndroid();
this._htOption = htOption;
this._elCanvas = document.createElement("canvas");
this._elCanvas.width = htOption.width;
this._elCanvas.height = htOption.height;
el.appendChild(this._elCanvas);
this._el = el;
this._oContext = this._elCanvas.getContext("2d");
this._bIsPainted = false;
this._elImage = document.createElement("img");
this._elImage.alt = "Scan me!";
this._elImage.style.display = "none";
this._el.appendChild(this._elImage);
this._bSupportDataURI = null;
};
/**
* Draw the QRCode
*
* @param {QRCode} oQRCode
*/
Drawing.prototype.draw = function (oQRCode) {
var _elImage = this._elImage;
var _oContext = this._oContext;
var _htOption = this._htOption;
var nCount = oQRCode.getModuleCount();
var nWidth = _htOption.width / nCount;
var nHeight = _htOption.height / nCount;
var nRoundedWidth = Math.round(nWidth);
var nRoundedHeight = Math.round(nHeight);
_elImage.style.display = "none";
this.clear();
for (var row = 0; row < nCount; row++) {
for (var col = 0; col < nCount; col++) {
var bIsDark = oQRCode.isDark(row, col);
var nLeft = col * nWidth;
var nTop = row * nHeight;
_oContext.strokeStyle = bIsDark ? _htOption.colorDark : _htOption.colorLight;
_oContext.lineWidth = 1;
_oContext.fillStyle = bIsDark ? _htOption.colorDark : _htOption.colorLight;
_oContext.fillRect(nLeft, nTop, nWidth, nHeight);
// 안티 앨리어싱 방지 처리
_oContext.strokeRect(
Math.floor(nLeft) + 0.5,
Math.floor(nTop) + 0.5,
nRoundedWidth,
nRoundedHeight
);
_oContext.strokeRect(
Math.ceil(nLeft) - 0.5,
Math.ceil(nTop) - 0.5,
nRoundedWidth,
nRoundedHeight
);
}
}
this._bIsPainted = true;
};
/**
* Make the image from Canvas if the browser supports Data URI.
*/
Drawing.prototype.makeImage = function () {
if (this._bIsPainted) {
_safeSetDataURI.call(this, _onMakeImage);
}
};
/**
* Return whether the QRCode is painted or not
*
* @return {Boolean}
*/
Drawing.prototype.isPainted = function () {
return this._bIsPainted;
};
/**
* Clear the QRCode
*/
Drawing.prototype.clear = function () {
this._oContext.clearRect(0, 0, this._elCanvas.width, this._elCanvas.height);
this._bIsPainted = false;
};
/**
* @private
* @param {Number} nNumber
*/
Drawing.prototype.round = function (nNumber) {
if (!nNumber) {
return nNumber;
}
return Math.floor(nNumber * 1000) / 1000;
};
return Drawing;
})();
/**
* Get the type by string length
*
* @private
* @param {String} sText
* @param {Number} nCorrectLevel
* @return {Number} type
*/
function _getTypeNumber(sText, nCorrectLevel) {
var nType = 1;
var length = _getUTF8Length(sText);
for (var i = 0, len = QRCodeLimitLength.length; i <= len; i++) {
var nLimit = 0;
switch (nCorrectLevel) {
case QRErrorCorrectLevel.L :
nLimit = QRCodeLimitLength[i][0];
break;
case QRErrorCorrectLevel.M :
nLimit = QRCodeLimitLength[i][1];
break;
case QRErrorCorrectLevel.Q :
nLimit = QRCodeLimitLength[i][2];
break;
case QRErrorCorrectLevel.H :
nLimit = QRCodeLimitLength[i][3];
break;
}
if (length <= nLimit) {
break;
} else {
nType++;
}
}
if (nType > QRCodeLimitLength.length) {
throw new Error("Too long data");
}
return nType;
}
function _getUTF8Length(sText) {
var replacedText = encodeURI(sText).toString().replace(/\%[0-9a-fA-F]{2}/g, 'a');
return replacedText.length + (replacedText.length != sText ? 3 : 0);
}
/**
* @class QRCode
* @constructor
* @example
* new QRCode(document.getElementById("test"), "http://jindo.dev.naver.com/collie");
*
* @example
* var oQRCode = new QRCode("test", {
* text : "http://naver.com",
* width : 128,
* height : 128
* });
*
* oQRCode.clear(); // Clear the QRCode.
* oQRCode.makeCode("http://map.naver.com"); // Re-create the QRCode.
*
* @param {HTMLElement|String} el target element or 'id' attribute of element.
* @param {Object|String} vOption
* @param {String} vOption.text QRCode link data
* @param {Number} [vOption.width=256]
* @param {Number} [vOption.height=256]
* @param {String} [vOption.colorDark="#000000"]
* @param {String} [vOption.colorLight="#ffffff"]
* @param {QRCode.CorrectLevel} [vOption.correctLevel=QRCode.CorrectLevel.H] [L|M|Q|H]
*/
QRCode = function (el, vOption) {
this._htOption = {
width : 256,
height : 256,
typeNumber : 4,
colorDark : "#000000",
colorLight : "#ffffff",
correctLevel : QRErrorCorrectLevel.H
};
if (typeof vOption === 'string') {
vOption = {
text : vOption
};
}
// Overwrites options
if (vOption) {
for (var i in vOption) {
this._htOption[i] = vOption[i];
}
}
if (typeof el == "string") {
el = document.getElementById(el);
}
if (this._htOption.useSVG) {
Drawing = svgDrawer;
}
this._android = _getAndroid();
this._el = el;
this._oQRCode = null;
this._oDrawing = new Drawing(this._el, this._htOption);
if (this._htOption.text) {
this.makeCode(this._htOption.text);
}
};
/**
* Make the QRCode
*
* @param {String} sText link data
*/
QRCode.prototype.makeCode = function (sText) {
this._oQRCode = new QRCodeModel(_getTypeNumber(sText, this._htOption.correctLevel), this._htOption.correctLevel);
this._oQRCode.addData(sText);
this._oQRCode.make();
this._el.title = sText;
this._oDrawing.draw(this._oQRCode);
this.makeImage();
};
/**
* Make the Image from Canvas element
* - It occurs automatically
* - Android below 3 doesn't support Data-URI spec.
*
* @private
*/
QRCode.prototype.makeImage = function () {
if (typeof this._oDrawing.makeImage == "function" && (!this._android || this._android >= 3)) {
this._oDrawing.makeImage();
}
};
/**
* Clear the QRCode
*/
QRCode.prototype.clear = function () {
this._oDrawing.clear();
};
/**
* @name QRCode.CorrectLevel
*/
QRCode.CorrectLevel = QRErrorCorrectLevel;
})();

48
js/szatuna.js Normal file
View File

@ -0,0 +1,48 @@
/* Raktárhely szép kiírtás */
function NumberToABC(n) {
const abc = 'ABCDEFGHIJKLMNOPQRSTUVWXYZ';
if (typeof n === 'string') {
const num = parseInt(n, 10);
if (isNaN(num) || num < 1 || num > 26) return null;
return abc.charAt(num - 1);
}
if (typeof n !== 'number' || n < 1 || n > 26) return null;
return abc.charAt(n - 1);
}
function padWithZero(str) {
if (str.length === 2) return str;
return str.toString().padStart(2, '0');
}
/* Menu elemek */
function fitMenuTexts() {
const buttons = document.querySelectorAll('.menubtn');
let minFontSize = 14;
buttons.forEach(btn => {
const p = btn.querySelector('p');
if (!p) return;
const availableWidth = btn.clientWidth - 10 - 36 - 15 - 10;
if (availableWidth <= 0) return;
p.style.whiteSpace = 'nowrap';
let fontSize = 14;
p.style.fontSize = fontSize + 'px';
while (p.scrollWidth > availableWidth && fontSize > 0.1) {
fontSize -= 0.1;
p.style.fontSize = fontSize + 'px';
}
if (fontSize < minFontSize) minFontSize = fontSize;
});
buttons.forEach(btn => {
const p = btn.querySelector('p');
if (p) p.style.fontSize = minFontSize + 'px';
});
}
fitMenuTexts();

25601
js/user-agents_bot-crawler.txt Normal file

File diff suppressed because it is too large Load Diff

24
js/xlsx.full.min.js vendored Normal file

File diff suppressed because one or more lines are too long

1424
managers/OrderProcessor.php Normal file

File diff suppressed because it is too large Load Diff

View File

@ -0,0 +1,217 @@
<?php
include 'cookie.php';
require_once 'mail.php';
header('Content-Type: application/json');
try {
$input = file_get_contents('php://input');
$data = json_decode($input, true);
if (!$data) {
throw new Exception('Hibás JSON adatok');
}
if (empty($data['description']) || empty($data['url'])) {
throw new Exception('Hiányzó kötelező mezők');
}
$bugReportDir = 'bugreport';
if (!is_dir($bugReportDir)) {
mkdir($bugReportDir, 0755, true);
}
$timestamp = date('Y-m-d_H-i-s');
$randomId = substr(md5(uniqid()), 0, 8);
$filePrefix = $timestamp . '_' . $randomId;
$attachments = [];
$toEmailAttachments = [];
// Console logok mentése (log.txt)
if (!empty($data['logs'])) {
$logFile = $bugReportDir . '/log_' . $filePrefix . '.txt';
$logContent = "=== CONSOLE LOGS ===\n";
$logContent .= "Időpont: " . ($data['timestamp'] ?? date('c')) . "\n";
$logContent .= "URL: " . $data['url'] . "\n";
$logContent .= "User Agent: " . ($data['userAgent'] ?? 'N/A') . "\n";
$logContent .= "\n=== FELHASZNÁLÓ ADATAI ===\n";
$logContent .= "Név: ". (isset($userName) ? $userName : 'N/A') . " (" . (isset($userID) ? $userID : 'N/A') . ")" . "\n";
$logContent .= "Jogosultságok: ". (isset($userPermsList) ? $userPermsList : 'N/A') ." \n";
$logContent .= "Hiba leírása: " . ($data['description'] ?? 'N/A') . "\n";
$logContent .= "\n=== LOGOK ===\n";
foreach ($data['logs'] as $log) {
$logContent .= $log . "\n";
}
file_put_contents($logFile, $logContent);
$attachments[] = $logFile;
$toEmailAttachments[] = $logFile;
}
// Browser adatok mentése (browser.txt)
if (!empty($data['browserData'])) {
$browserFile = $bugReportDir . '/browser_' . $filePrefix . '.txt';
$browserContent = "\n=== FELHASZNÁLÓ ADATAI ===\n";
$browserContent .= "Név: ". (isset($userName) ? $userName : 'N/A') . " (" . (isset($userID) ? $userID : 'N/A') . ")" . "\n";
$browserContent .= "Jogosultságok: ". (isset($userPermsList) ? $userPermsList : 'N/A') ." \n";
$browserContent .= "Hiba leírása: " . ($data['description'] ?? 'N/A') . "\n";
$browserContent .= "\n=== Böngésző adatai ===\n";
foreach ($data['browserData'] as $browser) {
$browserContent .= $browser . "\n";
}
file_put_contents($browserFile, $browserContent);
$attachments[] = $browserFile;
}
// Screenshot mentése
if (!empty($data['screenshot'])) {
$screenshotFile = $bugReportDir . '/screenshot_' . $filePrefix . '.png';
$screenshotData = $data['screenshot'];
if (strpos($screenshotData, 'data:image/png;base64,') === 0) {
$screenshotData = substr($screenshotData, strlen('data:image/png;base64,'));
}
$decodedImage = base64_decode($screenshotData);
if ($decodedImage !== false) {
file_put_contents($screenshotFile, $decodedImage);
$attachments[] = $screenshotFile;
$toEmailAttachments[] = $screenshotFile;
}
}
if (!empty($data['screenshotFull'])) {
$screenshotFile = $bugReportDir . '/screenshotFull_' . $filePrefix . '.png';
$screenshotData = $data['screenshotFull'];
if (strpos($screenshotData, 'data:image/png;base64,') === 0) {
$screenshotData = substr($screenshotData, strlen('data:image/png;base64,'));
}
$decodedImage = base64_decode($screenshotData);
if ($decodedImage !== false) {
file_put_contents($screenshotFile, $decodedImage);
$attachments[] = $screenshotFile;
$toEmailAttachments[] = $screenshotFile;
}
}
if (!empty($data['screenshotPainted'])) {
$screenshotFile = $bugReportDir . '/screenshotPainted_' . $filePrefix . '.png';
$screenshotData = $data['screenshotPainted'];
if (strpos($screenshotData, 'data:image/png;base64,') === 0) {
$screenshotData = substr($screenshotData, strlen('data:image/png;base64,'));
}
$decodedImage = base64_decode($screenshotData);
if ($decodedImage !== false) {
file_put_contents($screenshotFile, $decodedImage);
$attachments[] = $screenshotFile;
$toEmailAttachments[] = $screenshotFile;
}
}
// Email tartalom összeállítása
$AttachmentsDiff = array_diff($attachments, $toEmailAttachments);
$subject = 'BUG REPORT - ' . date('Y-m-d H:i:s');
$emailContent = "<h2>=== SZATURNUSZ HIBABEJELENTÉS ===</h2><br><br>";
$emailContent .= "<b>FELHASZNÁLÓ ADATOK:</b><br>";
$emailContent .= "<b>Név: </b>" . (isset($userName) ? $userName : 'N/A') . " (" . (isset($userID) ? $userID : 'N/A') . ")" . "<br>";
$emailContent .= "<b>Jogosultságok: </b>" . (isset($userPermsList) ? $userPermsList : 'N/A') . "<br><br>";
$emailContent .= "<b>HIBA LEÍRÁSA:</b><br>";
$emailContent .= $data['description'] . "<br><br>";
$emailContent .= "<b>TECHNIKAI ADATOK</b>:<br>";
$emailContent .= "<b>URL: </b>" . $data['url'] . "<br>";
$emailContent .= "<b>Időpont: </b>" . ($data['timestamp'] ?? date('c')) . "<br>";
$emailContent .= "<b>User Agent: </b>" . ($data['userAgent'] ?? 'N/A') . "<br>";
$emailContent .= "<b>Szerver IP: </b>" . $_SERVER['SERVER_ADDR'] . "<br>";
$emailContent .= "<b>Kliens IP: </b>" . $_SERVER['REMOTE_ADDR'] . "<br><br>";
$emailContent .= "<b>CSATOLMÁNYOK:</b><br>";
foreach ($toEmailAttachments as $attachment) {
$emailContent .= "- " . basename($attachment) . "<br>";
}
$emailContent .= "<br><b>SZERVEREN PLUSZ FÁJL:</b><br>";
foreach ($AttachmentsDiff as $attachment) {
$emailContent .= "- " . basename($attachment) . "<br>";
}
// Email küldése
$recipient_email = 'sperg.tamas@gmail.com';
$recipient_name = 'Sperg Tamás';
$attachment_path = null;
$zipFile = null;
$zip = null;
if (count($toEmailAttachments) === 1) {
$attachment_path = $toEmailAttachments[0];
} elseif (count($toEmailAttachments) > 1) {
$zipFile = $bugReportDir . '/report_' . $filePrefix . '.zip';
$zip = new ZipArchive();
if ($zip->open($zipFile, ZipArchive::CREATE) === TRUE) {
foreach ($toEmailAttachments as $file) {
$zip->addFile($file, basename($file));
}
$zip->close();
$attachment_path = $zipFile;
}
}
$res_mail = sendFormattedEmail($recipient_email, $recipient_name, $subject, $emailContent, $attachment_path);
/* Csatolmány Management */
if (isset($zipFile) && file_exists($zipFile)) {
foreach ($toEmailAttachments as $file) {
if (file_exists($file)) {
unlink($file);
}
}
}
if (count($AttachmentsDiff) > 0) {
if ($zip == null) {
$zipFile = $bugReportDir . '/report_' . $filePrefix . '.zip';
$zip = new ZipArchive();
}
if ($zip->open($zipFile, ZipArchive::CREATE) === TRUE) {
foreach ($AttachmentsDiff as $file) {
$zip->addFile($file, basename($file));
}
$zip->close();
}
foreach ($AttachmentsDiff as $file) {
if (file_exists($file)) {
unlink($file);
}
}
}
echo json_encode([
'success' => true,
'message' => 'Hibabejelentés sikeresen elküldve',
'email_result' => $res_mail
]);
} catch (Exception $e) {
http_response_code(500);
echo json_encode([
'success' => false,
'error' => $e->getMessage()
]);
}
?>

111
managers/code.php Normal file
View File

@ -0,0 +1,111 @@
<?php
class coder {
public static function decode($string, $key) {
$result = '';
for ($i = 0; $i < strlen($string); $i+=2) {
$result .= chr(hexdec($string[$i].$string[($i + 1)]));
}
$string = base64_decode($result);
$result = '';
for($i = 0; $i < strlen($string); $i++) {
$char = substr($string, $i, 1);
$keychar = substr($key, ($i % strlen($key)) - 1, 1);
$char = chr(ord($char) - ord($keychar));
$result .= $char;
}
return $result;
}
public static function encode($string, $key) {
$result = '';
for($i = 0; $i < strlen($string); $i++) {
$char = substr($string, $i, 1);
$keychar = substr($key, ($i % strlen($key)) - 1, 1);
$char = chr(ord($char) + ord($keychar));
$result .= $char;
}
$result = base64_encode($result);
$result = bin2hex($result);
return $result;
}
public static function base64($string) {
$path = $string;
$type = pathinfo($path, PATHINFO_EXTENSION);
$data = file_get_contents($path);
$base64 = 'data:image/' . $type . ';base64,' . base64_encode($data);
return $base64;
}
public static function today_private_key() {
$days_name = ['VasárnaP', 'HétfŐ', 'KedD', 'SzerdA', 'CsütörtöK', 'PénteK', 'SzombaT'];
$daily_key = date('Y-m-d').'-'.$_SERVER['REMOTE_ADDR'].'-'.$days_name[date('w')];
$private_key = hash('sha256', $daily_key);
return $private_key;
}
}
class TOTP {
private $alphabet = "ABCDEFGHIJKLMNOPQRSTUVWXYZ234567";
public function getOtp($key) {
$binary_key = $this->base32Decode(str_replace(" ", "", strtoupper($key)));
$timeSlice = floor(time() / 30);
$binary_timestamp = pack('N*', 0) . pack('N*', $timeSlice);
$hash = hash_hmac('sha1', $binary_timestamp, $binary_key, true);
$offset = ord($hash[19]) & 0xf;
$otp = (
((ord($hash[$offset + 0]) & 0x7f) << 24) |
((ord($hash[$offset + 1]) & 0xff) << 16) |
((ord($hash[$offset + 2]) & 0xff) << 8) |
(ord($hash[$offset + 3]) & 0xff)
) % 1000000;
return str_pad($otp, 6, '0', STR_PAD_LEFT);
}
private function base32Decode($base32) {
$binary_key = '';
$n = 0;
$j = 0;
for ($i = 0; $i < strlen($base32); $i++) {
$n = $n << 5;
$n += strpos($this->alphabet, $base32[$i]);
$j += 5;
if ($j >= 8) {
$j -= 8;
$binary_key .= chr(($n & (0xFF << $j)) >> $j);
}
}
return $binary_key;
}
public function isValidKey($secret, $CheckLength = true) {
if (strlen($secret) < 16 && $CheckLength) {
return false;
}
$pattern = '/^[A-Z2-7]+$/';
if (!preg_match($pattern, $secret)) {
return false;
}
return true;
}
public function generateKey($length = 16) {
$characters = 'ABCDEFGHIJKLMNOPQRSTUVWXYZ234567';
$charactersLength = strlen($characters);
$randomString = '';
for ($i = 0; $i < $length; $i++) {
$randomString .= $characters[rand(0, $charactersLength - 1)];
}
return $randomString;
}
}
?>

95
managers/cookie.php Normal file
View File

@ -0,0 +1,95 @@
<?php
setlocale(LC_COLLATE, 'hu_HU.UTF-8');
date_default_timezone_set('Europe/Budapest');
header('X-Frame-Options: SAMEORIGIN');
include 'code.php';
include 'dbconn.php';
include 'log.php';
$coderclass = new coder;
$loggerclass = new Logger;
$protocol = (!empty($_SERVER['HTTPS']) && $_SERVER['HTTPS'] !== 'off') ? "https://" : "http://";
$host = $_SERVER['HTTP_HOST'];
$currentUrl = $protocol . $host;
$currentAdvancedUrl = str_replace('.php', '', $currentUrl.$_SERVER['REQUEST_URI']);
ini_set('session.cookie_httponly', 1);
ini_set('session.cookie_secure', 1);
session_set_cookie_params([
'lifetime' => 0,
'path' => '/',
'domain' => $_SERVER['HTTP_HOST'],
'secure' => true,
'httponly' => true,
'samesite' => 'Strict'
]);
session_start();
$auth_cookie = htmlspecialchars($_COOKIE['auth_token'] ?? '');
$userID = $coderclass->decode($auth_cookie, $coderclass->today_private_key());
$userName = "User";
$sql = mysqli_query($conn,"SELECT full_name, perms, status FROM users WHERE uid = '$userID'");
$userSQL = mysqli_fetch_array($sql);
if (!UserHasPerm()) {
die('|$6b4ea69e17243db95f7b46c384d40370$|!<script type="text/javascript">window.location="'.$currentUrl.'/managers/logout.php";</script>');
} else {
setcookie("auth_token", $_COOKIE['auth_token'], [ 'expires' => time() + 3600, 'path' => "/", 'domain' => $_SERVER['SERVER_NAME'], 'secure' => true, 'httponly' => true, 'samesite' => 'Strict' ]);
setcookie('auth_timer', time() + 3600, ['expires' => time() + 3610, 'path' => '/', 'domain' => $_SERVER['SERVER_NAME'],'secure' => true,'httponly' => false, 'samesite' => 'Strict']);
$userName = $coderclass->decode($userSQL[0], "TIT4");
$loggerclass->init($userID);
}
setcookie("lastURL", urlencode($currentAdvancedUrl), time() + 3600, "/");
$userPermsList = $coderclass->decode($userSQL[1], 'AFDG');
function UserHasPerm($the_perm = "log_in") {
global $userSQL, $userPermsList, $conn;
$the_perm = htmlspecialchars($the_perm);
if ($the_perm == "log_in") {
if ($userSQL == null) {
return false;
} else if ($userSQL[2] == 1) {
return true;
}
} else {
if (str_contains($userPermsList, 'god_profile')) {
$permsql = mysqli_query($conn, "SELECT perm_status FROM perm_database WHERE perm_id = 'god_profile'");
$permsqlfetch = mysqli_fetch_array($permsql);
if ($permsqlfetch == null) {
return false;
} else if ($permsqlfetch[0] != 2) {
} else {
return true;
}
}
if (str_contains($userPermsList, $the_perm)) {
$permsql = mysqli_query($conn, "SELECT perm_status FROM perm_database WHERE perm_id = '$the_perm'");
$permsqlfetch = mysqli_fetch_array($permsql);
if ($permsqlfetch == null) {
return false;
} else if ($permsqlfetch[0] == 0) {
return false;
} else {
return true;
}
}
}
return false;
}
?>

12
managers/dbconn.php Normal file
View File

@ -0,0 +1,12 @@
<?php
$servername = "localhost";
$username = "szatunaweb";
$password = "5vZb.0GfLEB2E!";
$serverdb = "szatuna";
$conn = new mysqli($servername, $username, $password, $serverdb);
/* Joga van: SELECT, INSERT, UPDATE */
?>

17
managers/devplan.json Normal file
View File

@ -0,0 +1,17 @@
{
"plans": [
"LOG",
"Termékgyártás - os szabad raktáras elemeinek kiemelése",
"Készletinformáció APIn a 0-ás raktárkészletnek is szerepelnie kell",
"Gyártás lezárása elött a raktározási lépésre kötelezés",
"Felkiáltó jeles kártyák előre sorolása",
"Lezárt gyártások ÖSSZES szűrő",
"Több márka és típus \/ cikkszám katalógusadatok frissítés",
"Termék katalógus letöltés",
"Hátsó cikkszámok doboz mennyisége a szettben szereplő mennyisége legyen",
"Árazás törlés és árfolyam számolás funkciója",
"Rendeléseknél vevőtípus megadása",
"Bugreport ticketing rendszerré bővítése",
"Kimenő levél módosító menu"
]
}

64
managers/log.php Normal file
View File

@ -0,0 +1,64 @@
<?php
class Logger {
private static $conn = null;
private static $userId;
public static function init($userId) {
self::$userId = $userId;
}
private static function dbconn() {
$servername = "localhost";
$username = "szatunaweb";
$password = "5vZb.0GfLEB2E!";
$serverdb = "log";
if (self::$conn === null) {
self::$conn = new mysqli($servername, $username, $password, $serverdb);
}
/* Joga van: SELECT, INSERT */
return self::$conn;
}
public static function writeLogWarehouse($params) {
$conn = self::dbconn();
$date_create = time();
$protocol = isset($_SERVER['HTTPS']) && $_SERVER['HTTPS'] === 'on' ? 'https' : 'http';
$full_url = $protocol . '://' . $_SERVER['HTTP_HOST'] . $_SERVER['REQUEST_URI'];
$referrer_url = $_SERVER['HTTP_REFERER'] ?? $full_url;
$reason = $params['reason'] ?? '';
$reason_code = $params['reason_code'] ?? 0;
$item_id = $params['item_id'] ?? '';
$from_place = $params['from_place'] ?? '';
$to_place = $params['to_place'] ?? '';
$amount_left = $params['amount_left'] ?? 0;
$amount_right = $params['amount_right'] ?? 0;
if (empty(trim($reason))) {
die('LOG ERROR - Nem lett specifikálva indoklás!');
}
$stmt = $conn->prepare("INSERT INTO warehouse(date_create, user_id, url, reason, reason_code, item_id, from_place, to_place, amount_left, amount_right) VALUES (?,?,?,?,?,?,?,?,?,?)");
$stmt->bind_param("iississsii",
$date_create, self::$userId,
$referrer_url, $reason, $reason_code,
$item_id, $from_place, $to_place,
$amount_left, $amount_right);
$stmt->execute();
if (!empty(trim($item_id))) {
$_GET['type'] = 'daily';
$_GET['item_id'] = $item_id;
$_GET['silent'] = true;
include 'statistics.php';
}
return;
}
}
?>

20
managers/logout.php Normal file
View File

@ -0,0 +1,20 @@
<?php
ini_set('session.cookie_httponly', 1);
ini_set('session.cookie_secure', 1);
session_set_cookie_params([
'lifetime' => 0,
'path' => '/',
'domain' => $_SERVER['HTTP_HOST'],
'secure' => true,
'httponly' => true,
'samesite' => 'Strict'
]);
session_start();
setcookie('auth_token', '', [ 'expires' => time() - 3600, 'path' => '/', 'domain' => $_SERVER['SERVER_NAME'], 'secure' => true, 'httponly' => true, 'samesite' => 'Strict']);
header("Location: ../");
session_destroy();
?>

78
managers/mail.php Normal file
View File

@ -0,0 +1,78 @@
<?php
require __DIR__.'/../vendor/autoload.php';
use PHPMailer\PHPMailer\PHPMailer;
use PHPMailer\PHPMailer\Exception;
use PHPMailer\PHPMailer\SMTP;
function sendFormattedEmail($recipient_email, $recipient_name, $subject, $content, $attachment_path = null) {
$mail = new PHPMailer(true);
try {
$mail->isSMTP();
$mail->Host = 'localhost';
$mail->SMTPAuth = false;
$mail->Port = 25;
$mail->CharSet = 'UTF-8';
$mail->setLanguage('hu');
$mail->XMailer = false;
unset($mail->Headers['X-Mailer']);
$mail->Mailer = 'smtp';
$mail->setFrom('szaturnusz@szatuna.hu', 'Szatuna Kft');
$mail->addReplyTo('kapcsolat@szatuna.hu', 'Szatuna Kft');
$templatePath = __DIR__ . '/template/mail.html';
if (!file_exists($templatePath)) {
return ['success'=>false,'message'=>'Sablon nem található: '.$templatePath];
}
$html_template = file_get_contents($templatePath);
$html_body = str_replace('{{SUBJECT}}', $subject, $html_template);
$localIP = trim(shell_exec('hostname -I | cut -d" " -f1'));
if ($localIP == '192.168.15.10') {
$recipient_list = explode(",", $recipient_email);
for ($i=0; $i < count($recipient_list); $i++) {
$mail->addBCC(trim($recipient_list[$i]), $recipient_name);
}
$html_body = str_replace('{{CONTENT}}', $content, $html_body);
} else {
$content .= '<br clear="all"><br><br><p style="color: green;">TEST ENVIROMENT!<br> - Recipient email: '.$recipient_email.'<br> - Recipient name: '.$recipient_name.'</p>';
$html_body = str_replace('{{CONTENT}}', $content, $html_body);
$mail->addAddress("sperg.tamas@gmail.com", "Sperg Tamás");
}
$mail->isHTML(true);
$mail->Subject = $subject;
$imgPath = __DIR__ . '/../img/szatunalogo.png';
$mail->addEmbeddedImage($imgPath, 'logo_cid', 'szatunalogo.png');
$mail->Body = $html_body;
$mail->AltBody = strip_tags($content);
if ($attachment_path) {
if (is_array($attachment_path)) {
foreach ($attachment_path as $file) {
if (file_exists($file)) {
$mail->addAttachment($file);
}
}
} elseif (is_string($attachment_path) && file_exists($attachment_path)) {
$mail->addAttachment($attachment_path);
}
}
$mail->send();
return ['success' => true, 'message' => 'Levél elküldve.'];
} catch (Exception $e) {
return ['success' => false, 'message' => "Nem sikerült elküldeni a levelet. Hiba: {$mail->ErrorInfo}"];
}
}
?>

309
managers/menu.php Normal file
View File

@ -0,0 +1,309 @@
<?php
include 'cookie.php';
$linkHome = "'../dashboard'";
/* Terméklista */
$linkProductCatalog = "'products'";
$linkItemCreator = "'itemcreator'";
$linkMontlyStat = "'monthlystat'";
/* Gyártás */
$linkProduction = "'production'";
$linkBoxing = "'boxing'";
$linkProductionStat = "'productionstat'";
/* Rendeléskezelés */
$linkWarehouseOrders = "'wh_orders'";
$linkWarehouseReturnGoods = "'return_goods'";
$linkPricing = "'pricing'";
/* Raktárak */
$linkWarehouse = "'warehouse'";
$linkWarehouseAdd = "'wh_add'";
$linkWarehouseRemove = "'wh_remove'";
/* Fiók kezelés */
$linkProfile = "'profile'";
$linkUserEditor = "'usereditor'";
$linkPermEditor = "'permlist'";
$linkLogOut = "'../managers/logout.php'";
/* Indikátor */
function MenuIndicator($name) {
$current_url = (isset($_SERVER['HTTPS']) && $_SERVER['HTTPS'] === 'on' ? "https" : "http") . "://$_SERVER[HTTP_HOST]$_SERVER[REQUEST_URI]";
$parsed_url = parse_url($current_url);
$path = $parsed_url['path'];
$file_name = "'" . basename($path) . "'";
if ($name == $file_name) {
return '<div class="active"></div>';
}
return '';
}
/* Van e aktív fejlesztés */
$ServerLocalIP = trim(shell_exec('hostname -I | cut -d" " -f1'));
$sql = mysqli_query($conn,"SELECT param_value FROM system_params WHERE param_key = 'is_active_development'");
if (mysqli_fetch_array($sql)[0] == '1') {
$TextActiveDevelopment = '<p style="color: #FF4D00; display: inline-block;"><b>Aktív fejlesztés!</b> Hibák és esetleges leállások jelentkezhetnek!</p>';
} else if ($ServerLocalIP != '192.168.15.10') {
$TextActiveDevelopment = '<p style="color: green; display: inline-block;"><b>Teszt környezet</b> A jelenegi rendszer a teszt környezetben üzemel!</p>';
} else {
$TextActiveDevelopment = '';
}
$menuhtml = '<div class="top">
<div style="position: absolute; left: 220px;">'.$TextActiveDevelopment.'</div>
<span style="position: absolute; right: 10px; top: 25px; color: var(--panelcolor); opacity: 0.4;" id="TimeBeforeLogOutSpan"></span>
<div class="title">
<a href="#menu"><img src="data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAGAAAABgCAYAAADimHc4AAAABmJLR0QA/wD/AP+gvaeTAAAAhElEQVR4nO3awQnAMAwEQSv996y0EIPF4TDzNwjv99YCAAAAAAAA4K9q90F398Qhf1FVW3/6TB3CNwKECRAmQJgAYQKECQAAAAAAADDMLugwu6DLCBAmQJgAYQKECRAmAAAAAAAAwDC7oMPsgi4jQJgAYQKECRAmQJgAAAAAAAAAADDkBY73DC4/UsNcAAAAAElFTkSuQmCC"></a>
<p>Kezelőfelület</p>
</div>
<div class="profile" onclick="window.location='.$linkProfile.';">
<img src="data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAADAAAAAwCAYAAABXAvmHAAAACXBIWXMAAAsTAAALEwEAmpwYAAAD/klEQVR4nO2Yb2gTZxzHb3u5F3bCXdUXTjuLvau6DhR14By+0Pln2kISROsrNy9VVEQRxW4+VyesL3y5DZQpDAfDf/hCU+9pNGtyTVuaf64ts7ZgQ6y2Kkn/LWnSNv2N59rcIv2bXLyLkB984Xjuud/z+eSeu4NQVK5ylatcJZdkZkoch/Lv2Hm6x8HTUYeZgRnST2VbSUfoa7MAvxU7z7ipbKnG40s3ec4tb50vvJwKpsHNL/lIb3aqns+vcFTkx1OCT4RnPNLhvIW6wdvNdHVa4MlbyczU6ALvOER/ZTcz42oFHGYGJJ4xaS/AM5YEQNtPLESl3TDSUAqvb22G9kurofn0J+A8uhicxxaDt7IAui6vhUG8DcaayyAqfQOPz69Iugu0VXsBM9NHFnedWQZxtwHAZ0wpo42l0Hh8SWIbBXUQoP8li7+6+WXK8IkErq2ffJjpIT0EntUfWRRP59dPJObcDVJFPhHo1EOgofVi0Ui68Il4KwtGHTzj0FzAzjNXu66si6sV6Pz58zjppYMAfeLVjc2q4MFnlN9apJem8OA1FQfvbukexF+rFgg/2gmkF3j2ctoJPDadJO/8kaYy1QJjzWUQc+4B0lM7Aa9hh1rwKfGYtmsn0FS+AHzGJxkUeEJ6aiagiGRIgNKrwGeIqBcwRHQUMDZmQKBBRwHDAdUCXsM+/QQAfQg+oyV9eOM90kM3AVmiZf9C8BncaQi4wFf6MZUNBW5THviMNSnAW3R5bc5WANQHPffXw5h75q8zOUfmkLlUNlbn3a3Q/kch9Fo2Qrh+uwxMQo57LRug/XohkDlUNlURerCcQ7XnWCQ+DHZ7oePWF/DP7wXThpwjc1gBW8k13I/3l+kGzlY92MUKop1D4jgnYCAJDQzBUN8L8Fu/mwJPxsg5Micxn0Pi+ESP2p2aga9ENZ9xCNsUiKR0vAxCOByWE/LXwTOLQQ45Tox3vAhOuY6TZbCt6IJ1zTuFLxbEclbA4WkBBAy3XX4FtKk7AofrovCtLQZSYFgZv+3qml5AIBGHOSQefCfwnCBWzrzwRMp/a1JAr7ZFYcOdETm//h1VxsmcufqwSDybUfjiqlpT8l6fLb2hQRk0EIooAs9DEXmsJzgw5/Xc5LNRhMT9GYH/tNqaxwpi37wWFjD8Ynsqwz7yDysCNv/EFiLn5tuHQ2J/CfpL/ZeaReL5eS86mdehAbjc8v8WutIShTd9g7AqxT4cwt9nQAC3pSpgvu6CU/UxReC0MwbH/vSkBi/ID3WragEO4WjqC2MQ7G8UAXKcTg9OEIfVC6S18ER+kPrlqOlBqS1WwM/VAKgJi3BA/R2owjv0kGARDhQjUbu/WnKVK+r9rP8Agj27s/V2DZ4AAAAASUVORK5CYII=">
<div class="userNameDiv" id="userNameDiv"><p id="userNameP">'.$userName.'</p></div>
</div>
</div>
<div class="menu scrollable">
<div class="menubtn" onclick="window.location='.$linkHome.';">
'.MenuIndicator("'dashboard'").'
<img src="data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAADAAAAAwCAYAAABXAvmHAAAACXBIWXMAAAsTAAALEwEAmpwYAAACD0lEQVR4nO2YO0/CUBTH+zVcnDSmoMIgXKKDq8bEODkZVwejnwF8JzopuukGU0siOgjloZRJjRMaHHRQVyXRAQSTYw4+Ath7C1hp1ftP/gkBWs7vvHqDIHBxcXFxcb3LLZdG3HLxjshFsKSl4i0JlYYFmspfMDtIWRfihg5gdnByfeYApCIbqfgEXB/1Q1iZgem9JHjkZ2tXoC+QA4f/HOzLaRB9MXhJt1X5NDEG47tZ3fvsRBYgr7Z/uR6N729HFo0FcEsFcKxnQPRGQfRGPq0VQE7tgqk9lQnwpHZoXvvhR7XTOAAMvmf1uCpwFsAHBKsSmOE8qwIHS8YB9G5kNINnAaDPkqM/MhNCIwDY87VtUy8AGgfbVACH/5wafD0AYWXWXAA7bptvAFwdDmgG4dzMguhTtO/rU8CxlTUGwDYXYwKc7A8yAZLxSWjmvra5uFEAceYPNRsEZlhkVMC5edmaFmLZvpI2vP9Jw0O8wR5ilp3+C/MBXIEc2BhrlNo+3ii4gjnzAUi5CvQHGc24fllBtGwLEbRUgG7KUULLPWsnQHSewC3bQqQCAueB1U742Vvm9Y8PLdtCpHYmgnicvihvGMwiGl/jwP5UzxMjAaxggQPIvALAW0hLtKw8pETdYzPNTR8E5xPGDfF9yva7AYjFLPxdAOm3/7kbKg1bGkIq3njk0hAVgIuLi4vr3+kV2KuTy9D28uEAAAAASUVORK5CYII=">
<p>Áttekintés</p>
</div>';
/* Terméklista */
$isProduct = false;
if (UserHasPerm('pr_parameters_read') || UserHasPerm('pr_parameters_edit') || UserHasPerm("edit_item_introduction_basic_data")) {
$isProduct = true;
$menuhtml .= '
<p class="category">Terméklista</p>
<div class="menubtn" onclick="window.location='.$linkProductCatalog.';">
'.MenuIndicator($linkProductCatalog).'
<img src="data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAADAAAAAwCAYAAABXAvmHAAAACXBIWXMAAAsTAAALEwEAmpwYAAACeUlEQVR4nO2ZTU8TQRjHe5JXRZTW4ks8+wVYz3AAPgd60+/gga+iB+ma4A2LQCkUiiCWlmINHqTefAMbjCwyfzM7O7PD7jZhmymG+DzJLyE9/X4P02m2TSRoaGiazpB9tGzZDtrBvSczLvprw1P7mHyWxUplF49zv2FlnLr14ng80eq0S75ZgGU7GJnaR61Ww8cvDfFaxtm7UAGW7bgBjYYXYDugAIv+Aw4doZaG3sQ23UKga9SiDzLn330S48NtnJka5xbwXnIT2PGocgaBbY9KWgWgfEOw5VFKnVNAUHhHFx4MCbuU00pYBZRSgnecJLCZbFMAl40SrgaF02Fhud0tT7aU8gM2hTTeDgg2BgwG6MKfHwK/isDJT+DkADgsAvUHQH1C/P3nQHC4CnyaUMfB33BSbZijAja49HVg3cdcgL7huBMQ1jfMhVXAm2s+a5x+gwH6+Y07AWG1YU9WBaz1A0UBW73qYi5AvyHiTkBYblcKywDGpVc4fWAFgbkA/YaIO1K4GN4wF1YBhT6w5SuCJYG5AP38xhwlG7FhLqsCli6D5TUWew0G6Oc3bkBA2N+wEFUBi72CHKcHbKHHYIB+Q3x/CVTHgfW7Lmx7DPg27cIqo2DFO4LyKPB1OiQstytRAQtCms13C+a6DQZE3BDh4xC94VPCudMb5qiAOS7dBfbaY7bLXECz86u/4ZoL+7LBDXNhFTDLpTvBspIOgwFRwvkzCM+Hhf0Nd7qogFcdPjOXXOh7ITn0UG/TQz3ood6ih3qHvl5PtDp0jdp0jeLCXaMjJn/kG8oc5c8zYPj5D0w+zaJQ2cUj8TPr3n37eKzlABqa/2D+AmoXqZXlipnIAAAAAElFTkSuQmCC" alt="moleskine">
<p>Termékkatalógus</p>
</div>';
}
if (UserHasPerm('edit_item_introduction_basic_data') || UserHasPerm('edit_item_introduction_tools_send') || UserHasPerm('edit_item_introduction_testing') || UserHasPerm('edit_item_introduction_final') || UserHasPerm('read_item_introduction')) {
if (!$isProduct) { $isProduct = true; $menuhtml .= '<p class="category">Terméklista</p>'; }
$menuhtml .= '
<div class="menubtn" onclick="window.location='.$linkItemCreator.';">
'.MenuIndicator($linkItemCreator).'
<img src="data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAADAAAAAwCAYAAABXAvmHAAAACXBIWXMAAAsTAAALEwEAmpwYAAAF5UlEQVR4nO2W609TdxzGGxPdgHKRq+Jtb7bEl7sJ1haQtkDpldIDpeXmHf+JdV5QAe93FDcviIpuzt0VTcw2F1tLoVwsxmwvxhITFi+zL8BlPc/S03Pa09PSnlKsycI3+b6D5PM8fb7P7wgEczM3czM3czM3/6fBo61KuLb+ibGtwFgLMLYFcHl3M+DaBLg2Ag+9uwF4uB54uA4Y9W4zMNoEjDb6dqQBGKmn1wwMm4DhOnqNwFAtMFRDLwEMGQBnNb16wFkFDOro1QID6nE4VYroAlwt4z7wFg74Jg44A8+AN7HAGzjgDLwRGK5lwRM0uCEY3A+vBQY1vh1QAw7lH9EFBIGzXd8Q2fURtutmjutGjusEx3U9MFwtwqBOHADXBsAHVPQqweMXiOL66HSuR4jLMK+4iOHUSgKuq1nwSmpJRyUfAZs54GzXmzmuc+IyEm9ctGFdx0AlSIeCWh4CYj3SGcQl3JEOhnPdC87AV4B0lPMQwOtIY40LjyN1aEUYVInZcQmA++DJ/jI+AmYal1hcDxOXQZUYTqWEHRc2uG/lPATEFJcZdjrPuJD9DLwcZL+MWh4CEtTpnHYhw8TFB07D26XU8hAwC50eLS5h2gWOMhHsFeJwrvvgS0Ha1/IQMFJvmYVOjxKXUNdhrxDDXi4Jdb3UDw9biSWqAErEsPn7+DtdE9V1MsyRsuPCgJP2Enhsxd/xgqcEDJlkieh0MkpcqH1QAvJBMWAVS/kLsBPpcXX6DI4UtrUi2GViPzwN7tsiwC5Lj00A13VnfEcaLS6wy8Swl0q8cQnAF/nWJolRwBAhT0Snk9PEJQAvAWkTUwubWBaDAMOPieh0knWkwa57wRn4NSBtInjui37gB+8ktsXb6bG67rEVAzaJ6J/7RZJnd0T4q68AE7dW4entArh/KsCre4Xw3C+Ex1rwKQ8B8cYlkuuBTmccn7xXhCe3Rdh4g9i2+npjX8kXJqzsXYeVvc0ovmpEyzUtem6sxZObH2Hy5495PGQJ6HTG9Rd316D3WzmKv2zAO1c3YEXveqy4sg7LLzdj+aUmLOtpwtKLjVja3QBRD4HL1yV8BLz+I/3XWoSJOyJ88pUmKviSC/VYct6M/HNm5J81YfHndR0Ci2Xe9AJm7UhD48Ic6Yu7Xng1B7yZAl8WBF7PBseiz4xYdMaI3K7atggC4u/0SO0y+YsYV76RYUUvf/DFNHheVy3yTtcg9xSB3E69bhoBr6/TPVYxnvQVQnLNTMEvo+LSiKUXG/zw+efNeD7lxrMpt9/1vDNscAI5Jw3IOq7/XdBLLAgV8Bo7/dWvIlz8WjoteP45ExafrQMzFHhXDXJPExR8TqcBOSerkX1Cj6zjVcg8XkWEEcAzLhFdD3wCBB6jNVSnb7mqDTrQfD94IOfM5NKuB4PrkXWsCplHdcg8ou0OETAbR8r+BGBeUtK6Gk/7VkFyqYbVLKYg8EW048ywwbODwbHwsAYZh9RjIQI8/YrxeI6U+wlAWn3wpLUQE7c+wHvnTdSBssGfT7kRbZ5OvqTBtVh4SIOMg2qk7Ve6QyPkkCs89rLxeOPCuO4F920BJm6+j3fP1XEcr8WzqZe8BDDgGQdUSN+vROpe5d+CRE/eGeMjbiXmUFExIPtENRUVZjKP6IIc94GrkLZPibS9lUhtV7gSL6CrtidQiYYgcG/Gs47q/AK44OkMeIcCqe0VELaVX0i4gOxTRA3T5dlB4FWU45mHtX4BGQfUYcAVELZVQLinHMJWuSHhAgSdm+dnn9Q/Zro8i2kWVlS8effudOApu8uQ0ir/TWAJ85AlYjKP6fShlaih4NPpA03bV+mHF/rigpQ9ZRR8cqscSTul2jcC7xdxWNPhBV8YC/guOZJbZUjaId0jeONjsczLOKhuD4CHHChS6Lj4wXdK8dZ2aVvEz+lEj3CvSpfaUfk4GvjbO6SPF2wrebOxmXY6P5wvbK8gkneXdyfvlruSd8ndya0yd9IOqStpe2l30vZSg/dvwv3vf1t9PzQz/v8bAAAAAElFTkSuQmCC" alt="add-ticket">
<p>Új Termék</p>
</div>';
}
if (UserHasPerm('statistics_menu')) {
if (!$isProduct) { $isProduct = true; $menuhtml .= '<p class="category">Terméklista</p>'; }
$menuhtml .= '
<div class="menubtn" onclick="window.location='.$linkMontlyStat.';">
'.MenuIndicator($linkMontlyStat).'
<img src="data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAADAAAAAwCAYAAABXAvmHAAAACXBIWXMAAAsTAAALEwEAmpwYAAACg0lEQVR4nO2ZPU/bQBjH8wWQmErCQDKUfoV0A6ntUIbede/Uj9AXXipQGSt2RKVK7ZB26oxCi7r1A4QRQtQQ+W6lYogDhfyr56iRe7Extu9iI/mRniGyL7nf4+d+d3JKpSKKKKKIXMZTgUdcos0lkGUyge4TBw9jA3CJo6wnzz0IiYMkAMgRgFsAcMs51+pjpiFQbQjMt1w7AGvHwMaJnZz9LFD50FNJENpvD4wA2Jr8xglQ+9QzDCAwDAMIa4Ok15kzxNT6T0xtHqL28Qjze+7tAqhvdzHx/CtmFpt493sYNDa/AIyqv7ijAJ796AY/IYnT3ALU/1X/zqvL6hsDYAIXtgGYr/r3ty+rnxkAeXz2i1CpezxsfN1XfYIZG0CUx+82nEhtUrtUl5r/9X4ogMCZdQC/x6e3Olhz3Gvvp0lP+MxjA+A8icfLm4eYfLGLyso3LBwMAser+183r3o/8vttA/g9TpWvvPmuPpeXdvB43x0Zr/c+zxIgyOML7UEghNf7fvPwm0hC4I81gDCPB0H4e1+vPjcNQIPSelyHWO31UVsOrj7PAoAmQZOhBRnmcVrItKAnX+6ivNVRC50WvF59Pk4Ar5e9auoe13NdDjD9vnOlWTpxXnc/H13E58YBvF6mzUj3eFDS5uYB0KZnHYAJnIUB6L0f2QIS6nhBx4x7dNQYPe8jQqNmAeJ6PO11ZhIgkcfTA1wYA0jk8UwAJE71L/KbJ5bH8wAw1+qrE6fy+NuYHs8DQLUhbuzxtMlHN7KhUYAoj6fJ1WNDAPQqQ/d41Xv1F+JxaykMAGSa4rYDSCAJQDtHT+BXbADm4AH9vZP15JnEPs0lNkARRRRRRGkc8RfqdxZO+/ApvQAAAABJRU5ErkJggg==" alt="graph">
<p>Statisztika</p>
</div>';
}
/* Gyártás */
$isProduction = false;
if (UserHasPerm('production_classic') || UserHasPerm('production_injmold') || UserHasPerm("production_sporty")) {
$isProduction = true;
$menuhtml .= '
<p class="category">Gyártás</p>
<div class="menubtn" onclick="window.location='.$linkProduction.';">
'.MenuIndicator($linkProduction).'
<img src="data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAADAAAAAwCAYAAABXAvmHAAAACXBIWXMAAAsTAAALEwEAmpwYAAAFDElEQVR4nO2Ya0xbZRzGj5q4zBhvCX41MWRRNt2WnlNR5qZzujF2A90XE43JHLs5GeMyLoW29AqMgnNgDyYmJvpBjR+ck10Y7fuWrQM2MEZjjJ/McCYaHe/bcr895m0LK4yVFlxXTJ/k+dKc9/T3O/9zayUpmWSSkZxO5yVVVRFqu7TUot6ED1T6vwoohFsVyvsVyi1SIgucyXkcbW+ngOxJAd2bApqbAk9uCjJcf0GhHAphWNfOHpWWmsCG1mtBAcqh8fS9IS25U4iyb6YEZMI+juU70PP6TnyfQ9Cd04/u7P6J7mw3urN3/CcCTqdzKBoBmXL7tADlvdHuf6Inxz7Zk43JbtFdwV7diQnRKzusixZQVfVNVVUH5p8Af2dKQFTr8aXNt2/07NopYIPAOwQwJq5sx0TXNox3ZWG8cyvGOjO3LVqiubl5pdPp7FJV9dTtttG6eXq4gMbD8+fb7/iV7SQInIXxrq0Y78zEWMcWjHVsxtjl1zB6+VWMeDe5pHhktbvvkXABmfCz860Z68z0zwD2bsKo9xWMXtqIkUsvY+TiSxhu3+CT4hWFsD9uXgdsKN2L5ZG2H/Fu8gvgEQF8cQp4PYbbX8SwZx2GPBkYJC/wuAnIlLvCp6BQtjmiwMX17gCwJwRMMzBEn8cgScegW4tBl4IBl6YtbgIK5Y0zTiPKP4+0/TDJ2D5EBPBzAeABl4yBNg0GLqxF/4U16G99Frx1VVb8BNzs8MwJBGqItGagba0lCLsa/vPPwH9+Ffzn0uA7+zT4mRVmKZ5R2v0rFcJGZ0vIhOdFWsfPrtzGzzzl8rWs8POWVB8/ndrGTz8ZvyMfHplw0y1TIGxSS317pKWQtJ9wv0LZj7dMgbLxhHpHihQNZVoBPMckJhTKW7WE7RaiUiJHIax2jgs6/Lq4oVCuKu6+NVIiJt2L5TJlv0aSCJtMh0xYrrbj74ekRIpCfetDp838EsGp/CNTXigB90qJEvEwi1bg5kT4V6ktWCYlQmTKPo1ZIPgU/yIhJiETfmEhAkqwjYlwN/plEQJQCC+4uwKU+xcnwCZlN3/rrsBrWm88vADo326ZGmEjWtq3Me4Cstu/KuaLl/Bz6V72mHg2zPqcx/2hp7jZlgUIfCbWprn/fFC8dsyaxPW1bTeeiJuAeANdwDnvmFqf2oJlCmVfz7y9sp/FhOIiIBOmj/3+z0rD97H7S9ynUPbJLMkOzdXrD9x5AcqbYxWY83cDcI9MWd3MbdkpIXdHBRTKvlvANXDbvxQVyg2zZL+9owIy4T/EPAE3T4+4T8oOKZQHXhBlwmP/z8juaMyyNzT9bm/4CNHWVt8UqNXRBIujEZa6RpjrTsJ8/CRMxz9EVa3oCRhrTsBQ/UGgensDKkVt9agQtTqgszpQbqkLtMxch1LTcdHeYmNtZtQCtvqm3ikY6zwwxpoQTHVDEMjWEIKpD8DoLI5pmDJzAAYlplqUVNXimLEGxaKGahSJ6u0o1NtRUClqw9EKG/IrrMjXWZGns1yLWsBQ3dA7++jcDqZ0CiYMKAhTHYApDIM5GoI5orPgSLkFeeVm5JWZ8X6ZCYdLTThcUoX3Sqpw6JioEQeLjThQbMCBIgP2FemjFxDjOmas6Q0/OoXTR8eGgjCY/GkYSwjGHIQpNQVggkBBmIMhmP1Feuwv1GNfYSX2FVQit6ACe4+K6vBu/hw9oru2J798S9QCySSTTDJSvPIv7UjuaOvpQHkAAAAASUVORK5CYII=" alt="construction-worker">
<p>Termékgyártás</p>
</div>';
}
if (UserHasPerm('production_boxing')) {
if (!$isProduction) { $isProduction = true; $menuhtml .= '<p class="category">Gyártás</p>'; }
$menuhtml .= '
<div class="menubtn" onclick="window.location='.$linkBoxing.';">
'.MenuIndicator($linkBoxing).'
<img src="data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAADAAAAAwCAYAAABXAvmHAAAACXBIWXMAAAsTAAALEwEAmpwYAAAEZklEQVR4nO2YX0wcRRzHR4ymYnzQ2IcmPpgYk4amcu3OHtRSEJE/QkGgRawasVJj1ERNjDHRRF8aTXzR1AcTX/re4IO1QfoHduaOu9v7w0FbKGljUo0W00SXmT3+3MHtfs0dAgcc3BEuzZLwSebldmbz/ezOzP7mCNlhB+cCrWsXxlseIduNhF5Xmgw1DSQjzUl7qBUYOnYTw8dfI9uBxGCVK+GvMef1Bliho7AiL8EeagOix1LtA+J04p6KgcTgc5jzv4BksAFWuBn2osRw+wwiJx4nTgXnleJpVpaMe44g4avGXKAWyeCLyxLRdiDacZw4FXFh/6PT/Qpm2SHEvSmJ5zEfqEMy2Agr3IL0eoi2vUGczNSlZ36bHqCY5c8i7q3EXEpCr0cy1AQr0gJEW0qIk5EXS7qmrpRiRlMxyw8jMViFOX9NWsIKNvWQ7UCsr+Tj2BVXfEZzY9aTkkgv6h6M1D5Mtgtmr2v3zOUDnbNa2cmE9/A+4lQoE6rKRS9l0lS5nFS5+MntMZ09zxehTLaoXMRVLrGqxVRNUOJkjvCpPZSLZJbw6UaZ/IsARcSpqEz2rxd+SYLLj4gToUy+lSv8/wJ/KhE8sDgO429/i7FuGzdOAmNdwOjrgPAD8YmFdrUdGGkFhpuB4SZY0Xq94OHLtMknKZMyH4GFqSTeWxK40a2vCH/9VUD4lgUywtvRBthDdUBEWXoAWwcookzwfMOnGxMTSuRO8YLAm/qK8Nc7gWsda578Yng7UlNYAcrlJ5sKv7ygz7i9Rml87FRwM+HtSHXhBFJ7O+ViNve8F0mFCZbtWjn7135lcByf65dxNnQWPaEzmBo5sW54O1xZGIGSUTxImfwjzzn/WblfPKbm2b/JexuxaEfW8HaoojACKhODec53X8c53J8aU8bk0yoX4/mMGw2/nzW8HTy0dQFFM/eqTNh5BIkp/eKpFYOB+yibPKAy8TJl8sOvAucnvgz8ind9Oho9v6PKcxdf+C4gOdSQNbwdLNu6QP4L1zyV61642qZvtGDtVeFtXS2IwOnc4cXP+dwLw636ZsLbgYOFEBCdOcIjNd/zEoge1TcT3va7ti6wsAOJmzkW7zf5CTSdtobqDStSa1jhGsMKVxtWqNKwQhWGFSw3rKDbsHRqWIGDhuV3GZZv/yVSCMo0s4J6xPwGAnOOPwOo3tg+lQljg/3/dmrXIU6XoEzcXU9CGRDvEKejaOZeysXf2QTcLPYDcTxAEeXCk3UaeeWPxOmoTHy67mL2iO+Ik6ELZUFig29CL3EqVRp2qVxcy1FK3yJORWXy+zWBPbJP5eZkhsB85hnYMbi5qFtdkVIm+9JvhcmezN/zLSvuGS6PuXv13k+ZvJgKn7ru5mb3im8Bk43ESah85fEwM3wKhU/tyXw7jvsviGacgykX3nI/HlrTRxO3MiQLU4AVCsrk16lijTLJlQiKs/bh8tyypPkLcRzYuEhza/88kd5imbijaGbFvQu2ww47/AeJmFhkVItJWQAAAABJRU5ErkJggg==" alt="manual-handling">
<p>Termékdobozolás</p>
</div>';
}
if (UserHasPerm('production_statistics')) {
if (!$isProduction) { $isProduction = true; $menuhtml .= '<p class="category">Gyártás</p>'; }
$menuhtml .= '
<div class="menubtn" onclick="window.location='.$linkProductionStat.';">
'.MenuIndicator($linkProductionStat).'
<img src="data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAADAAAAAwCAYAAABXAvmHAAAACXBIWXMAAAsTAAALEwEAmpwYAAADTUlEQVR4nO2ZXWvTUBiAQ1JhQ+cPcLALvRYcE+d+hGtRvBG03R8w0V042C46ryZ+MARhooJ40esWJlutboNNknZDtHNJmg/X7WZsbWoi7NYjpx8zXZMmJzl1rfSF9/b0eXLevHnPKUF0oxvd+P8jwKQvkwy7STFciWS4e638Le5a+Co3Gt5Nj4azmetj530veOouNwTBKYYDMAP3N0BvNJ8kWhBcKDyUDkZK6WAEwIQiG6E7F7DC980UwNmnv0Dv9C5Wie3t7RFxIZVMh8bK8EcSwciOp51ogB+H8Adl+DOPCmUZiuFmcMDLsjyiqqqhqioQFz+ucKGx33USqDsBa56iWb0GD7NnSirDwx2owlfLaWfeL7yiKIaiKKCWwkJq5fhOpIORb64XJWn2uxneLGGG/1tO+fe44JVqiqnlz3USo+G864UpmtOsBJruCM1GUeFlWTZkWQZ2aZIwYHdyvThslU4CVjvitpwKS8TQ3trgVyknapIkgWa5Nb+YRII/kqDZB24kULsThC9+IkraEgH2Vy+qOVHQcrkcsEpRFHVJktDhUSRQupMZvpb7NhK+4d1K2Hen+o+dFbxmkhAFXhNFEYIDQRAMnuf9w6NIWHenSjk1g9dMEgK/pfE8jxferYTdjtx88vCdtkQYzeC1au6tXvrC89kR7PBeJCD8YPQtUBf7HMG1ShrFZQL/k/cq0ZbwbiXaGt5JoiPg7SQ6Cv64BAp8/sPpcnci2iVuPJ5+jgJ/Zfp1S092SOHmI2UF36qTXcvhbcaPGaJT4O1H8XyyY+C9juLtBz/euosC3/Cwz996NvUCxyh+IvC1j5TfUfxE4f2O4hSOcvIL70UigKuccMGjSlA4yumwuNtfXO3XcQ9m8P7IEX68sTsh34obhnFbP9gE2toA9qnSSaLHojvByzYkAV3X3+i6DhwkPI/EbiQCNXiGA/D/CVSBH2UBewnf8zzlopwqT5/V4YWz64Xj8fjw+vp6Bd5aAtthhHR6sSE8zQ4jLRqLxV5NTk6CTCbTIFFcGyjhPkmRdhJe4GHMzc3JExMTwCShwncCvtiHhZ1zOOFtJbzCw5idnf0JJWKx2MtEIvHPzq1k5Va8RNJcFqnmu9GNbhAdG38AQsYOuBigmlUAAAAASUVORK5CYII=" alt="design">
<p>Gyártástervező</p>
</div>';
}
/* Rendeléskezelés */
$isOrders = false;
if (UserHasPerm('removal_from_warehouse') || UserHasPerm('warehouse_reservation') || UserHasPerm('warehouse_reservation_order')) {
if (!$isOrders) { $isOrders = true; $menuhtml .= '<p class="category">Rendeléskezelés</p>'; }
$menuhtml .= '
<div class="menubtn" onclick="window.location='.$linkWarehouseOrders.';">
'.MenuIndicator($linkWarehouseOrders).'
<img src="data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAADAAAAAwCAYAAABXAvmHAAAACXBIWXMAAAsTAAALEwEAmpwYAAAF+ElEQVR4nO2YeWwUZRjGp4hIidcfRmJijEajQi+0IG25CqVAW662bGm7yx60LEqiiFztbgMiqCCIRzQiRoNHiCliuwtGIqQF2pntMdvu7sw3W1uVUBHFA4gEUrX7PWZmdnvtlpLYIa3pk7x/zPwxeX7P977ffDMMM6IRjej/q/JycczBKn5qxWlvWkV1893McNHh0941FTVilYOVrjo5CUqx5JrDJeUwQ13lXHu0kyOdsmkHS6iTk0QHJ50IQlwu57+/ixnqcrIkzcmSpU6+5Z7ue9JxFUoqYIajnKxUogBw5F1mOMrBtUwLAgjMcFS5KI6Rh1qZix6tNazk5EiVsgq1ZAkzHOVgyTZ1WyV7BvvZ4LPvA78oCWCiGK1UyZG56hxIDf/1WfDoHoI31wRv9ofwLGlF8yKgOQtwZ1gYreTk+XFOVvrLwUn/VNb677hhs0AULlTMx69fHcDF021o23Qe3lzAmw14lgAe2fxC0KZMBNwLyjUDUCA44pJX4Qjrn9+/Yd0tIMYYtNk34JLrHK5+F0DHeXTVT/sBbw7gWQp4Fivm0ZwJ2rQAAfe8n7UFYKVdwRfaji7Dom4MWqzT4bfaIBV/DWL5E8QMSBbg2tlu46H6/Zvu9JvV1qFNGaBN80Hd6UB92qOaAThYaWHwfHRKMQ8mCi2rRfhXA/5VgFQEEAtATIC4ArhUA1w7A1w8CZzbB7RuBHy6XunTJjV96p4H6p4L8HOKNQOQz0LyWcnBkY7q6jNjFQi/9WKXeWkllPSJERANACkGhALAlwf4lkVonSw1fbeaPuXTEOBTP2a0lIOTPPIqVLJkpgIgrXLCXxxuXtQHzS9XU+85uGGtM09Jn/JzEGhM/UFTACcrva20kYvYFQB/8UY1/R6tEzIvyObzAG+k9DN7tY5snvKpoI2zAH7aA5oBODiiC56LjikAUnFSWPpCISDk92md/geX8mmg/GzFPG2cAdSn6LUDcPnGBwf5SnV19WhUbx0NYr4Sln6k1vGEzEdIv1FOfyZow3QE6lP2aQagQLDkW/UjR5giX0M0He82Hyn9/lonvXf6DTNAG6YhUJ9MtAb4QJ0D6QUVYMWW8NYZaHDT+7SOmj5tSEGgLomCTb5XM4AjnGQMnosqFADBOLv34PZtnch7Pu3TOrJ5Wp8MWj8VcE3W7hu8wuV/MPhG/mMrMAqcLhq+wo6BW6f3nk97DK7cOiHztG4KAq7ENxgt5eCks+q5SIqVr+HLr72xPT8d1J3WT/pJoHVPgdZNRsD1hFtbAFb6TFkFF3lGARDyXlXNh6cfsXX4kPnw9KkrEQHXpE7widr9BXFy4urgB85BBcCXlxneOgPv+bTLfHf61PUkKDcJ7SfmZD9mF1Ieebb1tkEHOOoSJgQBzisArfo74c3pDN/zM25gcJMU85drZqGqsgi7P9qF/D0ViCnzBCaU+TChzPv6oAPIHypOTrogQ3xZKzys3PPkuAc+LnTv+b/VZKDK8TT2HtgN3WtHEVfmRYxdwES5yuSSzSulzd8QJ0sOq3PgN6sA2W9eb89vP7UMlV9sxpb39yPrlSrE2sVgCYrxUIUDeOn967joQTVvtVrHbdzy8rE1z6+HqcjaoTeZG/e+pN9PFfMLEXBnoe2kGZ8f2obN732KudtZxNkI4myiUrFd5gcC8PofL/NtH1TzOt2a2w1GS4PBZEHf2lDyHNa+cwizXmxAgo0gvkf1BIjrAxE03hlj9zVPtAtvxdiE3NhS33hGC+mN5l2RzIcqde0hJJSSMID4PgAxdvHvWJvIxtiFnbE2X1biZv7m/Dw2mMw/hswWGIxYtrwAeqOpC2CpdVtEgLhScjXOJtbGlQo7423CoptmuI+i9EZzIGQ2Ny8fi7NzkZdf2AWgK1qPhFIJ8aXi5fhS8WhcKdkUWyIlJ1r5W5mhIIPR0n69FdCtXOdPsImTmK0YxQxFGYzmHdebgUKzuZAZytLpdNEGo6U2knm90fKJ3GbMUJfJZBqrN1lKDEZLs8Fo/kVvMnN6s3nlsDA/ohGNiBkS+hfJJlDyRMsDFAAAAABJRU5ErkJggg==" alt="handcart">
<p>Rendelések</p>
</div>';
}
if (UserHasPerm('return_goods')) {
if (!$isOrders) { $isOrders = true; $menuhtml .= '<p class="category">Rendeléskezelés</p>'; }
$menuhtml .= '
<div class="menubtn" onclick="window.location='.$linkWarehouseReturnGoods.';">
'.MenuIndicator($linkWarehouseReturnGoods).'
<img src="data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAADAAAAAwCAYAAABXAvmHAAAACXBIWXMAAAsTAAALEwEAmpwYAAAFCUlEQVR4nO2YfUwTdxjHzxYL4khmgjNbpjGLCVYY4GS6mbpyN0JiNhezyLI5wkuyLYuJ21yySGk3Z3xjGsUFh7q4THqMJWRTqUqWMYeVXmXMgn25H4WWogIKfYFiNo3tdc9yd6Uw6ZK2V3kxfJNPcrk/nt/zuefJ74/DsLnMZS6PNNCJLWfsIgtjn2eBXmw5NpsCPdgyxirqCXSLgIXpFt2ELuy5uB6y5OSN15accPSnVjn6FlXaN8arLliwZQwS9wSsYuARQaBLBIw1zhJPHe/tS61ywJOVdlh+tBs0FO3QUOirc7rOFEHN0+KeAC2GAJpAJw9jFcdPIrXK0cc2n3LQBkuPWEGjRzwUrWtu7k2KpXm/WdzDmBOAw8IToFnEPEgMDIqTxKJK+8aUg7a+5P3WW8l7rRs1evSCRo/srMR5HXo/2nr+6wndjHE+cJgSxnlIiEfchT2KnKPQ2/wUUFPUAtfEBNMhKQhxfT5wcFKsjLhgDL9ZjD8SgZ+16OngGnkBYJ6QWkz7fGA6xsGmKm/UDTOb6kYgr3bURqi9OlztPU+QXjVOjlYQ5OjHuHq4iFAPb8qrGZbhpz3peXWuZ8IKXJMAYwjSLpk6ga317kGCvAs8o2HwhmHkPqEeuY2rR2hCPaLbcPxGo79NAv4/g1yTgPxU7+a8H4ZleN3/S8cl750Z1EYvwEmE2FBtB/8fieO0JcKGahsQtcNBPECQnns46b5FkO4OnPQ0EbXuOrzWVYWTri9x0r0dJ53v4KQ7/9U65+r8Hz1Ld+0CUUQC284O7Y2LwNUk8F9N5GkNI1AbDncYXDykqz4iga3VnWty93VD/mF7YO2BXsO6Qzep9Uf7tbJvBptlJ4e08lMuSv69x0CcHrHiau8ATnr/DitAJfHoeYQK4LXO5giXCOatVdGBbAWCrBA0TzlP5kNklaP72V+godW7rfacfTZTtrK13deyAHwtSeDX8bxUaW7PrXGbctUeO066h6IWIJ3HIhTAsPz9yBmNAMvzHBYO6Sct4NMu4LnCI93RAhlKC2QozZDOorLcy9yNBrL2dlnXVHQbXjzsoNZ9fUP7cnXfZdm3A9pXvrtDyU8PGogapxUnnQNEzeCHEQtsPkTrBAs0J4PvMssCjkkCyv+yagzVGCYOaZA0pTk3YoEtR+gKwQKXksH3+zhCBVYo2hdHLIDvMa8XLNC0EHy/BbkkUEBpcmHRZNUui2SNkv5HiMCDXxeO07RQ4ASMkd5AE6eAPLEKrNpBgefCYnjwyxMc7guLQfopJWSFjkUtIN9tuRirQMZOA2xS1cBH+/dwvK6qgfQyQ8wCKz83botaYLXCsj1WAU5CYYKMMiOkK4yQXm4KNh+rgEketUDmTotMiEBIJNR47AIrormBxpL2WWdKVhkdmG6BlUrTUNTNh6agQLbpFpDGcgNNEKiffgHTsdgFypBiugVWxnIDjSVbgeTTLZBWbsqJWaC+xbLsgxPofo5q6gWkKtNfUpXxACYkDXr6J/YvRYMeXWxsNT6LzbZo9PRdVmBWNv9YCDRQ9BluhSjUeLbNvBSbbTmn60xroJAn9ON3immgUItgCXZ9NHpU30DRo1MuoEdXsHjl3eLSisLiUpgI+26m1p2UwuKS22zxN7e8xcEdVFR6B5uhdSelsKhkYNJBxaX92AytG9GoC4tKDszUupNSUFAg4Q5jv1hRyQD7zL7DZmjduczlcc+/aqqxdF1QA2IAAAAASUVORK5CYII=" alt="return-purchase">
<p>Visszáru</p>
</div>';
}
if (UserHasPerm('manage_pricing')) {
if (!$isOrders) { $isOrders = true; $menuhtml .= '<p class="category">Rendeléskezelés</p>'; }
$menuhtml .= '
<div class="menubtn" onclick="window.location='.$linkPricing.';">
'.MenuIndicator($linkPricing).'
<img src="data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAADAAAAAwCAYAAABXAvmHAAAACXBIWXMAAAsTAAALEwEAmpwYAAAD0UlEQVR4nO2W609TdxyHT9vTm3FLeKHxFpWLF6D8A3vnS/+AvTARpEK5tFZoy4tlyeKrxSzqMNFp3KwxXpAWyq2czoFYrgICe7HCqq5xBKX3V0Zjlsg+5pzfOb2gxlZaTpv0kzyv+zwn39MciiqssMIK+2CApIoJ6zRMZLGSibzTMFFUDkZQ6SRUDLCEUd5PONzH0xt6e9ARnDrUHThCibYzkGpckd+qXFGw4mnI41AP4aAjuCZOREbkQ2wADnQHpvJDvieIkpvPccDuT5APoszmh7ra9lp93DamOn7vmxyVD6GobQTq2m5sbXSitGOFk+foCkJdYydUd77LXsQGzqasYwWq2h6oah1Q1zqw++JfMfkyewDqmq5YhKrGNpN7N+8I4uuWIai0PdhS34/iW8sxeS7gRDfUJ7oINfb/cvKFLbOvYs8VL0rurCTJl9oC3GmRCBKSOXlAomGiVzLzbxNMOhtBnkU4LSEkr+RLOwPcaSW+I3klX9Lph0rby0NC8kq+5J4fqpN9CRG9yCv54g42oJ9E8CF5JV/c4Yeyjg0Q6IPI3zbpye+78xLKugEeEpE3T37/3VXsvuaDst4JZZ0zFpKevEhPfv/dVY6iH6ahrB/kISEp+1e5oiYx5bef80DZwECpYxIiBtMIYCJLosmf90DR8DsUDS4odC4SoWOgqHf+m3KAhom+Ek2+8Q8+gI+Ih7SnHjAYmdx8+UUoGodIQON9ghCic3kovXtrygHlTPhopTO8tnnyS5A3DUPRNARFExsgwEV4KK1rG5XuKgZC2oqB8FrW5S8sQd78APLmYS5CzkXwIQ33v0w+MaK8L/R/1uR//hty/UM+gI/gQ+imIe8WvXsHtdEV337xffbk3SRAP0LgQ+jmYQ9l3MCTX79d13zXMyrf7gVtGAVtcIM2sAECI6D1DzIrL2znVZ81Y/KnRuMY3LEQunnES2XibD61HVd91o3JPwFtHAdtHAN9aiwpRKZ/mF35WMQv/1i/RH5b+xPITk+ANk7wEfEQmWF0c+TjET5rWvIXn0J2epJnIilEZhzfXPnEiJTlW6biJIWMiyMvbPsln/Wz8q3TkLU+gqzl0bqQCXHlYxGXn974uPwzSE0zkLayTK8LmfRS+lnx5YUV/eQ9u/PXZey9/QK7rMv46sdFSC2zkJpYZpJDWqa9VFsOycdmWdBKzY/XpJY5SM2PE0gIaZ3JUXlhlgWtxDxHItaHmHJdXphloVpinn8jscyTCBbT7BRl/DPznwdZW9t8KdU2/53EPNdOmeeOUd/aZdn7scIKK4zK570HcWf1vtE6suoAAAAASUVORK5CYII=" alt="tags">
<p>Árazás</p>
</div>';
}
/* Raktárak */
$isWarehouse = false;
if (UserHasPerm('warehouse_editor') || UserHasPerm('warehouse_statistic')) {
$isWarehouse = true;
$menuhtml .= '
<p class="category">Raktározás</p>
<div class="menubtn" onclick="window.location='.$linkWarehouse.';">
'.MenuIndicator($linkWarehouse).'
<img src="data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAADAAAAAwCAYAAABXAvmHAAAACXBIWXMAAAsTAAALEwEAmpwYAAAEbElEQVR4nO2US2gcZRzAx+zO7COa0hYKHhQEI2raZLOb3W8mqbbSSxUFpc2peCgU0UOpBQ8efNRLsFLx0UMrSg4eBAsWCiKNs2myuzOz70cmu3nuZrM7eWzT0hw8KDnkL7P2C2Mys5kvXbMr5A8/WJaZ//f7wX5LUXuzN803Mycp2zjb8r7c2xKVuZaI+ln9jmr2AYp6TOYs/RnOUhjrtYCWDGcpy1zLO0BRLVQzTgZZUYqzCGnOCjVhLfEUaz1GNcukENOe5Kw3Ehy9nuRoMEuCo/l0H93RMPGolzoYY+lvYhy9Fudo2EziJSdMD7xXRf2s90yMo9fUHequXRPPvkgxYcRciCBmNcoyoIf87glYTIpw7/79KktyHLIfnIIoZ9N9PoqYP6KIvjRyjLL/pxdU4ph+iWUKYdYGeqTe9kFp5FdYWbmniyL8DumzfbrvhlkbSCxTjiBb/S96EDmQgBhBZG2gR/T1Z2Dmx6+gslyByt2V2lTuQuHmIMTebNfd9ZC4xNof/aKPIqY9hGw3gqx9PcTaYTPi8YOQ+/pDWFJKsFypkLGgwOT3AyCeOLRl7wbIzoe8O7joEtt2IOBzfB7wOf4KIAdsoa8NMh+fhfJUFhaXl7dw+roAL1wa+hf910O6zyqzUyBfvgjBvn1bz0EOGEWOtQCyfydyrYdMyY+wjvOjyLE6ipygR/zCW1BMSLCwuGTIZnlMrXeKCam62+hc1Ul1qynPe/bvu4OcoId0hoVZ/hYoC4vbYhRg5t1Z/lb1LD2HYeRc/813oK12hK/1pt/XCpjAa8+CPPglzJfKUFIWTGEUYPb9UlmB3M8/QOCN5zc8/sH5y7Y/Id77xHND3sf/9L/yJKSufgbFQgHmywoRRgGke4qFQtVBdVGdVDdT94D32J/O57IwN1/aEaeuBbfIn74W2vG+fC4Lt3vsT1EkUyjOQzNBkU5+rgjNBEU6M4U5aCYo0pnOFwDzyeVv4dzFj3aVT7+4unG+CnHA1EweMLstf+4hWgfigInpWcB0dLoawoTGgTggNzUNmEYF5DQOxAHjk1OA6ejsbgjjGgfiADk3CZjDXd0NQdY4EAeMZScAY/bAVb8L1sO1ecC7TO8b0zgQB6THc4A53OU2xXbyGLP70hoH4oCUnAVMowJSGgfigERGBkyjAhIaB+KAeHoMMEdcblOYDTC7L65xIA6IpTKAOeLymMJ8gLl9MY0DcUAkmQZMowIiGgfigHA8BZjO7h5TPDDzN+p3md4X1jgQB4ixJGC63D5dJgatoPxE1US4UpvbA1bD/VoH4gAhGgeMy4N02U7eTIBwhTLcr3UgDghFYoBxe1ld6hXgNtivdSAOCEhRwHh8nC71CvAY7Nc6EAeMihHA9KA+XeoV0GOwX+tAHHBHCAPGyx7VpV4BXoP9WgfiAH9IVIZDEqig3pd1qVcAMtiPzx8OieUdBIRe5YOC4g+KwB09rsvEIP3IAUMDtOF+9Wx/UCzzQekkccDe7M3eUP+L+RtcE7PsW6laOgAAAABJRU5ErkJggg==" alt="warehouse-1">
<p>Raktár</p>
</div>';
}
if (UserHasPerm('warehouse_add')) {
if (!$isWarehouse) { $isWarehouse = true; $menuhtml .= '<p class="category">Raktározás</p>'; }
$menuhtml .= '
<div class="menubtn" onclick="window.location='.$linkWarehouseAdd.';">
'.MenuIndicator($linkWarehouseAdd).'
<img src="data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAADAAAAAwCAYAAABXAvmHAAAACXBIWXMAAAsTAAALEwEAmpwYAAACKUlEQVR4nO2UTWsTURSGzyoggpiWNtOY1i+SzEwSu5XiX/AP6R8QW0QQDBm/QMGFZJLMZBTcWtxEEKsEbWucpJVm7p3aCm5aN0cm0FJukskUxiQ33Afe7Xvuw+FcAIFAIJg4lAq9LZfpgVwmmC4RTBfJQVJ3bgEvyBVK5ArFY4ESwVTRIcALcoXsdwu094EXZKOXgMOpQFkIDJ+J2IDiCZy8A+4FdCEw5A0YkyRQFgLhk7F+LWUtepixXOyk6qLqxfRC0dvAUbxNpCsEp5fXUMo3UCrYOKc1O5EKzcNZzb4OwyZn/Y5mq269r8BJCR+BOc2uLzxsRWEUXHvbns1Uab1bgNlCHwFJszfmH7fiMEqyhhNTLfrVE8icQkAq2JuJ/NYFGAdyb3YTquk2+t6BJ1ByjgViBbsVy9uXYJxQzb0Fter+6CeQLO50BGL5xlZMa16GcUSx9i6qJm32+ok6AnfXfs4UNq7COCO/pinVdHdYgSsv7L9Td74owAMZa1dRTEqOvtJUqf0nfu/TTeCJdNnJqQZZVwzyLalvL476PQLBIKieeE/1eeQixcRql0D7VRx5CrBsv5SQpwBL8/kM8hRg+f5sGv2y+TS65HdDjSfRG4M6wuwClvVH59EvfgODdoTZBSz1/Dn0S5ChgzrC7AKWzw/Ool+CDB3UEWYXsHy8fwb9EmTooI4wu4ClthxZ/bASwV6prUTeBRnq1xFmVy1gh0AgEMB/5x8+sW8rsiFSWQAAAABJRU5ErkJggg==" alt="load-cargo">
<p>Raktári bevét</p>
</div>';
}
if (UserHasPerm('removal_from_warehouse')) {
if (!$isWarehouse) { $isWarehouse = true; $menuhtml .= '<p class="category">Raktározás</p>'; }
$menuhtml .= '
<div class="menubtn" onclick="window.location='.$linkWarehouseRemove.';">
'.MenuIndicator($linkWarehouseRemove).'
<img src="data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAADAAAAAwCAYAAABXAvmHAAAACXBIWXMAAAsTAAALEwEAmpwYAAADnElEQVR4nO3ZWVNScRjHcSaX3GYar2qc6Q00LZYCB1TAjcSlsjRbNW3zXfRW6qqZXkATB5E2kfUgolC3OlNzEBsvm9Ln1xwwlUHk/P8c0Auemef+84Wz/Ad0uspUpjKVOZGD7y8HkZhdx7dZIPESSLwAEs+B+DMg/hSIzwDxaWBV2SfA6hTw+4e6XR4HlseA6B0gehuIjgJLt3b3JrB0A4iMAJFhQBpah+RwsAeowj/Zx69OMgSoxEeGgMggdiTHGnsAK37lsfoABjxJDpA0AI5vgBG/8oghgA1P0nWeAEb8ykOGgNED8JsF8RTmCsiHnzocH3sAxO4DsXtAbAJYVvbuETesejyF7RwBJwhP4X6egOPG2/fwFO7jCSgV/gYznkK9PAEH8ZMq8He58CTl4v8E+pHy2LD12YbtQA8o1MMRwIuPFoensD2N9400Q5o9j023BdsBG0/A/0umnPj+9MpzVnwx1uGTsR6hmRakXB08AVriR1TjKdwH2WXZC/horEdwpgUeq66aLUAVflxzPIV6Ibu6sgI8xga4DQ1vmSK0wG9Lw/j1aQAbHjs2PP1Izivbh+R8L5LzPUi6u5F023bXiuScBcm5Lvx0duQEzLNGaPHJK/jERDOWzVWImquwZKpGxFSNsKkaIVMNgqYaBIRa+IVaLAqn4RVOY0Gow1eh7vAAYyNEfeObVzrdKRUBxV42w+lPPGY+pWmAy9AIp76pcER+/JgqfCagryQBoqEJTn3DVIGA4vDKDSu7SxfwwdAwWSCgOLzytClhwGsVlxAPfijrUbn5sRdxrW9iQ2NhfDog51yTB591KMt+zv8N2bHp6YY8Z0u/XZUXVGa7ILs6IYsdkEUzZNEEWRQgO42QnQb8eK/P+xh9N66rKojPBBSHz35JZV5QmVUOZ92goA0UtIKCFlCwCxToBAU6QAEzZGduABM+E6A1vkcVnvxKQHv2UWL6HJjw6QDV+EFN8eQ3QXa27R/mps8iJbZyHObS8PLjyS8g5WqHf/gMIrPnsClexba3jTegXHjTHp78RvxZ0CMlXsOWO4OnxWs8AVrgu5nx5DOAfHqQrx3ky+Bp8SpHQMEfnMqHJ76Ak4JvBXl5buKS44XD8Yu5ePJe4Qg4Ch8+Cm/LxgeKx5P3Mk/AYb/ZHA+evJd4Ak4OnhYucgRIg+va440q8Fdy8DsLFzj+4JAcjh1pYE0d3lpSPLwXBpgDKlOZylRGV475B8IqZ4P6TFjOAAAAAElFTkSuQmCC" alt="move-stock">
<p>Raktári kivét</p>
</div>';
}
/* Fiók kezelés */
$menuhtml .= '
<p class="category">Fiókműveletek</p>
<div class="menubtn" onclick="window.location='.$linkProfile.';">
'.MenuIndicator($linkProfile).'
<img src="data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAADAAAAAwCAYAAABXAvmHAAAACXBIWXMAAAsTAAALEwEAmpwYAAADj0lEQVR4nO2Y709TVxjH7z9xTRZpFoyTFBgCRe8WTLYXSxT2Zhh9IW5xAzXLtjdL9mLJtkzmCxV1WaJTNLEqOITmnhZpe3u9tPf2F1DaMuZIcIsLZkx9o0ZoIMOL8WvOEaqYTX6UhrPsfpNP8uTp7T3nc885TXoFwYoVKyueSPKGLZr+TY6kRjLh1EgmkrrujievFwn/hUSSwzY9MXxfTwwjS/8wQv2/3jcS1woE3qP1Dsk98V/QE/vZF+wbWqskrhVo8SFFiw1Biw26BN4TCKczgUgaipHIPm01krQp4RT8RnJC4D2+UAKU5wU8atLmDfbDG+yDwHu6rsbBUKMKUYwCjxqxeQKxgEeNwaNG8y+wmcy8u5mYtyRiYjkQJQziD0P2G/PxUfRl3VOiyOZfknumZkEBduFyByEmOruD6OzuQeeVZ3QwNEYu95Zkc2xhgVwGICbOug20uwP4aQ4yh4LTJJSbADEX3oK5DrBTvoNTLg2tLi/jIqXTix9dGnbIt/kXkPKMYAkQE2+SaXx96BBC+15BeK+IcKMI4yMR+h4Rvob1fK/Atkuj6Ph8C4y9IiL7n0IljAYR+oci/LttqHWO8Ctw+stdbLJG4xrEPhYR3b8mi1YvQqkT8f0n9fwKqA2vQvt0Pca9RZjs2YipkINB6/HuIlzZVwJ3XSG/At2NGzDQXMYm/Xe0Gg/jbzFoTXuJow64tm/gV8D52VaMOkvZhM2+d/BooIZBa9obu1yJlj1b//X7xQd12A9cXRTFB/WVFzjz1S7cc5exp04n/njwPQataW/CX46TX9TzKzB4Yh0ygYpZgdrnBGpZbzJYifQP+fspFXIV8LXXYTK4EdPRLbNbqJZBa9qjh5lew62AREyMBaoxpVexCT+Mv82g9ZTuwJ+B6pd+d9W3kERMfNvVjoxqx2SwnIlQaD2h2vGNp4N/AYmY+K6rFQ986zChvMagdVNXW962jrSSApsuj6Pi7Ch+byvEzY6n0Jr26GfcClS13sXrzYnsEqcuFGPkYiEjfb4k2y9tHoCj7e6St1DxP2yZFRMob7kB+wFt3oAfNB9D+FwVjHOb8P6R4y9MSENFyx98CFQ6by364L2Iw5n7vzApV4HSw73LFig50rv6Avam+VtnSTRpHKzA0WcHd6nQA73qAhJHCJYA4X0F5NxeLeYVeTGvFt0zNVxKyObYG2Rm24ICVqxYsWLlf5UnC1iPM8geNSsAAAAASUVORK5CYII=" alt="badge--v1">
<p>Fiókom</p>
</div>';
if (UserHasPerm('user_read_perm') || UserHasPerm('user_edit_perm')) {
$menuhtml .= '
<div class="menubtn" onclick="window.location='.$linkUserEditor.';">
'.MenuIndicator($linkUserEditor).'
<img src="data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAADAAAAAwCAYAAABXAvmHAAAACXBIWXMAAAsTAAALEwEAmpwYAAAEW0lEQVR4nO1Ub2wTZRw+owQlUUJcby0wEnXEXQcbUNfSrdxtdNvVYMymogGdX/hkCF+MiaiJrQOnyAdx4sDEbewPU2/vtV1XuisKOmcY6iDosLKBQwut8YuiMrarlp95u3WurK233m3+yT3J8+HufZ/f83t+73tHECpUqFChQsX/FR6DbpGT1jzkYjQOJ02+yNOaZzE7S7NN/3pP32M5T/EMGeUZEm4kosmtUmp4LYuXIAt593RyFq1mLj0JPAFvdc7HyYrE6SrXjaRqBAjiJr5Uc5inybEU+j1KeybAVZbdlq7Q1ETKSG+ikiB6qpaavdUrQmkbsWbvU9IzAVyJbgViyOvHt62EoLsCzrfQcGqXAU7uLIAze4rgO7QRgp4K+KDmHsD7OEajjWs76axHnWXJj38GafJ5JTxnwMVo1iCGhIucFcJ+W0oONVomJsLcmYd1iM5a6SyduDLeB5eD26qd0XRXpQ66Ny2LP0c5i1YvxzMp+A1ZuiNVOT+mKxSn5/6lP3HlSxbHdDT5Ci5+4plVsbXL3koINJjh9O51cLrOEJtqTCfYoG8HFf8o7XI8U6JvBzUopVjv9rwv4xrEaA66K7R/hHzs3+rwNXFas6OI1rwuxzMlAgeKBSnFAgdL3FMnR2t29W6/d1SKDvP4ttyr+N9OyPBMibBg65BSLCTYmqcFePLMa0XjUgMMvLT2Kv7oCRmeigbopLPWnmu0SA4w9E7Jb05aS81VgH3SGmFfjWt8ttyFQZd1TGqAoKv8ykcMcYscz9QBfDZ92M+mnWbIz/4aFCpzE4Oz16QGCAvsz0p4pkToKLslJNh+T2EuXu5hy2/UyAmQqWdaXOgybwx2MwmFLnUzcKm7pDTZ/pBgG5EaICSwASU8k8LggUVGJNY8gEa4QMtdMNShhwvcGhjuoAA/b0Lfvr+eFx/H+6brwoLtBckn4GefVsIzAUwz3GpEkedMSPzFxEfAzI/Dp23mWIE4+1qLY+/xuokXr5hQZCfWYT0MGBaEBfZDCdM/Atzmm5XwnIKRH11uRJFTE5v+4iOdg8C3b4H+ViOg9q3wMHc2YX2y6BfrudFluE7wxObbwn62Pc3kG4d9toVKehLGNrjDxEe+nrlpVjxb7IbbcT3D2wMLzr+3CoKeDfjjg7BQCd97LDD8bj7gNcU9TbxYJ7MQGNE4FDZ846bs/qOUQxgbbMlNuAaY+B1lF65RDsFf+Na5LqwxyfXlxd2EEUUuyiliaApB/su9QDn8U2w9UDUjwKGG6oQ9+XW9Ma3MECOECYnXMxLjqdcPJjQVZ1GtE97c/wScbCqA/qZCqN9fA/fVupLuLazHd1zMMIAYJTJNn6r5TFjwxlcZn0JGAQzNYcWapya57tAP8xdg9d7PFA+weu/n8xdAX3tM8QD62mOZBTAisWe2IqWbpyY56wBI7CcywVwFIOYLagDHP38C0f/0Fcqz+1uVDpFn938ybwFUqFChQgUxiT8BIKhhoCtS0CsAAAAASUVORK5CYII=">
<p>Felhasználók</p>
</div>';
}
if (UserHasPerm('perm_read')) {
$menuhtml .= '
<div class="menubtn" onclick="window.location='.$linkPermEditor.';">
'.MenuIndicator($linkPermEditor).'
<img src="data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAADAAAAAwCAYAAABXAvmHAAAACXBIWXMAAAsTAAALEwEAmpwYAAADEklEQVR4nO2YT0gUURzHXwlZJAXm+23FSqlL1DZz6pCBvd+WBB4ygvBi2jkDK5mJbtkhLTp3qFMQIjn7nlKBK3Xpjx2y3Dq4EwlGpRVRh1IqFsyJN7ribjvpbrYzC/uFH+xh5/H5/ub35+0SUlBBBf13GdX+NZxBWDCYEginSd7BI70rECw7GEyQvIVHsCL15V0kX+AFo/cWwj9orHgW09UZU1ONkbZgKckn+IdHK6M2vK5ac/HOPKMgyVN4O2K6Mm1qyjmroaGIeL5sUuCTQlMio62BdXmTeYcYGjkRLHHNgD3nk+ArnmYAb82V1G3XyokjTCbg7zdufZIpvDkfSrsrBuSG5QjvBw6Wd2cPr9qN/VLbGSJuytTVrmwNmLMmJlzdE2Nnd603NfXtP5roJm5KLil7zv+DiYFD/h5Zlq5dAGVDZgs/2Fz1IjEUOMI3VwyM1gWKoy3bX2cK/6i56vnCkSwQenIObyAt4Qwifft8VrRlx9Iz31QVXQgvb7NySeYUXuwt2yQQ5kGkieHji7+JxymZdwXeqNkYFIy+SQaBfllOsiecGnuwOTDsOnwvgz2c0c8p8MOynBLfkUsqpinjnoPnIXpEMPozCYTBuMBSf7o9EdPVazb8MQ/UPGdwSiD8SpocDL72MVD/9lyk3n/TVXijgRRxhCspI88SSOPhENQu9jyfXVLuwF/HLas5gpEKzxFmwghNSzlDILTJW6w8J6fwvbWbNwgGg39m3s6+TrwsXgOVHOFVOniO9CrxssIh326O9FNaeEbvyJ4gXhVHOMyRfnfI/NCNA761xKsSSFsFg2mHmh+7tR98xIuyCFkhkJ5PD26XzZfemrJtxIvqrwsUy2usE7xA+kMgVBOviiNccoRnMC17gnhZgsFHZwNlJ4nXJZwMMLhM8kGCwcU0BnraCVmZ6VkxXe00NTWe8W9jTY2bmtKRlQEjGFwlTXCEDzLkZ9nY2Zxl6upU1n+vaOokcUOCQae8lTpPsUyDxjnSjlwamFo+eEjcdHP3NmS2lvsNCKQXcmagoIIKIjnRb11UiFNqLpkFAAAAAElFTkSuQmCC" alt="law">
<p>Jog lista</p>
</div>';
}
$menuhtml .= '</div>';
/* Globális funkciók */
function StopAndDie($reason = "Jogosultság megtagadva! Önnek nincsen joga a kért tartalom megtekintéséhez!") {
global $currentUrl;
$_SESSION['error_message'] = $reason;
header('X-Frame-Options: DENY');
header("Location: ".$currentUrl."/dashboard");
die();
}
function getItemsSlice(array $items, int $page, int $limit = 25): array {
$offset = ($page - 1) * $limit;
return array_slice($items, $offset, $limit);
}
function idToHexColor(string $id): string {
$hash = md5($id);
$color = substr($hash, 0, 6);
return '#' . $color;
}
function escapeForJson($string) {
$escaped = str_replace('"', "'", $string);
$escaped = str_replace("\\", "\\\\", $escaped);
$escaped = str_replace("/", "\\/", $escaped);
$escaped = str_replace("\n", "\\n", $escaped);
$escaped = str_replace("\r", "\\r", $escaped);
$escaped = str_replace("\t", "\\t", $escaped);
return $escaped;
}
function splitSetitem_id($item_id) {
if (strpos($item_id, '+') === false) {
return null;
}
$parts = explode('+', $item_id, 2);
$first = trim($parts[0]);
$second = trim($parts[1]);
// Prefix
$prefix = '';
$first_numeric = $first;
if (preg_match('/^([^0-9]{1,2})(.*)$/', $first, $matches)) {
$prefix = $matches[1];
$first_numeric = $matches[2];
} else {
$first_numeric = (string)intval($first);
}
$item1 = $prefix . $first_numeric;
$second_numeric = $second;
if ($prefix === '') {
$second_numeric = (string)intval($second);
}
$item2 = $prefix . $second_numeric;
return ['item1' => $item1, 'item2' => $item2];
}
/* scriptek */
$SystemVersion = file_get_contents($currentUrl.'/version.php?v=1');
$menuhtml .= "<div class='VersionData'><a href='".$currentUrl."/version.php' target='_blank'>" . $SystemVersion . "</a></div>";
$menuhtml .= '<script src="../js/szatuna.js?v='.date('Ymd').'"></script>';
$menuhtml .= '<script src="../js/bug_report.js?v='.date('Ymd').'"></script>';
?>

132
managers/prdb.json Normal file
View File

@ -0,0 +1,132 @@
{
"DBList": [
{ "ID": "pr_parameters", "NAME": "Termék paraméterek" },
{ "ID": "pr_data_for_toolmaking", "NAME": "Szerszám készítéshez szükséges adatok" },
{ "ID": "pr_tool_loc", "NAME": "Szerszámhely" },
{ "ID": "pr_basic_info", "NAME": "Alapadatok" },
{ "ID": "pr_cutting_parameters", "NAME": "Felvágási paraméterek" },
{ "ID": "pr_press_parameters", "NAME": "Préselési paraméterek" },
{ "ID": "pr_process_parameters", "NAME": "Feldolgozási paraméterek" },
{ "ID": "pr_packing_parameters", "NAME": "Csomagolási paraméterek" },
{ "ID": "pr_warehouse_parameters", "NAME": "Raktározási paraméterek" },
{ "ID": "pr_support", "NAME": "Terméktámogatás" }
],
"Parameters": [
{ "ID": "pr_parameters_category", "NAME": "Termékkategória", "TYPE": "String", "DATALIST": true },
{ "ID": "pr_parameters_car_brand", "NAME": "Autó", "TYPE": "String", "DATALIST": true },
{ "ID": "pr_parameters_car_type", "NAME": "Típus", "TYPE": "String", "DATALIST": true },
{ "ID": "pr_parameters_car_year", "NAME": "Évjárat", "TYPE": "String", "DATALIST": false },
{ "ID": "pr_parameters_car_doors", "NAME": "Ajtók", "TYPE": "String", "DATALIST": false },
{ "ID": "pr_parameters_name_in_db", "NAME": "Terméknév szatuna adatbázisában", "TYPE": "String", "DATALIST": true },
{ "ID": "pr_parameters_front_and_rear", "NAME": "Első / hátsó", "TYPE": "String", "DATALIST": true },
{ "ID": "pr_parameters_ean_code", "NAME": "EAN kód", "TYPE": "String", "DATALIST": false },
{ "ID": "pr_parameters_price_category", "NAME": "Árkategória", "TYPE": "String", "DATALIST": true },
{ "ID": "pr_parameters_unit_of_measure", "NAME": "Mennyiségi egység", "TYPE": "String", "DATALIST": true },
{ "ID": "pr_data_for_toolmaking_type", "NAME": "Típus", "TYPE": "String", "DATALIST": true },
{ "ID": "pr_data_for_toolmaking_doorway_front", "NAME": "Ajtónút elöl (mm)", "TYPE": "String", "DATALIST": false },
{ "ID": "pr_data_for_toolmaking_doornail_front", "NAME": "Ajtóköröm elöl (mm)", "TYPE": "String", "DATALIST": false },
{ "ID": "pr_data_for_toolmaking_doorway_top", "NAME": "Ajtónút felül (mm)", "TYPE": "String", "DATALIST": false },
{ "ID": "pr_data_for_toolmaking_doornail_top", "NAME": "Ajtóköröm felül (mm)", "TYPE": "String", "DATALIST": false },
{ "ID": "pr_data_for_toolmaking_doorway_back", "NAME": "Ajtónút hátul (mm)", "TYPE": "String", "DATALIST": false },
{ "ID": "pr_data_for_toolmaking_doornail_back", "NAME": "Ajtóköröm hátul (mm)", "TYPE": "String", "DATALIST": false },
{ "ID": "pr_data_for_toolmaking_glassthickness_front", "NAME": "Üvegvastagság elöl (mm)", "TYPE": "String", "DATALIST": false },
{ "ID": "pr_data_for_toolmaking_glassthickness_back", "NAME": "Üvegvastagság hátul (mm)", "TYPE": "String", "DATALIST": false },
{ "ID": "pr_data_for_toolmaking_string_height", "NAME": "Húrmagasság 330mm-en (mm)", "TYPE": "String", "DATALIST": false },
{ "ID": "pr_data_for_toolmaking_water_spreader_rubber_overhang", "NAME": "Víz vezető gumin túlnyúlás (mm)", "TYPE": "String", "DATALIST": false },
{ "ID": "pr_data_for_toolmaking_glass_mirror_gap", "NAME": "Becsukott tükörnél az üveg és tükör közti legkisebb rés mérete (mm)", "TYPE": "String", "DATALIST": false },
{ "ID": "pr_tool_loc_disc_position", "NAME": "Lemez pozíció", "TYPE": "String", "DATALIST": true },
{ "ID": "pr_tool_loc_core_position", "NAME": "Magpozíció", "TYPE": "String", "DATALIST": true },
{ "ID": "pr_tool_loc_note", "NAME": "Megjegyzés", "TYPE": "String", "DATALIST": false },
{ "ID": "pr_basic_info_tools", "NAME": "Szerszám", "TYPE": "String", "DATALIST": true },
{ "ID": "pr_basic_info_press_machine", "NAME": "Présgép", "TYPE": "String", "DATALIST": true },
{ "ID": "pr_cutting_parameters_is_layout_drawing_prepared", "NAME": "Van-e a cikkszámról felvágáshoz előkészített terítékrajz", "TYPE": "String", "DATALIST": true },
{ "ID": "pr_cutting_parameters_layout_drawing_scan_id", "NAME": "Beszkennelt terítékfájl rajzszáma", "TYPE": "String", "DATALIST": false },
{ "ID": "pr_cutting_parameters_is_digital_layout_drawing", "NAME": "Van-e róla digitális szerszámrajz?", "TYPE": "String", "DATALIST": true },
{ "ID": "pr_cutting_parameters_tablesize_x", "NAME": "Táblaméret x (mm)", "TYPE": "String", "DATALIST": true },
{ "ID": "pr_cutting_parameters_tablesize_y", "NAME": "Táblaméret y (mm)", "TYPE": "String", "DATALIST": true },
{ "ID": "pr_cutting_parameters_pcs", "NAME": "Teríték/tábla (db)", "TYPE": "String", "DATALIST": true },
{ "ID": "pr_cutting_parameters_offset", "NAME": "Eltolás (mm)", "TYPE": "String", "DATALIST": true },
{ "ID": "pr_press_parameters_is_codereader", "NAME": "Van kódbesütő?", "TYPE": "String", "DATALIST": true },
{ "ID": "pr_press_parameters_core_pos_left", "NAME": "Bal magpozíció az ALU lapon (X;Y koordináták)", "TYPE": "String", "DATALIST": true },
{ "ID": "pr_press_parameters_core_pos_right", "NAME": "Jobb magpozíció az ALU lapon (X;Y koordináták)", "TYPE": "String", "DATALIST": true },
{ "ID": "pr_press_parameters_goliath_heating_program", "NAME": "Góliát fűtésprogram", "TYPE": "String", "DATALIST": true },
{ "ID": "pr_press_parameters_note", "NAME": "Megjegyzés", "TYPE": "String", "DATALIST": false },
{ "ID": "pr_process_parameters_front_air_deflector_edge", "NAME": "Légterelő perem elől (mm)", "TYPE": "String", "DATALIST": false },
{ "ID": "pr_process_parameters_top_air_deflector_edge", "NAME": "Légterelő perem fent (mm)", "TYPE": "String", "DATALIST": false },
{ "ID": "pr_process_parameters_back_air_deflector_edge", "NAME": "Légterelő perem hátul (mm)", "TYPE": "String", "DATALIST": false },
{ "ID": "pr_process_parameters_front_air_deflector_nail", "NAME": "Légterelőköröm elöl (mm)", "TYPE": "String", "DATALIST": false },
{ "ID": "pr_process_parameters_top_air_deflector_nail", "NAME": "Légterelőköröm fent (mm)", "TYPE": "String", "DATALIST": false },
{ "ID": "pr_process_parameters_back_air_deflector_nail", "NAME": "Légterelőköröm hátul (mm)", "TYPE": "String", "DATALIST": false },
{ "ID": "pr_process_parameters_front_air_deflector_nut", "NAME": "Légterelőnút elöl (mm)", "TYPE": "String", "DATALIST": false },
{ "ID": "pr_process_parameters_top_air_deflector_nut", "NAME": "Légterelőnút fent (mm)", "TYPE": "String", "DATALIST": false },
{ "ID": "pr_process_parameters_back_air_deflector_nut", "NAME": "Légterelőnút hátul (mm)", "TYPE": "String", "DATALIST": false },
{ "ID": "pr_process_parameters_milled_or_planed", "NAME": "Mart vagy gyalult", "TYPE": "String", "DATALIST": true },
{ "ID": "pr_process_parameters_note", "NAME": "Megjegyzés", "TYPE": "String", "DATALIST": false },
{ "ID": "pr_process_parameters_processing_class", "NAME": "Feldolgozási osztály (A vagy B)", "TYPE": "String", "DATALIST": true },
{ "ID": "pr_packing_parameters_instructions", "NAME": "Utasítás", "TYPE": "String", "DATALIST": true },
{ "ID": "pr_packing_parameters_corner_element", "NAME": "Sarokelem", "TYPE": "String", "DATALIST": true },
{ "ID": "pr_packing_parameters_u_profile_type", "NAME": "U-profil típusa", "TYPE": "String", "DATALIST": true },
{ "ID": "pr_packing_parameters_u_profile_pcs", "NAME": "U-profil darabszáma (db)", "TYPE": "String", "DATALIST": false },
{ "ID": "pr_packing_parameters_is_tape_infront", "NAME": "Van szalag elöl?", "TYPE": "String", "DATALIST": true },
{ "ID": "pr_packing_parameters_is_tape_intop", "NAME": "Van szalag felül?", "TYPE": "String", "DATALIST": true },
{ "ID": "pr_packing_parameters_is_tape_inback", "NAME": "Van szalag hátul?", "TYPE": "String", "DATALIST": true },
{ "ID": "pr_packing_parameters_note", "NAME": "Megjegyzés", "TYPE": "String", "DATALIST": false },
{ "ID": "pr_warehouse_parameters_foil_product_place", "NAME": "Fóliás termékhely", "TYPE": "String", "DATALIST": true },
{ "ID": "pr_warehouse_parameters_size", "NAME": "Doboz mérete", "TYPE": "String", "DATALIST": true },
{ "ID": "pr_support_instruction", "NAME": "Utasítás", "TYPE": "String", "DATALIST": true },
{ "ID": "pr_support_video", "NAME": "Felszerelési videó", "TYPE": "String", "DATALIST": false },
{ "ID": "pr_support_u_position", "NAME": "U profil helye", "TYPE": "String", "DATALIST": true },
{ "ID": "pr_support_u_type_db", "NAME": "U profil típusa és mennyisége", "TYPE": "String", "DATALIST": true },
{ "ID": "pr_support_video_export", "NAME": "Felszerelési videó export", "TYPE": "String", "DATALIST": false }
],
"BoxSizes": [
{ "Name": "ClimAir első", "ACCEPTABLE": "" },
{ "Name": "ClimAir hátsó", "ACCEPTABLE": "" },
{ "Name": "ClimAir bumeráng", "ACCEPTABLE": "" },
{ "Name": "Bumeráng", "ACCEPTABLE": "" },
{ "Name": "Sporty", "ACCEPTABLE": "" },
{ "Name": "Univerzális", "ACCEPTABLE": "" },
{ "Name": "Hármas", "ACCEPTABLE": "" },
{ "Name": "Nagy kamion", "ACCEPTABLE": "" }
],
"ProductionPerms": [
{ "PARAM": "item_id", "PERM": "production_prep" },
{ "PARAM": "db_start", "PERM": "production_prep" },
{ "PARAM": "date_start", "PERM": "production_prep" },
{ "PARAM": "remain_r", "PERM": "production_prep" },
{ "PARAM": "remain_l", "PERM": "production_prep" },
{ "PARAM": "ordered", "PERM": "production_prep" },
{ "PARAM": "tablesize_x", "PERM": "production_prep" },
{ "PARAM": "tablesize_y", "PERM": "production_prep" },
{ "PARAM": "db_table", "PERM": "production_prep" },
{ "PARAM": "db_granules", "PERM": "production_prep" },
{ "PARAM": "date_prep", "PERM": "production_tools" },
{ "PARAM": "date_prepend", "PERM": "production_tools" },
{ "PARAM": "date_cut", "PERM": "production_cut" },
{ "PARAM": "date_cutend", "PERM": "production_cut" },
{ "PARAM": "db_cut_r", "PERM": "production_cut" },
{ "PARAM": "db_cut_l", "PERM": "production_cut" },
{ "PARAM": "date_press", "PERM": "production_press" },
{ "PARAM": "date_pressend", "PERM": "production_press" },
{ "PARAM": "db_press_r", "PERM": "production_press" },
{ "PARAM": "db_press_l", "PERM": "production_press" },
{ "PARAM": "press_machine", "PERM": "production_press" },
{ "PARAM": "date_process", "PERM": "production_process" },
{ "PARAM": "date_processend", "PERM": "production_process" },
{ "PARAM": "db_process_r", "PERM": "production_process" },
{ "PARAM": "db_process_l", "PERM": "production_process" },
{ "PARAM": "process_mode", "PERM": "production_process" },
{ "PARAM": "db_granules_used", "PERM": "production_process" },
{ "PARAM": "kwh_start", "PERM": "production_process" },
{ "PARAM": "kwh_stop", "PERM": "production_process" },
{ "PARAM": "date_clean", "PERM": "production_postprocess" },
{ "PARAM": "date_cleanend", "PERM": "production_postprocess" },
{ "PARAM": "db_clean_r", "PERM": "production_postprocess" },
{ "PARAM": "db_clean_l", "PERM": "production_postprocess" },
{ "PARAM": "date_warehouseend", "PERM": "warehouse_add" },
{ "PARAM": "db_revenue", "PERM": "warehouse_add" },
{ "PARAM": "date_revenue", "PERM": "production_revenue" },
{ "PARAM": "db_revenue_bulk_r", "PERM": "production_revenue" },
{ "PARAM": "db_revenue_bulk_l", "PERM": "production_revenue" }
]
}

536
managers/statistics.php Normal file
View File

@ -0,0 +1,536 @@
<?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!");
}
?>

127
managers/synch.php Normal file
View File

@ -0,0 +1,127 @@
<?php
header('Content-Type: application/json');
include 'dbconn.php';
$localIP = trim(shell_exec('hostname -I | cut -d" " -f1'));
if (isset($_GET['mode'])) {
if ($localIP == '192.168.15.10' && $_GET['mode'] == 'sender') {
try {
$result = $conn->query("SHOW TABLES");
$tables = [];
while ($row = $result->fetch_array(MYSQLI_NUM)) {
$tables[] = $row[0];
}
$dump = [];
foreach ($tables as $table) {
$schema_result = $conn->query("DESCRIBE `$table`");
$schema = [];
while ($row = $schema_result->fetch_assoc()) {
$schema[] = $row;
}
$data_result = $conn->query("SELECT * FROM `$table`");
$data = [];
while ($row = $data_result->fetch_assoc()) {
$data[] = $row;
}
$dump[$table] = [
'schema' => $schema,
'data' => $data,
'count' => count($data)
];
}
$version = json_decode(file_get_contents(__DIR__ . '/version.json'), true);
$devplan = json_decode(file_get_contents(__DIR__ . '/devplan.json'), true);
echo json_encode([
'status' => 'success',
'database' => $serverdb,
'tables' => $dump,
'table_count' => count($tables),
'version' => $version,
'devplan' => $devplan
]);
} catch (Exception $e) {
http_response_code(500);
echo json_encode([
'status' => 'error',
'message' => $e->getMessage()
]);
}
} else if ($localIP == '192.168.15.11' && $_GET['mode'] == 'importer') {
$source_url = 'https://szaturnusz.szatuna.hu/managers/synch.php?mode=sender';
try {
$response = file_get_contents($source_url);
$data = json_decode($response, true);
if ($data['status'] !== 'success') {
throw new Exception('Küldő hiba: ' . $data['message']);
}
$results = [];
foreach ($data['tables'] as $table => $table_data) {
mysqli_query($conn, "TRUNCATE TABLE `$table`");
$rows = $table_data['data'];
if (empty($rows)) {
$results[$table] = 'Üres táblázat';
continue;
}
$columns = array_keys($rows[0]);
$placeholders = implode(',', array_map(fn($col) => "`$col`", $columns));
$values_placeholders = implode(',', array_fill(0, count($columns), '?'));
$updates = implode(',', array_map(fn($col) => "`$col`=VALUES(`$col`)", $columns));
$sql = "INSERT INTO `$table` ($placeholders) VALUES ($values_placeholders) ON DUPLICATE KEY UPDATE $updates";
$stmt = $conn->prepare($sql);
$types = str_repeat('s', count($columns));
$imported = 0;
foreach ($rows as $row) {
$values = array_values($row);
$stmt->bind_param($types, ...$values);
$stmt->execute();
$imported++;
}
$results[$table] = "$imported sor importálva";
}
file_put_contents(__DIR__ . '/version.json', json_encode($data['version'], JSON_PRETTY_PRINT | JSON_UNESCAPED_UNICODE));
file_put_contents(__DIR__ . '/devplan.json', json_encode($data['devplan'], JSON_PRETTY_PRINT | JSON_UNESCAPED_UNICODE));
$results['version.json'] = 'Szinkronizálva';
$results['devplan.json'] = 'Szinkronizálva';
echo json_encode([
'status' => 'success',
'database' => $serverdb,
'results' => $results,
'table_count' => count($results)
]);
} catch (Exception $e) {
http_response_code(500);
echo json_encode([
'status' => 'error',
'message' => $e->getMessage()
]);
}
}
}
?>

View File

@ -0,0 +1,85 @@
<p style="color: #333333; margin-bottom: 0px; margin-left: 0px; font-size: 23px; font-weight: bold;">Dobozolási folyamat</p>
<p style="opacity: 0.8; margin-top: 0px;">Cikkszám: <span style="color: var(--panelcolor);" id="item_id">##</span></p>
<div class="accordion">
<div class="AppSection"><div class="header">Dobozolásra kerül <span id="date_start" style="opacity: 0.8; margin-left: 15px;"></span><i class='icon' title='Katalógus' onclick="OpenCatalogue('Dobozolásra kerül', 'pr_packing_parameters_instructions,pr_packing_parameters_corner_element,pr_packing_parameters_u_profile_type,pr_packing_parameters_u_profile_pcs,pr_packing_parameters_is_tape_infront,pr_packing_parameters_is_tape_intop,pr_packing_parameters_is_tape_inback,pr_packing_parameters_note,pr_warehouse_parameters_size');"><i data-feather='book-open'></i></i></div><div class="information">
<div style="display: inline; float: left; padding-left: 15px;">
<p>Cikkszám: </p>
<input onchange="SaveSingleParam(this.id, this.id);" type="text" id="item_id" placeholder="Cikkszám..." autocomplete="off" autocapitalize="off" spellcheck="false" autocorrect="off" style="width: 147px; height: 17px;">
</div><div style="display: inline; float: left; padding-left: 15px;">
<p>Dobozolandó pár mennyisége: </p>
<input onchange="SaveSingleParam(this.id, this.id);" type="number" min="1" id="db_start" placeholder="Dobozolandó pár mennyisége..." autocomplete="off" autocapitalize="off" spellcheck="false" autocorrect="off" style="width: 147px; height: 17px;">
</div><div style="display: inline; float: left; padding-left: 15px;">
<p style="color: #f5f5f5;">: </p>
<button onclick="ProdStart();" id="date_start_btn" title="$[date_start]">Dobozolás elindítása</button>
<input type="hidden" id="date_start">
</div>
</div></div>
<div class="AppSection"><div class="header">Raktározás <span id="date_warehouseend" style="opacity: 0.8; margin-left: 15px;"></span></div><div class="information" id="WarehouseSection">
<div style="display: inline; float: left; padding-left: 15px;">
<p>Hány pár dobozolva : </p>
<p><span id="db_revenue" style="color: var(--panelcolor);">0</span> / <span id="db_start">0</span><i style="opacity: 0.8;"> pár dobozolva</i></p>
</div><div style="display: inline; float: right; margin-right: 15px;">
<button onclick="WarehouseEnd();" id="date_warehouseend_btn" title="$[date_warehouseend]">Raktározás elmentése</button>
<input type="hidden" id="date_warehouseend">
</div>
<div id="WarehouseAdd">
<br clear="all">
<p style="width: calc(100% - 15px); border-bottom: solid 1px rgb(211,220,228); display: inline-block; color: #d3dce4;">Raktározási program</p>
<br clear="all">
<div style="width: 100%; min-height: 85px;">
<div style="display: inline; float: left; padding-left: 15px;">
<p>Mennyiség: </p>
<input type="number" min="1" id="filter-amount" value="1" placeholder="Mennyiség..." onkeydown="if (event.keyCode == 13) {SearchWarehouse();}" autocomplete="off" style="width: 147px; height: 17px;">
</div><div style="display: inline; float: left; padding-left: 15px;">
<p>Raktárhely: </p>
<select id="filter-location">$[filter-location]</select>
</div><div style="display: inline; float: left; padding-left: 15px;">
<p style="color: #f5f5f5;">: </p>
<button onclick="SearchWarehouse();">Optimális hely keresése</button>
</div>
</div>
<br clear="all">
<div style="border-top: solid 1px rgb(211,220,228); width: calc(100% - 15px); height: 0px; margin-top: 15px;"></div>
<br clear="all">
<div id="result_div" style="display: none; visibility: invisible;">
<div style="width: 100%; margin-left: 10px; margin-top: 10px; display: inline; float: left;">
<div class="tables" style="width: 100%">
<table id="table">
<thead>
<tr style="top: 0px; position: sticky; z-index: 1;">
<th style="background-color: #ddd; width: 100px; color: #333; border: none; text-align: center;">Cikkszám</th>
<th>Helye</th>
<th>Mennyiség</th>
<th style="width: 100px;">Elhelyezés</th>
</tr>
</thead>
<tbody>
</tbody>
</table>
</div>
</div>
<br clear="all">
<div style="border-top: solid 1px rgb(211,220,228); width: calc(100% - 15px); height: 0px; margin-top: 15px;"></div>
<br clear="all">
</div>
</div>
</div></div>
</div>

View File

@ -0,0 +1,167 @@
<p style="color: #333333; margin-bottom: 0px; margin-left: 0px; font-size: 23px; font-weight: bold;">Classic termékgyártás</p>
<i class="icon" title='Szerkesztő mód' onclick="EditorMode()" id="EditorMode_icon"><i data-feather='edit'></i></i>
<i class="icon" title='Duplikálás' onclick="DuplicateProduction()" id="DuplicateProduction_icon"><i data-feather='copy'></i></i>
<p style="opacity: 0.8; margin-top: 0px; width: calc(100% - 70px);">Cikkszám: <span style="color: var(--panelcolor);" id="item_id">##</span></p>
<div class="accordion">
<div class="AppSection"><div class="header">Gyártásba kerül <span id="date_start" style="opacity: 0.8; margin-left: 15px;"></span><i class='icon' title='Katalógus' onclick="OpenCatalogue('Gyártásba kerül', 'st_annual_total_consumption,st_annual_average_production,st_annual_average_scrap');"><i data-feather='book-open'></i></i></div><div class="information">
<div style="display: inline; float: left; padding-left: 15px;">
<p>Cikkszám: </p>
<input onchange="SaveSingleParam(this.id, this.id);" type="text" id="item_id" placeholder="Cikkszám..." autocomplete="off" autocapitalize="off" spellcheck="false" autocorrect="off" style="width: 147px; height: 17px;">
</div><div style="display: inline; float: left; padding-left: 15px;">
<p>Gyártandó pár mennyisége: </p>
<input onchange="SaveSingleParam(this.id, this.id);" type="number" min="1" id="db_start" placeholder="Gyártandó pár mennyisége..." autocomplete="off" autocapitalize="off" spellcheck="false" autocorrect="off" style="width: 147px; height: 17px;">
</div><div style="display: inline; float: left; padding-left: 15px;">
<p style="color: #f5f5f5;">: </p>
<button onclick="ProdStart();" id="date_start_btn" title="$[date_start]">Gyártás elindítása</button>
<input type="hidden" id="date_start">
</div>
</div></div>
<div class="AppSection"><div class="header">Gyártás előkészítése <span id="ordered" style="opacity: 0.8; margin-left: 15px;"></span><i class='icon' title='Katalógus' onclick="OpenCatalogue('Gyártás előkészítése', 'pr_cutting_parameters_pcs,wh_foil_right,wh_foil_left');"><i data-feather='book-open'></i></i></div><div class="information">
<div style="display: inline; float: left; padding-left: 15px;">
<p>Maradék bal: </p>
<input onchange="SaveSingleParam(this.id, this.id);" type="number" min="0" id="remain_l" placeholder="Maradék bal..." autocomplete="off" autocapitalize="off" spellcheck="false" autocorrect="off" style="width: 147px; height: 17px;">
</div><div style="display: inline; float: left; padding-left: 15px;">
<p>Maradék jobb: </p>
<input onchange="SaveSingleParam(this.id, this.id);" type="number" min="0" id="remain_r" placeholder="Maradék jobb..." autocomplete="off" autocapitalize="off" spellcheck="false" autocorrect="off" style="width: 147px; height: 17px;">
</div><div style="display: inline; float: left; padding-left: 15px;">
<p>Táblaméret x (mm): </p>
<input onchange="SaveSingleParam(this.id, this.id);" type="number" min="1" id="tablesize_x" placeholder="Táblaméret x (mm)..." autocomplete="off" autocapitalize="off" spellcheck="false" autocorrect="off" style="width: 147px; height: 17px;">
</div><div style="display: inline; float: left; padding-left: 15px;">
<p>Táblaméret y (mm): </p>
<input onchange="SaveSingleParam(this.id, this.id);" type="number" min="1" id="tablesize_y" placeholder="Táblaméret y (mm)..." autocomplete="off" autocapitalize="off" spellcheck="false" autocorrect="off" style="width: 147px; height: 17px;">
</div><div style="display: inline; float: left; padding-left: 15px;">
<p>Tábla mennyiség: </p>
<input onchange="SaveSingleParam(this.id, this.id);" type="number" min="1" id="db_table" placeholder="Tábla mennyiség..." autocomplete="off" autocapitalize="off" spellcheck="false" autocorrect="off" style="width: 147px; height: 17px;">
</div><div style="display: inline; float: left; padding-left: 15px;">
<p style="color: #f5f5f5;">: </p>
<button onclick="ClassicPrepEnd();" id="ordered_btn" title="$[ordered]">Mentés</button>
<input type="hidden" id="ordered">
</div>
</div></div>
<div class="AppSection"><div class="header">Szerszám előkészítése <span id="date_prepend" style="opacity: 0.8; margin-left: 15px;"></span><i class='icon' title='Katalógus' onclick="OpenCatalogue('Szerszám előkészítése', 'pr_press_parameters_core_pos_left,pr_press_parameters_core_pos_right,pr_tool_loc_disc_position,pr_tool_loc_core_position,pr_tool_loc_note,pr_basic_info_press_machine');"><i data-feather='book-open'></i></i></div><div class="information">
<div style="display: inline; float: left; padding-left: 15px;">
<button onclick="ToolPrepStart();" id="date_prep_btn" title="$[date_prep]">Start</button>
<input type="hidden" id="date_prep">
</div><div style="display: inline; float: left; padding-left: 15px;">
<button onclick="ClassicToolPrepEnd();" id="date_prepend_btn" title="$[date_prepend]">Stop</button>
<input type="hidden" id="date_prepend">
</div>
</div></div>
<div class="AppSection"><div class="header">Terítékfelvágás <span id="date_cutend" style="opacity: 0.8; margin-left: 15px;"></span></div><div class="information">
<div style="display: inline; float: left; padding-left: 15px;">
<p style="color: #f5f5f5;">: </p>
<button onclick="CutStart();" id="date_cut_btn" title="$[date_cut]">Start</button>
<input type="hidden" id="date_cut">
</div><div style="display: inline; float: left; padding-left: 15px;">
<p>Kész bal: </p>
<input onchange="SaveSingleParam(this.id, this.id);" type="number" min="1" id="db_cut_l" placeholder="Kész bal..." autocomplete="off" autocapitalize="off" spellcheck="false" autocorrect="off" style="width: 147px; height: 17px;">
</div><div style="display: inline; float: left; padding-left: 15px;">
<p>Kész jobb: </p>
<input onchange="SaveSingleParam(this.id, this.id);" type="number" min="1" id="db_cut_r" placeholder="Kész jobb..." autocomplete="off" autocapitalize="off" spellcheck="false" autocorrect="off" style="width: 147px; height: 17px;">
</div><div style="display: inline; float: left; padding-left: 15px;">
<p style="color: #f5f5f5;">: </p>
<button onclick="CutEnd();" id="date_cutend_btn" title="$[date_cutend]">Stop</button>
<input type="hidden" id="date_cutend">
</div>
</div></div>
<div class="AppSection"><div class="header">Préslégformázás <span id="date_pressend" style="opacity: 0.8; margin-left: 15px;"></span><i class='icon' title='Katalógus' onclick="OpenCatalogue('Préslégformázás', 'pr_process_parameters_front_air_deflector_edge,pr_process_parameters_top_air_deflector_edge,pr_process_parameters_back_air_deflector_edge,pr_press_parameters_is_codereader,pr_process_parameters_milled_or_planed');"><i data-feather='book-open'></i></i></div><div class="information">
<div style="display: inline; float: left; padding-left: 15px;">
<p style="color: #f5f5f5;">: </p>
<button onclick="PressStart();" id="date_press_btn" title="$[date_press]">Start</button>
<input type="hidden" id="date_press">
</div><div style="display: inline; float: left; padding-left: 15px;">
<p>Kész bal: </p>
<input onchange="SaveSingleParam(this.id, this.id);" type="number" min="1" id="db_press_l" placeholder="Kész bal..." autocomplete="off" autocapitalize="off" spellcheck="false" autocorrect="off" style="width: 147px; height: 17px;">
</div><div style="display: inline; float: left; padding-left: 15px;">
<p>Kész jobb: </p>
<input onchange="SaveSingleParam(this.id, this.id);" type="number" min="1" id="db_press_r" placeholder="Kész jobb..." autocomplete="off" autocapitalize="off" spellcheck="false" autocorrect="off" style="width: 147px; height: 17px;">
</div><div style="display: inline; float: left; padding-left: 15px;">
<p>Présgép: </p>
<select id="press_machine" onchange="SaveSingleParam(this.id, this.id);">
<option value="Futkosó">Futkosó</option>
<option value="Góliát">Góliát</option>
</select>
</div><div style="display: inline; float: left; padding-left: 15px;">
<p style="color: #f5f5f5;">: </p>
<button onclick="ClassicPressEnd();" id="date_pressend_btn" title="$[date_pressend]">Stop</button>
<input type="hidden" id="date_pressend">
</div>
</div></div>
<div class="AppSection"><div class="header">Feldolgozás <span id="date_processend" style="opacity: 0.8; margin-left: 15px;"></span><i class='icon' title='Katalógus' onclick="OpenCatalogue('Feldolgozás', 'pr_process_parameters_front_air_deflector_nail,pr_process_parameters_top_air_deflector_nail,pr_process_parameters_back_air_deflector_nail,pr_process_parameters_front_air_deflector_nut,pr_process_parameters_top_air_deflector_nut,pr_process_parameters_back_air_deflector_nut,pr_process_parameters_milled_or_planed');"><i data-feather='book-open'></i></i></div><div class="information">
<div style="display: inline; float: left; padding-left: 15px;">
<p style="color: #f5f5f5;">: </p>
<button onclick="ProcessStart();" id="date_process_btn" title="$[date_process]">Start</button>
<input type="hidden" id="date_process">
</div><div style="display: inline; float: left; padding-left: 15px;">
<p>Kész bal: </p>
<input onchange="SaveSingleParam(this.id, this.id);" type="number" min="1" id="db_process_l" placeholder="Kész bal..." autocomplete="off" autocapitalize="off" spellcheck="false" autocorrect="off" style="width: 147px; height: 17px;">
</div><div style="display: inline; float: left; padding-left: 15px;">
<p>Kész jobb: </p>
<input onchange="SaveSingleParam(this.id, this.id);" type="number" min="1" id="db_process_r" placeholder="Kész jobb..." autocomplete="off" autocapitalize="off" spellcheck="false" autocorrect="off" style="width: 147px; height: 17px;">
</div><div style="display: inline; float: left; padding-left: 15px;">
<p>Módja: </p>
<select id="process_mode" onchange="SaveSingleParam(this.id, this.id);">
<option value="Gyalus">Gyalus</option>
<option value="Marós">Marós</option>
</select>
</div><div style="display: inline; float: left; padding-left: 15px;">
<p style="color: #f5f5f5;">: </p>
<button onclick="ClassicProcessEnd();" id="date_processend_btn" title="$[date_processend]">Stop</button>
<input type="hidden" id="date_processend">
</div>
</div></div>
<div class="AppSection"><div class="header">Tisztítás <span id="date_cleanend" style="opacity: 0.8; margin-left: 15px;"></span><i class='icon' title='Katalógus' onclick="OpenCatalogue('Tisztítás', 'pr_packing_parameters_instructions,pr_packing_parameters_corner_element,pr_packing_parameters_u_profile_type,pr_packing_parameters_u_profile_pcs,pr_packing_parameters_is_tape_infront,pr_packing_parameters_is_tape_intop,pr_packing_parameters_is_tape_inback,pr_packing_parameters_note');"><i data-feather='book-open'></i></i></div><div class="information">
<div style="display: inline; float: left; padding-left: 15px;">
<p style="color: #f5f5f5;">: </p>
<button onclick="PostprocessStart();" id="date_clean_btn" title="$[date_clean]">Start</button>
<input type="hidden" id="date_clean">
</div><div style="display: inline; float: left; padding-left: 15px;">
<p>Kész bal: </p>
<input onchange="SaveSingleParam(this.id, this.id);" type="number" min="1" id="db_clean_l" placeholder="Kész bal..." autocomplete="off" autocapitalize="off" spellcheck="false" autocorrect="off" style="width: 147px; height: 17px;">
</div><div style="display: inline; float: left; padding-left: 15px;">
<p>Kész jobb: </p>
<input onchange="SaveSingleParam(this.id, this.id);" type="number" min="1" id="db_clean_r" placeholder="Kész jobb..." autocomplete="off" autocapitalize="off" spellcheck="false" autocorrect="off" style="width: 147px; height: 17px;">
</div><div style="display: inline; float: left; padding-left: 15px;">
<p style="color: #f5f5f5;">: </p>
<button onclick="PostprocessEnd();" id="date_cleanend_btn" title="$[date_cleanend]">Stop</button>
<input type="hidden" id="date_cleanend">
</div>
</div></div>
<div class="AppSection"><div class="header">Raktározás <span id="date_warehouseend" style="opacity: 0.8; margin-left: 15px;"></span><i class='icon' title='Katalógus' onclick="OpenCatalogue('Raktározás', 'pr_warehouse_parameters_size');"><i data-feather='book-open'></i></i></div><div class="information" id="WarehouseSection">
<div style="display: none; float: left;">
<p>Hány pár dobozolva : </p>
<p><span id="db_revenue" style="color: var(--panelcolor);">0</span><i style="opacity: 0.8;"> pár dobozolva</i></p>
</div><div style="display: inline; float: left; padding-left: 15px;">
<p>Hány bal került fóliásba: </p>
<p><span id="db_revenue_bulk_l" style="color: var(--panelcolor);">0</span><i style="opacity: 0.8;"> db</i></p>
</div><div style="display: inline; float: left; padding-left: 15px;">
<p>Hány jobb került fóliásba: </p>
<p><span id="db_revenue_bulk_r" style="color: var(--panelcolor);">0</span><i style="opacity: 0.8;"> db</i></p>
</div><div style="display: inline; float: right; margin-right: 15px;">
<button onclick="WarehouseEnd();" id="date_warehouseend_btn" title="$[date_warehouseend]">Bevételezés és gyártás lezárása</button>
<input type="hidden" id="date_warehouseend">
</div>
<br clear="all">
<div id="WarehouseAdd" style="border-top: 1px solid rgb(211, 220, 228);"></div>
</div></div>
</div>

View File

@ -0,0 +1,113 @@
<p style="color: #333333; margin-bottom: 0px; margin-left: 0px; font-size: 23px; font-weight: bold;">Fröccsöntött termékgyártás</p>
<i class="icon" title='Szerkesztő mód' onclick="EditorMode()" id="EditorMode_icon"><i data-feather='edit'></i></i>
<i class="icon" title='Duplikálás' onclick="DuplicateProduction()" id="DuplicateProduction_icon"><i data-feather='copy'></i></i>
<p style="opacity: 0.8; margin-top: 0px; width: calc(100% - 70px);">Cikkszám: <span style="color: var(--panelcolor);" id="item_id">##</span></p>
<div class="accordion">
<div class="AppSection"><div class="header">Gyártásba kerül <span id="date_start" style="opacity: 0.8; margin-left: 15px;"></span><i class='icon' title='Katalógus' onclick="OpenCatalogue('Gyártásba kerül', 'st_annual_total_consumption,st_annual_average_production,st_annual_average_scrap');"><i data-feather='book-open'></i></i></div><div class="information">
<div style="display: inline; float: left; padding-left: 15px;">
<p>Cikkszám: </p>
<input onchange="SaveSingleParam(this.id, this.id);" type="text" id="item_id" placeholder="Cikkszám..." autocomplete="off" autocapitalize="off" spellcheck="false" autocorrect="off" style="width: 147px; height: 17px;">
</div><div style="display: inline; float: left; padding-left: 15px;">
<p>Gyártandó pár mennyisége: </p>
<input onchange="SaveSingleParam(this.id, this.id);" type="number" min="1" id="db_start" placeholder="Gyártandó pár mennyisége..." autocomplete="off" autocapitalize="off" spellcheck="false" autocorrect="off" style="width: 147px; height: 17px;">
</div><div style="display: inline; float: left; padding-left: 15px;">
<p style="color: #f5f5f5;">: </p>
<button onclick="ProdStart();" id="date_start_btn" title="$[date_start]">Gyártás elindítása</button>
<input type="hidden" id="date_start">
</div>
</div></div>
<div class="AppSection"><div class="header">Gyártás előkészítése <span id="ordered" style="opacity: 0.8; margin-left: 15px;"></span><i class='icon' title='Katalógus' onclick="OpenCatalogue('Gyártás előkészítése', 'pr_cutting_parameters_pcs,wh_foil_right,wh_foil_left');"><i data-feather='book-open'></i></i></div><div class="information">
<div style="display: inline; float: left; padding-left: 15px;">
<p>Megrendelt granulátom (kg): </p>
<input onchange="SaveSingleParam(this.id, this.id);" type="number" min="1" id="db_granules" placeholder="Megrendelt granulátom..." autocomplete="off" autocapitalize="off" spellcheck="false" autocorrect="off" style="width: 147px; height: 17px;">
</div><div style="display: inline; float: left; padding-left: 15px;">
<p style="color: #f5f5f5;">: </p>
<button onclick="InjmoldPrepEnd();" id="ordered_btn" title="$[ordered]">Mentés</button>
<input type="hidden" id="ordered">
</div>
</div></div>
<div class="AppSection"><div class="header">Szerszám előkészítése <span id="date_prepend" style="opacity: 0.8; margin-left: 15px;"></span></div><div class="information">
<div style="display: inline; float: left; padding-left: 15px;">
<button onclick="ToolPrepStart();" id="date_prep_btn" title="$[date_prep]">Start</button>
<input type="hidden" id="date_prep">
</div><div style="display: inline; float: left; padding-left: 15px;">
<button onclick="InjmoldToolPrepEnd();" id="date_prepend_btn" title="$[date_prepend]">Stop</button>
<input type="hidden" id="date_prepend">
</div>
</div></div>
<div class="AppSection"><div class="header">Fröccsöntés <span id="date_processend" style="opacity: 0.8; margin-left: 15px;"></span></div><div class="information">
<div style="display: inline; float: left; padding-left: 15px;">
<p>Villanyóra start (kWh): </p>
<input onchange="SaveSingleParam(this.id, this.id);" type="number" min="1" id="kwh_start" placeholder="Villanyóra start..." autocomplete="off" autocapitalize="off" spellcheck="false" autocorrect="off" style="width: 147px; height: 17px;">
</div><div style="display: inline; float: left; padding-left: 15px;">
<p style="color: #f5f5f5;">: </p>
<button onclick="ProcessStart();" id="date_process_btn" title="$[date_process]">Start</button>
<input type="hidden" id="date_process">
</div><div style="display: inline; float: left; padding-left: 15px;">
<p>Kész bal: </p>
<input onchange="SaveSingleParam(this.id, this.id);" type="number" min="1" id="db_process_l" placeholder="Kész bal..." autocomplete="off" autocapitalize="off" spellcheck="false" autocorrect="off" style="width: 147px; height: 17px;">
</div><br clear="all"><div style="display: inline; float: left;">
<p>Kész jobb: </p>
<input onchange="SaveSingleParam(this.id, this.id);" type="number" min="1" id="db_process_r" placeholder="Kész jobb..." autocomplete="off" autocapitalize="off" spellcheck="false" autocorrect="off" style="width: 147px; height: 17px;">
</div><div style="display: inline; float: left; padding-left: 15px;">
<p>Használt anyag (kg): </p>
<input onchange="SaveSingleParam(this.id, this.id);" type="number" min="1" id="db_granules_used" placeholder="Használt anyag..." autocomplete="off" autocapitalize="off" spellcheck="false" autocorrect="off" style="width: 147px; height: 17px;">
</div><br clear="all"><div style="display: inline; float: left;">
<p>Villanyóra stop (kWh): </p>
<input onchange="SaveSingleParam(this.id, this.id);" type="number" min="1" id="kwh_stop" placeholder="Villanyóra stop..." autocomplete="off" autocapitalize="off" spellcheck="false" autocorrect="off" style="width: 147px; height: 17px;">
</div><div style="display: inline; float: left; padding-left: 15px;">
<p style="color: #f5f5f5;">: </p>
<button onclick="InjmoldProcessEnd();" id="date_processend_btn" title="$[date_processend]">Stop</button>
<input type="hidden" id="date_processend">
</div>
</div></div>
<div class="AppSection"><div class="header">Utómunka <span id="date_cleanend" style="opacity: 0.8; margin-left: 15px;"></span><i class='icon' title='Katalógus' onclick="OpenCatalogue('Tisztítás', 'pr_packing_parameters_instructions,pr_packing_parameters_corner_element,pr_packing_parameters_u_profile_type,pr_packing_parameters_u_profile_pcs,pr_packing_parameters_is_tape_infront,pr_packing_parameters_is_tape_intop,pr_packing_parameters_is_tape_inback,pr_packing_parameters_note');"><i data-feather='book-open'></i></i></div><div class="information">
<div style="display: inline; float: left; padding-left: 15px;">
<p style="color: #f5f5f5;">: </p>
<button onclick="PostprocessStart();" id="date_clean_btn" title="$[date_clean]">Start</button>
<input type="hidden" id="date_clean">
</div><div style="display: inline; float: left; padding-left: 15px;">
<p>Kész bal: </p>
<input onchange="SaveSingleParam(this.id, this.id);" type="number" min="1" id="db_clean_l" placeholder="Kész bal..." autocomplete="off" autocapitalize="off" spellcheck="false" autocorrect="off" style="width: 147px; height: 17px;">
</div><div style="display: inline; float: left; padding-left: 15px;">
<p>Kész jobb: </p>
<input onchange="SaveSingleParam(this.id, this.id);" type="number" min="1" id="db_clean_r" placeholder="Kész jobb..." autocomplete="off" autocapitalize="off" spellcheck="false" autocorrect="off" style="width: 147px; height: 17px;">
</div><div style="display: inline; float: left; padding-left: 15px;">
<p style="color: #f5f5f5;">: </p>
<button onclick="PostprocessEnd();" id="date_cleanend_btn" title="$[date_cleanend]">Stop</button>
<input type="hidden" id="date_cleanend">
</div>
</div></div>
<div class="AppSection"><div class="header">Raktározás <span id="date_warehouseend" style="opacity: 0.8; margin-left: 15px;"></span><i class='icon' title='Katalógus' onclick="OpenCatalogue('Raktározás', 'pr_warehouse_parameters_size');"><i data-feather='book-open'></i></i></div><div class="information" id="WarehouseSection">
<div style="display: none; float: left; padding-left: 15px;">
<p>Hány pár dobozolva : </p>
<p><span id="db_revenue" style="color: var(--panelcolor);">0</span><i style="opacity: 0.8;"> pár dobozolva</i></p>
</div><div style="display: inline; float: left; padding-left: 15px;">
<p>Hány bal került fóliásba: </p>
<p><span id="db_revenue_bulk_l" style="color: var(--panelcolor);">0</span><i style="opacity: 0.8;"> db</i></p>
</div><div style="display: inline; float: left; padding-left: 15px;">
<p>Hány jobb került fóliásba: </p>
<p><span id="db_revenue_bulk_r" style="color: var(--panelcolor);">0</span><i style="opacity: 0.8;"> db</i></p>
</div><div style="display: inline; float: right; margin-right: 15px;">
<button onclick="WarehouseEnd();" id="date_warehouseend_btn" title="$[date_warehouseend]">Bevételezés és gyártás lezárása</button>
<input type="hidden" id="date_warehouseend">
</div>
<br clear="all">
<div id="WarehouseAdd" style="border-top: 1px solid rgb(211, 220, 228);"></div>
</div></div>
</div>

View File

@ -0,0 +1,91 @@
<!DOCTYPE html>
<html lang="hu">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<link rel="stylesheet" href="../../css/login.css">
<title>Belépés sikeres</title>
</head>
<style>
:root {
--color-primary: #2180a8;
--color-bg-primary: #fcfcf9;
--color-text-primary: #134252;
--color-success: #22c55e;
--color-white: #ffffff;
--radius-base: 8px;
}
* {
margin: 0;
padding: 0;
box-sizing: border-box;
}
body {
font-family: -apple-system, BlinkMacSystemFont, 'Segoe UI', sans-serif;
display: flex;
align-items: center;
justify-content: center;
min-height: 100vh;
background: var(--color-bg-primary);
color: var(--color-text-primary);
}
.acontainer {
text-align: center;
background: linear-gradient(135deg, rgba(255,255,255,0.2) 0%,rgba(0,0,0,0.2) 100%);
padding: 48px 40px;
border-radius: var(--radius-base);
box-shadow: 0 4px 6px -1px rgba(0, 0, 0, 0.04), 0 2px 4px -1px rgba(0, 0, 0, 0.02);
max-width: 400px;
}
.success-icon {
width: 64px;
height: 64px;
display: flex;
align-items: center;
justify-content: center;
margin: 0 auto 24px;
background: rgba(34, 197, 94, 0.1);
border-radius: 50%;
font-size: 32px;
color: var(--color-success);
}
.success-icon img {
border-radius: 50px;
width: 96px;
height: 96px;
}
h1 {
font-size: 24px;
font-weight: 600;
color: #f5f5f5;
margin-bottom: 12px;
}
p {
font-size: 16px;
color: #f5f5f5;
line-height: 1.5;
opacity: 0.8;
}
</style>
<body>
<div class="bg"></div>
<div class="acontainer">
<div class="success-icon"><img src="../../img/success.gif"></div>
<h1>Sikeresen belépve</h1>
<p>Ha az ablak nem záródik be magától, nyugodtan zárja be</p>
</div>
<script>
setTimeout(() => {
window.close();
}, 3000);
</script>
</body>
</html>

View File

@ -0,0 +1,74 @@
<!DOCTYPE html>
<html lang="hu">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Szaturnusz</title>
<style>
body {
font-family: Arial, sans-serif;
line-height: 1.6;
color: #333;
max-width: 600px;
margin: 0 auto;
padding: 20px;
background-color: #f4f4f4;
}
.email-container {
background-color: #ffffff;
padding: 30px;
border-radius: 8px;
box-shadow: 0 2px 10px rgba(0,0,0,0.1);
}
.header {
text-align: center;
border-bottom: 3px solid #2980b9;
padding-bottom: 20px;
margin-bottom: 30px;
}
.header h1 {
color: #2980b9;
margin: 0;
display: inline-block;
}
.header img {
height: 54px;
float: right;
}
.content {
margin-bottom: 30px;
}
.footer {
text-align: center;
padding-top: 20px;
border-top: 1px solid #eee;
color: #666;
font-size: 12px;
}
a {
color: #2980b9;
text-decoration: none;
}
a:hover {
text-decoration: underline;
}
</style>
</head>
<body>
<div class="email-container">
<div class="header">
<h1>{{SUBJECT}}</h1>
<img src="cid:logo_cid">
</div>
<div class="content">
{{CONTENT}}
</div>
<div class="footer">
<p>Ez egy automatikusan generált email.<br>
Szatuna Kft | kapcsolat@szatuna.hu</p>
</div>
</div>
</body>
</html>

View File

@ -0,0 +1,105 @@
<p style="color: #333333; margin-bottom: 0px; margin-left: 0px; font-size: 23px; font-weight: bold;">Sporty termékgyártás</p>
<i class="icon" title='Szerkesztő mód' onclick="EditorMode()" id="EditorMode_icon"><i data-feather='edit'></i></i>
<i class="icon" title='Duplikálás' onclick="DuplicateProduction()" id="DuplicateProduction_icon"><i data-feather='copy'></i></i>
<p style="opacity: 0.8; margin-top: 0px; width: calc(100% - 70px);">Cikkszám: <span style="color: var(--panelcolor);" id="item_id">##</span></p>
<div class="accordion">
<div class="AppSection"><div class="header">Gyártásba kerül <span id="date_start" style="opacity: 0.8; margin-left: 15px;"></span><i class='icon' title='Katalógus' onclick="OpenCatalogue('Gyártásba kerül', 'st_annual_total_consumption,st_annual_average_production,st_annual_average_scrap');"><i data-feather='book-open'></i></i></div><div class="information">
<div style="display: inline; float: left; padding-left: 15px;">
<p>Cikkszám: </p>
<input onchange="SaveSingleParam(this.id, this.id);" type="text" id="item_id" placeholder="Cikkszám..." autocomplete="off" autocapitalize="off" spellcheck="false" autocorrect="off" style="width: 147px; height: 17px;">
</div><div style="display: inline; float: left; padding-left: 15px;">
<p>Gyártandó pár mennyisége: </p>
<input onchange="SaveSingleParam(this.id, this.id);" type="number" min="1" id="db_start" placeholder="Gyártandó pár mennyisége..." autocomplete="off" autocapitalize="off" spellcheck="false" autocorrect="off" style="width: 147px; height: 17px;">
</div><div style="display: inline; float: left; padding-left: 15px;">
<p style="color: #f5f5f5;">: </p>
<button onclick="ProdStart();" id="date_start_btn" title="$[date_start]">Gyártás elindítása</button>
<input type="hidden" id="date_start">
</div>
</div></div>
<div class="AppSection"><div class="header">Gyártás előkészítése <span id="ordered" style="opacity: 0.8; margin-left: 15px;"></span><i class='icon' title='Katalógus' onclick="OpenCatalogue('Gyártás előkészítése', 'pr_basic_info_tools,pr_cutting_parameters_pcs,wh_foil_right,wh_foil_left');"><i data-feather='book-open'></i></i></div><div class="information">
<div style="display: inline; float: left; padding-left: 15px;">
<p>Maradék bal: </p>
<input onchange="SaveSingleParam(this.id, this.id);" type="number" min="0" id="remain_l" placeholder="Maradék bal..." autocomplete="off" autocapitalize="off" spellcheck="false" autocorrect="off" style="width: 147px; height: 17px;">
</div><div style="display: inline; float: left; padding-left: 15px;">
<p>Maradék jobb: </p>
<input onchange="SaveSingleParam(this.id, this.id);" type="number" min="0" id="remain_r" placeholder="Maradék jobb..." autocomplete="off" autocapitalize="off" spellcheck="false" autocorrect="off" style="width: 147px; height: 17px;">
</div><div style="display: inline; float: left; padding-left: 15px;">
<p>Táblaméret x (mm): </p>
<input onchange="SaveSingleParam(this.id, this.id);" type="number" min="1" id="tablesize_x" placeholder="Táblaméret x (mm)..." autocomplete="off" autocapitalize="off" spellcheck="false" autocorrect="off" style="width: 147px; height: 17px;">
</div><div style="display: inline; float: left; padding-left: 15px;">
<p>Táblaméret y (mm): </p>
<input onchange="SaveSingleParam(this.id, this.id);" type="number" min="1" id="tablesize_y" placeholder="Táblaméret y (mm)..." autocomplete="off" autocapitalize="off" spellcheck="false" autocorrect="off" style="width: 147px; height: 17px;">
</div><div style="display: inline; float: left; padding-left: 15px;">
<p>Tábla mennyiség: </p>
<input onchange="SaveSingleParam(this.id, this.id);" type="number" min="1" id="db_table" placeholder="Tábla mennyiség..." autocomplete="off" autocapitalize="off" spellcheck="false" autocorrect="off" style="width: 147px; height: 17px;">
</div><div style="display: inline; float: left; padding-left: 15px;">
<p style="color: #f5f5f5;">: </p>
<button onclick="SportyPrepEnd();" id="ordered_btn" title="$[ordered]">Mentés</button>
<input type="hidden" id="ordered">
</div>
</div></div>
<div class="AppSection"><div class="header">Terítékfelvágás <span id="date_cutend" style="opacity: 0.8; margin-left: 15px;"></span></div><div class="information">
<div style="display: inline; float: left; padding-left: 15px;">
<p style="color: #f5f5f5;">: </p>
<button onclick="CutStart();" id="date_cut_btn" title="$[date_cut]">Start</button>
<input type="hidden" id="date_cut">
</div><div style="display: inline; float: left; padding-left: 15px;">
<p>Kész bal: </p>
<input onchange="SaveSingleParam(this.id, this.id);" type="number" min="1" id="db_cut_l" placeholder="Kész bal..." autocomplete="off" autocapitalize="off" spellcheck="false" autocorrect="off" style="width: 147px; height: 17px;">
</div><div style="display: inline; float: left; padding-left: 15px;">
<p>Kész jobb: </p>
<input onchange="SaveSingleParam(this.id, this.id);" type="number" min="1" id="db_cut_r" placeholder="Kész jobb..." autocomplete="off" autocapitalize="off" spellcheck="false" autocorrect="off" style="width: 147px; height: 17px;">
</div><div style="display: inline; float: left; padding-left: 15px;">
<p style="color: #f5f5f5;">: </p>
<button onclick="CutEnd();" id="date_cutend_btn" title="$[date_cutend]">Stop</button>
<input type="hidden" id="date_cutend">
</div>
</div></div>
<div class="AppSection"><div class="header">Préselés <span id="date_pressend" style="opacity: 0.8; margin-left: 15px;"></span></div><div class="information">
<div style="display: inline; float: left; padding-left: 15px;">
<p style="color: #f5f5f5;">: </p>
<button onclick="PressStart();" id="date_press_btn" title="$[date_press]">Start</button>
<input type="hidden" id="date_press">
</div><div style="display: inline; float: left; padding-left: 15px;">
<p>Kész bal: </p>
<input onchange="SaveSingleParam(this.id, this.id);" type="number" min="1" id="db_press_l" placeholder="Kész bal..." autocomplete="off" autocapitalize="off" spellcheck="false" autocorrect="off" style="width: 147px; height: 17px;">
</div><div style="display: inline; float: left; padding-left: 15px;">
<p>Kész jobb: </p>
<input onchange="SaveSingleParam(this.id, this.id);" type="number" min="1" id="db_press_r" placeholder="Kész jobb..." autocomplete="off" autocapitalize="off" spellcheck="false" autocorrect="off" style="width: 147px; height: 17px;">
</div><div style="display: inline; float: left; padding-left: 15px;">
<p style="color: #f5f5f5;">: </p>
<button onclick="SportyPressEnd();" id="date_pressend_btn" title="$[date_pressend]">Stop</button>
<input type="hidden" id="date_pressend">
</div>
</div></div>
<div class="AppSection"><div class="header">Raktározás <span id="date_warehouseend" style="opacity: 0.8; margin-left: 15px;"></span><i class='icon' title='Katalógus' onclick="OpenCatalogue('Raktározás', 'pr_warehouse_parameters_size');"><i data-feather='book-open'></i></i></div><div class="information" id="WarehouseSection">
<div style="display: none; float: left;">
<p>Hány pár dobozolva : </p>
<p><span id="db_revenue" style="color: var(--panelcolor);">0</span><i style="opacity: 0.8;"> pár dobozolva</i></p>
</div><div style="display: inline; float: left; padding-left: 15px;">
<p>Hány bal került fóliásba: </p>
<p><span id="db_revenue_bulk_l" style="color: var(--panelcolor);">0</span><i style="opacity: 0.8;"> db</i></p>
</div><div style="display: inline; float: left; padding-left: 15px;">
<p>Hány jobb került fóliásba: </p>
<p><span id="db_revenue_bulk_r" style="color: var(--panelcolor);">0</span><i style="opacity: 0.8;"> db</i></p>
</div><div style="display: inline; float: right; margin-right: 15px;">
<button onclick="WarehouseEnd();" id="date_warehouseend_btn" title="$[date_warehouseend]">Bevételezés és gyártás lezárása</button>
<input type="hidden" id="date_warehouseend">
</div>
<br clear="all">
<div id="WarehouseAdd" style="border-top: 1px solid rgb(211, 220, 228);"></div>
</div></div>
</div>

6
managers/test.php Normal file
View File

@ -0,0 +1,6 @@
<?php
$xml = @file_get_contents('https://www.mnb.hu/arfolyamok/daily/webservice/CurrentExchangeRates.xml');
if ($xml === false) { die('Hiba'); }
$rates = simplexml_load_string($xml);
?>

327
managers/version.json Normal file
View File

@ -0,0 +1,327 @@
{
"updates": [
{
"build": "lb1771398000",
"changes": [
"Termék katalógus exportban szerepelnek az árak",
"Termék katalógus letöltés",
"APIn csak az értékesíthető és kifutó termékek jelennek meg"
]
},
{
"build": "lb1770793200",
"changes": [
"Havi statisztikába classic munkafolyamatok termelését",
"Több márka és típus \/ cikkszám katalógusadatok frissítés",
"Eladható mennyiség számolása a napi statisztikában",
"BUGFIX - Lezárt gyártások megjelenítése",
"Hátsó cikkszámoknál a gyártás kiemelésnél a dobozolt szetteket is figyelembe veszi",
"Készletinformáció APIn a 0-ás raktárkészletnek is szerepelnie kell",
"Lezárt gyártások ÖSSZES szűrő",
"Felkiáltó jeles kártyák előre sorolása",
"Termékgyártás - os szabad raktáras elemeinek kiemelése",
"BUGFIX - Raktározási program nem jelenik meg visszárú létrehozásnál",
"LOG - Raktármozgás",
"BUGFIX - Tizedes értékek megadása az Árazásban",
"Teljes web - adatbázis kapcsolat optimalizálás",
"Kiszedésnél szetteket lehessen doboz + fóliás kombinációjával is",
"1722 és 1722+1723 kifutóra állítva, dobozolás törölve",
"Rendelések lezárásának dátuma és törölt-e érték",
"Cikkszám specifikus statisztika",
"Statisztika letöltése",
"Árak megadása a statisztikában",
"Gyártási összidők"
]
},
{
"build": "lb1770188400",
"changes": [
"BUGFIX - Kiszedési lista",
"Havi statisztikák menupont",
"250, 500 és 1000 \/ oldal lehetőség",
"Dinamikus menu szövegméret",
"BUGFIX - Kiszedés listázása",
"BUGFIX - Polcméret ellenőrzése akkor is, ha az már szerepel a polcon",
"Csomagszám helyett Rendelésszám megjelenítése elsődlegesen",
"BUGFIX - Lezárt gyártások lapozás",
"Meghosszabbított belépési idő",
"BUGFIX - Dobozos raktár bevét modul duplikációk megszüntetése",
"Automatikus tábla mennyiség kitöltés",
"BUGFIX - Raktározásnál többszőr ne lehessen az elhelyezem gombra nyomni"
]
},
{
"build": "lb1768978800",
"changes": [
"Új megjelölés csk aktív elemekre",
"Árazás menupont",
"Új szektor paraméter, hányadik sortól lehet több cikkszám a polcon",
"Adatszinkron a teszt környezetbe",
"Napi statisztikából a megszűnt termékeket figyelmen kívűl hagyja",
"Hármas helyre csak hármas kerülhet",
"Átlag gyártási idő helyett az éves fogyást",
"Kritikus dobozos készlet",
"A raktár statisztika bővítése, hogy a töltöttséget kiírja százalékosan is a dobozos raktárnak.",
"Doboz áthelyező funkció",
"Új termékek jelölése a gyártástervezőben",
"Dobozolás lezárásának tiltása ha nincs kiszedve az összes szükséges elem",
"Dobozolási tervből cikkszámok kivétele",
"Visszáru rögzítő ablak, bevét modul",
"Dobozolási prioritás kiszámolásának módosítása",
"Raktárkészlet helyett szabad raktárkészletet vesz figyelembe a gyártás \/ dobozolás kártyáin",
"Rendelések teljesíthetőségének jelöléseinek bővítése",
"Dobozolás nem kell a gyártás végén",
"Gyártás és dobozolási lista lapozás hiba javítva",
"Nullás raktárkészletű gyártási kártyák jelölése",
"BUGFIX - 0 ás gyártás indítások tiltása",
"Gyártás szétszedése"
]
},
{
"build": "lb1768374000",
"changes": [
"Elsődlegesen PLEX raktárból kiszedés paraméter",
"Gyártási \/ Dobozolási statisztikában cikkszám elrejtés",
"Dobozolásnál automatikusan indítja a raktározási programot",
"Teríték \/ tábla a gyártás előkészítése könyvben",
"Dobozolási statisztika bővítése termékcsaládonként",
"Dobozolás kártyáin a kezdeti dobozolandó pár mennyisségének jelölése",
"Visszárú 'lezárt' jelzése",
"BUGFIX - Fóliás dobozolás joghiba",
"Dobozos raktárak közül a FŐxxxx raktárakból elsődlegesen.",
"BUGFIX - Selejt helyett Részben-t mentett",
"BUGFIX - A - jelet tartalmazó rendelések kezelése",
"Kiskönyv bővítése a Gyártásba kerül résznél az éves statisztikai adatokkal",
"Egyedi rendelések rendezése a kiszedési listában függetlenül a típustól",
"Raktárhely kereső",
"BUGFIX - Több emailes rendelés",
"Lezárt rendelések levél átirányítása ' rendeles@szatuna.hu'-ra",
"BUGFIX - Nagy méretű rendelések feltöltése tűzfal hiba",
"BUGFIX - Rendelés lezárása",
"Raktárpolc töltöttségi színes indikátor javítása",
"Napi statisztika automatikusan frissül gyártás \/ dobozolás felvétele és lezárásakor",
"Termékgyártás kártyáin Startolt jelölése, a kezdeti gyártandó pár mennyisségének jelölése",
"BUGFIX - Fóliás raktárakat figyelmen kívűl hagyta a kiszedési lista generálásakor",
"BUGFIX - Táblázati feltöltésnél katalógusban szereplő cikkszámot ment",
"BUGFIX - excel import hiba",
"Egyedi rendelések rendezése a kiszedési listában",
"Fóliás raktárak közül a FŐxxxx raktárakból elsődlegesen.",
"Raktári kivéteknél (HA párban van, nem csak jobbos vagy csak balos) elsődlegesen fóliásból szed most ki, de legyen elsődlegesen dobozosból",
"Dobozméret szabályok módosítva",
"BUGFIX - Napi statisztika",
"Hiányzó termék értesítő szövegezésének módosítása",
"Emailbe-logót beletenni",
"Utólagos gyártás módosítás jog",
"A 4. sortól lehet több doboz egymáson a raktározásban",
"Külső biztonsági mentés",
"BUGFIX - A '-jelet tartalmazó megrendelők kezelése",
"BUGFIX - Szektor szerkessztő alapértelmezett polc kapacitás nem mentődött",
"Gyártástervező sorrend módosítás",
"BUGFIX - Termék bevezetés Végső ellenőrzés lépésének javítása"
]
},
{
"build": "lb1767769200",
"changes": [
"Jobb - Bal oldal megfordítása Bal - Jobb-ra",
"BUGFIX - Gyártási folyamat raktározási program megjelenése",
"Présgép alapadat a classic szerszám előkészítése könyvben",
"Out of Stock levél módosítása",
"Levelezési rendszer frissítése",
"Levelek válaszcíme a 'kapcsolat@szatuna.hu'",
"Napi statisztikai script módosítások",
"BUGFIX - Rendelés statisztika",
"BUGFIX - Raktár keresőben hiba volt",
"BUGFIX - Dobozos elem hozzáadásakor a Katalógusban szereplő item_id formátum mentődik",
"Szektor módosítás átmenetileg kapott jogot",
"BUGFIX - Raktár statisztika"
]
},
{
"build": "lb1767596400",
"changes": [
"STAT - A rendszer 55 fájl és 21 224 sor 'tiszta' kód",
"Gyártásnál a maradék automatikus kitöltése",
"Új cikkszámok gyártásának indíthatósága",
"Több értesítési cím rendeléseknél",
"Gyártástervezőben a létrehozott gyártásokkhoz gyorslink",
"Adatbázis biztonsági mentése 30p-enként",
"Raktár dobozmennyiség polc helyenként",
"DEMO adatok törölve"
]
},
{
"build": "ld1767164400",
"changes": [
"Termékdobozolás szett cikkszám kezelése",
"Fóliás raktárhely változások",
"Fóliás adatok a gyártás előkészítése könyvben",
"Visszárú menupont v2",
"Termék bevezetés lezárásával a napi statisztikája frissűl",
"Rendelések statisztika v2",
"Dobozos raktár leltár",
"Fóliás raktérhely törlő",
"Szerszám alapadat a Sporty gyártás előkészítése könyvben",
"Fóliás raktárhely szerkesztő",
"API Dokumentáció",
"2025 eladási számok"
]
},
{
"build": "ld1766905200",
"changes": [
"Sporty Tisztítás nem kell",
"Újrarendeléskor az átvételi mód és megjegyzés is kerüljön át",
"BUGFIX - Oszlopszámok elcsúszása",
"Gyártás jogrendszer - Jog ellenőrzési sorrend",
"Raktárkészlet infó átadása a webáruháznak"
]
},
{
"build": "ld1766127600",
"changes": [
"Gyártás és dobozolás adatbázisok kiürítése"
]
},
{
"build": "ld1765954800",
"changes": [
"Raktárkészlet statisztika",
"Termék \"megszűnt\" státusza",
"Szerszám előkészítés külön lépés",
"Sporty szerszám előkészítése nem kell",
"Dobozolási folyamatok raktárkezelése",
"Újraszámítás gomb a megrendeléseknél",
"Lemezpozicíó, Magpozició a Classic gyártás szerszám előkészítése könyvben",
"Kamionos és bumeráng doboz hely",
"Teríték \/ Tábla adatpótlás",
"Árkategória és Mennyiségi egység import",
"Selejt kivét előzmény lista javítás",
"Selejt kivét raktárhely ellenőrzés",
"Selejt kivét rossz odlalt vett ki",
"BUGFIX - raktár menupont fóliás raktár Design hiba",
"Raktározás & Rendeléskezelés",
"Kimaradt termékek feltöltése",
"Régi archív legyen archív",
"Új termékparaméterek",
"Szett cikkszámok létrehozása"
]
},
{
"build": "ld1765350000",
"changes": [
"Raktár adatok kinyerése JSON, CSV, XML",
"Bugreport Screenshot javítás",
"Gombok Designja",
"Dobozolás Katalógus adat kiirása",
"Gyártási folyamatoknál a bevételezési lépés törlése",
"Rendelések rendezési szempontja",
"BUGFIX - Garanciális kivét hiba üzenet nem fog megjelenni",
"BUGFIX - Kódbeli warningok kezelése",
"BUGFIX - Bugreport",
"BUGFIX - Termékdobozolás fóliás raktár választó",
"BUGFIX - Féloldalas kiszedés"
]
},
{
"build": "ld1764745200",
"changes": [
"Termékgyártás Katalógus adat kiirása",
"Rendelések jogainak szerkesztése",
"Kiszedési lista fél oldalas rendelések kezelése",
"Dobozolási folyamatok fóliás raktárkezelése",
"Polconként ne max 2, hanem mindegy",
"ClimAir szett cikkszámok kezelése a rendeléseknél",
"BUGFIX - Szettek fóliás kiszedési hibája",
"ClimAir hátsó és bumeráng raktározható a ClimAir első polcokra",
"Gyártási folyamatok fóliás raktárkezelése",
"Rendelés kezelés adatkiírás bővítése",
"Új excel template",
"Átvételi mód a rendeléseknél a megjegyzések mintájára",
"Címke generátor Fóliás és Összes",
"Gyártástervező Statisztika",
"Dobozolás tervező számítások optimalizálása",
"BUGFIX - Gyártás előkészítése hiba"
]
},
{
"build": "ld1764140400",
"changes": [
"STAT - A rendszer 51 fájl és 18 623 sor 'tiszta' kód",
"Termékgyártás folyamatban lévő elemeinek statisztikái",
"Táblaméret x, y",
"Kiszedési lista Raktár oszlop átrendezése",
"Gyártás előkészítése rész is lenyílik",
"Termékgyártás és dobozolás lezárt elemei",
"Raktár kereső fóliás elemek darabszámát helyesen számolja",
"Excel és manuálisan is megjegyzés kezelése",
"Kivétek elsődlegesen fóliásból"
]
},
{
"build": "ld1763535600",
"changes": [
"Kiszedési lista generálás prioritás módosítás",
"Raktár keresője fóliás raktárakat is megmutatja",
"Cikkszám visszahelyezési figyelmeztetés bővítése",
"Cimke generálás",
"Rendelés létrehozása hibaüzenet helyesen számol",
"Kiszedési lista elsődleges forrása",
"Rendelések megjegyzés kezelése",
"Selejt kivét művelete"
]
},
{
"build": "ld1762930800",
"changes": [
"Termékbevezetésnél csak a Termék paraméterek a kötelező",
"Törléskor cikkszám visszahelyezési figyelmeztetés",
"BUGFIX - Fóliás raktár 0 db-os helyeket is felajánlott",
"Rendelés lezárásánál automatikus levél",
"Egyszerre több cikkszám felvétele rendeléskor",
"Raktári bevét a kivét mintájára",
"Raktár rendszerek kódnevei",
"Ratári kivétek",
"Raktározás -> Raktári bevét"
]
},
{
"build": "ld1762326000",
"changes": [
"Hátsó cikkszámokat nem kell dobozolni",
"Teljes rendelések törlése"
]
},
{
"build": "ld1761721200",
"changes": [
"Kódnevek a raktárnál",
"Hármas dobozméret kerülhet Univerzális helyre",
"Dobozos raktár készlet kitartás",
"Szettek",
"Fóliás raktárak felülre rendezése a kiszedésnél",
"Katalógus státusz szűrő 'összes' opció",
"Rendelés felvételénél a hibaüzenet módosítása",
"Hiányzó cikkszámok és szettek feltöltve",
"Webes rendelések helyes kezelése",
"BUGFIX - Rendelés felvétele hiba",
"Sor Oszlop kiírása és vezető nulla",
"Termékkatalógus szerkesztő design"
]
},
{
"build": "ld1761285600",
"changes": [
"Cikkszám szerkesztő Admin fiókoknak",
"Termékgyártás folyamatos mentése",
"Fóliás raktárak +-10 opció",
"Fóliás raktárak külön kezelése",
"Kivont cikkszámok kezelése",
"Kivont cikkszámok feltöltése",
"BUGFIX - Kis és Nagybetűk kezelése a raktározásnál",
"Termékkatalógus adat státusz nevek",
"Fejlesztési tervek"
]
}
]
}

2
robots.txt Normal file
View File

@ -0,0 +1,2 @@
User-agent: *
Disallow: /

312
version.php Normal file

File diff suppressed because one or more lines are too long