diff --git a/.gitignore b/.gitignore index 4040daa..5141cc1 100644 --- a/.gitignore +++ b/.gitignore @@ -1,3 +1,20 @@ __pycache__/ *.pyc .gstack/ + +# iesiri si date de firme de productie - raman pe disc, nu in git +init_*.xlsx +export_*.xlsx +mapare_*.xlsx +balanta_*.csv +!init_facturi_balanta_note.xlsx + +# etalonul de regresie e anonimizat si se comite; tabela de corespondenta NU +tests/_corespondenta_anonimizare.json + +# copii de baze de client si iesiri intermediare ale convertorului +*.fdb +*.FDB +parteneri_*.csv +facturi_*.csv +corectii_*.xlsx diff --git a/balanta_FUNDATIA.csv b/balanta_FUNDATIA.csv deleted file mode 100644 index 160337a..0000000 --- a/balanta_FUNDATIA.csv +++ /dev/null @@ -1,89 +0,0 @@ -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 deleted file mode 100644 index 170a50f..0000000 --- a/balanta_MASTERJOB.csv +++ /dev/null @@ -1,89 +0,0 @@ -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/handoff_etapa2_convertor.md b/docs/handoff_etapa2_convertor.md new file mode 100644 index 0000000..02b23f2 --- /dev/null +++ b/docs/handoff_etapa2_convertor.md @@ -0,0 +1,167 @@ +# Handoff - etapa 2, convertorul reutilizabil SAGA -> ROA + +Scris 21.09.2026. Sesiunea urmatoare este **orchestrator**, nu executant: imparte pe lane-uri, +trimite sarcinile la agenti opencode, verifica portile. Nu scrie ea codul. + +**Stare: planul e gata si aprobat pe decizii; nu s-a scris nicio linie de cod pentru etapa 2.** +Marius nu a dat inca "porneste" pe lane-uri. Intreaba-l inainte sa lansezi primul lane. + +--- + +## 1. Ce sa citesti, in ordine, si de ce + +| fisier | de ce | +|---|---| +| `docs/plan_etapa2_convertor.md` | **contractul de lucru, v3.** Tot ce urmeaza se masoara fata de el | +| `docs/raport_sursa_saga_xlsx.md` | SAGA veche (VFP); conventiile `conturi_roa.dbf` (`.TOATE`, `.RESTUL`) | +| `docs/raport_exporturi_saga_noua.md` | SAGA noua (Firebird); structura exporturilor si a bazei | +| `docs/decizii_import.md` | regulile de mapare, **validate in productie - nu se redeschid** | +| `docs/review_ceo_etapa2.md`, `docs/review_eng_etapa2.md` | de unde vin corectiile din v3; reciteste doar daca vrei sa redeschizi o decizie | + +Nu reface cercetarea. Cele doua rapoarte au costat doua lane-uri si contin dovezi cu fisier si linie. + +## 2. Ce e gata + +- Etapele 1-6 din `docs/plan_solduri2roa.md`: cele doua xlsx au fost **importate in ROACONT si au + trecut**; scripturile `sql/update_cod_fiscal_*.sql` au fost **executate** de Marius. +- Cercetarea pe ambele formate SAGA + conectarea la Firebird, verificata live. +- Planul v3, dupa review de strategie si de arhitectura. +- `.gitignore` + `git rm --cached` pe iesirile de productie (fisierele raman pe disc). + +- **Etalonul de regresie este facut si pus in git** (21.09.2026): `tests/golden/` cu + `golden_FUNDATIA_2025_12.xlsx` si `golden_MASTER_2025_12.xlsx`, produse de + `tests/anonimizeaza_etalon.py`. Verificat: structura, numarul de randuri si sumele sunt + identice cu originalele (`SUM(totdeb) = SUM(totcred)` neatins), au fost schimbate doar + coloanele 10-14 pe randurile FACTURA plus IBAN-urile; zero IBAN si zero cod fiscal real + ramase. Tabela de corespondenta (`tests/_corespondenta_anonimizare.json`) e ignorata de git - + nu o comite, cu ea anonimizarea se desface. + +## 3. Ce NU e facut + +Tot ce e in tabelul de lane-uri din plan, mai putin etalonul. Niciun fisier de cod nou pentru +conversie, niciun test, niciun `config/conturi_parteneri.csv`. + +## 4. Deciziile deja luate - nu le redeschide + +1. **Conturile cu parteneri**: setul validat din `genereaza_xlsx.py:46-50` este autoritatea, tinut + in `config/conturi_parteneri.csv`. `CONFIG_CONT_IREG` e consultativ; unealta **raporteaza** + divergentele, nu le aplica. Motivul, cu dovada, e in plan - Oracle nu listeaza 5121/5124/5311. +2. **`acont` pentru conturi cu parteneri** ramane decis de `genereaza_xlsx.py`; maparea doar + suprascrie explicit. Randurile de diferenta raman calculate in cod. +3. **Maparea = doua fisiere**: `mapare_.xlsx` scris doar de unealta (regenerat complet), + `corectii_.xlsx` scris doar de Marius. +4. **Cititorul FDB se face acum**, marcat explicit "verificat doar pe cazul sintetic". +5. **Etalonul de regresie**: xlsx-uri intregi, **anonimizate** (sume si structura neatinse), in + `tests/golden/`. Tabela de corespondenta nume real -> nume fals **nu se comite**. +6. **Teste**: `unittest` din stdlib. Fara dependinte noi de test. +7. Sursa: PDF, foaie de calcul SAGA si Firebird, toate trei, egale. + +## 5. Ordinea lane-urilor + +`contract` singur, primul -> apoi `citire-xlsx` si `mapare` in paralel -> `citire-fdb` -> +`integrare` -> `regresie`. Criteriile de terminare sunt in plan, in tabelul de lane-uri si in cel de +testare. Etalonul din `tests/golden/` a fost fixat **inainte** sa se schimbe vreo linie de cod - +asta e tot rostul ordinii. Daca vreun lane modifica `genereaza_xlsx.py` si regresia incepe sa pice, +etalonul are dreptate, nu codul nou. + +## 6. Cum lansezi un lane (verificat azi, functioneaza) + +Ghidul complet: `D:\ROA\ROACONT\COMUN\docs\opencode_agenti_orchestrare.md`. + +- **Port pentru acest proiect: 4296.** Nu-l folosi pe 4196 (ROACONT) sau 4096 (ROAFACTURARE) - + oprirea serverului dintr-un proiect omoara lane-urile celuilalt. Portul 4296 **nu e inca trecut in + tabelul din ghid** - adauga-l acolo (COMUN are nevoie de aprobare inainte de commit). +- Pornire, din directorul proiectului: `opencode serve --port 4296` +- Model: `{"providerID":"opencode-go","modelID":"deepseek-v4.1-flash"}` +- Promptul de sistem, obligatoriu la fiecare sesiune, in campul `system`: + `D:\ROA\ROACONT\COMUN\docs\opencode_prompt_initial.md` +- Sesiune noua: `POST /session {title}` -> `id`; + sarcina: `POST /session/:id/prompt_async?directory=D:\ROA\IMPORT2ROA\solduri2roa` +- Stare: `GET /session/status` - sesiunea lipseste cand e libera, `{}` = toate libere. +- Oprire la final: + `Stop-Process -Id (Get-NetTCPConnection -LocalPort 4296 -State Listen).OwningProcess` + +Sablon PowerShell pentru trimitere (JSON pe UTF-8, altfel se strica diacriticele si ghilimelele): + +```powershell +$u='http://127.0.0.1:4296' +$sys = [IO.File]::ReadAllText('D:\ROA\ROACONT\COMUN\docs\opencode_prompt_initial.md') +$m = @{providerID='opencode-go'; modelID='deepseek-v4.1-flash'} +$sid = (Invoke-RestMethod -Method Post "$u/session" -ContentType 'application/json' -Body '{"title":"lane-X"}').id +$b = @{model=$m; system=$sys; parts=@(@{type='text';text=$task})} | ConvertTo-Json -Depth 5 +Invoke-RestMethod -Method Post "$u/session/$sid/prompt_async?directory=D:\ROA\IMPORT2ROA\solduri2roa" ` + -ContentType 'application/json; charset=utf-8' -Body ([Text.Encoding]::UTF8.GetBytes($b)) +``` + +Asteptarea: nu face `Start-Sleep` lung in foreground (harness-ul il blocheaza). Foloseste Bash in +fundal: `until curl -s http://127.0.0.1:4296/session/status | grep -qv busy; do sleep 20; done`. + +**Ce trebuie sa contina fiecare sarcina de lane**: numele lane-ului, fisierele exacte de atins, +criteriul de terminare luat din plan, interdictiile (fara commit, fara `sed -i`, fara modificari in +`D:\ROA\ROACONT`, `D:\SAGA250909`, `saga2roa*`), unde scrie raportul, si ultimul mesaj +`GATA ` / `BLOCAT : motiv`. Agentii respecta asta; doi lane-uri au mers azi asa. + +## 7. Capcane deja platite - nu le redescoperi + +- `openpyxl` **nu** citeste `.xls` (BIFF). Pentru `.xls`: `xlrd` (instalat, 2.0.2) sau conversie + `soffice --headless --convert-to xlsx`. Ambele verificate. +- Firebird: **numai embedded**. `firebird-driver` (instalat, 2.0.3) + `fdb.load_api` catre + `C:\Program Files\Firebird\Firebird30_Saga\fbclient.dll`, SYSDBA/masterkey, charset `WIN1250`, + `access_mode=READ`, `no_gc=True`. Pe TCP 3060 parola implicita **nu** merge. +- In `CONTURI` **soldurile stocate sunt 0**; balanta se obtine agregand `REGISTRU`. Cine citeste + `CONTURI.DEB_PREC` scoate o balanta goala fara nicio eroare. +- Coloanele `_1` din export (S..AF) seamana cu cele principale. Potrivirea numelor de coloana se + face **exact**, niciodata pe substring: `TOTAL_DEB` vs `TOTAL_DEB_1`. +- Numele foii difera intre surse (`balanta` / `xl` / `Sheet1`) - ia prima foaie, nu cauta dupa nume. +- `CONT` se citeste ca text. `401.00002` citit ca numar se strica. +- Heredoc-urile lungi in Bash au esuat pe fisierele mari de documentatie; scrie-le cu tool-ul de + scriere de fisiere. +- `python` direct din Bash e stub Windows Store si nu scrie nimic (iese 0 si fisierul ramane + neatins). Foloseste `py`, sau PowerShell. + +## 8. Starea pe disc - nimic periculos, dar necomis + +`git status` la predare (HEAD = `ceab089`, branch `main`): + +``` +M .gitignore +D balanta_FUNDATIA.csv +D balanta_MASTERJOB.csv + M docs/parteneri_cui_gasite.md + M docs/plan_solduri2roa.md +D export_balanta_fundatia_12_2025.xlsx +D init_FUNDATIA_2025_12.xlsx +D init_MASTER_2025_12.xlsx + M sql/update_cod_fiscal_FUNDATIA.sql + M sql/update_cod_fiscal_MASTER.sql +A tests/anonimizeaza_etalon.py +A tests/golden/golden_FUNDATIA_2025_12.xlsx +A tests/golden/golden_MASTER_2025_12.xlsx +?? docs/handoff_etapa2_convertor.md +?? docs/plan_etapa2_convertor.md +?? docs/raport_exporturi_saga_noua.md +?? docs/raport_sursa_saga_xlsx.md +?? docs/review_ceo_etapa2.md +?? docs/review_eng_etapa2.md +?? exemple/ +``` + +Verificari inainte de orice altceva: +- `init_FUNDATIA_2025_12.xlsx` si `init_MASTER_2025_12.xlsx` sunt pe disc dar nu mai sunt in git. + Etalonul anonimizat e deja generat din ele si comis, deci poarta de regresie nu mai depinde de + ele. Sunt necesare doar daca vrei sa **regenerezi** etalonul (`py testsnonimizeaza_etalon.py`). +- Nu se da commit fara ca Marius sa vada diff-ul (regula proiectului). +- Niciun proces ramas viu: serverul opencode de pe 4296 a fost oprit la predare. Il pornesti tu, + cu comanda din sectiunea 6. +- `D:\ROA\ROACONT`, `D:\SAGA250909` si `saga2roa*` nu au fost modificate si nu se modifica. + +## 9. Primul lucru de facut in sesiunea noua + +1. Citeste planul v3. +2. Intreaba-l pe Marius daca pornesti (nu a dat inca "da" pe lansarea lane-urilor). +3. La "da": lanseaza **doar** lane-ul `contract`. Etalonul exista deja, deci lane-ul are de facut + `config/conturi_parteneri.csv` + scriptul de divergenta Oracle, si de scris testul de regresie + care compara iesirea codului de azi cu `tests/golden/`, pe valori de celula (nu pe hash: un + xlsx rescris de alta versiune de openpyxl are alti octeti cu acelasi continut). Testul trebuie + sa treaca **cu codul de conversie neschimbat**. Daca nu trece, e bug in test sau in etalon, nu + in cod, si restul lane-urilor nu au voie sa porneasca. diff --git a/docs/parteneri_cui_gasite.md b/docs/parteneri_cui_gasite.md index c24cab4..ee49c03 100644 --- a/docs/parteneri_cui_gasite.md +++ b/docs/parteneri_cui_gasite.md @@ -77,3 +77,13 @@ Motivul fiecaruia; CUI-ul ramane provizoriu. - 401.00018 HOSTVISION SRL, 401.00003 TEMPLUM PLUS si 4111.00004 EM INTERNATIONAL SERVICES GROUP sunt singurele potriviri exacte, dar firmele sunt dizolvate/radiate/inactive. Sunt trecute la "gasite" cu starea notata; de verificat daca partenerul din balanta este chiar acesta. + +## Prefix RO (plătitori de TVA) + +Verificare ANAF 21.09.2026 (POST `https://webservicesp.anaf.ro/api/PlatitorTvaRest/v9/tva`, +câmpul `scpTVA`) pentru toate cele 17 CUI-uri găsite. Codul fiscal se scrie cu prefix `RO` +doar la plătitorii de TVA; neplătitorii rămân cu CUI-ul simplu. + +Neplătitori (fără prefix): 14446160 TEMPLUM PLUS (radiat 26.03.2021), 33048749 CREATIV EXPERT +CONSTRUCT, 3598139 HOSTVISION, 44234399 EM INTERNATIONAL SERVICES GROUP. +Restul de 13 au prefix `RO` în scripturile `sql/update_cod_fiscal_*.sql`. diff --git a/docs/plan_etapa2_convertor.md b/docs/plan_etapa2_convertor.md new file mode 100644 index 0000000..a57cc91 --- /dev/null +++ b/docs/plan_etapa2_convertor.md @@ -0,0 +1,248 @@ +# Plan etapa 2 - convertorul reutilizabil SAGA -> xlsx initializare ROA + +Stare: **v3, deciziile luate, lansarea lane-urilor neaprobata inca**. Versiunea v2 a trecut prin +review de strategie si de arhitectura (`docs/review_ceo_etapa2.md`, `docs/review_eng_etapa2.md`); ce urmeaza include corectiile. + +Premise: importurile FUNDATIA + MASTER au trecut in ROACONT, scripturile de coduri fiscale au fost +executate (confirmat 21.09.2026). Regulile din `decizii_import.md` sunt validate in productie si +**nu se redeschid**. + +Cercetarea pe care se sprijina planul: +- `docs/raport_sursa_saga_xlsx.md` - SAGA veche (VFP), conventiile tabelei `conturi_roa.dbf`; +- `docs/raport_exporturi_saga_noua.md` - SAGA noua (Firebird), exporturile xlsx si baza `.FDB`. + +## Ce ramane in scop si ce nu + +IN scop: **initializarea soldurilor la o luna**, adica fisierul pe care il inghite +`frm_initializare_facturi_balanta` din ROACONT. + +IN AFARA scopului (asta faceau programele `saga2roa*` vechi, noi nu): importul registrului jurnal, +generarea balantelor de verificare lunare, generarea nomenclatorului de parteneri la fiecare luna. + +## Corectia cea mai importanta fata de v2: cine decide conturile cu parteneri + +v2 spunea ca `CONFIG_CONT_IREG` din Oracle e sursa de adevar. **Este gresit si ar fi produs o +regresie tacuta.** Dovada: + +- `genereaza_xlsx.py:46-50` trateaza ca parteneri `5121`, `5124` (banca, cu analitic) si `5311` + (casa, fara analitic); +- in `docs/config_cont_ireg.md:89` (lista `CU_INREGISTRARI = 1`) **niciunul dintre ele nu apare**; +- invers, Oracle listeaza `404, 408, 409, 4091, 4093, 4094, 418, 419, 471, 472, 456, 457...` + pe care codul validat **nu** le trateaza ca parteneri. + +Daca unealta ar fi decis din Oracle, `5121.01 PIRAEUS BANK` de la MASTER - cazul din +`decizii_import.md` pct. 15, cu sold creditor pe cont de trezorerie - ar fi devenit cont obisnuit, +fara rand `FACTURA`, fara ca nimic sa dea eroare. + +**Regula, de acum:** setul operational este cel validat in productie, tinut intr-un fisier in repo, +`config/conturi_parteneri.csv`, cu o coloana de categorie (`BANCA` / `SINTETIC` / `FARA_ANALITICE`) +si una de motiv. `CONFIG_CONT_IREG` ramane **consultativ**: un script mic il exporta alaturi, iar +unealta **raporteaza divergentele** la fiecare rulare (cont in Oracle si nu la noi, sau invers) - +le raporteaza, nu le aplica. Divergenta constatata azi se scrie in `docs/decizii_import.md`, ca sa +nu fie redescoperita. + +## Arhitectura: un contract intern, trei cititoare + +``` + PDF balanta --\ + xlsx/xls SAGA --+--> [cititor] --> contractul intern --> mapare --> init___.xlsx + CONT_BAZA.FDB --/ +``` + +### Contractul intern - fixat aici, nu lasat la latitudinea cititoarelor + +Trei fisiere, nume si coloane exacte. Potrivirea numelor de coloana la citire este **exacta si +case-insensitive**, niciodata pe substring (`TOTAL_DEB` vs `TOTAL_DEB_1` se confunda usor). + +| fisier | coloane | scris de | +|---|---|---| +| `balanta_.csv` | `pagina, cont, denumire, prec_d, prec_c, rulaj_d, rulaj_c, total_d, total_c, sold_d, sold_c, este_total, tip` | toate cele 3 cititoare | +| `parteneri_.csv` | `cont_analitic, cod, denumire, cod_fiscal` | xlsx (fara `cod_fiscal`), FDB (complet) | +| `facturi_.csv` | `cont_analitic, numar, data, scadent, sold` | xlsx (fara `scadent`), FDB (complet) | + +Coloanele pe care o sursa nu le poate da raman **goale**, niciodata inventate. `tip` (A/P) exista +doar pe drumurile xlsx si FDB; consumatorul ei e stabilirea laturii soldului, in locul deducerii +dupa clasa contului. Ultimele doua fisiere lipsesc cu totul cand sursa e doar balanta - atunci se +cade pe comportamentul de azi (un `FACTURA` per partener, sold total). + +### Cititorul 1 - PDF (exista, nemodificat) +`extract_balanta.py`, pdfplumber pe coordonate. Singura sursa care merge pe orice versiune SAGA, +fiind raportul tiparit. Nu se atinge: e validat pe FUNDATIA si MASTER. + +### Cititorul 2 - foaie de calcul SAGA (`.xls` sau `.xlsx`), nou +`.xlsx` cu openpyxl, `.xls` cu `xlrd` (`openpyxl` nu citeste BIFF). Acelasi cititor pentru SAGA +veche si noua: au aceleasi 35 de coloane, in aceeasi ordine. +Maparea: `DEB_PREC/CRED_PREC -> prec_d/prec_c`, `RULAJ_D/RULAJ_C -> rulaj_d/rulaj_c`, +`TOTAL_DEB/TOTAL_CRED -> total_d/total_c`, `FIN_D/FIN_C -> sold_d/sold_c`, `TIP -> tip`. +`pagina` si `este_total` raman goale (exportul nu are rand de totaluri). +Foaia: prima foaie a registrului - numele difera (`balanta` la VFP, `xl` la `.xls` nou, `Sheet1` la +`.xlsx`), deci nu se cauta dupa nume. +`CONT` se citeste ca **text**: `401.00002` citit ca numar se strica. + +### Cititorul 3 - Firebird, nou +Parametru: calea catre o **copie** de `CONT_BAZA.FDB`. Niciodata baza vie a clientului. +Conexiune embedded (pe TCP 3060 parola implicita nu merge), `access_mode=READ`, `no_gc=True`, +doar SELECT, `rollback` la final. Charset `WIN1250`. + +**Algoritmul balantei, specificat aici pentru ca e inima corectitudinii.** Soldurile stocate in +`CONTURI` sunt 0 (`raport_exporturi_saga_noua.md` C.4); cifrele vin din agregarea `REGISTRU`. +Sunt necesare **trei intervale de data**, nu unul - exportul are patru marimi distincte: + +| marime | interval | +|---|---| +| `DEB_INIT/CRED_INIT` | tot ce e anterior inceputului anului fiscal | +| `prec_d/prec_c` | de la inceputul anului pana la inceputul lunii cerute | +| `rulaj_d/rulaj_c` | in luna ceruta | +| `total_*` | `prec + rulaj` ; `sold_d - sold_c = total_d - total_c` | + +**Rollup la sintetic**: `REGISTRU.CONT_D`/`CONT_C` contin analiticul (`401.00002`), iar exportul +SAGA are sinteticul (`401`) - `raport_exporturi_saga_noua.md` C.4. Agregarea grupeaza pe partea din +stanga punctului si emite si randul analitic, si sinteticul. Randul `%` din `CONTURI` este cont +colector si se exclude. + +Mai produce: `parteneri_.csv` din `FURNIZORI` + `CLIENTI` (**codul fiscal real vine de +aici**, deci pe acest drum etapa 5b - cautarea pe ANAF - dispare) si `facturi_.csv` din +`INTRD`/`INTRARI` si `IESIRI`/`IES_DET`, toate deodata, nu per partener. + +**Garzi pe NULL, nu presupuneri**: `INTRD.SCADENT` a fost NULL pe singurul rand existent, iar +`FURNIZORI.COD_FISCAL` era gol la unul din doi. Deci "scadenta reala" si "cod fiscal real" inseamna +*cand exista*: scadenta lipsa cade pe ultima zi a lunii (ca azi), codul fiscal lipsa cade pe codul +provizoriu `.` si partenerul intra in lista pentru cautarea ANAF. + +## Poarta de verificare a cititoarelor + +**Cititorul 3 (FDB) si cititorul 2 (xlsx) trebuie sa produca acelasi `balanta_.csv`** pentru +firma de joaca `D:\SAGA250909\0001\CONT_BAZA.FDB`, luna 09/2026, al carei export este in `exemple\`. +Daca difera, e bug de cititor, nu date gresite. Acesta inchide lane-ul `citire-fdb`, nu "ruleaza +fara eroare". + +**Limitele acestei porti, scrise si in raport, nu ascunse:** firma de joaca are 10 conturi, **toate +sintetice, niciun analitic**, 2 furnizori, 0 clienti, 1 factura. Deci poarta dovedeste rollup-ul si +periodizarea pe cazul sintetic si **nimic despre analitice** - exact partea grea. Pana la o baza +reala, cititorul FDB este **verificat partial** si se marcheaza ca atare in ajutorul uneltei; nu se +foloseste la un client fara rerularea portii pe datele lui. + +**Inlocuitorul verificarii "Totaluri:"**. Pe drumul PDF, poarta era randul "Totaluri:" din raport. +Exportul xlsx si baza nu au asa ceva. Nu se sterge verificarea, se inlocuieste cu una reala: +`SUM(REGISTRU)` pe fiecare latura, la data ceruta, = netul balantei generate. Pe drumul xlsx, unde +`REGISTRU` nu e disponibil, ramane `SUM(sold_d) = SUM(sold_c)` pe frunze plus relatiile +`total = prec + rulaj` si `sold_d - sold_c = total_d - total_c` pe fiecare cont (au trecut 341/341 +pe DANUBE si 10/10 pe firma de joaca). + +## Pasul de mapare + +Fiecare firma are propriile analitice, deci fiecare firma are propriul fisier. Implicit merge pe +propunerile automate; corectiile sunt posibile oricand, fara sa fie obligatorii. + +**Doua fisiere, cu proprietari diferiti** - asa regenerarea nu-ti poate distruge corectiile: + +| fisier | cine scrie | ce contine | +|---|---|---| +| `mapare_.xlsx` | **doar unealta**, regenerat complet la fiecare rulare | toate conturile din balanta, cu propunerea automata: `cont_saga`, `denumire`, `sold`, `cont`, `acont`, `sursa` (`AUTO` sau `CORECTAT`) | +| `corectii_.xlsx` | **doar tu** | numai randurile pe care le schimbi: `cont_saga`, `cont`, `acont`, `exclus`, `motiv` | + +La rulare: se citeste balanta, se propune automat, se suprapun corectiile, se scrie maparea +completa ca sa vezi rezultatul final. Fisierul de corectii se creeaza gol, cu antet si un exemplu +comentat, doar la prima rulare a firmei - pentru o firma simpla nu-l deschizi niciodata. + +Propunerea automata, cu regula de azi din `decizii_import.md`: `cont` = primele max 4 caractere, +`acont` = cifrele analiticului concatenate, max 4. + +**Conventii preluate din `conturi_roa.dbf`** (`raport_sursa_saga_xlsx.md` 2.3), ca sa nu ai sute de +randuri de corectat - se scriu in `corectii_.xlsx`: +- `.TOATE` - toate analiticele sinteticului merg pe acelasi `cont`/`acont` ROA; +- `.RESTUL` - la fel, dar doar pentru analiticele fara rand propriu. + +Ordinea de cautare: potrivire exacta -> `.RESTUL` -> `.TOATE`. +`PLANCONT` **nu** se preia: era fallback pentru planul de conturi, noi nu generam plan de conturi. + +Maparea acopera si **redenumirea sinteticului** (`409 -> 4091`, `431 -> 4311`), nu doar analiticul - +era jumatate din ce facea `conturi_roa.dbf` si lipsea din v2. + +**Ce NU se configureaza aici**: care conturi merg pe parteneri (vezi sectiunea de mai sus - fisierul +`config/conturi_parteneri.csv`). + +## Cine detine forma lui `acont` (corectie fata de v2) + +v2 spunea ca `genereaza` ia `cont`/`acont` din mapare in loc sa le calculeze. **Prea larg**, si ar +fi dublat o regula deja validata. Doua lucruri nu pot veni din mapare: + +- **randurile de diferenta** nu exista in balanta, sunt calculate (`genereaza_xlsx.py:204-212`, + `:243-249`) - raman in cod; +- **forma lui `acont` pentru conturile cu parteneri** depinde de categorie: `401` cere `acont` gol + pe ambele randuri, `5121` cere `acont` completat identic pe BALANTA si FACTURA + (`decizii_import.md` pct. 16). O regula generica de pre-completare ar pune `acont` pe `401` -> + chei diferite -> **dublare tacuta a sumei**, exact capcana din pct. 16. + +**Regula:** `genereaza_xlsx.py` ramane singurul care decide forma pentru conturile cu parteneri; +maparea doar suprascrie ce ii dai explicit. Restul fisierului - randuri BALANTA / FACTURA, sume +negative pe latura opusa, verificarile din etapa 5 - ramane neatins. + +Opreste-te cu eroare, nu cu ghicit, daca: `cont` sau `acont` depaseste 4 caractere; doua conturi +SAGA diferite produc acelasi `(cont, acont)` **fara** sa fie acoperite de un `.TOATE`/`.RESTUL` +comun (colapsarea intentionata e legala, coliziunea accidentala nu); un rand din `corectii` nu +corespunde niciunui cont din balanta (typo tacut). + +## Testare + +`unittest` din stdlib, fara dependinte noi. Proiectul nu are azi niciun test; fiecare lane lasa in +urma cel putin unul, altfel lane-ul nu e gata: + +| lane | testul pe care il lasa | +|---|---| +| `citire-xlsx` | citeste `exemple\saga-sqlite-balanta-09-2026.xlsx` si `saga2roa_danube\balanta.xls`; relatiile de sume trec pe toate randurile; `CONT` ramane text | +| `mapare` | o corectie supravietuieste regenerarii; `.TOATE`/`.RESTUL` se aplica in ordinea ceruta; un `cont_saga` inexistent in corectii da eroare | +| `citire-fdb` | CSV-ul din FDB identic cu cel din xlsx pe firma de joaca; `SCADENT` NULL cade pe ultima zi a lunii | +| `integrare` | rulare capat-la-capat pe firma de joaca, din ambele surse | +| `regresie` | FUNDATIA + MASTER reproduc etalonul | + +## Poarta de regresie si etalonul + +`tests/golden/` primeste copii **anonimizate** ale celor doua xlsx importate in productie: sumele, +conturile, structura randurilor si numarul lor raman **neatinse**; denumirile de parteneri devin +`PARTENER 001...` si codurile fiscale `CF000001...`, stabil (acelasi nume real -> acelasi nume fals, +ca relatiile dintre randuri sa se pastreze). Asa poarta compara orice celula si in git nu intra +numele niciunui client. Scriptul de anonimizare se comite; **tabela de corespondenta nu**. + +Comparatia se face pe **valori de celula**, nu pe hash de fisier: un xlsx rescris de alta versiune +de openpyxl are alti octeti cu acelasi continut. + +Regresia ruleaza **dupa fiecare lane care atinge generatorul**, nu doar la final - e cel mai ieftin +test care protejeaza zona deja validata in productie. + +## Git + +`.gitignore` ignora `init_*.xlsx`, `export_*.xlsx`, `mapare_*.xlsx`, `balanta_*.csv`. Se adauga: +`*.fdb`, `*.FDB` (copii de baze de client, zeci de MB), `parteneri_*.csv`, `facturi_*.csv`, +`corectii_*.xlsx`. Exceptii explicite: sablonul si `tests/golden/`. +PDF-urile sursa raman in git: sunt datele pe care ruleaza regresia. +`exemple\` ramane in git - firma de joaca, nu date de client. + +Dependintele noi (`xlrd`, `firebird-driver`) se trec in `CLAUDE.md`, la `Mediu`. + +## Ordinea de lucru (lane-uri opencode) + +| lane | livrabil | criteriu de terminare | depinde de | +|---|---|---|---| +| `contract` | `config/conturi_parteneri.csv` + scriptul de divergenta Oracle; anonimizatorul + `tests/golden/` | regresia ruleaza si trece pe etalonul anonimizat, cu codul de azi neschimbat | - | +| `citire-xlsx` | cititorul de foaie de calcul SAGA | vezi tabelul de testare | contract | +| `mapare` | propunerea automata + `corectii_.xlsx` + `.TOATE`/`.RESTUL` + redenumirea sinteticului | vezi tabelul de testare | contract | +| `citire-fdb` | balanta + parteneri + facturi din Firebird | CSV identic cu drumul xlsx pe firma de joaca | citire-xlsx | +| `integrare` | `extrage.py` / `genereaza.py` cu parametri | rulare capat-la-capat din ambele surse | toate | +| `regresie` | rerularea pe FUNDATIA + MASTER | identice cu etalonul, pe valori de celula | integrare | + +Lane-ul `contract` merge primul si singur: fixeaza etalonul **inainte** ca vreo linie de cod sa se +schimbe, altfel regresia masoara fata de un rezultat deja mutat. + +Poarta finala: `regresie`. Daca noul flux nu reproduce randurile celor doua xlsx-uri validate in +productie, nu e gata - indiferent cat de curat e codul. + +## Ce ramane pentru mai tarziu + +- **o baza `.FDB` reala + exportul ei de balanta**, ca sa se reruleze poarta pe date cu analitice si + cu volum. Pana atunci cititorul FDB e verificat partial (vezi mai sus); +- procedura pentru client: cum isi face copia bazei (`gbak` da o copie consistenta si mai mica decat + fisierul brut) si ca trebuie sa opreasca SAGA daca trimite fisierul direct. Se scrie odata cu + lane-ul `citire-fdb`, altfel livram un cititor care nu se poate folosi in teren; +- conectarea la un Firebird prin retea - azi nu merge cu parola implicita + (`raport_exporturi_saga_noua.md` C.1), deci cere credentiale de la client. diff --git a/docs/plan_solduri2roa.md b/docs/plan_solduri2roa.md index 6458a81..0592f7f 100644 --- a/docs/plan_solduri2roa.md +++ b/docs/plan_solduri2roa.md @@ -47,6 +47,18 @@ Iesire: `init_FUNDATIA_2025_12.xlsx`, `init_MASTER_2025_12.xlsx`, generate din s - `cont` <= 4 caractere, `acont` <= 4 caractere, fara dubluri `cont+acont` Raport: `docs\verificare_.md`, cu totalurile din balanta alaturi de totalurile din xlsx. +## Etapa 5b - codurile fiscale reale ale partenerilor +Pasul e obligatoriu, nu optional: partenerii intra in xlsx cu cod fiscal provizoriu +(`.` din SAGA) si trebuie corectati cu CUI-ul real. +1. Lista partenerilor fara CUI: `parteneri_de_cautat.md`. +2. Cautare pe demoanaf.ro (denumire -> CUI), rezultat in `parteneri_cui_gasite.md`. +3. Verificare TVA pe ANAF pentru fiecare CUI gasit (POST + `https://webservicesp.anaf.ro/api/PlatitorTvaRest/v9/tva`, campul `scpTVA`): + platitor de TVA -> cod fiscal cu prefix `RO`; neplatitor -> CUI fara prefix. +4. Scripturile de corectie, per schema: `sql/update_cod_fiscal_.sql` (neexecutate, + se ruleaza manual dupa import). +5. Partenerii negasiti raman cu codul provizoriu si se raporteaza explicit. + ## 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). diff --git a/docs/raport_exporturi_saga_noua.md b/docs/raport_exporturi_saga_noua.md new file mode 100644 index 0000000..bec1269 --- /dev/null +++ b/docs/raport_exporturi_saga_noua.md @@ -0,0 +1,326 @@ +# Raport exporturi SAGA noua (Firebird) - cercetare read-only + +Lane: `exporturi-saga-noua`. Sarcina de cercetare, fara modificari de cod. +Fisiere analizate in `D:\ROA\IMPORT2ROA\solduri2roa\exemple\`: +`saga-sqlite-balanta-09-2026.xlsx`, `saga-sqlite-balanta-09-2026.xls`, +`saga-sqlite-furnizori-09-2026.xlsx`, `saga-sqlite-furnizori-facturi-un-furnizor-09-2026.xlsx`. +Baza explorata: `D:\SAGA250909\0001\CONT_BAZA.FDB` (Firebird, NU SQLite). +Temporarele de lucru: `C:\Users\mmari\AppData\Local\Temp\opencode`. Nu s-a modificat nimic in +`D:\SAGA250909` (doar SELECT, tranzactie read-only). Fisierele nu sunt SQLite; numele contin +"sqlite" dar continutul sunt foi de calcul obisnuite (vezi mai jos). + +--- + +## PARTEA A - structura celor 4 exporturi + +### A.1 `saga-sqlite-balanta-09-2026.xlsx` + +- O singura foaie: `Sheet1`. Dimensiune `A1:AI11` = **11 randuri x 35 coloane** + (1 antet + 10 randuri de date). Fara foi ascunse, fara celule fuzionate. +- Antetul este pe **randul 1**. Datele incep la randul 2 si se termina la randul 11. +- **NU exista rand de totaluri** (ultimul rand este o data: contul `6461`). + +Coloanele, in ordine (litera = nume): + +| Lit | Nume | Lit | Nume | Lit | Nume | +|---|---|---|---|---|---| +| A | CONT | M | RULAJT_D | Y | RULAJ_D_1 | +| B | DENUMIRE | N | RULAJT_C | Z | RULAJ_C_1 | +| C | CATEGORIE | O | TOTAL_DEB | AA | RULAJT_D_1 | +| D | TIP | P | TOTAL_CRED | AB | RULAJT_C_1 | +| E | DEB_INIT | Q | FIN_D | AC | TOTAL_DEB_1 | +| F | CRED_INIT | R | FIN_C | AD | TOTAL_CRED_1 | +| G | DEB_PREC | S | DEB_INIT_1 | AE | FIN_D_1 | +| H | CRED_PREC | T | CRED_INIT_1 | AF | FIN_C_1 | +| I | SOLD_IN_D | U | DEB_PREC_1 | AG | ANALITIC | +| J | SOLD_IN_C | V | CRED_PREC_1 | AH | VALIDAT | +| K | RULAJ_D | W | SOLD_IN_D_1 | AI | LINIE | +| L | RULAJ_C | X | SOLD_IN_C_1 | | | + +Primele 8 randuri de date (rand Excel 2..9; sumele relevante, D/C separate): + +| Rand | A cont | B denumire | D tip | E/F init | G/H prec | K/L rulaj | O/P total | Q/R fin | AG | AH | AI | +|---|---|---|---|---|---|---|---|---|---|---|---| +| 2 | 371 | MARFURI | A | 0 / 0 | 2615 / 0 | 0 / 0 | 2615 / 0 | 2615 / 0 | 0 | 1 | 1 | +| 3 | 401 | FURNIZORI | P | 0 / 0 | 0 / 3164.15 | 0 / 0 | 0 / 3164.15 | 0 / 3164.15 | 0 | 1 | 2 | +| 4 | 421 | PERSONAL - SALARII DATORATE | P | 0 / 2574 | 0 / 2574 | 0 / 0 | 0 / 2574 | 0 / 2574 | 0 | 0 | 3 | +| 5 | 4315 | CONTR. DE ASIGURARI SOCIALE | P | 0 / 938 | 0 / 938 | 0 / 0 | 0 / 938 | 0 / 938 | 0 | 0 | 4 | +| 6 | 4316 | CONTR. DE ASIGURARI SOCIALE DE SANATATE | P | 0 / 375 | 0 / 375 | 0 / 0 | 0 / 375 | 0 / 375 | 0 | 0 | 5 | +| 7 | 436 | CONTR. ASIGURATORIE DE MUNCA | P | 0 / 84 | 0 / 84 | 0 / 0 | 0 / 84 | 0 / 84 | 0 | 0 | 6 | +| 8 | 4426 | TVA DEDUCTIBILA | A | 0 / 0 | 549.15 / 0 | 0 / 0 | 549.15 / 0 | 549.15 / 0 | 0 | 1 | 7 | +| 9 | 444 | IMPOZITUL PE VENITURI DE NATURA SALARIILOR | P | 0 / 163 | 0 / 163 | 0 / 0 | 0 / 163 | 0 / 163 | 0 | 0 | 8 | + +Ultimele 3 randuri (rand Excel 9..11): + +| Rand | A cont | B denumire | D tip | E/F init | G/H prec | O/P total | Q/R fin | AG | AH | AI | +|---|---|---|---|---|---|---|---|---|---|---| +| 9 | 444 | IMPOZIT... SALARIILOR | P | 0 / 163 | 0 / 163 | 0 / 163 | 0 / 163 | 0 | 0 | 8 | +| 10 | 641 | CHELT. CU SALARIILE PERSONALULUI | A | 4050 / 0 | 4050 / 0 | 4050 / 0 | 4050 / 0 | 0 | 0 | 9 | +| 11 | 6461 | CHELT. CU CONTRIB. ASIGURATORIE PT. MUNCA A SALARIATILOR | A | 84 / 0 | 84 / 0 | 84 / 0 | 84 / 0 | 0 | 0 | 10 | + +**Tipuri reale de valori** (openpyxl): +- `CONT` (A) = **text** (str), ex. `Sheet1!A2` = `'371'`. Nu e numar. `DENUMIRE` (B) = text. +- `TIP` (D) = text (`'A'` sau `'P'`); `CATEGORIE` (C) = gol pe toate randurile. +- Sumele (E..R si `_1`) = **numerice** (float la citire, dar stocate ca numar). +- `ANALITIC` (AG) = boolean (`False` pe toate randurile); `VALIDAT` (AH), `LINIE` (AI) = intregi. + +**Cont sintetic vs analitic**: in acest fisier **nu exista niciun cont analitic** - toate cele 10 +coduri sunt fara punct (371, 401, 421, 4315, 4316, 436, 4426, 444, 641, 6461), iar `ANALITIC` +(AG) este 0/False pe toate randurile. Deci din acest fisier singur nu se poate arata cum arata un +rand analitic. Formatul analitic se vede in schimb in exportul de furnizori: +`saga-sqlite-furnizori-09-2026.xlsx!H2` = `401.00002` (text). Rezulta: sintetic = cod fara punct +(`401`), analitic = `sintetic.cod` (`401.00002`). Daca si coloana `ANALITIC` distinge ceva ramane +neclar (aici e 0 pe toate randurile, inclusiv pe cele care in vechiul export VFP aveau 1 - vezi B). + +**Coloane de sume** (maparea ceruta): + +| Rol | Coloane | +|---|---| +| precedent D / C | `DEB_PREC` (G) / `CRED_PREC` (H) | +| rulaj D / C | `RULAJ_D` (K) / `RULAJ_C` (L) | +| total D / C | `TOTAL_DEB` (O) / `TOTAL_CRED` (P) | +| sold D / C | `FIN_D` (Q) / `FIN_C` (R) | + +`TOTAL_*` sunt **sume cumulative** (precedent + rulaj), NU solduri; soldul final este `FIN_*`. +Exista in plus: `DEB_INIT/CRED_INIT` (E/F) = sold la inceputul anului, `SOLD_IN_D/SOLD_IN_C` +(I/J) = sold la inceput de perioada, `RULAJT_D/RULAJT_C` (M/N) = rulaj total cumulat. + +Relatiile cerute, verificate pe toate cele 10 randuri (toleranta 0.005): + +| Verificare | Rezultat | +|---|---| +| `TOTAL_DEB = DEB_PREC + RULAJ_D` | **10/10 OK** | +| `TOTAL_CRED = CRED_PREC + RULAJ_C` | **10/10 OK** | +| `FIN_D - FIN_C = TOTAL_DEB - TOTAL_CRED` | **10/10 OK** | +| (suplimentar) `SOLD_IN_D - SOLD_IN_C = DEB_PREC - CRED_PREC` | 10/10 OK | +| (suplimentar) acelasi set `_1` (S..AF) identic cu setul principal | 10/10 OK | + +Nu exista rand care sa pice. Setul `_1` (S..AF) este **identic** cu setul principal pe toate +randurile - consecvent cu observatia din `raport_sursa_saga_xlsx.md` (pe conturile sintetice `_1` +este copia setului principal). + +### A.2 `saga-sqlite-balanta-09-2026.xls` vs `.xlsx` + +Fisierele au **acelasi continut** (aceleasi 35 coloane in aceeasi ordine si aceleasi 10 randuri de +date, cu aceleasi valori). Semnaturi: `.xls` = OLE2/BIFF8 (`d0cf11e0a1b11ae1...`), `.xlsx` = +OOXML/ZIP (`PK..`). Diferente constatate: + +| Aspect | `.xls` | `.xlsx` | +|---|---|---| +| Nume foaie | `xl` | `Sheet1` | +| Antet | litere mici (`cont`, `denumire`, ...) | litere mari (`CONT`, `DENUMIRE`, ...) | +| `CATEGORIE` goala | sir vid `''` | celula `None` | +| Restul valorilor | identice | identice | + +Comparatia programatica (valori numerice + text case-insensitive) a dat **0 diferente** in afara +celor de mai sus. Deci: acelasi export, doar alt format si alta conventie de nume/case. + +### A.3 `saga-sqlite-furnizori-09-2026.xlsx` + +- O foaie `Sheet1`, `A1:J2` = **2 randuri x 10 coloane** (1 antet + **1 rand de date**). +- Antet pe randul 1; datele pe randul 2. **Nu exista rand de totaluri.** +- Coloane: A `COD`, B `DENUMIRE`, C `NE_INIT`, D `TOTAL`, E `INCASARI`, F `NE_FIN`, + G `NEACHITAT`, H `ANALITIC`, I `SOLD`, J `GRUPA`. + +Randul de date (rand 2): `A2='00002'`, `B2='TRANSPORT'`, `C2=3164.15`, `D2=0`, `E2=0`, +`F2=3164.15`, `G2=3164.15`, `H2='401.00002'`, `I2=3164.15`, `J2` gol. + +Tipuri: `COD` (A) si `ANALITIC` (H) = **text**; `DENUMIRE` (B) = text; sumele C..G, I numerice; +`GRUPA` (J) gol. + +**Ce identifica partenerul**: in acest export partenerul este identificat prin: +- `COD` = codul SAGA al tertului (`00002`), text; +- `ANALITIC` = contul analitic `401.00002` (text) - **da, apare codul contului analitic**; +- `DENUMIRE` = `TRANSPORT`. +Exportul **NU contine codul fiscal** (desi tabelul `FURNIZORI` din baza il are - vezi Partea C). +Deci legatura cu partenerul se face pe `COD` si/sau pe `ANALITIC`, nu pe cod fiscal. + +### A.4 `saga-sqlite-furnizori-facturi-un-furnizor-09-2026.xlsx` + +- O foaie `Sheet1`, `A1:J2` = **2 randuri x 10 coloane** (1 antet + **1 rand de date**). +- Antet pe randul 1; datele pe randul 2. **Nu exista rand de totaluri.** +- Coloane: A `DATA`, B `NR`, C `CONT_FUR`, D `NE_INIT`, E `TOTAL`, F `PLATI`, G `NE_FIN`, + H `NEACHITAT`, I `INF_SUPLM`, J `DATA_DOC`. + +Randul de date (rand 2): `A2=2026-07-02` (datetime), `B2='123'` (text), `C2='401.00002'` (text), +`D2=3164.15`, `E2=0`, `F2=0`, `G2=3164.15`, `H2=3164.15`, `I2` gol, `J2` gol. + +**Campuri de factura prezente**: numar (`NR`), data operare (`DATA`), cont furnizor (`CONT_FUR`), +sold initial neachitat (`NE_INIT`), total factura (`TOTAL`), plati (`PLATI`), neachitat final +(`NE_FIN`), neachitat (`NEACHITAT`), informatii suplimentare (`INF_SUPLM`), data document +(`DATA_DOC`). +**Lipsesc**: **data scadenta** si **valuta** (desi in baza, tabelul de intrari, are `SCADENT` si +`COD_VALUTA` - exportul nu le include). Nu exista nici o coloana de serie. +**Legatura de furnizor**: prin `CONT_FUR = 401.00002` (acelasi analitic ca in A.3) - nu exista +`COD` de tert in acest export. + +--- + +## PARTEA B - comparatie cu ce stim deja + +### B.1 Cu CSV-ul din PDF (`extract_balanta.py`) + +CSV-ul din PDF are coloanele: +`pagina, cont, denumire, prec_d, prec_c, rulaj_d, rulaj_c, total_d, total_c, sold_d, sold_c, este_total`. + +Corespondenta cu exportul nou: + +| CSV (PDF) | Export nou (balanta) | +|---|---| +| `cont` | `CONT` (A) | +| `denumire` | `DENUMIRE` (B) | +| `prec_d` / `prec_c` | `DEB_PREC` (G) / `CRED_PREC` (H) | +| `rulaj_d` / `rulaj_c` | `RULAJ_D` (K) / `RULAJ_C` (L) | +| `total_d` / `total_c` | `TOTAL_DEB` (O) / `TOTAL_CRED` (P) | +| `sold_d` / `sold_c` | `FIN_D` (Q) / `FIN_C` (R) | +| `pagina` | **lipseste** | +| `este_total` | **lipseste** | + +**Se poate produce acelasi CSV din exportul SAGA nou?** Pentru partea de conturi + cele 8 sume: +**da**, maparea e 1:1 si relatiile sunt aceleasi (verificate 10/10 la A.1). Ce **lipseste**: +- `pagina` - proprie PDF-ului, depinde de paginare, nu are echivalent in export; +- `este_total` - exportul **nu are deloc randuri de totaluri**; in CSV-ul din PDF acest marker + distinge randurile "Total sume clasa N" si randul "Totaluri:", care in export nu exista + (ar trebui calculate, nu citite); +- setul de conturi poate diferi: in exemplul nou apar doar conturile cu miscare, la nivel sintetic. + +### B.2 Cu vechiul export SAGA-pe-VFP (`raport_sursa_saga_xlsx.md`, sectiunea 1) + +Structura este **identica** cu cea documentata acolo pentru `balanta.xls` (VFP): aceleasi **35 de +coloane, in aceeasi ordine, cu aceleasi nume** (`cont..fin_c`, `_1`, `analitic`, `validat`, +`linie`). Singurele diferente observate: +- numele foii: `xl`/`Sheet1` (nou) vs `balanta` (VFP); +- case-ul antetului (mic in `.xls`, mare in `.xlsx`) - in raportul VFP antetul era cu litere mici; +- valoarea coloanei `analitic`: in fisierul VFP vechi era **1 pe toate randurile**, in exportul nou + este **0/False pe toate randurile** (dar aici toate randurile sunt sintetice - nu se poate + decide daca diferenta e de semantica sau doar de firma/perioada). + +Concluzie: un convertor care stie deja sa citeasca exportul VFP (`conturi.dbf` / `balanta.xls`) +poate citi **neschimbat** si exportul SAGA nou Firebird - layout-ul de coloane este acelasi. + +Observatie importanta (dovada in Partea C): desi layout-ul e identic cu tabelul `CONTURI`, +valorile din export **nu sunt un dump brut** al tabelului - soldurile stocate in `CONTURI` sunt 0, +iar cifrele din export corespund agregarii registrului de note (`REGISTRU`). Deci exportul e un +raport calculat, nu o citire directa de tabel. + +--- + +## PARTEA C - baza Firebird `CONT_BAZA.FDB` (explorare, NUMAI CITIRE) + +### C.1 Ce client/server exista pe masina + +- Server Firebird **instalat si pornit**: serviciul `FirebirdServerFirebird30_Saga` + (`"C:\Program Files\Firebird\Firebird30_Saga\firebird.exe" -s Firebird30_Saga`, LocalSystem). +- `C:\Program Files\Firebird\Firebird30_Saga\` contine: `isql.exe`, `fbclient.dll`, + `firebird.exe`, `gsec.exe`, `gbak.exe`, `gfix.exe`, `fbsvcmgr.exe`, plus `plugins\engine12.dll` + (Firebird 3.0). In plus SAGA are clientul in `D:\SAGA250909\FbClient\` (`fbclient.dll`, + `plugins\engine12.dll`, `legacy_auth.dll`, etc.). +- Versiunea raportata de baza: **3.0.7** (via `rdb$get_context('SYSTEM','ENGINE_VERSION')`). +- Port de ascultare: doar **3060** (`RemoteServicePort = 3060` in `firebird.conf`; pe 3050 nu + asculta nimic). O conexiune TCP la `localhost/3060` ajunge la baza dar raspunde cu eroare de + autentificare (`Your user name and password are not defined`) - deci parola SYSDBA nu e + `masterkey`/`masterke` la server. + +### C.2 Cum s-a reusit conectarea (read-only) + +- S-a instalat `firebird-driver` (`py -m pip install firebird-driver` -> 2.0.3) si s-a indicat + explicit clientul: `fdb.load_api(r"C:\Program Files\Firebird\Firebird30_Saga\fbclient.dll")`. +- Conexiunea **embedded** la fisier a functionat: + `fdb.connect(database=r"D:\SAGA250909\0001\CONT_BAZA.FDB", user="SYSDBA", password="masterkey", + charset="WIN1250", no_gc=True)` -> **OK, versiune 3.0.7**. Embedded accepta `masterkey`/`masterke` + (autentificare locala/trusted); TCP la 3060 nu. +- Respectarea "NUMAI CITIRE": s-a folosit o **tranzactie read-only** + (`fdb.tpb(Isolation.READ_COMMITTED, access_mode=TraAccessMode.READ)`) si `no_gc=True`; s-au rulat + **doar SELECT**-uri, apoi `rollback`. Nu s-a scris, nu s-a facut ALTER, nu s-a copiat baza. + +### C.3 Ce contine baza + +**191 de tabele**, **0 view-uri**. Cele relevante pentru conversie: + +| Tabel | Randuri | Ce este | +|---|---|---| +| `CONTURI` | 586 | planul de conturi + solduri stocate | +| `FURNIZORI` | 2 | furnizori | +| `CLIENTI` | 0 | clienti | +| `INTRARI` / `INTRD` | 0 / 1 | intrari = facturi furnizori (antet / detaliat) | +| `IESIRI` / `IES_DET` | 0 / - | iesiri = facturi clienti | +| `REGISTRU` | 8 | registru de note contabile (miscarile pe conturi) | +| `FFACT` | 5 | **NU** e tabel de facturi - e tabela de formulare/layout de tiparire | + +Structuri (campurile cheie; tipurile sunt cele din `rdb$relation_fields`/`rdb$fields`): + +**`CONTURI`** (586 randuri) - plan de conturi: +`CONT` VARCHAR(20) NOT NULL, `DENUMIRE` VARCHAR(64), `TIP` CHAR(1), +`DEB_INIT`/`CRED_INIT`/`DEB_PREC`/`CRED_PREC` NUMERIC(15,2), +`CONT_INCH` VARCHAR(20), `DEB_INIT_V`/`CRED_INIT_V`/`DEB_PREC_V`/`CRED_PREC_V` NUMERIC(14,2), +`COD_VALUTA` VARCHAR(3), `BLOCAT` SMALLINT. +Exemplu de rand: `('1012', 'CAPITAL SUBSCRIS VARSAT', 'P', 0.00, 0.00, 0.00, 0.00, ...)`. +Atentie: `CONT` e **text** (se citeste ca sir, deci `401.00002` nu se strica); +in acest exemplu **toate soldurile stocate sunt 0** - vezi C.4. + +**`FURNIZORI`** (2 randuri): +`COD` VARCHAR(8) NOT NULL, `DENUMIRE` VARCHAR(64), `COD_FISCAL` VARCHAR(20), `REG_COM` VARCHAR(16), +`ANALITIC` VARCHAR(20), `GRUPA` VARCHAR(16), plus adresa/IBAN/agent/etc. +Randuri: `('00001','ROMFAST','','401.00001')`, `('00002','TRANSPORT','1879855','401.00002')`. + +**`CLIENTI`** (0 randuri): aceeasi structura de tert ca `FURNIZORI` +(`COD`, `DENUMIRE`, `COD_FISCAL`, `ANALITIC`, `GRUPA`, adresa, agent, limita credit, e-Factura...). + +**`INTRARI`** (0) / **`INTRD`** (1 rand) - facturi furnizori: +`ID_INTRARE`, `NR_NIR`, `NR_INTRARE`, `COD`, `DENUMIRE`, `CONT_FUR`, `DATA`, `SCADENT`, +`NEACHITAT` NUMERIC(15,2), `NEACHITAT_VAL`, `COD_VALUTA`, `CURS`, `VAL_VAL`, `VAL_LEI`, +`BAZA_TVA`, `TOTAL`, `TVA`, `TRANSP_VAL/LEI`, `VALIDAT`, `DATA_DOC`, `INF_SUPLM`, ... +Randul existent: `ID_INTRARE=24, NR_INTRARE='123', COD='00001', CONT_FUR='401.00001', +DATA=2026-07-02, SCADENT=NULL, TOTAL=0, NEACHITAT=0, COD_VALUTA='EUR'`. + +**`IESIRI`** (0) - facturi clienti: +`NR_IESIRE`, `ID_IESIRE`, `COD`, `DENUMIRE`, `CONT_CLI`, `DATA`, `SCADENT`, `TOTAL`, +`NEACHITAT`, `BAZA_TVA`, `TVA`, `COMANDA`, `DATA_DOC`, `INF_SUPLM`, `IS_EF`, ... + +**`REGISTRU`** (8 randuri) - notele contabile (sursa miscarilor): +`ID_NOTA`, `CONT_D` VARCHAR(20), `CONT_C` VARCHAR(20), `SUMA` NUMERIC(15,2), `DATA`, +`EXPLICATIE`, `VALIDAT`, `COD`, `TIP_O`, `PK`. Aici se vede cheia: contul analitic apare in +`CONT_D`/`CONT_C` ca text (`401.00002`), iar `%` este un cont colector. + +Deci: planul de conturi cu solduri = `CONTURI`; furnizorii = `FURNIZORI`; clientii = `CLIENTI`; +facturile furnizorilor = `INTRARI`/`INTRD`; facturile clientilor = `IESIRI`/`IES_DET`. + +### C.4 Dovada ca exporturile sunt rapoarte calculate, nu dump de tabel + +- `CONTURI` are 585 randuri utile (fara randul `%`) si **0 randuri cu sold stocat nenul** + (`deb_prec/cred_prec/deb_init/cred_init` = 0 pentru toti), si totusi exportul de balanta are + cifre. Deci cifrele vin din agregarea `REGISTRU` la data raportului. +- Potriviri exacte: `REGISTRU` are pe `371` debit `2615.00` -> exportul are `371` `DEB_PREC=2615`; + pe `401.00002` credit `2615.00 + 549.15 = 3164.15` -> exportul are `401` `CRED_PREC=3164.15` + si exportul de furnizori `SOLD=3164.15`. In plus, miscarea veche pe `641` este din 2025-11-30 -> + exportul are `DEB_INIT=4050` (sold la inceput de an), ceea ce confirma semantica + `DEB_INIT/CRED_INIT` = inceput de an si `DEB_PREC/CRED_PREC` = inceput de perioada. +- In exportul de balanta contul apare ca `401` (sintetic), iar `401.00002` (analitic) nu apare ca + rand separat -> exportul ruleaza analiticele in sinteticul lor (sau a fost cerut la nivel + sintetic). Regula exacta de includere sintetic/analitic **nu se poate stabili** din acest singur + exemplu. + +### C.5 Ce NU se poate stabili + +- Nu se poate confirma exact din ce tabel/se selecteaza randul de factura din exportul + `saga-sqlite-furnizori-facturi-un-furnizor`: exportul are `CONT_FUR='401.00002'` si `NR='123'`, + dar singurul rand din `INTRD` are `CONT_FUR='401.00001'` (ROMFAST), tot cu `NR_INTRARE='123'`. + Coloanele `DATA/NR/CONT_FUR/TOTAL/NEACHITAT/INF_SUPLM/DATA_DOC` exista in `INTRD`, dar + `NE_INIT`, `PLATI`, `NE_FIN` **nu exista ca si coloane** in baza - sunt calculate (sold initial, + plati, sold final). Potrivirea exacta a randului nu se poate face cu datele disponibile. +- Semnificatia coloanei `ANALITIC` din balanta (0/False la toate randurile) nu se poate stabili. + +--- + +## Stare si verificari + +- Nu s-a modificat niciun fisier din proiect sau din `D:\SAGA250909`; nu s-a facut write-back; + nu s-a comis nimic (git/svn). Baza Firebird a fost accesata doar cu SELECT, in tranzactie + read-only, `no_gc=True`, fara copiere. +- Verificari rulate: relatiile de sume pe balanta (10/10 OK pentru toate cele trei relatii cerute); + comparatia `.xls` vs `.xlsx` (0 diferente reale); listarea tabelelor (191 tabele, 0 view-uri) si + a structurilor cheie; potrivirea soldurilor export vs `REGISTRU`. +- Temporare: `C:\Users\mmari\AppData\Local\Temp\opencode\` (`analiza.py`, `verif.py`, `fbtest*.py`, + `fblist.py`, `fbcols.py`, `fbdata.py`, `fbsearch.py` + dump-uri txt). Nu sunt in proiect. +- Fara stare periculoasa: niciun `.vc2` editat fara write-back, niciun proces lasat pornit, fara + date de test consumate. diff --git a/docs/raport_sursa_saga_xlsx.md b/docs/raport_sursa_saga_xlsx.md new file mode 100644 index 0000000..6ec3e33 --- /dev/null +++ b/docs/raport_sursa_saga_xlsx.md @@ -0,0 +1,351 @@ +# Raport sursa-saga: balanta.xls SAGA, tabela conturi_roa si exporturile folosite + +Cercetare read-only. Nu s-a modificat niciun fisier din `saga2roa`, `saga2roa_danube`, +`saga2roa_rompetrol`. Fisierele temporare sunt in +`C:\Users\mmari\AppData\Local\Temp\opencode\sursa_saga`. + +## 0. Cum am citit .xls-ul (ce a mers) + +Ordinea ceruta, cu rezultatul exact: + +1. `pandas` + `xlrd`: **pandas NU e instalat** (`ModuleNotFoundError: No module named 'pandas'`), + `xlrd` la fel. Am instalat doar `xlrd` (`py -m pip install xlrd` -> 2.0.2). Cu `xlrd.open_workbook` + fisierul se citeste corect. +2. `openpyxl` pe `.xls` **esueaza** (confirmat): + `openpyxl.utils.exceptions.InvalidFileException: openpyxl does not support the old .xls file format`. +3. LibreOffice exista (`C:\Program Files\LibreOffice\program\soffice.exe`) si conversia a mers: + `soffice --headless --convert-to xlsx --outdir balanta.xls` -> exit 0. Fidelitate verificata: + xlsx-ul convertit are tot 342 randuri x 35 coloane, sheet `balanta`, acelasi antet. +4. Excel COM din PowerShell: **nu a fost nevoie** (xlrd si LibreOffice au acoperit). + +Concluzie: se poate citi fie direct cu `xlrd`, fie prin conversie LibreOffice. + +## 1. Structura balantei SAGA exportate in Excel (`saga2roa_danube\balanta.xls`) + +- O singura foaie: `balanta`. 342 randuri x 35 coloane. +- **Randul 1 (index 0) = antetul**, direct pe prima linie; nu exista randuri de titlu deasupra. + Datele incep la randul 2 (index 1). Ultimul rand de date = randul 342 (index 341). +- **NU exista rand de totaluri.** Toate cele 341 de randuri de date au `cont` si `denumire` + completate; ultimul rand este contul `7651`. Randul "Totaluri:" exista doar in raportul PDF + "Balanta de verificare", nu in acest xls. + +### 1.1 Coloanele, in ordine (litera + nume) + +| Lit. | Nume | Lit. | Nume | Lit. | Nume | +|---|---|---|---|---|---| +| A | cont | M | rulajt_d | Y | rulaj_d_1 | +| B | denumire | N | rulajt_c | Z | rulaj_c_1 | +| C | categorie | O | total_deb | AA | rulajt_d_1 | +| D | tip | P | total_cred | AB | rulajt_c_1 | +| E | deb_init | Q | fin_d | AC | total_deb_1 | +| F | cred_init | R | fin_c | AD | total_cred_1 | +| G | deb_prec | S | deb_init_1 | AE | fin_d_1 | +| H | cred_prec | T | cred_init_1 | AF | fin_c_1 | +| I | sold_in_d | U | deb_prec_1 | AG | analitic | +| J | sold_in_c | V | cred_prec_1 | AH | validat | +| K | rulaj_d | W | sold_in_d_1 | AI | linie | +| L | rulaj_c | X | sold_in_c_1 | | | + +Aceasta lista coincide **exact** cu structura `conturi.dbf` documentata in cod la +`saga2roa_danube\saga2roa_danube.prg:25` (comentariul cu capul tabelei SAGA). Deci +`balanta.xls` este **exportul in Excel al tabelei SAGA `conturi` (plan de conturi cu solduri)**, +NU raportul "Balanta de verificare". Confirmare suplimentara: `saga2roa_danube.prg:30` citeste +direct `conturi.dbf` din directorul SAGA (`K:\MARIUS\SAGA C.3.0\0001\`). + +### 1.2 Primele 10 randuri de date (Excel rand 2..11) + +| cont | denumire | tip | deb_init | cred_init | deb_prec | cred_prec | rulaj_d | rulaj_c | total_deb | total_cred | fin_d | fin_c | +|---|---|---|---|---|---|---|---|---|---|---|---|---| +| 1012 | CAPITAL SUBSCRIS VARSAT | P | 0 | 2000.00 | 0 | 2000.00 | 0 | 0 | 0 | 2000.00 | 0 | 2000.00 | +| 105 | REZERVE DIN REEVALUARE | P | 0 | 3009833.83 | 0 | 3009833.83 | 0 | 0 | 0 | 3009833.83 | 0 | 3009833.83 | +| 105.10 | REZERVE DIN REEVALUARE CELULA INSILOZARE | P | 0 | 167629.29 | 0 | 167629.29 | 0 | 0 | 0 | 167629.29 | 0 | 167629.29 | +| 105.102 | REZERVA DIN REEVAL.TRANSPORTOR TORNADO ORIZONTAL | P | 0 | 4669.56 | 0 | 4669.56 | 0 | 0 | 0 | 4669.56 | 0 | 4669.56 | +| 105.103 | REZERVA DIN REEVAL.TRANSPOROTR TORNADO ORIZONTAL | P | 0 | 2263.31 | 0 | 2263.31 | 0 | 0 | 0 | 2263.31 | 0 | 2263.31 | +| 105.104 | REZERVA DIN REEVAL.TRANSPORTOR TORNADO ORIZONTAL | P | 0 | 4669.56 | 0 | 4669.56 | 0 | 0 | 0 | 4669.56 | 0 | 4669.56 | +| 105.105 | REZERVA DIN REEVAL TRANSPORTOR ELEVATOR TEE100 | P | 0 | 3788.75 | 0 | 3788.75 | 0 | 0 | 0 | 3788.75 | 0 | 3788.75 | +| 105.106 | REZERVA DIN REEVAL TRNASPORTOR ELEVATOR TEE100 | P | 0 | 3940.44 | 0 | 3940.44 | 0 | 0 | 0 | 3940.44 | 0 | 3940.44 | +| 105.11 | REZERVA DIN REEV.CELULA INSILOZARE | P | 0 | 167628.38 | 0 | 167628.38 | 0 | 0 | 0 | 167628.38 | 0 | 167628.38 | +| 105.17 | REZERVA DIN REEVAL.RETEA ELECTRICA | P | 0 | 12143.52 | 0 | 12143.52 | 0 | 0 | 0 | 12143.52 | 0 | 12143.52 | + +### 1.3 Ultimele 5 randuri (Excel rand 338..342) + +| cont | denumire | tip | deb_init | cred_init | deb_prec | cred_prec | rulaj_d | rulaj_c | total_deb | total_cred | fin_d | fin_c | +|---|---|---|---|---|---|---|---|---|---|---|---|---| +| 6811 | CHELT. DE EXPLOATARE CU AMORTIZAREA IMOBILIZARILOR | A | 0 | 0 | 119978.76 | 119978.76 | 39992.94 | 39992.94 | 159971.70 | 159971.70 | 0 | 0 | +| 698 | CHELT. CU IMPOZITUL PE VENIT SI CU ALTE IMPOZITE | A | 0 | 0 | 1722.00 | 1722.00 | 0 | 0 | 1722.00 | 1722.00 | 0 | 0 | +| 704 | VEN. DIN SERVICII PRESTATE | P | 0 | 0 | 172156.50 | 172156.50 | 25185.81 | 25185.81 | 197342.31 | 197342.31 | 0 | 0 | +| 7584 | VEN. DIN SUBVENTII PT. INVESTITII | P | 0 | 0 | 6956.34 | 6956.34 | 2318.78 | 2318.78 | 9275.12 | 9275.12 | 0 | 0 | +| 7651 | VEN. DIN DIFERENTE FAVORABILE DE CURS VALUTAR | P | 0 | 0 | 14081.25 | 14081.25 | 7523.61 | 7523.61 | 21604.86 | 21604.86 | 0 | 0 | + +Nu exista rand de totaluri dupa acestea; randul 342 este ultimul. + +### 1.4 Sintetic vs analitic + +- **Nu exista indentare si nu exista o coloana separata** care sa spuna sintetic/analitic. + Coloana `analitic` (AG) este **1 pe toate cele 341 de randuri**, deci nu distinge nimic. +- Singurul criteriu real este **punctul in codul de cont**: + - 78 randuri fara punct (`0` puncte) = **conturi sintetice** (ex. `1012`, `105`, `1171`, `401`); + - 263 randuri cu exact 1 punct = **conturi analitice** (ex. `105.10`, `105.102`, `1171.100`, + `208.500`, `2813.114`, `401.00032`); + - nu exista coduri cu 2 sau mai multe puncte in acest fisier. +- Partea de analitic are lungime variabila 1..5 caractere si poate fi si alfanumerica: + in fisier apar si `105.RAI`, `4428.TP` (litere), pe langa `00001..00134` (5 cifre). +- Atentie: un cont sintetic fara punct poate fi si frunza (ex. `1012` nu are analitice), deci + "are punct" = analitic, dar "nu are punct" NU inseamna automat parinte. +- Codul de analitic arata exact ca in exemplu (`401.00027`), adica `sintetic.`. + +### 1.5 Coloanele de sume: ce sunt totaluri si ce sunt solduri + +Relatii verificate pe **toate cele 341 de randuri** (toleranta 0.005): + +| Verificare | Rezultat | +|---|---| +| `total_deb = deb_prec + rulaj_d` si `total_cred = cred_prec + rulaj_c` | 341/341 OK | +| `fin_d - fin_c = total_deb - total_cred` | 341/341 OK | +| `sold_in_d - sold_in_c = deb_prec - cred_prec` | 341/341 OK | + +Interpretare (sprijinita si de cod, `saga2roa\balanta.sql:11`: +`deb_init+deb_prec as debit, cred_init+cred_prec as credit`): +- `deb_prec` / `cred_prec` = **sume precedente** (rulaj cumulat pana la inceputul perioadei) — + corespund coloanelor "Sume precedente" din raportul PDF; +- `rulaj_d` / `rulaj_c` = **rulaj perioada**; +- `total_deb` / `total_cred` = **sume totale** = precedente + rulaj (NU sold); +- `fin_d` / `fin_c` = **sold final**; +- `deb_init` / `cred_init` = solduri de preluare (initial), separat de precedent; +- `sold_in_d` / `sold_in_c` = sold la inceput, pe netul precedentelor; +- `rulajt_d` / `rulajt_c` = rulaj total cumulat; in acest fisier **nu este egal cu `total_deb/cred`** + decat pe 95/341 randuri (deci nu e o simpla copie a lui `total_deb`). + +Setul `_1` (coloanele S..AF): pe 265/341 randuri este **complet zero**, iar pe 78/341 randuri este +**identic cu setul principal**. Cele 78 sunt exact randurile sintetice (fara punct), cele 265 sunt +analiticele + 2 randuri sintetice complet zero. Nu am putut stabili din fisierele disponibile ce +reprezinta setul `_1` (pare o a doua balanta / a doua perioada); **nu il folosesc ca fapt dovedit**. + +### 1.6 Comparatie cu CSV-ul produs de `extract_balanta.py` din PDF + +CSV-ul din PDF (`balanta_FUNDATIA.csv`) are coloanele: +`pagina, cont, denumire, prec_d, prec_c, rulaj_d, rulaj_c, total_d, total_c, sold_d, sold_c, este_total`. + +Corespondenta de semantica (raportul PDF "Balanta de verificare" = 8 coloane numerice, vezi +si `saga2roa\Balanta de verificare 16052018 1317.xls` rand 7-9: Sume precedente / Rulaje perioada / +Sume totale / Solduri finale): + +| CSV (PDF) | xls | +|---|---| +| prec_d / prec_c | deb_prec / cred_prec | +| rulaj_d / rulaj_c | rulaj_d / rulaj_c | +| total_d / total_c | total_deb / total_cred | +| sold_d / sold_c | fin_d / fin_c | + +Coloane in CSV care **lipsesc** din xls: `pagina` (numarul paginii PDF), `este_total` +(markerul randului de totaluri). +Coloane in xls care **nu exista** in CSV: `categorie`, `tip`, `deb_init`, `cred_init`, +`sold_in_d`, `sold_in_c`, `rulajt_d`, `rulajt_c`, cele 16 coloane `_1`, `analitic`, `validat`, `linie`. + +**Se poate produce EXACT acelasi CSV din xls?** Nu exact, dar foarte aproape: +- Coloanele de cont si de sume se pot mapa 1:1 si valorile sunt coerente (aceleasi relatii + `total = prec + rulaj`, `sold = total` pe net); +- `pagina` nu se poate reface din xls (e proprie PDF-ului, depinde de paginare si de + ruperile de denumire); +- `este_total`: xls-ul **nu are rand de totaluri**; s-ar putea doar calcula/adapta, nu citi; +- denumirea poate diferi: in PDF denumirea e recompusa din fragmente pe pagini + (`extract_balanta.py:124-126` lipeste randurile de continuare), in xls e o singura celula; +- setul de conturi poate diferi daca PDF-ul si xls-ul sunt din perioade/firme diferite + (in cazul de fata xls este DANUBE, CSV-urile existente sunt FUNDATIA/MASTERJOB). +Deci: **da pentru conturi + cele 8 sume, nu pentru `pagina` si `este_total`.** + +## 2. Tabela de corespondenta conturi SAGA -> conturi ROA + +### 2.1 Cele doua fisiere, structura DBF + +**`saga2roa\CONTURI_ROA.DBF`** (varianta DANUBE, 56 inregistrari, 4 campuri): + +| Camp | Tip | Lungime | +|---|---|---| +| CONT | C | 20 | +| ACONT | C | 20 | +| CONT2 | C | 4 | +| ACONT2 | C | 4 | + +Primele 15 randuri (CONT | ACONT | CONT2 | ACONT2): + +``` +2131 | TOATE | 2131 | (gol) +2133 | TOATE | 2133 | (gol) +214 | TOATE | 214 | (gol) +2813 | TOATE | 2813 | (gol) +2814 | TOATE | 2814 | (gol) +3024 | ATM | 3024 | 1 +3024 | ATUO | 3024 | 2 +3024 | (gol) | 3024 | 3 +303 | TOATE | 303 | (gol) +371 | TOATE | 371 | 5 +371 | MARFA | 371 | 6 +371 | MCKM4-5 | 371 | 7 +378 | MCKM4-5 | 378 | 7 +378 | MFEN | 378 | 1 +378 | (gol) | 378 | 1 +``` + +Observatii: `ACONT2` poate fi gol, o cifra, sau alfanumeric (`X`, `PG`, `PO`, `TXV`, `ANAF`, +`C4-5`). `CONT2` poate diferi de `CONT` (ex. `409 -> 4091`, `431 -> 4311`, `4314 -> 4313`, +`4374 -> 4371`, `4381 -> 4371`). Exista un export identic ca structura in +`saga2roa\conturi.csv` (antet `cont;acont;cont2;acont2`, 56 randuri) si `saga2roa\conturi.xls` +(foaie `Sheet1`, 57 randuri cu antet) — dar acestea doua NU sunt identice bit-cu-bit cu +`CONTURI_ROA.DBF`: in csv/xls codul analitic e lipit in `cont` (`707.ATM`) si `acont` e gol, +iar unele valori difera (`MCKM4-5` vs `MCK4-5`). Sunt variante, nu acelasi fisier. + +**`saga2roa_rompetrol\conturi_roa.dbf`** (varianta ROMPETROL, 135 inregistrari, 6 campuri): + +| Camp | Tip | Lungime | +|---|---|---| +| CONT2 | C | 4 | +| ACONT2 | C | 4 | +| DENUMIRE | C | 100 | +| CONT_ALT | C | 20 | +| COD | C | 20 | +| CONT | C | 20 | + +Primele 15 randuri (CONT2 | ACONT2 | DENUMIRE | CONT_ALT | COD | CONT): + +``` +121 | 3001 | PROFIT SI PIERDERE | (gol) | B1203010_NG_011 | 121 +167 | 5501 | GARANTIE DE BUNA EXECUTIE _NG | (gol) | B1203080_NG_081 | 167.01 +201 | 1101 | CHELTUIELI DE CONSTITUIRE_SOLD INITIAL | (gol) | B1301010_NG_011 | 201 +303 | 2201 | MAT. DE NATURA OB. DE INVENTAR | (gol) | B1301010_NG_022 | 303.TOATE +401 | 6301 | FURNIZORI NG | (gol) | B1301010_NG_032 | 401.RESTUL +401 | 6302 | FURNIZORI G | (gol) | B1307010_NG_011 | 401.00032 +401 | 6302 | FURNIZORI G | (gol) | B1307010_KMGR_022 | 401.00005 +401 | 6302 | FURNIZORI G | (gol) | B1307010_RSC_022 | 401.00018 +401 | 6302 | FURNIZORI G | (gol) | B1307080_NG_081 | 401.00002 +401 | 6302 | FURNIZORI G | (gol) | B1307080_NG_085 | 401.00001 +404 | 6301 | FURNIZORI DE IMOBILIZARI NG | (gol) | B1311010_NG_011 | 404.RESTUL +404 | 6302 | FURNIZORI DE IMOBILIZARI G | (gol) | B1311010_NG_022 | 404.0002 +404 | 6302 | FURNIZORI DE IMOBILIZARI G | (gol) | B1311010_RIV_022 | 404.00005 +404 | 6302 | FURNIZORI DE IMOBILIZARI G | (gol) | B1311010_NG_032 | 404.00012 +408 | 6305 | FURNIZORI - FACTURI NESOSITE IMOBILIZARI NG | (gol) | B1311090_NG_011 | PLANCONT +``` + +Aici `CONT` este codul SAGA complet (inclusiv analitic: `401.00032`, `611.1`) sau un marcaj +special (`303.TOATE`, `401.RESTUL`, `PLANCONT`); `CONT2`/`ACONT2` sunt contul sintetic/analitic +ROA; `CONT_ALT` = cont alternativ ROA; `COD` = codul suplimentar ROMPETROL (structura +`B.../I..._NG_...`). + +### 2.2 Unde se foloseste tabela in cele doua .prg + +Toate locurile (grep `conturi_roa` in `*.prg`): + +**`saga2roa_danube\saga2roa_danube.prg`** +- `:30-34` defineste caile; `:40-44` daca `conturi_roa.dbf` lipseste o creeaza **goala** + (`CREATE TABLE (cont C(20), acont C(20), cont2 C(4), acont2 C(4))`); +- `:79` `Select Cast(Alltrim(Cont) + '.' + Alltrim(acont) As C(20)) As Cont, cont2, acont2 From conturi_roa` + -> cheia de cautare este `cont + '.' + acont`; +- `:173-203` ("Corectare conturi analitice") este locul de fond: + ``` + lcContSintetic = Left(m.lcCont, m.lnPos - 1) + lcContAnalitic = Substr(m.lcCont, m.lnPos + 1) + lcContToate = m.lcContSintetic + '.TOATE' + ... + Locate For Alltrim(Cont) = m.lcCont + If !Found() + Locate For Alltrim(Cont) = m.lcContToate + ... + Replace cont2 With m.lcCont2, acont2 With m.lcAcont2 + ``` + +**`saga2roa_rompetrol\saga2roa_rompetrol3.prg`** +- `:59-73` caile + crearea goala (6 campuri); +- `:120-124` citeste tabela si comenteaza rolul coloanelor + (`cont = cont saga`, `cont2/acont2 = conturi ROA`, `cont_alt = cont alternativ ROA`, + `cod = cod suplimentar ROMPETROL`); +- `:126-169` construieste planul ROA (`cPlanROA`): face `Full Join` intre `conturi_roa` si + planul SAGA pe `cont`, plus un `Join` special pentru randurile cu `cont = 'PLANCONT'` + (`:134-138`), si sterge din plan conturile acoperite de un `X.TOATE` (`:152-157`); +- `:244-306` foloseste tabela la corectarea **registrului jurnal**, atat pe debit cat si pe + credit (`:262-273` si `:292-303`), cu `X.TOATE` **si** `X.RESTUL` (`:265`, `:295`); +- `:572-575` foloseste `cPlanROA` (deci indirect tabela) pentru planul de conturi analitic. + +In `saga2roa\balanta.prg` (versiune mai veche, firma COFFEE) tabela se foloseste identic ca in +danube (`:34`, `:40-44`, `:79`, `:188`); in `saga2roa\balanta.BAK:28` apare chiar o cale fixa +`E:\vali\COFFEE\conturi_roa.dbf`. + +### 2.3 Ce decide exact tabela + +Tabela **doar re-codeaza contul**: pentru un cod SAGA dat (`cont`, optional cu analitic) stabileste +`cont2` (sinteticul ROA, max 4 car.) si `acont2` (analiticul ROA, max 4 car.). Deci: +- **redenumirea sinteticului** (ex. SAGA `409` -> ROA `4091`, `431` -> `4311`); +- **analiticul** (`acont2`), care poate fi gol (cont fara analitic in ROA), o cifra, sau + alfanumeric; +- suporta **marcaje speciale** in coloana `cont`: `X.TOATE` (toate analiticele sinteticului X), + `X.RESTUL` (restul, doar in rompetrol), `PLANCONT` (fallback de plan pe `cont2`); +- in rompetrol mai decide **denumirea ROA** (`denumire`), **contul alternativ** (`cont_alt`) si + **codul suplimentar** (`cod`). + +Ce **NU** decide tabela: +- **nu decide `tip` (D/P)**: tipul vine din planul SAGA (`cPlan`, danube `:81`) si e transportat + prin join-uri (`:154`, rompetrol `:572`); tabela nu are coloana de tip. +- **nu decide conturile cu parteneri**: listele sunt **hardcodate in .prg** + (`lcListaConturiBalP` / `lcListaConturiIregP`, danube `:308-309`, rompetrol `:114-115`). + Partenerii vin din `clienti.dbf`/`furnizori.dbf`, nu din tabela. +- nu decide sume, doar maparea de coduri. + +### 2.4 Completata manual sau generata automat? + +Dovada: **niciunul dintre .prg nu scrie in tabela**. Singurele operatii pe `conturi_roa` sunt +`Use`, `Select`, `Locate` si `CREATE TABLE` (doar daca fisierul lipseste) — vezi +danube `:36-44`, `:79`, `:188-199` si rompetrol `:65-73`, `:120`, `:132-138`, `:262-303`. +Nu exista `INSERT`/`REPLACE`/`APPEND` catre `conturi_roa` in niciun .prg. + +Concluzie: tabela este **completata manual** (un nomenclator de corespondenta intretinut de om), +posibil pornita dintr-un export (in rompetrol coloana `COD` are coduri structurate de tip +`B1203010_NG_011`, care par generate din planul ROMPETROL) si apoi corectata/curatata manual +(valori de mana: `acont2` = `X`, `PG`, `PO`, `TXV`, `ANAF`; randuri `PLANCONT`, `TOATE`, `RESTUL`). + +## 3. Alte exporturi SAGA folosite in .prg (in afara de balanta) + +Ambele .prg citesc din directorul SAGA urmatoarele tabele (danube `:30-34`, rompetrol `:59-63`): + +| Fisier SAGA | Rol | Campuri folosite (din cod) | Exemplu in directoare | +|---|---|---|---| +| `conturi.dbf` | plan de conturi + solduri | `Cont, tip, denumire, deb_init, deb_prec, cred_init, cred_prec` (danube `:81`, `:103`; balanta.sql:11) | `saga2roa\conturi.dbf` (864 inreg.) | +| `registru.dbf` | registru jurnal / note contabile | danube: `cont_d, cont_c, explicatie, cod, suma, Data` (`:94-99`); rompetrol: + `id_nota, id_cont_d, id_cont_c, Curs, suma_val, cod_valuta, ndp, fel_d` (`:232`) | `saga2roa\REGISTRU.DBF` (2619 inreg.) | +| `clienti.dbf` | nomenclator clienti (parteneri) | `cod, denumire, cod_fiscal, reg_com, analitic, judet, adresa, tara, is_tva` (+ `banca, cont_banca, tel, email` in rompetrol) | `saga2roa\clienti.dbf` (11 inreg.) | +| `furnizori.dbf` | nomenclator furnizori (parteneri) | aceleasi campuri | `saga2roa\furnizori.dbf` (76 inreg.) | + +Structurile reale ale fisierelor-exemplu (format SAGA mai vechi): +- `conturi.dbf` (15 campuri): `CONT C(20), DENUMIRE C(60), TIP C(1), DEB_INIT N(15,2), + CRED_INIT N(15,2), DEB_PREC N(15,2), CRED_PREC N(15,2), CONT_INCH C(20), DEB_INIT_V N(14,2), + CRED_INIT_ N(14,2), DEB_PREC_V N(14,2), CRED_PREC_ N(14,2), COD_VALUTA C(3), BLOCAT N(1)`. + Atentie: aceasta difera de structura documentata in cod (`saga2roa_danube.prg:25`, 35 campuri), + care este formatul SAGA C.3.0 folosit de danube — si care coincide cu `balanta.xls`. +- `REGISTRU.DBF` (23 campuri): `ID_NOTA N(10), VALIDAT C(1), CONT_D C(20), CONT_C C(20), + SUMA N(15,2), COD_VALUTA C(3), CURS N(15,4), SUMA_VAL N(14,2), TVA N(15,2), EXPLICATIE C(70), + DATA D(8), ID_CONT_D C(20), ID_CONT_C C(20), CATEGORIE C(16), NDP C(16), FEL_D C(20), TIP C(1), + COD C(8), PLAN C(1), SECTOR C(1), SURSA C(1), CAPITOL C(1), ARTICOL C(1)`. +- `clienti.dbf` / `furnizori.dbf`: incep cu `COD C(8), DENUMIRE C(64), COD_FISCAL C(20), + REG_COM C(16), ANALITIC C(20)` (clienti are 31 campuri, furnizori 27). + +**Nu exista** exporturi separate de tip "solduri furnizori" sau "solduri clienti" sau +"facturi" folosite de aceste .prg. Soldurile per partener se calculeaza in .prg din +`registru.dbf` + nomenclatoarele `clienti/furnizori` (danube `:85-92`, `:311-343`), nu se citesc +dintr-un fisier dedicat. In directoare exista si fisiere `saga2roa\facturi_jurnal_tva_COFFEE*.xlsx` +(coloane `an, luna, cont, tip, numar, data, nume, cod_fiscal, sold, soldtvaneex, baza24, tva24, ...`), +dar **niciun .prg nu le refera** (grep pe `facturi_jurnal`, `balanta.xls`, `Balanta de verificare` +in toate .prg-urile: zero rezultate). Sunt exporturi folosite de alt flux, nu de `saga2roa*`. + +## 4. Raport de lucru + +1. **Facut**: cercetare read-only; citit `balanta.xls` (xlrd + conversie LibreOffice), structurile + DBF `saga2roa\CONTURI_ROA.DBF` si `saga2roa_rompetrol\conturi_roa.dbf`, toate locurile + `conturi_roa` din cele trei .prg, plus structurile `conturi/registru/clienti/furnizori.dbf`. + Scris acest fisier. +2. **Verificari**: `openpyxl` pe `.xls` -> `InvalidFileException` (confirmat); `xlrd 2.0.2` OK; + `soffice --headless --convert-to xlsx` -> exit 0, fidelitate 342x35. Relatii de sume pe + 341/341 randuri (tabel 1.5). Niciun fisier din `saga2roa*` modificat (doar citire); grep + `conturi_roa` = 19 potriviri, toate citite; grep exporturi nefolosite = 0. +3. **Nefacut / deschis**: semnificatia setului `_1` din `balanta.xls` (265 randuri zero, + 78 identice cu setul principal) nu e dovedibila din fisierele disponibile; perioada la care + se refera `balanta.xls` (nu exista in fisier un camp de an/luna); `este_total` nu are + echivalent in xls (nu exista rand de totaluri). +4. **Stare periculoasa**: niciuna. Fisierele de proiect nu au fost atinse; temporarele sunt in + `Temp\opencode\sursa_saga`; nu s-a facut write-back, nu au ramas procese, nu s-au consumat date. diff --git a/docs/review_ceo_etapa2.md b/docs/review_ceo_etapa2.md new file mode 100644 index 0000000..59669f0 --- /dev/null +++ b/docs/review_ceo_etapa2.md @@ -0,0 +1,424 @@ +# Review CEO - planul etapei 2 (`plan_etapa2_convertor.md`, PROPUNERE v2) + +Review de strategie, aplicat ca analiza (fara intrebari interactive). Nu s-a modificat planul. +Nu s-a scris cod. Scorurile si modurile de mai jos sunt o adaptare a skill-ului `plan-ceo-review` +la un plan intern, cu un singur utilizator (Marius). + +Documente citite integral: `plan_etapa2_convertor.md`, `plan_solduri2roa.md`, `decizii_import.md`, +`raport_sursa_saga_xlsx.md`, `raport_exporturi_saga_noua.md`, `raport_form_init_balanta.md`, +`config_cont_ireg.md`, `conturi_cu_analitice.md`, `verificare_FUNDATIA.md`, `CLAUDE.md`, +`extract_balanta.py`, `genereaza_xlsx.py`, `.gitignore`. + +## 0. Modul de review propus (Step 0F adaptat) + +Skill-ul cere alegerea unui mod. Nu pot intreba, deci il propun si il justific: +**SELECTIVE EXPANSION cu felie de HOLD** - planul e pe directia corecta, dar are 2-3 bucati care +nu-si justifica existenta acum (cititorul FDB fara date reale, complexitatea merge-ului de mapare) +si 1-2 bucati lipsa (contractul intermediar, sursa setului de parteneri). Nu e "go big": produsul +e intern, utilizatorul e unul singur, migrarile sunt rare. Nu e nici "reduction": cateva lucruri +din plan sunt chiar indispensabile (contractul de CSV, maparea per firma, regresia). +Motivul principal de a nu face HOLD pur: planul nu a evaluat nicio alternativa de arhitectura +(vezi C10), deci "scopul e acceptat" nu se poate sustine inca. + +--- + +## 1. Scoruri pe dimensiunile skill-ului + +| # | Dimensiune (skill) | Nota | Ce ar duce-o la 10 | +|---|---|---|---| +| 1 | Premisa corecta (0A) | 6/10 | Raspuns explicit la "cat de des migram?" si "PDF e suficient cat timp clientul nu da baza?". Planul presupune ca FDB e drumul viitor fara sa spuna cat de des ajunge acolo. | +| 2 | Refolosire cod existent (0B) | 8/10 | Nume per sub-problema la ce cod exista deja: reader PDF neatins; tot restul vine din `genereaza_xlsx.py`. Lipseste doar explicitarea setului de parteneri hardcodat (C1). | +| 3 | Alternative de implementare (0C-bis) | 3/10 | Planul are o singura arhitectura ("un format intern, trei cititoare"). Lipsesc varianta minima (un script `--sursa`) si varianta "FDB ca sursa primara". | +| 4 | Aliniere cu starea ideal 12 luni (0C) | 7/10 | O comanda `migreaza.py --firma --an --luna --sursa` cu mapare persistenta. Planul merge exact spre ea, dar nu scrie cum arata finalul (interfata, contract). | +| 5 | Arhitectura (S1) | 7/10 | Contractul intermediar este definit complet, negru pe alb (C4). Acum "acelasi CSV + optional doua fisiere" e o intentie, nu o specificatie. | +| 6 | Harta erorilor / rescue (S2) | 4/10 | 3 conditii de stop sunt numite (bun), dar lipsesc clasele de eroare pentru cititoare (fisier lipsa, antet schimbat, FDB blocat) si ce vede utilizatorul (C16). | +| 7 | Securitate / date de client (S3) | 6/10 | `.gitignore` extins pentru `.FDB`, `parteneri_*.csv`, `facturi_*.csv` (C8). Risc mic dar real: datele de partener sunt PII/financiar. | +| 8 | Data flow / edge cases (S4) | 6/10 | Regula de periodizare REGISTRU -> prec/rulaj/fin scrisa si testata pe o luna cu miscari inainte (C3); tratarea `scadent` NULL (C15). | +| 9 | Calitatea codului (S5) | 7/10 | Decizia despre complexitatea merge-ului de mapare (C6); altfel e curat si reutilizeaza ce exista. | +| 10 | Teste / porti de verificare (S6) | 6/10 | Poarta FDB-vs-xlsx declarata ca ceea ce este (nu inchide lane-ul pe date de joaca, C2) + testul de regresie rulat la fiecare lane, nu doar la final (C5). | +| 11 | Performanta (S7) | 8/10 | Nimic de facut; FDB e o copie citita o data, agregare unica. De notat doar ca firma de joaca nu spune nimic despre timp pe o baza reala. | +| 12 | Observabilitate (S8) | 6/10 | Raportul `verificare_.md` extins cu numar de parteneri/facturi, sursa folosita si invariantul care inlocuieste "Totaluri" pe sursele xlsx/fdb (C9). | +| 13 | Deploy / rulare la client (S9) | 5/10 | Procedura de copiere a bazei (gbak) mutata in Etapa 2 odata cu cititorul FDB, sau cititorul FDB declarat explicit "intern, nefolosibil la client" (C7/C12). | +| 14 | Traiectorie pe termen lung (S10) | 7/10 | E ok. Reversibilitate 5/5 (scripturi interne, git). Singura datorie: `conturi_cu_analitice.md` contrazice `decizii_import.md` pct.15 pe 5125 (C14). | +| 15 | Design / UX intern (S11) | 5/10 | `mapare_.xlsx` este interfata omului: header congelat, dropdown la `stare`, evidentiere `NOU`/`DISPARUT`. Planul nu spune nimic despre aspectul lui. | + +Scor mediu (nesponderat): ~6,1/10. Planul este peste media unui plan intern, dar isi asuma prea +mult pe incredere (FDB) si prea putin pe specificatie (contract, sursa parteneri). + +--- + +## 2. Constatari (fiecare: ce e in plan -> ce e in neregula -> ce propun) + +### C1. Conturile cu parteneri: planul spune "sursa de adevar = Oracle", dar codul le are hardcodate, iar cele doua liste nu coincid + +**In plan** (sectiunea "Pasul de mapare"): *"Ce NU se configureaza aici: care conturi merg pe +parteneri. Ramana `CONFIG_CONT_IREG` din Oracle ... e sursa de adevar a ROACONT ... Programele +vechi aveau lista hardcodata in `.prg`, exact ce nu repetam."* + +**In neregula:** planul nu spune NICIODATA cum ajunge configuratia Oracle in unealta. Iar codul de +azi o are hardcodata: `genereaza_xlsx.py:43-53` (`PARTENER_SINTETIC = {401,4092,4111,461,462,4551}`, +`PARTENER_BANCA = {5121,5124}`, `PARTENER_FARA_ANALITICE = {5311}`). Lista din Oracle +(`config_cont_ireg.md:89-91`) are **33 de conturi cu `CU_INREGISTRARI=1`** (403, 404, 408, 409, +4091, 4093, 4094, 4118, 413, 418, 419, 426, 4511, 456, 457, 471, 472, 4754, 542, 8051, 1621, 167, +232, 234, 261, 2678, 2691 ...). Daca unealta citeste fidel Oracle, comportamentul se schimba fata +de ce s-a validat in productie (unde doar lista mica a fost folosita). Nu e o eroare, dar este o +divergenta nerezolvata intre doua surse pe care planul le trateaza ca sinonime. + +**Propun:** alege o singura sursa si scrie-o in plan: +(a) snapshot local versionat `config/cont_ireg.csv` (coloanele `cont`, `fel_cont`, `cu_inregistrari`), +generat de un SQL documentat, citit de unealta - fara dependinta Oracle la rulare; +(b) pastrezi setul hardcodat (dar atunci scoti din plan afirmatia "Oracle e sursa de adevar"); +(c) citire live Oracle - de evitat (contra "fara alte dependinte"). +Recomand (a): o sursa, zero credentiale la rulare, si se vede in git cand se schimba. + +### C2. Cititorul FDB e cel mai valoros si cel mai putin verificat; poarta lui de terminare e aproape vida + +**In plan** (sectiunea "Poarta de verificare"): *"cititorul 3 (FDB) si cititorul 2 (xlsx) trebuie +sa produca acelasi CSV ... Acesta este criteriul care inchide lane-ul `citire-fdb`, nu 'ruleaza fara +eroare'."* + +**In neregula:** planul recunoaste singur (aceeasi sectiune) ca firma de joaca *"are doar conturi +sintetice, niciun analitic... 2 furnizori, 0 clienti, 1 factura"*. Deci poarta care "inchide" +lane-ul nu atinge exact partile riscante: analitice, parteneri, facturi per partener, cod fiscal, +scadenta. Pe 10 randuri sintetice, orice cititor plauzibil trece. Poarta e utila ca fumegatoare, +nu ca definitie de "gata". In plus, dovada din `raport_exporturi_saga_noua.md` C.3/C.5 arata ca +singurul rand din `INTRD` are `SCADENT=NULL` si `NEACHITAT=0` - deci nici "scadenta reala" nu e +demonstrata. + +**Propun:** muta obtinerea unei baze `.FDB` reale + exportul ei din Etapa 3 in Etapa 2, ca +**preconditie** pentru lane-ul `citire-fdb` (nu pentru tot planul). Cat timp nu exista, scrie in +plan ca `citire-fdb` se poate livra doar ca "pregatit, neverificat pe analitice". Nu numi poarta +"criteriu care inchide lane-ul". + +### C3. Semantica de periodizare REGISTRU -> prec/rulaj/fin nu este definita (inima corectitudinii FDB) + +**In plan** (sectiunea "Cititorul 3 - Firebird"): *"balanta: agregare pe `REGISTRU` la data ceruta. +... nu se citeste `CONTURI.DEB_PREC`, se agrega `REGISTRU`."* + +**In neregula:** planul nu defineste ce inseamna "la data ceruta" si cum se separa +`DEB_PREC` (inceput de perioada), `RULAJ_D` (perioada) si `FIN_D` (final). Exportul SAGA are +4 notiuni distincte (`raport_exporturi_saga_noua.md` A.1, C.4): `DEB_INIT` = inceput de an, +`DEB_PREC` = inceput de perioada, `RULAJ` = perioada, `FIN` = final. CSV-ul tinta cere +`prec_d/prec_c, rulaj_d/rulaj_c, total_d/total_c, sold_d/sold_c`. Daca intervalele nu sunt +definite exact, CSV-urile FDB si xlsx **nu vor fi identice pe date reale** - vor coincide doar pe +firma de joaca, unde toate miscarile sunt inainte de perioada (8 note in `REGISTRU`). + +**Propun:** scrie in plan formulele exacte, de obicei: +`prec = SUM(suma) unde DATA < prima_zi_a_lunii_cerute`, `rulaj = SUM unde luna_ceruta`, +`total = prec + rulaj`, `sold = total pe net`; si pentru `DEB_INIT` separat, pentru `sold_in`. +Adu ca test o luna cu miscari in 3 locuri: anul precedent, inainte de luna, in luna. + +### C4. Contractul intermediar (CSV + parteneri + facturi) nu este specificat + +**In plan** (sectiunea "Arhitectura"): *"Toate cele trei cititoare produc acelasi CSV ... plus - +optional - doua fisiere de parteneri."* Si la "Randurile FACTURA": parametrii +`--furnizori `, `--clienti `, `--facturi `, `--fdb `. + +**In neregula:** nu exista nume de fisiere, coloane si relatia dintre "fisierele de parteneri" ale +pasului de citire si flagurile generatorului. In plus, cititorul 2 propune `TIP` ca "a 13-a +coloana, optionala", in timp ce reader 1 (`extract_balanta.py`) ramane "nemodificat" si scrie +12 coloane (`pagina, cont, denumire, prec_d, prec_c, rulaj_d, rulaj_c, total_d, total_c, sold_d, +sold_c, este_total`). Rezulta doua contracte care trebuie tolerate simultan, fara sa fie scris. + +**Propun:** fixeaza in plan: +- `balanta_.csv` - exact 12 coloane, neschimbat; `TIP` nu se adauga (nu e nevoie in + generator; `genereaza_xlsx.py` nu citeste `tip`); +- `parteneri_.csv` - `cont_saga, denumire, cod_fiscal, analitic`; +- `facturi_.csv` - `cont_partener, numar, data, scadent, neachitat`; +- preconditii de potrivire nume de coloana: **exact, case-insensitive** (nu substring - + `TOTAL_DEB` este prefix al `TOTAL_DEB_1`, iar un match partial ar lua coloana gresita). + +### C5. Regresia pe FUNDATIA + MASTER trebuie rulata dupa fiecare lane care atinge generatorul, nu doar la final + +**In plan** (tabelul "Ordinea de lucru"): lane `regresie` depinde de `integrare`; *"Poarta finala: +lane-ul `regresie`. Daca noul flux nu reproduce randurile celor doua xlsx-uri validate in productie, +nu e gata."* + +**In neregula:** planul schimba doua lucruri in zona validata in productie: (1) `cont`/`acont` vin +din mapare in loc sa fie calculate, (2) setul de conturi cu parteneri (C1). Ambele pot muta cifre. +Daca regresia ruleaza doar la final, un bug introdus in lane-ul `mapare` se descopera dupa toate +celelalte lane-uri. + +**Propun:** poarta de regresie FUNDATIA + MASTER se ruleaza dupa `mapare` si dupa `integrare` +(de doua ori), nu o singura data la final. Este cel mai ieftin test de siguranta din tot planul: +doua PDF-uri in git, doua xlsx de referinta pe disc. + +### C6. Merge-ul de mapare (`MANUAL`/`NOU`/`DISPARUT` + `.TOATE`/`.RESTUL`) este cea mai mare bucata de cod pentru un utilizator unic + +**In plan** (sectiunea "Pasul de mapare"): *"Merge la rulare noua, nu suprascriere: randurile +`MANUAL` raman intacte; analiticele disparute din balanta se pastreaza, marcate `DISPARUT` ...; +analiticele noi se adauga cu `NOU`."* + +**In neregula:** nu e gresit, dar este cea mai complexa componenta a planului (stare persistenta, +reconciliere pe 3 tranzitii, marcaje) si se justifica doar daca Marius editeaza manual maparea +des. Planul nu spune cat de des se intampla asta. Alternativa: maparea se regenereaza complet la +fiecare rulare, iar corectiile omului traiesc intr-un fisier mic separat +(`mapare__manual.csv`, doar randurile atinse), peste care se aplica. + +**Propun:** decid: (a) merge complet ca in plan (accepti complexitatea, adaugi testele celor 3 +tranzitii - deja in criteriu), sau (b) overlay manual separat (mai simplu de testat, dar doua +fisiere). Nu am o preferinta puternica; depinde de cat de des editeaza Marius maparea. + +### C7. Dependinte noi nedeclarate in `CLAUDE.md` + +**In plan** (antet): *"Python 3.13, fara dependinte in afara de openpyxl/pdfplumber/xlrd/firebird-driver."* +`CLAUDE.md:6-7`: *"Instalate: pdfplumber, openpyxl. Fara alte dependinte."* + +**In neregula:** planul introduce `xlrd` si `firebird-driver` (si `fbclient.dll` dintr-o cale fixa +de masina: `C:\Program Files\Firebird\Firebird30_Saga\fbclient.dll`, `raport_exporturi_saga_noua.md` +C.2). `CLAUDE.md` nu le mentioneaza, iar calea `fbclient` nu e portabila intre masini/clienti. + +**Propun:** adauga in `CLAUDE.md` (si intr-un scurt `README`/`--help`) lista de dependinte + pasul +de instalare + faptul ca `fbclient.dll` se descopera la rulare (nu cale fixa). Verificat: pe +masina asta toate cele 4 module se importa. + +### C8. `.gitignore` nu acopera copii `.FDB` si fisierele de parteneri/facturi (date de client) + +**In plan** (sectiunea "Git"): enumera ignorarea pentru `init_*.xlsx`, `export_*.xlsx`, +`mapare_*.xlsx`, `balanta_*.csv`. `.gitignore` real confirma exact acestea. + +**In neregula:** noile artefacte din plan - copii `.FDB`, `parteneri_*.csv`, `facturi_*.csv`, +fisiere `.xls` - nu sunt acoperite. O copie `.FDB` de client contine CUI, denumiri, IBAN, solduri. + +**Propun:** adauga in `.gitignore`: `*.FDB`, `*.fdb`, `parteneri_*.csv`, `facturi_*.csv`, +`config/cont_ireg.csv` (daca se decide snapshot-ul, vezi C1 - sau, dimpotriva, comite-l intentionat +daca nu contine date de client). Nu e o urgenta, dar e o scapare concreta. + +### C9. Raportul de verificare este orientat pe PDF; pentru xlsx/fdb, verificarea cu "Totaluri" dispare tacit + +**In plan** (sectiunea "Cititorul 2"): *"`este_total` = gol (exportul nu are rand de totaluri)"*. + +**In neregula:** `genereaza_xlsx.citeste_totaluri` cauta un rand cu "totaluri" in denumire si +intoarce `None` pe sursele xlsx/fdb (`genereaza_xlsx.py:89-94`). Verificarea "NET xlsx vs NET +Totaluri" (una din garzile din `CLAUDE.md`) nu se mai poate rula, fara ca planul sa spuna ce o +inlocuieste. Ramane doar `SUM(totdeb)=SUM(totcred)`, care e necesara dar nu suficienta. + +**Propun:** pentru sursele xlsx/fdb, invariantul de inlocuire se scrie in plan si in raport: +pe fiecare rand din CSV `total_d = prec_d + rulaj_d`, `total_c = prec_c + rulaj_c`, +`sold_d - sold_c = total_d - total_c` (exact verificarile deja rulate in cercetare, 10/10 pe +exportul nou; vezi `raport_exporturi_saga_noua.md` A.1). + +### C10. Planul nu evalueaza nicio alternativa si nu spune cat de des se migreaza (premisa) + +**In plan:** o singura arhitectura ("Arhitectura: un format intern, trei cititoare"), 5 lane-uri. + +**In neregula:** pentru un utilizator unic si 2 migrari facute pana acum, "5 lane-uri + 3 cititoare ++ mapare persistanta + parteneri/facturi din FDB" poate fi supradimensionat. Exista o varianta mult +mai mica: un singur script care citeste PDF sau xlsx (`--sursa`), fara FDB, fara mapare +persistanta, cu partenerii si cod fiscal provizoriu ca azi (etapa 5b ANAF exista deja si a +functionat). FDB-ul aduce valoare reala (cod fiscal real, scadenta, facturi per partener, dispare +etapa 5b) - dar numai dupa ce exista o baza reala de validat (C2). + +**Propun:** raspunde la doua intrebari in plan: cat de des se face o migrare si cat de des vine +clientul cu baza `.FDB`. Daca migrarile sunt rare sau FDB-ul e rar, varianta minima acopera cazul +real mai repede si mai sigur. + +### C11. Ordinea lane-urilor poate fi paralelizata, iar `citire-fdb` depinde de prea putin + +**In plan** (tabelul "Ordinea de lucru"): `citire-xlsx` fara dependinte, `mapare` fara dependinte, +`citire-fdb` depinde de `citire-xlsx`, `integrare` depinde de toate. + +**In neregula:** `citire-xlsx` si `mapare` nu depind una de alta si pot rula in paralel (planul le +pune amandoua "fara dependinte", deci e ok, dar nu o spune). `citire-fdb` depinde de `citire-xlsx` +pentru ca exportul e oracolul - corect ca tehnica, dar slab ca dovada pe date de joaca (C2). + +**Propun:** numeste explicit `citire-xlsx` + `mapare` ca lane-uri paralele si muta `citire-fdb` +dupa ce exista date reale sau dupa decizia D2. + +### C12. Etapa 3 contine procedura de client, fara de care cititorul FDB nu se poate folosi la client + +**In plan** (sectiunea "Etapa 3"): *"procedura pentru client: cum isi face copia bazei (`gbak` ... +) si ca trebuie sa opreasca SAGA daca trimite fisierul direct"*. + +**In neregula:** daca `citire-fdb` se livreaza in Etapa 2, dar procedura de obtinere a bazei ramane +in Etapa 3, unealta nu poate fi folosita la un client. Planul nu spune daca Etapa 2 FDB e "intern, +pe baza proprie" sau "folosibil la client". + +**Propun:** fie muti procedura `gbak`/opreste-SAGA in Etapa 2 odata cu cititorul, fie declari +explicit ca Etapa 2 FDB este doar pe baza proprie si procedura ramane in Etapa 3. + +### C13. Testul de regresie: "identice" trebuie definit pe date, nu pe octeti + +**In plan** (tabelul): *"xlsx-urile noi **identice** cu cele importate deja in productie"*. + +**In neregula:** `genereaza_xlsx.scrie_xlsx` re-salveaza sablonul cu `openpyxl`; metadate/formatari +pot diferi, deci "identic bit-cu-bit" e fragil ca test. Ce conteaza sunt valorile celulelor. + +**Propun:** defineste poarta ca "identic pe toate celulele de date (rand >= 2), pe toate coloanele", +nu pe hash de fisier. Compara cu `openpyxl.load_workbook` valorile celula cu celula. + +### C14. `conturi_cu_analitice.md` contrazice decizia finala pentru 5125 + +**In plan:** planul nu mentioneaza 5125. +**In neregula:** `conturi_cu_analitice.md:29,105` propune `5125 = PARTENER`; `decizii_import.md` +pct.15 (revizuit 20.09.2026) decide `5125 = doar analitice, fara parteneri`. Codul respecta pct.15 +(5125 nu e in `PARTENER`, `genereaza_xlsx.py:53`). Un om care citeste docul de conturi rămâne cu +informatia veche. Planul nu spune care doc castiga. + +**Propun:** o linie in plan ("pct.15 din `decizii_import.md` prevaleaza; `conturi_cu_analitice.md` +se actualizeaza") plus corectarea tabelului la urmatoarea atingere a acelui fisier. + +### C15. `scadent` din FDB poate fi NULL; planul il trateaza ca "scadenta reala" + +**In plan** (tabelul "Randurile FACTURA"): randul "baza `.FDB`" -> *"cu cod fiscal real si scadenta +reala"*. +**In neregula:** dovedit in `raport_exporturi_saga_noua.md` C.3, singurul rand din `INTRD` are +`SCADENT=NULL`; iar `NEACHITAT=0`. Deci "scadenta reala" si "facturi cu sold" nu sunt garantate de +baza. +**Propun:** in plan, regula pentru `SCADENT` NULL (fallback pe ultima zi a lunii, ca la exporturi) +si pentru selectia facturilor (ex. `NEACHITAT <> 0`), plus raportarea cazurilor. + +### C16. Harta erorilor nu numeste ce vede utilizatorul la esec de citire + +**In plan** (sectiunea "Ce se pastreaza neatins"): 3 conditii de oprire ("analitic fara rand in +mapare", "cont/acont > 4", "doua randuri cu acelasi (cont,acont)"). Bun, dar sunt doar in generator. +**In neregula:** nu exista erori numite pentru cititoare: fisier lipsa, foaie inexistenta/redenumita, +antet fara coloana asteptata, `cont` citit ca numar, FDB blocat/versiune greșita/`fbclient` +negasit. `raport_form_init_balanta.md` arata ca formularul insusi e lax (rand fara `an` = ignorat +tacut), deci un CSV gresit poate produce un xlsx "valid" dar incomplet. +**Propun:** tabel de erori in plan (codepath | ce poate merge prost | clasa/exceptie | ce vede +Marius). Minim: fiecare cititor valideaza antetul prin nume exacte si se opreste cu mesaj care +spune fisierul, foaia si coloana lipsa. + +--- + +## 3. DECIZII DE LUAT DE MARIUS + +### D1. Cat de mare e etapa 2: planul complet (5 lane-uri, 3 cititoare) sau o felie minima intai? +- A) **Felia minima intai**: un script cu `--sursa pdf|xlsx`, fara FDB si fara mapare persistanta + (cod fiscal provizoriu + etapa 5b ca azi); FDB cand apare un client cu baza. (uman: ~1 zi / CC: ~1h) +- B) **Planul complet ca acum** (5 lane-uri, inclusiv FDB + parteneri/facturi). +- C) **Planul complet, dar FDB ultimul si conditionat** de o baza reala (hibrid cu D2). +- **Recomandare: C** - pastrezi valoarea FDB, dar nu blochezi livrarea pe cea mai putin verificata + bucata. Rezultatul il simti imediat pe PDF/xlsx, iar FDB se adauga cand ai dovada. (Daca + migrarile sunt rare si clientii nu dau baza, A devine alegerea corecta.) + +### D2. Cititorul FDB: il construim acum sau dupa o baza reala? +- A) Mutam obtinerea unei baze `.FDB` reale + exportul ei in Etapa 2, ca preconditie. (recomandat) +- B) Il construim acum pe firma de joaca si acceptam ca "verificat, nu pe analitice". +- C) Il scoatem din etapa 2 complet (revine in etapa 3). +- **Recomandare: A** - poarta FDB-vs-xlsx pe 10 randuri sintetice nu poate inchide un lane care + promite analitice, parteneri, cod fiscal si scadenta reala. + +### D3. Sursa setului de conturi cu parteneri (C1) +- A) Snapshot local `config/cont_ireg.csv` generat de SQL, citit de unealta. (recomandat) +- B) Pastram setul hardcodat din `genereaza_xlsx.py` si scoatem afirmatia "Oracle e sursa de adevar". +- C) Citire live Oracle la rulare. +- **Recomandare: A** - o singura sursa, fara credentiale si fara client Oracle la rulare, si se + vede in git cand se schimba. Important: decide daca snapshot-ul include toate cele 33 de conturi + `CU_INREGISTRARI=1` sau doar setul validat - altfel rezultatul pe FUNDATIA/MASTER se poate schimba. + +### D4. Contractul intermediar (C4) +- A) Il fixezi in plan acum: 3 fisiere, nume si coloane exacte, fara `TIP`, match exact de antet. + (recomandat) +- B) Lasi cititoarele sa produca ce vor si adaptezi generatorul. +- **Recomandare: A** - e cel mai ieftin lucru de scris din tot planul si elimina cea mai frecventa + sursa de buguri tacite (potrivire de coloane). + +### D5. Merge-ul de mapare (C6) +- A) Merge complet (`MANUAL`/`NOU`/`DISPARUT` + `.TOATE`/`.RESTUL`) ca in plan. +- B) Overlay manual separat peste o mapare regenerata complet. (mai simplu de testat) +- **Recomandare: B** daca Marius editeaza maparea rar; A daca o editeaza des. Neutral - decizia + tine de cat de des corecteaza manual. + +### D6. Poarta de regresie (C5, C13) +- A) Rulezi regresia FUNDATIA + MASTER dupa `mapare` si dupa `integrare`, comparand valori de + celule (nu hash de fisier). (recomandat) +- B) Ramane o singura rulare la final, pe hash de fisier. +- **Recomandare: A** - cel mai ieftin test de siguranta, si protejeaza exact zona validata in + productie pe care planul o atinge. + +### D7. Procedura de client pentru baza FDB (C12) +- A) O muti in Etapa 2 odata cu cititorul FDB. (recomandat daca D2 = A/B) +- B) Ramane in Etapa 3; declari Etapa 2 FDB "intern, nefolosibil la client". +- **Recomandare: A** - altfel livrezi un cititor pe care nu-l poti folosi in teren. + +### D8. Cine e "adevarul" pe 5125 si pe docurile contradictorii (C14) +- A) `decizii_import.md` pct.15 prevaleaza; actualizezi `conturi_cu_analitice.md`. (recomandat) +- B) Lasat asa, se rezolva la urmatoarea atingere. +- **Recomandare: A** - o linie in plan si o corectie mica elimina o capcana pentru viitor. + +--- + +## 4. Ce am verificat si ce NU am putut verifica + +**Verificat (cu dovada):** +- Structura celor doua exporturi SAGA (VFP si Firebird) identica pe 35 de coloane si maparea + 1:1 pe cele 8 sume - `raport_sursa_saga_xlsx.md` 1.5/1.6 si `raport_exporturi_saga_noua.md` + A.1/B.2 (relatii de sume 341/341 si 10/10). +- `CONTURI` cu solduri 0, cifrele din agregarea `REGISTRU` - `raport_exporturi_saga_noua.md` C.4. +- Firma de joaca: FDB exista (`D:\SAGA250909\0001\CONT_BAZA.FDB`, 21 MB), exporturi in `exemple\`, + 0 analitice, 2 furnizori, 0 clienti, 1 factura - planul si raportul C.3 confirma. +- Setul hardcodat de parteneri din cod vs lista Oracle `CU_INREGISTRARI=1` (33 conturi) - C1: + `genereaza_xlsx.py:43-53` vs `config_cont_ireg.md:89-91`. +- `5125`: codul respecta `decizii_import.md` pct.15, docul `conturi_cu_analitice.md` nu - C14. +- `.gitignore` real nu acopera `.FDB`/`parteneri_*.csv`/`facturi_*.csv` - C8. +- Dependintele pe masina asta: `pdfplumber`, `openpyxl`, `xlrd`, `firebird.driver` se importa toate. +- `genereaza_xlsx.py` citeste `totaluri` din CSV, deci pe sursele xlsx/fdb verificarea scade - C9. +- `extract_balanta.py` scrie 12 coloane, deci `TIP` ca a 13-a coloana ar rupe contractul - C4. + +**NU am putut verifica (afirmatii neacoperite de un fisier citit):** +- Cat de des se face o migrare si cat de des vine clientul cu baza `.FDB` (premisa pentru D1). + Nu exista niciun document cu volumul de migrari. +- Daca `REGISTRU` permite reconstruirea exacta a `DEB_PREC`/`RULAJ`/`FIN` pe analitice pe o baza + reala - nu exista decat firma de joaca (8 note). C3 ramane o cerinta, nu o dovada. +- Daca vreun client are baza `.FDB` pe o versiune Firebird diferita (aici 3.0.7, `fbclient` dintr-o + cale fixa) - nerezolvat, risc de deploy nenumit in plan. +- Ordinea exacta de prioritate dintre `conturi_cu_analitice.md` (PARTENER pe 5125) si + `decizii_import.md` pct.15 (analitic) din partea lui Marius - am presupus ca pct.15, mai nou si + revizuit, este cel corect. +- Outside voice (Codex / subagent) NU a fost rulat: skill-ul il cere implicit, dar acest task este + o analiza fara aprobare interactiva, iar rezultatul ar fi informational. De reluat manual daca + Marius vrea a doua voce. + +**Anexa A - diagrama de arhitectura (cum e acum in plan; `[?]` = nespecificat)** + +``` + SURSE CITITOARE CONTRACT GENERATOR IESIRE + PDF balanta ------> citire-pdf (exista) -> balanta_.csv (12 col) --> genereaza -------> init___.xlsx + xlsx/xls SAGA -----> citire-xlsx (NOU) -> balanta_.csv + CONT_BAZA.FDB -----> citire-fdb (NOU) -> parteneri_.csv [nume/coloane ?] + mapare_.xlsx + facturi_.csv [nume/coloane ?] + docs/verificare_.md +``` + +**Anexa B - registru de erori propus (S2)** + +| Codepath | Ce poate merge prost | Tratament propus (acum lipseste) | +|---|---|---| +| citire-pdf | PDF fara text (scanat) | Stop, mesaj "PDF fara strat de text" | +| citire-xlsx | fisier lipsa / foaie redenumita / antet schimbat | Stop cu numele foii si coloanei asteptate | +| citire-xlsx | `cont` citit ca numar (`401.00002`) | citire ca text, verificat deja in cercetare | +| citire-fdb | `fbclient.dll` negasit / versiune Firebird diferita | Stop cu calea cautata si versiunea | +| citire-fdb | `CONTURI` cu solduri 0 (folosire gresita) | agregare `REGISTRU`, cu invariant de sume; de numit explicit | +| generator | analitic fara rand in mapare | deja in plan: Stop | +| generator | `(cont,acont)` duplicat | deja in plan: Stop | +| generator | rand fara `an` (formular il ignora tacit) | validare proprie, nu te baza pe formular | + +**Anexa C - registru de failure modes (S4)** + +| Codepath | Failure mode | Prins? | Test? | Marius vede? | Logat? | +|---|---|---|---|---|---| +| citire-fdb | CSV "corect" dar fara analitice (agregare sintetic) | N (C2) | N (date de joaca) | **Silent** | raport | +| citire-fdb | `SCADENT` NULL tratat ca data valida | N (C15) | N | partial | nu | +| citire-xlsx | antet cu coloana lipsa -> 0 pe toate | N (C16) | partial | posibil Silent | nu | +| generator | `Totaluri` absent -> verificare sarita | partial (C9) | da | notat in raport | da | +| deploy | `fbclient` lipsa la client | N (C7) | N | Stop (daca mesaj clar) | nu | + +Rândurile `RESCUED=N, TEST=N, USER SEES=Silent` sunt golurile critice: primul si al treilea. + +**Anexa D - "ce exista deja"** + +- `extract_balanta.py` = cititorul PDF (reused, nemodificat; corect). +- `genereaza_xlsx.py` = toti pasii de mapare si constructie a randurilor BALANTA/FACTURA, cu + verificarile din etapa 5 (reused; planul il extinde corect cu maparea si `exclus`). +- `decizii_import.md` pct.11-16 = regulile validate in productie (nu se redeschid; corect). +- Sablonul `init_facturi_balanta_note.xlsx` (rand 1 = cap de tabel, import incepe de la rand 2). + +**Anexa E - "NOT in scope" (confirmat de plan, cu o exceptie)** + +- importul registrului jurnal, balantele de verificare lunare, nomenclatorul de parteneri lunar + (programele `saga2roa*` vechi) - corect in afara scopului; +- planul de conturi syntetic generat de SAGA (`PLANCONT`) - corect nepreluat; +- conectarea Firebird prin retea - corect amanata. +- **Exceptie de re-verificat:** "procedura de client pentru copia bazei" este scoasa in Etapa 3, + dar daca FDB se livreaza in Etapa 2 (D2/D7), ea este in scop. diff --git a/docs/review_eng_etapa2.md b/docs/review_eng_etapa2.md new file mode 100644 index 0000000..c403ccb --- /dev/null +++ b/docs/review_eng_etapa2.md @@ -0,0 +1,395 @@ +# Review eng - plan etapa 2 (`docs/plan_etapa2_convertor.md`, PROPUNERE v2) + +Lane: `review-eng`. Analiza statica, read-only. Nu am modificat planul, nu am scris cod, nu am dat commit. +Am aplicat skill-ul `plan-eng-review` (SKILL.md + `sections/review-sections.md`) ca analiza: unde skill-ul +cere AskUserQuestion, am scris DECIZII DE LUAT (sectiunea 3). Sursa de adevar pentru fiecare afirmatie +de mai jos este un fisier citit; unde am presupus, scrie explicit "presupunere". + +Fisiere citite: planul; `raport_sursa_saga_xlsx.md`; `raport_exporturi_saga_noua.md`; `decizii_import.md`; +`plan_solduri2roa.md`; `config_cont_ireg.md`; `raport_form_init_balanta.md`; `conturi_cu_analitice.md`; +`extract_balanta.py`; `genereaza_xlsx.py`; `.gitignore`; CLAUDE.md; git status/log. + +--- + +## 0. Step 0 - Scope challenge (rezultat) + +- **Ce exista deja si e refolosit corect**: `extract_balanta.py` (PDF, nemodificat - bine), + `genereaza_xlsx.py` (constructia BALANTA/FACTURA, ramane), sablonul `init_facturi_balanta_note.xlsx`, + conventiile `.TOATE`/`.RESTUL` din `conturi_roa.dbf` (`raport_sursa_saga_xlsx.md` 2.1-2.3), regulile + validate `decizii_import.md`. Planul nu reconstruieste ce exista - punct bun. +- **Minimum set**: planul e rezonabil de minimal (3 cititoare + mapare + integrare + regresie). + Nu am gasit scope creep mare. Etapa 3 (baza reala, gbak, Firebird pe retea) e corect lasata afara + (`plan_etapa2_convertor.md:172-180`). +- **Complexity check** (skill: 8+ fisiere / 2+ clase noi = smell): planul atinge ~6-8 module noi + (`citire_xlsx`, `citire_fdb`, `mapare`, `extrage`, `genereaza`, test) - la limita, nu peste. + Nu declanshez reducere de scope pe acest motiv. +- **Completeness check**: planul propune varianta completa pe hartie (poarta de identitate CSV, + regresie pe productie) - dar doua dintre porti nu sunt executabile cu artefactele actuale + (vezi C2, C3). Deci "complet" e declarat, nu livrabil. +- **Distribution check**: unealta interna, rulata de Marius pe masina lui. Nu necesita pipeline de + publicare. Corect lasat afara. + +--- + +## 1. Scoruri pe dimensiunile skill-ului + +| Dimensiune (din skill) | Nota | Ce ar aduce-o la maxim | +|---|---|---| +| Scope challenge | 8/10 | Sa declare explicit ce se pierde cand "un singur CSV" nu e suficient (parteneri, totaluri, rollup) - vezi C5, C11 | +| Architecture / data flow | 5/10 | Contract intern real (balanta + parteneri + facturi), nu un singur CSV; regula de rollup FDB specificata (C2, C11) | +| Code quality / DRY | 6/10 | Clarifica cine detine cont/acont (mapare vs `genereaza`), evita re-encodarea pct. 16 in doua locuri (C4, C9) | +| Test coverage | 4/10 | Golden fixtures comise in git + framework de test; altfel poarta de regresie si poarta FDB nu ruleaza (C3, C5, sec. 2.5) | +| Performance | 7/10 | Agregare in SQL (GROUP BY pe 3 intervale de data), nu `SELECT *` in Python; charset WIN1250 (C15) | +| Failure modes / esecuri tacute | 5/10 | Trateaza explicit: verificarea Totaluri care dispare tacut, SCADENT NULL, cod fiscal gol (C5, C6) | +| Diagrame | 8/10 | Diagrama de pipeline exista (`:35-39`); lipseste diagrama de forma a datelor per cititor (ce coloane intra/ies) | +| Outside voice (cross-model) | n/a | Nu am putut rula Codex/subagent in acest lane; nu e o nota, e o limita de mediu | + +Verdict de ansamblu: **plan bun ca intentie, cu 3 gauri de executie care il opresc sa fie "gata"** +(poarta FDB fara regula, poarta de regresie fara fixture, sursa partenerilor care contrazice productia). + +--- + +## 2. Constatari + +Format: `[Px] (confidence N/10) ce e in plan / ce e in neregula / ce propun`. + +### C1 [P1] (confidence 9/10) - `CONFIG_CONT_IREG` nu reproduce setul de parteneri validat + +- **In plan**: `:119-122` - "Ce NU se configureaza aici: care conturi merg pe parteneri. Ramane + `CONFIG_CONT_IREG` din Oracle ... e sursa de adevar a ROACONT". +- **In neregula**: codul validat in productie foloseste alt set. `genereaza_xlsx.py:47-53`: + `PARTENER_BANCA={5121,5124}`, `PARTENER_SINTETIC={401,4092,4111,461,462,4551}`, + `PARTENER_FARA_ANALITICE={5311}`. In `config_cont_ireg.md:89-91` (CU_INREGISTRARI=1) **nu apar + 5121, 5124, 5311**, iar in lista Oracle apar 404,408,4091-4094,418,419 etc. pe care `genereaza` + NU le trateaza ca parteneri. Deci: daca unealta decide partenerii doar din Oracle, 5121/5124/5311 + (decisiuni validate, `decizii_import.md` pct. 14-15) devin conturi obisnuite -> regresie tacuta pe + MASTER (`5121.01 PIRAEUS`). +- **Propun**: sursa de adevar operationala = o lista in repo, derivata din setul validat + reconciliata + explicit cu `CONFIG_CONT_IREG`; Oracle ramane consultativ. Documenteaza divergenta (Oracle listeaza + trezoreriile ca `CU_INREGISTRARI=0`, dar `decizii_import.md:52-55` arata ca formularul are liste + hardcodate separate `:1104`/`:1107`). + +### C2 [P1] (confidence 9/10) - agregarea REGISTRU pentru balanta e sub-specificata; poarta de identitate nu e demonstrabila + +- **In plan**: `:62-64` - "balanta: agregare pe `REGISTRU` la data ceruta" si `:75` - "cititorul 3 (FDB) + si cititorul 2 (xlsx) trebuie sa produca acelasi CSV". +- **In neregula**: (a) balanta exportului are 4 marimi, nu una: `DEB_INIT/CRED_INIT` (inceput de an), + `DEB_PREC/CRED_PREC` (inceput de perioada), `RULAJ_*` (perioada), `FIN_*` (sold) - deci sunt necesare + **doua praguri de data**, nu unul (`raport_exporturi_saga_noua.md` C.4:288-297 o arata pe cazul + `641` din 2025-11-30 -> `DEB_INIT`). (b) exportul **ruleaza analiticul in sintetic**: `REGISTRU` are + `401.00002`, exportul are `401` (`C.4:294,298-301`), iar `C.5:303-304` spune explicit ca "regula exacta + de includere sintetic/analitic nu se poate stabili". Fara regula de rollup, agregarea din + `CONT_D/CONT_C` produce `401.00002`, iar CSV-ul nu e identic - testul pica din cauza regulii lipsa, + nu a unui bug de cititor. +- **Propun**: specifica algoritmul in plan (nu in cod): grupare pe sintetic (`stanga punctului`), + 3 intervale de data (an, perioada, in perioada) + `FIN=PREC+RULAJ`; declara explicit ca testul pe + firma de joaca dovedeste doar cazul sintetic (`:80-82`). Adauga in plan un al doilea prag (`an`). + +### C3 [P1] (confidence 9/10) - poarta `regresie` nu are fixture comis in git + +- **In plan**: `:167` - "xlsx-urile noi **identice** cu cele importate deja in productie"; + `:154-156` - `.gitignore` ignora `init_*.xlsx` si "fisierele de productie au fost scoase cu + `git rm --cached`". +- **In neregula**: `git status` arata `D init_FUNDATIA_2025_12.xlsx`, `D init_MASTER_2025_12.xlsx`, iar + `.gitignore:6` ignora `init_*.xlsx`. Criteriul de terminare al lane-ului de regresie compara cu + fisiere care nu sunt in repo -> pe alt checkout/masina poarta nu se poate rula, iar rezultatul nu e + reproductibil nici de autor peste o luna. +- **Propun**: comite o copie golden sub `tests/golden/` (exceptie in `.gitignore`), sau un manifest de + hash-uri + regulile de numarare; atunci "identice" devine verificabil automat. PDF-urile sunt deja in + git (bine), dar output-ul-tinta lipseste. + +### C4 [P1] (confidence 8/10) - "genereaza ia cont/acont din mapare" se bate cap in cap cu logica pastrata in cod + +- **In plan**: `:143-146` - "singura schimbare de fond este ca ia `cont`/`acont` din mapare in loc sa le + calculeze"; `:103-104` - pre-completarea e generica ("primele max 4 caractere" + "cifrele + analiticului concatenate, max 4"). +- **In neregula**: (a) randurile de diferenta NU exista in balanta, deci nu pot veni din mapare; + sunt calculate (`genereaza_xlsx.py:204-212,243-249`) - planul nu spune cine le mai emite. (b) forma + `acont` depinde de categorie: `401` -> acont gol, `5121` -> acont completat identic pe BALANTA si + FACTURA (`decizii_import.md` pct. 16; `genereaza_xlsx.py:219-249,252-283`). Regula generica de + pre-completare ar pune acont pe `401` -> chei diferite -> dublare tacuta (pct. 16). +- **Propun**: decide cine detine `acont`: ori pre-completarea din mapare e constienta de categorie + (partener -> pct. 16, analitic -> regula generica), ori `genereaza` ramane singurul care decide + forma pentru parteneri, iar maparea doar suprascrie. A doua e mai putin riscanta (codul deja validat). + +### C5 [P2] (confidence 8/10) - verificarea "Totaluri" dispare tacut pe drumurile xlsx/FDB + +- **In plan**: `:54` - `este_total = gol` pe exportul de foaie de calcul; `:56` - xls/xlsx nu au rand de + totaluri. +- **In neregula**: `genereaza_xlsx.py:89-94` cauta randul "Totaluri" si `:330,381-390` face cross-check-ul + net xlsx vs net Totaluri doar daca il gaseste. Pe drumurile noi `citeste_totaluri` intoarce `None`, + deci cea mai puternica verificare cap-la-cap se **omite silentios** - exact tiparul de esec tacut pe + care planul il interzice in alta parte. +- **Propun**: inlocuieste verificarea pierduta cu una echivalenta: pe FDB, `SUM(REGISTRU)` pe latura la + data ceruta = netul balantei (cifra de control reala); pe xlsx, re-calculeaza netul din coloanele + citite. Daca nu exista echivalent, scrie explicit in `verificare_.md` "verificare indisponibila", + nu o sari. + +### C6 [P2] (confidence 8/10) - "cod fiscal real" si "scadenta reala" nu sunt garantate de baza + +- **In plan**: `:65-66` - "Codul fiscal real vine de aici" si `:134` - FDB da "cod fiscal real si + scadenta reala ... nimic lipseste". +- **In neregula**: in baza de joaca, `FURNIZORI` are `***('00001','ROMFAST','','401.00001')***` - cod + fiscal **gol** (`raport_exporturi_saga_noua.md` C.3:264), iar singurul `INTRD` are `SCADENT=NULL` + (C.3:274). Deci "real" poate insemna gol/NULL pe date reale. +- **Propun**: pastreaza fallback-urile de azi (cod provizoriu `.`, scadenta = ultima zi + a lunii) ca default cand FDB da NULL/gol, si raporteaza cate randuri au cazut pe fallback. + +### C7 [P2] (confidence 7/10) - semantica `MANUAL` in merge e nedeclarata + +- **In plan**: `:100` `stare` e "nu" (need editabila); `:114-117` - "randurile `MANUAL` raman intacte". +- **In neregula**: nu se spune **cine** si **cum** face trecerea `AUTO -> MANUAL`. Daca utilizatorul + editeaza `cont`/`acont`, cine observa? Cum se distinge o editare de o re-preluare a aceleiasi valori? + La a doua rulare, daca regula auto ar produce exact valoarea editata, randul ramane AUTO si poate fi + suprascris mai tarziu. De asemenea: un MANUAL care devine `DISPARUT` si reapare - ce stare are? +- **Propun**: defineste regula (ex.: orice modificare a `cont`/`acont`/`exclus` fata de valoarea + pre-completata marcheaza `MANUAL`; `stare` devine `READONLY`), si trateaza revenirea `DISPARUT -> MANUAL`. + +### C8 [P2] (confidence 8/10) - regula de coliziune se bate cu `.TOATE`/`.RESTUL` + +- **In plan**: `:148-150` - opreste cu eroare daca "doua randuri produc acelasi `(cont, acont)` fara sa + fie acelasi cont SAGA"; `:106-109` - `.TOATE` = toate analiticele merg pe acelasi `(cont, + acont)` ROA. +- **In neregula**: `.TOATE`/`.RESTUL` sunt **agregare intentionata** a mai multor conturi SAGA pe aceeasi + cheie ROA, exact ce regula de mai sus declara eroare. Asa cum e scris, tool-ul se opreste pe cazul + suportat. In plus, pentru conturile-partener `acont` e irelevant (pct. 16) - nu trebuie sa intre in + verificarea de coliziune. +- **Propun**: scuteste agregarea intentionata (acelasi `cont_saga` de baza sub `.TOATE`/`.RESTUL`) si + exclude partenerii din verificarea de coliziune; raporteaza doar coliziunile neintentionate. + +### C9 [P2] (confidence 7/10) - redenumirea sinteticului (`409 -> 4091`) nu vine din noul mapare + +- **In plan**: `:106-112` preia doar `.TOATE`/`.RESTUL` din `conturi_roa.dbf`; pre-completarea `:103-104` + copiaza sinteticul SAGA. +- **In neregula**: `raport_sursa_saga_xlsx.md` 2.1/2.3 arata ca `conturi_roa.dbf` face si redenumire de + sintetic (`409 -> 4091`, `431 -> 4311`, `4374 -> 4371`). Regula de pre-completare nu o produce, deci + o firma cu `409` iese cu `cont=409` in loc de `4091`. Ramane corectabila manual, dar planul pretinde + reutilizare. +- **Propun**: semeneaza maparea din `conturi_roa.dbf` cand exista (CONT2/ACONT2), sau adauga tabela de + redenumire explicita. + +### C10 [P2] (confidence 8/10) - selectia foii nu e specificata si difera intre surse + +- **In plan**: `:48-56` (cititorul 2) nu spune cum alege foaia; `raport_sursa_saga_xlsx.md` spune ca + foaia VFP se numeste `balanta`, iar `raport_exporturi_saga_noua.md` A.2:110 spune `xl` (xls) vs + `Sheet1` (xlsx). +- **In neregula**: un cititor care cauta fix `Sheet1` pica pe exportul VFP; unul care ia `active` pica + pe fisiere cu foi ascunse. +- **Propun**: alege prima foaie, sau cauta dupa nume in lista cunoscuta, cu eroare clara daca nu exista. + +### C11 [P2] (confidence 7/10) - "un singur CSV intern" nu e suficient pentru nivelul 3-4 de FACTURA + +- **In plan**: `:41-42` - "Restul lantului nu stie din ce sursa vine"; dar `:136` parametri + `--furnizori/--clienti/--facturi/--fdb` intra in **generator**, nu in cititor. +- **In neregula**: numele partenerului, codul fiscal real si detaliul de factura nu stau in CSV-ul de + balanta; sunt intrari separate. Diagrama `:35-39` sugereaza un singur flux, iar contractul real are + 3 intrari. Nu e fatal, dar planul se contrazice si ascunde o dependenta. +- **Propun**: scrie contractul real: `balanta_.csv` + optional `parteneri_.csv` + + optional `facturi_.csv`; `genereaza` accepta cele doua optionale si degradeaza la nivelul + corespunzator (`:124-134`). + +### C12 [P3] (confidence 7/10) - coloana `TIP` (a 13-a) nu are consumator + +- **In plan**: `:55` - "Coloana `TIP` (A/P) se duce in CSV ca a 13-a coloana, optionala". +- **In neregula**: `genereaza_xlsx.py` nu citeste niciodata `TIP`; natura D/C vine din latura hardcodata + (`:43`) si din net. Deci coloana e greutate moarta sau scop nedeclarat. +- **Propun**: fie o lasi afara, fie ii dai un consumator concret (ex. validare latura/cont de partener). + +### C13 [P3] (confidence 6/10) - facturile de clienti din FDB sunt speculativ specificate + +- **In plan**: `:67-68` - `IESIRI`/`IES_DET` -> facturi clienti. +- **In neregula**: `raport_exporturi_saga_noua.md` C.3:280 da `IESIRI` (0 randuri) si `IES_DET` cu + structura "-" (necunoscuta); firma are 0 clienti. Deci SQL-ul de facturi clienti e presupunere. +- **Propun**: marcheaza partea de clienti ca neverificata si nu o promite ca livrabil pana nu ai o baza + reala (Etapa 3, `:175`). + +### C14 [P3] (confidence 6/10) - Oracle (retea + credentiale) intr-un flux de fisiere offline + +- **In plan**: `:119-122` - partenerii vin din `CONFIG_CONT_IREG` (Oracle local). +- **In neregula**: aduce o dependenta de DSN/VPN/tnsnames si de parola din + `D:\ROA\ROACONT\docs\oracle_parola_standard.secret` (`config_cont_ireg.md:7,17`) intr-o unealta care + altfel lucreaza doar pe fisiere. Esti pe acelasi LAN (`10.0.20.121`), deci e fezabil, dar adauga + moduri de esec (DNS, cont SQL*Plus, parola expirata) pentru un pas care se schimba rar. +- **Propun**: instantaneu versionat (`config/cont_ireg.csv`) regenerat de un script mic cand Oracle se + schimba; unealta citeste instantaneul offline. Vezi si C1. + +### C15 [P3] (confidence 6/10) - performanta FDB si charset + +- **In plan**: `:58-64` nu spune cum se agrega. +- **In neregula**: la clienti cu `REGISTRU` mare, `SELECT *` + agregare in Python e lent si consuma + memorie; iar `CONT_D/CONT_C` si denumirile au diacritice/CP1250. +- **Propun**: agregare in SQL (`GROUP BY cont, CASE pe intervale de data`), `charset=WIN1250` + (`raport_exporturi_saga_noua.md` C.2:230 foloseste deja WIN1250). + +### C16 [P3] (confidence 5/10) - potrivirea numelor de coloane trebuie exacta, nu substring + +- **In plan**: `:51-53` compara antetul case-insensitive. +- **In neregula**: exportul are si `DEB_PREC` si `DEB_PREC_1` (setul `_1`, `raport_sursa_saga_xlsx.md` + 1.1). O potrivire prin `in`/startswith poate alege coloana gresita tacut. +- **Propun**: normalizeaza si compara egalitate exacta dupa nume; ignora explicit coloanele `_1`. + +--- + +## 2.5 Test review (per lane - ce test automat lasa fiecare) + +Azi nu exista niciun test (`tests/` lipseste; `pytest` neinstalat, verificat). Skill-ul cere 100% +acoperire; propun concret pentru fiecare lane: + +| Lane | Test lasat in urma | Observatie | +|---|---|---| +| `citire-xlsx` | `tests/test_citire_xlsx.py`: CSV produs din `exemple/saga-sqlite-balanta-09-2026.xlsx` == CSV golden comis; + relatiile `total=prec+rulaj`, `sold=total` pe toate randurile | Fixture e deja in git (`exemple/`) | +| `mapare` | `tests/test_mapare.py` pe functia de merge: MANUAL supravietuieste, analitic nou -> `NOU`, disparut -> `DISPARUT`, coliziune neintentionata -> Stop, `.TOATE` NU e coliziune | Pur logic, fara dependinte | +| `citire-fdb` | `tests/test_citire_fdb.py`: CSV produs din `D:\SAGA250909\0001\CONT_BAZA.FDB` == CSV golden comis (inghetat o data). Live, doar daca baza exista (skip motivat) | Baza nu e in repo -> testul depinde de mediu; de aceea ingheata CSV-ul | +| `integrare` | rulare cap-la-cap pe firma de joaca, comparatie cu xlsx golden | Necesita C3 | +| `regresie` | `tests/test_regresie.py`: `init_FUNDATIA_2025_12.xlsx` si `init_MASTER_2025_12.xlsx` regenerate == golden comis | Necesita C3 (altfel nu ruleaza) | + +Problema transversala: **fara fixture comis (C3), 2 din 5 lane-uri nu pot demonstra criteriul de +terminare**. Recomand `unittest` din stdlib ca sa nu adaugi dependinte (CLAUDE.md: doar pdfplumber, +openpyxl, xlrd, firebird-driver), sau `pytest` acceptat explicit ca dependinta dev-only. + +Acoperire estimata azi: 0%. Dupa cele 5 testuri de mai sus, portile reale ale planului devin +automate. Cazurile pe care planul insusi le declara neacoperite (`:80-83`: 0 analitice, 2 furnizori, +0 clienti, 1 factura) raman neacoperite pana la o baza reala (Etapa 3) - corect de raportat, nu de ascuns. + +--- + +## 2.6 Failure modes (esec + test + eroare vizibila?) - cele fara test SI fara mesaj = critical gap + +| Failure mode | Test? | Eroare clara? | Verdict | +|---|---|---|---| +| Rollup FDB analitic->sintetic gresit (C2) | Nu (poarta nu are regula) | Nu, iese un CSV diferit | **CRITICAL GAP** | +| Verificarea Totaluri dispare tacut (C5) | Nu | Nu | **CRITICAL GAP** | +| Regresie fara golden -> cineva crede ca a trecut (C3) | Nu | Nu | **CRITICAL GAP** | +| Editare MANUAL suprascrisa la a 2-a rulare (C7) | Nu | Nu | **CRITICAL GAP** | +| Coliziune `.TOATE` oprita ca eroare / coliziune reala ratata (C8) | Nu | Da (Stop) / Nu | Risc mediu | +| `fbclient.dll` lipsa / cale gresita | Nu | Da (exceptie driver) | Risc mic | +| Foaie gresita aleasa (C10) | Nu | Depinde | Risc mediu | +| Cod fiscal gol / SCADENT NULL din FDB (C6) | Nu | Nu (valoare proasta) | Risc mediu | +| Facturi clienti FDB pe structura necunoscuta (C13) | Nu | Nu | Risc mediu, amanat | + +--- + +## 2.7 Required outputs (cerute de skill) + +**NOT in scope** (plan `:16-17`, `:172-180`): import registru jurnal; balante lunare; nomenclator +parteneri lunar; baza `.FDB` reala; procedura `gbak` pentru client; Firebird prin retea. Corect +delimitat. De adaugat explicit: pipeline de distributie (nu exista, unealta interna) si testarea pe +analitice reale (amanata la Etapa 3). + +**What already exists** (reutilizat): `extract_balanta.py` (nemodificat), `genereaza_xlsx.py` +(constructie + verificari), sablonul, `decizii_import.md`, `conturi_roa.dbf` (conventii), baza de joaca ++ exporturile din `exemple/`. Planul reutilizeaza bine; singurul lucru reconstruit inutil ar fi +`TIP` (C12) si, potential, setul de parteneri (C1). + +**Diagrams**: exista diagrama de pipeline (`:35-39`). Lipseste o diagrama de forma a datelor: pentru +fiecare cititor, ce coloane intra si ce iese in CSV (utila exact pentru C5/C10/C11/C16). + +**Worktree parallelization**: + +| Step | Module | Depinde de | +|---|---|---| +| citire-xlsx | `citire_xlsx` | - | +| mapare | `mapare` | - | +| citire-fdb | `citire_fdb` | citire-xlsx (contract CSV comun) | +| integrare | `extrage`, `genereaza` | toate | +| regresie | `tests`, golden | integrare | + +Lane A: citire-xlsx -> citire-fdb (secvential, contract comun). Lane B: mapare (independent). +Apoi integrare, apoi regresie. Fara conflict de module intre A si B. Planul are deja dependenta +`citire-fdb -> citire-xlsx` (`:165`), corect. + +**Implementation Tasks** (sinteza): +- T1 (P1) - scrie regula de agregare/rollup FDB in plan (C2). +- T2 (P1) - comite golden fixtures pentru regresie (C3). +- T3 (P1) - reconciliaza setul de parteneri cu productia (C1). +- T4 (P1) - decide proprietarul `cont/acont` si trata diferentele (C4). +- T5 (P2) - inlocuieste verificarea Totaluri pe drumurile noi (C5). +- T6 (P2) - specifica merge-ul `MANUAL`/coliziuni/.TOATE (C7, C8). +- T7 (P2) - selectie foaie + fallback cod fiscal/scadenta (C6, C10). + +--- + +## 3. DECIZII DE LUAT DE MARIUS + +### D1 - Sursa setului de conturi cu parteneri +- **A)** Interogare Oracle `CONFIG_CONT_IREG` la fiecare rulare (retea + credentiale). +- **B)** Instantaneu versionat in repo (`config/cont_ireg.csv`), regenerat de un script mic; setul + operational (5121/5124/5311 etc.) adaugat explicit langa el. (recomandat) +- **C)** Hardcodeaza setul validat in `genereaza_xlsx.py`. +- **Recomandare: B** - offline pentru flux, dar totusi auditat si actualizabil; A aduce esecuri de + retea intr-un pas care se schimba rar; C e exact "lista hardcodata in `.prg`" pe care planul (`:121`) + vrea sa o evite. Motiv: explicitudine + portabilitate. + +### D2 - Regula de agregare FDB (ca sa treaca poarta de identitate) +- **A)** Rollup la sintetic (stanga punctului) + 3 intervale de data; test pe firma de joaca dovedeste + doar sinteticul. (recomandat) +- **B)** Pastreaza analiticul ca atare si cere exportul SAGA tot la nivel analitic. +- **C)** Amaneaza FDB pana ai o baza reala cu analitice. +- **Recomandare: A** - e singurul mod in care poarta `:75` poate pica/trece pe datele existente; + C amana tot lane-ul, B muta problema la client. + +### D3 - Fixture pentru poarta de regresie +- **A)** Comite copiile `init_FUNDATIA_2025_12.xlsx` / `init_MASTER_2025_12.xlsx` sub `tests/golden/` + (exceptie in `.gitignore`). (recomandat) +- **B)** Manifest de hash-uri + un CSV golden al continutului. +- **C)** Renunta la poarta de regresie. +- **Recomandare: A** - e poarta finala a planului (`:167-170`); fara fixture nu exista; continutul e + date de test validate in productie, nu secrete. + +### D4 - Cine detine `cont`/`acont` si randurile de diferenta +- **A)** Maparea pre-completeaza constient de categorie (partener pct. 16 vs analitic), `genereaza` doar + citeste. (planul de azi) +- **B)** `genereaza` ramane singurul care decide forma pentru parteneri; maparea doar suprascrie; + randurile de diferenta raman calculate in cod. (recomandat) +- **C)** Reescrie `genereaza` complet pe mapare, inclusiv diferentele (rescriere mai mare). +- **Recomandare: B** - codul de parteneri e deja validat in productie (`decizii_import.md` pct. 16, + `genereaza_xlsx.py:219-303`); re-encodarea lui in generatorul de mapare dubleaza regula (DRY) si + risca regresia pe MASTER. + +### D5 - Verificarea echivalenta "Totaluri" pe drumurile xlsx/FDB +- **A)** Adauga un check real: `SUM(REGISTRU)` pe latura la data ceruta = netul balantei generate. (recomandat) +- **B)** Doar avertizare explicita in raport ca verificarea nu e disponibila. +- **C)** Ignora. +- **Recomandare: A** - planul declara ca nu ajusteaza cifre ca sa treaca verificari (`CLAUDE.md`); + verificarea trebuie inlocuita cu una reala, nu doar scoasa. + +### D6 - Framework de test +- **A)** `unittest` stdlib (fara dependinte noi). (recomandat) +- **B)** `pytest` (dependinta dev-only). +- **C)** Scripturi shell/py ad-hoc, fara framework. +- **Recomandare: A** - respecta "fara alte dependinte"; C nu da raportare de totaluri/esecuri. + +--- + +## 4. Ce am verificat si ce NU am putut verifica + +**Verificat (dovada in fisier):** +- `genereaza_xlsx.py` citeste din CSV doar `cont/denumire/total_d/total_c/este_total`; + nu citeste `sold_*`, nu citeste `TIP`, iar cross-check-ul Totaluri depinde de un rand care exista + doar in PDF (`:65-94,196-304,321-390`). +- `extract_balanta.py` scrie 12 coloane; `pagina`/`este_total` sunt coloanele care nu au echivalent + in export (`:232-237`, plan `:54`). +- Setul de parteneri din cod (5121/5124/5311) contrazice `CU_INREGISTRARI` din Oracle + (`genereaza_xlsx.py:47-53` vs `config_cont_ireg.md:89-91`). +- Baza de joaca: 0 analitice in export, `FURNIZORI.COD_FISCAL` gol pentru `ROMFAST`, + `INTRD.SCADENT=NULL`, regulile de rollup analitic->sintetic declarate necunoscute + (`raport_exporturi_saga_noua.md` A.1, C.3, C.4, C.5). +- `.gitignore` ignora `init_*.xlsx`; `git status` arata xlsx-urile de productie scoase din index. +- Mediu: `xlrd 2.0.2` si `firebird-driver` instalate; `pytest` NU; `tests/` NU. + +**Nu am putut verifica (si nu am inventat):** +- Daca `409 -> 4091` sau alte redenumiri sunt necesare pe firmele viitoare (nu apar in FUNDATIA/MASTER). +- Structura `IES_DET` din Firebird (raportul o da ca necunoscuta) - partea de facturi clienti e + presupunere pana la o baza reala. +- Daca `CONFIG_CONT_IREG` s-a schimbat fata de dump-ul din `config_cont_ireg.md` (nu am interogat Oracle). +- Regula exacta de includere sintetic/analitic in exportul SAGA (`C.5` o declara nedeterminabila). +- Comportamentul real al formularului pe combinatia "acont gol pe FACTURA + acont completat pe BALANTA" + pe alte conturi decat cele deja tratate (am luat de bun `decizii_import.md` pct. 16). + +**Nu am rulat** Codex/outside voice (mediu de subagent, fara Codex) si nici testul real de identitate +CSV (nu am voie sa rulez VFP/cod in acest lane; oricum planul nu are inca cititoarele). + +--- + +Stare: niciun fisier modificat in afara acestui raport; fara commit; fara procese pornite; +fara date de test consumate. diff --git a/exemple/saga-sqlite-balanta-09-2026.xls b/exemple/saga-sqlite-balanta-09-2026.xls new file mode 100644 index 0000000..5f05082 Binary files /dev/null and b/exemple/saga-sqlite-balanta-09-2026.xls differ diff --git a/exemple/saga-sqlite-balanta-09-2026.xlsx b/exemple/saga-sqlite-balanta-09-2026.xlsx new file mode 100644 index 0000000..cac1a6e Binary files /dev/null and b/exemple/saga-sqlite-balanta-09-2026.xlsx differ diff --git a/exemple/saga-sqlite-furnizori-09-2026.xlsx b/exemple/saga-sqlite-furnizori-09-2026.xlsx new file mode 100644 index 0000000..7e134ed Binary files /dev/null and b/exemple/saga-sqlite-furnizori-09-2026.xlsx differ diff --git a/exemple/saga-sqlite-furnizori-facturi-un-furnizor-09-2026.xlsx b/exemple/saga-sqlite-furnizori-facturi-un-furnizor-09-2026.xlsx new file mode 100644 index 0000000..355f068 Binary files /dev/null and b/exemple/saga-sqlite-furnizori-facturi-un-furnizor-09-2026.xlsx differ diff --git a/export_balanta_fundatia_12_2025.xlsx b/export_balanta_fundatia_12_2025.xlsx deleted file mode 100644 index fa94baf..0000000 Binary files a/export_balanta_fundatia_12_2025.xlsx and /dev/null differ diff --git a/init_FUNDATIA_2025_12.xlsx b/init_FUNDATIA_2025_12.xlsx deleted file mode 100644 index d9aa688..0000000 Binary files a/init_FUNDATIA_2025_12.xlsx and /dev/null differ diff --git a/init_MASTER_2025_12.xlsx b/init_MASTER_2025_12.xlsx deleted file mode 100644 index 8c471c0..0000000 Binary files a/init_MASTER_2025_12.xlsx and /dev/null differ diff --git a/sql/update_cod_fiscal_FUNDATIA.sql b/sql/update_cod_fiscal_FUNDATIA.sql index 28019e2..d919640 100644 --- a/sql/update_cod_fiscal_FUNDATIA.sql +++ b/sql/update_cod_fiscal_FUNDATIA.sql @@ -9,16 +9,17 @@ -- Partenerii NEGASITI nu apar mai jos si raman cu codul fiscal -- provizoriu neschimbat. -- Sursa CUI : https://demoanaf.ro (cautare ONRC + verificare ANAF) +-- Prefix RO : pus doar la platitorii de TVA (verificare ANAF 21.09.2026). -- Script NEexecutat; se ruleaza manual pe schema FUNDATIA. -- ============================================================ update nom_parteneri set cod_fiscal = '3598139' where cod_fiscal = '401.00018'; -- HOSTVISION SRL -update nom_parteneri set cod_fiscal = '27648528' where cod_fiscal = '401.00043'; -- BRIT MOTOR AG SRL -update nom_parteneri set cod_fiscal = '25709173' where cod_fiscal = '401.00049'; -- APA-CANAL ILFOV SA -update nom_parteneri set cod_fiscal = '4556450' where cod_fiscal = '401.00050'; -- CEGIM SRL -update nom_parteneri set cod_fiscal = '2554568' where cod_fiscal = '401.00051'; -- CRAMA SPARLENI SRL -update nom_parteneri set cod_fiscal = '2816464' where cod_fiscal = '401.00054'; -- DEDEMAN SRL -update nom_parteneri set cod_fiscal = '30141834' where cod_fiscal = '401.00055'; -- AGROMECANIC IMPEX SRL +update nom_parteneri set cod_fiscal = 'RO27648528' where cod_fiscal = '401.00043'; -- BRIT MOTOR AG SRL +update nom_parteneri set cod_fiscal = 'RO25709173' where cod_fiscal = '401.00049'; -- APA-CANAL ILFOV SA +update nom_parteneri set cod_fiscal = 'RO4556450' where cod_fiscal = '401.00050'; -- CEGIM SRL +update nom_parteneri set cod_fiscal = 'RO2554568' where cod_fiscal = '401.00051'; -- CRAMA SPARLENI SRL +update nom_parteneri set cod_fiscal = 'RO2816464' where cod_fiscal = '401.00054'; -- DEDEMAN SRL +update nom_parteneri set cod_fiscal = 'RO30141834' where cod_fiscal = '401.00055'; -- AGROMECANIC IMPEX SRL update nom_parteneri set cod_fiscal = '44234399' where cod_fiscal = '4111.00004'; -- EM INTERNATIONAL SERVICES GROUP S.R.L. commit; diff --git a/sql/update_cod_fiscal_MASTER.sql b/sql/update_cod_fiscal_MASTER.sql index bb30db7..b107b44 100644 --- a/sql/update_cod_fiscal_MASTER.sql +++ b/sql/update_cod_fiscal_MASTER.sql @@ -9,17 +9,18 @@ -- Partenerii NEGASITI nu apar mai jos si raman cu codul fiscal -- provizoriu neschimbat. -- Sursa CUI : https://demoanaf.ro (cautare ONRC + verificare ANAF) +-- Prefix RO : pus doar la platitorii de TVA (verificare ANAF 21.09.2026). -- Script NEexecutat; se ruleaza manual pe schema MASTER. -- ============================================================ update nom_parteneri set cod_fiscal = '14446160' where cod_fiscal = '401.00003'; -- TEMPLUM PLUS SRL -update nom_parteneri set cod_fiscal = '38784649' where cod_fiscal = '401.00007'; -- ACVATIC TES S.R.L. -update nom_parteneri set cod_fiscal = '29134450' where cod_fiscal = '401.00008'; -- DREAM FISH SRL -update nom_parteneri set cod_fiscal = '16702141' where cod_fiscal = '401.00009'; -- LEROY MERLIN ROMANIA SRL -update nom_parteneri set cod_fiscal = '39005550' where cod_fiscal = '401.00010'; -- SERVICE ONLAPTOP S.R.L. +update nom_parteneri set cod_fiscal = 'RO38784649' where cod_fiscal = '401.00007'; -- ACVATIC TES S.R.L. +update nom_parteneri set cod_fiscal = 'RO29134450' where cod_fiscal = '401.00008'; -- DREAM FISH SRL +update nom_parteneri set cod_fiscal = 'RO16702141' where cod_fiscal = '401.00009'; -- LEROY MERLIN ROMANIA SRL +update nom_parteneri set cod_fiscal = 'RO39005550' where cod_fiscal = '401.00010'; -- SERVICE ONLAPTOP S.R.L. update nom_parteneri set cod_fiscal = '33048749' where cod_fiscal = '401.00013'; -- CREATIV EXPERT CONSTRUCT S.R.L. -update nom_parteneri set cod_fiscal = '35056829' where cod_fiscal = '401.00017'; -- TIRES AND PARTS SRL -update nom_parteneri set cod_fiscal = '4837404' where cod_fiscal = '401.00023'; -- ANGLO CARS SRL -update nom_parteneri set cod_fiscal = '37246323' where cod_fiscal = '401.00027'; -- SEBASTIAN CONSTRUCTII MONTAJ SRL +update nom_parteneri set cod_fiscal = 'RO35056829' where cod_fiscal = '401.00017'; -- TIRES AND PARTS SRL +update nom_parteneri set cod_fiscal = 'RO4837404' where cod_fiscal = '401.00023'; -- ANGLO CARS SRL +update nom_parteneri set cod_fiscal = 'RO37246323' where cod_fiscal = '401.00027'; -- SEBASTIAN CONSTRUCTII MONTAJ SRL commit; diff --git a/tests/anonimizeaza_etalon.py b/tests/anonimizeaza_etalon.py new file mode 100644 index 0000000..e61e877 --- /dev/null +++ b/tests/anonimizeaza_etalon.py @@ -0,0 +1,120 @@ +"""Produce etalonul de regresie: copii anonimizate ale xlsx-urilor importate in productie. + +Ce se pastreaza NEATINS: conturile, sumele, structura si numarul randurilor, datele, tipul +randului. Asta este ce verifica poarta de regresie. +Ce se inlocuieste: + - pe randurile FACTURA: numele partenerului, codul fiscal, registrul comertului, adresa, + explicatia; + - ORIUNDE in fisier: IBAN-urile. Randurile BALANTA de pe 5121/5124 au in `nume` denumirea + analiticului, care la conturile de banca este chiar IBAN-ul clientului + (`RO73 BACX 0000 0008 7243 0001`). Restul denumirilor de cont (CAPITAL SOCIAL, REZULTAT + REPORTAT, DEBITORI DIVERSI) sunt din planul de conturi si raman. + +Inlocuirea e stabila: acelasi nume real primeste mereu acelasi nume fals, ca relatiile dintre +randuri (mai multe facturi ale aceluiasi partener) sa se pastreze. + +Tabela de corespondenta se scrie in tests/_corespondenta_anonimizare.json, care este IGNORAT de +git. Nu o comite: cu ea, anonimizarea se poate desface. + +Rulare: py tests\anonimizeaza_etalon.py +""" +import json +import pathlib +import re +import shutil + +import openpyxl + +RADACINA = pathlib.Path(__file__).resolve().parent.parent +GOLDEN = RADACINA / "tests" / "golden" +CORESP = RADACINA / "tests" / "_corespondenta_anonimizare.json" + +SURSE = [ + ("init_FUNDATIA_2025_12.xlsx", "golden_FUNDATIA_2025_12.xlsx"), + ("init_MASTER_2025_12.xlsx", "golden_MASTER_2025_12.xlsx"), +] + +# coloana (1-based) -> cum se falsifica +COL_NUME = 10 +COL_COD_FISCAL = 11 +COL_REG_COM = 12 +COL_ADRESA = 13 +COL_EXPLICATIA = 14 +COL_TIP = 5 + +# IBAN romanesc, cu sau fara spatii: RO + 2 cifre + 4 litere + 16 caractere alfanumerice +IBAN = re.compile(r"RO\s?\d{2}(?:\s?[A-Z0-9]{4}){5}", re.IGNORECASE) + + +def anonimizeaza(): + GOLDEN.mkdir(parents=True, exist_ok=True) + coresp = {"nume": {}, "cod_fiscal": {}, "iban": {}} + raport = [] + + for sursa, tinta in SURSE: + cale = RADACINA / sursa + if not cale.exists(): + raise SystemExit( + "Lipseste %s. Etalonul nu se poate construi - vezi docs/handoff_etapa2_convertor.md" + % sursa + ) + shutil.copy(cale, GOLDEN / tinta) + wb = openpyxl.load_workbook(GOLDEN / tinta) + ws = wb.active + schimbate = 0 + + for rand in range(2, ws.max_row + 1): + if (ws.cell(rand, COL_TIP).value or "").strip().upper() != "FACTURA": + continue + schimbate += 1 + + nume = ws.cell(rand, COL_NUME).value + if nume: + if nume not in coresp["nume"]: + coresp["nume"][nume] = "PARTENER %03d" % (len(coresp["nume"]) + 1) + ws.cell(rand, COL_NUME).value = coresp["nume"][nume] + + cf = ws.cell(rand, COL_COD_FISCAL).value + if cf: + cf = str(cf) + if cf not in coresp["cod_fiscal"]: + coresp["cod_fiscal"][cf] = "CF%06d" % (len(coresp["cod_fiscal"]) + 1) + ws.cell(rand, COL_COD_FISCAL).value = coresp["cod_fiscal"][cf] + + for col in (COL_REG_COM, COL_ADRESA, COL_EXPLICATIA): + if ws.cell(rand, col).value: + ws.cell(rand, col).value = None + + # IBAN-urile apar si in afara randurilor FACTURA (denumirea analiticului de banca) + ibanuri = 0 + for rand in ws.iter_rows(): + for celula in rand: + if not isinstance(celula.value, str) or not IBAN.search(celula.value): + continue + def fals(m, _c=coresp): + real = m.group(0) + if real not in _c["iban"]: + _c["iban"][real] = "RO00 IBAN %04d" % (len(_c["iban"]) + 1) + return _c["iban"][real] + + celula.value = IBAN.sub(fals, celula.value) + ibanuri += 1 + + wb.save(GOLDEN / tinta) + raport.append((tinta, ws.max_row - 1, schimbate, ibanuri)) + + CORESP.write_text(json.dumps(coresp, ensure_ascii=False, indent=1), encoding="utf-8") + + for tinta, randuri, schimbate, ibanuri in raport: + print( + "%-34s %4d randuri, %3d FACTURA anonimizate, %2d celule cu IBAN" + % (tinta, randuri, schimbate, ibanuri) + ) + print( + "%d nume, %d coduri fiscale si %d IBAN-uri inlocuite. Corespondenta: %s (ignorata de git)" + % (len(coresp["nume"]), len(coresp["cod_fiscal"]), len(coresp["iban"]), CORESP.name) + ) + + +if __name__ == "__main__": + anonimizeaza() diff --git a/tests/golden/golden_FUNDATIA_2025_12.xlsx b/tests/golden/golden_FUNDATIA_2025_12.xlsx new file mode 100644 index 0000000..9bc7f96 Binary files /dev/null and b/tests/golden/golden_FUNDATIA_2025_12.xlsx differ diff --git a/tests/golden/golden_MASTER_2025_12.xlsx b/tests/golden/golden_MASTER_2025_12.xlsx new file mode 100644 index 0000000..37d93cd Binary files /dev/null and b/tests/golden/golden_MASTER_2025_12.xlsx differ