From b5da2ff050dbf49afa0ecc8a833959f1f4660c85 Mon Sep 17 00:00:00 2001 From: guy Date: Mon, 21 Aug 1995 07:45:45 +0000 Subject: [PATCH] Gestione saldaconto git-svn-id: svn://10.65.10.50/trunk@1713 c028cbd2-c16b-5b4b-a496-9718f37d4682 --- cg/cg2100.cpp | 2 +- cg/cg2100.h | 39 --- cg/cg2100p.h | 63 ++++- cg/cg2100p.uml | 496 +++++++++++++++++++----------------- cg/cg2100s.uml | 121 ++++----- cg/cg2102.cpp | 58 +++-- cg/cg2102.h | 38 +-- cg/cg2104.cpp | 613 +------------------------------------------- cg/cg2105.cpp | 665 ++++++++++++++++++++++++++++++++++++++++++++++++ cg/cglib02.cpp | 2 +- cg/pagament.cpp | 399 ++++++++++++++++++++++++----- cg/pagament.h | 89 ++++++- 12 files changed, 1510 insertions(+), 1075 deletions(-) create mode 100755 cg/cg2105.cpp diff --git a/cg/cg2100.cpp b/cg/cg2100.cpp index e2c900fe2..e65102af1 100755 --- a/cg/cg2100.cpp +++ b/cg/cg2100.cpp @@ -312,7 +312,7 @@ bool TPrimanota_application::read_caus(const char* cod, int year) if (nriga < 12 && nriga != 10) continue; // Si considerano solo le spese tipr = nriga == 10 ? 'G' : 'L'; } - const int pos = set_cgs_row(-1,zero,tc,desc,tipr); + const int pos = set_cgs_row(-1, zero, tc, desc, tipr); if (sezione > ' ' && tipr != ' ') cgs().disable_cell(pos, sezione == 'A' ? 0 : 1); } diff --git a/cg/cg2100.h b/cg/cg2100.h index 235e9bfb7..443205199 100755 --- a/cg/cg2100.h +++ b/cg/cg2100.h @@ -125,43 +125,4 @@ #define K_ANNOES 514 #define K_DATACOMP 515 -// Scadenze - -#define S_ANNO 101 -#define S_NUM 102 -#define S_RIGA 103 -#define S_DATADOC 104 -#define S_NUMPROT 105 -#define S_NUMDOC 106 -#define S_DESCR 107 -#define S_RATA 108 -#define S_DATASCAD 109 -#define S_IMPORTO 110 -#define S_IMPORTOVAL 111 -#define S_SEZIONE 112 -#define S_IMPORTOPAG 113 -#define S_RITENUTE 114 -#define S_SEZRITENUTE 115 -#define S_SALDOACC 116 -#define S_RESIDUO 117 -#define S_DATAPAG 118 -#define S_CODPAG 119 -#define S_TIPOPAG 120 -#define S_TIPO 121 -#define S_GRUPPO 122 -#define S_CONTO 123 -#define S_SOTTOCONTO 124 -#define S_DESCRCONTO 125 -#define S_DESCAGG 126 -#define S_VSABI 127 -#define S_VSCAB 128 -#define S_DESCVSABI 129 -#define S_AGENTE 130 -#define S_DESCAGENTE 131 -#define S_NSABI 132 -#define S_NSCAB 133 -#define S_DESCNSABI 134 -#define S_DESPAG 135 -#define S_CODDESC 136 - #endif diff --git a/cg/cg2100p.h b/cg/cg2100p.h index 767fabf59..f2435741f 100755 --- a/cg/cg2100p.h +++ b/cg/cg2100p.h @@ -1,11 +1,52 @@ -#define P_TIPOC 101 -#define P_GRUPPO 102 -#define P_CONTO 103 -#define P_SOTTOCONTO 104 -#define P_DESCR 105 -#define P_RESIDUO 106 -#define P_ANNO 107 -#define P_NUMERO 108 -#define P_SCAMBIO 190 -#define P_PARTITE 201 -#define P_SCADENZE 202 +#define P_TIPOC 101 +#define P_GRUPPO 102 +#define P_CONTO 103 +#define P_SOTTOCONTO 104 +#define P_DESCR 105 +#define P_RESIDUO 106 +#define P_ANNO 107 +#define P_NUMERO 108 +#define P_SHOWALL 180 +#define P_SCAMBIO 190 +#define P_PARTITE 201 +#define P_SCADENZE 202 + +// Scadenze + +#define S_ANNO 101 +#define S_NUM 102 +#define S_RIGA 103 +#define S_DATADOC 104 +#define S_NUMPROT 105 +#define S_NUMDOC 106 +#define S_DESCR 107 +#define S_RATA 108 +#define S_DATASCAD 109 +#define S_IMPORTO_SCAD 110 +#define S_IMPORTOVAL_SCAD 111 +#define S_SEZIONE_SCAD 112 + +#define S_IMPORTO 113 +#define S_RITENUTE 114 +#define S_IMPORTOVAL 115 +#define S_SALDOACC 116 +#define S_RESIDUO 117 +#define S_DATAPAG 118 +#define S_CODPAG 119 +#define S_TIPOPAG 120 +#define S_TIPO 121 +#define S_GRUPPO 122 +#define S_CONTO 123 +#define S_SOTTOCONTO 124 +#define S_DESCRCONTO 125 +#define S_DESCAGG 126 +#define S_VSABI 127 +#define S_VSCAB 128 +#define S_DESCVSABI 129 +#define S_AGENTE 130 +#define S_DESCAGENTE 131 +#define S_NSABI 132 +#define S_NSCAB 133 +#define S_DESCNSABI 134 +#define S_DESPAG 135 +#define S_CODDESC 136 diff --git a/cg/cg2100p.uml b/cg/cg2100p.uml index aec11e1e7..95bc861a3 100755 --- a/cg/cg2100p.uml +++ b/cg/cg2100p.uml @@ -1,240 +1,256 @@ -#include "cg2100p.h" - -TOOLBAR "" 0 20 0 2 - -BUTTON DLG_NEWREC 10 2 -BEGIN - PROMPT -12 -1 "~Nuovo" -END - -BUTTON DLG_OK 10 2 -BEGIN - PROMPT -22 -1 "" -END - -ENDPAGE - - -PAGE "PARTITE" -1 -1 77 20 - -LIST P_TIPOC 1 12 -BEGIN - PROMPT 1 1 "Tipo conto " - ITEM " |Conto" - ITEM "C|Cliente" - ITEM "F|Fornitore" - FLAGS "D" -END - -NUMBER P_GRUPPO 3 -BEGIN - PROMPT 26 1 "Gruppo " - FLAGS "D" -END - -NUMBER P_CONTO 3 -BEGIN - PROMPT 40 1 "Conto " - FLAGS "D" -END - -NUMBER P_SOTTOCONTO 6 -BEGIN - PROMPT 54 1 "Sottoconto " - FLAGS "D" -END - -STRING P_DESCR 50 -BEGIN - PROMPT 1 2 "Descrizione " - FLAGS "D" -END - -NUMBER P_RESIDUO 15 -BEGIN - PROMPT 1 3 "Residuo " - FLAGS "D" -END - -NUMBER P_ANNO 4 -BEGIN - PROMPT 1 4 "Anno " - FLAGS "A" -END - -STRING P_NUMERO 7 -BEGIN - PROMPT 26 4 "Numero " -END - -SPREADSHEET P_PARTITE 0 6 -BEGIN - PROMPT 0 5 "" - ITEM "Anno" - ITEM "Partita@7" - ITEM "Data doc.@10" - ITEM "Num doc.@7" - ITEM "Saldo@14" - ITEM "Documenti@14" - ITEM "Pagamenti@14" - ITEM "Altri importi@14" - ITEM "Descrizione@50" - FLAGS "D" -END - -SPREADSHEET P_SCADENZE 0 7 -BEGIN - PROMPT 0 11 "" - ITEM "Rata" - ITEM "Data doc.@10" - ITEM "Num. reg." - ITEM "Data reg.@10" - ITEM "Data scad." - ITEM "Importo Lire@14" - ITEM "Importo Valuta@14" - ITEM "Descrizione@50" - ITEM "Num. doc." - ITEM "Prot. IVA" - FLAGS "D" -END - -BUTTON P_SCAMBIO 28 -BEGIN - PROMPT -11 -1 "Num. reg. <-> Num. doc." -END - -ENDPAGE - -ENDMASK - - - -PAGE "Sheet Partite" -1 -1 66 8 - -STRING 109 50 -BEGIN - PROMPT 1 1 "Descrizione " -END - -NUMBER 101 4 -BEGIN - PROMPT 1 2 "Anno " -END - -STRING 102 7 -BEGIN - PROMPT 1 3 "Partita " -END - -DATA 103 -BEGIN - PROMPT 1 4 "Data documento " -END - -STRING 104 7 -BEGIN - PROMPT 1 5 "Numero documento " -END - -STRING 106 14 -BEGIN - PROMPT 34 2 "Documenti " - FLAGS "R" -END - -STRING 107 14 -BEGIN - PROMPT 34 3 "Pagamenti " - FLAGS "R" -END - -STRING 108 14 -BEGIN - PROMPT 34 4 "Altri importi " - FLAGS "R" -END - -STRING 105 14 -BEGIN - PROMPT 34 5 "Saldo " - FLAGS "R" -END - -BUTTON DLG_CANCEL 10 2 -BEGIN - PROMPT -11 -1 "" -END - -ENDPAGE - -ENDMASK - - -PAGE "Sheet Scadenze" -1 -1 66 8 - -NUMBER 101 4 -BEGIN - PROMPT 1 1 "Numero rata " -END - -DATE 102 -BEGIN - PROMPT 30 1 "Data documento " -END - -NUMBER 103 5 -BEGIN - PROMPT 1 2 "Numero reg. " -END - -DATE 104 -BEGIN - PROMPT 30 2 "Data reg. " -END - -NUMBER 109 5 -BEGIN - PROMPT 1 3 "Numero doc. " -END - -NUMBER 110 5 -BEGIN - PROMPT 30 3 "Protocollo IVA " -END - -DATE 105 -BEGIN - PROMPT 1 4 "Data scad. " -END - -STRING 108 50 -BEGIN - PROMPT 1 5 "Descrizione " -END - -NUMBER 106 12 -BEGIN - PROMPT 1 6 "Importo Lire " -END - -NUMBER 107 12 2 -BEGIN - PROMPT 30 6 "Importo Valuta " - PICTURE ".2" -END - - -BUTTON DLG_CANCEL 12 2 -BEGIN - PROMPT -12 -1 "" -END - -BUTTON 100 12 2 -BEGIN - PROMPT -22 -1 "~Pagamento" -END - - -ENDPAGE - -ENDMASK +#include "cg2100p.h" + +TOOLBAR "" 0 20 0 2 + +BUTTON DLG_NEWREC 10 2 +BEGIN + PROMPT -12 -1 "~Nuovo" +END + +BUTTON DLG_OK 10 2 +BEGIN + PROMPT -22 -1 "" +END + +ENDPAGE + + +PAGE "PARTITE" -1 -1 77 20 + +LIST P_TIPOC 1 12 +BEGIN + PROMPT 1 1 "Tipo conto " + ITEM " |Conto" + ITEM "C|Cliente" + ITEM "F|Fornitore" + FLAGS "D" +END + +NUMBER P_GRUPPO 3 +BEGIN + PROMPT 26 1 "Gruppo " + FLAGS "D" +END + +NUMBER P_CONTO 3 +BEGIN + PROMPT 40 1 "Conto " + FLAGS "D" +END + +NUMBER P_SOTTOCONTO 6 +BEGIN + PROMPT 54 1 "Sottoconto " + FLAGS "D" +END + +STRING P_DESCR 50 +BEGIN + PROMPT 1 2 "Descrizione " + FLAGS "D" +END + +NUMBER P_RESIDUO 15 +BEGIN + PROMPT 1 3 "Residuo " + FLAGS "D" +END + +NUMBER P_ANNO 4 +BEGIN + PROMPT 1 4 "Anno " + FLAGS "A" +END + +STRING P_NUMERO 7 +BEGIN + PROMPT 26 4 "Numero " +END + +SPREADSHEET P_PARTITE 0 6 +BEGIN + PROMPT 0 5 "" + ITEM "Anno" + ITEM "Partita@7" + ITEM "Data doc.@10" + ITEM "Num doc.@7" + ITEM "Saldo@14" + ITEM "Documenti@14" + ITEM "Pagamenti@14" + ITEM "Altri importi@14" + ITEM "Descrizione@50" + FLAGS "D" +END + +SPREADSHEET P_SCADENZE 0 7 +BEGIN + PROMPT 0 11 "" + ITEM "Riga" + ITEM "Rata" + ITEM "Data doc.@10" + ITEM "Num. reg." + ITEM "Data reg.@10" + ITEM "Data scad." + ITEM "Importo Lire@14" + ITEM "Importo Valuta@14" + ITEM "Descrizione@50" + ITEM "Num. doc." + ITEM "Prot. IVA" + ITEM "Pagamento" + FLAGS "D" +END + +BOOLEAN P_SHOWALL +BEGIN + PROMPT 1 -1 "Mostra tutte le partite" +END + +BUTTON P_SCAMBIO 28 +BEGIN + PROMPT 40 -1 "Num. reg. <-> Num. doc." +END + +ENDPAGE + +ENDMASK + + + +PAGE "Sheet Partite" -1 -1 66 8 + +STRING 109 50 +BEGIN + PROMPT 1 1 "Descrizione " +END + +NUMBER 101 4 +BEGIN + PROMPT 1 2 "Anno " +END + +STRING 102 7 +BEGIN + PROMPT 1 3 "Partita " +END + +DATA 103 +BEGIN + PROMPT 1 4 "Data documento " +END + +STRING 104 7 +BEGIN + PROMPT 1 5 "Numero documento " +END + +STRING 106 14 +BEGIN + PROMPT 34 2 "Documenti " + FLAGS "R" +END + +STRING 107 14 +BEGIN + PROMPT 34 3 "Pagamenti " + FLAGS "R" +END + +STRING 108 14 +BEGIN + PROMPT 34 4 "Altri importi " + FLAGS "R" +END + +STRING 105 14 +BEGIN + PROMPT 34 5 "Saldo " + FLAGS "R" +END + +BUTTON DLG_CANCEL 10 2 +BEGIN + PROMPT -11 -1 "" +END + +ENDPAGE + +ENDMASK + + +PAGE "Sheet Scadenze" -1 -1 66 10 + +NUMBER 101 4 +BEGIN + PROMPT 1 1 "Numero riga " +END + +NUMBER 102 4 +BEGIN + PROMPT 30 1 "Numero rata " +END + +NUMBER 112 4 +BEGIN + PROMPT 1 2 "Riga pagamento " +END + +DATE 103 +BEGIN + PROMPT 30 2 "Data documento " +END + +NUMBER 104 5 +BEGIN + PROMPT 1 3 "Numero reg. " +END + +DATE 105 +BEGIN + PROMPT 30 3 "Data reg. " +END + +NUMBER 110 5 +BEGIN + PROMPT 1 4 "Numero doc. " +END + +NUMBER 111 5 +BEGIN + PROMPT 30 5 "Protocollo IVA " +END + +DATE 106 +BEGIN + PROMPT 30 4 "Data scad. " +END + +STRING 109 50 +BEGIN + PROMPT 1 6 "Descrizione " +END + +NUMBER 107 12 +BEGIN + PROMPT 1 7 "Importo Lire " +END + +NUMBER 108 12 2 +BEGIN + PROMPT 30 7 "Importo Valuta " + PICTURE ".2" +END + +BUTTON DLG_CANCEL 12 2 +BEGIN + PROMPT -12 -1 "" +END + +BUTTON 100 12 2 +BEGIN + PROMPT -22 -1 "~Pagamento" +END + + +ENDPAGE + +ENDMASK diff --git a/cg/cg2100s.uml b/cg/cg2100s.uml index 42be2a722..0ccc33607 100755 --- a/cg/cg2100s.uml +++ b/cg/cg2100s.uml @@ -1,4 +1,4 @@ -#include "cg2100.h" +#include "cg2100p.h" TOOLBAR "" 0 20 0 2 @@ -42,13 +42,20 @@ BEGIN FIELD NUMPART END -STRING S_RIGA 4 +NUMBER S_RIGA 4 BEGIN PROMPT 40 1 "Riga " - FLAGS "DR" + FLAGS "D" FIELD NRIGA END +NUMBER S_RATA 4 +BEGIN + PROMPT 60 1 "Rata " + FLAGS "D" + FIELD NRATA +END + STRING S_NUMDOC 7 BEGIN PROMPT 2 2 "Numero Documento " @@ -73,15 +80,9 @@ BEGIN FLAGS "D" END -NUMBER S_RATA 4 -BEGIN - PROMPT 2 4 "Rata " - FLAGS "DR" -END - DATE S_DATASCAD BEGIN - PROMPT 21 4 "Data " + PROMPT 20 4 "Data " FLAGS "D" END @@ -92,21 +93,21 @@ BEGIN FLAGS "DR" END -NUMBER S_IMPORTOVAL 15 2 +NUMBER S_IMPORTOVAL_SCAD 15 2 BEGIN - PROMPT 2 5 "Importo in valuta " + PROMPT 2 5 "Importo in valuta " PICTURE ".2" FLAGS "DR" END -NUMBER S_IMPORTO 15 +NUMBER S_IMPORTO_SCAD 15 BEGIN PROMPT 38 5 "Importo " PICTURE "." FLAGS "DR" END -LIST S_SEZIONE 6 +LIST S_SEZIONE_SCAD 6 BEGIN PROMPT 68 5 "" ITEM "A|Avere" @@ -114,75 +115,49 @@ BEGIN FLAGS "D" END - - GROUPBOX DLG_NULL 78 12 BEGIN PROMPT 1 7 "@BPagamento" END -NUMBER S_IMPORTOPAG 15 +NUMBER S_IMPORTO 15 BEGIN PROMPT 2 8 "Importo pagamento " PICTURE "." - FIELD IMPORTO - FLAGS "UR" + FLAGS "U" WARNING "Inserire un importo inferiore al residuo" + FIELD IMPORTO + MESSAGE EMPTY CLEAR,S_RITENUTE + MESSAGE ENABLE,S_RITENUTE +END + +NUMBER S_IMPORTOVAL 15 2 +BEGIN + PROMPT 2 9 "Importo in valuta " + PICTURE ".2" + FLAGS "U" + FIELD IMPORTOVAL END NUMBER S_RITENUTE 15 BEGIN PROMPT 38 8 "Ritenute professionali " PICTURE "." - FLAGS "UR" + FLAGS "U" FIELD RITENUTE END LIST S_SALDOACC 1 12 BEGIN - PROMPT 2 9 "Saldo " + PROMPT 2 10 "Saldo/Acc." ITEM "A|Acconto" ITEM "S|Saldo" - FIELD SALACC + FIELD ACCSAL END -DATE S_DATAPAG -BEGIN - PROMPT 38 9 "Data pagamento " - FIELD DATAREG -END - -STRING S_CODPAG 4 -BEGIN - PROMPT 2 10 "Pagamento " - FLAGS "UZ" - USE %CPG - INPUT CODTAB S_CODPAG - DISPLAY "Codice" CODTAB - DISPLAY "Descrizione@50" S0 - DISPLAY "Tipo" I0 - OUTPUT S_CODPAG CODTAB - OUTPUT S_DESPAG S0 - OUTPUT S_TIPOPAG I0 - FIELD CODPAG - CHECKTYPE REQUIRED -END - -STRING S_DESPAG 50 -BEGIN - PROMPT 24 10 "" - USE CPG KEY 2 - INPUT S0 S_DESPAG - DISPLAY "Descrizione@50" S0 - DISPLAY "Codice" CODTAB - DISPLAY "Tipo" I0 - COPY OUTPUT S_CODPAG - CHECKTYPE REQUIRED -END - LIST S_TIPOPAG 2 35 BEGIN - PROMPT 2 11 "Tipo pagamento " + PROMPT 27 10 "Tipo pagamento " ITEM "1|Rimessa Diretta" ITEM "2|Tratta" ITEM "3|Ricevuta Bancaria" @@ -195,7 +170,36 @@ BEGIN ITEM "10|Altro" FIELD TIPOPAG END - + +/* +STRING S_CODPAG 4 +BEGIN + PROMPT 2 11 "Pagamento " + FLAGS "UZ" + USE %CPG + INPUT CODTAB S_CODPAG + DISPLAY "Codice" CODTAB + DISPLAY "Descrizione@50" S0 + DISPLAY "Tipo" I0 + OUTPUT S_CODPAG CODTAB + OUTPUT S_DESPAG S0 + OUTPUT S_TIPOPAG I0 + CHECKTYPE REQUIRED +END + +STRING S_DESPAG 50 +BEGIN + PROMPT 24 11 "" + USE CPG KEY 2 + INPUT S0 S_DESPAG + DISPLAY "Descrizione@50" S0 + DISPLAY "Codice" CODTAB + DISPLAY "Tipo" I0 + COPY OUTPUT S_CODPAG + CHECKTYPE REQUIRED +END +*/ + TEXT DLG_NULL BEGIN PROMPT 2 12 "@bContropartita" @@ -280,7 +284,6 @@ BEGIN DISPLAY "Descrizione@50" S0 DISPLAY "Codice" CODTAB COPY OUTPUT S_CODDESC - FIELD DESCR END NUMBER S_VSABI 5 diff --git a/cg/cg2102.cpp b/cg/cg2102.cpp index 2ef8294c7..01ab58625 100755 --- a/cg/cg2102.cpp +++ b/cg/cg2102.cpp @@ -303,21 +303,23 @@ TImporto TPrimanota_application::get_cgs_imp(int n) } // Certified 90% -TImporto TPrimanota_application::add_cgs_imp(int n, const TImporto& imp) +bool TPrimanota_application::add_cgs_imp(int n, const TImporto& imp) { - TImporto tot(get_cgs_imp(n)); - tot.set(imp.sezione(), tot.valore() + imp.valore()); + TImporto tot; + tot = cgs().row(n); + tot += imp; set_cgs_imp(n, tot); - return tot; + return tot.is_zero();; } // Certified 90% -TImporto TPrimanota_application::sub_cgs_imp(int n, const real& imp) +bool TPrimanota_application::sub_cgs_imp(int n, const TImporto& imp) { - TImporto tot(get_cgs_imp(n)); - tot.set(tot.sezione(), tot.valore() - imp); + TImporto tot; + tot = cgs().row(n); + tot -= imp; set_cgs_imp(n, tot); - return tot; + return tot.is_zero(); } @@ -341,7 +343,7 @@ TImporto TPrimanota_application::real2imp(const real& r, char row_type) // Disabilita le celle della riga contabile n in base al suo tipo void TPrimanota_application::disable_cgs_cells(int n, char tipo) { - int last = 0; + int first = 0, last = 0; switch(tipo) { case 'A': // Abbuoni attivi @@ -355,6 +357,8 @@ void TPrimanota_application::disable_cgs_cells(int n, char tipo) case 'T': // Totale documento last = 3; break; + case 'K': // Riga cliente/fornitore per saldaconto + first = 2; case 'I': last = 7; // Imponibile break; @@ -366,7 +370,7 @@ void TPrimanota_application::disable_cgs_cells(int n, char tipo) if (last > 0) { TSheet_field& cg = cgs(); - for (int i = 0; i < last; i++) + for (int i = first; i < last; i++) cg.disable_cell(n, i); if (tipo == 'T' && !causale().corrispettivi()) { @@ -553,11 +557,12 @@ bool TPrimanota_application::cg_handler(TMask_field& f, KEY k) return f.error_box("La contropartita della riga %d non e' completa", i+1); empty = FALSE; - if (row_type(r) <= ' ' && app().iva() == nessuna_iva && app().is_saldaconto()) + const char tipo = row_type(r); + if ((tipo <= ' ' || tipo == 'K') && app().iva() == nessuna_iva && app().is_saldaconto()) { const long numreg = f.mask().get_long(F_NUMREG); const int currig = i+1; - const TImporto speso = app()._partite.importo_speso(numreg, currig); + const TImporto speso = app().partite().importo_speso(numreg, currig); if (importo != speso) { bool ok = yesno_box("L'importo dei pagamenti %c %s\ne' diverso dall'importo sulla riga %d.\n" @@ -565,6 +570,11 @@ bool TPrimanota_application::cg_handler(TMask_field& f, KEY k) if (ok) app().set_cgs_imp(i, speso); else return FALSE; } + if (tipo != 'K' && !speso.is_zero()) + { + r.add("K", -2); + app().disable_cgs_cells(i, 'K'); + } } } } @@ -993,13 +1003,17 @@ bool TPrimanota_application::iva_notify(TSheet_field& iva, int r, KEY k) int delimp = -1, deliva = -1; // Eventuali righe contabili da cancellare if (oldpos >= 0) // Se il conto esisteva anche prima ... { // sottrai il vecchio imponibile - const TImporto imp = app().sub_cgs_imp(oldpos, oldimp); - if (imp.is_zero()) delimp = oldpos; + TImporto i(app().get_cgs_imp(oldpos)); + i.valore() -= oldimp; + app().set_cgs_imp(oldpos, i); + if (i.is_zero()) delimp = oldpos; } if (oldposiva >= 0) // Se conto IVA esisteva anche prima ... { // sottrai la vecchia imposta - const TImporto imp = app().sub_cgs_imp(oldposiva, oldiva); - if (imp.is_zero()) deliva = oldposiva; + TImporto i(app().get_cgs_imp(oldposiva)); + i.valore() -= oldiva; + app().set_cgs_imp(oldposiva, i); + if (i.is_zero()) deliva = oldposiva; } real imponibile(row.get(0)); // Nuovo imponibile @@ -1043,8 +1057,8 @@ bool TPrimanota_application::iva_notify(TSheet_field& iva, int r, KEY k) else { TImporto val(app().real2imp(imponibile, 'I')); - val = app().add_cgs_imp(newpos, val); - if (val.valore().is_zero()) // Se la riga si e' azzerata ... + const bool empty = app().add_cgs_imp(newpos, val); + if (empty) // Se la riga si e' azzerata ... { // ... cancellala app().reset_cgs_row(newpos); newpos = -1; @@ -1072,11 +1086,11 @@ bool TPrimanota_application::iva_notify(TSheet_field& iva, int r, KEY k) } else { - TImporto val(app().real2imp(imposta, 'I')); - val = app().add_cgs_imp(newposiva, val); - if (val.is_zero()) // Se l'imposta si e' azzerata ... + const TImporto val(app().real2imp(imposta, 'I')); + const bool empty = app().add_cgs_imp(newposiva, val); + if (empty) // Se l'imposta si e' azzerata ... { - app().reset_cgs_row(newposiva); // ... cancellala + app().reset_cgs_row(newposiva); // ... cancellala newposiva = -1; } diff --git a/cg/cg2102.h b/cg/cg2102.h index 6e5e1e96d..99db3bb4b 100755 --- a/cg/cg2102.h +++ b/cg/cg2102.h @@ -152,20 +152,15 @@ protected: void set_saldaconto(bool b) { _is_saldaconto = b; } void fill_sheet(TMask& m) const; - void init_mask(TMask& m); - TSheet_field& cgs() const; - TSheet_field& ivas() const; - TSheet_field& pags() const; - TString_array& pag_rows() { return _pag_rows; } - static int bill2pos(const TBill& conto, char tipo); static TipoIVA reg2IVA(const char* registro, int anno); static TipoIVA cau2IVA(const char* causale, int anno); static int type2pos(char tipo); static const real& cod2IVA(const TMask& m); static real scorpora(real& imponibile, const real& percentuale); static bool detraibile(TToken_string& row); + static int bill2pos(const TBill& conto, char tipo); bool IVA2bill(const TCodiceIVA& iva, TBill& bill); int bill2contr(const TBill& c, char sezione) const; @@ -181,20 +176,19 @@ protected: TImporto real2imp(const real& r, char tipo); real totale_documento(); - void set_cgs_imp(int n, const TImporto& importo); - TImporto get_cgs_imp(int n); - TImporto add_cgs_imp(int n, const TImporto& importo); - TImporto sub_cgs_imp(int n, const real& imp); - void ivas_pack(); void cgs_pack(); bool ci_sono_importi() const; real calcola_saldo() const; real calcola_imp() const; - int set_cgs_row(int n, const TImporto& importo, TBill& conto, const char* desc, char tipo); - void disable_cgs_cells(int n, char tipo); void add_cgs_tot(TMask& m); + int set_cgs_row(int n, const TImporto& importo, TBill& conto, const char* desc, char tipo); + void set_cgs_imp(int n, const TImporto& importo); + TImporto get_cgs_imp(int n); + bool add_cgs_imp(int n, const TImporto& importo); + bool sub_cgs_imp(int n, const TImporto& importo); + void disable_cgs_cells(int n, char tipo); void add_cgs_rit(bool fisc); void generazione_righe_cg(int r); @@ -210,9 +204,6 @@ protected: void write_scadenze(const TMask& m); bool edit_partite(int riga); - bool edit_scadenze(const TBill& clifo, int anno, const char* num); - int nuovo_pagamento(TPartita& partita, int rata, int rmov, TRectype& part); - bool edit_pagamento(TPartita& partita, TRectype& part); bool notify_cgline_deletion(TPartita& partita, long nreg, int numrig); bool notify_cgline_deletion(int numrig); @@ -220,9 +211,20 @@ protected: long calcola_m770(int tipo_coll, real& spese, real& compenso, real& iva, real& ritfis); bool link_m770(); -public: - static TPrimanota_application& app() { return (TPrimanota_application&)main_app(); } +public: + TPartite_array& partite() { return _partite; } // Partite editate + int nuovo_pagamento(TPartita& p, int nriga, int rata, int rmov); + bool edit_pagamento(TPartita& p, int nriga, int nrata, int nrigp); + + TSheet_field& cgs() const; + TSheet_field& ivas() const; + TSheet_field& pags() const; + TString_array& pag_rows() { return _pag_rows; } + TPrimanota_application(); }; +inline TPrimanota_application& app() +{ return (TPrimanota_application&)main_app(); } + #endif diff --git a/cg/cg2104.cpp b/cg/cg2104.cpp index 90f1f6dce..0e70c6778 100755 --- a/cg/cg2104.cpp +++ b/cg/cg2104.cpp @@ -9,7 +9,6 @@ #include "cg2102.h" #include "cg2100.h" #include "cg21sld.h" -#include "cg2100p.h" #include #include @@ -276,9 +275,9 @@ bool TPrimanota_application::read_scadenze(TMask& m) { // cerca rata scadenza.zero(); - scadenza.put(PART_ANNO, anno); - scadenza.put(PART_NUMPART, numpart); - scadenza.put(PART_NRATA, i+1); + scadenza.put(SCAD_ANNO, anno); + scadenza.put(SCAD_NUMPART, numpart); + scadenza.put(SCAD_NRATA, i+1); if (scadenza.read() == NOERR) { @@ -450,609 +449,3 @@ void TPrimanota_application::write_scadenze(const TMask& m) } -/////////////////////////////////////////////////////////// -// Sheet partite -/////////////////////////////////////////////////////////// - -HIDDEN void add_importo(TToken_string& s, const TImporto& i) -{ - if (i.is_zero()) - s.add(""); - else - { - s.add(i.valore().string()); - s << ' ' << i.sezione(); - } -} - -HIDDEN bool partite_notify(TSheet_field& partite, int r, KEY k) -{ - if (k == K_TAB) - { - TMask& m = partite.mask(); - TSheet_field& scadenze = (TSheet_field&)m.field(P_SCADENZE); - scadenze.destroy(); - - const TBill zio(m.get_int(P_GRUPPO), m.get_int(P_CONTO), - m.get_long(P_SOTTOCONTO), m.get(P_TIPOC)[0]); - TToken_string& row = partite.row(r); - const int anno = row.get_int(0); - const TString16 num = row.get(); - m.set(P_ANNO, anno); // Aggiorna campi di ricerca - m.set(P_NUMERO, num); - - TPartita game(zio, anno, num); - TRecord_array& p = game.rows_array(); - const int lastr = p.last_row(); - for (int r = p.first_row(); r <= lastr; r++) if (p.exist(r)) - { - const TRiga_partite& riga = game.riga(r); - for (int ra = 1; ra <= riga.rate(); ra++) - { - const TRiga_scadenze& scad = riga.rata(ra); - TToken_string& row = scadenze.row(-1); - row.add(ra); - row.add(riga.get(PART_DATADOC)); - row.add(riga.get(PART_NREG)); - row.add(riga.get(PART_DATAREG)); - row.add(scad.get(SCAD_DATASCAD)); - row.add(scad.get(SCAD_IMPORTO)); - row.add(scad.get(SCAD_IMPORTOVAL)); - row.add(riga.get(PART_DESCR)); - row.add(riga.get(PART_NUMDOC)); - row.add(riga.get(PART_PROTIVA)); - - const TRecord_array& ap = scad.rows_array(); - const int lastp = ap.last_row(); - for (int pa = ap.first_row(); pa < lastp; pa++) if (ap.exist(pa)) - { - const TRectype& pag = ap.row(pa); - - TToken_string& row = scadenze.row(-1); - row.add(""); - row.add(riga.get(PART_DATADOC)); - row.add(riga.get(PART_DATAREG)); - row.add(scad.get(SCAD_DATASCAD)); - row.add(pag.get_real(SCAD_IMPORTO).string(0, 0)); - row.add(pag.get_real(SCAD_IMPORTOVAL).string(0, 2)); - row.add(riga.get(PART_DESCR)); - row.add(riga.get(PART_NUMDOC)); - row.add(riga.get(PART_PROTIVA)); - } - } - } - scadenze.force_update(); - } - - return TRUE; -} - -HIDDEN bool numpart_handler(TMask_field& f, KEY k) -{ - if (k == K_TAB && f.dirty()) - { - const TMask& m = f.mask(); - const int anno = m.get_int(P_ANNO); - const TString16 num = f.get(); - if (anno > 0 && num.not_empty()) - { - TSheet_field& sheet = (TSheet_field&)m.field(P_PARTITE); - for (int i = 0; i < sheet.items(); i++) - { - TToken_string& row = sheet.row(i); - if (anno == row.get_int(0)) // Se corrisponde l'anno e ... - if (num == row.get()) // corrisponde il numero partita ... - { - sheet.select(i); // Seleziona la partita - partite_notify(sheet, i, K_TAB); // ed esplodi le sue righe - break; - } - } - if (i >= sheet.items()) - f.warning_box("Partita inesistente"); - } - } - return TRUE; -} - -HIDDEN bool annopart_handler(TMask_field& f, KEY k) -{ - if (k == K_TAB && f.dirty() && f.get().not_empty()) - { - TMask_field& n = f.mask().field(P_NUMERO); - n.set_dirty(); - numpart_handler(f, k); - } - return TRUE; -} - - -HIDDEN bool scambio_handler(TMask_field& f, KEY k) -{ - const TMask& m = f.mask(); - if (k == K_SPACE && m.is_running()) - { - const TSheet_field& sheet = (TSheet_field&)m.field(P_SCADENZE); - sheet.swap_columns(103, 109); - sheet.swap_columns(104, 110); - } - return TRUE; -} - -bool TPrimanota_application::edit_partite(int riga) -{ - TToken_string& cgr = cgs().row(riga); - const TBill b(cgr, 2, 0x3); // Legge il conto della riga selezionata - - if (!b.ok()) return FALSE; - - begin_wait(); - - TMask mask("cg2100p"); // Inizializzazione maschera di selezione partite - - const char tipocf[2] = { b.tipo(), '\0' }; - mask.set(P_TIPOC, tipocf); - mask.set(P_GRUPPO, b.gruppo()); - mask.set(P_CONTO, b.conto()); - mask.set(P_SOTTOCONTO, b.sottoconto()); - mask.set(P_DESCR, ((TBill&)b).descrizione()); - - mask.set_handler(P_ANNO, annopart_handler); - mask.set_handler(P_NUMERO, numpart_handler); - mask.set_handler(P_SCAMBIO, scambio_handler); - - TSheet_field& sheet = (TSheet_field&)mask.field(P_PARTITE); - sheet.set_notify(partite_notify); - TString_array& a = sheet.rows_array(); - - TLocalisamfile partita(LF_PARTITE); - partita.zero(); - if (b.tipo() > ' ') // Ignora gruppo e conto dei clifo - { - partita.put(PART_TIPOCF, b.tipo()); - partita.put(PART_SOTTOCONTO, b.sottoconto()); - } - else b.put(partita.curr()); // Scrive completamente i conti normali - - const TRectype filter(partita.curr());// Record campione - - int ult, anno; // Anno ultima partita - TString16 last, num; // Ultimo numero partita e numero corrente - TString desc; // Descrizione prima partita del gruppo - TString16 numdoc; - TString16 datadoc; - - TImporto saldo; // Saldo ultima parita - TImporto documenti; // Documenti ultima parita - TImporto pagamenti; // Pagamenti ultima parita - TImporto importi; // Altri importi ultima parita - TToken_string r(80); - - const long curreg = curr_mask().get_long(F_NUMREG); // Numero registrazione - - for (int err = partita.read(_isgteq); err == NOERR && partita.curr() == filter; err = partita.next()) - { - anno = partita.get_int(PART_ANNO); - num = partita.get(PART_NUMPART); - - const int tipomov = partita.get_int(PART_TIPOMOV); - if (num == last && anno == ult) // Se la partita e' la stessa ... - { - const TImporto i(partita.get_char(PART_SEZ), partita.get_real(PART_IMPORTO)); - switch (tipomov) - { - case 1: - case 2: - documenti += i; - break; - case 3: - pagamenti += i; - break; - default: - importi += i; - break; - } - saldo += i; // ... incrementa totale - } - else - { - if (!saldo.is_zero()) // Se il saldo non e' nullo allora e' aperta - { - r.cut(0); - r.add(ult); - r.add(last); - r.add(datadoc); - r.add(numdoc); - add_importo(r, saldo); - add_importo(r, documenti); - add_importo(r, pagamenti); - add_importo(r, importi); - r.add(desc); - a.add(r); // Aggiunge partita alla lista - } - ult = anno; - last = num; - numdoc = partita.get(PART_NUMDOC); - datadoc = partita.get(PART_DATADOC); - desc = partita.get(PART_DESCR); - - saldo.set(partita.get_char(PART_SEZ), partita.get_real(PART_IMPORTO)); - switch (tipomov) - { - case 1: - case 2: - documenti = saldo; - pagamenti.set('D', ZERO); - importi.set('D', ZERO); - break; - case 3: - pagamenti = saldo; - documenti.set('D', ZERO); - importi.set('D', ZERO); - break; - default: - importi = saldo; - documenti.set('D', ZERO); - pagamenti.set('D', ZERO); - break; - } - } - } - - if (!saldo.is_zero()) // Aggiunge ultima partita se aperta - { - r.cut(0); - r.add(ult); - r.add(last); - r.add(datadoc); - r.add(numdoc); - add_importo(r, saldo); - add_importo(r, documenti); - add_importo(r, pagamenti); - add_importo(r, importi); - r.add(desc); - a.add(r); - } - - end_wait(); - - if (a.items() > 0) - { - sheet.force_update(); - mask.run(); - } - - return TRUE; -} - - -int TPrimanota_application::nuovo_pagamento(TPartita& partita, int rata, int rmov, TRectype& part) -{ -/* - CHECKD(rata >= 1 && rata <= partita.rate(), "Rata errata ", rata); - CHECKD(!partita.rata_pagata(rata), "Rata pagata ", rata); - - const int nriga = partita.righe(); - CHECKD(nriga > 0, "Riga partita errata ", nriga); - - part = partita.riga(1); - - // PART_ANNO viene preso dalla partita base - // PART_NUMPART viene preso dalla partita base - part.put(PART_NRIGA, nriga+1); // Riga di partita - - part.put(PART_TIPOMOV, causale().tipomov()); // Dati causale corrente - part.put(PART_CODCAUS, causale().codice()); - - part.put(PART_NREG, curr_mask().get(F_NUMREG)); // Numero operazione - part.put(PART_NUMRIG, rmov); // Riga su cui ho cliccato - - // Copia dati movimento corrente - part.put(PART_DATAREG, curr_mask().get(F_DATAREG)); - part.put(PART_DATADOC, curr_mask().get(F_DATADOC)); - part.put(PART_NUMDOC, curr_mask().get(F_NUMDOC)); - part.put(PART_DESCR, curr_mask().get(F_DESCR)); - - part.zero(PART_REG); - part.zero(PART_PROTIVA); - -// part.put(PART_SEZ, (partita.totale().sezione() == 'D') ? 'A' : 'D'); - part.zero(PART_IMPORTO); // Azzera importi vari - part.zero(PART_IMPOSTA); - part.zero(PART_SPESE); - - part.zero(PART_CODVAL); - part.zero(PART_CAMBIO); - part.zero(PART_IMPORTOVAL); - part.zero(PART_DATACAM); - - TString80 tmp; - - const TRectype& scadenza = partita.rata(rata); - tmp = scadenza.get(SCAD_CODPAG); - part.put(PART_CODPAG, tmp); - - tmp = scadenza.get(SCAD_TIPOPAG); - part.put(PART_TIPOPAG, tmp); - - int caus = 2; // Calcola riga causale per la contropartita in base al tipo pagamento - switch (atoi(tmp)) - { - case 2: // Tratta - case 7: // Tratta accettata - caus = 3; break; - case 3: // Ricevuta bancaria - caus = 4; break; - case 4: // Cessione - caus = 5; break; - case 5: // Paghero' - caus = 6; break; - case 6: // Fattura di credito - caus = 7; break; - case 1: // Rimessa - case 8: // Rapporti interbancari diretti - case 9: // Bonifico - default: - caus = 2; break; - } - - TBill bill; causale().bill(caus, bill); // Legge conto contropartita - if (bill.empty()) causale().bill(caus = 1, bill); - bill.put(part, TRUE); - - // PART_TIPOC viene preso dalla partita base - // PART_GRUPPO viene preso dalla partita base - // PART_CONTO viene preso dalla partita base - // PART_SOTTOCONTO viene preso dalla partita base - - bill.get(part); // Legge conto principale - if (bill.tipo() > ' ') // Se cliente o fornitore cerca sua banca - { - TRelation cliforel(LF_CLIFO); - cliforel.add(LF_CFVEN, "TIPOCF=TIPOCF|CODCF=CODCF"); - TRectype& clifo = cliforel.lfile().curr(); - - clifo.put(CLI_TIPOCF, bill.tipo()); - clifo.put(CLI_CODCF, bill.codclifo()); - const int err = cliforel.read(); - CHECK(err == NOERR, "Chiss'e' fregato il clifo"); - - tmp = clifo.get(CLI_CODABI); - part.put(PART_CODABI, tmp); - tmp = clifo.get(CLI_CODCAB); - part.put(PART_CODCAB, tmp); - tmp = cliforel.lfile(LF_CFVEN).get(CLI_CODAG); - part.put(PART_CODAG, tmp); - } - else - { - part.zero(PART_CODABI); - part.zero(PART_CODCAB); - part.zero(PART_CODAG); - } - - part.zero(PART_IMPTOTPAG); - part.zero(PART_SALACC); - part.zero(PART_RITENUTE); - - part.zero(PART_DATARIFPAG); - part.zero(PART_NUMRIFPAG); - part.zero(PART_CHIUSA); - - tmp = scadenza.get(SCAD_NRATA); - part.put(PART_NRATA, tmp); - - tmp = scadenza.get(SCAD_CODABIPR); - part.put(PART_CODABIPR, tmp); - - tmp = scadenza.get(SCAD_CODCABPR); - part.put(PART_CODCABPR, tmp); - - return nriga+1; -*/ - return 1; -} - - -// Edit scadenze relative all'anno/numero partita specificati -bool TPrimanota_application::edit_scadenze(const TBill& clifo, int anno, const char* num) -{ - TString caption; caption.format("Pagamenti della partita %s dell'anno %d", num, anno); - TArray_sheet a(-1, -1, 0, 0, caption, "Rata|Data@10|Dare@15R|Avere@15R|Descrizione@50|Riga", 0x8); - TPartita& partita = _partite.partita(clifo, anno, num); - - const long curreg = curr_mask().get_long(F_NUMREG); // Numero registrazione corrente - const int currig = cgs().selected()+1; // Numero riga corrente - - return FALSE; -} - - -static bool importopag_handler(TMask_field& f, KEY k) -{ - if (k == K_F8) - { - TMask& m = f.mask(); - f.set(m.get(S_IMPORTO)); - k = K_TAB; - } - - if (f.to_check(k)) - { - TMask& m = f.mask(); - real i(f.get()); - const real tot(m.get(S_IMPORTO)); - if (i > tot) - { - warning_box("Non e' possibile inserire un importo superiore a ", tot.string(".")); - i = tot; - f.set(i.string()); - } - if (i == tot) - m.set(S_SALDOACC, "S"); - } - return TRUE; -} - - -bool TPrimanota_application::edit_pagamento(TPartita& p, TRectype& part) -{ -/* - TMask m("cg2100s"); - m.set_handler(S_IMPORTOPAG, importopag_handler); - - TRelation rel(LF_PARTITE); // Working relation - TLocalisamfile& partita = rel.lfile(); - partita.curr() = part; - m.autoload(&rel); // Load current record on mask - - const TRectype& parbas = p.riga(1); - const int rata = part.get_int(PART_NRATA); - const TRectype& scaden = p.rata(rata); - - const real dapagare(scaden.get(SCAD_IMPORTO)); - const real pagato(scaden.get(SCAD_IMPORTOPAG)); - const real residuo = dapagare - pagato; - - // Dati del documento (fattura) che ha generato la scadenza - m.set(S_NUMDOC, parbas.get(PART_NUMDOC)); // Numero documento - m.set(S_DATADOC, parbas.get(PART_DATADOC)); // Data documento - m.set(S_NUMPROT, parbas.get(PART_PROTIVA)); // Protocollo IVA - m.set(S_DESCR, parbas.get(PART_DESCR)); // Descrizione documento - - // Dati della scadenza che ha generato la partita - m.set(S_RESIDUO, residuo.string()); // Residuo da pagare - m.set(S_DATASCAD, scaden.get(SCAD_DATASCAD)); // Data della scadenza - m.set(S_IMPORTO, dapagare.string()); // Importo della rata - m.set(S_IMPORTOVAL, scaden.get(SCAD_IMPORTOVAL)); // " in valuta - m.set(S_RATA, scaden.get(SCAD_NRATA)); - - const char sez = part.get_char(PART_SEZ); // Sezione importo e rituenute - const char controsez = sez == 'D' ? 'A' : 'D'; // Sezione opposta (contropartita) - - // Memorizza importi prima di eventuali variazioni - const real old_importo(part.get(PART_IMPORTO)); - const real old_ritenute(part.get(PART_RITENUTE)); - - const TBill old_conto(m.get_int(S_GRUPPO), m.get_int(S_CONTO), m.get_long(S_SOTTOCONTO)); - const int old_riga = old_conto.ok() ? bill2pos(old_conto, 'I') : -1; - - const KEY key = m.run(); - if (key == K_ENTER || key == K_DEL) - { - if (key == K_DEL) - { - m.reset(S_IMPORTOPAG); - m.reset(S_RITENUTE); - } - - m.autosave(&rel); - part = partita.curr(); - - if (old_riga >= 0) - sub_cgs_imp(old_riga, old_importo); - - // Importo della contropartita - const TImporto new_importo(controsez, part.get_real(PART_IMPORTO)); - if (!new_importo.is_zero()) - { - TBill new_conto; new_conto.get(part, TRUE); - const int riga = bill2pos(new_conto, 'I'); - if (riga < 0) - set_cgs_row(riga, new_importo, new_conto, part.get(PART_DESCR), 'I'); - else - add_cgs_imp(riga, new_importo); - } - - const real rit(part.get(PART_RITENUTE)); - const TImporto grow_ritenute(controsez, rit-old_ritenute); // Variazione ritenute fiscali - - if (!grow_ritenute.is_zero()) - { - const riga = type2pos('F'); - if (riga < 0) - { - TBill conto_rit; causale().bill(11, conto_rit); - set_cgs_row(riga, grow_ritenute, conto_rit, "", 'F'); - } - else add_cgs_imp(riga, grow_ritenute); - } - - if (key == K_ENTER) - p.add_riga(part); - else - p.remove_riga(part); - } - - return key != K_ESC; -*/ - return FALSE; -} - -bool TPrimanota_application::notify_cgline_deletion(TPartita& partita, long nreg, int numrig) -{ - bool found = FALSE; - const int riga_ritenute = type2pos('F'); - - for (int r = 1; r > 0; r--) - { - TRectype pag(partita.riga(r)); - - const long reg = pag.get_long(PART_NREG); - if (reg == nreg) // Se la registrazione corrisponde - { - if (numrig > 0) - { - const int num = pag.get_int(PART_NUMRIG); - if (num == numrig) // Se anche la riga corrisponde - { - const real ritenute(pag.get(PART_RITENUTE)); - if (!ritenute.is_zero()) - { - if (riga_ritenute >= 0) - sub_cgs_imp(riga_ritenute, ritenute); - else - error_box("Non esiste la riga delle ritenute di un pagamento della riga %d", numrig); - } - const real importo(pag.get(PART_IMPORTO)); - if (!importo.is_zero()) - { - TBill contro; contro.get(pag); - const int riga_contro = bill2pos(contro, 'I'); - if (riga_contro >= 0) - sub_cgs_imp(riga_contro, importo); - else - error_box("Non esiste la riga dell'importo di un pagamento della riga %d", numrig); - } -// partita.remove_riga(pag); - found = TRUE; - } - else - { - const int n = pag.get_int(PART_NUMRIG); - pag.put(PART_NUMRIG, n-1); -// partita.add_riga(pag); - } - } - else // numrig == 0 - { -// partita.remove_riga(pag); // Cancellazione pura e semplice - found = TRUE; // usata solo da ::remove - } - } // if reg == numreg - } - - return found; -} - -bool TPrimanota_application::notify_cgline_deletion(int numrig) -{ - bool found = FALSE; - const long nreg = curr_mask().get_long(F_NUMREG); - _partite.add_reg_num(nreg, 0); - - for (TPartita* game = _partite.first(); game; game = _partite.next()) - found |= notify_cgline_deletion(*game, nreg, numrig); - - return found; -} \ No newline at end of file diff --git a/cg/cg2105.cpp b/cg/cg2105.cpp new file mode 100755 index 000000000..b62f28999 --- /dev/null +++ b/cg/cg2105.cpp @@ -0,0 +1,665 @@ +#include "cg2102.h" // Applicazione di prima nota + +#include "cg2100.h" // Campi maschere prima nota +#include "cg2100p.h" // Campi maschere partite e pagamenti + +#include // Archivio clienti/fornitori +#include // Archivio partite +#include // Archivio scadenze +#include // Archivio pagamenti + +/////////////////////////////////////////////////////////// +// Maschera partite +/////////////////////////////////////////////////////////// + +class TGame_mask : public TMask +{ + const TBill _conto; // Conto fisso + +protected: + static bool annopart_handler(TMask_field& f, KEY k); + static bool numpart_handler(TMask_field& f, KEY k); + static bool partite_notify(TSheet_field& partite, int r, KEY k); + static bool show_all_handler(TMask_field& f, KEY k); + static bool scambio_handler(TMask_field& f, KEY k); + static bool edit_scadenza_handler(TMask_field& f, KEY k); + + void add_importo(TToken_string& s, const TImporto& i) const; + void fill_partite(bool all) const; + +public: + TSheet_field& partite() const { return (TSheet_field&)field(P_PARTITE); } + TSheet_field& scadenze() const { return (TSheet_field&)field(P_SCADENZE); } + const TBill& conto() const { return _conto; } + + TGame_mask(const TBill& bill); + virtual ~TGame_mask() {} +}; + +TGame_mask::TGame_mask(const TBill& bill) + : TMask("cg2100p"), _conto(bill) +{ + const char tipocf[2] = { bill.tipo(), '\0' }; + set(P_TIPOC, tipocf); + set(P_GRUPPO, bill.gruppo()); + set(P_CONTO, bill.conto()); + set(P_SOTTOCONTO, bill.sottoconto()); + set(P_DESCR, ((TBill&)bill).descrizione()); + + set_handler(P_ANNO, annopart_handler); + set_handler(P_NUMERO, numpart_handler); + set_handler(P_SHOWALL, show_all_handler); + set_handler(P_SCAMBIO, scambio_handler); + + partite().set_notify(partite_notify); + scadenze().sheet_mask().set_handler(100, edit_scadenza_handler); +} + +bool TGame_mask::annopart_handler(TMask_field& f, KEY k) +{ + if (k == K_TAB && f.dirty() && f.get().not_empty()) + { + TMask_field& n = f.mask().field(P_NUMERO); + n.set_dirty(); + numpart_handler(f, k); + } + return TRUE; +} + +bool TGame_mask::numpart_handler(TMask_field& f, KEY k) +{ + if (k == K_TAB && f.dirty()) + { + const TGame_mask& m = (const TGame_mask&)f.mask(); + + const int anno = m.get_int(P_ANNO); + const TString16 num = f.get(); + if (anno > 0 && num.not_empty()) + { + TSheet_field& sheet = m.partite(); + for (int i = 0; i < sheet.items(); i++) + { + TToken_string& row = sheet.row(i); + if (anno == row.get_int(0)) // Se corrisponde l'anno e ... + if (num == row.get()) // corrisponde il numero partita ... + { + sheet.select(i); // ... seleziona la partita + partite_notify(sheet, i, K_TAB); // ed esplodi le sue righe + break; + } + } + if (i >= sheet.items()) + f.warning_box("Partita inesistente"); + } + } + return TRUE; +} + +bool TGame_mask::show_all_handler(TMask_field& f, KEY k) +{ + if (k == K_SPACE) + { + const TGame_mask& gm = (const TGame_mask&)f.mask(); + const bool all = f.get().not_empty(); + gm.fill_partite(all); + } + return TRUE; +} + +bool TGame_mask::scambio_handler(TMask_field& f, KEY k) +{ + if (k == K_SPACE) + { + const TGame_mask& gm = (const TGame_mask&)f.mask(); + const TSheet_field& sheet = gm.scadenze(); + sheet.swap_columns(103, 109); + sheet.swap_columns(104, 110); + } + return TRUE; +} + +bool TGame_mask::partite_notify(TSheet_field& partite, int r, KEY k) +{ + if (k == K_TAB) + { + TGame_mask& gm = (TGame_mask&)partite.mask(); + TSheet_field& scadenze = gm.scadenze(); + scadenze.destroy(); + + const TBill& zio = gm.conto(); // Conto cliente/fornitore + TToken_string& row = partite.row(r); + const int anno = row.get_int(0); // Anno partita + const TString16 num = row.get(); // Numero partita + gm.set(P_ANNO, anno); // Aggiorna campi di ricerca + gm.set(P_NUMERO, num); + + TPartita* game = app().partite().exist(zio, anno, num); // Cerca la partita tra quelle editate + const bool should_delete_game = (game == NULL); // Ricorda di fare delete + if (should_delete_game) // Se non c'era ... + game = new TPartita(zio, anno, num); // ... creane una temporanea + + const int lastrow = game->last(); + for (int ri = game->first(); ri <= lastrow; ri = game->succ(ri)) + { + const TRiga_partite& riga = game->riga(ri); + for (int ra = 1; ra <= riga.rate(); ra++) + { + const TRiga_scadenze& scad = riga.rata(ra); + TToken_string& row = scadenze.row(-1); + row.add(ri); + row.add(ra); + row.add(riga.get(PART_DATADOC)); + row.add(riga.get(PART_NREG)); + row.add(riga.get(PART_DATAREG)); + row.add(scad.get(SCAD_DATASCAD)); + row.add(scad.get(SCAD_IMPORTO)); + row.add(scad.get_real(SCAD_IMPORTOVAL).string(0, 2)); + row.add(riga.get(PART_DESCR)); + row.add(riga.get(PART_NUMDOC)); + row.add(riga.get(PART_PROTIVA)); + + const TRecord_array& ap = scad.rows_array(); + const int lastp = ap.last_row(); + for (int pa = ap.first_row(); pa < lastp; pa++) if (ap.exist(pa)) + { + const TRiga_partite& rigp = game->riga(pa); + const TRectype& pag = ap.row(pa); + + TToken_string& row = scadenze.row(-1); + row.add(ri); + row.add(ra); + row.add(rigp.get(PART_DATADOC)); + row.add(rigp.get(PART_NREG)); + row.add(rigp.get(PART_DATAREG)); + row.add(scad.get(SCAD_DATASCAD)); + row.add(pag.get_real(SCAD_IMPORTO).string()); + row.add(pag.get_real(SCAD_IMPORTOVAL).string(0, 2)); + row.add(rigp.get(PART_DESCR)); + row.add(rigp.get(PART_NUMDOC)); + row.add(rigp.get(PART_PROTIVA)); + row.add(pa); + } + } + } + scadenze.force_update(); + if (should_delete_game) + delete game; + } + + return TRUE; +} + +bool TGame_mask::edit_scadenza_handler(TMask_field& f, KEY k) +{ + if (k == K_SPACE) + { + TMask& m = f.mask(); + TGame_mask& gm = (TGame_mask&)(m.get_sheet()->mask()); + + const TBill& bill = gm.conto(); + const int anno = gm.get_int(P_ANNO); + const TString16 numero = gm.get(P_NUMERO); + const int nriga = m.get_int(101); + const int nrata = m.get_int(102); + const int rmov = app().cgs().selected()+1; + + CHECK(nriga && nrata, "La riga della scadenza sembra vuota, ma tutti sanno che e' una balla!"); + + int nrigp = m.get_int(112); + if (nrigp == 0) + { + TPartita& game = app().partite().partita(bill, anno, numero); + nrigp = app().nuovo_pagamento(game, nriga, nrata, rmov); + if (nrigp < 1) + return f.error_box("La rata %d e' gia' stata pagata", nrata); + } + else + { + const TMask& cm = app().curr_mask(); + const long cur_reg = cm.get_long(F_NUMREG); + const long nreg = m.get_long(104); + if (cur_reg != nreg) + return f.error_box("Non si possono modificare pagamenti di movimenti diversi dal %ld", + cur_reg); + } + + TPartita& game = app().partite().partita(bill, anno, numero); + app().edit_pagamento(game, nriga, nrata, nrigp); + } + return TRUE; +} + + +void TGame_mask::add_importo(TToken_string& s, const TImporto& i) const +{ + if (i.is_zero()) + s.add(""); + else + { + s.add(i.valore().string()); + s << ' ' << i.sezione(); + } +} + +void TGame_mask::fill_partite(bool all) const +{ + TString_array& a = partite().rows_array(); + a.destroy(); + + app().begin_wait(); + + TLocalisamfile partita(LF_PARTITE); + partita.zero(); + if (conto().tipo() > ' ') // Ignora gruppo e conto dei clifo + { + partita.put(PART_TIPOCF, conto().tipo()); + partita.put(PART_SOTTOCONTO, conto().sottoconto()); + } + else conto().put(partita.curr()); // Scrive completamente i conti normali + + const TRectype filter(partita.curr()); // Record campione + + int ultimo_anno = 0, anno; // Anno ultima partita + TString16 ultimo_num, num; // Ultimo numero partita + TToken_string r(80); + + for (int err = partita.read(_isgteq); err == NOERR && partita.curr() == filter; err = partita.next()) + { + anno = partita.get_int(PART_ANNO); + num = partita.get(PART_NUMPART); + + if (ultimo_anno != anno && ultimo_num != num) + { + TPartita* game = NULL; + bool should_delete_game = FALSE; + if (app().partite().exist(conto(), anno, num)) + game = &app().partite().partita(conto(), anno, num); + else + { + game = new TPartita(conto(), anno, num); + should_delete_game = TRUE; + } + + TImporto saldo, doc, pag, imp; + game->calcola_saldo(saldo, doc, pag, imp); + + if (all || !saldo.is_zero()) + { + int riga_fatt = game->prima_fattura(); + if (riga_fatt < 1) riga_fatt = 1; // E' un anticipo + + const TRiga_partite& riga = game->riga(riga_fatt); + const TString16 data_doc = riga.get(PART_DATADOC); + const TString16 num_doc = riga.get(PART_NUMDOC); + const char*descr = riga.get(PART_DESCR); + + r.cut(0); + r.add(anno); + r.add(num); + r.add(data_doc); + r.add(num_doc); + add_importo(r, saldo); + add_importo(r, doc); + add_importo(r, pag); + add_importo(r, imp); + r.add(descr); + a.add(r); // Aggiunge partita alla lista + } + + if (should_delete_game) + delete game; + + ultimo_anno = anno; + ultimo_num = num; + } + } + + partite().force_update(); + if (a.items() > 0) + partite_notify(partite(), 0, K_TAB); + else + { + scadenze().destroy(); + scadenze().force_update(); + } + app().end_wait(); +} + +/////////////////////////////////////////////////////////// +// Metodi di prima nota +/////////////////////////////////////////////////////////// + +bool TPrimanota_application::edit_partite(int riga) +{ + TToken_string& cgr = cgs().row(riga); + const TBill b(cgr, 2, 0x3); // Legge il conto della riga selezionata + if (!b.ok()) return FALSE; + + TGame_mask mask(b); // Inizializzazione maschera di selezione partite + mask.run(); + + return TRUE; +} + + +int TPrimanota_application::nuovo_pagamento(TPartita& partita, int nriga, int rata, int rmov) +{ + const TRiga_partite& riga_part = partita.riga(nriga); + CHECKD(rata >= 1 && rata <= riga_part.rate(), "Rata errata ", rata); + + TRiga_scadenze& riga_scad = riga_part.rata(rata); + if (riga_scad.pagata()) + return -1; + + TBill conto; partita.conto(conto); // Legge conto principale + + const long numreg = curr_mask().get_long(F_NUMREG); + int nrigp = partita.mov2rig(numreg, rmov); // Cerca riga partita relativa alla riga rmov + + if (nrigp < 1) // Devo creare una nuova riga di partita + { + TRiga_partite& part = partita.nuova_riga(); // Creazione nuova riga vuota + nrigp = part.get_int(PART_NRIGA); + + // Copia dati movimento corrente + part.put(PART_NREG, numreg); // Numero operazione + part.put(PART_NUMRIG, rmov); // Riga su cui ho cliccato + part.put(PART_DATAREG, curr_mask().get(F_DATAREG)); + part.put(PART_DATADOC, curr_mask().get(F_DATADOC)); + part.put(PART_NUMDOC, curr_mask().get(F_NUMDOC)); + part.put(PART_DESCR, curr_mask().get(F_DESCR)); + part.put(PART_CAMBIO, curr_mask().get(S_CAMBIO)); + part.put(PART_DATACAM, curr_mask().get(S_DATACAMBIO)); + + // Copia dati causale corrente + const int tipomov = causale().tipomov(); + part.put(PART_TIPOMOV, tipomov); + part.put(PART_CODCAUS, causale().codice()); + const TRegistro& reg = causale().reg(); + part.put(PART_REG, reg.name()); + part.put(PART_PROTIVA, reg.protocol()); + + // Complesso algoritmo per calcolare la sezione di una nuova riga partita + char sezione = ' '; // Sezione nulla + TBill bill; causale().bill(1, bill); // Legge primo conto causale + if (bill.tipo() == conto.tipo()) // Se il tipo coincide ... + sezione = causale().sezione(1); // ... usa la sezione della causale + + if (sezione <= ' ') // Se non c'e' la sezione bell'e' ch'e' pronta + { + if (tipomov == 1 || tipomov == 5) // calcola in base al tipo movimento e + sezione = (conto.tipo() == 'C') ? 'D' : 'A'; // al tipo cliente/fornitore + else + sezione = (conto.tipo() == 'C') ? 'A' : 'D'; + + if (bill.tipo() != conto.tipo()) // Compensazioni + sezione = (sezione == 'D') ? 'A' : 'D'; // scambia segno + } + part.put(PART_SEZ, sezione); // Memorizza solo la sezione (importi nulli) + } + + TRectype& pagamento = riga_scad.row(nrigp, TRUE); // Crea nuovo pagamento + + int caus = 2; // Calcola riga causale per la contropartita in base al tipo pagamento + switch (riga_scad.get_int(SCAD_TIPOPAG)) + { + case 2: // Tratta + case 7: // Tratta accettata + caus = 3; break; + case 3: // Ricevuta bancaria + caus = 4; break; + case 4: // Cessione + caus = 5; break; + case 5: // Paghero' + caus = 6; break; + case 6: // Fattura di credito + caus = 7; break; + case 1: // Rimessa + case 8: // Rapporti interbancari diretti + case 9: // Bonifico + default: + caus = 2; break; + } + + TBill contro; causale().bill(caus, contro); // Legge conto contropartita + if (contro.empty()) // Se non specificato ... + causale().bill(caus = 1, contro); // ... prende il primo + contro.put(pagamento, TRUE); // Scrive conto contropartita + + if (conto.tipo() > ' ') // Se cliente o fornitore cerca sua banca + { + TRelation cliforel(LF_CLIFO); + cliforel.add(LF_CFVEN, "TIPOCF=TIPOCF|CODCF=CODCF"); + TRectype& clifo = cliforel.lfile().curr(); + + clifo.put(CLI_TIPOCF, conto.tipo()); + clifo.put(CLI_CODCF, conto.codclifo()); + const int err = cliforel.read(); + CHECK(err == NOERR, "Chiss'e' fregato il clifo"); + + pagamento.put(PAGSCA_CODABI, clifo.get(CLI_CODABI)); + pagamento.put(PAGSCA_CODCAB, clifo.get(CLI_CODCAB)); + pagamento.put(PAGSCA_CODAG, cliforel.lfile(LF_CFVEN).get(CLI_CODAG)); + } + pagamento.put(PAGSCA_CODABIPR, riga_scad.get(SCAD_CODABIPR)); + pagamento.put(PAGSCA_CODCABPR, riga_scad.get(SCAD_CODCABPR)); + + return nrigp; +} + +HIDDEN bool importo_handler(TMask_field& f, KEY k) +{ + if (k == K_F8) + { + TMask& m = f.mask(); + f.set(m.get(S_IMPORTO)); + k = K_TAB; + } + + if (f.to_check(k)) + { + TMask& m = f.mask(); + real i(f.get()); + const real tot(m.get(S_IMPORTO)); + if (i > tot) + { + warning_box("Non e' possibile inserire un importo superiore a ", tot.string(".")); + i = tot; + f.set(i.string()); + } + if (i == tot) + m.set(S_SALDOACC, "S"); + } + return TRUE; +} + + +bool TPrimanota_application::edit_pagamento(TPartita& p, int nriga, int nrata, int nrigp) +{ + TMask m("cg2100s"); + m.set_handler(S_IMPORTO, importo_handler); + + const TRiga_partite& parbas = p.riga(nriga); + TRiga_scadenze& scaden = parbas.rata(nrata); + const TRectype& oldpag = scaden.row(nrigp); + TRiga_partite& somma = p.riga(nrigp); + + const bool in_valuta = scaden.get(SCAD_CODVAL).not_empty(); + m.show(S_IMPORTOVAL_SCAD, in_valuta); + m.show(S_IMPORTOVAL, in_valuta); + + TRelation rel(LF_PAGSCA); // Working relation + rel.lfile().curr() = oldpag; + m.autoload(&rel); // Load current record on mask + + m.set(S_DESCAGG, somma.get(PART_DESCR)); + + // Dati del documento (fattura) che ha generato la scadenza + m.set(S_NUMDOC, parbas.get(PART_NUMDOC)); // Numero documento + m.set(S_DATADOC, parbas.get(PART_DATADOC)); // Data documento + m.set(S_NUMPROT, parbas.get(PART_PROTIVA)); // Protocollo IVA + m.set(S_DESCR, parbas.get(PART_DESCR)); // Descrizione documento + + // Dati della scadenza che ha generato la partita + TReal_field& residuo = (TReal_field&)m.field(S_RESIDUO); + residuo.set_decimals(in_valuta ? 2 : 0); + residuo.set(scaden.residuo().string()); // Residuo da pagare + m.set(S_DATASCAD, scaden.get(SCAD_DATASCAD)); // Data della scadenza + m.set(S_SEZIONE_SCAD, parbas.get(PART_SEZ)); // Sezione della rata + m.set(S_RATA, scaden.get(SCAD_NRATA)); + m.set(S_IMPORTO_SCAD, scaden.get(SCAD_IMPORTO)); // Importo della rata + m.set(S_IMPORTOVAL_SCAD, scaden.get(SCAD_IMPORTOVAL)); // Importo in valuta + + const char sez = parbas.get_char(PART_SEZ); // Sezione importo e rituenute + const char controsez = sez == 'D' ? 'A' : 'D'; // Sezione opposta (contropartita) + + // Memorizza importi prima di eventuali variazioni + const TImporto old_importo(controsez, real(m.get(S_IMPORTO))); + const TImporto old_ritenute(controsez, real(m.get(S_RITENUTE))); + + const TBill old_conto(m.get_int(S_GRUPPO), m.get_int(S_CONTO), m.get_long(S_SOTTOCONTO)); + const int old_riga = old_conto.ok() ? bill2pos(old_conto, 'I') : -1; + + const KEY key = m.run(); + if (key == K_ENTER || key == K_DEL) + { + if (key == K_DEL) + { + m.reset(S_IMPORTO); + m.reset(S_IMPORTOVAL); + m.reset(S_RITENUTE); + } + else + { + somma.put(PART_DESCR, m.get(S_DESCAGG)); // Aggiorna descrizione (comune ai pagamenti) + } + + m.autosave(&rel); + const TRectype& paga = rel.lfile().curr(); + + const TImporto new_importo(controsez, paga.get_real(PART_IMPORTO)); + if (old_importo != new_importo) + { + if (old_riga >= 0) + sub_cgs_imp(old_riga, old_importo); + + // Importo della contropartita + if (!new_importo.is_zero()) + { + TBill new_conto; new_conto.get(paga, TRUE); + const int riga = bill2pos(new_conto, 'I'); + if (riga < 0) + set_cgs_row(riga, new_importo, new_conto, m.get(S_DESCAGG), 'I'); + else + add_cgs_imp(riga, new_importo); + } + } + + const real rit(m.get(S_RITENUTE)); // Valore ritenute fiscali + const TImporto grow_ritenute(controsez, rit-old_ritenute.valore()); + if (!grow_ritenute.is_zero()) + { + const riga = type2pos('F'); + if (riga < 0) + { + TBill conto_rit; causale().bill(11, conto_rit); + set_cgs_row(riga, grow_ritenute, conto_rit, "", 'F'); + } + else + add_cgs_imp(riga, grow_ritenute); + } + + char old_ap, new_ap; + TImporto old_abbuono, new_abbuono, old_diffcam, new_diffcam; + const bool empty = p.modifica_pagamento(paga, + old_ap, old_abbuono, new_abbuono, + new_ap, new_abbuono, new_diffcam); + + // Se c'e' differenza negli abbuoni + if (old_abbuono != new_abbuono || old_ap != new_ap) + { + const int riga_contabile = app().cgs().selected(); + if (old_ap != ' ') // Se c'era un abbuono ... + { + const int riga_abb = type2pos(old_ap); + CHECK(riga_abb >= 0, "Chiss'e' fregato gli abbuoni?"); + sub_cgs_imp(riga_abb, old_abbuono); + + // Sottrae l'abbuono con la sezione invertita dalla riga contabile + add_cgs_imp(riga_contabile, old_abbuono); + } + if (new_ap != ' ') // Se ci sono abbuoni + { + const riga_abb = type2pos(new_ap); + if (riga_abb < 0) + { + TBill conto_abb; causale().bill(new_ap == 'A' ? 9 : 8, conto_abb); + app().set_cgs_row(riga_abb, new_abbuono, conto_abb, "", new_ap); + } + else + add_cgs_imp(riga_abb, new_abbuono); + sub_cgs_imp(riga_contabile, new_abbuono); // Aggiunge l'abbuono con la sezione invertita + } + } + + // Se c'e' variazione nella differenza cambi + if (old_diffcam != new_diffcam) + { + const int riga_diffcam = type2pos('C'); + if (!old_diffcam.is_zero()) // Se c'era una differenza cambi + { + CHECK(riga_diffcam >= 0, "Chiss'e' fregato la differenza cambi?"); + sub_cgs_imp(riga_diffcam, old_diffcam); + } + if (!new_diffcam.is_zero()) + { + if (riga_diffcam < 0) + { + TBill conto_diffcam; causale().bill(12, conto_diffcam); + set_cgs_row(riga_diffcam, new_diffcam, conto_diffcam, "", 'C'); + } + else + add_cgs_imp(riga_diffcam, new_diffcam); + } + } + } + + return key != K_ESC; +} + +bool TPrimanota_application::notify_cgline_deletion(TPartita& partita, long nreg, int numrig) +{ + bool found = FALSE; + const int riga_ritenute = type2pos('F'); + + for (int r = partita.last(); r > 0; r = partita.pred(r)) + { + TRiga_partite& part = partita.riga(r); + const long reg = part.get_long(PART_NREG); + if (reg == nreg) // Se la registrazione corrisponde + { + const int num = part.get_int(PART_NUMRIG); + if (numrig > 0) + { + } + else // numrig == 0 + { + found = TRUE; // usata solo da ::remove + } + } + } + + return found; +} + +bool TPrimanota_application::notify_cgline_deletion(int numrig) +{ + bool found = FALSE; + const long nreg = curr_mask().get_long(F_NUMREG); + _partite.add_reg_num(nreg, 0); + + for (TPartita* game = _partite.first(); game; game = _partite.next()) + found |= notify_cgline_deletion(*game, nreg, numrig); + + return found; +} \ No newline at end of file diff --git a/cg/cglib02.cpp b/cg/cglib02.cpp index c39e68e10..e39247963 100755 --- a/cg/cglib02.cpp +++ b/cg/cglib02.cpp @@ -251,7 +251,7 @@ void TSaldo_agg::registra() const TImporto avere('A', saldi.get_real(SLD_PAVERE)); sf += dare; sf += avere; - sf.normalize(); + sf.normalize(+1); // Rendi sempre positivo tcon.saldo_finale() = sf; } } diff --git a/cg/pagament.cpp b/cg/pagament.cpp index 00be71abb..0cef7a104 100755 --- a/cg/pagament.cpp +++ b/cg/pagament.cpp @@ -3,8 +3,9 @@ #include "pagament.h" #include +#include #include - +#include int TPagamento::_rata_ifield(int n, int f) const { @@ -1199,28 +1200,234 @@ int TTree_rectype::remove(TBaseisamfile& f) return err; } + /////////////////////////////////////////////////////////// // TRiga_scadenze /////////////////////////////////////////////////////////// -TRiga_scadenze::TRiga_scadenze() - : TTree_rectype(LF_SCADENZE, LF_PAGSCA, "NRIGP") +TRiga_scadenze::TRiga_scadenze(TRiga_partite* riga) + : TTree_rectype(LF_SCADENZE, LF_PAGSCA, "NRIGP"), _riga(riga) { zero(); } +TRiga_scadenze::TRiga_scadenze(const TRiga_scadenze& s) + : TTree_rectype(s), _riga(s._riga) +{ + zero(); +} + +TPartita& TRiga_scadenze::partita() const +{ + return riga().partita(); +} + + +// Controlla se la rata e' in valuta +bool TRiga_scadenze::in_valuta() const +{ + return get(SCAD_CODVAL).not_empty(); +} + +// Controlla se la rata e' stata completamente pagata +int TRiga_scadenze::pagata() const +{ + const TRecord_array& a = rows_array(); + for (int p = a.last_row(); p > 0; p = a.pred_row(p)) + { + const TRectype& pag = a.row(p); + if (pag.get_char("ACCSAL") == 'S') + return p; + } + return 0; +} + +// Calcola il totale dei pagamenti (eventualmente in valuta) +TImporto TRiga_scadenze::importo_pagato(bool val) const +{ + const TPartita& game = partita(); + const char* imp_field = in_valuta() && val ? PAGSCA_IMPORTOVAL : PAGSCA_IMPORTO; + TImporto totale; + const TRecord_array& a = rows_array(); + for (int p = a.last_row(); p > 0; p = a.pred_row(p)) + { + const TRectype& pag = a.row(p); // Riga pagamento + const TRiga_partite& sum = game.riga(p); // Riga partite + const TImporto imp(sum.get_char(PART_SEZ), pag.get_real(imp_field)); + totale += imp; + } + + return totale; +} + +// Calcola l'importo da pagare (eventualmente in valuta) +TImporto TRiga_scadenze::importo_da_pagare(bool val) const +{ + const char* imp_field = in_valuta() && val ? PAGSCA_IMPORTOVAL : PAGSCA_IMPORTO; + const TRiga_partite& r = riga(); // Riga fattura + const TImporto totale(r.get_char(PART_SEZ), get_real(imp_field)); + return totale; +} + +// Calcola l'abbuono della rata e ritorna il suo tipo: +// 'A' abbuono attivo; 'P' abbuono passivo +// La sezione dell'abbuono calcolato e' quella della riga contabile in cui finira' +char TRiga_scadenze::calcola_abbuono(TImporto& abbuono, bool val) const +{ + bool ap = ' '; + if (pagata()) + { + abbuono = importo_da_pagare(TRUE); + abbuono += importo_pagato(TRUE); + + const int sign = abbuono.valore().sign(); + if (sign != 0) + { + if (sign > 0) + ap = abbuono.sezione() == 'D' ? 'P' : 'A'; + else + ap = abbuono.sezione() == 'D' ? 'A' : 'P'; + } + + if (val && in_valuta()) + { + abbuono.valore() *= get_real(SCAD_CAMBIO); + abbuono.valore().round(); + } + } + else + abbuono.valore() = ZERO; + + return ap; +} + +// Calcola la differenza cambi con la sezione da mettere nella riga contabile corrispondente +TImporto TRiga_scadenze::calcola_differenza_cambio(bool update) +{ + TImporto diffcam; + const int riga_saldo = pagata(); + if (riga_saldo > 0) + { + TRectype& pag = row(riga_saldo, FALSE); + const TRiga_partite& sum = partita().riga(riga_saldo); + const char sez = sum.sezione(); + + if (update) + { + diffcam = importo_da_pagare(FALSE); + diffcam += importo_pagato(FALSE); + + real a = pag.get_real(PAGSCA_ABBUONI); + if (in_valuta()) + { + a *= get_real(SCAD_CAMBIO); + a.round(); + } + + const TImporto abb_lit(sez, a); + diffcam += abb_lit; + diffcam.normalize(sez); + pag.put(PAGSCA_DIFFCAM, diffcam.valore()); + } + else + { + diffcam.set(sez, pag.get_real(PAGSCA_DIFFCAM)); + } + } + return diffcam; +} + +real TRiga_scadenze::residuo() const +{ + const char* imp_field = get(SCAD_CODVAL).not_empty() ? SCAD_IMPORTOVAL : SCAD_IMPORTO; + const real da_pagare(get(imp_field)); + const real pagato(get(SCAD_IMPORTOPAG)); + const real residuo = da_pagare - pagato; + return residuo; +} + + +bool TRiga_scadenze::modifica_pagamento(const TRectype& new_pag, + char& old_ap, TImporto& old_abb, TImporto& old_diffcam, + char& new_ap, TImporto& new_abb, TImporto& new_diffcam) +{ + const int nrigp = new_pag.get_int(PAGSCA_NRIGP); + const TRectype old_pag(row(nrigp)); + TRiga_partite& sum = partita().riga(nrigp); + + old_ap = calcola_abbuono(old_abb, FALSE); + old_diffcam = calcola_differenza_cambio(FALSE); + + const char* imp_field = get(SCAD_CODVAL).not_empty() ? PAGSCA_IMPORTOVAL : PAGSCA_IMPORTO; + const real importo(new_pag.get(imp_field)); + const bool empty = importo.is_zero(); + if (empty) + rows_array().destroy_row(nrigp); + else + row(nrigp, FALSE) = new_pag; + + TImporto abbuono; + new_ap = calcola_abbuono(abbuono, TRUE); // Calcolo abbuono in valuta + + TImporto imp(abbuono); imp.swap_section(); + imp.normalize(sum.sezione()); + if (new_ap != ' ') + { + CHECK(nrigp == pagata(), "Aggiornamento abbuoni inconsistente"); + TRectype& pag = row(nrigp, FALSE); + pag.put(PAGSCA_ABBUONI, imp.valore()); + + new_abb = abbuono; + if (in_valuta()) + { + new_abb.valore() *= get_real(SCAD_CAMBIO); + new_abb.valore().round(); + } + } + else + new_abb.valore() = ZERO; + + if (old_abb != new_abb) + { + const TImporto old(sum.sezione(), old_pag.get_real(PART_ABBUONI)); + TImporto abbuoni(sum.get_char(PART_SEZABB), sum.get_real(PART_ABBUONI)); + abbuoni -= old; + abbuoni += imp; + abbuoni.normalize(); + sum.put(PART_SEZABB, abbuoni.sezione()); + sum.put(PART_ABBUONI, abbuoni.valore()); + } + + new_diffcam = calcola_differenza_cambio(TRUE); + if (old_diffcam != new_diffcam) + { + TImporto tot_dc(sum.get_char(PART_SEZDIFCAM), sum.get_real(PART_DIFFCAM)); + tot_dc -= old_diffcam; + tot_dc += new_diffcam; + tot_dc.normalize(); + sum.put(PART_SEZDIFCAM, tot_dc.sezione()); + sum.put(PART_DIFFCAM, tot_dc.valore()); + } + + sum.update(old_pag, new_pag, PART_IMPORTO); + sum.update(old_pag, new_pag, PART_IMPORTOVAL); + sum.update(old_pag, new_pag, PART_RITENUTE); + + return empty; +} + /////////////////////////////////////////////////////////// // TRiga_partite /////////////////////////////////////////////////////////// -TRiga_partite::TRiga_partite() - : TTree_rectype(LF_PARTITE, LF_SCADENZE, "NRATA") +TRiga_partite::TRiga_partite(TPartita* game) + : TTree_rectype(LF_PARTITE, LF_SCADENZE, "NRATA"), _partita(game) { zero(); } TRiga_partite::TRiga_partite(const TRiga_partite& r) - : TTree_rectype(r) + : TTree_rectype(r), _partita(r._partita) {} @@ -1229,12 +1436,12 @@ int TRiga_partite::read(TBaseisamfile& f, word op) int err = TRectype::read(f, op); if (err == NOERR && get_int(PART_TIPOMOV) == 1) { - TRiga_scadenze* s = new TRiga_scadenze; + TRiga_scadenze* s = new TRiga_scadenze(this); copy_key_to_row(*s); err = _recarr.read(s); // Deve esistere almento una scadenza #ifdef DBG if (err != NOERR) - yesnofatal_box("Riga di partite senza nessuna scadenza"); + yesnofatal_box("Riga di fattura senza nessuna scadenza"); #endif } else @@ -1242,30 +1449,19 @@ int TRiga_partite::read(TBaseisamfile& f, word op) return err; } -TObject* TRiga_partite::dup() const -{ - return new TRiga_partite(*this); -} - -int TRiga_partite::add_rata(const TRectype& r) -{ - return 1; -} - int TRiga_partite::ultimo_pagamento(int r) const { const TRiga_scadenze& s = rata(r); return s.rows_array().last_row(); } -// Controlla se la rata r e' stata completamente pagata -bool TRiga_partite::rata_pagata(int r) const +bool TRiga_partite::update(const TRectype& vec, const TRectype& nuo, const char* field) { - const TRiga_scadenze& scad = rata(r); - real importo(scad.get(SCAD_IMPORTO)); - importo -= scad.get_real(SCAD_IMPORTOPAG); - const bool pagata = importo.is_zero(); - return pagata; + real totale = get_real(field); + totale -= vec.get_real(field); + totale += nuo.get_real(field); + put(field, totale); + return !totale.is_zero(); } @@ -1279,40 +1475,14 @@ TPartita::TPartita(const TBill& clifo, int anno, const char* num) read(clifo, anno, num); } -int TPartita::add_riga(const TRiga_partite& r) -{ - CHECK(r.num() == LF_PARTITE, "Tipo record errato"); - - const char sez = r.get_char(PART_SEZ); - const real val = r.get_real(PART_IMPORTO); - const TImporto imp(sez, val); - - TImporto grow(imp); - const int n = r.get_int(PART_NRIGA); - CHECK(n > 0, "Numero riga nullo"); - if (n <= _part.last_row()) - { - const TRectype& oldrow = riga(n); - const char osez = oldrow.get_char(PART_SEZ); - const real oval = oldrow.get_real(PART_IMPORTO); - const TImporto old(osez, oval); - grow -= old; - } - - return _part.add_row(r); -} - -void TPartita::remove_riga(TRiga_partite& z) -{ - z.zero(PART_IMPORTO); - add_riga(z); - _part.destroy_row(z, TRUE); -} +TPartita::TPartita() + : _part(LF_PARTITE, PART_NRIGA), _unassigned(LF_PAGSCA, "NRIGP") +{} // Costruisce le righe della partita bool TPartita::read(const TBill& clifo, int anno, const char* num) { - TRiga_partite* partita = new TRiga_partite; // Record campione della partita + TRiga_partite* partita = new TRiga_partite(this); // Record campione della partita partita->put(PART_TIPOCF, clifo.tipo()); // Tipo clifo if (clifo.tipo() <= ' ') { @@ -1332,8 +1502,8 @@ bool TPartita::read(const TBill& clifo, int anno, const char* num) unas.put(PART_SOTTOCONTO, partita->get(PART_SOTTOCONTO)); unas.put(PART_ANNO, partita->get(PART_ANNO)); unas.put(PART_NUMPART, partita->get(PART_NUMPART)); - unas.put(PART_NRIGA, 9999); // Numeri magici di non assegamento - unas.put(SCAD_NRATA, 9999); + unas.put(PART_NRIGA, 0); // Numeri magici di non assegamento + unas.put(SCAD_NRATA, 0); _unassigned.read(unas); return ok(); @@ -1354,12 +1524,11 @@ bool TPartita::write(bool re) return ok; } - TImporto TPartita::importo_speso(long nreg, int numrig) const { TImporto imp; - for (int r = _part.last_row(); r > 0; r--) + for (int r = _part.last_row(); r > 0; r = pred(r)) { const TRectype& pag = riga(r); @@ -1381,7 +1550,7 @@ TImporto TPartita::importo_speso(long nreg, int numrig) const void TPartita::update_reg_num(long nreg, const TRectype& mov) { - for (int r = _part.last_row(); r > 0; r--) + for (int r = _part.last_row(); r > 0; r = pred(r)) { TRectype& pag = _part.row(r, FALSE); @@ -1396,6 +1565,115 @@ void TPartita::update_reg_num(long nreg, const TRectype& mov) } } +// Calcola la riga di movimento relativa a una riga partita +int TPartita::rig2mov(int rp) const +{ + const TRiga_partite& r = riga(rp); + return r.get_int(PART_NUMRIG); +} + +// Calcola la riga di partita relativa a una riga movimento +int TPartita::mov2rig(long numreg, int rm) const +{ + for (int r = _part.last_row(); r > 0; r = pred(r)) + { + const TRiga_partite& row = riga(r); + if (row.get_long(PART_NREG) == numreg && row.get_int(PART_NUMRIG) == rm) + return r; + } + return -1; +} + +// Trova la prima riga della partita contenente una fattura +int TPartita::prima_fattura() const +{ + const int lastrow = last(); + for (int r = first(); r <= lastrow; r = succ(r)) + { + const TRiga_partite& row = riga(r); + const int tipomov = row.get_int(PART_TIPOMOV); + if (tipomov == 1 || tipomov == 2) + return r; + } + return -1; +} + +void TPartita::calcola_saldo(TImporto& saldo, TImporto& doc, TImporto& pag, TImporto& imp) const +{ + doc = pag = imp = TImporto('D', ZERO); + + for (int r = _part.last_row(); r > 0; r = pred(r)) + { + const TRiga_partite& row = riga(r); + TImporto i(row.get_char(PART_SEZ), row.get_real(PART_IMPORTO)); + switch (row.get_int(PART_TIPOMOV)) + { + case 1: + case 2: + doc += i; // documenti + break; + case 3: + pag += i; // pagamenti + break; + default: + imp += i; // altri importi + break; + } + + i.set(row.get_char(PART_SEZ), row.get_real(PART_ABBUONI)); + imp += i; + + i.set(row.get_char(PART_SEZ), row.get_real(PART_DIFFCAM)); + imp += i; + } + + saldo = doc; + saldo += pag; + saldo += imp; +} + + +bool TPartita::utilizzata(int nrigp) const +{ + for (int p = _part.last_row(); p > 0; p = pred(p)) + { + const TRiga_partite& fatt = riga(p); + const int tipomov = fatt.get_int(PART_TIPOMOV); + if (tipomov == 1) + { + for (int r = fatt.rate(); r > 0; r--) + { + const TRiga_scadenze& scad = fatt.rata(r); + if (scad.rows_array().exist(nrigp)) + return TRUE; + } + } + } + return FALSE; +} + +bool TPartita::modifica_pagamento(const TRectype& new_pag, + char& old_ap, TImporto& old_abb, TImporto& old_diffcam, + char& new_ap, TImporto& new_abb, TImporto& new_diffcam) +{ + const int nriga = new_pag.get_int(PAGSCA_NRIGA); + const TRiga_partite& fattura = riga(nriga); + + const int nrata = new_pag.get_int(PAGSCA_NRATA); + TRiga_scadenze& scaden = fattura.rata(nrata); + + const int nrigp = new_pag.get_int(PAGSCA_NRIGP); + const TRectype& old_pag = scaden.row(nrigp); + + const bool empty = scaden.modifica_pagamento(new_pag, + old_ap, old_abb, old_diffcam, + new_ap, new_abb, new_diffcam); + + if (empty && !utilizzata(nrigp)) + _part.destroy_row(nrigp); + + return empty; +} /////////////////////////////////////////////////////////// // TPartite_array @@ -1506,4 +1784,5 @@ void TPartite_array::update_reg_num(long nreg, const TRectype& mov) for (TPartita* game = first(); game; game = next()) game->update_reg_num(nreg, mov); } + \ No newline at end of file diff --git a/cg/pagament.h b/cg/pagament.h index 11749c22a..91564b35c 100755 --- a/cg/pagament.h +++ b/cg/pagament.h @@ -189,6 +189,9 @@ protected: // TRectype public: const TRecord_array& rows_array() const { return _recarr; } + TRecord_array& rows_array() { return _recarr; } + const TRectype& row(int r) const { return ((TRecord_array&)_recarr).row(r, FALSE); } + TRectype& row(int r, bool create) { return _recarr.row(r, create); } TTree_rectype(const TRectype& testata, const TRectype& riga, const char* num); TTree_rectype(int testata, int riga, const char* num); @@ -196,27 +199,66 @@ public: virtual ~TTree_rectype() {} }; + class TRiga_scadenze : public TTree_rectype -{ -public: - TRiga_scadenze(); +{ + friend class TPartita; + friend class TRiga_partite; + + TRiga_partite* _riga; + +protected: + char calcola_abbuono(TImporto& abbuono, bool val) const; + TImporto calcola_differenza_cambio(bool update); + + bool modifica_pagamento(const TRectype& new_pag, + char& old_ap, TImporto& old_abb, TImporto& old_diffcam, + char& new_ap, TImporto& new_abb, TImporto& new_diffcam); + +protected: // TRecord_tree + virtual TObject* dup() const { return new TRiga_scadenze(*this); } + +public: + int pagata() const; // Riga che chiude la rata o 0 se non pagata completamente + + real residuo() const; + + bool in_valuta() const; + + TPartita& partita() const; + TRiga_partite& riga() const { return *_riga; } // Riga partite generante (fattura) + + TImporto importo_pagato(bool val) const; + TImporto importo_da_pagare(bool val) const; + + TRiga_scadenze(TRiga_partite* riga); + TRiga_scadenze(const TRiga_scadenze& s); virtual ~TRiga_scadenze() {} }; class TRiga_partite : public TTree_rectype -{ +{ + friend class TPartita; + friend class TRiga_scadenze; + TPartita* _partita; + +protected: + bool update(const TRectype& vec, const TRectype& nuo, const char* field); + public: // TTree_rectype - virtual TObject* dup() const; + virtual TObject* dup() const { return new TRiga_partite(*this); } virtual int read(TBaseisamfile& f, word op); public: int rate() const { return _recarr.rows(); } TRiga_scadenze& rata(int r) const { return (TRiga_scadenze&)_recarr.row(r); } - bool rata_pagata(int r) const; - int add_rata(const TRectype& r); - int ultimo_pagamento(int rata) const; - TRiga_partite(); + int ultimo_pagamento(int rata) const; + char sezione() const { return get_char("SEZ"); } + + TPartita& partita() const { return *_partita; } // Partita di appartenenza + + TRiga_partite(TPartita* game); TRiga_partite(const TRiga_partite& r); virtual ~TRiga_partite() {} }; @@ -230,16 +272,23 @@ public: // TObject virtual bool ok() const { return _part.rows() > 0; } public: - int add_riga(const TRiga_partite& r); - const TRiga_partite& riga(int r) const { return (const TRiga_partite&)_part.row(r); } - TRecord_array& rows_array() { return _part; } - - void remove_riga(TRiga_partite& z); + TRiga_partite& riga(int r) const { return (TRiga_partite&)_part.row(r); } + TRiga_partite& nuova_riga() { return (TRiga_partite&)_part.row(last()+1, TRUE); } + int succ(int r) const { return _part.succ_row(r); } + int pred(int r) const { return _part.pred_row(r); } + int first() const { return _part.first_row(); } + int last() const { return _part.last_row(); } + bool reread(); bool read(const TBill& clifo, int anno, const char* num); bool write(bool re = FALSE); bool rewrite() { return write(TRUE); } + + int mov2rig(long nreg, int rmov) const; + int rig2mov(int rmov) const; + int prima_fattura() const; + bool utilizzata(int r) const; // Controlla se esistono pagamenti sommati alla riga r void conto(TBill& c) const { c.get(_part.key()); } int anno() const { return _part.key().get_int(PART_ANNO); } @@ -248,8 +297,14 @@ public: TImporto importo_speso(long numreg, int numrig) const; void update_reg_num(long nreg, const TRectype& mov); + void calcola_saldo(TImporto& saldo, TImporto& doc, TImporto& pag, TImporto& imp) const; + + bool modifica_pagamento(const TRectype& new_pag, + char& old_ap, TImporto& old_abb, TImporto& old_diffcam, + char& new_ap, TImporto& new_abb, TImporto& new_diffcam); TPartita(const TBill& clifo, int anno, const char* num); + TPartita(); }; @@ -269,6 +324,12 @@ public: TPartita& partita(const TBill& clifo, int anno, const char* numero); TPartita& partita(const TRectype& r); + TPartita* exist(const TBill& clifo, int anno, const char* numero) const + { return ((TPartite_array*)this)->find(clifo, anno, numero, FALSE); } + + TPartita* exist(const TRectype& part) const + { return ((TPartite_array*)this)->find(part, FALSE); } + bool write(bool re = FALSE); bool rewrite() { return write(TRUE); }