diff --git a/cg/cg0200a.uml b/cg/cg0200a.uml index 48dd8ace4..3ccc47da5 100755 --- a/cg/cg0200a.uml +++ b/cg/cg0200a.uml @@ -178,7 +178,7 @@ END NUMBER F_STATOCF 3 BEGIN -PROMPT 2 8 "Comune:Stato " +PROMPT 2 8 "Comune: Stato " FIELD LF_CLIFO->STATOCF FLAGS "Z" USE %STA diff --git a/cg/cg2100.cpp b/cg/cg2100.cpp index dad824ecc..4aed55fd4 100755 --- a/cg/cg2100.cpp +++ b/cg/cg2100.cpp @@ -96,7 +96,9 @@ TMask* TPrimanota_application::load_mask(int n) TSheet_field& ps = (TSheet_field&)m->field(FS_RATESHEET); ps.set_notify(pag_notify); m->set_handler(FS_RESET, reset_handler); - m->set_handler(FS_NRATE, nrate_handler); + m->set_handler(FS_NRATE, nrate_handler); + m->set_handler(FS_NSCAB, codcab_handler); + m->set_handler(FS_VSCAB, codcab_handler); } case 1: if (m) diff --git a/cg/cg2100c.uml b/cg/cg2100c.uml index dd0b5e15c..0d2c14a6a 100755 --- a/cg/cg2100c.uml +++ b/cg/cg2100c.uml @@ -15,7 +15,7 @@ END BOOLEAN F_STAMPATO BEGIN - FIELD STAMPATO + FIELD STAMPATO FLAGS "H" END diff --git a/cg/cg2102.cpp b/cg/cg2102.cpp index 6ca0880e9..01081f640 100755 --- a/cg/cg2102.cpp +++ b/cg/cg2102.cpp @@ -1644,18 +1644,14 @@ bool TPrimanota_application::clifo_handler(TMask_field& f, KEY key) if (key == K_TAB && f.active()) { TMask& m = f.mask(); - - const char cf = app().clifo(); - TLocalisamfile& clifo = ((TEdit_field&)f).browse()->cursor()->file(); - if (clifo.get_char(CLI_TIPOCF) != cf || clifo.get(CLI_CODCF) != f.get()) - { - clifo.setkey(1); - clifo.put(CLI_TIPOCF, cf); - clifo.put(CLI_CODCF, f.get()); - clifo.read(); - CHECK(clifo.good(), "Impossibile ritrovare il clifo"); - } + const char cf = app().clifo(); + TRelation cliforel(LF_CLIFO); cliforel.add(LF_CFVEN, "TIPOCF=TIPOCF|CODCF=CODCF"); + TRectype& clifo = cliforel.curr(); + clifo.put(CLI_TIPOCF, cf); + clifo.put(CLI_CODCF, f.get()); + cliforel.read(); + if (!suspended_handler(f, key)) return FALSE; @@ -1671,6 +1667,21 @@ bool TPrimanota_application::clifo_handler(TMask_field& f, KEY key) const TString& s = clifo.get(CLI_CODPAG); if (s.not_empty()) m.set(F_CODPAG, s, TRUE); + + if (app().is_saldaconto()) + { + if (m.field(S_VALUTA).active()) + { + const TString& valuta = clifo.get(CLI_CODVAL); + if (valuta.not_empty()) + m.set(S_VALUTA, valuta, TRUE); + } + m.set(FS_VSABI, clifo.get(CLI_CODABI)); + m.set(FS_VSCAB, clifo.get(CLI_CODCAB)); + m.send_key(K_TAB, FS_VSCAB); + m.set(FS_AGENTE, cliforel.curr(LF_CFVEN).get(CLI_CODAG), TRUE); + m.send_key(K_TAB, FS_AGENTE); + } } const bool occas = clifo.get_bool(CLI_OCCAS); @@ -1682,18 +1693,6 @@ bool TPrimanota_application::clifo_handler(TMask_field& f, KEY key) if (f.focusdirty()) { app().add_cgs_tot(m); - - if (m.field(S_VALUTA).active()) - { - const TString16 valuta(clifo.get("CODVAL")); - if (valuta.not_empty() && valuta != m.get(S_VALUTA)) - { - TTable val("%val"); - val.put("CODTAB", valuta); - if (val.read() == NOERR) - m.set(S_VALUTA, valuta); - } - } if (occas && app().occas_mask().get(O_CODICE).empty()) m.send_key(K_SPACE, F_OCCASEDIT); // Lancia maschera occasionali } diff --git a/cg/cg2102.h b/cg/cg2102.h index a42388af9..c4cc645c9 100755 --- a/cg/cg2102.h +++ b/cg/cg2102.h @@ -113,6 +113,7 @@ class TPrimanota_application : public TRelation_application static bool codpag_handler(TMask_field& f, KEY key); static bool reset_handler(TMask_field& f, KEY key); static bool nrate_handler(TMask_field& f, KEY key); + static bool codcab_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); diff --git a/cg/cg2104.cpp b/cg/cg2104.cpp index 8f89134eb..c9a330698 100755 --- a/cg/cg2104.cpp +++ b/cg/cg2104.cpp @@ -27,6 +27,7 @@ bool TPrimanota_application::pag_notify(TSheet_field&, int r, KEY k) // ts contiene la vecchia riga, ns la nuova TToken_string ts(36), ns(36); + TString16 banca; bool doit = TRUE, m_imp = FALSE, m_perc = FALSE, m_pag = FALSE; bool m_scad = FALSE, m_tipo = FALSE, mod = FALSE; @@ -39,16 +40,14 @@ bool TPrimanota_application::pag_notify(TSheet_field&, int r, KEY k) switch (k) { - case K_SPACE: - break; case K_ENTER: ns = ps.row(r); ts = rws.row(r); news = ns.get(0); - newp = ns.get(2); - newi = ns.get(1); - newt = ns.get(3); + newi = ns.get(); + newp = ns.get(); + newt = ns.get(); // qui viene il bello, si fa per dire if (news != ts.get(0)) // modificata data scadenza @@ -71,6 +70,11 @@ bool TPrimanota_application::pag_notify(TSheet_field&, int r, KEY k) { mod = m_tipo = TRUE; } + + banca = ns.get(5); ts.add(banca, 6); + banca = ns.get(6); ts.add(banca, 7); + banca = ns.get(7); ts.add(banca, 8); + banca = ns.get(8); ts.add(banca, 9); break; case K_DEL: case K_INS: @@ -99,7 +103,7 @@ bool TPrimanota_application::pag_notify(TSheet_field&, int r, KEY k) rdiff, mcomm, need_recalc); // see if rdiff changed msk->set(FS_RDIFFER, pag.rate_differenziate() ? "1" : "2"); - msk->set(FS_NRATE, format("%d", pag.n_rate())); + msk->set(FS_NRATE, pag.n_rate()); } if (!recalc) { @@ -107,10 +111,10 @@ bool TPrimanota_application::pag_notify(TSheet_field&, int r, KEY k) // put data as they are TToken_string& trw = pag.rata(r); TToken_string srw = trw; - if (m_scad) trw.add(news,3); if (m_perc) trw.add(newp,1); - if (m_imp) trw.add(newi,4); if (m_tipo) trw.add(newt,2); + if (m_scad) trw.add(news,3); + if (m_imp) trw.add(newi,4); // validate the payment if ((ahiahi = pag.validate()) != P_OK) pag.rata(r) = srw; @@ -130,7 +134,6 @@ bool TPrimanota_application::pag_notify(TSheet_field&, int r, KEY k) ps.row(r) = rws.row(r); ps.force_update(r); } - else if (recalc && mod && need_recalc) { // ridefinisci lo sheet sulla base delle nuove rate @@ -171,10 +174,10 @@ bool TPrimanota_application::reset_handler(TMask_field& f, KEY key) bool TPrimanota_application::nrate_handler(TMask_field& f, KEY key) { TMask& m = f.mask(); - TSheet_field& ps = (TSheet_field&)m.field(FS_RATESHEET); if (key == K_TAB && m.is_running() && app().is_saldaconto()) { + TSheet_field& ps = (TSheet_field&)m.field(FS_RATESHEET); if (app().pagamento() != NULL) { app().pagamento()->set_numero_rate(atoi(f.get()), /*TBI*/-1); @@ -186,6 +189,28 @@ bool TPrimanota_application::nrate_handler(TMask_field& f, KEY key) return TRUE; } +bool TPrimanota_application::codcab_handler(TMask_field& f, KEY key) +{ + if (key == K_TAB && f.focusdirty()) + { + const TMask& m = f.mask(); + const short id = f.dlg() == FS_NSCAB ? FS_NSABI : FS_VSABI; + const int pos = id == FS_NSABI ? 5 : 7; + const TString16 abi = m.get(id); + const TString16 cab = m.get(id+1); + + TSheet_field& ps = (TSheet_field&)m.field(FS_RATESHEET); + for (int i = ps.items()-1; i >= 0; i--) + { + TToken_string& row = ps.row(i); + row.add(abi, pos); + row.add(cab, pos+1); + } + ps.force_update(); + } + + return TRUE; +} void TPrimanota_application::reset_pagamento() { @@ -208,8 +233,10 @@ void TPrimanota_application::set_scadenze(TMask& m) const real imponibile(m.get(F_IMPONIBILI)); const real imposta(m.get(F_IMPOSTE)); const real spese(0.0); + const real cambio(m.get(S_CAMBIO)); TPagamento& pag = *pagamento(); + pag.set_cambio(cambio); m.set(FS_RDIFFER, pag.rate_differenziate() ? "1" : "2"); m.set(FS_NAMEPAG, pag.name()); @@ -226,6 +253,7 @@ void TPrimanota_application::set_scadenze(TMask& m) // prepara lo sheet pag.set_sheet(ps); + _pag_rows = ps.rows_array(); m.set(FS_NRATE, pag.n_rate()); @@ -267,7 +295,6 @@ bool TPrimanota_application::read_scadenze(TMask& m) const TString16 codval (testa.get("CODVAL")); const real cambio(testa.get("CAMBIO")); - const TRectype& prima = _rel->cg(0); const char sezione = prima.get_char("SEZIONE"); // Dare/Avere const int nriga = 1; @@ -282,7 +309,7 @@ bool TPrimanota_application::read_scadenze(TMask& m) int npart = part.prima_fattura(nreg); bool fromscratch = FALSE; - if (npart != -1) // la gh'e' + if (npart > 0) // la gh'e' { const TRiga_partite& partita = part.riga(npart); @@ -308,7 +335,9 @@ bool TPrimanota_application::read_scadenze(TMask& m) if(!fromscratch) m.field(FS_RECALC).set(""); } if (fromscratch) + { pag.set_rate_auto(); + } else { pag.zap_rate(); @@ -319,8 +348,28 @@ bool TPrimanota_application::read_scadenze(TMask& m) const TDate scad = scadenza.get(SCAD_DATASCAD); const int tipop = scadenza.get_int(SCAD_TIPOPAG); const bool paid = scadenza.get_bool(SCAD_PAGATA); - const TString16 ulc = scadenza.get(SCAD_ULTCLASS); - pag.set_rata(i-1, importo, scad, tipop, ulc, paid); + const TString16 ulc = scadenza.get(SCAD_ULTCLASS); + if (scadenza.in_valuta()) + { + const real impval(scadenza.get(SCAD_IMPORTOVAL)); + pag.set_rata(i-1, impval, importo, scad, tipop, ulc, paid); + } + else + pag.set_rata(i-1, importo, ZERO, scad, tipop, ulc, paid); + + TToken_string& str = ps.row(i-1); + str.add(scadenza.get(SCAD_CODABIPR), 6); + str.add(scadenza.get(SCAD_CODCABPR), 7); + str.add(scadenza.get(SCAD_CODABI), 8); + str.add(scadenza.get(SCAD_CODCAB), 9); + if (i == 1) + { + m.set(FS_NSABI, str.get(6)); + m.set(FS_NSCAB, str.get(7)); + m.set(FS_VSABI, str.get(8)); + m.set(FS_VSCAB, str.get(9)); + m.set(FS_AGENTE, scadenza.get(SCAD_CODAG)); + } } } //else } @@ -360,10 +409,10 @@ void TPrimanota_application::write_scadenze(const TMask& m) const TString16 codcaus(causale().codice()); const TString16 codval (m.get(S_VALUTA)); const real cambio (m.get(S_CAMBIO)); + const TString16 agente (m.get(FS_AGENTE)); const char sezione = get_cgs_imp(0).sezione(); // Dare/Avere - CHECK(sezione > ' ', "Invalid section in row 0"); - - const TBill clifo(cgs().row(0), 2, 0x3); + + const TBill clifo(cgs().row(0), 2, 0x3); newgame = new TPartita(clifo, anno, numpart); const int row = newgame->prima_fattura(nreg); @@ -377,10 +426,10 @@ void TPrimanota_application::write_scadenze(const TMask& m) partita.put(PART_DATAREG, dreg); partita.put(PART_DATADOC, ddoc); partita.put(PART_NUMDOC, ndoc); - partita.put(PART_REG, reg); partita.put(PART_DESCR, desc); - partita.put(PART_PROTIVA, protiva); partita.put(PART_CODCAUS, codcaus); + partita.put(PART_REG, reg); + partita.put(PART_PROTIVA, protiva); partita.put(PART_SEZ, sezione); partita.put(PART_CODVAL, codval); partita.put(PART_CAMBIO, cambio); @@ -388,19 +437,33 @@ void TPrimanota_application::write_scadenze(const TMask& m) partita.put(PART_IMPOSTA, pag.imposta()); partita.put(PART_SPESE, pag.spese()); + TSheet_field& ps = (TSheet_field&)m.field(FS_RATESHEET); partita.elimina_rate(); for (int i = 0; i < pag.n_rate(); i++) - { + { + TToken_string& row = ps.row(i); + TRiga_scadenze& scadenza = partita.new_row(); - scadenza.put(SCAD_CODPAG, pag.code()); scadenza.put(SCAD_TIPOPAG, pag.tipo_rata(i)); scadenza.put(SCAD_ULTCLASS, pag.ulc_rata(i)); - scadenza.put(SCAD_IMPORTO, pag.tpay_rata(i)); + if (partita.in_valuta()) + { + scadenza.put(SCAD_IMPORTO, pag.tlit_rata(i)); + scadenza.put(SCAD_IMPORTOVAL, pag.tpay_rata(i)); + } + else + { + scadenza.put(SCAD_IMPORTO, pag.tpay_rata(i)); + scadenza.zero(SCAD_IMPORTOVAL); + } scadenza.put(SCAD_DATASCAD, pag.data_rata(i)); + scadenza.put(SCAD_CODABIPR, row.get(5)); + scadenza.put(SCAD_CODCABPR, row.get(6)); + scadenza.put(SCAD_CODABI, row.get(7)); + scadenza.put(SCAD_CODCAB, row.get(8)); scadenza.put(SCAD_PAGATA, pag.ratapagata(i)); -// scadenza.put(SCAD_CODABIPR, pag.codabipr(i)); // TBI -// scadenza.put(SCAD_CODCABPR, pag.codcabpr(i)); // TBI + scadenza.put(SCAD_CODAG, agente); } } diff --git a/cg/cg2105.cpp b/cg/cg2105.cpp index 64298194b..0be83184f 100755 --- a/cg/cg2105.cpp +++ b/cg/cg2105.cpp @@ -970,23 +970,6 @@ int TPrimanota_application::nuovo_pagamento(TPartita& partita, int nriga, int ra causale().bill(caus = 1, contro); // ... prende il primo contro.put(pagamento, TRUE); // Scrive conto contropartita - /* TBG Da regalare a Ferdinando - 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.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)); - } - */ return nrigp; } diff --git a/cg/cg21rata.uml b/cg/cg21rata.uml index af25bc2fe..0d0c0f58c 100755 --- a/cg/cg21rata.uml +++ b/cg/cg21rata.uml @@ -1,4 +1,4 @@ -PAGE "Rata pagamento" -1 -1 50 8 +PAGE "Rata pagamento" -1 -1 50 13 DATE 101 BEGIN @@ -12,18 +12,31 @@ BEGIN FLAGS "R" END -NUMBER 103 8 3 +BOOLEAN 111 +BEGIN + PROMPT 41 3 "Pagata" + FLAGS "D" +END + +NUMBER 103 15 2 +BEGIN + PROMPT 1 4 "Importo valuta " + PICTURE ".2" + FLAGS "R" +END + +NUMBER 104 8 3 BEGIN PROMPT 1 2 "Percentuale " PICTURE ".3" FLAGS "R" END -NUMBER 104 2 0 +NUMBER 105 2 0 BEGIN - PROMPT 1 4 "Tipo pagamento " + PROMPT 1 5 "Tipo pagamento " SHEET "Codice|Tipo pagamento@32" - INPUT 104 + INPUT 105 ITEM "1|Rimessa diretta o contanti" ITEM "2|Tratta" ITEM "3|Ricevuta Bancaria" @@ -32,16 +45,84 @@ BEGIN ITEM "6|Lettera di credito" ITEM "7|Tratta accettata" ITEM "8|Altro pagamento" - OUTPUT 104 OUTPUT 105 + OUTPUT 106 END -STRING 105 32 +STRING 106 32 BEGIN - PROMPT 1 5 "Descrizione " + PROMPT 1 6 "Descrizione " FLAGS "D" END - + +NUMBER 107 5 +BEGIN + PROMPT 1 7 "Ns. Banca ABI " + FLAGS "Z" + USE %BAN + INPUT CODTAB[1,5] 107 + INPUT CODTAB[6,10] 108 + DISPLAY "ABI@5" CODTAB[1,5] + DISPLAY "CAB@5" CODTAB[6,10] + DISPLAY "Denominazione@50" S0 + OUTPUT 107 CODTAB[1,5] + OUTPUT 108 CODTAB[6,10] + OUTPUT 126 S0 + CHECKTYPE NORMAL +END + +NUMBER 108 5 +BEGIN + PROMPT 27 8 "Ns. Banca CAB " + FLAGS "Z" + COPY ALL 107 + CHECKTYPE NORMAL +END + +STRING 126 50 45 +BEGIN + PROMPT 1 8 "" + USE %BAN KEY 2 + INPUT S0 126 + DISPLAY "Denominazione@50" S0 + DISPLAY "ABI@5" CODTAB[1,5] + DISPLAY "CAB@5" CODTAB[6,10] + COPY OUTPUT 107 + CHECKTYPE NORMAL +END + +NUMBER 109 5 +BEGIN + PROMPT 1 9 "Vs. Banca ABI " + FLAGS "Z" + COPY USE 107 + INPUT CODTAB[1,5] 109 + INPUT CODTAB[6,10] 110 + COPY DISPLAY 107 + OUTPUT 108 CODTAB[1,5] + OUTPUT 109 CODTAB[6,10] + OUTPUT 128 S0 + CHECKTYPE NORMAL +END + +NUMBER 110 5 +BEGIN + PROMPT 27 9 "Vs. Banca CAB " + FLAGS "Z" + COPY ALL 109 + CHECKTYPE NORMAL +END + +STRING 128 50 45 +BEGIN + PROMPT 1 10 "" + COPY USE 109 + INPUT S0 128 + COPY DISPLAY 126 + COPY OUTPUT 109 + CHECKTYPE NORMAL +END + BUTTON DLG_CANCEL 10 2 BEGIN PROMPT -12 -1 "" @@ -53,4 +134,5 @@ BEGIN END ENDPAGE + ENDMASK diff --git a/cg/cg21sld.h b/cg/cg21sld.h index b885c52f2..c7ecf19c3 100755 --- a/cg/cg21sld.h +++ b/cg/cg21sld.h @@ -10,3 +10,12 @@ #define FS_MCOMM 510 #define FS_RESET 511 #define FS_NRATE 512 +#define FS_NSABI 513 +#define FS_NSCAB 514 +#define FS_DESCNSABI 515 +#define FS_VSABI 516 +#define FS_VSCAB 517 +#define FS_DESCVSABI 518 +#define FS_AGENTE 519 +#define FS_DESCAGENTE 520 + diff --git a/cg/cg21sld.uml b/cg/cg21sld.uml index f98b0e672..b493f0391 100755 --- a/cg/cg21sld.uml +++ b/cg/cg21sld.uml @@ -1,85 +1,183 @@ PAGE "Registrazione Scadenze" -1 -1 77 20 - -GROUPBOX DLG_NULL 79 3 + +TEXT DLG_NULL BEGIN - PROMPT 0 1 "@bScadenzario" + PROMPT 1 0 "@bGestione scadenzario" END - + NUMBER FS_IMPONIBILI 15 BEGIN - PROMPT 1 2 "Imponibili " - PICTURE "." - FLAGS "DR" + PROMPT 1 1 "Imponibili " + PICTURE "." + FLAGS "DR" END NUMBER FS_IMPOSTE 15 BEGIN - PROMPT 29 2 "Imposte " - PICTURE "." - FLAGS "DR" + PROMPT 29 1 "Imposte " + PICTURE "." + FLAGS "DR" END NUMBER FS_SPESE 15 BEGIN - PROMPT 54 2 "Spese " - PICTURE "." - FLAGS "DR" + PROMPT 54 1 "Spese " + PICTURE "." + FLAGS "DR" END RADIOBUTTON FS_RDIFFER 31 BEGIN - PROMPT 1 4 "Opzioni ricalcolo rate" - ITEM "1|Differenziate" MESSAGE DISABLE,FS_NRATE - ITEM "2|Uguali (obbligate dalla 2a)" MESSAGE ENABLE,FS_NRATE - ITEM "3|Uguali dall'ultima modificata" MESSAGE DISABLE,FS_NRATE - ITEM "4|Uguali finche' possibile" MESSAGE DISABLE,FS_NRATE + PROMPT 1 2 "Opzioni ricalcolo rate" + ITEM "1|Differenziate" MESSAGE DISABLE,FS_NRATE + ITEM "2|Uguali (obbligate dalla 2a)" MESSAGE ENABLE,FS_NRATE + ITEM "3|Uguali dall'ultima modificata" MESSAGE DISABLE,FS_NRATE + ITEM "4|Uguali finche' possibile" MESSAGE DISABLE,FS_NRATE END NUMBER FS_NRATE 3 0 BEGIN - PROMPT 36 8 "Numero di rate " + PROMPT 36 6 "Numero di rate " END BOOLEAN FS_RECALC BEGIN - PROMPT 58 7 "Ricalcolo automatico" - MESSAGE TRUE ENABLE,FS_RDIFFER|ENABLE,FS_MCOMM|K_SPACE,FS_RDIFFER - MESSAGE FALSE DISABLE,FS_RDIFFER|DISABLE,FS_MCOMM|DISABLE,FS_NRATE - HELP "Attiva/disattiva il ricalcolo automatico delle scadenze" + PROMPT 58 5 "Ricalcolo automatico" + MESSAGE TRUE ENABLE,FS_RDIFFER|ENABLE,FS_MCOMM|K_SPACE,FS_RDIFFER + MESSAGE FALSE DISABLE,FS_RDIFFER|DISABLE,FS_MCOMM|DISABLE,FS_NRATE + HELP "Attiva/disattiva il ricalcolo automatico delle scadenze" END BOOLEAN FS_MCOMM BEGIN - PROMPT 36 7 "Mese commerciale" + PROMPT 36 5 "Mese commerciale" END STRING FS_NAMEPAG 27 BEGIN - PROMPT 36 5 "Pagamento " - FLAGS "D" + PROMPT 36 3 "Pagamento " + FLAGS "D" END STRING FS_TIPOPR 27 BEGIN - PROMPT 36 6 "Tipo prima rata " - FLAGS "D" + PROMPT 36 4 "Tipo prima rata " + FLAGS "D" +END + +NUMBER FS_NSABI 5 +BEGIN + PROMPT 2 8 "Ns. Banca ABI " + FLAGS "Z" + USE %BAN + INPUT CODTAB[1,5] FS_NSABI + INPUT CODTAB[6,10] FS_NSCAB + DISPLAY "ABI@5" CODTAB[1,5] + DISPLAY "CAB@5" CODTAB[6,10] + DISPLAY "Denominazione@50" S0 + OUTPUT FS_NSABI CODTAB[1,5] + OUTPUT FS_NSCAB CODTAB[6,10] + OUTPUT FS_DESCNSABI S0 + CHECKTYPE NORMAL END -SPREADSHEET FS_RATESHEET 0 8 +NUMBER FS_NSCAB 5 +BEGIN + PROMPT 25 8 "CAB " + FLAGS "Z" + COPY ALL FS_NSABI + CHECKTYPE NORMAL +END + +STRING FS_DESCNSABI 50 37 +BEGIN + PROMPT 40 8 "" + USE %BAN KEY 2 + INPUT S0 FS_DESCNSABI + DISPLAY "Denominazione@50" S0 + DISPLAY "ABI@5" CODTAB[1,5] + DISPLAY "CAB@5" CODTAB[6,10] + COPY OUTPUT FS_NSABI + CHECKTYPE NORMAL +END + +NUMBER FS_VSABI 5 +BEGIN + PROMPT 2 9 "Vs. Banca ABI " + FLAGS "Z" + COPY USE FS_NSABI + INPUT CODTAB[1,5] FS_VSABI + INPUT CODTAB[6,10] FS_VSCAB + COPY DISPLAY FS_NSABI + OUTPUT FS_VSABI CODTAB[1,5] + OUTPUT FS_VSCAB CODTAB[6,10] + OUTPUT FS_DESCVSABI S0 + CHECKTYPE NORMAL +END + +NUMBER FS_VSCAB 5 +BEGIN + PROMPT 25 9 "CAB " + FLAGS "Z" + COPY ALL FS_VSABI + CHECKTYPE NORMAL +END + +STRING FS_DESCVSABI 50 37 +BEGIN + PROMPT 40 9 "" + COPY USE FS_DESCNSABI + INPUT S0 FS_DESCVSABI + COPY DISPLAY FS_DESCNSABI + COPY OUTPUT FS_VSABI + CHECKTYPE NORMAL +END + +STRING FS_AGENTE 5 +BEGIN + PROMPT 2 10 "Agente " + FLAGS "UZ" + USE AGE + INPUT CODTAB FS_AGENTE + DISPLAY "Codice" CODTAB + DISPLAY "Descrizione @50" S0 + OUTPUT FS_AGENTE CODTAB + OUTPUT FS_DESCAGENTE S0 + CHECKTYPE NORMAL +END + +STRING FS_DESCAGENTE 50 +BEGIN + PROMPT 27 10 "" + USE AGE KEY 2 + INPUT S0 FS_DESCAGENTE + DISPLAY "Descrizione @50" S0 + DISPLAY "Codice" CODTAB + COPY OUTPUT FS_AGENTE + CHECKTYPE NORMAL +END + +SPREADSHEET FS_RATESHEET BEGIN - PROMPT 1 10 "Rate" - ITEM "Scadenza@10" - ITEM "Importo@15" - ITEM "Percentuale@12" - ITEM "Tipo" - ITEM "Pagamento@32" + PROMPT 0 11 "Rate" + ITEM "Scadenza@10" + ITEM "Importo@15" + ITEM "In Valuta@15" + ITEM "Percentuale@12" + ITEM "Tipo" + ITEM "Pagamento@32" + ITEM "Ns.ABI" + ITEM "Ns.CAB" + ITEM "Vs.ABI" + ITEM "Vs.CAB" + ITEM "Pagata" END BUTTON FS_RESET 7 1 BEGIN - PROMPT 1 -1 "Reset" + PROMPT 1 -1 "Reset" END ENDPAGE diff --git a/cg/pagament.cpp b/cg/pagament.cpp index e6f46991c..ebdb38989 100755 --- a/cg/pagament.cpp +++ b/cg/pagament.cpp @@ -1,1324 +1,1360 @@ -#include -#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, int rdiff) -{ - _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; - int i = 0; - - if (_inited || (!_inited && rdiff == 1)) // se e' inited rdiff e' 2 per forza - { - real tot = _inited ? (_tpr < 4 ? _firstr : _secndr) : real(100.0); - if (n == 1) - { - if (_inited) set_imprata(first, tot); - set_percrata(first, real(100.0)); - if (_inited && _tpr > 0 && _tpr < 4) - set_imprata(first, tpay_rata(first) + _secndr); - i = first + 1; // per rimozione successiva - } - else - { - - if (nr == first + 1) - { - // suddividi equamente e riaggiusta la percentuale di conseguenza - real div = tot / real(n); - real perc = real(100.0)*(div/tot); - for (i = first; i < n; i++) - { - if (i > 0) - add_rata(perc, (sscad == -1 ? scad_rata(0) : sscad), tipo_rata(0)); - if (_inited) set_imprata (i, div); - set_percrata(i, perc); - } - if (_inited && _tpr > 0 && _tpr < 4) - set_imprata(0, tpay_rata(0) + _secndr); - } - else if (nr > first + 1) - { - // dalla prima nota e' abilitato solo se rdiff == 2 - // e' selezionato UGUALI: devo: lasciare la prima - // rata com'e' (a meno che non ce ne sia una sola) e - // suddividere il resto dell'importo tra le altre - real rfirst = _inited ? tpay_rata(first) : perc_rata(first); - if (_inited && _tpr > 0 && _tpr < 4) rfirst -= _secndr; - - real rest = tot - rfirst; - const real div = rest / real(n - 1); - real perc = real(100.0)*(div/tot); - - for (i = first+1; i < n; i++) - { - if (i >= nr) - add_rata(perc, (sscad == -1 ? (i < nr ? scad_rata(i) : scad_rata(nr-1)) : sscad), - tipo_rata(nr-1)); - if (_inited) set_imprata (i, div); - set_percrata(i, perc); - } - } - } - } - - else - { - - for (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 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); -} - -void TPagamento::set_percrata(int i, real r) -{ - TToken_string& tt = (TToken_string&)_rate[i]; - TDate d = _inizio; - tt.add(r.string(), 1); -} - - -TToken_string& TPagamento::set_rata(int index, 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); - int first = _tpr < 4 ? 0 : 1; - - 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); - - if (index == first && _tpr > 0 && _tpr < 4) - howmuch -= _secndr; - - real perc = (_tpr > 3 && index == 0) ? ZERO : howmuch/toshare; - - if (index == first && _tpr > 0 && _tpr < 4) - howmuch += _secndr; - - 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) - { -// RIMOSSO in quanto con rate uguali non si usa la percentuale, -// per evitare merdaglia -// 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"; - if (err & P_NEG) - s << "\n L'importo dato e' inferiore al minimo possibile"; - if (err & P_TROP) - s << "\n L'importo dato e' superiore al massimo possibile"; -} - -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 interban. 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) - { - for (int k = 0; k < srate.items(); k++) - { - // deve farlo per tutte dalla 1 in poi se rdiff == 2, - // soltanto per row diversamente - if ((rdiff == 2 && row > 0 && k > 0) || k == row) - { - TToken_string& tt = rata(k); - TToken_string& ss = (TToken_string&)srate[k]; - tt.add(typ,2); - ss.add(typ,2); - need_recalc = TRUE; - // 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; -// *** 5/9/85: UGUALI (2) significa la seguente menata: se c'e' una sola rata -// *** uguale al totale importo, come prima; diversamente, la prima rata -// *** va mantenuta uguale comunque sia, e occorre ridefinire le restanti in -// *** modo che siano uguali. In questo caso deve far fede il NUMERO di RATE -// *** indicato, che in prima nota non c'e' e va quindi inserito (porcoddio). - - // si registrano rate UGUALI soltanto se specificato UGUALI - // il che non e' sorprendente, ma coi tempi che corrono... - _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 == 2 && srate.items() > 1) - { - // HERE - - int n = srate.items(); // questo rimane per forza costante - real tot = is_perc_modified ? real(100.0) : (_tpr < 4 ? _firstr : _secndr); - real delta = is_perc_modified ? ZERO : - ((_tpr > 0 && _tpr) < 4 ? _secndr : ZERO); - real nimp(new_value); - - // se ho modificato la prima, divido il resto nelle successive - // lasciando costante il numero rate - if (row == first) - { - if (!delta.is_zero()) nimp -= delta; - // inferiore al minimo - if (nimp.sign() < 0) { _rate = srate; return P_NEG; } - real remainder = tot - nimp; - real div = remainder / real(n - 1); - div.round(is_perc_modified ? 3 : _round); - nimp = tot - (div * real(n-1)); - - for (int k = first; k < n; k++) - { - TToken_string& trt = (TToken_string&)srate[k]; - if (_inited) dd = trt.get(3); - type = atoi(trt.get(2)); - nscd = k == 0 ? 0 : atoi(trt.get(0)); - if (type == 0) type = 1; - if (k > 0 && nscd == 0) nscd = oldscad; - if (_inited && dd == lastdate && k > 0) - next_scad(dd,nscd,mcomm,k); - - set_rata(k, is_perc_modified ? (k == first ? nimp : div) : ZERO, - nscd, type); - if (!is_perc_modified) - set_imprata (k, k == first ? (nimp + delta) : div); - } - } - else - { - // se ho modificato la seconda o oltre, faccio tutte uguali dalla - // seconda in poi; la prima resta com'e' se possibile, mentre se - // c'e' un resto glielo sommo. - // Dunque: prendo la prima, calcolo il resto, divido per quella nuova, - // se resto lo sommo alla prima, e faccio quante rate servono - - TToken_string& trt = (TToken_string&)srate[first]; - real rfirst(is_perc_modified ? trt.get(1) : trt.get(4)); - if (!delta.is_zero()) rfirst -= delta; - real rest = tot - rfirst; - real div = rest / nimp; - if (div < real(1.0)) { _rate = srate; return P_TROP; } - - int nr = (int)div.integer() + (_tpr > 4 ? 2 : 1); - real reminder = rest - (nimp * real(nr -1)); - rfirst += reminder; - for (int k = first; k < nr; k++) - { - nscd = oldscad; - type = _def_tpr; - TString16 ulc(_def_ulc); - - if (srate.items() > k) - { - TToken_string& trt = (TToken_string&)srate[k]; - if (_inited) dd = trt.get(3); - type = atoi(trt.get(2)); - nscd = atoi(trt.get(0)); - ulc = trt.get(5); - } - - if (type == 0) type = 1; - - if (_inited && dd == lastdate && k > 0) - next_scad(dd,nscd,mcomm,k); - - set_rata(k, is_perc_modified ? (k == first ? rfirst : nimp) : ZERO, - nscd, type, ulc); - if (!is_perc_modified) - set_imprata (k, k == first ? (rfirst + delta) : nimp); - } - } - } - - else if (rdiff != 4) - for (j = frs; sum < mx; j++) - { - // 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); - // togli pezxo di troppo - if (!is_perc_modified && j == first && _tpr > 0 && _tpr < 4) - rvl -= _secndr; - real zpx = rvl/rmax; // percentuale - dt.add(zpx); - } - for (j = first; j < _rate.items(); j++) - { - real rfirst(0.0); - TToken_string& tr = rata(j); - - real rvl = dt.get(); - - if (j == first) - { - rfirst = rvl; - if (rdiff == 2) - { - real reminder = toshare - rfirst; - real rdiv = reminder / real(_rate.items() - (1+first)); - rdiv.round( is_perc_modified ? _round : 3); - rfirst += reminder - (rdiv * real(_rate.items() - (1+first))); - rvl = rdiv; - } - } - - if (is_perc_modified && j == first && _tpr > 0 && _tpr < 4) - rfirst += _secndr; - - tr.add((j == first ? rfirst.string() : 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) + _secndr; -// tr.add(tot.string(), 4); -// } - - } - - need_recalc = TRUE; - return P_OK; - } // new_value != NULL - } - else // i != row modified - { - if (rdiff == 2) continue; - 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(); - - // usa la percentuale per la prima rata - r1 = (toslice * perc_rata(first))/real(100.0); - r1.round(_round); - real reminder = toslice - r1; - if (!reminder.is_zero()) - { - ro = reminder/real(rut-1); ro.trunc(_round); - r1 = (toslice - (ro*real(rut-1))); - } - } - - 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) + _secndr); -} - - - -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: - _secndr = _imposta; - _firstr = _imponibile + _spese; - break; - case 2: - _secndr = _spese; - _firstr = _imposta + _imponibile; - break; - case 3: - _secndr = _imposta + _spese; - _firstr = _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"); +#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); +} + +long TPagamento::_rata_lfield(int n, int f) const +{ + TToken_string& t = (TToken_string&)_rate[n]; + return t.get_long(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[16]; + TToken_string& t = (TToken_string&)_rate[n]; + const char* k = t.get(f); + if (k != NULL) + strncpy(kak, k, 16); + else + kak[0] = '\0'; + return kak; +} + +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 : in) : in, 0); + } +} + +void TPagamento::set_mese_commerciale(bool v, int& sscad) +{ + _dirty = FALSE; + if (_mcomm == v) return; + if (sscad < 0) 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.destroy(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, int rdiff) +{ + _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; + int i = 0; + + if (_inited || (!_inited && rdiff == 1)) // se e' inited rdiff e' 2 per forza + { + real tot = _inited ? (_tpr < 4 ? _firstr : _secndr) : real(100.0); + if (n == 1) + { + if (_inited) set_imprata(first, tot); + set_percrata(first, real(100.0)); + if (_inited && _tpr > 0 && _tpr < 4) + set_imprata(first, tpay_rata(first) + _secndr); + i = first + 1; // per rimozione successiva + } + else + { + + if (nr == first + 1) + { + // suddividi equamente e riaggiusta la percentuale di conseguenza + real div = tot / real(n); + real perc = real(100.0)*(div/tot); + for (i = first; i < n; i++) + { + if (i > 0) + add_rata(perc, (sscad == -1 ? scad_rata(0) : sscad), tipo_rata(0)); + if (_inited) set_imprata (i, div); + set_percrata(i, perc); + } + if (_inited && _tpr > 0 && _tpr < 4) + set_imprata(0, tpay_rata(0) + _secndr); + } + else if (nr > first + 1) + { + // dalla prima nota e' abilitato solo se rdiff == 2 + // e' selezionato UGUALI: devo: lasciare la prima + // rata com'e' (a meno che non ce ne sia una sola) e + // suddividere il resto dell'importo tra le altre + real rfirst = _inited ? tpay_rata(first) : perc_rata(first); + if (_inited && _tpr > 0 && _tpr < 4) rfirst -= _secndr; + + real rest = tot - rfirst; + const real div = rest / real(n - 1); + real perc = real(100.0)*(div/tot); + + for (i = first+1; i < n; i++) + { + if (i >= nr) + add_rata(perc, (sscad == -1 ? (i < nr ? scad_rata(i) : scad_rata(nr-1)) : sscad), + tipo_rata(nr-1)); + if (_inited) set_imprata (i, div); + set_percrata(i, perc); + } + } + } + } + else + { + for (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.destroy(i); + _rate.pack(); + + _dirty = TRUE; +} + +void TPagamento::set_cambio(const real& cambio) +{ + if (cambio.sign() <= 0) + _cambio = 1.0; + else + _cambio = cambio; + set_round(_cambio == 1.0 ? 0 : 2); +} + + +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 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.destroy(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(""); // data + tt->add(""); // importo + tt->add(ulc); // 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(64); + + 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 (imp && *imp > ' ' && _cambio != 1.0) + { + real implit(imp); + implit *= _cambio; + implit.round(); + tt->add(implit.string(), 7); + } + + 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); +} + +void TPagamento::set_percrata(int i, real r) +{ + TToken_string& tt = (TToken_string&)_rate[i]; + TDate d = _inizio; + tt.add(r.string(), 1); +} + + +TToken_string& TPagamento::set_rata(int index, const real& howmuch, const real& quanto, + 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); + int first = _tpr < 4 ? 0 : 1; + + const bool nwr = (tt == NULL); // nuova rata + + if (nwr) tt = new TToken_string(64); + + TDate oldd = index > 0 ? data_rata(index -1) : _inizio; + int day = date - oldd; + real toshare(_tpr < 4 ? _firstr : _secndr); + + real hm = howmuch; + if (index == first && _tpr > 0 && _tpr < 4) + hm -= _secndr; + + real perc = (_tpr > 3 && index == 0) ? ZERO : hm/toshare; + perc *= real(100.0); + perc.round(2); + + tt->cut(0); + tt->add(day); // 0 - scadenza + tt->add(perc.string()); // 1 - percentuale + tt->add(type); // 2 - tipo + tt->add(date.string()); // 3 - data + tt->add(howmuch.string()); // 4 - importo + tt->add(ulc); // 5 - ulc(era?) + tt->add(pagato ? "X" : " "); // 6 - pagata + tt->add(quanto.string()); // 7 - Importo in lire + 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) + { +// RIMOSSO in quanto con rate uguali non si usa la percentuale, +// per evitare merdaglia +// 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"; + if (err & P_NEG) + s << "\n L'importo dato e' inferiore al minimo possibile"; + if (err & P_TROP) + s << "\n L'importo dato e' superiore al massimo possibile"; +} + +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 interban. diretti"; break; + case 9: o = "Bonifici"; break; + default: 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; + TString_array 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) + { + for (int k = 0; k < srate.items(); k++) + { + // deve farlo per tutte dalla 1 in poi se rdiff == 2, + // soltanto per row diversamente + if ((rdiff == 2 && row > 0 && k > 0) || k == row) + { + TToken_string& tt = rata(k); + TToken_string& ss = (TToken_string&)srate[k]; + tt.add(typ,2); + ss.add(typ,2); + need_recalc = TRUE; + // 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; +// *** 5/9/85: UGUALI (2) significa la seguente menata: se c'e' una sola rata +// *** uguale al totale importo, come prima; diversamente, la prima rata +// *** va mantenuta uguale comunque sia, e occorre ridefinire le restanti in +// *** modo che siano uguali. In questo caso deve far fede il NUMERO di RATE +// *** indicato, che in prima nota non c'e' e va quindi inserito (porcoddio). + + // si registrano rate UGUALI soltanto se specificato UGUALI + // il che non e' sorprendente, ma coi tempi che corrono... + _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.destroy(j); + } + else + { + // l'importante e' esagerare + for(int j = row+1; j < srate.items(); j++) + _rate.destroy(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.destroy(j); + + if (rdiff == 2 && srate.items() > 1) + { + // HERE + + int n = srate.items(); // questo rimane per forza costante + real tot = is_perc_modified ? real(100.0) : (_tpr < 4 ? _firstr : _secndr); + real delta = is_perc_modified ? ZERO : + ((_tpr > 0 && _tpr) < 4 ? _secndr : ZERO); + real nimp(new_value); + + // se ho modificato la prima, divido il resto nelle successive + // lasciando costante il numero rate + if (row == first) + { + if (!delta.is_zero()) nimp -= delta; + // inferiore al minimo + if (nimp.sign() < 0) { _rate = srate; return P_NEG; } + real remainder = tot - nimp; + real div = remainder / real(n - 1); + div.round(is_perc_modified ? 3 : _round); + nimp = tot - (div * real(n-1)); + + for (int k = first; k < n; k++) + { + TToken_string& trt = (TToken_string&)srate[k]; + if (_inited) dd = trt.get(3); + type = atoi(trt.get(2)); + nscd = k == 0 ? 0 : atoi(trt.get(0)); + if (type == 0) type = 1; + if (k > 0 && nscd == 0) nscd = oldscad; + if (_inited && dd == lastdate && k > 0) + next_scad(dd,nscd,mcomm,k); + + set_rata(k, is_perc_modified ? (k == first ? nimp : div) : ZERO, + nscd, type); + if (!is_perc_modified) + set_imprata (k, k == first ? (nimp + delta) : div); + } + } + else + { + // se ho modificato la seconda o oltre, faccio tutte uguali dalla + // seconda in poi; la prima resta com'e' se possibile, mentre se + // c'e' un resto glielo sommo. + // Dunque: prendo la prima, calcolo il resto, divido per quella nuova, + // se resto lo sommo alla prima, e faccio quante rate servono + + TToken_string& trt = (TToken_string&)srate[first]; + real rfirst(is_perc_modified ? trt.get(1) : trt.get(4)); + if (!delta.is_zero()) rfirst -= delta; + real rest = tot - rfirst; + real div = rest / nimp; + if (div < real(1.0)) { _rate = srate; return P_TROP; } + + int nr = (int)div.integer() + (_tpr > 4 ? 2 : 1); + real reminder = rest - (nimp * real(nr -1)); + rfirst += reminder; + for (int k = first; k < nr; k++) + { + nscd = oldscad; + type = _def_tpr; + TString16 ulc(_def_ulc); + + if (srate.items() > k) + { + TToken_string& trt = (TToken_string&)srate[k]; + if (_inited) dd = trt.get(3); + type = atoi(trt.get(2)); + nscd = atoi(trt.get(0)); + ulc = trt.get(5); + } + + if (type == 0) type = 1; + + if (_inited && dd == lastdate && k > 0) + next_scad(dd,nscd,mcomm,k); + + set_rata(k, is_perc_modified ? (k == first ? rfirst : nimp) : ZERO, + nscd, type, ulc); + if (!is_perc_modified) + set_imprata (k, k == first ? (rfirst + delta) : nimp); + } + } + } + + else if (rdiff != 4) + for (j = frs; sum < mx; j++) + { + // 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.destroy(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); + // togli pezxo di troppo + if (!is_perc_modified && j == first && _tpr > 0 && _tpr < 4) + rvl -= _secndr; + real zpx = rvl/rmax; // percentuale + dt.add(zpx); + } + for (j = first; j < _rate.items(); j++) + { + real rfirst(0.0); + TToken_string& tr = rata(j); + + real rvl = dt.get(); + + if (j == first) + { + rfirst = rvl; + if (rdiff == 2) + { + real reminder = toshare - rfirst; + real rdiv = reminder / real(_rate.items() - (1+first)); + rdiv.round( is_perc_modified ? _round : 3); + rfirst += reminder - (rdiv * real(_rate.items() - (1+first))); + rvl = rdiv; + } + } + + if (is_perc_modified && j == first && _tpr > 0 && _tpr < 4) + rfirst += _secndr; + + tr.add((j == first ? rfirst.string() : 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) + _secndr; +// tr.add(tot.string(), 4); +// } + + } + + need_recalc = TRUE; + return P_OK; + } // new_value != NULL + } + else // i != row modified + { + if (rdiff == 2) continue; + 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; + } + + TString16 s; + 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 + + TString16 s; + 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", 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) +{ + TString16 s; 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", 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(); + + // usa la percentuale per la prima rata + r1 = (toslice * perc_rata(first))/real(100.0); + r1.round(_round); + real reminder = toslice - r1; + if (!reminder.is_zero()) + { + ro = reminder/real(rut-1); ro.trunc(_round); + r1 = (toslice - (ro*real(rut-1))); + } + } + + 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) + _secndr); +} + + + +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: + _secndr = _imposta; + _firstr = _imponibile + _spese; + break; + case 2: + _secndr = _spese; + _firstr = _imposta + _imponibile; + break; + case 3: + _secndr = _imposta + _spese; + _firstr = _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) +{ + if (_inited && _rate.items() > 0) + { + const bool in_valuta = _cambio != 1.0; + + // si istanzia uno sheet di primanota + for (int i = 0; i < n_rate(); i++) + { + TToken_string& ts = sf.row(i); + // istanzia, o stronzo + ts.add((const char*)data_rata(i), 0); // 0 - Data scadenza + if (in_valuta) + { + ts.add(tlit_rata(i).string(), 1); // 1 - Importo in lire + ts.add(tpay_rata(i).string(), 2); // 2 - Importo in valuta + } + else + { + ts.add(tpay_rata(i).string(), 1); // 1 - Importo + ts.add("", 2); + } + ts.add(perc_rata(i).string(), 3); // 3 - Percentuale + ts.add(tipo_rata(i), 4); // 4 - Tipo rata + ts.add(desc_tipo(tipo_rata(i)), 5); // 5 - Descrizione tipo rata + // 6,7,8,9 - Banche + const bool paid = ratapagata(i); + ts.add(paid ? "X" : "", 10); // 10 - Pagaya + if (paid) + { + sf.disable_cell(i,1); // importo + sf.disable_cell(i,2); // in valuta + sf.disable_cell(i,3); // percentuale + } + } + for (; i < sf.items(); i++) + sf.destroy(i); + + sf.enable_column(2, in_valuta); + } + else + if (_rate.items() > 0) // not inited: set edit sheet + { + sf.destroy(); + 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), _cambio(1.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 00181c43a..0ea3131a2 100755 --- a/cg/pagament.h +++ b/cg/pagament.h @@ -29,9 +29,10 @@ class TPagamento : public TObject real _imponibile; // imponibile da affettare real _imposta; // imposta da affettare real _spese; // spese da affettare + real _cambio; // cambio valuta TDistrib _slicer; // affettatrice bool _new; // non letto da database - TArray _rate; // rate medesime + TString_array _rate; // rate medesime char _inscad; // inizio scadenze: S1 bool _mcomm; // mese commerciale: B0 bool _rdiff; // rate differenziate: B1 @@ -47,6 +48,7 @@ class TPagamento : public TObject int _int_rate; int _rata_ifield(int n, int f) const; + long _rata_lfield(int n, int f) const; real _rata_rfield(int n, int f) const; TDate _rata_dfield(int n, int f) const; const char* _rata_sfield(int n, int f) const; @@ -65,21 +67,21 @@ public: real imposta() const { return _imposta; } real spese() const { return _spese; } - int tipo_rata(int n) const { return _rata_ifield(n,2);} - real perc_rata(int n) const { return _rata_rfield(n,1);} - int scad_rata(int n) const { return _rata_ifield(n,0);} - TDate data_rata(int n) const { return _rata_dfield(n,3);} - real tpay_rata(int n) const { return _rata_rfield(n,4);} + int scad_rata(int n) const { return _rata_ifield(n,0);} + real perc_rata(int n) const { return _rata_rfield(n,1);} + int tipo_rata(int n) const { return _rata_ifield(n,2);} + TDate data_rata(int n) const { return _rata_dfield(n,3);} + real tpay_rata(int n) const { return _rata_rfield(n,4);} const char* ulc_rata(int n) const { return _rata_sfield(n,5);} + bool ratapagata(int n) const { return _rata_sfield(n,6)[0] > ' ';} + real tlit_rata(int n) const { return _rata_rfield(n,7);} + char inizio_scadenza() const { return _inscad; } bool mese_commerciale() const { return _mcomm; } bool rate_differenziate() const { return _rdiff; } int tipo_prima_rata() const { return _tpr; } int decs() const { return _round; } - // mi scuso per la mancanza di underscore, ma mi piaceva cosi' - bool ratapagata(int n); - const TString& name() const { return _name; } const TString& code() const { return _code; } const char* desc_tpr() const; @@ -101,6 +103,7 @@ public: void set_inizio_scadenza(char v) { _inscad = v; } void set_code(const char* c) { _code = c; } void set_round(int n) { _round = n; } + void set_cambio(const real& ex); // check consistency: returns word with errors flagged, 0 if ok word validate() const; @@ -121,9 +124,10 @@ public: TToken_string& set_rata (int index, real perc, int day, int type, const char* ulc = NULL, const char* imp = NULL, const char* data = NULL); + // questa calcola percentuali e scadenze a partire dagli importi - TToken_string& set_rata (int index, real& howmuch, const TDate& date, int type, - const char* ulc, bool pagato); + TToken_string& set_rata(int index, const real& howmuch, const real& quanto, + const TDate& date, int type, const char* ulc, bool pagata); // settano tipo rata e ult. class default per le rate; se bool = TRUE // modificano anche le eventuali rate esistenti diff --git a/cg/saldacon.cpp b/cg/saldacon.cpp index e14a3fec5..1fbe7b2bf 100755 --- a/cg/saldacon.cpp +++ b/cg/saldacon.cpp @@ -229,11 +229,20 @@ bool TRiga_scadenze::in_valuta() const } // Controlla se la rata e' stata completamente pagata -bool TRiga_scadenze::chiusa() const -{ - TImporto imp(importo_da_pagare(TRUE)); - imp += importo_pagato(TRUE, 0x3); - return imp.is_zero(); +bool TRiga_scadenze::chiusa(bool update) const +{ + bool chiusa; + if (update) + { + TImporto imp(importo_da_pagare(TRUE)); + imp += importo_pagato(TRUE, 0x3); + chiusa = imp.is_zero(); + ((TRectype*)this)->put(SCAD_PAGATA, chiusa ? "X" : ""); + } + else + chiusa = get_bool(SCAD_PAGATA); + + return chiusa; } // Calcola il totale dei pagamenti (eventualmente in valuta) @@ -877,7 +886,7 @@ bool TPartita::chiusa(bool update) for (int r = part.last(); r > 0; r--) { const TRiga_scadenze& scad = part.rata(r); - if (!scad.chiusa()) + if (!scad.chiusa(update)) { forse_chiusa = FALSE; break; diff --git a/cg/saldacon.h b/cg/saldacon.h index 1513f0691..d2c5c8094 100755 --- a/cg/saldacon.h +++ b/cg/saldacon.h @@ -125,7 +125,7 @@ protected: // TRecord_tree virtual TObject* dup() const { return new TRiga_scadenze(*this); } public: - bool chiusa() const; + bool chiusa(bool update = FALSE) const; bool in_valuta() const;