added multiple tested components
This commit is contained in:
parent
78154e43a9
commit
cd3bccd183
@ -4,7 +4,7 @@ header('Content-Type: application/json');
|
|||||||
ini_set('display_errors', 1);
|
ini_set('display_errors', 1);
|
||||||
error_reporting(E_ALL);
|
error_reporting(E_ALL);
|
||||||
|
|
||||||
require_once(__DIR__ . '/include/headscript.php'); // così hai Auth + $iduserlogin + DBHandlerSelect
|
require_once(__DIR__ . '/include/headscript.php'); // Auth + $iduserlogin + DBHandlerSelect
|
||||||
|
|
||||||
try {
|
try {
|
||||||
if ($_SERVER['REQUEST_METHOD'] !== 'POST') {
|
if ($_SERVER['REQUEST_METHOD'] !== 'POST') {
|
||||||
@ -12,40 +12,79 @@ try {
|
|||||||
}
|
}
|
||||||
|
|
||||||
$iddatadb = isset($_POST['iddatadb']) ? (int)$_POST['iddatadb'] : 0;
|
$iddatadb = isset($_POST['iddatadb']) ? (int)$_POST['iddatadb'] : 0;
|
||||||
$part_description = isset($_POST['part_description']) ? trim($_POST['part_description']) : '';
|
|
||||||
|
|
||||||
if ($iddatadb <= 0) {
|
if ($iddatadb <= 0) {
|
||||||
throw new Exception('Missing iddatadb');
|
throw new Exception('Missing iddatadb');
|
||||||
}
|
}
|
||||||
|
|
||||||
if ($part_description === '') {
|
// ✅ Supporta sia singola stringa (con |) che array part_descriptions[]
|
||||||
throw new Exception('Part description is empty');
|
$parts = [];
|
||||||
|
|
||||||
|
if (isset($_POST['part_descriptions']) && is_array($_POST['part_descriptions'])) {
|
||||||
|
$parts = $_POST['part_descriptions'];
|
||||||
|
} else {
|
||||||
|
$raw = isset($_POST['part_description']) ? (string)$_POST['part_description'] : '';
|
||||||
|
// split su "|" per multi-part
|
||||||
|
$parts = preg_split('/\s*\|\s*/', $raw);
|
||||||
}
|
}
|
||||||
|
|
||||||
// (opzionale ma consigliato) limita lunghezza come da DB varchar(255)
|
// normalizza: trim + rimuovi vuoti + dedup
|
||||||
if (mb_strlen($part_description) > 255) {
|
$cleanParts = [];
|
||||||
$part_description = mb_substr($part_description, 0, 255);
|
foreach ($parts as $p) {
|
||||||
|
$p = trim((string)$p);
|
||||||
|
if ($p === '') continue;
|
||||||
|
|
||||||
|
// limita lunghezza come da DB varchar(255)
|
||||||
|
if (mb_strlen($p) > 255) {
|
||||||
|
$p = mb_substr($p, 0, 255);
|
||||||
|
}
|
||||||
|
$cleanParts[] = $p;
|
||||||
|
}
|
||||||
|
$cleanParts = array_values(array_unique($cleanParts));
|
||||||
|
|
||||||
|
if (count($cleanParts) === 0) {
|
||||||
|
throw new Exception('Part description is empty');
|
||||||
}
|
}
|
||||||
|
|
||||||
$db = DBHandlerSelect::getInstance();
|
$db = DBHandlerSelect::getInstance();
|
||||||
$pdo = $db->getConnection();
|
$pdo = $db->getConnection();
|
||||||
|
|
||||||
// Insert minimal
|
$pdo->beginTransaction();
|
||||||
$stmt = $pdo->prepare("
|
|
||||||
INSERT INTO identification_parts (iddatadb, part_number, part_description)
|
|
||||||
VALUES (?, 1, ?)
|
|
||||||
");
|
|
||||||
$ok = $stmt->execute([$iddatadb, $part_description]);
|
|
||||||
|
|
||||||
if (!$ok) {
|
try {
|
||||||
throw new Exception('Insert failed');
|
// prende il prossimo part_number per iddatadb
|
||||||
|
$stmtMax = $pdo->prepare("SELECT COALESCE(MAX(part_number), 0) AS maxnum FROM identification_parts WHERE iddatadb = ?");
|
||||||
|
$stmtMax->execute([$iddatadb]);
|
||||||
|
$nextNumber = (int)$stmtMax->fetchColumn() + 1;
|
||||||
|
|
||||||
|
$stmtIns = $pdo->prepare("
|
||||||
|
INSERT INTO identification_parts (iddatadb, part_number, part_description)
|
||||||
|
VALUES (?, ?, ?)
|
||||||
|
");
|
||||||
|
|
||||||
|
$insertedIds = [];
|
||||||
|
|
||||||
|
foreach ($cleanParts as $p) {
|
||||||
|
$ok = $stmtIns->execute([$iddatadb, $nextNumber, $p]);
|
||||||
|
if (!$ok) {
|
||||||
|
throw new Exception('Insert failed');
|
||||||
|
}
|
||||||
|
$insertedIds[] = $pdo->lastInsertId();
|
||||||
|
$nextNumber++;
|
||||||
|
}
|
||||||
|
|
||||||
|
$pdo->commit();
|
||||||
|
|
||||||
|
echo json_encode([
|
||||||
|
'success' => true,
|
||||||
|
'message' => 'Parts added',
|
||||||
|
'count' => count($insertedIds),
|
||||||
|
'ids' => $insertedIds
|
||||||
|
]);
|
||||||
|
} catch (Exception $e) {
|
||||||
|
if ($pdo->inTransaction()) $pdo->rollBack();
|
||||||
|
throw $e;
|
||||||
}
|
}
|
||||||
|
|
||||||
echo json_encode([
|
|
||||||
'success' => true,
|
|
||||||
'message' => 'Part added',
|
|
||||||
'id' => $pdo->lastInsertId()
|
|
||||||
]);
|
|
||||||
} catch (Exception $e) {
|
} catch (Exception $e) {
|
||||||
echo json_encode(['success' => false, 'message' => $e->getMessage()]);
|
echo json_encode(['success' => false, 'message' => $e->getMessage()]);
|
||||||
}
|
}
|
||||||
|
|||||||
File diff suppressed because one or more lines are too long
@ -1964,50 +1964,68 @@ function fixedDefaultValue(array $f): string
|
|||||||
const $cell = $(this).closest('.grid-cell');
|
const $cell = $(this).closest('.grid-cell');
|
||||||
const $input = $cell.find('input[name^="rows["][name$="[tested_component]"]');
|
const $input = $cell.find('input[name^="rows["][name$="[tested_component]"]');
|
||||||
|
|
||||||
const partDescription = ($input.val() || '').trim();
|
const raw = ($input.val() || '').trim();
|
||||||
|
|
||||||
if (!iddatadb) {
|
// ✅ split multiplo con "|"
|
||||||
alert('❌ iddatadb not found on row');
|
const parts = raw
|
||||||
return;
|
.split('|')
|
||||||
}
|
.map(s => s.trim())
|
||||||
|
.filter(s => s.length > 0);
|
||||||
|
|
||||||
if (!partDescription) {
|
// (opzionale) dedup per evitare doppioni tipo "Cap | Cap"
|
||||||
|
const uniqueParts = [...new Set(parts)];
|
||||||
|
|
||||||
|
if (!uniqueParts.length) {
|
||||||
alert('⚠️ Inserisci prima una descrizione nel campo Tested Component.');
|
alert('⚠️ Inserisci prima una descrizione nel campo Tested Component.');
|
||||||
$input.focus();
|
$input.focus();
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
try {
|
try {
|
||||||
const formData = new FormData();
|
let okCount = 0;
|
||||||
formData.append('iddatadb', iddatadb);
|
const errors = [];
|
||||||
formData.append('part_description', partDescription);
|
|
||||||
|
|
||||||
const resp = await fetch('add_part_quick.php', {
|
// ✅ esegue una chiamata per ogni parte (compatibile con l’attuale add_part_quick.php)
|
||||||
method: 'POST',
|
for (const p of uniqueParts) {
|
||||||
body: formData
|
const formData = new FormData();
|
||||||
});
|
formData.append('iddatadb', iddatadb);
|
||||||
|
formData.append('part_description', p);
|
||||||
|
|
||||||
const data = await resp.json();
|
const resp = await fetch('add_part_quick.php', {
|
||||||
|
method: 'POST',
|
||||||
|
body: formData
|
||||||
|
});
|
||||||
|
|
||||||
if (!resp.ok || !data.success) {
|
let data = {};
|
||||||
throw new Error(data.message || ('HTTP ' + resp.status));
|
try {
|
||||||
|
data = await resp.json();
|
||||||
|
} catch (e) {}
|
||||||
|
|
||||||
|
if (!resp.ok || !data.success) {
|
||||||
|
errors.push(`"${p}": ${(data && data.message) ? data.message : ('HTTP ' + resp.status)}`);
|
||||||
|
} else {
|
||||||
|
okCount++;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// ✅ Do NOT clear tested_component: keep it as a warning/notice
|
// feedback UI
|
||||||
$input.addClass('cell-changed');
|
$input.addClass('cell-changed');
|
||||||
setTimeout(() => $input.removeClass('cell-changed'), 1200);
|
setTimeout(() => $input.removeClass('cell-changed'), 1200);
|
||||||
|
|
||||||
// opzionale: se vuoi comunque “registrare” il cambiamento nel tracker unsaved
|
|
||||||
$input.trigger('change');
|
$input.trigger('change');
|
||||||
|
|
||||||
|
if (errors.length === 0) {
|
||||||
showQuickPartModal('✅ Parte aggiunta con successo!');
|
showQuickPartModal(`✅ Parti aggiunte: ${okCount}`);
|
||||||
|
} else {
|
||||||
|
// aggiunge comunque se alcune sono ok
|
||||||
|
showQuickPartModal(`⚠️ Parti aggiunte: ${okCount}\nErrori:\n- ${errors.join('\n- ')}`);
|
||||||
|
console.error('Add parts errors:', errors);
|
||||||
|
}
|
||||||
|
|
||||||
} catch (err) {
|
} catch (err) {
|
||||||
alert('❌ Errore aggiunta parte: ' + err.message);
|
alert('❌ Errore aggiunta parti: ' + err.message);
|
||||||
console.error(err);
|
console.error(err);
|
||||||
}
|
}
|
||||||
|
|
||||||
});
|
});
|
||||||
|
|
||||||
function showQuickPartModal(message) {
|
function showQuickPartModal(message) {
|
||||||
|
|||||||
@ -460,7 +460,7 @@
|
|||||||
{
|
{
|
||||||
"IdSchemaCustomFields": 129,
|
"IdSchemaCustomFields": 129,
|
||||||
"ConteggioClienti": 0,
|
"ConteggioClienti": 0,
|
||||||
"Nome": "Carhartt",
|
"Nome": "Z_Carhartt",
|
||||||
"Descrizione": "SCHEMA DA UTILIZZARE SOLO PER RICHIESTE UFFICIALI CARHARTT\r\n\r\n\r\n"
|
"Descrizione": "SCHEMA DA UTILIZZARE SOLO PER RICHIESTE UFFICIALI CARHARTT\r\n\r\n\r\n"
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
@ -864,6 +864,12 @@
|
|||||||
"ConteggioClienti": 0,
|
"ConteggioClienti": 0,
|
||||||
"Nome": "HERMES PAP FEMME",
|
"Nome": "HERMES PAP FEMME",
|
||||||
"Descrizione": "Schema per tutti i campioni di HERMES PAP FEMME \r\n15\/01\/2025\r\n\r\n\r\n"
|
"Descrizione": "Schema per tutti i campioni di HERMES PAP FEMME \r\n15\/01\/2025\r\n\r\n\r\n"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"IdSchemaCustomFields": 200,
|
||||||
|
"ConteggioClienti": 0,
|
||||||
|
"Nome": "CARHARTT ( provvisiorio in revisione)",
|
||||||
|
"Descrizione": "Schema per tutti i campioni CARHARTT provvissorio\r\n\r\n"
|
||||||
}
|
}
|
||||||
]
|
]
|
||||||
}
|
}
|
||||||
Loading…
x
Reference in New Issue
Block a user