diff --git a/cg/cg2100.cpp b/cg/cg2100.cpp index aa2f6ed91..4ec6d0c2f 100755 --- a/cg/cg2100.cpp +++ b/cg/cg2100.cpp @@ -235,6 +235,7 @@ bool TPrimanota_application::read_caus(const char* cod, int year) m->efield(F_NUMDOC).check_type(nob ? CHECK_REQUIRED : CHECK_NORMAL); // Num. doc. obbligatorio m->efield(F_DATADOC).check_type(dob ? CHECK_REQUIRED : CHECK_NORMAL); // Data doc. obbligatoria + m->enable(F_PROVVISORIO, !_is_saldaconto); // Il saldaconto vieta i movimenti provvisori if (iva == nessuna_iva) { diff --git a/cg/cg2105.cpp b/cg/cg2105.cpp index 9ada378b1..2a781a3cb 100755 --- a/cg/cg2105.cpp +++ b/cg/cg2105.cpp @@ -26,9 +26,13 @@ protected: static bool edit_scadenza_handler(TMask_field& f, KEY k); void add_importo(TToken_string& s, const TImporto& i) const; + TImporto get_importo(TToken_string& s, int pos) const; + void fill_partite(bool all) const; real aggiorna_residuo(); - void update_partita(const TPartita& game, int prow, bool all) const; + + void update_partita(const TPartita& game, int prow) const; + void update_saldo_clifo() const; public: TSheet_field& partite() const { return (TSheet_field&)field(P_PARTITE); } @@ -144,7 +148,7 @@ bool TGame_mask::partite_notify(TSheet_field& partite, int r, KEY k) TGame_mask& gm = (TGame_mask&)partite.mask(); gm._riga_partite = r; - TSheet_field& scadenze = gm.scadenze(); + TString_array& scadenze = gm.scadenze().rows_array(); scadenze.destroy(); const TBill& zio = gm.conto(); // Conto cliente/fornitore @@ -166,7 +170,8 @@ bool TGame_mask::partite_notify(TSheet_field& partite, int r, KEY k) for (int ra = 1; ra <= riga.rate(); ra++) { const TRiga_scadenze& scad = riga.rata(ra); - TToken_string& row = scadenze.row(-1); + + TToken_string& row = scadenze.row(scadenze.add("")); row.add(ri); row.add(ra); row.add(riga.get(PART_DATADOC)); @@ -180,12 +185,13 @@ bool TGame_mask::partite_notify(TSheet_field& partite, int r, KEY k) row.add(riga.get(PART_PROTIVA)); const int lastp = scad.last(); + const bool in_valuta = scad.in_valuta(); for (int pa = scad.first(); pa <= lastp; pa = scad.succ(pa)) { const TRiga_partite& rigp = game->riga(pa); const TRectype& pag = scad.row(pa); - TToken_string& row = scadenze.row(-1); + TToken_string& row = scadenze.row(scadenze.add("")); row.add(ri); row.add(ra); row.add(rigp.get(PART_DATADOC)); @@ -193,15 +199,29 @@ bool TGame_mask::partite_notify(TSheet_field& partite, int r, KEY k) row.add(rigp.get(PART_DATAREG)); row.add(scad.get(SCAD_DATASCAD)); row.add(pag.get_real(SCAD_IMPORTO).string()); - row.add(pag.get_real(SCAD_IMPORTOVAL).string(0, 2)); + row.add(in_valuta ? pag.get_real(SCAD_IMPORTOVAL).string(0, 2) : ""); row.add(rigp.get(PART_DESCR)); row.add(rigp.get(PART_NUMDOC)); row.add(""); row.add(pa); } + + TToken_string& sal = scadenze.row(scadenze.add("")); + sal.add(ri); + sal.add(ra); + sal.add(""); + sal.add(""); + sal.add(""); + sal.add(""); + sal.add(scad.residuo(FALSE).string()); + sal.add(in_valuta ? scad.residuo(TRUE).string(0, 2) : ""); + sal.add("Saldo della rata "); sal << ra; + sal.add(""); + sal.add(""); } } - scadenze.force_update(); + + gm.scadenze().force_update(); if (should_delete_game) delete game; } @@ -248,7 +268,7 @@ bool TGame_mask::edit_scadenza_handler(TMask_field& f, KEY k) if (dirty) { - gm.update_partita(game, gm._riga_partite, TRUE); + gm.update_partita(game, gm._riga_partite); partite_notify(gm.partite(), gm._riga_partite, K_TAB); gm.aggiorna_residuo(); } @@ -268,29 +288,74 @@ void TGame_mask::add_importo(TToken_string& s, const TImporto& i) const } } -void TGame_mask::update_partita(const TPartita& game, int prow, bool all) const +TImporto TGame_mask::get_importo(TToken_string& s, int pos) const +{ + const TFixed_string imp(s.get(pos)); + const real i(imp); + const char sez = imp.right(1)[0]; + return TImporto(sez, i); +} + + +void TGame_mask::update_partita(const TPartita& game, int prow) const { TImporto saldo, doc, pag, imp; game.calcola_saldo(saldo, doc, pag, imp); - if (all || !saldo.is_zero()) - { - int riga_fatt = game.prima_fattura(); - if (riga_fatt < 1) riga_fatt = game.first(); // E' un anticipo - const TRiga_partite& riga = game.riga(riga_fatt); - - TToken_string &r = partite().row(prow); // Stringa di lavoro per lo sheet - r.cut(0); - r.add(riga.get(PART_ANNO)); - r.add(riga.get(PART_NUMPART)); - r.add(riga.get(PART_DATADOC)); - r.add(riga.get(PART_NUMDOC)); - add_importo(r, saldo); - add_importo(r, doc); - add_importo(r, pag); - add_importo(r, imp); - r.add(riga.get(PART_DESCR)); + int riga_fatt = game.prima_fattura(); + if (riga_fatt <= 0) riga_fatt = game.first(); // E' un anticipo + const TRiga_partite& riga = game.riga(riga_fatt); + + TToken_string &r = partite().row(prow); // Stringa di lavoro per lo sheet + r.cut(0); + r.add(riga.get(PART_ANNO)); + r.add(riga.get(PART_NUMPART)); + r.add(riga.get(PART_DATADOC)); + r.add(riga.get(PART_NUMDOC)); + add_importo(r, saldo); + add_importo(r, doc); + add_importo(r, pag); + add_importo(r, imp); + r.add(riga.get(PART_DESCR)); + + if (prow >= 0) + update_saldo_clifo(); +} + +void TGame_mask::update_saldo_clifo() const +{ + TString_array& s = partite().rows_array(); + + TImporto sal, doc, pag, imp; + for (int i = 0; i < s.items(); i++) + { + TToken_string& r = s.row(i); + if (r.get_int(0) > 0) + { + sal += get_importo(r, 4); + doc += get_importo(r, -1); + pag += get_importo(r, -1); + imp += get_importo(r, -1); + } + else + break; } + + TToken_string& r = s.row(s.add("", i)); + r.add(""); + r.add(""); + r.add(TDate(TODAY).string()); + r.add(""); + add_importo(r, sal); + add_importo(r, doc); + add_importo(r, pag); + add_importo(r, imp); + r.add("Saldo "); + + if (get(P_TIPOC)[0] == 'C') + r << "cliente"; + else + r << "fornitore"; } void TGame_mask::fill_partite(bool all) const @@ -308,7 +373,8 @@ void TGame_mask::fill_partite(bool all) const partita.put(PART_SOTTOCONTO, conto().sottoconto()); } else conto().put(partita.curr()); // Scrive completamente i conti normali - + + const long nreg = app().curr_mask().get_long(F_NUMREG); const TRectype filter(partita.curr()); // Record campione for (int err = partita.read(_isgteq); @@ -328,13 +394,15 @@ void TGame_mask::fill_partite(bool all) const should_delete_game = TRUE; } - update_partita(*game, -1, all); + if (all || (!game->chiusa() || game->mov2rig(nreg, 0) > 0)) + update_partita(*game, -1); if (should_delete_game) delete game; partita.put(PART_NRIGA, 9999); // Forza lettura partita successiva nella prossima read } + update_saldo_clifo(); partite().force_update(); if (a.items() > 0) diff --git a/cg/saldacon.cpp b/cg/saldacon.cpp index 9c4084ab6..d8b306f05 100755 --- a/cg/saldacon.cpp +++ b/cg/saldacon.cpp @@ -37,9 +37,9 @@ void TTree_rectype::copy_key_to_row(TRectype& row) const 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]; + for (int i = recd->Ky[numkey].NkFields-1; i >= 0; 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; @@ -253,7 +253,7 @@ TImporto TRiga_scadenze::calcola_differenza_cambio(bool update) real TRiga_scadenze::residuo(bool val) const { TImporto residuo(importo_da_pagare(val)); - residuo -= importo_pagato(val); + residuo += importo_pagato(val); // Somma con sezione opposta return residuo.valore(); } @@ -335,7 +335,20 @@ TRiga_partite::TRiga_partite(const TRiga_partite& r) { CHECK(_partita, "Partita nulla"); } - + +TRiga_scadenze& TRiga_partite::new_row(int r) +{ + if (r <= 0) r = last()+1; + + if (_recarr.rows() == 0) + { + TRiga_scadenze* scad = new TRiga_scadenze(this); + copy_key_to_row(*scad); + _recarr.set_key(scad); // Altrimenti le righe sarebbero dei TRectype! + } + + return (TRiga_scadenze&)_recarr.row(r, TRUE); +} int TRiga_partite::read(TBaseisamfile& f, word op) { @@ -345,10 +358,6 @@ int TRiga_partite::read(TBaseisamfile& f, word op) 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(); @@ -436,8 +445,8 @@ bool TPartita::read(const TBill& clifo, int anno, const char* num) unas.put(PART_SOTTOCONTO, partita->get(PART_SOTTOCONTO)); unas.put(PART_ANNO, partita->get(PART_ANNO)); unas.put(PART_NUMPART, partita->get(PART_NUMPART)); - unas.put(PART_NRIGA, 0); // Numeri magici di non assegamento - unas.put(SCAD_NRATA, 0); + unas.put(PART_NRIGA, (int)UNASSIGNED); + unas.put(SCAD_NRATA, (int)UNASSIGNED); _unassigned.read(unas); return ok(); @@ -462,8 +471,20 @@ bool TPartita::remove() { _part.destroy_rows(); return rewrite(); +} + + +// Crea un nuova riga partite e gli copia la chiave principale e il conto cliente/fornitore +TRiga_partite& TPartita::nuova_riga() +{ + TRiga_partite& nuova = (TRiga_partite&)_part.row(last()+1, TRUE); + const TRiga_partite& prima = riga(first()); + nuova.put(PART_GRUPPOCL, prima.get(PART_GRUPPOCL)); + nuova.put(PART_CONTOCL, prima.get(PART_CONTOCL)); + return nuova; } + TImporto TPartita::importo_speso(long nreg, int numrig, bool extra) const { TImporto imp; @@ -529,8 +550,11 @@ int TPartita::mov2rig(long numreg, int rm) const for (int r = last(); 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; + if (row.get_long(PART_NREG) == numreg) + { + if (rm <= 0 || row.get_int(PART_NUMRIG) == rm) + return r; + } } return -1; } @@ -619,10 +643,34 @@ bool TPartita::utilizzata(int nrigp) const return TRUE; } } - } - return FALSE; + } + return _unassigned.exist(nrigp); } + +bool TPartita::remove_unassigned(long nreg) +{ + bool found = FALSE; + + for (int u = _unassigned.last_row(); u > 0; u = _unassigned.pred_row(u)) + { + const TRectype& pag = _unassigned.row(u); + const int nrigp = pag.get_int(PAGSCA_NRIGP); + TRiga_partite& sum = riga(nrigp); + if (sum.get_long(PART_NREG) == nreg) + { + TRectype zero(pag); zero.zero(); + sum.update(pag, zero, PART_IMPORTO); + sum.update(pag, zero, PART_IMPORTOVAL); + sum.update(pag, zero, PART_RITENUTE); + _unassigned.destroy_row(u); + found = TRUE; + } + } + + return found; +} + 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) @@ -774,7 +822,10 @@ int TPartite_array::add_reg_num(long nreg, int numrig) TCursor cur(&rel, "", 2, &filter, &filter); for (cur = 0; cur.ok(); ++cur) - partita(part); // Aggiungi partita se non esiste gia' + { + TPartita& p = partita(part); // Aggiungi partita se non esiste gia' + p.remove_unassigned(nreg); // Togli righe non assegnate + } return (int)cur.items(); } diff --git a/cg/saldacon.h b/cg/saldacon.h index 5a796c4f4..0fe2c65bd 100755 --- a/cg/saldacon.h +++ b/cg/saldacon.h @@ -107,6 +107,7 @@ public: // TTree_rectype public: int rate() const { return _recarr.rows(); } TRiga_scadenze& rata(int r) const { return (TRiga_scadenze&)_recarr.row(r); } + TRiga_scadenze& new_row(int r = -1); int ultimo_pagamento(int rata) const; char sezione() const { return get_char("SEZ"); } @@ -120,6 +121,8 @@ public: class TPartita : public TObject { + enum { UNASSIGNED = 9999 }; + TRecord_array _part; TRecord_array _unassigned; @@ -128,7 +131,7 @@ public: // TObject 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); } + TRiga_partite& nuova_riga(); int succ(int r) const { return _part.succ_row(r); } int pred(int r) const { return _part.pred_row(r); } @@ -147,6 +150,7 @@ public: int primo_pagamento(long nreg = -1l) const; bool utilizzata(int r) const; // Controlla se esistono pagamenti sommati alla riga r + bool remove_unassigned(long nreg); bool chiusa(bool update = FALSE);