diff --git a/cg/cg2100.cpp b/cg/cg2100.cpp index 790fdc4e3..bb459d7e0 100755 --- a/cg/cg2100.cpp +++ b/cg/cg2100.cpp @@ -279,7 +279,7 @@ bool TPrimanota_application::read_caus(const char* cod, int year) if (nriga < 1) continue; // Considera solo righe reali (non riempimenti) TBill tc; causale().bill(nriga, tc); - if (tc.gruppo() < 1) continue; // Considera solo gruppi validi + if (tc.gruppo() <= 0) continue; // Considera solo gruppi validi if (tc.tipo() > ' ' && tc.ok()) { @@ -289,8 +289,8 @@ bool TPrimanota_application::read_caus(const char* cod, int year) } int err = 0; - if (tc.descrizione() == "Sconosciuto") err = 1; else - if (tc.sospeso()) err = 2; + if (tc.descrizione() == "Sconosciuto") err = 1; + else if (tc.sospeso()) err = 2; if (err) { @@ -310,8 +310,8 @@ bool TPrimanota_application::read_caus(const char* cod, int year) char tipr = ' '; if (_is_saldaconto) { - if (nriga < 13 && nriga != 10 && nriga != 2) continue; // Si considerano solo le spese - tipr = (nriga == 2) ? 'L' : 'G'; + if (nriga < 13 && nriga != 10) continue; // Si considerano solo le spese + tipr = 'G'; } const int pos = set_cgs_row(-1, zero, tc, desc, tipr); if (sezione > ' ') @@ -543,7 +543,15 @@ void TPrimanota_application::init_insert_mode(TMask& m) void TPrimanota_application::init_modify_mode(TMask& m) { - init_mask(m); + init_mask(m); + + partite().destroy(); + if (is_pagamento()) + { + const long numreg = m.get_long(F_NUMREG); + partite().add_numreg(numreg); + } + calcola_saldo(); // Verifica eventuali sbilanci contabili } @@ -611,10 +619,6 @@ int TPrimanota_application::read(TMask& m) disable_cgs_cells(i, tipo); } - partite().destroy(); - if (is_pagamento()) - partite().add_numreg(numreg); - if (_iva == nessuna_iva) return _rel->status(); diff --git a/cg/cg2102.cpp b/cg/cg2102.cpp index 0af5ee2d4..207134d09 100755 --- a/cg/cg2102.cpp +++ b/cg/cg2102.cpp @@ -102,7 +102,6 @@ bool TPrimanota_application::suspended_handler(TMask_field& f, KEY k) { if (f.to_check(k)) { - CHECKD(f.is_edit(), "Can't check suspension of a non edit-field ", f.dlg()); const TEdit_field& c = (const TEdit_field&)f; const TBrowse* b = c.browse(); CHECKD(b, "Can't check suspension of a edit-field without a USE ", f.dlg()); @@ -418,15 +417,22 @@ void TPrimanota_application::cgs_pack() { TString_array& rows = cgs().rows_array(); const bool pagamento = is_pagamento(); + const long numreg = curr_mask().get_long(F_NUMREG); for (int i = rows.items()-1; i >= 0; i--) { TToken_string& r = rows.row(i); if (can_remove(r)) - { + { + bool ok = TRUE; if (pagamento && row_type(r) == 'K') - cg_notify(cgs(), i, K_DEL); - rows.destroy(i, TRUE); + { + ok = !partite().utilizzata(numreg, i+1); + if (ok) + cg_notify(cgs(), i, K_DEL); + } + if (ok) + rows.destroy(i, TRUE); } } if (!pagamento) // Il pagamento e' gia' ordinato diff --git a/cg/cg2104.cpp b/cg/cg2104.cpp index 357277a52..073b93bb4 100755 --- a/cg/cg2104.cpp +++ b/cg/cg2104.cpp @@ -15,6 +15,7 @@ #include #include #include +#include bool TPrimanota_application::pag_notify(TSheet_field&, int r, KEY k) { @@ -539,3 +540,236 @@ void TPrimanota_application::write_scadenze(const TMask& m) } +/////////////////////////////////////////////////////////// +// Gestione pagamenti +/////////////////////////////////////////////////////////// + +bool TPrimanota_application::showpartite_handler(TMask_field& f, KEY k) +{ + bool ok = TRUE; + TMask& m = f.mask(); + + const char tipo = m.get(116)[0]; + if (tipo == 'K' || (tipo == 'T' && app().causale().tipomov() == 2)) + { + TSheet_field& s = *m.get_sheet(); + const int riga = s.selected(); + + if (k == K_SPACE) + { + const bool ok = app().edit_partite(riga); + if (ok) + k = K_ENTER; + } + + if (k == K_ENTER) + { + const long curreg = app().curr_mask().get_long(F_NUMREG); + const TImporto importo(app().get_cgs_imp(riga)); + const TImporto speso(app().partite().importo_speso(curreg, riga+1)); + if (importo != speso) + { + const char* ss = speso.valore().string("."); + return f.error_box("L'importo deve essere %s %c", ss, speso.sezione()); + } + if (tipo == 'K' && !speso.is_zero()) + app().disable_cgs_cells(riga, 'K'); + } + } + return ok; +} + + +// deleting significato +// -1 non sto cancellando nulla +// 0 sto cancellando tutto +// 1 sto cancellando la prima riga contabile +// n sto cancellando la ennesima riga contabile +bool TPrimanota_application::notify_edit_pagamento(TPartita& p, TRectype& new_pag, + const TValuta& valuta, int deleting) +{ + const int nriga = new_pag.get_int(PAGSCA_NRIGA); // Riga fattura + const int nrata = new_pag.get_int(PAGSCA_NRATA); // Numero rata + const int nrigp = new_pag.get_int(PAGSCA_NRIGP); // Riga pagamento + const TRectype& old_pag = p.pagamento(nriga, nrata, nrigp); + const TRiga_partite& somma = p.riga(nrigp); + const int riga_contabile = somma.get_int(PART_NUMRIG); // Riga movimento + + if (deleting != 0) + { + const char sez = somma.sezione(); // Sezione importo e ritenute + const char controsez = sez == 'A' ? 'D' : 'A'; // Sezione contropartita + + // Aggiornamento contopartita + const TImporto old_importo(controsez, old_pag.get_real(PAGSCA_IMPORTO)); + TBill old_conto; old_conto.get(old_pag, TRUE); + + const TImporto new_importo(controsez, new_pag.get_real(PAGSCA_IMPORTO)); + TBill new_conto; new_conto.get(new_pag, TRUE); + + if (old_importo != new_importo || old_conto != new_conto) + { + const int old_riga = bill2pos(old_conto, 'I'); + if (old_riga >= 0) + { + const bool empty = sub_cgs_imp(old_riga, old_importo); + if (empty && (new_importo.is_zero() || new_conto != old_conto)) + reset_cgs_row(old_riga); + } + + // Importo della contropartita + if (!new_importo.is_zero() && new_conto.ok()) + { + const int new_riga = bill2pos(new_conto, 'I'); + if (new_riga < 0) + set_cgs_row(new_riga, new_importo, new_conto, "", 'I'); + else + add_cgs_imp(new_riga, new_importo); + } + } + + // Aggiornamento ritenute + const real old_ritenute(old_pag.get(PAGSCA_RITENUTE)); + const real new_ritenute(new_pag.get(PAGSCA_RITENUTE)); + if (old_ritenute != new_ritenute) + { + const TImporto grow_ritenute(controsez, new_ritenute-old_ritenute); + const riga = type2pos('F'); + if (riga < 0) + { + TBill conto_rit; causale().bill(11, conto_rit); + set_cgs_row(riga, grow_ritenute, conto_rit, causale().desc_agg(11), 'F'); + } + else + { + const bool empty = add_cgs_imp(riga, grow_ritenute); + if (empty) reset_cgs_row(riga); + } + } + } // if (deleting != 0) + + char old_ap, new_ap; + TImporto old_abbuono, new_abbuono, old_diffcam, new_diffcam; + const bool empty = p.modifica_pagamento(new_pag, valuta, + old_ap, old_abbuono, old_diffcam, + new_ap, new_abbuono, new_diffcam); + + if (deleting != 0) + { + // Se c'e' differenza negli abbuoni + if (old_abbuono != new_abbuono || old_ap != new_ap) + { + if (old_ap != ' ') // Se c'era un abbuono ... + { + const int riga_abb = type2pos(old_ap); + CHECK(riga_abb >= 0, "Chiss'e' fregato gli abbuoni?"); + const bool empty = sub_cgs_imp(riga_abb, old_abbuono); + if (empty && new_ap != old_ap) + reset_cgs_row(riga_abb); + + if (deleting != riga_contabile) + { + // Sottrae l'abbuono con la sezione invertita dalla riga contabile + add_cgs_imp(riga_contabile-1, old_abbuono); + } + } + if (new_ap != ' ') // Se ci sono abbuoni + { + const riga_abb = type2pos(new_ap); + if (riga_abb < 0) + { + const int rc = new_ap == 'A' ? 9 : 8; + TBill conto_abb; causale().bill(rc, conto_abb); + app().set_cgs_row(riga_abb, new_abbuono, conto_abb, causale().desc_agg(rc), new_ap); + } + else + add_cgs_imp(riga_abb, new_abbuono); + + if (deleting != riga_contabile) + { + // Aggiunge l'abbuono con la sezione invertita + sub_cgs_imp(riga_contabile-1, new_abbuono); + } + } + } + + // Se c'e' variazione nella differenza cambi + if (old_diffcam != new_diffcam) + { + const int riga_diffcam = type2pos('C'); + TImporto grow_diffcam(new_diffcam); + grow_diffcam -= old_diffcam; + grow_diffcam.normalize(); + + if (riga_diffcam < 0) + { + TBill conto_diffcam; causale().bill(12, conto_diffcam); + set_cgs_row(riga_diffcam, grow_diffcam, conto_diffcam, causale().desc_agg(12), 'C'); + } + else + { + const bool empty = add_cgs_imp(riga_diffcam, grow_diffcam); + if (empty) reset_cgs_row(riga_diffcam); + } + + if (deleting != riga_contabile) + { + // Aggiunge la differenza con la sezione invertita + sub_cgs_imp(riga_contabile-1, grow_diffcam); + } + } + } // if (deleting != 0) + + return empty; +} + +// Scorre tutte le righe della partita ed azzera i pagamenti relativi a alla riga contabile +// cancellata e decrementa i numeri riga superiori a numrig +bool TPrimanota_application::notify_cgline_deletion(TPartita& partita, long nreg, int numrig) +{ + bool found = FALSE; + + for (int p = partita.last(); p > 0; p = partita.pred(p)) + { + TRiga_partite& part = partita.riga(p); + if (part.get_int(PART_TIPOMOV) == 1) + { + for (int r = part.rate(); r > 0; r--) + { + const TRiga_scadenze& scad = part.rata(r); + for (int s = scad.last(); s > 0; s = scad.pred(s)) + { + const TRiga_partite& sum = partita.riga(s); + if (sum.get_long(PART_NREG) == nreg && + (numrig <= 0 || sum.get_int(PART_NUMRIG) == numrig)) + { + TRectype nul_pag(scad.row(s)); + nul_pag.zero(PAGSCA_IMPORTO); + nul_pag.zero(PAGSCA_IMPORTOVAL); + nul_pag.zero(PAGSCA_RITENUTE); + nul_pag.put(PAGSCA_ACCSAL, 'A'); + const TValuta val; // Non cambiare valuta + notify_edit_pagamento(partita, nul_pag, val, numrig); + found = TRUE; + } + } + } + } + else + { + if (numrig > 0 && part.get_long(PART_NREG) == nreg && part.get_int(PART_NUMRIG) > numrig) + part.put(PART_NUMRIG, numrig-1); + } + } + + return found; +} + +bool TPrimanota_application::notify_cgline_deletion(int numrig) +{ + bool found = FALSE; + const long nreg = curr_mask().get_long(F_NUMREG); + for (TPartita* game = _partite.first(); game; game = _partite.next()) + found |= notify_cgline_deletion(*game, nreg, numrig); + return found; +} \ No newline at end of file diff --git a/cg/cg2105.cpp b/cg/cg2105.cpp index fce460790..6f46acd0f 100755 --- a/cg/cg2105.cpp +++ b/cg/cg2105.cpp @@ -1,8 +1,14 @@ #include // Serve per DLG_NEWREC -#include "cg2102.h" // Applicazione di prima nota +#ifdef __EXTRA__ +#else + +#include "cg2102.h" // Applicazione di prima nota #include "cg2100.h" // Campi maschere prima nota + +#endif + #include "cg2100p.h" // Campi maschere partite e pagamenti #include // Archivio clienti/fornitori @@ -11,6 +17,138 @@ #include // Archivio partite #include // Archivio scadenze +/////////////////////////////////////////////////////////// +// Maschera pagamenti +/////////////////////////////////////////////////////////// + +class TPay_mask : public TMask +{ + real _da_pagare; + TValuta _valuta; + +protected: + static bool importo_handler(TMask_field& f, KEY k); + +public: + void set_pag(const TRectype& oldpag, const TRiga_scadenze& scad); + void get_pag(TRectype& oldpag) const; + const TValuta& valuta() const { return _valuta; } + + TPay_mask(); + virtual ~TPay_mask() {} +}; + +TPay_mask::TPay_mask() : TMask("cg2100s") +{ +} + +void TPay_mask::set_pag(const TRectype& oldpag, const TRiga_scadenze& scad) +{ + TRelation rel(LF_PAGSCA); // Working relation + rel.curr() = oldpag; + autoload(&rel); // Load current record on mask + + const TRiga_partite& fatt = scad.riga(); + set(S_NUMDOC, fatt.get(PART_NUMDOC)); // Numero documento + set(S_DATADOC, fatt.get(PART_DATADOC)); // Data documento + set(S_NUMPROT, fatt.get(PART_PROTIVA)); // Protocollo IVA + set(S_DESCR, fatt.get(PART_DESCR)); // Descrizione documento + + set(S_DATA_SCAD, scad.get(SCAD_DATASCAD)); // Data della scadenza + set(S_SEZIONE_SCAD, scad.riga().sezione()); // Sezione della rata + set(S_IMPORTO_SCAD, scad.get(SCAD_IMPORTO)); // Importo della rata + set(S_IMPORTOVAL_SCAD, scad.get(SCAD_IMPORTOVAL)); // Importo in valuta + + const bool in_valuta = scad.in_valuta(); + _da_pagare = scad.residuo(in_valuta).valore(); // Calcola residuo in valuta + + TReal_field& res = (TReal_field&)field(S_RESIDUORATA); + res.set_decimals(in_valuta ? 2 : 0); + res.set(_da_pagare.string()); + if (!_da_pagare.is_zero()) + set_handler(in_valuta ? S_IMPORTOVAL : S_IMPORTO, importo_handler); + + // Ricorda l'importo da pagare + _da_pagare += oldpag.get_real(in_valuta ? PAGSCA_IMPORTOVAL : PAGSCA_IMPORTO); + + // Attiva campi relativi alla valuta + show(-3, in_valuta); + + const TPartita& p = scad.partita(); + const int nrigp = oldpag.get_int(PAGSCA_NRIGP); + const TRiga_partite& sum = p.riga(nrigp); + _valuta.get(sum); + + const long numreg = sum.get_long(PART_NREG); + const int numrig = sum.get_int(PART_NUMRIG); +#ifdef __EXTRA__ + TImporto residuo(app().curr_mask().get(F_TOTALE)); +#else + TImporto residuo(app().get_cgs_imp(numrig-1)); +#endif + residuo -= app().partite().importo_speso(numreg, numrig); + set(S_RESIDUOPAG, residuo.valore().string()); + + // Il flag di saldo/acconto e' attivo solo se non ci sono acconti + bool sa = oldpag.get_int(PAGSCA_NRIGA) != TPartita::UNASSIGNED; + if (sa) + { + const TDate datasca(fatt.get(PART_DATADOC)); + const TDate datapag(sum.get(PART_DATADOC)); + sa = datapag >= datasca; + } + else + { + hide(S_RESIDUORATA); + } + enable(S_SALDOACC, sa); + +#ifdef __EXTRA__ + const bool disabilita = TRUE; +#else + const bool disabilita = app().causale().tipomov() == 2; +#endif + if (disabilita) + send_key(K_CTRL + K_SHIFT + 'c', -2); // Disabilita contropartita e ritenute +} + +void TPay_mask::get_pag(TRectype& newpag) const +{ + TRelation rel(LF_PAGSCA); // Working relation + rel.curr() = newpag; + autosave(&rel); // Load current record from mask + newpag = rel.curr(); +} + +bool TPay_mask::importo_handler(TMask_field& f, KEY k) +{ + TPay_mask& m = (TPay_mask&)f.mask(); + + if (k == K_F8) + { + f.set(m._da_pagare.string()); + k = K_TAB; + } + + if (k == K_TAB && f.focusdirty()) + { + const real i(f.get()); + if (i >= m._da_pagare && m.field(S_SALDOACC).active()) + m.set(S_SALDOACC, "S"); + + const real residuo(m._da_pagare - i); + m.set(S_RESIDUORATA, residuo.string()); + + if (f.dlg() == S_IMPORTOVAL) + { + const real lit = m.valuta().val2lit(i); + m.set(S_IMPORTO, lit.string()); + } + } + + return TRUE; +} + /////////////////////////////////////////////////////////// // Maschera partite /////////////////////////////////////////////////////////// @@ -40,7 +178,8 @@ protected: int update_partita(const TPartita& game, int prow); void update_saldo_clifo(); - int nuovo_pagamento(TPartita& partita, int nriga, int rata); + int nuovo_pagamento(TPartita& partita, int nriga, int rata) const; + bool edit_pagamento(TPartita& p, int nriga, int nrata, int nrigp) const; bool cerca_valuta(TValuta& val) const; void aggiorna_valuta(const TValuta& val); @@ -65,19 +204,13 @@ TGame_mask::TGame_mask(const TBill& bill, long numreg, int riga) set(P_DESCR, ((TBill&)_conto).descrizione()); TValuta val; - if (numreg > 0) - { - TMask& cm = app().curr_mask(); - val.get(cm, S_VALUTA, S_DATACAMBIO, S_CAMBIO); - } - if (val.in_valuta()) - { - cerca_valuta(val); - val.set(*this, P_VALUTA, P_DATACAMBIO, P_CAMBIO); - enable(-3); - } - else - disable(-3); +#ifndef __EXTRA__ + TMask& cm = app().curr_mask(); + val.get(cm, S_VALUTA, S_DATACAMBIO, S_CAMBIO); +#endif + cerca_valuta(val); + val.set(*this, P_VALUTA, P_DATACAMBIO, P_CAMBIO); + enable(-3, val.in_valuta()); set_handler(P_ANNO, annopart_handler); set_handler(P_NUMERO, numpart_handler); @@ -173,8 +306,12 @@ bool TGame_mask::cambio_handler(TMask_field& f, KEY k) /////////////////////////////////////////////////////////// real TGame_mask::aggiorna_residuo() -{ +{ +#ifdef __EXTRA__ + TImporto residuo(app().curr_mask().get(F_TOTALE)); +#else TImporto residuo(app().get_cgs_imp(_numrig-1)); +#endif residuo -= app().partite().importo_speso(_numreg, _numrig); set(P_RESIDUO, residuo.valore().string()); return residuo.valore(); @@ -227,7 +364,11 @@ void TGame_mask::aggiorna_valuta(const TValuta& val) real imp(pag.get(PAGSCA_IMPORTOVAL)); val.val2lit(imp); pag.put(PAGSCA_IMPORTO, imp); // Converte in lire l'importo in valuta +#ifdef __EXTRA__ + game->modifica_pagamento(pag, val); +#else app().notify_edit_pagamento(*game, pag, val); +#endif } } } @@ -235,9 +376,14 @@ void TGame_mask::aggiorna_valuta(const TValuta& val) } if (annorif != 0) - { - const bool nota_credito = app().causale().tipomov() == 2; - if (nota_credito) + { + const bool proponi = +#ifdef __EXTRA__ + TRUE; +#else + app().causale().tipomov() == 2; +#endif + if (proponi) { const TMask& cm = app().curr_mask(); const int anno = cm.get_int(F_ANNORIF); @@ -336,7 +482,7 @@ bool TGame_mask::partite_notify(TSheet_field& partite, int r, KEY k) if (in_valuta) { add_importo(rabb, scad.importo_pagato(FALSE, 0x2)); - add_importo(rabb, abb.normalize()); + add_importo(rabb, abb); } else { @@ -364,13 +510,15 @@ bool TGame_mask::partite_notify(TSheet_field& partite, int r, KEY k) rsal.add("", 5); TImporto sl(scad.residuo(FALSE, 0x7)); + sl.normalize(); add_importo(rsal, sl); - tot_lit += sl.normalize(); + tot_lit += sl; if (in_valuta) { sl = scad.residuo(TRUE, 0x3); - tot_val += sl.normalize(); + sl.normalize(); + tot_val += sl; add_importo(rsal, sl, 2); } } @@ -394,12 +542,14 @@ bool TGame_mask::partite_notify(TSheet_field& partite, int r, KEY k) row.add(""); TImporto i(sum.sezione(), pag.get_real(PAGSCA_IMPORTO)); + i.normalize(); tot_lit += i; add_importo(row, i); if (in_valuta) { i = TImporto(sum.sezione(), pag.get_real(PAGSCA_IMPORTOVAL)); tot_val += i; + i.normalize(); add_importo(row, i, 2); } else @@ -425,13 +575,16 @@ bool TGame_mask::partite_notify(TSheet_field& partite, int r, KEY k) return TRUE; } -int TGame_mask::nuovo_pagamento(TPartita& partita, int nriga, int rata) +int TGame_mask::nuovo_pagamento(TPartita& partita, int nriga, int rata) const { const TBill& conto = partita.conto(); // Legge conto principale int nrigp = partita.mov2rig(_numreg, _numrig); // Cerca riga partita relativa alla riga rmov TMask& cm = app().curr_mask(); + +#ifndef __EXTRA__ const TCausale& causale = app().causale(); - +#endif + if (nrigp <= 0) // Devo creare una nuova riga di partita { TRiga_partite& part = partita.new_row(); // Creazione nuova riga vuota @@ -440,14 +593,21 @@ int TGame_mask::nuovo_pagamento(TPartita& partita, int nriga, int rata) // Copia dati movimento corrente part.put(PART_NREG, _numreg); // Numero operazione part.put(PART_NUMRIG, _numrig); // Riga su cui ho cliccato - part.put(PART_DATAREG, cm.get(F_DATAREG)); part.put(PART_DATADOC, cm.get(F_DATADOC)); - part.put(PART_NUMDOC, cm.get(F_NUMDOC)); part.put(PART_DESCR, cm.get(F_DESCR)); - part.put(PART_CODVAL, cm.get(S_VALUTA)); - part.put(PART_CAMBIO, cm.get(S_CAMBIO)); - part.put(PART_DATACAM, cm.get(S_DATACAMBIO)); + part.put(PART_CODVAL, get(P_VALUTA)); + part.put(PART_CAMBIO, get(P_CAMBIO)); + part.put(PART_DATACAM, get(P_DATACAMBIO)); +#ifdef __EXTRA__ + part.zero(PART_DATAREG); + part.zero(PART_NUMDOC); + // Complesso algoritmo per calcolare la sezione di una nuova riga partita + const char sezione = (conto.tipo() == 'C') ? 'A' : 'D'; +#else + part.put(PART_DATAREG, cm.get(F_DATAREG)); + part.put(PART_NUMDOC, cm.get(F_NUMDOC)); + // Copia dati causale corrente const int tipomov = causale.tipomov(); part.put(PART_TIPOMOV, tipomov); @@ -457,7 +617,7 @@ int TGame_mask::nuovo_pagamento(TPartita& partita, int nriga, int rata) part.put(PART_REG, cm.get(F_CODREG)); part.put(PART_PROTIVA, cm.get(F_PROTIVA)); } - + // Complesso algoritmo per calcolare la sezione di una nuova riga partita char sezione = causale.sezione(1); // Usa la sezione della causale if (sezione <= ' ') // Se non c'e' la sezione bell'e' ch'e' pronta @@ -474,6 +634,7 @@ int TGame_mask::nuovo_pagamento(TPartita& partita, int nriga, int rata) if (bill.tipo() != conto.tipo()) sezione = (sezione == 'D') ? 'A' : 'D'; // scambia segno } +#endif part.put(PART_SEZ, sezione); // Memorizza solo la sezione (importi nulli) part.put(PART_SEZABB, sezione); @@ -515,11 +676,13 @@ int TGame_mask::nuovo_pagamento(TPartita& partita, int nriga, int rata) pagamento.put(PAGSCA_CODAG, scad.get(SCAD_CODAG)); pagamento.put(PAGSCA_DATAPAG, cm.get(F_DATADOC)); } - + +#ifndef __EXTRA__ TBill contro; causale.bill(caus, contro); // Legge conto contropartita - if (contro.empty()) // Se non specificato ... - causale.bill(caus = 1, contro); // ... prende il primo + if (caus != 2 && contro.empty()) // Se non specificato ... + causale.bill(caus = 2, contro); // ... prende il primo contro.put(pagamento, TRUE); // Scrive conto contropartita +#endif return nrigp; } @@ -557,8 +720,7 @@ bool TGame_mask::edit_scadenza_handler(TMask_field& f, KEY k) return f.error_box("Modificare il movimento %ld", nreg); } - const bool dirty = app().edit_pagamento(game, nriga, nrata, nrigp); - + const bool dirty = gm.edit_pagamento(game, nriga, nrata, nrigp); if (dirty) { gm.update_partita(game, gm._riga_partite); @@ -580,7 +742,12 @@ bool TGame_mask::nuovo_handler(TMask_field& f, KEY k) new_game.add_button(DLG_CANCEL, 0, "" , -22, 3, 8, 2); new_game.first_focus(P_NUMERO); - if (app().causale().tipomov() == 2) +#ifdef __EXTRA__ + const bool proponi = TRUE; +#else + const bool proponi = app().causale().tipomov() == 2; +#endif + if (proponi) { const TMask& cm = app().curr_mask(); new_game.set(P_ANNO, cm.get(F_ANNORIF)); @@ -599,7 +766,7 @@ bool TGame_mask::nuovo_handler(TMask_field& f, KEY k) const int nriga = TPartita::UNASSIGNED; const int nrata = TPartita::UNASSIGNED; const int nrigp = gm.nuovo_pagamento(game, nriga, nrata); - app().edit_pagamento(game, nriga, nrata, nrigp); + gm.edit_pagamento(game, nriga, nrata, nrigp); if (game.ok()) { game.write(); @@ -787,340 +954,8 @@ void TGame_mask::fill_partite(int annorif, const char* numrif) app().end_wait(); } -/////////////////////////////////////////////////////////// -// Paymask -/////////////////////////////////////////////////////////// -class TPay_mask : public TMask -{ - bool _in_valuta; - real _da_pagare; - TValuta _valuta; - -protected: - static bool importo_handler(TMask_field& f, KEY k); - -public: - void set_pag(const TRectype& oldpag, const TRiga_scadenze& scad); - void get_pag(TRectype& oldpag) const; - const TValuta& valuta() const { return _valuta; } - - TPay_mask(); - virtual ~TPay_mask() {} -}; - -TPay_mask::TPay_mask() : TMask("cg2100s") -{ -} - -void TPay_mask::set_pag(const TRectype& oldpag, const TRiga_scadenze& scad) -{ - TRelation rel(LF_PAGSCA); // Working relation - rel.curr() = oldpag; - autoload(&rel); // Load current record on mask - - const TRiga_partite& fatt = scad.riga(); - set(S_NUMDOC, fatt.get(PART_NUMDOC)); // Numero documento - set(S_DATADOC, fatt.get(PART_DATADOC)); // Data documento - set(S_NUMPROT, fatt.get(PART_PROTIVA)); // Protocollo IVA - set(S_DESCR, fatt.get(PART_DESCR)); // Descrizione documento - - set(S_DATA_SCAD, scad.get(SCAD_DATASCAD)); // Data della scadenza - set(S_SEZIONE_SCAD, scad.riga().sezione()); // Sezione della rata - set(S_IMPORTO_SCAD, scad.get(SCAD_IMPORTO)); // Importo della rata - set(S_IMPORTOVAL_SCAD, scad.get(SCAD_IMPORTOVAL)); // Importo in valuta - - _in_valuta = scad.in_valuta(); - _da_pagare = scad.residuo(_in_valuta).valore(); // Calcola residuo in valuta - - TReal_field& res = (TReal_field&)field(S_RESIDUORATA); - res.set_decimals(_in_valuta ? 2 : 0); - res.set(_da_pagare.string()); - if (!_da_pagare.is_zero()) - set_handler(_in_valuta ? S_IMPORTOVAL : S_IMPORTO, importo_handler); - - // Ricorda l'importo da pagare - _da_pagare += oldpag.get_real(_in_valuta ? PAGSCA_IMPORTOVAL : PAGSCA_IMPORTO); - - // Attiva campi relativi alla valuta - show(-3, _in_valuta); - - const TPartita& p = scad.partita(); - const int nrigp = oldpag.get_int(PAGSCA_NRIGP); - const TRiga_partite& sum = p.riga(nrigp); - _valuta.get(sum); - - const long numreg = sum.get_long(PART_NREG); - const int numrig = sum.get_int(PART_NUMRIG); - TImporto residuo(app().get_cgs_imp(numrig-1)); - residuo -= app().partite().importo_speso(numreg, numrig); - set(S_RESIDUOPAG, residuo.valore().string()); - - // Il flag di saldo/acconto e' attivo solo se non ci sono acconti - bool sa = oldpag.get_int(PAGSCA_NRIGA) != TPartita::UNASSIGNED; - if (sa) - { - const TDate datasca(fatt.get(PART_DATADOC)); - const TDate datapag(sum.get(PART_DATADOC)); - sa = datapag >= datasca; - } - else - { - hide(S_RESIDUORATA); - } - enable(S_SALDOACC, sa); - - const bool nota_credito = app().causale().tipomov() == 2; - if (nota_credito) - send_key(K_CTRL + K_SHIFT + 'c', -2); // Disabilita contropartita e ritenute -} - -void TPay_mask::get_pag(TRectype& newpag) const -{ - TRelation rel(LF_PAGSCA); // Working relation - rel.curr() = newpag; - autosave(&rel); // Load current record from mask - newpag = rel.curr(); -} - -bool TPay_mask::importo_handler(TMask_field& f, KEY k) -{ - TPay_mask& m = (TPay_mask&)f.mask(); - - if (k == K_F8) - { - f.set(m._da_pagare.string()); - k = K_TAB; - } - - if (k == K_TAB && f.focusdirty()) - { - const real i(f.get()); - if (i >= m._da_pagare && m.field(S_SALDOACC).active()) - m.set(S_SALDOACC, "S"); - - const real residuo(m._da_pagare - i); - m.set(S_RESIDUORATA, residuo.string()); - - if (f.dlg() == S_IMPORTOVAL) - { - const real lit = m.valuta().val2lit(i); - m.set(S_IMPORTO, lit.string()); - } - } - - return TRUE; -} - -/////////////////////////////////////////////////////////// -// Metodi di prima nota -/////////////////////////////////////////////////////////// - -bool TPrimanota_application::showpartite_handler(TMask_field& f, KEY k) -{ - bool ok = TRUE; - TMask& m = f.mask(); - - const char tipo = m.get(116)[0]; - if (tipo == 'K' || (tipo == 'T' && app().causale().tipomov() == 2)) - { - TSheet_field& s = *m.get_sheet(); - const int riga = s.selected(); - - if (k == K_SPACE) - { - const bool ok = app().edit_partite(riga); - if (ok) - k = K_ENTER; - } - - if (k == K_ENTER) - { - const long curreg = app().curr_mask().get_long(F_NUMREG); - const TImporto importo(app().get_cgs_imp(riga)); - const TImporto speso(app().partite().importo_speso(curreg, riga+1)); - if (importo != speso) - { - const char* ss = speso.valore().string("."); - return f.error_box("L'importo deve essere %s %c", ss, speso.sezione()); - } - if (tipo == 'K' && !speso.is_zero()) - app().disable_cgs_cells(riga, 'K'); - } - } - return ok; -} - - -bool TPrimanota_application::edit_partite(int riga) -{ - TToken_string& cgr = cgs().row(riga); - - TImporto imp; imp = cgr; - if (imp.is_zero()) // Esci se 'importo e' nullo - return FALSE; - - const TBill b(cgr, 2, 0x3); // Legge il conto della riga selezionata - if (!b.ok()) - return FALSE; // Esci se il conto della riga cliente non e' valido - - curr_mask().autosave(get_relation()); // Aggiorna i dati della testata sulle partite - const TRectype& mov = get_relation()->curr(); - partite().update_reg(mov); - - // Esecuzione maschera di selezione partite - TGame_mask mask(b, mov.get_long(MOV_NUMREG), riga+1); - mask.run(); - cgs().force_update(); // Aggiornamento righe contabili - - return TRUE; -} - -// deleting significato -// -1 non sto cancellando nulla -// 0 sto cancellando tutto -// 1 sto cancellando la prima riga contabile -// n sto cancellando la ennesima riga contabile -bool TPrimanota_application::notify_edit_pagamento(TPartita& p, TRectype& new_pag, - const TValuta& valuta, int deleting) -{ - const int nriga = new_pag.get_int(PAGSCA_NRIGA); // Riga fattura - const int nrata = new_pag.get_int(PAGSCA_NRATA); // Numero rata - const int nrigp = new_pag.get_int(PAGSCA_NRIGP); // Riga pagamento - const TRectype& old_pag = p.pagamento(nriga, nrata, nrigp); - const TRiga_partite& somma = p.riga(nrigp); - const int riga_contabile = somma.get_int(PART_NUMRIG); // Riga movimento - - if (deleting != 0) - { - const char sez = somma.sezione(); // Sezione importo e ritenute - const char controsez = sez == 'A' ? 'D' : 'A'; // Sezione contropartita - - // Aggiornamento contopartita - const TImporto old_importo(controsez, old_pag.get_real(PAGSCA_IMPORTO)); - TBill old_conto; old_conto.get(old_pag, TRUE); - - const TImporto new_importo(controsez, new_pag.get_real(PAGSCA_IMPORTO)); - TBill new_conto; new_conto.get(new_pag, TRUE); - - if (old_importo != new_importo || old_conto != new_conto) - { - const int old_riga = bill2pos(old_conto, 'I'); - if (old_riga >= 0) - { - const bool empty = sub_cgs_imp(old_riga, old_importo); - if (empty && (new_importo.is_zero() || new_conto != old_conto)) - reset_cgs_row(old_riga); - } - - // Importo della contropartita - if (!new_importo.is_zero() && new_conto.ok()) - { - const int new_riga = bill2pos(new_conto, 'I'); - if (new_riga < 0) - set_cgs_row(new_riga, new_importo, new_conto, "", 'I'); - else - add_cgs_imp(new_riga, new_importo); - } - } - - // Aggiornamento ritenute - const real old_ritenute(old_pag.get(PAGSCA_RITENUTE)); - const real new_ritenute(new_pag.get(PAGSCA_RITENUTE)); - if (old_ritenute != new_ritenute) - { - const TImporto grow_ritenute(controsez, new_ritenute-old_ritenute); - const riga = type2pos('F'); - if (riga < 0) - { - TBill conto_rit; causale().bill(11, conto_rit); - set_cgs_row(riga, grow_ritenute, conto_rit, causale().desc_agg(11), 'F'); - } - else - { - const bool empty = add_cgs_imp(riga, grow_ritenute); - if (empty) reset_cgs_row(riga); - } - } - } // if (deleting != 0) - - char old_ap, new_ap; - TImporto old_abbuono, new_abbuono, old_diffcam, new_diffcam; - const bool empty = p.modifica_pagamento(new_pag, valuta, - old_ap, old_abbuono, old_diffcam, - new_ap, new_abbuono, new_diffcam); - - if (deleting != 0) - { - // Se c'e' differenza negli abbuoni - if (old_abbuono != new_abbuono || old_ap != new_ap) - { - if (old_ap != ' ') // Se c'era un abbuono ... - { - const int riga_abb = type2pos(old_ap); - CHECK(riga_abb >= 0, "Chiss'e' fregato gli abbuoni?"); - const bool empty = sub_cgs_imp(riga_abb, old_abbuono); - if (empty && new_ap != old_ap) - reset_cgs_row(riga_abb); - - if (deleting != riga_contabile) - { - // Sottrae l'abbuono con la sezione invertita dalla riga contabile - add_cgs_imp(riga_contabile-1, old_abbuono); - } - } - if (new_ap != ' ') // Se ci sono abbuoni - { - const riga_abb = type2pos(new_ap); - if (riga_abb < 0) - { - const int rc = new_ap == 'A' ? 9 : 8; - TBill conto_abb; causale().bill(rc, conto_abb); - app().set_cgs_row(riga_abb, new_abbuono, conto_abb, causale().desc_agg(rc), new_ap); - } - else - add_cgs_imp(riga_abb, new_abbuono); - - if (deleting != riga_contabile) - { - // Aggiunge l'abbuono con la sezione invertita - sub_cgs_imp(riga_contabile-1, new_abbuono); - } - } - } - - // Se c'e' variazione nella differenza cambi - if (old_diffcam != new_diffcam) - { - const int riga_diffcam = type2pos('C'); - TImporto grow_diffcam(new_diffcam); - grow_diffcam -= old_diffcam; - grow_diffcam.normalize(); - - if (riga_diffcam < 0) - { - TBill conto_diffcam; causale().bill(12, conto_diffcam); - set_cgs_row(riga_diffcam, grow_diffcam, conto_diffcam, causale().desc_agg(12), 'C'); - } - else - { - const bool empty = add_cgs_imp(riga_diffcam, grow_diffcam); - if (empty) reset_cgs_row(riga_diffcam); - } - - if (deleting != riga_contabile) - { - // Aggiunge la differenza con la sezione invertita - sub_cgs_imp(riga_contabile-1, grow_diffcam); - } - } - } // if (deleting != 0) - - return empty; -} - - -bool TPrimanota_application::edit_pagamento(TPartita& p, int nriga, int nrata, int nrigp) +bool TGame_mask::edit_pagamento(TPartita& p, int nriga, int nrata, int nrigp) const { const TRectype& oldpag = p.pagamento(nriga, nrata, nrigp); TRiga_partite& somma = p.riga(nrigp); @@ -1154,66 +989,48 @@ bool TPrimanota_application::edit_pagamento(TPartita& p, int nriga, int nrata, i m.reset(S_RITENUTE); // Azzera ritenute } else -{ somma.put(PART_DESCR, m.get(S_DESCAGG)); // Aggiorna descrizione (comune ai pagamenti) -} -TRectype new_pag(oldpag); -m.get_pag(new_pag); -const TValuta val; // Non cambiare valuta! -notify_edit_pagamento(p, new_pag, val); -} -return key != K_ESC; -} + + TRectype new_pag(oldpag); + m.get_pag(new_pag); - -// Scorre tutte le righe della partita ed azzera i pagamenti relativi a alla riga contabile -// cancellata e decrementa i numeri riga superiori a numrig -bool TPrimanota_application::notify_cgline_deletion(TPartita& partita, long nreg, int numrig) -{ - bool found = FALSE; - - for (int p = partita.last(); p > 0; p = partita.pred(p)) - { - TRiga_partite& part = partita.riga(p); - if (part.get_int(PART_TIPOMOV) == 1) - { - for (int r = part.rate(); r > 0; r--) - { - const TRiga_scadenze& scad = part.rata(r); - for (int s = scad.last(); s > 0; s = scad.pred(s)) - { - const TRiga_partite& sum = partita.riga(s); - if (sum.get_long(PART_NREG) == nreg && - (numrig <= 0 || sum.get_int(PART_NUMRIG) == numrig)) - { - TRectype nul_pag(scad.row(s)); - nul_pag.zero(PAGSCA_IMPORTO); - nul_pag.zero(PAGSCA_IMPORTOVAL); - nul_pag.zero(PAGSCA_RITENUTE); - nul_pag.put(PAGSCA_ACCSAL, 'A'); - const TValuta val; // Non cambiare valuta - notify_edit_pagamento(partita, nul_pag, val, numrig); - found = TRUE; - } - } - } - } - else - { - if (numrig > 0 && part.get_long(PART_NREG) == nreg && part.get_int(PART_NUMRIG) > numrig) - part.put(PART_NUMRIG, numrig-1); - } + const TValuta val; // Non cambiare valuta! +#ifdef __EXTRA__ + p.modifica_pagamento(new_pag, val); +#else + app().notify_edit_pagamento(p, new_pag, val); +#endif } - return found; + return key != K_ESC; } -bool TPrimanota_application::notify_cgline_deletion(int numrig) -{ - bool found = FALSE; - const long nreg = curr_mask().get_long(F_NUMREG); - for (TPartita* game = _partite.first(); game; game = _partite.next()) - found |= notify_cgline_deletion(*game, nreg, numrig); - return found; +/////////////////////////////////////////////////////////// +// Edit delle partite +/////////////////////////////////////////////////////////// + +bool TPrimanota_application::edit_partite(int riga) +{ + TToken_string& cgr = cgs().row(riga); + + TImporto imp; imp = cgr; + if (imp.is_zero()) // Esci se 'importo e' nullo + return FALSE; + + const TBill b(cgr, 2, 0x3); // Legge il conto della riga selezionata + if (!b.ok()) + return FALSE; // Esci se il conto della riga cliente non e' valido + + curr_mask().autosave(get_relation()); // Aggiorna i dati della testata sulle partite + const TRectype& mov = get_relation()->curr(); + partite().update_reg(mov); + + // Esecuzione maschera di selezione partite + TGame_mask mask(b, mov.get_long(MOV_NUMREG), riga+1); + mask.run(); + cgs().force_update(); // Aggiornamento righe contabili + + return TRUE; } + diff --git a/cg/saldacon.cpp b/cg/saldacon.cpp index f9677d9b1..89b06ed18 100755 --- a/cg/saldacon.cpp +++ b/cg/saldacon.cpp @@ -132,7 +132,7 @@ TValuta::TValuta() : _cod(""), _dat(TODAY), _cam(1.0) void TValuta::adjust() { _cod.upper(); - if (_cod.empty() || _cod == "LIT") + if (_cod.empty() || _cod == "LIT" || _cam.is_zero()) _cam = 1.0; } @@ -154,16 +154,34 @@ void TValuta::get(const TRectype& rec) void TValuta::put(TRectype& rec) const { - rec.put("CODVAL", _cod); - rec.put("DATACAM", _dat); - rec.put("CAMBIO", _cam); + if (in_lire()) + { + rec.zero("CODVAL"); + rec.zero("DATACAM"); + rec.zero("CAMBIO"); + } + else + { + rec.put("CODVAL", _cod); + rec.put("DATACAM", _dat); + rec.put("CAMBIO", _cam); + } } void TValuta::set(TMask& m, short v, short d, short c) const { - m.set(v, _cod); - m.set(d, _dat.string()); - m.set(c, _cam.string()); + if (in_lire()) + { + m.reset(v); + m.reset(d); + m.reset(c); + } + else + { + m.set(v, _cod); + m.set(d, _dat.string()); + m.set(c, _cam.string()); + } } void TValuta::get(const TMask& m, short v, short d, short c) @@ -286,7 +304,7 @@ TImporto TRiga_scadenze::importo_pagato(bool val, int mode) const } } - return totale; + return totale.normalize(); } // Calcola l'importo da pagare (eventualmente in valuta) @@ -362,7 +380,8 @@ TImporto TRiga_scadenze::calcola_differenza_cambio(int p, bool update) if (update) pag.zero(PAGSCA_DIFFCAM); } - return diffcam; + + return diffcam.normalize(); } TImporto TRiga_scadenze::residuo(bool val, int mode) const @@ -408,6 +427,7 @@ bool TRiga_scadenze::modifica_pagamento(const TRectype& new_pag, const TValuta& new_abb.valore() *= sum.get_real(PART_CAMBIO); new_abb.valore().round(); } + new_abb.normalize(); // Scambia sezione per registrazione contabile old_abbuono.swap_section(); @@ -720,17 +740,16 @@ void TPartita::update_reg(long nreg, const TRectype& mov) { for (int r = last(); r > 0; r = pred(r)) { - TRectype& pag = _part.row(r, FALSE); - const long reg = pag.get_long(PART_NREG); - if (reg == nreg) + TRiga_partite& rig = riga(r); + if (rig.get_long(PART_NREG) == nreg) { - pag.put(PART_NREG, mov.get(MOV_NUMREG)); - pag.put(PART_DATAREG, mov.get(MOV_DATAREG)); - pag.put(PART_DATADOC, mov.get(MOV_DATADOC)); - pag.put(PART_NUMDOC, mov.get(MOV_NUMDOC)); - pag.put(PART_REG, mov.get(MOV_REG)); - pag.put(PART_PROTIVA, mov.get(MOV_PROTIVA)); - pag.put(PART_CODCAUS, mov.get(MOV_CODCAUS)); + rig.put(PART_NREG, mov.get(MOV_NUMREG)); + rig.put(PART_DATAREG, mov.get(MOV_DATAREG)); + rig.put(PART_DATADOC, mov.get(MOV_DATADOC)); + rig.put(PART_NUMDOC, mov.get(MOV_NUMDOC)); + rig.put(PART_REG, mov.get(MOV_REG)); + rig.put(PART_PROTIVA, mov.get(MOV_PROTIVA)); + rig.put(PART_CODCAUS, mov.get(MOV_CODCAUS)); } } } @@ -754,7 +773,7 @@ int TPartita::mov2rig(long numreg, int rm) const return r; } } - return -1; + return 0; } // Trova la prima riga della partita contenente una fattura @@ -815,14 +834,19 @@ void TPartita::calcola_saldo(TImporto& saldo, TImporto& doc, TImporto& pag, TImp abbuoni.valore() *= row.get_real(PART_CAMBIO); abbuoni.valore().round(); } + imp += abbuoni; - imp += TImporto(row.get_char(PART_SEZDIFCAM), row.get_real(PART_DIFFCAM)); } saldo = doc; saldo += pag; saldo += imp; + + saldo.normalize(); + doc.normalize(); + pag.normalize(); + imp.normalize(); } // Controlla se esistono pagamenti riferiti alla riga nrigp @@ -1150,7 +1174,7 @@ int TPartite_array::add_numreg(long nreg) if (nreg != _numreg) { TRelation rel(LF_PARTITE); - TRectype& part = rel.lfile().curr(); + TRectype& part = rel.curr(); // Costruzione cursore filtrato part.zero(); @@ -1167,12 +1191,24 @@ int TPartite_array::add_numreg(long nreg) return items(); } +bool TPartite_array::utilizzata(long numreg, int numrig) +{ + bool ok = FALSE; + for (TPartita* game = first(); game; game = next()) + { + ok = game->mov2rig(numreg, numrig) > 0; + if (ok) break; + } + return ok; +} + TImporto TPartite_array::importo_speso(long nreg, int numrig) { TImporto imp; add_numreg(nreg); for (TPartita* game = first(); game; game = next()) imp += game->importo_speso(nreg, numrig); + imp.normalize(); return imp; } diff --git a/cg/saldacon.h b/cg/saldacon.h index 2a1e0b440..cf671bc12 100755 --- a/cg/saldacon.h +++ b/cg/saldacon.h @@ -276,6 +276,9 @@ public: TImporto importo_speso(long numreg, int numrig); void update_reg(const TRectype& mov, long old_reg = 0); + // Controlla se esistono righe di pagamento relative alla riga numrig + bool utilizzata(long numreg, int numrig); + TPartita* first() { restart(); return next(); } TPartita* next() { return (TPartita*)get(); }