#include #include #include #include #include #include #include #include #include "../ca/calib01.h" #include "../ca/calib02.h" #include "../ca/movana.h" #include "../ca/rmovana.h" #include "../cg/cg2101.h" #include "../cg/cglib02.h" #include "celib.h" #include "ce2101.h" #include "ce4400a.h" #include "ammce.h" #include "cespi.h" #include "movam.h" #include "movce.h" #include "salcecms.h" //=============================================================================================== //maschera class TContabilizza_ce_mask: public TAutomask { protected: virtual bool on_field_event(TOperable_field& o, TField_event e, long jolly); public: TContabilizza_ce_mask():TAutomask("ce4400a") { ditta_cespiti().init_mask(*this); } }; bool TContabilizza_ce_mask::on_field_event(TOperable_field& o, TField_event e, long jolly) { switch (o.dlg()) { case F_PROVDEF: if (e == fe_modify) { const char definitivo = o.get()[0]; if (definitivo == 'X') { TEsercizi_contabili esc; int anno = get_int(F_ESERCIZIO); TDate dal, al; if (esc.code2range(anno, dal, al)) { set(F_DATACALC, al); disable(F_DATACALC); } else return error_box("Esercizio non corretto!"); } else { enable(F_DATACALC); const TDate today(TODAY); set(F_DATACALC, today); } } break; case F_DATACALC: if (e == fe_close) { const TDate data_fine_es = get(F_FINE_ES); const TDate data_ini_es = get(F_INIZIO_ES); TDate datacalc = o.get(); if (datacalc < data_ini_es) return error_box("La data di calcolo deve essere pari o successiva alla data inizio dell'esercizio selezionato"); if (!datacalc.ok()) { datacalc = data_fine_es; o.set(datacalc.string()); } if (datacalc < data_ini_es || datacalc > data_fine_es) return error_box(TR("La data di calcolo deve appartenere all'esercizio selezionato!")); } break; case F_DATAREG: if (e == fe_modify || e == fe_close) { const int ese = get_int(F_ESERCIZIO); TDate datalim; TEsercizi_contabili esc; const int nesen = esc.next(ese); if (nesen > 0) { datalim = esc[nesen].fine(); } else { datalim = esc[ese].fine(); datalim.addyear(1); } TDate datareg = o.get(); if (datareg > datalim) return error_box(FR("La data registrazione deve essere inferiore al %s"), datalim.string()); //solo in caso di trasferimento definitivo, sennò, se si sceglie una datareg nel futuro rispetto alla data di sistema,.. //..il movimento contabile generato non si può aprire con Campo in CG a meno di cambiare la data si sistema operativo if (datareg < get_date(F_DATACALC) && get_bool(F_PROVDEF)) return error_box("La data di registrazione non puo' essere inferiore alla data di calcolo"); } default: break; } return true; } //============================================================================================== // Metodi static che servono in giro static long get_new_numreg_CG() { TLocalisamfile mov(LF_MOV); mov.last(); //primo numero libero da usare come 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) { TEsercizi_contabili esc; const int codes = esc.date2esc(datacomp); head.put(MOV_ANNOES, codes); head.put(MOV_NUMREG, numreg); head.put(MOV_DATAREG, datareg); head.put(MOV_DATACOMP, datacomp); head.put(MOV_CODCAUS, codcaus); //campi dei soli movimenti di vendita/eliminazione head.put(MOV_NUMDOC, numdoc); head.put(MOV_TIPODOC, tipodoc); head.put(MOV_DATADOC, datadoc); if (!definitivo) head.put(MOV_PROVVIS, 'C'); } //=============================================================================================== //Rectype da utilizzare per la creazione delle righe movimento contabili. Deriva da LF_RMOV ma ha.. //..3 valori in piu' (gruppo,specie,categoria) che servono per gli ordinamenti in fase di generazione.. //..movimenti contabili class TRigamov : public TRectype { TString4 _spc; int _grp, _cat; public: virtual int compare(const TSortable& s) const; const TRectype& categoria() const; const TString& descr_categoria() const; TRigamov(const int grp, const TString& spc, const int cat, bool is_anal = false) : TRectype(is_anal ? LF_RMOVANA : LF_RMOV) { _grp = grp; _spc = spc; _cat = cat; } }; const TRectype& TRigamov::categoria() const { return ditta_cespiti().categoria(_grp, _spc, _cat, true); } const TString& TRigamov::descr_categoria() const { TString& wrkstring = get_tmp_string(); wrkstring << _grp << ' ' << _spc << ' ' << _cat << ' ' ; wrkstring << ditta_cespiti().categoria(_grp, _spc, _cat, false).get("S0"); return wrkstring; } //confrontatore di saldi_per_codice int TRigamov::compare(const TSortable& s) const { int cmp = 0; const TRigamov& sc = (const TRigamov&)s; cmp = _grp - sc._grp; if (cmp == 0) { cmp = _spc.compare(sc._spc); if (cmp == 0) cmp = _cat - sc._cat; } return cmp; } //=============================================================================================== //Struct che serve per avere ammortamenti per categoria (Codcat|Qamm_tot|Qperse_tot) 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); bool use_pdcc() const; virtual int compare(const TSortable& s) const; const TRectype& categoria() const; const TString& descr_categoria() const; int trova_quota_e_conto_CG(const int tipo, real& quota, TBill& zio, TLog_report& log) const; int trova_quota_e_conto_CA(const int tipo, real& quota, TAnal_bill& zio, TLog_report& log) const; int compila_rmov_CG(const int tipo, const int riga_nor, TArray& righe_mov, TLog_report& log, const int movdett) const; int genera_righe_CG(TArray& righe_mov, TLog_report& log, const int movdett) const; int compila_rmovana_CA(const int tipo, const int riga_nor, TArray& righe_movana, TLog_report& log, const int movdett) const; int genera_righe_CA(TArray& righe_movana, TLog_report& log, const int movdett) const; TSaldo_per_codice(const int grp, const TString& spc, const int cat, const char* idcespite = "") : _grp(grp),_spc(spc), _cat(cat), _idcespite(idcespite) {} }; bool TSaldo_per_codice::use_pdcc() const { static char _use_pdcc = ' '; if (_use_pdcc == ' ') { TConfig& cfg = ca_config(); _use_pdcc = cfg.get_bool("UsePdcc"); } return _use_pdcc != '\0'; } 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; } const TRectype& TSaldo_per_codice::categoria() const { //viene chiamato il metodo standard della ditta_cespiti con l'ultimo parametro true in modo che usi solo... //...le categorie valide per il collegamento alla contabilita' (tabella CCC) return ditta_cespiti().categoria(_grp, _spc, _cat, true); } const TString& TSaldo_per_codice::descr_categoria() const { TString& wrkstring = get_tmp_string(); wrkstring << _grp << ' ' << _spc << ' ' << _cat << ' ' ; wrkstring << ditta_cespiti().categoria(_grp, _spc, _cat, false).get("S0"); return wrkstring; } 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::trova_quota_e_conto_CG(int tipo, real& quota, TBill& zio, TLog_report& log) const { int pos = 0; const char* field = "S1"; switch (tipo) { case 1: quota = _qnor; pos = 24; break; case 2: quota = _qant; pos = 36; break; case 3: quota = _qacc; pos = 48; break; default: break; } if (quota <= ZERO) return 0; const TRectype& rec_ccc = categoria(); const TString& stringona = rec_ccc.get(field); if (!str2bill(stringona, pos, zio)) { pos = 24; if (tipo == 1 || !str2bill(stringona, pos, zio)) { TString msg; msg << TR("Manca il conto per le quote ammortamento normali della categoria ") << descr_categoria(); log.log(2, msg); return 0; } else tipo = 1; } return tipo; } int TSaldo_per_codice::trova_quota_e_conto_CA(int tipo, real& quota, TAnal_bill& zio, TLog_report& log) const { //caso CA con use_pdcc TString80 stringona; if (use_pdcc()) { int pos = 0; const char* field = "S1"; switch (tipo) { case 1: quota = _qnor; pos = 24; break; case 2: quota = _qant; pos = 36; break; case 3: quota = _qacc; pos = 48; break; default: break; } if (quota <= ZERO) return 0; const TRectype& rec_ccc = categoria(); stringona = rec_ccc.get(field).mid(pos, 12); zio.set_conto(stringona); if (stringona.blank()) { pos = 24; stringona = rec_ccc.get(field).mid(pos, 12); if (tipo == 1 || stringona.blank()) { TString msg; msg << TR("Manca il conto per le quote ammortamento normali della categoria ") << descr_categoria(); log.log(2, msg); return 0; } else tipo = 1; } } else //caso CA con use_pconana { char* field; switch (tipo) { case 1: quota = _qnor; field = "S3"; break; case 2: quota = _qant; field = "S4"; break; case 3: quota = _qacc; field = "S5"; break; default: break; } if (quota <= ZERO) return 0; const TRectype& rec_ccc = categoria(); stringona = rec_ccc.get(field); if (stringona.blank()) { stringona = rec_ccc.get("S3"); if (tipo == 1 || stringona.blank()) { TString msg; msg << TR("Manca il conto analitico per le quote ammortamento normali della categoria ") << descr_categoria(); log.log(2, msg); return 0; } else tipo = 1; } } if (tipo > 0) zio.set_conto(stringona); return tipo; } //metodi per contabilità generale CG //----------------------------------- int TSaldo_per_codice::compila_rmov_CG(const int tipo, const int riga_nor, TArray& righe_mov, TLog_report& log, const int movdett) const { real quota; TBill zio; const int tipo_trovato = trova_quota_e_conto_CG(tipo, quota, zio, log); if (tipo_trovato <= 0) return -1; if (tipo_trovato == 1 && riga_nor >= 0) { TRectype& rmovnor = (TRectype&)righe_mov[riga_nor]; rmovnor.add(RMV_IMPORTO, quota); return riga_nor; } TRigamov* rmov = new TRigamov(_grp, _spc, _cat); 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: //dettaglio per categoria rmov->put(RMV_DESCR, rmov->descr_categoria()); break; case 1: //dettaglio per cespite { const TRectype& rec_cespi = cache().get(LF_CESPI, _idcespite); rmov->put(RMV_DESCR, rec_cespi.get(CESPI_DESC)); } break; case 2: //dettaglio per cespite con sottoconto=idcespite (idcespite numerico e di 6 cifre max!) { 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); ok = zio.find(); } } if (!ok) { TString msg; msg.format(FR("Il codice cespite %s non è 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_CG(TArray& righe_mov, TLog_report& log, const int movdett) const { const int righe_prima = righe_mov.items(); const int riga_nor = compila_rmov_CG(1, -1, righe_mov, log, movdett); const int riga_ant = compila_rmov_CG(2, riga_nor, righe_mov, log, movdett); const int riga_acc = compila_rmov_CG(3, riga_nor, righe_mov, log, movdett); //const int riga_persa = compila_rmov_CG(4, -1, righe_mov, log, movdett); const int righe_dopo = righe_mov.items(); return righe_dopo - righe_prima; //messo qui tanto per poter compilare } //metodi per analitica CA //------------------------- int TSaldo_per_codice::compila_rmovana_CA(const int tipo, const int riga_nor, TArray& righe_movana, TLog_report& log, const int movdett) const { real quota; TAnal_bill zio; const int tipo_trovato = trova_quota_e_conto_CA(tipo, quota, zio, log); if (tipo_trovato <= 0) return -1; if (tipo_trovato == 1 && riga_nor >= 0) { TRectype& rmovananor = (TRectype&)righe_movana[riga_nor]; rmovananor.add(RMOVANA_IMPORTO, quota); return riga_nor; } TRigamov* rmovana = new TRigamov(_grp, _spc, _cat, true); rmovana->put(RMOVANA_SEZIONE, "D"); rmovana->put(RMOVANA_IMPORTO, quota); //conto e descrizione dipendono dal livello di dettaglio stabilito nella configurazione del collegamento CG/CE switch (movdett) { case 0: //dettaglio per categoria rmovana->put(RMOVANA_DESCR, rmovana->descr_categoria()); break; case 1: //dettaglio per cespite { const TRectype& rec_cespi = cache().get(LF_CESPI, _idcespite); rmovana->put(RMOVANA_DESCR, rec_cespi.get(CESPI_DESC)); } break; case 2: //dettaglio per cespite con sottoconto=idcespite (idcespite numerico e di 6 cifre max!) { const TRectype& rec_cespi = cache().get(LF_CESPI, _idcespite); rmovana->put(RMOVANA_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) { TString16 stringona = zio.conto().left(6); stringona << _idcespite.right(6); zio.set_conto(stringona); ok = zio.ok(); } } 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; } 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); } int TSaldo_per_codice::genera_righe_CA(TArray& righe_movana, TLog_report& log, const int movdett) const { const int righe_prima = righe_movana.items(); const int riga_nor = compila_rmovana_CA(1, -1, righe_movana, log, movdett); const int riga_ant = compila_rmovana_CA(2, riga_nor, righe_movana, log, movdett); const int riga_acc = compila_rmovana_CA(3, riga_nor, righe_movana, log, movdett); const int righe_dopo = righe_movana.items(); return righe_dopo - righe_prima; } //=============================================================================================== //TMovimentoPN_CE class TMovimentoPN_CE : public TMovimentoPN { TSaldo_agg _sagg; protected: void salda_rmov(const bool add); public: virtual int read(TIsamop op = _isequal, TReclock lockop = _nolock); virtual int write(bool force = true); virtual int rewrite(bool force = true); virtual int remove(); TRectype& nuova_riga(); TRectype& nuova_riga(const TRectype& row); }; void TMovimentoPN_CE::salda_rmov(const bool add) { _sagg.set_anno_es(curr().get_int(MOV_ANNOES)); _sagg.set_movprovv(curr().get_char(MOV_PROVVIS) > ' '); _sagg.set_movimentato(true); TBill zio; TImporto imp; for (int i = 0; i < cg_items(); i++) { const TRectype& rmov = cg(i); //riga i-esima corrente zio.get(rmov); imp.set(rmov.get_char(RMV_SEZIONE), rmov.get_real(RMV_IMPORTO)); _sagg.aggiorna(zio, imp, add); } } int TMovimentoPN_CE::read(TIsamop op, TReclock lockop) { int err = TMovimentoPN::read(op, lockop); if (err == NOERR) { _sagg.reset(); salda_rmov(false); } return err; } int TMovimentoPN_CE::remove() { int err = TMovimentoPN::remove(); if (err == NOERR) { _sagg.registra(); _sagg.reset(); } return err; } int TMovimentoPN_CE::write(bool force) { int err = TMovimentoPN::write(force); if (err == NOERR) { salda_rmov(true); _sagg.set_num_ulmov(curr().get_long(MOV_NUMREG)); _sagg.set_data_ulmov(curr().get_date(MOV_DATAREG)); _sagg.registra(); } return err; } int TMovimentoPN_CE::rewrite(bool force) { int err = TMovimentoPN::rewrite(force); if (err == NOERR) { salda_rmov(true); _sagg.registra(); } return err; } //nuova riga fondo TRectype& TMovimentoPN_CE::nuova_riga() { TRectype& riga = cg(-1); riga.put(RMV_NUMRIG, cg_items()); riga.put(RMV_ANNOES, curr().get(MOV_ANNOES)); riga.put(RMV_DATAREG, curr().get(MOV_DATAREG)); return riga; } //nuova riga normale TRectype& TMovimentoPN_CE::nuova_riga(const TRectype& row) { TRectype& riga = cg(-1); riga = row; riga.put(RMV_NUMRIG, cg_items()); riga.put(RMV_ANNOES, curr().get(MOV_ANNOES)); riga.put(RMV_DATAREG, curr().get(MOV_DATAREG)); //resettatore del saldo ad ogni nuovo movimento (righe tot presenti 1 = nuovo movimento) if (cg_items() == 1) _sagg.reset(); return riga; } //=============================================================================================== //TAmmortamento_per_cespite class TPlus_minus : public TSaldo_per_codice { TArray _ammmv, _movam, _movce; public: void genera_mov_elim_ven(const TDate& datareg, const TDate& datacomp, const bool definitivo, TLog_report& log) const; TPlus_minus(const int gruppo, const TString& specie, const int categoria, const TArray& ammmv, const TArray& movam, const TArray& movce) : TSaldo_per_codice(gruppo, specie, categoria), _ammmv(ammmv), _movam(movam), _movce(movce) {} }; //metodo per la generazione dei movimenti dovuti a plus/minus void TPlus_minus::genera_mov_elim_ven(const TDate& datareg, const TDate& datacomp, const bool definitivo, TLog_report& log) const { //Parametri dalla maschera //parametri da utilizzare piu' volte TString4 codcaus; //conti fondo, immobilizzo, sopravenienza passiva, plusvalenza, minusvalenza cespite const TString& stringona = categoria().get("S1"); TBill zio_fondo; str2bill(stringona, 12, zio_fondo); if (!zio_fondo.find()) { TString msg; msg << TR("Conto del fondo errato o mancante per la categoria ") << descr_categoria(); log.log(2, msg); return; } TBill zio_immobilizzo; str2bill(stringona, 0, zio_immobilizzo); if (!zio_immobilizzo.find()) { TString msg; msg << TR("Conto di immobilizzo errato o mancante per la categoria ") << descr_categoria(); log.log(2, msg); return; } //Riempie i campi della testata movimento 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++) { const TRectype& movce = (const TRectype&)_movce[i]; const TRectype& movam = (const TRectype&)_movam[i]; //causale movimento const real impven = movce.get_real(MOVCE_IMPVEN); const bool eliminazione = impven == ZERO; //estremi documento di vendita const TString& numdoc = movce.get(MOVCE_NDOC); const TString& tipodoc = movce.get(MOVCE_TPDOC); const TDate& datadoc = movce.get_date(MOVCE_DTDOC); TConfig config_ditta_ce(CONFIG_DITTA, "ce"); if (eliminazione) codcaus = config_ditta_ce.get("COAUEL"); else codcaus = config_ditta_ce.get("COAUCH"); if (codcaus.empty()) { TString msg; msg << TR("Causale di vendita o eliminazione mancante"); log.log(2, msg); return; } //movimento contabile TMovimentoPN_CE pn; TRectype& head = pn.curr(); fill_head(head, datacomp, datareg, numreg, codcaus, definitivo, numdoc, tipodoc, datadoc); head.put(MOV_DESCR, movce.get(MOVCE_DESC)); numreg ++; //incrementa il numreg per l'eventuale testata successiva //Aggiunge le righe //le prime 2 righe sono comuni a tutti i tipi di movimento (esistono solo con importo non nullo) //riga 1: fondo const real val_fondo_cesp = movam.get_real(MOVAM_QNOR) + movam.get_real(MOVAM_QANT) + movam.get_real(MOVAM_QACC); if (!val_fondo_cesp.is_zero()) { TRectype& riga_fondo = pn.nuova_riga(); riga_fondo.put(RMV_SEZIONE, 'D'); riga_fondo.put(RMV_IMPORTO, val_fondo_cesp); //somma qnor+qant+qacc in movam); zio_fondo.put(riga_fondo); riga_fondo.put(RMV_DESCR, TR("Fondo")); } //riga 2: immobilizzo const real val_imm_cesp = movce.get_real(MOVCE_CSTO); if (!val_imm_cesp.is_zero()) { TRectype& riga_immobilizzo = pn.nuova_riga(); riga_immobilizzo.put(RMV_SEZIONE, 'A'); riga_immobilizzo.put(RMV_IMPORTO, val_imm_cesp); zio_immobilizzo.put(riga_immobilizzo); riga_immobilizzo.put(RMV_DESCR, TR("Immobilizzo")); } //le successive righe dipendono dai parametri del config_ditta_ce e dalla differenza di importi riga2-riga1 const real val_sopravv_pass = val_imm_cesp - val_fondo_cesp; if (eliminazione) //caso di ELIMINAZIONE cespite: { //riga 3: sopravenienza passiva (SOLO se movimento sbilanciato!) if (!val_sopravv_pass.is_zero()) { TRectype& riga_sopravv = pn.nuova_riga(); riga_sopravv.put(RMV_SEZIONE, 'D'); riga_sopravv.put(RMV_IMPORTO, val_sopravv_pass); TBill zio_sopravv(config_ditta_ce.get_int("GRCOTELI"), config_ditta_ce.get_int("COCOTELI"), config_ditta_ce.get_long("SOCOTELI")); if (!zio_sopravv.find()) { TString msg; msg << TR("Conto di sopravvenienza errato o mancante"); log.log(2, msg); return; } zio_sopravv.put(riga_sopravv); riga_sopravv.put(RMV_DESCR, TR("Sopravenienza passiva")); } } else //caso di VENDITA cespite: { //riga 3: vendita; parte comune (anche questa, come le altre, deve avere importo non nullo) if (!impven.is_zero()) { TRectype& riga_ven = pn.nuova_riga(); riga_ven.put(RMV_SEZIONE, 'D'); riga_ven.put(RMV_IMPORTO, impven); const bool tiposcrit = config_ditta_ce.get_bool("COR5PM"); if (tiposcrit) //tipo scrittura per vendita: su conto cespite (conto in categoria CCC) { zio_immobilizzo.put(riga_ven); riga_ven.put(RMV_DESCR, TR("Vendita su conto cespite")); } else //tipo scrittura per vendita: su conto vendita (conto in configurazione ditta) { TBill zio_vendita(config_ditta_ce.get_int("GRCOTVEN"), config_ditta_ce.get_int("COCOTVEN"), config_ditta_ce.get_long("SOCOTVEN")); if (!zio_vendita.find()) { TString msg; msg << TR("Conto di vendita cespite errato o mancante"); log.log(2, msg); return; } zio_vendita.put(riga_ven); riga_ven.put(RMV_DESCR, TR("Vendita su conto vendita")); } } //if(!impven.is_zero... //riga 4: plus/minus-valenza TImporto imp_fondo('D', val_fondo_cesp); TImporto imp_immobilizzo('A', val_imm_cesp); TImporto imp_ven('D', impven); TImporto imp_valenza = imp_fondo; imp_valenza += imp_immobilizzo; imp_valenza += imp_ven; if (!imp_valenza.is_zero()) //SOLO se movimento sbilanciato dopo le prime 3 righe, ovvero come le precedenti { imp_valenza.swap_section(); imp_valenza.normalize(); TRectype& riga_valenza = pn.nuova_riga(); const char sezione_valenza = imp_valenza.sezione(); riga_valenza.put(RMV_SEZIONE, sezione_valenza); riga_valenza.put(RMV_IMPORTO, imp_valenza.valore()); if (sezione_valenza == 'A') //plusvalenza { TBill zio_plus(config_ditta_ce.get_int("GRCOTPLU"), config_ditta_ce.get_int("COCOTPLU"), config_ditta_ce.get_long("SOCOTPLU")); if (!zio_plus.find()) { TString msg; msg << TR("Conto di plusvalenza errato o mancante"); log.log(2, msg); return; } zio_plus.put(riga_valenza); riga_valenza.put(RMV_DESCR, TR("Plusvalenza")); } else //minusvalenza { TBill zio_minus(config_ditta_ce.get_int("GRCOTMIN"), config_ditta_ce.get_int("COCOTMIN"), config_ditta_ce.get_long("SOCOTMIN")); if (!zio_minus.find()) { TString msg; msg << TR("Conto di minusvalenza errato o mancante"); log.log(2, msg); return; } zio_minus.put(riga_valenza); riga_valenza.put(RMV_DESCR, TR("Minusvalenza")); } } //if(!imp_valenza.is_zero... } //else di if(eliminazione... //finalmente scrive sul file qesti movimenti... int err = pn.write(); if (err != NOERR) { TString msg; msg << TR("Impossibile registrare il movimento ") << numreg << "\n"; log.log(2, msg); } else { TString msg; msg << TR("Registrato movimento ") << numreg << TR(" da movimento cespite ") << movce.get_long(MOVCE_IDMOV) << "\n"; log.log(0, msg); } } //for(int i=0;... (ciclo sui movimenti di un cespite) } //=============================================================================================== //Applicazione class TContabilizza_ce : public TSkeleton_application { TContabilizza_ce_mask* _mask; TConfig* _config_ditta_ce; bool _has_ca; protected: virtual void main_loop(); virtual bool create(); virtual bool destroy(); void elabora(); //metodo di alto livello per la gestione ordinata del casino 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 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: }; //eliminatore dei movimenti CG e CA eventualmente collegati void TContabilizza_ce::delete_old_movs(const TDate& ini_es) { TMovimentoPN_CE 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 movimenti provvisori cespiti...", false, true); for (cur_mov = 0; cur_mov.pos() < items; ++cur_mov) { progind.addstatus(1); pn.read(); TRectype& head = pn.curr(); const long numreg = head.get_long(MOV_NUMREG); int err = pn.remove(); //rimuove anche l'eventuale movana collegato if (_has_ca) { TString query; query << "USE MOVANA KEY 3"; query << "\nFROM NUMREGCG=#NUMREGCG"; query << "\nTO NUMREGCG=#NUMREGCG"; TISAM_recordset recset(query); recset.set_var("#NUMREGCG", numreg); if (recset.items() > 0) { TAnal_mov movana(recset.cursor()->curr(LF_MOVANA)); movana.remove(recset.cursor()->file()); } } //if(_has_ca)... } } //metodo per la generazione di movimenti contabili con righe per categoria long TContabilizza_ce::genera_mov_CG(TArray& righe_mov, TLog_report& log) { //Parametri config ditta cespiti const TString4 codcaus = _config_ditta_ce->get("COAUQU"); const int movdett = _config_ditta_ce->get_int("MOVDETT"); //Parametri maschera 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 const long first_numreg = get_new_numreg_CG(); long numreg = first_numreg; TMovimentoPN_CE pn; TRectype& head = pn.curr(); 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 righe_mov.add(new TRigamov(0, EMPTY_STRING, 0)); //Ciclo su tutte le righe dell'array delle righe mov. Ad ogni cambio di categoria dovra' inserire la riga.. //..fondo per bilanciare la categoria, quindi scrivere sul movimento le righe ammortamento (da 1 a 3, ovvero.. //..qnor,qant,qacc) e la riga fondo di quella categoria, quindi passare alla categoria successiva. for (int i = 0; i < righe_mov.items(); i++) { //record di righe_mov const TRigamov& rigamov = (const TRigamov&)righe_mov[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 && (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(); //Inverte la sezione del fondo calcolato per il bilancamento fondo.swap_section(); //inverte la sezione fondo.normalize(); //normalizza il segno riga_fondo.put(RMV_SEZIONE, fondo.sezione()); //inserisce nella riga fondo le sezione.. riga_fondo.put(RMV_IMPORTO, fondo.valore()); //..ed il valore //Deve mettere nella riga fondo gr/co/sot che stanno nella categoria in CCC //Serve la categoria precedente, perche' in questo momento l'ha cambiata! Quindi [i-1] const TRigamov& prev_riga_mov = (const TRigamov&)righe_mov[i-1]; const TString& stringone = prev_riga_mov.categoria().get("S1"); riga_fondo.put(RMV_GRUPPO, stringone.mid(12,3)); riga_fondo.put(RMV_CONTO, stringone.mid(15,3)); riga_fondo.put(RMV_SOTTOCONTO, stringone.mid(18,6)); const TString descat = prev_riga_mov.descr_categoria(); riga_fondo.put(RMV_DESCR, descat); //se il movimento supera le 95 righe va salvato sul file MOV, poi distrutto per poter costruirne uno nuovo.. //..con le righe di righe_mov che sono rimaste if (pn.cg_items() > 95 || i == righe_mov.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); head.put(MOV_DESCR, desc); } int err = pn.write(); //scrive il movimento sul file if (err != NOERR) { TString msg; msg << TR("Impossibile registrare il movimento ") << numreg << "\n"; log.log(2, msg); } else { TString msg; msg << TR("Registrato movimento ") << numreg << TR(" categoria ") << descat << "\n"; log.log(0, msg); } pn.destroy_rows(numreg); //ne elimina le righe per poter ricominciare head.put(MOV_NUMREG, ++numreg); //nuova testata per nuovo movimento } //azzera il valore del fondo in modo da ricominciare a calcolarlo con la nuova categoria fondo.reset(); } //if i>0&&rigamov.compare... //Se la categoria non e' cambiata crea normalmente la nuova riga //Aggiorna l'importo del fondo che e' pari alla somma di tutte le righe della stessa categoria TImporto imp_riga(rigamov.get_char(RMV_SEZIONE), rigamov.get_real(RMV_IMPORTO)); fondo += imp_riga; pn.nuova_riga(rigamov); } //for(inti=0;... return first_numreg; } 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) } //metodo che gestisce la creazione dei movimenti CG dovuti ad ammortamenti 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); const int movdett = _config_ditta_ce->get_int("MOVDETT"); //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_CG(righe_mov, cont_cesp_log, movdett); } //controllo sul numero righe dell'array (serve solo per controllo al sagace programmatore...) const int nrighemov = righe_mov.items(); //a questo punto ha l'array con le righe movimento CG completo (righe_mov); da queste righe deve costruire.. //..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! 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(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); const int movdett = _config_ditta_ce->get_int("MOVDETT"); //array con le righe movimento CA TArray righe_movana; //riempie l'array delle righe movimento CA FOR_EACH_ARRAY_ITEM(anal_saldi_ordinati, riga, sldobj) { const TSaldo_per_codice& anal_sld = *(const TSaldo_per_codice*)sldobj; anal_sld.genera_righe_CA(righe_movana, cont_cesp_log, movdett); } //controllo sul numero righe dell'array (serve solo per controllo al sagace programmatore...) const int nrighmovana = righe_movana.items(); //metodo per la creazione del/dei movana analitici 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); } //metodo per gestire la successione degli eventi ad alto livello void TContabilizza_ce::elabora() { // 0) Acquisizione parametri generali, eliminazione movimenti provvisori //-------------------------------------------------------------------------------- //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); //se il trasferimento e' definitivo la data di calcolo e' quella finale dell'esercizio selezionato, senno'... //...e' quella indicata in F_DATACALC TDate datacalc; const bool definitivo = _mask->get_bool(F_PROVDEF); if (definitivo) datacalc = _mask->get_date(F_FINE_ES); else datacalc = _mask->get_date(F_DATACALC); const TDate datareg = _mask->get_date(F_DATAREG); const TDate datacomp = min(fine_es, datareg); //Legge un po' di parametri dal ditta.ini che servono al tipo di calcolo //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"); //Genera movimenti plus/minus? Parametro decisivo per poter generare movimenti cg da movimenti ce const bool mov_plusmin = _config_ditta_ce->get_bool("COPLMN"); //deve accoppare i movimenti provvisori di prima nota da inizio esercizio ad oggi? if (_mask->get_bool(F_KILLOLD)) { delete_old_movs(ini_es); } //report con log errori TLog_report cont_cesp_log(TR("Contabilizzazione cespiti")); cont_cesp_log.kill_duplicates(); // 1) Preparazione contabilizzazione CG/CA: ammortamenti //---------------------------------------------------------------------- //programma vero e proprio (calcolo ammortamenti, selezione cespiti validi, trasferimento) TISAM_recordset cespiti("USE CESPI"); const TRecnotype nrec = cespiti.items(); //Assoc_array Categoria-QammTot TAssoc_array quote_per_codice, anal_quote_per_codice; TArray ammo_plus_minus; //giro su tutti i cespiti 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) //1.1) preparazione contabilizzazione CG //---------------------------------------- TToken_string gsc; //chiave per CG 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); //Parte relativa ad AMMMV (per generazione movimenti cg da movim. cespiti) if (mov_plusmin) { const TArray& ammmv = cespite.ammmv(); const TArray& movam = cespite.movam(); const TArray& movce = cespite.movce(); TPlus_minus* pm = new TPlus_minus(gruppo, specie, codcat, ammmv, movam, movce); ammo_plus_minus.add(pm); } //1.2) preparazione contabilizzazione CA //---------------------------------------- if (_has_ca) { //per prima cosa necessita dei valori da salcecms TToken_string key; key.add(idcespite); key.add(codes); TRecord_array righe_salcecms(key, LF_SALCECMS); // 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)) { const TRectype& curr_salcecms_line = righe_salcecms.row(i); const real percutil = curr_salcecms_line.get_real(SALCECMS_PERCUTIL); percutil_tot += percutil; } // Aggiunge una eventuale ripartizione sulla commessa di default (GENSPA) per raggiungere 100 if (percutil_tot < CENTO) { 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); if (anal_sc == NULL) { anal_sc = new TSaldo_per_codice(gruppo, specie, codcat, idcespite); //ricordiamo la key: gr/sp/cat/(cespite)/cdc/cms/fase int offset = 0; if (movdett > 0) //se il dettaglio richiede il cespite -> offset della key offset++; anal_sc->_conto.set_costo(key.get(3 + offset)); anal_sc->_conto.set_commessa(key.get(4 + offset)); anal_sc->_conto.set_fase(key.get(5 + offset)); 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... } //if(_has_ca)... } //if (cespite.calc_amm(tpamm,... } //for (int i = 0; cespiti.move_to(i); i++)... // 2) Generazione movimenti CG da ammortamenti cespiti //---------------------------------------------------------------- //contabilizzazione in CG const long first_numreg_CG = contabilizza_CG(quote_per_codice, cont_cesp_log); // 3) Generazione movimenti CG da movimenti cespiti di vendita/eliminazione //---------------------------------------------------------------------------------- //solo se in configurazione ditta cespiti e' attivo il flag di generazione movimenti plus/minus... if (mov_plusmin) { //controllo sul numero righe dell'array (serve solo per controllo al sagace programmatore...) const int nrigheammo = ammo_plus_minus.items(); //scandisce l'array con i valori per i movimenti di plus/minus creando un movimento cg per ognuno FOR_EACH_ARRAY_ITEM(ammo_plus_minus, riga, pmobj) { const TPlus_minus& pm = *(const TPlus_minus*)pmobj; pm.genera_mov_elim_ven(datareg, datacomp, definitivo, cont_cesp_log); } } // 4) Generazione movimenti CA da ammortamenti cespiti //---------------------------------------------------------- //contabilizzazione in CA if (_has_ca) contabilizza_CA(first_numreg_CG, anal_quote_per_codice, cont_cesp_log); // 5) stampa il log degli errori //--------------------------------------- TReport_book book; book.add(cont_cesp_log); book.preview(); } bool TContabilizza_ce::create() { _mask = new TContabilizza_ce_mask; //chiede se ha la CA; serve per la contabilizzazione analitica _has_ca = dongle().active(CAAUT); //config ditta cespiti _config_ditta_ce = new TConfig(CONFIG_DITTA, "ce"); return TSkeleton_application::create(); } bool TContabilizza_ce::destroy() { delete _config_ditta_ce; delete _mask; return true; } void TContabilizza_ce::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[]) { TContabilizza_ce a; a.run(argc,argv,TR("Contabilizzazione cespiti")); return 0; }