← Files VeraARCHIVED FILE
modules/bilancio-xbrl-it/scripts/accounts_preview_text.py
14.2 KB · Oct 2, 2026 · 00:29 UTC
"""Translate fixed workflow wording without rewriting case-specific judgments."""
from __future__ import annotations
import re
from typing import Any, Mapping
__all__ = ["preview_text", "preview_check_message", "preview_reason"]
# Exact source strings make a changed rule-pack question visible to the release
# check. This is UI localization, not a classifier or a substitute for review.
_ITALIAN = {
"Accounting policies applied": "Criteri di valutazione applicati",
"Current approved accounting-policy schedule": "Prospetto corrente dei criteri di valutazione approvati",
"Allocation of profit or coverage of loss": "Destinazione dell’utile o copertura della perdita",
"Resolution or proposed allocation": "Delibera o proposta di destinazione del risultato",
"Basis and form of preparation": "Criteri generali e forma del bilancio",
"Approved form decision and accounting-policy evidence": "Scelta della forma approvata e documentazione dei criteri di valutazione",
"Changes in accounting policies": "Cambiamenti nei criteri di valutazione",
"Explicit annual confirmation and policy-change evidence where applicable": "Conferma annuale esplicita e documentazione degli eventuali cambiamenti nei criteri",
"Contingent liabilities": "Passività potenziali",
"Legal claims register or explicit annual confirmation": "Prospetto dei contenziosi o conferma annuale esplicita",
"Corrections of material prior-period errors": "Correzioni di errori rilevanti di esercizi precedenti",
"Explicit annual confirmation and correction schedule where applicable": "Conferma annuale esplicita e prospetto delle eventuali correzioni",
"Current and deferred taxes": "Imposte correnti, anticipate e differite",
"Tax computation": "Calcolo delle imposte",
"Debts by maturity and security": "Debiti per scadenza e garanzie",
"Loan plans or payable maturity schedule": "Piani di rimborso o scadenziario dei debiti",
"December 2025 OIC amendments review": "Revisione degli emendamenti OIC di dicembre 2025",
"Professional applicability assessment for each amended standard, or an explicit not-applicable reason": "Valutazione professionale dell’applicabilità di ogni principio modificato o motivazione esplicita della non applicabilità",
"Derivatives and fair-value reserve": "Derivati e riserva di fair value",
"Contracts, valuations, or explicit annual confirmation": "Contratti, valutazioni o conferma annuale esplicita",
"Employees and corporate bodies": "Dipendenti e organi sociali",
"Payroll and compensation schedules": "Prospetti del personale e dei compensi",
"Finance leases": "Leasing finanziari",
"Lease contracts and schedules": "Contratti e prospetti dei leasing",
"Fixed-asset movements and impairment": "Movimenti e perdite durevoli di valore delle immobilizzazioni",
"Fixed-asset register and ledger detail": "Registro dei cespiti e dettaglio contabile",
"Going-concern uncertainties": "Incertezze sulla continuità aziendale",
"Explicit annual confirmation and assessment where triggered": "Conferma annuale esplicita e valutazione quando richiesta dal caso",
"Group and participation information": "Informazioni su gruppo e partecipazioni",
"Participation and group schedule": "Prospetto delle partecipazioni e del gruppo",
"Guarantees and commitments": "Garanzie e impegni",
"Register or explicit annual confirmation": "Registro o conferma annuale esplicita",
"Inventory movements and valuation evidence": "Movimenti delle rimanenze e documentazione della valutazione",
"Inventory ledger, count or alternative procedures, costing records, net-realisable-value and obsolescence assessments, and pledge evidence": "Contabilità di magazzino, inventario fisico o procedure alternative, calcolo dei costi, valutazioni del valore netto di realizzo e dell’obsolescenza, documentazione dei pegni",
"Material post-closing events": "Fatti rilevanti successivi alla chiusura",
"Explicit annual confirmation": "Conferma annuale esplicita",
"OIC 34 revenue-recognition review": "Revisione della rilevazione dei ricavi secondo OIC 34",
"Professional OIC 34 assessment and material contract review, or an explicit not-applicable reason": "Valutazione professionale OIC 34 e revisione dei contratti rilevanti o motivazione esplicita della non applicabilità",
"Off-balance-sheet arrangements": "Accordi non risultanti dallo stato patrimoniale",
"Contract register or explicit annual confirmation": "Registro dei contratti o conferma annuale esplicita",
"Other triggered statutory disclosures": "Altre informazioni civilistiche richieste dal caso",
"Topic-specific supporting schedules": "Prospetti di supporto relativi alla materia",
"Provisions and TFR movements": "Movimenti dei fondi e del TFR",
"Provisions and payroll/TFR schedules": "Prospetti dei fondi, del personale e del TFR",
"Receivable maturity and geography": "Scadenze e distribuzione geografica dei crediti",
"Receivable aging or maturity schedule": "Scadenziario o analisi dell’anzianità dei crediti",
"Related-party transactions": "Operazioni con parti correlate",
"Related-party schedule and explicit confirmation": "Prospetto delle parti correlate e conferma esplicita",
"Revenue and significant income-statement details": "Ricavi e dettagli rilevanti del conto economico",
"Revenue and ledger analysis": "Analisi dei ricavi e dei mastri contabili",
"Substantive taxonomy representation differences": "Differenze sostanziali nella rappresentazione tassonomica",
"Explicit annual confirmation and differences analysis where applicable": "Conferma annuale esplicita e analisi delle eventuali differenze",
"Transactions not concluded on market terms": "Operazioni non concluse a condizioni di mercato",
"Explicit annual confirmation and transaction schedule where applicable": "Conferma annuale esplicita e prospetto delle eventuali operazioni",
"The micro footer-versus-notes treatment is not confirmed": "La scelta tra informazioni in calce e nota integrativa per la micro-impresa non è confermata",
"Current assets do not equal liabilities and equity": "Per l’esercizio corrente, l’attivo non coincide con il passivo e il patrimonio netto",
"Comparative assets do not equal liabilities and equity": "Per l’esercizio comparativo, l’attivo non coincide con il passivo e il patrimonio netto",
"Primary statutory taxonomy presentation coverage has not been reviewed": "La copertura delle voci dei prospetti civilistici non è stata rivista",
"An effective-dated disclosure rule pack has not been activated": "Non è stato attivato il pacchetto delle informazioni richieste valido per l’esercizio",
"The prior filed XBRL is not attached for comparative and opening checks": "Il precedente XBRL depositato non è allegato per i controlli comparativi e sui saldi iniziali",
"The debit/credit convention is not confirmed": "La convenzione Dare/Avere non è confermata",
"Statements have not been computed": "I prospetti non sono stati calcolati",
"A trial balance is required": "È necessaria una situazione contabile",
"Upload or enter source-backed schedule data": "Fornisci i dati del prospetto con i relativi riferimenti alle fonti",
"Accepted statement facts or the selected statutory form activate this supporting schedule.": "Le voci di bilancio riviste o la forma scelta richiedono questo prospetto di supporto.",
}
_SCHEDULES = {
"FIXED_ASSETS": "immobilizzazioni",
"INVENTORIES": "rimanenze",
"RECEIVABLES": "crediti",
"PAYABLES": "debiti",
"EQUITY": "patrimonio netto",
"PROVISIONS": "fondi",
"TFR": "trattamento di fine rapporto",
"TAXES": "imposte",
"GUARANTEES_COMMITMENTS": "garanzie e impegni",
"CASH_FLOW": "rendiconto finanziario",
}
_FLAGS = {
"EMPLOYEES_OR_BODIES_PRESENT": (
"dipendenti o organi sociali",
"employees or corporate bodies",
),
"FINANCE_LEASES_PRESENT": ("leasing finanziari", "finance leases"),
"GROUP_OR_PARTICIPATIONS_PRESENT": (
"gruppo o partecipazioni",
"group or participations",
),
"OTHER_STATUTORY_DISCLOSURES_REQUIRED": (
"altre informazioni civilistiche",
"other statutory disclosures",
),
"REVENUE_OR_EXCEPTIONAL_DETAIL_REQUIRED": (
"ricavi o componenti eccezionali",
"revenue or exceptional items",
),
}
_SECTIONS = {
"INTRODUCTION": ("introduzione alla nota", "introduction to the notes"),
"POLICIES": ("criteri di valutazione", "accounting policies"),
"COMMITMENTS_RELATED": (
"impegni e rapporti correlati",
"commitments and related matters",
),
"POST_CLOSING_GOING_CONCERN": (
"fatti successivi e continuità aziendale",
"subsequent events and going concern",
),
"ADDITIONAL": ("ulteriori informazioni", "additional information"),
}
def preview_text(value: Any, language: str) -> str:
"""Translate only an exact fixed string; retain unknown and authored text."""
text = "—" if value is None else str(value)
if language == "it":
required = re.fullmatch(r"Provide the required (\w+) schedule", text)
if required and required[1].upper() in _SCHEDULES:
return "Fornisci il prospetto richiesto: " + _SCHEDULES[required[1].upper()]
return _ITALIAN.get(text, text) if language == "it" else text
def preview_reason(value: Any, language: str) -> str:
"""Localize the disclosure engine's exact reason formats, retaining prose."""
reason = "—" if value is None else str(value)
if reason in _ITALIAN:
return preview_text(reason, language)
locale = 0 if language == "it" else 1
schedules = {
"FIXED_ASSETS": ("immobilizzazioni", "fixed assets"),
"INVENTORIES": ("rimanenze", "inventories"),
"RECEIVABLES": ("crediti", "receivables"),
"PAYABLES": ("debiti", "payables"),
"EQUITY": ("patrimonio netto", "equity"),
"PROVISIONS": ("fondi", "provisions"),
"TFR": ("trattamento di fine rapporto", "severance pay"),
"TAXES": ("imposte", "taxes"),
"GUARANTEES_COMMITMENTS": ("garanzie e impegni", "guarantees and commitments"),
"CASH_FLOW": ("rendiconto finanziario", "cash flow"),
}
translated = []
for part in reason.split("; "):
if part == "always applicable for the selected form":
translated.append(
(
"Richiesto per la forma di bilancio scelta",
"Required for the selected statutory form",
)[locale]
)
continue
schedule = re.fullmatch(
r"schedule (\w+) is present or reviewer-triggered", part
)
if schedule and schedule[1] in schedules:
subject = schedules[schedule[1]][locale]
translated.append(
(
f"Prospetto presente o richiesto dal revisore: {subject}"
if locale == 0
else f"Schedule present or requested by the reviewer: {subject}"
)
)
continue
flag = re.fullmatch(r"reviewer trigger (\w+)", part)
if flag and flag[1] in _FLAGS:
subject = _FLAGS[flag[1]][locale]
translated.append(
(
f"Informazione richiesta dal revisore: {subject}"
if locale == 0
else f"Disclosure requested by the reviewer: {subject}"
)
)
continue
line = re.fullmatch(r"statement line (.+) is non-zero", part)
if line:
translated.append(
(
f"La voce {line[1]} ha un importo diverso da zero"
if locale == 0
else f"Statement item {line[1]} has a non-zero amount"
)
)
continue
return reason
return "; ".join(translated)
def preview_check_message(
issue: Mapping[str, Any], case: Mapping[str, Any], language: str
) -> str:
"""Display known native message formats with their exact declared subjects."""
message = str(issue.get("message") or "")
locale = 0 if language == "it" else 1
schedule_prefix = "Required schedules are missing: "
if language == "it" and message.startswith(schedule_prefix):
subjects = message[len(schedule_prefix) :].split(", ")
return "Mancano i prospetti richiesti: " + ", ".join(
_SCHEDULES.get(subject, subject) for subject in subjects
)
count = re.fullmatch(r"(\d+) annual negative confirmations are missing", message)
if count:
return (
f"Mancano {count[1]} conferme annuali sull’assenza delle fattispecie richieste"
if language == "it"
else f"{count[1]} annual confirmations of absence are missing"
)
manual_prefix = "Disclosure applicability requires professional decisions for: "
if message.startswith(manual_prefix):
flags = message[len(manual_prefix) :].split(", ")
subjects = [_FLAGS.get(flag, (flag, flag))[locale] for flag in flags]
prefix = (
"Occorre una decisione professionale sulle informazioni applicabili a: "
if language == "it"
else "Professional decisions are needed on disclosures for: "
)
return prefix + "; ".join(subjects)
missing_prefix = "Triggered disclosure is incomplete: "
if message.startswith(missing_prefix):
answers = {
str(q.get("answer_key")): str(q.get("title"))
for q in case.get("questionnaire", [])
if q.get("answer_key") and q.get("title")
}
subjects = []
for item in message[len(missing_prefix) :].split(", "):
kind, separator, key = item.partition(":")
if separator and kind == "ANSWER" and key in answers:
subjects.append(preview_text(answers[key], language))
elif separator and kind == "NARRATIVE_SECTION" and key in _SECTIONS:
subjects.append(_SECTIONS[key][locale])
else:
subjects.append(item)
prefix = "Da completare: " if language == "it" else "To complete: "
return prefix + "; ".join(subjects)
return preview_text(message, language)
SHA-256: f9324e3158dd90e6f09d5d99a4aa095762538b3e585d006703caaeced3e7515e