#include #include #include #include #include #include "../cg/cg2101.h" #include "celib.h" #include "ce2101.h" #include "ce4400a.h" #include "ammce.h" #include "cespi.h" //=============================================================================================== //maschera class TTrasf_mov_ce_cg_mask: public TAutomask { protected: virtual bool on_field_event(TOperable_field& o, TField_event e, long jolly); public: TTrasf_mov_ce_cg_mask():TAutomask("ce4400a") { ditta_cespiti().init_mask(*this); } }; bool TTrasf_mov_ce_cg_mask::on_field_event(TOperable_field& o, TField_event e, long jolly) { /* switch (o.dlg()) { default: break; }*/ return true; } //=============================================================================================== //Struct che serve per avere ammortamenti per categoria (Codcat|Qamm_tot|Qperse_tot) struct TSaldo_per_codice :public TSortable { TString4 _spc; int _grp, _cat; TString80 _idcespite; real _qnor, _qant, _qacc, _qperse; void add(const TRectype& rec_ammce); virtual int compare(const TSortable& s) const; const TRectype& categoria() const; int compila_rmov(const int tipo, const int riga_nor, TArray& righe_mov, TLog_report& log, const int movdett) const; int genera_righe(TArray& righe_mov, TLog_report& log, const int movdett) const; TSaldo_per_codice(const int grp, const TString4 spc, const int cat, const char* idcespite = "") : _grp(grp),_spc(spc), _cat(cat), _idcespite(idcespite) {} }; void TSaldo_per_codice::add(const TRectype& rec_ammce) { //valore totale degli ammortamenti del cespite di tipo qnor,qant,qacc che trova in AMMCE const real qnor = rec_ammce.get_real(AMMCE_QNOR); const real qant = rec_ammce.get_real(AMMCE_QANT); const real qacc = rec_ammce.get_real(AMMCE_QACC); //valore totale delle qperse del cespite che trova in AMMCE const real qperse = rec_ammce.get_real(AMMCE_QPERSE); _qnor += qnor; _qant += qant; _qacc += qacc; _qperse += qperse; } //confrontatore di saldi_per_codice int TSaldo_per_codice::compare(const TSortable& s) const { int cmp = 0; const TSaldo_per_codice& sc = (const TSaldo_per_codice&)s; cmp = _grp - sc._grp; if (cmp == 0) { cmp = _spc.compare(sc._spc); if (cmp == 0) { cmp = _cat - sc._cat; if (cmp == 0) cmp = _idcespite.compare(sc._idcespite); } } return cmp; } bool str2bill(const TString& stringona, const int pos, TBill& zio) { const int gr = atoi(stringona.mid(pos, 3)); const int co = atoi(stringona.mid(pos+3, 3)); if (co <= 0) return false; const long so = atoi(stringona.mid(pos+6, 6)); zio.set(gr, co, so); return true; } int TSaldo_per_codice::compila_rmov(const int tipo, const int riga_nor, TArray& righe_mov, TLog_report& log, const int movdett) const { int pos = 0; const char* field = "S1"; real quota; switch (tipo) { case 1: quota = _qnor; pos = 24; break; case 2: quota = _qant; pos = 36; break; case 3: quota = _qacc; pos = 48; break; case 4: quota = _qperse; pos = 0; field = "S2"; break; default: break; } if (quota <= ZERO) return -1; const TRectype& rec_cac = categoria(); const TString& stringona = rec_cac.get(field); TBill zio; if (!str2bill(stringona, pos, zio)) { if (tipo < 4) { pos = 24; if (tipo == 1 || !str2bill(stringona, pos, zio)) { TString msg; msg << TR("Manca il conto per le quote ammortamento normali della categoria ") << rec_cac.get("CODTAB"); log.log(2, msg); return -1; } } else { TString msg; msg << TR("Manca il conto per le quote perse della categoria ") << rec_cac.get("CODTAB"); log.log(2, msg); return -1; } } if (pos == 24 && riga_nor >= 0) { TRectype& rmovnor = (TRectype&)righe_mov[riga_nor]; rmovnor.add(RMV_IMPORTO, quota); return riga_nor; } TRectype* rmov = new TRectype(LF_RMOV); rmov->put(RMV_SEZIONE, "D"); rmov->put(RMV_IMPORTO, quota); //conto e descrizione dipendono dal livello di dettaglio stabilito nella configurazione del collegamento CG/CE switch (movdett) { case 0: rmov->put(RMV_DESCR, rec_cac.get("S0")); break; case 1: { const TRectype& rec_cespi = cache().get(LF_CESPI, _idcespite); rmov->put(RMV_DESCR, rec_cespi.get(CESPI_DESC)); } break; case 2: { const TRectype& rec_cespi = cache().get(LF_CESPI, _idcespite); rmov->put(RMV_DESCR, rec_cespi.get(CESPI_DESC)); bool ok = real::is_natural(_idcespite); if (ok) { const long sottoc = atol(_idcespite); ok = sottoc > 0 && sottoc < 1000000; if (ok) zio.set(zio.gruppo(), zio.conto(), sottoc); } if (!ok) { TString msg; msg.format(FR("Il codice cespite %s non e' un sottoconto valido"), (const char*)_idcespite); log.log(2, msg); } } break; default: break; } zio.put(*rmov); return righe_mov.add(rmov); } //metodo di alto livello per la compilazione delle righe contabili;chiama il metodo di basso livello.. //..compila_rmov con i parametri caso x caso int TSaldo_per_codice::genera_righe(TArray& righe_mov, TLog_report& log, const int movdett) const { const int righe_prima = righe_mov.items(); const int riga_nor = compila_rmov(1, -1, righe_mov, log, movdett); const int riga_ant = compila_rmov(2, riga_nor, righe_mov, log, movdett); const int riga_acc = compila_rmov(3, riga_nor, righe_mov, log, movdett); const int riga_persa = compila_rmov(4, -1, righe_mov, log, movdett); const int righe_dopo = righe_mov.items(); return righe_dopo - righe_prima; //messo qui tanto per poter compilare } const TRectype& TSaldo_per_codice::categoria() const { return ditta_cespiti().categoria(_grp, _spc, _cat); } //=============================================================================================== //Applicazione class TTrasf_mov_ce_cg : public TSkeleton_application { TTrasf_mov_ce_cg_mask* _mask; protected: virtual void main_loop(); virtual bool create(); virtual bool destroy(); void elabora(); void delete_old_movs(const TDate& ini_es); public: }; void TTrasf_mov_ce_cg::delete_old_movs(const TDate& ini_es) { TMovimentoPN pn; TRectype darec(LF_MOV); darec.put(MOV_DATAREG, ini_es); TString filtro; filtro.format("(PROVVIS==\"C\")"); TCursor cur_mov (&pn, filtro, 2, &darec); const long items = cur_mov.items(); cur_mov.freeze(); TProgind progind(items, "Eliminazione vecchi movimenti provvisori cespiti in corso...", false, true); for (cur_mov = 0; cur_mov.pos() < items; ++cur_mov) { progind.addstatus(1); pn.read(); pn.remove(); } } //metodo per gestire la successione degli eventi ad alto livello void TTrasf_mov_ce_cg::elabora() { //gettiamo un po' di parametri dalla maschera const long codes = _mask->get_long(F_ESERCIZIO); const TDate ini_es = _mask->get_date(F_INIZIO_ES); const TDate fine_es = _mask->get_date(F_FINE_ES); //deve accoppare i movimenti provvisori di prima nota da inizio esercizio ad oggi? if (_mask->get_bool(F_KILLOLD)) delete_old_movs(ini_es); TDate datacalc; //se il trasferimento e' definitivo la data di calcolo e' quella finale dell'esercizio selezionato, senno'... //...e' quella indicata in F_DATACALC if (_mask->get_bool(F_PROVDEF)) datacalc = _mask->get_date(F_FINE_ES); else datacalc = _mask->get_date(F_DATACALC); //programma vero e proprio (calcolo ammortamenti, selezione cespiti validi, trasferimento) TISAM_recordset cespiti("USE CESPI"); const TRecnotype nrec = cespiti.items(); //report con log errori TLog_report cont_cesp_log(TR("Contabilizzazione cespiti")); //Legge un po' di parametri dal ditta.ini che servono al tipo di calcolo TConfig config_ditta_ce(CONFIG_DITTA, "ce"); //Situazione fiscale (99,99%) o civilistica (1 suora su 1.000.000)? const int tpamm = config_ditta_ce.get_int("TPAMM"); //Tipo di calcolo da eseguire in base al dettaglio const int movdett = config_ditta_ce.get_int("MOVDETT"); //Assoc_array Categoria-QammTot-QperseTot TAssoc_array quote_per_codice; TProgind pi(nrec, TR("Ricalcolo ammortamenti in corso..."), true, true); for (int i = 0; cespiti.move_to(i); i++) { if (!pi.addstatus(1)) break; //id e categoria del cespite corrente const TString& idcespite = cespiti.get(CESPI_IDCESPITE).as_string(); const int gruppo = cespiti.get(CESPI_CODCGRA).as_int(); const TString4 specie = cespiti.get(CESPI_CODSPA).as_string(); const int codcat = cespiti.get(CESPI_CODCAT).as_int(); //calcola gli ammortamenti di tutti i cespiti; situazione presa dal config_ditta poco prima //la calc_amm pensa da sola a calcolare gli ammortamenti solo per i cespiti validi //l'ultimo parametro e' true x' il calcolo viene fatto in memoria! TCespite cespite(idcespite); if (cespite.calc_amm(tpamm, datacalc, false, true)) { //controlla le quote del cespite in questione su AMMCE const TRectype& rec_ammce = cespite.amm_pro(); //in base al tipo di dettaglio sceglie il codice dell'assoc_array //movdett=0 -> codice=codice categoria (assoc_array con record per categorie) //movdett=1;2 -> codice=idcespite (assoc_array con record per cespite) TToken_string gsc; gsc.add(gruppo); gsc.add(specie); gsc.add(codcat); if (movdett != 0) gsc.add(idcespite); TSaldo_per_codice* sc = (TSaldo_per_codice*)quote_per_codice.objptr(gsc); //se non trova il codice (categoria o cespite) lo aggiunge... if (sc == NULL) { sc = new TSaldo_per_codice(gruppo, specie, codcat, idcespite); quote_per_codice.add(gsc, sc); } //..e poi somma i valori comunque sc->add(rec_ammce); } } //for(int i... TArray saldi_ordinati; //riempie l'array saldi_ordinati con gli elementi dell'assoc quote_per_codice FOR_EACH_ASSOC_OBJECT(quote_per_codice, h, k, obj) saldi_ordinati.add(h->remove_obj()); //accoppa l'assoc quote_per_codice.destroy(); //e ordina l'array (questo assurdo giro serve perche' l'assoc non e' ordinabile) saldi_ordinati.sort(); //array con le righe movimento CG TArray righe_mov; //riempie l'array delle righe movimento CG FOR_EACH_ARRAY_ITEM(saldi_ordinati, riga, sldobj) { const TSaldo_per_codice& sld = *(const TSaldo_per_codice*)sldobj; sld.genera_righe(righe_mov, cont_cesp_log, movdett); } /*TMovimentoPN mov; mov.last(); //primo numero libero da usare come numreg long numreg = mov.curr().get_long(MOV_NUMREG) + 1;*/ TReport_book book; book.add(cont_cesp_log); book.preview(); //calcolati,se richiesti,gli ammortamenti, passa in rassegna AMMCE e AMMMV alla ricerca dei cespiti.. //..da considerare per il trasferimento vero e proprio (sono quelli } bool TTrasf_mov_ce_cg::create() { _mask = new TTrasf_mov_ce_cg_mask; return TSkeleton_application::create(); } bool TTrasf_mov_ce_cg::destroy() { delete _mask; return true; } void TTrasf_mov_ce_cg::main_loop() { KEY k = K_ENTER; while (k != K_QUIT) { k = _mask->run(); switch (k) { case K_ENTER: elabora(); break; default: break; } } } int ce4400(int argc, char* argv[]) { TTrasf_mov_ce_cg a; a.run(argc,argv,TR("Trasferimento cespiti in contabilita'")); return 0; }