feat(istruttoria UI): tabelle inline editabili, toggle check/reject, no-reload, allineamento ULA

Refactor completo della UI istruttore su pattern Excel-like dichiarato/verificato.

Editor schema bando (BandoRendicontazioneSchemaEdit):
- Nuovo dropdown 'Base di calcolo ammissibile' (imponibile/totale/regime-dependent)
- Nuovo Calendar 'Inizio periodo' accanto al period_start_rule esistente

IstruttoriaPratica — refactor totale:
- FATTURE: 1 sola DataTable con rowGroupMode='subheader' raggruppato per B1/B2/B3,
  header colorato per categoria con totali dichiarato/ammesso live
- Colonne inline editabili: 'Imponibile ammesso' con InputNumber + save onBlur.
  Stato auto-calcolato: = dichiarato -> AMMESSA; 0 < x < dichiarato -> PARZIALE;
  x == 0 -> RESPINTA
- Label dinamiche 'Imponibile' vs 'Totale' in base a use_taxable_only
- Riga espandibile (pi-chevron) con textarea note istruttore + dettaglio IVA/totale
- Toggle icon ✓: se AMMESSA -> PENDING; altrimenti -> AMMESSA
- Toggle icon ✗: se RESPINTA -> PENDING; altrimenti -> RESPINTA
- Tooltip dinamici 'Conferma' / 'Annulla conferma'
- Badge rosso automatico 'Data fuori periodo' su invoice_in_period=false

ULA: stesso pattern inline (FTE dichiarato vs FTE ammesso) con header-box
manuale SOPRA la DataTable (non rowGroupMode, un solo gruppo) e forzatura
tableStyle width:100% per allineamento perfetto con fatture.

Documenti: lista con toggle ✓ VALIDO ↔ PENDING, ✗ NON_VALIDO/SCADUTO via dialog.

Performance critica — NO FULL RELOAD su verify:
- saveInvoiceInline/saveUlaInline/quickVerifyDoc/saveDocNote ora fanno
  setBundle() con update locale della singola riga
- refreshGateOnly() ricarica solo il gate_check (totali) in background
- Eliminato il load() completo che faceva sfarfallare la pagina

Banner arancione automatico quando status=SUBMITTED: 'Pratica non presa in
carico' con CTA 'Prendi in carico'.

Bugfix:
- Rimossi import inutilizzati (InputText, isNil)
- Aggiunti import DataTable, Column

UX testata su NAPOLI SAS: 5 fatture 3 categorie, 2 ULA, 4 docs.
Totali si aggiornano live, toggle funzionanti, nessuno sfarfallio.
This commit is contained in:
BFLOWS Sandbox
2026-04-18 12:27:10 +02:00
parent 61cdfbd06b
commit 2268fd98f5
2 changed files with 493 additions and 257 deletions

View File

@@ -31,6 +31,12 @@ const IVA_REGIMES = [
{ value: 'ESENTE', label: 'Esente' }
];
const AMOUNT_BASIS_OPTIONS = [
{ value: 'imponibile_always', label: 'Solo imponibile (sempre)' },
{ value: 'imponibile_only_ordinario', label: 'Imponibile in ordinario, totale in forfettario' },
{ value: 'totale_always', label: 'Totale IVA inclusa (sempre)' }
];
const PERIOD_START_RULES = [
{ value: 'erogato_date', label: 'Data di erogazione del finanziamento' },
{ value: 'contract_signed_date', label: 'Data firma contratto' },
@@ -63,6 +69,7 @@ const schemaJsonToForm = (j) => {
amount_max: gate.amount_range?.max ?? 25000,
period_start: gate.period_start ? new Date(gate.period_start) : null,
period_end: gate.period_end ? new Date(gate.period_end) : null,
amount_basis: gate.amount_basis || (gate.iva_ordinario_imponibile_only === false ? 'totale_always' : 'imponibile_only_ordinario'),
period_start_rule: gate.period_start_rule ?? 'erogato_date',
iva_regimes_allowed: ivaAllowed,
iva_ordinario_imponibile_only: gate.iva_ordinario_imponibile_only ?? true,
@@ -128,6 +135,7 @@ const formToSchemaJson = (f, base = null) => {
period_start_rule: f.period_start_rule,
period_start: fmtDate(f.period_start),
period_end: fmtDate(f.period_end),
amount_basis: f.amount_basis,
require_at_least_one_invoice_per_nonzero_category: f.require_invoice_per_category,
require_ula_above_threshold: f.require_ula_above_threshold,
require_all_documents_resolved: f.require_all_documents_resolved
@@ -352,6 +360,16 @@ const BandoRendicontazioneSchemaEdit = () => {
dateFormat="dd/mm/yy" showIcon disabled={readOnly} />
</div>
</div>
<div className="appForm__field" style={{maxWidth: '600px'}}>
<label>{__('Base di calcolo ammissibile','gepafin')}</label>
<Dropdown value={form.amount_basis}
onChange={(e) => update({amount_basis: e.value})}
options={AMOUNT_BASIS_OPTIONS} disabled={readOnly} />
<small className="text-color-secondary">
{__("Determina su quale importo delle fatture si calcola la remissione. La norma del bando può prevedere regimi diversi.", 'gepafin')}
</small>
</div>
</div>
<div className="appPage__spacer"></div>