dolibarr.handybarcodescanner/handybarcodescannerindex.php
data 3e803cf71f Remove page title to save space on mobile
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
2026-02-17 11:33:58 +01:00

189 lines
7.2 KiB
PHP
Executable file

<?php
/* Copyright (C) 2026 Eduard Wisch <data@data-it-solution.de>
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation; either version 3 of the License, or
* (at your option) any later version.
*/
/**
* \file handybarcodescanner/handybarcodescannerindex.php
* \ingroup handybarcodescanner
* \brief Mobile Barcode Scanner - Hauptseite (Dolibarr integriert)
*/
// Load Dolibarr environment
$res = 0;
if (!$res && !empty($_SERVER["CONTEXT_DOCUMENT_ROOT"])) {
$res = @include $_SERVER["CONTEXT_DOCUMENT_ROOT"]."/main.inc.php";
}
$tmp = empty($_SERVER['SCRIPT_FILENAME']) ? '' : $_SERVER['SCRIPT_FILENAME'];
$tmp2 = realpath(__FILE__);
$i = strlen($tmp) - 1;
$j = strlen($tmp2) - 1;
while ($i > 0 && $j > 0 && isset($tmp[$i]) && isset($tmp2[$j]) && $tmp[$i] == $tmp2[$j]) {
$i--;
$j--;
}
if (!$res && $i > 0 && file_exists(substr($tmp, 0, ($i + 1))."/main.inc.php")) {
$res = @include substr($tmp, 0, ($i + 1))."/main.inc.php";
}
if (!$res && $i > 0 && file_exists(dirname(substr($tmp, 0, ($i + 1)))."/main.inc.php")) {
$res = @include dirname(substr($tmp, 0, ($i + 1)))."/main.inc.php";
}
if (!$res && file_exists("../main.inc.php")) {
$res = @include "../main.inc.php";
}
if (!$res && file_exists("../../main.inc.php")) {
$res = @include "../../main.inc.php";
}
if (!$res && file_exists("../../../main.inc.php")) {
$res = @include "../../../main.inc.php";
}
if (!$res) {
die("Include of main fails");
}
require_once DOL_DOCUMENT_ROOT.'/core/class/html.formfile.class.php';
// Load translation files
$langs->loadLangs(array("handybarcodescanner@handybarcodescanner", "products", "orders", "stocks"));
// Get parameters
$action = GETPOST('action', 'aZ09');
$mode = GETPOST('mode', 'alpha') ?: 'order';
// Security check
if (!$user->hasRight('handybarcodescanner', 'use')) {
// Fallback für ältere Rechte-Prüfung
if (!$user->hasRight('fournisseur', 'commande', 'creer') && !$user->hasRight('supplier_order', 'creer')) {
accessforbidden('You need permission to use the barcode scanner');
}
}
// Check mode-specific permissions
$enableOrder = getDolGlobalInt('HANDYBARCODESCANNER_ENABLE_ORDER', 1);
$enableShop = getDolGlobalInt('HANDYBARCODESCANNER_ENABLE_SHOP', 1);
$enableInventory = getDolGlobalInt('HANDYBARCODESCANNER_ENABLE_INVENTORY', 1);
/*
* View
*/
$form = new Form($db);
// CSS einbinden (JS wird manuell am Ende geladen)
$arrayofcss = array('/handybarcodescanner/css/scanner.css');
llxHeader('', $langs->trans("HandyBarcodeScanner"), '', '', 0, 0, array(), $arrayofcss, '', 'mod-handybarcodescanner page-scanner classforhorizontalscrolloftabs');
print '<div class="scanner-wrapper fichecenter">';
// Mode Tabs - Dolibarr Style
$head = array();
$h = 0;
if ($enableOrder) {
$head[$h][0] = dol_buildpath('/handybarcodescanner/handybarcodescannerindex.php', 1).'?mode=order';
$head[$h][1] = img_picto('', 'order', 'class="pictofixedwidth"').$langs->trans("Order");
$head[$h][2] = 'order';
$h++;
}
if ($enableShop) {
$head[$h][0] = dol_buildpath('/handybarcodescanner/handybarcodescannerindex.php', 1).'?mode=shop';
$head[$h][1] = img_picto('', 'globe', 'class="pictofixedwidth"').$langs->trans("Shop");
$head[$h][2] = 'shop';
$h++;
}
if ($enableInventory) {
$head[$h][0] = dol_buildpath('/handybarcodescanner/handybarcodescannerindex.php', 1).'?mode=inventory';
$head[$h][1] = img_picto('', 'stock', 'class="pictofixedwidth"').$langs->trans("Inventory");
$head[$h][2] = 'inventory';
$h++;
}
print dol_get_fiche_head($head, $mode, '', -1, '');
// Scanner Container
print '<div class="div-table-responsive-no-min">';
print '<div class="scanner-box">';
// Video Container
print '<div id="scanner-video-container" class="scanner-video-box">';
print '<video id="scanner-video" playsinline></video>';
print '<div class="scan-region-highlight"></div>';
print '</div>';
// Scanner Controls
print '<div class="scanner-controls center">';
print '<button type="button" id="start-scan-btn" class="button butAction">'.$langs->trans("StartScan").'</button>';
print '<button type="button" id="stop-scan-btn" class="button butActionDelete hidden">'.$langs->trans("StopScan").'</button>';
print '</div>';
print '</div>'; // scanner-box
print '</div>'; // div-table-responsive
// Manual Barcode Input (for testing without camera/HTTPS)
print '<div class="manual-input-section marginbottomonly margintoponly">';
print '<div style="display: flex; gap: 10px; align-items: center;">';
print '<input type="text" id="manual-barcode-input" class="flat" placeholder="'.$langs->trans("BarcodeManualInput").'" style="flex: 1; padding: 12px; font-size: 16px; border: 1px solid #ccc; border-radius: 4px;">';
print '<button type="button" id="manual-search-btn" class="button" style="background: #0077b3; color: #fff; padding: 12px 20px; border: none; border-radius: 4px; font-size: 16px; cursor: pointer;">'.$langs->trans("Search").'</button>';
print '</div>';
print '</div>';
// Last Scan Info
print '<div class="scanner-last-scan marginbottomonly margintoponly">';
print '<span class="opacitymedium">'.$langs->trans("LastScan").':</span> ';
print '<span id="last-scan-code" class="badge badge-status4 badge-status">-</span>';
print '</div>';
// Result Area
print '<div id="result-area" class="scanner-result hidden">';
print '<!-- Dynamic content loaded via JavaScript -->';
print '</div>';
print dol_get_fiche_end();
print '</div>'; // scanner-wrapper
// Hidden config for JavaScript
?>
<script>
var SCANNER_CONFIG = {
ajaxUrl: '<?php echo dol_buildpath('/handybarcodescanner/ajax/', 1); ?>',
token: '<?php echo newToken(); ?>',
mode: '<?php echo $mode; ?>',
enableVibration: <?php echo getDolGlobalInt('HANDYBARCODESCANNER_ENABLE_VIBRATION', 1); ?>,
enableSound: <?php echo getDolGlobalInt('HANDYBARCODESCANNER_ENABLE_SOUND', 0); ?>,
lang: {
productNotFound: '<?php echo $langs->trans("ProductNotFound"); ?>',
added: '<?php echo $langs->trans("Added"); ?>',
saved: '<?php echo $langs->trans("Saved"); ?>',
error: '<?php echo $langs->trans("Error"); ?>',
selectSupplier: '<?php echo $langs->trans("SelectSupplier"); ?>',
noSupplier: '<?php echo $langs->trans("NoSupplierForProduct"); ?>',
quantity: '<?php echo $langs->trans("Qty"); ?>',
add: '<?php echo $langs->trans("Add"); ?>',
price: '<?php echo $langs->trans("Price"); ?>',
stock: '<?php echo $langs->trans("Stock"); ?>',
currentStock: '<?php echo $langs->trans("CurrentStock"); ?>',
newStock: '<?php echo $langs->trans("NewStock"); ?>',
save: '<?php echo $langs->trans("Save"); ?>',
confirmStockChange: '<?php echo $langs->trans("ConfirmStockChange"); ?>',
cancel: '<?php echo $langs->trans("Cancel"); ?>',
confirm: '<?php echo $langs->trans("Confirm"); ?>',
openShop: '<?php echo $langs->trans("OpenShop"); ?>',
cheapest: '<?php echo $langs->trans("Cheapest"); ?>',
cameraError: '<?php echo $langs->trans("CameraAccessError"); ?>',
ref: '<?php echo $langs->trans("Ref"); ?>',
product: '<?php echo $langs->trans("Product"); ?>'
}
};
</script>
<script src="https://cdn.jsdelivr.net/npm/@ericblade/quagga2@1.8.4/dist/quagga.min.js"></script>
<script src="<?php echo dol_buildpath('/handybarcodescanner/js/scanner.js', 1); ?>"></script>
<?php
// End of page
llxFooter();
$db->close();