diff --git a/public/languages/en/general.php b/public/languages/en/general.php index 82a67da..c0ad6c6 100644 --- a/public/languages/en/general.php +++ b/public/languages/en/general.php @@ -32,3 +32,4 @@ $langdatatables = [ "paginate_next" => "Next", "paginate_previous" => "Previous" ]; +$quotationstitle = "Quotations"; diff --git a/public/userarea/delete_part_quotation.php b/public/userarea/delete_part_quotation.php new file mode 100644 index 0000000..ace1700 --- /dev/null +++ b/public/userarea/delete_part_quotation.php @@ -0,0 +1,28 @@ +getConnection(); + +$data = json_decode(file_get_contents('php://input'), true); + +$partId = $data['part_id'] ?? null; + +if (!$partId) { + echo json_encode(['success' => false, 'message' => 'ID parte mancante']); + exit; +} + +try { + $stmt = $pdo->prepare("DELETE FROM identification_parts WHERE id = :part_id"); + $stmt->execute([':part_id' => $partId]); + $rowCount = $stmt->rowCount(); + if ($rowCount > 0) { + echo json_encode(['success' => true, 'message' => 'Parte eliminata con successo']); + } else { + echo json_encode(['success' => false, 'message' => 'Nessuna parte trovata con ID ' . $partId]); + } +} catch (PDOException $e) { + echo json_encode(['success' => false, 'message' => 'Errore nell\'eliminazione: ' . $e->getMessage()]); +} diff --git a/public/userarea/include/navbar.php b/public/userarea/include/navbar.php index a99b4db..5df1b53 100644 --- a/public/userarea/include/navbar.php +++ b/public/userarea/include/navbar.php @@ -41,7 +41,21 @@ - --> + +
  • + +
    +
    + +
    + +
  • + diff --git a/public/userarea/load_parts_quotation.php b/public/userarea/load_parts_quotation.php new file mode 100644 index 0000000..a88782d --- /dev/null +++ b/public/userarea/load_parts_quotation.php @@ -0,0 +1,23 @@ +getConnection(); + +$idquotations = $_GET['idquotations'] ?? null; + +if (!$idquotations) { + echo json_encode(['success' => false, 'message' => 'ID quotations mancante']); + exit; +} + +try { + $stmt = $pdo->prepare("SELECT id, idquotations, part_number, part_description FROM identification_parts WHERE idquotations = :idquotations ORDER BY part_number ASC"); + $stmt->execute([':idquotations' => $idquotations]); + $parts = $stmt->fetchAll(); + + echo json_encode(['success' => true, 'parts' => $parts]); +} catch (PDOException $e) { + echo json_encode(['success' => false, 'message' => 'Errore nel caricamento: ' . $e->getMessage()]); +} diff --git a/public/userarea/load_photo_quotation.php b/public/userarea/load_photo_quotation.php new file mode 100644 index 0000000..2eab4cc --- /dev/null +++ b/public/userarea/load_photo_quotation.php @@ -0,0 +1,33 @@ +getConnection(); + +$idquotations = isset($_GET['idquotations']) ? intval($_GET['idquotations']) : null; + +if (!$idquotations) { + echo json_encode(['success' => false, 'message' => 'ID quotation mancante']); + exit; +} + +try { + // Seleziona le foto per il dato idquotations dalla tabella datadb_photos + $stmt = $pdo->prepare("SELECT id, file_path FROM datadb_photos WHERE idquotations = ?"); + $stmt->execute([$idquotations]); + $photos = $stmt->fetchAll(PDO::FETCH_ASSOC); + + if ($photos && count($photos) > 0) { + $photoPaths = array_map(function ($photo) { + return '../photostrf/' . $photo['file_path']; + }, $photos); + echo json_encode(['success' => true, 'photos' => $photoPaths]); + } else { + echo json_encode(['success' => false, 'message' => 'Nessuna foto trovata']); + } +} catch (PDOException $e) { + echo json_encode(['success' => false, 'message' => 'Errore nel caricamento: ' . $e->getMessage()]); +} diff --git a/public/userarea/modal_parts.php b/public/userarea/modal_parts.php index c3d595d..b95ca9b 100644 --- a/public/userarea/modal_parts.php +++ b/public/userarea/modal_parts.php @@ -1,4 +1,4 @@ - +

    Manage Photos

    -

    ID Row:

    -

    Sample Code:

    +

    ID:

    +

    Code:

    Scan the QR Code with the mobile to take photo with camera:

    - QR Code + QR Code

    @@ -136,7 +198,7 @@ $result->saveToFile($qrCodeFile);
    -

    No Photos present.

    +

    Nessuna foto presente.

    + Gestione Quotations - <?= htmlspecialchars($titlewebsite, ENT_QUOTES, 'UTF-8'); ?> @@ -212,8 +250,8 @@ if (isset($_GET['edit_id'])) {
    Azioni
    - - + +
    @@ -242,11 +280,12 @@ if (isset($_GET['edit_id'])) { + - - + + @@ -376,6 +415,15 @@ if (isset($_GET['edit_id'])) { // I bottoni photos e parts usano gli script esistenti (photos.js, parts.js), passando data-idquotations }); + + + + \ No newline at end of file diff --git a/public/userarea/renumber_parts_quotation.php b/public/userarea/renumber_parts_quotation.php new file mode 100644 index 0000000..3c455cb --- /dev/null +++ b/public/userarea/renumber_parts_quotation.php @@ -0,0 +1,63 @@ +getConnection(); + +$data = json_decode(file_get_contents('php://input'), true); + +$idquotations = $data['idquotations'] ?? null; +$parts = $data['parts'] ?? []; + +if (!$idquotations || empty($parts)) { + echo json_encode(['success' => false, 'message' => 'Dati mancanti']); + exit; +} + +try { + $pdo->beginTransaction(); + + // Elimina tutte le parti esistenti per idquotations + $stmt = $pdo->prepare("DELETE FROM identification_parts WHERE idquotations = :idquotations"); + $stmt->execute([':idquotations' => $idquotations]); + + // Prepara l'inserimento delle nuove parti + $stmt = $pdo->prepare(" + INSERT INTO identification_parts + (idquotations, part_number, part_description, mix, created_at, updated_at) + VALUES (:idquotations, :part_number, :part_description, :mix, NOW(), NOW()) + "); + + $part_ids = []; + foreach ($parts as $part) { + $partNumber = $part['part_number'] ?? null; + $partDescription = $part['part_description'] ?? ''; + $mix = $part['mix'] ?? 'N'; + + if (!$partNumber || !$partDescription) { + throw new PDOException("Numero parte o descrizione mancante per parte: " . json_encode($part)); + } + + $stmt->execute([ + ':idquotations' => $idquotations, + ':part_number' => $partNumber, + ':part_description' => $partDescription, + ':mix' => $mix + ]); + $part_ids[] = $pdo->lastInsertId(); + } + + $pdo->commit(); + echo json_encode([ + 'success' => true, + 'part_ids' => $part_ids, + 'message' => 'Parti rinumerate con successo' + ]); +} catch (PDOException $e) { + $pdo->rollBack(); + echo json_encode([ + 'success' => false, + 'message' => 'Errore nel salvataggio: ' . $e->getMessage() + ]); +} diff --git a/public/userarea/save_annotated_photo_quotation.php b/public/userarea/save_annotated_photo_quotation.php new file mode 100644 index 0000000..fff1d05 --- /dev/null +++ b/public/userarea/save_annotated_photo_quotation.php @@ -0,0 +1,59 @@ + false, 'message' => 'Dati mancanti']); + exit; +} + +try { + // Verifica che idquotations esista nella tabella quotations + $dbHandler = DBHandlerSelect::getInstance(); + $pdo = $dbHandler->getConnection(); + $stmt = $pdo->prepare("SELECT idquotations FROM quotations WHERE idquotations = :idquotations"); + $stmt->execute([':idquotations' => $idquotations]); + if (!$stmt->fetch()) { + echo json_encode(['success' => false, 'message' => 'idquotations non valido']); + exit; + } + + // Salva l'immagine + $data = explode(',', $dataURL)[1]; + $decodedData = base64_decode($data); + + $dirPath = '../photostrf/annotated'; + if (!file_exists($dirPath)) { + mkdir($dirPath, 0777, true); + } + + $filePath = $dirPath . '/' . $filename; + file_put_contents($filePath, $decodedData); + + // Registra nel database + $stmt = $pdo->prepare(" + INSERT INTO datadb_photos (idquotations, file_path, file_name, uploaded_at, uploaded_by) + VALUES (:idquotations, :file_path, :file_name, NOW(), :uploaded_by) + "); + $stmt->execute([ + ':idquotations' => $idquotations, + ':file_path' => $filePath, + ':file_name' => $filename, + ':uploaded_by' => $iduserlogin + ]); + + echo json_encode([ + 'success' => true, + 'file_path' => $filePath, + 'message' => 'Foto salvata con successo e registrata nel DB' + ]); +} catch (Exception $e) { + echo json_encode(['success' => false, 'message' => 'Errore: ' . $e->getMessage()]); +} diff --git a/public/userarea/save_parts_quotation.php b/public/userarea/save_parts_quotation.php new file mode 100644 index 0000000..2445f70 --- /dev/null +++ b/public/userarea/save_parts_quotation.php @@ -0,0 +1,60 @@ +getConnection(); + +$data = json_decode(file_get_contents('php://input'), true); + +$idquotations = $data['idquotations'] ?? null; +$parts = $data['parts'] ?? []; + +if (!$idquotations || empty($parts)) { + echo json_encode(['success' => false, 'message' => 'Dati mancanti']); + exit; +} + +$part = $parts[0]; +$partId = $part['id'] ?? null; +$partNumber = $part['part_number'] ?? null; +$partDescription = $part['part_description'] ?? ''; +$mix = $part['mix'] ?? 'N'; + +if ($partDescription) { + try { + if ($partId) { + // UPDATE se esiste già la parte + $stmt = $pdo->prepare("UPDATE identification_parts + SET part_number = :part_number, + part_description = :part_description, + mix = :mix, + updated_at = NOW() + WHERE id = :id"); + $stmt->execute([ + ':id' => $partId, + ':part_number' => $partNumber, + ':part_description' => $partDescription, + ':mix' => $mix + ]); + echo json_encode(['success' => true, 'part_id' => $partId, 'part_number' => $partNumber, 'message' => 'Parte aggiornata con successo']); + } else { + // INSERT se è nuova + $stmt = $pdo->prepare("INSERT INTO identification_parts + (idquotations, part_number, part_description, mix, created_at, updated_at) + VALUES (:idquotations, :part_number, :part_description, :mix, NOW(), NOW())"); + $stmt->execute([ + ':idquotations' => $idquotations, + ':part_number' => $partNumber, + ':part_description' => $partDescription, + ':mix' => $mix + ]); + $newId = $pdo->lastInsertId(); + echo json_encode(['success' => true, 'part_id' => $newId, 'part_number' => $partNumber, 'message' => 'Parte salvata con successo']); + } + } catch (PDOException $e) { + echo json_encode(['success' => false, 'message' => 'Errore nel salvataggio: ' . $e->getMessage()]); + } +} else { + echo json_encode(['success' => false, 'message' => 'Descrizione mancante']); +} diff --git a/public/userarea/upload_photo.php b/public/userarea/upload_photo.php index 64cb8dc..9db0284 100644 --- a/public/userarea/upload_photo.php +++ b/public/userarea/upload_photo.php @@ -4,13 +4,23 @@ include('include/headscript.php'); header('Content-Type: application/json'); -if ($_SERVER['REQUEST_METHOD'] !== 'POST' || !isset($_FILES['photo']) || !isset($_POST['iddatadb'])) { +if ($_SERVER['REQUEST_METHOD'] !== 'POST' || !isset($_FILES['photo']) || (!isset($_POST['iddatadb']) && !isset($_POST['idquotations']))) { echo json_encode(['success' => false, 'message' => 'Richiesta non valida']); exit; } -$iddatadb = intval($_POST['iddatadb']); -$photo = $_FILES['photo']; +$iddatadb = isset($_POST['iddatadb']) ? intval($_POST['iddatadb']) : null; +$idquotations = isset($_POST['idquotations']) ? intval($_POST['idquotations']) : null; + +if ($iddatadb && $idquotations) { + echo json_encode(['success' => false, 'message' => 'Non è possibile specificare sia iddatadb che idquotations']); + exit; +} + +if (!$iddatadb && !$idquotations) { + echo json_encode(['success' => false, 'message' => 'ID TRF o ID quotations mancante']); + exit; +} // Verifica che l'utente loggato esista in auth_users $db = DBHandlerSelect::getInstance(); @@ -25,6 +35,28 @@ if (!$userExists) { exit; } +// Verifica l'esistenza dell'ID nella tabella corrispondente +try { + if ($iddatadb) { + $stmt = $pdo->prepare("SELECT iddatadb FROM datadb WHERE iddatadb = ?"); + $stmt->execute([$iddatadb]); + if (!$stmt->fetch()) { + echo json_encode(['success' => false, 'message' => 'iddatadb non valido']); + exit; + } + } else { + $stmt = $pdo->prepare("SELECT id FROM quotations WHERE id = ?"); + $stmt->execute([$idquotations]); + if (!$stmt->fetch()) { + echo json_encode(['success' => false, 'message' => 'idquotations non valido']); + exit; + } + } +} catch (PDOException $e) { + echo json_encode(['success' => false, 'message' => 'Errore nella validazione: ' . $e->getMessage()]); + exit; +} + // Usa un percorso assoluto per la cartella photostrf $uploadDir = realpath(__DIR__ . '/../photostrf') . '/'; if (!is_dir($uploadDir)) { @@ -41,6 +73,7 @@ if (!is_writable($uploadDir)) { } // Verifica che il file sia un'immagine (inclusi HEIC/HEIF) +$photo = $_FILES['photo']; $allowedTypes = ['image/jpeg', 'image/png', 'image/gif', 'image/heic', 'image/heif']; if (!in_array($photo['type'], $allowedTypes)) { echo json_encode(['success' => false, 'message' => 'Il file deve essere un\'immagine (JPEG, PNG, GIF, HEIC)']); @@ -53,10 +86,11 @@ if (!file_exists($photo['tmp_name']) || !is_uploaded_file($photo['tmp_name'])) { exit; } -// Rinomina il file: idriga-timestamp-nomeoriginale.estensione +// Rinomina il file: id-timestamp-nomeoriginale.estensione $timestamp = date('YmdHis'); $originalName = pathinfo($photo['name'], PATHINFO_FILENAME); $extension = strtolower(pathinfo($photo['name'], PATHINFO_EXTENSION)); +$id = $iddatadb ?: $idquotations; // Se il file è HEIC/HEIF, convertilo in JPEG if (in_array($photo['type'], ['image/heic', 'image/heif'])) { @@ -74,11 +108,11 @@ if (in_array($photo['type'], ['image/heic', 'image/heif'])) { } // Crea un nuovo nome per il file JPEG - $newFileName = "{$iddatadb}-{$timestamp}-{$originalName}.jpg"; + $newFileName = "{$id}-{$timestamp}-{$originalName}.jpg"; $destination = $uploadDir . $newFileName; // Salva l'immagine come JPEG - if (!imagejpeg($image, $destination, 90)) { // 90 è la qualità JPEG + if (!imagejpeg($image, $destination, 90)) { imagedestroy($image); echo json_encode(['success' => false, 'message' => 'Errore durante la conversione del file HEIC in JPEG']); exit; @@ -88,7 +122,7 @@ if (in_array($photo['type'], ['image/heic', 'image/heif'])) { imagedestroy($image); } else { // Per i formati non HEIC, usa il nome e l'estensione originali - $newFileName = "{$iddatadb}-{$timestamp}-{$originalName}.{$extension}"; + $newFileName = "{$id}-{$timestamp}-{$originalName}.{$extension}"; $destination = $uploadDir . $newFileName; // Salva il file @@ -105,7 +139,12 @@ error_log("Destination: $destination"); error_log("Temp file: " . $photo['tmp_name']); // Salva il riferimento nel database -$stmt = $pdo->prepare("INSERT INTO datadb_photos (iddatadb, file_path, file_name, uploaded_by) VALUES (?, ?, ?, ?)"); -$stmt->execute([$iddatadb, $newFileName, $newFileName, $iduserlogin]); +try { + $stmt = $pdo->prepare("INSERT INTO datadb_photos (iddatadb, idquotations, file_path, file_name, uploaded_by) VALUES (?, ?, ?, ?, ?)"); + $stmt->execute([$iddatadb, $idquotations, $newFileName, $newFileName, $iduserlogin]); +} catch (PDOException $e) { + echo json_encode(['success' => false, 'message' => 'Errore durante il salvataggio nel database: ' . $e->getMessage()]); + exit; +} echo json_encode(['success' => true, 'message' => 'Foto caricata con successo']); diff --git a/public/userarea/upload_photos_mobile.php b/public/userarea/upload_photos_mobile.php index e16d421..d4abaea 100644 --- a/public/userarea/upload_photos_mobile.php +++ b/public/userarea/upload_photos_mobile.php @@ -5,24 +5,41 @@ include('include/headscript.php'); $db = DBHandlerSelect::getInstance(); $pdo = $db->getConnection(); -// Verifica che l'iddatadb sia stato passato -if (!isset($_GET['iddatadb']) || empty($_GET['iddatadb'])) { - die('ID riga non fornito'); +// Verifica che almeno uno degli ID sia passato +$iddatadb = isset($_GET['iddatadb']) && !empty($_GET['iddatadb']) ? intval($_GET['iddatadb']) : null; +$idquotations = isset($_GET['idquotations']) && !empty($_GET['idquotations']) ? intval($_GET['idquotations']) : null; + +if (!$iddatadb && !$idquotations) { + die('ID riga o ID quotations non fornito'); } -$iddatadb = intval($_GET['iddatadb']); +if ($iddatadb && $idquotations) { + die('Non è possibile specificare sia iddatadb che idquotations'); +} -// Recupera i dettagli della riga (idriga e sample_code) -$stmt = $pdo->prepare("SELECT iddatadb, sample_code FROM datadb WHERE iddatadb = ?"); -$stmt->execute([$iddatadb]); +// Verifica che l'utente loggato esista +$stmt = $pdo->prepare("SELECT id FROM auth_users WHERE id = ?"); +$stmt->execute([$iduserlogin]); +if (!$stmt->fetch(PDO::FETCH_ASSOC)) { + die('Utente non valido'); +} + +// Determina quale ID usare e verifica l'esistenza +$paramName = $iddatadb ? 'iddatadb' : 'idquotations'; +$paramValue = $iddatadb ?: $idquotations; +$table = $iddatadb ? 'datadb' : 'quotations'; +$field = $iddatadb ? 'sample_code' : 'quotation_code'; + +$stmt = $pdo->prepare("SELECT {$paramName}, {$field} FROM {$table} WHERE {$paramName} = ?"); +$stmt->execute([$paramValue]); $row = $stmt->fetch(PDO::FETCH_ASSOC); if (!$row) { die('Riga non trovata'); } -$idriga = $row['iddatadb']; -$sampleCode = $row['sample_code'] ?? 'Non disponibile'; +$id = $row[$paramName]; +$code = $row[$field] ?? 'Non disponibile'; ?> @@ -32,17 +49,23 @@ $sampleCode = $row['sample_code'] ?? 'Non disponibile'; Carica Foto da Mobile + -

    Carica Foto per ID Riga:

    -

    Sample Code:

    - +

    Carica Foto per ID:

    +

    Codice:

    +
    +
    + +

    Caricamento in corso...

    +
    +
    +
    -

    Scatta una foto o seleziona un'immagine

    - -
    - -
    - +

    Scatta una foto o seleziona immagini

    +
    +
    - + \ No newline at end of file