dolibarr.handybarcodescanner/ajax/searchproduct.php
data 5f9c522db2 v5.1: Bestellungen löschen, Freitext-Bearbeitung, Dark Theme Fix
Bestellungen verwalten:
- Lösch-Button an Entwurfs-Bestellungen mit Bestätigungsdialog
- Freitext-Zeilen: Beschreibung und Menge änderbar
- Letzter Freitext-Lieferant wird für nächsten Eintrag gemerkt

Dark Theme:
- Bestellzeilen korrekt lesbar (war weiß auf hell)
- Dialoge mit konsistenten Dark Theme Farben
- Aktive Bestellung besser hervorgehoben

Entfernt:
- Swipe-Hinweis-Button (überflüssig)

Neuer AJAX-Endpoint:
- deleteorder.php

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
2026-02-25 13:53:24 +01:00

121 lines
3.3 KiB
PHP
Executable file

<?php
/* Copyright (C) 2026 Eduard Wisch <data@data-it-solution.de>
*
* AJAX: Search products by name/ref for autocomplete
*/
if (!defined('NOTOKENRENEWAL')) {
define('NOTOKENRENEWAL', '1');
}
if (!defined('NOREQUIREMENU')) {
define('NOREQUIREMENU', '1');
}
if (!defined('NOREQUIREHTML')) {
define('NOREQUIREHTML', '1');
}
if (!defined('NOREQUIREAJAX')) {
define('NOREQUIREAJAX', '1');
}
// Load Dolibarr environment
$res = 0;
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(json_encode(['success' => false, 'error' => 'Failed to load Dolibarr']));
}
require_once DOL_DOCUMENT_ROOT.'/product/class/product.class.php';
require_once DOL_DOCUMENT_ROOT.'/fourn/class/fournisseur.product.class.php';
header('Content-Type: application/json; charset=utf-8');
// Security check
if (!$user->hasRight('produit', 'lire') && !$user->hasRight('product', 'read')) {
echo json_encode(['success' => false, 'error' => 'Access denied']);
exit;
}
$search = GETPOST('q', 'alphanohtml');
$limit = GETPOSTINT('limit') ?: 15;
if (empty($search) || strlen($search) < 2) {
echo json_encode(['success' => true, 'products' => []]);
exit;
}
$products = [];
// Search products by ref, label
$sql = "SELECT p.rowid, p.ref, p.label, p.barcode, p.stock as stock_reel, p.fk_unit";
$sql .= " FROM ".MAIN_DB_PREFIX."product as p";
$sql .= " WHERE p.entity IN (".getEntity('product').")";
$sql .= " AND (p.ref LIKE '%".$db->escape($search)."%'";
$sql .= " OR p.label LIKE '%".$db->escape($search)."%'";
$sql .= " OR p.barcode LIKE '%".$db->escape($search)."%')";
$sql .= " ORDER BY p.label ASC";
$sql .= " LIMIT ".((int) $limit);
$resql = $db->query($sql);
if ($resql) {
while ($obj = $db->fetch_object($resql)) {
// Get suppliers for this product
$suppliers = [];
$productFourn = new ProductFournisseur($db);
$supplierPrices = $productFourn->list_product_fournisseur_price($obj->rowid);
if ($supplierPrices) {
foreach ($supplierPrices as $sp) {
// Get supplier name
$supplierSql = "SELECT nom FROM ".MAIN_DB_PREFIX."societe WHERE rowid = ".((int) $sp->fourn_id);
$supplierRes = $db->query($supplierSql);
$supplierObj = $db->fetch_object($supplierRes);
$refFourn = $sp->ref_supplier ?? $sp->fourn_ref ?? $sp->ref_fourn ?? '';
$suppliers[] = [
'id' => $sp->fourn_id,
'name' => $supplierObj->nom ?? 'Unknown',
'price' => (float) $sp->fourn_price,
'ref_fourn' => $refFourn
];
}
// Sort by price
usort($suppliers, function($a, $b) {
return $a['price'] <=> $b['price'];
});
}
// Get unit label
$stockUnit = 'Stk';
if (!empty($obj->fk_unit)) {
$unitSql = "SELECT label FROM ".MAIN_DB_PREFIX."c_units WHERE rowid = ".((int) $obj->fk_unit);
$unitRes = $db->query($unitSql);
if ($unitRes && $unitObj = $db->fetch_object($unitRes)) {
$stockUnit = $unitObj->label;
}
}
$products[] = [
'id' => $obj->rowid,
'ref' => $obj->ref,
'label' => $obj->label,
'barcode' => $obj->barcode,
'stock' => (float) $obj->stock_reel,
'stock_unit' => $stockUnit,
'suppliers' => $suppliers
];
}
}
echo json_encode([
'success' => true,
'products' => $products
]);