Gestione saldaconto

git-svn-id: svn://10.65.10.50/trunk@1713 c028cbd2-c16b-5b4b-a496-9718f37d4682
This commit is contained in:
guy 1995-08-21 07:45:45 +00:00
parent 5015ca30de
commit b5da2ff050
12 changed files with 1510 additions and 1075 deletions

View File

@ -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);
}

View File

@ -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

View File

@ -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

View File

@ -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

View File

@ -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

View File

@ -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;
}

View File

@ -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

View File

@ -9,7 +9,6 @@
#include "cg2102.h"
#include "cg2100.h"
#include "cg21sld.h"
#include "cg2100p.h"
#include <clifo.h>
#include <partite.h>
@ -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;
}

665
cg/cg2105.cpp Executable file
View File

@ -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 <clifo.h> // Archivio clienti/fornitori
#include <partite.h> // Archivio partite
#include <scadenze.h> // Archivio scadenze
#include <pagsca.h> // 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;
}

View File

@ -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;
}
}

View File

@ -3,8 +3,9 @@
#include "pagament.h"
#include <mov.h>
#include <partite.h>
#include <scadenze.h>
#include <pagsca.h>
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);
}

View File

@ -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); }