#include #include #include #include #include "celib.h" #include "../ve/velib.h" #include "../ca/commesse.h" #include "ce4200a.h" #include "ce4200.h" #include "ammce.h" #include "cespi.h" #include "salcecms.h" //=============================================================================================== //maschera class TCalc_cesp_cms_mask: public TAutomask { public: virtual bool on_field_event(TOperable_field& o, TField_event e, long jolly); TCalc_cesp_cms_mask():TAutomask("ce4200a") {} }; bool TCalc_cesp_cms_mask::on_field_event(TOperable_field& o, TField_event e, long jolly) { /* switch (o.dlg()) { default: break; }*/ return true; } //=============================================================================================== //form class TCalc_cesp_cms_form : public TForm { TDitta_cespiti _ditta; protected: bool validate(TForm_item &cf, TToken_string &s); public: TCalc_cesp_cms_form(); virtual ~TCalc_cesp_cms_form(); }; TCalc_cesp_cms_form::TCalc_cesp_cms_form() :TForm ("ce4200a") { } TCalc_cesp_cms_form::~TCalc_cesp_cms_form() { } bool TCalc_cesp_cms_form::validate(TForm_item &cf, TToken_string &s) { if (s == "_DESCRCAT") { const int codcat = cursor()->curr().get_int(DOC_NDOC); const TRectype& cat =_ditta.categoria(0, "", codcat); cf.set(cat.get("S0")); return true; //ricava la descrizione del cespite e la manda in stampa } return TForm::validate(cf,s); } //=============================================================================================== //Applicazione class TCalc_cesp_cms : public TSkeleton_application { TCalc_cesp_cms_mask* _mask; TCalc_cesp_cms_form* _form; bool _soloperc; protected: virtual void main_loop(); virtual bool create(); virtual bool destroy(); public: void utilizzo_per_cms(const TRectype& ammce_rec); real calc_perc_util_cesp(const TRectype& salcecms_rec, const TDate& dtinices, const TDate& dtfineces); void delete_cespi_docs(); TRiga_documento& cerca_riga(TDocumento& doc_cesp, const TString& idcesp, const TString& codcms) const; void elabora_docs(); bool stampa_docs(); }; //Calcolo % utilizzo del cespite nella commessa //--------------------------------------------- // percutil = a quella dei saldi per commessa (SALCECMS_PERCUTIL) // percutil = percutil/100 normalizzazione // Se si devono considerare le date... // stabilisce l'intervallo di date di riferimento per calcolare il numero dei giorni di utilizzo // del cespite nella commessa delta_cms = (dtfine-dtini+1)/(dtfineces-dtinices+1) // dove: // dtinices e dtfineces sono le date di inizio e fine cespite // dtini e dtfine sono le date di inizio e fine UTILIZZO del cespite nella commessa // quindi la percentuale di utilizzo del cespite nella commessa risultera' come: // percutil = percutil * delta_cms // fine Se // real TCalc_cesp_cms::calc_perc_util_cesp(const TRectype& salcecms_rec, const TDate& dtinices, const TDate& dtfineces) { //adesso prende la percentuale di utilizzo del cespite nella commessa.. real percutil = salcecms_rec.get_real(SALCECMS_PERCUTIL); //normalizza la percentuale... percutil = percutil / CENTO; if (!_soloperc) { //prende il codice commessa del record.. TString80 codcms = salcecms_rec.get(SALCECMS_CODCMS); //..ed accede cosi' alla tabella delle commesse const TRectype& cms = cache().get(LF_COMMESSE, codcms); //prende le date di inizio e fine commessa dalla tabella per poterle confrontare con le date limite //del cespite nell'esercizio TDate dtfine = dtfineces; //se esiste una data di proroga (DATAPROR) -> la data fine commessa e' la data proroga,altrimenti e' //la normale data fine commessa (DATAFINE) TDate dtfinecms = cms.get_date(COMMESSE_DATAPROR); if (!dtfinecms.ok()) dtfinecms = cms.get_date(COMMESSE_DATAFINE); if (dtfinecms.ok() && (dtfinecms < dtfineces)) dtfine = dtfinecms; TDate dtini = dtinices; const TDate dtinicms = cms.get_date(COMMESSE_DATAINIZIO); if ((dtinicms.ok()) && (dtinicms > dtinices)) dtini = dtinicms; //intervallo giorni di utilizzo cespite nella commessa const real delta_cms = real(dtfine - dtini + 1) / real(dtfineces - dtinices + 1); //...e la porta in giorni rispetto al totale di utilizzo dei giorni del cespite nell'esercizio //(il 100% sono i giorni di utilizzo del cespite in tutte le commesse dell'esercizio) percutil *= delta_cms; } return percutil; } TRiga_documento& TCalc_cesp_cms::cerca_riga(TDocumento& doc_cesp, const TString& idcesp, const TString& codcms) const { //deve raggruppare per commessa? const bool groupcms = _mask->get_bool(F_CMSGROUP); //se c'e' il flag di raggruppamento per commessa... if (groupcms) { for (int i =1; i < doc_cesp.rows(); i++) { TRiga_documento& rigadoc = doc_cesp[i]; if (rigadoc.get(RDOC_CODCMS) == codcms) return rigadoc; //se esiste gia' una riga con codice cespite e codice commessa correnti } } const TString4 tiporiga = _mask->get(F_TIPORIGA); TRiga_documento& rigadoc = doc_cesp.new_row(tiporiga); rigadoc.put(RDOC_CODCMS, codcms); if (groupcms) //se raggruppa per cms tanto vale mettere la descrizione della commessa rigadoc.put(RDOC_DESCR, cache().get(LF_COMMESSE, codcms, COMMESSE_DESCRIZ)); else //se non raggruppa puo' usare anche il codice cespite, che scrive in codart { rigadoc.put(RDOC_CODART, idcesp); rigadoc.put(RDOC_DESCR, cache().get(LF_CESPI, idcesp, CESPI_DESC)); } rigadoc.put(RDOC_QTA, 1); rigadoc.put(RDOC_DATACONS, TDate(TODAY)); //data di elaborazione rigadoc.put(RDOC_CODIVA, _mask->get(F_CODIVA)); //codice IVA obbligatorio return rigadoc; } void TCalc_cesp_cms::utilizzo_per_cms(const TRectype& ammce_rec) { const bool groupcms = _mask->get_bool(F_CMSGROUP); //totale quote del cespite in esame per l'esercizio corrente (per tutte le commesse) real qtot = ammce_rec.get_real(AMMCE_QNOR); qtot += ammce_rec.get_real(AMMCE_QACC); qtot += ammce_rec.get_real(AMMCE_QANT); if (qtot != ZERO) { //controllo su date inizio e fine del periodo di utilizzo del cespite nell'esercizio selezionato const TString16 idcesp = ammce_rec.get(CESPI_IDCESPITE); const TRectype& cespi = cache().get(LF_CESPI, idcesp); const int codcat = cespi.get_int(CESPI_CODCAT); const TString80 cmsgen(_mask->get(F_CMSGEN)); const TDate dtinies = _mask->get_date(F_INIZIO_ES); const TDate dtfines = _mask->get_date(F_FINE_ES); TDate dtfine = dtfines; const TDate dtalien = cespi.get_date(CESPI_DTALIEN); if (dtalien.ok() && (dtalien < dtfines)) dtfine = dtalien; TDate dtini = dtinies; const TDate dtfunz = cespi.get_date(CESPI_DTFUNZ); if (dtfunz.ok() && (dtfunz > dtinies)) dtini = dtfunz; //..a questo punto dtini e dtfine rappresentano il periodo di utilizzo del cespite //nell'esercizio selezionato //quindi il periodo di utilizzo del cespite nell'esercizio,in giorni,sara'... const long delta_cesp = dtfine - dtini + 1; //Adesso si controlla la durata di ogni commessa (alla quale il cespite ha partecipato) durante //l'esercizio delezionato const int current_ese = ammce_rec.get_int(AMMCE_CODES); //crea un record array dove memorizzare i record del file salcecms riguardanti il cespite e //l'esercizio selezionati //dalla 2.2 sara' possibile sostituire le 5 righe seguenti con le 4 commentate //TToken_string key; //key.add(idcesp); //key.add(current_ese); //TRecord_array salcecms(key, LF_SALCECMS); TRecord_array salcecms(LF_SALCECMS, "NRIGA"); TRectype* key = new TRectype(LF_SALCECMS); key->put("IDCESPITE",idcesp); key->put("CODES",current_ese); salcecms.read(key); const TString4 codnum = _mask->get(F_CODNUM); const TString4 tiporiga = _mask->get(F_TIPORIGA); //documento con la categoria del cespite in oggetto, la numerazione indicata sulla maschera, //l'anno dell'esercizio selezionato; se esiste gia' non lo deve creare ma aggiungervi solo le righe TDocumento doc_cesp('D', current_ese, codnum, codcat); const bool doc_exist = doc_cesp.rows() > 0; if (!doc_exist) { doc_cesp.put(DOC_TIPODOC, _mask->get(F_TIPODOC)); doc_cesp.put(DOC_DATADOC, _mask->get(F_GENERA_DOC)); } //completa la testata con i dati della maschera doc_cesp.put(DOC_TIPOCF, 'F'); doc_cesp.put(DOC_CODCF, _mask->get(F_CODCF)); doc_cesp.put(DOC_NUMDOCRIF, _mask->get(F_NUMDOCRIF)); //ciclo su SALCECMS data una chiave idcespite + esercizio (si fa solo se salcecms non e' vuoto, //e' inutile perdere tempo..) if (salcecms.rows() > 0) { //crea documento relativo al cespite in questione (nell'esercizio);ogni riga del documento //sara' relativa ad una commessa TGeneric_distrib distrib(qtot, TCurrency::get_firm_dec()); int i; for (i=1; i<=salcecms.last_row(); i++ ) { const real perc = calc_perc_util_cesp(salcecms[i], dtini, dtfine); distrib.add(perc); } //e riempiamo 'sta riga! for (i=1; i<=salcecms.last_row(); i++ ) { //per prima cosa deve sapere se e' da creare o da modificare... const TString & codcms = salcecms[i].get(SALCECMS_CODCMS); //codice commessa TRiga_documento& rigadoc = cerca_riga(doc_cesp, idcesp, codcms); //se c'e' il flag di raggruppamento per commessa... const real quota = distrib.get(); if (groupcms) { real somma = rigadoc.get(RDOC_PREZZO); somma += quota; rigadoc.put(RDOC_PREZZO, somma); //ammortamento cespite per la commessa } else { rigadoc.put(RDOC_PREZZO, quota); //ammortamento cespite per la commessa const real perc_cms = salcecms[i].get_real(SALCECMS_PERCUTIL); rigadoc.put(RDOC_QTAGG1, perc_cms); //% utilizzo cespite nella commessa rigadoc.put(RDOC_QTAGG2, dtfine - dtini); //giorni di utilizzo cespite nella commessa rigadoc.put(RDOC_QTAGG3, delta_cesp); //giorni di utilizzo cespite nell'esercizio real perc = quota * CENTO / qtot; perc.round(2); //percentuale della quota rigadoc.put(RDOC_QTAGG4, perc); } } //scrittura del documento sul file doc_cesp.write(); }//fine if (salcecms.rows()>0) else { if (cmsgen.not_empty()) { TRiga_documento& rigadoc = cerca_riga(doc_cesp, idcesp, cmsgen); //se c'e' il flag di raggruppamento per commessa... if (groupcms) { real somma = rigadoc.get(RDOC_PREZZO); somma += qtot; rigadoc.put(RDOC_PREZZO, somma); //ammortamento cespite per la commessa } else rigadoc.put(RDOC_PREZZO, qtot); //ammortamento cespite per la commessa doc_cesp.write(); } } }//fine if(qtot!=0) } void TCalc_cesp_cms::delete_cespi_docs() { const int anno = _mask->get_int(F_ESERCIZIO); const TString& codnum = _mask->get(F_CODNUM); TRelation rel_doc(LF_DOC); TRectype& rec = rel_doc.curr(); rec.put(DOC_PROVV, "D"); rec.put(DOC_ANNO, anno); rec.put(DOC_CODNUM, codnum); TCursor cur_doc (&rel_doc, "", 1, &rec, &rec); const long items = cur_doc.items(); cur_doc.freeze(); TProgind progind(items, "Eliminazione vecchi documenti in corso...", false, true); for (cur_doc = 0; cur_doc.pos() < items; ++cur_doc) { progind.addstatus(1); TDocumento doc(rec); doc.remove(); } } void TCalc_cesp_cms::elabora_docs() { //deve accoppare tutti i documenti con ANNO e NUM che trova nella maschera delete_cespi_docs(); TRectype darec(LF_AMMCE),arec(LF_AMMCE); const int esercizio = _mask->get_int(F_ESERCIZIO); const TString80 da_cespite(_mask->get(F_DA_IDCESPITE)); const TString80 a_cespite(_mask->get(F_A_IDCESPITE)); if (!da_cespite.empty()) darec.put(AMMCE_IDCESPITE, da_cespite); if (!a_cespite.empty()) arec.put(AMMCE_IDCESPITE, a_cespite); TString filtro; filtro.format("(CODES==%d)&&(TPSALDO==2)&&(TPAMM==1)",esercizio); TRelation rel(LF_AMMCE); TCursor cur(&rel, filtro, 1, &darec, &arec); const long items = cur.items(); cur.freeze(); TProgind progind(items, "Elaborazione documenti in corso...", false, true); //ciclo sui cespiti di AMMCE nel codes selezionato for (cur=0; cur.pos()find_field('H', odd_page, FR_CODDITTA).set(_mask->get(F_DITTA)); _form->find_field('H', odd_page, FR_RAGSOC).set(_mask->get(F_RAGSOC)); _form->find_field('H', odd_page, FR_ESERCIZIO).set(_mask->get(F_ESERCIZIO)); _form->find_field('H', odd_page, FR_DATAINIZIO).set(_mask->get(F_INIZIO_ES)); _form->find_field('H', odd_page, FR_DATAFINE).set(_mask->get(F_FINE_ES)); //stampa i documenti via form (ci vuole una setregion) TCursor& curform = *_form->cursor(); TRectype darec(curform.curr()); darec.put(RDOC_PROVV, 'D'); darec.put(RDOC_ANNO, _mask->get_int(F_ESERCIZIO)); darec.put(RDOC_CODNUM, _mask->get(F_CODNUM)); // darec.put(RDOC_NDOC, ); da usare se si volesse aggiungere la ricerca per categoria (NDOC) TRectype arec(darec); // arec.put(RDOC_NDOC, ); curform.setregion(darec, arec); TString filtro; const TString& dacespite = _mask->get(F_DA_IDCESPITE); const TString& acespite = _mask->get(F_A_IDCESPITE); if (dacespite.not_empty()) filtro << "(CODART>='" << dacespite << "')" ; if (acespite.not_empty()) { if (dacespite.not_empty()) filtro << "&&"; filtro << "(CODART<='" << acespite << "')" ; } curform.setfilter(filtro); _form->print(); return true; } bool TCalc_cesp_cms::create() { _mask = new TCalc_cesp_cms_mask; _form = new TCalc_cesp_cms_form; TConfig config_doc ("ce4200a.ini", "Main"); _mask->set(F_CODNUM, config_doc.get("CODNUM")); _mask->set(F_TIPODOC, config_doc.get("TIPODOC")); _mask->set(F_TIPORIGA, config_doc.get("TIPORIGA")); _mask->set(F_CODIVA, config_doc.get("CODIVA")); _mask->set(F_CODCF, config_doc.get("CODCF")); _mask->set(F_NUMDOCRIF, config_doc.get("NUMDOCRIF")); _mask->set(F_CMSGEN, config_doc.get("CMSGEN")); return TSkeleton_application::create(); } bool TCalc_cesp_cms::destroy() { delete _mask; delete _form; return true; } void TCalc_cesp_cms::main_loop() { KEY k = K_ENTER; while (k != K_QUIT) { k = _mask->run(); _soloperc = _mask->get_bool(F_SOLOPERC); switch (k) { case K_ENTER: elabora_docs(); break; case K_ESC: if (stampa_docs() && !_mask->get_bool(F_DEFINITIVA)) //eventuale eliminazione dei documenti appena creati (richiesta di Eva Braun) delete_cespi_docs(); break; default: break; } } } int ce4200(int argc, char* argv[]) { TCalc_cesp_cms a; a.run(argc,argv,TR("Calcolo e stampa cespiti per commessa")); return 0; }