diff --git a/.gitignore b/.gitignore
index a639741..4b1191a 100644
--- a/.gitignore
+++ b/.gitignore
@@ -24,3 +24,9 @@ Thumbs.db
.vscode/
.idea/
credentials/
+
+# ANAF Monitor state files
+tools/anaf-monitor/hashes.json
+tools/anaf-monitor/versions.json
+tools/anaf-monitor/snapshots/
+tools/anaf-monitor/monitor.log
diff --git a/tools/anaf-monitor/bilant_compare/2025_vs_2024/RAPORT_2025_vs_2024.md b/.trash/bilant_compare/2025_vs_2024/RAPORT_2025_vs_2024.md
similarity index 100%
rename from tools/anaf-monitor/bilant_compare/2025_vs_2024/RAPORT_2025_vs_2024.md
rename to .trash/bilant_compare/2025_vs_2024/RAPORT_2025_vs_2024.md
diff --git a/tools/anaf-monitor/bilant_compare/2025_vs_2024/s1002_2024.xsd b/.trash/bilant_compare/2025_vs_2024/s1002_2024.xsd
similarity index 100%
rename from tools/anaf-monitor/bilant_compare/2025_vs_2024/s1002_2024.xsd
rename to .trash/bilant_compare/2025_vs_2024/s1002_2024.xsd
diff --git a/tools/anaf-monitor/bilant_compare/2025_vs_2024/s1002_2025.xsd b/.trash/bilant_compare/2025_vs_2024/s1002_2025.xsd
similarity index 100%
rename from tools/anaf-monitor/bilant_compare/2025_vs_2024/s1002_2025.xsd
rename to .trash/bilant_compare/2025_vs_2024/s1002_2025.xsd
diff --git a/tools/anaf-monitor/bilant_compare/RAPORT_DIFERENTE_2024_vs_2023.md b/.trash/bilant_compare/RAPORT_DIFERENTE_2024_vs_2023.md
similarity index 100%
rename from tools/anaf-monitor/bilant_compare/RAPORT_DIFERENTE_2024_vs_2023.md
rename to .trash/bilant_compare/RAPORT_DIFERENTE_2024_vs_2023.md
diff --git a/tools/anaf-monitor/bilant_compare/s1002_2023.xsd b/.trash/bilant_compare/s1002_2023.xsd
similarity index 100%
rename from tools/anaf-monitor/bilant_compare/s1002_2023.xsd
rename to .trash/bilant_compare/s1002_2023.xsd
diff --git a/tools/anaf-monitor/bilant_compare/s1002_2024.xsd b/.trash/bilant_compare/s1002_2024.xsd
similarity index 100%
rename from tools/anaf-monitor/bilant_compare/s1002_2024.xsd
rename to .trash/bilant_compare/s1002_2024.xsd
diff --git a/tools/anaf-monitor/bilant_compare/s1003_2023.xsd b/.trash/bilant_compare/s1003_2023.xsd
similarity index 100%
rename from tools/anaf-monitor/bilant_compare/s1003_2023.xsd
rename to .trash/bilant_compare/s1003_2023.xsd
diff --git a/tools/anaf-monitor/bilant_compare/s1003_2024.xsd b/.trash/bilant_compare/s1003_2024.xsd
similarity index 100%
rename from tools/anaf-monitor/bilant_compare/s1003_2024.xsd
rename to .trash/bilant_compare/s1003_2024.xsd
diff --git a/tools/anaf-monitor/bilant_compare/s1004_2023.xsd b/.trash/bilant_compare/s1004_2023.xsd
similarity index 100%
rename from tools/anaf-monitor/bilant_compare/s1004_2023.xsd
rename to .trash/bilant_compare/s1004_2023.xsd
diff --git a/tools/anaf-monitor/bilant_compare/s1004_2024.xsd b/.trash/bilant_compare/s1004_2024.xsd
similarity index 100%
rename from tools/anaf-monitor/bilant_compare/s1004_2024.xsd
rename to .trash/bilant_compare/s1004_2024.xsd
diff --git a/tools/anaf-monitor/bilant_compare/s1005_2023.xsd b/.trash/bilant_compare/s1005_2023.xsd
similarity index 100%
rename from tools/anaf-monitor/bilant_compare/s1005_2023.xsd
rename to .trash/bilant_compare/s1005_2023.xsd
diff --git a/tools/anaf-monitor/bilant_compare/s1005_2024.xsd b/.trash/bilant_compare/s1005_2024.xsd
similarity index 100%
rename from tools/anaf-monitor/bilant_compare/s1005_2024.xsd
rename to .trash/bilant_compare/s1005_2024.xsd
diff --git a/tools/anaf-monitor/bilant_compare/structura_2023.pdf b/.trash/bilant_compare/structura_2023.pdf
similarity index 100%
rename from tools/anaf-monitor/bilant_compare/structura_2023.pdf
rename to .trash/bilant_compare/structura_2023.pdf
diff --git a/tools/anaf-monitor/bilant_compare/structura_2024.pdf b/.trash/bilant_compare/structura_2024.pdf
similarity index 100%
rename from tools/anaf-monitor/bilant_compare/structura_2024.pdf
rename to .trash/bilant_compare/structura_2024.pdf
diff --git a/tools/anaf-monitor/monitor.py b/.trash/monitor.py
similarity index 100%
rename from tools/anaf-monitor/monitor.py
rename to .trash/monitor.py
diff --git a/tools/anaf-monitor/monitor.sh b/.trash/monitor.sh
similarity index 100%
rename from tools/anaf-monitor/monitor.sh
rename to .trash/monitor.sh
diff --git a/TOOLS.md b/TOOLS.md
index f621c5b..d64a786 100644
--- a/TOOLS.md
+++ b/TOOLS.md
@@ -153,8 +153,15 @@ memory_get path="memory/file.md" from=1 lines=50
- **Commit:** `python3 tools/git_commit.py --push`
### ANAF Monitor
-- **Script:** `python3 tools/anaf-monitor/monitor_v2.py`
-- **Monitorizează:** D100, D101, D200, D390, D406, situații financiare, E-Factura
+- **Script:** `python3 tools/anaf-monitor/monitor_v2.py` (v2.2)
+- **Job:** `anaf-monitor` (10:00 și 16:00 București, luni-vineri)
+- **Monitorizează:** D100, D101, D300, D390, D394, D205, D406, Bilanț 2025, situații financiare
+- **Funcții:**
+ - Hash detection - detectează ORICE schimbare pe pagină
+ - Version extraction - extrage date soft A/J (toate variantele: S1002, S1003, etc.)
+ - Text snapshots - salvează textul în `snapshots/*.txt`
+ - Diff - arată exact ce s-a modificat
+- **Output:** JSON cu changes + diff (dacă există)
### Google Calendar
- **Credentials:** `credentials/google-calendar.json` (OAuth client)
@@ -238,6 +245,7 @@ create_event(
| 01:00 | 03:00 | night-execute-late | #echo-work | Continuă execuția task-uri (run 2) |
| 03:00 | 05:00 | archive-tasks | #echo-work | Arhivează task-uri vechi |
| 06:00,17:00 | 08:00,19:00 | insights-extract | - | Extrage insights din memory/kb/ + actualizează tehnici-pauza.md |
+| 08:00,14:00 | 10:00,16:00 | anaf-monitor | #echo-work (doar alerte) | Verifică modificări ANAF (hash + diff) |
| 06:30 | 08:30 | morning-report | 📧 EMAIL | Raport dimineață - vezi [FLUX-JOBURI.md](memory/kb/projects/FLUX-JOBURI.md) |
| 07:00 | 09:00 | morning-coaching | #echo-self + 📧 | Gând + provocare → memory/kb/coaching/ |
| 07-17 | 09-19 | respiratie-orar | #echo-self | Pauze orare (skip dacă busy în calendar) |
diff --git a/dashboard/status.json b/dashboard/status.json
index 7ff789c..b3976e0 100644
--- a/dashboard/status.json
+++ b/dashboard/status.json
@@ -13,7 +13,7 @@
"ok": true,
"status": "OK",
"message": "Nicio modificare detectată",
- "lastCheck": "02 Feb 2026, 07:52",
+ "lastCheck": "03 Feb 2026, 21:39",
"changesCount": 0
}
}
\ No newline at end of file
diff --git a/dashboard/todos.json b/dashboard/todos.json
index 3611b44..cd54948 100644
--- a/dashboard/todos.json
+++ b/dashboard/todos.json
@@ -1,5 +1,5 @@
{
- "lastUpdated": "2026-02-03T07:00:00.000Z",
+ "lastUpdated": "2026-02-03T21:16:13.452Z",
"items": [
{
"id": "prov-2026-02-03",
@@ -8,8 +8,8 @@
"example": "Exemplu de umbră: 'Nu mă consider destul de deștept ca antreprenor' - asta e o parte pe care o ascunzi. Când o accepți ('ok, am și limite'), eliberezi energia pe care o consumi să o maschezi cu scuze sau evitare.",
"domain": "self",
"dueDate": "2026-02-03",
- "done": false,
- "doneAt": null,
+ "done": true,
+ "doneAt": "2026-02-03T21:16:13.452Z",
"source": "Zoltan Vereș - Umbrele Workshop",
"sourceUrl": "https://moltbot.tailf7372d.ts.net/echo/files.html#memory/kb/youtube/2026-02-02_zoltan-veres-umbrele-workshop-complet.md",
"createdAt": "2026-02-03T07:00:00.000Z"
@@ -28,4 +28,4 @@
"createdAt": "2026-02-02T09:00:00Z"
}
]
-}
+}
\ No newline at end of file
diff --git a/tools/anaf-monitor/hashes.json b/tools/anaf-monitor/hashes.json
deleted file mode 100644
index ea6d80b..0000000
--- a/tools/anaf-monitor/hashes.json
+++ /dev/null
@@ -1,14 +0,0 @@
-{
- "D100": "10d051263016cb5ef71a883b7dc3b1d8d2f9ff29909740a74b729d3e980b6460",
- "D101": "937209d4785ca013cbcbe5a0d0aa8ba0e7033d3d8e6c121dadd8e38b20db8026",
- "D300": "0623da0873a893fc3b1635007a32059804d94b740ec606839f471b895e774c60",
- "D394": "c4c4e62bda30032f12c17edf9a5087b6173a350ccb1fd750158978b3bd0acb7d",
- "D406": "b3c621b61771d7b678b4bb0946a2f47434abbc332091c84de91e7dcb4effaab6",
- "SIT_FIN_SEM_2025": "8164843431e6b703a38fbdedc7898ec6ae83559fe10f88663ba0b55f3091d5fe",
- "SIT_FIN_AN_2025": "4294ca9271da15b9692c3efc126298fd3a89b0c68e0df9e2a256f50ad3d46b77",
- "DESCARCARE_DECLARATII": "d66297abcfc2b3ad87f65e4a60c97ddd0a889f493bb7e7c8e6035ef39d55ec3f",
- "D205": "f707104acc691cf79fbaa9a80c68bff4a285297f7dd3ab7b7a680715b54fd502",
- "D390": "4726938ed5858ec735caefd947a7d182b6dc64009478332c4feabdb36412a84e",
- "BILANT_2024": "fbb8d66c2e530d8798362992c6983e07e1250188228c758cb6da4cde4f955950",
- "BILANT_2025": "3d4e363b0f352e0b961474bca6bfa99ae44a591959210f7db8b10335f4ccede6"
-}
\ No newline at end of file
diff --git a/tools/anaf-monitor/monitor_v2.py b/tools/anaf-monitor/monitor_v2.py
index 4facbe3..8ee230e 100644
--- a/tools/anaf-monitor/monitor_v2.py
+++ b/tools/anaf-monitor/monitor_v2.py
@@ -1,21 +1,67 @@
#!/usr/bin/env python3
"""
-ANAF Monitor v2 - Extrage și compară versiuni soft A/J din numele fișierelor
+ANAF Monitor v2.2 - Hash detection + version extraction + text diff
+- Hash-based change detection (catches ANY change)
+- Extracts ALL soft A/J versions from page
+- Saves page text and shows diff on changes
"""
import json
import re
+import hashlib
import urllib.request
import ssl
+import difflib
from datetime import datetime
from pathlib import Path
+from html.parser import HTMLParser
SCRIPT_DIR = Path(__file__).parent
CONFIG_FILE = SCRIPT_DIR / "config.json"
VERSIONS_FILE = SCRIPT_DIR / "versions.json"
+HASHES_FILE = SCRIPT_DIR / "hashes.json"
+SNAPSHOTS_DIR = SCRIPT_DIR / "snapshots"
LOG_FILE = SCRIPT_DIR / "monitor.log"
DASHBOARD_STATUS = SCRIPT_DIR.parent.parent / "dashboard" / "status.json"
+# Ensure snapshots directory exists
+SNAPSHOTS_DIR.mkdir(exist_ok=True)
+
+
+class TextExtractor(HTMLParser):
+ """Extract visible text from HTML"""
+ def __init__(self):
+ super().__init__()
+ self.text = []
+ self.skip_tags = {'script', 'style', 'head', 'meta', 'link'}
+ self.current_tag = None
+
+ def handle_starttag(self, tag, attrs):
+ self.current_tag = tag.lower()
+
+ def handle_endtag(self, tag):
+ self.current_tag = None
+
+ def handle_data(self, data):
+ if self.current_tag not in self.skip_tags:
+ text = data.strip()
+ if text:
+ self.text.append(text)
+
+ def get_text(self):
+ return '\n'.join(self.text)
+
+
+def html_to_text(html):
+ """Convert HTML to plain text"""
+ parser = TextExtractor()
+ try:
+ parser.feed(html)
+ return parser.get_text()
+ except:
+ # Fallback: just strip tags
+ return re.sub(r'<[^>]+>', ' ', html)
+
SSL_CTX = ssl.create_default_context()
SSL_CTX.check_hostname = False
SSL_CTX.verify_mode = ssl.CERT_NONE
@@ -39,14 +85,58 @@ def save_json(path, data):
def fetch_page(url, timeout=30):
try:
req = urllib.request.Request(url, headers={
- 'User-Agent': 'Mozilla/5.0 (compatible; ANAF-Monitor/2.0)'
+ 'User-Agent': 'Mozilla/5.0 (compatible; ANAF-Monitor/2.1)'
})
with urllib.request.urlopen(req, timeout=timeout, context=SSL_CTX) as resp:
- return resp.read().decode('utf-8', errors='ignore')
+ return resp.read()
except Exception as e:
log(f"ERROR fetching {url}: {e}")
return None
+def compute_hash(content):
+ """Compute SHA256 hash of content"""
+ return hashlib.sha256(content).hexdigest()
+
+
+def load_snapshot(page_id):
+ """Load previous page text snapshot"""
+ snapshot_file = SNAPSHOTS_DIR / f"{page_id}.txt"
+ try:
+ return snapshot_file.read_text(encoding='utf-8')
+ except:
+ return None
+
+
+def save_snapshot(page_id, text):
+ """Save page text snapshot"""
+ snapshot_file = SNAPSHOTS_DIR / f"{page_id}.txt"
+ snapshot_file.write_text(text, encoding='utf-8')
+
+
+def generate_diff(old_text, new_text, context_lines=3):
+ """Generate unified diff between old and new text"""
+ if not old_text:
+ return None
+
+ old_lines = old_text.splitlines(keepends=True)
+ new_lines = new_text.splitlines(keepends=True)
+
+ diff = list(difflib.unified_diff(
+ old_lines, new_lines,
+ fromfile='anterior',
+ tofile='actual',
+ n=context_lines
+ ))
+
+ if not diff:
+ return None
+
+ # Limitează diff-ul la maxim 50 linii pentru output
+ if len(diff) > 50:
+ diff = diff[:50] + ['... (truncat)\n']
+
+ return ''.join(diff)
+
def parse_date_from_filename(filename):
"""Extrage data din numele fișierului (ex: D394_26092025.pdf -> 26.09.2025)"""
# Pattern: _DDMMYYYY. sau _DDMMYYYY_ sau _YYYYMMDD
@@ -69,10 +159,10 @@ def parse_date_from_filename(filename):
return None
def extract_versions(html):
- """Extrage primul soft A și soft J din HTML"""
+ """Extrage soft A/J din HTML - primul generic + toate cele cu label (S1002, etc.)"""
versions = {}
- # Găsește primul link soft A (PDF)
+ # Găsește PRIMUL link soft A (PDF) - versiunea curentă
soft_a_match = re.search(
r']+href=["\']([^"\']*\.pdf)["\'][^>]*>\s*soft\s*A\s*',
html, re.IGNORECASE
@@ -84,17 +174,33 @@ def extract_versions(html):
if date:
versions['soft_a_date'] = date
- # Găsește primul link soft J (ZIP)
- soft_j_match = re.search(
- r']+href=["\']([^"\']*\.zip)["\'][^>]*>\s*soft\s*J',
+ # Găsește soft J-uri CU LABEL (ex: "soft J - S1002") - toate
+ soft_j_labeled = re.findall(
+ r']+href=["\']([^"\']*\.zip)["\'][^>]*>\s*soft\s*J\s*-\s*([^<]+)',
html, re.IGNORECASE
)
- if soft_j_match:
- url = soft_j_match.group(1)
- versions['soft_j_url'] = url
- date = parse_date_from_filename(url)
- if date:
- versions['soft_j_date'] = date
+
+ if soft_j_labeled:
+ # Pagină cu soft-uri denumite (bilanț)
+ for url, label in soft_j_labeled:
+ label = label.strip()
+ key = f'soft_j_{label.replace(" ", "_")}'
+ versions[f'{key}_url'] = url
+ date = parse_date_from_filename(url)
+ if date:
+ versions[f'{key}_date'] = date
+ else:
+ # Pagină cu soft J simplu - ia doar primul
+ soft_j_match = re.search(
+ r']+href=["\']([^"\']*\.zip)["\'][^>]*>\s*soft\s*J',
+ html, re.IGNORECASE
+ )
+ if soft_j_match:
+ url = soft_j_match.group(1)
+ versions['soft_j_url'] = url
+ date = parse_date_from_filename(url)
+ if date:
+ versions['soft_j_date'] = date
# Găsește data publicării din text
publish_match = re.search(
@@ -106,71 +212,106 @@ def extract_versions(html):
return versions
-def format_date(d):
- """Formatează data pentru afișare"""
- if not d:
- return "N/A"
- return d
-
-def compare_versions(old, new, page_name):
+def compare_versions(old, new):
"""Compară versiunile și returnează diferențele"""
changes = []
- fields = [
- ('soft_a_date', 'Soft A'),
- ('soft_j_date', 'Soft J'),
- ('published', 'Publicat')
- ]
+ # Colectează toate cheile unice
+ all_keys = set(old.keys()) | set(new.keys())
+ date_keys = sorted([k for k in all_keys if k.endswith('_date') or k == 'published'])
- for field, label in fields:
- old_val = old.get(field)
- new_val = new.get(field)
+ for key in date_keys:
+ old_val = old.get(key)
+ new_val = new.get(key)
+
+ # Formatează label-ul
+ label = key.replace('_date', '').replace('_', ' ').title()
if new_val and old_val != new_val:
if old_val:
changes.append(f"{label}: {old_val} → {new_val}")
else:
- changes.append(f"{label}: {new_val} (nou)")
+ changes.append(f"{label}: {new_val} (NOU)")
return changes
-def check_page(page, saved_versions):
+def format_current_versions(versions):
+ """Formatează versiunile curente pentru output"""
+ result = {}
+ for key, val in versions.items():
+ if key.endswith('_date'):
+ label = key.replace('_date', '')
+ result[label] = val
+ return result
+
+def check_page(page, saved_versions, saved_hashes):
"""Verifică o pagină și returnează modificările"""
page_id = page["id"]
name = page["name"]
url = page["url"]
- html = fetch_page(url)
- if html is None:
+ content = fetch_page(url)
+ if content is None:
return None
+ # 1. Verifică hash-ul mai întâi (detectează ORICE schimbare)
+ new_hash = compute_hash(content)
+ old_hash = saved_hashes.get(page_id)
+
+ html = content.decode('utf-8', errors='ignore')
+ new_text = html_to_text(html)
new_versions = extract_versions(html)
old_versions = saved_versions.get(page_id, {})
- # Prima rulare - doar salvează, nu raportează
- if not old_versions:
- log(f"INIT: {page_id} - {new_versions}")
+ # Încarcă snapshot-ul anterior
+ old_text = load_snapshot(page_id)
+
+ # Prima rulare - inițializare
+ if not old_hash:
+ log(f"INIT: {page_id}")
+ saved_hashes[page_id] = new_hash
saved_versions[page_id] = new_versions
+ save_snapshot(page_id, new_text)
return None
- changes = compare_versions(old_versions, new_versions, name)
- saved_versions[page_id] = new_versions
+ # Compară hash-uri
+ hash_changed = new_hash != old_hash
- if changes:
- log(f"CHANGES in {page_id}: {changes}")
- return {
+ # Compară versiuni pentru detalii
+ version_changes = compare_versions(old_versions, new_versions)
+
+ # Generează diff dacă s-a schimbat
+ diff = None
+ if hash_changed and old_text:
+ diff = generate_diff(old_text, new_text)
+
+ # Actualizează starea
+ saved_hashes[page_id] = new_hash
+ saved_versions[page_id] = new_versions
+ save_snapshot(page_id, new_text)
+
+ if hash_changed:
+ if version_changes:
+ log(f"CHANGES in {page_id}: {version_changes}")
+ else:
+ log(f"HASH CHANGED in {page_id} (no version changes detected)")
+ version_changes = ["Pagina s-a modificat (vezi diff)"]
+
+ result = {
"id": page_id,
"name": name,
"url": url,
- "changes": changes,
- "current": {
- "soft_a": new_versions.get('soft_a_date', 'N/A'),
- "soft_j": new_versions.get('soft_j_date', 'N/A')
- }
+ "changes": version_changes,
+ "current": format_current_versions(new_versions)
}
- else:
- log(f"OK: {page_id}")
- return None
+
+ if diff:
+ result["diff"] = diff
+
+ return result
+
+ log(f"OK: {page_id}")
+ return None
def update_dashboard_status(has_changes, changes_count):
"""Actualizează status.json pentru dashboard"""
@@ -188,18 +329,20 @@ def update_dashboard_status(has_changes, changes_count):
log(f"ERROR updating dashboard status: {e}")
def main():
- log("=== Starting ANAF monitor v2 ===")
+ log("=== Starting ANAF monitor v2.1 ===")
config = load_json(CONFIG_FILE, {"pages": []})
saved_versions = load_json(VERSIONS_FILE, {})
+ saved_hashes = load_json(HASHES_FILE, {})
all_changes = []
for page in config["pages"]:
- result = check_page(page, saved_versions)
+ result = check_page(page, saved_versions, saved_hashes)
if result:
all_changes.append(result)
save_json(VERSIONS_FILE, saved_versions)
+ save_json(HASHES_FILE, saved_hashes)
# Update dashboard status
update_dashboard_status(len(all_changes) > 0, len(all_changes))
diff --git a/tools/anaf-monitor/versions.json b/tools/anaf-monitor/versions.json
deleted file mode 100644
index 5f44e70..0000000
--- a/tools/anaf-monitor/versions.json
+++ /dev/null
@@ -1,57 +0,0 @@
-{
- "D100": {
- "soft_a_url": "http://static.anaf.ro/static/10/Anaf/Declaratii_R/AplicatiiDec/D100_710_XML_0126_260126.pdf",
- "soft_a_date": "26.01.2026",
- "soft_j_url": "http://static.anaf.ro/static/10/Anaf/Declaratii_R/AplicatiiDec/D100_22012026.zip",
- "soft_j_date": "22.01.2026"
- },
- "D101": {
- "soft_a_url": "https://static.anaf.ro/static/10/Anaf/Declaratii_R/AplicatiiDec/D101_XML_2025_260126.pdf",
- "soft_a_date": "26.01.2026",
- "soft_j_url": "https://static.anaf.ro/static/10/Anaf/Declaratii_R/AplicatiiDec/D101_J1102.zip"
- },
- "D300": {
- "soft_a_url": "https://static.anaf.ro/static/10/Anaf/Declaratii_R/AplicatiiDec/D300_v11.0.7_16122025.pdf",
- "soft_a_date": "16.12.2025",
- "soft_j_url": "https://static.anaf.ro/static/10/Anaf/Declaratii_R/AplicatiiDec/D300_20250910.zip",
- "soft_j_date": "10.09.2025"
- },
- "D390": {
- "soft_a_url": "https://static.anaf.ro/static/10/Anaf/Declaratii_R/AplicatiiDec/D390_XML_2020_300424.pdf",
- "soft_a_date": "30.04.2024",
- "soft_j_url": "https://static.anaf.ro/static/10/Anaf/Declaratii_R/AplicatiiDec/D390_20250625.zip",
- "soft_j_date": "25.06.2025"
- },
- "D394": {
- "soft_a_url": "https://static.anaf.ro/static/10/Anaf/Declaratii_R/AplicatiiDec/D394_26092025.pdf",
- "soft_a_date": "26.09.2025",
- "soft_j_url": "https://static.anaf.ro/static/10/Anaf/Declaratii_R/AplicatiiDec/D394_17092025.zip",
- "soft_j_date": "17.09.2025"
- },
- "D205": {
- "soft_a_url": "https://static.anaf.ro/static/10/Anaf/Declaratii_R/AplicatiiDec/D205_XML_2025_150126.pdf",
- "soft_a_date": "15.01.2026",
- "soft_j_url": "https://static.anaf.ro/static/10/Anaf/Declaratii_R/AplicatiiDec/D205_J901_P400.zip"
- },
- "D406": {
- "soft_a_url": "https://static.anaf.ro/static/10/Anaf/Declaratii_R/AplicatiiDec/R405_XML_2017_080321.pdf",
- "soft_a_date": "08.03.2021",
- "soft_j_url": "https://static.anaf.ro/static/10/Anaf/Declaratii_R/AplicatiiDec/D406_20251030.zip",
- "soft_j_date": "30.10.2025"
- },
- "BILANT_2025": {
- "soft_a_url": "https://static.anaf.ro/static/10/Anaf/Declaratii_R/AplicatiiDec/bilant_SC_1225_XML_270126.pdf",
- "soft_a_date": "27.01.2026",
- "soft_j_url": "https://static.anaf.ro/static/10/Anaf/Declaratii_R/AplicatiiDec/S1002_20260128.zip",
- "soft_j_date": "28.01.2026"
- },
- "SIT_FIN_SEM_2025": {
- "soft_j_url": "https://static.anaf.ro/static/10/Anaf/Declaratii_R/AplicatiiDec/S1012_20250723.zip",
- "soft_j_date": "23.07.2025"
- },
- "SIT_FIN_AN_2025": {
- "soft_a_url": "https://static.anaf.ro/static/10/Anaf/Declaratii_R/AplicatiiDec/bilant_S1030_XML_consolidare_270126_bis.pdf",
- "soft_a_date": "27.01.2026"
- },
- "DESCARCARE_DECLARATII": {}
-}
\ No newline at end of file