#include #include #include #include #include #include "cg2100.h" #include "cg2102.h" #include "cg21sld.h" #include /////////////////////////////////////////////////////////// // Funzioni di decodifica/calcolo /////////////////////////////////////////////////////////// char TPrimanota_application::row_type(const TToken_string& s) { const int l = s.len()-1; return l > 0 ? s[l] : ' '; } // Determina il tipo IVA da causale+anno // Certified 100% TipoIVA TPrimanota_application::cau2IVA(const char* cod, int annoiva) { if (!read_caus(cod, annoiva)) error_box("Causale errata: '%s'", cod); return causale().iva(); } // Calcolo della percentuale di un dato codice IVA // Certified 99% const real& TPrimanota_application::cod2IVA(const TMask& m) { static TString16 _codiva; // Ultimo codice iva decodificato static real _percent; // Percentuale dell'ultimo codice iva // Tipo Costo Ricavo if (app().iva() == iva_acquisti && m.get_int(103) == 3) return ZERO; const TString& codiva = m.get(102); if (_codiva != codiva) { _codiva = codiva; TCodiceIVA c(_codiva); _percent = c.percentuale(); } return _percent; } // Scorpora dall'imponibile la percentuale d'imposta(0.0%-100.0%) e ritorna l'imposta stessa // Certified 99% Non sono sicurissimo degli imponibili negativi real TPrimanota_application::scorpora(real& imponibile, const real& percent) { real imposta = abs(imponibile) * percent / (percent + 100.0); imposta.ceil(); if (imponibile.sign() < 0) imposta = -imposta; imponibile -= imposta; return imposta; } // Calcola il totale del documento tenendo conto del segno della prima riga e di quella delle // ritenute sociali sulla causale real TPrimanota_application::totale_documento() { const TMask& m = curr_mask(); const bool swapt = test_swap(FALSE); // Totale invertito ? const bool swaps = test_swap(TRUE); // Ritenute sociali invertite ? real tot(m.get(F_TOTALE)); // Legge totale const real ritfis(m.get(F_RITFIS)); tot += ritfis; // Somma ritenute fiscali real ritsoc(m.get(F_RITSOC)); if (swapt ^ swaps) ritsoc = -ritsoc; tot += ritsoc; // Somma ritenute sociali con segno return tot; } // Determina se un codice sospeso o no // Certified 99% bool TPrimanota_application::suspended_handler(TMask_field& f, KEY k) { if (f.to_check(k)) { 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()); const TLocalisamfile& i = b->cursor()->file(); // Tabella File const char* sf = i.tab() ? "B2" : "SOSPESO"; const bool suspended = i.get_bool(sf); if (suspended) { sf = f.get(); return f.error_box("Il codice '%s' e' sospeso e non puo' essere utilizzato", sf); } } return TRUE; } // Determina se un codice detrazione e' di tipo detraibile o no // Certified 70% bool TPrimanota_application::detraibile(TToken_string& row) { if (app().iva() == iva_vendite) // Vendite sempre detraibili return TRUE; const int tipo_det = row.get_int(2); // Leggi tipo detraibilita if (tipo_det != 0) return FALSE; const real& prorata = app().causale().reg().prorata(); return prorata < 100.0; // Se prorata = 100% e' indetraibile } /////////////////////////////////////////////////////////// // Funzioni di ricerca /////////////////////////////////////////////////////////// int TPrimanota_application::type2pos(char tipo) { TString_array& cg = app().cgs().rows_array(); for (int i = 0; i < cg.items(); i++) { const TToken_string& s = cg.row(i); const char t = row_type(s); if (t == tipo) return i; } return -1; } // Trova nelle righe contabili un conto nelle righe di tipo prescelto int TPrimanota_application::bill2pos(const TBill& conto, char tipo) { TString_array& cg = app().cgs().rows_array(); const int num_rows = cg.items(); for (int i = 0; i < num_rows; i++) { TToken_string& s = cg.row(i); const char t = row_type(s); if (t == tipo) { const TBill c(s, 3, 0x0); if (c == conto) return i; } } return -1; } // Trova nelle righe contabili un conto di contropartita per il conto dato int TPrimanota_application::bill2contr(const TBill& conto, char sezione) const { TString_array& rows = cgs().rows_array(); const int num_rows = rows.items(); TBill c; // Conto corrente (Buona questa!) for (int i = 0; i < num_rows; i++) { TToken_string& r = rows.row(i); const real dare(r.get(0)); const char sez = dare.is_zero() ? 'A' : 'D'; if (sez == sezione) // Devo cercare sezione contraria continue; c.get(r, 3, 0x0); if (conto == c) return i; } return -1; } // Controlla se un conto e' usato nelle righe IVA int TPrimanota_application::bill_used(const TBill& conto) const { TString_array& rows = ivas().rows_array(); TBill c; // Conto corrente int users = 0; for (int i = rows.items(); i >= 0 ; i--) { TToken_string& row = rows.row(i); if (!row.empty_items()) { c.get(row, 6, 0x0); if (conto == c) users++; } } return users; } /////////////////////////////////////////////////////////// // Gestione sheet CG /////////////////////////////////////////////////////////// TSheet_field& TPrimanota_application::cgs() const { const TMask* m = _msk[_iva == nessuna_iva ? 1 : 2]; CHECK(m, "Null cgs() mask"); TSheet_field& s = (TSheet_field&)m->field(F_SHEETCG); return s; } // Certified 100% // Scrive l'importo imp nella opportuna colonna della riga n void TPrimanota_application::set_cgs_imp(int n, const TImporto& imp) { TSheet_field& s = cgs(); imp.add_to(s.row(n), 0); s.force_update(n); } // Legge l'importo della riga n e lo ritorna col segno dovuto // Certified 100% TImporto TPrimanota_application::get_cgs_imp(int n) { TSheet_field& s = cgs(); TImporto importo; const TMask& m = s.sheet_mask(); if (m.is_running() && s.selected() == n) { const TString& imp = m.get(CG_DARE); if (imp.not_empty()) importo.set('D', real(imp)); else importo.set('A', real(m.get(CG_AVERE))); } else importo = s.row(n); return importo; } // Certified 90% bool TPrimanota_application::add_cgs_imp(int n, const TImporto& imp) { TImporto tot(get_cgs_imp(n)); tot += imp; tot.normalize(); set_cgs_imp(n, tot); return tot.is_zero(); } // Certified 90% bool TPrimanota_application::sub_cgs_imp(int n, const TImporto& imp) { TImporto tot(get_cgs_imp(n)); tot -= imp; tot.normalize(); set_cgs_imp(n, tot); return tot.is_zero(); } TImporto TPrimanota_application::real2imp(const real& r, char row_type) { bool dare; if (row_type == 'S') { dare = causale().sezione_ritsoc() == 'D'; } else { dare = causale().sezione_clifo() == 'D'; if (row_type != 'T' && row_type != 'F') dare = !dare; } TImporto importo(dare ? 'D' : 'A', r); return importo; } // Disabilita le celle della riga contabile n in base al suo tipo void TPrimanota_application::disable_cgs_cells(int n, char tipo) { TSheet_field& cg = cgs(); int first = 0, last = 0; // Range di righe da disabilitare switch(tipo) { case 'T': // Totale documento if (causale().corrispettivi()) { last = 2; } else { last = 3; cg.disable_cell(n, 5); cg.disable_cell(n, 6); } break; case 'A': // Abbuoni attivi case 'C': // Differenza cambio case 'D': // IVA Detraibile case 'F': // Ritenute Fiscali case 'L': // Contropartita delle spese case 'N': // IVA Non detraibile case 'P': // Abbuoni passivi case 'R': // Ritenute professionali case 'S': // Ritenute Sociali last = 3; break; case 'K': // Riga cliente/fornitore per saldaconto if (curr_mask().is_running() && n == cg.items()-1) // Sono in inserimento di una riga nuova break; first = 2; case 'I': last = 7; // Imponibile break; default: last = 0; // Solo contabile break; } bool needs_update = FALSE; if (last) { for (int i = first; i < last; i++) cg.disable_cell(n, i); needs_update = TRUE; } COLOR back_color, fore_color; type2colors(tipo, back_color, fore_color); if (back_color != NORMAL_BACK_COLOR || fore_color != NORMAL_COLOR) { cg.set_back_and_fore_color(back_color, fore_color, n); needs_update = TRUE; } if (needs_update) cg.force_update(n); } void TPrimanota_application::reset_sheet_row(TSheet_field& s, int n) { s.row(s.items()); // Append a new line s.destroy(n); // Remove line n } int TPrimanota_application::set_cgs_row(int n, const TImporto& imp, TBill& conto, const char* desc, char tipo) { TSheet_field& cg = cgs(); if (n < 0) n = cg.first_empty(); TToken_string& row = cg.row(n); row = ""; imp.add_to(row, 0); row.add(conto.string(0x3)); row.add(""); // Codice decrizione row.add(desc); // Descrizione aggiuntiva if (tipo == 'T') // Calcolo contropartita { TToken_string& irow = ivas().row(0); TBill contro(irow, 5, 0x3); if (contro.ok()) // Errore MI3599 row.add(contro.string(0x3)); else row.add(" | | | | "); } else { const int pos = type2pos('T'); if (pos >= 0) { TBill contro(cg.row(pos), 2, 0x3); if (contro.ok()) row.add(contro.string(0x3)); } else row.add(" | | | | "); } row << "| |" << tipo; disable_cgs_cells(n, tipo); return n; } HIDDEN int compare_rows(const TObject** o1, const TObject** o2) { // Totale, Rit.Fisc., Rit.Soc., da riga IVA, riga contabile, IVA detr., IVA non detr. const char* const sort_order = "TFSI DNAPRC"; const TToken_string* r1 = (const TToken_string*)*o1; const TToken_string* r2 = (const TToken_string*)*o2; const char c1 = app().row_type(*r1); const char c2 = app().row_type(*r2); return int(strchr(sort_order, c1) - strchr(sort_order, c2)); } HIDDEN bool can_remove(TToken_string& s) { const char* dare = s.get(0); bool yes = dare == NULL ; if (!yes) { if (*dare == '\0' || *dare == ' ' || strcmp(dare,"0") == 0) { const char* avere = s.get(); yes = (avere == NULL || *avere == '\0' || *avere == ' ' || strcmp(avere,"0") == 0); } } return yes; } 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') { 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 rows.TArray::sort(compare_rows); // Pack and sort array } bool TPrimanota_application::ci_sono_importi() const { TString_array& rows = cgs().rows_array(); for (int i = 0; i < rows.items(); i++) { TToken_string& r = rows.row(i); const real dare(r.get(0)); if (dare != ZERO) return TRUE; const real avere(r.get()); if (avere != ZERO) return TRUE; } return FALSE; } real TPrimanota_application::calcola_saldo() const { real tdare, tavere; TImporto saldaconto; const bool pag = is_pagamento() && !_as400; TString_array& rows = cgs().rows_array(); const int max = rows.items(); for (int i = 0; i < max; i++) { TToken_string& r = rows.row(i); const real dare(r.get(0)); const real avere(r.get()); tdare += dare; tavere += avere; if (pag) { const char tipo = row_type(r); if (strchr("ACGKP", tipo) != NULL) // Abbuoni attivi, differenze cambio, { // spese, clienti/fornitori, abbuoni passivi const char sez = dare.is_zero() ? 'A' : 'D'; const TImporto importo(sez, sez == 'A' ? avere : dare); saldaconto += importo; } } } TMask& m = curr_mask(); const real sbilancio = abs(tdare)-abs(tavere); const real absbilancio = abs(tdare - tavere); switch (sbilancio.sign()) { case +1: // Il dare supera l'avere in valore assoluto m.set(F_DARE, absbilancio); m.reset(F_AVERE); break; case -1: // L'avere supera il dare in valore assoluto m.reset(F_DARE); m.set(F_AVERE, absbilancio); break; default: // Sbilancio nullo m.reset(F_DARE); m.reset(F_AVERE); break; } if (pag) { const char s(causale().sezione(2)); // Conto della cassa const real t(m.get(F_TOTALE)); TImporto totdoc(s, t); totdoc += saldaconto; totdoc.normalize(s); m.set(K_RESIDUO, totdoc.valore().string()); } return sbilancio; } HIDDEN bool imptot_error(const TImporto& imptot, const TImporto& impsal, bool val) { bool ok = TRUE; TImporto cassa(impsal); cassa.swap_section(); TImporto residuo(imptot); residuo -= cassa; residuo.normalize(imptot.sezione()); if (!residuo.is_zero()) { const char* const pic = val ? ".3" : "."; TPrimanota_application& a = app(); const TMask& m = a.curr_mask(); TString msg(255); msg << "Il totale documento "; if (val) msg << "in valuta " << m.get(SK_VALUTA); else msg << "inserito"; msg << " e' " << imptot.valore().string(pic) << ' ' << imptot.sezione() << ",\n"; msg << "i pagamenti e le spese ammontano a " << cassa.valore().string(pic) << ' ' << cassa.sezione() << ",\n"; msg << "per cui il residuo e' " << residuo.valore().string(pic) << '.'; if (m.edit_mode() && impsal.is_zero()) { msg << "\nSi desidera registrare ugualmente?"; ok = a.cgs().yesno_box(msg); } else ok = a.cgs().error_box(msg); } return ok; } // Handler dello sheet di contabilita' // Certified 90% bool TPrimanota_application::cg_handler(TMask_field& f, KEY k) { if (k == K_ENTER) { TPrimanota_application& a = app(); const real saldo = a.calcola_saldo(); if (saldo != ZERO) { const char* ss = saldo.string("."); if (*ss == '-') ss++; return f.error_box("Il movimento e' sbilanciato di %s lire.", ss); } TMask& m = f.mask(); const bool paga = a.is_pagamento(); const bool nota = a.is_nota_credito() && m.field(F_NUMRIF).active(); const bool fatt = a.is_fattura() && m.page_enabled(2); const long numreg = m.get_long(F_NUMREG); const bool in_valuta = m.get(SK_VALUTA).not_empty(); TImporto saldaconto, saldaconto_val; TSheet_field& cg = a.cgs(); bool empty = TRUE; for (int i = 0; i < cg.items(); i++) { TToken_string& r = cg.row(i); TImporto importo; importo = r; if (!importo.is_zero()) { const TBill c(r, 3, 0x0); if (!c.ok()) return f.error_box("Il conto della riga %d non e' completo", i+1); const TBill co(r, 10, 0x0); if (!co.empty() && !co.ok()) { const bool ok = f.yesno_box("La contropartita della riga %d non e' completa:\n" "Si desidera continuare ugualmente?", i+1); if (!ok) return FALSE; } empty = FALSE; if (paga || nota) { const char tipo = row_type(r); if (tipo == 'K' || tipo == 'T' || a._as400) { const int currig = i+1; const TImporto speso = a.partite().importo_speso(numreg, currig); bool errato = importo != speso; if (errato && a._as400 && speso.is_zero()) errato = FALSE; if (errato) { TString msg(128); msg << "L'importo sul saldaconto della riga " << currig << " e' " << speso.valore().string("."); if (!speso.is_zero()) msg << (speso.sezione() == 'A' ? " Avere" : " Dare"); 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("ACGKPT", tipo) != NULL) { saldaconto += importo; if (in_valuta) saldaconto_val += a.partite().importo_speso(numreg, i+1, TRUE, 0x1); } } } } if (empty) return f.error_box("Il movimento non ha nessuna riga contabile con un importo"); if ((paga || nota) && !a._as400) { const char sez(a.causale().sezione(2)); const TImporto totdoc(sez, m.get_real(F_TOTALE)); bool ok = imptot_error(totdoc, saldaconto, FALSE); if (ok && in_valuta && !saldaconto.is_zero()) { const TImporto totdoc_val(sez, m.get_real(SK_TOTDOCVAL)); ok = imptot_error(totdoc_val, saldaconto_val, TRUE); } if (!ok) return FALSE; } if (fatt || nota) { TBill contocf; if (a.cerca_conto_cf(contocf) < 0) { 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()) { msg << "Si desidera eliminare il saldaconto?"; const bool kill = f.yesno_box(msg); if (kill) { if (fatt) // Se e' una fattura elimina il numero partita { m.reset(F_ANNORIF); m.reset(F_NUMRIF); } else { // Se e' una nota credito elimina il saldaconto a.notify_cgline_deletion(-1); } } else return FALSE; } else { msg << "Impossibile registrare il saldaconto!"; return f.error_box(msg); } } } } return TRUE; } void TPrimanota_application::generazione_righe_cg(int r) { TSheet_field& cg = cgs(); TToken_string& row = cg.row(r); if (can_remove(row)) // Ignora righe senza importo return; begin_wait(); TImporto importo; importo = row; const bool causale_ok = causale().codice()[0] > ' '; if (r == 0 && cg.row(1).empty_items()) { TBill contro(row, 9, 0x3); // Contropartita della prima riga if (causale_ok && !contro.ok()) { causale().bill(2, contro); // Prendi contropartita dalla causale if (contro.ok()) { contro.add_to(row, 9, 0x3); cg.force_update(r); } } if (contro.ok()) { importo.swap_section(); set_cgs_row(1, importo, contro, "", ' '); TBill conto(row, 2, 0x3); conto.add_to(cg.row(1), 9, 0x3); cg.force_update(1); } } if (causale_ok) { int first_not_empty = 0; for (int i = 0; i < r; i++) { TToken_string& row = cg.row(i); if (!can_remove(row)) { first_not_empty = i; break; } } TBill conto(row, 2, 0x3); if (first_not_empty == r) // Sono la prima riga con importo ? { int last = -1; for (i = r+1; i < cg.items(); i++) // Aggiorna tutte le altre contropartite { TToken_string& rowi = cg.row(i); int gruppo = rowi.get_int(3); if (gruppo != 0) // Considera righe con conto ... { gruppo = rowi.get_int(10); if (gruppo == 0) // ... e senza contropartita { char sez = ' '; // Calcola sezione D/A della riga i if (cg.cell_disabled(i,0)) sez = 'A'; else if (cg.cell_disabled(i,1)) sez = 'D'; if (sez != ' ' && importo.sezione() != sez) // Considera solo le sezioni opposte { conto.add_to(rowi, 9, 0x3); cg.force_update(i); if (last < 0) last = i; else last = 0; } } } } if (last > r) { importo.swap_section(); set_cgs_imp(last, importo); const int gruppo = row.get_int(10); if (gruppo == 0) // Se non ho contropartita ... { TBill contro(cg.row(last), 2, 0x3); // ... copiala dalla riga corrispondente contro.add_to(row, 9, 0x3); cg.force_update(r); } } } else { TToken_string& first = cg.row(first_not_empty); int gruppo = first.get_int(10); if (gruppo == 0) // Se la prima riga non ha contropartita ... { conto.add_to(first, 9, 0x3); // ... copiaci la mia partita cg.force_update(first_not_empty); } gruppo = row.get_int(10); if (gruppo == 0) // Se non ho contropartita ... { TBill contro(first, 2, 0x3); // ... copiala dalla prima riga contro.add_to(row, 9, 0x3); cg.force_update(r); } } } end_wait(); } int TPrimanota_application::crea_somma_spese(TImporto& imp) { TConto cassa; causale().bill(2, cassa); const TString80 desc(causale().desc_agg(2)); imp.swap_section(); imp.normalize(); const int r = set_cgs_row(-1, imp, cassa, desc, 'L'); cgs().force_update(); return r; } bool TPrimanota_application::cg_notify(TSheet_field& cg, int r, KEY k) { static TImporto old_spesa; static bool delete_l = FALSE; CHECKD(r >= 0, "Chi e' quel ca$$one che notifica la riga ", r); TPrimanota_application& a = app(); if (k == K_CTRL + K_DEL) { if (delete_l) { const int l = type2pos('L'); CHECK(l >= 0, "Impossibile cancellare riga di tipo L"); cg.destroy(l); delete_l = FALSE; } a.calcola_saldo(); // Ricalcola saldo dopo cancellazione return TRUE; // Ritorna subito, altrimenti crea riga vuota } if (k == K_INS) // La riga non esiste ancora return TRUE; TToken_string& row = cg.row(r); const char tipo = row_type(row); // Tipo della riga in esame switch(k) { case K_SPACE: if (tipo == 'G') old_spesa = row; break; case K_TAB: cg.sheet_mask().enable(DLG_DELREC, tipo <= ' ' || tipo == 'K' || tipo == 'G'); break; case K_DEL: if (tipo == 'G') { row.add("", 0); row.add("", 1); } else { if (tipo == 'K') { a.notify_cgline_deletion(r+1); } break; } case K_ENTER: if (tipo == 'G') { TImporto growth; growth = row; growth -= old_spesa; if (!growth.is_zero()) { const int s = type2pos('L'); if (s < 0) a.crea_somma_spese(growth); else delete_l = a.sub_cgs_imp(s, growth); } } else { if (a.iva() == nessuna_iva && !a.is_saldaconto()) a.generazione_righe_cg(r); } if (k == K_ENTER) a.calcola_saldo(); // Altrimenti ci pensa CTRL-DEL break; case K_CTRL+K_INS: // Post inserimento if (a.is_pagamento()) { const char tipo = cg.mask().get(SK_TIPORIGA)[0]; if (tipo == 'K' || tipo == 'G') { const int k = tipo == 'K' ? 1 : RIGA_SPESE; TBill conto; a.causale().bill(k, conto); const TString80 desc(a.causale().desc_agg(k)); const char sez = a.causale().sezione(k); const real imp(cg.mask().get(K_RESIDUO)); TImporto importo(sez, imp); a.set_cgs_row(r, importo, conto, desc, tipo); if (tipo == 'K') { for (int i = 0; i < r; i++) { const TToken_string& row = cg.row(i); if (row_type(row) != 'K') { cg.swap_rows(r, i); cg.force_update(); cg.select(i, FALSE); break; } } } else { if (!importo.is_zero()) { const int s = type2pos('L'); if (s < 0) a.crea_somma_spese(importo); else a.sub_cgs_imp(s, importo); } } a.calcola_saldo(); } } break; default: break; } return TRUE; } bool TPrimanota_application::descr_handler(TMask_field& f, KEY k) { if (k == K_TAB && f.focusdirty()) { if (app().iva() != nessuna_iva) { const int first = type2pos('T'); if (first >= 0) { TSheet_field& cg = app().cgs(); const TString80 old = cg.row(first).get(8); if (old.blank()) { cg.row(first).add(f.get(), 8); cg.force_update(first); } } } } if (k == K_ENTER && f.get().empty()) { if (f.mask().get(F_CODCAUS).empty()) return f.error_box("La descrizione del documento e' necessaria in mancanza della causale"); } return TRUE; } // Handler per le colonne 'Dare' e 'Avere' dello sheet contabile. // Scrivendo qualcosa in dare (101) cancella l'importo in avere (102) e viceversa bool TPrimanota_application::dareavere_handler(TMask_field& f, KEY k) { TPrimanota_application& a = app(); TSheet_field& cgs = a.cgs(); const int currig = cgs.selected(); if (k == K_F8 && a.is_pagamento()) { const long numreg = a.curr_mask().get_long(F_NUMREG); const TImporto speso = a.partite().importo_speso(numreg, currig+1); const char* ss = speso.valore().string(); TMask& m = f.mask(); m.set(CG_DARE, speso.sezione() == 'D' ? ss : ""); m.set(CG_AVERE, speso.sezione() == 'A' ? ss : ""); if (!m.is_running()) { speso.add_to(cgs.row(currig), 0); // Aggiorna riga sheet a.calcola_saldo(); // Aggiorna saldo e residuo } } if (k == K_TAB && f.focusdirty()) { const TString& val = f.get(); TToken_string& row = cgs.row(currig); row.add(val, f.dlg() - CG_DARE); // Aggiorno stringa sheet if (val.not_empty()) { // Calcola id del campo da resettare const int id = f.dlg() == CG_DARE ? CG_AVERE : CG_DARE; f.mask().reset(id); // Aggiorna maschera e ... row.add("", id - CG_DARE); // ... riga dello sheet } if (!f.mask().is_running()) a.calcola_saldo(); // Aggiorna saldo e residuo } return TRUE; } TSheet_field& TPrimanota_application::pags() const { CHECK(is_fattura(), "Can't use rate sheet without a fattura"); const int pos = _msk[2]->id2pos(FS_RATESHEET); CHECK(pos > 0, "Can't find rate sheet"); TSheet_field& s = (TSheet_field&)_msk[2]->fld(pos); return s; } /////////////////////////////////////////////////////////// // Gestione sheet IVA /////////////////////////////////////////////////////////// // Ritorna lo sheet delle righe IVA // Certified 100% TSheet_field& TPrimanota_application::ivas() const { TSheet_field& s = (TSheet_field&)_msk[2]->field(F_SHEETIVA); return s; } /* TBill& TPrimanota_application::ivas_bill(TBill& c) { if (iva() == iva_vendite) { const int spric = c.tipo_cr(); if (spric == 2 || spric == 3) { const TString& td = causale().tipo_doc(); if (td == "FV" || td == "NC" || td == "ND") c.tipo_cr(4); } } return c; } */ // Gestione del campo imponibile sullo sheet iva // Certified 90% bool TPrimanota_application::imponibile_handler(TMask_field& f, KEY key) { if (key == K_TAB && f.dirty()) { TMask& m = f.mask(); TString16 iva(m.get(102)); if (iva.empty()) { iva = app().curr_mask().get(F_CODIVA); m.set(102, iva); } if (iva.not_empty() && !app().causale().corrispettivi()) { const real& percent = cod2IVA(m); const real imponibile(f.get()); real imposta = abs(imponibile) * percent / 100.0; imposta.ceil(); if (imponibile.sign() < 0) imposta = -imposta; m.set(104, imposta); } } return TRUE; } // Gestione del codice IVA sullo sheet iva // Certified 90% bool TPrimanota_application::codiva_handler(TMask_field& f, KEY key) { if (!suspended_handler(f, key)) return FALSE; if (key == K_TAB && f.dirty()) { TMask& m = f.mask(); if (m.get_int(107) == 0) { TCodiceIVA iva(f.get()); TBill b; app().IVA2bill(iva, b); char cr[2] = { b.tipo_cr() + '0', '\0' }; m.set(105, *cr > '0' ? cr : ""); const char tipo[2] = { b.tipo(), '\0' }; m.set(106, tipo); m.set(107, b.gruppo()); m.set(108, b.conto()); const short id = b.tipo() == 'C' ? 209 : (b.tipo() == 'F' ? 309 : 109); m.set(id, b.sottoconto()); m.set(id+1, b.descrizione()); } TMask_field& im = m.field(101); im.set_dirty(); im.on_hit(); } else if (key == K_ENTER) { if (f.get().empty() && f.mask().get(101).not_empty()) return f.error_box("Codice IVA obbligatorio"); } return TRUE; } // Gestione del codice detrazione sullo sheet iva // Certified 90% bool TPrimanota_application::detrazione_handler(TMask_field& f, KEY key) { if (key == K_TAB && f.dirty() && app().iva() == iva_acquisti) { TMask_field& ci = f.mask().field(101); ci.set_dirty(); ci.on_hit(); } return TRUE; } // Gestione del campo imposta sullo sheet iva // Certified 90% bool TPrimanota_application::imposta_handler(TMask_field& f, KEY key) { if ((key == K_ENTER || key == K_TAB) && f.dirty()) { const real imponibile(f.mask().get(101)); const real percent = app().causale().corrispettivi() ? ZERO : cod2IVA(f.mask()); real imposta = abs(imponibile) * percent / 100.0; imposta.ceil(); if (imponibile.sign() < 0) imposta = -imposta; const real val(f.get()); if (val != imposta) { f.warning_box("L'imposta dovrebbe essere %s", (const char*)imposta.string(".")); } } else if (key == K_F8) { real imposta(f.get()); if (imposta.is_zero()) { real imponibile(f.mask().get(101)); const real& percent = cod2IVA(f.mask()); imposta = scorpora(imponibile, percent); f.mask().set(101, imponibile.string()); f.set(imposta.string()); } else f.warning_box("Cancellare l'imposta (tasto F2) prima di effettuare lo scorporo"); } return TRUE; } // Calcola il totale degli imponibili e delle imposte e aggiorna // i corrispondenti campi della maschera // Certified 99% real TPrimanota_application::calcola_imp() const { TArray& rows = ivas().rows_array(); real imponibili, imposte; for (int r = rows.items()-1; r >= 0; r--) { TToken_string& row = (TToken_string&)rows[r]; imponibili += real(row.get(0)); imposte += real(row.get(3)); } TMask& m = curr_mask(); m.set(F_IMPONIBILI, imponibili); m.set(F_IMPOSTE, imposte); // Se e' attiva la terza pagina allora riporta i totali in testata if (is_fattura()) { real tot(m.get(F_TOTALE)); tot -= imposte; m.set(FS_IMPONIBILI, tot); m.set(FS_IMPOSTE, imposte); } return imponibili+imposte; } // Elimina dallo sheet le righr iva senza importi (imponibile e imposta) // Certified 99% void TPrimanota_application::ivas_pack() { TString_array& rows = ivas().rows_array(); const int max = rows.items(); for (int i = 0; i < max; i++) { TToken_string& r = rows.row(i); const real imponibile(r.get(0)); if (imponibile != ZERO) continue; const real imposta(r.get(3)); if (imposta != ZERO) continue; rows.destroy(i, FALSE); } rows.pack(); // Pack array } // Certified 50% bool TPrimanota_application::iva_notify(TSheet_field& iva, int r, KEY k) { static int oldpos,oldposiva; static TImporto oldimp, oldiva; TPrimanota_application& a = app(); if (a._as400) return TRUE; if (k == K_INS || k == K_CTRL+K_DEL) return TRUE; TToken_string& row = iva.row(r); const TCausale& cau = a.causale(); if (k == K_SPACE) { oldimp = a.real2imp(real(row.get(0)), 'I'); // Imponibile oldiva = a.real2imp(real(row.get(3)), 'I'); // Imposta if (oldiva.is_zero() && cau.corrispettivi()) // In caso di corrispettivi ... { const TString zanicchi(row.get(1)); // Codice IVA const TCodiceIVA i(zanicchi); oldiva.valore() = i.scorpora(oldimp.valore()); // ... scorpora imposta dall'imponibile } const char tipod = detraibile(row) ? 'D' : 'N'; oldposiva = type2pos(tipod); if (oldposiva < 0 && !oldiva.is_zero()) { const int ri = tipod == 'D' ? RIGA_IVA_DETRAIBILE : RIGA_IVA_NON_DETRAIBILE; TBill c; cau.bill(ri, c); if (c.ok()) { const TString80 d(cau.desc_agg(ri)); oldposiva = a.set_cgs_row(-1, a.real2imp(ZERO, 'I'), c, d, tipod); } else if (ri == 4) // Se non esiste il conto IVA indetraibile ... { // ... somma imponibile e imposta oldimp += oldiva; oldiva = 0.0; } } TBill oldconto(row, 6, 0x0); // g/c/s 6 7 8 if (oldconto.ok()) { oldpos = bill2pos(oldconto, 'I'); if (oldpos < 0) { const TString d(cau.desc_agg(2)); oldpos = a.set_cgs_row(-1, a.real2imp(ZERO, 'I'), oldconto, d, 'I'); } } else oldpos = -1; // Se il conto e' incompleto ignoralo } if (k == K_DEL) // Cancellazione di una riga { row.add("0", 0); // Azzera imponibile row.add("0", 3); // Azzera imposta k = K_ENTER; // Elegante o Sporco trucco (dipende dai gusti!) } if (k == K_ENTER) { int delimp = -1, deliva = -1; // Eventuali righe contabili da cancellare if (oldpos >= 0) // Se il conto esisteva anche prima ... { // sottrai il vecchio imponibile TImporto i(a.get_cgs_imp(oldpos)); i -= oldimp; a.set_cgs_imp(oldpos, i); if (i.is_zero()) delimp = oldpos; } if (oldposiva >= 0) // Se conto IVA esisteva anche prima ... { // sottrai la vecchia imposta TImporto i(a.get_cgs_imp(oldposiva)); i -= oldiva; a.set_cgs_imp(oldposiva, i); if (i.is_zero()) deliva = oldposiva; } real imponibile(row.get(0)); // Nuovo imponibile real imposta(row.get(3)); // Nuova imposta if (imposta.is_zero() && cau.corrispettivi()) // In caso di corrispettivi ... { const TString zanicchi(row.get(1)); const TCodiceIVA i(zanicchi); imposta = i.scorpora(imponibile); // ... scorpora imposta dall'imponibile } TBill conto(row, 5, 0x3); int newpos = bill2pos(conto, 'I'); // Riga in cui andra' l'imponibile const bool detrarre = detraibile(row); // Determina se IVA detraibile // Calcola riga causale col conto opportuno const int ri = detrarre ? RIGA_IVA_DETRAIBILE : RIGA_IVA_NON_DETRAIBILE; TBill contoiva; cau.bill(ri, contoiva); if (!detrarre && !contoiva.ok()) // Se non c'e' il conto IVA indetraibile ... { // ... somma imponibile e imposta imponibile += imposta; imposta = 0.0; } const TImporto newimp = a.real2imp(imponibile, 'I'); // Aggiorna conto sulla riga contabile if (newpos < 0) { if (delimp >= 0) { a.reset_cgs_row(delimp); // Cancella vecchia riga if (deliva > delimp) deliva--; } if (conto.ok() && !newimp.is_zero()) // Se c'e' imponibile ... { // crea una nuova riga contabile const TString d(cau.desc_agg(2)); a.set_cgs_row(-1, newimp, conto, d, 'I'); } } else { const bool empty = a.add_cgs_imp(newpos, newimp); if (empty) // Se la riga si e' azzerata ... { // ... cancellala a.reset_cgs_row(newpos); newpos = -1; } } oldimp = newimp; oldpos = newpos; // Aggiorna conto IVA sulla riga contabile const char tipod = detrarre ? 'D' : 'N'; int newposiva = type2pos(tipod); if (deliva >= 0 && newposiva != deliva) // E' cambiato il tipo d'imposta a.reset_cgs_row(deliva); // Azzera il vecchio tipo se necessario const TImporto newiva = a.real2imp(imposta, 'I'); if (newposiva < 0) { if (!imposta.is_zero()) // Se c'e' imposta ... { // ... crea nuova riga per l'IVA const TString d(cau.desc_agg(ri)); newposiva = a.set_cgs_row(-1, newiva, contoiva, d, tipod); } } else { const bool empty = a.add_cgs_imp(newposiva, newiva); if (empty) // Se l'imposta si e' azzerata ... { a.reset_cgs_row(newposiva); // ... cancellala newposiva = -1; } } oldiva = newiva; oldposiva = newposiva; TMask& m = a.curr_mask(); if (r == 0) // Se cambio la prima riga ... { a.add_cgs_tot(m); // ... ricalcola conti e imponibili } else { a.calcola_saldo(); // Calcola sbilancio a.calcola_imp(); // Calcola imponibili } if (a.is_fattura() && m.insert_mode()) { TPagamento& pag = a.pagamento(); const TValuta cambio(m, SK_VALUTA, SK_DATACAMBIO, SK_CAMBIO); const bool inv = cambio.in_valuta(); real imposta, imponibile; if (inv) { const real il(m.get(F_IMPOSTE)); imposta = cambio.lit2val(il); imponibile = m.get_real(SK_TOTDOCVAL) - imposta; } else { imposta = m.get_real(F_IMPOSTE); imponibile = m.get_real(F_TOTALE) - imposta; } imposta.round(pag.round(inv)); imponibile.round(pag.round(inv)); real pimposta(pag.imposta(inv)); real pimponibile(pag.imponibile(inv)); pimposta.round(pag.round(inv)); pimponibile.round(pag.round(inv)); if (pimposta != imposta || pimponibile != imponibile) a.set_scadenze(m); // Ricalcola rate } } return TRUE; } // Handler dello sheet // Certified 90% bool TPrimanota_application::iva_handler(TMask_field& f, KEY k) { if ((k == K_TAB && !f.mask().is_running()) || k == K_ENTER) { const real imp = app().calcola_imp(); if (k == K_ENTER) { const real tot = app().totale_documento(); if (imp != tot) { const TString t(tot.string(".")); const TString i(imp.string(".")); return error_box("La somma del totale documento e delle ritenute (%s) e' diverso dalla " "somma degli imponibili e delle imposte (%s)", (const char*)t, (const char*)i); } TSheet_field& iva = app().ivas(); for (int i = 0; i < iva.items(); i++) { TToken_string& row = iva.row(i); const real im(row.get(0)); if (!im.is_zero()) { TBill c(row, 5, 0x1); if (!c.ok() || !c.find()) return error_box("Il conto della riga iva %d e' errato o incompleto", i+1); } } } } return TRUE; } // Il gruppo non possiede una ricerca propria per cui se viene variato richiama // quella del conto. bool TPrimanota_application::cg_gruppo_handler(TMask_field& f, KEY key) { if (key == K_TAB && f.focusdirty()) { TEdit_field& conto = f.mask().efield(f.dlg()+1); const TRectype& curr = conto.browse()->cursor()->curr(); if (curr.get(RMV_GRUPPO) != f.get()) // Se non e' gia' posizionato ... conto.check(RUNNING_CHECK); // ... forza ricerca sul conto } return TRUE; } bool TPrimanota_application::cg_conto_handler(TMask_field& f, KEY key) { bool ok = TRUE; if (key == K_ENTER) { TMask& m = f.mask(); if (m.get(CG_ROWTYPE)[0] == 'T' && !app().causale().corrispettivi()) { const char tipo = app().clifo(); // Tipo conto richiesto dal movimento char cf = m.get(f.dlg()-2)[0]; if (cf < ' ') cf = ' '; // Tipo conto della riga if (cf != tipo) // Incongruenza! { const char* d = tipo == 'C' ? "clienti" : "fornitori"; ok = f.error_box("La riga totale richiede un conto %s.", d); } } } return ok; } // Gestore del sottoconto dello sheet IVA // Attenzione questo handler e' agganciato anche alla descrizione del sottoconto bool TPrimanota_application::iva_sottoconto_handler(TMask_field& f, KEY key) { if (!suspended_handler(f, key)) return FALSE; if (key == K_TAB && f.dirty()) { TMask& m = f.mask(); const TEdit_field& e = (const TEdit_field&)f; const TRectype& piano = e.browse()->cursor()->curr(); int spric = piano.get_int("TIPOSPRIC"); if (app().iva() == iva_vendite) { const TCausale& caus = app().causale(); if (spric == 2 || spric == 3) { const TString& td = caus.tipo_doc(); if (td == "FV" || td == "NC" || td == "ND") spric = 4; } } TString s; if (spric > 0) s << spric; m.set(105, s, TRUE); // Setta il campo spesa-ricavo della riga IVA } return TRUE; } bool TPrimanota_application::sheet_clifo_handler(TMask_field& f, KEY k) { if (!suspended_handler(f, k)) return FALSE; if (k == K_TAB || k == K_ENTER) { const long codice = atol(f.get()); if (codice > 0L) { TMask& m = f.mask(); const short cid = 100 + (f.dlg() % 100) -1; const short gid = cid-1; const int conto = m.get_int(cid); const int gruppo = m.get_int(gid); if (gruppo == 0 && conto == 0) { TBill c(0, 0, codice, f.dlg() > 300 ? 'F' : 'C'); m.set(f.dlg()+1, c.descrizione()); // Carica gruppo e conto if (c.ok()) { m.set(gid-1, c.tipo() == 'C' ? "C" : "F"); m.set(gid, c.gruppo()); m.set(cid, c.conto()); } } } } return TRUE; } /////////////////////////////////////////////////////////// // Handlers dei campi della testata /////////////////////////////////////////////////////////// // Handler of the F_NUMREG field on the query mask // Certified 99% bool TPrimanota_application::num_handler(TMask_field& f, KEY key) { if (key == K_TAB && f.to_check(key, TRUE)) { TPrimanota_application& a = app(); TMask& m = f.mask(); a._skip_giornale_check = FALSE; a._skip_bollato_check = FALSE; const long max = a._lastreg+1; const long num = f.empty() ? max : atol(f.get()); if (num < max) { if (a.find(1)) { const TLocalisamfile& mov = a._rel->lfile(); bool ok = TRUE; if (mov.get_bool(MOV_STAMPATO)) { ok = yesno_box("Il movimento e' gia' stato stampato sul libro giornale:\n" "si desidera continuare ugualmente?"); a._skip_giornale_check = ok; } if (ok && mov.get_bool(MOV_REGST)) { ok = yesno_box("Il movimento e' gia' stato stampato sul bollato:\n" "si desidera continuare ugualmente?"); a._skip_bollato_check = ok; } if (ok && mov.get_bool(MOV_INVIATO)) { ok = yesno_box("Il movimento e' stato inviato ad un'altra contabilita':\n" "si desidera continuare ugualmente?"); } if (ok) { // Riempie a mano i campi necessari nel caso non sia stato usata la ricerca F9 m.set(F_DATAREG, mov.get(MOV_DATAREG), TRUE); // DATACOMP new way // m.set(F_DATACOMP, mov.get("DATACOMP"), TRUE); m.set(F_CODCAUS, mov.get(MOV_CODCAUS)); f.set_focusdirty(FALSE); ok = m.stop_run(K_AUTO_ENTER); } else { m.reset(F_NUMREG); if (a.lnflag()) m.stop_run(K_FORCE_CLOSE); } return ok; } } else if (num > max) { f.set(format("%ld", max)); return f.error_box("Non e' possibile inserire movimenti superiori al %ld", max); } } return TRUE; } // Handler of the F_CODCAUS field on the query mask // Certified 99% bool TPrimanota_application::caus_query_handler(TMask_field& f, KEY key) { const TMask& m = f.mask(); if (!m.is_running()) return TRUE; if (f.to_check(key)) { const TString cau = f.get(); const int ann = m.get_int(F_ANNOIVA); const TipoIVA i = app().cau2IVA(cau, ann); // Cerca causale e suo tipo if (i != iva_errata) { const bool ok = suspended_handler(f, key); // Controlla sospensione if (ok && key == K_TAB) { f.set_focusdirty(FALSE); return f.mask().stop_run(K_INS); // Entra in modo inserimento } } else { return error_box("Causale non presente in archivio"); } } return TRUE; } // Handler of the F_CODCAUS field on the modify mask // Certified 99% bool TPrimanota_application::caus_modify_handler(TMask_field& f, KEY key) { if (f.to_check(key)) { bool ok = suspended_handler(f, key); if (!ok) return FALSE; const int ann = f.mask().get_int(F_ANNOIVA); const TString cau(f.get()); const TCausale c(cau, ann); if (!c.ok()) return FALSE; ok = app().causale().similar(c); if (!ok) return FALSE; // L'errore viene gia' segnalato dalla similar if (key == K_TAB) { app().read_caus(cau, ann); app().cgs().force_update(); } } return TRUE; } // Handler of the F_DATAREG field // Certified 70% bool TPrimanota_application::datareg_handler(TMask_field& f, KEY key) { bool ok = TRUE; TMask& m = f.mask(); //if ((key == K_TAB && m.is_running() ) || key == K_ENTER) if (key == K_TAB && f.focusdirty() || key == K_ENTER) { const TDate dr(f.get()); // Data dell'operazione if (dr > TDate(TODAY)) return f.error_box("La data dell'operazione e' superiore quella di sistema"); TPrimanota_application& a = app(); const int ae = a._esercizi.date2esc(dr); // Codice esercizio if (ae <= 0) return f.error_box("La data dell'operazione non appartiene a nessun esercizio"); TLibro_giornale& gio = a.giornale(); const int ar = dr.year(); // Anno per registri if (m.query_mode() || gio.year() != ar) { ok = gio.read(ar); if (!ok) return f.error_box("Non esiste il libro giornale del %d", ar); } else ok = TRUE; if (key == K_ENTER || f.focusdirty()) { const long numreg = m.get_long(F_NUMREG); const bool error = numreg == 0 || numreg > a._lastreg; if (key != K_ENTER && !a._skip_giornale_check) { if (dr < gio.last_print()) { f.error_box("La data dell'operazione e' antecedente al %s,\n" "ultima stampa del libro giornale del %d", gio.last_print().string(), ar); if (error) return FALSE; } if (key == K_TAB && dr < gio.last_reg()) f.warning_box("La data dell'operazione e' antecedente al %s,\n" "ultima registrazione sul libro giornale del %d", gio.last_reg().string(), ar); } if (m.query_mode()) a.read_caus(m.get(F_CODCAUS), ar); TRegistro& reg = a.causale().reg(); const TString codreg(reg.name()); if (codreg.not_empty()) { if (reg.year() != ar) { const bool ok = reg.read(codreg, ar); if (!ok) return FALSE; a.read_caus(NULL, 0); if (a.iva() != nessuna_iva) m.field(F_CODREG).on_hit(); } if (!a._skip_bollato_check) { if (dr < reg.last_print()) { f.error_box("La data dell'operazione e' antecedente al %s,\n" "ultima stampa del registro '%s' del %d", reg.last_print().string(), (const char*)codreg, ar); if (error) return FALSE; } if (f.dirty() && dr < reg.last_reg()) f.warning_box("La data dell'operazione e' antecedente al %s,\n" "ultima registrazione sul registro '%s' del %d", reg.last_reg().string(), (const char*)codreg, ar); } if (reg.iva() != nessuna_iva && a._rel->controlla_liquidazione(dr, reg) == TRUE) { const char* const mese = itom(dr.month()); f.warning_box("La liquidazione IVA relativa al mese di %s e' gia' stata calcolata", mese); } } } } return ok; } // Handler of the F_DATACOMP field on the modify mask // Certified 90% bool TPrimanota_application::datacomp_handler(TMask_field& f, KEY key) { TMask& m = f.mask(); if (key == K_TAB || key == K_ENTER) { const TDate dr(m.get(F_DATAREG)); // Data operazione TString16 datacomp = f.get(); if (datacomp.empty()) { datacomp = dr.string(); // DATACOMP new way if (key == K_ENTER) f.set(datacomp); } const TDate dc(datacomp); // Data di competenza TEsercizi_contabili& esc = app()._esercizi; const int ae = esc.date2esc(dc); // Esercizio corrispondente const char* data = "del 74/ter"; if (f.dlg() == F_DATACOMP) { m.set(F_ANNOES, ae, TRUE); // Aggiorna anno esercizio in entrambe le pagine data = "di competenza"; } if (ae) { const int ar = esc.date2esc(dr); // Esercizio in corso const int pr = esc.pred(ar); // Esercizio precedente if (ae != ar && ae != pr) { TString e(80); e << "La data " << data << " deve appartenere all'esercizio " << ar; if (pr > 0) e << " o al " << pr; return f.error_box(e); } } else { if (m.is_running()) return f.error_box("La data %s non appartiene a nessun esercizio", data); } } return TRUE; } // Handler of the F_DATA74TER field on the modify mask // Certified 90% bool TPrimanota_application::data74ter_handler(TMask_field& f, KEY key) { if (!f.to_check(key)) return TRUE; bool ok = datacomp_handler(f, key); if (ok) { const TDate d74(f.get()); const TLibro_giornale& g = app().giornale(); if (d74 < g.last_print()) { ok = f.error_box("La data per il 74/ter e' antecedente alla data di stampa " "del libro giornale dell'esercizio %d", g.year()); } } return ok; } bool TPrimanota_application::numdoc_handler(TMask_field& f, KEY key) { TMask& m = f.mask(); if (key == K_TAB && f.to_check(key, TRUE) && m.insert_mode() && app().is_saldaconto()) { const TString n = f.get(); if (n.not_empty() && !app().npart_is_prot()) // Copiare numero documento nel numero partita? { if (m.field(F_NUMRIF).active() && m.get(F_NUMRIF).blank()) m.set(F_NUMRIF, n, TRUE); } } return TRUE; } bool TPrimanota_application::datadoc_handler(TMask_field& f, KEY key) { TMask& m = f.mask(); if (key == K_TAB && f.to_check(key, TRUE) && app().is_saldaconto()) { const TDate dd(f.get()); // Fattura o nota credito if (dd.ok()) { if (m.insert_mode() && m.field(F_ANNORIF).active() && m.get(F_ANNORIF).empty()) m.set(F_ANNORIF, dd.year()); // copia anno documento TPrimanota_application& a = app(); if (a.is_fattura()) { if (m.insert_mode()) { if (m.get_bool(FS_RECALC)) // Evita scancellamenti indesiderati a.recalc_scadenze(dd); } else { if (a._pag) a._pag->set_datadoc(dd); } } } } return TRUE; } bool TPrimanota_application::occas_code_handler(TMask_field& f, KEY key) { TMask& m = f.mask(); if (key == K_TAB && (f.dirty() || !m.is_running())) { const TString& code = f.get(); if (code.not_empty()) { TRelation occas(LF_OCCAS); occas.curr().put("CFPI", code); if (occas.read(_isequal) == NOERR) { m.autoload(occas); m.send_key(K_TAB, O_COMUNE); // Forza decodifica comuni m.send_key(K_TAB, O_COMUNENAS); } } } return TRUE; } bool TPrimanota_application::occas_handler(TMask_field& f, KEY key) { if (key == K_SPACE && f.mask().is_running()) { TMask& om = app().occas_mask(); om.run(); f.set_focus(); } return TRUE; } // Crea o aggiorna la riga contabile col totale documento // Certified 99% void TPrimanota_application::add_cgs_tot(TMask& m) { const bool corri = causale().corrispettivi(); const char tipo = corri ? ' ' : app().clifo(); int gruppo = 0, conto = 0; long codice = corri ? 0L : m.get_long(tipo == 'C' ? F_CLIENTE : F_FORNITORE); TSheet_field& ss = cgs(); const int riga_totale = type2pos('T'); // Cerca di preservare il gruppo-conto-sottoconto sulla riga totale if (riga_totale >= 0) { TToken_string& rowt = ss.row(riga_totale); gruppo = rowt.get_int(3); conto = rowt.get_int(); const long oldcode = rowt.get_long(); if (corri) codice = oldcode; // I corrispettivi non hanno un cliente in testata else { if (m.insert_mode()) // Errore MI3567: se cambio cliente ripesca conto { if (codice != oldcode) // Se cambia il codice cliente ... gruppo = conto = 0; // ... forza il ricalcolo del gruppo-conto } } } TBill nuovo(gruppo, conto, codice, tipo); if (!corri && (gruppo == 0 || conto == 0)) nuovo.find(); // Compila anche gruppo e conto in base al codice clifo if (nuovo.gruppo() == 0 || nuovo.conto() == 0) { // Se l'utente non ha ancora specificato un conto lo prendo dalla prima riga della causale causale().bill(1, nuovo); // Nelle fatture si deve sempre aggiungere il codice clifo (in causale normalmente non c'e') if (!corri) nuovo.codclifo() = codice; } if (riga_totale >= 0) { TToken_string& row = ss.row(riga_totale); const TBill vecchio(row, 2, 0x1); if (!vecchio.empty() && nuovo != vecchio) // Se cambio cliente/fornitore { for (int i = 0; i < ss.items(); i++) if (i != riga_totale) { TToken_string& r = ss.row(i); const TBill tacchia(r, 9, 0x1); if (tacchia == vecchio) { nuovo.add_to(r, 9, 0x3); // Aggiorna contropartite ss.force_update(i); } } } } if (!_as400) { // Creazione/Aggiornamento riga totale const real tot(m.get(F_TOTALE)); set_cgs_row(riga_totale, real2imp(tot, 'T'), nuovo, m.get(F_DESCR), 'T'); } calcola_imp(); // Ricalcola totale IVA calcola_saldo(); // Ricalcola sbilanci } // Handler of the F_CLIENTE & F_FORNITORE field on the modify mask // Certified 99% bool TPrimanota_application::clifo_handler(TMask_field& f, KEY key) { if (!suspended_handler(f, key)) return FALSE; if (key == K_TAB && f.active()) { TPrimanota_application& a = app(); TMask& m = f.mask(); if (f.focusdirty() && a.is_nota_credito()) { TPartite_array& p = a.partite(); if (m.edit_mode()) p.add_numreg(m.get_long(F_NUMREG)); const TPartita* game = p.first(); if (game != NULL && atol(f.get()) != game->conto().codclifo()) { const bool del = f.yesno_box("Si desidera cancellare i pagamenti effettuati?"); if (!del) // Ripristina codice copiandolo dalla prima partita { TString cod; cod << game->conto().codclifo(); f.set(cod); return TRUE; } f.set_dirty(); // yesno_box cleared the dirty flag a.notify_cgline_deletion(-1); } } const char cf = a.clifo(); const long codice = atol(f.get()); if (codice == 0) { m.hide(F_OCCASEDIT); // Spegni bottone occasionali m.show(F_STATOPAIV); // Stato partita IVA m.show(cf == 'C' ? F_PIVACLIENTE : F_PIVAFORNITORE); // Partita IVA m.show(cf == 'C' ? F_COFICLIENTE : F_COFIFORNITORE); // Codice Fiscale a.activate_numrif(m, TRUE); return TRUE; } 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, codice); cliforel.read(); if (!m.is_running() || f.dirty()) { a._conto_ricavo.set(clifo.get_int(CLI_GRUPPORIC), clifo.get_int(CLI_CONTORIC), clifo.get_long(CLI_SOTTOCRIC)); const int alleg = clifo.get_int(CLI_ALLEG); TEdit_field& upi = m.efield(F_RIEPILOGO); upi.check_type(alleg == 3 ? CHECK_REQUIRED : CHECK_NORMAL); if (m.insert_mode() && m.get(F_CODPAG).empty()) { const TString& s = clifo.get(CLI_CODPAG); if (s.not_empty()) { TEdit_field& cp = m.efield(F_CODPAG); if (cp.active()) // Se il campo F_CODPAG e' attivo { cp.set(s); // Setta il codice di pagamento sulla maschera cp.check(RUNNING_CHECK); // lo decodifica cp.on_hit(); // lo ricopia eventualmente a pag.3 } } } if (f.focusdirty() && a.is_saldaconto()) { if (m.field(SK_VALUTA).active() && m.get(SK_VALUTA).empty()) { const TString& valuta = clifo.get(CLI_CODVAL); if (valuta.not_empty()) m.set(SK_VALUTA, valuta, TRUE); } if (a.is_fattura()) { if (clifo.get(CLI_CODCAB).not_empty()) { m.set(FS_VSABI, clifo.get(CLI_CODABI)); m.set(FS_VSCAB, clifo.get(CLI_CODCAB)); m.send_key(K_TAB, FS_VSCAB); } const TString& agente = cliforel.curr(LF_CFVEN).get(CLI_CODAG); if (agente.not_empty()) { m.set(FS_AGENTE, agente, TRUE); m.send_key(K_TAB, FS_AGENTE); } } } } const bool occas = clifo.get_bool(CLI_OCCAS); m.show(F_OCCASEDIT, occas); // Bottone Dati anagrafici m.show(F_STATOPAIV, !occas); // Stato partita IVA m.show(cf == 'C' ? F_PIVACLIENTE : F_PIVAFORNITORE, !occas); // Partita IVA m.show(cf == 'C' ? F_COFICLIENTE : F_COFIFORNITORE, !occas); // Codice Fiscale if (occas && a.is_fattura() && a.partite().first() != NULL) { f.warning_box("Attenzione, il saldaconto verra' eliminato!"); f.set_dirty(); // warning_box cleans the field! } a.activate_numrif(m, TRUE); if (f.focusdirty()) { a.add_cgs_tot(m); if (occas && a.occas_mask().get(O_CODICE).blank()) m.send_key(K_SPACE, F_OCCASEDIT); // Lancia maschera occasionali } } return TRUE; } bool TPrimanota_application::IVA2bill(const TCodiceIVA& iva, TBill& bill) { const TCausale& cau = causale(); if (!cau.corrispettivi()) bill = _conto_ricavo; return cau.IVA2bill(iva, bill); } // Handler of the F_CODIVA // Certified 99% bool TPrimanota_application::main_codiva_handler(TMask_field& f, KEY key) { if (key == K_TAB && f.get().not_empty()) { if (!suspended_handler(f, key)) return FALSE; TPrimanota_application& a = app(); const real imp(a.ivas().row(1).get(0)); // Se il totale non e' stato spezzato if (imp.is_zero()) { TToken_string& row = a.ivas().row(0); TMask& m = f.mask(); iva_notify(a.ivas(), 0, K_SPACE); const TCodiceIVA iva(f.get()); const bool corr = a.causale().corrispettivi(); const bool acq3 = (a.iva() == iva_acquisti) && (row.get_int(2) == 3); real tot = a.totale_documento(); // Calcola totale documento real imposta; // Calcola imposta if (!corr && !acq3) imposta = iva.scorpora(tot); row.add(tot.string(), 0); // imponibile row.add(imposta.string(), 3); // imposta if (iva.codice() != row.get(1)) { row.add(iva.codice(), 1); // Aggiorna codice IVA TBill bill; // Aggiorna conto della prima riga IVA a.IVA2bill(iva, bill); bill.add_to(row, 4, 0x7); } a.ivas().force_update(0); iva_notify(a.ivas(), 0, K_ENTER); } } return TRUE; } // Riempie i campi valuta a zero in base agli altri void TPrimanota_application::gioca_cambi(int force) { TMask& m = curr_mask(); if (m.get(SK_VALUTA).empty()) return; const real totale = m.get(F_TOTALE); const real totval = m.get(SK_TOTDOCVAL); const real cambio = m.get(SK_CAMBIO); if ( (force == 0x1 || totale.is_zero()) && !(totval.is_zero() || cambio.is_zero()) ) { const TValuta cam(m, SK_VALUTA, SK_DATACAMBIO, SK_CAMBIO); const real new_totale = cam.val2lit(totval); if (new_totale != totale) m.set(F_TOTALE, new_totale, TRUE); } if ( (force == 0x2 || totval.is_zero()) && !(totale.is_zero() || cambio.is_zero()) ) { const TValuta cam(m, SK_VALUTA, SK_DATACAMBIO, SK_CAMBIO); const real new_totval = cam.lit2val(totale); if (new_totval != totval) m.set(SK_TOTDOCVAL, new_totval, TRUE); } if ( (force == 0x4 || cambio.is_zero()) && !(totale.is_zero() || totval.is_zero()) ) { real new_cambio = totale / totval; new_cambio.round(5); if (new_cambio != cambio) m.set(SK_CAMBIO, new_cambio, TRUE); } } // Handler of the F_TOTALE // Certified 99% bool TPrimanota_application::totdoc_handler(TMask_field& f, KEY key) { bool ok = TRUE; TMask& m = f.mask(); if (key == K_TAB && f.focusdirty()) { TPrimanota_application& a = app(); a.gioca_cambi(); if (a.iva() != nessuna_iva) { a.add_cgs_tot(m); if (m.insert_mode()) // Se si e' in inserimento provoca ricalcolo m.field(F_CODIVA).on_hit(); // dello sheet iva e delle scadenze } else { if (a.is_pagamento()) a.calcola_saldo(); } } if (key == K_ENTER) { const real totale(f.get()); if (totale.is_zero()) ok = yesno_box("Totale documento nullo: continuare ugualmente?"); if (ok) { const TValuta cambio(m, SK_VALUTA, SK_DATACAMBIO, SK_CAMBIO); if (cambio.in_valuta()) { const real totval(m.get(SK_TOTDOCVAL)); const real totlit = cambio.val2lit(totval); if (totale != totlit) ok = yesno_box("Il totale documento in lire dovrebbe essere %s: continuare ugualmente?", totlit.string(".")); } } } return ok; } bool TPrimanota_application::totdocval_handler(TMask_field& f, KEY key) { if (key == K_TAB && f.focusdirty()) { TPrimanota_application& a = app(); a.gioca_cambi(); TMask& m = f.mask(); if (a.is_fattura() && m.insert_mode()) a.set_scadenze(m); } return TRUE; } // Aggiunge o aggiorna la riga delle ritenute fiscali o sociali // Certified 99% void TPrimanota_application::add_cgs_rit(bool fiscali) { if (_as400) return; TMask& m = curr_mask(); const real imp(m.get(fiscali ? F_RITFIS : F_RITSOC)); // Determina importo const char tipo = fiscali ? 'F' : 'S'; const int pos = type2pos(tipo); // Cerca la riga contabile if (pos < 0) // Se non c'e' ... { if (!imp.is_zero()) // ... e l'importo e' valido { // crea una nuova riga di ritenute const int riga = fiscali ? RIGA_RITENUTE_FISCALI : RIGA_RITENUTE_SOCIALI; TBill conto; causale().bill(riga, conto); const TString desc(causale().desc_agg(riga)); set_cgs_row(-1, real2imp(imp, tipo), conto, desc, tipo); } } else { if (imp.is_zero()) // se l'importo e' nullo ... reset_cgs_row(pos); // ... azzera la riga contabile else // altrimenti ... set_cgs_imp(pos, real2imp(imp, tipo)); // ... aggiorna importo } if (m.insert_mode()) m.field(F_CODIVA).on_hit(); // Ricalcola sheet iva e contabile else app().calcola_saldo(); // Ricalcola solo lo sbilancio } // Handler of the F_PROTIVA bool TPrimanota_application::protiva_handler(TMask_field& f, KEY key) { bool ok = TRUE; TMask& m = f.mask(); if (m.insert_mode()) { if (key == K_ENTER && f.dirty()) { const long protiva = atol(f.get()); const long protocol = app().causale().reg().protocol() + 1; if (protiva != protocol) ok = f.yesno_box("Accettare il protocollo IVA fuori sequenza: %ld invece di %ld", protiva, protocol); } else if (key == K_TAB && m.insert_mode() && app().npart_is_prot() && m.field(F_NUMRIF).active() && m.get(F_NUMRIF).blank()) { const TString& piva = f.get(); if (piva.not_empty()) m.set(F_NUMRIF, piva, TRUE); } } return ok; } // Handler of the F_RITFIS // Certified 99% bool TPrimanota_application::ritfis_handler(TMask_field& f, KEY key) { if (key == K_TAB && f.focusdirty()) app().add_cgs_rit(TRUE); return TRUE; } // Handler of F_RITSOC // Certified 99% bool TPrimanota_application::ritsoc_handler(TMask_field& f, KEY key) { if (key == K_TAB && f.focusdirty()) app().add_cgs_rit(FALSE); return TRUE; } // Handler of F_CORRLIRE // Certified 99% bool TPrimanota_application::corrlire_handler(TMask_field& f, KEY key) { TMask& m = f.mask(); if (key == K_ENTER && f.get().empty()) { if (m.get(F_CORRVALUTA).not_empty()) { TMask_field& cv = m.field(F_CORRVALUTA); cv.set_focusdirty(); cv.on_hit(); } else key = K_F8; } if (key == K_F8) { f.set(m.get(F_IMPONIBILI)); f.set_dirty(); m.reset(F_CORRVALUTA); key = K_TAB; } if (key == K_TAB && f.focusdirty()) { if (m.get(F_CORRVALUTA).empty()) { const real cambio = m.get(F_CAMBIOINTRA); if (cambio != ZERO && m.get(F_CORRVALUTA).empty()) { real c(f.get()); c /= cambio; m.set(F_CORRVALUTA, c.string()); } } } if (key == K_ENTER) { const TString im(m.get(F_IMPONIBILI)); const char* cl = f.get(); if (im != cl) warning_box("Il corrispettivo in lire e' diverso dal totale degli imponibili"); } return TRUE; } // Handler of F_CORRVALUTA // Certified 99% bool TPrimanota_application::corrvaluta_handler(TMask_field& f, KEY key) { if (key == K_TAB && f.focusdirty()) { TMask& m = f.mask(); if (m.get(F_CORRLIRE).empty()) { const real cambio = m.get(F_CAMBIOINTRA); if (cambio != ZERO) { real c = f.get(); c *= cambio; m.set(F_CORRLIRE, c.string()); } } } else if (key == K_ENTER && f.get().empty()) { TMask_field& cl = f.mask().field(F_CORRLIRE); cl.set_dirty(); cl.on_hit(); } return TRUE; } bool TPrimanota_application::activate_numrif(TMask& m, bool init_pag) { bool shown = is_saldaconto(); // Il numero riferimento esiste if (shown) { const bool hide = m.get_bool(F_SOLAIVA) || m.field(F_OCCASEDIT).shown(); if (hide) shown = FALSE; } if (shown != m.field(F_NUMRIF).shown()) { m.show(F_ANNORIF, shown); m.show(F_NUMRIF, shown); if (shown) { if (m.get(F_ANNORIF).empty()) { m.set(F_ANNORIF, m.get(F_DATADOC).right(4)); m.set(F_NUMRIF, m.get(_npart_is_prot ? F_PROTIVA : F_NUMDOC)); } } else { m.reset(F_ANNORIF); m.reset(F_NUMRIF); } } // Gestione pagina 3 const bool page = shown && is_fattura() && !m.get(F_NUMRIF).blank(); if (page != m.page_enabled(2)) { m.enable_page(2, page); if (page && init_pag && m.is_running()) { if (m.edit_mode()) { const TString16 dt(m.get(F_DATADOC)); set_pagamento(NULL, dt); // Reset pagamento set_totale_pagamento(TRUE); } else set_scadenze(m); // Inizializza pagamento } } return shown; } // Handler del checkbox di movimento di sola IVA bool TPrimanota_application::solaiva_handler(TMask_field& f, KEY key) { TMask& m = f.mask(); const bool run = m.is_running(); if ((key == K_TAB && f.focusdirty()) || !run) { TPrimanota_application& a = app(); bool anchecg = f.get()[0] != 'X'; bool recalcg = anchecg; if (run && a.is_fattura()) { const TPartita* game = a.partite().first(); if (anchecg) { if (game != NULL) { m.set(F_ANNORIF, game->anno()); m.set(F_NUMRIF, game->numero()); } } else { bool del = TRUE; if (game != NULL) del = f.yesno_box("Si desidera cancellare il saldaconto?"); if (!del) { f.reset(); anchecg = TRUE; recalcg = FALSE; } } a.activate_numrif(m, TRUE); } m.show(F_SHEETCG, anchecg); m.show(F_DARE, anchecg); m.show(F_AVERE, anchecg); if (run && recalcg) { TSheet_field& iva = a.ivas(); const int righe = iva.items(); TProgind pi(righe, "Generazione righe contabilita'", FALSE, TRUE, 16); TSheet_field& cg = a.cgs(); cg.reset(); a.add_cgs_tot(m); // Genera totale documento if (m.get(F_RITFIS).not_empty()) a.add_cgs_rit(TRUE); // Genera ritenute fiscali if (m.get(F_RITSOC).not_empty()) a.add_cgs_rit(FALSE); // Genera ritenute sociali TToken_string oldrow(128); for (int i = 0; i < righe; i++) { TToken_string& r = iva.row(i); if (!r.empty_items()) { oldrow = r; r = ""; iva_notify(iva, i, K_SPACE); // Simula la creazione di una nuova riga iva r = oldrow; iva_notify(iva, i, K_ENTER); } pi.setstatus(i+1); } a.fill_sheet(m); // Aggiunge righe vuote cg.force_update(); m.set_focus(); // Ripristina il focus al campo (a causa della progind) } } return TRUE; }