perioada luna anterioara finalizata

This commit is contained in:
2026-02-16 14:12:03 +02:00
parent bc05d02319
commit 85423cfe94
5 changed files with 299 additions and 157 deletions

View File

@@ -13,3 +13,7 @@ ORACLE_PASSWORD=PAROLA
# Output settings
OUTPUT_DIR=./output
COMPANY_NAME=Data Intelligence Report
# Reporting period end month (optional, default: previous complete month)
# Format: YYYY-MM. Example: 2026-01 means "report through January 2026"
# REPORT_END_MONTH=2026-01

View File

@@ -14,16 +14,42 @@ python -m venv .venv
source .venv/bin/activate # Linux/WSL
pip install -r requirements.txt
# Run report (default: last 12 months)
# Run report (default: last 12 months, previous complete month)
python main.py
# Custom period
# Custom period duration
python main.py --months 6
# Custom end month (report through January 2026)
python main.py --end-month 2026-01
# Combined: 6 months through December 2025
python main.py --months 6 --end-month 2025-12
# Docker alternative
docker-compose run --rm report-generator
```
## Configurable Reporting Period
**Default behavior**: Reports cover data through the **last complete month** (excludes current incomplete month).
- Example: If today is 2026-02-16, default reports data through 2026-01-31
**Override with CLI**:
```bash
python main.py --end-month 2026-01 # Report through January 2026
```
**Override with environment variable**:
```bash
export REPORT_END_MONTH=2026-01
python main.py
```
**Internals**: All SQL queries receive `:data_referinta` as an Oracle DATE bind variable (= first day of month AFTER end-month).
- Ensures consistent period boundaries across all queries (sales, balances, aging, etc.)
- YoY comparisons auto-adjust based on configured period
## Oracle Connection
| Environment | ORACLE_HOST value |

View File

@@ -26,6 +26,9 @@ def get_dsn():
OUTPUT_DIR = Path(os.getenv('OUTPUT_DIR', './output'))
COMPANY_NAME = os.getenv('COMPANY_NAME', 'Data Intelligence Report')
# Reporting period - end month (YYYY-MM format, default: previous complete month)
REPORT_END_MONTH = os.getenv('REPORT_END_MONTH', None)
# Ensure output directory exists
OUTPUT_DIR.mkdir(parents=True, exist_ok=True)

68
main.py
View File

@@ -48,11 +48,12 @@ check_dependencies()
import oracledb
import pandas as pd
from dateutil.relativedelta import relativedelta
from datetime import timedelta
from config import (
ORACLE_CONFIG, get_dsn, OUTPUT_DIR, COMPANY_NAME,
ANALYSIS_MONTHS, MIN_SALES_FOR_ANALYSIS, LOW_MARGIN_THRESHOLD,
RECOMMENDATION_THRESHOLDS
RECOMMENDATION_THRESHOLDS, REPORT_END_MONTH
)
from queries import QUERIES
from report_generator import (
@@ -279,6 +280,41 @@ class PerformanceLogger:
print(f"\n📝 Log saved to: {log_file}")
def compute_data_referinta(end_month_str: str = None) -> datetime:
"""
Compute reference date (first day of month AFTER the last reporting month).
If end_month_str is None: default to first day of current month
(i.e., report through end of previous month).
If end_month_str is 'YYYY-MM': parse it and return first day of next month.
"""
if end_month_str:
parsed = datetime.strptime(end_month_str, '%Y-%m')
if parsed.month == 12:
return datetime(parsed.year + 1, 1, 1)
else:
return datetime(parsed.year, parsed.month + 1, 1)
else:
today = datetime.now()
return datetime(today.year, today.month, 1)
def resolve_dynamic_tables(sql: str, data_referinta: datetime, months: int = 12) -> str:
"""
Replace vjv2025/vjc2025 with correct year (or UNION ALL if spanning years).
"""
end_year = (data_referinta - timedelta(days=1)).year
start_year = (data_referinta - relativedelta(months=months)).year
if start_year == end_year:
sql = sql.replace('vjv2025', f'vjv{end_year}')
sql = sql.replace('vjc2025', f'vjc{end_year}')
else:
sql = sql.replace('vjv2025', f'(SELECT * FROM vjv{start_year} UNION ALL SELECT * FROM vjv{end_year})')
sql = sql.replace('vjc2025', f'(SELECT * FROM vjc{start_year} UNION ALL SELECT * FROM vjc{end_year})')
return sql
class OracleConnection:
"""Context manager for Oracle database connection"""
@@ -316,6 +352,11 @@ def execute_query(connection, query_name: str, query_info: dict) -> pd.DataFrame
sql = query_info['sql']
params = query_info.get('params', {})
# Resolve dynamic table names (vjv/vjc year-specific tables)
if 'data_referinta' in params:
months = params.get('months', 12)
sql = resolve_dynamic_tables(sql, params['data_referinta'], months)
print(f" 📊 Executare: {query_name}...", end=" ")
with connection.cursor() as cursor:
@@ -339,22 +380,26 @@ def generate_reports(args):
excel_path = OUTPUT_DIR / f"data_intelligence_report_{timestamp}.xlsx"
pdf_path = OUTPUT_DIR / f"data_intelligence_report_{timestamp}.pdf"
# Compute reference date
data_referinta = compute_data_referinta(args.end_month)
end_date = data_referinta - timedelta(days=1) # last day of reporting period
start_date = data_referinta - relativedelta(months=args.months)
period_str = f"Perioada: {start_date.strftime('%d.%m.%Y')} - {end_date.strftime('%d.%m.%Y')}"
print("\n" + "="*60)
print(" DATA INTELLIGENCE REPORT GENERATOR")
print("="*60)
print(f" Perioada: Ultimele {args.months} luni")
print(f" {period_str} ({args.months} luni)")
print(f" Output: {OUTPUT_DIR}")
print("="*60 + "\n")
# Update parameters with command line arguments
# Update parameters with command line arguments and inject data_referinta
for query_info in QUERIES.values():
if 'months' in query_info.get('params', {}):
query_info['params']['months'] = args.months
# Calculate reporting period string
end_date = datetime.now()
start_date = end_date - relativedelta(months=args.months)
period_str = f"Perioada: {start_date.strftime('%d.%m.%Y')} - {end_date.strftime('%d.%m.%Y')}"
# Inject data_referinta into ALL queries
query_info.setdefault('params', {})
query_info['params']['data_referinta'] = data_referinta
# Add period to descriptions for queries with months parameter
for query_name, query_info in QUERIES.items():
@@ -1102,6 +1147,13 @@ Exemple:
help=f'Numărul de luni pentru analiză (default: {ANALYSIS_MONTHS})'
)
parser.add_argument(
'--end-month', '-e',
type=str,
default=REPORT_END_MONTH,
help='Luna finala de raportare YYYY-MM (default: luna completa anterioara). Ex: 2026-01'
)
parser.add_argument(
'--output-dir', '-o',
type=Path,

View File

@@ -33,7 +33,8 @@ LEFT JOIN nom_parteneri p ON f.id_part = p.id_part
WHERE f.sters = 0
AND f.tip > 0
AND f.tip NOT IN (7, 8, 9, 24)
AND f.data_act >= ADD_MONTHS(TRUNC(SYSDATE, 'MM'), -:months)
AND f.data_act >= ADD_MONTHS(:data_referinta, -:months)
AND f.data_act < :data_referinta
GROUP BY f.id_part, p.denumire, p.cod_fiscal
ORDER BY marja_bruta DESC
"""
@@ -58,7 +59,8 @@ SELECT * FROM (
LEFT JOIN nom_parteneri p ON f.id_part = p.id_part
WHERE f.sters = 0
AND f.tip > 0 AND f.tip NOT IN (7, 8, 9, 24)
AND f.data_act >= ADD_MONTHS(TRUNC(SYSDATE, 'MM'), -:months)
AND f.data_act >= ADD_MONTHS(:data_referinta, -:months)
AND f.data_act < :data_referinta
GROUP BY f.id_part, p.denumire, p.cod_fiscal
HAVING SUM(d.cantitate * CASE WHEN d.pret_cu_tva = 1 THEN d.pret / (1 + d.proc_tvav/100) ELSE d.pret END) > :min_sales
)
@@ -88,7 +90,8 @@ LEFT JOIN nom_articole art ON d.id_articol = art.id_articol
LEFT JOIN vgest_art_sbgr sg ON art.id_subgrupa = sg.id_subgrupa
WHERE f.sters = 0
AND f.tip > 0 AND f.tip NOT IN (7, 8, 9, 24)
AND f.data_act >= ADD_MONTHS(TRUNC(SYSDATE, 'MM'), -:months)
AND f.data_act >= ADD_MONTHS(:data_referinta, -:months)
AND f.data_act < :data_referinta
GROUP BY sg.id_grupa, sg.grupa, art.id_subgrupa, sg.subgrupa
ORDER BY vanzari_fara_tva DESC
"""
@@ -115,7 +118,8 @@ FROM vanzari f
JOIN vanzari_detalii d ON d.id_vanzare = f.id_vanzare AND d.sters = 0
WHERE f.sters = 0
AND f.tip > 0 AND f.tip NOT IN (7, 8, 9, 24)
AND f.data_act >= ADD_MONTHS(TRUNC(SYSDATE, 'MM'), -:months)
AND f.data_act >= ADD_MONTHS(:data_referinta, -:months)
AND f.data_act < :data_referinta
GROUP BY CASE
WHEN d.cont IN ('341', '345') THEN 'Producție proprie'
WHEN d.cont = '301' THEN 'Materii prime'
@@ -145,7 +149,8 @@ WITH preturi_detalii AS (
LEFT JOIN gest_art_sbgr g ON a.id_subgrupa = g.id_subgrupa
WHERE f.sters = 0
AND f.tip > 0 AND f.tip NOT IN (7, 8, 9, 24)
AND f.data_act >= ADD_MONTHS(TRUNC(SYSDATE), -:months)
AND f.data_act >= ADD_MONTHS(:data_referinta, -:months)
AND f.data_act < :data_referinta
AND d.pret > 0
)
SELECT
@@ -184,7 +189,8 @@ WITH base_prices AS (
JOIN NOM_PARTENERI p ON f.id_part = p.id_part
WHERE f.sters = 0 AND d.sters = 0
AND f.tip > 0 AND f.tip NOT IN (7, 8, 9, 24)
AND f.data_act >= ADD_MONTHS(TRUNC(SYSDATE), -:months)
AND f.data_act >= ADD_MONTHS(:data_referinta, -:months)
AND f.data_act < :data_referinta
AND d.pret > 0
),
preturi_medii AS (
@@ -231,7 +237,8 @@ LEFT JOIN nom_parteneri p ON f.id_part = p.id_part
LEFT JOIN nom_articole art ON d.id_articol = art.id_articol
WHERE f.sters = 0
AND f.tip > 0 AND f.tip NOT IN (7, 8, 9, 24)
AND f.data_act >= ADD_MONTHS(TRUNC(SYSDATE, 'MM'), -:months)
AND f.data_act >= ADD_MONTHS(:data_referinta, -:months)
AND f.data_act < :data_referinta
AND d.pret_achizitie > 0
AND d.pret > 0
AND CASE WHEN d.pret_cu_tva = 1 THEN d.pret / (1 + d.proc_tvav/100) ELSE d.pret END < d.pret_achizitie
@@ -247,17 +254,18 @@ WITH vanzari_perioade AS (
SELECT /*+ LEADING(f d) USE_NL(d) INDEX(f IDX_VANZARI_NR) */
f.id_part,
p.denumire AS client,
SUM(CASE WHEN f.data_act >= ADD_MONTHS(TRUNC(SYSDATE), -12)
SUM(CASE WHEN f.data_act >= ADD_MONTHS(:data_referinta, -12)
THEN d.cantitate * CASE WHEN d.pret_cu_tva = 1 THEN d.pret / (1 + d.proc_tvav/100) ELSE d.pret END ELSE 0 END) AS vanzari_an_curent,
SUM(CASE WHEN f.data_act >= ADD_MONTHS(TRUNC(SYSDATE), -24)
AND f.data_act < ADD_MONTHS(TRUNC(SYSDATE), -12)
SUM(CASE WHEN f.data_act >= ADD_MONTHS(:data_referinta, -24)
AND f.data_act < ADD_MONTHS(:data_referinta, -12)
THEN d.cantitate * CASE WHEN d.pret_cu_tva = 1 THEN d.pret / (1 + d.proc_tvav/100) ELSE d.pret END ELSE 0 END) AS vanzari_an_trecut
FROM vanzari f
JOIN vanzari_detalii d ON d.id_vanzare = f.id_vanzare AND d.sters = 0
LEFT JOIN nom_parteneri p ON f.id_part = p.id_part
WHERE f.sters = 0
AND f.tip > 0 AND f.tip NOT IN (7, 8, 9, 24)
AND f.data_act >= ADD_MONTHS(TRUNC(SYSDATE), -24)
AND f.data_act >= ADD_MONTHS(:data_referinta, -24)
AND f.data_act < :data_referinta
GROUP BY f.id_part, p.denumire
)
SELECT
@@ -292,7 +300,8 @@ WITH total_vanzari AS (
JOIN vanzari_detalii d ON d.id_vanzare = f.id_vanzare AND d.sters = 0
WHERE f.sters = 0
AND f.tip > 0 AND f.tip NOT IN (7, 8, 9, 24)
AND f.data_act >= ADD_MONTHS(TRUNC(SYSDATE), -:months)
AND f.data_act >= ADD_MONTHS(:data_referinta, -:months)
AND f.data_act < :data_referinta
),
vanzari_client AS (
SELECT /*+ LEADING(f d) USE_NL(d) INDEX(f IDX_VANZARI_NR) */
@@ -304,7 +313,8 @@ vanzari_client AS (
LEFT JOIN nom_parteneri p ON f.id_part = p.id_part
WHERE f.sters = 0
AND f.tip > 0 AND f.tip NOT IN (7, 8, 9, 24)
AND f.data_act >= ADD_MONTHS(TRUNC(SYSDATE), -:months)
AND f.data_act >= ADD_MONTHS(:data_referinta, -:months)
AND f.data_act < :data_referinta
GROUP BY f.id_part, p.denumire
),
top_clienti AS (
@@ -357,7 +367,8 @@ FROM VANZARI f
JOIN VANZARI_DETALII d ON d.id_vanzare = f.id_vanzare
WHERE f.sters = 0 AND d.sters = 0
AND f.tip > 0 AND f.tip NOT IN (7, 8, 9, 24)
AND f.data_act >= ADD_MONTHS(TRUNC(SYSDATE), -24)
AND f.data_act >= ADD_MONTHS(:data_referinta, -24)
AND f.data_act < :data_referinta
GROUP BY TO_CHAR(f.data_act, 'YYYY-MM')
ORDER BY luna
"""
@@ -379,8 +390,8 @@ SELECT
END AS valoare_stoc_vanzare
FROM vstoc s
JOIN nom_gestiuni g ON s.id_gestiune = g.id_gestiune
WHERE s.an = EXTRACT(YEAR FROM SYSDATE)
AND s.luna = EXTRACT(MONTH FROM SYSDATE)
WHERE s.an = EXTRACT(YEAR FROM (:data_referinta - 1))
AND s.luna = EXTRACT(MONTH FROM (:data_referinta - 1))
AND (s.cants + s.cant - s.cante) > 0
GROUP BY s.id_gestiune, s.nume_gestiune, g.nr_pag, s.id_grupa, s.grupa, s.id_subgrupa, s.subgrupa
ORDER BY valoare_stoc_achizitie DESC
@@ -396,12 +407,12 @@ SELECT
(s.cants + s.cant - s.cante) AS cantitate,
ROUND((s.cants + s.cant - s.cante) * s.pret, 2) AS valoare,
s.dataout AS ultima_iesire,
ROUND(SYSDATE - NVL(s.dataout, s.datain)) AS zile_fara_miscare
ROUND((:data_referinta - 1) - NVL(s.dataout, s.datain)) AS zile_fara_miscare
FROM vstoc s
WHERE s.an = EXTRACT(YEAR FROM SYSDATE)
AND s.luna = EXTRACT(MONTH FROM SYSDATE)
WHERE s.an = EXTRACT(YEAR FROM (:data_referinta - 1))
AND s.luna = EXTRACT(MONTH FROM (:data_referinta - 1))
AND (s.cants + s.cant - s.cante) > 0
AND (s.dataout IS NULL OR s.dataout < SYSDATE - 90)
AND (s.dataout IS NULL OR s.dataout < (:data_referinta - 1) - 90)
AND (s.cants + s.cant - s.cante) * s.pret > 100
ORDER BY zile_fara_miscare DESC NULLS FIRST
FETCH FIRST 100 ROWS ONLY
@@ -419,7 +430,8 @@ WITH vanzari_articole AS (
JOIN vanzari v ON r.id_fact = v.id_fact
WHERE r.id_tip_rulaj = 0
AND r.cante <> 0
AND r.dataact >= ADD_MONTHS(TRUNC(SYSDATE), -12)
AND r.dataact >= ADD_MONTHS(:data_referinta, -12)
AND r.dataact < :data_referinta
GROUP BY r.id_articol
),
stoc_curent AS (
@@ -429,8 +441,8 @@ stoc_curent AS (
s.nume_gestiune,
SUM((s.cants + s.cant - s.cante) * s.pret) AS valoare_stoc
FROM vstoc s
WHERE s.an = EXTRACT(YEAR FROM SYSDATE)
AND s.luna = EXTRACT(MONTH FROM SYSDATE)
WHERE s.an = EXTRACT(YEAR FROM (:data_referinta - 1))
AND s.luna = EXTRACT(MONTH FROM (:data_referinta - 1))
AND (s.cants + s.cant - s.cante) > 0
GROUP BY s.id_articol, s.denumire, s.nume_gestiune
)
@@ -482,7 +494,8 @@ SELECT
ROUND(SUM((NVL(r.cant, 0) - NVL(r.cante, 0)) * NVL(r.pret, 0)), 2) AS sold_net_valoare
FROM vrul r
WHERE r.cont IN ('301', '341', '345')
AND r.dataact >= ADD_MONTHS(TRUNC(SYSDATE), -:months)
AND r.dataact >= ADD_MONTHS(:data_referinta, -:months)
AND r.dataact < :data_referinta
GROUP BY TO_CHAR(r.dataact, 'YYYY-MM'),
CASE WHEN r.cont = '301' THEN 'Materii prime'
WHEN r.cont = '341' THEN 'Semifabricate'
@@ -506,7 +519,8 @@ WITH base_data AS (
JOIN VANZARI_DETALII d ON d.id_vanzare = f.id_vanzare
WHERE f.sters = 0 AND d.sters = 0
AND f.tip > 0 AND f.tip NOT IN (7, 8, 9, 24)
AND f.data_act >= ADD_MONTHS(TRUNC(SYSDATE), -12)
AND f.data_act >= ADD_MONTHS(:data_referinta, -12)
AND f.data_act < :data_referinta
),
aggregated AS (
SELECT
@@ -586,7 +600,8 @@ LEFT JOIN nom_articole a ON d.id_articol = a.id_articol
LEFT JOIN gest_art_sbgr g ON a.id_subgrupa = g.id_subgrupa
WHERE f.sters = 0
AND f.tip > 0 AND f.tip NOT IN (7, 8, 9, 24)
AND f.data_act >= ADD_MONTHS(TRUNC(SYSDATE), -:months)
AND f.data_act >= ADD_MONTHS(:data_referinta, -:months)
AND f.data_act < :data_referinta
GROUP BY d.id_articol, NVL2(d.id_articol, a.denumire, d.explicatie), g.subgrupa, a.um
ORDER BY valoare_vanzari DESC
FETCH FIRST 50 ROWS ONLY
@@ -612,7 +627,8 @@ LEFT JOIN nom_gestiuni g ON d.id_gestiune = g.id_gestiune
JOIN nom_articole a ON d.id_articol = a.id_articol
WHERE f.sters = 0
AND f.tip > 0 AND f.tip NOT IN (7, 8, 9, 24)
AND f.data_act >= ADD_MONTHS(TRUNC(SYSDATE, 'MM'), -:months)
AND f.data_act >= ADD_MONTHS(:data_referinta, -:months)
AND f.data_act < :data_referinta
AND NVL(a.in_stoc, 1) = 1
GROUP BY d.id_gestiune, g.nume_gestiune
ORDER BY vanzari_fara_tva DESC
@@ -642,7 +658,8 @@ LEFT JOIN nom_articole art ON d.id_articol = art.id_articol
LEFT JOIN vgest_art_sbgr sg ON art.id_subgrupa = sg.id_subgrupa
WHERE f.sters = 0
AND f.tip > 0 AND f.tip NOT IN (7, 8, 9, 24)
AND f.data_act >= ADD_MONTHS(TRUNC(SYSDATE, 'MM'), -:months)
AND f.data_act >= ADD_MONTHS(:data_referinta, -:months)
AND f.data_act < :data_referinta
AND NVL(art.in_stoc, 0) = 0
GROUP BY d.id_articol, art.denumire, d.explicatie, sg.subgrupa, art.um
ORDER BY vanzari_fara_tva DESC
@@ -665,8 +682,8 @@ SELECT
FROM vbalanta_parteneri b
JOIN vnom_parteneri p ON b.id_part = p.id_part
WHERE b.cont LIKE '4111%'
AND b.an = EXTRACT(YEAR FROM SYSDATE)
AND b.luna = EXTRACT(MONTH FROM SYSDATE)
AND b.an = EXTRACT(YEAR FROM (:data_referinta - 1))
AND b.luna = EXTRACT(MONTH FROM (:data_referinta - 1))
GROUP BY p.id_part, p.denumire, p.cod_fiscal
HAVING SUM(b.solddeb - b.soldcred) <> 0
ORDER BY sold_curent DESC
@@ -689,8 +706,8 @@ SELECT
FROM vbalanta_parteneri b
JOIN vnom_parteneri p ON b.id_part = p.id_part
WHERE b.cont LIKE '401%'
AND b.an = EXTRACT(YEAR FROM SYSDATE)
AND b.luna = EXTRACT(MONTH FROM SYSDATE)
AND b.an = EXTRACT(YEAR FROM (:data_referinta - 1))
AND b.luna = EXTRACT(MONTH FROM (:data_referinta - 1))
GROUP BY p.id_part, p.denumire, p.cod_fiscal
HAVING SUM(b.soldcred - b.solddeb) <> 0
ORDER BY sold_curent DESC
@@ -702,7 +719,9 @@ ORDER BY sold_curent DESC
# FIX: Filter by last closed calendar period to avoid duplicate invoices
AGING_CREANTE = """
WITH ultima_luna AS (
SELECT anul, luna FROM calendar ORDER BY anul DESC, luna DESC FETCH FIRST 1 ROW ONLY
SELECT EXTRACT(YEAR FROM (:data_referinta - 1)) AS anul,
EXTRACT(MONTH FROM (:data_referinta - 1)) AS luna
FROM dual
),
solduri_clienti AS (
SELECT
@@ -716,8 +735,8 @@ solduri_clienti AS (
(r.precdeb + r.debit) - (r.preccred + r.credit) AS sold_ramas,
CASE
WHEN r.datascad IS NULL THEN 0
WHEN r.datascad >= TRUNC(SYSDATE) THEN 0
ELSE ROUND(TRUNC(SYSDATE) - r.datascad)
WHEN r.datascad >= :data_referinta THEN 0
ELSE ROUND((:data_referinta - 1) - r.datascad)
END AS zile_restante
FROM vireg_parteneri r, ultima_luna ul
WHERE (r.cont LIKE '4111%' OR r.cont LIKE '461%')
@@ -744,20 +763,22 @@ ORDER BY total_sold DESC
# FIX: Filter by last closed calendar period to avoid duplicate invoices
FACTURI_RESTANTE = """
WITH ultima_luna AS (
SELECT anul, luna FROM calendar ORDER BY anul DESC, luna DESC FETCH FIRST 1 ROW ONLY
SELECT EXTRACT(YEAR FROM (:data_referinta - 1)) AS anul,
EXTRACT(MONTH FROM (:data_referinta - 1)) AS luna
FROM dual
)
SELECT
r.nume AS client,
r.serie_act || ' ' || r.nract AS nr_factura,
r.dataact AS data_factura,
r.datascad AS data_scadenta,
ROUND(TRUNC(SYSDATE) - r.datascad) AS zile_intarziere,
ROUND((:data_referinta - 1) - r.datascad) AS zile_intarziere,
ROUND((r.precdeb + r.debit) - (r.preccred + r.credit), 2) AS suma_restanta
FROM vireg_parteneri r, ultima_luna ul
WHERE (r.cont LIKE '4111%' OR r.cont LIKE '461%')
AND (r.precdeb + r.debit) - (r.preccred + r.credit) <> 0
AND r.datascad IS NOT NULL
AND r.datascad < TRUNC(SYSDATE)
AND r.datascad < :data_referinta
AND r.an = ul.anul AND r.luna = ul.luna
ORDER BY zile_intarziere DESC
FETCH FIRST 100 ROWS ONLY
@@ -770,7 +791,9 @@ FETCH FIRST 100 ROWS ONLY
# FIX: Filter by last closed calendar period to avoid duplicate invoices
AGING_DATORII = """
WITH ultima_luna AS (
SELECT anul, luna FROM calendar ORDER BY anul DESC, luna DESC FETCH FIRST 1 ROW ONLY
SELECT EXTRACT(YEAR FROM (:data_referinta - 1)) AS anul,
EXTRACT(MONTH FROM (:data_referinta - 1)) AS luna
FROM dual
),
solduri_furnizori AS (
SELECT
@@ -784,8 +807,8 @@ solduri_furnizori AS (
(r.preccred + r.credit) - (r.precdeb + r.debit) AS sold_ramas,
CASE
WHEN r.datascad IS NULL THEN 0
WHEN r.datascad >= TRUNC(SYSDATE) THEN 0
ELSE ROUND(TRUNC(SYSDATE) - r.datascad)
WHEN r.datascad >= :data_referinta THEN 0
ELSE ROUND((:data_referinta - 1) - r.datascad)
END AS zile_restante
FROM vireg_parteneri r, ultima_luna ul
WHERE (r.cont LIKE '401%' OR r.cont LIKE '404%' OR r.cont LIKE '462%')
@@ -812,20 +835,22 @@ ORDER BY total_sold DESC
# FIX: Filter by last closed calendar period to avoid duplicate invoices
FACTURI_RESTANTE_FURNIZORI = """
WITH ultima_luna AS (
SELECT anul, luna FROM calendar ORDER BY anul DESC, luna DESC FETCH FIRST 1 ROW ONLY
SELECT EXTRACT(YEAR FROM (:data_referinta - 1)) AS anul,
EXTRACT(MONTH FROM (:data_referinta - 1)) AS luna
FROM dual
)
SELECT
r.nume AS furnizor,
r.serie_act || ' ' || r.nract AS nr_factura,
r.dataact AS data_factura,
r.datascad AS data_scadenta,
ROUND(TRUNC(SYSDATE) - r.datascad) AS zile_intarziere,
ROUND((:data_referinta - 1) - r.datascad) AS zile_intarziere,
ROUND((r.preccred + r.credit) - (r.precdeb + r.debit), 2) AS suma_restanta
FROM vireg_parteneri r, ultima_luna ul
WHERE (r.cont LIKE '401%' OR r.cont LIKE '404%' OR r.cont LIKE '462%')
AND (r.preccred + r.credit) - (r.precdeb + r.debit) <> 0
AND r.datascad IS NOT NULL
AND r.datascad < TRUNC(SYSDATE)
AND r.datascad < :data_referinta
AND r.an = ul.anul AND r.luna = ul.luna
ORDER BY zile_intarziere DESC
FETCH FIRST 100 ROWS ONLY
@@ -852,8 +877,8 @@ WITH vanzari_12_luni AS (
) AS total_vanzari
FROM vjv2025
WHERE (an * 12 + luna) BETWEEN
(EXTRACT(YEAR FROM ADD_MONTHS(SYSDATE, -12)) * 12 + EXTRACT(MONTH FROM ADD_MONTHS(SYSDATE, -12)))
AND (EXTRACT(YEAR FROM SYSDATE) * 12 + EXTRACT(MONTH FROM SYSDATE))
(EXTRACT(YEAR FROM ADD_MONTHS(:data_referinta, -12)) * 12 + EXTRACT(MONTH FROM ADD_MONTHS(:data_referinta, -12)))
AND (EXTRACT(YEAR FROM (:data_referinta - 1)) * 12 + EXTRACT(MONTH FROM (:data_referinta - 1)))
AND EXTRACT(YEAR FROM dataireg) = an
AND EXTRACT(MONTH FROM dataireg) = luna
),
@@ -862,8 +887,8 @@ sold_clienti AS (
SELECT SUM(CASE WHEN b.solddeb > b.soldcred THEN b.solddeb - b.soldcred ELSE 0 END) AS total_creante
FROM vbalanta_parteneri b
WHERE b.cont LIKE '4111%'
AND b.an = EXTRACT(YEAR FROM SYSDATE)
AND b.luna = EXTRACT(MONTH FROM SYSDATE)
AND b.an = EXTRACT(YEAR FROM (:data_referinta - 1))
AND b.luna = EXTRACT(MONTH FROM (:data_referinta - 1))
),
achizitii_12_luni AS (
-- Achiziții fără TVA din ultimele 12 luni (jurnal cumpărări vjc2025)
@@ -889,8 +914,8 @@ achizitii_12_luni AS (
) AS total_achizitii
FROM vjc2025
WHERE (an * 12 + luna) BETWEEN
(EXTRACT(YEAR FROM ADD_MONTHS(SYSDATE, -12)) * 12 + EXTRACT(MONTH FROM ADD_MONTHS(SYSDATE, -12)))
AND (EXTRACT(YEAR FROM SYSDATE) * 12 + EXTRACT(MONTH FROM SYSDATE))
(EXTRACT(YEAR FROM ADD_MONTHS(:data_referinta, -12)) * 12 + EXTRACT(MONTH FROM ADD_MONTHS(:data_referinta, -12)))
AND (EXTRACT(YEAR FROM (:data_referinta - 1)) * 12 + EXTRACT(MONTH FROM (:data_referinta - 1)))
AND EXTRACT(YEAR FROM dataireg) = an
AND EXTRACT(MONTH FROM dataireg) = luna
),
@@ -899,8 +924,8 @@ sold_furnizori AS (
SELECT SUM(CASE WHEN b.soldcred > b.solddeb THEN b.soldcred - b.solddeb ELSE 0 END) AS total_datorii
FROM vbalanta_parteneri b
WHERE b.cont LIKE '401%'
AND b.an = EXTRACT(YEAR FROM SYSDATE)
AND b.luna = EXTRACT(MONTH FROM SYSDATE)
AND b.an = EXTRACT(YEAR FROM (:data_referinta - 1))
AND b.luna = EXTRACT(MONTH FROM (:data_referinta - 1))
)
SELECT
'DSO (Zile incasare clienti)' AS indicator,
@@ -945,8 +970,8 @@ SELECT
END AS valuta
FROM vbal b
WHERE (b.cont LIKE '512%' OR b.cont LIKE '531%')
AND b.an = EXTRACT(YEAR FROM SYSDATE)
AND b.luna = EXTRACT(MONTH FROM SYSDATE)
AND b.an = EXTRACT(YEAR FROM (:data_referinta - 1))
AND b.luna = EXTRACT(MONTH FROM (:data_referinta - 1))
GROUP BY b.cont
HAVING SUM(b.solddeb - b.soldcred) <> 0
ORDER BY b.cont
@@ -963,8 +988,8 @@ WITH metrici AS (
(SELECT SUM(b.solddeb - b.soldcred)
FROM vbal b
WHERE b.cont LIKE '3%'
AND b.an = EXTRACT(YEAR FROM SYSDATE)
AND b.luna = EXTRACT(MONTH FROM SYSDATE)) AS stoc_curent,
AND b.an = EXTRACT(YEAR FROM (:data_referinta - 1))
AND b.luna = EXTRACT(MONTH FROM (:data_referinta - 1))) AS stoc_curent,
-- COGS din facturi (preț achiziție articole vândute)
(SELECT /*+ LEADING(f d) USE_NL(d) INDEX(f IDX_VANZARI_NR) */
SUM(d.cantitate * d.pret_achizitie)
@@ -972,13 +997,14 @@ WITH metrici AS (
JOIN vanzari_detalii d ON d.id_vanzare = f.id_vanzare AND d.sters = 0
WHERE f.sters = 0
AND f.tip > 0 AND f.tip NOT IN (7, 8, 9, 24)
AND f.data_act >= ADD_MONTHS(TRUNC(SYSDATE), -12)) AS cogs_12_luni,
AND f.data_act >= ADD_MONTHS(:data_referinta, -12)
AND f.data_act < :data_referinta) AS cogs_12_luni,
-- Creanțe clienți
(SELECT SUM(CASE WHEN b.solddeb > b.soldcred THEN b.solddeb - b.soldcred ELSE 0 END)
FROM vbalanta_parteneri b
WHERE b.cont LIKE '4111%'
AND b.an = EXTRACT(YEAR FROM SYSDATE)
AND b.luna = EXTRACT(MONTH FROM SYSDATE)) AS creante,
AND b.an = EXTRACT(YEAR FROM (:data_referinta - 1))
AND b.luna = EXTRACT(MONTH FROM (:data_referinta - 1))) AS creante,
-- Vânzări 12 luni din jurnal TVA vânzări (vjv2025)
(SELECT SUM(
-- Baze impozabile (ro*b)
@@ -993,16 +1019,16 @@ WITH metrici AS (
NVL(wrscdd, 0) + NVL(fodd, 0) + NVL(fofdd, 0) + NVL(wrscfdd, 0) + NVL(wrn, 0))
FROM vjv2025
WHERE (an * 12 + luna) BETWEEN
(EXTRACT(YEAR FROM ADD_MONTHS(SYSDATE, -12)) * 12 + EXTRACT(MONTH FROM ADD_MONTHS(SYSDATE, -12)))
AND (EXTRACT(YEAR FROM SYSDATE) * 12 + EXTRACT(MONTH FROM SYSDATE))
(EXTRACT(YEAR FROM ADD_MONTHS(:data_referinta, -12)) * 12 + EXTRACT(MONTH FROM ADD_MONTHS(:data_referinta, -12)))
AND (EXTRACT(YEAR FROM (:data_referinta - 1)) * 12 + EXTRACT(MONTH FROM (:data_referinta - 1)))
AND EXTRACT(YEAR FROM dataireg) = an
AND EXTRACT(MONTH FROM dataireg) = luna) AS vanzari_12_luni,
-- Datorii furnizori
(SELECT SUM(CASE WHEN b.soldcred > b.solddeb THEN b.soldcred - b.solddeb ELSE 0 END)
FROM vbalanta_parteneri b
WHERE b.cont LIKE '401%'
AND b.an = EXTRACT(YEAR FROM SYSDATE)
AND b.luna = EXTRACT(MONTH FROM SYSDATE)) AS datorii_furnizori,
AND b.an = EXTRACT(YEAR FROM (:data_referinta - 1))
AND b.luna = EXTRACT(MONTH FROM (:data_referinta - 1))) AS datorii_furnizori,
-- Achiziții 12 luni din jurnal TVA cumpărări (vjc2025)
(SELECT SUM(
-- Baze impozabile domestice (ro*b)
@@ -1025,8 +1051,8 @@ WITH metrici AS (
NVL(cen, 0))
FROM vjc2025
WHERE (an * 12 + luna) BETWEEN
(EXTRACT(YEAR FROM ADD_MONTHS(SYSDATE, -12)) * 12 + EXTRACT(MONTH FROM ADD_MONTHS(SYSDATE, -12)))
AND (EXTRACT(YEAR FROM SYSDATE) * 12 + EXTRACT(MONTH FROM SYSDATE))
(EXTRACT(YEAR FROM ADD_MONTHS(:data_referinta, -12)) * 12 + EXTRACT(MONTH FROM ADD_MONTHS(:data_referinta, -12)))
AND (EXTRACT(YEAR FROM (:data_referinta - 1)) * 12 + EXTRACT(MONTH FROM (:data_referinta - 1)))
AND EXTRACT(YEAR FROM dataireg) = an
AND EXTRACT(MONTH FROM dataireg) = luna) AS achizitii_12_luni
FROM dual
@@ -1081,7 +1107,8 @@ WITH vanzari_detaliate AS (
JOIN vanzari_detalii d ON d.id_vanzare = f.id_vanzare AND d.sters = 0
WHERE f.sters = 0
AND f.tip > 0 AND f.tip NOT IN (7, 8, 9, 24)
AND f.data_act >= ADD_MONTHS(TRUNC(SYSDATE, 'MM'), -:months)
AND f.data_act >= ADD_MONTHS(:data_referinta, -:months)
AND f.data_act < :data_referinta
),
total AS (
SELECT SUM(vanzare) AS total_vanzari, SUM(marja) AS total_marja
@@ -1114,7 +1141,8 @@ WITH vanzari_lunare AS (
JOIN vanzari_detalii d ON d.id_vanzare = f.id_vanzare AND d.sters = 0
WHERE f.sters = 0
AND f.tip > 0 AND f.tip NOT IN (7, 8, 9, 24)
AND f.data_act >= ADD_MONTHS(TRUNC(SYSDATE), -24)
AND f.data_act >= ADD_MONTHS(:data_referinta, -24)
AND f.data_act < :data_referinta
GROUP BY EXTRACT(MONTH FROM f.data_act), TO_CHAR(f.data_act, 'Month', 'NLS_DATE_LANGUAGE=ROMANIAN'), EXTRACT(YEAR FROM f.data_act)
),
statistici_luna AS (
@@ -1155,50 +1183,55 @@ WITH clienti_activi_3_luni AS (
SELECT /*+ INDEX(f IDX_VANZARI_NR) */ COUNT(DISTINCT f.id_part) AS cnt
FROM vanzari f
WHERE f.sters = 0 AND f.tip > 0 AND f.tip NOT IN (7, 8, 9, 24)
AND f.data_act >= ADD_MONTHS(TRUNC(SYSDATE), -3)
AND f.data_act >= ADD_MONTHS(:data_referinta, -3)
AND f.data_act < :data_referinta
),
clienti_activi_12_luni AS (
SELECT /*+ INDEX(f IDX_VANZARI_NR) */ COUNT(DISTINCT f.id_part) AS cnt
FROM vanzari f
WHERE f.sters = 0 AND f.tip > 0 AND f.tip NOT IN (7, 8, 9, 24)
AND f.data_act >= ADD_MONTHS(TRUNC(SYSDATE), -12)
AND f.data_act >= ADD_MONTHS(:data_referinta, -12)
AND f.data_act < :data_referinta
),
clienti_noi AS (
SELECT /*+ INDEX(f IDX_VANZARI_NR) */ COUNT(DISTINCT f.id_part) AS cnt
FROM vanzari f
WHERE f.sters = 0 AND f.tip > 0 AND f.tip NOT IN (7, 8, 9, 24)
AND f.data_act >= ADD_MONTHS(TRUNC(SYSDATE), -12)
AND f.data_act >= ADD_MONTHS(:data_referinta, -12)
AND f.data_act < :data_referinta
AND f.id_part NOT IN (
SELECT /*+ INDEX(f2 IDX_VANZARI_NR) */ DISTINCT f2.id_part
FROM vanzari f2
WHERE f2.sters = 0 AND f2.tip > 0 AND f2.tip NOT IN (7, 8, 9, 24)
AND f2.data_act < ADD_MONTHS(TRUNC(SYSDATE), -12)
AND f2.data_act < ADD_MONTHS(:data_referinta, -12)
)
),
clienti_pierduti AS (
SELECT /*+ INDEX(f IDX_VANZARI_NR) */ COUNT(DISTINCT f.id_part) AS cnt
FROM vanzari f
WHERE f.sters = 0 AND f.tip > 0 AND f.tip NOT IN (7, 8, 9, 24)
AND f.data_act >= ADD_MONTHS(TRUNC(SYSDATE), -24)
AND f.data_act < ADD_MONTHS(TRUNC(SYSDATE), -6)
AND f.data_act >= ADD_MONTHS(:data_referinta, -24)
AND f.data_act < :data_referinta
AND f.data_act < ADD_MONTHS(:data_referinta, -6)
AND f.id_part NOT IN (
SELECT /*+ INDEX(f2 IDX_VANZARI_NR) */ DISTINCT f2.id_part
FROM vanzari f2
WHERE f2.sters = 0 AND f2.tip > 0 AND f2.tip NOT IN (7, 8, 9, 24)
AND f2.data_act >= ADD_MONTHS(TRUNC(SYSDATE), -6)
AND f2.data_act >= ADD_MONTHS(:data_referinta, -6)
)
),
clienti_inactivi AS (
SELECT /*+ INDEX(f IDX_VANZARI_NR) */ COUNT(DISTINCT f.id_part) AS cnt
FROM vanzari f
WHERE f.sters = 0 AND f.tip > 0 AND f.tip NOT IN (7, 8, 9, 24)
AND f.data_act >= ADD_MONTHS(TRUNC(SYSDATE), -6)
AND f.data_act < ADD_MONTHS(TRUNC(SYSDATE), -3)
AND f.data_act >= ADD_MONTHS(:data_referinta, -6)
AND f.data_act < :data_referinta
AND f.data_act < ADD_MONTHS(:data_referinta, -3)
AND f.id_part NOT IN (
SELECT /*+ INDEX(f2 IDX_VANZARI_NR) */ DISTINCT f2.id_part
FROM vanzari f2
WHERE f2.sters = 0 AND f2.tip > 0 AND f2.tip NOT IN (7, 8, 9, 24)
AND f2.data_act >= ADD_MONTHS(TRUNC(SYSDATE), -3)
AND f2.data_act >= ADD_MONTHS(:data_referinta, -3)
)
)
SELECT 'Clienti activi (ultimele 3 luni)' AS indicator, cnt AS valoare, 'Au cumparat recent' AS explicatie FROM clienti_activi_3_luni
@@ -1228,7 +1261,8 @@ WITH frecventa_curenta AS (
LEFT JOIN nom_parteneri p ON f.id_part = p.id_part
WHERE f.sters = 0
AND f.tip > 0 AND f.tip NOT IN (7, 8, 9, 24)
AND f.data_act >= ADD_MONTHS(TRUNC(SYSDATE), -12)
AND f.data_act >= ADD_MONTHS(:data_referinta, -12)
AND f.data_act < :data_referinta
GROUP BY f.id_part, p.denumire
),
frecventa_anterioara AS (
@@ -1238,8 +1272,9 @@ frecventa_anterioara AS (
FROM vanzari f
WHERE f.sters = 0
AND f.tip > 0 AND f.tip NOT IN (7, 8, 9, 24)
AND f.data_act >= ADD_MONTHS(TRUNC(SYSDATE), -24)
AND f.data_act < ADD_MONTHS(TRUNC(SYSDATE), -12)
AND f.data_act >= ADD_MONTHS(:data_referinta, -24)
AND f.data_act < :data_referinta
AND f.data_act < ADD_MONTHS(:data_referinta, -12)
GROUP BY f.id_part
)
SELECT
@@ -1270,7 +1305,8 @@ WITH total_vanzari AS (
JOIN vanzari_detalii d ON d.id_vanzare = f.id_vanzare AND d.sters = 0
WHERE f.sters = 0
AND f.tip > 0 AND f.tip NOT IN (7, 8, 9, 24)
AND f.data_act >= ADD_MONTHS(TRUNC(SYSDATE), -:months)
AND f.data_act >= ADD_MONTHS(:data_referinta, -:months)
AND f.data_act < :data_referinta
),
vanzari_client AS (
SELECT /*+ LEADING(f d) USE_NL(d) INDEX(f IDX_VANZARI_NR) */
@@ -1281,7 +1317,8 @@ vanzari_client AS (
JOIN vanzari_detalii d ON d.id_vanzare = f.id_vanzare AND d.sters = 0
WHERE f.sters = 0
AND f.tip > 0 AND f.tip NOT IN (7, 8, 9, 24)
AND f.data_act >= ADD_MONTHS(TRUNC(SYSDATE), -:months)
AND f.data_act >= ADD_MONTHS(:data_referinta, -:months)
AND f.data_act < :data_referinta
GROUP BY f.id_part
)
SELECT
@@ -1337,7 +1374,8 @@ WITH vanzari_client AS (
LEFT JOIN nom_parteneri p ON f.id_part = p.id_part
WHERE f.sters = 0
AND f.tip > 0 AND f.tip NOT IN (7, 8, 9, 24)
AND f.data_act >= ADD_MONTHS(TRUNC(SYSDATE), -:months)
AND f.data_act >= ADD_MONTHS(:data_referinta, -:months)
AND f.data_act < :data_referinta
GROUP BY f.id_part, p.denumire
)
SELECT
@@ -1379,7 +1417,8 @@ LEFT JOIN nom_articole art ON d.id_articol = art.id_articol
LEFT JOIN vgest_art_sbgr sg ON art.id_subgrupa = sg.id_subgrupa
WHERE f.sters = 0
AND f.tip > 0 AND f.tip NOT IN (7, 8, 9, 24)
AND f.data_act >= ADD_MONTHS(TRUNC(SYSDATE, 'MM'), -:months)
AND f.data_act >= ADD_MONTHS(:data_referinta, -:months)
AND f.data_act < :data_referinta
GROUP BY f.id_part, p.denumire, sg.id_grupa, sg.grupa
HAVING SUM(d.cantitate * CASE WHEN d.pret_cu_tva = 1 THEN d.pret / (1 + d.proc_tvav/100) ELSE d.pret END) > 1000
ORDER BY p.denumire, vanzari DESC
@@ -1399,8 +1438,9 @@ WITH preturi_vechi AS (
LEFT JOIN nom_articole a ON d.id_articol = a.id_articol
WHERE f.sters = 0
AND f.tip > 0 AND f.tip NOT IN (7, 8, 9, 24)
AND f.data_act >= ADD_MONTHS(TRUNC(SYSDATE), -12)
AND f.data_act < ADD_MONTHS(TRUNC(SYSDATE), -6)
AND f.data_act >= ADD_MONTHS(:data_referinta, -12)
AND f.data_act < :data_referinta
AND f.data_act < ADD_MONTHS(:data_referinta, -6)
AND d.pret > 0
GROUP BY d.id_articol, a.denumire
HAVING COUNT(*) >= 5
@@ -1413,7 +1453,8 @@ preturi_noi AS (
JOIN vanzari_detalii d ON d.id_vanzare = f.id_vanzare AND d.sters = 0
WHERE f.sters = 0
AND f.tip > 0 AND f.tip NOT IN (7, 8, 9, 24)
AND f.data_act >= ADD_MONTHS(TRUNC(SYSDATE), -6)
AND f.data_act >= ADD_MONTHS(:data_referinta, -6)
AND f.data_act < :data_referinta
AND d.pret > 0
GROUP BY d.id_articol
HAVING COUNT(*) >= 5
@@ -1441,8 +1482,8 @@ capitaluri AS (
FROM vbal b
WHERE (b.cont LIKE '101%' OR b.cont LIKE '104%' OR b.cont LIKE '105%'
OR b.cont LIKE '106%' OR b.cont LIKE '117%' OR b.cont LIKE '121%')
AND b.an = EXTRACT(YEAR FROM SYSDATE)
AND b.luna = EXTRACT(MONTH FROM SYSDATE)
AND b.an = EXTRACT(YEAR FROM (:data_referinta - 1))
AND b.luna = EXTRACT(MONTH FROM (:data_referinta - 1))
),
-- Datorii totale (16x, 40x, 42x, 44x, 46x)
datorii AS (
@@ -1450,8 +1491,8 @@ datorii AS (
FROM vbal b
WHERE (b.cont LIKE '16%' OR b.cont LIKE '40%' OR b.cont LIKE '42%'
OR b.cont LIKE '44%' OR b.cont LIKE '46%')
AND b.an = EXTRACT(YEAR FROM SYSDATE)
AND b.luna = EXTRACT(MONTH FROM SYSDATE)
AND b.an = EXTRACT(YEAR FROM (:data_referinta - 1))
AND b.luna = EXTRACT(MONTH FROM (:data_referinta - 1))
),
-- Total activ (sold debitor toate conturile de activ)
activ AS (
@@ -1461,8 +1502,8 @@ activ AS (
OR b.cont LIKE '4%' OR b.cont LIKE '5%')
AND b.cont NOT LIKE '16%' AND b.cont NOT LIKE '40%' AND b.cont NOT LIKE '42%'
AND b.cont NOT LIKE '44%' AND b.cont NOT LIKE '46%' AND b.cont NOT LIKE '47%'
AND b.an = EXTRACT(YEAR FROM SYSDATE)
AND b.luna = EXTRACT(MONTH FROM SYSDATE)
AND b.an = EXTRACT(YEAR FROM (:data_referinta - 1))
AND b.luna = EXTRACT(MONTH FROM (:data_referinta - 1))
),
-- Vanzari si profit din ultimele 12 luni
vanzari_calc AS (
@@ -1473,7 +1514,8 @@ vanzari_calc AS (
JOIN vanzari_detalii d ON d.id_vanzare = f.id_vanzare AND d.sters = 0
WHERE f.sters = 0
AND f.tip > 0 AND f.tip NOT IN (7, 8, 9, 24)
AND f.data_act >= ADD_MONTHS(TRUNC(SYSDATE), -12)
AND f.data_act >= ADD_MONTHS(:data_referinta, -12)
AND f.data_act < :data_referinta
)
SELECT
'Grad indatorare' AS indicator,
@@ -1586,23 +1628,23 @@ cash AS (
SELECT SUM(b.solddeb - b.soldcred) AS cash_total
FROM vbal b
WHERE (b.cont LIKE '512%' OR b.cont LIKE '531%')
AND b.an = EXTRACT(YEAR FROM SYSDATE)
AND b.luna = EXTRACT(MONTH FROM SYSDATE)
AND b.an = EXTRACT(YEAR FROM (:data_referinta - 1))
AND b.luna = EXTRACT(MONTH FROM (:data_referinta - 1))
),
-- Creante (cont 4111)
creante AS (
SELECT SUM(CASE WHEN b.solddeb > b.soldcred THEN b.solddeb - b.soldcred ELSE 0 END) AS creante_total
FROM vbalanta_parteneri b
WHERE b.cont LIKE '4111%'
AND b.an = EXTRACT(YEAR FROM SYSDATE)
AND b.luna = EXTRACT(MONTH FROM SYSDATE)
AND b.an = EXTRACT(YEAR FROM (:data_referinta - 1))
AND b.luna = EXTRACT(MONTH FROM (:data_referinta - 1))
),
-- Stocuri
stocuri AS (
SELECT SUM((s.cants + s.cant - s.cante) * s.pret) AS stoc_total
FROM vstoc s
WHERE s.an = EXTRACT(YEAR FROM SYSDATE)
AND s.luna = EXTRACT(MONTH FROM SYSDATE)
WHERE s.an = EXTRACT(YEAR FROM (:data_referinta - 1))
AND s.luna = EXTRACT(MONTH FROM (:data_referinta - 1))
AND (s.cants + s.cant - s.cante) > 0
),
-- Datorii curente (401, 404, 462)
@@ -1610,8 +1652,8 @@ datorii_curente AS (
SELECT SUM(CASE WHEN b.soldcred > b.solddeb THEN b.soldcred - b.solddeb ELSE 0 END) AS datorii_total
FROM vbalanta_parteneri b
WHERE (b.cont LIKE '401%' OR b.cont LIKE '404%' OR b.cont LIKE '462%')
AND b.an = EXTRACT(YEAR FROM SYSDATE)
AND b.luna = EXTRACT(MONTH FROM SYSDATE)
AND b.an = EXTRACT(YEAR FROM (:data_referinta - 1))
AND b.luna = EXTRACT(MONTH FROM (:data_referinta - 1))
)
SELECT
'Lichiditate curenta' AS indicator,
@@ -1692,8 +1734,8 @@ WITH datorii_scadenta AS (
(r.preccred + r.credit) - (r.precdeb + r.debit) AS sold_ramas,
CASE
WHEN r.datascad IS NULL THEN 'TERMEN_NEDEFINIT'
WHEN r.datascad <= TRUNC(SYSDATE) + 30 THEN 'TERMEN_SCURT'
WHEN r.datascad <= TRUNC(SYSDATE) + 90 THEN 'TERMEN_MEDIU'
WHEN r.datascad <= (:data_referinta - 1) + 30 THEN 'TERMEN_SCURT'
WHEN r.datascad <= (:data_referinta - 1) + 90 THEN 'TERMEN_MEDIU'
ELSE 'TERMEN_LUNG'
END AS clasificare
FROM vireg_parteneri r
@@ -1745,23 +1787,23 @@ cash_curent AS (
SELECT SUM(b.solddeb - b.soldcred) AS cash_total
FROM vbal b
WHERE (b.cont LIKE '512%' OR b.cont LIKE '531%')
AND b.an = EXTRACT(YEAR FROM SYSDATE)
AND b.luna = EXTRACT(MONTH FROM SYSDATE)
AND b.an = EXTRACT(YEAR FROM (:data_referinta - 1))
AND b.luna = EXTRACT(MONTH FROM (:data_referinta - 1))
),
incasari_asteptate AS (
SELECT
ROUND(SUM(CASE WHEN r.datascad <= TRUNC(SYSDATE) + 30 THEN (r.precdeb + r.debit) - (r.preccred + r.credit) ELSE 0 END), 0) AS incasari_30,
ROUND(SUM(CASE WHEN r.datascad <= TRUNC(SYSDATE) + 60 THEN (r.precdeb + r.debit) - (r.preccred + r.credit) ELSE 0 END), 0) AS incasari_60,
ROUND(SUM(CASE WHEN r.datascad <= TRUNC(SYSDATE) + 90 THEN (r.precdeb + r.debit) - (r.preccred + r.credit) ELSE 0 END), 0) AS incasari_90
ROUND(SUM(CASE WHEN r.datascad <= (:data_referinta - 1) + 30 THEN (r.precdeb + r.debit) - (r.preccred + r.credit) ELSE 0 END), 0) AS incasari_30,
ROUND(SUM(CASE WHEN r.datascad <= (:data_referinta - 1) + 60 THEN (r.precdeb + r.debit) - (r.preccred + r.credit) ELSE 0 END), 0) AS incasari_60,
ROUND(SUM(CASE WHEN r.datascad <= (:data_referinta - 1) + 90 THEN (r.precdeb + r.debit) - (r.preccred + r.credit) ELSE 0 END), 0) AS incasari_90
FROM vireg_parteneri r
WHERE (r.cont LIKE '4111%' OR r.cont LIKE '461%')
AND (r.precdeb + r.debit) - (r.preccred + r.credit) <> 0
),
plati_scadente AS (
SELECT
ROUND(SUM(CASE WHEN r.datascad <= TRUNC(SYSDATE) + 30 THEN (r.preccred + r.credit) - (r.precdeb + r.debit) ELSE 0 END), 0) AS plati_30,
ROUND(SUM(CASE WHEN r.datascad <= TRUNC(SYSDATE) + 60 THEN (r.preccred + r.credit) - (r.precdeb + r.debit) ELSE 0 END), 0) AS plati_60,
ROUND(SUM(CASE WHEN r.datascad <= TRUNC(SYSDATE) + 90 THEN (r.preccred + r.credit) - (r.precdeb + r.debit) ELSE 0 END), 0) AS plati_90
ROUND(SUM(CASE WHEN r.datascad <= (:data_referinta - 1) + 30 THEN (r.preccred + r.credit) - (r.precdeb + r.debit) ELSE 0 END), 0) AS plati_30,
ROUND(SUM(CASE WHEN r.datascad <= (:data_referinta - 1) + 60 THEN (r.preccred + r.credit) - (r.precdeb + r.debit) ELSE 0 END), 0) AS plati_60,
ROUND(SUM(CASE WHEN r.datascad <= (:data_referinta - 1) + 90 THEN (r.preccred + r.credit) - (r.precdeb + r.debit) ELSE 0 END), 0) AS plati_90
FROM vireg_parteneri r
WHERE (r.cont LIKE '401%' OR r.cont LIKE '404%' OR r.cont LIKE '462%')
AND (r.preccred + r.credit) - (r.precdeb + r.debit) <> 0
@@ -1825,23 +1867,23 @@ cash_curent AS (
SELECT SUM(b.solddeb - b.soldcred) AS cash_total
FROM vbal b
WHERE (b.cont LIKE '512%' OR b.cont LIKE '531%')
AND b.an = EXTRACT(YEAR FROM SYSDATE)
AND b.luna = EXTRACT(MONTH FROM SYSDATE)
AND b.an = EXTRACT(YEAR FROM (:data_referinta - 1))
AND b.luna = EXTRACT(MONTH FROM (:data_referinta - 1))
),
incasari_programate AS (
SELECT
SUM(CASE WHEN r.datascad <= TRUNC(SYSDATE) + 30 THEN (r.precdeb + r.debit) - (r.preccred + r.credit) ELSE 0 END) AS incasari_30,
SUM(CASE WHEN r.datascad > TRUNC(SYSDATE) + 30 AND r.datascad <= TRUNC(SYSDATE) + 60 THEN (r.precdeb + r.debit) - (r.preccred + r.credit) ELSE 0 END) AS incasari_31_60,
SUM(CASE WHEN r.datascad > TRUNC(SYSDATE) + 60 AND r.datascad <= TRUNC(SYSDATE) + 90 THEN (r.precdeb + r.debit) - (r.preccred + r.credit) ELSE 0 END) AS incasari_61_90
SUM(CASE WHEN r.datascad <= (:data_referinta - 1) + 30 THEN (r.precdeb + r.debit) - (r.preccred + r.credit) ELSE 0 END) AS incasari_30,
SUM(CASE WHEN r.datascad > (:data_referinta - 1) + 30 AND r.datascad <= (:data_referinta - 1) + 60 THEN (r.precdeb + r.debit) - (r.preccred + r.credit) ELSE 0 END) AS incasari_31_60,
SUM(CASE WHEN r.datascad > (:data_referinta - 1) + 60 AND r.datascad <= (:data_referinta - 1) + 90 THEN (r.precdeb + r.debit) - (r.preccred + r.credit) ELSE 0 END) AS incasari_61_90
FROM vireg_parteneri r
WHERE (r.cont LIKE '4111%' OR r.cont LIKE '461%')
AND (r.precdeb + r.debit) - (r.preccred + r.credit) <> 0
),
plati_programate AS (
SELECT
SUM(CASE WHEN r.datascad <= TRUNC(SYSDATE) + 30 THEN (r.preccred + r.credit) - (r.precdeb + r.debit) ELSE 0 END) AS plati_30,
SUM(CASE WHEN r.datascad > TRUNC(SYSDATE) + 30 AND r.datascad <= TRUNC(SYSDATE) + 60 THEN (r.preccred + r.credit) - (r.precdeb + r.debit) ELSE 0 END) AS plati_31_60,
SUM(CASE WHEN r.datascad > TRUNC(SYSDATE) + 60 AND r.datascad <= TRUNC(SYSDATE) + 90 THEN (r.preccred + r.credit) - (r.precdeb + r.debit) ELSE 0 END) AS plati_61_90
SUM(CASE WHEN r.datascad <= (:data_referinta - 1) + 30 THEN (r.preccred + r.credit) - (r.precdeb + r.debit) ELSE 0 END) AS plati_30,
SUM(CASE WHEN r.datascad > (:data_referinta - 1) + 30 AND r.datascad <= (:data_referinta - 1) + 60 THEN (r.preccred + r.credit) - (r.precdeb + r.debit) ELSE 0 END) AS plati_31_60,
SUM(CASE WHEN r.datascad > (:data_referinta - 1) + 60 AND r.datascad <= (:data_referinta - 1) + 90 THEN (r.preccred + r.credit) - (r.precdeb + r.debit) ELSE 0 END) AS plati_61_90
FROM vireg_parteneri r
WHERE (r.cont LIKE '401%' OR r.cont LIKE '404%' OR r.cont LIKE '462%')
AND (r.preccred + r.credit) - (r.precdeb + r.debit) <> 0
@@ -1897,19 +1939,27 @@ FROM cash_curent c, incasari_programate i, plati_programate p
# 39. SUMAR EXECUTIV YoY (cu comparatie an anterior)
# =============================================================================
# OPTIMIZED: Single 24-month scan with CASE-based period partitioning instead of 2 separate view scans
# f.tip NOT IN (21,22,23,24,25) - excludes avizele de expeditie, si tranzactii similare non-vanzare
SUMAR_EXECUTIV_YOY = """
WITH base_data AS (
SELECT
f.id_vanzare,
f.id_part,
CASE WHEN f.data_act >= ADD_MONTHS(TRUNC(SYSDATE), -12) THEN 'CURENT' ELSE 'ANTERIOR' END AS perioada,
d.cantitate * CASE WHEN d.pret_cu_tva = 1 THEN d.pret / (1 + d.proc_tvav/100) ELSE d.pret END AS vanzare,
d.cantitate * (CASE WHEN d.pret_cu_tva = 1 THEN d.pret / (1 + d.proc_tvav/100) ELSE d.pret END - d.pret_achizitie) AS marja
CASE WHEN f.data_act >= ADD_MONTHS(:data_referinta, -12) THEN 'CURENT' ELSE 'ANTERIOR' END AS perioada,
(CASE WHEN d.pret_cu_tva = 1 THEN round((ROUND(NVL(c.curs, 1) * ROUND(NVL(d.pret, 0), 4) / NVL(c.multiplicator, 1), 4)) / d.proc_tvav, 4) ELSE (ROUND(NVL(c.curs, 1) * ROUND(NVL(d.pret, 0), 4) / NVL(c.multiplicator, 1), 4)) END) AS pret_unitar_ron,
ROUND(NVL(c.curs, 1) * NVL(d.discount_unitar, 4) / NVL(c.multiplicator, 1), 4) AS discount_unitar_ron,
((CASE WHEN d.pret_cu_tva = 1 THEN round((ROUND(NVL(c.curs, 1) * ROUND(NVL(d.pret, 0), 4) / NVL(c.multiplicator, 1), 4)) / d.proc_tvav, 4) ELSE (ROUND(NVL(c.curs, 1) * ROUND(NVL(d.pret, 0), 4) / NVL(c.multiplicator, 1), 4)) END) - ROUND(NVL(c.curs, 1) * NVL(d.discount_unitar, 4) / NVL(c.multiplicator, 1), 4)) AS pret_unitar_final,
d.cantitate * ((CASE WHEN d.pret_cu_tva = 1 THEN round((ROUND(NVL(c.curs, 1) * ROUND(NVL(d.pret, 0), 4) / NVL(c.multiplicator, 1), 4)) / d.proc_tvav, 4) ELSE (ROUND(NVL(c.curs, 1) * ROUND(NVL(d.pret, 0), 4) / NVL(c.multiplicator, 1), 4)) END) - ROUND(NVL(c.curs, 1) * NVL(d.discount_unitar, 4) / NVL(c.multiplicator, 1), 4)) AS vanzare,
d.cantitate * (((CASE WHEN d.pret_cu_tva = 1 THEN round((ROUND(NVL(c.curs, 1) * ROUND(NVL(d.pret, 0), 4) / NVL(c.multiplicator, 1), 4)) / d.proc_tvav, 4) ELSE (ROUND(NVL(c.curs, 1) * ROUND(NVL(d.pret, 0), 4) / NVL(c.multiplicator, 1), 4)) END) - ROUND(NVL(c.curs, 1) * NVL(d.discount_unitar, 4) / NVL(c.multiplicator, 1), 4)) - d.pret_achizitie) AS marja
FROM VANZARI f
JOIN VANZARI_DETALII d ON d.id_vanzare = f.id_vanzare
LEFT JOIN VANZARI_CURSURI c ON d.id_vanzare = c.id_vanzare
AND d.id_valuta = c.id_valuta
WHERE f.sters = 0 AND d.sters = 0
AND f.tip > 0 AND f.tip NOT IN (7, 8, 9, 24)
AND f.data_act >= ADD_MONTHS(TRUNC(SYSDATE), -24)
AND f.tip > 0 AND f.tip NOT IN (21,22,23,24,25)
AND f.data_act >= ADD_MONTHS(:data_referinta, -24)
AND f.data_act < :data_referinta
),
aggregated AS (
SELECT
@@ -2002,27 +2052,29 @@ vanzari_curente AS (
JOIN vanzari_detalii d ON d.id_vanzare = f.id_vanzare AND d.sters = 0
WHERE f.sters = 0
AND f.tip > 0 AND f.tip NOT IN (7, 8, 9, 24)
AND f.data_act >= ADD_MONTHS(TRUNC(SYSDATE), -12)
AND f.data_act >= ADD_MONTHS(:data_referinta, -12)
AND f.data_act < :data_referinta
),
sold_clienti_curent AS (
SELECT SUM(CASE WHEN b.solddeb > b.soldcred THEN b.solddeb - b.soldcred ELSE 0 END) AS total_creante
FROM vbalanta_parteneri b
WHERE b.cont LIKE '4111%'
AND b.an = EXTRACT(YEAR FROM SYSDATE)
AND b.luna = EXTRACT(MONTH FROM SYSDATE)
AND b.an = EXTRACT(YEAR FROM (:data_referinta - 1))
AND b.luna = EXTRACT(MONTH FROM (:data_referinta - 1))
),
achizitii_curente AS (
SELECT SUM(ABS(r.cant * r.pret)) AS total_achizitii
FROM vrul r
WHERE r.id_tip_rulaj = 1 AND r.cant > 0
AND r.dataact >= ADD_MONTHS(TRUNC(SYSDATE), -12)
AND r.dataact >= ADD_MONTHS(:data_referinta, -12)
AND r.dataact < :data_referinta
),
sold_furnizori_curent AS (
SELECT SUM(CASE WHEN b.soldcred > b.solddeb THEN b.soldcred - b.solddeb ELSE 0 END) AS total_datorii
FROM vbalanta_parteneri b
WHERE b.cont LIKE '401%'
AND b.an = EXTRACT(YEAR FROM SYSDATE)
AND b.luna = EXTRACT(MONTH FROM SYSDATE)
AND b.an = EXTRACT(YEAR FROM (:data_referinta - 1))
AND b.luna = EXTRACT(MONTH FROM (:data_referinta - 1))
),
-- Metrici anterioare (aproximare - vanzari an anterior)
vanzari_anterioare AS (
@@ -2032,30 +2084,32 @@ vanzari_anterioare AS (
JOIN vanzari_detalii d ON d.id_vanzare = f.id_vanzare AND d.sters = 0
WHERE f.sters = 0
AND f.tip > 0 AND f.tip NOT IN (7, 8, 9, 24)
AND f.data_act >= ADD_MONTHS(TRUNC(SYSDATE), -24)
AND f.data_act < ADD_MONTHS(TRUNC(SYSDATE), -12)
AND f.data_act >= ADD_MONTHS(:data_referinta, -24)
AND f.data_act < :data_referinta
AND f.data_act < ADD_MONTHS(:data_referinta, -12)
),
achizitii_anterioare AS (
SELECT SUM(ABS(r.cant * r.pret)) AS total_achizitii
FROM vrul r
WHERE r.id_tip_rulaj = 1 AND r.cant > 0
AND r.dataact >= ADD_MONTHS(TRUNC(SYSDATE), -24)
AND r.dataact < ADD_MONTHS(TRUNC(SYSDATE), -12)
AND r.dataact >= ADD_MONTHS(:data_referinta, -24)
AND r.dataact < :data_referinta
AND r.dataact < ADD_MONTHS(:data_referinta, -12)
),
-- Solduri anterioare (aproximare - luna curenta anul trecut)
sold_clienti_anterior AS (
SELECT SUM(CASE WHEN b.solddeb > b.soldcred THEN b.solddeb - b.soldcred ELSE 0 END) AS total_creante
FROM vbalanta_parteneri b
WHERE b.cont LIKE '4111%'
AND b.an = EXTRACT(YEAR FROM SYSDATE) - 1
AND b.luna = EXTRACT(MONTH FROM SYSDATE)
AND b.an = EXTRACT(YEAR FROM (:data_referinta - 1)) - 1
AND b.luna = EXTRACT(MONTH FROM (:data_referinta - 1))
),
sold_furnizori_anterior AS (
SELECT SUM(CASE WHEN b.soldcred > b.solddeb THEN b.soldcred - b.solddeb ELSE 0 END) AS total_datorii
FROM vbalanta_parteneri b
WHERE b.cont LIKE '401%'
AND b.an = EXTRACT(YEAR FROM SYSDATE) - 1
AND b.luna = EXTRACT(MONTH FROM SYSDATE)
AND b.an = EXTRACT(YEAR FROM (:data_referinta - 1)) - 1
AND b.luna = EXTRACT(MONTH FROM (:data_referinta - 1))
)
SELECT
'DSO (Zile incasare)' AS indicator,
@@ -2105,7 +2159,8 @@ vanzari_curent AS (
JOIN vanzari_detalii d ON d.id_vanzare = f.id_vanzare AND d.sters = 0
WHERE f.sters = 0
AND f.tip > 0 AND f.tip NOT IN (7, 8, 9, 24)
AND f.data_act >= ADD_MONTHS(TRUNC(SYSDATE), -12)
AND f.data_act >= ADD_MONTHS(:data_referinta, -12)
AND f.data_act < :data_referinta
GROUP BY f.id_part
),
ranked_curent AS (
@@ -2129,8 +2184,9 @@ vanzari_anterior AS (
JOIN vanzari_detalii d ON d.id_vanzare = f.id_vanzare AND d.sters = 0
WHERE f.sters = 0
AND f.tip > 0 AND f.tip NOT IN (7, 8, 9, 24)
AND f.data_act >= ADD_MONTHS(TRUNC(SYSDATE), -24)
AND f.data_act < ADD_MONTHS(TRUNC(SYSDATE), -12)
AND f.data_act >= ADD_MONTHS(:data_referinta, -24)
AND f.data_act < :data_referinta
AND f.data_act < ADD_MONTHS(:data_referinta, -12)
GROUP BY f.id_part
),
ranked_anterior AS (
@@ -2220,14 +2276,15 @@ WITH base_data AS (
WHEN d.cont = '301' THEN 'Materii prime'
ELSE 'Marfa revanduta'
END AS linie_business,
CASE WHEN f.data_act >= ADD_MONTHS(TRUNC(SYSDATE), -12) THEN 'CURENT' ELSE 'ANTERIOR' END AS perioada,
CASE WHEN f.data_act >= ADD_MONTHS(:data_referinta, -12) THEN 'CURENT' ELSE 'ANTERIOR' END AS perioada,
d.cantitate * CASE WHEN d.pret_cu_tva = 1 THEN d.pret / (1 + d.proc_tvav/100) ELSE d.pret END AS vanzare,
d.cantitate * (CASE WHEN d.pret_cu_tva = 1 THEN d.pret / (1 + d.proc_tvav/100) ELSE d.pret END - d.pret_achizitie) AS marja
FROM VANZARI f
JOIN VANZARI_DETALII d ON d.id_vanzare = f.id_vanzare
WHERE f.sters = 0 AND d.sters = 0
AND f.tip > 0 AND f.tip NOT IN (7, 8, 9, 24)
AND f.data_act >= ADD_MONTHS(TRUNC(SYSDATE), -24)
AND f.data_act >= ADD_MONTHS(:data_referinta, -24)
AND f.data_act < :data_referinta
)
SELECT
linie_business,