diff --git a/public/userarea/include/topbar.php b/public/userarea/include/topbar.php
index 7964a840..39d618e6 100644
--- a/public/userarea/include/topbar.php
+++ b/public/userarea/include/topbar.php
@@ -7,7 +7,7 @@
if ($testEnv === 'true'):
?>
-
AMBIENTE DI TEST — NON È PRODUZIONE
diff --git a/public/userarea/migrate_add_fatturazione.php b/public/userarea/migrate_add_fatturazione.php
new file mode 100644
index 00000000..85dc05c5
--- /dev/null
+++ b/public/userarea/migrate_add_fatturazione.php
@@ -0,0 +1,106 @@
+getConnection();
+
+$confirm = isset($_GET['confirm']) && $_GET['confirm'] == '1';
+
+// Stessi default usati da create_fixed_fields.php per ClienteFatturazione
+$FIELD_KEY = 'ClienteFatturazione';
+$DATA_TYPE = 'INT';
+$IS_MANUAL = 1;
+$IS_REQUIRED = 1;
+$DEFAULT_VAL = null;
+$IS_VISIBLE = 1;
+
+try {
+ // 1. Tutti i template_id distinti che hanno già fixed fields
+ $stmt = $pdo->query("SELECT DISTINCT template_id FROM template_fixed_mapping ORDER BY template_id ASC");
+ $allTemplateIds = $stmt->fetchAll(PDO::FETCH_COLUMN);
+
+ // 2. Tra questi, quelli che NON hanno già ClienteFatturazione
+ $placeholders = implode(',', array_fill(0, count($allTemplateIds), '?'));
+ $missingTemplateIds = $allTemplateIds;
+
+ if (!empty($allTemplateIds)) {
+ $stmt = $pdo->prepare("
+ SELECT DISTINCT template_id
+ FROM template_fixed_mapping
+ WHERE fixed_field_key = ?
+ AND template_id IN ({$placeholders})
+ ");
+ $stmt->execute(array_merge([$FIELD_KEY], $allTemplateIds));
+ $alreadyHave = $stmt->fetchAll(PDO::FETCH_COLUMN);
+
+ $missingTemplateIds = array_values(array_diff($allTemplateIds, $alreadyHave));
+ }
+
+ $report = [
+ 'total_templates_with_fixed_fields' => count($allTemplateIds),
+ 'templates_missing_fatturazione' => count($missingTemplateIds),
+ 'template_ids_missing' => $missingTemplateIds,
+ 'dry_run' => !$confirm,
+ 'inserted' => 0,
+ ];
+
+ if (empty($missingTemplateIds)) {
+ echo json_encode(['success' => true] + $report, JSON_PRETTY_PRINT);
+ exit;
+ }
+
+ if (!$confirm) {
+ // Dry run: mostra solo cosa farebbe, non inserisce nulla
+ echo json_encode(['success' => true] + $report, JSON_PRETTY_PRINT);
+ exit;
+ }
+
+ // 3. Esecuzione reale
+ $pdo->beginTransaction();
+
+ $ins = $pdo->prepare("
+ INSERT INTO template_fixed_mapping
+ (template_id, fixed_field_key, is_manual, data_type, is_required, default_value, is_visible_import)
+ VALUES
+ (:template_id, :fixed_field_key, :is_manual, :data_type, :is_required, :default_value, :is_visible_import)
+ ");
+
+ $insertedCount = 0;
+ foreach ($missingTemplateIds as $tid) {
+ $ins->execute([
+ ':template_id' => $tid,
+ ':fixed_field_key' => $FIELD_KEY,
+ ':is_manual' => $IS_MANUAL,
+ ':data_type' => $DATA_TYPE,
+ ':is_required' => $IS_REQUIRED,
+ ':default_value' => $DEFAULT_VAL,
+ ':is_visible_import' => $IS_VISIBLE,
+ ]);
+ $insertedCount++;
+ }
+
+ $pdo->commit();
+
+ $report['inserted'] = $insertedCount;
+
+ echo json_encode(['success' => true] + $report, JSON_PRETTY_PRINT);
+} catch (Exception $e) {
+ if ($pdo->inTransaction()) $pdo->rollBack();
+ echo json_encode(['success' => false, 'message' => $e->getMessage()]);
+}