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:
@@ -68,6 +68,15 @@ class InvoiceOut(InvoiceCreate):
|
||||
id: UUID
|
||||
practice_id: UUID
|
||||
created_at: datetime
|
||||
# istruttoria
|
||||
taxable_verified: Optional[Decimal] = None
|
||||
vat_verified: Optional[Decimal] = None
|
||||
total_verified: Optional[Decimal] = None
|
||||
verification_status: str = "PENDING"
|
||||
verification_notes: Optional[str] = None
|
||||
date_checks: Optional[dict] = None
|
||||
verified_by: Optional[int] = None
|
||||
verified_at: Optional[datetime] = None
|
||||
|
||||
model_config = {"from_attributes": True}
|
||||
|
||||
@@ -89,6 +98,12 @@ class UlaEmployeeOut(UlaEmployeeCreate):
|
||||
id: UUID
|
||||
practice_id: UUID
|
||||
created_at: datetime
|
||||
# istruttoria
|
||||
fte_pct_verified: Optional[Decimal] = None
|
||||
verification_status: str = "PENDING"
|
||||
verification_notes: Optional[str] = None
|
||||
verified_by: Optional[int] = None
|
||||
verified_at: Optional[datetime] = None
|
||||
|
||||
model_config = {"from_attributes": True}
|
||||
|
||||
@@ -110,6 +125,11 @@ class DocumentOut(BaseModel):
|
||||
uploaded_at: Optional[datetime] = None
|
||||
expires_at: Optional[date] = None
|
||||
notes: Optional[str] = None
|
||||
# istruttoria
|
||||
verification_status: str = "PENDING"
|
||||
verification_notes: Optional[str] = None
|
||||
verified_by: Optional[int] = None
|
||||
verified_at: Optional[datetime] = None
|
||||
|
||||
model_config = {"from_attributes": True}
|
||||
|
||||
@@ -130,6 +150,16 @@ class PracticeOut(BaseModel):
|
||||
updated_at: datetime
|
||||
submitted_at: Optional[datetime] = None
|
||||
|
||||
# istruttoria
|
||||
assigned_instructor_id: Optional[int] = None
|
||||
reviewed_at: Optional[datetime] = None
|
||||
reviewed_by: Optional[int] = None
|
||||
rejection_reason: Optional[str] = None
|
||||
approved_remission: Optional[Decimal] = None
|
||||
instructor_final_notes: Optional[str] = None
|
||||
instructor_checklist: Optional[dict] = None
|
||||
verbale_date: Optional[date] = None
|
||||
|
||||
invoices: List[InvoiceOut] = []
|
||||
ula_employees: List[UlaEmployeeOut] = []
|
||||
documents: List[DocumentOut] = []
|
||||
@@ -223,6 +253,35 @@ class InstructorQueueItem(BaseModel):
|
||||
model_config = {"from_attributes": True}
|
||||
|
||||
|
||||
|
||||
# Verifica singola fattura
|
||||
class InvoiceVerifyBody(BaseModel):
|
||||
verification_status: str # AMMESSA | PARZIALE | RESPINTA
|
||||
taxable_verified: Optional[Decimal] = None
|
||||
vat_verified: Optional[Decimal] = None
|
||||
total_verified: Optional[Decimal] = None
|
||||
verification_notes: Optional[str] = None
|
||||
|
||||
|
||||
# Verifica singolo dipendente ULA
|
||||
class UlaVerifyBody(BaseModel):
|
||||
verification_status: str # AMMESSA | PARZIALE | RESPINTA
|
||||
fte_pct_verified: Optional[Decimal] = None
|
||||
verification_notes: Optional[str] = None
|
||||
|
||||
|
||||
# Verifica singolo documento
|
||||
class DocumentVerifyBody(BaseModel):
|
||||
verification_status: str # VALIDO | NON_VALIDO | SCADUTO
|
||||
verification_notes: Optional[str] = None
|
||||
|
||||
|
||||
# Note finali istruttore + checklist
|
||||
class InstructorFinalNotesBody(BaseModel):
|
||||
instructor_final_notes: Optional[str] = None
|
||||
instructor_checklist: Optional[dict] = None
|
||||
|
||||
|
||||
# ====================== Wrapper ======================
|
||||
|
||||
class ApiResponse(BaseModel):
|
||||
|
||||
Reference in New Issue
Block a user