#include #include #include #include #include #include #include "../cg/cgsaldac.h" #include "../ef/ef0101.h" #include "velib.h" /////////////////////////////////////////////////////////// // TGenerazione_effetti /////////////////////////////////////////////////////////// static TPagamento* _pagamento = NULL; TGenerazione_effetti::TGenerazione_effetti(const char* cod) : TElaborazione(cod) { _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 _docfile = new TLocalisamfile(LF_DOC); _rdocfile = new TLocalisamfile(LF_RIGHEDOC); // _cessfile = new TLocalisamfile(LF_CESS); _occas = new TLocalisamfile(LF_OCCAS); _clifo = new TLocalisamfile(LF_CLIFO); _cfven = new TLocalisamfile(LF_CFVEN); _tab = new TLocalisamfile(LF_TAB); _efffile = new TLocalisamfile(LF_EFFETTI); _refffile = new TLocalisamfile(LF_REFFETTI); _cpg = new TTable("%CPG"); } TGenerazione_effetti::TGenerazione_effetti(const TRectype& rec) : TElaborazione(rec) { _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 _docfile = new TLocalisamfile(LF_DOC); _rdocfile = new TLocalisamfile(LF_RIGHEDOC); // _cessfile = new TLocalisamfile(LF_CESS); _occas = new TLocalisamfile(LF_OCCAS); _clifo = new TLocalisamfile(LF_CLIFO); _cfven = new TLocalisamfile(LF_CFVEN); _tab = new TLocalisamfile(LF_TAB); _efffile = new TLocalisamfile(LF_EFFETTI); _refffile = new TLocalisamfile(LF_REFFETTI); _cpg = new TTable("%CPG"); } TGenerazione_effetti::~TGenerazione_effetti() { delete _docfile; delete _rdocfile; // delete _cessfile; delete _occas; delete _clifo; delete _cfven; delete _efffile; delete _refffile; delete _tab; delete _cpg; } void TGenerazione_effetti::display_error(TDocumento& doc) { TString msg; TString numerazione = doc.numerazione(); const long numero = doc.numero(); switch (_error) { 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. } error_type TGenerazione_effetti::change_doc_status(TDocumento& doc) // Cambia lo stato del documento { doc.stato(get("S4")[0]); if (doc.rewrite() != NOERR) _error = chg_stat_error; return _error; } error_type TGenerazione_effetti::change_group_status(TDocumento& doc) // 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); if (doc.read(provv,anno,codnum,numdoc) == NOERR) // Legge il documento { doc.put(DOC_STATO,get("S4")[0]); doc.rewrite(); } } } } return _error; } error_type TGenerazione_effetti::write_groups() { const int items = _effetti_array.items(); int err = NOERR; _error = no_error; for (int i = 0; irestart(); 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(doc,codpag,data); CHECK(_pagamento,"Failed to create a TPagamento"); const int numrate = _pagamento->n_rate( ); if (numrate < 1) { _error = scadenze_error; delete _pagamento; _pagamento = NULL; 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() && _can_write) if (write_groups() == no_error) { _total_bills += _effetti_array.items(); change_group_status(doc); } _effetti_array.destroy(); _group_array.destroy(); } bool TGenerazione_effetti::valid_type(int pag) const { return _valid_array[pag]; } void TGenerazione_effetti::calc_pagamento(TDocumento& doc, TString16& codpag, TString16& data) { _pagamento = new TPagamento(codpag, data); const real change = doc.cambio(); real totspese = doc.spese(); real totimposte = doc.imposta(); real totimponibili = doc.totale_doc() - totimposte - totspese; if (doc.in_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(); } void TGenerazione_effetti::generate_bill(TDocumento& doc) // bill in inglese significa anche effetto eheheh ;-) { // That's my JOB! // Ogni rata della fattura (si parla di effetti attivi per ora) genera 1 effetto. // con almeno una riga. // Ad es. Se ho una fattura suddivisa in 3 rate essa generera' 3 effetti con una riga. // Nel caso si decida di raggruppare gli effetti (vedi criteri di raggruppamento) // avro' un effetto con tante righe quante scadenze di fattura sono raggruppabili // Le fatture possono generare effetti solo per i seguenti tipi di pagamento: // 2 - Tratta // 3 - Ri.Ba. // 5 - Paghero' // 7 - Tratta accettata // 8 - Rapporti interbancari diretti // Caso mai tale insieme risultasse incompleto od errato basta solo modificare l'enum posto all'inizio del programma TString16 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(); // Importo in valuta if (totale_fatt > ZERO) { const bool valuta = doc.in_valuta(); const real change = doc.cambio(); // calcolo delle scadenze calc_pagamento(doc,codpag,data); 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(doc); } bool TGenerazione_effetti::elabora(TLista_documenti& doc_in, TLista_documenti& doc_out, const TDate& data_elab) { _pagamento = NULL; _error = no_error; _can_write = TRUE; _total_bills = 0L; const int items = doc_in.items(); // Numero dei documenti in questa elaborazione TProgind p(items,"Generazione effetti",FALSE,TRUE,1); for (int i = 0; i < items ; i++) // Scorriamo tutti i documenti nella lista { generate_bill(doc_in[i]); // Genera gli effetti corrispondenti p.setstatus(i+1); if (!good()) display_error(doc_in[i]); } // Effettua il raggruppamento di eventuali documenti rimasti TDocumento doc; if (good()) group_bills(doc); // Mostra eventuali errori residui if (!good()) display_error(doc); return _can_write; }