#include #include #include #include #include #include #include "in0.h" #include "in0200a.h" #include "inlib01.h" #include #include /////////////////////////////////////////////////////////// // TRecord_intra /////////////////////////////////////////////////////////// struct TIntra_context { char _tipo; long _progr; char _freq; int _anno; int _periodo; long _righe_riep; real _totale_riep; long _righe_rett; real _totale_rett; unsigned long _written; unsigned long _disksize; TIntra_context(); }; TIntra_context::TIntra_context() { _tipo = 'C'; _freq = 'T'; _anno = 1999; _periodo = 1; _progr = _righe_riep = _righe_rett = 0L; _written = _disksize = 0L; } class TRecord_intra : public TString { int _ndec; protected: virtual void print_on(ostream& o) const; public: void reset(const TIntra_context& ic); void reset_data(); void put(const char* str, int pos, int dim, const char* flags = ""); void put(real num, int pos, int dim, int dec = 0); void put(long num, int pos, int dim); void put(char chr, int pos); void genera_testata(const TIntra_context& ic); void put(const TRectype& rec, TIntra_context& ic); TRecord_intra(); virtual ~TRecord_intra() { } }; // Scrive un campo generico sul record di invio void TRecord_intra::put(const char* str, int pos, int dim, const char* flags) { CHECKD(pos > 0 && pos < size(), "Invalid field position:", pos); CHECKD(dim > 0 && dim <= 50, "Invalid field dimension:", dim); TString256 val(str); if (val.len() < dim) { const bool rj = strchr(flags, 'R') != NULL; const bool zf = strchr(flags, 'Z') != NULL; if (rj) val.right_just(dim, zf ? '0' : ' '); else val.left_just(dim, zf ? '0' : ' '); } else val.cut(dim); overwrite(val, pos-1); } // Scrive un campo numerico sul record di invio void TRecord_intra::put(real num, int pos, int dim, int dec) { TString80 str; if (!num.is_zero()) { num.round(dec); const bool negativo = num < ZERO; if (negativo) num *= -1.0; if (dec < 0) { str = num.string(dim-dec, 0, '0'); str.rtrim(-dec); } else { str = num.string(dim, dec, '0'); } if (negativo) str[dim-1] += 64; } put(str, pos, dim, "RZ"); } // Scrive un campo intero sul record di invio void TRecord_intra::put(long num, int pos, int dim) { TString16 str; str.format("%0*ld", dim, num); put(str, pos, dim, "RZ"); } // Scrive un campo carattere sul record di invio void TRecord_intra::put(char chr, int pos) { const char str[2] = { chr, '\0' }; put(str, pos, 1); } // Azzera il record void TRecord_intra::reset(const TIntra_context& ic) { spaces(); put("EUROA", 1, 5); const TRectype& ditta = cache().get(LF_NDITTE, main_app().get_firm()); TString16 cod; cod.format("%c|%ld", ditta.get_char(NDT_TIPOA), ditta.get_long(NDT_CODANAGR)); const TRectype& anagr = cache().get(LF_ANAG, cod); put(anagr.get(ANA_PAIV), 6, 11); put(ic._progr, 17, 6); } void TRecord_intra::reset_data() { const TString80 key = left(22); spaces(); overwrite(key, 0); } // Scrive la testata con le informazioni della ditta void TRecord_intra::genera_testata(const TIntra_context& ic) { reset(ic); put('0', 23); // Tipo record frontespizio put("", 24, 5, "RZ"); // Numero riga (0 per frontespizio) put(ic._tipo, 29); // Tipo riepilogo put(ic._anno % 100, 30, 2); put(ic._freq, 32); put(ic._periodo, 33, 2); TString16 cod = mid(5, 11); // Ricopia la parita iva della ditta put(cod, 35, 11); const TRectype& ditta = cache().get(LF_NDITTE, main_app().get_firm()); put(ditta.get_bool("PRESELEN") ? '1' : '0', 46); put(ditta.get_bool("CESSIVA") ? '1' : '0', 47); cod.cut(0); cod << ditta.get_char("TIPOSOGDEL") << '|'; cod << ditta.get("CODSOGDEL"); if (cod.len() >= 3) { const TRectype& sogdel = cache().get(LF_ANAG, cod); put(sogdel.get(ANA_PAIV), 48, 11); } else put("", 48, 11, "Z"); put(ic._righe_riep, 59, 5); put(ic._totale_riep, 64, 13, _ndec); put(ic._righe_rett, 77, 5); put(ic._totale_rett, 82, 13, _ndec); } // Scrive un intero record del file riepiloghi/rettifiche void TRecord_intra::put(const TRectype& rec, TIntra_context& ic) { reset_data(); put(rec.get_long("NUMRIG"), 24, 5); const char tipo = rec.get_char("TIPO"); switch (tipo) { case 'A': put('1', 23); put(rec.get("STATO"), 29, 2); put(rec.get("PIVA"), 31, 12); put(rec.get_real("AMMLIRE"), 43, 13, _ndec); put(rec.get_real("AMMVALUTA"), 56, 13); put(rec.get_char("NATURA"), 69); put(rec.get("NOMENCL"), 70, 8, "Z"); if (ic._freq == 'M') { put(rec.get_real("MASSAKG"), 78, 10, 0); put(rec.get_real("MASSAUMS"), 88, 10, 0); put(rec.get_real("VALSTAT"), 98, 13, _ndec); put(rec.get_char("CONSEGNA"), 111); put(rec.get_char("TRASPORTO"), 112); put(rec.get("PAESE"), 113, 2); put(rec.get("PAESEORIG"), 115, 2); put(rec.get("PROV"), 117, 2); } else put("", 78, 100); break; case 'B': { put('2', 23); if (ic._freq == 'M') put(rec.get("PERETT"), 29, 2, "RZ"); else put("", 29, 2, "RZ"); if (ic._freq == 'T') put(rec.get("PERETT")[1], 31); else put('0', 31); put(rec.get("ANNORETT").right(2), 32, 2, "RZ"); put(rec.get("STATO"), 34, 2); put(rec.get("PIVA"), 36, 12); put(rec.get("SEGNORETT"), 48, 1); put(rec.get_real("AMMLIRE"), 49, 13, _ndec); put(rec.get_real("AMMVALUTA"), 62, 13); put(rec.get_char("NATURA"), 75); put(rec.get("NOMENCL"), 76, 8, "Z"); if (ic._freq == 'M') put(rec.get_real("VALSTAT"), 84, 13, _ndec); else put("", 84, 13); } break; case 'C': put('1', 23); put(rec.get("STATO"), 29, 2); put(rec.get("PIVA"), 31, 12); put(rec.get_real("AMMLIRE"), 43, 13, _ndec); put(rec.get_char("NATURA"), 56); put(rec.get("NOMENCL"), 57, 8, "Z"); if (ic._freq == 'M') { put(rec.get_real("MASSAKG"), 65, 10); put(rec.get_real("MASSAUMS"), 75, 10); put(rec.get_real("VALSTAT"), 85, 13, _ndec); put(rec.get_char("CONSEGNA"), 98); put(rec.get_char("TRASPORTO"), 99); put(rec.get("PAESE"), 100, 2); put(rec.get("PROV"), 102, 2); } else put("", 65, 100); break; case 'D': { put('2', 23); if (ic._freq == 'M') put(rec.get("PERETT"), 29, 2, "RZ"); else put("", 29, 2, "RZ"); if (ic._freq == 'T') put(rec.get("PERETT")[1], 31); else put('0', 31); put(rec.get("ANNORETT").right(2), 32, 2, "RZ"); put(rec.get("STATO"), 34, 2); put(rec.get("PIVA"), 36, 12); put(rec.get("SEGNORETT"), 48, 1); put(rec.get_real("AMMLIRE"), 49, 13, _ndec); put(rec.get("NATURA"), 62, 1); put(rec.get("NOMENCL"), 63, 8, "Z"); if (ic._freq == 'M') put(rec.get_real("VALSTAT"), 71, 13, _ndec); else put("", 71, 13); } break; default: NFCHECK("Record di tipo sconosciuto: %c", tipo); break; } } // Scrive su file il record void TRecord_intra::print_on(ostream& o) const { ((TRecord_intra*)this)->rtrim(); TString::print_on(o); o << endl; } TRecord_intra::TRecord_intra() : TString(132) { _ndec = TCurrency::get_firm_dec() > 0 ? 0 : -3; } /////////////////////////////////////////////////////////// // TDischetto_mask /////////////////////////////////////////////////////////// class TDischetto_mask : public TIntra_mask { protected: virtual bool on_field_event(TOperable_field& o, TField_event e, long jolly); virtual short type_field() const { return F_TIPO; } virtual short period_field() const { return F_PERIODO_M; } virtual int anno() const { return get_int(F_ANNO); } long calcola_totale(TCursor& cur, real& tot) const; bool write_record(ofstream& out, const TRecord_intra& rec, TIntra_context& ic); void proponi_numero(); public: void genera_dischetto(char tip, int mode = 0); TDischetto_mask(); }; void TDischetto_mask::proponi_numero() { const char tip = tipo(); int a = anno(), p = periodo(); long d = 0; TTable ird("IRD"); int err = ird.last(); while (err == NOERR) { const TString16 str = ird.get("CODTAB"); a = atoi(str.mid(1,4)); p = atoi(str.mid(5,2)); d = ird.get_long("I0"); if (tip == 'T' || tip == str[0]) break; err = ird.prev(); } if (anno() > a || periodo() > p) set(F_NUMERO, d+1); else set(F_NUMERO, d == 0 ? 1L : d); set(F_LAST, d); } bool TDischetto_mask::on_field_event(TOperable_field& o, TField_event e, long jolly) { switch (o.dlg()) { case F_ANNO: if (e == fe_init || e == fe_modify) { const int anno = atoi(o.get()); const char fa = frequenza(anno, 'A'); const char fc = frequenza(anno, 'C'); TList_field& list = (TList_field&)field(type_field()); TToken_string codes = "A|C"; TToken_string descr = "Acquisti|Cessioni"; if (fa == fc) { codes.add("T"); descr.add("Tutti"); } list.replace_items(codes, descr); proponi_numero(); } break; case F_TIPO: case F_PERIODO_M: case F_PERIODO_T: case F_PERIODO_A: if (e == fe_modify) proponi_numero(); break; case F_RIEPILOGHI: if (e == fe_button) { const char tip = tipo(); if (tip == 'T') { ::genera_riepiloghi('A', anno(), periodo()); ::genera_riepiloghi('C', anno(), periodo()); } else ::genera_riepiloghi(tip, anno(), periodo()); } break; default:break; } return TIntra_mask::on_field_event(o, e, jolly); } long TDischetto_mask::calcola_totale(TCursor& cur, real& tot) const { TWait_cursor arrow; const long items = cur.items(); cur.freeze(); tot = ZERO; const TRectype& rec = cur.curr(); for (cur = 0L; cur.pos() < items; ++cur) { const char tipo = rec.get_char("TIPO"); const real val = rec.get_real("AMMLIRE"); // Da chiarire: come sommare le rettifiche negative! if ((tipo == 'B' || tipo == 'D') && rec.get_char("SEGNORETT") == '-') tot -= val; // Rettifiche negative else tot += val; } return items; } bool TDischetto_mask::write_record(ofstream& out, const TRecord_intra& rec, TIntra_context& ic) { out << rec; bool good = out.good() != 0; if (good) ic._written += rec.len()+2; if (ic._written >= ic._disksize) { out.close(); TFilename name; name = get(F_DISCO); name.add(get(F_PATH)); name.add("scambi.cee"); message_box("Inserire un nuovo dischetto prima di continuare."); out.open(name); if (out) { ic._written = 0; good = TRUE; } } if (!good) error_box("Errore di scrittura su disco: ripetere l'operazione."); return good; } // mode 0 = ask; 1 = append; 2 = remove void TDischetto_mask::genera_dischetto(char tip, int mode) { TIntra_context ic; ic._tipo = tip; ic._anno = anno(); ic._freq = frequenza(ic._anno); ic._periodo = periodo(); ic._progr = get_long(F_NUMERO); TString16 codtab; codtab.format("%c%04d%02d", ic._tipo, ic._anno, ic._periodo); TTable ird("IRD"); ird.put("CODTAB", codtab); const bool exist = ird.read() == NOERR; if (exist) { const char* ac = tip == 'A' ? "agli acquisti" : "alle cessioni"; if (!yesno_box("Il dischetto relativo %s del periodo indicato è già stato generato:\n" "Si desidera proseguire ugualmente?", ac)) return; } TRelation rel(LF_RIEPRETT); TRectype filter(LF_RIEPRETT); filter.put("TIPO", ic._tipo); filter.put("ANNO", ic._anno); filter.put("PERIODO", periodo_str()); TCursor riep(&rel, "", 1, &filter, &filter); ic._righe_riep = calcola_totale(riep, ic._totale_riep); filter.put("TIPO", char(ic._tipo+1)); TCursor rett(&rel, "", 1, &filter, &filter); ic._righe_rett = calcola_totale(rett, ic._totale_rett); TFilename name; name = get(F_DISCO); name.add(get(F_PATH)); name.add("scambi.cee"); if (name.exist()) { bool do_remove = (mode == 2); if (mode == 0) { do_remove = yesno_box("Il file %s, esiste gia': si desiderla eliminarlo?\n" "Rispondendo SI i dati sul dischetto verranno azzerati.\n" "Rispondendo NO i dati verranno accodati a quelli già presenti", (const char*)name); } if (do_remove) ::remove(name); } ofstream out(name, ios::out | ios::app); if (!out) { error_box("Impossibile creare il file %s\n" "Assicurarsi di avere inserito un dischetto\n" "formattato e ripetere nuovamente l'operazione.", (const char*)name); return; } ic._disksize = os_get_disk_size(name) - (64L*1024L); ic._written = 0; const long total = ic._righe_riep + ic._righe_rett; TProgind pi(total, "Generazione scambi.cee", FALSE, TRUE); TRecord_intra rec; rec.genera_testata(ic); out << rec; rec.reset_data(); for (riep = 0L; riep.pos() < ic._righe_riep; ++riep) { pi.addstatus(1); rec.put(riep.curr(), ic); if (!write_record(out, rec, ic)) return; } rec.reset_data(); for (rett = 0L; rett.pos() < ic._righe_rett; ++rett) { pi.addstatus(1); rec.put(riep.curr(), ic); if (!write_record(out, rec, ic)) return; } codtab.format("%c%04d%02d", ic._tipo, ic._anno, ic._periodo); ird.put("CODTAB", codtab); ird.put("I0", ic._progr); // Numero progressivo dischetto // ird.put("I1", ??? ); ird.put("I2", ic._righe_riep); ird.put("I3", ic._righe_rett); ird.put("R0", ic._totale_riep); ird.put("R1", ic._totale_rett); if (exist) ird.rewrite(); else ird.write(); } TDischetto_mask::TDischetto_mask() : TIntra_mask("in0200a") { } /////////////////////////////////////////////////////////// // TDischetto_app /////////////////////////////////////////////////////////// class TDischetto_app : public TSkeleton_application { protected: virtual void main_loop(); }; void TDischetto_app::main_loop() { open_files(LF_TABCOM, LF_TAB, LF_CLIFO, LF_INTRA, LF_RINTRA, LF_RIEPRETT, 0); TDischetto_mask m; while (m.run() == K_ENTER) { const char tip = m.tipo(); if (tip == 'T') { m.genera_dischetto('A', 2); m.genera_dischetto('C', 1); } else m.genera_dischetto(tip); } } int in0200(int argc, char* argv[]) { TDischetto_app a; a.run(argc, argv, "Generazione dischetti INTRA"); return 0; }