463 lines
24 KiB
PHP
463 lines
24 KiB
PHP
@php
|
|
$fornitoriFieldGroups = $fornitoriFieldGroups ?? \App\Support\FornitoriImportTargets::groups();
|
|
$fornitoriMapping = $fornitoriMapping ?? [];
|
|
$fornitoriManualValues = $fornitoriManualValues ?? [];
|
|
$fornitoriTargetAdminId = $fornitoriTargetAdminId ?? ($selectedAmministratoreId ?? ($amministratore->id ?? null));
|
|
$fornitoriReferenceData = $fornitoriReferenceData ?? [
|
|
'regimi_fiscali' => collect(),
|
|
'tipologie_cassa' => collect(),
|
|
'aliquote_iva' => collect(),
|
|
];
|
|
$amministratoriDisponibili = $amministratoriDisponibili ?? collect();
|
|
if (!($amministratoriDisponibili instanceof \Illuminate\Support\Collection)) {
|
|
$amministratoriDisponibili = collect($amministratoriDisponibili);
|
|
}
|
|
@endphp
|
|
|
|
<div class="netgescon-card">
|
|
<div class="netgescon-card-header flex justify-between items-center">
|
|
<h3 class="card-title mb-0"><i class="mdi mdi-store me-2"></i> Fornitori</h3>
|
|
<div class="flex gap-2 flex-wrap">
|
|
<button type="button" class="netgescon-btn netgescon-btn-sm netgescon-btn-outline-primary" onclick="openStagingPanel_fornitori()">
|
|
<i class="mdi mdi-database-import"></i> Staging MDB
|
|
</button>
|
|
<button type="button" class="netgescon-btn netgescon-btn-sm netgescon-btn-outline-secondary" onclick="location.reload()">
|
|
<i class="mdi mdi-refresh"></i> Aggiorna
|
|
</button>
|
|
<button type="button" class="netgescon-btn netgescon-btn-sm netgescon-btn-outline-danger" onclick="fornitoriResetProgress()">
|
|
<i class="mdi mdi-backspace"></i> Reset stato
|
|
</button>
|
|
<button type="button" class="netgescon-btn netgescon-btn-sm netgescon-btn-outline-success" onclick="window.location.href='/admin/gescon-import/export/fornitori'">
|
|
<i class="mdi mdi-file-excel"></i> Esporta
|
|
</button>
|
|
</div>
|
|
</div>
|
|
<div class="netgescon-card-body p-0">
|
|
<div class="table-responsive">
|
|
<table class="table table-striped table-hover mb-0">
|
|
<thead class="table-light">
|
|
<tr>
|
|
<th>Ragione Sociale</th>
|
|
<th>CF / P.IVA</th>
|
|
<th>Città</th>
|
|
<th>Contatti</th>
|
|
<th>Creato</th>
|
|
</tr>
|
|
</thead>
|
|
<tbody>
|
|
@forelse(($fornitori ?? []) as $f)
|
|
<tr>
|
|
<td><strong>{{ $f->ragione_sociale }}</strong></td>
|
|
<td>
|
|
@if($f->partita_iva)
|
|
<span class="netgescon-badge">P.IVA: {{ $f->partita_iva }}</span>
|
|
@elseif($f->codice_fiscale)
|
|
<span class="netgescon-badge">CF: {{ $f->codice_fiscale }}</span>
|
|
@else
|
|
<span class="text-gray-500">—</span>
|
|
@endif
|
|
</td>
|
|
<td>
|
|
{{ $f->citta ?? '—' }}
|
|
@if($f->provincia) ({{ $f->provincia }}) @endif
|
|
</td>
|
|
<td>
|
|
@if($f->telefono || $f->email)
|
|
@if($f->telefono)
|
|
<div><i class="mdi mdi-phone"></i> {{ $f->telefono }}</div>
|
|
@endif
|
|
@if($f->email)
|
|
<div><i class="mdi mdi-email"></i> {{ $f->email }}</div>
|
|
@endif
|
|
@else
|
|
<span class="text-gray-500">N/D</span>
|
|
@endif
|
|
</td>
|
|
<td><small>{{ optional($f->created_at)->format('d/m/Y H:i') }}</small></td>
|
|
</tr>
|
|
@empty
|
|
<tr>
|
|
<td colspan="5" class="text-center text-gray-500 py-3">Nessun fornitore</td>
|
|
</tr>
|
|
@endforelse
|
|
</tbody>
|
|
</table>
|
|
</div>
|
|
</div>
|
|
@if(isset($fornitori) && method_exists($fornitori, 'hasPages') && $fornitori->hasPages())
|
|
<div class="netgescon-card-footer flex justify-end">
|
|
{{ $fornitori->links() }}
|
|
</div>
|
|
@endif
|
|
</div>
|
|
|
|
@include('admin.gescon-import.partials.staging-panel', [
|
|
'context' => 'fornitori',
|
|
'title' => 'Staging MDB Fornitori → DB (gescon_import)'
|
|
])
|
|
|
|
<div class="netgescon-card mt-3">
|
|
<div class="netgescon-card-header flex justify-between items-center">
|
|
<strong><i class="mdi mdi-tune"></i> Valori di default e lookup fiscali</strong>
|
|
<small class="text-gray-500">Salvati insieme al mapping</small>
|
|
</div>
|
|
<div class="netgescon-card-body">
|
|
<div class="grid md:grid-cols-12 gap-3">
|
|
<div class="col-span-12 md:col-span-4">
|
|
<label class="form-label small">Regime fiscale predefinito</label>
|
|
<select class="netgescon-input fornitori-manual" data-manual-key="lookup.regime_fiscale">
|
|
<option value="">— Non impostare —</option>
|
|
@foreach($fornitoriReferenceData['regimi_fiscali'] as $regime)
|
|
<option value="{{ $regime->codice }}" @selected(($fornitoriManualValues['lookup.regime_fiscale'] ?? null) === $regime->codice)>
|
|
{{ $regime->codice }} — {{ $regime->descrizione }}
|
|
</option>
|
|
@endforeach
|
|
</select>
|
|
</div>
|
|
<div class="col-span-12 md:col-span-4">
|
|
<label class="form-label small">Tipologia cassa predefinita</label>
|
|
<select class="netgescon-input fornitori-manual" data-manual-key="lookup.tipologia_cassa">
|
|
<option value="">— Non impostare —</option>
|
|
@foreach($fornitoriReferenceData['tipologie_cassa'] as $cassa)
|
|
<option value="{{ $cassa->codice }}" @selected(($fornitoriManualValues['lookup.tipologia_cassa'] ?? null) === $cassa->codice)>
|
|
{{ $cassa->codice }} — {{ $cassa->descrizione }}
|
|
</option>
|
|
@endforeach
|
|
</select>
|
|
</div>
|
|
<div class="col-span-12 md:col-span-4">
|
|
<label class="form-label small">Aliquota IVA predefinita</label>
|
|
<select class="netgescon-input fornitori-manual" data-manual-key="lookup.aliquota_iva">
|
|
<option value="">— Non impostare —</option>
|
|
@foreach($fornitoriReferenceData['aliquote_iva'] as $iva)
|
|
<option value="{{ $iva->codice }}" @selected(($fornitoriManualValues['lookup.aliquota_iva'] ?? null) === $iva->codice)>
|
|
{{ $iva->codice }} — {{ number_format($iva->valore, 2) }}%
|
|
@if($iva->descrizione)
|
|
({{ $iva->descrizione }})
|
|
@endif
|
|
</option>
|
|
@endforeach
|
|
</select>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
|
|
<div class="netgescon-card mt-3">
|
|
<div class="netgescon-card-header flex justify-between items-center">
|
|
<strong><i class="mdi mdi-source-merge me-2"></i> Mapping Fornitori (SX: Legacy/Staging → DX: NetGescon)</strong>
|
|
<small class="text-gray-500">1) Seleziona tabella di staging 2) Mappa colonne 3) Salva mapping 4) Importa con progress</small>
|
|
</div>
|
|
<div class="netgescon-card-body">
|
|
<div class="grid md:grid-cols-12 gap-3 items-end">
|
|
<div class="col-span-12 md:col-span-5">
|
|
<label class="form-label small">Tabella di staging</label>
|
|
<div class="flex gap-2">
|
|
<select id="fornitori-staging-table" class="netgescon-input">
|
|
<option value="">— Carico… —</option>
|
|
</select>
|
|
<button type="button" class="netgescon-btn netgescon-btn-outline-secondary" id="btn-fornitori-refresh">Aggiorna</button>
|
|
<button type="button" class="netgescon-btn netgescon-btn-outline-secondary" id="btn-fornitori-load-cols">Colonne</button>
|
|
</div>
|
|
<div class="text-sm text-gray-500 mt-1">Colonne rilevate: <span id="fornitori-cols-count">0</span></div>
|
|
</div>
|
|
<div class="col-span-6 md:col-span-3">
|
|
<label class="form-label small">Chunk size</label>
|
|
<input type="number" id="fornitori-chunk" class="netgescon-input" value="500" min="50" max="2000" step="50"/>
|
|
</div>
|
|
<div class="col-span-6 md:col-span-4">
|
|
<label class="form-label small">Amministratore destinatario</label>
|
|
@if($amministratoriDisponibili->count())
|
|
<select id="fornitori-target-admin" class="netgescon-input">
|
|
<option value="">— Usa amministratore corrente —</option>
|
|
@foreach($amministratoriDisponibili as $amm)
|
|
@php
|
|
$label = trim($amm->denominazione_studio ?? '') ?: trim(($amm->nome ?? '') . ' ' . ($amm->cognome ?? ''));
|
|
if ($label === '') {
|
|
$label = 'Amministratore #' . $amm->id;
|
|
}
|
|
@endphp
|
|
<option value="{{ $amm->id }}" @selected(($fornitoriTargetAdminId ?? null) == $amm->id)>{{ $label }} (ID {{ $amm->id }})</option>
|
|
@endforeach
|
|
</select>
|
|
@else
|
|
<input type="hidden" id="fornitori-target-admin" value="{{ $fornitoriTargetAdminId }}">
|
|
<div class="text-sm text-gray-500">Import associato a {{ $amministratore->denominazione_studio ?? $amministratore->nome ?? 'amministratore corrente' }}</div>
|
|
@endif
|
|
</div>
|
|
<div class="col-span-12 md:col-span-4 text-right">
|
|
<div class="flex gap-2 justify-end">
|
|
<button type="button" class="netgescon-btn netgescon-btn-primary" id="btn-fornitori-start">Avvia Import</button>
|
|
<button type="button" class="netgescon-btn netgescon-btn-outline-secondary" id="btn-fornitori-pause" disabled>Pausa</button>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
|
|
<div class="grid md:grid-cols-12 gap-3 mt-3">
|
|
<div class="col-span-12 lg:col-span-6">
|
|
<div class="netgescon-card h-100">
|
|
<div class="netgescon-card-header"><strong>Sorgenti (SX) — Colonne Staging</strong></div>
|
|
<div class="netgescon-card-body">
|
|
<ul class="list-group" id="fornitori-cols-list">
|
|
<li class="list-group-item text-gray-500">Nessuna colonna caricata</li>
|
|
</ul>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
<div class="col-span-12 lg:col-span-6">
|
|
<div class="netgescon-card h-100">
|
|
<div class="netgescon-card-header flex justify-between items-center">
|
|
<strong>Destinazione (DX) — Campi NetGescon</strong>
|
|
<div class="flex gap-2">
|
|
<button type="button" class="netgescon-btn netgescon-btn-sm netgescon-btn-outline-secondary" id="btn-fornitori-clear-mapping">Svuota campi</button>
|
|
<button type="button" class="netgescon-btn netgescon-btn-sm netgescon-btn-success" id="btn-fornitori-save-mapping">Salva Mapping</button>
|
|
</div>
|
|
</div>
|
|
<div class="netgescon-card-body space-y-4">
|
|
@foreach($fornitoriFieldGroups as $group)
|
|
<div>
|
|
<div class="text-xs uppercase text-gray-500 font-semibold mb-2">{{ $group['label'] }}</div>
|
|
<div class="grid md:grid-cols-12 gap-2">
|
|
@foreach($group['fields'] as $field)
|
|
<div class="col-span-12 md:col-span-4">
|
|
<label class="form-label small">{{ $field['label'] }}</label>
|
|
<select class="netgescon-input fornitori-map" data-key="{{ $field['key'] }}" data-saved-value="{{ $fornitoriMapping[$field['key']] ?? '' }}">
|
|
<option value="">— Seleziona —</option>
|
|
</select>
|
|
</div>
|
|
@endforeach
|
|
</div>
|
|
</div>
|
|
@endforeach
|
|
</div>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
|
|
<div class="mt-3">
|
|
<div class="text-sm text-gray-500 mb-1">Avanzamento</div>
|
|
<div class="progress" style="height: 18px;">
|
|
<div id="fornitori-progress-bar" class="progress-bar" role="progressbar" style="width: 0%;" aria-valuenow="0" aria-valuemin="0" aria-valuemax="100">0%</div>
|
|
</div>
|
|
<div class="flex justify-between text-sm mt-2">
|
|
<div>Processati: <span id="fornitori-processed">0</span> / <span id="fornitori-total">0</span></div>
|
|
<div>Stato: <span id="fornitori-status" class="netgescon-badge netgescon-badge-secondary">idle</span></div>
|
|
</div>
|
|
<div class="flex justify-between text-xs text-gray-500 mt-1">
|
|
<div>Ultimo chunk importato: <span id="fornitori-last-chunk">0</span></div>
|
|
<div>Aggiornato: <span id="fornitori-last-at">—</span></div>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
|
|
<script>
|
|
const fornitoriCsrf = @json(csrf_token());
|
|
const fornitoriSavedMapping = @json($fornitoriMapping ?? []);
|
|
const fornitoriManualValues = @json($fornitoriManualValues ?? []);
|
|
let fornitoriTargetAdmin = @json($fornitoriTargetAdminId ?? null);
|
|
let fornitoriTimer = null;
|
|
let fornitoriRunning = false;
|
|
let fornitoriColumns = [];
|
|
|
|
async function fornitoriLoadStagingTables(){
|
|
try {
|
|
const res = await fetch(@json(route('admin.gescon-import.fornitori-import.staging-tables')));
|
|
const j = await res.json();
|
|
const sel = document.getElementById('fornitori-staging-table');
|
|
sel.innerHTML = '';
|
|
const tables = j.tables||[];
|
|
if (!tables.length){ const o=document.createElement('option'); o.value=''; o.textContent='— Nessuna tabella mdb%fornit% —'; sel.appendChild(o); return; }
|
|
tables.forEach(t=>{ const o=document.createElement('option'); o.value=t; o.textContent=t; sel.appendChild(o); });
|
|
} catch(e){ console.error(e); alert('Errore caricamento tabelle'); }
|
|
}
|
|
|
|
async function fornitoriLoadColumns(){
|
|
const table = document.getElementById('fornitori-staging-table').value;
|
|
if (!table){ alert('Seleziona una tabella'); return; }
|
|
const url = new URL(@json(route('admin.gescon-import.fornitori-import.staging-columns')), window.location.origin);
|
|
url.searchParams.set('table', table);
|
|
const res = await fetch(url.toString());
|
|
const j = await res.json();
|
|
if (!j.ok){ alert('Errore lettura colonne'); return; }
|
|
fornitoriColumns = j.columns||[];
|
|
document.getElementById('fornitori-cols-count').textContent = String(fornitoriColumns.length);
|
|
const list = document.getElementById('fornitori-cols-list');
|
|
list.innerHTML = '';
|
|
fornitoriColumns.forEach(c=>{ const li=document.createElement('li'); li.className='list-group-item small'; li.textContent=c; list.appendChild(li); });
|
|
document.querySelectorAll('.fornitori-map').forEach(sel=>{
|
|
const saved = sel.dataset.savedValue || sel.value || '';
|
|
sel.innerHTML = '<option value="">— Seleziona —</option>' + fornitoriColumns.map(c=>`<option value="${c}">${c}</option>`).join('');
|
|
sel.value = saved;
|
|
});
|
|
fornitoriApplySavedMapping();
|
|
}
|
|
|
|
function fornitoriApplySavedMapping(){
|
|
document.querySelectorAll('.fornitori-map').forEach(sel=>{
|
|
const key = sel.getAttribute('data-key');
|
|
if (!key) return;
|
|
const saved = sel.dataset.savedValue || fornitoriSavedMapping[key] || '';
|
|
if (saved && !Array.from(sel.options).some(opt => opt.value === saved)) {
|
|
const opt = document.createElement('option');
|
|
opt.value = saved;
|
|
opt.textContent = `${saved} (legacy)`;
|
|
sel.appendChild(opt);
|
|
}
|
|
sel.value = saved || '';
|
|
});
|
|
}
|
|
|
|
function fornitoriApplyManualDefaults(){
|
|
document.querySelectorAll('.fornitori-manual').forEach(input => {
|
|
const key = input.dataset.manualKey;
|
|
if (!key) return;
|
|
const saved = fornitoriManualValues[key];
|
|
if (typeof saved !== 'undefined') {
|
|
input.value = saved;
|
|
}
|
|
});
|
|
const targetAdminSelect = document.getElementById('fornitori-target-admin');
|
|
if (targetAdminSelect && fornitoriTargetAdmin) {
|
|
targetAdminSelect.value = fornitoriTargetAdmin;
|
|
}
|
|
}
|
|
|
|
function fornitoriClearMapping(){
|
|
document.querySelectorAll('.fornitori-map').forEach(sel=>{
|
|
sel.value = '';
|
|
sel.dataset.savedValue = '';
|
|
const key = sel.getAttribute('data-key');
|
|
if (key) delete fornitoriSavedMapping[key];
|
|
});
|
|
document.querySelectorAll('.fornitori-manual').forEach(input=>{
|
|
input.value = '';
|
|
const key = input.dataset.manualKey;
|
|
if (key) delete fornitoriManualValues[key];
|
|
});
|
|
}
|
|
|
|
async function fornitoriSaveMapping(){
|
|
const selects = Array.from(document.querySelectorAll('.fornitori-map'));
|
|
const mapping = {};
|
|
selects.forEach(s=>{ const k = s.getAttribute('data-key'); const v = (s.value || '').trim(); if (k && v) mapping[k] = v; });
|
|
const manualInputs = Array.from(document.querySelectorAll('.fornitori-manual'));
|
|
const fd = new FormData();
|
|
fd.set('_mapping_only', '1');
|
|
fd.set('_legacy_code', 'fornitori');
|
|
for (const [k,v] of Object.entries(mapping)) {
|
|
fd.append(`mapping[${k}]`, v);
|
|
}
|
|
manualInputs.forEach(input => {
|
|
const key = input.dataset.manualKey;
|
|
const value = (input.value || '').trim();
|
|
if (key && value !== '') {
|
|
fd.append(`manual_target_values[${key}]`, value);
|
|
}
|
|
});
|
|
const targetAdminSelect = document.getElementById('fornitori-target-admin');
|
|
if (targetAdminSelect) {
|
|
fd.set('target_admin_id', targetAdminSelect.value || '');
|
|
}
|
|
const res = await fetch(@json(route('admin.gescon-import.mapping.save')), { method:'POST', headers:{'X-CSRF-TOKEN': fornitoriCsrf}, body: fd });
|
|
selects.forEach(sel => {
|
|
const key = sel.getAttribute('data-key');
|
|
const value = sel.value || '';
|
|
sel.dataset.savedValue = value;
|
|
if (key) {
|
|
if (value) {
|
|
fornitoriSavedMapping[key] = value;
|
|
} else {
|
|
delete fornitoriSavedMapping[key];
|
|
}
|
|
}
|
|
});
|
|
manualInputs.forEach(input => {
|
|
const key = input.dataset.manualKey;
|
|
if (!key) return;
|
|
const value = (input.value || '').trim();
|
|
if (value) {
|
|
fornitoriManualValues[key] = value;
|
|
} else {
|
|
delete fornitoriManualValues[key];
|
|
}
|
|
});
|
|
if (targetAdminSelect) {
|
|
fornitoriTargetAdmin = targetAdminSelect.value || null;
|
|
}
|
|
if (res.redirected){ window.location.href = res.url; return; }
|
|
try { const j = await res.json(); if (j.success) alert('Mapping salvato'); } catch(_e){ /* ignore */ }
|
|
}
|
|
|
|
async function fornitoriInit(){
|
|
const table = document.getElementById('fornitori-staging-table').value;
|
|
if (!table){ alert('Seleziona una tabella di staging'); return false; }
|
|
const fd = new FormData(); fd.set('staging_table', table);
|
|
const res = await fetch(@json(route('admin.gescon-import.fornitori-import.init')), { method:'POST', headers:{'X-CSRF-TOKEN': fornitoriCsrf}, body: fd });
|
|
const j = await res.json(); if (!j.ok){ alert(j.error||'Errore init'); return false; }
|
|
fornitoriUpdateUI(j.progress); return true;
|
|
}
|
|
|
|
async function fornitoriProcessTick(){
|
|
if (!fornitoriRunning) return;
|
|
const chunk = parseInt(document.getElementById('fornitori-chunk').value||'500',10);
|
|
const fd = new FormData(); fd.set('chunk', String(chunk));
|
|
try{
|
|
const res = await fetch(@json(route('admin.gescon-import.fornitori-import.process-chunk')), { method:'POST', headers:{'X-CSRF-TOKEN': fornitoriCsrf}, body: fd });
|
|
const j = await res.json(); if (j.ok){ fornitoriUpdateUI(j.progress); if (j.progress.status==='completed') fornitoriStop(); }
|
|
}catch(e){ console.error(e); fornitoriStop(); }
|
|
}
|
|
|
|
function fornitoriStart(){ if (fornitoriRunning) return; fornitoriRunning=true; document.getElementById('btn-fornitori-start').disabled=true; document.getElementById('btn-fornitori-pause').disabled=false; fornitoriProcessTick(); fornitoriTimer = setInterval(fornitoriProcessTick, 800); }
|
|
function fornitoriPause(){ fornitoriRunning=false; document.getElementById('btn-fornitori-start').disabled=false; document.getElementById('btn-fornitori-pause').disabled=true; if (fornitoriTimer){ clearInterval(fornitoriTimer); fornitoriTimer=null; } }
|
|
function fornitoriStop(){ fornitoriPause(); fornitoriPollProgress(); }
|
|
|
|
async function fornitoriPollProgress(){ try{ const res = await fetch(@json(route('admin.gescon-import.fornitori-import.progress'))); const j = await res.json(); if (j.ok) fornitoriUpdateUI(j.progress);}catch(e){console.error(e);} }
|
|
|
|
function fornitoriUpdateUI(p){
|
|
if (!p) return;
|
|
const pct = Math.max(0, Math.min(100, parseInt(p.percent||((p.processed||0)/(p.total||1)*100),10)));
|
|
const bar = document.getElementById('fornitori-progress-bar');
|
|
bar.style.width = pct+'%'; bar.setAttribute('aria-valuenow', String(pct)); bar.textContent = pct+'%';
|
|
document.getElementById('fornitori-processed').textContent = String(p.processed||0);
|
|
document.getElementById('fornitori-total').textContent = String(p.total||0);
|
|
const st = document.getElementById('fornitori-status');
|
|
const status = p.status||'idle';
|
|
st.textContent = status;
|
|
st.className='netgescon-badge ' + (status==='completed'?'netgescon-badge-success':(status==='running'?'netgescon-badge-primary':'netgescon-badge-secondary'));
|
|
document.getElementById('fornitori-last-chunk').textContent = String(p.last_chunk_imported ?? 0);
|
|
const lastAtEl = document.getElementById('fornitori-last-at');
|
|
if (p.last_chunk_at) {
|
|
const d = new Date(p.last_chunk_at);
|
|
lastAtEl.textContent = isNaN(d.getTime()) ? p.last_chunk_at : d.toLocaleString();
|
|
} else {
|
|
lastAtEl.textContent = '—';
|
|
}
|
|
}
|
|
|
|
async function fornitoriResetProgress(){
|
|
if (!confirm('Azzerare stato e progress dell\'import fornitori?')) return;
|
|
try {
|
|
const res = await fetch(@json(route('admin.gescon-import.fornitori-import.reset')), { method:'POST', headers:{'X-CSRF-TOKEN': fornitoriCsrf} });
|
|
if (res.ok) {
|
|
fornitoriUpdateUI({ processed: 0, total: 0, status: 'idle', percent: 0, last_chunk_imported: 0 });
|
|
}
|
|
} catch (e) {
|
|
console.error(e);
|
|
}
|
|
}
|
|
|
|
document.addEventListener('DOMContentLoaded', ()=>{
|
|
fornitoriLoadStagingTables();
|
|
fornitoriApplySavedMapping();
|
|
fornitoriApplyManualDefaults();
|
|
fornitoriPollProgress();
|
|
document.getElementById('btn-fornitori-refresh').addEventListener('click', fornitoriLoadStagingTables);
|
|
document.getElementById('btn-fornitori-load-cols').addEventListener('click', fornitoriLoadColumns);
|
|
document.getElementById('btn-fornitori-save-mapping').addEventListener('click', fornitoriSaveMapping);
|
|
document.getElementById('btn-fornitori-clear-mapping').addEventListener('click', fornitoriClearMapping);
|
|
document.getElementById('btn-fornitori-start').addEventListener('click', async ()=>{ const ok = await fornitoriInit(); if (ok) fornitoriStart(); });
|
|
document.getElementById('btn-fornitori-pause').addEventListener('click', fornitoriPause);
|
|
});
|
|
</script>
|