// ve6300.cpp: programma di generazione effetti // Muliebrica parodia... // Il cavo delirante che irrompe nel silenzio dell'apogeo // * * * * * * * // * // _ _______ _____________ ___================ // _I_I___oo_____ii__| |_|| | | \ | |O| |_| |_| // | | - - | I | | | L M S | | | | // _|___|________|____ I____|_|=|_____________|=II=|__|_|_____________ // I=| o (_)--(_)--(_)--(_) O--O O-O +++++ O-O \--/ ()==() ++++ //======================================================================= // // // ____||____============____||___ ___=============================== // /__| OOOOOOOOOOOOO [_] | | |[]| [_] [_] [_] [_] // / S N C F | | | | // \________________________________|_ii_|__|__|___________________________ // ()==() === ++++ === ()==() ()==() +++ +++ ++++++++ //========================================================================= // // Have you ever heard MK ? #include #include #include #include #include #include #include #include #include #include #include #include #include "../cg/cgsaldac.h" #include "../ef/ef0101.h" #include "velib.h" #include "sconti.h" #include "ve6300a.h" // Enum di possibili errori enum error_type { no_error, elaboration_error, nr_doc_error, chg_stat_error, datadoc_error, codpag_error, scadenze_error, write_error, generic_error }; // TGenerazioneEffetti_app // Applicazione di generazione effetti class TGenerazioneEffetti_app : public TApplication { TString16 _cod_el; // codice elaborazione immesso TDate _data_reg; // data di registrazione immessa TDate _data_ini; // data di inizio intervallo TDate _data_fine; // data di fine intervallo bool _raggruppa; // se TRUE raggruppa gli effetti secondo i criteri TMask *_msk; // maschera di selezione dati TRelation *_clifo; // relazione dei clienti e fornitori + cfven TLocalisamfile *_docfile, // file dei documenti (per far funzionare TDocumento) *_rdocfile, // file delle righe documento (per far funzionare TDocumento) *_efffile, // file effetti *_refffile, // file righe di effetti *_cessfile, // file righe di cessionari *_occas, // file degli occasionali *_tab; // tabella di ditta TTable *_cpg; // tabella condizioni di pagamento TDocumento *_doc; // documento corrente TCond_vendita *_condv; // Condizioni di vendita // TCliFor *_clifor; // Cliente TPagamento *_pagamento; // pagamento corrente, ricalcolato prima di scrivere le scadenze TBit_array _valid_array; // array dei tipi di pagamento validi per la generazione di effetti TArray_sheet *_num_sheet; // Array sheet selezionabile dei codici numerazione TString_array _tipi_doc; // Array di stringhe contenente i tipi documenti da elaborare TArray _effetti_array;//Array di effetti (TEffetto) da scrivere TAssoc_array _group_array; // Assoc_array dei documenti da raggruppare. La chiave di ogni elemento // e composta dagli stessi criteri di raggruppamento (vedi sotto) // Ogni elemento e una TToken_string. Ogni elemento della TToken_string contiene // la chiave per identificare il documento che fa parte di quel raggruppamento error_type _error; // Errore rilevato durante l'elaborazione long _total_bills; // Totale effetti generati bool _can_write; // se TRUE e' abilitata la scrittura. Non appena rileva un errore rimane a FALSE for this instance char _final_doc_status; // Valore per lo stato finale del documento // Flags di raggruppamento opzionali (%ELD->S1): bool _group_by_date, // raggruppa per data di scadenza _group_by_sosp, // raggruppa per flag sosp. d'imposta _group_by_change, // raggruppa per cambio _group_by_pag, // raggruppa per cond. di pagamento _group_by_bank, // raggruppa per banca (ABI-CAB) _group_by_type, // raggruppa per tipo di documento _group_by_num, // raggruppa per cod. numerazione _group_by_agent; // raggruppa per agente protected: // TApplication // Cambia lo stato del documento error_type change_doc_status(); // Coontrolla se lo stato ed il tipo del documento sono validi e rispettano la selezione bool doc_tipo_stato_ok(); // Visualizza l'ultimo errore rilevato void display_error(); // Genera l'effetto void generate_bill(); // Genera gli effetti void generate(); // Le 4 seguenti non hanno bisogno di commenti virtual bool menu(MENU_TAG mt); virtual bool create(); virtual bool destroy(); // Handler del codice elaborazione differita static bool handle_cod_eld(TMask_field& f, KEY k); // Handler dell'intervallo di date static bool handle_data_range(TMask_field& f, KEY k); // Handler del pulsante di selezione codici numerazione static bool handle_select(TMask_field& f, KEY k); // Ritorna il TArray_sheet contenente le selezioni sui codici numerazione TArray_sheet* get_num_sheet() const { return _num_sheet; } // Costruisce lo sheet dei codici numerazione void build_num_sheet(); // Restituisce TRUE se il tipo di pagamento passato e' valido per generare l'effetto bool valid_type(int tipo_pag) const ; // Aggiunge il documento corrente alla lista dei documenti raggruppabili void add_to_group_list(); // Costruisce la stringa chiave per raggruppamento void build_group_key(TString& key); // Costruisce la stringa chiave per documento void build_doc_key(TToken_string& key); // Setta i flags di raggruppamento opzionali in base alla tabella void set_options(); // Effettua il raggruppamento vero e proprio degli effetti (solo se ci sono elementi nell'assoc_array void group_bills(); // Istanzia il pagamento corrente void calc_pagamento(TString16& codpag, const real& totale_fatt, TString16& data, const bool valuta, const real& change); // Scrive i record array degli effetti raggruppati error_type write_groups(); // Cambia lo stato dei gruppi di documenti raggruppati in effetti error_type change_group_status(); public: // Verifica se non ci sono stati errori bool good() const { return _error == no_error;} TGenerazioneEffetti_app() {_msk = NULL; _num_sheet = NULL;} virtual ~TGenerazioneEffetti_app() { } }; inline TGenerazioneEffetti_app& app() { return (TGenerazioneEffetti_app&) main_app(); } bool TGenerazioneEffetti_app::handle_data_range(TMask_field& f, KEY k) { if (k==K_ENTER && f.dirty()) { TMask& m = f.mask(); TDate da(m.get_date(F_DATA_INI)); TDate a(m.get_date(F_DATA_FIN)); //m.field(F_DATA_REG).set_dirty(); //if (a == botime || da == botime) return TRUE; if (a < da) { f.error_box("La data di inizio deve essere minore della data di fine."); return FALSE; } //if ((a - da) > 15) //{ // f.error_box("L'intervallo tra le date non puo' eccedere i 15 giorni."); // return FALSE; //} } return TRUE; } bool TGenerazioneEffetti_app::handle_cod_eld(TMask_field& f, KEY k) { if (f.to_check(k) && k == K_TAB) // se e' cambiato ricostruisce anche lo sheet dei codici numerazione { app()._cod_el = f.get(); // aggiorna il codice elaborazione per la build_num_sheet() f.mask().disable(DLG_OK); app().build_num_sheet(); } return TRUE; } bool TGenerazioneEffetti_app::handle_select(TMask_field& f, KEY k) { if (k == K_SPACE) { TMask& m = f.mask(); TArray_sheet* s = app().get_num_sheet(); if (s->run()) { if (s->checked() != 0) // Hai selezionato qualcosa ? m.enable(DLG_OK); // allora abilita il pulsante di conferma else m.disable(DLG_OK); } } return TRUE; } void TGenerazioneEffetti_app::build_num_sheet() { _num_sheet->destroy(); TTable eld("%ELD"); TTable num("%NUM"); TString s1,s2,s3; TString16 tipon1,tipon2,tipon3,tipon4,tipon5; // tipi documento validi per la numerazione long pos; eld.put("CODTAB",_cod_el); if (eld.read() == NOERR) { TToken_string t; s1.format("%-20s",(const char*)eld.get("S2")); s3 = eld.get("S7"); _final_doc_status = eld.get("S4")[0]; for (int i=0;i<5;i++) { t = s1.mid(i*4,4); // Tipo documento if (t.trim().empty()) break; t.add(s3.mid(i,1)); // Stato iniziale _tipi_doc.add(t); // Aggiunge questo tipo documento alla lista } for (pos=0,num.first();num.good();num.next(),pos++) // scorre tutte le numerazioni possibili { TToken_string t; t.add(" "); t.add(num.get("CODTAB")); t.add(num.get("S0")); _num_sheet->add(t); s2 = num.get("S2"); // reperisce i tipi documento validi per questa numerazione tipon1 = s2.mid(0,4); tipon2 = s2.mid(4,4); tipon3 = s2.mid(8,4); tipon4 = s2.mid(12,4); tipon5 = s2.mid(16,4); const int n1 = s1.find(tipon1); const int n2 = s1.find(tipon2); const int n3 = s1.find(tipon3); const int n4 = s1.find(tipon4); const int n5 = s1.find(tipon5); if ((tipon1.empty() || n1<0) && (tipon2.empty() || n2<0) && (tipon3.empty() || n3<0) && (tipon4.empty() || n4<0) && (tipon5.empty() || n5<0)) _num_sheet->disable_row(pos); else _num_sheet->enable_row(pos); } } } bool TGenerazioneEffetti_app::valid_type(int pag) const { return _valid_array[pag]; } bool TGenerazioneEffetti_app::create() { TApplication::create(); if (!has_module(EFAUT)) { error_box("Impossibile eseguire il programma se il modulo Effetti non e' abilitato"); return FALSE; } _error = no_error; _can_write = TRUE; _pagamento = NULL; _msk = new TMask("ve6300a"); _msk->set_handler(F_CODICE_ELAB,handle_cod_eld); _msk->set_handler(F_DATA_INI,handle_data_range); _msk->set_handler(F_DATA_FIN,handle_data_range); _msk->set_handler(DLG_USER,handle_select); _num_sheet = new TArray_sheet(-1,-1,-4,-4,"Codici numerazione", "@1|Cod. numerazione|Descrizione@50"); _docfile = new TLocalisamfile(LF_DOC); _rdocfile = new TLocalisamfile(LF_RIGHEDOC); _efffile = new TLocalisamfile(LF_EFFETTI); _refffile = new TLocalisamfile(LF_REFFETTI); _cessfile = new TLocalisamfile(LF_CESS); _occas = new TLocalisamfile(LF_OCCAS); // _clifor = new TCliFor(); // _condv = new TCond_vendita(_clifor); _cpg = new TTable("%CPG"); _tab = new TLocalisamfile(LF_TAB); _clifo = new TRelation(LF_CLIFO); _clifo->add(LF_CFVEN,"TIPOCF=TIPOCF|CODCF=CODCF"); _condv = new TCond_vendita(NULL); _doc = new TDocumento(); _condv->set_clifo(&_doc->clifor()); _doc->set_condv(_condv); // Settaggio dell'array dei tipi documento che possono generare effetti _valid_array.set(2); // tratta _valid_array.set(3); // riba _valid_array.set(5); // paghero' _valid_array.set(7); // tratta accettata _valid_array.set(8); // rapporti interbancari diretti (rid) _valid_array.reset(9); // bonifici dispatch_e_menu(BAR_ITEM(1)); return TRUE; } bool TGenerazioneEffetti_app::destroy() { if (_msk) delete _msk; if (_num_sheet) delete _num_sheet; if (_docfile) delete _docfile; if (_rdocfile) delete _rdocfile; if (_efffile) delete _efffile; if (_refffile) delete _refffile; if (_cessfile) delete _cessfile; if (_occas) delete _occas; if (_doc) delete _doc; if (_cpg) delete _cpg; if (_tab) delete _tab; if (_clifo) delete _clifo; return TApplication::destroy(); } bool TGenerazioneEffetti_app::menu(MENU_TAG mt) { while (_msk->run() == K_ENTER) { _cod_el = _msk->get(F_CODICE_ELAB); _data_ini = _msk->get_date(F_DATA_INI); _data_fine = _msk->get_date(F_DATA_FIN); _raggruppa = _msk->get_bool(F_RAGGRUPPA); generate(); } return FALSE; } bool TGenerazioneEffetti_app::doc_tipo_stato_ok() // Verifica che il tipo documento corrente esista tra i tipi previsti dalla elaborazione // differita selezionata { const int items = _tipi_doc.items(); bool found = FALSE; const TString16 tipo(_doc->tipo().codice()); const char stato = _doc->stato(); for (int i=0;istato(_final_doc_status); if (_doc->head().rewrite(*_docfile) != NOERR) _error = chg_stat_error; return _error; } error_type TGenerazioneEffetti_app::change_group_status() // Cambia lo stato dei documenti raggruppati { const int items = _group_array.items(); if (items > 0) { _error = no_error; TToken_string * group_element; int i=0; // Ciclo sugli elementi dell'assoc_array for (group_element = (TToken_string *) _group_array.first_item(); group_element != NULL && i < items; i++,group_element = (TToken_string*)_group_array.succ_item()) { group_element->restart(); const int doc_items = group_element->items(); for (int j=0;jget(j),'$'); char provv = t.get_char(0); int anno = t.get_int(1); TString codnum(t.get(2)); long numdoc = t.get_long(3); _docfile->put(DOC_PROVV,provv); _docfile->put(DOC_ANNO,anno); _docfile->put(DOC_CODNUM,codnum); _docfile->put(DOC_NDOC,numdoc); if (_docfile->read() == NOERR) // Legge il documento { _docfile->put(DOC_STATO,_final_doc_status); _docfile->rewrite(); } } } } return _error; } void TGenerazioneEffetti_app::display_error() { TString msg; TString numerazione = _doc->numerazione(); const long numero = _doc->numero(); switch (_error) { case elaboration_error: msg.format("Il documento %s/%ld non rientra tra i tipi documento validi per l'elaborazione." "Verificare i tipi documento ed il loro stato iniziale sul codice elaborazione inserito.",(const char*)numerazione,numero); break; case nr_doc_error: msg.format("Rilevato un numero di documento errato contabilizzando il documento %s/%ld." "Verificare il numero documento e il codice numerazione inseriti in tabella.",(const char*)numerazione,numero); break; case chg_stat_error: msg.format("Rilevato un errore cambiando lo stato al documento %s/%ld." "Verificare l'integrita' del file documenti.",(const char*)numerazione,numero); break; case datadoc_error: msg.format("Rilevato una data documento vuota relativamente al documento %s/%ld." "Verificare l'informazione inserita.",(const char*)numerazione,numero); break; case codpag_error: msg.format("Rilevato un codice pagamento non esistente relativamente al documento %s/%ld." "Verificare l'esistenza del codice pagamento inserito.",(const char*)numerazione,numero); break; case scadenze_error: msg.format("Calcolate 0 scadenze relativamente al documento %s/%ld." "Verificare la correttezza del codice pagamento inserito.",(const char*)numerazione,numero); break; case write_error: if (_efffile->status() != NOERR) msg.format("Si e' verificato l' errore %d in scrittura sul file effetti relativamente al documento %s/%ld" "Verificare la consistenza del file.",_efffile->status(),(const char*)numerazione,numero); else msg.format("Si e' verificato l' errore %d in scrittura sul file righe effetti relativamente al documento %s/%ld" "Verificare la consistenza del file.",_refffile->status(),(const char*)numerazione,numero); break; default: msg.format("E' stato rilevato un errore generico contabilizzando il documento %s/%ld.", (const char*)numerazione,numero); break; } warning_box(msg); _error = no_error; // reset error, as any other one would do, so you can show me the other ones. _can_write = FALSE; // But from now on u cannot write anymore. U must exit this program and repair errors occurred. } // Criteri di raggruppamento effetti. // Un documento puo' essere raggruppato con i seguenti criteri: // - flag di raggruppamento effetti a TRUE (obbligatorio) // - cliente (obbligatorio) // - valuta (obbligatorio) // - data scadenza (opzionale) // - flag di sosp. d'imposta (opzionale) // - cambio valuta (opzionale) // - cond di pagamento (opzionale) // - banca (opzionale) // - tipo doc. (opzionale) // - cod. numerazione (opzionale) // - agente (opzionale) // I parametri opzionali sono decisi nella tabella elaborazioni // Spiegazione del raggruppamento: // Il raggruppamento di documenti diversi in uno stesso effetto consiste nella creazione // di piu' righe dello stesso effetto. // Ad esempio supponiamo di avere il cliente 10 con 4 fatture ognuna con condizioni di pagamento diverse // la fattura 1 e' suddivisa in 2 rate (10.000 + 30.000) // la fattura 2 e' suddivisa in 4 rate (15.000 + 20.000 + 25.000 + 30.000) // la fattura 3 e' suddivisa in 5 rate (20.000 + 40.000 + 80.000 + 160.000 + 320.000) // la fattura 4 e' suddivisa in 3 rate (50.000 + 100.000 + 150.000) // Il numero di effetti generati equivale al massimo numero di rate (5 in questo caso) // quindi avremo 5 effetti: // il primo avra' 4 righe (prima rata di tutte le fatture) // il secondo avra' 4 righe (seconda rata di tutte le fatture) // il terzo avra' 3 righe (terza rata delle fatture 2,3,4) // il quarto avra' 2 righe (quarta rata delle fatture 2 e 3) // il quinto avra' 1 riga (quinta rata della fattura 3) // La testata di ogni effetto conterra' il totale (somma) dei singoli importi delle righe // ovvero: // tot. primo effetto: 95.000 // tot. secondo effetto: 190.000 // tot. terzo effetto: 255.000 // tot. quarto effetto: 190.000 // tot. quinto effetto: 320.000 // I dati della testata (soprattutto la data di scadenza) di ogni effetto vengono presi dal // primo documento valido per la generazione dell'effetto corrente: // per i primi due effetti vale la fattura 1 // per gli effetti 3 e 4 vale la fattura 2 // per l'effetto 5 vale la fattura 3. // Questo e' quanto ho appreso (Hope I'm right...) ;-) void TGenerazioneEffetti_app::add_to_group_list() { TString key; TToken_string t("",'$'); build_group_key(key); build_doc_key(t); const bool is_key = _group_array.is_key(key); TToken_string tt(is_key ? (TToken_string&) _group_array[key]: ""); tt.add(t); _group_array.add(key,tt, is_key ? TRUE : FALSE); } void TGenerazioneEffetti_app::build_group_key(TString& key) { long cli = _doc->get_long(DOC_CODCF); TString16 val(_doc->get(DOC_CODVAL)); // campi obbligatori key.format("%7ld%3s",cli,(const char*)val); // campi opzionali if (_group_by_date) { TString16 d(_doc->get(DOC_DATAINSC)); if (d.empty()) d = _doc->get(DOC_DATADOC); key << d; } // Qual'e' il flag di sospensione d'imposta del documento ?? // if (_group_by_sosp) // key << _doc->get(DOC_????); if (_group_by_change) key << _doc->get(DOC_CAMBIO); if (_group_by_pag) key << _doc->get(DOC_CODPAG); if (_group_by_bank) { key << _doc->get(DOC_CODABIA); // banca cliente key << _doc->get(DOC_CODCABA); } if (_group_by_type) key << _doc->get(DOC_TIPODOC); if (_group_by_num) key << _doc->get(DOC_CODNUM); if (_group_by_agent) key << _doc->get(DOC_CODAG); } void TGenerazioneEffetti_app::build_doc_key(TToken_string& key) { key.add(_doc->get(DOC_PROVV)); key.add(_doc->get(DOC_ANNO)); key.add(_doc->get(DOC_CODNUM)); key.add(_doc->get(DOC_NDOC)); } void TGenerazioneEffetti_app::set_options() { TTable eld("%ELD"); eld.put("CODTAB",_cod_el); if (eld.read() == NOERR) { TString s1; s1.format("%-20s",(const char*)eld.get("S1")); // Forzo la sua lunghezza a 20 per evitare subscript errors _group_by_date = s1[12] == 'X'; _group_by_sosp = s1[13] == 'X'; _group_by_change = s1[0] == 'X'; _group_by_pag = s1[4] == 'X'; _group_by_bank = s1[5] == 'X'; _group_by_type = s1[2] == 'X'; _group_by_num = s1[3] == 'X'; _group_by_agent = s1[7] == 'X'; } } void TGenerazioneEffetti_app::calc_pagamento(TString16& codpag,const real& totale_fatt, TString16& data, const bool valuta, const real& change) { _pagamento = new TPagamento(codpag, data); real totspese = _doc->spese(); real totimposte = _doc->imposta(); real totimponibili = totale_fatt - totimposte - totspese; if (valuta) { real val1 = totimponibili * change; real val2 = totimposte * change; real val3 = totspese * change; _pagamento->set_total_valuta( totimponibili, totimposte, totspese, change, val1, val2 ,val3); } else _pagamento->set_total( totimponibili, totimposte, totspese ); _pagamento->set_rate_auto( ); } error_type TGenerazioneEffetti_app::write_groups() { const int items = _effetti_array.items(); int err = NOERR; _error = no_error; for (int i = 0; iget(DOC_CODPAG)); _cpg->put("CODTAB",codpag); if (_cpg->read()!= NOERR) { _error = codpag_error; return; } TString16 data(_doc->get(DOC_DATAINSC)); if (data.empty()) data = _doc->get(DOC_DATADOC); const real totale_fatt = _doc->totale_doc(); // Importo in valuta if (totale_fatt > ZERO) { const bool valuta = _doc->in_valuta(); const real change = _doc->cambio(); // calcolo delle scadenze calc_pagamento(codpag,totale_fatt,data,valuta,change); CHECK(_pagamento,"Failed to create a TPagamento"); const int numrate = _pagamento->n_rate( ); if (numrate < 1) { _error = scadenze_error; return; } _efffile->last(); // Variabili per la scrittura dell'effetto long nprog = _efffile->get_long(EFF_NPROGTR)+1; const long codcf = _doc->get_long(DOC_CODCF); const TString16 codval(_doc->get(DOC_CODVAL)); const TDate data_cambio = _doc->get_date(DOC_DATACAMBIO); const long codabi = _doc->get_long(DOC_CODABIA); const long codcab = _doc->get_long(DOC_CODCABA); const TString16 provv(_doc->get(DOC_PROVV)); const int anno = _doc->get_int(DOC_ANNO); const TString16 codnum(_doc->get(DOC_CODNUM)); const long nfatt = _doc->get_long(DOC_NDOC); const TDate datafatt = _doc->get_date(DOC_DATADOC); TRectype& effetto = _efffile->curr(); TRectype& reffetto = _refffile->curr(); real importo; for (int i = 0; i < numrate && good(); i++) { if (valid_type(_pagamento->tipo_rata(i))) { effetto.zero(); reffetto.zero(); effetto.put(EFF_NPROGTR,nprog); effetto.put(EFF_DATASCAD, _pagamento->data_rata(i)); effetto.put(EFF_TIPOPAG,_pagamento->tipo_rata(i)); effetto.put(EFF_ULTCLASS,_pagamento->ulc_rata(i)); effetto.put(EFF_CODCF, codcf); effetto.put(EFF_CODVAL, codval); if (valuta) { effetto.put(EFF_CAMBIO, change); effetto.put(EFF_DATACAMBIO,data_cambio); } effetto.put(EFF_CODABI,codabi); effetto.put(EFF_CODCAB,codcab); effetto.put(EFF_EFFCOMP,TRUE); if (i == numrate - 1) effetto.put(EFF_ULTRATA,TRUE); // Put sulla riga dell'effetto reffetto.put(REFF_NPROGTR,nprog); reffetto.put(REFF_NRIGATR,1); reffetto.put(REFF_DATAFATT, datafatt); reffetto.put(REFF_NRATA,i+1); reffetto.put(REFF_PROVV,provv); reffetto.put(REFF_ANNODOC,anno); reffetto.put(REFF_CODNUM,codnum); reffetto.put(REFF_NFATT,nfatt); importo = _pagamento->importo_rata(i,FALSE); effetto.put(EFF_IMPORTO,importo); reffetto.put(REFF_IMPFATT,totale_fatt); reffetto.put(REFF_IMPORTO,importo); if (valuta) { importo = _pagamento->importo_rata(i,TRUE); // Importo in valuta real totfatlit = totale_fatt*change; //Not sure about this... effetto.put(EFF_IMPORTOVAL,importo); reffetto.put(REFF_IMPFATTVAL,totale_fatt); reffetto.put(REFF_IMPFATT,totfatlit); reffetto.put(REFF_IMPORTOVAL,importo); } if (_efffile->write() == NOERR && _refffile->write() == NOERR) { _total_bills++; nprog++; } else _error = write_error; } } } if (_pagamento) { delete _pagamento; _pagamento = NULL; } if (good() && _can_write) change_doc_status(); } void TGenerazioneEffetti_app::group_bills() { // Bail out if there aren't items... _error = no_error; const int items = _group_array.items(); if (items == 0) return; int i=0,j,n,offset=0; TString msg1,msg2; TString16 codpag; real imprata, imprataval, importo, importoval; msg1 = "Raggruppamento effetti "; msg1 << "dal "; msg1 << _data_ini.string() << " al "; msg1 << _data_fine.string(); #ifdef DBG TProgind p(items,msg1,TRUE,TRUE,1); #else TProgind p(items,msg1,FALSE,TRUE,1); #endif TToken_string * group_element; // Ciclo sugli elementi dell'assoc_array for (group_element = (TToken_string *) _group_array.first_item(); group_element != NULL && i < items; i++,group_element = (TToken_string*)_group_array.succ_item()) { #ifdef DBG if (p.iscancelled()) break; #endif p.setstatus(i+1); // Ciclo sui documenti da raggruppare group_element->restart(); const int doc_items = group_element->items(); for (j=0;jget(j),'$'); char provv = t.get_char(0); int anno = t.get_int(1); TString codnum(t.get(2)); long numdoc = t.get_long(3); if (_doc->read(provv,anno,codnum,numdoc) != NOERR) continue; // Legge il documento (giusto saltare e proseguire se non lo trova?) msg2 = "Documento: "; msg2 << codnum << "/" << numdoc; xvt_statbar_set(msg2); do_events(); // Ricalcola le scadenze codpag = _doc->get(DOC_CODPAG); _cpg->put("CODTAB",codpag); if (_cpg->read()!= NOERR) { _error = codpag_error; return; } TString16 data(_doc->get(DOC_DATAINSC)); if (data.empty()) data = _doc->get(DOC_DATADOC); const real totale_fatt = _doc->totale_doc(); const bool valuta = _doc->in_valuta(); const real change = _doc->cambio(); const TDate datafatt = _doc->get_date(DOC_DATADOC); calc_pagamento(codpag,totale_fatt,data,valuta,change); CHECK(_pagamento,"Failed to create a TPagamento"); const int numrate = _pagamento->n_rate( ); if (numrate < 1) { _error = scadenze_error; return; } // Scorre le scadenze for (n = 1; n <= numrate && good(); n++) { // Se non esiste effetto n-esimo (corrisponde al numero di rata corrente+offset) // lo genera con la relativa riga. Se esiste vi somma gli importi ed accoda la riga const bool is_new = n+offset > _effetti_array.items(); if (is_new) // Nuovo effetto: crea effetto con i dati di questo documento (e' il primo che incontro nella scansione) { TEffetto effetto; // Setta i dati della testata; effetto.put(EFF_DATASCAD, _pagamento->data_rata(n-1)); effetto.put(EFF_TIPOPAG,_pagamento->tipo_rata(n-1)); effetto.put(EFF_ULTCLASS,_pagamento->ulc_rata(n-1)); effetto.put(EFF_CODCF, _doc->get_long(DOC_CODCF)); effetto.put(EFF_CODVAL, _doc->get(DOC_CODVAL)); effetto.put(EFF_CAMBIO, change); effetto.put(EFF_DATACAMBIO,_doc->get_date(DOC_DATACAMBIO)); effetto.put(EFF_CODABI,_doc->get(DOC_CODABIA)); effetto.put(EFF_CODCAB,_doc->get(DOC_CODCABA)); effetto.put(EFF_EFFCOMP,TRUE); _effetti_array.add(effetto); } // aggiorna totale effetto (testata) TEffetto& effetto=(TEffetto&)_effetti_array[n+offset-1]; importo = effetto.get_real(EFF_IMPORTO); imprata = _pagamento->importo_rata(n-1,FALSE); importo += imprata; effetto.put(EFF_IMPORTO,importo); if (valuta) { importoval = effetto.get_real(EFF_IMPORTOVAL); imprataval = _pagamento->importo_rata(n-1,TRUE); importoval += imprataval; effetto.put(EFF_IMPORTOVAL,importoval); } // Crea la nuova riga di questo effetto const int rows = effetto.rows_r(); TRectype& riga = effetto.row_r(rows+1,TRUE); // reffetto.put(REFF_NPROGTR,nprog); riga.put(REFF_NRIGATR,rows+1); riga.put(REFF_NRATA,n); riga.put(REFF_DATAFATT, datafatt); riga.put(REFF_PROVV,provv); riga.put(REFF_ANNODOC,anno); riga.put(REFF_CODNUM,codnum); riga.put(REFF_NFATT,numdoc); riga.put(REFF_IMPFATT,totale_fatt); riga.put(REFF_IMPORTO,imprata); if (valuta) { riga.put(REFF_IMPFATTVAL,totale_fatt); real totfatlit = totale_fatt*change; riga.put(REFF_IMPFATT,totfatlit); riga.put(REFF_IMPORTOVAL,imprataval); } } // Ciclo sulle scadenze if (_pagamento) { delete _pagamento; _pagamento = NULL; } } // Ciclo sui documenti di questo gruppo offset=_effetti_array.items(); } // Ciclo sui gruppi // Cambia lo stato a tutti i documenti raggruppati if (good()) if (write_groups() == no_error) { _total_bills += _effetti_array.items(); change_group_status(); } } void TGenerazioneEffetti_app::generate() { TRelation doc_rel(LF_DOC); TRectype da(LF_DOC),a(LF_DOC); const long items = _num_sheet->items(); int year_from = _data_ini.year(); int year_to = _data_fine.year(); TString16 codnum; TString msg,filt_expr; _total_bills = 0; _group_array.destroy(); _effetti_array.destroy(); set_options(); da.put("DATADOC",_data_ini); da.put("PROVV","D"); da.put("ANNO",year_from); a.put("DATADOC",_data_fine); a.put("PROVV","D"); a.put("ANNO",year_to); for (long i=0L; ichecked(i)) // Se la numerazione corrente e' stata selezionata { // istanzia un cursore per la numerazione corrente, con i limiti di data codnum = _num_sheet->row(i).get(1); filt_expr = "CODNUM=\""; filt_expr << codnum << "\""; TCursor doc_cur(&doc_rel,filt_expr,3,&da,&a); const long cur_items = doc_cur.items(); // Scorre tutti i documenti che rientrano nell'intervallo selezionato if (cur_items == 0) { warning_box("Non vi sono effetti da generare per il codice numerazione %s",(const char*)codnum); continue; } msg = "Generazione effetti "; msg << codnum << " dal "; msg << _data_ini.string() << " al "; msg << _data_fine.string(); #ifdef DBG TProgind p(cur_items,msg,TRUE,TRUE,1); #else TProgind p(cur_items,msg,FALSE,TRUE,1); #endif long j = 0; // Comportamento: // - scorre i documenti della numerazione corrente. // - se e' possibile generare subito l'effetto (tipo di pagamento valido, // stato documento valido e non e' abilitato il raggruppamento) lo fa, // altrimenti compone una lista dei documenti da raggruppare // - alla fine del ciclo per numerazioni scorre la lista residua e genera gli // effetti rimasti #ifdef DBG for (;jread(doc_cur.curr()) != NOERR) continue;// legge il documento if (codnum != _doc->get(DOC_CODNUM)) continue; // patch del cazzo if (doc_tipo_stato_ok()) // controlla che il tipo documento e lo stato siano coerenti con la ELD selezionata { TPagamento & pag = _doc->pagamento(); if (pag.code().not_empty()) // && valid_type(pag.tipo_rata(0))) // il tipo di pagamento puo' generare effetti ? { const bool raggruppabile = _doc->get_bool(DOC_RAGGREFF); if (!_raggruppa || (_raggruppa && !raggruppabile)) generate_bill(); else add_to_group_list(); } else if (good() && _can_write) change_doc_status(); } // else // { // ATTENZIONE!: se non ha ancora cominciato a generare effetti, eventuali // documenti con tipo o stato differenti vengono semplicemente scartati // senza segnalare errori // if (_total_bills > 0) // _error = elaboration_error; // } if (!good()) display_error(); } #ifdef DBG if (p.iscancelled()) break; #endif } // Effettua il raggruppamento di eventuali documenti rimasti if (good()) group_bills(); // Mostra eventuali errori residui if (!good()) display_error(); if (_total_bills > 0) message_box("Totale effetti generati: %ld",_total_bills); xvt_statbar_set(""); } int ve6300 (int argc, char **argv) { TGenerazioneEffetti_app a; a.run(argc,argv,"Generazione effetti"); return TRUE; }