// 770200 - collegamento 1a nota (versamento) - ritenuta percipienti #include #include #include #include #include #include #include #include #include #include "77lib.h" #include "770200a.h" class TVersa_rit : public TApplication { private: TLink770 _coll; real _versato; TRelation* _rel; TCursor* _cur; TCursor_sheet* _sheet_perc; TArray_sheet* _schede; TArray_sheet* _pagam; TMask* _msk; TLocalisamfile* _perc, *_scperc, *_rpag, *_rver; TAssoc_array _apags; // Estremi versamento TString16 _data, _serie, _numero; char _luogo, _tipo; void add(const long codditta, char tipoa, const long codanagr, const int nprog, TToken_string& rriga); TToken_string* find(const long codditta, char tipoa, const long codanagr, const int nprog); void remove(const long codditta, char tipoa, const long codanagr, const int nprog); static void work_tipoluogo(TMask_field& f); static bool luo_hndl (TMask_field& f, KEY k); static bool tipo_hndl(TMask_field& f, KEY k); static bool abicab_hndl(TMask_field& f, KEY k); protected: virtual bool create(); virtual bool destroy(); virtual bool menu(MENU_TAG m); int split_rpag(const long codditta,char tipoa, const long codanagr, const int nprog, const int nriga, real& versato, real& da_versare, const long newvers); int attach_rpag(const long codditta, char tipoa, const long codanagr, const int nprog, const int nriga, const long new_vers); long add_new_vers(const long codditta, char tipoa, const long codanagr, const int nprog, real& versato); void attach_pag_vers(TToken_string& r, real& versato, const bool last=FALSE); real ritenuta_versata(const long codditta,const long numvers); bool ha_pagamenti_non_versati(const long codditta, char tipoa,const long codanagr,const int nprog); TCursor* meik_curs(TRelation* rel); bool do_all(); void build_schede_sheet(const long codditta); void build_pagam_sheet(const long codditta); public: TVersa_rit() {} ~TVersa_rit() {} }; TCursor* TVersa_rit::meik_curs(TRelation* rel) { TString16 filt; TCursor* cur; const long codditta = get_firm(); filt.format("CODDITTA=%ld", codditta); cur = new TCursor(rel, filt); return cur; } bool TVersa_rit::create() { TApplication::create(); // simulo una chiamata da contabilità // (lo lascio per eventuali prove) // real totdocla = ZERO; // real spesela = ZERO; // real compensola = ZERO; // real impostela = ZERO; // real ritenutela = 70000; // TToken_string s(80); // s.add(4); // s.add("M"); // s.add("F"); // s.add(30010); // s.add(1); // s.add("2"); // s.add("02-09-1997"); // s.add(totdocla.string()); // s.add(spesela.string()); // s.add(compensola.string()); // s.add(impostela.string()); // s.add(ritenutela.string()); // const char* name = "770 -1"; // TMessage mla(name, "LINK770", s); // mla.send(); // Collegamento da contabilita' TMailbox m; TMessage* msg = m.next_s("LINK770"); // Questo programma si richiama solo dalla contabilita' if (!msg) return FALSE; if ( !_coll.read(msg->body()) ) return warning_box("Errore nei parametri passati"); _perc = new TLocalisamfile(LF_PERC); _scperc = new TLocalisamfile(LF_SCPERC); _rpag = new TLocalisamfile(LF_RPAG); _rver = new TLocalisamfile(LF_RVER); _rel = new TRelation(LF_PERC); _rel->add(LF_ANAG, "TIPOA=TIPOA|CODANAGR=CODANAGR"); _cur = meik_curs(_rel); _msk = new TMask("770200a"); _msk->set_handler(F_LUOGO, luo_hndl); _msk->set_handler(F_TIPO, tipo_hndl); _msk->set_handler(F_SERIE, abicab_hndl); _msk->set_handler(F_NUMERO, abicab_hndl); _msk->set(F_DATA, _coll._datadoc); _msk->set(F_VERSATO, _coll._ritenute.string()); _sheet_perc = new TCursor_sheet(_cur, " |TIPOA|CODANAGR|6->RAGSOC", "Selezione percipienti", "@1|Tipo|Codice|Ragione sociale@50", 8, 3); _schede = new TArray_sheet(3, 3, -3, -3, "Selezione schede", "@1|T|Codice|Scheda n.|Data@10|Ragione@50"); _pagam = new TArray_sheet(3, 3, -3, -3, "Selezione ritenute da versare", "@1|T|Codice|Scheda n.|Riga n.|Ritenuta@18R"); _apags.destroy(); dispatch_e_menu (BAR_ITEM(1)); return TRUE; } bool TVersa_rit::destroy() { delete _rel; delete _cur; delete _msk; delete _schede; delete _pagam; delete _sheet_perc; delete _rver; delete _rpag; delete _scperc; delete _perc; return TApplication::destroy(); } void TVersa_rit::work_tipoluogo(TMask_field& f) { TMask& m = f.mask(); char tipo = m.get(F_TIPO)[0]; char luogo = m.get(F_LUOGO)[0]; m.hide (-2); // nasconde tutto if (tipo == 'D') { if (luogo == 'T') m.show(-3); // SOLO quietanza else m.show(-4); // serie e numero } else if (tipo == 'B') m.show (-6); // ABI e CAB else if (tipo == 'C') m.show (-5); // SOLO numero versamento } bool TVersa_rit::luo_hndl(TMask_field& f, KEY k) { if (k == K_TAB) work_tipoluogo(f); if (k == K_ENTER) { TMask& m = f.mask(); char tipo = m.get(F_TIPO)[0]; char luogo = m.get(F_LUOGO)[0]; // Se ho indicato il luogo => devo indicare anche il TIPO if (isalpha(luogo)) return tipo == ' ' || tipo == '\0' ? f.warning_box("Indicare il tipo del versamento") : TRUE; } return TRUE; } bool TVersa_rit::tipo_hndl(TMask_field& f, KEY k) { if (k == K_TAB) work_tipoluogo(f); if (k == K_ENTER || k == K_TAB) { TMask& m = f.mask(); char tipo = m.get(F_TIPO)[0]; char luogo = m.get(F_LUOGO)[0]; // Se ho indicato il tipo => devo indicare anche il LUOGO if (isalpha(tipo)) if (luogo == ' ' || luogo == '\0') f.warning_box("Indicare il luogo del versamento"); } return TRUE; } bool TVersa_rit::abicab_hndl(TMask_field& f, KEY k) { if (f.to_check(k)) { TString16 park(f.get()); TMask& m = f.mask(); char tipo = m.get(F_TIPO)[0]; // ABI/CAB solo se tipo e' B if (tipo != 'B') return TRUE; for (int i=0; i ZERO) { found = TRUE; rriga.add(nriga); rriga.add(resto.string()); } } ***************************************************************/ rpag.next(); } if (found) add(codditta,tipoa,codanagr,nprog,rriga); return found; } void TVersa_rit::build_pagam_sheet(const long codditta) { _pagam->destroy(); // build array_sheet dei pagamenti non collegati o non del tutto versati int nriga = 0; for (int i=0; i < _schede->items(); i++) if (_schede->checked(i)) { TToken_string& r = _schede->row(i); char tipoa = r.get_char(1); long codanagr = r.get_long(2); const int nprog = r.get_int(3); TToken_string* tpag = find(codditta,tipoa,codanagr,nprog); if (!tpag) continue; while ( (nriga = tpag->get_int()) != 0 ) // le righe partono da 1 { const real da_versare = tpag->get(); // leggo importo rimasto da versare const TCurrency k(da_versare); TToken_string rr(100); rr.add(" "); // Spazio per selezionare rr.add(tipoa); rr.add(codanagr); // rr.add(ragsoc); rr.add(nprog); rr.add(nriga); rr.add(k.string(TRUE)); _pagam->add(rr); } } } void TVersa_rit::build_schede_sheet(const long codditta) { // Costruisco lista schede _schede->destroy(); TLocalisamfile sch(LF_SCPERC); sch.setkey(1); for (int i=0; i<_sheet_perc->items(); i++) if (_sheet_perc->checked(i)) { // Leggo tipo e codice del percipiente selezionato TToken_string& r = _sheet_perc->row(i); char tipoa = r.get_char(1); long codanagr = r.get_long(2); TString80 ragsoc(r.get(3)); sch.zero(); sch.put("CODDITTA", (long)codditta); sch.put("TIPOA", tipoa); sch.put("CODANAGR", codanagr); TRectype dep(sch.curr()); // Leggo tutte le schede del percipiente scelto sch.read(_isgteq); while (sch.curr() == dep && !sch.eof()) { const int nprog = sch.get_int("NPROG"); TString16 datadoc(sch.get("DATADOC")); // Considero solo le schede con pagamenti non ancora versati if (ha_pagamenti_non_versati(codditta,tipoa,codanagr,nprog)) { TToken_string rr(100); rr.add(" "); // Spazio per selezionare rr.add(tipoa); rr.add(codanagr); rr.add(nprog); rr.add(datadoc); rr.add(ragsoc); _schede->add(rr); } sch.next(); } } // if checked } bool TVersa_rit::do_all() { KEY kp; long items = 0L; // esecuzione prima maschera: richiesta estremi versamento kp = _msk->run(); if (kp != K_ENTER) return FALSE; else { _data = _msk->get(F_DATA); _luogo = _msk->get(F_LUOGO)[0]; _tipo = _msk->get(F_TIPO)[0]; _versato = real(_msk->get(F_VERSATO)); if (_tipo == DELEGA_BANCARIA) { _serie = _msk->get(F_ABI); _numero = _msk->get(F_CAB); } else { _serie = _msk->get(F_SERIE); _numero = _msk->get(F_NUMERO); } } // loop di gestione sheet di scelta percipiente, // scelta scheda e scelta pagamento da versare while (TRUE) { items = _sheet_perc->items(); if (items == 0L) { warning_box("Nessun percipiente registrato"); return FALSE; } kp = _sheet_perc->run(); if (kp == K_ENTER) if (!_sheet_perc->one_checked()) { warning_box("Nessun percipiente selezionato"); continue; } if (kp == K_ESC) return FALSE; const long selected = _sheet_perc->selected(); const long codditta = get_firm(); build_schede_sheet(codditta); items = _schede->items(); if (items == 0L) { warning_box("Non esistono pagamenti non versati per i percipienti selezionati"); continue; } kp = _schede->run(); if (kp == K_ENTER) if (!_schede->one_checked()) { warning_box("Nessuna scheda selezionata"); continue; } if (kp == K_ESC) continue; build_pagam_sheet(codditta); kp = _pagam->run(); if (kp == K_ENTER) if (!_pagam->one_checked()) { warning_box("Nessun pagamento selezionato"); continue; } if (kp == K_ESC) continue; // Leggo importo arrivato dalla contabilita' // _versato = _coll._totdoc; // Distribuisce _versato sui pagamenti selezionati creando la riga di // versamento se occorre long chk = 0L; for (int i=0; i < _pagam->items(); i++) if (_pagam->checked(i)) { chk++; if (_versato == ZERO) break; // Sull'ultimo pagamento metto tutto il versamento rimasto const bool last_checked = chk == _pagam->checked(); TToken_string& r = _pagam->row(i); real da_versare(r.get(5)); attach_pag_vers(r, _versato, last_checked); if (da_versare > _versato) _versato = ZERO; else _versato -= da_versare; } return warning_box("Creazione versamenti terminata"); } // while (TRUE) return TRUE; } void TVersa_rit::attach_pag_vers(TToken_string& r, real& versato, const bool last) { char tipoa = r.get_char(1); const long codanagr = r.get_long(2); const int nprog = r.get_int(3); const int nriga = r.get_int(4); const long codditta = get_firm(); real da_versare(r.get(5)); // importo ancora "scoperto" in questo pag. /************************************************************************* TLocalisamfile rpag(LF_RPAG); rpag.setkey(1); rpag.zero(); rpag.put("CODDITTA", (long)codditta); rpag.put("TIPOA", tipoa); rpag.put("CODANAGR", (long)codanagr); rpag.put("NPROG", nprog); rpag.put("NRIGA", nriga); if (rpag.read() != NOERR) return; // Non dovrebbe succedere mai // Decido l'importo da attribuire al nuovo versamento real ritenuta = rpag.get_real("RITENUTA"); *************************************************************************/ real vers_corr = ZERO; // Se e' l'ultimo pagamento metto tutto l'importo del versamento if (last) vers_corr = versato; else vers_corr = versato > da_versare ? da_versare : versato; // const long numvers = rpag.get_long("NUMVERS"); const long new_vers = add_new_vers(codditta,tipoa,codanagr,nprog,vers_corr); // Se il pagamento era gia' collegato ad un versamento lo divido in due // pagamenti: uno lo lascio collegato al precedente versamento, l'altro // collegato al nuovo. // Ogni pagamento puo' essere collegato A UNO E UNO SOLO versamento /****** if (numvers > 0) split_rpag(codditta,tipoa,codanagr,nprog,nriga,versato,da_versare,new_vers); else *****/ attach_rpag(codditta,tipoa,codanagr,nprog,nriga,new_vers); } int TVersa_rit::split_rpag(const long codditta,char tipoa, const long codanagr, const int nprog, const int nriga, real& versato, real& da_versare, const long new_vers) { TLocalisamfile rpag(LF_RPAG); long numpag = 0L; long pag = 0L; int new_riga = 0; int ret_code = 0; // Determino un nuovo NUMPAG for (rpag.first(); !rpag.eof(); rpag.next()) { pag = rpag.get_long("NUMPAG"); if (pag > numpag) numpag = pag; } numpag++; // Determino un nuovo NRIGA rpag.zero(); rpag.put("CODDITTA", (long)codditta); rpag.put("TIPOA", tipoa); rpag.put("CODANAGR", (long)codanagr); rpag.put("NPROG", nprog); TRectype dep(rpag.curr()); rpag.read(_isgteq); while (rpag.curr() == dep && !rpag.eof()) { new_riga = rpag.get_int("NRIGA"); rpag.next(); } new_riga++; // Sposto il pagamento preesistente rpag.zero(); rpag.put("CODDITTA", (long)codditta); rpag.put("TIPOA", tipoa); rpag.put("CODANAGR", (long)codanagr); rpag.put("NPROG", nprog); rpag.put("NRIGA", nriga); if ((ret_code = rpag.read()) != NOERR) return ret_code; // Leggo ritenuta del vecchio record e il suo versamento eventuale // La parte che era stata gia' versata resta con il vecchio record // La parte versata ora viene registrata nel nuovo. real ritenuta = rpag.get_real("RITENUTA"); real parte_versata = ritenuta - da_versare; TRectype salvo(rpag.curr()); rpag.zero(); rpag.curr() = salvo; // Cambio solo: NUMPAG, NRIGA, e aggiorno la ritenuta. NUMVERS resta uguale rpag.put("NUMPAG", (long)numpag); rpag.put("NRIGA", new_riga); rpag.put("RITENUTA", parte_versata); // Registro il vecchio pagamento nella nuova posizione if ((ret_code = rpag.write()) != NOERR) warning_box("Pagamento non inserito. Codice %d", ret_code); // Modifico l'originale per puntare al nuovo versamento rpag.zero(); rpag.curr() = salvo; rpag.put("NUMVERS", (long) new_vers); rpag.put("RITENUTA", da_versare); // Salvo le modifiche al vecchio pagamento if ((ret_code = rpag.rewrite()) != NOERR) warning_box("Pagamento non modificato. Codice %d", ret_code); return ret_code; } int TVersa_rit::attach_rpag(const long codditta, char tipoa, const long codanagr, const int nprog, const int nriga, const long new_vers) { TLocalisamfile rpag(LF_RPAG); int ret_code = 0; rpag.zero(); rpag.put("CODDITTA", (long)codditta); rpag.put("TIPOA", tipoa); rpag.put("CODANAGR", (long)codanagr); rpag.put("NPROG", nprog); rpag.put("NRIGA", nriga); if ((ret_code = rpag.read()) != NOERR) { warning_box("Pagamento non trovato. Codice %d", ret_code); return ret_code; } rpag.put("NUMVERS", (long)new_vers); if ((ret_code = rpag.rewrite()) != NOERR) { warning_box("Pagamento non modificato. Codice %d", ret_code); return ret_code; } return ret_code; } long TVersa_rit::add_new_vers(const long codditta, char tipoa, const long codanagr, const int nprog, real& versata) { TLocalisamfile rver(LF_RVER); int nriga = 0; // Determino un numero di riga nuovo rver.zero(); rver.put("CODDITTA", (long)codditta); rver.put("TIPOA", tipoa); rver.put("CODANAGR", (long)codanagr); rver.put("NPROG", nprog); TRectype dep(rver.curr()); rver.read(_isgteq); while (rver.curr() == dep && !rver.eof()) { nriga = rver.get_int("NRIGA"); rver.next(); } nriga++; // Scrivo il nuovo record rver.zero(); rver.put("CODDITTA", (long)codditta); rver.put("TIPOA", tipoa); rver.put("CODANAGR", (long)codanagr); rver.put("NPROG", nprog); rver.put("NRIGA", nriga); // rver.put("NUMVERS", (long)nriga); rver.put("DATAVERS", _data); rver.put("LUOVERS", _luogo); rver.put("TIPOVERS", _tipo); rver.put("SERIE", _serie); rver.put("NUMERO", _numero); rver.put("RITENUTA", versata); if (rver.write() != NOERR) { warning_box("Fallita creazione versamento. Codice %d", rver.status()); return 0L; } return nriga; } bool TVersa_rit::menu(MENU_TAG m) { if (m == BAR_ITEM(1)) return do_all(); return FALSE; } int collega_vers_rit(int argc, char* argv[]) { TVersa_rit a; a.run(argc, argv, "Versamento ritenute"); return 0; }