diff --git a/cg/cg2100.cpp b/cg/cg2100.cpp index 09d63e720..ee6141524 100755 --- a/cg/cg2100.cpp +++ b/cg/cg2100.cpp @@ -249,8 +249,8 @@ bool TPrimanota_application::read_caus(const char* cod, int year) if (ok) { _is_saldaconto = gestione_saldaconto() && causale().saldaconto(); - dob = _is_saldaconto || causale().data_doc(); - nob = _is_saldaconto || causale().num_doc(); + dob = is_fattura() || causale().data_doc(); + nob = is_fattura() || causale().num_doc(); iva = causale().iva(); } @@ -716,10 +716,13 @@ int TPrimanota_application::read(TMask& m) calcola_imp(); // Calcola totale imponibile ed imposte - if (is_fattura()) // Ci sono scadenze + if (is_fattura()) // Ci dovrebbero essere delle scadenze { - if (!read_scadenze(m)) - set_scadenze(m); + if (!read_scadenze(m)) // Se non esiste fattura + { + const TString dd(m.get(F_DATADOC)); + set_pagamento(NULL, dd); // Ignora codice pagamento in testata + } } return _rel->status(); diff --git a/cg/cg2100p.uml b/cg/cg2100p.uml index 843cdc370..cca8397e8 100755 --- a/cg/cg2100p.uml +++ b/cg/cg2100p.uml @@ -35,7 +35,7 @@ BEGIN PROMPT 18 2 "Data cambio " FLAGS "DR" USE CAM - INPUT CODTAB[1,3] P_VALUTA + INPUT CODTAB[1,3] P_VALUTA SELECT INPUT CODTAB[4,11] P_DATACAMBIO DISPLAY "Valuta" CODTAB[1,3] DISPLAY "Data@10" D0 @@ -49,7 +49,7 @@ END NUMBER P_CAMBIO 15 5 BEGIN PROMPT 48 2 "Cambio " - FLAGS "DRU" + FLAGS "DU" GROUP 3 PICTURE ".5" CHECKTYPE REQUIRED diff --git a/cg/cg2102.cpp b/cg/cg2102.cpp index 5c26bde76..653ec9f02 100755 --- a/cg/cg2102.cpp +++ b/cg/cg2102.cpp @@ -505,6 +505,31 @@ real TPrimanota_application::calcola_saldo() const return sbilancio; } +HIDDEN bool imptot_error(const TImporto& imptot, const TImporto& impsal, bool val) +{ + bool ok = TRUE; + TImporto residuo(imptot); residuo += impsal; residuo.normalize(); + + if (!residuo.is_zero()) + { + const char* const pic = val ? ".3" : "."; + TString msg(255); + msg << "Il totale documento " << (val ? "in valuta" : "inserito") + << " e' " << imptot.valore().string(pic) << ' ' << imptot.sezione() << ",\n"; + msg << "i pagamenti e le spese ammontano a " + << impsal.valore().string(pic) << ' ' << impsal.sezione() << ",\n"; + msg << "per cui il residuo e' " << residuo.valore().string(pic) << '.'; + if (app().curr_mask().edit_mode() && impsal.is_zero()) + { + msg << "\nSi desidera registrare ugualmente?"; + ok = app().cgs().yesno_box(msg); + } + else + ok = app().cgs().error_box(msg); + } + + return ok; +} // Handler dello sheet di contabilita' // Certified 90% @@ -555,9 +580,20 @@ bool TPrimanota_application::cg_handler(TMask_field& f, KEY k) const TImporto speso = app().partite().importo_speso(numreg, currig); if (importo != speso) { - const char* ss = speso.valore().string("."); - return f.error_box("L'importo sulla riga %d deve essere %s %c", - currig, ss, speso.sezione()); + TString msg(128); + msg << "L'importo sulla riga " << currig << " deve essere " + << speso.valore().string(".") << ' ' << speso.sezione(); + + bool ok = FALSE; + if (m.edit_mode() && speso.is_zero()) + { + msg << "\nSi desidera registrare ugualmente?"; + ok = f.yesno_box(msg); + } + else + ok = f.error_box(msg); + if (!ok) + return FALSE; } } if (strchr("ACGKP", tipo) != NULL) @@ -575,37 +611,15 @@ bool TPrimanota_application::cg_handler(TMask_field& f, KEY k) const char s(app().causale().sezione(2)); const real t(f.mask().get(F_TOTALE)); const TImporto totdoc(s, t); - TImporto residuo(totdoc); residuo += saldaconto; residuo.normalize(); - if (!residuo.is_zero()) - { - const TString st(totdoc.valore().string(".")); - const TString ss(saldaconto.valore().string(".")); - const TString sr(residuo.valore().string(".")); - return f.error_box("Il totale documento inserito e' %s %c,\n" - "i pagamenti e le spese ammontano a %s %c,\n" - "per cui il residuo e' %s.", - (const char*)st, totdoc.sezione(), - (const char*)ss, saldaconto.sezione(), - (const char*)sr); - } + const bool ok = imptot_error(totdoc, saldaconto, FALSE); + if (!ok) return FALSE; if (in_valuta) { const real t(f.mask().get(SK_TOTDOCVAL)); - const TImporto totdoc(s, t); - TImporto residuo(totdoc); residuo += saldaconto_val; residuo.normalize(); - if (!residuo.is_zero()) - { - const TString st(totdoc.valore().string(".3")); - const TString ss(saldaconto_val.valore().string(".3")); - const TString sr(residuo.valore().string(".3")); - return f.error_box("Il totale documento in valuta e' %s %c,\n" - "i pagamenti e le spese ammontano a %s %c,\n" - "per cui il residuo e' %s.", - (const char*)st, totdoc.sezione(), - (const char*)ss, saldaconto.sezione(), - (const char*)sr); - } + const TImporto totdoc_val(s, t); + const bool ok = imptot_error(totdoc_val, saldaconto_val, TRUE); + if (!ok) return FALSE; } } @@ -617,17 +631,20 @@ bool TPrimanota_application::cg_handler(TMask_field& f, KEY k) TString msg(80); msg = "Non esiste una riga contabile riferita al "; msg << (contocf.tipo() == 'C' ? "cliente" : "fornitore") << ' '; msg << contocf.codclifo() << ":\n"; - if (m.edit_mode() && m.field(F_NUMRIF).enabled()) - { - msg << "Si desidera eliminare il saldaconto?"; - const bool kill = f.yesno_box(msg); - if (kill) - { - m.reset(F_ANNORIF); - m.reset(F_NUMRIF); - } - else - return FALSE; + if (m.edit_mode()) + { + if (m.page_enabled(2)) + { + msg << "Si desidera eliminare il saldaconto?"; + const bool kill = f.yesno_box(msg); + if (kill) + { + m.reset(F_ANNORIF); + m.reset(F_NUMRIF); + } + else + return FALSE; + } } else { @@ -1735,12 +1752,19 @@ bool TPrimanota_application::datadoc_handler(TMask_field& f, KEY key) { if (m.get(F_ANNORIF).empty() && m.insert_mode()) m.set(F_ANNORIF, dd.year()); // copia anno documento - if (app().is_fattura()) + + TPrimanota_application& a = app(); + if (a.is_fattura()) { if (m.insert_mode()) - app().recalc_scadenze(dd); + { + a.recalc_scadenze(dd); + } else - app().pagamento().set_datadoc(dd); + { + if (a._pag) + a._pag->set_datadoc(dd); + } } } } diff --git a/cg/cg2104.cpp b/cg/cg2104.cpp index 829f5dfde..19bc54034 100755 --- a/cg/cg2104.cpp +++ b/cg/cg2104.cpp @@ -445,26 +445,28 @@ bool TPrimanota_application::cambio_handler(TMask_field& f, KEY key) if (key == K_TAB) { TMask& m = f.mask(); + TPrimanota_application& a = app(); bool update = FALSE; // Devo ricopiarmi a pagina 3? if (f.focusdirty()) - { - app().gioca_cambi(0x1); // Forza il ricalcolo del totale in lire + { + // Forza il ricalcolo del totale in lire se necessario + a.gioca_cambi(m.insert_mode() ? 0x1 : 0x0); - if (app().is_fattura()) + if (a.is_fattura()) { - TPagamento& pag = app().pagamento(); + TPagamento& pag = a.pagamento(); const real ex(f.get()); pag.set_cambio(ex); // Aggiorna cambio sul pagamento update = TRUE; TSheet_field& ps = (TSheet_field&)m.field(FS_RATESHEET); pag.set_sheet(ps); - app().pag_rows() = ps.rows_array(); + a.pag_rows() = ps.rows_array(); } } else - update = app().is_fattura() && !m.is_running(); + update = a.is_fattura() && !m.is_running(); if (update) m.set(FS_CAMBIO, f.get()); // Copia a pagina 3 @@ -669,15 +671,16 @@ bool TPrimanota_application::read_scadenze(TMask& m) const TRectype& testa = _rel->curr(); const long nreg = testa.get_long(MOV_NUMREG); const TDate datadoc = testa.get_date(MOV_DATADOC); - TString codpag = testa.get(MOV_CODPAG); // Puo' variare! const int npart = part.prima_fattura(nreg); if (npart <= 0) // Non esiste una riga per questo movimento { partite().destroy(); - return FALSE; // Non dovrebbe succedere mai! + return FALSE; // Non dovrebbe succedere mai, in quanto gia' beccato sopra! } - + + // Determino il codice pagamento dalla riga di fattura + TString codpag; const TRiga_partite& partita = part.riga(npart); if (partita.rate() > 0) { diff --git a/cg/cg2105.cpp b/cg/cg2105.cpp index 954a96a73..e522d7f54 100755 --- a/cg/cg2105.cpp +++ b/cg/cg2105.cpp @@ -367,6 +367,7 @@ protected: int nuovo_pagamento(TPartita& partita, int nriga, int rata) const; bool edit_pagamento(TPartita& p, int nriga, int nrata, int nrigp) const; + char calcola_sezione() const; void align_number(TMask_field& f) const; long number_distance(const char* key, const char* num) const; bool same_number(const char* key, const char* num) const; @@ -414,7 +415,7 @@ TGame_mask::TGame_mask(const TBill& bill, long numreg, int riga) append_conto(descr); descr << ' ' << ((TBill&)_conto).descrizione(); set(P_DESCR, descr); - + TValuta val; #ifndef __EXTRA__ const TRiga_partite* row = cerca_prima_riga(); @@ -540,6 +541,10 @@ real TGame_mask::aggiorna_residuo() _importo = app().get_cgs_imp(_numrig-1); // Importo sulla riga contabile _residuo = _importo; _residuo -= app().partite().importo_speso(_numreg, _numrig); // Residuo della riga + + const char sez = calcola_sezione(); // Sezione di riferimento + _residuo.normalize(sez); + const real& res = _residuo.valore(); set(P_RESIDUO, res); @@ -550,6 +555,7 @@ real TGame_mask::aggiorna_residuo() { TImporto resval = _importo; cambio.lit2val(resval); resval -= app().partite().importo_speso(_numreg, _numrig, TRUE); // Residuo della riga + resval.normalize(sez); set(P_RESIDUOVAL, resval.valore()); } } @@ -870,6 +876,37 @@ bool TGame_mask::scadenze_notify(TSheet_field& scadenze, int r, KEY k) return TRUE; } + +// Complesso algoritmo per calcolare la sezione di una nuova riga partita +char TGame_mask::calcola_sezione() const +{ + char sezione = ' '; + +#ifndef __EXTRA + const TCausale& causale = app().causale(); + const tipo_movimento tm = (tipo_movimento)causale.tipomov(); + const char tipoc = conto().tipo(); + + sezione = causale.sezione(1); // Usa la sezione della causale + if (sezione <= ' ') // Se non c'e' la sezione bell'e' ch'e' pronta + { + if (tm == tm_fattura || tm == tm_insoluto) // calcola in base al tipo movimento e + sezione = (tipoc == 'C') ? 'D' : 'A'; // al tipo cliente/fornitore + else + sezione = (tipoc == 'C') ? 'A' : 'D'; + } + if (tipoc > ' ') // Se il tipo e' C o F + { + TBill bill; causale.bill(1, bill); // Legge primo conto causale + const char tc = bill.tipo(); + if (tc > ' ' && tc != tipoc) + sezione = (sezione == 'D') ? 'A' : 'D'; // scambia segno + } +#endif + + return sezione; +} + int TGame_mask::nuova_riga(TPartita& partita) const { TRiga_partite& part = partita.new_row(); // Creazione nuova riga vuota @@ -934,22 +971,8 @@ int TGame_mask::nuova_riga(TPartita& partita) const part.put(PART_PROTIVA, cm.get(F_PROTIVA)); } - const char tipoc = conto().tipo(); - // 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 - { - if (tm == tm_fattura || tm == tm_insoluto) // calcola in base al tipo movimento e - sezione = (tipoc == 'C') ? 'D' : 'A'; // al tipo cliente/fornitore - else - sezione = (tipoc == 'C') ? 'A' : 'D'; - } - if (tipoc > ' ') // Se il tipo e' C o F - { - TBill bill; causale.bill(1, bill); // Legge primo conto causale - if (bill.tipo() != tipoc) - sezione = (sezione == 'D') ? 'A' : 'D'; // scambia segno - } + const char sezione = calcola_sezione(); + // Memorizza solo la sezione (importi nulli) part.put(PART_SEZ, sezione); part.put(PART_SEZABB, sezione); @@ -1089,20 +1112,34 @@ bool TGame_mask::edit_scadenza_handler(TMask_field& f, KEY k) } #endif } + if (cambiato) { + TToken_string& cur_game = gm.partite().row(gm._riga_partite); + const int cur_year = cur_game.get_int(0); + const char* cur_num = cur_game.get(); + const bool on_sheet = game.anno() == cur_year && game.numero() == cur_num; + if (game.ok()) - { - gm.update_partita(game, gm._riga_partite); - const int r = gm._riga_partite; - gm._riga_partite = -1; // Forza aggiornamento sheet - partite_notify(gm.partite(), r, K_TAB); + { + if (on_sheet) + { + gm.update_partita(game, gm._riga_partite); + const int r = gm._riga_partite; + gm._riga_partite = -1; // Forza aggiornamento sheet + partite_notify(gm.partite(), r, K_TAB); + } } else - { - app().partite().destroy(game); - gm.fill_partite(); + { + // Se la partita e' presente anche su file non posso cancellarla: + // altrimenti non verra' rimossa alla registrazione! + if (!game.is_on_file()) + app().partite().destroy(game); + if (on_sheet) + gm.fill_partite(); } + gm._changed = TRUE; } } @@ -1188,8 +1225,13 @@ bool TGame_mask::nuovo_handler(TMask_field& f, KEY k) gm._changed = TRUE; } else - app().partite().destroy(game); - gm.fill_partite(); // Aggiorna sheet partite + { + if (!game.is_on_file()) + app().partite().destroy(game); + } + + // Aggiorna sheet partite: aggiunge la nuova partita e lo riordina + gm.fill_partite(); } } @@ -1365,13 +1407,18 @@ void TGame_mask::fill_partite() app().begin_wait(); - for (TPartita* gioco = app().partite().first(); gioco != NULL; gioco = app().partite().next()) - { - const TBill& zio = gioco->conto(); - if (zio.tipo() <= ' ' || zio.sottoconto() == conto().sottoconto()) - update_partita(*gioco, -1); - } - + for (TPartita* gioco = app().partite().first(); + gioco != NULL; + gioco = app().partite().next()) + { + if (gioco->ok()) + { + const TBill& zio = gioco->conto(); + if (zio.tipo() <= ' ' || zio.sottoconto() == conto().sottoconto()) + update_partita(*gioco, -1); + } + } + TLocalisamfile partita(LF_PARTITE); partita.zero(); if (conto().tipo() > ' ') // Ignora gruppo e conto dei clifo diff --git a/cg/saldacon.cpp b/cg/saldacon.cpp index 389faf5ae..9c7411623 100755 --- a/cg/saldacon.cpp +++ b/cg/saldacon.cpp @@ -138,13 +138,12 @@ void TValuta::adjust() { _cod.cut(0); _cam = 1.0; - } - - if (_cam <= ZERO) - { - _cod = ""; - _cam = 1.0; - } + } + else + { + if (_cam <= ZERO) + _cam = 1.0; + } } int TValuta::compare(const TSortable& s) const @@ -908,6 +907,28 @@ void TPartita::allinea(char all) } +bool TPartita::is_on_file() const +{ + TLocalisamfile partite(LF_PARTITE); + TRectype& part = partite.curr(); + part.zero(); + part.put(PART_TIPOCF, _conto.tipo()); + if (_conto.tipo() <= ' ') + { + part.put(PART_GRUPPO, _conto.gruppo()); + part.put(PART_CONTO, _conto.conto()); + } + part.put(PART_SOTTOCONTO, _conto.sottoconto()); + part.put(PART_ANNO, _anno); + part.put(PART_NUMPART, _num); + + const TRectype filter(part); + + // Cerca la partita usando l'allineamento richiesto dall'utente + const bool found = partite.read(_isgteq) == NOERR && part.compare_key(filter, 1, 1) == 0; + return found; +} + // Costruisce le righe della partita bool TPartita::read(const TBill& clifo, int year, const char* num) { @@ -917,17 +938,8 @@ bool TPartita::read(const TBill& clifo, int year, const char* num) if (_conto.tipo() > ' ' && allineamento_corrente() > ' ') { - // Prepara la chiave per verificare l'esistenza della partita specificata - TLocalisamfile part(LF_PARTITE); - part.zero(); - part.put(PART_TIPOCF, _conto.tipo()); - part.put(PART_SOTTOCONTO, _conto.codclifo()); - part.put(PART_ANNO, _anno); - part.put(PART_NUMPART, _num); - TRectype filter(part.curr()); - // Cerca la partita usando l'allineamento richiesto dall'utente - if (part.read(_isgteq) == NOERR && part.curr() == filter) + if (is_on_file()) { // Trovata! } @@ -940,8 +952,7 @@ bool TPartita::read(const TBill& clifo, int year, const char* num) _num.right_just(NUMLEN); // Riprova a cercarla col nuovo allineamento - filter.put(PART_NUMPART, _num); - if (part.read(_isgteq) == NOERR && part.curr() == filter) + if (is_on_file()) { // Esiste: memorizzo l'allineamento } diff --git a/cg/saldacon.h b/cg/saldacon.h index feefdae95..328376f60 100755 --- a/cg/saldacon.h +++ b/cg/saldacon.h @@ -1,3 +1,4 @@ + #ifndef __SALDACON_H #define __SALDACON_H @@ -265,6 +266,8 @@ public: bool write(bool re = FALSE) const; bool rewrite() const { return write(TRUE); } bool remove() const; + + bool is_on_file() const; int mov2rig(long nreg, int rmov) const; int rig2mov(int rmov) const;