#include #include #include #include #include #include #include "cg2100.h" #include "cg2102.h" #include "cg21sld.h" #include #include #include int TClinton::compare(const TSortable& obj) const { int cmp = TBill::compare(obj); if (cmp == 0) { const TClinton& bill = (const TClinton&)obj; cmp = _cms.compare(bill.commessa()); if (cmp == 0) cmp = _fas.compare(bill.fase()); } return cmp; } TClinton::TClinton(TToken_string& row, bool iva) : TBill(row, iva ? 6 : 3, 0x0) { set_commessa(row.get((iva ? 111 : CG_COMMESSA) - FIRST_FIELD)); set_fase(row.get((iva ? 112 : CG_FASE) - FIRST_FIELD)); } /////////////////////////////////////////////////////////// // Funzioni di decodifica/calcolo /////////////////////////////////////////////////////////// // Determina il tipo di una riga contabile in formato TToken_string 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(FR("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; const int dec = TCurrency::get_firm_dec(); if (dec == 0) // Gestione Lire { imposta = abs(imponibile) * percent / (percent + 100.0); imposta.ceil(); if (imponibile.sign() < 0) imposta = -imposta; } else { // Gestione Euro imposta = imponibile * percent / (percent + 100.0); imposta.round(dec); } 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) && !f.empty()) { const TEdit_field& c = (const TEdit_field&)f; const TBrowse* b = c.browse(); CHECKD(b, "Can't check suspension of an 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(TR("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 90% bool TPrimanota_application::detraibile(TToken_string& row) { const TPrimanota_application& a = app(); if (a.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 int annodoc = a._msk[2]->get_date(F_DATADOC).year(); const bool prorata100 = a.causale().reg().prorata100(annodoc); return !prorata100; // 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; } int TPrimanota_application::clint2pos(const TClinton& conto, char tipo) { TSheet_field& cg = app().cgs(); FOR_EACH_SHEET_ROW(cg, i, s) { const char t = row_type(*s); if (t == tipo) { const TClinton c(*s, FALSE); 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 = m->sfield(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; } // Se disabilito il sottoconto alloro spengo anche le commesse if (cg.cell_disabled(n, 5)) { cg.disable_cell(n, CG_COMMESSA); // Commessa cg.disable_cell(n, CG_DESC_CDC); cg.disable_cell(n, CG_FASE); // Fase cg.disable_cell(n, CG_DESC_FASE); 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, const char* cms, const char* fas) { 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(" | | | | "); } if (conto.tipo() <= ' ') // Cerca di impostare la commessa sui conti normali { if (cms == NULL || *cms <= ' ') { if (row.get_char(CG_COMMESSA-FIRST_FIELD) <= ' ') { TString80 codcms, fascms; if (conto.default_cdc(codcms, fascms)) { row.add(codcms, CG_COMMESSA-FIRST_FIELD); row.add(cache().get("CMS", codcms, "S0"), CG_DESC_CDC-FIRST_FIELD); row.add(fascms, CG_FASE-FIRST_FIELD); row.add(cache().get("FSC", fascms, "S0"), CG_DESC_FASE-FIRST_FIELD); } } } else { row.add(cms, CG_COMMESSA-FIRST_FIELD); row.add(cache().get("CMS", cms, "S0"), CG_DESC_CDC-FIRST_FIELD); row.add(fas, CG_FASE-FIRST_FIELD); row.add(cache().get("FSC", fas, "S0"), CG_DESC_FASE-FIRST_FIELD); } cg.enable_cell(n, CG_COMMESSA); // Commessa cg.enable_cell(n, CG_DESC_CDC); cg.enable_cell(n, CG_FASE); // Fase cg.enable_cell(n, CG_DESC_FASE); } else // Azzera commessa sui conti clifo { row.add("", CG_COMMESSA-FIRST_FIELD); row.add("", CG_DESC_CDC-FIRST_FIELD); row.add("", CG_FASE-FIRST_FIELD); row.add("", CG_DESC_FASE-FIRST_FIELD); cg.disable_cell(n, CG_COMMESSA); // Commessa cg.disable_cell(n, CG_DESC_CDC); cg.disable_cell(n, CG_FASE); // Fase cg.disable_cell(n, CG_DESC_FASE); } row.add(tipo, CG_ROWTYPE-FIRST_FIELD); 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() { TSheet_field& s = cgs(); TString_array& rows = s.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(s, 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 { TImporto importo, bilancio, saldaconto; const bool pag = is_pagamento() && !_as400; TString_array& rows = cgs().rows_array(); for (int i = rows.last(); i >= 0; i--) { TToken_string& r = rows.row(i); importo = r; bilancio += importo; if (pag) { const char tipo = row_type(r); if (strchr("ACGKP", tipo) != NULL) // Abbuoni attivi, differenze cambio, saldaconto += importo; } } TMask& m = curr_mask(); bilancio.normalize(); const real& sbil = bilancio.valore(); const char sez = bilancio.is_zero() ? 'Z' : bilancio.sezione(); switch (sez) { case 'D': m.set(F_DARE, sbil); m.reset(F_AVERE); break; case 'A': m.reset(F_DARE); m.set(F_AVERE, sbil); 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 sbil; } HIDDEN bool imptot_error(const TImporto& imptot, const TImporto& impsal, bool val) { TImporto cassa(impsal); cassa.swap_section(); TImporto residuo(imptot); residuo -= cassa; residuo.normalize(imptot.sezione()); bool ok = TRUE; // if (!residuo.is_zero()) if (abs(residuo.valore()) >= 0.001) { TPrimanota_application& a = app(); const TMask& m = a.curr_mask(); TString16 codval; if (val) codval = m.get(SK_VALUTA); TCurrency euro(imptot.valore(), codval); TString msg(255); if (codval.not_empty()) msg << TR("Il totale documento in valuta") << ' ' << codval; else msg << TR("Il totale documento inserito"); msg << TR(" e' ") << euro.string(TRUE) << ' ' << imptot.sezione() << ",\n"; euro.set_num(cassa.valore()); msg << TR("i pagamenti e le spese ammontano a ") << euro.string(TRUE) << ' ' << cassa.sezione() << ",\n"; euro.set_num(residuo.valore()); msg << TR("per cui il residuo e' ") << euro.string(TRUE); if (m.edit_mode() && impsal.is_zero()) { msg << TR("\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 TCurrency saldo(a.calcola_saldo()); if (!saldo.get_num().is_zero()) { const char* ss = saldo.string(TRUE); if (*ss == '-') ss++; const TRectype& rec = cache().get("%VAL", TCurrency::get_firm_val()); const char* name = rec.get("S0"); return f.error_box(FR("Il movimento e' sbilanciato di %s %s."), ss, name); } 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.insert_mode() ? NUMREG_PROVVISORIO : 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()) { TBill c(r, 2, 0x1); if (!c.ok()) return f.error_box(FR("Il conto della riga %d non e' completo"), i+1); if (m.insert_mode() && c.sospeso()) return f.error_box(FR("Il conto della riga %d e' sospeso"), i+1); TBill co(r, 10, 0x0); if (!co.empty() && !co.ok()) { const bool ok = f.yesno_box(FR("La contropartita della riga %d non e' completa:\n" "Si desidera continuare ugualmente?"), i+1); if (!ok) return FALSE; } if (app().is_transaction()) { // Controlla esistenza conti nelle transazioni (visto che non c'e' controllo in inserimento) if (!c.find()) return f.error_box("Il conto della riga %d non esiste", i+1); if (!co.empty() && !co.find()) return f.error_box("Il conto di contropartita della riga %d non esiste", i+1); } 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 (nota && errato && speso.is_zero()) { const int annorif = m.get_int(F_ANNORIF); const TString& numrif = m.get(F_NUMRIF); if (annorif > 0 && !numrif.blank() && yesno_box(FR("Si desidera generare automaticamente la partita %d %s?"), annorif, (const char*)numrif)) { const TBill bill(r, 2, 0x1); errato = !a.crea_partita(bill, annorif, numrif, currig, importo); } } if (errato) { TString msg(128); const TCurrency euro(speso.valore()); msg.format("L'importo sul saldaconto della riga %d e' %s", currig, (const char*)euro.string(TRUE)); if (!speso.is_zero()) msg << (speso.sezione() == 'A' ? TR(" Avere") : TR(" Dare")); bool ok = FALSE; if (m.edit_mode() && speso.is_zero()) { msg << TR("\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) { if (tipo == 'G') // Le spese non si trovano sul saldaconto { const TExchange cam(m.get(SK_VALUTA), m.get_real(SK_CAMBIO)); TCurrency spe(importo.valore()); spe.change_value(cam); const TImporto imp_spe(importo.sezione(), spe.get_num()); saldaconto_val += imp_spe; } else if (tipo == 'K' || tipo == 'T') saldaconto_val += a.partite().importo_speso(numreg, i+1, TRUE, 0x1); } } } // La commessa è vuota: controlliamo se era obbligatoria const TString80 cms = r.get(CG_COMMESSA-FIRST_FIELD); if (c.tipo() <= ' ' && cms.blank()) { TToken_string k = c.string(); const TRectype& pc = cache().get(LF_PCON, k); if (pc.get_bool(PCN_CMSNEEDED)) { k.replace('|', ' '); return f.error_box(FR("Il codice commessa è obbligatorio per il conto %s della riga %d"), (const char*)k, i+1); } } } } if (empty) return f.error_box(TR("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 = TR("Non esiste una riga contabile riferita al "); msg << (contocf.tipo() == 'C' ? TR("cliente") : TR("fornitore")) << ' '; msg << contocf.codclifo() << ":\n"; if (m.edit_mode()) { msg << TR("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 << TR("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; TWait_cursor hourglass; TImporto importo; importo = row; const bool causale_ok = causale().codice()[0] > ' '; // Se la seconda riga e' vuota la genero completamente dalla prima 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(0); } } if (contro.ok()) { importo.swap_section(); // Inverto la sezione D/A 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 ... { long sotto = rowi.get_long(12); if (sotto == 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 long sotto = row.get_long(12); if (sotto == 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); long sotto = first.get_long(12); if (sotto == 0) // Se la prima riga non ha contropartita ... { conto.add_to(first, 9, 0x3); // ... copiaci la mia partita cg.force_update(first_not_empty); } sotto = row.get_long(12); if (sotto == 0) // Se non ho contropartita ... { TBill contro(first, 2, 0x3); // ... copiala dalla prima riga contro.add_to(row, 9, 0x3); cg.force_update(r); } } } } int TPrimanota_application::crea_somma_spese(TImporto& imp) { TBill cassa; causale().bill(2, cassa); const TString 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; } void TPrimanota_application::update_saldo_riga(int r) { TSheet_field& sheet = cgs(); TToken_string row = sheet.row(r); TBill bill; bill.get(row, 2, 0x1); if (bill.ok()) { TMask& m = curr_mask(); const int annoes = m.get_int(F_ANNOES); // Legge il saldo finale del conto TBalance bilancio; bilancio.read(bill, annoes, false, false); TImporto saldo = bilancio.saldo_finale(); // Sottrae (somma algebricamente) il valore iniziale del conto const TConto* conto = _saldi.find(bill, annoes); if (conto != NULL) { saldo += TImporto('D', conto->dare()); saldo += TImporto('A', conto->avere()); } // Somma l'importo delle singole righe con quel conto for (int i = sheet.items()-1; i >= 0; i--) { row = sheet.row(i); if (!row.empty_items()) { TBill zio; zio.get(row, 2, 0x1); if (zio == bill) { TImporto da; da = row; saldo += da; } } } TString80 s; // Stringa di lavoro // Trasforma il saldo in stringa saldo.normalize(); if (!saldo.is_zero()) { const TCurrency imp = saldo.valore(); s = imp.string(true); s << ' ' << saldo.sezione(); } bill.set(m, F_GRUPPO, F_CONTO, F_SOTTOCONTO); // Stampa conto m.set(F_SALDOCONTO, s); // Stampa saldo // Controlla se il conto ha attivato il controllo del segno s = bill.string(); // Chiave del sottoconto da controllare if (bill.tipo() > ' ') // Per i clienti/fornitori devo controllare il solo gruppo/conto { const int pipe = s.rfind('|'); s.cut(pipe); } const TRectype& pcon = cache().get(LF_PCON, s); const char sez = pcon.get_char(PCN_SEZSALDI); bool red = false; if (sez > ' ' && !saldo.is_zero()) // Il conto ha impostato il controllo della sezione! red = sez != saldo.sezione(); // Scrive in nero o rosso la parola Saldo s = TR("Saldo"); if (red) { s.upper(); s.insert("@b$[r]"); } m.field(F_SALDOCONTO).set_prompt(s); } } bool TPrimanota_application::cg_notify(TSheet_field& cg, int r, KEY k) { static TImporto old_spesa; static bool delete_l = FALSE; static bool selecting = 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; else old_spesa.valore() = ZERO; break; case K_TAB: if (!selecting) { cg.sheet_mask().enable(DLG_DELREC, tipo <= ' ' || tipo == 'K' || tipo == 'G'); if (row.empty_items()) { selecting = TRUE; cg.select(r, 1); // Vado alla prima colonna delle righe vuote selecting = FALSE; } a.update_saldo_riga(r); } break; case K_DEL: if (tipo == 'G') { if (old_spesa.is_zero()) old_spesa = row; 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 TString 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); importo.normalize(); if (tipo == 'G') { const char sezbanca = a.causale().sezione(2); if (sezbanca == sez) importo.swap_section(); } 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.post_select(i); 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() || f.get().find(old) >= 0) { 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(TR("La descrizione del documento e' necessaria in assenza 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(); TMask& m = f.mask(); if (k == K_F8 && a.is_pagamento()) { const TMask& cm = a.curr_mask(); const long numreg = cm.insert_mode() ? NUMREG_PROVVISORIO : cm.get_long(F_NUMREG); const TImporto speso = a.partite().importo_speso(numreg, currig+1); const char* ss = speso.valore().string(); 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 a.update_saldo_riga(currig); } } 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; m.reset(id); // Aggiorna maschera e ... row.add("", id - CG_DARE); // ... riga dello sheet } if (!m.is_running()) { a.calcola_saldo(); // Aggiorna saldo e residuo a.update_saldo_riga(currig); } } if (k == K_ENTER && f.dirty() && m.is_running()) { a.calcola_saldo(); // Aggiorna saldo e residuo a.update_saldo_riga(currig); } return TRUE; } // La fase puo' esistere solo con la commessa bool TPrimanota_application::fase_handler(TMask_field& f, KEY k) { bool ok = TRUE; if (f.to_check(k) && !f.empty()) { const TEdit_field& cms_fld = f.mask().efield(f.dlg()-1); if (cms_fld.empty()) ok = f.error_box(TR("E' necessario specificare anche la commessa")); } return ok; } TSheet_field& TPrimanota_application::pags() const { CHECK(is_fattura(), "Can't use rate sheet without a fattura"); TMask& m = *_msk[iva() == nessuna_iva ? 1 : 2]; return m.sfield(FS_RATESHEET); } /////////////////////////////////////////////////////////// // Gestione sheet IVA /////////////////////////////////////////////////////////// // Ritorna lo sheet delle righe IVA // Certified 100% TSheet_field& TPrimanota_application::ivas() const { TSheet_field& s = _msk[2]->sfield(F_SHEETIVA); return s; } // Gestione del campo imponibile sullo sheet iva // Certified 99% 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); if (iva.not_empty()) m.set(102, iva, TRUE); } if (iva.not_empty() && !app().causale().corrispettivi()) { const real& percent = cod2IVA(m); const real imponibile(f.get()); const int dec = TCurrency::get_firm_dec(); real imposta; if (dec == 0) { imposta = abs(imponibile) * percent / 100.0; imposta.ceil(); if (imponibile.sign() < 0) imposta = -imposta; } else { imposta = imponibile * percent / 100.0; imposta.round(dec); } 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(); TCodiceIVA iva(f.get()); if (m.get_int(107) == 0) { 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()); TString80 codcms, fascms; if (b.default_cdc(codcms, fascms)) { m.set(111, codcms, TRUE); m.set(112, fascms, TRUE); } } if (app().iva() == iva_acquisti) { const int det = iva.detraibilita(); if (det > 0) m.set(103, det); } 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(TR("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& m = f.mask(); TMask_field& ci = m.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) { TMask& m = f.mask(); if ((key == K_ENTER || key == K_TAB) && f.dirty()) { const real imponibile(m.get(101)); const real percent = app().causale().corrispettivi() ? ZERO : cod2IVA(m); const int dec = TCurrency::get_firm_dec(); real imposta; if (dec == 0) { imposta = abs(imponibile) * percent / 100.0; imposta.ceil(); if (imponibile.sign() < 0) imposta = -imposta; } else { imposta = imponibile * percent / 100.0; imposta.round(dec); } const real val(f.get()); if (val != imposta) { const TCurrency euro(imposta); f.warning_box(FR("L'imposta dovrebbe essere %s"), euro.string(TRUE)); } } else if (key == K_F8) { real imposta(f.get()); if (imposta.is_zero()) { real imponibile(m.get(101)); const real& percent = cod2IVA(m); imposta = scorpora(imponibile, percent); m.set(101, imponibile); f.set(imposta.string()); } else f.warning_box(TR("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 righe 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; static bool selecting = FALSE; 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_TAB) { if (!selecting && row.empty_items()) { selecting = TRUE; iva.select(r, 1); // Vado alla prima colonna delle righe vuote selecting = FALSE; } return TRUE; } 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 TString16 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.set('D', ZERO); } } TClinton oldconto(row, TRUE); if (oldconto.ok()) { oldpos = clint2pos(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', oldconto.commessa(), oldconto.fase()); } } 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; i.normalize(); 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; i.normalize(); 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 } TClinton conto(row, TRUE); int newpos = clint2pos(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 = ZERO; } TImporto newimp = a.real2imp(imponibile, 'I'); newimp.normalize(); // Aggiorna conto sulla riga contabile if (newpos < 0) { TString saved_descr; if (delimp >= 0) { TSheet_field& s = a.cgs(); saved_descr = s.row(delimp).get(8); // Memorizza vecchia descrizione 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 if (saved_descr.blank()) saved_descr = cau.desc_agg(2); newpos = a.set_cgs_row(-1, newimp, conto, saved_descr, 'I', conto.commessa(), conto.fase()); } } 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; } else { if (delimp >= 0 && delimp != newpos) { a.reset_cgs_row(delimp); // Cancella vecchia riga if (deliva > delimp) deliva--; } } } 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 TImporto newiva = a.real2imp(imposta, 'I'); newiva.normalize(); 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, SK_CONTROEURO); 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 99% bool TPrimanota_application::iva_handler(TMask_field& f, KEY k) { if ((k == K_TAB && !f.mask().is_running()) || k == K_ENTER) { const TCurrency imp(app().calcola_imp()); if (k == K_ENTER) { const TCurrency tot(app().totale_documento()); if (imp != tot) { const TString t(tot.string(TRUE)); const TString i(imp.string(TRUE)); return error_box(FR("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()) { const TFixed_string codiva = row.get(1); if (codiva.blank()) return error_box(FR("Il codice IVA della riga %d e' obbligatorio"), i+1); TBill c(row, 5, 0x1); if (!c.ok() || !c.find()) return error_box(FR("Il conto della riga iva %d e' errato o incompleto"), i+1); } } } } return TRUE; } bool TPrimanota_application::cg_tipo_handler(TMask_field& f, KEY key) { if (key == K_TAB && f.focusdirty() || key == K_ENTER) { TMask& m = f.mask(); const bool on = f.get().blank() && m.field(CG_SOTTOCONTO).active(); if (!on) { m.reset(CG_COMMESSA); m.reset(CG_FASE); } m.enable(CG_COMMESSA, on); m.enable(CG_FASE, on); } 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_TAB) { TMask& m = f.mask(); if (m.field(CG_SOTTOCONTO).active()) // Controlla se sottoconto acceso { const char cf = m.get(CG_TIPO)[0]; // Tipo conto const bool enc = cf <= ' '; // Commessa ammessa per conti normali if (!enc) { m.reset(CG_COMMESSA); m.reset(CG_FASE); } m.enable(CG_COMMESSA, enc); m.enable(CG_FASE, enc); } } 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' ? TR("clienti") : TR("fornitori"); ok = f.error_box(FR("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; TMask& m = f.mask(); if (key == K_TAB && f.dirty()) { 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; } } TString16 s; if (spric > 0) s << spric; m.set(105, s, TRUE); // Setta il campo spesa-ricavo della riga IVA } if (!f.empty() && (key == K_ENTER || (key == K_TAB && f.dirty()))) { TEdit_field& cdc = m.efield(111); if (cdc.active() && cdc.empty()) { TBill zio; zio.get(m, 107, 108, 109); if (key == K_TAB) { TString80 cms, fas; if (zio.default_cdc(cms, fas)) { m.set(111, cms, 0x2); m.set(112, fas, 0x2); } } TToken_string k = zio.string(); const TRectype& pc = cache().get(LF_PCON, k); if (key == K_ENTER && cdc.empty() && pc.get_bool(PCN_CMSNEEDED)) { k.replace(k.separator(), ' '); return cdc.error_box(FR("Il conto %s richiede che sia specificato il codice CDC/Commessa"), (const char*)k); } } } return TRUE; } bool TPrimanota_application::cg_sottoconto_handler(TMask_field& f, KEY k) { if (!suspended_handler(f, k)) return FALSE; if (!f.empty() && (k == K_ENTER || (k == K_TAB && f.dirty()))) { TMask& m = f.mask(); TEdit_field& cdc = m.efield(CG_COMMESSA); if (cdc.active() && cdc.empty()) { TBill zio; zio.get(m, CG_GRUPPO, CG_CONTO, CG_SOTTOCONTO); TToken_string key = zio.string(); const TRectype& pc = cache().get(LF_PCON, key); if (k == K_TAB) { m.set(CG_COMMESSA, pc.get(PCN_CODCMS), 0x2); m.set(CG_FASE, pc.get(PCN_FASCMS), 0x2); } if (k == K_ENTER && cdc.empty() && pc.get_bool(PCN_CMSNEEDED)) { key.replace(key.separator(), ' '); return cdc.error_box(FR("Il conto %s richiede che sia specificato il codice CDC/Commessa"), (const char*)key); } } } 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 ((k == K_TAB && f.focusdirty()) || (gruppo == 0 && conto == 0)) { TBill c(0, 0, codice, f.dlg() > 300 ? 'F' : 'C'); c.find(); // 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)) { TMask& m = f.mask(); TPrimanota_application& a = app(); if (a.autodeleting() == 0x3) return TRUE; // Non effettuare controlli inutili in cancellazione a._skip_giornale_check = FALSE; a._skip_bollato_check = FALSE; const TRectype& mov = cache().get(LF_MOV, f.get()); if (!mov.empty()) { bool ok = TRUE; if (mov.get_bool(MOV_STAMPATO)) { ok = f.yesno_box(TR("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 = f.yesno_box(TR("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 = f.yesno_box(TR("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; } } 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) return suspended_handler(f, key); // Controlla sospensione else return error_box(TR("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(TR("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(TR("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(FR("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(FR("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(FR("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(FR("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(FR("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(FR("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 = TR("La data del 74/ter"); if (f.dlg() == F_DATACOMP) { m.set(F_ANNOES, ae, TRUE); // Aggiorna anno esercizio in entrambe le pagine data = TR("La data di competenza"); if (dc > dr) { bool ok = FALSE; const TString& ca = m.get(F_CODCAUS); if (ca.not_empty()) // Controlla ratei e risconti { TConfig ini(CONFIG_DITTA, "cg"); const TString& ra = ini.get("RrCcRa"); const TString& ri = ini.get("RrCcRi"); ok = (ca == ra) || (ca == ri); } if (!ok) return f.error_box("La data di competenza non può superare la data di registrazione"); } } 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.format(FR("%s deve appartenere all'esercizio %d"), data, ar); if (pr > 0) e << TR(" o all'esercizio ") << pr; return f.error_box(e); } } else { if (m.is_running()) return f.error_box(FR("%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; const TDate dr(f.mask().get(F_DATAREG)); // Data operazione const TDate d74(f.get()); // Data 74/ter if (d74 > dr) return TRUE; if (d74.year() < dr.year()-1) return error_box(FR("La data 74/ter non puo' essere antecedente all'anno %d"), dr.year()-1); const TLibro_giornale g(d74.year()); if (!g.ok()) return error_box(TR("La data 74/ter non appartiene ad un esercizio valido")); if (d74 < g.last_print()) { const char* lp = g.last_print().string(); return f.error_box(FR("La data 74/ter e' antecedente al %s,\n" "data di stampa del libro giornale del %d"), lp, g.year()); } return TRUE; } bool TPrimanota_application::numdoc_handler(TMask_field& f, KEY key) { if (f.to_check(key, TRUE)) { TMask& m = f.mask(); if (key == K_TAB && m.insert_mode() && app().is_saldaconto()) { if (!f.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, f.get(), TRUE); } } } // Controllo documenti duplicati if (key == K_ENTER && !f.empty() && app().iva() == iva_acquisti) { TMask& m = f.mask(); const int annodoc = m.get_date(F_DATADOC).year(); const long fornitore = m.get_long(F_FORNITORE); if (annodoc > 0 && fornitore > 0) { // SELECT NUMREG,DATAREG,DATADOC,NUMDOC FROM MOV // WHERE TIPO='F' AND CODCF=F_FORNITORE AND // NUMDOC=F_NUMDOC AND DATAREG>=F_DATADOC AND NUMREG<>F_NUMREG TString filter; filter << MOV_NUMDOC << "=\"" << f.get() << '"'; if (m.edit_mode()) { filter.insert("("); filter << ")&&(" << MOV_NUMREG << "!=\"" << m.get(F_NUMREG) << "\")"; } TRelation rel(LF_MOV); TRectype& rec = rel.curr(); TRectype recfrom(rec); recfrom.put(MOV_TIPO, "F"); recfrom.put(MOV_CODCF, fornitore); recfrom.put(MOV_DATAREG, TDate(1, 1, annodoc)); TRectype recto(recfrom); recto.put(MOV_DATAREG, TDate(31, 12, annodoc+1)); TCursor cur(&rel, filter, 3, &recfrom, &recto); const TRecnotype items = cur.items(); cur.freeze(); for (cur = 0; cur.pos() < items; ++cur) { const int ad = rec.get_date(MOV_DATADOC).year(); if (ad == annodoc) return yesno_box("Il documento %d / %s e' gia' stato inserito con la registrazione %ld\nSi desidera continuare ugualmente?", annodoc, (const char*)f.get(), rec.get_long(MOV_NUMREG)); } } } 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)); TString descr; if (riga_totale >= 0) descr = cgs().row(riga_totale).get(8); if (descr.blank()) descr = m.get(F_DESCR); set_cgs_row(riga_totale, real2imp(tot, 'T'), nuovo, 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(); const TPartita* game = p.first(); if (game != NULL && atol(f.get()) != game->conto().codclifo()) { const bool del = f.yesno_box(TR("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)); if (a._conto_ricavo.find()) { if (a._conto_ricavo.sospeso()) { f.error_box(TR("Il conto di ricavo e' sospeso")); a._conto_ricavo.set(0,0,0); } } const int alleg = clifo.get_int(CLI_ALLEG); TEdit_field& upi = m.efield(F_RIEPILOGO); upi.check_type(alleg == 3 ? CHECK_REQUIRED : CHECK_NORMAL); TEdit_field& cp = m.efield(F_CODPAG); if ((f.focusdirty() && m.is_running()) || (cp.empty() && !m.is_running())) { const TString& oldpag = cp.get(); const TString& s = clifo.get(CLI_CODPAG); if (s != oldpag) { 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 (cf == 'F' && app().causale().valintra()) { const TString16 valintra(clifo.get("VALINTRA")); if (!valintra.empty()) m.set(F_VALUTAINTRA, valintra, TRUE); } } 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()) { const TRectype& clifov = cliforel.curr(LF_CFVEN); 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); } if (clifov.get(CFV_CODCABPR).not_empty()) { m.set(FS_NSABI, clifov.get(CFV_CODABIPR)); m.set(FS_NSCAB, clifov.get(CFV_CODCABPR)); m.send_key(K_TAB, FS_NSCAB); } const TString& agente = clifov.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 if (!occas) m.set(F_STATOPAIV, clifo.get(CLI_STATOPAIV)); 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(TR("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.empty()) { if (!suspended_handler(f, key)) return FALSE; TPrimanota_application& a = app(); const real imp(a.ivas().row(1).get(0)); if (imp.is_zero()) // Se il totale documento non e' stato spezzato { 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 const int det = iva.detraibilita(); if (det > 0) row.add(det, 2); TBill bill; // Aggiorna conto della prima riga IVA a.IVA2bill(iva, bill); bill.add_to(row, 4, 0x7); if (bill.tipo() <= ' ' && bill.sottoconto() > 0) { TString80 cms, fas; if (bill.default_cdc(cms, fas)) { row.add(cms, 10); // Cdc/commessa su riga IVA row.add(fas, 11); // Fase } } } 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, SK_CONTROEURO); 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, SK_CONTROEURO); 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; if (m.id2pos(SK_CONTROEURO) >= 0) m.reset(SK_CONTROEURO); exchange_type dummy_contro_euro; const real& fc = TCurrency::get_firm_change(dummy_contro_euro); if (fc > ZERO) new_cambio *= fc; new_cambio.round(6); 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 TCurrency totale(real(f.get())); if (totale.get_num().is_zero()) ok = yesno_box(TR("Totale documento nullo: continuare ugualmente?")); if (ok) { const TValuta cambio(m, SK_VALUTA, SK_DATACAMBIO, SK_CAMBIO, SK_CONTROEURO); if (cambio.in_valuta()) { const real totval(m.get(SK_TOTDOCVAL)); const TCurrency totlit(cambio.val2lit(totval)); if (totale != totlit) ok = f.yesno_box(FR("Il totale documento dovrebbe essere %s: continuare ugualmente?"), totlit.string(TRUE)); } } } 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(FR("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; } HIDDEN void inventa_cambio_intra(TMask& m) { const TString& codval = m.get(F_VALUTAINTRA); if (codval.not_empty() && TCurrency::get_firm_val() != codval) { TTable cam("CAM"); cam.put("CODTAB", codval); const int err = cam.read(_isgteq); bool yes = err != NOERR; if (!yes) { TString16 v = cam.get("CODTAB"); v.cut(3).rtrim(); yes = v != codval; } if (yes) m.set(F_CAMBIOINTRA, cache().get("%VAL", codval, "S4")); } } // Handler of F_CORRLIRE // Certified 99% bool TPrimanota_application::corrlire_handler(TMask_field& f, KEY key) { TMask& m = f.mask(); TMask_field& cv = m.field(F_CORRVALUTA); if (key == K_ENTER && f.get().empty()) { if (!cv.empty()) { cv.set_focusdirty(); cv.on_hit(); } else key = K_F8; } if (key == K_F8) { f.set(m.get(F_IMPONIBILI)); f.set_dirty(); cv.set(""); key = K_TAB; } if (key == K_TAB && f.focusdirty()) { if (cv.empty()) { if (m.field(F_CAMBIOINTRA).empty()) inventa_cambio_intra(m); const TExchange cambio(m.get(F_VALUTAINTRA), m.get_real(F_CAMBIOINTRA)); TCurrency imp(real(f.get())); imp.change_value(cambio); cv.set(imp.get_num().string()); } } if (key == K_ENTER) { const real im(m.get(F_IMPONIBILI)); const real cl(f.get()); if (im != cl) { const TRectype& rec = cache().get("%VAL", TCurrency::get_firm_val()); const char* name = (const char*)rec.get("S0"); warning_box(FR("Il corrispettivo in %s e' diverso dal totale degli imponibili"), name); } } return TRUE; } // Handler of F_CORRVALUTA // Certified 99% bool TPrimanota_application::corrvaluta_handler(TMask_field& f, KEY key) { TMask& m = f.mask(); TMask_field& cl = m.field(F_CORRISPETTIVO); if (key == K_TAB && f.focusdirty()) { if (cl.empty()) { if (m.field(F_CAMBIOINTRA).empty()) inventa_cambio_intra(m); const TExchange cambio(m.get(F_VALUTAINTRA), m.get_real(F_CAMBIOINTRA)); TCurrency imp(real(f.get()), cambio); imp.change_to_firm_val(); cl.set(imp.get_num().string()); } } else { if (key == K_ENTER && f.get().empty()) { 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) { if (m.id2pos(F_SOLAIVA) >= 0) // Maschera moviventi IVA { 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(TR("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, TR("Generazione righe contabilita'"), FALSE, TRUE); 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; }