#include #include #include #include #include #include #include #include "inlib01.h" #include "in0500a.h" #include "../cg/cgsaldac.h" #include #include #include #include TIntra_context::TIntra_context() { _tipo = 'C'; _freq = 'T'; _anno = 1999; _periodo = 1; _progr = 0L; // Intra 12/13 _tInvioIntra = _Intra12; _nb = _nc = 1; _righeintra = 0L; } /////////////////////////////////////////////////////////// // TIntra_frequency /////////////////////////////////////////////////////////// char TIntra_frequency::frequenza(int a, const char t) const { if (a <= 0) a = today.year(); if (a < today.year()) { TLocalisamfile riep(LF_RIEPRETT); riep.put("TIPO", t); riep.put("ANNO", a); if (riep.read(_isgteq) == NOERR) { if (riep.get(RIEPINTRA_TIPO) == t && riep.get_int(RIEPINTRA_ANNO) == a) { const char freq = riep.get_char(RIEPINTRA_FREQUENZA); if (freq > ' ') return freq; } } } return (t == 'A') ? _freq_acq : _freq_ces; } int TIntra_frequency::date2periodo(const TDate& d, char tipo) const { const char freq = frequenza(d.year(), tipo); if (freq == 'A') return 1; const int month = d.month(); if (freq == 'T') return (month / 3) + 1; return month; } int TIntra_frequency::compare_periodo(const TDate& dtcomp, const TDate& dtreg, char tipo) const { int cmp = dtcomp.year() - dtreg.year(); if (cmp == 0) { const int pc = date2periodo(dtcomp, tipo); const int pr = date2periodo(dtreg, tipo); cmp = pc - pr; } return cmp; } void TIntra_frequency::update() { const long firm = prefix().get_codditta(); const TRectype& ditta = cache().get(LF_NDITTE, firm); _freq_ces = ditta.get_char("FREQCES"); _freq_acq = ditta.get_char("FREQACQ"); if (_freq_ces <= ' ') _freq_ces = 'T'; if (_freq_acq <= ' ') _freq_acq = 'T'; } TIntra_frequency::TIntra_frequency() { update(); } /////////////////////////////////////////////////////////// // TIntra_mask // Maschera generica con dati utili a tutte quelle intra /////////////////////////////////////////////////////////// void TIntra_mask::on_firm_change() { if (is_running()) TAutomask::on_firm_change(); _freq.update(); } char TIntra_mask::frequenza(int a, char t) const { if (a <= 0) a = anno(); if (t < 'A') t = tipo(); return _freq.frequenza(a, t); } int TIntra_mask::date2periodo(const TDate& d) const { return _freq.date2periodo(d, tipo()); } const char* TIntra_mask::periodo_str() const { const short id = period_field(); const char* pe = "01"; if (id != DLG_NULL) { switch(frequenza(anno())) { case 'M': pe = get(id); break; case 'T': pe = get(id+1); break; default : break; } } else NFCHECK("Non e' stato specificato il campo del periodo"); return pe; } int TIntra_mask::periodo() const { return atoi(periodo_str()); } bool TIntra_mask::on_field_event(TOperable_field& o, TField_event e, long jolly) { if (jolly == 0 && o.dlg() == type_field()) { if (e == fe_modify || e == fe_init) { const short id = period_field(); if (id != DLG_NULL) { const char freq = frequenza(anno()); show(id+0, freq == 'M'); show(id+1, freq == 'T'); show(id+2, freq == 'A'); } } } return true; } TIntra_mask::TIntra_mask(const char* name) : TAutomask(name) { on_firm_change(); } /////////////////////////////////////////////////////////// // TRiepiloghi_Intra /////////////////////////////////////////////////////////// class TRiepiloghi_Intra : public TObject { TAssoc_array _ass; public: void destroy() { _ass.destroy(); } void add(const TRectype& row, const TRectype& head, int peri, char freq); int items() const { return _ass.items(); } int write(int from = 1); }; int TRiepiloghi_Intra::write(int from) { TString_array keys; TLocalisamfile riep(LF_RIEPRETT); TProgress_monitor pi(items(), TR("Scrittura riepiloghi intra..."), false); _ass.get_keys(keys); keys.sort(); FOR_EACH_ARRAY_ITEM(keys, r, k) { TString * key = (TString *) k; TRectype * rec = (TRectype *) _ass.objptr(*key); pi.addstatus(1L); rec->put(RIEPINTRA_NUMRIG, r + from); const int err = rec->write_rewrite(riep); if (err != NOERR) error_box(FR("Errore %d durante la scrittura dei riepiloghi riga %d"), err, r + from); } return from + items(); } void TRiepiloghi_Intra::add(const TRectype& row, const TRectype& head, int peri, char freq) { TString8 cod; cod << head.get_char(INTRA_TIPOCF) << '|' << head.get(INTRA_CODCF); const TRectype& clifo = cache().get(LF_CLIFO, cod); TString4 codval = head.get(INTRA_CODVAL); if (::is_euro_value(codval)) codval.cut(0); TRectype rec(LF_RIEPRETT); const TString4 tipointra = row.get(RINTRA_TIPOINTRA); const TString4 tipo = head.get(INTRA_TIPOMOV); TToken_string key; key.add(head.get(INTRA_TIPOMOV)); key.add(tipointra); key.add(clifo.get(CLI_STATOPAIV)); key.add(clifo.get(CLI_PAIV)); key.add(codval); // Non e' chiaro se raggruppare per valuta! key.add(row.get(RINTRA_NATURA)); if (tipointra == "B") { key.add(row.get(RINTRA_NOMENCL)); key.add(row.get(RINTRA_CONSEGNA)); key.add(row.get(RINTRA_TRASPORTO)); key.add(row.get(RINTRA_PAESE)); key.add(row.get(RINTRA_PAESEORIG)); // Campo solo per Acquisti key.add(row.get(RINTRA_PROV)); } else { key.add(row.get(RINTRA_CODSERV)); key.add(row.get(RINTRA_MODEROG)); key.add(row.get(RINTRA_MODINCPAG)); key.add(row.get(RINTRA_ISOINCPAG)); } rec.put(RIEPINTRA_SEZIONE, tipointra == "B" ? 1 : 3); rec.put(RIEPINTRA_TIPO, tipo); rec.put(RIEPINTRA_ANNO, head.get_date(INTRA_DATAREG).year()); rec.put(RIEPINTRA_PERIODO, peri); rec.zero(RIEPINTRA_NUMRIG); rec.put(RIEPINTRA_TIPOCF, head.get(INTRA_TIPOCF)); rec.put(RIEPINTRA_STATO, clifo.get(CLI_STATOPAIV)); rec.put(RIEPINTRA_PIVA, clifo.get(CLI_PAIV)); rec.put(RIEPINTRA_NATURA, row.get(RINTRA_NATURA)); rec.put(RIEPINTRA_NOMENCL, row.get(RINTRA_NOMENCL)); rec.put(RIEPINTRA_CONSEGNA, row.get(RINTRA_CONSEGNA)); rec.put(RIEPINTRA_TRASPORTO, row.get(RINTRA_TRASPORTO)); rec.put(RIEPINTRA_PAESE, row.get(RINTRA_PAESE)); rec.put(RIEPINTRA_PAESEORIG, row.get(RINTRA_PAESEORIG)); rec.put(RIEPINTRA_PROV, row.get(RINTRA_PROV)); rec.put(RIEPINTRA_AMMLIRE, row.get(RINTRA_AMMLIRE)); rec.put(RIEPINTRA_AMMVALUTA, row.get(RINTRA_AMMVALUTA)); rec.put(RIEPINTRA_CODVAL, codval); rec.put(RIEPINTRA_VALSTAT, row.get(RINTRA_VALSTAT)); rec.put(RIEPINTRA_MASSAKG, row.get(RINTRA_MASSAKG)); rec.put(RIEPINTRA_MASSAUMS, row.get(RINTRA_MASSAUMS)); rec.put(RIEPINTRA_FREQUENZA, freq); rec.put(RIEPINTRA_CODSERV, row.get(RINTRA_CODSERV)); rec.put(RIEPINTRA_MODEROG, row.get(RINTRA_MODEROG)); rec.put(RIEPINTRA_MODINCPAG, row.get(RINTRA_MODINCPAG)); rec.put(RIEPINTRA_ISOINCPAG, row.get(RINTRA_ISOINCPAG)); TRectype * data = (TRectype *)_ass.objptr(key); if (data == nullptr) _ass.add(key, rec); else { data->add(RIEPINTRA_AMMLIRE, row.get_real(RINTRA_AMMLIRE)); data->add(RIEPINTRA_AMMVALUTA, row.get_real(RINTRA_AMMVALUTA)); data->add(RIEPINTRA_VALSTAT, row.get_real(RINTRA_VALSTAT)); data->add(RIEPINTRA_MASSAKG, row.get_real(RINTRA_MASSAKG)); data->add(RIEPINTRA_MASSAUMS, row.get_real(RINTRA_MASSAUMS)); } } class TRettifiche_Intra : public TObject { TArray _rett; TIntra_frequency _freq; protected: long rett2riep(const TRectype& rett) const; public: int items() const { return _rett.items(); } long nc2ft(long numreg_nc) const; int add(const TRectype& rintra, const TRectype& mov, long nr_fattura); int load_manual_rett(char tipo, int anno, int periodo); int write(int from = 1); }; long TRettifiche_Intra::nc2ft(long numreg_nc) const { long numreg_ft = 0L; TPartite_array games; games.add_numreg(numreg_nc); // Carica le partite in cui è coinvolta questa nota di credito (sempre e solo una!) for (TPartita* p = games.first(); p != nullptr && numreg_ft<=0; p = games.next()) { for (int r = p->prima_fattura(); r >= 0 && r <= p->last(); r = p->succ(r)) { const TRiga_partite& partita = p->riga(r); const tipo_movimento tm = partita.tipo(); if (tm == tm_fattura) { const long n = partita.get_long(PART_NREG); if (n > 0 && n != numreg_nc) // Puo' succedere che n==numreg_nc con le fatture negative! { numreg_ft = n; break; } } } } return numreg_ft; } int TRettifiche_Intra::load_manual_rett(char tipo, int anno, int periodo) { _rett.destroy(); tipo = tipo < 'C' ? 'B' : 'D'; // forzatura tipo = B o D TString query, filtro; filtro << "TIPO=" << tipo << " ANNO=" << anno << " PERIODO=" << periodo; query << "USE " << LF_RIEPRETT << " SELECT NUMREG=\"\""; query << "\nFROM " << filtro; query << "\nTO " << filtro; TISAM_recordset rett(query); for (bool good = rett.move_first(); good; good = rett.move_next()) _rett.add(rett.cursor()->curr()); return _rett.items(); } long TRettifiche_Intra::rett2riep(const TRectype& rett) const { TString query, filter; filter << " TIPO=" << (rett.get_char(RIEPINTRA_TIPO) == 'B' ? 'A' : 'C') << " ANNO=" << rett.get(RIEPINTRA_ANNORETT) << " PERIODO=" << rett.get(RIEPINTRA_PERETT); query << "USE " << LF_RIEPRETT << "\nSELECT ((NOMENCL='" << rett.get(RIEPINTRA_NOMENCL) << "')||(CODSERV=='" << rett.get(RIEPINTRA_CODSERV) << "'))&&(PIVA='" << rett.get(RIEPINTRA_PIVA) << "')" << "\nFROM " << filter << "\nTO " << filter; long nriga = 1; TISAM_recordset rr(query); if (rr.move_first()) nriga = rr.get(RINTRA_NUMRIG).as_int(); return nriga; } int TRettifiche_Intra::add(const TRectype& rintra, const TRectype& mov, long nr_fattura) { CHECKD(rintra.num() == LF_RINTRA, "Record non INTRA ", rintra.num()); const TDate datareg = mov.get(MOV_DATAREG); TRectype rett(LF_RIEPRETT); const char tipo = mov.get_char(INTRA_TIPOMOV); const TString4 tipointra = rintra.get(RINTRA_TIPOINTRA); rett.put(RIEPINTRA_ANNO, datareg.year()); rett.put(RIEPINTRA_PERIODO, _freq.date2periodo(datareg, tipo)); rett.zero(RIEPINTRA_NUMRIG); // Auto rett.put(RIEPINTRA_SEZIONE, tipointra ? 2 : 4); rett.put(RIEPINTRA_TIPO, tipo); TString8 cod; cod << mov.get_char(INTRA_TIPOCF) << '|' << mov.get(INTRA_CODCF); const TRectype& clifo = cache().get(LF_CLIFO, cod); TString4 codval = mov.get(MOV_CODVALI); if (::is_euro_value(codval)) codval.cut(0); rett.put(RIEPINTRA_TIPOCF, mov.get(INTRA_TIPOCF)); rett.put(RIEPINTRA_STATO, clifo.get(CLI_STATOPAIV)); rett.put(RIEPINTRA_PIVA, clifo.get(CLI_PAIV)); rett.put(RIEPINTRA_NATURA, rintra.get(RINTRA_NATURA)); rett.put(RIEPINTRA_NOMENCL, rintra.get(RINTRA_NOMENCL)); rett.put(RIEPINTRA_CONSEGNA, rintra.get(RINTRA_CONSEGNA)); rett.put(RIEPINTRA_TRASPORTO, rintra.get(RINTRA_TRASPORTO)); rett.put(RIEPINTRA_PAESE, rintra.get(RINTRA_PAESE)); if (tipo == 'B') // Campi solo per Acquisti { rett.put(RIEPINTRA_PAESEORIG, rintra.get(RINTRA_PAESEORIG)); rett.put(RIEPINTRA_PROV, rintra.get(RINTRA_PROV)); } const real euri = rintra.get_real(RINTRA_AMMLIRE); rett.put(RIEPINTRA_SEGNORETT, euri > ZERO ? '+' : '-'); rett.put(RIEPINTRA_AMMLIRE, abs(euri)); if (codval.full()) { rett.put(RIEPINTRA_CODVAL, codval); const real impval = rintra.get_real(RINTRA_AMMVALUTA); rett.put(RIEPINTRA_AMMVALUTA, abs(impval)); } rett.put(RIEPINTRA_VALSTAT, abs(rintra.get_real(RINTRA_VALSTAT))); rett.put(RIEPINTRA_MASSAKG, rintra.get(RINTRA_MASSAKG)); rett.put(RIEPINTRA_MASSAUMS, rintra.get(RINTRA_MASSAUMS)); rett.put(RIEPINTRA_NUMREG, mov.get(MOV_NUMREG)); rett.put(RIEPINTRA_CODSERV, rintra.get(RINTRA_CODSERV)); rett.put(RIEPINTRA_MODEROG, rintra.get(RINTRA_MODEROG)); rett.put(RIEPINTRA_MODINCPAG, rintra.get(RINTRA_MODINCPAG)); rett.put(RIEPINTRA_MODEROG, rintra.get(RINTRA_MODEROG)); const TDate dt_fatt = cache().get(LF_MOV, nr_fattura, MOV_DATAREG); rett.put(RIEPINTRA_ANNORETT, dt_fatt.year()); rett.put(RIEPINTRA_PERETT, _freq.date2periodo(dt_fatt, tipo)); rett.put(RIEPINTRA_NUMRETT, rett2riep(rett)); return _rett.add(rett); } int TRettifiche_Intra::write(int from) { _rett.pack(); const int items = _rett.items(); TLocalisamfile riep(LF_RIEPRETT); FOR_EACH_ARRAY_ITEM(_rett, r, data) { TRectype* rec = (TRectype*) data; rec->put(RIEPINTRA_NUMRIG, r + from); const int err = rec->write_rewrite(riep); if (err != NOERR) error_box(FR("Errore %d durante la scrittura dei riepiloghi riga %d"), err, r + from); } return from + items; } /////////////////////////////////////////////////////////// // TGenerazione_mask /////////////////////////////////////////////////////////// class TGenerazione_mask : public TIntra_mask { TRiepiloghi_Intra _riep; TRettifiche_Intra _rett; protected: virtual short type_field() const { return R_TIPO; } virtual short period_field() const { return R_PERIODO_M; } virtual int anno() const { return get_int(R_ANNO); } public: bool genera_riepiloghi(); TGenerazione_mask(); virtual ~TGenerazione_mask() { } }; bool TGenerazione_mask::genera_riepiloghi() { const char tipo = get(R_TIPO)[0]; const int anno_r = anno(); const int peri = periodo(); const char freq = frequenza(anno_r, tipo); TString msg; msg.format(FR("Si sta per generare il riepilogo %s del periodo %d dell'anno %d."), tipo == 'A' ? TR("acquisti") : TR("cessioni"), peri, anno_r); if (is_riepilogo(tipo, anno_r, peri)) msg << TR("\nAttenzione questo riepilogo è già stato generato.\nSi desidera continuare ugualmente?"); else msg << TR("\nSi desidera procedere?"); if (!yesno_box(msg)) return false; _riep.destroy(); _rett.load_manual_rett(tipo+1, anno_r, peri); int da_mese = peri, a_mese = peri; switch (freq) { case 'T': da_mese = (peri-1) * 3 + 1; a_mese = da_mese+2; break; case 'A': da_mese = 1; a_mese = 12; break; default: da_mese = a_mese = peri; break; } // Range delle date di competenza (o registrazione) intra const TDate da_data(1, da_mese, anno_r); const TDate a_data(TDate::last_day(a_mese, anno_r), a_mese, anno_r); // Range delle date di registrazione intra const TDate filtro_da_data(1, 1, anno_r-1); const TDate filtro_a_data(31,12, anno_r+1); TRectype filter_da(LF_INTRA), filter_a(LF_INTRA); filter_da.put(INTRA_DATAREG, filtro_da_data); filter_a.put(INTRA_DATAREG, filtro_a_data); TRelation rel(LF_INTRA); rel.add(LF_RINTRA, "NUMREG==NUMREG"); rel.add(LF_MOV, "NUMREG==NUMREG"); const TRectype& head = rel.curr(LF_INTRA); const TRectype& row = rel.curr(LF_RINTRA); const TRectype& mov = rel.curr(LF_MOV); TString filter; filter << "TIPOMOV==\"" << tipo << '"'; TCursor cur(&rel, filter, 2, &filter_da, &filter_a); // Cursore ordinato per data const long items = cur.items(); if (items > 0) { TProgress_monitor pi(items, TR("Lettura movimenti intra...")); cur.freeze(); for (cur = 0; cur.pos() < items; ++cur) { if (!pi.add_status()) return warning_box(TR("Operazione annullata")); const TDate datacomp = head.get_date(MOV_DATAREG); if (datacomp >= da_data && datacomp <= a_data) { bool rowok = rel.is_first_match(LF_RINTRA); while (rowok) { bool is_rettifica = false; const tipo_movimento tm = (tipo_movimento)mov.get_int(MOV_TIPOMOV); long numreg_ft = 0; if (tm_nota_credito || (tm==tm_fattura && mov.get_real(MOV_TOTDOC) < ZERO)) { const long numreg_nc = mov.get_long(MOV_NUMREG); numreg_ft = _rett.nc2ft(numreg_nc); if (numreg_ft > 0) { const TRectype& head_ft = cache().get(LF_MOV, numreg_ft); const TDate data_ft = head_ft.get_date(MOV_DATAREG); const int anno_ft = data_ft.year(); const int peri_ft = _freq.date2periodo(data_ft, tipo); is_rettifica = anno_ft != anno_r || peri_ft != peri; // Rettifica solo se periodo diverso dalla fattura } } if (is_rettifica) _rett.add(row, mov, numreg_ft); else _riep.add(row, head, peri, freq); rowok = rel.next_match(LF_RINTRA); } } } } else return warning_box(TR("Non ci sono movimenti nel periodo specificato")); TLocalisamfile riep(LF_RIEPRETT); const int riepiloghi = _riep.items(); int last_row = 0; if (riepiloghi > 0) last_row = _riep.write(); const int rettifiche = _rett.items(); if (rettifiche > 0) last_row = _rett.write(last_row); // cancella gli altri event TString query; query << "USE " << LF_RIEPRETT << "\nFROM TIPO=" << tipo << " ANNO=" << anno_r << " PERIODO=" << peri << " NUMRIG=" << long(last_row + 1) << "\nTO TIPO=" << tipo << " ANNO=" << anno_r << " PERIODO=" << peri; TISAM_recordset riepset(query); for (bool ok = riepset.move_first(); ok; ok = riepset.move_next()) riepset.cursor()->file().remove(); return true; } TGenerazione_mask::TGenerazione_mask() : TIntra_mask("in0500b") { } /////////////////////////////////////////////////////////// // Generazione riepiloghi /////////////////////////////////////////////////////////// void genera_riepiloghi(char tipo, int anno, int periodo) { TGenerazione_mask m; int num_fields = 0; if (tipo > ' ' ) { TString16 t; t << tipo; m.set(R_TIPO, t); num_fields++; } if (anno > 0) { m.set(R_ANNO, anno); num_fields++; } if (periodo > 0) { m.set(R_PERIODO_M, periodo); m.set(R_PERIODO_T, periodo); num_fields++; } if (num_fields == 3 || m.run() == K_ENTER) m.genera_riepiloghi(); } bool is_riepilogo(char tipo, int anno, int periodo) { TLocalisamfile riep(LF_RIEPRETT); riep.put("TIPO", tipo); riep.put("ANNO", anno); riep.put("PERIODO", periodo); riep.put("NUMRIG", 1); int err = riep.read(); return err == NOERR; }