#include #include #include #include #include #include #include #include #include "../ca/movana.h" #include "../ca/rmovana.h" #include "../ve/velib04.h" #include "../cg/cgsaldac.h" #include "pg0068100a.h" /////////////////////////////////////////////// // MASCHERA /////////////////////////////////////////////// class TElabollazione_HK_mask : public TAutomask { TArray_sheet* _num_sheet; TString_array _tipi_doc; protected: virtual bool on_field_event(TOperable_field& o, TField_event e, long jolly); // Costruisce lo sheet dei codici numerazione void build_num_sheet(); public: // Controlla se lo stato ed il tipo del documento sono validi e rispettano la selezione bool doc_tipo_stato_ok(const TRectype& doc); // Restituisce lo sheet con le numerazioni da elaborare TArray_sheet& num_sheet() const { return *_num_sheet; } // Constructor and Distructor TElabollazione_HK_mask(); ~TElabollazione_HK_mask(); }; TElabollazione_HK_mask::TElabollazione_HK_mask() : TAutomask("pg0068100a") { _num_sheet = new TArray_sheet(-1, -1, -4, -4, "Codici numerazione", "@1|Cod. numerazione|Descrizione@50"); } TElabollazione_HK_mask::~TElabollazione_HK_mask() { delete _num_sheet; } bool TElabollazione_HK_mask::on_field_event(TOperable_field& o, TField_event e, long jolly) { switch (o.dlg()) { case F_ELAB_COSTI: case F_ELAB_PROVV: if (e == fe_modify || e == fe_init) { const bool full = !o.empty(); if (full) build_num_sheet(); enable(DLG_USER, full); enable(DLG_OK, full && _num_sheet->one_checked()); } break; case DLG_USER: if (e == fe_button && _num_sheet->run()) { // Hai selezionato qualcosa ? allora abilita il pulsante di conferma enable(DLG_OK, _num_sheet->one_checked()); } break; default: break; } return true; } void TElabollazione_HK_mask::build_num_sheet() //(const short field) { _num_sheet->destroy(); _tipi_doc.destroy(); const TContabilizzazione_analitica contanal(get(F_ELAB_COSTI)); if (!contanal.empty()) { TToken_string t; TString4 tipo; for (int i = 0; i < TElaborazione::_max_tipi_doc_elab; i++) { tipo = contanal.tipo_iniziale(i); if (tipo.full()) { t = tipo; t.add(contanal.stato_iniziale(i)); // Stato iniziale _tipi_doc.add(t); // Aggiunge questo tipo documento alla lista } } TString s1,s2,s3; TTable num("%NUM"); for (num.first(); num.good(); num.next()) // scorre tutte le numerazioni possibili { TToken_string t,z; t.add(" "); t.add(num.get("CODTAB")); t.add(num.get("S0")); s2 = num.get("S2"); // reperisce i tipi documento validi per questa numerazione for (int x = 0; x <= s2.len(); x += 4) z.add(s2.mid(x,4)); bool found = false; for (int i = _tipi_doc.last(); !found && i >= 0; i--) found |= s2.find(_tipi_doc.row(i).get(0)) >= 0; if (found) _num_sheet->add(t); } if (_num_sheet->items() == 1) _num_sheet->check(0); } } bool TElabollazione_HK_mask::doc_tipo_stato_ok(const TRectype& doc) // Verifica che il tipo documento corrente esista tra i tipi previsti dalla elaborazione // differita selezionata { bool found = false; const TString4 tipo = doc.get(DOC_TIPODOC); const char stato = doc.get_char(DOC_STATO); const int items = _tipi_doc.items(); for (int i = 0; i < items && !found; i++) { TToken_string& t = _tipi_doc.row(i); const TString4 tipox(t.get(0)); const char statox = t.get(1)[0]; if (tipo == tipox && stato == statox) found = true; } return found; } //////////////////////////////////////////////////////////////////////////////////////////////////// // CLASSI DERIVATE DALLA TContabilizzazione_analitica (con le modifiche per il caso in questione) //////////////////////////////////////////////////////////////////////////////////////////////////// class TContabilizzazione_analitica_costi : public TContabilizzazione_analitica { TString4 _codcaus; bool _costi; TCausale * _caus; const TElabollazione_HK_mask* _msk; public: virtual bool elabora(TDocumento& doc, long numreg_cg, TViswin* viswin, bool can_write, TAnal_mov& mov, bool riclassifica_fdr_fde = true); virtual const TCausale& doc2caus(const TDocumento& doc); TContabilizzazione_analitica_costi(const TString& codcaus, const TElabollazione_HK_mask* msk, const char* cod = NULL, bool costi = true) : TContabilizzazione_analitica(cod), _codcaus(codcaus), _msk(msk), _costi(costi), _caus(NULL) {} TContabilizzazione_analitica_costi(const TString& codcaus, const TElabollazione_HK_mask* msk, const TRectype& rec, bool costi = true) : TContabilizzazione_analitica(rec), _codcaus(codcaus), _msk(msk), _costi(costi), _caus(NULL) {} virtual ~TContabilizzazione_analitica_costi() {} }; const TCausale& TContabilizzazione_analitica_costi::doc2caus(const TDocumento& doc) { if (_caus == NULL) _caus = new TCausale(_codcaus); return *_caus; } bool TContabilizzazione_analitica_costi::elabora(TDocumento& doc, long numreg_cg, TViswin* viswin, bool can_write, TAnal_mov& mov, bool riclassifica_fdr_fde) { TDate datareg, datacomp, datadoc; int annoes = 0; TString descr, msg, codcaus; TCausale caus(_codcaus); datadoc = doc.get(DOC_DATADOC); datareg = datacomp = datadoc; annoes = esercizi().date2esc(datareg); 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; } //..e quindi dovrebbe sempre bastare sezione = 'D' char sezione = 'D'; //questo non dovrebbe mai capitare!... if (doc.is_nota_credito()) sezione = 'A'; const int decimals = TCurrency::get_firm_dec(); //in caso di righe doc di costo -> sul doc usa numregca, in caso di righe provvigione usa un campo virtuale.. //..NUMREGCAPR; questo č per poter avere i movimenti distinti (costi - provvigioni) e per poter collegare.. //..movana e doc di origine nei 2 versi TString field_name(DOC_NUMREGCA); if (!_costi) field_name = "NUMREGCAPR"; long numreg_ca = doc.get_long(field_name); 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); mov.put(MOVANA_CODCAUS, caus.codice()); 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, const int righe_doc = doc.physical_rows(); for (int r = 1; r <= righe_doc; r++) { const TRiga_documento& riga = doc[r]; bool pareggio = false; // salto descrizioni, e omaggi if (riga.is_descrizione()) continue; real valore; if (_costi) { const real qta = riga.get(RDOC_QTA); const real costo = riga.articolo().get_real(ANAMAG_ULTCOS1); valore = qta * costo; } else valore = riga.provvigione(); if (valore.is_zero()) continue; if (tiva != iva_vendite && !riga.is_sconto()) { const TString4 tipodet = riga.get(RDOC_TIPODET); int td; const real pind = indetraibile_al(tipodet, caus, datareg.year(), td); if (pind > ZERO) { const real imposta = riga.iva().imposta(valore); const real ivaind = (imposta * pind) / CENTO; if (bill.ok()) { if (bill.is_analitico()) { TString_array conti_ind; const char tipomov = mov.get_char(MOVANA_TIPOMOV); if (find_conti_iva_indetraibile(riga, bill, conti_ind, annoes, tipomov, pareggio)) //qui { TGeneric_distrib esso(ivaind, decimals); init_distrib(conti_ind, esso, pareggio); 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)); const bool negative = pareggio && j > 0; const bool totale = pareggio && j == 0; TImporto imp(sezione, totale ? ivaind : real(esso.get())); if (negative) imp.swap_section(); 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 char tipomov = mov.get_char(MOVANA_TIPOMOV); const bool ok = find_conti(riga, conti, annoes, riclassifica_fdr_fde, tipomov, pareggio); if (!ok) { if (viswin != NULL) { TString msg; msg.format(FR("*** Riga %d: Manca il conto analitico dell'articolo '%s'"), r, (const char*)riga.get(RDOC_CODART)); viswin->add_line(msg); } //_error = conto_error; can_write = false; continue; } if (riga.is_omaggio()) { const int gruppo = _msk->get_int(F_GRUPPO); const int conto = _msk->get_int(F_CONTO); const long sottoconto = _msk->get_int(F_SOTTOCONTO); TString conto_omaggio; conto_omaggio.format("%03d%03d%06ld", gruppo, conto, sottoconto); TToken_string& riga_conti = conti.row(0); riga_conti.add(conto_omaggio, 0); } TGeneric_distrib esso(valore, decimals); init_distrib(conti, esso, pareggio); 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)); const bool negative = pareggio && i > 0; const bool totale = pareggio && i == 0; TImporto imp(sezione, totale ? valore : real(esso.get())); if (negative) imp.swap_section(); 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(field_name, 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; } class TContabilizzazione_analitica_provvigioni : public TContabilizzazione_analitica_costi { public: TContabilizzazione_analitica_provvigioni(const TString& codcaus, const TElabollazione_HK_mask* msk, const char* cod = NULL) : TContabilizzazione_analitica_costi(codcaus, msk, cod, false) {} TContabilizzazione_analitica_provvigioni(const TString& codcaus, const TElabollazione_HK_mask* msk, const TRectype& rec) : TContabilizzazione_analitica_costi(codcaus, msk, rec, false) {} virtual ~TContabilizzazione_analitica_provvigioni() {} }; ////////////////////////////////////////////// // APPLICAZIONE ///////////////////////////////////////////// // TElabollazione_HK // Applicazione di contabilizzazione documenti class TElabollazione_HK_app : public TSkeleton_application { TElabollazione_HK_mask* _msk; virtual bool check_autorization() const {return false;} virtual const char * extra_modules() const {return "ve";} protected: // TApplication // Contabilizza i documenti void contabilize(); public: virtual bool create(); virtual bool destroy(); virtual void main_loop(); }; void TElabollazione_HK_app::contabilize() { //Prende i dati dalla maschera (date,sheet numerazioni) const TDate data_ini = _msk->get_date(F_DATA_INI); int year_from = data_ini.year(); const TDate data_fine = _msk->get_date(F_DATA_FIN); int year_to = data_fine.year(); const TDate data_reg(TODAY); TArray_sheet& num_sheet = _msk->num_sheet(); const long items = num_sheet.items(); //Relazione su LF_DOC TRelation doc_rel(LF_DOC); TRectype da(LF_DOC); TRectype a(LF_DOC); TString16 codnum; TString msg, filt_expr; TToken_string nums; // Compone la lista dei documenti da elaborare for (long i = 0L; i < items; i++) // Scorre per tutte le numerazioni dello sheet { if (num_sheet.checked(i)) // Costruisce una espressione sul codice numerazione: "CODNUM="x0" || CODNUM="x1" || ..." { codnum = num_sheet.row(i).get(1); filt_expr << "(CODNUM=\""; filt_expr << codnum << "\")||"; nums.add(codnum); } } filt_expr.rtrim(2); da.put(DOC_DATADOC, data_ini); da.put(DOC_PROVV, "D"); da.put(DOC_ANNO, year_from); a.put(DOC_DATADOC, data_fine); a.put(DOC_PROVV, "D"); a.put(DOC_ANNO, year_to); // Se ho una sola numerazione ottimizzo la setregion! if (nums.items() == 1) { da.put(DOC_CODNUM, nums); a.put(DOC_CODNUM, nums); } // Cursore complessivo con limiti di data (chiave 3). Viene sfruttata l'ottimizzazione // sulla costruzione dei cursori nel caso i campi presenti nell'espressione siano campi // chiave, nel nostro caso CODNUM soddisfa i requisiti. TCursor doc_cur(&doc_rel, filt_expr, 3, &da, &a); const TRecnotype cur_items = doc_cur.items(); if (cur_items > 0) { TLista_documenti lista_in, lista_out; doc_cur.freeze(); msg = "Selezione documenti dal "; msg << data_ini.string() << " al "; msg << data_fine.string(); TProgind p(cur_items, msg, false, true); const TRectype& cur_rec = doc_cur.curr(); // Scorre tutti i documenti che rientrano nell'intervallo selezionato for (doc_cur = 0; doc_cur.pos() < cur_items; ++doc_cur) { p.addstatus(1); // controlla che il tipo documento e lo stato siano coerenti con la ELD selezionata if (nums.get_pos(cur_rec.get(DOC_CODNUM)) >= 0 && _msk->doc_tipo_stato_ok(cur_rec)) { TDocumento* doc = new TDocumento; if (doc->read(doc_cur.curr()) == NOERR) // legge il documento lista_in.add(doc); // Viene aggiunto alla lista dei documenti else delete doc; } } //E finalmente fa l'agognata elaborazione!!!!! TString16 elaborazione_costi = _msk->get(F_ELAB_COSTI); TContabilizzazione_analitica_costi contanal_costi(_msk->get(F_CAUS_COSTI), _msk, elaborazione_costi); contanal_costi.TContabilizzazione_analitica::elabora(lista_in, lista_out, data_reg); if (contanal_costi.processed_docs() > 0L) message_box(FR("Totale documenti di costo contabilizzati: %ld"), contanal_costi.processed_docs()); TString16 elaborazione_provv = _msk->get(F_ELAB_PROVV); TContabilizzazione_analitica_provvigioni contanal_provv(_msk->get(F_CAUS_PROVV), _msk, elaborazione_provv); contanal_provv.TContabilizzazione_analitica::elabora(lista_in, lista_out, data_reg); if (contanal_provv.processed_docs() > 0L) message_box(FR("Totale documenti di provvigione contabilizzati: %ld"), contanal_provv.processed_docs()); } else warning_box(TR("Non vi sono documenti da contabilizzare per le numerazioni selezionate.")); xvtil_statbar_set(""); } bool TElabollazione_HK_app::create() { //se non ha le vendite e l'analitica č impossibile da utilizzare if (!has_module(VEAUT) || !has_module(CAAUT)) return error_box(TR("Modulo non autorizzato")); //open_files(LF_TABCOM, LF_TAB, LF_DOC, LF_RIGHEDOC, LF_MOVANA, LF_RMOVANA, 0); _msk = new TElabollazione_HK_mask(); return TSkeleton_application::create(); } bool TElabollazione_HK_app::destroy() { if (_msk) delete _msk; return TSkeleton_application::destroy(); } void TElabollazione_HK_app::main_loop() { while (_msk->run() == K_ENTER) contabilize(); } int pg0068100 (int argc, char **argv) { TElabollazione_HK_app a; a.run(argc,argv, TR("Contabilizzazione Hair Kulture")); return true; }