#include #include "calib01.h" #include "calib02.h" #include "ca3883.h" #include "panapdc.h" #include "pconana.h" #include "commesse.h" #include "fasi.h" #include "saldana.h" //////////////////////////////////////////////////////////////////////////////////////// // Classe per ricavare l'indicatore di bilancio dei conti analitici riclassificati e non //////////////////////////////////////////////////////////////////////////////////////// TObject* TIndbil_cache::key2obj(const char* key) { TString80 conto = key; if (_usepdcc && conto.len() == 12 && real::is_natural(conto)) { TLocalisamfile panapdc(LF_PANAPDC); panapdc.setkey(2); const int gr = atoi(conto.left(3)); const int co = atoi(conto.mid(3,3)); const long so = atol(conto.mid(6,6)); TRectype& panapdrec = panapdc.curr(); int i; for (i = 2; i >= 0; i--) { panapdrec.zero(); panapdrec.put(PANAPDC_GRUPPO, gr); if (i > 0) panapdrec.put(PANAPDC_CONTO, co); if (i == 2) panapdrec.put(PANAPDC_SOTTOCONTO, so); //occhio al prefisso! panapdrec.put(PANAPDC_CODCONTO, _prefix); if (panapdc.read(_isgteq) == NOERR) { bool found = panapdrec.get_int(PANAPDC_GRUPPO) == gr; if (found) found = panapdrec.get_int(PANAPDC_CONTO) == (i > 0 ? co : 0); if (found) found = panapdrec.get_long(PANAPDC_SOTTOCONTO) == (i > 1 ? so : 0L); if (found && _prefix.full()) found = panapdrec.get(PANAPDC_CODCONTO).starts_with(_prefix); if (found) { conto = panapdrec.get(PANAPDC_CODCONTO); break; } } } //se non trova il corrispondente conto analitico azzera il conto per il prossimo giro if (i < 0) conto.cut(0); } //conto analitico TAnal_bill bill(conto); int indbil = bill.indicatore_bilancio(); TToken_string* ib = new TToken_string; *ib << indbil; ib->add(conto); return ib; } int TIndbil_cache::get_indbil(const TString& conto, TString& conto_anale) { int indicatore = 0; TToken_string* ib = (TToken_string*)objptr(conto); if (ib != NULL) { indicatore = ib->get_int(0); ib->get(1, conto_anale); } return indicatore; } void TIndbil_cache::set_prefix(const char* prefix) { if (_prefix != prefix) { _prefix = prefix; destroy(); } } TIndbil_cache::TIndbil_cache() { TConfig& cfg = ca_config(); _usepdcc = cfg.get_bool("UsePdcc"); } ///////////////////////////////////////////////////////////////////////////////// //Classe di report speciale con numero colonne adattabile in base ad un parametro ///////////////////////////////////////////////////////////////////////////////// void TCRPA_report::merge_array(TString_array& c, TString_array& t, TString_array& codici, TString_array& testate) const { while (c.items() > 0) { TObject* cod = c.remove(0,true); TObject* tes = t.remove(0,true); codici.TArray::add(cod); testate.TArray::add(tes); } } void TCRPA_report::analize_pconana_structure (const TString& prefix, const int depth, TString_array& codici, TString_array& testate) const { //cerca quale e' la lunghezza della stringa conto da considerare in base alla depth scelta TConfig& cfg = ca_config(); const TMultilevel_code_info& pconana_info = ca_multilevel_code_info(LF_PCONANA); const long total_length = pconana_info.total_len(depth); //scandisce il piano dei conti analitico alla ricerca dei conti di lunghezza pari a.. //..quella appena ricavata TISAM_recordset recset("USE PCONANA\nSELECT LEN(CODCONTO)=#LUN\nFROM CODCONTO=#PREFIX\nTO CODCONTO=#PREFIX"); recset.set_var("#LUN", TVariant(total_length)); recset.set_var("#PREFIX", TVariant(prefix)); const int prefix_length = prefix.len(); TString_array codici_c, testate_c, codici_r, testate_r; //riempie gli array con i codici conto di lunghezza opportuna e relative testate TString80 codice; for (bool ok = recset.move_first(); ok; ok = recset.move_next()) { const TString& codconto = recset.get(PCONANA_CODCONTO).as_string(); const TAnal_bill zio(codconto); const int indbil = zio.indicatore_bilancio(); //solo Costi e Ricavi! if (indbil == 3 || indbil == 4) { codice.cut(0) << "#RECORD." << codconto.mid(prefix_length); const TString& testata = zio.testata(); if (indbil == 3) { codici_c.add(codice); testate_c.add(testata); } else { codici_r.add(codice); testate_r.add(testata); } } } if (codici_r.items() == 1) //se il campo da stampare e' uno solo->e' il totale del livello { codici_r.destroy(); testate_r.destroy(); } codici_r.add("#RICAVI"); testate_r.add(TR("RICAVI")); //..analogo per i Costi if (codici_c.items() == 1) { codici_c.destroy(); testate_c.destroy(); } codici_c.add("#COSTI"); testate_c.add(TR("COSTI")); //condensa gli array di Costo e Ricavo in un unico array che servira' di base per la stampa merge_array(codici_r, testate_r, codici, testate); merge_array(codici_c, testate_c, codici, testate); } void TCRPA_report::offset_and_fill_columns(TReport_section& rep_sect, const TString_array& str_arr, const int model_id) { TReport_field& rep_field = *rep_sect.find_field(model_id); //deve spostare i campi a destra della colonna modello //prende il rettangolo del campo.. const TRectangle& rep_field_rect = rep_field.get_rect(); //si memorizza i campi a destra del campo modello per poterli mettere a destra di tutti.. //..i campi che saranno generati TPointer_array campi_a_destra; for (int j = 0; j < rep_sect.items(); j++) { const TReport_field& campo = rep_sect.field(j); const TRectangle& rct = campo.get_rect(); //se il campo e' a destra del modello lo aggiunge all'array dei campi_a_destra if (rct.left() >= rep_field_rect.right()) campi_a_destra.add(campo); } //duplica il campo modello e riempie i duplicati con i valori degli array //serve il tipo di sezione poiche' gli header vanno trattati diversamente dai body const char sect_type = rep_sect.type(); //ciclo su tutti gli elementi dell'array con i valori da settare nei nuovi campi for (int i = 0; i < str_arr.items(); i++) { TReport_field* new_field = i == 0 ? &rep_field : (TReport_field*)rep_field.dup(); if (i > 0) { rep_sect.add(new_field); new_field->set_pos(rep_field_rect.left() + rep_field_rect.width() * i, rep_field_rect.top()); new_field->set_id(rep_field.id() + i); } switch (sect_type) { case 'H': //gli header devono stampare l'intestazione { new_field->set_picture(str_arr.row(i)); } break; case 'B': //i body devono stampare i valori e sommarli ai totali nei footer { new_field->set_field(str_arr.row(i)); TString ps = "MESSAGE ADD,F3."; ps << new_field->id(); ps << "|ADD,F4."; ps << new_field->id(); new_field->set_postscript(ps); } break; case 'F': //i footer devono calcolarsi i totali;ma i footer di totale fasi (4) non devono.. //..fare assolutamente nulla! if (rep_sect.level() > 1 && rep_sect.level() < 4) { new_field->set_field(""); TString ps = "MESSAGE ADD,F"; ps << (rep_sect.level() - 1) << '.' << new_field->id(); new_field->set_postscript(ps); } break; default: break; } } //sposta a destra gli ultimi campi non generati const TReport_field& ultimo_campo = rep_sect.field(rep_sect.last()); const TPoint offset(ultimo_campo.get_rect().right() - rep_field.get_rect().right(), 0); for (int k = 0; k < campi_a_destra.items(); k++) { TReport_field& campo = (TReport_field&)campi_a_destra[k]; campo.offset(offset); } rep_sect.sort(); } bool TCRPA_report::generate_columns (TString_array& codici, TString_array& testate, const int model_id) { //sezioni del report da modificare TReport_section& b1 = section('B', 1); //controllo dell'esistenza dei campi modello da replicare e loro duplicazione e riempimento! TReport_field* b1_model = b1.find_field(model_id); if (b1_model == NULL) return false; offset_and_fill_columns(b1, codici, model_id); //testate //la testata di pagina deve invece riempire le intestazioni delle colonne generate TReport_section& h0 = section('H', 0); TReport_field* h0_model = h0.find_field(model_id); if (h0_model == NULL) warning_box(TR("Manca l'intestazione della colonna modello (H0.%d)"),model_id); else offset_and_fill_columns(h0, testate, model_id); //le testate di sezione devono resettare i campi totale dei corrispondenti footers for (int j = 4; j > 0; j--) { TReport_section& head = section('H', j); if (head.items() > 0) { TString ps(256); ps = "MESSAGE "; //i campi dei totali da resettare sono tanti quante le colonne generate //k=0 per includere la colonna 69!!! usata nel caso i ricavi siano solo di livello 1 (depth=1) for (int k = 0; k <= codici.items(); k++) { if (k > 0) ps << '|'; ps << "RESET,F" << head.level() << '.' << (k+model_id); } head.set_prescript(ps); } } //footers for (int i = 4; i > 0; i--) { TReport_section& foot = section('F', i); TReport_field* foot_model = foot.find_field(model_id); if (foot_model == NULL) warning_box(TR("Manca la colonna modello (F%d.%d)"), i, model_id); else offset_and_fill_columns(foot, codici, model_id); } #ifdef DBG save("cazzone.rep"); #endif return true; } TCRPA_report::TCRPA_report (const char* rep_name, const TString& prefix, const int depth) { //che report usare? load (rep_name); //array contenenti i conti analitici e le loro descrizioni di testata che diventeranno.. //.colonne del report dopo lungo e periglioso travaglio TString_array codici, testate; //per prima cosa si deve analizzare la struttura del piano conti.. //..da stampare fino al livello richiesto! analize_pconana_structure (prefix, depth, codici, testate); //poi vanno generate le colonne del report corrispondenti alla struttura analizzata generate_columns (codici, testate, 69); } /////////////////////////////////////////////////////////////////// // roba del recordset /////////////////////////////////////////////////////////////////// const TFixed_string CMS_DEL_CAZZO("@@@@@@@@@@@@@@@@@@@@"); static int righe_compare(const TObject** o1, const TObject** o2) { TAssoc_array& a1 = *(TAssoc_array*)*o1; TAssoc_array& a2 = *(TAssoc_array*)*o2; int cmp = 0; const int l1 = atoi(*(TString*)a1.objptr("LEVEL")); const int l2 = atoi(*(TString*)a2.objptr("LEVEL")); cmp = l1 - l2; if (cmp == 0) { const TString& c1 = *(TString*)a1.objptr("CODCMS"); const TString& c2 = *(TString*)a2.objptr("CODCMS"); cmp = c1.compare(c2); if (cmp == 0) { const TString& f1 = *(TString*)a1.objptr("FASE"); const TString& f2 = *(TString*)a2.objptr("FASE"); cmp = f1.compare(f2); } else { const int z1 = c1.starts_with("DETR_"); const int z2 = c2.starts_with("DETR_"); if (z1 || z2) cmp = z1 - z2; } } return cmp; } ///////////////////////////////////////////////////////////////////////////////// //Classe di recordset speciale per stampe con saldana (ca3800, ca3900) ///////////////////////////////////////////////////////////////////////////////// bool TPrint_saldana_recordset::move_to(TRecnotype pos) { _curr = pos; return pos >= 0 && pos < items(); } void TPrint_saldana_recordset::parse_bill(const TString& bill, TString& conto) const { TConfig& cfg = ca_config(); const TMultilevel_code_info& pconana_info = ca_multilevel_code_info(LF_PCONANA); const int pconana_levels = pconana_info.levels(); const int prefix = cfg.get_int("PdcPrefix")-1; //lunghezza dell'eventuale prefisso di gruppo e conto const int prefix_len = (prefix >= 0) ? pconana_info.total_len(prefix) : 0; //quanto e' lungo il codice del conto da considerare? E' il livello - il prefisso const int conto_end = pconana_info.total_len(_depth) - prefix_len; //stringa con cio' che segue il prefisso ed e' richiesto conto = bill.mid(prefix_len, conto_end); } int TPrint_saldana_recordset::estrai_saldi(const TRecordset& saldana, const int indbil, TImporto& saldo, TImporto& saldop) const { int flag = 0; //stampa bilancio di commessa (_tipo=8) if (_tipo == 8) { if (_tipostima == 'C' && indbil == 3) { const TImporto imp_saldo(saldana.get(SALDANA_SEZIONE).as_string()[0], saldana.get(SALDANA_SALDO).as_real()); saldo = imp_saldo; flag |= saldo.is_zero() ? 0 : 1; } else saldo.reset(); if (_tipostima == 'T' || (_tipostima == 'C' && indbil == 4)) //stima Tempo o (Costi e indbil=ricavo) { const TImporto imp_saldop(saldana.get(SALDANA_SEZIONEP).as_string()[0], saldana.get(SALDANA_SALDOP).as_real()); const TImporto imp_saldov(saldana.get(SALDANA_SEZIONEV).as_string()[0], saldana.get(SALDANA_SALDOV).as_real()); saldop = imp_saldop; saldop += imp_saldov; flag |= saldop.is_zero() ? 0 : 2; } else saldop.reset(); } // stampa stima ricavi (_tipo=9) else { const TImporto imp_saldo(saldana.get(SALDANA_SEZIONE).as_string()[0], saldana.get(SALDANA_SALDO).as_real()); saldo = imp_saldo; flag |= saldo.is_zero() ? 0 : 1; const TImporto imp_saldop(saldana.get(SALDANA_SEZIONEP).as_string()[0], saldana.get(SALDANA_SALDOP).as_real()); const TImporto imp_saldov(saldana.get(SALDANA_SEZIONEV).as_string()[0], saldana.get(SALDANA_SALDOV).as_real()); saldop = imp_saldop; saldop += imp_saldov; flag |= saldop.is_zero() ? 0 : 2; /* correzione per ottenere la sezione in base all'indicatore di bilancio inutile per ora... const char sezione_positiva = (indbil == 2 || indbil == 3) ? 'D' : 'A'; saldo.normalize(sezione_positiva); saldop.normalize(sezione_positiva);*/ } return flag; } TAssoc_array& TPrint_saldana_recordset::get_row(TAssoc_array& cms, const char* chiave, const int indice, const TString& codcms, const TString& fase, const TString& descrizione) { //cerca se la commessa (e l'eventuale fase) esistono gia' nell'assocarray delle commesse TAssoc_array* riga_array = (TAssoc_array*)cms.objptr(chiave); //se non esiste la crea! if (riga_array == NULL) { riga_array = new TAssoc_array; TString4 str_indice; //l'indice va stringato per l'assoc_array str_indice << indice; riga_array->add("LEVEL", str_indice); riga_array->add("CODCMS", codcms); if (_tipo == 8) riga_array->add("FASE", fase); riga_array->add("DESCRIZ", descrizione); //inizializza i campi importo sicuramente presenti (modifica DECISIVA) //senza questa inizializzazione, nel caso trovasse campi nulli (in realta' 0), il bastardo.. //..anziche' considerarli 0 ci mette l'ultimo valore != che ha in memoria nella stessa posizione.. //..facendo sballare tutti i conti! //bilancio commessa (_tipo=8) if (_tipo == 8) { riga_array->add("RICAVI", EMPTY_STRING); riga_array->add("COSTI", EMPTY_STRING); } //stima ricavi (_tipo=9) else { riga_array->add("COS_BDG", EMPTY_STRING); riga_array->add("COS_MAT", EMPTY_STRING); riga_array->add("RIC_BDG", EMPTY_STRING); riga_array->add("RIC_MAT", EMPTY_STRING); } //aggiunge la riga all'array-one cms.add(chiave, riga_array); } return *riga_array; } //for ca3800 only! void TPrint_saldana_recordset::aggiorna_importo(TAssoc_array& riga_array, const TString& livello, const int indbil, const TRecordset& saldana, const bool inverti) const { TString* str_imp = (TString*)riga_array.objptr(livello); if (str_imp == NULL) { str_imp = new TString; riga_array.add(livello, str_imp); } //dare o avere? const char sezione = indbil == 3 ? 'D' : 'A'; TImporto imp(sezione, real(*str_imp)); //ci sono tutti i tipi di saldo, ma solo quelli che rientrano nei parametri iniziali.. //..verranno considerati (_tipostima,indbil) TImporto imp_saldo, imp_saldop; estrai_saldi(saldana, indbil, imp_saldo, imp_saldop); if (inverti) // Devo sottrarre l'importo = gli scambio la sezione { imp_saldo.swap_section(); imp_saldop.swap_section(); } imp += imp_saldo; imp += imp_saldop; imp.normalize(sezione); *str_imp = imp.valore().string(); } //for ca3800 only! real TPrint_saldana_recordset::calcola_avanzamento_tempo() const { real avanzamento; const TDate& datafinesc = _esc[_anno].fine(); TDate dataini, datafine; const TString& codfase = get("FASE").as_string(); if (codfase.empty()) { const TString& codcms = get("CODCMS").as_string(); const TRectype& rec_commesse = cache().get(LF_COMMESSE, codcms); dataini = rec_commesse.get(COMMESSE_DATAINIZIO); //attenzione alle commesse prorogate di nascosto.. if (rec_commesse.get_bool(COMMESSE_PROROGA) && rec_commesse.get_date(COMMESSE_DATAPROR).ok()) datafine = rec_commesse.get(COMMESSE_DATAPROR); else datafine = rec_commesse.get(COMMESSE_DATAFINE); } else { const TRectype& rec_fasi = cache().get(LF_FASI, codfase); dataini = rec_fasi.get(FASI_DATAINIZIO); datafine = rec_fasi.get(FASI_DATAFINE); } //Si prende SOLO la Fine Esercizio come riferimento di avanzamento (in realta' si.. //..potrebbe usare today al posto di datafinesc se si volesse la situazione ad oggi,.. //..ma i calcoli degli importi sarebbero da rivedere). Quindi: //se la commessa finisce prima della fine dell'esercizio if (datafine < datafinesc) avanzamento = CENTO; //se invece prosegue anche dopo la fine dell'esercizio... else { const long time_gone = datafinesc - dataini; const long durata = datafine - dataini; avanzamento = ((real)(time_gone * CENTO) / durata); } return avanzamento; } //for ca3900 only! void TPrint_saldana_recordset::incrementa_importo(TAssoc_array& riga_array, const TString& livello, const int indbil, const TImporto& saldo, const bool inverti) const { TString* str_imp = (TString*)riga_array.objptr(livello); if (str_imp == NULL) { str_imp = new TString; riga_array.add(livello, str_imp); } //dare o avere? const char sezione = indbil == 3 ? 'D' : 'A'; TImporto imp(sezione, real(*str_imp)); if (inverti) // Devo sottrarre l'importo = gli scambio la sezione imp -= saldo; else imp += saldo; imp.normalize(sezione); *str_imp = imp.valore().string(); } //metodo usato solo per la stima ricavi (_tipo=9, ca3900) void TPrint_saldana_recordset::aggiorna_importi(TAssoc_array& riga_array, const int indbil, const TRecordset& saldana, const bool inverti) const { TString8 livello; TImporto imp_saldo, imp_saldop; estrai_saldi(saldana, indbil, imp_saldo, imp_saldop); //saldi normali:Maturato if (!imp_saldo.is_zero()) { livello.format("%s_MAT", indbil == 3 ? "COS" : "RIC"); incrementa_importo(riga_array, livello, indbil, imp_saldo, inverti); } //saldi preventivi:Budget if (!imp_saldop.is_zero()) { livello.format("%s_BDG", indbil == 3 ? "COS" : "RIC"); incrementa_importo(riga_array, livello, indbil, imp_saldop, inverti); } } void TPrint_saldana_recordset::requery() { //prende le date di inizio e fine dell'eserizio selezionato sulla maschera TEsercizi_contabili esc; TDate datainiesc, datafinesc; esc.code2range(_anno, datainiesc, datafinesc); //deve procedere al confronto tra le date inizio-fine esercizio e quelle inizio-fine commessa.. //..per spostare il record in esame nell'array corretto TAssoc_array cms[4]; TString query; query = "USE SALDANA"; if (_tipo == 8) { if (_use_fasi && _fase.full()) query << " SELECT FASE=\"" << _fase << "\""; //stampa standard non a vita intera per la 3800 if (!_vitaintera) query << "\nTO ANNO=" << _anno; } TISAM_recordset saldana(query); const long saldana_items = saldana.items(); TProgind pi(saldana_items, "Scansione saldi...", true, true); for (bool ok = saldana.move_first(); ok; ok = saldana.move_next()) { //progind tanto per gradire pi.addstatus(1); if (pi.iscancelled()) break; const TString& codconto = saldana.get(SALDANA_CONTO).as_string(); //trova l'indicatore di bilancio TString80 conto_anale; const int indbil = _indicatori.get_indbil(codconto, conto_anale); //solo i Costi(3) ed i Ricavi(4) devono essere considerati per la stampa if (indbil == 3 || indbil == 4) { TImporto saldo, saldop; const int flag = estrai_saldi(saldana, indbil, saldo, saldop); if (flag != 0) { const TString& codcms = saldana.get(SALDANA_COMMESSA).as_string(); const TString& fase = saldana.get(SALDANA_FASE).as_string(); const TRectype& rec_commesse = cache().get(LF_COMMESSE, codcms); const TDate dataini = rec_commesse.get(COMMESSE_DATAINIZIO); //per la data fine deve tener conto di eventuali proroghe.. TDate datafine; if (rec_commesse.get_bool(COMMESSE_PROROGA) && rec_commesse.get(COMMESSE_DATAPROR).ok()) datafine = rec_commesse.get(COMMESSE_DATAPROR); else datafine = rec_commesse.get(COMMESSE_DATAFINE); //e' inutile considerare le commesse terminate prima dell'esercizio selezionato.. //..cioe' nel passato oppure che iniziano nel futuro! if (datafine >= datainiesc && dataini <= datafinesc) { int indice = datafine <= datafinesc ? 0 : 2; if (dataini >= datainiesc) indice++; TString80 chiave = codcms; //selezione fasi solo su bilancio commessa (_tipo=8) if (_tipo == 8 && _use_fasi) chiave << '|' << fase; //riempie le righe degli array da mandare poi in stampa //dapprima le righe normali.. //gruppo e conto servono solo per il caso _tipo=8 ma vanno dichiarati e ricavati.. //..qui in modo che siano a disposizione delle commesse del cazzo poco sotto const char* gruppo = indbil == 3 ? "COSTI" : "RICAVI"; TString80 conto; parse_bill(conto_anale, conto); //bilancio di commessa (_tipo=8) if (_tipo == 8) { TAssoc_array& riga_array = get_row(cms[indice], chiave, indice, codcms, fase, rec_commesse.get(COMMESSE_DESCRIZ)); //aggiunge gli importi e normalizza aggiorna_importo(riga_array, gruppo, indbil, saldana); aggiorna_importo(riga_array, conto, indbil, saldana); } //stima ricavi (_tipo=9) else { TAssoc_array& riga_array = get_row(cms[indice], chiave, indice, codcms, EMPTY_STRING, rec_commesse.get(COMMESSE_DESCRIZ)); //aggiunge gli importi e normalizza aggiorna_importi(riga_array, indbil, saldana); } //..poi le righe speciali,che esistono solo se la commessa e' iniziata prima dell'anno //selezionato,quindi se l'indice e' 0 o 2 if (indice %2 == 0) { //aggiorna il record speciale con la somma dei saldi con anno anteriore a quello.. //..selezionato sulla maschera (CRPA request) const int anno = saldana.get(SALDANA_ANNO).as_int(); if (anno < _anno) { TString16 cazzo_cod; cazzo_cod.format("DETR_%04d", _anno - 1); TString cazzo_descr = "DETRAZIONE PER COMPETENZA "; cazzo_descr << (_anno - 1); TAssoc_array& riga_array = get_row(cms[indice], CMS_DEL_CAZZO, indice, cazzo_cod, EMPTY_STRING, cazzo_descr); if (_tipo == 8) { aggiorna_importo(riga_array, gruppo, indbil, saldana, true); aggiorna_importo(riga_array, conto, indbil, saldana, true); } else { aggiorna_importi(riga_array, indbil, saldana, true); } } } //if(indice... } //if (datafine >= datainiesc &&... } //if (saldop != ZERO.. } //if (indbil == 3 ||... } //merging dei 4 arrayini cms nell'arrayone _righe da mandare in stampa _righe.destroy(); for (int i = 0; i < 4; i++) { TAssoc_array& a = cms[i]; TObject* cazzo_cms = NULL; FOR_EACH_ASSOC_OBJECT(a, h, k, r) { TObject* obj = h->remove_obj(); if (strcmp(k, CMS_DEL_CAZZO) == 0) cazzo_cms = obj; else _righe.add(obj); // Copia nella destinazione la riga corrente e la toglie dall'originale } if (cazzo_cms != NULL) _righe.add(cazzo_cms); } //for(int... _righe.sort(righe_compare); //sorting delle commesse } const TVariant& TPrint_saldana_recordset::get(unsigned int column) const { return NULL_VARIANT; } const TVariant& TPrint_saldana_recordset::get(const char* column_name) const { if (_curr >= 0 && _curr < items()) { if (*column_name == '#') column_name++; TVariant& var = get_tmp_var(); if (strcmp(column_name, "ANNO") == 0) { var.set(_anno); } else if (strcmp(column_name, "TIPOSTIMA") == 0) { var.set(_tipostima == 'T' ? "T" : "C"); } else if (strcmp(column_name, "DEPTH") == 0) { var.set(_depth); } else if (strcmp(column_name, "VITAINTERA") == 0) { var.set(_vitaintera == true ? "SI" : "NO"); } else if (strcmp(column_name, "STAMPAFASI") == 0) { var.set(_use_fasi == true ? "X" : ""); } else if (strcmp(column_name, "AVANZAMENTO") == 0) { //Calcola lo stato di avanzamento della commessa real avanzamento; if (_tipostima == 'T') { avanzamento = calcola_avanzamento_tempo(); } else //se stima e' di tipo Costi... { } var.set(avanzamento); } else //if(strcmp(column_name,AVANZAMENTO... { TAssoc_array& riga = (TAssoc_array&)_righe[_curr]; const TString* val = (TString*)riga.objptr(column_name); if (val) var.set(*val); else var.set_null(); } return var; } return NULL_VARIANT; } void TPrint_saldana_recordset::set_filter(const TMask& msk) { //tira su un po' di parametri dalla maschera... _anno = msk.get_int(F_ESERCIZIO); //prende anche il prefix TString80 prefix; for (short id = F_PRE1; id <= F_PRE3 && msk.id2pos(id) > 0; id++) prefix << msk.get(id); _indicatori.set_prefix(prefix); if (_tipo == 8) { _tipostima = msk.get(F_TIPOSTIMA)[0]; _vitaintera = msk.get_bool(F_VITAINTERA); _depth = msk.get_int(F_DEPTH); //trattazione delle fasi _use_fasi = msk.get_bool(F_FASI); _fase.cut(0); if (_use_fasi) { /* ***gestione fasi multilivello for (short id = F_FASE1; msk.id2pos(id) > 0; id++) _fase << msk.get(id);*/ _fase = msk.get(F_FASE); } } }