// ve6100.cpp: programma di contabilizzazione documenti // Orgiastica visione... // L'anatra del dubbio dalle labbra di Vermouth. //****************************************************************************** // \\\\\\\\ e * // b \\\\\\\\ b * // \\\\\\\\ e r d l * // \\\\\\\\ * // \\\\\\\\ i V o e h * // L \\\\\\\\ * // \\\\\\\\ b d * // o \\\\\\\\ m a * // +++++++++++++++++++++++++ b t * // ++++++++++++++++++++++++++--------------------------------------------------| // ++++++++++++++++++++++++++--------------------------------------------------| // ++++++++++++++++++++++++ |---------------------------------------| // u //////// u |---------------------------------------| // ' //////// a | /\ /\ | // //////// i | r / \ r / \ | // a //////// \|/ / \ / \ l | // ////////-----------------*---\ a / t \ / a \ /| // //////// /|\ \ / \ / \ / | // d //////// n | \ / \ / \ / | // //////// l d | \/ a \/ l \/ | //-----------------------------------------------------------------------------| // // Scared uh? #include #include #include #include #include #include #include #include #include "../cg/cg2101.h" #include "../cg/cglib.h" #include "../cg/saldacon.h" #include "velib02.h" #include "ve6100a.h" #include #include #include #include #include #include #include enum error_type { no_error, elaboration_error, nr_es_error, nr_reg_error, nr_doc_error, chg_stat_error, clifo_error, ultprot_error, datadoc_error, caus_error, register_error, change_error, val_error, codpag_error, row_type_error, no_rows_error, conto_error, movement_error, mov_write_error, generic_error }; // TMovimentoPN_VE // Classe derivata da TMovimentoPN per calcolare automaticamente le righe contabili // una volta settate le righe iva e la riga di totale documento // Sostanzialmente di tratta di aggiungere un metodo in piu' : // recalc_cg_rows(), liberamente ispirato alla notify_iva() in cg2102.cpp class TMovimentoPN_VE : public TMovimentoPN { TCausale * _caus; protected: // simula il K_SPACE di iva_notify void create_row(int i); // simula il K_ENTER di iva_notify void enter_row(int i); // verifica se si tratta di iva indetraibile bool detraibile(TRectype& rec) const ; // cerca la prima tra quelle di contabilita' che corrisponde al tipo indicato int type2pos(char tipo); // Trova nelle righe contabili un conto nelle righe di tipo prescelto int bill2pos(const TBill& conto, char tipo); // trasforma un real in TImporto, in base al tipo riga TImporto real2imp(const real& r, char row_type); // setta il record delle righe di contabilita' int set_cg_rec(int n, const TImporto& imp, TBill& conto, const char* desc, char tipo); // aggiunge l'importo indicato alla n-esima riga di contabilita' bool add_cg_rec(int n, const TImporto& imp); // Legge l'importo della riga n e lo ritorna col segno dovuto TImporto get_cg_imp(int n); // Setta l'importo della riga n void set_cg_imp(int n, const TImporto& imp); public: // verifica se il movimento e' quadrato oppure ha qualche maledetto sbilancio // ritorna TRUE, ovviamente, se everything's alright. bool movement_ok() ; // ricalcola le righe di contabilita' dalle righe iva presenti // e verifica la quadratura del movimento. Ritorna TRUE se il movimento e' scrivibile bool recalc_cg_rows(TCausale* caus = NULL); TMovimentoPN_VE() {}; virtual ~TMovimentoPN_VE() {} }; TImporto TMovimentoPN_VE::real2imp(const real& r, char row_type) { CHECK(_caus,"Orgggssbb..._caus pointer is NULL!"); bool dare; if (row_type == 'S') { dare = _caus->sezione_ritsoc() == 'D'; } else { dare = _caus->sezione_clifo() == 'D'; if (row_type != 'T' && row_type != 'F') dare = !dare; } TImporto importo(dare ? 'D' : 'A', r); return importo; } bool TMovimentoPN_VE::detraibile(TRectype& rec) const { CHECK(_caus,"Orgggssbb..._caus pointer is NULL!"); if (_caus->iva() == iva_vendite) return TRUE; if (rec.get_int(RMI_TIPODET) != 0) return FALSE; const real & p = _caus->reg().prorata(); return p < 100.0; } int TMovimentoPN_VE::bill2pos(const TBill& conto, char tipo) { const int items = cg_items(); for (int i = 0; i < items; i++) { TRectype& s = cg(i); const char t = s.get_char(RMV_ROWTYPE); if (t == tipo) { TBill c; const int gr = s.get_int(RMV_GRUPPO); const int co = s.get_int(RMV_CONTO); const long so = s.get_long(RMV_SOTTOCONTO); c.set(gr,co,so); if (c == conto) return i; } } return -1; } int TMovimentoPN_VE::type2pos(char tipo) { const int items = cg_items(); for (int i = 0; i < items; i++) { TRectype& s = cg(i); const char t = s.get_char(RMV_ROWTYPE); if (t == tipo) return i; } return -1; } void TMovimentoPN_VE::set_cg_imp(int n, const TImporto& imp) { TRectype& rec = cg(n); rec.put(RMV_SEZIONE,imp.sezione()); rec.put(RMV_IMPORTO,imp.valore()); } TImporto TMovimentoPN_VE::get_cg_imp(int n) { TRectype& rec = cg(n); TImporto importo; const char sez = rec.get_char(RMV_SEZIONE); const real valore(rec.get_real(RMV_IMPORTO)); importo.set(sez,valore); return importo; } bool TMovimentoPN_VE::add_cg_rec(int n, const TImporto& imp) { TImporto tot(get_cg_imp(n)); tot += imp; tot.normalize(); set_cg_imp(n, tot); return tot.is_zero(); } int TMovimentoPN_VE::set_cg_rec(int n, const TImporto& imp, TBill& conto, const char* desc, char tipo) { const bool insert = n < 0; if (insert) n = cg_items(); // Questa e' la prima riga di contabilita' vuota e disponibile TRectype& rec = cg(n); if (insert) { TRectype& head = lfile().curr(); const int annoes = head.get_int(MOV_ANNOES); const long numreg = head.get_long(MOV_NUMREG); TDate datareg(head.get_date(MOV_DATAREG)); rec.put(RMV_ANNOES,annoes); rec.put(RMV_NUMREG,numreg); rec.put(RMV_DATAREG,datareg); } rec.put(RMV_SEZIONE,imp.sezione()); rec.put(RMV_IMPORTO,imp.valore()); rec.put(RMV_TIPOC,conto.tipo()); rec.put(RMV_GRUPPO,conto.gruppo()); rec.put(RMV_CONTO,conto.conto()); rec.put(RMV_SOTTOCONTO,conto.sottoconto()); //rec.put(RMV_DESCR,conto.descrizione()); if (tipo == 'T') // Calcolo contropartita { TRectype& irec = iva(0); const char t = irec.get_char(RMI_TIPOC); const int gr = irec.get_int(RMI_GRUPPO); const int co = irec.get_int(RMI_CONTO); const long so = irec.get_long(RMI_SOTTOCONTO); rec.put(RMV_TIPOCC,t); rec.put(RMV_GRUPPOC,gr); rec.put(RMV_CONTOC,co); rec.put(RMV_SOTTOCONTOC,so); } else { const int pos = type2pos('T'); if (pos >= 0) { TRectype& crec = cg(pos); const char t = crec.get_char(RMV_TIPOC); const int gr = crec.get_int(RMV_GRUPPO); const int co = crec.get_int(RMV_CONTO); const long so = crec.get_long(RMV_SOTTOCONTO); rec.put(RMV_TIPOCC,t); rec.put(RMV_GRUPPOC,gr); rec.put(RMV_CONTOC,co); rec.put(RMV_SOTTOCONTOC,so); } } rec.put(RMV_ROWTYPE,tipo); return n; } void TMovimentoPN_VE::create_row(int i) { CHECK(_caus,"Orgggssbb..._caus pointer is NULL!"); TRectype& cur = iva(i); real oldimp = cur.get_real(RMI_IMPONIBILE); real oldiva = cur.get_real(RMI_IMPOSTA); if (oldiva.is_zero() && _caus->corrispettivi()) // In caso di corrispettivi ... { const TString zanicchi(cur.get(RMI_CODIVA)); // Codice IVA const TCodiceIVA i(zanicchi); oldiva = i.scorpora(oldimp); // ... scorpora imposta dall'imponibile } const char tipod = detraibile(cur) ? 'D' : 'N'; if (type2pos(tipod) < 0 && !oldiva.is_zero()) { const int ri = tipod == 'D' ? 3 : 4; // Calcola riga causale per l'IVA TBill c; _caus->bill(ri, c); if (c.ok()) { const TString80 d(_caus->desc_agg(ri)); set_cg_rec(-1, 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; const int gr = cur.get_int(RMI_GRUPPO); const int co = cur.get_int(RMI_CONTO); const long so = cur.get_long(RMI_SOTTOCONTO); oldconto.set(gr,co,so); if (oldconto.ok()) { if (bill2pos(oldconto, 'I') < 0) { const TString d(_caus->desc_agg(2)); set_cg_rec(-1, real2imp(ZERO, 'I'), oldconto, d, 'I'); } } } void TMovimentoPN_VE::enter_row(int i) { CHECK(_caus,"Orgggssbb..._caus pointer is NULL!"); TRectype& cur = iva(i); real imponibile = cur.get_real(RMI_IMPONIBILE); real imposta = cur.get_real(RMI_IMPOSTA); if (imposta.is_zero() && _caus->corrispettivi()) // In caso di corrispettivi ... { const TString zanicchi(cur.get(RMI_CODIVA)); const TCodiceIVA i(zanicchi); imposta = i.scorpora(imponibile); // ... scorpora imposta dall'imponibile } TBill conto; const char t = cur.get_char(RMI_TIPOC); const int gr = cur.get_int(RMI_GRUPPO); const int co = cur.get_int(RMI_CONTO); const long so = cur.get_long(RMI_SOTTOCONTO); conto.set(gr,co,so,t); int newpos = bill2pos(conto, 'I'); // Riga in cui andra' l'imponibile const bool detrarre = detraibile(cur); // Determina se IVA detraibile // Calcola riga causale col conto opportuno const int ri = detrarre ? RIGA_IVA_DETRAIBILE : RIGA_IVA_NON_DETRAIBILE; TBill contoiva; _caus->bill(ri, contoiva); if (ri == 4 && !contoiva.ok()) // Se non c'e' il conto IVA indetraibile ... { // ... somma imponibile e imposta imponibile += imposta; imposta = 0.0; } // Aggiorna conto sulla riga contabile if (newpos < 0) // conto non esistente: da inserire { const TImporto val(real2imp(imponibile, 'I')); if (conto.ok() && !val.is_zero()) // Se c'e' imponibile ... { // crea una nuova riga contabile const TString d(_caus->desc_agg(2)); set_cg_rec(-1, val, conto, d, 'I'); } } else { TImporto val(real2imp(imponibile, 'I')); add_cg_rec(newpos, val); } // Aggiorna conto IVA sulla riga contabile const char tipod = detrarre ? 'D' : 'N'; int newposiva = type2pos(tipod); if (newposiva < 0) { if (!imposta.is_zero()) // Se c'e' imposta ... { // ... crea nuova riga per l'IVA const TImporto val(real2imp(imposta, 'I')); const TString d(_caus->desc_agg(ri)); set_cg_rec(-1, val, contoiva, d, tipod); } } else { const TImporto val(real2imp(imposta, 'I')); add_cg_rec(newposiva, val); } } bool TMovimentoPN_VE::movement_ok() { TImporto tot_imp; TImporto imp; const int max = cg_items(); for (int i = 0; i < max; i++) { TRectype& r = cg(i); const char sez = r.get_char(RMV_SEZIONE); const real val(r.get_real(RMV_IMPORTO)); imp.set(sez,val); tot_imp+=imp; } if (!tot_imp.is_zero()) return FALSE; return TRUE; } bool TMovimentoPN_VE::recalc_cg_rows(TCausale* caus) { const int righe = iva_items(); bool external_caus = TRUE; if (caus == NULL) { external_caus = FALSE; TRectype& head = lfile().curr(); TString16 codcau(head.get(MOV_CODCAUS)); int year = head.get_int(MOV_ANNOIVA); _caus = new TCausale (codcau,year); } else _caus = caus; for (int i=0; i 15) { f.error_box("L'intervallo tra le date non puo' eccedere i 15 giorni."); return FALSE; } } return TRUE; } bool TContabilizzazione_app::handle_data_reg(TMask_field& f, KEY k) { if (k==K_ENTER && f.dirty()) { TMask& m = f.mask(); TDate data_reg(f.get()); if (data_reg == botime) return TRUE; TDate da(m.get_date(F_DATA_INI)); //if (!da.ok()) return TRUE; if ((data_reg - da) > 15) { f.error_box("L'intervallo tra la data di registrazione e la data di inizio non puo' eccedere i 15 giorni."); return FALSE; } if (data_reg < da) { f.error_box("La data di registrazione non puo' essere minore della data di inizio."); return FALSE; } } return TRUE; } bool TContabilizzazione_app::handle_cod_eld(TMask_field& f, KEY k) { if (f.to_check(k) && k == K_TAB) // se e' cambiato ricostruisce anche lo sheet dei codici numerazione { app()._cod_el = f.get(); // aggiorna il codice elaborazione per la build_num_sheet() f.mask().disable(DLG_OK); app().build_num_sheet(); } return TRUE; } bool TContabilizzazione_app::handle_select(TMask_field& f, KEY k) { if (k == K_SPACE) { TMask& m = f.mask(); TArray_sheet* s = app().get_num_sheet(); if (s->run()) { if (s->checked() != 0) // Hai selezionato qualcosa ? m.enable(DLG_OK); // allora abilita il pulsante di conferma else m.disable(DLG_OK); } } return TRUE; } void TContabilizzazione_app::build_num_sheet() { _num_sheet->destroy(); TTable eld("%ELD"); TTable num("%NUM"); TString s1,s2,s3; TString16 tipon1,tipon2,tipon3,tipon4,tipon5; // tipi documento validi per la numerazione long pos; eld.put("CODTAB",_cod_el); if (eld.read() == NOERR) { TToken_string t; s1.format("%-20s",(const char*)eld.get("S2")); s3 = eld.get("S7"); _final_doc_status = eld.get("S4")[0]; for (int i=0;i<5;i++) { t = s1.mid(i*4,4); // Tipo documento if (t.trim().empty()) break; t.add(s3.mid(i,1)); // Stato iniziale _tipi_doc.add(t); // Aggiunge questo tipo documento alla lista } for (pos=0,num.first();num.good();num.next(),pos++) // scorre tutte le numerazioni possibili { TToken_string t; t.add(" "); t.add(num.get("CODTAB")); t.add(num.get("S0")); _num_sheet->add(t); s2 = num.get("S2"); // reperisce i tipi documento validi per questa numerazione tipon1 = s2.mid(0,4); tipon2 = s2.mid(4,4); tipon3 = s2.mid(8,4); tipon4 = s2.mid(12,4); tipon5 = s2.mid(16,4); const int n1 = s1.find(tipon1); const int n2 = s1.find(tipon2); const int n3 = s1.find(tipon3); const int n4 = s1.find(tipon4); const int n5 = s1.find(tipon5); if ((tipon1.empty() || n1<0) && (tipon2.empty() || n2<0) && (tipon3.empty() || n3<0) && (tipon4.empty() || n4<0) && (tipon5.empty() || n5<0)) _num_sheet->disable_row(pos); else _num_sheet->enable_row(pos); } } } void TContabilizzazione_app::on_config_change() { TPartita::carica_allineamento(); } bool TContabilizzazione_app::create() { TApplication::create(); if (!has_module(CGAUT)) { error_box("Impossibile eseguire il programma se il modulo Contabilita' Generale non e' abilitato"); return FALSE; } _error = no_error; _can_write = TRUE; _caus = NULL; _pagamento = NULL; _movimento = NULL; _msk = new TMask("ve6100a"); _msk->set_handler(F_CODICE_ELAB,handle_cod_eld); _msk->set_handler(F_DATA_INI,handle_data_range); _msk->set_handler(F_DATA_FIN,handle_data_range); _msk->set_handler(F_DATA_REG,handle_data_reg); _msk->set_handler(DLG_USER,handle_select); _num_sheet = new TArray_sheet(-1,-1,-4,-4,"Codici numerazione", "@1|Cod. numerazione|Descrizione@50"); _docfile = new TLocalisamfile(LF_DOC); _rdocfile = new TLocalisamfile(LF_RIGHEDOC); _doc = new TDocumento; _cpg = new TTable("%CPG"); _tri = new TTable("%TRI"); _val = new TTable("%VAL"); _prs = new TTable("PRS"); _spp = new TTable("SPP"); _caa = new TTable("CAA"); _cra = new TTable("CRA"); _gmc = new TTable("GMC"); _rfa = new TTable("RFA"); _cve = new TTable("CVE"); _cco = new TTable("CCO"); _clifo = new TRelation(LF_CLIFO); _clifo->add(LF_CFVEN,"TIPOCF=TIPOCF|CODCF=CODCF"); _fcaus = new TLocalisamfile(LF_CAUSALI); _frcaus = new TLocalisamfile(LF_RCAUSALI); _part = new TLocalisamfile(LF_PARTITE); _scad = new TLocalisamfile(LF_SCADENZE); _pags = new TLocalisamfile(LF_PAGSCA); _attiv = new TLocalisamfile(LF_ATTIV); // Altrimenti TRegistro non va! _anamag = new TLocalisamfile(LF_ANAMAG); TConfig conf(CONFIG_DITTA); _search_seq = conf.get("RICERCACR","ve"); // costruisce la stringa che controlla la ricerca del conto costo/ricavo // Attenzione! non esegue alcun controllo di consistenza sulla corretta sequenza // presuppone che il programma di configurazione abbia generato correttamente // il tutto. if (_search_seq.items() == 0) { error_box("Non e' abilitata alcuna ricerca per il conto di costo/ricavo in configurazione."); return FALSE; } _sc_enabled = conf.get_bool("GesSal","cg"); _nump_cfg = conf.get_bool("RifPro","cg"); int gr,co; long so; gr = conf.get_int("SCOPRCODCON","ve",1); co = conf.get_int("SCOPRCODCON","ve",2); so = conf.get_long("SCOPRCODCON","ve",3); _sco_perc_bill.set(gr,co,so); gr = conf.get_int("SCOIMCODCON","ve",1); co = conf.get_int("SCOIMCODCON","ve",2); so = conf.get_long("SCOIMCODCON","ve",3); _sco_imp_bill.set(gr,co,so); gr = conf.get_int("SPINCODCONA","ve",1); co = conf.get_int("SPINCODCONA","ve",2); so = conf.get_long("SPINCODCONA","ve",3); _spin_billa.set(gr,co,so); gr = conf.get_int("SPINCODCONV","ve",1); co = conf.get_int("SPINCODCONV","ve",2); so = conf.get_long("SPINCODCONV","ve",3); _spin_billv.set(gr,co,so); gr = conf.get_int("SPBOCODCONA","ve",1); co = conf.get_int("SPBOCODCONA","ve",2); so = conf.get_long("SPBOCODCONA","ve",3); _spbo_billa.set(gr,co,so); gr = conf.get_int("SPBOCODCONV","ve",1); co = conf.get_int("SPBOCODCONV","ve",2); so = conf.get_long("SPBOCODCONV","ve",3); _spbo_billv.set(gr,co,so); _spin_cod = conf.get("SPINCODIVA","ve"); _spbo_cod = conf.get("SPBOCODIVA","ve"); dispatch_e_menu(BAR_ITEM(1)); return TRUE; } bool TContabilizzazione_app::destroy() { if (_msk) delete _msk; if (_num_sheet) delete _num_sheet; if (_docfile) delete _docfile; if (_rdocfile) delete _rdocfile; if (_doc) delete _doc; if (_cpg) delete _cpg; if (_tri) delete _tri; if (_val) delete _val; if (_gmc) delete _gmc; if (_rfa) delete _rfa; if (_cve) delete _cve; if (_cco) delete _cco; if (_prs) delete _prs; if (_spp) delete _spp; if (_caa) delete _caa; if (_cra) delete _cra; if (_fcaus) delete _fcaus; if (_frcaus) delete _frcaus; if (_part) delete _part; if (_scad) delete _scad; if (_pags) delete _pags; if (_clifo) delete _clifo; if (_attiv) delete _attiv; if (_anamag) delete _anamag; return TApplication::destroy(); } bool TContabilizzazione_app::menu(MENU_TAG mt) { while (_msk->run() == K_ENTER) { _cod_el = _msk->get(F_CODICE_ELAB); _data_ini = _msk->get_date(F_DATA_INI); _data_fine = _msk->get_date(F_DATA_FIN); _data_reg = _msk->get_date(F_DATA_REG); _auto_data = _msk->get_bool(F_DATA_AUTO); //_data_fine++; contabilize(); } return FALSE; } error_type TContabilizzazione_app::search_costo_ricavo(TBill& conto, const TRiga_documento& r) { const int items = _search_seq.items(); TLocalisamfile & cli_file = _clifo->lfile(); // YES, arriva qui dentro quando la relazione e' gia' posizionata const bool is_cli = cli_file.get(CLI_TIPOCF) == "C"; bool skip_art_related = FALSE; bool skip_clifo = _clifo->bad(); TCodiceIVA codiva(r.get("CODIVA")); const char t = r.tipo().tipo(); int gr,co; long so; switch (t) { case 'O': // righe omaggio come articoli spiaccicato identico (avranno imponibile 0) case 'M': // righe di merce { // posiziona l'anagrafica sull'articolo specificato sulla ..iga _anamag->put("CODART",r.get("CODART")); if (_anamag->read() != NOERR) // se non trova l'articolo saltera' anche gmc,smc,rfa. skip_art_related = TRUE; // Scorre la stringa di ricerca for (int i=0;good() && iIVA2bill(codiva,conto)) break; // se lo trova esce } else if (tok == "AR") { if (skip_art_related) continue; gr = _anamag->get_int(is_cli ? "GRUPPOV" : "GRUPPOA"); co = _anamag->get_int(is_cli ? "CONTOV" : "CONTOA"); so = _anamag->get_long(is_cli ? "SOTTOCV" : "SOTTOCA"); conto.set(gr,co,so); if (!conto.ok()) // se il conto non c'e' guarda la categoria acquisti/vendite { TTable *t = is_cli ? _cra : _caa; t->put("CODTAB",_anamag->get(is_cli ? "CATCONV" : "CATCONA")); if (t->read() == NOERR) { gr = atoi(t->get("S1")); co = atoi(t->get("S2")); so = atol(t->get("S3")); conto.set(gr,co,so); } } if (conto.ok()) break; } else if (tok == "GM" || tok == "SM" || tok == "RF") { if (skip_art_related) continue; const bool is_fis = tok == "RF"; TTable * tab = is_fis ? _rfa : _gmc; TString codtab(_anamag->get(is_fis ? "GRMERC" : "RAGGFIS")); if (tok == "GM") codtab.cut(2); // gli ultimi 2 si riferiscono al sottogruppo. tab->put("CODTAB",codtab); if (tab->read() == NOERR) { gr = tab->get_int(is_cli ? "I3" : "I0"); co = tab->get_int(is_cli ? "I4" : "I1"); so = tab->get_long(is_cli ? "I5" : "I2"); conto.set(gr,co,so); } if (conto.ok()) break; } else if (tok == "CV" || tok == "CC") { const bool is_cve = tok == "CV"; if (is_cve && !is_cli) continue; // se e' un fornitore salta questa condizione TTable* t = is_cve ? _cve : _cco; TString cod(is_cve ? _doc->get("CATVEN") : ""); if (cod.empty()) { if (skip_clifo) continue; // se non aveva trovato il cliente salta al prossimo cod = _clifo->lfile(LF_CFVEN).get(is_cve ? CFV_CATVEN : CFV_CODCATC); } t->put("CODTAB",cod); if (t->read() == NOERR) { const bool x =(is_cve || is_cli); gr = t->get_int(x ? "I3" : "I0"); co = t->get_int(x ? "I4" : "I1"); so = t->get_long(x ? "I5": "I2"); conto.set(gr,co,so); } if (conto.ok()) break; } } break; // case 'M' } case 'P': // righe prestazione case 'S': // righe spese { TTable* tab = t == 'P' ? _prs : _spp; tab->put("CODTAB",r.get("CODART")); if (tab->read()==NOERR) { gr = tab->get_int(is_cli ? "I0" : "I3"); co = tab->get_int(is_cli ? "I1" : "I4"); so = tab->get_long(is_cli ? "I2" : "I5"); conto.set(gr,co,so); } break; // case 'P','S' } case 'C': // righe sconti (TBI) (reperire l'imposta e l'imponibile normalizzare. Il conto e' nei parametri) // quale sconto deve reperire dalla configurazione? Sconto ad importo o sconto a percentuale? if (!r.get("SCONTO").empty()) // se c'e' la percentuale reperisce il conto dello sconto a percentuale conto = _sco_perc_bill; else // altrimenti quello dello sconto ad importo conto = _sco_imp_bill; break; // case 'C' case 'D': // righe descrizioni (saltare) default : break; } // end of switch if (good() && !conto.find()) _error = conto_error; return _error; } bool TContabilizzazione_app::doc_tipo_stato_ok() // Verifica che il tipo documento corrente esista tra i tipi previsti dalla elaborazione // differita selezionata { const int items = _tipi_doc.items(); bool found = FALSE; const TString16 tipo(_doc->tipo().codice()); const char stato = _doc->stato(); for (int i=0;isaldaconto(); return rt; } error_type TContabilizzazione_app::compile_head_mov() // Compila la testata { TEsercizi_contabili esc; TLocalisamfile& mov = _movimento->lfile(); TRectype& mov_rec = mov.curr(); // Reperisce la data documento TDate datadoc(_doc->data()); if (!datadoc.ok()) { _error = datadoc_error; return _error; } // reperisce la data di registrazione, che e' anche la data di competenza ed // eventualmente la data74ter se nel registro della causale vi e' scritta l'informazione // sulle agenzie di viaggio. // se si e' specificata la data automatica prende invece la data del documento TDate data_reg(_auto_data ? datadoc : _data_reg); esc.update(); // reperisce il codice anno esercizio, int cod_es = esc.date2esc(data_reg); if (cod_es <= 0) { _error = nr_es_error; return _error; } // reperisce l'ultimo numero di registrazione disponibile mov.last(); const long numreg = mov.get_int(MOV_NUMREG) + 1; if (mov.status() != NOERR || numreg < 1) { _error = nr_reg_error; return _error; } TCodice_numerazione cod_num(_doc->numerazione()); // calcola il numero documento aggiungendo l'eventuale prefisso/postfisso. TString numdoc(cod_num.complete_num(_doc->numero())); if (numdoc.empty() || cod_num.status() != NOERR) { _error = nr_doc_error; return _error; } numdoc.upper(); // Il numero documento e' uppercase! // Istanzia la causale del documento corrente... const TTipo_documento& tipo = _doc->tipo(); const TString codcaus(tipo.causale()); _caus = new TCausale(codcaus,data_reg.year()); if (!_caus->ok()) { _error = caus_error; return _error; } // per reperire il tipo documento ed il tipo movimento // reperisce la descrizione dal tipo documento e la completa con la data documento ed il // numero documento TString descr(tipo.riferimento()); if (descr.empty()) descr = tipo.descrizione(); descr << " n. " << _doc->numero(); descr << " del " << datadoc.string(); // Codice registro IVA TRegistro& registro = _caus->reg(); if (!registro.ok()) { _error = register_error; return _error; } // Reperisce l'ultimo numero di protocollo long ult_prot = registro.protocol() +1; if (ult_prot < 1) { _error = ultprot_error; return _error; } // Reperisce la valuta TDate datacam(_doc->get_date("DATACAMBIO")); TString codval(_doc->valuta()); real cambio(_doc->cambio()); codval.trim(); if (codval == "LIT") { codval = ""; cambio = ZERO; } if (codval.not_empty()) { _val->put("CODTAB",codval); if (_val->read() != NOERR) { _error = val_error; return _error; } } // Reperisce il cambio if ((cambio != ZERO && codval.empty()) || cambio == ZERO && codval.not_empty()) { _error = change_error; return _error; } // Dati del cliente... TString tipocf(_doc->get("TIPOCF")); long codcf = _doc->get_long("CODCF"); TString occas; { TLocalisamfile& cli_file = _clifo->lfile(); cli_file.put(CLI_TIPOCF,tipocf); cli_file.put(CLI_CODCF,codcf); if (_clifo->read(_isequal) == NOERR) // posiziona il cliente una volta per tutte { if (cli_file.get_bool(CLI_OCCAS)) { occas = _doc->get("OCFPI"); TLocalisamfile ocf(LF_OCCAS); ocf.put(OCC_CFPI,occas); if (ocf.read() != NOERR) { _error = clifo_error; return _error; } } } else { _error = clifo_error; return _error; } } // Codice pagamento TString codpag(_doc->get("CODPAG")); { _cpg->put("CODTAB",codpag); if (_cpg->read() != NOERR) { _error = codpag_error; return _error; } } // Mo' riempie il record della incornata (testata) mov_rec.zero(); mov_rec.put(MOV_ANNOES,cod_es); mov_rec.put(MOV_NUMREG,numreg); mov_rec.put(MOV_DATAREG,data_reg); mov_rec.put(MOV_DATACOMP,data_reg); mov_rec.put(MOV_DATADOC,datadoc); if (registro.agenzia_viaggi()) mov_rec.put(MOV_DATA74TER,data_reg); mov_rec.put(MOV_NUMDOC,numdoc); mov_rec.put(MOV_TIPODOC,_caus->tipo_doc()); mov_rec.put(MOV_CODCAUS,_caus->codice()); mov_rec.put(MOV_DESCR,descr); mov_rec.put(MOV_TIPOMOV,char(_caus->tipomov()+'0')); mov_rec.put(MOV_ANNOIVA,data_reg.year()); mov_rec.put(MOV_REG,registro.name()); mov_rec.put(MOV_PROTIVA,ult_prot); mov_rec.put(MOV_CODVAL,codval); mov_rec.put(MOV_CAMBIO,cambio); mov_rec.put(MOV_TIPO,tipocf); mov_rec.put(MOV_DATACAM,datacam); mov_rec.put(MOV_CODCF,codcf); mov_rec.put(MOV_OCFPI,occas); mov_rec.put(MOV_CODPAG,codpag); if (_caus->intra()) { mov_rec.put(MOV_CODVALI,codval);mov_rec.put(MOV_CAMBIOI,cambio); real corrval(_doc->imponibile()); real corrlire = corrval*cambio; if (codval.not_empty() && codval != "LIT") { mov_rec.put(MOV_CORRLIRE,corrlire); mov_rec.put(MOV_CORRVALUTA,corrval); } else mov_rec.put(MOV_CORRLIRE,corrval); } real totdocval(_doc->totale_doc()); real totdoclit = totdocval * cambio; if (codval.not_empty() && codval != "LIT") { mov_rec.put(MOV_TOTDOC,totdoclit); mov_rec.put(MOV_TOTDOCVAL,totdocval); } else mov_rec.put(MOV_TOTDOC,totdocval); return _error; } void TContabilizzazione_app::calculate_spese(real& spese, real& sp_iva, int ndec, bool is_incasso) { char tipo; int gr,co; long so; const bool is_cli = _doc->get("TIPOCF") == "C"; const TBill& zio = is_incasso ? (is_cli ? _spin_billv : _spin_billa) : (is_cli ? _spbo_billv : _spbo_billa); TIVA sp_cod(is_incasso ? _spin_cod : _spbo_cod); TIVA_element el_tmp; TString key; sp_iva = iva(spese,sp_cod,ndec); tipo = zio.tipo(); gr = zio.gruppo(); co = zio.conto(); so = zio.sottoconto(); key.format("5|%-4s|%c|%3d|%3d|%6ld",(const char*)sp_cod.codice(),tipo,gr,co,so); const bool exists = _righe_iva.is_key(key); TIVA_element& el = (exists ? (TIVA_element&)_righe_iva[key] : el_tmp); el.imp() = spese; el.iva() = sp_iva; el.ali() = sp_cod.aliquota(); _righe_iva.add(key,el,exists); } error_type TContabilizzazione_app::add_spese_inbo() // Aggiunge le righe di spese incasso/bolli { real tot_netto, sp_incasso, sp_bolli; real iva_sp_incasso, iva_sp_bolli; const int ndec = _doc->in_valuta() ? 3 : 0; // Aggiunge le spese d'incasso tot_netto = _doc->totale_netto(); sp_incasso = _doc->spese_incasso(tot_netto,ndec, TRUE); if (sp_incasso != 0.0) calculate_spese(sp_incasso,iva_sp_incasso,ndec,TRUE); // Aggiunge le spese bolli tot_netto += sp_incasso + iva_sp_incasso; sp_bolli = _doc->bolli(tot_netto,ndec, TRUE); if (sp_bolli != 0) calculate_spese(sp_bolli,iva_sp_bolli,ndec,FALSE); return _error; } error_type TContabilizzazione_app::add_iva_row(const TBill& conto, const TRiga_documento& r) // Aggiunge le righe iva all'assoc_array di raggruppamento { TIVA_element el_tmp; TString cod(r.iva().codice()); const char tipo = conto.tipo(); const int gr = conto.gruppo(); const int co = conto.conto(); const long so = conto.sottoconto(); TString key; const char tipo_r = r.tipo().tipo(); int ord=0; // Ordine con cui vengono immesse le righe IVA: // merce, omaggi, prestazioni, spese, bolli/spese d'incasso, sconti. switch (tipo_r) { case 'M': ord = 1; break; case 'O': ord = 2; break; case 'P': ord = 3; break; case 'S': ord = 4; break; case 'C': ord = 6; break; default: break; } key.format("%d|%-4s|%c|%3d|%3d|%6ld",ord,(const char*)cod,tipo,gr,co,so); const bool exists = _righe_iva.is_key(key); TIVA_element& el = (exists ? (TIVA_element&)_righe_iva[key] : el_tmp); el += r; _righe_iva.add(key,el,exists); return no_error; } error_type TContabilizzazione_app::create_iva_rows() { const int items = _righe_iva.items(); const bool in_valuta = _doc->in_valuta(); TRectype& head = _movimento->lfile().curr(); int gr,co; long so; char tipo; TToken_string key; TString_array key_arr; TString16 codiva; TBill conto; const int annoes = head.get_int(MOV_ANNOES); const long numreg = head.get_long(MOV_NUMREG); real cambio = head.get_real(MOV_CAMBIO); real imponibile,imposta; _righe_iva.get_keys(key_arr); key_arr.sort(); //TIVA_element* cur = (TIVA_element*)_righe_iva.first_item(); TIVA_element cur; for (int i = 0; ikey(); key = key_arr.row(i); cur = (TIVA_element&) _righe_iva[key]; codiva = key.get(1); tipo = key.get_char(2); gr = key.get_int(3); co = key.get_int(4); so = atol(key.get(5)); conto.set(gr,co,so,tipo); conto.find(); imponibile = cur.imp(); if (in_valuta) { imponibile = cur.imp() * cambio; // imponibile in lire imposta = (imponibile * cur.ali()) / 100.0; // questa e' l'imposta ricalcolata } else imposta = cur.iva(); // In contabilita' abbiamo 2 decimali... imponibile.ceil(2); imposta.ceil(2); TRectype& rec_iva = _movimento->iva(i); rec_iva.put(RMI_ANNOES,annoes); rec_iva.put(RMI_NUMREG,numreg); rec_iva.put(RMI_NUMRIG,i+1); // La numerazione comincia da 1 rec_iva.put(RMI_CODIVA,codiva); rec_iva.put(RMI_IMPONIBILE,imponibile); rec_iva.put(RMI_IMPOSTA,imposta); rec_iva.put(RMI_TIPOCR,conto.tipo_cr()); rec_iva.put(RMI_INTRA,_caus->intra()); rec_iva.put(RMI_TIPOC,conto.tipo()); rec_iva.put(RMI_GRUPPO,conto.gruppo()); rec_iva.put(RMI_CONTO,conto.conto()); rec_iva.put(RMI_SOTTOCONTO,conto.sottoconto()); //cur = (TIVA_element*)_righe_iva.succ_item(); } return _error; } error_type TContabilizzazione_app::create_total_doc_row() // Crea la riga contabile di totale documento { TRectype& rec_cg = _movimento->cg(0); TRectype& head = _movimento->lfile().curr(); const int annoes = head.get_int(MOV_ANNOES); const long numreg = head.get_long(MOV_NUMREG); TDate datareg(head.get_date(MOV_DATAREG)); real totdoc(head.get_real(MOV_TOTDOC)); char rowtype = 'T'; TLocalisamfile& cli_file = _clifo->lfile(); TString16 tipocf(cli_file.get(CLI_TIPOCF)); const long codcf = cli_file.get_long(CLI_CODCF); int gruppo = 0, conto = 0; // Trova il mastro del cliente/fornitore // cerca prima sul record del cliente/fornitore if (_clifo->good()) { gruppo = cli_file.get_int(CLI_GRUPPO); conto = cli_file.get_int(CLI_CONTO); } // poi sulla categoria di vendita (solo per i clienti) if ((gruppo == 0 || conto == 0) && tipocf == "C") { TString16 cod_cve(_clifo->lfile(LF_CFVEN).get(CFV_CATVEN)); _cve->put("CODTAB",cod_cve); if (_cve->read() == NOERR) { gruppo = _cve->get_int("I3"); conto = _cve->get_int("I4"); } } TString descr; descr = head.get(MOV_DESCR);// La descrizione della riga di totale documento la prende dalla testata // se ancora non e' stato trovato piglia quello della causale if (gruppo == 0 || conto == 0) { TBill zio; _caus->bill(1,zio); gruppo = zio.gruppo(); conto = zio.conto(); } if (gruppo == 0 || conto == 0) _error = conto_error; TRectype& first_iva_row = _movimento->iva(0); const char tc = first_iva_row.get_char(RMI_TIPOC); const int grc = first_iva_row.get_int(RMI_GRUPPO); const int coc = first_iva_row.get_int(RMI_CONTO); const long soc =first_iva_row.get_long(RMI_SOTTOCONTO); rec_cg.put(RMV_ANNOES,annoes);rec_cg.put(RMV_NUMREG,numreg); rec_cg.put(RMV_NUMRIG,1); rec_cg.put(RMV_SEZIONE,tipocf == "C" ? "D" : "A"); rec_cg.put(RMV_DATAREG,datareg); rec_cg.put(RMV_TIPOC,tipocf); rec_cg.put(RMV_GRUPPO,gruppo);rec_cg.put(RMV_CONTO,conto); rec_cg.put(RMV_SOTTOCONTO,codcf); rec_cg.put(RMV_DESCR,descr); rec_cg.put(RMV_TIPOCC,tc); rec_cg.put(RMV_GRUPPOC,grc); rec_cg.put(RMV_CONTOC,coc);rec_cg.put(RMV_SOTTOCONTOC,soc); rec_cg.put(RMV_IMPORTO,totdoc); rec_cg.put(RMV_ROWTYPE,rowtype); return _error; } error_type TContabilizzazione_app::compile_rows_mov() // Compila le righe { const int rows = _doc->rows(); _righe_iva.destroy(); // resetta l'assoc_array delle righe di iva for (int i=1; good() && i<=rows; i++) // browse all this fucked document rows { const TRiga_documento& r= (*_doc)[i]; TString16 tiporiga(r.get("TIPORIGA")); _tri->put("CODTAB",tiporiga); if (_tri->read() == NOERR) // controlla l'esistenza della riga { TBill conto; const char tipo = r.tipo().tipo(); if (tipo != 'D') { search_costo_ricavo(conto,r); // l'errore eventuale viene settato qui dentro if (good()) add_iva_row(conto,r); } } else _error = row_type_error; } if (good() && _righe_iva.items() == 0) _error = no_rows_error; // Crea le righe per le spese d'incasso e bolli if (good()) add_spese_inbo(); // Crea le righe di IVA if (good()) create_iva_rows(); // Crea la riga di totale documento if (good()) create_total_doc_row(); // crea le righe di contabilita' if (good()) if (!_movimento->recalc_cg_rows(_caus)) _error = movement_error; return _error; } void TContabilizzazione_app::calc_pagament() { TRectype& head = _movimento->lfile().curr(); TString16 codpag(head.get(MOV_CODPAG)); TString16 data(_doc->get("DATAINSC")); _pagamento = new TPagamento(codpag, data); real totspese = _doc->spese(); real totimposte = _doc->imposta(); real totimponibili = _doc->totale_doc() - totimposte - totspese; const bool valuta = head.get(MOV_CODVAL).not_empty(); if (valuta) { const real change(head.get_real(MOV_CAMBIO)); real val1 = totimponibili * change; real val2 = totimposte * change; real val3 = totspese * change; _pagamento->set_total_valuta( totimponibili, totimposte, totspese, change, val1, val2 ,val3); } else _pagamento->set_total( totimponibili, totimposte, totspese ); _pagamento->set_rate_auto( ); } error_type TContabilizzazione_app::write_scadenze() // Scrive le scadenze. Liberamente tratto da cg2104.cpp. { calc_pagament(); const TRectype& head = _movimento->lfile().curr(); const long nreg = head.get_long(MOV_NUMREG); const int anno = head.get_int(MOV_ANNOIVA); const TString numpart(head.get(_nump_cfg ? MOV_PROTIVA : MOV_NUMDOC)); //TPartita* oldgame = partite().first(); TPartita* newgame = NULL; int nuova_riga = 0; if (anno > 0 && !numpart.blank()) { const int tmov = _caus->tipomov(); const TString desc(head.get(MOV_DESCR)); const TString codpag(head.get(MOV_CODPAG)); const TString codcaus(_caus->codice()); const TString v(head.get(MOV_CODVAL)); const TDate d(head.get_date(MOV_DATACAM)); const real c(head.get_real(MOV_CAMBIO)); const TValuta cambio(v, d, c); const TString agente(_doc->get("CODAG")); const char sezione = _movimento->cg(0).get_char(RMV_SEZIONE); // Dare/Avere TBill clifo; const char tipocf = head.get_char(MOV_TIPO); const long codcf = head.get_long(MOV_CODCF); clifo.set(0,0,codcf,tipocf); newgame = new TPartita(clifo, anno, numpart); const int row = newgame->prima_fattura(nreg); // Riga fattura di questo movimento TRiga_partite& partita = row <= 0 ? newgame->new_row() : newgame->riga(row); nuova_riga = partita.get_int(PART_NRIGA); CHECK(_pagamento,"E che diavolo! Ti avevo detto di calcolare prima _pagamento"); TPagamento& pag = *_pagamento; // put data on partita partita.put(PART_TIPOMOV, tmov); partita.put(PART_NREG, nreg); partita.put(PART_NUMRIG, 1); partita.put(PART_DATAREG, head.get_date(MOV_DATAREG)); partita.put(PART_DATADOC, head.get_date(MOV_DATADOC)); partita.put(PART_NUMDOC, head.get(MOV_NUMDOC)); partita.put(PART_DESCR, desc); partita.put(PART_CODCAUS, codcaus); partita.put(PART_REG, _caus->reg().name()); partita.put(PART_PROTIVA, head.get_long(MOV_PROTIVA)); partita.put(PART_SEZ, sezione); const real totdoc(head.get_real(MOV_TOTDOC)); partita.put(PART_IMPTOTDOC, totdoc); cambio.put(partita); const bool in_valuta = cambio.in_valuta(); real imponibile, imponibile_val; for (int i = pag.n_rate()-1; i >= 0; i--) { if (in_valuta) imponibile_val += pag.tval_rata(i); imponibile += pag.tlit_rata(i); } partita.put(PART_IMPORTO, imponibile); partita.put(PART_IMPORTOVAL, imponibile_val); partita.put(PART_IMPOSTA, pag.imposta()); partita.put(PART_SPESE, pag.spese()); const TString abipr(_doc->get("CODABIP")), cabpr(_doc->get("CODCABP")), abi(_doc->get("CODABIA")), cab(_doc->get("CODCABP")); partita.elimina_rata(-1); // Elimina tutte le rate eventuali const int nr = pag.n_rate(); for (i = 0; i < nr; i++) { TRiga_scadenze& scadenza = partita.new_row(); scadenza.put(SCAD_CODPAG, codpag); // Codice pagamento scadenza.put(SCAD_CODAG, agente); // Codice agente scadenza.put(SCAD_DATASCAD, pag.data_rata(i)); // Data scadenza scadenza.put(SCAD_IMPORTO, pag.tlit_rata(i)); // Importo if (in_valuta) scadenza.put(SCAD_IMPORTOVAL, pag.tval_rata(i)); // Importo in valuta scadenza.put(SCAD_TIPOPAG, pag.tipo_rata(i)); // Tipo pagamento scadenza.put(SCAD_ULTCLASS, pag.ulc_rata(i)); // Ulteriore classificazione scadenza.put(SCAD_CODABIPR, abipr); // Ns ABI scadenza.put(SCAD_CODCABPR, cabpr); // Ns CAB scadenza.put(SCAD_CODABI, abi); // Vs ABI scadenza.put(SCAD_CODCAB, cab); // Vs CAB // scadenza.put(SCAD_DESCR, ????); // Note } } if (newgame != NULL) // Se non ho cancellato il numero partita ... { if (!newgame->write()) // Salva nuova partita error_box("Si e' verificato un errore scrivendo le scadenze del documento."); delete newgame; } if (_pagamento != NULL) { delete _pagamento; _pagamento = NULL; } return _error; } error_type TContabilizzazione_app::write_all() // Scrive il movimento e le scadenze, gestendo la rinumerazione se il movimento e' gia presente { // N.B: _error non viene settato, per non stampare il messaggio di errore 2 volte. // basta solo ritornare qualcosa di != da no_error, per evitare le operazioni successive // a write_all TRectype& head = _movimento->lfile().curr(); long numreg = head.get_long(MOV_NUMREG); while (_movimento->write() == _isreinsert) head.put(MOV_NUMREG,++numreg); if (_movimento->status() != NOERR) { error_box("Errore %d scrivendo il movimento %ld.",_movimento->status(),numreg); return generic_error; } if (sc_enabled()) write_scadenze(); return no_error; } error_type TContabilizzazione_app::change_doc_status() // Cambia lo stato del documento { TLocalisamfile d(LF_DOC); _doc->stato(_final_doc_status); if (_doc->head().rewrite(d) != NOERR) _error = chg_stat_error; return _error; } void TContabilizzazione_app::display_error() { TString msg; TString numerazione = _doc->numerazione(); const long numero = _doc->numero(); switch (_error) { case elaboration_error: msg.format("Il documento %s/%ld non rientra tra i tipi documento validi per l'elaborazione." "Verificare i tipi documento ed il loro stato iniziale sul codice elaborazione inserito.",(const char*)numerazione,numero); break; case nr_es_error: msg.format("Rilevato un codice esercizio errato contabilizzando il documento %s/%ld." "Verificare l'esistenza e la correttezza della tabella esercizi e della data del documento.",(const char*)numerazione,numero); break; case nr_reg_error: msg.format("Rilevato un numero di registrazione errato contabilizzando il documento %s/%ld." "Verificare l'integrita' del file movimenti.",(const char*)numerazione,numero); break; case nr_doc_error: msg.format("Rilevato un numero di documento errato contabilizzando il documento %s/%ld." "Verificare il numero documento e il codice numerazione inseriti in tabella.",(const char*)numerazione,numero); break; case chg_stat_error: msg.format("Rilevato un errore cambiando lo stato al documento %s/%ld." "Verificare l'integrita' del file documenti.",(const char*)numerazione,numero); break; case clifo_error: msg.format("Rilevato un errore caricando le informazioni del Cli/Fo sul documento %s/%ld." "Verificare l'esistenza delle informazioni inserite sul file documenti e Cli/Fo.",(const char*)numerazione,numero); break; case ultprot_error: msg.format("Rilevato un numero di protocollo IVA errato relativamente al documento %s/%ld." "Verificare le informazioni inserite sul registro %s/%d.",(const char*)numerazione,numero, (const char*) _caus->reg().name(),_caus->reg().year()); break; case datadoc_error: msg.format("Rilevato una data documento vuota relativamente al documento %s/%ld." "Verificare l'informazione inserita.",(const char*)numerazione,numero); break; case caus_error: msg.format("Rilevato un errore caricando la causale relativamente al documento %s/%ld." "Verificare l'esistenza del codice causale inserito.",(const char*)numerazione,numero); break; case register_error: msg.format("Rilevato un errore caricando il registro relativamente al documento %s/%ld." "Verificare l'esistenza del codice causale/registro inseriti.",(const char*)numerazione,numero); break; case change_error: msg.format("Rilevato un cambio senza valuta relativamente al documento %s/%ld." "Verificare la correttezza delle informazioni inserite.",(const char*)numerazione,numero); break; case val_error: msg.format("Rilevato un codice valuta inesistente relativamente al documento %s/%ld." "Verificare la correttezza della informazione inserita.",(const char*)numerazione,numero); break; case codpag_error: msg.format("Rilevato un codice pagamento non esistente relativamente al documento %s/%ld." "Verificare l'esistenza del codice pagamento inserito.",(const char*)numerazione,numero); break; case row_type_error: msg.format("Rilevato un codice tipo riga non esistente relativamente al documento %s/%ld." "Verificare l'esistenza dei vari codici riga inseriti.",(const char*)numerazione,numero); break; case no_rows_error: msg.format("Nessuna riga iva contabile e' stata trovata relativamente al documento %s/%ld." "Verificare l'esistenza dei vari codici riga inseriti.",(const char*)numerazione,numero); break; case conto_error: msg.format("Rilevato un conto di costo/ricavo inesistente relativamente al documento %s/%ld." "Verificare l'esistenza dei conti associati alle righe.",(const char*)numerazione,numero); break; case movement_error: msg.format("Rilevato uno sbilancio nel movimento relativamente al documento %s/%ld." "Verificare la correttezza degli importi delle righe.",(const char*)numerazione,numero); break; case mov_write_error: msg.format("Rilevato un errore in scrittura movimento relativamente al documento %s/%ld." "Verificare la consistenza dei files.",(const char*)numerazione,numero); break; default: msg.format("E' stato rilevato un errore generico contabilizzando il documento %s/%ld.", (const char*)numerazione,numero); break; } warning_box(msg); _error = no_error; // reset error, as any other one would do, so you can show me the other ones. _can_write = FALSE; // But from now on u cannot write anymore. U must exit this program and repair errors occurred. } void TContabilizzazione_app::contabilize_document() { _movimento = new TMovimentoPN_VE; //_doc->compile_summary(); // ricalcola il documento compile_head_mov(); if (good()) compile_rows_mov(); if (good() && _can_write) if (write_all() == no_error) // Se la scrittura e' andata ok... { _total_docs++; change_doc_status(); } if (_caus != NULL) { delete _caus; _caus = NULL; } delete _movimento; } void TContabilizzazione_app::contabilize() { TRelation doc_rel(LF_DOC); TLocalisamfile righe_doc(LF_RIGHEDOC); TRectype da(LF_DOC),a(LF_DOC); const long items = _num_sheet->items(); int year_from = _data_ini.year(); int year_to = _data_fine.year(); TString16 codnum; TString msg,filt_expr; _total_docs = 0; da.put("DATADOC",_data_ini); da.put("PROVV","D"); da.put("ANNO",year_from); a.put("DATADOC",_data_fine); a.put("PROVV","D"); a.put("ANNO",year_to); for (long i=0L; ichecked(i)) // Se la numerazione corrente e' stata selezionata { // istanzia un cursore per la numerazione corrente, con i limiti di data codnum = _num_sheet->row(i).get(1); filt_expr = "CODNUM=\""; filt_expr << codnum << "\""; TCursor doc_cur(&doc_rel,filt_expr,3,&da,&a); const long cur_items = doc_cur.items(); // Scorre tutti i documenti che rientrano nell'intervallo selezionato if (cur_items == 0) { warning_box("Non vi sono documenti da contabilizzare per il codice numerazione %s",(const char*)codnum); continue; } msg = "Contabilizzazione documenti "; msg << codnum << " dal "; msg << _data_ini.string() << " al "; msg << _data_fine.string(); #ifdef DBG TProgind p(cur_items,msg,TRUE,TRUE,1); #else TProgind p(cur_items,msg,FALSE,TRUE,1); #endif long j = 0; #ifdef DBG for (;jread(doc_cur.curr()); // legge il documento if (codnum != _doc->get("CODNUM")) continue; // patch del cazzo if (doc_tipo_stato_ok()) // controlla che il tipo documento e lo stato siano coerenti con la ELD selezionata contabilize_document(); else { // ATTENZIONE!: se non ha ancora cominciato a contabilizzare, eventuali // documenti con tipo o stato differenti vengono semplicemente scartati // senza segnalare errori if (_total_docs > 0) _error = elaboration_error; } if (!good()) display_error(); } #ifdef DBG if (p.iscancelled()) break; #endif } if (_total_docs > 0) message_box("Totale documenti contabilizzati: %ld",_total_docs); } int ve6100 (int argc, char **argv) { TContabilizzazione_app a; a.run(argc,argv,"Contabilizzazione documenti"); return TRUE; }