// Programma di gestione autotrasportatori. #include #include #include #include #include #include #include #include #include #include "cg2101.h" #include "cg2103.h" #include "cg4a00a.h" #include "cglib01.h" static int __anno; bool cau_filter1 (const TRelation *r) { bool rt = FALSE; const TRectype& rec = r->curr(LF_CAUSALI); if (rec.get(CAU_TIPODOC) == "ST") // Solo i tipi documento STorno { TTable& reg = (TTable&) r->lfile("REG"); TString16 cod; cod << __anno; cod << rec.get(CAU_REG); reg.put("CODTAB", cod); if (reg.read() == NOERR ) { const int i9 = reg.get_int("I9"); const bool b1 = reg.get_bool("B1"); if (i9 == 1 || i9 == 0 && b1) // Il registro deve avere la X di sospensione NORMALE { TLocalisamfile & rcau = r->lfile(LF_RCAUSALI); // La riga 1 (gia' posizionata nella relazione) deve essere di tipo cliente if (rcau.get(RCA_TIPOCF) == "C") rt = TRUE; } } } return rt; } bool cau_filter2 (const TRelation *r) { bool rt = FALSE; const TRectype& rec = r->curr(LF_CAUSALI); const TString& tipo = rec.get(CAU_TIPODOC); if (tipo == "FV" || tipo == "NC") // Solo i tipi documento Fatture Vendita { TTable& reg = (TTable&) r->lfile("REG"); TString16 cod; cod << __anno; cod << rec.get(CAU_REG); reg.put("CODTAB", cod); if (reg.read() == NOERR) rt = !reg.get_bool("B1"); } return rt; } class TGestAutoTrasp_mask : public TAutomask { TAssoc_array _caudef; TCursor *_cur; TRelation *_rel; TTable *_reg; protected: void fill_sheet(const short id); const long get_last_nreg(); const long get_last_nprot(); void swap_sign(TMovimentoPN&); public: virtual bool on_key(KEY k); virtual bool on_field_event(TOperable_field& o, TField_event e, long jolly); void write_movs(); TGestAutoTrasp_mask(); virtual ~TGestAutoTrasp_mask(); }; TGestAutoTrasp_mask::TGestAutoTrasp_mask() : TAutomask("cg4a00a") { _rel = new TRelation(LF_MOV); _cur = NULL; _reg = new TTable("REG"); } TGestAutoTrasp_mask::~TGestAutoTrasp_mask() { if (_cur) delete _cur; delete _rel; delete _reg; } bool TGestAutoTrasp_mask::on_key(KEY k) { if (k == K_SHIFT + K_F12) { // Abilita la cella del numero prot. registro corrispondente alla riga // corrente dello spreadsheet if (focus_field().dlg() == F_SHEET_CAUSALI) { TSheet_field& sf = sfield(F_SHEET_CAUSALI); const int rs = sf.selected(); sf.enable_column(F_NUMPROT - F_CAUMOV); const int items = sf.items(); for (int i=0; icurr(); const TRecnotype items = _cur->items(); TProgind* pi = NULL; if (items > 10) pi = new TProgind(items, TR("Selezione movimenti..."), FALSE, TRUE); TLocalisamfile causali(LF_CAUSALI); // Azzera lo sheet TSheet_field& sf = sfield(F_SHEET_CAUSALI); TString_array& sa = sf.rows_array(); sa.destroy(); //azzera l'array _caudef.destroy(); for (*_cur = 0L; _cur->pos() < items; ++(*_cur)) { if (pi) pi->addstatus(1L); caus = rc.get(MOV_CODCAUS); if (!_caudef.is_key(caus)) // Se non è stata ancora aggiunta questa causale... { TToken_string* tt = new TToken_string; tt->add(caus, 0); _caudef.add(caus, new TString16); causali.put(CAU_CODCAUS, caus); const bool ok = causali.read() == NOERR; tt->add(ok ? causali.get(CAU_DESCR) : TR("** Non presente **"), 1); tt->add(ok ? causali.get(CAU_TIPODOC) : "**", 2); sa.add(tt); } } if (pi) delete pi; sf.force_update(); // Aggiorna lo sheet if (items == 0) { warning_box(TR("Non vi sono operazioni da effettuare nell'intervallo specificato.")); set_focus_field(id); } } } bool TGestAutoTrasp_mask::on_field_event(TOperable_field& o, TField_event e, long jolly) { switch (o.dlg()) { case F_DADATA: if (e == fe_modify || e == fe_init) { __anno = e == fe_modify ? atoi(o.get().right(4)) : 0; set(F_ANNO, __anno); TCursor* cur1 = efield(F_CAUS).browse()->cursor(); cur1->set_filterfunction(cau_filter1, TRUE); TCursor* cur2 = sfield(F_SHEET_CAUSALI).sheet_mask().efield(F_CAUDEF).browse()->cursor(); cur2->set_filterfunction(cau_filter2, TRUE); if (e == fe_modify) fill_sheet(o.dlg()); } break; case F_ADATA: case F_CODREG: if (e == fe_modify) fill_sheet(o.dlg()); break; case F_SHEET_CAUSALI: if (e == se_query_add) return FALSE; else if (e == fe_close) // Controllo sulla presenza dei codici causale nello spreadsheet { TSheet_field& sf = sfield(F_SHEET_CAUSALI); bool error = TRUE; for (int i=0; i < sf.items(); i++) { TToken_string& tt = sf.row(i); const TString16 c = tt.get(F_CAUDEF - F_CAUMOV); if (!c.blank()) { error = FALSE; break; } } if (error) { if (sf.items() == 0) error_box(TR("Non vi sono movimenti in sospensione da stornare nel periodo indicato.")); else error_box(TR("E' necessario indicare almeno una causale definitiva.")); } return !error; } break; case F_NUMPROT: case F_CAUDEF: if (e == fe_modify) { TString16 cod; cod << __anno; cod << o.mask().get(F_CAUDEFREG); _reg->put("CODTAB", cod); if (_reg->read() == NOERR) { if (o.dlg() == F_NUMPROT) { _reg->put("I5", o.mask().get_long(F_NUMPROT)); _reg->rewrite(); TSheet_field& sf = sfield(F_SHEET_CAUSALI); const int rs = sf.selected(); sf.enable_column(F_NUMPROT - F_CAUMOV, FALSE); sf.force_update(rs); } o.mask().set(F_NUMPROT, _reg->get_long("I5")); } } break; default: break; } return TRUE; } const long TGestAutoTrasp_mask::get_last_nreg() { TLocalisamfile& mov = _rel->lfile(); const int key = mov.getkey(); long nr = 1L; if (!mov.empty()) { mov.setkey(1); mov.last(); nr = mov.get_long(MOV_NUMREG) + 1L; mov.setkey(key); } return nr; } const long TGestAutoTrasp_mask::get_last_nprot() { long rt = 0l; TString16 cod; cod << __anno; cod << get(F_CODREG); _reg->put("CODTAB", cod); if (_reg->read() == NOERR) rt = _reg->get_long("I5"); return rt; } void TGestAutoTrasp_mask::swap_sign(TMovimentoPN& m) { // Scambia il segno sulla testata TRectype& h = m.curr(); real r; r = ZERO - h.get_real(MOV_TOTDOC); h.put(MOV_TOTDOC, r); r = ZERO - h.get_real(MOV_TOTDOCVAL); h.put(MOV_TOTDOCVAL, r); // e su tutte le righe iva const int items = m.iva_items(); for (int i=0; iitems(); TRectype& curr_rec = _cur->curr(); TMovimentoPN mpn_sosp; // Movimento di prima nota in sospensione TMovimentoPN mpn_storno; // Movimento di prima nota di storno sul reg. sospensione TMovimentoPN mpn_definitivo; // Movimento di prima nota solo IVA sul registro definitivo TRectype& mpn_sosp_rec = mpn_sosp.curr(); TRectype& mpn_storno_rec = mpn_storno.curr(); TRectype& mpn_definitivo_rec = mpn_definitivo.curr(); _cur->freeze(); TProgind pi(cur_items, TR("Creazione movimenti..."), FALSE, TRUE); int err = NOERR; int movs = 0; // Scorre i movimenti selezionati sul registro in sospensione for (*_cur = 0L; _cur->pos() < cur_items && err == NOERR; ++(*_cur)) { pi.addstatus(1); const TString16 cod_caus = curr_rec.get(MOV_CODCAUS); const TString16 cod_caus_def = (TString&)_caudef[cod_caus]; if (cod_caus_def.blank()) continue; mpn_sosp_rec = curr_rec; if (mpn_sosp.read(_isequal) == NOERR) { // Il prossimo numero di registrazione è... long nr = get_last_nreg(); long nsosp = mpn_sosp_rec.get_long(MOV_NUMREG); // Azzera le righe dei movimenti da scrivere mpn_storno.destroy_rows(nr); mpn_definitivo.destroy_rows(nr+1); // Sistema il movimento definitivo TCausale def_caus((TString&)_caudef[mpn_sosp_rec.get(MOV_CODCAUS)], __anno); mpn_definitivo_rec = mpn_sosp_rec; mpn_definitivo_rec.put(MOV_NUMREG, nr+1); mpn_definitivo_rec.put(MOV_PROTIVA, def_caus.reg().protocol()+1); mpn_definitivo_rec.put(MOV_DATAREG, dataop); mpn_definitivo_rec.put(MOV_DATACOMP, dataop); mpn_definitivo_rec.put(MOV_ANNOES, annoes); mpn_definitivo_rec.put(MOV_ANNOIVA, dataop.year()); mpn_definitivo_rec.put(MOV_CODCAUS, def_caus.codice()); mpn_definitivo_rec.put(MOV_REG, def_caus.reg().name()); mpn_definitivo_rec.put(MOV_TIPODOC, def_caus.tipo_doc()); // Flag operazione stampata in definitiva, solo per quelli in sospensione ed il movimento di storno, // il movimento definitivo non va flaggato. mpn_sosp_rec.put(MOV_STAMPATO, TRUE); mpn_sosp_rec.put(MOV_REGST, TRUE); // Sistema il movimento di storno a partire da quello in sospensione TCausale storno_caus(get(F_CAUS), __anno); // Forse è ridondante ma serve per tener aggiornato il nr. protocollo mpn_storno_rec = mpn_sosp_rec; mpn_storno_rec.put(MOV_NUMREG, nr); mpn_storno_rec.put(MOV_PROTIVA, storno_caus.reg().protocol()+1); mpn_storno_rec.put(MOV_DATAREG, dataop); mpn_storno_rec.put(MOV_DATACOMP, dataop); mpn_storno_rec.put(MOV_ANNOES, annoes); mpn_storno_rec.put(MOV_ANNOIVA, dataop.year()); mpn_storno_rec.put(MOV_CODCAUS, storno_caus.codice()); mpn_storno_rec.put(MOV_REG, storno_caus.reg().name()); mpn_storno_rec.put(MOV_TIPODOC, storno_caus.tipo_doc()); // Aggiunge le righe IVA const int iva_items = mpn_sosp.iva_items(); for (int j=0; jfreeze(FALSE); message_box(FR("Totale movimenti generati: %d"), movs); } class TGestAutoTrasp_app : public TSkeleton_application { TGestAutoTrasp_mask * _msk; protected: virtual bool create(); virtual bool destroy(); virtual void main_loop(); public: TGestAutoTrasp_app () {}; virtual ~TGestAutoTrasp_app () {}; }; bool TGestAutoTrasp_app::create() { _msk = new TGestAutoTrasp_mask(); open_files(LF_MOV, LF_ATTIV, 0); return TSkeleton_application::create(); } bool TGestAutoTrasp_app::destroy() { delete _msk; return TSkeleton_application::destroy(); } void TGestAutoTrasp_app::main_loop() { while (_msk->run() != K_QUIT) { if (yesno_box(TR("Procedo con la creazione dei movimenti?"))) { _msk->write_movs(); _msk->reset(); } } } int cg4a00(int argc, char* argv[]) { TGestAutoTrasp_app app; app.run(argc, argv, TR("Gestione Autotrasportatori")); return 0; }