commit 92dc8c7b32e1b4c9eb59628ef0f7c08e0fd46039 Author: Marius Mutu Date: Mon Sep 21 00:02:30 2026 +0300 solduri2roa: balante SAGA PDF -> xlsx initializare ROACONT Extragere pe coordonate (pdfplumber), generarea celor doua xlsx pentru FUNDATIA si MASTER 12/2025, regulile de mapare si rapoartele de verificare. Co-Authored-By: Claude Opus 5 (1M context) Claude-Session: https://claude.ai/code/session_01BdA5a3ECKFD6Citf1ptPZu diff --git a/.gitignore b/.gitignore new file mode 100644 index 0000000..7a60b85 --- /dev/null +++ b/.gitignore @@ -0,0 +1,2 @@ +__pycache__/ +*.pyc diff --git a/CLAUDE.md b/CLAUDE.md new file mode 100644 index 0000000..268174e --- /dev/null +++ b/CLAUDE.md @@ -0,0 +1,33 @@ +# solduri2roa + +Convertor balante SAGA (PDF) -> xlsx de initializare solduri ROACONT. + +## Mediu +- `py` (Python 3.13). Instalate: pdfplumber, openpyxl. Fara alte dependinte. +- Nu folosi `sed -i` (corupe fisierele). Scrie cu heredoc sau Python. +- `D:\ROA\ROACONT` = read-only. Nu comite (git/svn) fara aprobare. + +## Fisiere +| | | +|---|---| +| `extract_balanta.py` | PDF -> `balanta_.csv` (pdfplumber pe coordonate) | +| `genereaza_xlsx.py` | CSV -> `init___.xlsx` | +| `init_facturi_balanta_note.xlsx` | sablonul ROA (rand 1 = coloane, 2-13 instructiuni, 20+ exemple) | +| `docs/decizii_import.md` | **regulile de mapare - citeste intai** | +| `docs/conturi_cu_analitice.md` | per cont: ANALITIC sau PARTENER (confirmat de Marius) | +| `docs/config_cont_ireg.md` | `CONFIG_CONT_IREG` din Oracle local; `CONT` e VARCHAR2(4) | +| `docs/raport_form_init_balanta.md` | semantica formularului de import ROACONT | +| `docs/plan_solduri2roa.md` | etapele | + +## Reguli care se uita usor +- `pdftotext` decaleaza coloanele. Doar pdfplumber, grupare pe `top`, coloane dupa `x1`. +- `totdeb`/`totcred` = **sume totale**, nu solduri (bilantul/CPP se bazeaza pe ele). +- In xlsx intra **doar frunzele**; importul reface sinteticul din suma analiticelor. +- Conturile cu parteneri nu primesc analitice: rand `BALANTA` pe sintetic + cate un `FACTURA` per partener. +- `cont` <= 4 car., `acont` <= 4 car. Analitic SAGA lung -> cifre concatenate (`1171.01.12` -> `0112`). +- SAGA neteaza D/C la sintetice: diferentele se calculeaza **pe net**. Net != 0 -> analitic/partener de diferenta. +- Nu ajusta cifre ca sa treaca o verificare. Raporteaza. + +## Verificari obligatorii inainte de a declara gata +`SUM(totdeb)=SUM(totcred)`; total = randul "Totaluri:" din PDF; fiecare frunza din CSV apare exact o data; +per cont cu parteneri `SUM(sold FACTURA)` = netul sinteticului; fara `(cont,acont)` duplicat. diff --git a/IBB 31.12.2025.pdf b/IBB 31.12.2025.pdf new file mode 100644 index 0000000..1abea7e Binary files /dev/null and b/IBB 31.12.2025.pdf differ diff --git a/MJC 31.12.2025.pdf b/MJC 31.12.2025.pdf new file mode 100644 index 0000000..0dbee2c Binary files /dev/null and b/MJC 31.12.2025.pdf differ diff --git a/balanta_FUNDATIA.csv b/balanta_FUNDATIA.csv new file mode 100644 index 0000000..160337a --- /dev/null +++ b/balanta_FUNDATIA.csv @@ -0,0 +1,89 @@ +pagina,cont,denumire,prec_d,prec_c,rulaj_d,rulaj_c,total_d,total_c,sold_d,sold_c,este_total +1,101,CAPITAL SOCIAL,0.0,15000.0,0.0,0.0,0.0,15000.0,0.0,15000.0,0 +1,1171,REZULTATUL REPORTAT - PROFITUL NEREP./ PIREDERE NEACOP.,629448.54,0.0,144159.56,0.0,773608.1,0.0,773608.1,0.0,0 +1,1171.01,REZ. REPORTAT PT. EXCEDENT NEREP. SAU DEFICIT NEACOP. - AFSP,629448.54,0.0,144159.56,0.0,773608.1,0.0,773608.1,0.0,0 +1,1171.01.01,REZULTAT REPORTAT - 2013,7245.69,0.0,0.0,0.0,7245.69,0.0,7245.69,0.0,0 +1,1171.01.02,REZULTAT REPORTAT- 2014,0.0,462166.48,0.0,0.0,0.0,462166.48,0.0,462166.48,0 +1,1171.01.03,REZULTAT REPORTAT- 2015,62733.0,0.0,0.0,0.0,62733.0,0.0,62733.0,0.0,0 +1,1171.01.04,REZULTAT REPORTAT 2016,463593.57,0.0,0.0,0.0,463593.57,0.0,463593.57,0.0,0 +1,1171.01.05,REZULTAT REPORTAT 2017,64580.26,0.0,0.0,0.0,64580.26,0.0,64580.26,0.0,0 +1,1171.01.06,REZULTAT REPORTAT 2018,53819.82,0.0,0.0,0.0,53819.82,0.0,53819.82,0.0,0 +1,1171.01.07,REPORTAT PROFIT/PIERDERE 2019,0.0,277665.19,0.0,0.0,0.0,277665.19,0.0,277665.19,0 +1,1171.01.08,REPORTAT PROFIT/PIERDERE 2020,35546.5,0.0,0.0,0.0,35546.5,0.0,35546.5,0.0,0 +1,1171.01.09,REPORTAT PROFIT/PIERDERE 2021,67800.91,0.0,0.0,0.0,67800.91,0.0,67800.91,0.0,0 +1,1171.01.10,REPORTAT PROFIT/PIERDERE 2022,106630.74,0.0,0.0,0.0,106630.74,0.0,106630.74,0.0,0 +1,1171.01.11,REPORTAT PROFIT/PIERDERE 2023,507329.72,0.0,0.0,0.0,507329.72,0.0,507329.72,0.0,0 +1,1171.01.12,REPORTAT PROFIT/PIERDERE 2024,0.0,0.0,144159.56,0.0,144159.56,0.0,144159.56,0.0,0 +1,1211,EXCEDENT SAU DEFICIT PRIVIND AFSP,164431.54,0.0,130661.51,144159.56,295093.05,144159.56,150933.49,0.0,0 +1,1211.01,EXCEDENT SAU DEFICIT PRIVIND AFSP,164431.54,0.0,130661.51,144159.56,295093.05,144159.56,150933.49,0.0,0 +1,,Total sume clasa 1,793880.08,15000.0,274821.07,144159.56,1068701.15,159159.56,924541.59,15000.0,1 +1,2111,TERENURI,100000.0,0.0,0.0,0.0,100000.0,0.0,100000.0,0.0,0 +1,2111.03,TEREN MOGOSOAIA -260MP /NR CADASTRU 61309,100000.0,0.0,0.0,0.0,100000.0,0.0,100000.0,0.0,0 +1,212,CONSTRUCTII,1408257.53,0.0,0.0,0.0,1408257.53,0.0,1408257.53,0.0,0 +1,212.01,IMOBIL TEREN + CLADIRE MOGOSOAIA,241612.68,0.0,0.0,0.0,241612.68,0.0,241612.68,0.0,0 +1,212.02,IMOBIL APARTAMENT GH. BARITIU,244085.95,0.0,0.0,0.0,244085.95,0.0,244085.95,0.0,0 +1,212.03,IMOBIL MIERCANI TEREN + CONSTRUCTIE,331042.5,0.0,0.0,0.0,331042.5,0.0,331042.5,0.0,0 +1,212.04,IMOBIL STR COCARESCU NR 22,392986.4,0.0,0.0,0.0,392986.4,0.0,392986.4,0.0,0 +1,212.05,IMOBIL MOGOSOAIA-NR CADASTRU 61309,198530.0,0.0,0.0,0.0,198530.0,0.0,198530.0,0.0,0 +1,213,"INSTALATII TEHNICE,MIJ. TRANSP., ANIMALE SI PLANTATII",6300.0,0.0,0.0,0.0,6300.0,0.0,6300.0,0.0,0 +1,2133,MIJLOACE DE TRANSPORT C,250985.0,0.0,0.0,0.0,250985.0,0.0,250985.0,0.0,0 +2,214,"MOBILIER,APARATURA BIROTICA,ETC.",30950.0,0.0,0.0,0.0,30950.0,0.0,30950.0,0.0,0 +2,2812,AMORT. CONSTRUCTIILOR,0.0,409032.32,0.0,55016.88,0.0,464049.2,0.0,464049.2,0 +2,2813,"AMORT. INST., MIJ. DE TRANSPORT",0.0,177781.03,0.0,62746.26,0.0,240527.29,0.0,240527.29,0 +2,2814,AMORT. ALTOR IMOBILIZARI CORP.,0.0,16764.62,0.0,3868.74,0.0,20633.36,0.0,20633.36,0 +2,2814.01,"AMORT. AP. SI INST. DE MASURARE, CONTROL SI REGLARE - AFSP",0.0,16764.62,0.0,3868.74,0.0,20633.36,0.0,20633.36,0 +2,,Total sume clasa 2,1796492.53,603577.97,0.0,121631.88,1796492.53,725209.85,1796492.53,725209.85,1 +2,401,FURNIZORI,0.0,305673.95,0.0,9029.63,0.0,314703.58,0.0,314703.58,0 +2,401.00004,GTC AUTO TRADE,0.0,0.3,0.0,0.0,0.0,0.3,0.0,0.3,0 +2,401.00018,HOSTVISION SRL,0.0,143.92,0.0,470.18,0.0,614.1,0.0,614.1,0 +2,401.00043,BRIT MOTOR AG SRL,0.0,374.85,0.0,6265.77,0.0,6640.62,0.0,6640.62,0 +2,401.00045,TRACOM IMPEX S.R.L.,0.0,0.0,0.0,1392.75,0.0,1392.75,0.0,1392.75,0 +2,401.00049,APA CANAL ILFOV,0.0,604.89,0.0,521.93,0.0,1126.82,0.0,1126.82,0 +2,401.00050,SC CEGIM SRL,0.0,5599.99,0.0,0.0,0.0,5599.99,0.0,5599.99,0 +2,401.00051,S.C. CRAMA SPARLENI SRL,0.0,420.0,0.0,0.0,0.0,420.0,0.0,420.0,0 +2,401.00053,POPESCU LUMINITA-MACOVICIUC VERONICA,0.0,298530.0,0.0,0.0,0.0,298530.0,0.0,298530.0,0 +2,401.00054,DEDEMAN SRL,0.0,0.0,0.0,190.0,0.0,190.0,0.0,190.0,0 +2,401.00055,AGROMECANIC IMPEX SRL,0.0,0.0,0.0,189.0,0.0,189.0,0.0,189.0,0 +2,409,FURNIZORI DEBITORI,-0.01,0.0,0.0,0.0,-0.01,0.0,-0.01,0.0,0 +2,4092,FUR.-DEBIT PT.PRESTARI SERVICII,809.33,0.0,0.0,0.0,809.33,0.0,809.33,0.0,0 +2,4092.1,HOSTVISION,547.65,0.0,0.0,0.0,547.65,0.0,547.65,0.0,0 +2,4092.2,ROMARG,217.7,0.0,0.0,0.0,217.7,0.0,217.7,0.0,0 +2,4092.3,HORVARTH ALINA GABRIELA PROMISIUNE VZ-C,43.98,0.0,0.0,0.0,43.98,0.0,43.98,0.0,0 +2,4111,CLIENTI,15126.48,0.0,0.0,0.0,15126.48,0.0,15126.48,0.0,0 +2,4111.00004,EM INTERNATIONAL SERVICES GROUP S.R.L.,15126.48,0.0,0.0,0.0,15126.48,0.0,15126.48,0.0,0 +2,4411,IMPOZITUL PE PROFIT,0.0,26986.0,0.0,0.0,0.0,26986.0,0.0,26986.0,0 +2,446,ALTE IMPOZITE SI TAXE,0.0,-485.0,0.0,0.0,0.0,-485.0,0.0,-485.0,0 +2,446.1,IMPOZIT TEREN,0.0,-485.0,0.0,0.0,0.0,-485.0,0.0,-485.0,0 +2,4482,ALTE CREANTE FATA DE BUGET,17264.38,0.0,0.0,0.0,17264.38,0.0,17264.38,0.0,0 +2,4551,ASOCIATI-CONTURI CURENTE,0.0,1571531.33,0.0,0.0,0.0,1571531.33,0.0,1571531.33,0 +2,4551.01,IONESCU VALENTIN GHEORGHE,0.0,1383131.33,0.0,0.0,0.0,1383131.33,0.0,1383131.33,0 +2,4551.02,EURO ANTR RO12 PIRB 4250 7735 C 0200 1000,0.0,188400.0,0.0,0.0,0.0,188400.0,0.0,188400.0,0 +3,461,DEBITORI DIVERSI,477938.37,0.0,0.0,0.0,477938.37,0.0,477938.37,0.0,0 +3,461.01,SISTEME INTERNATIONALE DE AFACERI,15031.49,0.0,0.0,0.0,15031.49,0.0,15031.49,0.0,0 +3,461.02,IMPRUMUT ASOC. NO-ADD,10800.0,0.0,0.0,0.0,10800.0,0.0,10800.0,0.0,0 +3,461.03,TEMPLUM,29445.23,0.0,0.0,0.0,29445.23,0.0,29445.23,0.0,0 +3,461.04,DEBITOR EURO ANTREPRENOR,417000.01,0.0,0.0,0.0,417000.01,0.0,417000.01,0.0,0 +3,461.06,ADRIAN CRISTESCU,5000.0,0.0,0.0,0.0,5000.0,0.0,5000.0,0.0,0 +3,461.07,FUNDATIA DOMENIU OTETELESANU,661.64,0.0,0.0,0.0,661.64,0.0,661.64,0.0,0 +3,462,CREDITORI DIVERSI,0.0,3400771.0,0.0,0.0,0.0,3400771.0,0.0,3400771.0,0 +3,462.01,TEMPLUM PLUS,0.0,988640.0,0.0,0.0,0.0,988640.0,0.0,988640.0,0 +3,462.04,CREDITOR EURO PRO CONSTRUCT,0.0,1869897.0,0.0,0.0,0.0,1869897.0,0.0,1869897.0,0 +3,462.05,MODREA ALAIN FLORIN,0.0,542234.0,0.0,0.0,0.0,542234.0,0.0,542234.0,0 +3,473,DEC. DIN OP. IN CURS DE CLARIF.,14094.02,0.0,0.0,0.0,14094.02,0.0,14094.02,0.0,0 +3,,Total sume clasa 4,525232.57,5304477.28,0.0,9029.63,525232.57,5313506.91,525232.57,5313506.91,1 +3,5121,CONTURI LA BANCA IN LEI,81966.8,0.0,0.0,0.0,81966.8,0.0,81966.8,0.0,0 +3,5121.01,RO73 BACX 0000 0008 7243 0001,81966.8,0.0,0.0,0.0,81966.8,0.0,81966.8,0.0,0 +3,5124,CONTURI LA BANCA IN DEVIZE,2492540.28,0.0,0.0,0.0,2492540.28,0.0,2492540.28,0.0,0 +3,5124.01,RO89 BACX 0000 0008 7243 0004 - EURO,2492540.28,0.0,0.0,0.0,2492540.28,0.0,2492540.28,0.0,0 +3,5125,SUME IN CURS DE DECONTARE,160509.43,0.0,0.0,0.0,160509.43,0.0,160509.43,0.0,0 +3,5125.03,SUME PROPRIRI ANAF,1490.02,0.0,0.0,0.0,1490.02,0.0,1490.02,0.0,0 +3,5125.04,SUME IN CURS DECONTARE,159019.41,0.0,0.0,0.0,159019.41,0.0,159019.41,0.0,0 +3,5311,CASA IN LEI,72433.56,0.0,0.0,0.0,72433.56,0.0,72433.56,0.0,0 +3,,Total sume clasa 5,2807450.07,0.0,0.0,0.0,2807450.07,0.0,2807450.07,0.0,1 +3,6024,CHELT. CU PIESELE DE SCHIMB,0.0,0.0,1392.75,1392.75,1392.75,1392.75,0.0,0.0,0 +3,6051,CHELT. PRIVIND CONSUMUL DE ENERGIE,0.0,0.0,521.93,521.93,521.93,521.93,0.0,0.0,0 +3,611,CHELT. CU INTRETINEREA SI REP.,0.0,0.0,6265.77,6265.77,6265.77,6265.77,0.0,0.0,0 +3,628,ALTE CHELT.CU SERV.LA TERTI,0.0,0.0,849.18,849.18,849.18,849.18,0.0,0.0,0 +3,6811,CHELT. DE EXPL.CU AMORT. IMOB.,0.0,0.0,121631.88,121631.88,121631.88,121631.88,0.0,0.0,0 +3,,Total sume clasa 6,0.0,0.0,130661.51,130661.51,130661.51,130661.51,0.0,0.0,1 +4,,Totaluri:,5923055.25,5923055.25,405482.58,405482.58,6328537.83,6328537.83,6053716.76,6053716.76,1 diff --git a/balanta_MASTERJOB.csv b/balanta_MASTERJOB.csv new file mode 100644 index 0000000..170a50f --- /dev/null +++ b/balanta_MASTERJOB.csv @@ -0,0 +1,89 @@ +pagina,cont,denumire,prec_d,prec_c,rulaj_d,rulaj_c,total_d,total_c,sold_d,sold_c,este_total +1,1012,CAPITAL SUBSCRIS VARSAT,0.0,90000.0,0.0,0.0,0.0,90000.0,0.0,90000.0,0 +1,117,REZULTATUL REPORTAT,47431.79,0.0,0.0,0.0,47431.79,0.0,47431.79,0.0,0 +1,117.1,PIERDERE REPORTATA,4280.23,0.0,0.0,0.0,4280.23,0.0,4280.23,0.0,0 +1,117.2,PIERDERE REPORTATA,7743.14,0.0,0.0,0.0,7743.14,0.0,7743.14,0.0,0 +1,117.3,PIERDERE REPORTATA,7037.7,0.0,0.0,0.0,7037.7,0.0,7037.7,0.0,0 +1,117.4,PIERDERE 2007,7531.03,0.0,0.0,0.0,7531.03,0.0,7531.03,0.0,0 +1,117.5,PIERDERE 2008,5731.08,0.0,0.0,0.0,5731.08,0.0,5731.08,0.0,0 +1,117.6,PIERDERE 2009,3421.65,0.0,0.0,0.0,3421.65,0.0,3421.65,0.0,0 +1,117.7,PIERDERE 2010,2764.43,0.0,0.0,0.0,2764.43,0.0,2764.43,0.0,0 +1,117.8,PIERDERE 2011,6286.66,0.0,0.0,0.0,6286.66,0.0,6286.66,0.0,0 +1,1171,REZULTATUL REPORTAT - PROFITUL NEREP./ PIREDERE NEACOP.,106880.87,0.0,103625.3,0.0,210506.17,0.0,210506.17,0.0,0 +1,121,PROFIT SI PIERDERE,103625.3,0.0,100135.51,103625.3,203760.81,103625.3,100135.51,0.0,0 +1,,Total sume clasa 1,257937.96,90000.0,203760.81,103625.3,461698.77,193625.3,358073.47,90000.0,1 +1,201,CHELTUIELI DE CONSTITUIRE,581.27,0.0,0.0,0.0,581.27,0.0,581.27,0.0,0 +1,2111,TERENURI,439966.6,0.0,0.0,0.0,439966.6,0.0,439966.6,0.0,0 +1,2111.01,RISNOV- BRASOV,439966.6,0.0,0.0,0.0,439966.6,0.0,439966.6,0.0,0 +1,235,INVESTITII IMOBILIARE IN CURS DE EXECUTIE,292.0,0.0,0.0,0.0,292.0,0.0,292.0,0.0,0 +1,2813,"AMORT. INSTALATIILOR, MIJ. DE TRANSPORT",0.0,249314.46,0.0,87993.3,0.0,337307.76,0.0,337307.76,0 +1,,Total sume clasa 2,440839.87,249314.46,0.0,87993.3,440839.87,337307.76,440839.87,337307.76,1 +1,303,MAT. DE NATURA OB. DE INVENTAR,16802.46,0.0,0.0,0.0,16802.46,0.0,16802.46,0.0,0 +1,371,MARFURI,38850.0,0.0,0.0,0.0,38850.0,0.0,38850.0,0.0,0 +1,371.01,FURAJE PASTRAV,38850.0,0.0,0.0,0.0,38850.0,0.0,38850.0,0.0,0 +1,,Total sume clasa 3,55652.46,0.0,0.0,0.0,55652.46,0.0,55652.46,0.0,1 +1,401,FURNIZORI,0.0,534966.78,0.0,12142.21,0.0,547108.99,0.0,547108.99,0 +1,401.00001,MEDIAROM COMUNICATIONS,0.0,14293.76,0.0,0.0,0.0,14293.76,0.0,14293.76,0 +1,401.00003,TEMPLUM PLUS,0.0,500.0,0.0,0.0,0.0,500.0,0.0,500.0,0 +1,401.00006,BIROU INDIVIDUAL NOTARIAL GEORGE TRAGONE,0.0,952.0,0.0,0.0,0.0,952.0,0.0,952.0,0 +1,401.00007,ACVATIC TES S.R.L.,0.0,439966.6,0.0,0.0,0.0,439966.6,0.0,439966.6,0 +1,401.00008,DREAM FISH S.R.L.,0.0,38850.0,0.0,0.0,0.0,38850.0,0.0,38850.0,0 +1,401.00009,LEROY MERLIN ROMANIA SRL C,0.0,2902.91,0.0,0.0,0.0,2902.91,0.0,2902.91,0 +2,401.00010,SERVICE ONLAPTOP S.R.L.,0.0,1230.0,0.0,0.0,0.0,1230.0,0.0,1230.0,0 +2,401.00011,PET PRODUCT SRL,0.0,445.05,0.0,0.0,0.0,445.05,0.0,445.05,0 +2,401.00012,BIROU INDIVIDUAL NOTARIAL PIELEANU DANIELA,0.0,4879.0,0.0,0.0,0.0,4879.0,0.0,4879.0,0 +2,401.00013,CREATIV EXPERT CONSTRUCT S.R.L.,0.0,3300.0,0.0,0.0,0.0,3300.0,0.0,3300.0,0 +2,401.00014,,0.0,16802.46,0.0,0.0,0.0,16802.46,0.0,16802.46,0 +2,401.00015,ANDREEA BEATRICE VASILE,0.0,10000.0,0.0,0.0,0.0,10000.0,0.0,10000.0,0 +2,401.00017,TIRES AND PARTS SRL,0.0,845.0,0.0,400.0,0.0,1245.0,0.0,1245.0,0 +2,401.00023,ANGLO CARS S.R.L.,0.0,0.0,0.0,3700.9,0.0,3700.9,0.0,3700.9,0 +2,401.00024,DAW BENTA SRL,0.0,0.0,0.0,1948.01,0.0,1948.01,0.0,1948.01,0 +2,401.00025,ROMSYSTEMS S.R.L.,0.0,0.0,0.0,1380.4,0.0,1380.4,0.0,1380.4,0 +2,401.00026,UNIVERSAL GRUP SRL,0.0,0.0,0.0,1380.9,0.0,1380.9,0.0,1380.9,0 +2,401.00027,SEBASTIAN CONSTRUCTII MONTAJ SRL,0.0,0.0,0.0,3332.0,0.0,3332.0,0.0,3332.0,0 +2,4092,FURNIZORI — DEBITORI PT. PRESTARI DE SERVICII,4.0,0.0,0.0,0.0,4.0,0.0,4.0,0.0,0 +2,4092.01,ICI,4.0,0.0,0.0,0.0,4.0,0.0,4.0,0.0,0 +2,4111,CLIENTI,12000.0,0.0,0.0,0.0,12000.0,0.0,12000.0,0.0,0 +2,4111.00001,NEW HOME CONSTRUCT S.A.,12000.0,0.0,0.0,0.0,12000.0,0.0,12000.0,0.0,0 +2,421,PERSONAL - SALARII DATORATE,0.0,17689.0,0.0,0.0,0.0,17689.0,0.0,17689.0,0 +2,4315,CONTR. DE ASIGURARI SOCIALE,0.0,24297.0,0.0,0.0,0.0,24297.0,0.0,24297.0,0 +2,4316,CONTR. DE ASIGURARI SOCIALE DE SANATATE,0.0,10905.0,0.0,0.0,0.0,10905.0,0.0,10905.0,0 +2,436,CONTR. ASIGURATORIE DE MUNCA,0.0,1128.0,0.0,0.0,0.0,1128.0,0.0,1128.0,0 +2,4372,CONTRIBUTIA PERSONALULUI LA FONDUL DE SOMAJ,0.0,52.0,0.0,0.0,0.0,52.0,0.0,52.0,0 +2,441,IMPOZITUL PE PROFIT SI ALTE IMPOZITE,0.0,2567.0,0.0,0.0,0.0,2567.0,0.0,2567.0,0 +2,441.01,IMPOZIT FORFETAR,0.0,2567.0,0.0,0.0,0.0,2567.0,0.0,2567.0,0 +2,4411,IMPOZITUL PE PROFIT,0.0,7804.0,0.0,0.0,0.0,7804.0,0.0,7804.0,0 +2,4418,IMPOZITUL PE VENIT,0.0,360.0,0.0,0.0,0.0,360.0,0.0,360.0,0 +2,4424,TVA DE RECUPERAT,4669.56,0.0,0.0,0.0,4669.56,0.0,4669.56,0.0,0 +2,444,IMPOZITUL PE VENITURI DE NATURA SALARIILOR,0.0,3105.0,0.0,0.0,0.0,3105.0,0.0,3105.0,0 +2,447,FONDURI SPECIALE TAXE SI VARSAMINTE ASIMILATE,0.0,47.0,0.0,0.0,0.0,47.0,0.0,47.0,0 +2,447.01,COMISION ITM C,0.0,47.0,0.0,0.0,0.0,47.0,0.0,47.0,0 +3,4551,ACTIONARI/ASOCIATI - CONTURI CURENTE,0.0,751724.61,0.0,0.0,0.0,751724.61,0.0,751724.61,0 +3,4551.01,IONESCU VALENTIN,0.0,729308.61,0.0,0.0,0.0,729308.61,0.0,729308.61,0 +3,4551.02,TOMA IONEL VIOREL RO55 RZBR 0000 0600 1338 1717,0.0,22416.0,0.0,0.0,0.0,22416.0,0.0,22416.0,0 +3,461,DEBITORI DIVERSI,69289.0,0.0,0.0,0.0,69289.0,0.0,69289.0,0.0,0 +3,461.01,SISTEME INTARNATIONALE DE AF.,8289.0,0.0,0.0,0.0,8289.0,0.0,8289.0,0.0,0 +3,461.02,HABITAT SI AMBIENT,20000.0,0.0,0.0,0.0,20000.0,0.0,20000.0,0.0,0 +3,461.03,DEBITORI DIVERSI,41000.0,0.0,0.0,0.0,41000.0,0.0,41000.0,0.0,0 +3,462,CREDITORI DIVERSI,0.0,9810.0,0.0,0.0,0.0,9810.0,0.0,9810.0,0 +3,462.01,CREDITORI DIVERSI -IONESCU ALINA,0.0,3350.0,0.0,0.0,0.0,3350.0,0.0,3350.0,0 +3,462.02,CREDITORI DIVERSI - REZIDENT COM,0.0,700.0,0.0,0.0,0.0,700.0,0.0,700.0,0 +3,462.03,CREDITORI DIVERSI - IONESCU VALENTIN,0.0,760.0,0.0,0.0,0.0,760.0,0.0,760.0,0 +3,462.05,CREDITOR C.S.C.,0.0,5000.0,0.0,0.0,0.0,5000.0,0.0,5000.0,0 +3,473,DECONTARI DIN OPERATIUNI IN CURS DE CLARIFICARE,0.0,310905.94,0.0,0.0,0.0,310905.94,0.0,310905.94,0 +3,,Total sume clasa 4,85962.56,1675361.33,0.0,12142.21,85962.56,1687503.54,85962.56,1687503.54,1 +3,5121,CONTURI LA BANCA IN LEI,15730.61,0.0,0.0,0.0,15730.61,0.0,15730.61,0.0,0 +3,5121.01,PIRAEUS BANK - RON,0.0,20.8,0.0,0.0,0.0,20.8,0.0,20.8,0 +3,5121.02,RO45 PIRB 4250 7073 2600 1000 FIRST BANK,15599.25,0.0,0.0,0.0,15599.25,0.0,15599.25,0.0,0 +3,5124,CONTURI LA BANCA IN VALUTA,1060090.96,0.0,0.0,0.0,1060090.96,0.0,1060090.96,0.0,0 +3,5124.01,BANCA (EURO),5.71,0.0,0.0,0.0,5.71,0.0,5.71,0.0,0 +3,5124.02,RO11 PIRB 4250 7073 2600 2000 FIRST,1060085.25,0.0,0.0,0.0,1060085.25,0.0,1060085.25,0.0,0 +3,5125,SUME IN CURS DE DECONTARE,0.5,0.0,0.0,0.0,0.5,0.0,0.5,0.0,0 +3,5125.03,POPRIRE,0.5,0.0,0.0,0.0,0.5,0.0,0.5,0.0,0 +3,5311,CASA IN LEI,98460.87,0.0,0.0,0.0,98460.87,0.0,98460.87,0.0,0 +3,,Total sume clasa 5,1174282.94,0.0,0.0,0.0,1174282.94,0.0,1174282.94,0.0,1 +3,611,CHELT. CU INTRETINEREA SI REPARATIILE,0.0,0.0,2510.9,2510.9,2510.9,2510.9,0.0,0.0,0 +3,628,ALTE CHELT. CU SERVICIILE EXECUTATE DE TERTI,0.0,0.0,9631.31,9631.31,9631.31,9631.31,0.0,0.0,0 +3,6811,CHELT. DE EXPLOATARE CU AMORTIZAREA IMOBILIZARILOR,0.0,0.0,87993.3,87993.3,87993.3,87993.3,0.0,0.0,0 +3,,Total sume clasa 6,0.0,0.0,100135.51,100135.51,100135.51,100135.51,0.0,0.0,1 +4,,Totaluri:,2014675.79,2014675.79,303896.32,303896.32,2318572.11,2318572.11,2114811.3,2114811.3,1 diff --git a/docs/config_cont_ireg.md b/docs/config_cont_ireg.md new file mode 100644 index 0000000..a058a66 --- /dev/null +++ b/docs/config_cont_ireg.md @@ -0,0 +1,91 @@ +# CONFIG_CONT_IREG (MARIUSM_AUTO@ROA_CENTRAL) + +Sursa: Oracle LOCAL (server dezvoltare ROA_CENTRAL), NU productie. + +## Sursa si conectare + +- DSN (tnsnames.ora, `D:\ROA\instantclient_19_18\tnsnames.ora:206`): `ROA_CENTRAL` = HOST 10.0.20.121, PORT 1521, SERVICE_NAME ROA +- Schema citita: `MARIUSM_AUTO` +- Comanda exacta folosita: + +``` +set TNS_ADMIN=D:\ROA\instantclient_19_18 +set NLS_LANG=ROMANIAN_ROMANIA.AL32UTF8 +sqlplus.exe -S "MARIUSM_AUTO/ROMFASTSOFT@ROA_CENTRAL" +``` + +Parola: din `D:\ROA\ROACONT\docs\oracle_parola_standard.secret` (valoare implicita si in `COMUN\utile\Teste\test_init_env_auto.prg:22`). + +## Structura tabelei (DESC) + +| Coloana | Tip | NULL? | +|---|---|---| +| ID_CONT_IREG | NUMBER | N | +| CONT | VARCHAR2(4) | Y | +| EXPLICATIE | VARCHAR2(50) | Y | +| FEL_CONT | NUMBER | Y | +| CU_INREGISTRARI | NUMBER | Y | +| CU_VENCHELT | NUMBER | N | +| CU_PROC_TVA | NUMBER | N | +| LUNAI | NUMBER | Y | +| ANI | NUMBER | Y | + +Observatie: coloana ceruta ca "denumire" este de fapt `EXPLICATIE`. Tabela are si coloanele `FEL_CONT`, `CU_VENCHELT`, `CU_PROC_TVA`, `LUNAI`, `ANI`. `LUNAI`/`ANI` sunt completate doar pe randul 4511. + +## Randuri (47) + +| ID_CONT_IREG | CONT | EXPLICATIE | FEL_CONT | CU_INREGISTRARI | CU_VENCHELT | CU_PROC_TVA | LUNAI | ANI | +|---|---|---|---|---|---|---|---|---| +| 63 | 1011 | 1011 | 1 | 0 | 0 | 0 | | | +| 59 | 1621 | CREDITE PE TERMEN LUNG | 1 | 1 | 0 | 0 | | | +| 54 | 167 | 167 | 1 | 1 | 0 | 0 | | | +| 61 | 232 | AVANSURI FZ IMOB CORPORALE | 0 | 1 | 0 | 0 | | | +| 62 | 234 | AVANSURI FZ IMOB NECORPORALE | 0 | 1 | 0 | 0 | | | +| 47 | 261 | TITLURI DE PARTICIPARELA FILIALE DIN GRUP | 0 | 1 | 0 | 0 | | | +| 48 | 2678 | CREANTE IMOBILIZATE | 0 | 1 | 0 | 0 | | | +| 53 | 2691 | VARS.REF.TIT.PART.DET.LA FIL.GRUP | 1 | 1 | 0 | 0 | | | +| 60 | 371 | MARFA | 0 | 0 | 0 | 0 | | | +| 1 | 401 | FURNIZORI | 1 | 1 | 0 | 0 | | | +| 73 | 403 | EF. COM. 403 | 1 | 1 | 0 | 0 | | | +| 2 | 404 | FURNIZORI IMOBILIZARI | 1 | 1 | 0 | 0 | | | +| 3 | 408 | FACTURI NESOSITE | 1 | 1 | 0 | 1 | | | +| 4 | 409 | AVANSURI FURNIZORI | 0 | 1 | 0 | 0 | | | +| 56 | 4091 | AVANSURI FURNIZORI | 0 | 1 | 0 | 0 | | | +| 57 | 4092 | AVANSURI FURNIZORI | 0 | 1 | 0 | 0 | | | +| 79 | 4093 | AVANSURI FURNIZORI | 0 | 1 | 0 | 0 | | | +| 80 | 4094 | AVANSURI FURNIZORI | 0 | 1 | 0 | 0 | | | +| 5 | 4111 | CLIENTI | 0 | 1 | 0 | 0 | | | +| 6 | 4118 | CLIENTI INCERTI | 0 | 1 | 0 | 0 | | | +| 72 | 413 | EF. COM. 413 | 0 | 1 | 0 | 0 | | | +| 7 | 418 | FACTURI NEINTOCMITE | 0 | 1 | 0 | 1 | | | +| 8 | 419 | CLIENTI CREDITORI | 1 | 1 | 0 | 1 | | | +| 49 | 426 | DREPTURI DE PERSONAL NERIDICATE | 1 | 1 | 0 | 0 | | | +| 10 | 4281 | ALTE DATORII IN LEG.CU PERS. | 1 | 0 | 0 | 0 | | | +| 11 | 4282 | ALTE CREANTE IN LEGATURA CU PERSONALUL | 0 | 0 | 0 | 0 | | | +| 65 | 4511 | DECONTARI IN CADRUL GRUPULUI | 2 | 1 | 0 | 0 | 1 | 2013 | +| 76 | 4551 | ACTIONARI | 0 | 1 | 0 | 0 | | | +| 68 | 456 | DECONTARI CU ACTIONARII | 0 | 1 | 0 | 0 | | | +| 52 | 457 | DIVIDENDE 457 | 1 | 1 | 0 | 0 | | | +| 14 | 461 | DEBITORI DIVERSI | 0 | 1 | 0 | 0 | | | +| 15 | 462 | CREDITORI DIVERSI | 1 | 1 | 0 | 0 | | | +| 51 | 471 | CHELTUIELI IN AVANS | 0 | 1 | 0 | 0 | | | +| 67 | 472 | VENITURI IN AVANS | 1 | 1 | 0 | 0 | | | +| 75 | 4754 | SUBVENTII INVESTITII | 1 | 1 | 0 | 0 | | | +| 64 | 491 | PROVIZ.DEPREC.CREANTE-CLIENTI | 0 | 0 | 0 | 0 | | | +| 74 | 5081 | DEPOZITE BANCARE | 0 | 0 | 0 | 0 | | | +| 18 | 5121 | BANCA LEI | 0 | 0 | 0 | 0 | | | +| 50 | 5122 | CONT CURENT GARANTII BRD | 0 | 0 | 0 | 0 | | | +| 19 | 5124 | BANCA VALUTA | 0 | 0 | 0 | 0 | | | +| 69 | 5125 | SUME IN CURS DE DECONTARE - POS | 0 | 0 | 0 | 0 | | | +| 70 | 5126 | BANCA LEI TVA DEFALCAT | 0 | 0 | 0 | 0 | | | +| 71 | 5127 | BANCA VALUTA TVA DEFALCAT | 0 | 0 | 0 | 0 | | | +| 20 | 5311 | CASA LEI | 0 | 0 | 0 | 0 | | | +| 21 | 5314 | CASA VALUTA | 0 | 0 | 0 | 0 | | | +| 22 | 542 | ACHIZITORI | 0 | 1 | 0 | 0 | | | +| 58 | 8051 | DOBANDA EXTRABILANTIER | 0 | 1 | 0 | 0 | | | + +Total randuri: 47. + +## Conturi cu CU_INREGISTRARI = 1 + +1621, 167, 232, 234, 261, 2678, 2691, 401, 403, 404, 408, 409, 4091, 4092, 4093, 4094, 4111, 4118, 413, 418, 419, 426, 4511, 4551, 456, 457, 461, 462, 471, 472, 4754, 542, 8051 diff --git a/docs/conturi_cu_analitice.md b/docs/conturi_cu_analitice.md new file mode 100644 index 0000000..ac1e94a --- /dev/null +++ b/docs/conturi_cu_analitice.md @@ -0,0 +1,166 @@ +# Conturi cu analitice in balanta SAGA - analitic in ROA sau partener? + +Propunerea mea e in coloana **Propus**. Marius: corecteaza direct in tabel (scrie ANALITIC sau PARTENER) +sau spune-mi ce schimbi. Sursa: `balanta_FUNDATIA.csv`, `balanta_MASTERJOB.csv`. + +- **ANALITIC** = ramane cont analitic in planul de conturi ROA (acont 4 caractere) si in balanta. +- **PARTENER** = nu se creeaza analitic in ROA; se genereaza rand `FACTURA` per analitic, cu partener + nou (cod fiscal = codul SAGA, ex `401.00027`), iar soldul intra pe contul sintetic cu id_partd/id_partc. + +## FUNDATIA + +| Cont | Denumire | Nr. analitice | Sold total | Propus | +|---|---|---|---|---| +| 1171 | REZULTATUL REPORTAT - PROFITUL NEREP./ PIREDE | 1 | 773,608.10 | **ANALITIC** | +| 1171.01 | REZ. REPORTAT PT. EXCEDENT NEREP. SAU DEFICIT | 12 | 773,608.10 | **ANALITIC** | +| 1211 | EXCEDENT SAU DEFICIT PRIVIND AFSP | 1 | 150,933.49 | **ANALITIC** | +| 2111 | TERENURI | 1 | 100,000.00 | **ANALITIC** | +| 212 | CONSTRUCTII | 5 | 1,408,257.53 | **ANALITIC** | +| 2814 | AMORT. ALTOR IMOBILIZARI CORP. | 1 | -20,633.36 | **ANALITIC** | +| 401 | FURNIZORI | 10 | -314,703.58 | **PARTENER** | +| 4092 | FUR.-DEBIT PT.PRESTARI SERVICII | 3 | 809.33 | **PARTENER** | +| 4111 | CLIENTI | 1 | 15,126.48 | **PARTENER** | +| 446 | ALTE IMPOZITE SI TAXE | 1 | 485.00 | **ANALITIC** | +| 4551 | ASOCIATI-CONTURI CURENTE | 2 | -1,571,531.33 | **PARTENER** | +| 461 | DEBITORI DIVERSI | 6 | 477,938.37 | **PARTENER** | +| 462 | CREDITORI DIVERSI | 3 | -3,400,771.00 | **PARTENER** | +| 5121 | CONTURI LA BANCA IN LEI | 1 | 81,966.80 | **PARTENER** | +| 5124 | CONTURI LA BANCA IN DEVIZE | 1 | 2,492,540.28 | **PARTENER** | +| 5125 | SUME IN CURS DE DECONTARE | 2 | 160,509.43 | **PARTENER** | + +### Detaliu analitice propuse PARTENER + +**401 FURNIZORI** + +| Analitic SAGA | Denumire (nume partener) | Sold D | Sold C | +|---|---|---|---| +| 401.00004 | GTC AUTO TRADE | 0.00 | 0.30 | +| 401.00018 | HOSTVISION SRL | 0.00 | 614.10 | +| 401.00043 | BRIT MOTOR AG SRL | 0.00 | 6,640.62 | +| 401.00045 | TRACOM IMPEX S.R.L. | 0.00 | 1,392.75 | +| 401.00049 | APA CANAL ILFOV | 0.00 | 1,126.82 | +| 401.00050 | SC CEGIM SRL | 0.00 | 5,599.99 | +| 401.00051 | S.C. CRAMA SPARLENI SRL | 0.00 | 420.00 | +| 401.00053 | POPESCU LUMINITA-MACOVICIUC VERONICA | 0.00 | 298,530.00 | +| 401.00054 | DEDEMAN SRL | 0.00 | 190.00 | +| 401.00055 | AGROMECANIC IMPEX SRL | 0.00 | 189.00 | + +**4092 FUR.-DEBIT PT.PRESTARI SERVICII** + +| Analitic SAGA | Denumire (nume partener) | Sold D | Sold C | +|---|---|---|---| +| 4092.1 | HOSTVISION | 547.65 | 0.00 | +| 4092.2 | ROMARG | 217.70 | 0.00 | +| 4092.3 | HORVARTH ALINA GABRIELA PROMISIUNE VZ-C | 43.98 | 0.00 | + +**4111 CLIENTI** + +| Analitic SAGA | Denumire (nume partener) | Sold D | Sold C | +|---|---|---|---| +| 4111.00004 | EM INTERNATIONAL SERVICES GROUP S.R.L. | 15,126.48 | 0.00 | + +**4551 ASOCIATI-CONTURI CURENTE** + +| Analitic SAGA | Denumire (nume partener) | Sold D | Sold C | +|---|---|---|---| +| 4551.01 | IONESCU VALENTIN GHEORGHE | 0.00 | 1,383,131.33 | +| 4551.02 | EURO ANTR RO12 PIRB 4250 7735 C 0200 1000 | 0.00 | 188,400.00 | + +**461 DEBITORI DIVERSI** + +| Analitic SAGA | Denumire (nume partener) | Sold D | Sold C | +|---|---|---|---| +| 461.01 | SISTEME INTERNATIONALE DE AFACERI | 15,031.49 | 0.00 | +| 461.02 | IMPRUMUT ASOC. NO-ADD | 10,800.00 | 0.00 | +| 461.03 | TEMPLUM | 29,445.23 | 0.00 | +| 461.04 | DEBITOR EURO ANTREPRENOR | 417,000.01 | 0.00 | +| 461.06 | ADRIAN CRISTESCU | 5,000.00 | 0.00 | +| 461.07 | FUNDATIA DOMENIU OTETELESANU | 661.64 | 0.00 | + +**462 CREDITORI DIVERSI** + +| Analitic SAGA | Denumire (nume partener) | Sold D | Sold C | +|---|---|---|---| +| 462.01 | TEMPLUM PLUS | 0.00 | 988,640.00 | +| 462.04 | CREDITOR EURO PRO CONSTRUCT | 0.00 | 1,869,897.00 | +| 462.05 | MODREA ALAIN FLORIN | 0.00 | 542,234.00 | + +## MASTERJOB + +| Cont | Denumire | Nr. analitice | Sold total | Propus | +|---|---|---|---|---| +| 117 | REZULTATUL REPORTAT | 8 | 44,795.92 | **ANALITIC** | +| 2111 | TERENURI | 1 | 439,966.60 | **ANALITIC** | +| 371 | MARFURI | 1 | 38,850.00 | **ANALITIC** | +| 401 | FURNIZORI | 18 | -547,108.99 | **PARTENER** | +| 4092 | FURNIZORI — DEBITORI PT. PRESTARI DE SERVICII | 1 | 4.00 | **PARTENER** | +| 4111 | CLIENTI | 1 | 12,000.00 | **PARTENER** | +| 441 | IMPOZITUL PE PROFIT SI ALTE IMPOZITE | 1 | -2,567.00 | **ANALITIC** | +| 447 | FONDURI SPECIALE TAXE SI VARSAMINTE ASIMILATE | 1 | -47.00 | **ANALITIC** | +| 4551 | ACTIONARI/ASOCIATI - CONTURI CURENTE | 2 | -751,724.61 | **PARTENER** | +| 461 | DEBITORI DIVERSI | 3 | 69,289.00 | **PARTENER** | +| 462 | CREDITORI DIVERSI | 4 | -9,810.00 | **PARTENER** | +| 5121 | CONTURI LA BANCA IN LEI | 2 | 15,578.45 | **PARTENER** | +| 5124 | CONTURI LA BANCA IN VALUTA | 2 | 1,060,090.96 | **PARTENER** | +| 5125 | SUME IN CURS DE DECONTARE | 1 | 0.50 | **PARTENER** | + +### Detaliu analitice propuse PARTENER + +**401 FURNIZORI** + +| Analitic SAGA | Denumire (nume partener) | Sold D | Sold C | +|---|---|---|---| +| 401.00001 | MEDIAROM COMUNICATIONS | 0.00 | 14,293.76 | +| 401.00003 | TEMPLUM PLUS | 0.00 | 500.00 | +| 401.00006 | BIROU INDIVIDUAL NOTARIAL GEORGE TRAGONE | 0.00 | 952.00 | +| 401.00007 | ACVATIC TES S.R.L. | 0.00 | 439,966.60 | +| 401.00008 | DREAM FISH S.R.L. | 0.00 | 38,850.00 | +| 401.00009 | LEROY MERLIN ROMANIA SRL C | 0.00 | 2,902.91 | +| 401.00010 | SERVICE ONLAPTOP S.R.L. | 0.00 | 1,230.00 | +| 401.00011 | PET PRODUCT SRL | 0.00 | 445.05 | +| 401.00012 | BIROU INDIVIDUAL NOTARIAL PIELEANU DANIELA | 0.00 | 4,879.00 | +| 401.00013 | CREATIV EXPERT CONSTRUCT S.R.L. | 0.00 | 3,300.00 | +| 401.00014 | **(lipsa denumire in PDF)** | 0.00 | 16,802.46 | +| 401.00015 | ANDREEA BEATRICE VASILE | 0.00 | 10,000.00 | +| 401.00017 | TIRES AND PARTS SRL | 0.00 | 1,245.00 | +| 401.00023 | ANGLO CARS S.R.L. | 0.00 | 3,700.90 | +| 401.00024 | DAW BENTA SRL | 0.00 | 1,948.01 | +| 401.00025 | ROMSYSTEMS S.R.L. | 0.00 | 1,380.40 | +| 401.00026 | UNIVERSAL GRUP SRL | 0.00 | 1,380.90 | +| 401.00027 | SEBASTIAN CONSTRUCTII MONTAJ SRL | 0.00 | 3,332.00 | + +**4092 FURNIZORI — DEBITORI PT. PRESTARI DE SERVICII** + +| Analitic SAGA | Denumire (nume partener) | Sold D | Sold C | +|---|---|---|---| +| 4092.01 | ICI | 4.00 | 0.00 | + +**4111 CLIENTI** + +| Analitic SAGA | Denumire (nume partener) | Sold D | Sold C | +|---|---|---|---| +| 4111.00001 | NEW HOME CONSTRUCT S.A. | 12,000.00 | 0.00 | + +**4551 ACTIONARI/ASOCIATI - CONTURI CURENTE** + +| Analitic SAGA | Denumire (nume partener) | Sold D | Sold C | +|---|---|---|---| +| 4551.01 | IONESCU VALENTIN | 0.00 | 729,308.61 | +| 4551.02 | TOMA IONEL VIOREL RO55 RZBR 0000 0600 1338 1717 | 0.00 | 22,416.00 | + +**461 DEBITORI DIVERSI** + +| Analitic SAGA | Denumire (nume partener) | Sold D | Sold C | +|---|---|---|---| +| 461.01 | SISTEME INTARNATIONALE DE AF. | 8,289.00 | 0.00 | +| 461.02 | HABITAT SI AMBIENT | 20,000.00 | 0.00 | +| 461.03 | DEBITORI DIVERSI | 41,000.00 | 0.00 | + +**462 CREDITORI DIVERSI** + +| Analitic SAGA | Denumire (nume partener) | Sold D | Sold C | +|---|---|---|---| +| 462.01 | CREDITORI DIVERSI -IONESCU ALINA | 0.00 | 3,350.00 | +| 462.02 | CREDITORI DIVERSI - REZIDENT COM | 0.00 | 700.00 | +| 462.03 | CREDITORI DIVERSI - IONESCU VALENTIN | 0.00 | 760.00 | +| 462.05 | CREDITOR C.S.C. | 0.00 | 5,000.00 | diff --git a/docs/decizii_import.md b/docs/decizii_import.md new file mode 100644 index 0000000..f548a2d --- /dev/null +++ b/docs/decizii_import.md @@ -0,0 +1,116 @@ + +## 11. Trezorerie: banca si casa (512x / 531x) - PARTENERI, nu analitice +Stabilit 20.09.2026. + +- **Conturi bancare `512x`** (5121 lei, 5124 devize, 5125 sume in curs de decontare): analiticele SAGA + **nu** devin analitice in ROA. Pentru fiecare analitic se creeaza un **partener cu numele exact al + analiticului** (numele contului bancar, ex `RO73 BACX 0000 0008 7243 0001`, `PIRAEUS BANK - RON`), + cod fiscal = codul SAGA (`5121.01`), si un rand `FACTURA` pe contul sintetic. +- **Casa `531x`**: se creeaza partenerul **`CENTRALA`** (casa centrala), cod fiscal = codul contului + (`5311`). Contul nu are analitice in balantele astea - un singur rand `FACTURA` pe sintetic. + +## 12. Partener fara denumire in balanta +Daca analiticul nu are denumire in PDF (ex MASTERJOB `401.00014`), partenerul se creeaza cu numele +**`FURNIZOR `** (`FURNIZOR 401.00014`) si cod fiscal `401.00014`. Contabilitatea il +identifica dupa cod si il corecteaza in ROA. Nu se ghiceste numele. + +## 13. Postari directe pe contul sintetic (analitic de diferenta) +SAGA permite inregistrari **direct pe contul sintetic**, fara analitic, si in plus **neteaza** D/C la +sintetice. Importul ROA construieste sinteticul ca **suma analiticelor**, deci partea postata direct +pe sintetic s-ar pierde. + +Regula: +1. Diferenta se calculeaza **pe net** (`parinte_D - parinte_C` fata de `SUM(copii_D) - SUM(copii_C)`), + pentru ca gross-ul parintelui e netat de SAGA si nu e recuperabil. +2. Diferenta **net zero** = doar netare SAGA, se ignora (ex FUNDATIA `1171.01`: -739.831,67 pe ambele + laturi, net 0). +3. Diferenta **net diferita de zero** = postare reala pe sintetic: se adauga un **analitic nou de + diferenta**, cu suma pusa pe latura semnului diferentei, si se **raporteaza explicit** in + `verificare_.md` (nu se ajusteaza analiticele existente). +4. La conturile devenite PARTENERI, diferenta devine un **partener de diferenta**, nu un analitic. + +Cazuri gasite la importul 12/2025: +| Firma | Cont | Diferenta net | Tratament | +|---|---|---|---| +| FUNDATIA | 1171.01 | 0,00 (doar netare) | se ignora | +| MASTERJOB | 117 | +2.635,87 debit | analitic nou de diferenta | +| MASTERJOB | 5121 | +152,16 debit | partener de diferenta (5121 e cont cu parteneri) | + +## 14. Trezorerie (512x / 531x): parteneri pe randuri BALANTA, FARA randuri FACTURA +Stabilit 20.09.2026, inlocuieste partea de forma din pct. 11 (regula de continut ramane). + +Conturile de banca si casa **au parteneri, dar nu au facturi**: apar in balanta de verificare si in +balanta de parteneri, niciodata in registrul de facturi. + +In xlsx: +- **Nu** se genereaza randuri `TIP=FACTURA` pe `512x` / `531x`. +- Se genereaza cate un rand `TIP=BALANTA` **per cont bancar / casa**, pe contul sintetic + (`acont` gol), cu `nume` = denumirea analiticului SAGA (numele contului bancar, `CENTRALA` la + casa) si `cod_fiscal` = codul SAGA (`5121.01`, `5311`), `totdeb`/`totcred` = sumele totale ale + analiticului respectiv. + +Confirmare din codul ROA (`COMUN\ferestre\frm_initializare_facturi_balanta.sc2:1104-1107`), la +celalalt flux de import (balanta prin `conturi_roa.dbf`), unde exista doua liste distincte: +- `lcListaConturiBalP` (balanta de parteneri): `401,404,408,409,4091,4092,4093,4111,418,419,461,462,4551,`**`5311,5121,5124`** +- `lcListaConturiIregP` (inregistrari/facturi): aceeasi lista **fara** `5311,5121,5124` + +`5125` nu figureaza in niciuna dintre liste - de tratat separat. + +### Forma concreta in xlsx: randuri FACTURA (decis 20.09.2026) +Formularul de import xlsx **nu suporta parteneri pe randurile `BALANTA`**: +- `:828` goleste `denumire` cand `tip = 'BALANTA'` (o muta in `explicatia`) +- `:867` construieste nomenclatorul de parteneri doar din randurile `WHERE ALLTRIM(tip) = 'FACTURA'` + +Ca sa nu modificam formularul, trezoreria se pune **pe randuri `FACTURA`**, ca orice cont cu +parteneri: partenerul se creeaza corect, `id_partd`/`id_partc` se completeaza, iar +`balanta_parteneri` se reconstruieste din `ireg_parteneri` (`:1685-1695`), deci cifrele ies exact. + +Efect secundar acceptat: pe conturile de trezorerie raman documente de tip FACTURA +(`id_fdoc = 42`, `:528`) care nu sunt facturi reale. Nu deranjeaza balanta de parteneri. + +Regula de continut ramane cea de la pct. 11: un partener per cont bancar, cu numele analiticului +(`RO45 PIRB ...`, `PIRAEUS BANK - RON`), iar la casa partenerul `CENTRALA`. + +### Sensul soldului la trezorerie +Randurile FACTURA primesc latura dintr-o **lista fixa in cod** (`:379`): +`401, 404, 462, 419, 408, 4551` -> credit; **tot restul -> debit**. +Un cont bancar cu sold creditor (descoperit de cont) nu se poate exprima printr-un rand FACTURA: +se lasa fara rand FACTURA, iar randul `BALANTA` il duce pe credit, unde formularul ii pune automat +partenerul `NEREPARTIZAT` (`:415-431`). Se raporteaza cazul, ca sa fie corectat manual in ROA. +Caz gasit: MASTER `5121.01 PIRAEUS BANK - RON`, sold creditor 20,80. + +## 15. 512x: analitice SI parteneri; 5125 doar analitice +Revizuit 20.09.2026 (inlocuieste forma din pct. 11 si 14 pentru aceste conturi). + +- **`5121`, `5124`** (conturi bancare): analiticele **raman analitice** in planul de conturi si in + balanta, **si in plus** fiecare analitic primeste un partener. Concret, pentru fiecare analitic + se scriu DOUA randuri, pe acelasi `(cont, acont)`: + - un rand `TIP=BALANTA` cu `acont` completat si `totdeb`/`totcred` = sumele totale ale analiticului; + - un rand `TIP=FACTURA` cu **acelasi `acont`**, `nume` = denumirea analiticului (numele contului + bancar), `cod_fiscal` = codul SAGA (`5121.01`), `sold` = soldul analiticului. + + `acont` trebuie sa fie acelasi pe ambele randuri: formularul scade randurile FACTURA din randul + BALANTA care are acelasi `(cont, acont, latura)` (`:415-431`). Cu `acont` diferit suma s-ar + dubla si ar aparea un rest negativ pe `NEREPARTIZAT`. +- **`5311`** (casa, fara analitice): rand `BALANTA` pe `5311` (acont gol) + rand `FACTURA` pe + `5311` (acont gol), partener `CENTRALA`. +- **`5125`**: **doar analitice**, fara parteneri. Se trateaza ca orice cont obisnuit cu analitice. +- Un analitic cu soldul pe latura opusa laturii fixate in cod (`:379`, trezoreria merge pe debit) + nu primeste rand FACTURA; ramane doar randul BALANTA si formularul ii pune `NEREPARTIZAT`. + Caz gasit: MASTER `5121.01 PIRAEUS BANK - RON`, sold creditor 20,80. + +## 16. Regula generala: randul FACTURA trebuie sa aiba acelasi `acont` ca randul BALANTA pe care il consuma +Confirmat 20.09.2026. + +Formularul grupeaza randurile `FACTURA` pe `(cont, acont, latura)` si **scade** suma lor din randul +`BALANTA` cu exact aceeasi cheie; restul ramane pe partenerul `NEREPARTIZAT`, iar daca randul +`BALANTA` lipseste, il creeaza el (`frm_initializare_facturi_balanta.sc2:415-431`). + +Consecinte: +- `acont` gol pe `FACTURA` + `acont` completat pe `BALANTA` = cheie diferita: suma **se dubleaza** + (analiticul ramane intreg in balanta si se mai adauga un rand negativ pe sintetic, pe + `NEREPARTIZAT`). Greseala tacuta, nu da eroare. +- De aceea: cont cu parteneri **fara** analitice in ROA (401, 4092, 4111, 461, 462, 4551) -> + ambele randuri cu `acont` gol. Cont cu parteneri **si** analitice in ROA (5121, 5124) -> + ambele randuri cu acelasi `acont`. +- Latura conteaza si ea: un rand FACTURA pe debit nu atinge randul BALANTA de pe credit. diff --git a/docs/plan_solduri2roa.md b/docs/plan_solduri2roa.md new file mode 100644 index 0000000..6458a81 --- /dev/null +++ b/docs/plan_solduri2roa.md @@ -0,0 +1,58 @@ +# Plan: balante SAGA (PDF) -> xlsx de initializare ROA + +Proiect: `D:\ROA\IMPORT2ROA\solduri2roa` +Obiectiv prioritar: doua fisiere xlsx gata de importat in ROACONT pentru FUNDATIA si MASTER, luna 12/2025. +Obiectiv secundar (pasul 2): program reutilizabil de conversie SAGA -> xlsx ROA. + +Deciziile de mapare: `decizii_import.md`. Semantica formularului de import: `raport_form_init_balanta.md`. + +## Etapa 1 - extragere fidela din PDF (lane `pdf-extract`) +`extract_balanta.py` (pdfplumber, pe coordonate) -> `balanta_FUNDATIA.csv`, `balanta_MASTERJOB.csv` +cu `cont;denumire;prec_d;prec_c;rulaj_d;rulaj_c;total_d;total_c;sold_d;sold_c;este_total`. +Poarta de trecere (nu se avanseaza cat timp pica): +- `total_d = prec_d + rulaj_d`, `total_c = prec_c + rulaj_c` pe fiecare cont +- `sold_d - sold_c = total_d - total_c` pe fiecare cont +- `SUM(sold_d) = SUM(sold_c)` pe conturile frunza +- suma analiticelor = parintele, pe fiecare nivel +Un esec = parser gresit, nu date gresite: se repara parserul, nu cifrele. + +## Etapa 2 - semantica formularului (lane `form-init-balanta`) +Analiza `COMUN\ferestre\frm_initializare_facturi_balanta.sc2`: coloane obligatorii, validari +blocante, crearea partenerului dupa `cod_fiscal` (si daca respinge un "CUI" de forma `401.00027`), +regula `id_partd`/`id_partc`, lungimi `cont`/`acont`, rolul `CONFIG_CONT_IREG`. +Risc principal de oprit aici: o validare de CUI care refuza `401.00027`. + +## Etapa 3 - conturile cu parteneri (lane `config-cont-ireg`) +`CONFIG_CONT_IREG` din Oracle local -> lista conturilor cu `CU_INREGISTRARI = 1`. + +## Etapa 4 - maparea in structura ROA +Pentru fiecare firma, din CSV: +1. **Conturi fara parteneri**: se pastreaza doar frunzele. `cont` = primele max 4 caractere, + `acont` = restul cifrelor concatenate (max 4). Un rand `BALANTA` per frunza, cu + `totdeb = total_d`, `totcred = total_c`. Daca suma frunzelor difera de parinte -> analitic de + diferenta, raportat explicit. +2. **Conturi cu parteneri** (din etapa 3): un singur rand `BALANTA` pe sintetic (fara `acont`), + cu suma `total_d` / `total_c` a analiticelor, plus cate un rand `FACTURA` per analitic-partener: + `nume` = denumirea analiticului, `cod_fiscal` = `.` din SAGA, + `numar` = analiticul, `sold` = soldul analiticului (cu semnul dat de natura contului), + `data` = 01.12.2025, `datascad` = 31.12.2025. +3. Toate randurile: `an = 2025`, `luna = 12`. +Iesire: `init_FUNDATIA_2025_12.xlsx`, `init_MASTER_2025_12.xlsx`, generate din sablonul +`init_facturi_balanta_note.xlsx` cu randurile de instructiuni sterse. + +## Etapa 5 - verificare inainte de predare +- `SUM(totdeb) = SUM(totcred)` pe tot xlsx-ul +- pentru fiecare cont cu parteneri: `SUM(sold FACTURA) = soldul sintetic din balanta` +- fiecare cont din balanta apare exact o data (frunza) in xlsx; niciun cont pierdut +- `cont` <= 4 caractere, `acont` <= 4 caractere, fara dubluri `cont+acont` +Raport: `docs\verificare_.md`, cu totalurile din balanta alaturi de totalurile din xlsx. + +## Etapa 6 - git +`git init`, commit, push pe `gitea.romfast.ro:romfast/solduri2roa.git` (push-to-create). +Se comit: scripturile, `docs\`, CSV-urile si xlsx-urile generate. PDF-urile: da (sunt sursa, 30 KB). + +## Pasul 2 (dupa import) - convertorul reutilizabil +Generalizarea etapelor 1 + 4 intr-un singur script cu parametri (firma, an, luna, sursa PDF sau +xlsx SAGA), cu regulile din `decizii_import.md` scoase intr-un fisier de configurare +(conturi cu parteneri, maparea analiticelor). Nu se porneste inainte ca cele doua importuri sa +fie validate in ROA. diff --git a/docs/prompt_initial.md b/docs/prompt_initial.md new file mode 100644 index 0000000..c4443e1 --- /dev/null +++ b/docs/prompt_initial.md @@ -0,0 +1,12 @@ +# Prompt initial pentru agentii opencode - proiect solduri2roa + +Esti EXECUTANT, nu arhitect. Lucrezi in D:\ROA\IMPORT2ROA\solduri2roa. + +Reguli: +- Python 3.13 se apeleaza cu `py` (nu `python`). Librarii deja instalate: pdfplumber, openpyxl. +- Nu folosi NICIODATA `sed -i`. Scrie fisiere cu redirectare/heredoc sau cu Python. +- Nu da commit (git/svn) si nu modifica nimic in afara D:\ROA\IMPORT2ROA\solduri2roa (D:\ROA\ROACONT e read-only pentru tine). +- Codul e simplu si scurt: fara clase inutile, fara framework-uri, fara dependinte noi. +- Nu inventa date. Daca o valoare nu se poate extrage sigur, o raportezi ca problema, nu o ghicesti. +- Scrii raportul cerut in docs\raport_.md, scurt, cu fapte si numere, fara povestiri. +- Ultimul mesaj: `GATA ` sau `BLOCAT : motiv`. diff --git a/docs/raport_config-cont-ireg.md b/docs/raport_config-cont-ireg.md new file mode 100644 index 0000000..16ee3c8 --- /dev/null +++ b/docs/raport_config-cont-ireg.md @@ -0,0 +1,25 @@ +# Raport config-cont-ireg + +Read-only. Doar SELECT. Nu s-a modificat nimic in baza; nu s-a scris in D:\ROA\ROACONT. + +## 1. Facut + +- Livrat: `D:\ROA\IMPORT2ROA\solduri2roa\docs\config_cont_ireg.md` — schema sursa, comanda de conectare, DESC, toate cele 47 randuri, lista CU_INREGISTRARI=1. +- Citire: `MARIUSM_AUTO.CONFIG_CONT_IREG` prin `sqlplus -S "MARIUSM_AUTO/ROMFASTSOFT@ROA_CENTRAL"`, TNS_ADMIN=`D:\ROA\instantclient_19_18`. +- DSN `ROA_CENTRAL` (10.0.20.121:1521/ROA) din `D:\ROA\instantclient_19_18\tnsnames.ora:206`. Parola din `D:\ROA\ROACONT\docs\oracle_parola_standard.secret` (=`ROMFASTSOFT`, si in `COMUN\utile\Teste\test_init_env_auto.prg:22`). + +## 2. Verificari + +- Conectare verificata: `select user from dual` -> `MARIUSM_AUTO`. +- Numarare: `select count(*) from config_cont_ireg` -> 47 (toate scrise in livrabil). +- Coloana ceruta "denumire" nu exista; denumirea este `EXPLICATIE` (notat in livrabil). +- Tabela are in plus: `FEL_CONT`, `CU_VENCHELT`, `CU_PROC_TVA`, `LUNAI`, `ANI` (incluse in livrabil; LUNAI/ANI doar pe randul 4511). +- Nu au fost rulate teste VFP. + +## 3. Nefacut / blocat + +- Nimic in afara scopului. Nu am scris raportul in `D:\ROA\ROACONT` (interzis explicit de sarcina), l-am pus in folderul de livrare. + +## 4. Stare periculoasa + +- Niciuna: zero scrieri in baza, niciun fisier editat in ROACONT, niciun proces ramas. diff --git a/docs/raport_form_init_balanta.md b/docs/raport_form_init_balanta.md new file mode 100644 index 0000000..a54de33 --- /dev/null +++ b/docs/raport_form_init_balanta.md @@ -0,0 +1,217 @@ +# Semantica importului `init_facturi_balanta_note.xlsx` + +Analiza read-only. Sursa de cod: `D:\ROA\ROACONT\COMUN\ferestre\frm_initializare_facturi_balanta.sc2` +(liniile citate sunt cele din fisierul text FoxBin2Prg). Fara analize speculative. + +## Fluxul + +Butonul **Import** (`cmdNoteFacturiBalanta`, optiunea 1) executa in ordine: + +1. `VerificaImport()` - `frm...sc2:2354`, metoda la `2292-2310`. +2. `ExportDate()` - `frm...sc2:2360`, metoda la `738-993`. +3. `Creeazanote()` - `frm...sc2:2364`, metoda la `241-733`. +4. `ModificaNote()` sau `Scrienote()` - `frm...sc2:2368-2371`. + +`ExportDate` citeste xlsx-ul in cursorul `cFacturiTemp` (`frm...sc2:760-774`) si lasa in urma +cursorul `cFacturi` (`frm...sc2:825-847`). `Creeazanote` transforma `cFacturi` in `actactan` +(note in Registrul Jurnal, `id_set = 90024`, `frm...sc2:258`). + +**Maparea coloanelor este positionala**, nu dupa numele din capul de tabel: `appendfromxlsx` +ia campurile cursorului cu `AFIELDS` in ordine (`appendfromxlsx.prg:111-135`) si scrie pe rand. +De aceea numele xlsx difera de numele campului: + +| xlsx | cursor `cFacturiTemp` | citat | +|---|---|---| +| nume | denumire | `frm...sc2:761` (ord. camp 10) | +| numar | nract | `frm...sc2:760` (ord. 7) | +| data | dataact | `frm...sc2:760` | +| explicatia | explicatie | `frm...sc2:762` | +| **sold** | **valoare** | `frm...sc2:765` | +| **soldval** | **totval** | `frm...sc2:765` | +| **soldtvaneex** | **tva** | `frm...sc2:765` | +| **acont4428neex** | **acont4428** | `frm...sc2:765` | + +Maparea sold/soldval/soldtvaneex -> valoare/totval/tva e confirmata si de codul comentat +`frm...sc2:781-799` (`sold -> valoare`, `soldtvaneex -> tva`, `soldval -> totval`). + +--- + +## 1. Randurile TIP=BALANTA: totdeb/totcred + +**Sunt SUME TOTALE cumulate** (sold initial + rulaje), nu solduri nete. In sablon: +"Total sume debitoare BALANTA" / "Total sume creditoare BALANTA" (Sheet1, rand 1). Comentariul +din fluxul inrudit o spune explicit: `TOTDEB/TOTCRED = sume totale (sold la 1 ianuarie + rulaj +precedent anual + rulaj lunar)` (`frm...sc2:1034`). + +Ce face codul cu ele: +- Le transforma in cate o linie separata, nu intr-o diferenta: `totdeb as valoare` pe latura D, + `totcred as valoare` pe latura C, unite cu UNION ALL (`frm...sc2:350-356`). +- Latura (D/C) pentru BALANTA vine din union-ul de mai sus, NU din lista de la `383` (lista 401, + 404, 462, 419, 408, 4551 -> C se aplica doar peste `cFacturiTemp`, care la acel moment contine + doar randuri FACTURA; `frm...sc2:381-383`). +- Nota generata: `id_fdoc = 69` (SOLD) pentru BALANTA, fata de 42 (FACTURA) (`frm...sc2:508`). +- Semnul: daca `tipDC = 'C'` -> contul intra pe credit (`pcScc = pcCont`, `pcAscc = pcAcont`); + daca `tipDC = 'D'` -> pe debit (`pcScd = pcCont`, `pcAscd = pcAcont`) (`frm...sc2:551-579`). +- **Contrapartida: goala.** Partea opusa rămâne `''` (`pcScd/pcAscd` gol pe latura C, + `pcScc/pcAscc` gol pe latura D - `frm...sc2:553-556, 567-570`). Nu exista cont de sold + initial (891/892) in cod. Nota de BALANTA este **unilaterala**, cate o linie per cont/latura. +- Suma postata = soldul BALANTA minus TVA-ul neexigibil de pe aceeasi linie (pentru BALANTA + `tva = 0`, deci suma ramane `valoare`) (`frm...sc2:493, 504-506, 531-546`). +- Daca un cont are si totdeb si totcred nenule, se genereaza doua linii distincte. + +## 2. Randurile TIP=FACTURA + +**Coloane obligatorii** - sablonul le declara (Sheet1, rand 1 / instructiuni): `an, luna, cont, +nr, data, nume, cod_fiscal, sold factura` (optional `facturat/achitat`), `sold TVA Neexigibil` +daca exista; "Pentru FACTURA, OBLIGATORIU completati NUME si COD FISCAL". Codul insa **nu le +valideaza explicit**; singurul filtru dur este `an` numeric nenul (`frm...sc2:846`, +`WHERE !Empty(Val(Transform(an)))`). Un rand fara `an` este ignorat tacit. + +**Partenerul** se creeaza/gaseste astfel: +- `ExportDate` grupeaza randurile FACTURA dupa `denumire, cod_fiscal, reg_com` (`frm...sc2:865-869`) + si adauga mereu un partener `NEREPARTIZAT` (`frm...sc2:871-877`). +- `CompleteazaParteneriROA` (`oproceduri_import.prg:5571-5910`): normalizeaza codul + (`Upper`, fara spatii, `oproceduri_import.prg:5624`); daca lungimea <= 3, codul devine `''` si + cautarea se face **dupa denumire** (`oproceduri_import.prg:5626-5628, 5639-5650`). +- Cauta intai dupa cod exact (`5638-5641`), apoi dupa `NormalizeazaCUI` (`5643-5646`). Daca nu + gaseste, **creeaza partener nou** cu `pack_def.adauga_partener` (`5667-5717`), folosind codul + fiscal ca atare (`5677`), `tip_persoana = 1` daca lungimea < 13, altfel 2 (`5686`). +- **Nu exista validare de CUI (checksum/format).** `NormalizeazaCUI` doar face UPPER, scoate + spatiile si taie prefixul `RO` cand restul e numeric (`validare.prg:1679-1699`). Deci + `"401.00027"` rămâne `"401.00027"`; are 9 caractere (>3), este folosit ca `cod_fiscal`, iar + daca nu exista deja, creeaza un partener nou cu acest cod. **Randul nu este respins.** +- `id_part` se intoarce pe randurile FACTURA prin `Update cFacturi Set id_part ... Where + cod_fiscal = ... AND denumire = ... AND reg_com = ...` (`frm...sc2:902`). + +**Documentul/nota generata**: `id_fdoc = 42` (FACTURA) (`frm...sc2:508`), o linie de valoare +(`facturat` sau `valoare`, minus TVA neexigibil) si, daca exista, o linie `ACHITAT` +(`frm...sc2:529-633`), plus notele de TVA neexigibil (`frm...sc2:650-725`). `id_fact` se ia din +`vireg_parteneri` sau din `SEQ_IdFact` (`frm...sc2:262-320`). + +## 3. Legatura FACTURA <-> BALANTA + +Nu se aduna si nu se verifica egalitatea; **BALANTA se reduce cu totalul facturilor**: +- Se insumeaza `facturat - achitat` pe `cont, acont, tipDC` din randurile FACTURA + (`frm...sc2:389-392`); se adauga si soldul de 4428 TVA neexigibil (`frm...sc2:395-402`). +- Pentru fiecare grupa se cauta linia BALANTA pe `cont/acont/tipDC` (`frm...sc2:411-412`) si + `REPLACE valoare WITH valoare - lnSoldFactura` (`frm...sc2:428`). +- Daca linia BALANTA nu exista, se creeaza automat una cu explicatia `DIFERENTA FACTURI` si + partener `NEREPARTIZAT` (`frm...sc2:413-426`). +- `lnSoldFactura = IIF(sold <> 0, sold, valoare)` - daca `facturat-achitat` e 0, foloseste + `SUM(valoare)` (soldul facturii) (`frm...sc2:408`). +- **Nu exista verificare de egalitate si nici eroare la diferenta**; restul rămâne sold + `NEREPARTIZAT`. + +## 4. Lungimi `cont` / `acont` si combinare + +- Cursorul le declara `C(20)` (`frm...sc2:760`); la iesire se aplica `PADR(ALLTRIM(...), 4, ' ')` + (`frm...sc2:826-827`), deci minim 4, fara trunchiere la 4. In baza, `CONFIG_CONT_IREG.CONT` + este `VARCHAR2(4)` (docs/config_cont_ireg.md:24). Practic, sablonul cere `cont` <= 4 si + `acont` <= 4. +- Daca celula `cont` contine un punct (`401.01`), `ExportDate` o separa: `cont = LEFT(pana la + punct)`, `acont = SUBSTR(dupa punct)`, iar `acont`-ul din coloana proprie se pastreaza daca + nu e gol (`frm...sc2:806-816`). +- In nota finala contul sintetic si analiticul sunt **campuri separate**, nu concatenate: + `scd/ascd` si `scc/ascc` (`frm...sc2:639-645`); `pcCont = ALLTRIM(cont)`, + `pcAcont = ALLTRIM(acont)` (`frm...sc2:477-478`). + +## 5. Rolul `CONFIG_CONT_IREG` / `CU_INREGISTRARI` + +- Se citeste `select cont, decode(fel_cont,'0','D','C') as tipdc, cu_inregistrari from + CONFIG_CONT_IREG` (`frm...sc2:435`). Pentru fiecare cont din config, pe liniile BALANTA se + forteaza partenerul `NEREPARTIZAT` (`frm...sc2:438-443`), ca sa se poata genera balanta de + parteneri. +- `cu_inregistrari = 1` marcheaza conturile cu inregistrari de partener. In `Creeazanote`, daca + linia BALANTA are cont in config, `tipdc` de config este opus laturii curente si + `cu_inregistrari = 1`, atunci pe linia opusa se pune `id_factc/id_factd = id_fact` si + `perechec/pereded = nract` (`frm...sc2:582-595`). +- Lista efectiva a conturilor cu `CU_INREGISTRARI = 1` (dump Oracle local) este in + `docs/config_cont_ireg.md:89-91` (401, 403, 404, 408, 409, 4091-4094, 4111, 4118, 413, 418, + 419, 426, 4511, 4551, 456, 457, 461, 462, 471, 472, 4754, 542, 8051, plus 1621, 167, 232, + 234, 261, 2678, 2691). Fluxul de initializare directa are liste echivalente hardcodate: + parteneri-balanta `401,404,408,409,4091,4092,4093,4111,418,419,461,462,4551,5311,5121,5124` + (`frm...sc2:1104`) si inregistrari-parteneri fara 5311/5121/5124 (`frm...sc2:1107`). +- Randurile FACTURA cu partener sunt deci necesare pentru conturile din `CONFIG_CONT_IREG` cu + `cu_inregistrari = 1`; BALANTA pe acele conturi primeste partener de diferenta. + +## 6. Unde se completeaza `id_partd` / `id_partc` + +In `Creeazanote`, dupa regula debit/credit: +- Linia de valoare: `tipDC = 'C'` -> partenerul pe credit (`pnIdPartC = id_part`, + `pnIdPartD = 0`); `tipDC = 'D'` -> pe debit (`pnIdPartD = id_part`, `pnIdPartC = 0`) + (`frm...sc2:551-579`). Motivul e in comentariu: 401 pe credit, 4111 pe debit. +- Linia `ACHITAT`: invers - `tipDC = 'C'` (furnizor) -> partener pe debit; `tipDC = 'D'` + (client) -> pe credit (`frm...sc2:597-630`). +- Liniile de TVA neexigibil: 4428 vs 401/4111, partener pe latura contului de partener + (`frm...sc2:654-678`). +- Suplimentar pentru BALANTA, pe linia opusa, `id_factc/id_factd` din config + (`frm...sc2:582-595`). Insertul in `actactan` le scrie in `id_partd/partd/id_partc/partc` + (`frm...sc2:639-645, 716-721`). + +## 7. Validari care blocheaza / opresc importul (lista scurta) + +- Documente deja importate: doar avertisment de confirmare, nu blocheaza + (`frm...sc2:2292-2310`, mesaj la `2355`). +- `'Nu s-a generat id_fact!'` (`frm...sc2:313`). +- `'Nu s-a gasit/generat id-ul de factura. Se opreste generarea de id-uri!'` (`frm...sc2:323`). +- `'Eroare la adaugarea in clienti ROA ...'` - opreste `CompleteazaParteneriROA` + (`oproceduri_import.prg:5711`). +- Fisier neales: `Getfile` gol -> return (`frm...sc2:751-755`). +- Rand fara `an` numeric: ignorat tacit (`frm...sc2:846`). +- Erori de citire xlsx: `'Nimic de importat'`, `'Foaie inexistenta'` (`appendfromxlsx.prg:24-45, + 139-145`). +- `'Nu recunosc structura de balanta!'` - doar fluxul direct `InitBalanta` (`frm...sc2:1095`). +- Erori Oracle propagate prin `goExecutor.cEroare` (ex. `frm...sc2:292-294, 981`). + +Nu exista validare de completitudine pe coloanele FACTURA (nume/cod_fiscal/numar/data). + +## 8. `soldtvaneex` / `acont4428neex` / `baza..tva..` + +- `soldtvaneex` -> campul cursor `tva`: soldul TVA neexigibil al facturii + (`frm...sc2:765`; mapare in codul comentat `790`). +- `acont4428neex` -> campul cursor `acont4428`: contul analitic 4428 + (`frm...sc2:765`); folosit ca `ascd/ascc` pe liniile de 4428 + (`frm...sc2:656-657, 670-671`). +- `baza21/tva21 ... baza20/tva20` -> `baza..tva..`: baza si TVA neexigibil pe cote + (`frm...sc2:766-772`). Cota se determina in ordinea 21, 11, 19, 9, 5, 24, 20 + (`frm...sc2:679-711`), iar suma TVA-ului pe cote este `pnTottvatax` (`frm...sc2:510`). +- **Cand sunt obligatorii**: numai cand factura are TVA neexigibil (`lnTVA <> 0`, + `frm...sc2:650`). Sablonul cere explicit: "REGISTRE TVA TVA LA INCASARE. Trebuie completat + SOLD TVA NEEXIGIBIL + BAZA SI TVA NEEXIGIBIL pentru ca randul FACTURA sa aiba explicatie TVA + si sa apara in Registrele de TVA". `acont4428neex` se completeaza doar daca e nevoie. + Daca `tva = 0`, nu se genereaza nicio nota de exigibilitate. + +## 9. Contul sintetic din analitice - il creeaza singur (confirmat) + +- Instructiunea din sablon (Sheet1): "La tip BALANTA se completeaza DOAR CONTURILE ANALITICE, + DACA EXISTA, altfel contul sintetic (ex: 419.1 si 419.2 nu si 419). **Importul creeaza automat + contul sintetic din suma analiticelor**". +- Formularul separa `cont.acont` (`frm...sc2:806-816`) si creeaza intrarea de plan conturi + pentru analitic prin `merge into plcont` (`frm...sc2:943-986`). +- Sinteticul propriu-zis se construieste in engine, la scrierea notelor: + `PACK_CONTAFIN.SCRIE_IN_BALANTA` face `BAL` (sintetic) = `SUM(DEBIT)/SUM(CREDIT)` grupat pe + `scd/scc`, si `BALANA` (analitic) grupat pe `scd + ascd` (`ff_2026_09_09_06_COMUN_PACK_CONTAFIN.sql:6894-6957`), + apelat din `final_scriere_act_rul_local` (`...sql:8552-8553`). +- Fluxul direct `InitBalanta` o face explicit in VFP: "Balanta sintetica" = `SUM` grupat pe + `cont2` fara `acont2` (`frm...sc2:1151-1160`), insert in `bal` (`frm...sc2:1188-1200`) si + analitica in `balana` (`frm...sc2:1245-1258`). + +## 10. Randul de start si numele foii + +- `appendfromxlsx(m.lcFile, "cFacturiTemp", "", 2, "Sheet1", .T.)` (`frm...sc2:774`): + `lnStartRows = 2`, deci **randul 1 (capul de tabel) este sarit; citirea incepe de la randul 2**. + Sablonul o confirma: "IMPORTUL INCEPE DE LA RANDUL 2. LASATI RANDUL 1 (CAPUL DE TABEL)". +- Foaia asteptata: **`Sheet1`**, potrivita case-insensitive dupa nume in `get_sheet` + (`appendfromxlsx.prg:605-634`); in fisier `xl/workbook.xml` foaia se numeste `Sheet1`. +- Randurile de instructiuni (2-19 in sablon) sunt citite ca date dar eliminate de filtrul + `an` nenul (`frm...sc2:846`); datele reale incepand cu randul 20 in sablon. + +--- + +## Observatii + +- Ambele directii folosesc acelasi sablon `init_facturi_balanta_note.xlsx` (`frm...sc2:2258`); + optiunea 2 (initializare directa) foloseste insa `InitBalanta`/`InitFacturi`, cu alte fisiere + si alte structuri (`balanta.xlsx`, `facturi.xlsx`). +- Toate citatele de mai sus sunt din fisierul `.sc2` (text), nu din binar. +- Nu s-a modificat nimic in `D:\ROA\ROACONT`. diff --git a/docs/raport_genxlsx.md b/docs/raport_genxlsx.md new file mode 100644 index 0000000..23e2338 --- /dev/null +++ b/docs/raport_genxlsx.md @@ -0,0 +1,65 @@ +# Raport lane `genxlsx` (v2) + +Script: `genereaza_xlsx.py`. Produce pentru fiecare firma xlsx-ul de initializare +(`init__2025_12.xlsx`, un sheet, randul 1 = capul de tabel, fara instructiuni/exemple) +si raportul de verificare (`docs/verificare_.md`). + +## Livrabile +- `init_FUNDATIA_2025_12.xlsx` - 75 randuri (47 BALANTA, 28 FACTURA) +- `init_MASTER_2025_12.xlsx` - 79 randuri (46 BALANTA, 33 FACTURA) +- `docs/verificare_FUNDATIA.md`, `docs/verificare_MASTER.md` +- `genereaza_xlsx.py` + +## Rezultate verificari (toate OK) +| Firma | SUM(totdeb)=SUM(totcred) | frunze pierdute | parteneri | lungimi/dubluri | +|---|---|---|---|---| +| FUNDATIA | 7068369.50 = 7068369.50 (net 0.00) | 0 | OK | OK | +| MASTER | 2318592.91 = 2318592.91 (net 0.00) | 0 | OK | OK | + +## Corectii v2 (fata de v1) +1. **Randul FACTURA `DIFERENTA SINTETIC ` a fost eliminat** de pe conturile cu parteneri. + Formularul scade singur suma randurilor FACTURA din randul BALANTA de pe acelasi + `(cont, acont, latura)` si pune restul pe partenerul `NEREPARTIZAT` pe care il creeaza el + (`frm..sc2:415-431`). Diferenta nu se mai inventa de noi. +2. **Analitice cu sold pe latura opusa nu mai primesc FACTURA.** Latura FACTURA e fixa in cod + (`frm..sc2:379`/'383'): `401,404,462,419,408,4551` -> CREDIT, orice alt cont -> DEBIT. + Analiticul sarit ramane doar in randul BALANTA (pe latura lui corecta) si formularul ii pune + `NEREPARTIZAT`. Fiecare caz e listat in raport (sectiunea 4). +3. **Randul BALANTA reprezinta contul sintetic intreg.** La partenerii cu un singur BALANTA + agregat, `totdeb` = suma `total_d` a tuturor analiticelor + postarea directa pe sintetic + (idem `totcred`), nu doar analiticele pentru care s-a emis FACTURA. +4. **pct. 15 (revizuit 20.09.2026):** + - `5121`/`5124`: analiticele **raman analitice** si in plus primesc partener. Pentru fiecare + analitic se scriu **doua randuri pe acelasi `(cont, acont)`**: un `BALANTA` cu acont si + `totdeb`/`totcred` ale analiticului, si un `FACTURA` cu **acelasi acont**, `cod_fiscal` = + codul SAGA, `sold` = soldul analiticului. Acelasi `acont` e obligatoriu, altfel scaderea din + cod nu se potriveste si suma se dubleaza. + - `5125`: NU mai e cont cu parteneri - doar randuri BALANTA cu acont, fara FACTURA. + - `5311`: BALANTA (acont gol) + FACTURA (acont gol), partener `CENTRALA`. + - `401, 4092, 4111, 461, 462, 4551`: neschimbate - un BALANTA agregat pe sintetic (acont gol) + + cate un FACTURA per analitic (acont gol). + +## Ce ramane pe `NEREPARTIZAT`, per cont (sectiunea 3 din verificari) +`net sintetic - SUM(sold FACTURA cu semn) = analitice sarite + postare directa pe sintetic`. +Rezultat: toate conturile ies 0, mai putin MASTER `5121`: + +| cont | SUM FACTURA | net sintetic | sarite | postare directa | NEREPARTIZAT asteptat | diferenta | +|---|---|---|---|---|---|---| +| MASTER 5121 | 15599.25 | 15730.61 | -20.80 (`5121.01` creditor) | +152.16 | 131.36 | 131.36 | + +- MASTER `5121.01 PIRAEUS BANK - RON` (sold creditor 20,80): fara FACTURA, doar + `BALANTA 5121 acont 01` pe credit -> formularul ii pune `NEREPARTIZAT`. +- MASTER `5121` postare directa +152.16: rand `BALANTA 5121 acont 99` `DIFERENTA SINTETIC SAGA` + (fara FACTURA) -> `NEREPARTIZAT`. + +## Randuri de diferenta (pct. 13-15) generate +- MASTER `117` (nepartener): +2635.87 -> rand `BALANTA` cont 117, acont `99`, + nume `DIFERENTA SINTETIC SAGA`. +- MASTER `5121` (banca): +152.16 -> rand `BALANTA` cont 5121, acont `99`, fara FACTURA. +- FUNDATIA: niciunul (1171.01 are diferenta net zero - doar netare SAGA). + +## Observatii +- SUM(totdeb) difera de `Totaluri.total_d` din PDF (FUNDATIA +739831.67, MASTER +20.80): + gross-ul sinteticelor netate de SAGA nu se poate reconstrui din frunze; netul coincide exact. +- Coloana `explicatia` (control D/C) este goala in xlsx-ul final. +- Nu s-a facut niciun commit. diff --git a/docs/raport_pdf_extract.md b/docs/raport_pdf_extract.md new file mode 100644 index 0000000..398df69 --- /dev/null +++ b/docs/raport_pdf_extract.md @@ -0,0 +1,57 @@ +# Raport pdf-extract - balante SAGA 31.12.2025 + +Script: `extract_balanta.py` (pdfplumber, extract_words pe coordonate; NU pdftotext). +Rulare: `py extract_balanta.py "" ""`. + +## Volum extras + +| Firma | PDF | randuri CSV | conturi | randuri total | +|---|---|---|---|---| +| FUNDATIA | IBB 31.12.2025.pdf | 88 | 82 | 6 | +| MASTERJOB | MJC 31.12.2025.pdf | 88 | 81 | 7 | + +Conturi duplicate: niciunul. Randuri de continuare de denumire lipite corect +(ex: `1171` = "REZULTATUL REPORTAT - PROFITUL NEREP./ PIREDERE NEACOP."). + +## Rezultat verificari + +`frunze` = cont care nu e parinte. `radacini` = cont al carui parinte nu apare in balanta. +SAGA neteaza D/C la conturile sintetice, deci verificarea de inchidere corecta e pe radacini. + +| Verificare | FUNDATIA | MASTERJOB | +|---|---|---| +| (a) total_d = prec_d+rulaj_d si total_c = prec_c+rulaj_c | 82/82 OK | 81/81 OK | +| (b) sold_d-sold_c = total_d-total_c | 82/82 OK | 81/81 OK | +| (c) frunze: suma sold_d = suma sold_c | 6 793 548.43 = 6 793 548.43, dif 0.00 **OK** | 2 112 044.07 vs 2 114 832.10, dif **-2 788.03 ESEC** | +| (c2) radacini: suma sold_d = suma sold_c | 6 053 716.76 = 6 053 716.76, dif 0.00 OK | 2 114 811.30 = 2 114 811.30, dif 0.00 OK | +| randul "Totaluri:" din PDF | 6 053 716.76 = 6 053 716.76 | 2 114 811.30 = 2 114 811.30 | +| cross-check "Total sume clasa N" = suma radacinilor clasei | 5/5 OK | 6/6 OK | +| (d) parinte vs analitice | 6 diferente pe laturi, 0 pe net | 9 diferente pe laturi, 2 pe net | + +Numerele de mai sus arata ca parsarea coordonatelor este corecta: (a) si (b) trec pentru +toate conturile, iar fiecare rand "Total sume clasa N" egaleaza exact suma radacinilor din +clasa respectiva (5/5 si 6/6), iar suma radacinilor egaleaza exact randul "Totaluri:". + +## Conturi problematice si explicatie + +Nu sunt erori de parsare; sunt doua comportamente reale SAGA: + +1. Netare D/C la sintetice (FUNDATIA `1171.01`): parintele este prezentat net, + copiii pe laturi. + - `prec_d`: parinte 629 448.54 vs copii 1 369 280.21 (dif -739 831.67) + - `prec_c`: parinte 0.00 vs copii 739 831.67 (dif -739 831.67) + - pe NET: parinte 773 608.10 = copii 773 608.10 -> 0 diferente pe net. + De aceea suma frunzelor (6 793 548.43) difera de "Totaluri" (6 053 716.76) cu exact + 739 831.67; inchiderea reala se face pe radacini si coincide cu PDF. + +2. Postari directe pe conturi sintetice (MASTERJOB): + - `117`: parinte 47 431.79 vs copii 44 795.92 -> diferenta 2 635.87 + - `5121`: parinte 15 730.61 vs copii net 15 578.45 -> diferenta 152.16 + Suma postarilor directe = 2 635.87 + 152.16 = **2 788.03**, exact deficitul de la + verificarea (c) pe frunze (sold_c - sold_d = 2 788.03). Frunzele nu contin aceste + postari, de aceea (c) pica; incluzandu-le (c2, radacini) balanta este inchisa si + coincide cu "Totaluri:" = 2 114 811.30. + +Concluzie: nu s-a ajustat nicio data. Verificarile (a), (b), (c2) si cross-check-ul pe +clase trec pentru ambele firme; (c) pe frunze pica doar la MASTERJOB din cauza postarilor +directe pe sintetice, dovedita prin relatia de mai sus. diff --git a/docs/verificare_FUNDATIA.md b/docs/verificare_FUNDATIA.md new file mode 100644 index 0000000..e0323eb --- /dev/null +++ b/docs/verificare_FUNDATIA.md @@ -0,0 +1,60 @@ +# Verificare `init_FUNDATIA_2025_12.xlsx` + +Generat de `genereaza_xlsx.py` din `balanta_FUNDATIA.csv`. Randuri de date: 75 (47 BALANTA, 28 FACTURA). + +## 1. Balanta generala (SUM totdeb = SUM totcred) + +- SUM(totdeb) = 7068369.5 +- SUM(totcred) = 7068369.5 +- diferenta (totdeb - totcred) = 0.0 -> OK +- Totaluri balanta: total_d=6328537.83 total_c=6328537.83 net=0.0 +- NET xlsx (0.0) vs NET Totaluri (0.0) -> OK +- Nota: SUM(totdeb)=7068369.5 difera de Totaluri.total_d=6328537.83 cu 739831.67; suma pe laturi a PDF-ului nu se poate reconstrui din frunze acolo unde SAGA a netat sinteticul (gross-ul parintelui e netat). Netul se pastreaza exact. + +## 2. Conturi frunza din CSV, reprezentate o singura data + +- frunze in CSV: 66 +- reprezentate in xlsx: 66 +- conturi pierdute: [] (gol) -> OK +- frunze cu mai putin/mai mult de un rand dedicat: [] (gol) -> OK + +## 3. Conturi partener: FACTURA + NEREPARTIZAT = net sintetic + +Formularul scade din randul BALANTA suma randurilor FACTURA de pe acelasi `(cont, acont, latura)` si lasa restul pe partenerul `NEREPARTIZAT`. Deci: `net sintetic - SUM(sold FACTURA cu semn) = analitice sarite + postare directa pe sintetic`. + +| cont | SUM(sold FACTURA) | net sintetic | analitice sarite | postare directa | NEREPARTIZAT asteptat | diferenta | rezultat | +|---|---|---|---|---|---|---|---| +| 401 | -314703.58 | -314703.58 | 0.0 | 0.0 | 0.0 | 0.0 | OK | +| 4092 | 809.33 | 809.33 | 0.0 | 0.0 | 0.0 | 0.0 | OK | +| 4111 | 15126.48 | 15126.48 | 0.0 | 0.0 | 0.0 | 0.0 | OK | +| 4551 | -1571531.33 | -1571531.33 | 0.0 | 0.0 | 0.0 | 0.0 | OK | +| 461 | 477938.37 | 477938.37 | 0.0 | 0.0 | 0.0 | 0.0 | OK | +| 462 | -3400771.0 | -3400771.0 | 0.0 | 0.0 | 0.0 | 0.0 | OK | +| 5121 | 81966.8 | 81966.8 | 0.0 | 0.0 | 0.0 | 0.0 | OK | +| 5124 | 2492540.28 | 2492540.28 | 0.0 | 0.0 | 0.0 | 0.0 | OK | +| 5311 | 72433.56 | 72433.56 | 0.0 | 0.0 | 0.0 | 0.0 | OK | + +Rezultat: OK + +## 4. Analitice sarite (sold pe latura opusa formularului) + +Latura FACTURA e fixa in cod (`:379`): `401,404,462,419,408,4551` -> CREDIT, orice alt cont -> DEBIT. Un analitic cu sold pe latura opusa nu primeste rand FACTURA; ramane in BALANTA si formularul ii pune `NEREPARTIZAT`. + +Niciunul. + +## 5. Lungimi si dubluri + +- cont > 4 sau acont > 4: [] (gol) -> OK +- perechi (cont, acont) duplicate la BALANTA: [] (gol) -> OK + +## 6. Randuri de diferenta generate (pct. 13-15) + +Niciunul (toate diferentele nete sunt zero). + +Nota: randurile FACTURA de tip `DIFERENTA SINTETIC` au fost eliminate; diferenta nu se mai inventa, o rezolva formularul prin `NEREPARTIZAT`. + +## Verdict + +TOATE verificarile au trecut. + +Nota: coloana `explicatia` (D/C la FACTURA) a fost folosita doar ca control intern si este goala in xlsx-ul final (capul de tabel o pastreaza). diff --git a/docs/verificare_MASTER.md b/docs/verificare_MASTER.md new file mode 100644 index 0000000..5f5b4d4 --- /dev/null +++ b/docs/verificare_MASTER.md @@ -0,0 +1,63 @@ +# Verificare `init_MASTER_2025_12.xlsx` + +Generat de `genereaza_xlsx.py` din `balanta_MASTERJOB.csv`. Randuri de date: 79 (46 BALANTA, 33 FACTURA). + +## 1. Balanta generala (SUM totdeb = SUM totcred) + +- SUM(totdeb) = 2318592.91 +- SUM(totcred) = 2318592.91 +- diferenta (totdeb - totcred) = 0.0 -> OK +- Totaluri balanta: total_d=2318572.11 total_c=2318572.11 net=0.0 +- NET xlsx (0.0) vs NET Totaluri (0.0) -> OK +- Nota: SUM(totdeb)=2318592.91 difera de Totaluri.total_d=2318572.11 cu 20.8; suma pe laturi a PDF-ului nu se poate reconstrui din frunze acolo unde SAGA a netat sinteticul (gross-ul parintelui e netat). Netul se pastreaza exact. + +## 2. Conturi frunza din CSV, reprezentate o singura data + +- frunze in CSV: 67 +- reprezentate in xlsx: 67 +- conturi pierdute: [] (gol) -> OK +- frunze cu mai putin/mai mult de un rand dedicat: [] (gol) -> OK + +## 3. Conturi partener: FACTURA + NEREPARTIZAT = net sintetic + +Formularul scade din randul BALANTA suma randurilor FACTURA de pe acelasi `(cont, acont, latura)` si lasa restul pe partenerul `NEREPARTIZAT`. Deci: `net sintetic - SUM(sold FACTURA cu semn) = analitice sarite + postare directa pe sintetic`. + +| cont | SUM(sold FACTURA) | net sintetic | analitice sarite | postare directa | NEREPARTIZAT asteptat | diferenta | rezultat | +|---|---|---|---|---|---|---|---| +| 401 | -547108.99 | -547108.99 | 0.0 | 0.0 | 0.0 | 0.0 | OK | +| 4092 | 4.0 | 4.0 | 0.0 | 0.0 | 0.0 | 0.0 | OK | +| 4111 | 12000.0 | 12000.0 | 0.0 | 0.0 | 0.0 | 0.0 | OK | +| 4551 | -751724.61 | -751724.61 | 0.0 | 0.0 | 0.0 | 0.0 | OK | +| 461 | 69289.0 | 69289.0 | 0.0 | 0.0 | 0.0 | 0.0 | OK | +| 462 | -9810.0 | -9810.0 | 0.0 | 0.0 | 0.0 | 0.0 | OK | +| 5121 | 15599.25 | 15730.61 | -20.8 | 152.16 | 131.36 | 131.36 | OK | +| 5124 | 1060090.96 | 1060090.96 | 0.0 | 0.0 | 0.0 | 0.0 | OK | +| 5311 | 98460.87 | 98460.87 | 0.0 | 0.0 | 0.0 | 0.0 | OK | + +Rezultat: OK + +## 4. Analitice sarite (sold pe latura opusa formularului) + +Latura FACTURA e fixa in cod (`:379`): `401,404,462,419,408,4551` -> CREDIT, orice alt cont -> DEBIT. Un analitic cu sold pe latura opusa nu primeste rand FACTURA; ramane in BALANTA si formularul ii pune `NEREPARTIZAT`. + +| cont | analitic | sold (semnat) | motiv | +|---|---|---|---| +| 5121 | 5121.01 | -20.8 | sold creditor vs latura D a formularului | + +## 5. Lungimi si dubluri + +- cont > 4 sau acont > 4: [] (gol) -> OK +- perechi (cont, acont) duplicate la BALANTA: [] (gol) -> OK + +## 6. Randuri de diferenta generate (pct. 13-15) + +- 117: diferenta neta 2635.87 -> BALANTA (analitic de diferenta) +- 5121: diferenta neta 152.16 -> BALANTA (analitic de diferenta, fara FACTURA) + +Nota: randurile FACTURA de tip `DIFERENTA SINTETIC` au fost eliminate; diferenta nu se mai inventa, o rezolva formularul prin `NEREPARTIZAT`. + +## Verdict + +TOATE verificarile au trecut. + +Nota: coloana `explicatia` (D/C la FACTURA) a fost folosita doar ca control intern si este goala in xlsx-ul final (capul de tabel o pastreaza). diff --git a/extract_balanta.py b/extract_balanta.py new file mode 100644 index 0000000..6a2d380 --- /dev/null +++ b/extract_balanta.py @@ -0,0 +1,243 @@ +"""Extractor fidel pentru balantele de verificare SAGA (PDF cu text). + +Foloseste pdfplumber cu coordonate (NU pdftotext -layout, care decaleaza coloanele). +Fiecare pagina are un antet cu 8 coloane numerice: + Sume precedente (D,C) | Rulaje perioada (D,C) | Sume totale (D,C) | Solduri finale (D,C) + +Utilizare: + py extract_balanta.py "" "" +""" + +import csv +import re +import sys + +import pdfplumber + +CONT_RE = re.compile(r"^\d+(?:\.\d+)*$") +NUM_RE = re.compile(r"^-?\d[\d.]*$") + +CONT_MAX_X = 80.0 +DENUM_MAX_X = 240.0 +ROW_TOL = 3.0 +TOL = 0.01 + +HEADER_WORDS = {"Cont", "Denumirea", "contului", "Debitoare", "Creditoare", + "Sume", "precedente", "Rulaje", "perioada", "totale", + "Solduri", "finale"} +TOTAL_WORDS = ("total", "totaluri") + + +def coloane_numerice(page0): + """Centrele celor 8 coloane, din etichetele Debitoare/Creditoare de pe pagina 1.""" + labels = [w for w in page0.extract_words() + if w["text"] in ("Debitoare", "Creditoare") and 75 <= w["top"] <= 100] + labels.sort(key=lambda w: w["x0"]) + assert len(labels) == 8, f"astept 8 etichete numerice, gasit {len(labels)}" + centre = [(w["x0"] + w["x1"]) / 2.0 for w in labels] + granite = [(centre[i] + centre[i + 1]) / 2.0 for i in range(len(centre) - 1)] + return centre, granite, max(w["top"] for w in labels) + + +def col_index(center, granite): + idx = 0 + for g in granite: + if center >= g: + idx += 1 + else: + break + return idx + + +def randuri(pagina): + """Grupeaza cuvintele in randuri dupa coordonata top (toleranta ROW_TOL).""" + words = sorted(pagina.extract_words(), key=lambda w: (w["top"], w["x0"])) + rows = [] + for w in words: + if rows and abs(w["top"] - rows[-1][0]) <= ROW_TOL: + rows[-1][1].append(w) + else: + rows.append((w["top"], [w])) + return rows + + +def numar(txt): + txt = txt.strip() + if txt in ("", "-", "."): + return 0.0 + return float(txt) + + +def parse_pdf(path): + conturi = [] + with pdfplumber.open(path) as pdf: + _, granite, header_top = coloane_numerice(pdf.pages[0]) + for pno, page in enumerate(pdf.pages, start=1): + for top, ws in randuri(page): + if top < header_top: + continue + cont = None + denum = [] + valori = [None] * 8 + for w in ws: + t = w["text"] + if t in HEADER_WORDS: + continue + if w["x0"] < CONT_MAX_X: + if CONT_RE.match(t): + cont = t + continue + if w["x0"] < DENUM_MAX_X: + denum.append(w) + continue + if NUM_RE.match(t): + ci = col_index((w["x0"] + w["x1"]) / 2.0, granite) + if valori[ci] is None: + valori[ci] = [] + valori[ci].append(w) + + denum = " ".join(w["text"] for w in sorted(denum, key=lambda x: x["x0"])) + vals = [] + for i in range(8): + if valori[i] is None: + vals.append(0.0) + else: + txt = "".join(x["text"] for x in + sorted(valori[i], key=lambda x: x["x0"])) + vals.append(numar(txt)) + + este_total = any(k in denum.lower() for k in TOTAL_WORDS) + if cont: + conturi.append({ + "pagina": pno, "cont": cont, "denumire": denum, + **dict(zip(("prec_d", "prec_c", "rulaj_d", "rulaj_c", + "total_d", "total_c", "sold_d", "sold_c"), vals)), + "este_total": 0, + }) + elif este_total: + conturi.append({ + "pagina": pno, "cont": "", "denumire": denum, + **dict(zip(("prec_d", "prec_c", "rulaj_d", "rulaj_c", + "total_d", "total_c", "sold_d", "sold_c"), vals)), + "este_total": 1, + }) + elif denum and conturi and conturi[-1]["este_total"] == 0: + # rand de continuare a denumirii contului precedent + conturi[-1]["denumire"] = (conturi[-1]["denumire"] + " " + denum).strip() + return conturi + + +NUMS = ["prec_d", "prec_c", "rulaj_d", "rulaj_c", + "total_d", "total_c", "sold_d", "sold_c"] + + +def verifica(rows): + reale = [r for r in rows if not r["este_total"]] + totaluri = [r for r in rows if r["este_total"]] + + a = b = 0 + for r in reale: + if abs(r["total_d"] - (r["prec_d"] + r["rulaj_d"])) > TOL or \ + abs(r["total_c"] - (r["prec_c"] + r["rulaj_c"])) > TOL: + a += 1 + if abs((r["sold_d"] - r["sold_c"]) - (r["total_d"] - r["total_c"])) > TOL: + b += 1 + + coduri = {r["cont"] for r in reale if r["cont"]} + copii = {} + for c in coduri: + parts = c.split(".") + if len(parts) > 1: + copii.setdefault(".".join(parts[:-1]), []).append(c) + + # frunza = nu apare ca parinte; radacina = parintele ei nu exista in balanta + frunze = [r for r in reale if r["cont"] not in copii] + radacini = [r for r in reale + if ".".join(r["cont"].split(".")[:-1]) not in coduri] + + fd = round(sum(r["sold_d"] for r in frunze), 2) + fc = round(sum(r["sold_c"] for r in frunze), 2) + rd = round(sum(r["sold_d"] for r in radacini), 2) + rc = round(sum(r["sold_c"] for r in radacini), 2) + + # (d) parinte vs suma analiticelor: pe fiecare latura si pe net (SAGA neteaza D/C) + byk = {r["cont"]: r for r in reale} + d_laturi = [] + d_net = [] + for r in reale: + kids = copii.get(r["cont"]) + if not kids: + continue + for col in NUMS: + s = round(sum(byk[k][col] for k in kids if k in byk), 2) + if abs(s - r[col]) > TOL: + d_laturi.append((r["cont"], col, r[col], s, round(r[col] - s, 2))) + pnet = round(r["sold_d"] - r["sold_c"], 2) + cnet = round(sum(byk[k]["sold_d"] - byk[k]["sold_c"] + for k in kids if k in byk), 2) + if abs(pnet - cnet) > TOL: + d_net.append((r["cont"], pnet, cnet, round(pnet - cnet, 2))) + + # cross-check parser: fiecare "Total sume clasa N" = suma radacinilor din clasa + clase_ok = clase_rau = 0 + clase_det = [] + for t in totaluri: + if "clasa" not in t["denumire"].lower(): + continue + cl = t["denumire"].split()[-1] + top = [r for r in radacini if r["cont"].startswith(cl)] + sd = round(sum(r["sold_d"] for r in top), 2) + sc = round(sum(r["sold_c"] for r in top), 2) + ok = abs(sd - t["sold_d"]) <= TOL and abs(sc - t["sold_c"]) <= TOL + if ok: + clase_ok += 1 + else: + clase_rau += 1 + clase_det.append((cl, t["sold_d"], sd, t["sold_c"], sc)) + tot_row = [t for t in totaluri if "totaluri" in t["denumire"].lower()] + + print("=== VERIFICARE ===") + print(f"randuri conturi reale : {len(reale)}") + print(f"conturi frunza : {len(frunze)} conturi radacina: {len(radacini)}") + print(f"(a) total=prec+rulaj : {len(reale) - a}/{len(reale)} OK, {a} esec") + print(f"(b) sold=total : {len(reale) - b}/{len(reale)} OK, {b} esec") + print(f"(c) balanta frunze : sold_d={fd} sold_c={fc} " + f"diferenta={round(fd - fc, 2)} {'OK' if abs(fd - fc) <= TOL else 'ESEC'}") + print(f"(c2) balanta radacini : sold_d={rd} sold_c={rc} " + f"diferenta={round(rd - rc, 2)} {'OK' if abs(rd - rc) <= TOL else 'ESEC'}") + if tot_row: + tr = tot_row[0] + print(f" Totaluri (PDF) : sold_d={tr['sold_d']} sold_c={tr['sold_c']}") + print(f" cross-check clase: {clase_ok} OK, {clase_rau} esec") + print(f"(d) parinti vs analitice: {len(d_laturi)} diferente pe laturi, " + f"{len(d_net)} diferente pe net") + for p in d_laturi: + print(" d-latura", p) + for p in d_net: + print(" d-NET ", p) + for p in clase_det: + print(" clasa ", p) + return {"n": len(reale), "frunze": len(frunze), "radacini": len(radacini), + "a": a, "b": b, "fd": fd, "fc": fc, "rd": rd, "rc": rc, + "d_laturi": d_laturi, "d_net": d_net, "clase_det": clase_det, + "totaluri": [(t["sold_d"], t["sold_c"]) for t in tot_row]} + + +def main(): + if len(sys.argv) != 3: + print(__doc__) + sys.exit(1) + pdf_path, csv_path = sys.argv[1], sys.argv[2] + rows = parse_pdf(pdf_path) + cols = ["pagina", "cont", "denumire"] + NUMS + ["este_total"] + with open(csv_path, "w", newline="", encoding="utf-8-sig") as f: + wr = csv.DictWriter(f, fieldnames=cols) + wr.writeheader() + for r in rows: + wr.writerow(r) + print(f"scris {csv_path}: {len(rows)} randuri") + verifica(rows) + + +if __name__ == "__main__": + main() diff --git a/genereaza_xlsx.py b/genereaza_xlsx.py new file mode 100644 index 0000000..355d3b3 --- /dev/null +++ b/genereaza_xlsx.py @@ -0,0 +1,490 @@ +"""Genereaza fisierele xlsx de initializare ROACONT din balantele SAGA (CSV). + +Produce (pentru fiecare firma): + init__2025_12.xlsx - un sheet, randul 1 = capul de tabel, + datele de la randul 2 in jos + docs/verificare_.md - verificarile obligatorii + +Reguli: docs/decizii_import.md (pct. 11-15) si docs/conturi_cu_analitice.md. + +Forma randurilor (revizuit 20.09.2026, vezi pct. 14-15): +- cont obisnuit: doar BALANTA per frunza (acont completat). +- 401/4092/4111/461/462/4551: un BALANTA agregat pe sintetic (acont gol) + cate + un FACTURA per analitic (acont gol). +- 5121/5124: analiticele raman analitice; per analitic un BALANTA cu acont SI un + FACTURA cu ACELASI acont. +- 5311: BALANTA + FACTURA pe sintetic (acont gol), partener CENTRALA. +- 5125: cont obisnuit cu analitice (fara parteneri). +- diferenta neta parinte/copii (postare directa pe sintetic): la nepartener si la + 5121/5124 devine rand BALANTA de diferenta (analitic nou, fara FACTURA); la + ceilalti parteneri se include in BALANTA agregat. NU se mai emite FACTURA de + diferenta (o rezolva formularul, prin NEREPARTIZAT). +- analiticul cu sold pe latura opusa celei fixate de formular (':379') nu primeste + FACTURA; ramane doar in BALANTA si apare ca NEREPARTIZAT. +""" + +import csv +import os + +from openpyxl import load_workbook + +AN = 2025 +LUNA = 12 +DATA = "01.12.2025" +DATASCAD = "31.12.2025" +SERIE = None +VALUTA = None + +TEMPLATE = "init_facturi_balanta_note.xlsx" + +# Latura pe care formularul pune randurile FACTURA (frm...sc2:379/'383'): +# conturile din lista merg pe CREDIT, tot restul pe DEBIT. +LATURA_CREDIT = {"401", "404", "462", "419", "408", "4551"} + +# 5121/5124: analiticele raman analitice SI primesc partener (BALANTA + FACTURA +# pe acelasi acont). +PARTENER_BANCA = {"5121", "5124"} +# Conturi cu parteneri, un singur BALANTA agregat pe sintetic + FACTURA per analitic. +PARTENER_SINTETIC = {"401", "4092", "4111", "461", "462", "4551"} +# Casa: fara analitice, BALANTA + FACTURA pe sintetic. +PARTENER_FARA_ANALITICE = {"5311"} + +PARTENER = PARTENER_BANCA | PARTENER_SINTETIC | PARTENER_FARA_ANALITICE + +FIRME = [ + ("FUNDATIA", "balanta_FUNDATIA.csv"), + ("MASTER", "balanta_MASTERJOB.csv"), +] + + +class Stop(Exception): + """Conditie neprevazuta: nu ghicim, raportam.""" + + +def citeste_header(): + wb = load_workbook(TEMPLATE, read_only=True) + ws = wb.active + hdr = [c.value for c in ws[1]] + wb.close() + return hdr + + +def citeste_balanta(path): + rows = [] + with open(path, encoding="utf-8-sig", newline="") as f: + for r in csv.DictReader(f): + cont = (r["cont"] or "").strip() + if r["este_total"] == "1" or cont == "": + continue + rows.append({ + "cont": cont, + "denumire": (r["denumire"] or "").strip(), + "total_d": float(r["total_d"]), + "total_c": float(r["total_c"]), + }) + return rows + + +def citeste_totaluri(path): + with open(path, encoding="utf-8-sig", newline="") as f: + for r in csv.DictReader(f): + if "totaluri" in (r["denumire"] or "").lower(): + return float(r["total_d"]), float(r["total_c"]) + return None + + +def arbore(rows): + by = {r["cont"]: r for r in rows} + children = {} + for c in by: + p = ".".join(c.split(".")[:-1]) + if p in by: + children.setdefault(p, []).append(c) + return by, children + + +def este_partener(cont): + return cont.split(".")[0] in PARTENER + + +def latura_factura(cont): + """Latura fixa pe care formularul pune randurile FACTURA ale contului.""" + return "C" if cont.split(".")[0] in LATURA_CREDIT else "D" + + +def split_cont(cont): + seg = cont.split(".") + return seg[0], "".join(seg[1:]) + + +def diferente(by, children): + """(cont_parinte, diferenta_net) pentru parintii cu postare directa.""" + out = [] + for cont, r in by.items(): + kids = children.get(cont) + if not kids: + continue + pnet = round(r["total_d"] - r["total_c"], 2) + cnet = round(sum(by[k]["total_d"] - by[k]["total_c"] for k in kids), 2) + d = round(pnet - cnet, 2) + if abs(d) > 0.005: + out.append((cont, d)) + return out + + +def acont_diferenta(parent, kids): + """Primul cod liber de forma 99 (segmente scurte) / 9999 (segmente lungi).""" + seg = parent.split(".") + base = "".join(seg[1:]) + style = 2 if max(len(k.split(".")[-1]) for k in kids) <= 2 else 4 + cod = "99" if style == 2 else "9999" + ac = base + cod + if len(ac) > 4: + raise Stop(f"acont diferenta prea lung pentru {parent}: '{ac}'") + frati = {split_cont(k)[1] for k in kids} + if ac in frati: + raise Stop(f"acont diferenta '{ac}' deja folosit sub {parent}") + return ac + + +def rand(header, **kw): + r = {h: None for h in header} + r.update(an=AN, luna=LUNA, data=DATA, datascad=DATASCAD, + serie=SERIE, valuta=VALUTA) + r.update(kw) + return r + + +def _semn_sold(net): + return "creditor" if net < 0 else "debitor" + + +def genereaza(rows, header): + by, children = arbore(rows) + diffs = diferente(by, children) + diff_by_parent = dict(diffs) + + # verificarile de structura care nu se ghicesc + for cont in by: + if este_partener(cont): + continue + if cont not in children: + cont4, ac = split_cont(cont) + if len(cont4) > 4 or len(ac) > 4: + raise Stop(f"cont/acont prea lung: {cont} -> ({cont4},{ac})") + for parent in diff_by_parent: + if not este_partener(parent) or parent.split(".")[0] in PARTENER_BANCA: + acont_diferenta(parent, children[parent]) + for p in {c.split(".")[0] for c in by if este_partener(c)}: + for k in children.get(p, []): + if k in children: + raise Stop(f"analitic partener cu sub-analitice: {k}") + + out = [] + leaf_map = {} # frunza -> randurile dedicate (folosite la dubluri) + leaf_rep = set() # toate frunzele reprezentate (inclusiv in BALANTA agregat) + sarite = [] # (cont, analitic, sold_semnat, motiv) + + def add(r, leaf=None): + out.append(r) + if leaf is not None: + leaf_map.setdefault(leaf, []).append(len(out) - 1) + leaf_rep.add(leaf) + + # A. conturi nepartener: cate un BALANTA per frunza + for r in rows: + if este_partener(r["cont"]) or r["cont"] in children: + continue + cont4, ac = split_cont(r["cont"]) + add(rand(header, TIP="BALANTA", cont=cont4, acont=ac, numar=1, + nume=r["denumire"], totdeb=round(r["total_d"], 2), + totcred=round(r["total_c"], 2)), leaf=r["cont"]) + + # A. analitic de diferenta pe parinte nepartener (postare directa pe sintetic) + for cont, d in diffs: + if este_partener(cont): + continue + ac = acont_diferenta(cont, children[cont]) + add(rand(header, TIP="BALANTA", cont=cont.split(".")[0], acont=ac, + numar=1, nume="DIFERENTA SINTETIC SAGA", + totdeb=d if d > 0 else None, + totcred=-d if d < 0 else None)) + + parteneri = sorted({c.split(".")[0] for c in by if este_partener(c)}) + for p in parteneri: + direct = children.get(p, []) + side = latura_factura(p) + + if p in PARTENER_BANCA and direct: + # 5121/5124: BALANTA cu acont + FACTURA cu ACELASI acont. + for k in direct: + kd = by[k] + kac = split_cont(k)[1] + add(rand(header, TIP="BALANTA", cont=p, acont=kac, numar=1, + nume=kd["denumire"], totdeb=round(kd["total_d"], 2), + totcred=round(kd["total_c"], 2)), leaf=k) + net = round(kd["total_d"] - kd["total_c"], 2) + if net == 0: + continue + if (net > 0) == (side == "D"): + add(rand(header, TIP="FACTURA", cont=p, acont=kac, + numar=k.replace(".", ""), + nume=kd["denumire"] or f"FURNIZOR {k}", + cod_fiscal=k, sold=abs(net), explicatia=side)) + else: + sarite.append((p, k, net, + f"sold {_semn_sold(net)} vs latura {side} " + f"a formularului")) + if p in diff_by_parent: + d = diff_by_parent[p] + ac = acont_diferenta(p, direct) + add(rand(header, TIP="BALANTA", cont=p, acont=ac, numar=1, + nume="DIFERENTA SINTETIC SAGA", + totdeb=d if d > 0 else None, + totcred=-d if d < 0 else None)) + continue + + # 401/4092/4111/461/462/4551 si 5311 + if direct: + base_d = sum(by[k]["total_d"] for k in direct) + base_c = sum(by[k]["total_c"] for k in direct) + d = diff_by_parent.get(p, 0.0) + add(rand(header, TIP="BALANTA", cont=p, acont=None, numar=1, + nume=by[p]["denumire"], + totdeb=round(base_d + (d if d > 0 else 0.0), 2), + totcred=round(base_c + (-d if d < 0 else 0.0), 2))) + for k in direct: + net = round(by[k]["total_d"] - by[k]["total_c"], 2) + if net == 0: + leaf_rep.add(k) + continue + if (net > 0) == (side == "D"): + add(rand(header, TIP="FACTURA", cont=p, acont=None, + numar=k.replace(".", ""), + nume=by[k]["denumire"] or f"FURNIZOR {k}", + cod_fiscal=k, sold=abs(net), explicatia=side), + leaf=k) + else: + sarite.append((p, k, net, + f"sold {_semn_sold(net)} vs latura {side} " + f"a formularului")) + leaf_rep.add(k) + else: + net = round(by[p]["total_d"] - by[p]["total_c"], 2) + add(rand(header, TIP="BALANTA", cont=p, acont=None, numar=1, + nume=by[p]["denumire"], totdeb=round(by[p]["total_d"], 2), + totcred=round(by[p]["total_c"], 2)), leaf=p) + if net != 0: + if (net > 0) == (side == "D"): + nume = "CENTRALA" if p == "5311" else by[p]["denumire"] + add(rand(header, TIP="FACTURA", cont=p, acont=None, + numar=p, nume=nume, cod_fiscal=p, sold=abs(net), + explicatia=side)) + else: + sarite.append((p, p, net, + f"sold {_semn_sold(net)} vs latura {side} " + f"a formularului")) + return out, diffs, leaf_map, leaf_rep, sarite + + +def scrie_xlsx(header, rows, path): + wb = load_workbook(TEMPLATE) + ws = wb.active + if ws.max_row > 1: + ws.delete_rows(2, ws.max_row - 1) + for i, r in enumerate(rows, start=2): + for j, h in enumerate(header, start=1): + v = r.get(h) + if h == "explicatia": # coloana temporara de control + v = None + ws.cell(i, j, v) + wb.save(path) + + +def verifica(firma, csv_path, xlsx_path, rows, out, diffs, leaf_map, leaf_rep, + sarite, header): + by, children = arbore(rows) + leaves = [c for c in by if c not in children] + diff_by_parent = dict(diffs) + + totdeb = round(sum(r["totdeb"] or 0 for r in out), 2) + totcred = round(sum(r["totcred"] or 0 for r in out), 2) + net = round(totdeb - totcred, 2) + toturi = citeste_totaluri(csv_path) + + pierdute = sorted(set(leaves) - leaf_rep) + duplicate_leaf = sorted(c for c, v in leaf_map.items() if len(v) != 1) + + # lungimi + dubluri (cont,acont) pe BALANTA + lungimi = [] + bal_pairs = {} + for r in out: + if len(r["cont"]) > 4: + lungimi.append(("cont", r["cont"])) + if r["acont"] and len(r["acont"]) > 4: + lungimi.append(("acont", r["acont"])) + if r["TIP"] == "BALANTA": + bal_pairs.setdefault((r["cont"], r["acont"]), []).append(r) + dubluri_bal = {k: v for k, v in bal_pairs.items() if len(v) > 1} + + # parteneri: SUM(sold FACTURA cu semn) + NEREPARTIZAT asteptat = net sintetic + part_rows = {} + for r in out: + if r["TIP"] == "FACTURA": + semn = 1 if latura_factura(r["cont"]) == "D" else -1 + part_rows[r["cont"]] = part_rows.get(r["cont"], 0.0) + semn * (r["sold"] or 0) + + sarite_by_cont = {} + for cont, _k, s, _motiv in sarite: + sarite_by_cont[cont] = round(sarite_by_cont.get(cont, 0.0) + s, 2) + + part_verif = [] + for p in sorted({c.split(".")[0] for c in by if este_partener(c)}): + net_sint = round(by[p]["total_d"] - by[p]["total_c"], 2) + suma = round(part_rows.get(p, 0.0), 2) + sarit = round(sarite_by_cont.get(p, 0.0), 2) + direct = round(diff_by_parent.get(p, 0.0), 2) + asteptat = round(sarit + direct, 2) + diferenta = round(net_sint - suma, 2) + ok = abs(diferenta - asteptat) <= 0.005 + part_verif.append((p, suma, net_sint, sarit, direct, asteptat, diferenta, ok)) + + ok_bal = abs(net) <= 0.005 + ok_leaves = not pierdute and not duplicate_leaf + ok_part = all(x[7] for x in part_verif) + ok_lung = not lungimi and not dubluri_bal + + L = [] + L.append(f"# Verificare `{os.path.basename(xlsx_path)}`") + L.append("") + L.append(f"Generat de `genereaza_xlsx.py` din `{os.path.basename(csv_path)}`. " + f"Randuri de date: {len(out)} ({sum(1 for r in out if r['TIP']=='BALANTA')} BALANTA, " + f"{sum(1 for r in out if r['TIP']=='FACTURA')} FACTURA).") + L.append("") + L.append("## 1. Balanta generala (SUM totdeb = SUM totcred)") + L.append("") + L.append(f"- SUM(totdeb) = {totdeb}") + L.append(f"- SUM(totcred) = {totcred}") + L.append(f"- diferenta (totdeb - totcred) = {net} -> {'OK' if ok_bal else '**ESEC**'}") + if toturi: + td, tc = toturi + L.append(f"- Totaluri balanta: total_d={td} total_c={tc} " + f"net={round(td - tc, 2)}") + L.append(f"- NET xlsx ({net}) vs NET Totaluri ({round(td - tc, 2)}) -> " + f"{'OK' if abs(net - (td - tc)) <= 0.005 else '**ESEC**'}") + L.append(f"- Nota: SUM(totdeb)={totdeb} difera de Totaluri.total_d={td} cu " + f"{round(totdeb - td, 2)}; suma pe laturi a PDF-ului nu se poate " + f"reconstrui din frunze acolo unde SAGA a netat sinteticul (gross-ul " + f"parintelui e netat). Netul se pastreaza exact.") + L.append("") + L.append("## 2. Conturi frunza din CSV, reprezentate o singura data") + L.append("") + L.append(f"- frunze in CSV: {len(leaves)}") + L.append(f"- reprezentate in xlsx: {len(leaf_rep)}") + L.append(f"- conturi pierdute: {pierdute if pierdute else '[] (gol)'} -> " + f"{'OK' if not pierdute else '**ESEC**'}") + L.append(f"- frunze cu mai putin/mai mult de un rand dedicat: " + f"{duplicate_leaf if duplicate_leaf else '[] (gol)'} -> " + f"{'OK' if not duplicate_leaf else '**ESEC**'}") + L.append("") + L.append("## 3. Conturi partener: FACTURA + NEREPARTIZAT = net sintetic") + L.append("") + L.append("Formularul scade din randul BALANTA suma randurilor FACTURA de pe " + "acelasi `(cont, acont, latura)` si lasa restul pe partenerul " + "`NEREPARTIZAT`. Deci: `net sintetic - SUM(sold FACTURA cu semn) = " + "analitice sarite + postare directa pe sintetic`.") + L.append("") + L.append("| cont | SUM(sold FACTURA) | net sintetic | analitice sarite | postare directa | NEREPARTIZAT asteptat | diferenta | rezultat |") + L.append("|---|---|---|---|---|---|---|---|") + for p, suma, net_sint, sarit, direct, asteptat, diferenta, ok in part_verif: + L.append(f"| {p} | {suma} | {net_sint} | {sarit} | {direct} | {asteptat} " + f"| {diferenta} | {'OK' if ok else '**ESEC**'} |") + L.append("") + L.append(f"Rezultat: {'OK' if ok_part else '**ESEC**'}") + L.append("") + L.append("## 4. Analitice sarite (sold pe latura opusa formularului)") + L.append("") + L.append("Latura FACTURA e fixa in cod (`:379`): `401,404,462,419,408,4551` -> " + "CREDIT, orice alt cont -> DEBIT. Un analitic cu sold pe latura opusa nu " + "primeste rand FACTURA; ramane in BALANTA si formularul ii pune " + "`NEREPARTIZAT`.") + L.append("") + if not sarite: + L.append("Niciunul.") + else: + L.append("| cont | analitic | sold (semnat) | motiv |") + L.append("|---|---|---|---|") + for cont, k, s, motiv in sarite: + L.append(f"| {cont} | {k} | {s} | {motiv} |") + L.append("") + L.append("## 5. Lungimi si dubluri") + L.append("") + L.append(f"- cont > 4 sau acont > 4: {lungimi if lungimi else '[] (gol)'} -> " + f"{'OK' if not lungimi else '**ESEC**'}") + L.append(f"- perechi (cont, acont) duplicate la BALANTA: " + f"{list(dubluri_bal) if dubluri_bal else '[] (gol)'} -> " + f"{'OK' if not dubluri_bal else '**ESEC**'}") + L.append("") + L.append("## 6. Randuri de diferenta generate (pct. 13-15)") + L.append("") + if not diffs: + L.append("Niciunul (toate diferentele nete sunt zero).") + for cont, d in diffs: + base = cont.split(".")[0] + if base in PARTENER_BANCA: + kind = "BALANTA (analitic de diferenta, fara FACTURA)" + elif este_partener(cont): + kind = "inclus in BALANTA agregat al sinteticului (fara FACTURA)" + else: + kind = "BALANTA (analitic de diferenta)" + L.append(f"- {cont}: diferenta neta {d} -> {kind}") + L.append("") + L.append("Nota: randurile FACTURA de tip `DIFERENTA SINTETIC` au fost eliminate; " + "diferenta nu se mai inventa, o rezolva formularul prin `NEREPARTIZAT`.") + L.append("") + L.append("## Verdict") + L.append("") + toate = ok_bal and ok_leaves and ok_part and ok_lung + L.append(f"{'TOATE verificarile au trecut.' if toate else '**UNA SAU MAI MULTE VERIFICARI AU PICAT - datele NU au fost ajustate.**'}") + L.append("") + L.append("Nota: coloana `explicatia` (D/C la FACTURA) a fost folosita doar ca " + "control intern si este goala in xlsx-ul final (capul de tabel o pastreaza).") + L.append("") + + with open(os.path.join("docs", f"verificare_{firma}.md"), "w", + encoding="utf-8") as f: + f.write("\n".join(L)) + + return {"bal": ok_bal, "leaves": ok_leaves, "part": ok_part, "lung": ok_lung, + "totdeb": totdeb, "totcred": totcred, "net": net, + "pierdute": pierdute, "dubluri_leaf": duplicate_leaf, + "dubluri_bal": list(dubluri_bal), "lungimi": lungimi, + "part_verif": part_verif, "sarite": sarite} + + +def main(): + header = citeste_header() + assert len(header) == 39, f"cap de tabel neasteptat: {len(header)} coloane" + for firma, csv_path in FIRME: + rows = citeste_balanta(csv_path) + out, diffs, leaf_map, leaf_rep, sarite = genereaza(rows, header) + xlsx_path = f"init_{firma}_2025_12.xlsx" + scrie_xlsx(header, out, xlsx_path) + rez = verifica(firma, csv_path, xlsx_path, rows, out, diffs, leaf_map, + leaf_rep, sarite, header) + print(f"=== {firma} ===") + print(f" rows: {len(out)} totdeb={rez['totdeb']} totcred={rez['totcred']} net={rez['net']}") + print(f" balanta={'OK' if rez['bal'] else 'ESEC'} " + f"frunze={'OK' if rez['leaves'] else 'ESEC'} " + f"parteneri={'OK' if rez['part'] else 'ESEC'} " + f"lungimi={'OK' if rez['lung'] else 'ESEC'}") + print(f" scris {xlsx_path} si docs/verificare_{firma}.md") + if rez["sarite"]: + print(f" analitice sarite: {rez['sarite']}") + if rez["pierdute"] or rez["dubluri_leaf"] or rez["dubluri_bal"] or rez["lungimi"]: + print(" ATENTIE:", rez["pierdute"], rez["dubluri_leaf"], + rez["dubluri_bal"], rez["lungimi"]) + + +if __name__ == "__main__": + main() diff --git a/init_FUNDATIA_2025_12.xlsx b/init_FUNDATIA_2025_12.xlsx new file mode 100644 index 0000000..7a4555b Binary files /dev/null and b/init_FUNDATIA_2025_12.xlsx differ diff --git a/init_MASTER_2025_12.xlsx b/init_MASTER_2025_12.xlsx new file mode 100644 index 0000000..ee919b2 Binary files /dev/null and b/init_MASTER_2025_12.xlsx differ diff --git a/init_facturi_balanta_note.xlsx b/init_facturi_balanta_note.xlsx new file mode 100644 index 0000000..17c5db0 Binary files /dev/null and b/init_facturi_balanta_note.xlsx differ