#include #include #include #include "velib04.h" #include "../ca/movana.h" #include "../ca/rmovana.h" #include "../ca/rrip.h" #include "../cg/cg2103.h" #include "../mg/anamag.h" TBill _sco_perc_bill_an, _sco_imp_bill_an; class TCache_causali : public TCache { protected: TObject* key2obj(const char* key); public: const TCausale& causale(const TDocumento& doc); TCache_causali() : TCache(17) { } }; TObject* TCache_causali::key2obj(const char* key) { TToken_string k = key; const int year = k.get_int(1); return new TCausale(k.get(0), year); } const TCausale& TCache_causali::causale(const TDocumento& doc) { // Cerca il codice causale sul cliente const char* const fld = doc.is_nota_credito() ? CFV_CODCAUSNC : CFV_CODCAUS; TToken_string key; key.add(doc.get(DOC_TIPOCF)); key.add(doc.get(DOC_CODCF)); const TRectype& cfven = cache().get(LF_CFVEN, key); TString16 codcaus = cfven.get(fld); // Se non lo trova guarda sul tipo documento if (codcaus.empty()) { const TTipo_documento& tipo = doc.tipo(); codcaus = tipo.causale(); } //Assegna l'anno della causale const int year = doc.get_date(DOC_DATADOC).year(); TString16 chiave; chiave.format("%4s|%4d", codcaus, year); // Trasforma il codice in causale vera e propria return (const TCausale&)*objptr(chiave); } /////////////////////////////////////////////////////////// // TContabilizzazione_analitica /////////////////////////////////////////////////////////// static TCache_ripartizioni _rip; static TToken_string _search_seq; const TCausale& TContabilizzazione_analitica::doc2caus(const TDocumento& doc) { static TCache_causali _caus; return _caus.causale(doc); } const TCausale& TContabilizzazione_analitica::rdoc2caus(const TRiga_documento& rdoc) { return doc2caus(rdoc.doc()); } // Copiata dalla contabilizzazione ed eliminati riferimenti a tutte le variabili globali del cazzo bool TContabilizzazione_analitica::search_costo_ricavo(const TRiga_documento& r, TBill& conto) { if (_search_seq.blank()) { TConfig conf(CONFIG_DITTA, "ve"); _search_seq = conf.get("RICERCACR"); } const int items = _search_seq.items(); TString16 clifo_key; clifo_key.format("%c|%ld", r.doc().get_char(DOC_TIPOCF), r.doc().get_long(DOC_CODCF)); const TRectype& cli_file = cache().get(LF_CLIFO, clifo_key); const bool skip_clifo = cli_file.empty(); const bool is_cli = clifo_key[0] != 'F'; bool skip_art_related = false; const TCodiceIVA codiva(r.get(RDOC_CODIVA)); const char t = r.tipo().tipo(); switch (t) { case RIGA_OMAGGI: // righe omaggio come articoli spiaccicato identico (avranno imponibile 0) case RIGA_MERCE: // righe di merce { // posiziona l'anagrafica sull'articolo specificato sulla ..iga const TRectype& anamag = cache().get(LF_ANAMAG, r.get(RDOC_CODARTMAG)); if (anamag.empty()) // se non trova l'articolo saltera' anche gmc,smc,rfa. skip_art_related = true; TString4 tok; // Scorre la stringa di ricerca for (int i=0; i < items;i++) { _search_seq.get(i, tok); if (tok == "CF") { if (skip_clifo) continue; const int gr = cli_file.get_int(CLI_GRUPPORIC); const int co = cli_file.get_int(CLI_CONTORIC); const long so = cli_file.get_long(CLI_SOTTOCRIC); conto.set(gr,co,so); if (conto.ok()) break; // se lo trova esce (tutti != 0) } else if (tok == "CA") { const TCausale& caus = rdoc2caus(r); if (caus.IVA2bill(codiva,conto)) break; // se lo trova esce } else if (tok == "AR") { if (skip_art_related) continue; int gr = anamag.get_int(is_cli ? ANAMAG_GRUPPOV : ANAMAG_GRUPPOA); int co = anamag.get_int(is_cli ? ANAMAG_CONTOV : ANAMAG_CONTOA); long 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 { const TString16 codtab = anamag.get(is_cli ? ANAMAG_CATCONV : ANAMAG_CATCONA); const TRectype& t = cache().get(is_cli ? "CRA" : "CAA", codtab); if (!t.empty()) { gr = t.get_int("I0"); co = t.get_int("I1"); so = t.get_long("I2"); 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"; TString16 codtab = anamag.get(is_fis ? ANAMAG_RAGGFIS : ANAMAG_GRMERC); if (tok == "GM" && codtab.len() > 3) codtab.cut(3); // gli ultimi 2 si riferiscono al sottogruppo. const TRectype& tab = cache().get(is_fis ? "RFA" : "GMC", codtab); if (!tab.empty()) { const int gr = tab.get_int(is_cli ? "I3" : "I0"); const int co = tab.get_int(is_cli ? "I4" : "I1"); const long 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 TString16 cod = is_cve ? r.doc().get(DOC_CATVEN) : EMPTY_STRING; if (cod.empty()) { if (skip_clifo) continue; // se non aveva trovato il cliente salta al prossimo const TRectype& cfven = cache().get(LF_CFVEN, clifo_key); cod = cfven.get(is_cve ? CFV_CATVEN : CFV_CODCATC); } const TRectype& t = cache().get(is_cve ? "CVE" : "CCO", cod); if (!t.empty()) { const bool x =(is_cve || is_cli); const int gr = t.get_int(x ? "I3" : "I0"); const int co = t.get_int(x ? "I4" : "I1"); const long so = t.get_long(x ? "I5": "I2"); conto.set(gr,co,so); } if (conto.ok()) break; } } break; // case 'M' } case RIGA_SPESEDOC: case RIGA_PRESTAZIONI: case RIGA_ATTREZZATURE: case RIGA_RISORSE: { const TSpesa_prest tab(r.get(RDOC_CODART), t); if (!tab.empty()) { int gr = tab.get_int(is_cli ? "I0" : "I3"); int co = tab.get_int(is_cli ? "I1" : "I4"); long so = tab.get_long(is_cli ? "I2" : "I5"); conto.set(gr,co,so); if (!is_cli && !conto.ok()) { gr = r.get_int("QTAGG1"); co = r.get_int("QTAGG2"); so = r.get_long("QTAGG3"); conto.set(gr,co,so); } } // Cerca il conto nella stringa di ricerca (solo per prestazioni) if (t == RIGA_PRESTAZIONI && !conto.find()) { TString4 tok; // Scorre la stringa di ricerca ma solo per causale o CLI/FO for (int i=0; i 0) { __searching = true; search_costo_ricavo(r.doc()[row], conto); __searching = false; } } break; } case RIGA_SCONTI: case RIGA_DESCRIZIONI: default : break; } // end of switch return conto.ok() && conto.find(); } bool TContabilizzazione_analitica::find_conti_iva_indetraibile(const TRiga_documento& riga, const TBill & bill, TString_array& conti) { const TString80 riga_cos = riga.codice_costo(); const TString80 riga_cms = riga.codice_commessa(); const TString16 riga_fsc = riga.fase_commessa(); const bool riga_any = riga_cos.not_empty() || riga_cms.not_empty() || riga_fsc.not_empty(); if (_usepdcc) { TToken_string conto; conto.format("%03d%03d%06ld", bill.gruppo(), bill.conto(), bill.sottoconto()); if (riga_any) { conto.add(riga_cos, 1); conto.add(riga_cms, 2); conto.add(riga_fsc, 3); } conto.add(100, 4); conti.add(conto); } else { // Cerca la ripartizione del conto const TRecord_array& rip = _rip.righe(bill); TToken_string conto; for (int i = 1; i <= rip.rows(); i++) { const TRectype& rigarip = rip.row(i); conto = rigarip.get(RRIP_CODCONTO); if (riga_any) { conto.add(riga_cos, 1); conto.add(riga_cms, 2); conto.add(riga_fsc, 3); } else { conto.add(rigarip.get(RRIP_CODCOSTO), 1); conto.add(rigarip.get(RRIP_CODCMS), 2); conto.add(rigarip.get(RRIP_CODFASE), 3); } conto.add(rigarip.get(RRIP_RIPARTO), 4); conti.add(conto); } } return !conti.empty(); } bool TContabilizzazione_analitica::find_conti(const TRiga_documento& riga, TString_array& conti) { bool bArcticleFound = false; const char tipocf = riga.doc().get_char(DOC_TIPOCF); TString80 contanal; TBill bill; // Cerco il conto contabile if (riga.is_sconto()) { if (!_sco_perc_bill_an.ok()) { TConfig conf(CONFIG_DITTA, "ve"); int gr = conf.get_int("SCOPRCODCON","ve",1); int co = conf.get_int("SCOPRCODCON","ve",2); long so = conf.get_long("SCOPRCODCON","ve",3); _sco_perc_bill_an.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_an.set(gr,co,so); } if (riga.is_sconto_perc()) bill = _sco_perc_bill_an; else bill = _sco_imp_bill_an; if (!bill.is_analitico()) return true; if (_usepdcc) contanal.format("%03d%03d%06ld", bill.gruppo(), bill.conto(), bill.sottoconto()); } else { if (!search_costo_ricavo(riga, bill)) return true; if (!bill.is_analitico()) return true; if (riga.is_articolo()) { const TRectype& anamag = cache().get(LF_ANAMAG, riga.get(RDOC_CODARTMAG)); bArcticleFound = !anamag.empty(); if (_usepdcc) contanal.format("%03d%03d%06ld", bill.gruppo(), bill.conto(), bill.sottoconto()); else contanal = anamag.get(tipocf == 'F' ? ANAMAG_CONTOINDA : ANAMAG_CONTOINDV); } else { if (riga.is_spese() || riga.is_prestazione() || riga.is_risorsa() || riga.is_attrezzatura()) { const char tipo = riga.tipo().tipo(); const TSpesa_prest spp(riga.get(RDOC_CODART), tipo); bArcticleFound = !spp.empty(); if (_usepdcc) contanal.format("%03d%03d%06ld", bill.gruppo(), bill.conto(), bill.sottoconto()); else contanal = tipocf == 'F' ? spp.conto_analitico_acquisti() : spp.conto_analitico_vendite() ; } } if (!bArcticleFound) // Se l'anagrafica non esiste va bene cosi' return true; } const TString80 riga_cos = riga.codice_costo(); const TString80 riga_cms = riga.codice_commessa(); const TString16 riga_fsc = riga.fase_commessa(); const bool riga_any = riga_cos.not_empty() || riga_cms.not_empty() || riga_fsc.not_empty(); if (contanal.blank()) // Non ho trovato il conto in anagrafica ... { // Cerca la ripartizione del conto const TRecord_array& rip = _rip.righe(bill); TToken_string conto; for (int i = 1; i <= rip.rows(); i++) { const TRectype& rigarip = rip.row(i); conto = rigarip.get(RRIP_CODCONTO); if (riga_any) { conto.add(riga_cos, 1); conto.add(riga_cms, 2); conto.add(riga_fsc, 3); } else { conto.add(rigarip.get(RRIP_CODCOSTO), 1); conto.add(rigarip.get(RRIP_CODCMS), 2); conto.add(rigarip.get(RRIP_CODFASE), 3); } conto.add(rigarip.get(RRIP_RIPARTO), 4); conti.add(conto); } } else { // Ho trovato il conto in anagrafica ... TToken_string conto = contanal; if (riga_any) { conto.add(riga_cos, 1); conto.add(riga_cms, 2); conto.add(riga_fsc, 3); } conto.add(100, 4); conti.add(conto); } return !conti.empty(); } void TContabilizzazione_analitica::init_distrib(TString_array& conti, TGeneric_distrib& distrib) { FOR_EACH_ARRAY_ROW(conti, i, row) { real slice = row->get(4); if (slice <= ZERO) slice = UNO; distrib.add(slice); } } bool TContabilizzazione_analitica::elabora(TDocumento& doc, long numreg_cg, TViswin* viswin, bool can_write, TAnal_mov& mov) { TDate datareg, datacomp, datadoc; int annoes = 0; TString descr, msg, codcaus; bool dare = false; TCausale & caus = (TCausale &) doc2caus(doc); if (numreg_cg > 0) { const TRectype& mov_cg = cache().get(LF_MOV, numreg_cg); datareg = mov_cg.get_date(MOV_DATAREG); datacomp = mov_cg.get_date(MOV_DATACOMP); annoes = mov_cg.get_int(MOV_ANNOES); descr = mov_cg.get(MOV_DESCR); dare = !(caus.sezione_clifo() == 'D'); } else { datadoc = doc.get(DOC_DATADOC); datareg = datacomp = datadoc; annoes = datareg.year(); doc.riferimento(descr); if (descr.empty()) descr = doc.tipo().descrizione(); const TString8 rif = doc.get(DOC_NUMDOCRIF); codcaus = caus.codice(); const bool use_rif = caus.iva() == iva_acquisti && rif.not_empty(); if (use_rif) { descr << TR(" n. ") << rif; descr << TR(" del ") << doc.get(DOC_DATADOCRIF); } else { descr << TR(" n. ") << doc.numero(); descr << TR(" del ") << datadoc; } dare = doc.get_char(DOC_TIPOCF) == 'F'; if (doc.is_nota_credito()) dare= !dare; } const char sezione = dare ? 'D' : 'A'; const int decimals = TCurrency::get_firm_dec(); long numreg_ca = doc.get_long(DOC_NUMREGCA); if (numreg_ca > 0) { const int err = mov.read(numreg_ca); if (err == NOERR) { if (viswin != NULL) { msg.format("--- Il documento verrą ricontabilizzato nel movimento analitico %ld", numreg_ca); viswin->add_line(msg); } mov.body().destroy_rows(); } else mov.put(MOVANA_NUMREG, numreg_ca = 0); } mov.put(MOVANA_DATAREG, datareg); mov.put(MOVANA_DATACOMP, datacomp); mov.put(MOVANA_DATADOC, datadoc); mov.put(MOVANA_ANNOES, annoes); mov.put(MOVANA_DESCR, descr); mov.put(MOVANA_NUMREGCG, numreg_cg); // Movimento contabile associato mov.put(MOVANA_CODCAUS, codcaus); mov.put(MOVANA_DPROVV, doc.get(DOC_PROVV)); // Documento originale mov.put(MOVANA_DANNO, doc.get(DOC_ANNO)); mov.put(MOVANA_DCODNUM, doc.get(DOC_CODNUM)); mov.put(MOVANA_DNDOC, doc.get(DOC_NDOC)); TImporto totdoc; // Totale movimento analitico const TipoIVA tiva = caus.iva(); TBill bill; caus.bill(RIGA_IVA_NON_DETRAIBILE, bill); // Scandisco le righe del documento, for (int i = 1; i <= doc.physical_rows(); i++) { const TRiga_documento& riga = doc[i]; // salto descrizioni, sconti e omaggi // if (riga.is_descrizione() || riga.is_sconto() || riga.is_omaggio()) // salto descrizioni, e omaggi if (riga.is_descrizione() || riga.is_omaggio()) continue; // salto valori nulli const real qta = riga.get(RDOC_QTA); // const real valore = riga.valore(true, decimals); real valore = riga.importo(true, false); if (valore.is_zero()) continue; if (tiva != iva_vendite && !riga.is_sconto()) { real pind = ZERO; if (tiva != nessuna_iva) { const int annodoc = doc.get_date(DOC_DATADOC).year(); if (caus.reg().prorata100(annodoc)) pind = CENTO; } if (pind == ZERO) pind = riga.tipo().perc_indetraibilita(); if (pind > ZERO) { const real ivaind = (riga.imposta(false) * pind) / CENTO; if (bill.ok()) { if (bill.is_analitico()) { TString_array conti_ind; if (find_conti_iva_indetraibile(riga, bill, conti_ind)) //qui { TGeneric_distrib esso(ivaind, decimals); init_distrib(conti_ind, esso); FOR_EACH_ARRAY_ROW(conti_ind, j, row_ind) { TRectype& rmov = mov.new_row(); rmov.put(RMOVANA_ANNOES, annoes); rmov.put(RMOVANA_CODCONTO, row_ind->get(0)); rmov.put(RMOVANA_CODCCOSTO,row_ind->get()); rmov.put(RMOVANA_CODCMS, row_ind->get()); rmov.put(RMOVANA_CODFASE, row_ind->get()); rmov.put(RMOVANA_DESCR, riga.get(RDOC_DESCR)); TImporto imp(sezione, real(esso.get())); imp.normalize(); rmov.put(RMOVANA_SEZIONE, imp.sezione()); rmov.put(RMOVANA_IMPORTO, imp.valore()); totdoc += imp; } } } } else valore += ivaind; } } if (valore.is_zero()) continue; TString_array conti; const bool ok = find_conti(riga, conti); if (!ok) { if (viswin != NULL) { TString msg; msg.format(FR("*** Riga %d: Manca il conto analitico dell'articolo '%s'"), i, (const char*)riga.get(RDOC_CODART)); viswin->add_line(msg); } _error = conto_error; can_write = false; continue; } TGeneric_distrib esso(valore, decimals); init_distrib(conti, esso); FOR_EACH_ARRAY_ROW(conti, i, row) { TRectype& rmov = mov.new_row(); rmov.put(RMOVANA_ANNOES, annoes); rmov.put(RMOVANA_CODCONTO, row->get(0)); rmov.put(RMOVANA_CODCCOSTO,row->get()); rmov.put(RMOVANA_CODCMS, row->get()); rmov.put(RMOVANA_CODFASE, row->get()); rmov.put(RMOVANA_DESCR, riga.get(RDOC_DESCR)); TImporto imp(sezione, real(esso.get())); imp.normalize(); rmov.put(RMOVANA_SEZIONE, imp.sezione()); rmov.put(RMOVANA_IMPORTO, imp.valore()); totdoc += imp; } } if (can_write && mov.rows() > 0) { totdoc.normalize(); mov.put(MOVANA_SEZIONE, totdoc.sezione()); mov.put(MOVANA_TOTDOC, totdoc.valore()); TLocalisamfile movana(LF_MOVANA); if (numreg_ca > 0) mov.rewrite(movana); else { mov.write(movana); numreg_ca = mov.get_long(MOVANA_NUMREG); doc.put(DOC_NUMREGCA, numreg_ca); } if (viswin != NULL) { msg.format(FR("--- Movimento analitico $[r,w]%ld$[n,w] del %s"), numreg_ca, datacomp.string()); viswin->add_line(msg); } } return can_write; } static bool link_handler_ana(int n, const char* nreg) { switch (n) { case 0: { TRectype mov(LF_MOVANA); mov.put(MOVANA_NUMREG, nreg); return mov.edit(); } break; default: break; } return false; } bool TContabilizzazione_analitica::elabora(TLista_documenti& doc_in, TLista_documenti& doc_out, const TDate& data_elab, bool interattivo) { const TImporto zero; TPrinter& p = printer(); p.links().add("Movimento Analitico |r|w", 0); p.setlinkhandler(link_handler_ana); TViswin v(NULL, TR("Contabilizzazione documenti in analitica"), false, true, true); v.open_modal(); for (int i = 0; i < doc_in.items(); i++) { TAnal_mov mov; if (elabora(doc_in[i], 0, &v, true, mov)) doc_in[i].stato(get_char("S4")); else break; } v.close_print(); v.close_modal(); if (v.run() == K_CTRL+'S') // Ho premuto Stampa p.print_txt(v.text()); return true; } void TContabilizzazione_analitica::init() { TConfig& cfg = ca_config(); _usepdcc = cfg.get_bool("UsePdcc"); } TContabilizzazione_analitica::TContabilizzazione_analitica() : TElaborazione(NULL), _error(no_error) { init(); } TContabilizzazione_analitica::TContabilizzazione_analitica(const TRectype& rec) : TElaborazione(rec), _error(no_error) { init(); } TContabilizzazione_analitica::~TContabilizzazione_analitica() { }