netgescon-day0/resources/views/admin/gescon-import/tabs/banche.blade.php

258 lines
14 KiB
PHP

@php($legacyCode = request('legacy_code'))
<div class="netgescon-card">
<div class="netgescon-card-header flex justify-between items-center">
<h3 class="card-title mb-0"><i class="mdi mdi-bank me-2"></i> Banche (Legacy Staging NetGescon)</h3>
<div class="flex gap-2">
<button type="button" class="netgescon-btn netgescon-btn-sm netgescon-btn-outline-primary" onclick="openStagingPanel_banche()">
<i class="mdi mdi-database-import"></i> Staging MDB
</button>
<span id="iban-unique-badge" class="netgescon-badge netgescon-badge-secondary hidden"></span>
</div>
</div>
<div class="netgescon-card-body">
@php
$bankCount = null;
try{
$legacy = $legacyCode;
if ($legacy && \Illuminate\Support\Facades\Schema::hasTable('stabili')){
$col = \Illuminate\Support\Facades\Schema::hasColumn('stabili','codice_stabile') ? 'codice_stabile' : (\Illuminate\Support\Facades\Schema::hasColumn('stabili','denominazione') ? 'denominazione' : null);
if ($col){
$stab = \Illuminate\Support\Facades\DB::table('stabili')->where($col,$legacy)->first();
if ($stab && \Illuminate\Support\Facades\Schema::hasTable('dati_bancari')){
$bankCount = \Illuminate\Support\Facades\DB::table('dati_bancari')->where('stabile_id', $stab->id)->count();
}
}
}
}catch (\Throwable $e){ $bankCount = null; }
@endphp
<p class="text-gray-500 text-sm">Importa più conti bancari per ogni stabile. Mappa i campi legacy delle BANCA 1 / BANCA 2 / BANCA 3 (IBAN, Istituto, SWIFT, N. Conto, Intestatario, Cod. Cassa) verso NetGescon.
@if(isset($bankCount))
<span class="netgescon-badge netgescon-badge-info ms-2">Conti già presenti: {{ $bankCount }}</span>
@endif
</p>
<div class="flex items-center justify-between mb-3">
<div class="text-sm text-gray-600">Legacy selezionato: <span class="font-mono">{{ request('legacy_code') ?: '—' }}</span></div>
<div class="flex gap-2">
<button type="button" id="btn-add-banca" class="netgescon-btn netgescon-btn-sm netgescon-btn-outline-secondary" onclick="addBankRow()"><i class="mdi mdi-plus"></i> Aggiungi banca</button>
<button type="button" class="netgescon-btn netgescon-btn-sm netgescon-btn-outline-danger" onclick="clearBanks()"><i class="mdi mdi-delete"></i> Svuota</button>
</div>
</div>
<form id="banche-form" method="post" action="{{ route('admin.gescon-import.mapping.save') }}" onsubmit="return submitBanche(event)">
@csrf
<input type="hidden" name="_mapping_only" value="1">
<input type="hidden" name="_legacy_code" value="{{ request('legacy_code') }}">
<input type="hidden" name="banche_mapping" id="banche_mapping" value="[]">
<div id="banche-rows" class="space-y-3"></div>
<div class="form-check mt-2">
<input type="checkbox" id="markNostroConto" class="form-check-input">
<label class="form-check-label" for="markNostroConto">Contrassegna il primo conto come "nostro conto" (predefinito per incassi/operazioni)</label>
</div>
<div class="text-end mt-3">
<button type="submit" class="netgescon-btn netgescon-btn-primary"><i class="mdi mdi-content-save"></i> Salva Mapping Banche</button>
</div>
</form>
</div>
</div>
@include('admin.gescon-import.partials.staging-panel', [
'context' => 'banche',
'title' => 'Staging MDB Banche → DB (gescon_import)'
])
<script>
// Config campi target disponibili per banche
const BANK_TARGETS = [
{ value: 'banca.nome_banca', label: 'Banca → Istituto' },
{ value: 'banca.iban', label: 'Banca → IBAN' },
{ value: 'banca.swift', label: 'Banca → SWIFT/BIC' },
{ value: 'banca.conto', label: 'Banca → N. Conto' },
{ value: 'banca.intestatario', label: 'Banca → Intestatario' },
{ value: 'banca.cod_cassa', label: 'Banca → Cod. Cassa (legacy)'}
];
function buildTargetSelect(name, selected){
let html = '<select class="netgescon-input" name="'+escapeHtml(name)+'">';
html += '<option value="">— Seleziona —</option>';
BANK_TARGETS.forEach(tf => {
const sel = (selected && selected === tf.value) ? ' selected' : '';
html += '<option value="'+escapeHtml(tf.value)+'"'+sel+'>'+escapeHtml(tf.label)+'</option>';
});
html += '</select>';
return html;
}
function addBankRow(prefill){
const container = document.getElementById('banche-rows');
const idx = container ? container.children.length : 0;
if (idx >= 3) { // massimo BANCA 1/2/3
const btn = document.getElementById('btn-add-banca');
if (btn) btn.classList.add('hidden');
return;
}
const row = document.createElement('div');
row.className = 'netgescon-card';
row.innerHTML = `
<div class="netgescon-card-header flex justify-between items-center">
<strong>Banca #${idx+1}</strong>
<button type="button" class="netgescon-btn netgescon-btn-sm netgescon-btn-outline-danger" onclick="this.closest('.netgescon-card').remove(); renumberBanks()">
<i class="mdi mdi-close"></i> Rimuovi
</button>
</div>
<div class="netgescon-card-body">
<div class="grid md:grid-cols-12 gap-3">
<div class="md:col-span-6">
<label class="form-label">Istituto (legacy → target)</label>
<div class="flex gap-2">
<input type="text" class="netgescon-input" placeholder="campo legacy es. nome_banca" data-field="legacy_nome_banca" value="${escapeHtml(prefill?.legacy_nome_banca||prefill?.legacy?.nome_banca||'')}">
${buildTargetSelect('banche['+idx+'][nome_banca]', prefill?.target_nome_banca||prefill?.nome_banca||prefill?.target?.nome_banca||'')}
</div>
</div>
<div class="md:col-span-6">
<label class="form-label">IBAN (legacy → target)</label>
<div class="flex gap-2">
<input type="text" class="netgescon-input" placeholder="es. BANCA ${idx+1} → IBAN" data-field="legacy_iban" value="${escapeHtml(prefill?.legacy_iban||prefill?.legacy?.iban||'')}" oninput="updateIbanBadge()">
${buildTargetSelect('banche['+idx+'][iban]', prefill?.target_iban||prefill?.iban||prefill?.target?.iban||'')}
</div>
</div>
<div class="md:col-span-4">
<label class="form-label">SWIFT/BIC</label>
<div class="flex gap-2">
<input type="text" class="netgescon-input" placeholder="campo legacy es. swift" data-field="legacy_swift" value="${escapeHtml(prefill?.legacy_swift||prefill?.legacy?.swift||'')}">
${buildTargetSelect('banche['+idx+'][swift]', prefill?.target_swift||prefill?.swift||prefill?.target?.swift||'')}
</div>
</div>
<div class="md:col-span-4">
<label class="form-label">N. Conto</label>
<div class="flex gap-2">
<input type="text" class="netgescon-input" placeholder="campo legacy es. conto" data-field="legacy_conto" value="${escapeHtml(prefill?.legacy_conto||prefill?.legacy?.conto||'')}">
${buildTargetSelect('banche['+idx+'][conto]', prefill?.target_conto||prefill?.conto||prefill?.target?.conto||'')}
</div>
</div>
<div class="md:col-span-4">
<label class="form-label">Intestatario</label>
<div class="flex gap-2">
<input type="text" class="netgescon-input" placeholder="campo legacy es. intestatario" data-field="legacy_intestatario" value="${escapeHtml(prefill?.legacy_intestatario||prefill?.legacy?.intestatario||'')}">
${buildTargetSelect('banche['+idx+'][intestatario]', prefill?.target_intestatario||prefill?.intestatario||prefill?.target?.intestatario||'')}
</div>
</div>
<div class="md:col-span-4">
<label class="form-label">Cod. Cassa (legacy)</label>
<div class="flex gap-2">
<input type="text" class="netgescon-input" placeholder="es. COD_CASSA / modalita_pagamento" data-field="legacy_cod_cassa" value="${escapeHtml(prefill?.legacy_cod_cassa||prefill?.legacy?.cod_cassa||'')}">
${buildTargetSelect('banche['+idx+'][cod_cassa]', prefill?.target_cod_cassa_select||prefill?.target_cod_cassa||prefill?.cod_cassa||prefill?.target?.cod_cassa||'')}
</div>
</div>
<div class="md:col-span-4">
<label class="form-label">Codice Cassa da usare (CON/CCB/CDL)</label>
<div class="flex gap-2">
<input type="text" class="netgescon-input" placeholder="es. CCB" data-field="target_cod_cassa" value="${escapeHtml(prefill?.target_cod_cassa||prefill?.target?.codice_cassa||prefill?.codice_cassa||'')}">
<span class="text-xs text-gray-500 self-center">Opzionale: imposta il codice cassa da associare a questo conto</span>
</div>
</div>
</div>
</div>
`;
container.appendChild(row);
updateIbanBadge();
// Nascondi add se raggiunto limite
if (container.children.length >= 3) {
const btn = document.getElementById('btn-add-banca');
if (btn) btn.classList.add('hidden');
}
}
function renumberBanks(){
const container = document.getElementById('banche-rows');
Array.from(container.children).forEach((card, i) => {
const title = card.querySelector('.netgescon-card-header strong');
if (title) title.textContent = 'Banca #'+(i+1);
});
updateIbanBadge();
const btn = document.getElementById('btn-add-banca');
if (btn) {
if (container.children.length >= 3) btn.classList.add('hidden'); else btn.classList.remove('hidden');
}
}
function clearBanks(){
const container = document.getElementById('banche-rows');
container.innerHTML = '';
const btn = document.getElementById('btn-add-banca');
if (btn) btn.classList.remove('hidden');
updateIbanBadge();
}
function submitBanche(e){
try{
const data = [];
document.querySelectorAll('#banche-rows .netgescon-card').forEach(card => {
const obj = {
legacy: {
nome_banca: card.querySelector('[data-field="legacy_nome_banca"]').value || '',
iban: card.querySelector('[data-field="legacy_iban"]').value || '',
swift: card.querySelector('[data-field="legacy_swift"]').value || '',
conto: card.querySelector('[data-field="legacy_conto"]').value || '',
intestatario: card.querySelector('[data-field="legacy_intestatario"]').value || '',
cod_cassa: card.querySelector('[data-field="legacy_cod_cassa"]').value || ''
},
target: {
nome_banca: card.querySelector('select[name^="banche"][name$="[nome_banca]"]').value || '',
iban: card.querySelector('select[name^="banche"][name$="[iban]"]').value || '',
swift: card.querySelector('select[name^="banche"][name$="[swift]"]').value || '',
conto: card.querySelector('select[name^="banche"][name$="[conto]"]').value || '',
intestatario: card.querySelector('select[name^="banche"][name$="[intestatario]"]').value || '',
cod_cassa: card.querySelector('select[name^="banche"][name$="[cod_cassa]"]').value || ''
}
};
// Codice cassa esplicito associato a questa banca (es. CCB, CDL); viene salvato in target
const tc = card.querySelector('[data-field="target_cod_cassa"]').value || '';
if (tc) obj.target.codice_cassa = tc.toUpperCase().trim();
// ignora righe completamente vuote
if (Object.values(obj.legacy).join('').trim() === '' && Object.values(obj.target).join('').trim() === '') return;
data.push(obj);
});
// opzionale: marca il primo come nostro conto
try{ if (document.getElementById('markNostroConto').checked && data[0]) data[0].target.is_nostro_conto = true; }catch(e){}
document.getElementById('banche_mapping').value = JSON.stringify(data);
return true;
}catch(err){
alert('Errore nella preparazione del mapping banche');
e.preventDefault();
return false;
}
}
function escapeHtml(s){
return String(s).replaceAll('&','&amp;').replaceAll('<','&lt;').replaceAll('>','&gt;').replaceAll('"','&quot;').replaceAll("'",'&#39;');
}
document.addEventListener('DOMContentLoaded', function(){
// Pre-popola 3 slot fissi: BANCA 1/2/3 o dati salvati
try{
const saved = @json(optional(\App\Models\GesconImportMapping::where('user_id', auth()->id())->where('legacy_code', request('legacy_code'))->first())->meta['banche_mapping'] ?? []);
if (Array.isArray(saved) && saved.length){ saved.forEach(b => addBankRow(b)); }
else { addBankRow(); addBankRow(); addBankRow(); }
}catch(e){ addBankRow(); addBankRow(); addBankRow(); }
updateIbanBadge();
});
function updateIbanBadge(){
try{
const badge = document.getElementById('iban-unique-badge');
const ibans = Array.from(document.querySelectorAll('#banche-rows [data-field="legacy_iban"]'))
.map(i => (i.value || '').toUpperCase().replace(/\s+/g,'').trim())
.filter(v => v !== '');
const unique = Array.from(new Set(ibans));
if (unique.length > 0) {
badge.textContent = 'IBAN unici rilevati: ' + unique.length;
badge.classList.remove('hidden');
} else {
badge.classList.add('hidden');
}
}catch(e){ /* no-op */ }
}
</script>