added note field on template and export
This commit is contained in:
@@ -0,0 +1,20 @@
|
|||||||
|
<?php
|
||||||
|
|
||||||
|
declare(strict_types=1);
|
||||||
|
|
||||||
|
use Phinx\Migration\AbstractMigration;
|
||||||
|
|
||||||
|
final class AddAddnoteToTemplateMapping extends AbstractMigration
|
||||||
|
{
|
||||||
|
public function change(): void
|
||||||
|
{
|
||||||
|
$table = $this->table('template_mapping');
|
||||||
|
$table->addColumn('is_addnote', 'boolean', [
|
||||||
|
'default' => 0,
|
||||||
|
'null' => false,
|
||||||
|
'after' => 'is_visible_parts',
|
||||||
|
'comment' => 'Campo utilizzabile come addnote (multi-selezione)',
|
||||||
|
])
|
||||||
|
->update();
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -363,3 +363,14 @@
|
|||||||
2026-06-16 17:14:25 - Autenticazione fallita: HTTP 0, Errore cURL: Failed to connect to bvcpsitaly-elims.com port 443 after 21065 ms: Couldn't connect to server, Risposta:
|
2026-06-16 17:14:25 - Autenticazione fallita: HTTP 0, Errore cURL: Failed to connect to bvcpsitaly-elims.com port 443 after 21065 ms: Couldn't connect to server, Risposta:
|
||||||
2026-06-16 17:14:46 - Autenticazione fallita: HTTP 0, Errore cURL: Failed to connect to bvcpsitaly-elims.com port 443 after 21071 ms: Couldn't connect to server, Risposta:
|
2026-06-16 17:14:46 - Autenticazione fallita: HTTP 0, Errore cURL: Failed to connect to bvcpsitaly-elims.com port 443 after 21071 ms: Couldn't connect to server, Risposta:
|
||||||
2026-06-16 17:14:46 - Autenticazione fallita: HTTP 0, Errore cURL: Failed to connect to bvcpsitaly-elims.com port 443 after 21078 ms: Couldn't connect to server, Risposta:
|
2026-06-16 17:14:46 - Autenticazione fallita: HTTP 0, Errore cURL: Failed to connect to bvcpsitaly-elims.com port 443 after 21078 ms: Couldn't connect to server, Risposta:
|
||||||
|
2026-07-09 08:06:33 - Autenticazione fallita: HTTP 0, Errore cURL: Could not resolve host: bvcpsitaly-elims.com, Risposta:
|
||||||
|
2026-07-09 08:06:33 - Autenticazione fallita: HTTP 0, Errore cURL: Could not resolve host: bvcpsitaly-elims.com, Risposta:
|
||||||
|
2026-07-09 08:06:33 - Autenticazione fallita: HTTP 0, Errore cURL: Could not resolve host: bvcpsitaly-elims.com, Risposta:
|
||||||
|
2026-07-09 08:06:33 - Autenticazione fallita: HTTP 0, Errore cURL: Could not resolve host: bvcpsitaly-elims.com, Risposta:
|
||||||
|
2026-07-09 08:06:33 - Autenticazione fallita: HTTP 0, Errore cURL: Could not resolve host: bvcpsitaly-elims.com, Risposta:
|
||||||
|
2026-07-09 08:06:41 - Autenticazione fallita: HTTP 0, Errore cURL: Could not resolve host: bvcpsitaly-elims.com, Risposta:
|
||||||
|
2026-07-09 08:06:41 - Autenticazione fallita: HTTP 0, Errore cURL: Could not resolve host: bvcpsitaly-elims.com, Risposta:
|
||||||
|
2026-07-09 08:06:41 - Autenticazione fallita: HTTP 0, Errore cURL: Could not resolve host: bvcpsitaly-elims.com, Risposta:
|
||||||
|
2026-07-09 08:06:41 - Autenticazione fallita: HTTP 0, Errore cURL: Could not resolve host: bvcpsitaly-elims.com, Risposta:
|
||||||
|
2026-07-09 08:06:41 - Autenticazione fallita: HTTP 0, Errore cURL: Could not resolve host: bvcpsitaly-elims.com, Risposta:
|
||||||
|
2026-07-10 08:12:24 - Errore nella richiesta: SSL connection timeout
|
||||||
|
|||||||
@@ -150,7 +150,7 @@ try {
|
|||||||
// 🔹 STEP 1+2: Fetch Cliente ID from datadb and Schema ID from excel_templates
|
// 🔹 STEP 1+2: Fetch Cliente ID from datadb and Schema ID from excel_templates
|
||||||
// Also fetch fixed fields stored in datadb
|
// Also fetch fixed fields stored in datadb
|
||||||
$stmt = $pdo->prepare("
|
$stmt = $pdo->prepare("
|
||||||
SELECT d.idclient AS clienteId, et.idschema AS schemaId,
|
SELECT d.idclient AS clienteId, et.idschema AS schemaId, et.id AS templateId,
|
||||||
d.cliente_responsabile_id,
|
d.cliente_responsabile_id,
|
||||||
d.moltiplicatore_prezzo_id,
|
d.moltiplicatore_prezzo_id,
|
||||||
d.anagrafica_certest_object_id,
|
d.anagrafica_certest_object_id,
|
||||||
@@ -173,6 +173,7 @@ try {
|
|||||||
|
|
||||||
$clienteId = (int) $result['clienteId'];
|
$clienteId = (int) $result['clienteId'];
|
||||||
$schemaId = (int) $result['schemaId'];
|
$schemaId = (int) $result['schemaId'];
|
||||||
|
$templateId = (int) $result['templateId'];
|
||||||
|
|
||||||
// Extract fixed fields (nullable INTs)
|
// Extract fixed fields (nullable INTs)
|
||||||
$clienteResponsabile = !empty($result['cliente_responsabile_id']) ? (int) $result['cliente_responsabile_id'] : null;
|
$clienteResponsabile = !empty($result['cliente_responsabile_id']) ? (int) $result['cliente_responsabile_id'] : null;
|
||||||
@@ -212,6 +213,7 @@ try {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
// 🔹 STEP 4a: Auto-populate export_date / export_time fields
|
// 🔹 STEP 4a: Auto-populate export_date / export_time fields
|
||||||
$stmt = $pdo->prepare("
|
$stmt = $pdo->prepare("
|
||||||
UPDATE import_data_details idd
|
UPDATE import_data_details idd
|
||||||
@@ -235,7 +237,9 @@ try {
|
|||||||
idd.field_value,
|
idd.field_value,
|
||||||
m.field_label,
|
m.field_label,
|
||||||
m.schema_id,
|
m.schema_id,
|
||||||
m.field_id
|
m.field_id,
|
||||||
|
m.field_order,
|
||||||
|
m.is_addnote
|
||||||
FROM
|
FROM
|
||||||
import_data_details as idd
|
import_data_details as idd
|
||||||
JOIN template_mapping m ON idd.mapping_id = m.id
|
JOIN template_mapping m ON idd.mapping_id = m.id
|
||||||
@@ -255,6 +259,27 @@ try {
|
|||||||
$valueMap[(int) $row['field_id']] = $row['field_value'];
|
$valueMap[(int) $row['field_id']] = $row['field_value'];
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// 🔹 Note aggiuntive: custom field flaggati is_addnote e valorizzati.
|
||||||
|
// Valori a livello di commessa → identici su tutte le parti.
|
||||||
|
$addnoteChunks = [];
|
||||||
|
$addnoteRows = array_filter($rows, fn($r) => (int)($r['is_addnote'] ?? 0) === 1);
|
||||||
|
|
||||||
|
usort($addnoteRows, function ($a, $b) {
|
||||||
|
$oa = (int)($a['field_order'] ?? 9999);
|
||||||
|
$ob = (int)($b['field_order'] ?? 9999);
|
||||||
|
if ($oa !== $ob) return $oa <=> $ob;
|
||||||
|
return strcmp((string)($a['field_label'] ?? ''), (string)($b['field_label'] ?? ''));
|
||||||
|
});
|
||||||
|
|
||||||
|
foreach ($addnoteRows as $r) {
|
||||||
|
$val = trim((string)($r['field_value'] ?? ''));
|
||||||
|
if ($val !== '') {
|
||||||
|
$addnoteChunks[] = $val;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
$addnoteText = implode(' - ', $addnoteChunks);
|
||||||
|
|
||||||
// Logga i fieldValues in error_log
|
// Logga i fieldValues in error_log
|
||||||
$logFieldValues = "FieldValues dal DB (iddatadb={$iddatadb}):\n" . json_encode($fieldValues, JSON_PRETTY_PRINT);
|
$logFieldValues = "FieldValues dal DB (iddatadb={$iddatadb}):\n" . json_encode($fieldValues, JSON_PRETTY_PRINT);
|
||||||
error_log($logFieldValues);
|
error_log($logFieldValues);
|
||||||
@@ -311,7 +336,23 @@ try {
|
|||||||
|
|
||||||
$partDescription = $part["part_description"] ?? "";
|
$partDescription = $part["part_description"] ?? "";
|
||||||
$partNote = trim((string)($part["note"] ?? ""));
|
$partNote = trim((string)($part["note"] ?? ""));
|
||||||
$noteWebValue = $partNote !== "" ? $partDescription . " - " . $partNote : $partDescription;
|
|
||||||
|
// Note aggiuntive dai custom field flaggati is_addnote
|
||||||
|
$partDescription = $part["part_description"] ?? "";
|
||||||
|
$partNote = trim((string)($part["note"] ?? ""));
|
||||||
|
|
||||||
|
// Componi NoteWeb: descrizione [- note] [- addnote di commessa]
|
||||||
|
$noteParts = [];
|
||||||
|
if ($partDescription !== "") {
|
||||||
|
$noteParts[] = $partDescription;
|
||||||
|
}
|
||||||
|
if ($partNote !== "") {
|
||||||
|
$noteParts[] = $partNote;
|
||||||
|
}
|
||||||
|
if ($addnoteText !== "") {
|
||||||
|
$noteParts[] = $addnoteText;
|
||||||
|
}
|
||||||
|
$noteWebValue = implode(" - ", $noteParts);
|
||||||
|
|
||||||
$campionePayload = [
|
$campionePayload = [
|
||||||
"Commessa" => $commessaId,
|
"Commessa" => $commessaId,
|
||||||
|
|||||||
@@ -77,7 +77,8 @@ $stmt = $pdo->prepare("
|
|||||||
field_label,
|
field_label,
|
||||||
main_field,
|
main_field,
|
||||||
is_visible_import,
|
is_visible_import,
|
||||||
is_visible_parts
|
is_visible_parts,
|
||||||
|
is_addnote
|
||||||
FROM template_mapping
|
FROM template_mapping
|
||||||
WHERE template_id = ?
|
WHERE template_id = ?
|
||||||
ORDER BY field_order ASC, id ASC
|
ORDER BY field_order ASC, id ASC
|
||||||
@@ -183,7 +184,9 @@ $apiSampleJson = $template['api_sample_json'] ?? '';
|
|||||||
#schemaFieldsTable th:nth-child(2),
|
#schemaFieldsTable th:nth-child(2),
|
||||||
#schemaFieldsTable td:nth-child(2),
|
#schemaFieldsTable td:nth-child(2),
|
||||||
#schemaFieldsTable th:nth-child(3),
|
#schemaFieldsTable th:nth-child(3),
|
||||||
#schemaFieldsTable td:nth-child(3) {
|
#schemaFieldsTable td:nth-child(3),
|
||||||
|
#schemaFieldsTable th:nth-child(4),
|
||||||
|
#schemaFieldsTable td:nth-child(4) {
|
||||||
width: 48px;
|
width: 48px;
|
||||||
/* 🔥 più stretto */
|
/* 🔥 più stretto */
|
||||||
text-align: center;
|
text-align: center;
|
||||||
@@ -195,7 +198,8 @@ $apiSampleJson = $template['api_sample_json'] ?? '';
|
|||||||
/* Make checkbox itself not oversized */
|
/* Make checkbox itself not oversized */
|
||||||
#schemaFieldsTable td:nth-child(1) input[type="checkbox"],
|
#schemaFieldsTable td:nth-child(1) input[type="checkbox"],
|
||||||
#schemaFieldsTable td:nth-child(2) input[type="checkbox"],
|
#schemaFieldsTable td:nth-child(2) input[type="checkbox"],
|
||||||
#schemaFieldsTable td:nth-child(3) input[type="checkbox"] {
|
#schemaFieldsTable td:nth-child(3) input[type="checkbox"],
|
||||||
|
#schemaFieldsTable td:nth-child(4) input[type="checkbox"] {
|
||||||
transform: scale(0.95);
|
transform: scale(0.95);
|
||||||
margin: 0;
|
margin: 0;
|
||||||
}
|
}
|
||||||
@@ -398,6 +402,7 @@ $apiSampleJson = $template['api_sample_json'] ?? '';
|
|||||||
<th style="width:45px; text-align:center;">Main</th>
|
<th style="width:45px; text-align:center;">Main</th>
|
||||||
<th style="width:45px; text-align:center;">Import</th>
|
<th style="width:45px; text-align:center;">Import</th>
|
||||||
<th style="width:45px; text-align:center;">Parts</th>
|
<th style="width:45px; text-align:center;">Parts</th>
|
||||||
|
<th style="width:45px; text-align:center;">Note</th>
|
||||||
<th style="width:320px;">Title</th>
|
<th style="width:320px;">Title</th>
|
||||||
<th style="width:70px; text-align:center;">Order</th>
|
<th style="width:70px; text-align:center;">Order</th>
|
||||||
<th style="width:120px;">Type</th>
|
<th style="width:120px;">Type</th>
|
||||||
@@ -428,7 +433,12 @@ $apiSampleJson = $template['api_sample_json'] ?? '';
|
|||||||
data-mapping-id="<?php echo (int)$mapping['id']; ?>"
|
data-mapping-id="<?php echo (int)$mapping['id']; ?>"
|
||||||
<?php echo ((int)($mapping['is_visible_parts'] ?? 0) === 1) ? 'checked' : ''; ?>>
|
<?php echo ((int)($mapping['is_visible_parts'] ?? 0) === 1) ? 'checked' : ''; ?>>
|
||||||
</td>
|
</td>
|
||||||
|
<td class="text-center">
|
||||||
|
<input type="checkbox"
|
||||||
|
class="addnote-checkbox"
|
||||||
|
data-mapping-id="<?php echo (int)$mapping['id']; ?>"
|
||||||
|
<?php echo ((int)($mapping['is_addnote'] ?? 0) === 1) ? 'checked' : ''; ?>>
|
||||||
|
</td>
|
||||||
<td class="title-col">
|
<td class="title-col">
|
||||||
<?php echo htmlspecialchars($mapping['field_label'] ?? 'N/A'); ?>
|
<?php echo htmlspecialchars($mapping['field_label'] ?? 'N/A'); ?>
|
||||||
<?php if ((int)$mapping['is_required'] === 1): ?>
|
<?php if ((int)$mapping['is_required'] === 1): ?>
|
||||||
@@ -442,8 +452,6 @@ $apiSampleJson = $template['api_sample_json'] ?? '';
|
|||||||
|
|
||||||
<td><?php echo htmlspecialchars($mapping['data_type'] ?? 'N/A'); ?></td>
|
<td><?php echo htmlspecialchars($mapping['data_type'] ?? 'N/A'); ?></td>
|
||||||
|
|
||||||
<td><?php echo htmlspecialchars($mapping['data_type'] ?? 'N/A'); ?></td>
|
|
||||||
|
|
||||||
<td>
|
<td>
|
||||||
<?php
|
<?php
|
||||||
$isSceltaMultipla = ($mapping['data_type'] === 'SceltaMultipla');
|
$isSceltaMultipla = ($mapping['data_type'] === 'SceltaMultipla');
|
||||||
@@ -1938,6 +1946,10 @@ $apiSampleJson = $template['api_sample_json'] ?? '';
|
|||||||
if (el.classList.contains('visible-parts-checkbox')) {
|
if (el.classList.contains('visible-parts-checkbox')) {
|
||||||
saveMappingFlag(el, 'is_visible_parts');
|
saveMappingFlag(el, 'is_visible_parts');
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (el.classList.contains('addnote-checkbox')) {
|
||||||
|
saveMappingFlag(el, 'is_addnote');
|
||||||
|
}
|
||||||
});
|
});
|
||||||
// AUTO VALUE select change -> save auto_value
|
// AUTO VALUE select change -> save auto_value
|
||||||
document.getElementById('schemaFieldsBody').addEventListener('change', function(event) {
|
document.getElementById('schemaFieldsBody').addEventListener('change', function(event) {
|
||||||
|
|||||||
@@ -906,6 +906,12 @@
|
|||||||
"ConteggioClienti": 0,
|
"ConteggioClienti": 0,
|
||||||
"Nome": "COLDWATER CREEK",
|
"Nome": "COLDWATER CREEK",
|
||||||
"Descrizione": "\r\n"
|
"Descrizione": "\r\n"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"IdSchemaCustomFields": 208,
|
||||||
|
"ConteggioClienti": 0,
|
||||||
|
"Nome": "ETON",
|
||||||
|
"Descrizione": "Schema da usare per ETON\r\n"
|
||||||
}
|
}
|
||||||
]
|
]
|
||||||
}
|
}
|
||||||
@@ -21,7 +21,7 @@ $field = $data['field'];
|
|||||||
$value = isset($data['value']) && $data['value'] ? 1 : 0;
|
$value = isset($data['value']) && $data['value'] ? 1 : 0;
|
||||||
|
|
||||||
// Whitelist rigorosa dei campi aggiornabili: evita SQL injection sul nome colonna
|
// Whitelist rigorosa dei campi aggiornabili: evita SQL injection sul nome colonna
|
||||||
$allowedFields = ['main_field', 'is_visible_import', 'is_visible_parts'];
|
$allowedFields = ['main_field', 'is_visible_import', 'is_visible_parts', 'is_addnote'];
|
||||||
|
|
||||||
if (!in_array($field, $allowedFields, true)) {
|
if (!in_array($field, $allowedFields, true)) {
|
||||||
echo json_encode(["success" => false, "message" => "Invalid field"]);
|
echo json_encode(["success" => false, "message" => "Invalid field"]);
|
||||||
|
|||||||
Reference in New Issue
Block a user