#include #include #include #include #include #include "cg2200.h" #include "cg2101.h" #include "cglib01.h" #include "cglib02.h" #include TString& add_plural(TString& s, long num, const char* name) { const TFixed_string n(name); const char last = n[n.len()-1]; if (num < 1) { s << "nessun"; if (toupper(last) == 'A' || toupper(n[0]) == 'Z' || toupper(n[0]) == 'S' && strchr("aeiouAEIOU", n[1]) == NULL) s << tolower(last); s << ' ' << name; } else { s << num << ' ' << name; if (num > 1) s[s.len()-1] = (last == 'a') ? 'e' : 'i'; } return s; } class TProvvisori_app : public TApplication { TLocalisamfile* _sal; TLocalisamfile* _cau; TTable* _reg; char _provv; // Tipo provvisori da cancellare TString16 _from_caus, _to_caus; // Causali movimenti da considerare TSaldo_agg _saldi; protected: // TApplication virtual bool create(); virtual bool destroy(); virtual bool menu(MENU_TAG m); protected: static bool date_handler(TMask_field& f, KEY k); public: void inizia_saldi(const TRectype& mov); void aggiungi_saldi(const TRectype& rmov, bool lettura); void aggiorna_saldi(); bool confirm_provv(TCursor& cur, TProgind& pi); bool delete_provv(TCursor& cur, TProgind& pi); static bool filter(const TRelation* rel); void auto_delete(TCursor& cur); TProvvisori_app() {}; virtual ~TProvvisori_app() {} }; inline TProvvisori_app& app() { return (TProvvisori_app&)main_app(); } bool TProvvisori_app::create() { TApplication::create(); _cau = new TLocalisamfile(LF_CAUSALI); _sal = new TLocalisamfile(LF_SALDI); _reg = new TTable("REG"); dispatch_e_menu(BAR_ITEM(1)); return TRUE; } bool TProvvisori_app::destroy() { delete _reg; delete _sal; delete _cau; return TApplication::destroy(); } void TProvvisori_app::inizia_saldi(const TRectype& r) { CHECK(r.num() == LF_MOV, "Voglio un movimento"); _saldi.reset(); tiposal tsal = normale; const TString& c = r.get(MOV_CODCAUS); if (c.not_empty()) { _cau->put(CAU_CODCAUS, c); if (_cau->read() == NOERR) { if (_cau->get_char(CAU_MOVAP) == 'A') tsal = apertura; else if (_cau->get_char(CAU_MOVAP) == 'C') tsal = chiusura; } } _saldi.set_tipo_saldo(tsal); _saldi.set_anno_es(r.get_int(MOV_ANNOES)); _saldi.set_num_ulmov(r.get_long(MOV_NUMREG)); _saldi.set_data_ulmov(r.get_date(MOV_DATAREG)); } void TProvvisori_app::aggiungi_saldi(const TRectype& r, bool lettura) { CHECK(r.num() == LF_RMOV, "Voglio la riga di un movimento"); TBill conto; conto.get(r); TImporto importo(r.get_char(RMV_SEZIONE), r.get_real(RMV_IMPORTO)); _saldi.set_movprovv(lettura); // In lettura sono tutti provvisori _saldi.aggiorna(conto, importo, !lettura); // In lettura devo sottrarre l'importo } void TProvvisori_app::aggiorna_saldi() { _saldi.registra(); } bool TProvvisori_app::confirm_provv(TCursor& cur, TProgind& pi) { TLocalisamfile& mov = cur.file(LF_MOV); TLocalisamfile rmov(LF_RMOV); for (cur = 0; cur.pos() < cur.items(); ++cur) { const long numreg = mov.get_long(MOV_NUMREG); inizia_saldi(mov.curr()); int err = cur.lock(); for (int rig = 1; err == NOERR; rig++) { rmov.put(RMV_NUMREG, numreg); rmov.put(RMV_NUMRIG, rig); if (rmov.read(_isequal, _lock) != NOERR) break; aggiungi_saldi(rmov.curr(), TRUE); aggiungi_saldi(rmov.curr(), FALSE); } if (err == NOERR) { mov.zero(MOV_PROVVIS); err = mov.rewrite(); if (err == NOERR) { aggiorna_saldi(); pi.addstatus(1); } } if (err != NOERR) return error_box("Errore nella conferma del movimento %ld", numreg); } return TRUE; } bool TProvvisori_app::delete_provv(TCursor& cur, TProgind& pi) { TLocalisamfile& mov = cur.file(LF_MOV); TLocalisamfile rmov(LF_RMOV); TLocalisamfile rmoviva(LF_RMOVIVA); TString256 error; for (cur = 0; cur.pos() < cur.items(); ++cur) { const long numreg = mov.get_long(MOV_NUMREG); mov.setkey(1); // Isam bug on remove with key != 1 mov.put(MOV_NUMREG, numreg); int err = mov.read(_isequal, _lock); if (err != NOERR) return error_box("Errore %d nel bloccare il record %ld", err, numreg); inizia_saldi(mov.curr()); for (int rig = 1; err == NOERR; rig++) { rmov.put(RMV_NUMREG, numreg); rmov.put(RMV_NUMRIG, rig); if (rmov.read(_isequal, _lock) != NOERR) break; aggiungi_saldi(rmov.curr(), TRUE); err = rmov.remove(); if (err != NOERR) error.format("riga contabile %d", rig); } for (rig = 1; err == NOERR; rig++) { rmoviva.put(RMI_NUMREG, numreg); rmoviva.put(RMI_NUMRIG, rig); if (rmoviva.read(_isequal, _lock) != NOERR) break; err = rmov.remove(); if (err != NOERR) error.format("riga IVA %d", rig); } if (err == NOERR) { err = mov.remove(); if (err != NOERR) error = "testata"; } if (err == NOERR) { aggiorna_saldi(); pi.addstatus(1); } else return error_box("Errore %d nella cancellazione della %s del movimento %ld", err, (const char*)error, numreg); } return TRUE; } bool TProvvisori_app::filter(const TRelation* rel) { TProvvisori_app& a = app(); const TRectype& mov = rel->curr(); const char provv = mov.get_char(MOV_PROVVIS); bool ok = (a._provv <= ' ' && provv > ' ' || a._provv == provv); if (ok) { const char* caus = mov.get(MOV_CODCAUS); ok = a._from_caus <= caus && a._to_caus >= caus; } return ok; } // Deve essere specificata almeno una data (inizio o fine) bool TProvvisori_app::date_handler(TMask_field& f, KEY k) { bool ok = TRUE; if (k == K_ENTER && f.get().empty()) { const TMask& m = f.mask(); if (m.get(F_TODATE).empty()) ok = f.error_box("E' necessario specificare almeno una data"); } return ok; } void TProvvisori_app::auto_delete(TCursor& cur) { _from_caus = ""; _to_caus = "ZZZ"; _provv = argv(2)[0]; cur.set_filterfunction(filter); const long total = cur.items(); TProgind pi(total, "Cancellazione", FALSE, TRUE, 24); cur.freeze(TRUE); delete_provv(cur, pi); cur.freeze(FALSE); } bool TProvvisori_app::menu(MENU_TAG) { TMask m("cg2200a"); m.set_handler(F_FROMDATE, date_handler); TCursor& cur = *m.efield(F_FROMDATE).browse()->cursor(); if (argc() > 2) { auto_delete(cur); return FALSE; } while (TRUE) { TRectype from(LF_MOV), to(LF_MOV); cur.setregion(from, to); cur.set_filterfunction(NULL); m.reset(); KEY key = m.run(); if (key != K_ENTER && key != K_DEL) break; TString16 from_d = m.get(F_FROMDATE); TString16 to_d = m.get(F_TODATE); if (from_d.empty() && to_d.empty()) { error_box("E' nessario specificare almeno una data."); continue; } if (key == K_ENTER) { const TDate da(from_d); const TLibro_giornale lg(da.year()); const TDate lp(lg.last_print()); if (da < lp) { from_d = lp.string(); const bool ok = yesno_box("Il libro giornale e stato stampato il %s:\n" "Si desidera modificare la data iniziale?", (const char*)from_d); if (!ok) continue; } } if (from_d.not_empty()) from.put(MOV_DATAREG, from_d); const TString& from_r = m.get(F_FROMREG); if (from_r.not_empty()) from.put(MOV_NUMREG, from_r); _from_caus = m.get(F_FROMCAUS); if (to_d.not_empty()) to.put(MOV_DATAREG, to_d); const TString& to_r = m.get(F_TOREG); if (to_r.not_empty()) to.put(MOV_NUMREG, to_r); _to_caus = m.get(F_TOCAUS); _provv = m.get(F_PROVV)[0]; cur.setregion(from, to); cur.set_filterfunction(filter); const TRecnotype total = cur.items(); TString action(key == K_ENTER ? "conferma" : "cancellazione"); action << " di "; add_plural(action, total, "movimento"); TString caption("E' stata richiesta la "); caption << action << '.'; if (total > 0) { caption << "\nSi desidera continuare?"; if (!yesno_box(caption)) continue; } else { warning_box(caption); continue; } action[0] = toupper(action[0]); TProgind pi(total, action, FALSE, TRUE, 24); cur.freeze(TRUE); if (key == K_ENTER) confirm_provv(cur, pi); else delete_provv(cur, pi); cur.freeze(FALSE); } return FALSE; } int cg2200(int argc, char** argv) { TProvvisori_app a; a.run(argc, argv, "Gestione provvisori"); return 0; }