diff --git a/ce/ce4400.cpp b/ce/ce4400.cpp index 5f0392fe4..60b6e4fde 100755 --- a/ce/ce4400.cpp +++ b/ce/ce4400.cpp @@ -9,6 +9,7 @@ #include "../ca/calib01.h" #include "../ca/calib02.h" +#include "../ca/movana.h" #include "../ca/rmovana.h" #include "../cg/cg2101.h" @@ -90,7 +91,7 @@ bool TContabilizza_ce_mask::on_field_event(TOperable_field& o, TField_event e, l //============================================================================================== // Metodi static che servono in giro -static long get_new_numreg() +static long get_new_numreg_CG() { TLocalisamfile mov(LF_MOV); mov.last(); @@ -98,6 +99,13 @@ static long get_new_numreg() return mov.curr().get_long(MOV_NUMREG) + 1; } +static long get_new_numreg_CA() +{ + TLocalisamfile movana(LF_MOVANA); + movana.last(); + return movana.curr().get_long(MOVANA_NUMREG) + 1; +} + static void fill_head(TRectype& head, const TDate& datacomp, const TDate& datareg, const long numreg, const TString& codcaus, const bool definitivo, const TString& numdoc, const TString& tipodoc, const TDate& datadoc) @@ -173,6 +181,7 @@ struct TSaldo_per_codice : public TSortable TString4 _spc; int _grp, _cat; TString16 _idcespite; + TAnal_bill _conto; real _qnor, _qant, _qacc;//, _qperse; void add(const TRectype& rec_ammce); @@ -531,6 +540,9 @@ int TSaldo_per_codice::compila_rmovana_CA(const int tipo, const int riga_nor, TA break; } rmovana->put(RMOVANA_CODCONTO, zio.conto()); + rmovana->put(RMOVANA_CODCCOSTO, _conto.costo()); + rmovana->put(RMOVANA_CODCMS, _conto.commessa()); + rmovana->put(RMOVANA_CODFASE, _conto.fase()); return righe_movana.add(rmovana); } @@ -702,7 +714,7 @@ void TPlus_minus::genera_mov_elim_ven(const TDate& datareg, const TDate& datacom } //Riempie i campi della testata movimento - long numreg = get_new_numreg(); + long numreg = get_new_numreg_CG(); //attenzione!! ci possono essere piu' movimenti per lo stesso cespite!!! -> ciclo sui movce.items() for (int i = 0; i < _movce.items(); i++) @@ -903,13 +915,15 @@ protected: virtual bool destroy(); void elabora(); //metodo di alto livello per la gestione ordinata del casino - void contabilizza_CG(TAssoc_array& quote_per_codice, TLog_report& cont_cesp_log); //contabilizza ammortamenti in CG - void contabilizza_CA(TAssoc_array& anal_quote_per_codice, TLog_report& cont_cesp_log); //contabilizza ammortamenti in CA - void ordina_saldi(TAssoc_array& quote, TArray& saldi_ordinati); //prende quote e restituisce saldi_ordinati sortato - void genera_mov_CG(TArray& righe_mov, TLog_report& log); //genera movimenti CG - void genera_movana_CA(TArray& righe_movana, TLog_report& log); //genera movimenti CA + + long contabilizza_CG(TAssoc_array& quote_per_codice, TLog_report& cont_cesp_log); //contabilizza ammortamenti in CG + void contabilizza_CA(const long first_numreg_CG, TAssoc_array& anal_quote_per_codice, TLog_report& cont_cesp_log); //contabilizza ammortamenti in CA + long genera_mov_CG(TArray& righe_mov, TLog_report& log); //genera movimenti CG + void genera_movana_CA(const long first_numreg_CG, TArray& righe_movana, TLog_report& log); //genera movimenti CA + void delete_old_movs(const TDate& ini_es); //accoppa i movimenti provvisori (sia i CG che i CA collegati) - //void delete_old_movanas(const TDate& ini_es, const TString& codcaus); + void ordina_saldi(TAssoc_array& quote, TArray& saldi_ordinati); //prende quote e restituisce saldi_ordinati sortato + void fill_salcecms_default(const TString& idcespite, const int codes, TRectype& rec_salcecms) const; public: @@ -958,7 +972,7 @@ void TContabilizza_ce::delete_old_movs(const TDate& ini_es) //metodo per la generazione di movimenti contabili con righe per categoria -void TContabilizza_ce::genera_mov_CG(TArray& righe_mov, TLog_report& log) +long TContabilizza_ce::genera_mov_CG(TArray& righe_mov, TLog_report& log) { //Parametri config ditta cespiti const TString4 codcaus = _config_ditta_ce->get("COAUQU"); @@ -971,7 +985,8 @@ void TContabilizza_ce::genera_mov_CG(TArray& righe_mov, TLog_report& log) const bool definitivo = _mask->get_bool(F_PROVDEF); //Riempie i campi della testata movimento - long numreg = get_new_numreg(); + const long first_numreg = get_new_numreg_CG(); + long numreg = first_numreg; TMovimentoPN_CE pn; TRectype& head = pn.curr(); @@ -979,6 +994,8 @@ void TContabilizza_ce::genera_mov_CG(TArray& righe_mov, TLog_report& log) fill_head(head, datacomp, datareg, numreg, codcaus, definitivo, "", "", NULLDATE); head.put(MOV_DESCR, TR("Rilevazione quote amm. cespiti per categoria")); + //massimo numero consentito di righe per movimento + const int max_cg_rows = _has_ca ? 995 : 95; //Procedura di inserimento delle righe del movimento TImporto fondo; //aggiunge all'array con tutte le righe mov determinate con il calcolo una riga senza gr/sp/cat @@ -994,7 +1011,7 @@ void TContabilizza_ce::genera_mov_CG(TArray& righe_mov, TLog_report& log) //Controllo dell'eventuale cambio di categoria. Lo fa confrontando la riga iesima appena caricata con.. //..la riga i-1esima (la precedente,insomma) //Se la categoria e' cambiata... - if (i > 0 && (rigamov.compare((const TRigamov&)righe_mov[i-1]) != 0 || pn.cg_items() > 95)) + if (i > 0 && (rigamov.compare((const TRigamov&)righe_mov[i-1]) != 0 || pn.cg_items() > max_cg_rows)) { //crea una nuova riga per metterci il fondo;in questo momento la riga e' aggiunta ma va riempita!! TRectype& riga_fondo = pn.nuova_riga(); @@ -1054,27 +1071,116 @@ void TContabilizza_ce::genera_mov_CG(TArray& righe_mov, TLog_report& log) fondo += imp_riga; pn.nuova_riga(rigamov); } //for(inti=0;... - + + return first_numreg; } -void TContabilizza_ce::genera_movana_CA(TArray& righe_movana, TLog_report& log) +void TContabilizza_ce::genera_movana_CA(const long first_numreg_CG, TArray& righe_movana, TLog_report& log) { + //generazione dei movimenti analitci (collegati a quelli contabili) + //Parametri config ditta cespiti + const TString4 codcaus = _config_ditta_ce->get("COAUQU"); + const int movdett = _config_ditta_ce->get_int("MOVDETT"); + + //Parametri maschera + const int annoes = _mask->get_int(F_ESERCIZIO); + const TDate fine_es = _mask->get_date(F_FINE_ES); + const TDate datareg = _mask->get_date(F_DATAREG); + const TDate datacomp = min(fine_es, datareg); + const bool definitivo = _mask->get_bool(F_PROVDEF); + + //Riempie i campi della testata movimento analitico + long numregcg = first_numreg_CG; + long numregca = get_new_numreg_CA(); + //movimento analitico che sarà generato + TAnal_mov movana; + + movana.put(MOVANA_NUMREG, numregca); + movana.put(MOVANA_ANNOES, annoes); + movana.put(MOVANA_DATAREG, datareg); + movana.put(MOVANA_DATACOMP, datacomp); + movana.put(MOVANA_DATAFCOMP, datacomp); + + movana.put(MOVANA_DESCR, TR("Rilevazione quote amm. cespiti per categoria")); + movana.put(MOVANA_TIPOMOV, ""); + movana.put(MOVANA_CODCAUS, codcaus); + + movana.put(MOVANA_NUMREGCG, numregcg); //primo movana corrispondente al primo mov + + righe_movana.add(new TRigamov(0, EMPTY_STRING, 0, true)); + + TImporto totale_movana; + + //Ciclo su tutte le righe dell'array delle righe movana. + for (int i = 0; i < righe_movana.items(); i++) + { + const TRigamov& rmovana = (const TRigamov&)righe_movana[i]; + + //Controllo dell'eventuale cambio di categoria. Lo fa confrontando la riga iesima appena caricata con.. + //..la riga i-1esima (la precedente,insomma) + //Se la categoria e' cambiata... + if (i > 0 && (rmovana.compare((const TRigamov&)righe_movana[i-1]) != 0)) + { + //la descrizione viene dalla categoria precedente, visto che l'ha appena cambiata + const TRigamov& prev_rmovana = (const TRigamov&)righe_movana[i-1]; + const TString descat = prev_rmovana.descr_categoria(); + + if (i == righe_movana.last() || movdett > 0) + { + if (movdett > 0) //se va per cespite la descrizione cambia per ogni movimento in base alla categoria + { + TString desc; + desc << TR("Quote amm. ") << descat; + desc.cut(50); + movana.put(MOVANA_DESCR, desc); + } + //prepara l'importo totale + totale_movana.normalize(); + movana.put(MOVANA_SEZIONE, totale_movana.sezione()); + movana.put(MOVANA_TOTDOC, totale_movana.valore()); + totale_movana.reset(); + //scrive il movana + TLocalisamfile fmovana(LF_MOVANA); + int err = movana.write(fmovana); + + if (err != NOERR) + { + TString msg; + msg << TR("Impossibile registrare il movimento analitico ") << numregca << "\n"; + log.log(2, msg); + } + else + { + TString msg; + msg << TR("Registrato movimento analitico ") << numregca << TR(" categoria ") << descat << "\n"; + log.log(0, msg); + } + + movana.body().destroy_rows(); //ne elimina le righe per poter ricominciare + + movana.put(MOVANA_NUMREG, ++numregca); //nuova testata per nuovo movimento + movana.put(MOVANA_NUMREGCG, ++numregcg); //deve incrementare anche il numregcg + + } //if (i == righe_movana.last()... + } //if (i > 0 && (rmovana.compare((const.... (cambio categoria) + + //al cambio categoria va aggiunta una nuova riga al movana + TRectype& new_rmovana = movana.new_row(); //aggiunge una nuova riga analitica + new_rmovana = rmovana; + new_rmovana.put(RMOVANA_ANNOES, annoes); + new_rmovana.put(RMOVANA_NUMREG, numregca); + new_rmovana.put(RMOVANA_NUMRIG, movana.body().rows()); + TImporto importo_riga(new_rmovana.get_char(RMOVANA_SEZIONE), new_rmovana.get_real(RMOVANA_IMPORTO)); + totale_movana += importo_riga; + + } //for (int i = 0;... (giro delle righe_movana) + } -void TContabilizza_ce::ordina_saldi(TAssoc_array& quote, TArray& saldi_ordinati) -{ - //riempie l'array saldi_ordinati con gli elementi dell'assoc quote - FOR_EACH_ASSOC_OBJECT(quote, h, k, obj) - saldi_ordinati.add(h->remove_obj()); - //accoppa l'assoc - quote.destroy(); - //e ordina l'array per categorie e cespite (questo assurdo giro serve perche' l'assoc non e' ordinabile) - saldi_ordinati.sort(); -} //metodo che gestisce la creazione dei movimenti CG dovuti ad ammortamenti -void TContabilizza_ce::contabilizza_CG(TAssoc_array& quote_per_codice, TLog_report& cont_cesp_log) +long TContabilizza_ce::contabilizza_CG(TAssoc_array& quote_per_codice, TLog_report& cont_cesp_log) { TArray saldi_ordinati; ordina_saldi(quote_per_codice, saldi_ordinati); @@ -1097,11 +1203,15 @@ void TContabilizza_ce::contabilizza_CG(TAssoc_array& quote_per_codice, TLog_repo //..uno o piu' movimenti di prima nota //In base al movdett li creera' con righe per categoria o per cespite ma con fondi per categoria //E' un metodo semimagico! - genera_mov_CG(righe_mov, cont_cesp_log); + const long first_numreg_CG = genera_mov_CG(righe_mov, cont_cesp_log); + + return first_numreg_CG; } + + //metodo che gestisce la creazione dei movimenti CA dovuti ad ammortamenti -void TContabilizza_ce::contabilizza_CA(TAssoc_array& anal_quote_per_codice, TLog_report& cont_cesp_log) +void TContabilizza_ce::contabilizza_CA(const long first_numreg_CG, TAssoc_array& anal_quote_per_codice, TLog_report& cont_cesp_log) { TArray anal_saldi_ordinati; ordina_saldi(anal_quote_per_codice, anal_saldi_ordinati); @@ -1121,7 +1231,37 @@ void TContabilizza_ce::contabilizza_CA(TAssoc_array& anal_quote_per_codice, TLog const int nrighmovana = righe_movana.items(); //metodo per la creazione del/dei movana analitici - genera_movana_CA(righe_movana, cont_cesp_log); + genera_movana_CA(first_numreg_CG, righe_movana, cont_cesp_log); +} + + +void TContabilizza_ce::ordina_saldi(TAssoc_array& quote, TArray& saldi_ordinati) +{ + //riempie l'array saldi_ordinati con gli elementi dell'assoc quote + FOR_EACH_ASSOC_OBJECT(quote, h, k, obj) + saldi_ordinati.add(h->remove_obj()); + //accoppa l'assoc + quote.destroy(); + //e ordina l'array per categorie e cespite (questo assurdo giro serve perche' l'assoc non e' ordinabile) + saldi_ordinati.sort(); +} + + +void TContabilizza_ce::fill_salcecms_default(const TString& idcespite, const int codes, TRectype& rec_salcecms) const +{ + TString4 anno; + anno << codes; + const TRectype& rec_cce = cache().get("CCE", anno); + const TString& codcdc = rec_cce.get("S2"); + const TString& codcms = rec_cce.get("S3"); + const TString& codfase = rec_cce.get("S4"); + rec_salcecms.put(SALCECMS_IDCESPITE, idcespite); + rec_salcecms.put(SALCECMS_CODES, codes); + rec_salcecms.put(SALCECMS_NRIGA, 1); + rec_salcecms.put(SALCECMS_CODCDC, codcdc); + rec_salcecms.put(SALCECMS_CODCMS, codcms); + rec_salcecms.put(SALCECMS_CODFASE, codfase); + rec_salcecms.put(SALCECMS_PERCUTIL, CENTO); } @@ -1239,77 +1379,67 @@ void TContabilizza_ce::elabora() key.add(idcespite); key.add(codes); TRecord_array righe_salcecms(key, LF_SALCECMS); - //se il cespite, nell'esercizio selezionato, non ha manco un record in salcecms -> si assegna la chiave.. - //..di default di salcecms, che si trova nella tabella CCE dell'esercizio cespite in questione - if (righe_salcecms.rows() == 0) + + // calcolo percentuale totale di utilizzo (può essere < 100) + real percutil_tot; + for (int i = righe_salcecms.last_row(); i > 0; i = righe_salcecms.pred_row(i)) { - TString4 anno; - anno << codes; - const TRectype& rec_cce = cache().get("CCE", anno); - const TString& codcdc = rec_cce.get("S2"); - const TString& codcms = rec_cce.get("S3"); - const TString& codfase = rec_cce.get("S4"); - TRectype rec_salcecms_default(LF_SALCECMS); - rec_salcecms_default.put(SALCECMS_IDCESPITE, idcespite); - rec_salcecms_default.put(SALCECMS_CODES, codes); - rec_salcecms_default.put(SALCECMS_NRIGA, 1); - rec_salcecms_default.put(SALCECMS_CODCDC, codcdc); - rec_salcecms_default.put(SALCECMS_CODCMS, codcms); - rec_salcecms_default.put(SALCECMS_CODFASE, codfase); - rec_salcecms_default.put(SALCECMS_PERCUTIL, CENTO); - //aggiunge al record_array vuoto il record standard - righe_salcecms.add_row(rec_salcecms_default); + const TRectype& curr_salcecms_line = righe_salcecms.row(i); + const real percutil = curr_salcecms_line.get_real(SALCECMS_PERCUTIL); + percutil_tot += percutil; } - //se il record_array ha un solo elemento (99% dei casi) è inutile impazzire... - if (righe_salcecms.rows() == 1) + // Aggiunge una eventuale ripartizione sulla commessa di default (GENSPA) per raggiungere 100 + if (percutil_tot < CENTO) { - const TRectype& curr_salcecms_line = righe_salcecms.row(1); + if (percutil_tot > ZERO) + int cazzone = 1; + + TRectype rec_salcecms_tappo(LF_SALCECMS); + fill_salcecms_default(idcespite, codes, rec_salcecms_tappo); + rec_salcecms_tappo.put(SALCECMS_NRIGA, righe_salcecms.rows() + 1); + rec_salcecms_tappo.put(SALCECMS_PERCUTIL, CENTO - percutil_tot); + //aggiunge al record_array il record standard con la % per arrivare a 100% + righe_salcecms.add_row(rec_salcecms_tappo); + } + + // Inizializza i distrib con le percentuali di utilizzo + TGeneric_distrib d_qnor(rec_ammce.get_real(AMMCE_QNOR), 2); + TGeneric_distrib d_qacc(rec_ammce.get_real(AMMCE_QACC), 2); + TGeneric_distrib d_qant(rec_ammce.get_real(AMMCE_QANT), 2); + + for (int i = righe_salcecms.last_row(); i > 0; i = righe_salcecms.pred_row(i)) + { + const TRectype& curr_salcecms_line = righe_salcecms.row(i); + const real percutil = curr_salcecms_line.get_real(SALCECMS_PERCUTIL); + d_qnor.add(percutil); + d_qacc.add(percutil); + d_qant.add(percutil); + } + + // Ricava le quote di utilizzo in base alle perventuali precedenti + for (int i = righe_salcecms.last_row(); i > 0; i = righe_salcecms.pred_row(i)) + { + const TRectype& curr_salcecms_line = righe_salcecms.row(i); key = gsc; key.add(curr_salcecms_line.get(SALCECMS_CODCDC)); key.add(curr_salcecms_line.get(SALCECMS_CODCMS)); key.add(curr_salcecms_line.get(SALCECMS_CODFASE)); + TSaldo_per_codice* anal_sc = (TSaldo_per_codice*)anal_quote_per_codice.objptr(key); - //se non trova il codice (categoria o cespite) lo aggiunge... if (anal_sc == NULL) { anal_sc = new TSaldo_per_codice(gruppo, specie, codcat, idcespite); - quote_per_codice.add(key, anal_sc); + anal_sc->_conto.set_conto(key.get(0)); + anal_sc->_conto.set_costo(key.get()); + anal_sc->_conto.set_commessa(key.get()); + anal_sc->_conto.set_fase(key.get()); + anal_quote_per_codice.add(key, anal_sc); } - anal_sc->add(rec_ammce); - } - else //senno' impazziamo!... - { - TGeneric_distrib d_qnor(rec_ammce.get_real(AMMCE_QNOR), 2); - TGeneric_distrib d_qacc(rec_ammce.get_real(AMMCE_QACC), 2); - TGeneric_distrib d_qant(rec_ammce.get_real(AMMCE_QANT), 2); - - for (int i = righe_salcecms.last_row(); i > 0; i = righe_salcecms.pred_row(i)) - { - const TRectype& curr_salcecms_line = righe_salcecms.row(i); - const real percutil = curr_salcecms_line.get_real(SALCECMS_PERCUTIL); - d_qnor.add(percutil); - d_qacc.add(percutil); - d_qant.add(percutil); - } - for (int i = righe_salcecms.last_row(); i > 0; i = righe_salcecms.pred_row(i)) - { - const TRectype& curr_salcecms_line = righe_salcecms.row(i); - key = gsc; - key.add(curr_salcecms_line.get(SALCECMS_CODCDC)); - key.add(curr_salcecms_line.get(SALCECMS_CODCMS)); - key.add(curr_salcecms_line.get(SALCECMS_CODFASE)); - - TSaldo_per_codice* anal_sc = (TSaldo_per_codice*)anal_quote_per_codice.objptr(key); - if (anal_sc == NULL) - { - anal_sc = new TSaldo_per_codice(gruppo, specie, codcat, idcespite); - anal_quote_per_codice.add(key, anal_sc); - } - anal_sc->_qnor += d_qnor.get(); - anal_sc->_qacc += d_qacc.get(); - anal_sc->_qant += d_qant.get(); - } //for(int i... - } //else(if(righe_salcecms == 1... + anal_sc->_qnor += d_qnor.get(); + anal_sc->_qacc += d_qacc.get(); + anal_sc->_qant += d_qant.get(); + } //for(int i... + } //if(_has_ca)... } //if (cespite.calc_amm(tpamm,... @@ -1319,7 +1449,7 @@ void TContabilizza_ce::elabora() // 2) Generazione movimenti CG da ammortamenti cespiti //---------------------------------------------------------------- //contabilizzazione in CG - contabilizza_CG(quote_per_codice, cont_cesp_log); + const long first_numreg_CG = contabilizza_CG(quote_per_codice, cont_cesp_log); // 3) Generazione movimenti CG da movimenti cespiti di vendita/eliminazione @@ -1342,7 +1472,7 @@ void TContabilizza_ce::elabora() //---------------------------------------------------------- //contabilizzazione in CA if (_has_ca) - contabilizza_CA(anal_quote_per_codice, cont_cesp_log); + contabilizza_CA(first_numreg_CG, anal_quote_per_codice, cont_cesp_log); // 5) stampa il log degli errori //---------------------------------------