#include #include #include #include #include #include #include #include #include #include #include #include "../mg/anamag.h" #include "velib.h" #include "../cg/cg2101.h" #include "../cg/cg2103.h" #include "../cg/cgsaldac.h" /////////////////////////////////////////////////////////// // TContabilizzazione /////////////////////////////////////////////////////////// // 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; bool _valuta; 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); // verifica se il movimento e' quadrato oppure ha qualche maledetto sbilancio // ritorna TRUE, ovviamente, se everything's alright. bool movement_ok() ; public: // 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(bool valuta) : _valuta(valuta) {}; 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 int annodoc = curr().get_date(MOV_DATADOC).year(); const bool prorata100 = _caus->reg().prorata100(annodoc); return !prorata100; // Se prorata = 100% e' indetraibile } 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; // Se siamo in valuta, forzera' la riga totale documento a cio' che si ottiene dalla somma // delle singole righe per evitare sbilanci nel movimento di 2,3,4,5 lire dovuti agli arrotondamenti const int max = cg_items(); for (int i = 0; i < max; i++) { if (i == 0 && _valuta) continue; 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 (_valuta) { TRectype& r = cg(0); // Setta la riga di totale documento... r.put(RMV_IMPORTO,tot_imp.valore()); r.put(RMV_SEZIONE,tot_imp.sezione() == 'D' ? 'A' : 'D'); // Sezione contraria // ...ed anche il totale documento sulla testata lfile().curr().put(MOV_TOTDOC,tot_imp.valore()); tot_imp.valore() = 0.0; } 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; iadd(LF_CFVEN,"TIPOCF=TIPOCF|CODCF=CODCF"); } TContabilizzazione::TContabilizzazione(const TRectype& rec) : TElaborazione(rec), _auto_data(FALSE), _nump_iva(2) { _fcaus = new TLocalisamfile(LF_CAUSALI); _frcaus = new TLocalisamfile(LF_RCAUSALI);// Per far andare TCausale _attiv = new TLocalisamfile(LF_ATTIV); // Altrimenti TRegistro non va! _part = new TLocalisamfile(LF_PARTITE); _scad = new TLocalisamfile(LF_SCADENZE); _pags = new TLocalisamfile(LF_PAGSCA); // Per far funzionare TPartita _occas = new TLocalisamfile(LF_OCCAS); _docfile = new TLocalisamfile(LF_DOC); _rdocfile = new TLocalisamfile(LF_RIGHEDOC); // Per far funzionare TDocumento,TPartita ecc.. _anamag = new TLocalisamfile(LF_ANAMAG); _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"); } TContabilizzazione::~TContabilizzazione() { delete _clifo; delete _cpg; delete _tri; delete _val; delete _gmc; delete _rfa; delete _cve; delete _cco; delete _prs; delete _spp; delete _caa; delete _cra; delete _anamag; delete _fcaus; delete _frcaus; delete _attiv; delete _part; delete _scad; delete _pags; delete _occas; delete _docfile; delete _rdocfile; } bool TContabilizzazione::load_parameters() { 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); _contsclor = conf.get_bool("CONTSCLOR","ve"); 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"); return TRUE; } error_type TContabilizzazione::compile_head_mov(TDocumento& doc) // Compila la testata { 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); // 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 long numreg = 1L; if (!mov.empty()) { mov.last(); numreg = mov.get_long(MOV_NUMREG) + 1L; 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; } long ult_prot; if (_nump_iva == 1) // Reperisce l'ultimo numero di protocollo dal registro IVA { ult_prot = registro.protocol() +1; if (ult_prot < 1) { _error = ultprot_error; return _error; } } else // oppure dal numero di documento ult_prot = doc.numero(); // Reperisce la valuta TDate datacam(doc.get_date(DOC_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(DOC_TIPOCF)); long codcf = doc.get_long(DOC_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(DOC_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(DOC_CODPAG)); if (sc_enabled() || codpag.not_empty()) // La condizione di pagamento va controllata { // se e' abilitato il saldaconto o se e' stata inserita _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; } error_type TContabilizzazione::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(RDOC_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(ANAMAG_CODART,r.get(RDOC_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 ? ANAMAG_GRUPPOV : ANAMAG_GRUPPOA); co = _anamag->get_int(is_cli ? ANAMAG_CONTOV : ANAMAG_CONTOA); so = _anamag->get_long(is_cli ? ANAMAG_SOTTOCV : ANAMAG_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 ? ANAMAG_CATCONV : ANAMAG_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 ? ANAMAG_GRMERC : ANAMAG_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 ? r.doc().get(DOC_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(RDOC_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: vengono considerate in adjust_sconto_rows() case 'D': // righe descrizioni (saltare) default : break; } // end of switch if (good() && !conto.find()) _error = conto_error; return _error; } error_type TContabilizzazione::add_iva_row(const TBill& conto, const TRiga_documento& r, const int ndec) // Aggiunge le righe iva all'assoc_array di raggruppamento { TIVA_element el_tmp; const TIVA& tiva = r.iva(); TString cod(tiva.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(); const bool sconto_lordo = tipo_r != 'C' && _contsclor && _sco_perc_bill.ok(); bool exists; 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; default: break; } // Le righe di sconto ad importo o percentuale vanno saltate if (tipo_r != 'C') { key.format("%d|%-4s|%c|%3d|%3d|%6ld",ord,(const char*)cod,tipo,gr,co,so); exists = _righe_iva.is_key(key); TIVA_element& el = (exists ? (TIVA_element&)_righe_iva[key] : el_tmp); el.add(r,sconto_lordo,ndec); // Inserisce la riga IVA al netto o al lordo dello sconto _righe_iva.add(key,el,exists); // Le righe di sconto le aggiorna dopo } if (sconto_lordo) // Se e' settato il flag di contabilizzare anche gli sconti merce { real sconto = - r.sconto(); // Imponibile dello sconto (positivo, quindi si cambia di segno if (sconto != ZERO) { real ivasc = ::iva(sconto,tiva,ndec);// imposta calcolata sullo sconto key.format("6|%-4s|%c|%3d|%3d|%6ld", (const char*)cod, _sco_perc_bill.tipo(), _sco_perc_bill.gruppo(), _sco_perc_bill.conto(), _sco_perc_bill.sottoconto()); el_tmp.zero(); exists = _righe_iva.is_key(key); TIVA_element& el_sc = (exists ? (TIVA_element&)_righe_iva[key] : el_tmp); el_sc.ali() = tiva.aliquota(); el_sc.cod_iva() = tiva.codice(); el_sc.imp() += sconto; el_sc.iva() += ivasc; _righe_iva.add(key,el_sc,exists); // Sostituisce od aggiunge la riga relativa allo sconto } } return no_error; } void TContabilizzazione::calculate_spese(real& spese, real& sp_iva, int ndec, bool is_incasso, bool is_cli) { char tipo; int gr,co; long so; 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::add_spese_inbo(TDocumento& doc, const int ndec) // Aggiunge le righe di spese incasso/bolli { real tot_netto, sp_incasso, sp_bolli; real iva_sp_incasso, iva_sp_bolli; bool is_cli = doc.get(DOC_TIPOCF) == "C"; // Aggiunge le spese d'incasso tot_netto = doc.totale_netto(); sp_incasso = doc.spese_incasso(tot_netto,ndec,_netto); if (sp_incasso != 0.0) calculate_spese(sp_incasso,iva_sp_incasso,ndec,TRUE,is_cli); // Aggiunge le spese bolli tot_netto += sp_incasso + iva_sp_incasso; sp_bolli = doc.bolli(tot_netto,ndec, _netto); if (sp_bolli != 0) calculate_spese(sp_bolli,iva_sp_bolli,ndec,FALSE,is_cli); return _error; } // Aggiorna le righe di sconto (importo o a percentuale) error_type TContabilizzazione::adjust_sconto_rows(TDocumento& doc) { TIVA_element el_tmp; TAssoc_array& aa = doc.tabella_iva(); TRiepilogo_iva * riep; TString cod,key; // Codice IVA corrente real sconto,iva; const int ndec = doc.in_valuta() ? 3 : 0; // Scorre tutti gli elementi della tabella IVA del documento (elementi per codice iva) for (riep = (TRiepilogo_iva*) aa.first_item(); riep != NULL; riep = (TRiepilogo_iva*) aa.succ_item()) { const TIVA& codiva = riep->cod_iva(); cod = codiva.codice(); // Codice IVA for (int i = 0; i < 2; i++) // Ciclo per sconto a percentuale (i == 0) e ad importo (i == 1) { //Importo sconto (sconto_perc() o sconto_imp()) //Calcola ::iva() sullo sconto //Somma alla riga corrispondente o la crea se non esiste gia' //I conti per aggiustare l'iva vengono fatti in adjust_iva_rows() const bool perc = i == 0; TBill& conto = perc ? _sco_perc_bill : _sco_imp_bill; sconto = perc ? riep->sconto_perc() : riep->sconto_imp(); iva = ::iva(sconto,codiva,ndec); if (sconto != ZERO) { key.format("6|%-4s|%c|%3d|%3d|%6ld",(const char*)cod, conto.tipo(), conto.gruppo(), conto.conto(), conto.sottoconto()); const bool exists = _righe_iva.is_key(key); // Aggiorna imponibile ed imposta all'elemento relativo el_tmp.zero(); TIVA_element& el = exists ? (TIVA_element&)_righe_iva[key] : el_tmp; el.imp() += sconto; el.iva() += iva; el.ali() = codiva.aliquota(); el.cod_iva() = cod; _righe_iva.add(key,el,exists); } } } return no_error; } // "Aggiusta" l'imposta sulle righe IVA secondo la tabella interna al documento // Tratta anche i documenti in valuta. DI solito si tratta di poche lire. error_type TContabilizzazione::adjust_iva_rows(TDocumento& doc) { TAssoc_array& aa = doc.tabella_iva(); TRiepilogo_iva * riep; TString cod; // Codice IVA corrente const int items = _righe_iva.items(); // Numero di righe IVA const bool in_valuta = doc.in_valuta(); const real cambio = doc.cambio(); real iva_gen,imponibile; // Scorre tutti gli elementi della tabella IVA del documento (elementi per codice iva) for (riep = (TRiepilogo_iva*) aa.first_item(); riep != NULL; riep = (TRiepilogo_iva*) aa.succ_item()) { cod = riep->cod_iva().codice(); // Codice IVA iva_gen = riep->imposta(); if (in_valuta) // I documenti vanno sempre contabilizzati in lire iva_gen *= cambio; if (iva_gen < ZERO) iva_gen.floor(0); else iva_gen.ceil(0); TGeneric_distrib gd(iva_gen); // Instanzia il TGeneric_ditrib con la vera Imposta // Adesso scorre tutte le righe IVA contabili con questo codice IVA for (int i = 0; i < items; i++) { TRectype& ie = _movimento->iva(i); if (ie.get(RMI_CODIVA) == cod) // Se il codice IVA e' uguale gd.add(ie.get_real(RMI_IMPOSTA)); // Aggiunge al TGeneric_distrib l'imposta corrente } // Alla fine per performare tutto il calcolo (Thanx to TGeneric_distrib) si fanno le get // E le si mettono nel rispettivo record IVA for (i = 0; i < items; i++) { TRectype& ie = _movimento->iva(i); if (ie.get(RMI_CODIVA) == cod) // Se il codice IVA e' uguale ie.put(RMI_IMPOSTA,gd.get()); // Sostituisce l'imposta con quella ricalcolata al fine di avere tutto giusto } } // Visto che vengono restituiti nello stesso ordine in cui sono state chiamate le rispettive TGeneric_distrib::add() return no_error; } error_type TContabilizzazione::create_iva_rows(TDocumento& doc) { 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; for (int i = 0; i < items; i++) { 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) // I documenti vanno sempre contabilizzati in lire { imponibile = cur.imp() * cambio; // imponibile in lire imponibile.round(); imposta = abs(imponibile) * cur.ali() / 100.0; // questa e' l'imposta ricalcolata imposta.ceil(); if (imponibile < 0.0) imposta = -imposta; } else imposta = cur.iva(); 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()); } return _error; } error_type TContabilizzazione::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::compile_rows_mov(TDocumento& doc) // Compila le righe { const int rows = doc.rows(); const int ndec = doc.in_valuta() ? 3 : 0; _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(RDOC_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' && tipo != 'C') { search_costo_ricavo(conto,r); // l'errore eventuale viene settato qui dentro if (good()) add_iva_row(conto,r,ndec); } } 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(doc,ndec); // Aggiorna le righe di sconto (sconto ad importo o percentuale) if (good()) adjust_sconto_rows(doc); // Crea le righe di IVA if (good()) create_iva_rows(doc); // Controlla che le imposte per ogni aliquota ed eventualmente corregge le imposte stesse sulle righe if (good()) adjust_iva_rows(doc); // 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; } error_type TContabilizzazione::change_doc_status(TDocumento& doc) // Cambia lo stato del documento { doc.stato(get("S4")[0]); if (doc.rewrite() != NOERR) _error = chg_stat_error; return _error; } error_type TContabilizzazione::write_scadenze(TDocumento& doc) // Scrive le scadenze. Liberamente tratto da cg2104.cpp. { TRectype& head = _movimento->lfile().curr(); const TString16 codpag(head.get(MOV_CODPAG)); TString16 data(doc.get(DOC_DATAINSC));// Il costruttore di TPagamento vuole un const char * // Se la data di scadenza non e' compilata prende quella del documento if (data.empty()) data = doc.get(DOC_DATADOC); TPagamento * 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; real val1 = head.get_real(MOV_TOTDOC) - val2 - val3; // Cosi' corregge eventuali scompensi di poche lirette pagamento->set_total_valuta( totimponibili, totimposte, totspese, change, val1, val2 ,val3); } else pagamento->set_total( totimponibili, totimposte, totspese ); pagamento->set_rate_auto( ); 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* 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 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(DOC_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); 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(); if (in_valuta) { const real totdocval(head.get_real(MOV_TOTDOCVAL)); partita.put(PART_IMPTOTVAL,totdocval); } 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(DOC_CODABIP)), cabpr(doc.get(DOC_CODCABP)), abi(doc.get(DOC_CODABIA)), cab(doc.get(DOC_CODCABA)); 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; } delete pagamento; return _error; } error_type TContabilizzazione::write_all(TDocumento& doc) // 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(doc); return no_error; } void TContabilizzazione::display_error(TDocumento& doc) { TString msg; TString numerazione = doc.numerazione(); const long numero = doc.numero(); switch (_error) { 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 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: // errori generici o non indicati vengono visualizzati nel punto dell'errore //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. } bool TContabilizzazione::sc_enabled() const { bool rt = _sc_enabled; if (_caus != NULL) rt &= _caus->saldaconto(); return rt; } bool TContabilizzazione::elabora(TLista_documenti& doc_in, TLista_documenti& doc_out, const TDate& data_elab) { _error = no_error; _can_write = TRUE; _total_docs = 0L; _caus = NULL; _data_reg = data_elab; _esc.update(); if (!load_parameters()) // Carica i parametri dalla configurazione return FALSE; const int items = doc_in.items(); // Numero dei documenti in questa elaborazione TProgind p(items,"Contabilizzazione documenti",FALSE,TRUE,1); for (int i = 0; i < items ; i++) // Scorriamo tutti i documenti nella lista { p.setstatus(i+1); TDocumento& doc = doc_in[i]; _movimento = new TMovimentoPN_VE(doc.in_valuta()); compile_head_mov(doc); if (good()) compile_rows_mov(doc); if (good() && _can_write) if (write_all(doc) == no_error) // Se la scrittura e' andata ok... { _total_docs++; change_doc_status(doc); } if (_caus != NULL) { delete _caus; _caus = NULL; } if (!good()) display_error(doc); delete _movimento; } return _can_write; // Se non ha riscontrato errori per nessun documento, _can_write = TRUE }