feat(istruttoria): verifica riga-per-riga con dual declared/verified
Replica il workflow del foglio Excel originale (REMISSIONE_DEL_DEBITO_5888.xlsm).
Istruttore ora verifica ogni fattura, ogni dipendente ULA, ogni documento singolarmente
invece di accettare/respingere la pratica intera.
Modello dati - nuove colonne su 3 tabelle:
- remission_invoice: taxable_verified, vat_verified, total_verified,
verification_status (PENDING/AMMESSA/PARZIALE/RESPINTA), verification_notes,
date_checks (JSONB con invoice_in_period/payment_in_period), verified_by, verified_at
- remission_ula_employee: fte_pct_verified, verification_status, verification_notes,
verified_by, verified_at
- remission_document: verification_status (PENDING/VALIDO/NON_VALIDO/SCADUTO),
verification_notes, verified_by, verified_at
- remission_practice: instructor_final_notes, instructor_checklist (JSONB 3 gate SI/NO),
verbale_date
Nuovi endpoint:
- PUT /instructor/{id}/invoices/{inv_id}/verify (status + rettifica importi + note)
- PUT /instructor/{id}/ula-employees/{emp_id}/verify (rettifica FTE + note)
- PUT /instructor/{id}/documents/{doc_code}/verify (VALIDO/NON_VALIDO/SCADUTO + note)
- PUT /instructor/{id}/final-notes (note sintetiche + checklist)
Ricalcolo gate_check dual track:
- grand_total_declared: sempre (importo richiesto dal beneficiario)
- grand_total_verified: somma solo fatture AMMESSA/PARZIALE (se PARZIALE usa verified)
- remission_due: usa verified se any_verified=True, altrimenti declared (backward compat)
- residuo_da_restituire: amount_erogato - remission_due
- flag any_verified e all_verified per gating decisione finale
_auto_check_dates: fattura in periodo? pagamento in periodo?
Legge period_start e period_end da schema.gate_rules (superadmin editor).
Template: aggiunto period_start/period_end_date come campi 'editable_by superadmin'
nella sezione general static_fields.
Schema editor FE (BandoRendicontazioneSchemaEdit): aggiunto Calendar period_start
accanto a period_end in section gate rules. period_start_rule dropdown per logica
(erogato_date|fixed) resta; period_start data fissa usata dal check.
This commit is contained in:
@@ -67,6 +67,9 @@ class RemissionPractice(Base):
|
||||
reviewed_by = Column(Integer, nullable=True)
|
||||
rejection_reason = Column(Text, nullable=True)
|
||||
approved_remission = Column(Numeric(14, 2), nullable=True)
|
||||
instructor_final_notes = Column(Text, nullable=True)
|
||||
instructor_checklist = Column(JSONB, nullable=True, default=dict)
|
||||
verbale_date = Column(Date, nullable=True)
|
||||
|
||||
created_at = Column(DateTime(timezone=True), nullable=False, server_default=func.now())
|
||||
updated_at = Column(DateTime(timezone=True), nullable=False, server_default=func.now(), onupdate=func.now())
|
||||
@@ -101,6 +104,17 @@ class RemissionInvoice(Base):
|
||||
total = Column(Numeric(14, 2), nullable=False)
|
||||
pdf_filename = Column(String(512), nullable=True) # per ora solo nome, upload vero dopo
|
||||
|
||||
# Campi istruttoria (dual declared/verified)
|
||||
taxable_verified = Column(Numeric(14, 2), nullable=True)
|
||||
vat_verified = Column(Numeric(14, 2), nullable=True)
|
||||
total_verified = Column(Numeric(14, 2), nullable=True)
|
||||
verification_status = Column(String(16), nullable=False, default="PENDING")
|
||||
# PENDING | AMMESSA | PARZIALE | RESPINTA
|
||||
verification_notes = Column(Text, nullable=True)
|
||||
date_checks = Column(JSONB, nullable=True, default=dict)
|
||||
verified_by = Column(Integer, nullable=True)
|
||||
verified_at = Column(DateTime(timezone=True), nullable=True)
|
||||
|
||||
created_at = Column(DateTime(timezone=True), nullable=False, server_default=func.now())
|
||||
|
||||
practice = relationship("RemissionPractice", back_populates="invoices")
|
||||
@@ -127,6 +141,13 @@ class RemissionUlaEmployee(Base):
|
||||
supporting_doc_type = Column(String(64), nullable=True)
|
||||
supporting_doc_filename = Column(String(512), nullable=True)
|
||||
|
||||
# Campi istruttoria
|
||||
fte_pct_verified = Column(Numeric(5, 4), nullable=True)
|
||||
verification_status = Column(String(16), nullable=False, default="PENDING")
|
||||
verification_notes = Column(Text, nullable=True)
|
||||
verified_by = Column(Integer, nullable=True)
|
||||
verified_at = Column(DateTime(timezone=True), nullable=True)
|
||||
|
||||
created_at = Column(DateTime(timezone=True), nullable=False, server_default=func.now())
|
||||
|
||||
practice = relationship("RemissionPractice", back_populates="ula_employees")
|
||||
@@ -148,6 +169,13 @@ class RemissionDocument(Base):
|
||||
expires_at = Column(Date, nullable=True)
|
||||
notes = Column(Text, nullable=True)
|
||||
|
||||
# Campi istruttoria
|
||||
verification_status = Column(String(16), nullable=False, default="PENDING")
|
||||
# PENDING | VALIDO | NON_VALIDO | SCADUTO
|
||||
verification_notes = Column(Text, nullable=True)
|
||||
verified_by = Column(Integer, nullable=True)
|
||||
verified_at = Column(DateTime(timezone=True), nullable=True)
|
||||
|
||||
practice = relationship("RemissionPractice", back_populates="documents")
|
||||
|
||||
|
||||
|
||||
Reference in New Issue
Block a user