From 79ff0b85186ad020c37be8832a751a442a7a8166 Mon Sep 17 00:00:00 2001 From: villa Date: Thu, 24 Aug 1995 07:27:50 +0000 Subject: [PATCH] Un insieme di modifiche al saldaconto della prima nota, piu' una neceesaria depurazione di pagament.cpp onde evitare conflitti con Guido git-svn-id: svn://10.65.10.50/trunk@1732 c028cbd2-c16b-5b4b-a496-9718f37d4682 --- cg/cg2100.cpp | 14 +- cg/cg2100c.uml | 4 +- cg/cg2102.cpp | 70 +- cg/cg2102.h | 11 +- cg/cg2104.cpp | 56 +- cg/cg2104a.uml | 10 +- cg/cg21rata.uml | 16 +- cg/cg21sld.h | 3 +- cg/cg21sld.uml | 7 +- cg/cg5100a.uml | 4 +- cg/pagament.cpp | 2913 ++++++++++++++++++----------------------------- cg/pagament.h | 191 ---- 12 files changed, 1262 insertions(+), 2037 deletions(-) diff --git a/cg/cg2100.cpp b/cg/cg2100.cpp index dad3580fc..aa2f6ed91 100755 --- a/cg/cg2100.cpp +++ b/cg/cg2100.cpp @@ -66,6 +66,7 @@ TMask* TPrimanota_application::load_mask(int n) { m->set_handler(F_DATADOC, doc_handler); m->set_handler(F_NUMDOC, doc_handler); + m->set_handler(F_NUMRIF, numrif_handler); m->set_handler(F_DATA74TER, data74ter_handler); m->set_handler(F_PROTIVA, protiva_handler); m->set_handler(F_CLIENTE, clifo_handler); @@ -95,7 +96,7 @@ TMask* TPrimanota_application::load_mask(int n) // add saldaconto TSheet_field& ps = (TSheet_field&)m->field(FS_RATESHEET); ps.set_notify(pag_notify); - + m->set_handler(FS_RESET, reset_handler); } _iva_showed = FALSE; case 1: @@ -167,7 +168,7 @@ bool TPrimanota_application::user_create() _pag = NULL; _pag_rows = NULL; - _is_saldaconto = FALSE; + _is_saldaconto = FALSE; load_mask(0); @@ -415,10 +416,11 @@ void TPrimanota_application::on_firm_change() void TPrimanota_application::on_config_change() { TConfig cnf(CONFIG_DITTA); - _ges_val = cnf.get_bool("GesVal"); - _ges_sal = cnf.get_bool("GesSal"); - _num_cli = cnf.get_bool("NrCliDx"); - _num_for = cnf.get_bool("NrForDx"); + _ges_val = cnf.get_bool("GesVal"); + _ges_sal = cnf.get_bool("GesSal"); + _num_cli = cnf.get_bool("NrCliDx"); + _num_for = cnf.get_bool("NrForDx"); + _npart_is_prot = cnf.get_bool("RifPro"); } diff --git a/cg/cg2100c.uml b/cg/cg2100c.uml index c6797588e..4d62f617b 100755 --- a/cg/cg2100c.uml +++ b/cg/cg2100c.uml @@ -509,8 +509,8 @@ STRING F_NUMRIF 7 BEGIN PROMPT 68 15 "/ " FIELD LF_PARTITE->NUMPART - FLAGS "D" - HELP "Numero documento di riferimento" + FLAGS "U" + HELP "Numero di riferimento partita (documento o protocollo)" WARNING "E' richiesto il numero di riferimento partita" CHECKTYPE REQUIRED END diff --git a/cg/cg2102.cpp b/cg/cg2102.cpp index a268f8c35..142bee6c1 100755 --- a/cg/cg2102.cpp +++ b/cg/cg2102.cpp @@ -1514,7 +1514,7 @@ bool TPrimanota_application::doc_handler(TMask_field& f, KEY key) if (key == K_TAB) { TMask& m = f.mask(); - const TString& val = f.get(); + const TString16 val(f.get()); if (!val.empty() && m.field(F_ANNORIF).active()) { // Se c'e' gestione saldaconto @@ -1523,9 +1523,13 @@ bool TPrimanota_application::doc_handler(TMask_field& f, KEY key) const TDate dd(val); m.set(F_ANNORIF, dd.year()); // copia data documento } - else - { - m.set(F_NUMRIF, val); // copia numero documento + else if (!app().npart_is_prot()) + { + if (m.get(F_NUMRIF).empty()) + { + m.set(F_NUMRIF, val); // copia numero documento + app().set_numrif(val); + } } } } @@ -1533,6 +1537,52 @@ bool TPrimanota_application::doc_handler(TMask_field& f, KEY key) return TRUE; } + +bool TPrimanota_application::numrif_handler(TMask_field& f, KEY key) +{ + if (key == K_TAB) + { + TMask& m = f.mask(); + const TString& val = f.get(); + + if (f.focusdirty()) + { + // se cambiato chiedo conferma: + // se svuotato, azzero il cazzoconto + if (val.empty()) + { + if (yesno_box("Si desidera l'azzeramento delle scadenze?")) + { + // sbraga giu' il saldaconto: andra' tutto kancellato + // se c'era + app().remove_scadenze(f.mask(), app().get_numrif()); + f.mask().disable_page(2); + } +else f.set(app().get_numrif()); + } +else +{ + if (yesno_box("Si desidera la ridefinizione delle scadenze?")) + { + // lo ridefinisco da capo + // con il nuovo porcodio, riabilitando se + // non c'era + app().remove_scadenze(f.mask(), app().get_numrif()); + + app().reset_pagamento(); + app().set_scadenze(m); + f.mask().enable_page(2); + + } +else f.set(app().get_numrif()); +} +} +app().set_numrif(f.get()); +} +return TRUE; +} + + bool TPrimanota_application::occas_code_handler(TMask_field& f, KEY key) { if (key == K_TAB) @@ -1805,13 +1855,23 @@ void TPrimanota_application::add_cgs_rit(bool fiscali) bool TPrimanota_application::protiva_handler(TMask_field& f, KEY key) { bool ok = TRUE; + const TString16 piva(f.get()); if (key == K_ENTER && f.dirty() && f.mask().mode() == MODE_INS) { const long protiva = atol(f.get()); const long protocol = app().causale().reg().protocol() + 1; if (protiva != protocol) ok = f.yesno_box("Accettare il protocollo IVA fuori sequenza: %ld invece di %ld", - protiva, protocol); + protiva, protocol); + + } + else if (key == K_TAB && app().is_saldaconto() && f.mask().get(F_NUMRIF).empty()) + { + if (app().npart_is_prot()) + { + f.mask().set(F_NUMRIF, piva); + app().set_numrif(piva); + } } return ok; } diff --git a/cg/cg2102.h b/cg/cg2102.h index 8402566b2..10534d9bc 100755 --- a/cg/cg2102.h +++ b/cg/cg2102.h @@ -45,6 +45,7 @@ class TPrimanota_application : public TRelation_application TipoIVA _iva; // Tipo di IVA corrente bool _ges_val, _ges_sal; // Gestione valuta e saldaconto bool _num_cli, _num_for; // Riferimento partita allineato a destra + bool _npart_is_prot; // Riferimento partita = n. prot. IVA anziche' doc bool _skip_giornale_check; // Ignora controllo data stampa libro giornale bool _skip_bollato_check; // Ignora controllo data stampa bollato @@ -65,6 +66,7 @@ class TPrimanota_application : public TRelation_application TBill _conto_ricavo; // Conto di ricavo del clifo TString_array _pag_rows; + TString16 _numrif; // memorizza numrif per undo static bool showpartite_handler(TMask_field& f, KEY k); static bool speserimb_handler(TMask_field& f, KEY k); @@ -81,6 +83,7 @@ class TPrimanota_application : public TRelation_application static bool datacomp_handler(TMask_field& f, KEY key); static bool data74ter_handler(TMask_field& f, KEY key); static bool doc_handler(TMask_field& f, KEY key); + static bool numrif_handler(TMask_field& f, KEY key); static bool protiva_handler(TMask_field& f, KEY key); static bool clifo_handler(TMask_field& f, KEY key); static bool totale_handler(TMask_field& f, KEY key); @@ -104,6 +107,7 @@ class TPrimanota_application : public TRelation_application static bool dareavere_handler(TMask_field& f, KEY k); static bool cg_conto_handler(TMask_field& f, KEY key); static bool codpag_handler(TMask_field& f, KEY key); + static bool reset_handler(TMask_field& f, KEY key); static bool iva_notify(TSheet_field& s, int r, KEY key); static bool iva_handler(TMask_field& f, KEY key); @@ -112,7 +116,10 @@ class TPrimanota_application : public TRelation_application static bool pag_notify(TSheet_field& s, int r, KEY key); void reset_sheet_row(TSheet_field& s, int n); - + + void set_numrif(const char* s) { _numrif = s; } + const char* get_numrif() { return _numrif; } + protected: // TApplication virtual void on_firm_change(); virtual void on_config_change(); @@ -150,6 +157,7 @@ protected: bool gestione_saldaconto() const { return _ges_sal; } bool is_saldaconto() const { return _is_saldaconto; } void set_saldaconto(bool b) { _is_saldaconto = b; } + bool npart_is_prot() { return _npart_is_prot; } void fill_sheet(TMask& m) const; void init_mask(TMask& m); @@ -202,6 +210,7 @@ protected: void set_scadenze(TMask& m); bool read_scadenze(TMask& m); void write_scadenze(const TMask& m); + void remove_scadenze(const TMask& m, const char* rif); bool edit_partite(int riga); diff --git a/cg/cg2104.cpp b/cg/cg2104.cpp index 0e70c6778..f09bde3b6 100755 --- a/cg/cg2104.cpp +++ b/cg/cg2104.cpp @@ -44,8 +44,8 @@ bool TPrimanota_application::pag_notify(TSheet_field&, int r, KEY k) ts = rws.row(r); news = ns.get(0); - newp = ns.get(1); - newi = ns.get(2); + newp = ns.get(2); + newi = ns.get(1); newt = ns.get(3); // qui viene il bello, si fa per dire @@ -53,11 +53,11 @@ bool TPrimanota_application::pag_notify(TSheet_field&, int r, KEY k) { mod = m_scad = TRUE; } - if (newp != ts.get(1)) // modificata percentuale + if (newp != ts.get(2)) // modificata percentuale { mod = m_perc = TRUE; } - if (newi != ts.get(2)) // modificato importo + if (newi != ts.get(1)) // modificato importo { // se si modifica la percentuale l'importo non viene cagato if ((recalc && !m_perc) || (!recalc)) @@ -152,6 +152,29 @@ bool TPrimanota_application::codpag_handler(TMask_field& f, KEY key) } return TRUE; } + +bool TPrimanota_application::reset_handler(TMask_field& f, KEY key) +{ + TMask& m = f.mask(); + + if (key == K_SPACE && m.is_running() && app().is_saldaconto()) + { + app().reset_pagamento(); + app().set_scadenze(m); + } + return TRUE; +} + + +void TPrimanota_application::reset_pagamento() +{ + if (_pag != NULL) + { + _pag->read(); + _pag->set_rate_auto(); + } +} + void TPrimanota_application::set_pagamento(const char* c, const char* d) { @@ -254,7 +277,7 @@ bool TPrimanota_application::read_scadenze(TMask& m) if (pag.code() != partita.get("CODPAG")) fromscratch = TRUE; // se invece la maschera contiene importi diversi da quelli - // registrati si passa la palla al culano + // registrati si passa la palla al culano/a else if (imponibile != partita.get_real(PART_IMPORTO) || imposta != partita.get_real(PART_IMPOSTA) || spese != partita.get_real(PART_SPESE)) @@ -262,7 +285,7 @@ bool TPrimanota_application::read_scadenze(TMask& m) fromscratch = !yesno_box("Gli importi totali delle scadenze sono stati modificati rispetto" " all'ultima registrazione. Si desidera mantenere" " comunque la rateazione precedente"); - // nel caso, of course, si disabilitano gli automatismi + // nel qual caso, of course, si disabilitano gli automatismi if(!fromscratch) m.field(FS_RECALC).set(""); } if (fromscratch) @@ -305,12 +328,23 @@ bool TPrimanota_application::read_scadenze(TMask& m) return TRUE; } +void TPrimanota_application::remove_scadenze(const TMask& m, const char* nr) +{ + // TBI se _erase_sld == TRUE occorre cancellare tutte le scadenze + // eventualmente presenti; attenzione a riferimenti cambiati + TString numrif(nr); + if (numrif.empty()) return; + + // rimuovi se ci sono + +} + void TPrimanota_application::write_scadenze(const TMask& m) { real imponibile(0.0); real imposta(0.0); - real spese(0.0); - + real spese(0.0); + // should never happen but it doesn't hurt CHECK(!_rel->cg(0).empty(), "Missing first line"); @@ -340,6 +374,8 @@ void TPrimanota_application::write_scadenze(const TMask& m) int gruppo = (tipocf == 'C' || tipocf == 'F') ? 0 : _rel->cg(0).get_char("GRUPPO"); int conto = (tipocf == 'C' || tipocf == 'F') ? 0 : _rel->cg(0).get_char("CONTO"); long sottoconto = _rel->cg(0).get_long("SOTTOCONTO"); + + // TBI deve essere riga iniziale scadenze (puo' essere != 1 sul file) const int nriga = 1; int numrig = 1; @@ -406,7 +442,9 @@ void TPrimanota_application::write_scadenze(const TMask& m) scadenza.put(SCAD_SOTTOCONTO, sottoconto); scadenza.put(SCAD_ANNO, anno); scadenza.put(SCAD_NUMPART, numpart); - scadenza.put(SCAD_NRIGA, nriga); + scadenza.put(SCAD_NRIGA, nriga); + // TBI NO! Va visto se ce ne sono altre, con gestione riga + // iniziale nella partita scadenza.put(SCAD_NRATA, i+1); if (scadenza.read() != NOERR) diff --git a/cg/cg2104a.uml b/cg/cg2104a.uml index 4dcd6ec88..bc54bd9a8 100755 --- a/cg/cg2104a.uml +++ b/cg/cg2104a.uml @@ -73,8 +73,8 @@ SPREADSHEET F_RATESHEET 80 8 BEGIN PROMPT 1 10 "Rate" ITEM "Scadenza@10" - ITEM "Percentuale@12" ITEM "Importo@15" + ITEM "Percentuale@12" ITEM "Tipo" ITEM "Pagamento@32" END @@ -89,14 +89,14 @@ BEGIN PROMPT 1 2 "Scadenza " END -NUMBER 102 3 0 +NUMBER 102 15 0 BEGIN - PROMPT 1 3 "Percentuale " + PROMPT 1 3 "Importo " END -NUMBER 103 15 0 +NUMBER 103 3 2 BEGIN - PROMPT 1 4 "Importo " + PROMPT 1 4 "Percentuale " END NUMBER 104 2 0 diff --git a/cg/cg21rata.uml b/cg/cg21rata.uml index d6c7f50cb..af25bc2fe 100755 --- a/cg/cg21rata.uml +++ b/cg/cg21rata.uml @@ -5,20 +5,20 @@ BEGIN PROMPT 1 1 "Scadenza " END -NUMBER 102 8 3 -BEGIN - PROMPT 1 2 "Percentuale " - PICTURE ".3" - FLAGS "R" -END - -NUMBER 103 15 +NUMBER 102 15 BEGIN PROMPT 1 3 "Importo " PICTURE "." FLAGS "R" END +NUMBER 103 8 3 +BEGIN + PROMPT 1 2 "Percentuale " + PICTURE ".3" + FLAGS "R" +END + NUMBER 104 2 0 BEGIN PROMPT 1 4 "Tipo pagamento " diff --git a/cg/cg21sld.h b/cg/cg21sld.h index 1a4cca917..84bbc1389 100755 --- a/cg/cg21sld.h +++ b/cg/cg21sld.h @@ -7,4 +7,5 @@ #define FS_RECALC 507 #define FS_NAMEPAG 508 #define FS_TIPOPR 509 -#define FS_MCOMM 510 \ No newline at end of file +#define FS_MCOMM 510 +#define FS_RESET 511 diff --git a/cg/cg21sld.uml b/cg/cg21sld.uml index f270d43a4..957513fec 100755 --- a/cg/cg21sld.uml +++ b/cg/cg21sld.uml @@ -65,11 +65,16 @@ SPREADSHEET FS_RATESHEET 0 8 BEGIN PROMPT 1 10 "Rate" ITEM "Scadenza@10" - ITEM "Percentuale@12" ITEM "Importo@15" + ITEM "Percentuale@12" ITEM "Tipo" ITEM "Pagamento@32" END +BUTTON FS_RESET 7 1 +BEGIN + PROMPT 1 -1 "Reset" +END + ENDPAGE diff --git a/cg/cg5100a.uml b/cg/cg5100a.uml index 0e380a624..780de99c9 100755 --- a/cg/cg5100a.uml +++ b/cg/cg5100a.uml @@ -156,8 +156,8 @@ END BOOLEAN CHK_RIFPRO BEGIN - PROMPT 4 17 "Riferimento numero protocollo o documento" - HELP "Indicare se si desidera il numero protocollo/documento come riferimento" + PROMPT 4 17 "Riferimento partita con numero protocollo" + HELP "Indicare se si desidera il numero protocollo IVA anziche' il numero documento come riferimento partita" FIELD RifPro GROUP GROUP_SALDACONTO END diff --git a/cg/pagament.cpp b/cg/pagament.cpp index df308d23d..a78d03c04 100755 --- a/cg/pagament.cpp +++ b/cg/pagament.cpp @@ -1,1806 +1,1107 @@ -#include - -#include "pagament.h" - -#include -#include -#include -#include - -int TPagamento::_rata_ifield(int n, int f) const -{ - TToken_string& t = (TToken_string&)_rate[n]; - return t.get_int(f); -} - -real TPagamento::_rata_rfield(int n, int f) const -{ - TToken_string& t = (TToken_string&)_rate[n]; - return real(t.get(f)); -} - -TDate TPagamento::_rata_dfield(int n, int f) const -{ - TToken_string& t = (TToken_string&)_rate[n]; - return TDate(t.get(f)); -} - -const char* TPagamento::_rata_sfield(int n, int f) const -{ - static char kak[6]; - TToken_string& t = (TToken_string&)_rate[n]; - strcpy(kak,t.get(f)); - return kak; -} - - -bool TPagamento::ratapagata(int n) -{ - TToken_string& t = (TToken_string&)_rate[n]; - return t.items() > 6; -} - - - -void TPagamento::set_intervallo_rate(int in) -{ - _dirty = TRUE; - _int_rate = in; - if (_mcomm && (in % 30) != 0) - _mcomm = FALSE; - for (int i = 0; i < n_rate(); i++) - { - TToken_string& ts = rata(i); - ts.add(i == 0 ? (scad_rata(0) == 0 ? "0" : format("%d",in)) - : format("%d",in), 0); - } -} - -void TPagamento::set_mese_commerciale(bool v, int& sscad) -{ - _dirty = FALSE; - if (_mcomm == v) return; - if (sscad == -1) sscad = 30; - - if ((sscad % 30) != 0) sscad = 30 * ((sscad/30)+1); - set_intervallo_rate(sscad); - - _mcomm = v; -} - -void TPagamento::set_rate_differenziate(int v) -{ - _dirty = FALSE; - if (!_rdiff && v == 2) return; - - if (v == 2 && (100 % n_rate()) == 0) - { - int p = 100 / n_rate(); - for (int i = _tpr < 4 ? 0 : 1; i < n_rate(); i++) - { - TToken_string& tt = rata(i); - tt.add(p,1); - } - _rdiff = !(v == 2); - _dirty = TRUE; - } -} - -void TPagamento::set_tipo_prima_rata(int v, int sscad) -{ - _dirty = FALSE; - if (_tpr == v) return; - - if (v < 4 && _tpr > 3) - { - for (int i = n_rate() - 1; i > 0; i--) - { - TToken_string& tt = rata(i); - tt.add(scad_rata(i-1),0); - tt.add(tipo_rata(i-1),2); - tt.add(ulc_rata(i-1),5); - } - _rate.add(NULL,0); - _rate.pack(); - } - else if ( _tpr < 4 && v > 3) - { - TToken_string* ttn = new TToken_string(32); - ttn->add(0,0); - ttn->add(0,1); - ttn->add(1,2); - ttn->add("",3); - ttn->add("",4); - ttn->add("",5); - _rate.insert(ttn,0); - for (int i = 0; i < (n_rate()-1); i++) - { - TToken_string& tt = rata(i); - tt.add(scad_rata(i+1),0); - tt.add(tipo_rata(i+1),2); - tt.add(ulc_rata(i+1),5); - } - } - _tpr = v; - _dirty = TRUE; -} - -void TPagamento::set_numero_rate(int n, int sscad) -{ - _dirty = FALSE; - if (n == 0 || n == n_rate()) return; - - real p = real(100) / real(n); - p.round(2); - int nr = n_rate(); - int first = _tpr < 4 ? 0 : 1; - real sum = 0.0; - - for (int i = first; sum < real(100.0); i++) - { - if ((real(100.0) - sum) < p) - p = real(100.0) - sum; - - sum += p; - - // if necessary add remainder on first one - if ((real(100.0) - sum) /* still */ < p) - { - real prc = perc_rata(first); - prc += real(100.0) - sum; - TToken_string& rt = rata(first); - rt.add(prc.string(),1), - sum = 100; - } - - set_rata(i, real(p), - i == 0 ? (i < nr ? scad_rata(0) : 0): - (sscad == -1 ? (i < nr ? scad_rata(i) : scad_rata(nr-1)) : sscad), - (i < nr ? tipo_rata(i) : tipo_rata(nr-1))); - } - // erase remaining - for (; i < nr; i++) - _rate.add(NULL,i); - _rate.pack(); - - _dirty = TRUE; -} - - -void TPagamento::next_scad(TDate& d, int scad, bool mcomm, int rata) -{ - if (mcomm) - { - int nm = scad / 30; - int ny = nm / 12; - nm %= 12; - - int newm = d.month() + nm; - if (newm > 12) { newm -= 12; ny++; } - - bool last = d.is_end_month() && inizio_scadenza() == 'M'; - - int dy = d.day(); - - // la palla del febbraio & c. - if (rata > 1) - { - TDate oldd(data_rata(rata-2)); - if (oldd.day() > dy) dy = oldd.day(); - } - - d.set_day(1); // il giorno 1 ce l'hanno tutti - d.set_month(newm); - d.set_year(d.year()+ny); - - d.set_end_month(); - if (!last && dy < d.day()) - d.set_day(dy); - } - else - { - d += scad; - } - - // riaggiusta la minchia se ci sono scadenze fissate - if (_fixd[0] != 0 || _fixd[1] != 0 || _fixd[2] != 0) - { - for (int i = 0; i < 3; i++) - { - if (_fixd[i] > d.day()) - { - if (d.last_day(d.month(), d.year()) <= _fixd[i]) - d.set_day(_fixd[i]); - else d.set_end_month(); - break; - } - } - - if (i == 3) - { - if (_fixd[0] > 0 && _fixd[0] < d.day()) - { - d.set_day(_fixd[0]); - d.set_month(d.month() == 12 ? 1 : d.month() + 1); - } - } - - } -} - - -void TPagamento::set_default_type(int type, bool change_existing) -{ - _def_tpr = type; - if (change_existing) - { - for (int i = 0; i < n_rate(); i++) - { - TToken_string& tt = rata(i); - tt.add(type, 2); - } - _dirty = TRUE; - } -} - -void TPagamento::set_default_ulc(const char* ulc, bool change_existing) -{ - _def_ulc = ulc; - if (change_existing) - { - for (int i = 0; i < n_rate(); i++) - { - TToken_string& tt = rata(i); - tt.add(ulc, 5); - } - _dirty = TRUE; - } -} - -void TPagamento::remove_rata(int i) -{ - // non fa nessun ricalcolo, si limita ad impacchettare se - // necessario - _rate.add(NULL,i); - _rate.pack(); - _dirty = TRUE; -} - -TToken_string& TPagamento::add_rata(real perc, int day, int type, const char* ulc) -{ - TToken_string* tt = new TToken_string(16); - tt->add(day); // scadenza - tt->add(perc.string()); // percentuale - tt->add(type); // tipo - tt->add(""); - tt->add(""); - tt->add(ulc); - _rate.add(tt); - _dirty = TRUE; - return *tt; -} - -TToken_string& TPagamento::set_rata (int index, real perc, int day, int type, - const char* ulc, const char* imp, - const char* data) -{ - TToken_string* tt = (TToken_string*)_rate.objptr(index); - const bool nwr = (tt == NULL); - if (nwr) tt = new TToken_string(16); - - tt->add(day,0); // scadenza - tt->add(perc.string(),1); // percentuale - tt->add(type,2); // tipo - tt->add(data == NULL ? "" : data,3); - tt->add(imp == NULL ? "" : imp,4); - tt->add(ulc == NULL ? "" : ulc,5); - - if (!nwr) - { - if (index > _rate.items()) - { - error_box("Rate non contigue"); - delete tt; - } - } - else - { - _rate.add(tt,index); - _dirty = TRUE; - } - return *tt; -} - -void TPagamento::set_imprata(int i, real r) -{ - TToken_string& tt = (TToken_string&)_rate[i]; - TDate d = _inizio; - - for (int n = 0; n <= i; n++) - next_scad(d, scad_rata(n), _mcomm, n); - - tt.add((const char*)d, 3); - tt.add(r.string(), 4); -} - -TToken_string& TPagamento::set_rata(int index, const real& howmuch, - const TDate& date, int type,const char* ulc, bool pagato) -{ - // calcola percentuali e scadenze a partire dagli importi - TToken_string* tt = (TToken_string*)_rate.objptr(index); - - const bool nwr = (tt == NULL); // nuova rata - - if (nwr) tt = new TToken_string(16); - - TDate oldd = index > 0 ? data_rata(index -1) : _inizio; - int day = date - oldd; - real toshare(_tpr < 4 ? _firstr : _secndr); - real perc = (_tpr > 3 && index == 0) ? ZERO : howmuch/toshare; - perc *= real(100.0); - perc.round(2); - - tt->add(day,0); // scadenza - tt->add(perc.string(),1); // percentuale - tt->add(type,2); // tipo - tt->add(date.string(),3); - tt->add(howmuch.string(),4); - tt->add(ulc,5); - if (pagato) tt->add("X",6); - - if (!nwr) - { - if (index > _rate.items()) - { - error_box("Rate non contigue"); - delete tt; - } - } - else - { - _rate.add(tt, index); - _dirty = TRUE; - } - return *tt; -} - - - -word TPagamento::validate() const -{ - word res = 0x0000; - real r(0.0); - - int first = _tpr < 4 ? 0 : 1; - real toshare(_tpr < 4 ? _firstr : _secndr); - TDistrib ds(toshare,0); - - // check percentages & prepare slicer - for (int i = first; i < n_rate(); i++) - { - real p(perc_rata(i)); - ds.add(p); - r += p; - } - - if (r != real(100.0)) - res |= P_RSUM; - - - if (_inited) - { - ds.init(toshare); - // check importi rate consistenti con la percentuale - for (int i = first; i < n_rate(); i++) - { - real r1(tpay_rata(i)); - real r2(ds.get()); - if (r1 != r2) - { res |= P_IMPNC; break; } - } - - // check errori date scadenze (se istanziate) - TDate d(data_rata(0)); - if (d < _inizio) - res |= P_INIZIO; - for (i = 1; i < n_rate(); i++) - { - if (data_rata(i) <= d) - { res |= P_SCAD; break; } - d = data_rata(i); - } - } - return res; -} - - -void TPagamento::strerr(word err, TString& s) -{ - s = "Errore:"; - if (err & P_RSUM) - s << "\n Le percentuali non sommano a 100"; - if (err & P_IMPNC) - s << "\n Le percentuali sono inconsistenti con gli importi"; - if (err & P_SCAD) - s << "\n Le scadenze non sono consecutive"; - if (err & P_INIZIO) - s << "\n La prima rata e' antecedente alla data movimento"; -} - -const char* TPagamento::desc_tpr() const -{ - const char* o; - switch (_tpr) - { - case 0: o = "Totale su tutte le rate"; break; - case 1: o = "Tutte le imposte su 1a"; break; - case 2: o = "Tutte le spese su 1a"; break; - case 3: o = "Imposte + spese su 1a"; break; - case 4: o = "Spese + merce su 1a"; break; - case 5: o = "Merce + imposte su 1a"; break; - case 6: o = "Tutta la merce su 1a"; break; - default: o = ""; break; - } - return o; -} - -const char* TPagamento::desc_tipo(int i) const -{ - const char* o; - switch (i) - { - case 1: o = "Rimessa diretta o contanti"; break; - case 2: o = "Tratta"; break; - case 3: o = "Ricevuta bancaria"; break; - case 4: o = "Cessione"; break; - case 5: o = "Paghero'"; break; - case 6: o = "Lettera di credito"; break; - case 7: o = "Tratta accettata"; break; - case 8: o = "Rapporti interbancari diretti"; break; - case 9: o = "Bonifici"; break; - case 10: o = "Altro pagamento"; break; - } - return o; -} - -word TPagamento::recalc_rate(int row, bool is_perc_modified, - const char* new_value, const char* scad, - const char* typ, int rdiff, bool mcomm, - bool& need_recalc) - // ricalcola le rate sulla base di parametri modificati sulla riga row - // parametri: tutti i const char* possono essere NULL, il che vuol dire - // che i dati corrispondenti non sono stati modificati; - // se new_value non e' NULL puo' essere la percentuale (e - // allora is_perc_modified e' TRUE) o l'importo. Non e' - // possibile modificare entrambi; se succede viene data - // priorita' alla percentuale. -{ - CHECK(!(!is_perc_modified && new_value != NULL && !_inited), - "A'stronzo! E famme 'na pippa! Me dai n'importo che nun ce sta? Ma Vaffanculo!"); - - if (_rate.items() == 0) return P_OK; - - real rsum(0.0), newv(0.0), rmax(0.0); - int oldtype = tipo_rata(0); - int oldscad = scad_rata(0); - TDate lastdate = data_rata(0); - int first = _tpr < 4 ? 0 : 1; - TArray srate(_rate); // rate come erano - - - if (srate.items() > 1) - { - // calcola defaults per tipo pagamento e scadenza - // nel caso di rate nuove - oldscad = scad_rata(1); - } - - if (oldscad == 0) oldscad = 30; - if (oldtype == 0) oldtype = 1; - - if (new_value != NULL) - { - newv = new_value; - rmax = is_perc_modified? (real) 100.0 : (_tpr < 4 ? _firstr : _secndr); - if (newv > rmax) return P_RSUM; - } - - bool exhausted = FALSE; - - for (int i = first; i < srate.items(); i++) - { - if (i == row) - { - if (typ != NULL) - { - TToken_string& tt = rata(row); - TToken_string& ss = (TToken_string&)srate[row]; - tt.add(typ,2); - ss.add(typ,2); - // no error is possible - } - - if (scad != NULL) - { - // if !_inited scad e' il n. giorni, se no e' la rata - if (_inited) - { - TToken_string& tt = rata(row); - TToken_string& ss = (TToken_string&)srate[row]; - lastdate = scad; - // controlla errore sulla data scadenza - if (i > 0) - { - oldscad = (int)(lastdate - data_rata(i-1)); - if (oldscad <= 0l) return P_SCAD; - } - else if (lastdate < _inizio) return P_INIZIO; - tt.add(scad,3); - ss.add(scad,3); - // ricalcola rate successive: se si vuole modificarne solo una - // ci si fotte e si disabilita il ricalcolo - TDate ddd (lastdate); - for (int j = row+1; j < srate.items(); j++) - { - TToken_string& tt = rata(j); - TToken_string& ss = (TToken_string&)srate[j]; - next_scad(ddd,scad_rata(j),mcomm,j); - tt.add(ddd.string(),3); - ss.add(ddd.string(),3); - need_recalc = TRUE; - } - } - else - { - // nulla di speciale visto che si memorizza la derivata - int sc = atoi(scad); - for (int i = 0; i < row; i ++) - sc -= scad_rata(i); - if (sc < 0 || (row > 0 && sc == 0)) return P_SCAD; - if (_mcomm && (sc % 30) != 0) _mcomm = FALSE; - TToken_string& tt = rata(row); - TToken_string& ss = (TToken_string&)srate[row]; - tt.add(sc,0); - ss.add(sc,0); - need_recalc = TRUE; - } - } - - // here's the bell - if (new_value != NULL) - { - if (newv == ZERO || (rsum+newv) > rmax) - return P_RSUM; - // did not sforate - rsum += newv; - TToken_string& rt = rata(row); - // setta nuovo valore e ricalcola cio' che ne consegue - if (is_perc_modified) rt.add(new_value,1); - else rt.add(new_value,4); - // riaggiusta le rate rimanenti - real remainder(0.0); remainder = rmax - rsum; - if (!(exhausted = (remainder == real(0.0)))) - { - // se inited e scelto UGUALI (2) occorre dividere in N e - // aggiungere il resto sulla 1a rata - // controlla se rdiff e' compatibile con - // i dati e se e' il caso riaggiusta - if (rdiff == 3 && !((remainder % newv.integer()) == ZERO)) - rdiff = 2; -// *** 10/8/95: se uguali e non e' multiplo intero lo teniamo cosi' e poi -// *** aggiungiamo alla prima rata utile -// if (rdiff == 2 && !((rmax % newv.integer()) == ZERO)) -// rdiff = 1; - _rdiff = (rdiff == 1 || rdiff == 3 || rdiff == 4); - - // procedi - if (rdiff == 1) - { - // cancella tutte le rate successive, aggiungi un'unica rata - // con il resto dell'importo - if (row < (srate.items()-1)) - { - TToken_string& trt = rata(row+1); - trt.add(remainder.string(), is_perc_modified ? 1 : 4); - for(int j = row+2; j < srate.items(); j++) - _rate.add(NULL,j); - } - else - { - // l'importante e' esagerare - for(int j = row+1; j < srate.items(); j++) - _rate.add(NULL,j); - - TToken_string& trt = add_rata(is_perc_modified ? remainder : (real) 0.0, - oldscad, oldtype); - if (!is_perc_modified) trt.add(remainder.string(),4); - if (_inited) - { - TDate dd = data_rata(row); - next_scad(dd,oldscad,mcomm,row); - trt.add(dd.string(),3); - } - } - } - else // rate non differenziate (dall'inizio o da row) - { - // ripartisci l'importo nel numero necessario di rate per - // mantenere costante il valore - real sum(0.0); - if (_inited) lastdate = data_rata(rdiff == 2 ? first : row); - - TDate dd(lastdate); - int type = oldtype; - int nscd = oldscad; - - int frs = (rdiff == 3 || rdiff == 4) ? row+1 : first; - real mx = (rdiff == 3 || rdiff == 4) ? remainder : rmax; - - // cancelliamo tutto, va' - for (int j = frs; j < srate.items(); j++) - _rate.add(NULL,j); - - if (rdiff != 4) - for (j = frs; sum < mx; j++) - { - // TBI: qui mod se rdiff == 2 - // se c'e' la vecchia rata si tengono i parametri - // altrimenti si calcolano - if (j < srate.items()) - { - TToken_string& trt = (TToken_string&)srate[j]; - if (_inited) dd = trt.get(3); - type = atoi(trt.get(2)); - nscd = j == 0 ? 0 : atoi(trt.get(0)); - if (type == 0) type = 1; - if (j > 0 && nscd == 0) nscd = oldscad; - if (_inited && dd == lastdate && j > 0) - next_scad(dd,nscd,mcomm,j); - } - else if (_inited) - { - if (dd <= botime) dd = lastdate; - next_scad(dd,nscd,mcomm,j); - } - else nscd = _int_rate; - - TToken_string& ttr = set_rata(j, is_perc_modified ? newv : ZERO, - nscd, type); - if (_inited) - ttr.add(dd.string(), 3); - if (!is_perc_modified) - { - ttr.add(newv.string(),4); - } - if ((mx - sum) < newv) - { - // add remainder on first rate - newv += (mx - sum); - if (!is_perc_modified) - set_imprata(frs, newv); - else { - TToken_string& t = rata(frs); - t.add(newv.string(), 1); - } - remove_rata(j); - break; - } -// } - sum += newv; - } - else // rdiff == 4; uguali finche' possibile - { - bool basta = FALSE; - for (j = frs; ; j++) - { - // ultima rata puo' differire dalle precedenti - if (mx - sum <= newv) - { - newv = mx - sum; - basta = TRUE; - } - // se c'e' la vecchia rata si tengono i parametri - // altrimenti si calcolano - if (j < srate.items()) - { - TToken_string& trt = (TToken_string&)srate[j]; - if (_inited) dd = trt.get(3); - type = atoi(trt.get(2)); - nscd = j == 0 ? 0 : atoi(trt.get(0)); - if (type == 0) type = 1; - if (j > 0 && nscd == 0) nscd = oldscad; - if (_inited && dd == lastdate && j > 0) - next_scad(dd,nscd,mcomm,j); - } - else if (_inited) next_scad(dd,nscd,mcomm,j); - - TToken_string& ttr = set_rata(j, is_perc_modified ? newv : ZERO, - nscd, type); - if (_inited) - ttr.add(dd.string(), 3); - if (!is_perc_modified) - ttr.add(newv.string(),4); - if (basta) break; - sum += newv; - } - } - } - - } - else // exhausted - { - for(int j = row+1; j < srate.items(); j++) - _rate.add(NULL,j); - } - - - if (_inited) - { - // ricalcola il valore secondario (non modificato) - real toshare(100.0); - if (is_perc_modified) - toshare = (_tpr < 4 ? _firstr : _secndr); - TDistrib dt(toshare, is_perc_modified ? _round : 3); - - for (int j = first; j < _rate.items(); j++) - { - real rvl = is_perc_modified ? perc_rata(j) : tpay_rata(j); - real zpx = rvl/rmax; // percentuale - dt.add(zpx); - } - for (j = first; j < _rate.items(); j++) - { - TToken_string& tr = rata(j); - real rvl = dt.get(); - tr.add(rvl.string(), is_perc_modified ? 4 : 1); - } - - // se e' il caso aggiungi l'importo fisso sulla prima rata - if (_inited && _tpr > 0 && _tpr < 4) - { - TToken_string& tr = rata(0); - real tot = tpay_rata(0) + _firstr; - tr.add(tot.string(), 4); - } - - } - - need_recalc = TRUE; - return P_OK; - } // new_value != NULL - } - else // i != row modified - { - if (i > 0 && !((perc_rata(i-1) == perc_rata(i)))) - { - if (rdiff == 2) rdiff = 1; - _rdiff = FALSE; - } - if (is_perc_modified) - rsum += perc_rata(i); - else - rsum += tpay_rata(i); - - lastdate = data_rata(i); - oldtype = tipo_rata(i); - oldscad = scad_rata(i); - if (_inited && i > 0) - { - if (data_rata(i) <= data_rata(i-1)) - return P_SCAD; - } - else if (lastdate < _inizio) - return P_INIZIO; - } - } - - return P_OK; -} - - -bool TPagamento::read(TTable* t, TTable* r) -{ - // puo' chiamarla chiunque - bool istnew = FALSE; - if (t == NULL) - { - t = new TTable("%CPG"); - istnew = TRUE; - } - t->zero(); t->put("CODTAB",_code); - if (t->read() != NOERR) return FALSE; - - // set everything - _rdiff = t->get_bool("B1"); - _mcomm = t->get_bool("B0"); - _tpr = atoi(t->get("S3")); - _inscad = *((const char*)(t->get("S1"))); - _code = t->get("CODTAB"); - _name = t->get("S0"); - _fixd[0] = t->get_int("I0"); - _fixd[1] = t->get_int("I1"); - _fixd[2] = t->get_int("I2"); - - // TBI aggiusta _inizio secondo INSCAD; vedi mese commerciale etc. - if (_inscad == 'M') - { - if (_mcomm) _inizio.set_month(_inizio.month() == 2 ? 28 : 30); - else _inizio.set_end_month(); - } - else if (_inscad == 'F' && _mcomm && _inizio.month() == 31) - _inizio.set_month(30); - - // leggi rate e scadenze - bool isrnew = FALSE; - if (r == NULL) - { - r = new TTable("%RPG"); - isrnew = TRUE; - } - TString s(16); - - for (int i = 0; ;i++) - { - r->zero(); s.format("%s%3d",(const char*)_code, i); - r->put("CODTAB", (const char*)s); - if (r->read() != NOERR) break; - TToken_string* tt = new TToken_string(16); - tt->add((const char*)(r->get("I0"))); // scadenza - tt->add((const char*)(r->get("R0"))); // percentuale - tt->add((const char*)(r->get("I1"))); // tipo - // data e importo - TDate d = _inizio; - next_scad(d,(int)(r->get_long("I0")),_mcomm,i); - tt->add((const char*)d); - tt->add(""); - tt->add(r->get("S1")); - _slicer.add((real)r->get("R0")); - _rate.add(tt); - } - - if (istnew) delete t; - if (isrnew) delete r; - - return TRUE; -} - - -int TPagamento::write(TTable& r) -{ - // Scrive soltanto le righe di pagamento; si assume sia stata chiamata da una - // relapp, che ha scritto il file principale - - TString s(16); int err = NOERR; - for (int i = 0; err == NOERR && i < n_rate(); i++) - { - r.zero(); s.format("%s%3d",(const char*)_code, i); - r.put("CODTAB", (const char*)s); - r.put("I0", (long)scad_rata(i)); - r.put("R0", perc_rata(i).string()); - r.put("I1", (long)tipo_rata(i)); - r.put("S1", ulc_rata(i)); - err = r.write(); - } - return err; -} - -int TPagamento::rewrite(TTable& r) -{ - TString s(16); int err = NOERR; - for (int i = 0; err == NOERR && i < n_rate(); i++) - { - r.zero(); s.format("%s%3d",(const char*)_code, i); - r.put("CODTAB", (const char*)s); - bool was = (r.read() == NOERR); - r.zero(); s.format("%s%3d",(const char*)_code, i); - r.put("CODTAB", (const char*)s); - r.put("I0", (long)scad_rata(i)); - r.put("R0", perc_rata(i).string()); - r.put("I1", (long)tipo_rata(i)); - r.put("S1", ulc_rata(i)); - err = (was ? r.rewrite() : r.write()); - } - // erase possible rates > current n. rates - for (;err == NOERR;i++) - { - r.zero(); s.format("%s%3d",(const char*)_code, i); - r.put("CODTAB", (const char*)s); - if (r.read() == NOERR) err = r.remove(); - else break; - } - return err; -} - -int TPagamento::remove(TTable& r) -{ - TString s(16); int err = NOERR; - for (int i = 0 ; err == NOERR; i++) - { - r.zero(); s.format("%s%3d",(const char*)_code, i); - r.put("CODTAB", (const char*)s); - if (r.read() == NOERR) err = r.remove(); - else break; - } - return err; -} - -void TPagamento::set_rate_auto() -{ - // vedi rate esistenti e tipo prima rata - // deve fare riferimento ad un tipo pagamento esistente - // e sensato - int first = 0; - - real toslice = _firstr; - - if (n_rate() == 0 || !_inited || (_tpr > 3 && n_rate() == 1)) return; - if (_tpr > 3) // ripartisci _firstr su tutte le rate - { - first = 1; - toslice = _secndr; - } - - _slicer.init(toslice); - - if (_tpr > 3) - // prima rata obbligatoria - set_imprata(0, _firstr); - - // se rate uguali dividi l'importo totale per il numero di rate - real r1(0.0), ro(0.0); - if (!_rdiff) - { - int rut = _tpr > 3 ? n_rate() - 1 : n_rate(); - ro = toslice/real(rut); ro.trunc(_round); - r1 = ro + (toslice - (ro*real(rut))); - } - - for (int i = first; i < n_rate(); i++) - // setta le fette e le date di scadenza - set_imprata(i, _rdiff ? _slicer.get() : (i == first ? r1 : ro)); - - // se e' nei primi tre casi, si somma l'importo da non dividere alla - // prima rata - if (_tpr > 0 && _tpr < 4) - set_imprata(0, tpay_rata(0) + _firstr); -} - - - -void TPagamento::set_total(const real& imponibile, const real& imposta, const real& spese) -{ - _imponibile = imponibile; - _imposta = imposta; - _spese = spese; - _inited = TRUE; - - // istanzia _firstr e _secndr a seconda di _tpr - switch(_tpr) - { - case 0: - _firstr = _imponibile + _imposta + _spese; - _secndr = 0.0; - break; - case 1: - _firstr = _imposta; - _secndr = _imponibile + _spese; - break; - case 2: - _firstr = _spese; - _secndr = _imposta + _imponibile; - break; - case 3: - _firstr = _imposta + _spese; - _secndr = _imponibile; - break; - case 4: - _firstr = _spese + _imponibile; - _secndr = _imposta; - break; - case 5: - _firstr = _imponibile + _imposta; - _secndr = _spese; - break; - case 6: - _firstr = _imponibile; - _secndr = _imposta + _spese; - break; - } - - real toslice = _tpr > 1 ? _secndr : _firstr; - - _slicer.init(toslice, TRUE); - - for (int i = 0; i < _rate.items(); i++) - { - TToken_string& t = (TToken_string&)_rate[i]; - real rr(t.get(1)); - _slicer.add(rr); - } -} - - -void TPagamento::set_sheet(TSheet_field& sf, int sscad) -{ - sf.destroy(-1); - if (_inited && _rate.items() > 0) - { - // si istanzia uno sheet di primanota - for (int i = 0; i < n_rate(); i++) - { - TToken_string& ts = sf.row(-1); - // istanzia, o stronzo - ts.add((const char*)data_rata(i)); - ts.add(perc_rata(i).string()); - ts.add(tpay_rata(i).string()); - ts.add(tipo_rata(i)); - ts.add(desc_tipo(tipo_rata(i))); - if (ratapagata(i)) - { - sf.disable_cell(1,1); // percentuale - sf.disable_cell(1,2); // importo - } - } - } - else if (_rate.items() > 0) // not inited: set edit sheet - { - for (int i = 0, scr = 0; i < n_rate(); i++) - { - TToken_string& s = sf.row(-1); - scr += scad_rata(i); - s.add(scr); - s.add(perc_rata(i).string()); - s.add(tipo_rata(i)); - s.add(desc_tipo(tipo_rata(i))); - s.add(ulc_rata(i)); - } - } - else // new: set with 1 or 2 rates according to tpr - { - if (_tpr > 3) - add_rata(ZERO, sscad == -1 ? 0 : sscad, _def_tpr, _def_ulc); - add_rata(real(100.0), sscad == -1 ? (_tpr < 4 ? 0 : 30) : sscad, _def_tpr, _def_ulc); - - _dirty = TRUE; - - for (int i = 0, scr = 0; i < n_rate(); i++) - { - TToken_string& s = sf.row(-1); - scr += scad_rata(i); - s.add(scr); - s.add(perc_rata(i).string()); - s.add(tipo_rata(i)); - s.add(desc_tipo(tipo_rata(i))); - s.add(ulc_rata(i)); - } - } - if (_tpr > 3) - { - // disabilita campi da non toccare sulla prima rata - if (_inited) - { - sf.disable_cell(0,1); // percentuale - sf.disable_cell(0,2); // importo - } - else - { - sf.disable_cell(0,1); // percentuale - } - } - sf.force_update(); -} - -TPagamento::TPagamento(const char* codtab, const char* data) : -_slicer(0.0,0), _new(FALSE), _imponibile(0.0), _imposta(0.0), -_spese(0.0), _code(codtab), _dirty(FALSE), _inited(FALSE), -_def_tpr(1), _def_ulc(""), _round(0), _int_rate(30) -{ - _fixd[0] = _fixd[1] = _fixd[2] = 0; - if (data != NULL) - _inizio = data; - if (_code.blank() || !read()) - _new = TRUE; -// if (_new && data != NULL) error_box("Modalita' pagamento inesistente"); -} - - -/////////////////////////////////////////////////////////// -// TTree_rectype -/////////////////////////////////////////////////////////// - -TTree_rectype::TTree_rectype(const TRectype& testa, const TRectype& riga, const char* num) - : TRectype(testa), _recarr(riga, num) -{ -} - -TTree_rectype::TTree_rectype(int testa, int riga, const char* num) - : TRectype(testa), _recarr(riga, num) -{ -} - -TTree_rectype::TTree_rectype(const TTree_rectype& t) - : TRectype(t), _recarr(t._recarr) -{ -} - - -TObject* TTree_rectype::dup() const -{ - TTree_rectype* r = new TTree_rectype(*this); - return r; -} - -void TTree_rectype::copy_key_to_row(TRectype& row) const -{ - const int numkey = 0; // Memento! Gli indici delle chiavi partono da zero! - RecDes* recd = rec_des(); // Descrizione del record della testata - - row.zero(); - for (int i = 0; i < recd->Ky[numkey].NkFields; i++) - { - const KeyDes& kd = recd->Ky[numkey]; - const int nf = kd.FieldSeq[i] % MaxFields; - const RecFieldDes& rf = recd->Fd[nf]; - const char* name = rf.Name; - const TString& val = get(name); - row.put(name, val); - } -} - -int TTree_rectype::fill_array() -{ - TRectype* row = (TRectype*)_recarr.key().dup(); - copy_key_to_row(*row); - const int err = _recarr.read(row); - return err; -} - - -int TTree_rectype::read(TBaseisamfile& f, word op) -{ - int err = TRectype::read(f, op); - if (err == NOERR) - fill_array(); - else - _recarr.destroy_rows(); - return err; -} - -int TTree_rectype::next(TBaseisamfile& f) -{ - int err = TRectype::next(f); - if (err == NOERR) - fill_array(); - else - _recarr.destroy_rows(); - return err; -} - -int TTree_rectype::write(TBaseisamfile& f) const -{ - int err = TRectype::write(f); - if (err == NOERR) - err = _recarr.write(); - return err; -} - -int TTree_rectype::rewrite(TBaseisamfile& f) const -{ - int err = TRectype::rewrite(f); - if (err == NOERR) - err = _recarr.rewrite(); - return err; -} - -int TTree_rectype::remove(TBaseisamfile& f) -{ - int err = TRectype::remove(f); - if (err == NOERR) - err = _recarr.remove(); - return err; -} - - -/////////////////////////////////////////////////////////// -// TRiga_scadenze -/////////////////////////////////////////////////////////// - -TRiga_scadenze::TRiga_scadenze(TRiga_partite* r) - : TTree_rectype(LF_SCADENZE, LF_PAGSCA, "NRIGP"), _riga(r) -{ - CHECK(_riga, "Riga nulla"); -} - -TRiga_scadenze::TRiga_scadenze(const TRiga_scadenze& s) - : TTree_rectype(s), _riga(s._riga) - -{ - CHECK(_riga, "Riga nulla"); -} - -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; - - sum.update(old_abb, new_abb, PART_SEZABB, PART_ABBUONI); - - new_diffcam = calcola_differenza_cambio(TRUE); - sum.update(old_diffcam, new_diffcam, PART_SEZDIFCAM, PART_DIFFCAM); - - 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(TPartita* game) - : TTree_rectype(LF_PARTITE, LF_SCADENZE, "NRATA"), _partita(game) -{ - CHECK(_partita, "Partita nulla"); -} - -TRiga_partite::TRiga_partite(const TRiga_partite& r) - : TTree_rectype(r), _partita(r._partita) -{ - CHECK(_partita, "Partita nulla"); -} - - -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(this); - copy_key_to_row(*s); - err = _recarr.read(s); // Deve esistere almento una scadenza -#ifdef DBG - if (_recarr.rows() == 0) - yesnofatal_box("Riga di fattura senza nessuna scadenza"); -#endif - } - else - _recarr.destroy_rows(); - return err; -} - -int TRiga_partite::ultimo_pagamento(int r) const -{ - const TRiga_scadenze& s = rata(r); - return s.rows_array().last_row(); -} - -bool TRiga_partite::update(const TRectype& vec, const TRectype& nuo, const char* field) -{ - real totale(get(field)); - totale -= vec.get_real(field); - totale += nuo.get_real(field); - put(field, totale); - return totale.is_zero(); -} - -bool TRiga_partite::update(const TImporto& vec, const TImporto& nuo, - const char* sez, const char* val) -{ - bool zero = FALSE; - TImporto grow(nuo); grow -= vec; // Variazione al totale - - if (!grow.is_zero()) - { - const char sezione = get_char(sez); // Sezione del totale - TImporto totale; - if (sezione > ' ') // Se c'era una sezione (e quindi un importo) ... - totale.set(sezione, get_real(val)); // ... inizializza il totale - else - CHECKS(vec.is_zero(), "Sezione errata per l'importo ", val); - totale += grow; // incrementa il totale - totale.normalize(); - put(sez, totale.sezione()); // Aggiorna il totale sul record - put(val, totale.valore()); - zero = totale.is_zero(); - } - else - zero = get_real(val).is_zero(); - - return zero; -} - - - -/////////////////////////////////////////////////////////// -// TPartita -/////////////////////////////////////////////////////////// - -TPartita::TPartita(const TBill& clifo, int anno, const char* num) - : _part(LF_PARTITE, PART_NRIGA), _unassigned(LF_PAGSCA, "NRIGP") -{ - read(clifo, anno, num); -} - -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(this); // Record campione della partita - partita->put(PART_TIPOCF, clifo.tipo()); // Tipo clifo - if (clifo.tipo() <= ' ') - { - partita->put(PART_GRUPPO, clifo.gruppo()); // Scrivi gruppo e conto solamente - partita->put(PART_CONTO, clifo.conto()); // nei conti normali (no clifo) - } - partita->put(PART_SOTTOCONTO, clifo.sottoconto()); // Sottoconto o codice clifo - partita->put(PART_ANNO, anno); // Anno partita - partita->put(PART_NUMPART, num); // Numero partita - _part.read(partita); - -#ifdef DBG - for (int p = last(); p > 0; p = pred(p)) - CHECKD(riga(p)._partita == this, "Riga partite inconsistente", p); -#endif - - TRectype unas(LF_PAGSCA); // Record campione pagamenti non assegnati - unas.zero(); - unas.put(PART_TIPOCF, partita->get(PART_TIPOCF)); // Copia chiave partite - unas.put(PART_GRUPPO, partita->get(PART_GRUPPO)); - unas.put(PART_CONTO, partita->get(PART_CONTO)); - 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, 0); // Numeri magici di non assegamento - unas.put(SCAD_NRATA, 0); - _unassigned.read(unas); - - return ok(); -} - -bool TPartita::reread() -{ - TBill zio; - conto(zio); - const int year = anno(); - const TString16 num = numero(); - return read(zio, year, num); -} - -bool TPartita::write(bool re) -{ - const bool ok = _part.write(re); - return ok; -} - -TImporto TPartita::importo_speso(long nreg, int numrig) const -{ - TImporto imp; - - for (int r = _part.last_row(); r > 0; r = pred(r)) - { - const TRectype& pag = riga(r); - - const long reg = pag.get_long(PART_NREG); - if (reg == nreg) - { - const int num = pag.get_int(PART_NUMRIG); - if (num == numrig) - { - imp = TImporto(pag.get_char(PART_SEZ), pag.get_real(PART_IMPORTO)); - break; - } - } - } - - return imp; -} - - -void TPartita::update_reg_num(long nreg, const TRectype& mov) -{ - for (int r = _part.last_row(); r > 0; r = pred(r)) - { - TRectype& pag = _part.row(r, FALSE); - - const long reg = pag.get_long(PART_NREG); - if (reg == nreg) - { - pag.put(PART_NREG, mov.get(MOV_NUMREG)); - pag.put(PART_DATAREG, mov.get(MOV_DATAREG)); - pag.put(PART_NUMDOC, mov.get(MOV_NUMDOC)); - pag.put(PART_DATADOC, mov.get(MOV_DATADOC)); - } - } -} - -// 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 -/////////////////////////////////////////////////////////// - -// Certified 99% -const TString& TPartite_array::key(const TBill& clifo, int anno, const char* num) -{ - if (clifo.tipo() > ' ') - _key.format("%c%3d%3d%6ld%4d%s", clifo.tipo(), 0, 0, clifo.sottoconto(), anno, num); - else - _key.format("%c%3d%3d%6ld%4d%s", - clifo.tipo(), clifo.gruppo(), clifo.conto(), clifo.sottoconto(), anno, num); - return _key; -} - -// Certified 99% -TPartita* TPartite_array::find(const TBill& clifo, int anno, const char* num, bool create) -{ - const TString& k = key(clifo, anno, num); - TPartita* p = (TPartita*)objptr(k); - if (p == NULL && create) - { - p = new TPartita(clifo, anno, num); - if (p->ok()) - add(k, p); - else - { - delete p; - p = NULL; - } - } - return p; -} - -TPartita* TPartite_array::find(const TRectype& r, bool create) -{ - TBill zio; zio.get(r); - const int anno = r.get_int(PART_ANNO); - const char* num = r.get_str(PART_NUMPART); - return find(zio, anno, num, create); -} - -TPartita& TPartite_array::partita(const TBill& clifo, int anno, const char* num) -{ - TPartita* game = find(clifo, anno, num, TRUE); - CHECKS(game, "Partita errata ", num); - return *game; -} - -TPartita& TPartite_array::partita(const TRectype& r) -{ - TPartita* game = find(r, TRUE); - CHECK(game, "Partita errata"); - return *game; -} - -bool TPartite_array::write(bool re) -{ - int err = NOERR; - - TPartita* game; - restart(); - while ((game = (TPartita*)get()) != NULL) - { - err = game->write(re); - if (err != NOERR) // L'errore viene gia' segnalato dalla partita - break; - } - - return err == NOERR; -} - -// Aggiunge all'array tutte le partite che si riferiscono alla registrazione nreg -int TPartite_array::add_reg_num(long nreg, int numrig) -{ - TRelation rel(LF_PARTITE); - TRectype& part = rel.lfile().curr(); - - // Costruzione filtro del cursore - part.zero(); - part.put(PART_NREG, nreg); - if (numrig > 0) - part.put(PART_NUMRIG, numrig); - - const TRectype filter(part); - - TCursor cur(&rel, "", 2, &filter, &filter); - - for (cur = 0; cur.ok(); ++cur) - partita(part); // Aggiungi partita se non esiste gia' - - return (int)cur.items(); -} - -TImporto TPartite_array::importo_speso(long nreg, int numrig) -{ - TImporto imp; - add_reg_num(nreg, numrig); - for (TPartita* game = first(); game; game = next()) - imp += game->importo_speso(nreg, numrig); - return imp; -} - -void TPartite_array::update_reg_num(long nreg, const TRectype& mov) -{ - add_reg_num(nreg, 0); - for (TPartita* game = first(); game; game = next()) - game->update_reg_num(nreg, mov); -} - - \ No newline at end of file +#include + +#include "pagament.h" + +#include +#include +#include +#include + + +int TPagamento::_rata_ifield(int n, int f) const +{ + TToken_string& t = (TToken_string&)_rate[n]; + return t.get_int(f); +} + +real TPagamento::_rata_rfield(int n, int f) const +{ + TToken_string& t = (TToken_string&)_rate[n]; + return real(t.get(f)); +} + +TDate TPagamento::_rata_dfield(int n, int f) const +{ + TToken_string& t = (TToken_string&)_rate[n]; + return TDate(t.get(f)); +} + +const char* TPagamento::_rata_sfield(int n, int f) const +{ + static char kak[6]; + TToken_string& t = (TToken_string&)_rate[n]; + strcpy(kak,t.get(f)); + return kak; +} + + +bool TPagamento::ratapagata(int n) +{ + TToken_string& t = (TToken_string&)_rate[n]; + return t.items() > 6; +} + + + +void TPagamento::set_intervallo_rate(int in) +{ + _dirty = TRUE; + _int_rate = in; + if (_mcomm && (in % 30) != 0) + _mcomm = FALSE; + for (int i = 0; i < n_rate(); i++) + { + TToken_string& ts = rata(i); + ts.add(i == 0 ? (scad_rata(0) == 0 ? "0" : format("%d",in)) + : format("%d",in), 0); + } +} + +void TPagamento::set_mese_commerciale(bool v, int& sscad) +{ + _dirty = FALSE; + if (_mcomm == v) return; + if (sscad == -1) sscad = 30; + + if ((sscad % 30) != 0) sscad = 30 * ((sscad/30)+1); + set_intervallo_rate(sscad); + + _mcomm = v; +} + +void TPagamento::set_rate_differenziate(int v) +{ + _dirty = FALSE; + if (!_rdiff && v == 2) return; + + if (v == 2 && (100 % n_rate()) == 0) + { + int p = 100 / n_rate(); + for (int i = _tpr < 4 ? 0 : 1; i < n_rate(); i++) + { + TToken_string& tt = rata(i); + tt.add(p,1); + } + _rdiff = !(v == 2); + _dirty = TRUE; + } +} + +void TPagamento::set_tipo_prima_rata(int v, int sscad) +{ + _dirty = FALSE; + if (_tpr == v) return; + + if (v < 4 && _tpr > 3) + { + for (int i = n_rate() - 1; i > 0; i--) + { + TToken_string& tt = rata(i); + tt.add(scad_rata(i-1),0); + tt.add(tipo_rata(i-1),2); + tt.add(ulc_rata(i-1),5); + } + _rate.add(NULL,0); + _rate.pack(); + } + else if ( _tpr < 4 && v > 3) + { + TToken_string* ttn = new TToken_string(32); + ttn->add(0,0); + ttn->add(0,1); + ttn->add(1,2); + ttn->add("",3); + ttn->add("",4); + ttn->add("",5); + _rate.insert(ttn,0); + for (int i = 0; i < (n_rate()-1); i++) + { + TToken_string& tt = rata(i); + tt.add(scad_rata(i+1),0); + tt.add(tipo_rata(i+1),2); + tt.add(ulc_rata(i+1),5); + } + } + _tpr = v; + _dirty = TRUE; +} + +void TPagamento::set_numero_rate(int n, int sscad) +{ + _dirty = FALSE; + if (n == 0 || n == n_rate()) return; + + real p = real(100) / real(n); + p.round(2); + int nr = n_rate(); + int first = _tpr < 4 ? 0 : 1; + real sum = 0.0; + + for (int i = first; sum < real(100.0); i++) + { + if ((real(100.0) - sum) < p) + p = real(100.0) - sum; + + sum += p; + + // if necessary add remainder on first one + if ((real(100.0) - sum) /* still */ < p) + { + real prc = perc_rata(first); + prc += real(100.0) - sum; + TToken_string& rt = rata(first); + rt.add(prc.string(),1), + sum = 100; + } + + set_rata(i, real(p), + i == 0 ? (i < nr ? scad_rata(0) : 0): + (sscad == -1 ? (i < nr ? scad_rata(i) : scad_rata(nr-1)) : sscad), + (i < nr ? tipo_rata(i) : tipo_rata(nr-1))); + } + // erase remaining + for (; i < nr; i++) + _rate.add(NULL,i); + _rate.pack(); + + _dirty = TRUE; +} + + +void TPagamento::next_scad(TDate& d, int scad, bool mcomm, int rata) +{ + if (mcomm) + { + int nm = scad / 30; + int ny = nm / 12; + nm %= 12; + + int newm = d.month() + nm; + if (newm > 12) { newm -= 12; ny++; } + + bool last = d.is_end_month() && inizio_scadenza() == 'M'; + + int dy = d.day(); + + // la palla del febbraio & c. + if (rata > 1) + { + TDate oldd(data_rata(rata-2)); + if (oldd.day() > dy) dy = oldd.day(); + } + + d.set_day(1); // il giorno 1 ce l'hanno tutti + d.set_month(newm); + d.set_year(d.year()+ny); + + d.set_end_month(); + if (!last && dy < d.day()) + d.set_day(dy); + } + else + { + d += scad; + } + + // riaggiusta la minchia se ci sono scadenze fissate + if (_fixd[0] != 0 || _fixd[1] != 0 || _fixd[2] != 0) + { + for (int i = 0; i < 3; i++) + { + if (_fixd[i] > d.day()) + { + if (d.last_day(d.month(), d.year()) <= _fixd[i]) + d.set_day(_fixd[i]); + else d.set_end_month(); + break; + } + } + + if (i == 3) + { + if (_fixd[0] > 0 && _fixd[0] < d.day()) + { + d.set_day(_fixd[0]); + d.set_month(d.month() == 12 ? 1 : d.month() + 1); + } + } + + } +} + + +void TPagamento::set_default_type(int type, bool change_existing) +{ + _def_tpr = type; + if (change_existing) + { + for (int i = 0; i < n_rate(); i++) + { + TToken_string& tt = rata(i); + tt.add(type, 2); + } + _dirty = TRUE; + } +} + +void TPagamento::set_default_ulc(const char* ulc, bool change_existing) +{ + _def_ulc = ulc; + if (change_existing) + { + for (int i = 0; i < n_rate(); i++) + { + TToken_string& tt = rata(i); + tt.add(ulc, 5); + } + _dirty = TRUE; + } +} + +void TPagamento::remove_rata(int i) +{ + // non fa nessun ricalcolo, si limita ad impacchettare se + // necessario + _rate.add(NULL,i); + _rate.pack(); + _dirty = TRUE; +} + +TToken_string& TPagamento::add_rata(real perc, int day, int type, const char* ulc) +{ + TToken_string* tt = new TToken_string(16); + tt->add(day); // scadenza + tt->add(perc.string()); // percentuale + tt->add(type); // tipo + tt->add(""); + tt->add(""); + tt->add(ulc); + _rate.add(tt); + _dirty = TRUE; + return *tt; +} + +TToken_string& TPagamento::set_rata (int index, real perc, int day, int type, + const char* ulc, const char* imp, + const char* data) +{ + TToken_string* tt = (TToken_string*)_rate.objptr(index); + const bool nwr = (tt == NULL); + if (nwr) tt = new TToken_string(16); + + tt->add(day,0); // scadenza + tt->add(perc.string(),1); // percentuale + tt->add(type,2); // tipo + tt->add(data == NULL ? "" : data,3); + tt->add(imp == NULL ? "" : imp,4); + tt->add(ulc == NULL ? "" : ulc,5); + + if (!nwr) + { + if (index > _rate.items()) + { + error_box("Rate non contigue"); + delete tt; + } + } + else + { + _rate.add(tt,index); + _dirty = TRUE; + } + return *tt; +} + +void TPagamento::set_imprata(int i, real r) +{ + TToken_string& tt = (TToken_string&)_rate[i]; + TDate d = _inizio; + + for (int n = 0; n <= i; n++) + next_scad(d, scad_rata(n), _mcomm, n); + + tt.add((const char*)d, 3); + tt.add(r.string(), 4); +} + +TToken_string& TPagamento::set_rata(int index, const real& howmuch, + const TDate& date, int type,const char* ulc, bool pagato) +{ + // calcola percentuali e scadenze a partire dagli importi + TToken_string* tt = (TToken_string*)_rate.objptr(index); + + const bool nwr = (tt == NULL); // nuova rata + + if (nwr) tt = new TToken_string(16); + + TDate oldd = index > 0 ? data_rata(index -1) : _inizio; + int day = date - oldd; + real toshare(_tpr < 4 ? _firstr : _secndr); + real perc = (_tpr > 3 && index == 0) ? ZERO : howmuch/toshare; + perc *= real(100.0); + perc.round(2); + + tt->add(day,0); // scadenza + tt->add(perc.string(),1); // percentuale + tt->add(type,2); // tipo + tt->add(date.string(),3); + tt->add(howmuch.string(),4); + tt->add(ulc,5); + if (pagato) tt->add("X",6); + + if (!nwr) + { + if (index > _rate.items()) + { + error_box("Rate non contigue"); + delete tt; + } + } + else + { + _rate.add(tt, index); + _dirty = TRUE; + } + return *tt; +} + + + +word TPagamento::validate() const +{ + word res = 0x0000; + real r(0.0); + + int first = _tpr < 4 ? 0 : 1; + real toshare(_tpr < 4 ? _firstr : _secndr); + TDistrib ds(toshare,0); + + // check percentages & prepare slicer + for (int i = first; i < n_rate(); i++) + { + real p(perc_rata(i)); + ds.add(p); + r += p; + } + + if (r != real(100.0)) + res |= P_RSUM; + + + if (_inited) + { + ds.init(toshare); + // check importi rate consistenti con la percentuale + for (int i = first; i < n_rate(); i++) + { + real r1(tpay_rata(i)); + real r2(ds.get()); + if (r1 != r2) + { res |= P_IMPNC; break; } + } + + // check errori date scadenze (se istanziate) + TDate d(data_rata(0)); + if (d < _inizio) + res |= P_INIZIO; + for (i = 1; i < n_rate(); i++) + { + if (data_rata(i) <= d) + { res |= P_SCAD; break; } + d = data_rata(i); + } + } + return res; +} + + +void TPagamento::strerr(word err, TString& s) +{ + s = "Errore:"; + if (err & P_RSUM) + s << "\n Le percentuali non sommano a 100"; + if (err & P_IMPNC) + s << "\n Le percentuali sono inconsistenti con gli importi"; + if (err & P_SCAD) + s << "\n Le scadenze non sono consecutive"; + if (err & P_INIZIO) + s << "\n La prima rata e' antecedente alla data movimento"; +} + +const char* TPagamento::desc_tpr() const +{ + const char* o; + switch (_tpr) + { + case 0: o = "Totale su tutte le rate"; break; + case 1: o = "Tutte le imposte su 1a"; break; + case 2: o = "Tutte le spese su 1a"; break; + case 3: o = "Imposte + spese su 1a"; break; + case 4: o = "Spese + merce su 1a"; break; + case 5: o = "Merce + imposte su 1a"; break; + case 6: o = "Tutta la merce su 1a"; break; + default: o = ""; break; + } + return o; +} + +const char* TPagamento::desc_tipo(int i) const +{ + const char* o; + switch (i) + { + case 1: o = "Rimessa diretta o contanti"; break; + case 2: o = "Tratta"; break; + case 3: o = "Ricevuta bancaria"; break; + case 4: o = "Cessione"; break; + case 5: o = "Paghero'"; break; + case 6: o = "Lettera di credito"; break; + case 7: o = "Tratta accettata"; break; + case 8: o = "Rapporti interbancari diretti"; break; + case 9: o = "Bonifici"; break; + case 10: o = "Altro pagamento"; break; + } + return o; +} + +word TPagamento::recalc_rate(int row, bool is_perc_modified, + const char* new_value, const char* scad, + const char* typ, int rdiff, bool mcomm, + bool& need_recalc) + // ricalcola le rate sulla base di parametri modificati sulla riga row + // parametri: tutti i const char* possono essere NULL, il che vuol dire + // che i dati corrispondenti non sono stati modificati; + // se new_value non e' NULL puo' essere la percentuale (e + // allora is_perc_modified e' TRUE) o l'importo. Non e' + // possibile modificare entrambi; se succede viene data + // priorita' alla percentuale. +{ + CHECK(!(!is_perc_modified && new_value != NULL && !_inited), + "A'stronzo! E famme 'na pippa! Me dai n'importo che nun ce sta? Ma Vaffanculo!"); + + if (_rate.items() == 0) return P_OK; + + real rsum(0.0), newv(0.0), rmax(0.0); + int oldtype = tipo_rata(0); + int oldscad = scad_rata(0); + TDate lastdate = data_rata(0); + int first = _tpr < 4 ? 0 : 1; + TArray srate(_rate); // rate come erano + + + if (srate.items() > 1) + { + // calcola defaults per tipo pagamento e scadenza + // nel caso di rate nuove + oldscad = scad_rata(1); + } + + if (oldscad == 0) oldscad = 30; + if (oldtype == 0) oldtype = 1; + + if (new_value != NULL) + { + newv = new_value; + rmax = is_perc_modified? (real) 100.0 : (_tpr < 4 ? _firstr : _secndr); + if (newv > rmax) return P_RSUM; + } + + bool exhausted = FALSE; + + for (int i = first; i < srate.items(); i++) + { + if (i == row) + { + if (typ != NULL) + { + TToken_string& tt = rata(row); + TToken_string& ss = (TToken_string&)srate[row]; + tt.add(typ,2); + ss.add(typ,2); + // no error is possible + } + + if (scad != NULL) + { + // if !_inited scad e' il n. giorni, se no e' la rata + if (_inited) + { + TToken_string& tt = rata(row); + TToken_string& ss = (TToken_string&)srate[row]; + lastdate = scad; + // controlla errore sulla data scadenza + if (i > 0) + { + oldscad = (int)(lastdate - data_rata(i-1)); + if (oldscad <= 0l) return P_SCAD; + } + else if (lastdate < _inizio) return P_INIZIO; + tt.add(scad,3); + ss.add(scad,3); + // ricalcola rate successive: se si vuole modificarne solo una + // ci si fotte e si disabilita il ricalcolo + TDate ddd (lastdate); + for (int j = row+1; j < srate.items(); j++) + { + TToken_string& tt = rata(j); + TToken_string& ss = (TToken_string&)srate[j]; + next_scad(ddd,scad_rata(j),mcomm,j); + tt.add(ddd.string(),3); + ss.add(ddd.string(),3); + need_recalc = TRUE; + } + } + else + { + // nulla di speciale visto che si memorizza la derivata + int sc = atoi(scad); + for (int i = 0; i < row; i ++) + sc -= scad_rata(i); + if (sc < 0 || (row > 0 && sc == 0)) return P_SCAD; + if (_mcomm && (sc % 30) != 0) _mcomm = FALSE; + TToken_string& tt = rata(row); + TToken_string& ss = (TToken_string&)srate[row]; + tt.add(sc,0); + ss.add(sc,0); + need_recalc = TRUE; + } + } + + // here's the bell + if (new_value != NULL) + { + if (newv == ZERO || (rsum+newv) > rmax) + return P_RSUM; + // did not sforate + rsum += newv; + TToken_string& rt = rata(row); + // setta nuovo valore e ricalcola cio' che ne consegue + if (is_perc_modified) rt.add(new_value,1); + else rt.add(new_value,4); + // riaggiusta le rate rimanenti + real remainder(0.0); remainder = rmax - rsum; + if (!(exhausted = (remainder == real(0.0)))) + { + // se inited e scelto UGUALI (2) occorre dividere in N e + // aggiungere il resto sulla 1a rata + // controlla se rdiff e' compatibile con + // i dati e se e' il caso riaggiusta + if (rdiff == 3 && !((remainder % newv.integer()) == ZERO)) + rdiff = 2; +// *** 10/8/95: se uguali e non e' multiplo intero lo teniamo cosi' e poi +// *** aggiungiamo alla prima rata utile +// if (rdiff == 2 && !((rmax % newv.integer()) == ZERO)) +// rdiff = 1; + _rdiff = (rdiff == 1 || rdiff == 3 || rdiff == 4); + + // procedi + if (rdiff == 1) + { + // cancella tutte le rate successive, aggiungi un'unica rata + // con il resto dell'importo + if (row < (srate.items()-1)) + { + TToken_string& trt = rata(row+1); + trt.add(remainder.string(), is_perc_modified ? 1 : 4); + for(int j = row+2; j < srate.items(); j++) + _rate.add(NULL,j); + } + else + { + // l'importante e' esagerare + for(int j = row+1; j < srate.items(); j++) + _rate.add(NULL,j); + + TToken_string& trt = add_rata(is_perc_modified ? remainder : (real) 0.0, + oldscad, oldtype); + if (!is_perc_modified) trt.add(remainder.string(),4); + if (_inited) + { + TDate dd = data_rata(row); + next_scad(dd,oldscad,mcomm,row); + trt.add(dd.string(),3); + } + } + } + else // rate non differenziate (dall'inizio o da row) + { + // ripartisci l'importo nel numero necessario di rate per + // mantenere costante il valore + real sum(0.0); + if (_inited) lastdate = data_rata(rdiff == 2 ? first : row); + + TDate dd(lastdate); + int type = oldtype; + int nscd = oldscad; + + int frs = (rdiff == 3 || rdiff == 4) ? row+1 : first; + real mx = (rdiff == 3 || rdiff == 4) ? remainder : rmax; + + // cancelliamo tutto, va' + for (int j = frs; j < srate.items(); j++) + _rate.add(NULL,j); + + if (rdiff != 4) + for (j = frs; sum < mx; j++) + { + // TBI: qui mod se rdiff == 2 + // se c'e' la vecchia rata si tengono i parametri + // altrimenti si calcolano + if (j < srate.items()) + { + TToken_string& trt = (TToken_string&)srate[j]; + if (_inited) dd = trt.get(3); + type = atoi(trt.get(2)); + nscd = j == 0 ? 0 : atoi(trt.get(0)); + if (type == 0) type = 1; + if (j > 0 && nscd == 0) nscd = oldscad; + if (_inited && dd == lastdate && j > 0) + next_scad(dd,nscd,mcomm,j); + } + else if (_inited) + { + if (dd <= botime) dd = lastdate; + next_scad(dd,nscd,mcomm,j); + } + else nscd = _int_rate; + + TToken_string& ttr = set_rata(j, is_perc_modified ? newv : ZERO, + nscd, type); + if (_inited) + ttr.add(dd.string(), 3); + if (!is_perc_modified) + { + ttr.add(newv.string(),4); + } + if ((mx - sum) < newv) + { + // add remainder on first rate + newv += (mx - sum); + if (!is_perc_modified) + set_imprata(frs, newv); + else { + TToken_string& t = rata(frs); + t.add(newv.string(), 1); + } + remove_rata(j); + break; + } +// } + sum += newv; + } + else // rdiff == 4; uguali finche' possibile + { + bool basta = FALSE; + for (j = frs; ; j++) + { + // ultima rata puo' differire dalle precedenti + if (mx - sum <= newv) + { + newv = mx - sum; + basta = TRUE; + } + // se c'e' la vecchia rata si tengono i parametri + // altrimenti si calcolano + if (j < srate.items()) + { + TToken_string& trt = (TToken_string&)srate[j]; + if (_inited) dd = trt.get(3); + type = atoi(trt.get(2)); + nscd = j == 0 ? 0 : atoi(trt.get(0)); + if (type == 0) type = 1; + if (j > 0 && nscd == 0) nscd = oldscad; + if (_inited && dd == lastdate && j > 0) + next_scad(dd,nscd,mcomm,j); + } + else if (_inited) next_scad(dd,nscd,mcomm,j); + + TToken_string& ttr = set_rata(j, is_perc_modified ? newv : ZERO, + nscd, type); + if (_inited) + ttr.add(dd.string(), 3); + if (!is_perc_modified) + ttr.add(newv.string(),4); + if (basta) break; + sum += newv; + } + } + } + + } + else // exhausted + { + for(int j = row+1; j < srate.items(); j++) + _rate.add(NULL,j); + } + + + if (_inited) + { + // ricalcola il valore secondario (non modificato) + real toshare(100.0); + if (is_perc_modified) + toshare = (_tpr < 4 ? _firstr : _secndr); + TDistrib dt(toshare, is_perc_modified ? _round : 3); + + for (int j = first; j < _rate.items(); j++) + { + real rvl = is_perc_modified ? perc_rata(j) : tpay_rata(j); + real zpx = rvl/rmax; // percentuale + dt.add(zpx); + } + for (j = first; j < _rate.items(); j++) + { + TToken_string& tr = rata(j); + real rvl = dt.get(); + tr.add(rvl.string(), is_perc_modified ? 4 : 1); + } + + // se e' il caso aggiungi l'importo fisso sulla prima rata + if (_inited && _tpr > 0 && _tpr < 4) + { + TToken_string& tr = rata(0); + real tot = tpay_rata(0) + _firstr; + tr.add(tot.string(), 4); + } + + } + + need_recalc = TRUE; + return P_OK; + } // new_value != NULL + } + else // i != row modified + { + if (i > 0 && !((perc_rata(i-1) == perc_rata(i)))) + { + if (rdiff == 2) rdiff = 1; + _rdiff = FALSE; + } + if (is_perc_modified) + rsum += perc_rata(i); + else + rsum += tpay_rata(i); + + lastdate = data_rata(i); + oldtype = tipo_rata(i); + oldscad = scad_rata(i); + if (_inited && i > 0) + { + if (data_rata(i) <= data_rata(i-1)) + return P_SCAD; + } + else if (lastdate < _inizio) + return P_INIZIO; + } + } + + return P_OK; +} + + +bool TPagamento::read(TTable* t, TTable* r) +{ + // puo' chiamarla chiunque + bool istnew = FALSE; + if (t == NULL) + { + t = new TTable("%CPG"); + istnew = TRUE; + } + t->zero(); t->put("CODTAB",_code); + if (t->read() != NOERR) return FALSE; + + _rate.destroy(); + + // set everything + _rdiff = t->get_bool("B1"); + _mcomm = t->get_bool("B0"); + _tpr = atoi(t->get("S3")); + _inscad = *((const char*)(t->get("S1"))); + _code = t->get("CODTAB"); + _name = t->get("S0"); + _fixd[0] = t->get_int("I0"); + _fixd[1] = t->get_int("I1"); + _fixd[2] = t->get_int("I2"); + + // TBI aggiusta _inizio secondo INSCAD; vedi mese commerciale etc. + if (_inscad == 'M') + { + if (_mcomm) _inizio.set_month(_inizio.month() == 2 ? 28 : 30); + else _inizio.set_end_month(); + } + else if (_inscad == 'F' && _mcomm && _inizio.month() == 31) + _inizio.set_month(30); + + // leggi rate e scadenze + bool isrnew = FALSE; + if (r == NULL) + { + r = new TTable("%RPG"); + isrnew = TRUE; + } + TString s(16); + + for (int i = 0; ;i++) + { + r->zero(); s.format("%s%3d",(const char*)_code, i); + r->put("CODTAB", (const char*)s); + if (r->read() != NOERR) break; + TToken_string* tt = new TToken_string(16); + tt->add((const char*)(r->get("I0"))); // scadenza + tt->add((const char*)(r->get("R0"))); // percentuale + tt->add((const char*)(r->get("I1"))); // tipo + // data e importo + TDate d = _inizio; + next_scad(d,(int)(r->get_long("I0")),_mcomm,i); + tt->add((const char*)d); + tt->add(""); + tt->add(r->get("S1")); + _slicer.add((real)r->get("R0")); + _rate.add(tt); + } + + if (istnew) delete t; + if (isrnew) delete r; + + return TRUE; +} + + +int TPagamento::write(TTable& r) +{ + // Scrive soltanto le righe di pagamento; si assume sia stata chiamata da una + // relapp, che ha scritto il file principale + + TString s(16); int err = NOERR; + for (int i = 0; err == NOERR && i < n_rate(); i++) + { + r.zero(); s.format("%s%3d",(const char*)_code, i); + r.put("CODTAB", (const char*)s); + r.put("I0", (long)scad_rata(i)); + r.put("R0", perc_rata(i).string()); + r.put("I1", (long)tipo_rata(i)); + r.put("S1", ulc_rata(i)); + err = r.write(); + } + return err; +} + +int TPagamento::rewrite(TTable& r) +{ + TString s(16); int err = NOERR; + for (int i = 0; err == NOERR && i < n_rate(); i++) + { + r.zero(); s.format("%s%3d",(const char*)_code, i); + r.put("CODTAB", (const char*)s); + bool was = (r.read() == NOERR); + r.zero(); s.format("%s%3d",(const char*)_code, i); + r.put("CODTAB", (const char*)s); + r.put("I0", (long)scad_rata(i)); + r.put("R0", perc_rata(i).string()); + r.put("I1", (long)tipo_rata(i)); + r.put("S1", ulc_rata(i)); + err = (was ? r.rewrite() : r.write()); + } + // erase possible rates > current n. rates + for (;err == NOERR;i++) + { + r.zero(); s.format("%s%3d",(const char*)_code, i); + r.put("CODTAB", (const char*)s); + if (r.read() == NOERR) err = r.remove(); + else break; + } + return err; +} + +int TPagamento::remove(TTable& r) +{ + TString s(16); int err = NOERR; + for (int i = 0 ; err == NOERR; i++) + { + r.zero(); s.format("%s%3d",(const char*)_code, i); + r.put("CODTAB", (const char*)s); + if (r.read() == NOERR) err = r.remove(); + else break; + } + return err; +} + +void TPagamento::set_rate_auto() +{ + // vedi rate esistenti e tipo prima rata + // deve fare riferimento ad un tipo pagamento esistente + // e sensato + int first = 0; + + real toslice = _firstr; + + if (n_rate() == 0 || !_inited || (_tpr > 3 && n_rate() == 1)) return; + if (_tpr > 3) // ripartisci _firstr su tutte le rate + { + first = 1; + toslice = _secndr; + } + + _slicer.init(toslice); + + if (_tpr > 3) + // prima rata obbligatoria + set_imprata(0, _firstr); + + // se rate uguali dividi l'importo totale per il numero di rate + real r1(0.0), ro(0.0); + if (!_rdiff) + { + int rut = _tpr > 3 ? n_rate() - 1 : n_rate(); + ro = toslice/real(rut); ro.trunc(_round); + r1 = ro + (toslice - (ro*real(rut))); + } + + for (int i = first; i < n_rate(); i++) + // setta le fette e le date di scadenza + set_imprata(i, _rdiff ? _slicer.get() : (i == first ? r1 : ro)); + + // se e' nei primi tre casi, si somma l'importo da non dividere alla + // prima rata + if (_tpr > 0 && _tpr < 4) + set_imprata(0, tpay_rata(0) + _firstr); +} + + + +void TPagamento::set_total(const real& imponibile, const real& imposta, const real& spese) +{ + _imponibile = imponibile; + _imposta = imposta; + _spese = spese; + _inited = TRUE; + + // istanzia _firstr e _secndr a seconda di _tpr + switch(_tpr) + { + case 0: + _firstr = _imponibile + _imposta + _spese; + _secndr = 0.0; + break; + case 1: + _firstr = _imposta; + _secndr = _imponibile + _spese; + break; + case 2: + _firstr = _spese; + _secndr = _imposta + _imponibile; + break; + case 3: + _firstr = _imposta + _spese; + _secndr = _imponibile; + break; + case 4: + _firstr = _spese + _imponibile; + _secndr = _imposta; + break; + case 5: + _firstr = _imponibile + _imposta; + _secndr = _spese; + break; + case 6: + _firstr = _imponibile; + _secndr = _imposta + _spese; + break; + } + + real toslice = _tpr > 1 ? _secndr : _firstr; + + _slicer.init(toslice, TRUE); + + for (int i = 0; i < _rate.items(); i++) + { + TToken_string& t = (TToken_string&)_rate[i]; + real rr(t.get(1)); + _slicer.add(rr); + } +} + + +void TPagamento::set_sheet(TSheet_field& sf, int sscad) +{ + sf.destroy(-1); + if (_inited && _rate.items() > 0) + { + // si istanzia uno sheet di primanota + for (int i = 0; i < n_rate(); i++) + { + TToken_string& ts = sf.row(-1); + // istanzia, o stronzo + ts.add((const char*)data_rata(i)); + ts.add(tpay_rata(i).string()); + ts.add(perc_rata(i).string()); + ts.add(tipo_rata(i)); + ts.add(desc_tipo(tipo_rata(i))); + if (ratapagata(i)) + { + sf.disable_cell(1,1); // importo + sf.disable_cell(1,2); // percentuale + } + } + } + else if (_rate.items() > 0) // not inited: set edit sheet + { + for (int i = 0, scr = 0; i < n_rate(); i++) + { + TToken_string& s = sf.row(-1); + scr += scad_rata(i); + s.add(scr); + s.add(perc_rata(i).string()); + s.add(tipo_rata(i)); + s.add(desc_tipo(tipo_rata(i))); + s.add(ulc_rata(i)); + } + } + else // new: set with 1 or 2 rates according to tpr + { + if (_tpr > 3) + add_rata(ZERO, sscad == -1 ? 0 : sscad, _def_tpr, _def_ulc); + add_rata(real(100.0), sscad == -1 ? (_tpr < 4 ? 0 : 30) : sscad, _def_tpr, _def_ulc); + + _dirty = TRUE; + + for (int i = 0, scr = 0; i < n_rate(); i++) + { + TToken_string& s = sf.row(-1); + scr += scad_rata(i); + s.add(scr); + s.add(perc_rata(i).string()); + s.add(tipo_rata(i)); + s.add(desc_tipo(tipo_rata(i))); + s.add(ulc_rata(i)); + } + } + if (_tpr > 3) + { + // disabilita campi da non toccare sulla prima rata + if (_inited) + { + sf.disable_cell(0,1); // importo + sf.disable_cell(0,2); // percentuale + } + else + { + sf.disable_cell(0,1); // percentuale + } + } + sf.force_update(); +} + +TPagamento::TPagamento(const char* codtab, const char* data) : +_slicer(0.0,0), _new(FALSE), _imponibile(0.0), _imposta(0.0), +_spese(0.0), _code(codtab), _dirty(FALSE), _inited(FALSE), +_def_tpr(1), _def_ulc(""), _round(0), _int_rate(30) +{ + _fixd[0] = _fixd[1] = _fixd[2] = 0; + if (data != NULL) + _inizio = data; + if (_code.blank() || !read()) + _new = TRUE; +// if (_new && data != NULL) error_box("Modalita' pagamento inesistente"); +} \ No newline at end of file diff --git a/cg/pagament.h b/cg/pagament.h index 3ca84b1eb..77cb6a1a3 100755 --- a/cg/pagament.h +++ b/cg/pagament.h @@ -1,10 +1,6 @@ #ifndef __PAGAMENT_H #define __PAGAMENT_H -#ifndef __ASSOC_H -#include -#endif - #ifndef __MSKSHEET_H #include #endif @@ -17,10 +13,6 @@ #include #endif -#ifndef __CONTO_H -#include "conto.h" -#endif - // Error codes for pagation const word P_OK = 0x0000; // ok const word P_RSUM = 0x0001; // percentages do not sum up to 100 @@ -165,187 +157,4 @@ public: virtual ~TPagamento() {} }; - -#ifndef __PARTITE_H -#include -#endif - -class TTree_rectype : public TRectype -{ -protected: - TRecord_array _recarr; - - void copy_key_to_row(TRectype& row) const; - int fill_array(); - -protected: // TRectype - virtual TObject* dup() const; - - virtual int read(TBaseisamfile& f, word op = _isequal); - virtual int next(TBaseisamfile& f); - virtual int write(TBaseisamfile& f) const; - virtual int rewrite(TBaseisamfile& f) const; - virtual int remove(TBaseisamfile& f); - -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); } - - int last() const { return _recarr.last_row(); } - int pred(int r) const { return _recarr.pred_row(r); } - - TTree_rectype(const TRectype& testata, const TRectype& riga, const char* num); - TTree_rectype(int testata, int riga, const char* num); - TTree_rectype(const TTree_rectype& t); - virtual ~TTree_rectype() {} -}; - - -class TRiga_scadenze : public TTree_rectype -{ - 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 { CHECK(_riga, "Riga nulla"); return *_riga; } // Riga partite - - 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); - bool update(const TImporto& vec, const TImporto& nuo, const char* sez, const char* val); - -public: // TTree_rectype - 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); } - - int ultimo_pagamento(int rata) const; - char sezione() const { return get_char("SEZ"); } - - TPartita& partita() const { CHECK(_partita, "Partita nulla"); return *_partita; } - - TRiga_partite(TPartita* game); - TRiga_partite(const TRiga_partite& r); - virtual ~TRiga_partite() {} -}; - -class TPartita : public TObject -{ - TRecord_array _part; - TRecord_array _unassigned; - -public: // TObject - virtual bool ok() const { return _part.rows() > 0; } - -public: - 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); } - const TString& numero() const { return _part.key().get(PART_NUMPART); } - const TString& descrizione() const { return _part.key().get(PART_DESCR); } - - 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(); -}; - - -class TPartite_array : private TAssoc_array -{ - TString80 _key; // Work string - -protected: - const TString& key(const TBill& clifo, int anno, const char* num); // Build key for TAssoc_array - TPartita* find(const TBill& clifo, int anno, const char* numero, bool create); - TPartita* find(const TRectype& part, bool create); - -public: // TAssoc_array - virtual void destroy() { TAssoc_array::destroy(); } - -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); } - - int add_reg_num(long numreg, int numrig); - TImporto importo_speso(long numreg, int numrig); - void update_reg_num(long nreg, const TRectype& mov); - - TPartita* first() { restart(); return next(); } - TPartita* next() { return (TPartita*)get(); } - - TPartite_array() {} - virtual ~TPartite_array() {} -}; - #endif