#include #include #include #include #include #include #include #include "mglib.h" #include "mg1300a.h" #include "../cg/cglib01.h" #include "../mg/mag.h" #include "../mg/movmag.h" #include "../mg/rmovmag.h" #include "rdoc.h" /////////////////////////////////////////////////////////// // TSaldodata_mask /////////////////////////////////////////////////////////// class TSaldodata_mask : public TAutomask { protected: void preview(bool zero_giac); void load_physical(); void save_movmag(); virtual bool on_field_event(TOperable_field& o, TField_event e, long jolly); public: TSaldodata_mask(); }; static bool reset_cb(const TRelation& rel, void* pJolly) { return rel.file().remove() == NOERR; } void TSaldodata_mask::preview(bool zero_giac) { TString query; query = "USE &MAG"; if (zero_giac) query << "\nSELECT (S7=\"\")"; const TString& codmag = get(get_bool(F_USEDEP) ? F_DEP : F_MAG); if (codmag.full()) { query << "\nFROM CODTAB=" << codmag << "\nTO CODTAB=" << codmag; } TISAM_recordset recset(query); TToken_string fields = "CODTAB[1,5]|CODTAB[6,25]|CODTAB[26,35]|S7|R0|R1|R2|D0|S6|I0|I1|I2|I3|I4|I5|S0"; TToken_string heads = HR("Mag+Dep|Articolo@20|Livello@10|UM|Giacenza@12V|Effettiva@12V|Fisica@12V|Data@10|Gr.Mer.|Gr.A|Cnt.A|Sott.A|Gr.V|Cnt.V|Sott.V|Descrizione@50"); if (!ini_get_bool(CONFIG_DITTA, "mg", "GESDEPOSITI")) { fields.add("CODTAB[1,3]", 0); heads.add(HR("Mag"), 0); } if (!ini_get_bool(CONFIG_DITTA, "mg", "GESLIVGIAC")) { fields.destroy(2); heads.destroy(2); } TCursor_sheet s(recset.cursor(), fields, TR("Situazione"), heads, 0, 1); s.run(); } bool TSaldodata_mask::on_field_event(TOperable_field& o, TField_event e, long jolly) { switch (o.dlg()) { case F_DATA: if (e == fe_init || e == fe_modify) { const TDate d(o.get()); int anno = d.year(); if (d.month() < 10) anno--; set(F_ANNO, anno); set(F_DATACOMP, TDate(31,12,anno)); } break; case DLG_PREVIEW: if (e == fe_button) preview(false); break; case DLG_FINDREC: if (e == fe_button) preview(true); break; case DLG_DELREC: if (e == fe_button && noyes_box(TR("Si desiderano azzerare tutte le giacenze alla data?"))) { TISAM_recordset recset("USE &MAG"); recset.cursor()->scan(reset_cb, NULL, TR("Azzeramento")); return false; // Otherwise quits! } break; case DLG_SAVEREC: if (e == fe_button && check_fields() && yesno_box(TR("Si desiderano caricare le giacenza fisiche?"))) load_physical(); break; case DLG_NEXTREC: if (e == fe_button && check_fields() && yesno_box(TR("Si desiderano generare i movimenti di magazzino?"))) save_movmag(); break; default: break; } return true; } TSaldodata_mask::TSaldodata_mask() : TAutomask("mg1300a") { const bool gd = ini_get_bool(CONFIG_DITTA, "mg", "GESDEPOSITI"); enable(F_USEDEP, gd); } /////////////////////////////////////////////////////////// // TSaldo_info /////////////////////////////////////////////////////////// struct TSaldo_info : public TObject { real _giac; real _giac_eff; TString4 _um; TString8 _grmerc; TString80 _desc; TBill _billa, _billv; }; class TAssoc_saldi : public TAssoc_array { public: TSaldo_info& info(const char* key); }; TSaldo_info& TAssoc_saldi::info(const char* key) { TSaldo_info* i = (TSaldo_info*)objptr(key); if (i == NULL) { i = new TSaldo_info; TToken_string k(key); const TFixed_string codart = k.get(1); const TArticolo& art = cached_article(codart); i->_desc = art.get(ANAMAG_DESCR); i->_um = art.first_um(); i->_grmerc = art.get(ANAMAG_GRMERC); i->_billa.set(art.get_int(ANAMAG_GRUPPOA), art.get_int(ANAMAG_CONTOA), art.get_long(ANAMAG_SOTTOCA)); i->_billv.set(art.get_int(ANAMAG_GRUPPOV), art.get_int(ANAMAG_CONTOV), art.get_long(ANAMAG_SOTTOCV)); add(key, i); } return *i; } void TSaldodata_mask::load_physical() { const int anno = get_int(F_ANNO); const TString& codnum = get(F_CODNUM); const TString& dacod = get(F_ARTINI); const TString& acod = get(F_ARTFIN); TString query; query << "USE RDOC SELECT (CODARTMAG!=\"\")"; if (dacod.full() || acod.full()) query << "&&(BETWEEN(CODARTMAG,\"" << dacod << "\",\"" << acod << "\"))"; query << "\nFROM PROVV=D ANNO=" << anno << " CODNUM=" << codnum; query << "\nTO PROVV=D ANNO=" << anno << " CODNUM=" << codnum; TAssoc_array saldi; TISAM_recordset docs(query); if (!docs.empty()) { TProgind pi(docs.items(), TR("Scansione rilevazioni inventariali")); const TRectype& rec = docs.cursor()->curr(); TString80 key; for (bool ok = docs.move_first(); ok; ok = docs.move_next()) { if (!pi.addstatus(1)) break; const TString& codmag = rec.get(RDOC_CODMAG); const TString& codart = rec.get(RDOC_CODARTMAG); const TString& livgiac = rec.get(RDOC_LIVELLO); if (codmag.empty() || codart.empty()) continue; key.format("%-5s%-20s%s", (const char*)codmag, (const char*)codart, (const char*)livgiac); real* p = (real*)saldi.objptr(key); if (p == NULL) { p = new real; saldi.add(key, p); } *p += rec.get_real(RDOC_QTA); } } if (!saldi.empty()) { const TDate oggi(TODAY); TProgind pi(saldi.items(), TR("Aggiornamento giacenza fisica")); TFast_isamfile mag(LF_TABMOD); FOR_EACH_ASSOC_OBJECT(saldi, h, k, o) { if (!pi.addstatus(1)) break; mag.put("MOD", "MG"); mag.put("COD", "MAG"); mag.put("CODTAB", k); int err = mag.read(_isequal, _lock); if (err != NOERR) { mag.zero(); mag.put("MOD", "MG"); mag.put("COD", "MAG"); mag.put("CODTAB", k); mag.put("R2", *(real*)o); mag.put("S0", TR("Articolo senza giacenza")); mag.put("D0", oggi); err = mag.write(); } else { mag.put("R2", *(real*)o); err = mag.rewrite(); } } } } void TSaldodata_mask::save_movmag() { const TDate data_comp = get(F_DATACOMP); TLocalisamfile f(LF_MOVMAG); const bool giac_eff = get_int(F_GIAC) != 0; const int max_rows = 400; int nmov = 0; TMov_mag* mm = NULL; const bool use_dep = get_bool(F_USEDEP); const TString& codmag = get(use_dep ? F_DEP : F_MAG); TString query; query = "USE &MAG"; if (codmag.full()) { query << "\nFROM CODTAB=" << codmag << "\nTO CODTAB=" << codmag; } TISAM_recordset mag(query); TProgind pi(mag.items(), TR("Generazione movimenti")); TString8 last_mag; for (bool ok = mag.move_first(); ok; ok = mag.move_next()) { if (!pi.addstatus(1)) break; TString8 curr_mag = mag.get("CODTAB").as_string().left(3); curr_mag.cut(3); if (mm == NULL || mm->rows() >= max_rows || curr_mag != last_mag) { last_mag = curr_mag; if (mm) { nmov += mm->write(f) == NOERR; delete mm; } mm = new TMov_mag; mm->put(MOVMAG_ANNOES, get(F_ANNO)); mm->put(MOVMAG_CODCAUS, get(F_CAUSALE)); mm->put(MOVMAG_DATAREG, data_comp); mm->put(MOVMAG_DATACOMP, data_comp); mm->put(MOVMAG_CODCAUS, get(F_CAUSALE)); mm->put(MOVMAG_DESCR, TR("Differenze inventariali")); } real diff = mag.get("R2").as_real(); diff -= mag.get(giac_eff ? "R1" : "R0").as_real(); if (!diff.is_zero()) { TRectype& rmovmag = mm->new_row(); const TString& codtab = mag.get("CODTAB").as_string(); rmovmag.put(RMOVMAG_CODMAG, codtab.left(5)); rmovmag.put(RMOVMAG_CODART, codtab.mid(5, 20)); rmovmag.put(RMOVMAG_LIVGIAC,codtab.mid(25)); rmovmag.put(RMOVMAG_UM, mag.get("S1").as_string()); rmovmag.put(RMOVMAG_QUANT, diff); } } if (mm) { if (mm->rows() > 0) nmov += mm->write(f) == NOERR; delete mm; mm = NULL; } message_box(FR("Sono stati generati %d movimenti"), nmov); } /////////////////////////////////////////////////////////// // TSaldodata_app /////////////////////////////////////////////////////////// class TSaldodata_app : public TSkeleton_application { protected: void reset_saldi(const TDate& data, const TString& codmag); void init_saldi_iniziali(const TDate& data, bool use_dep,const TString& codmag, const TString& dacod, const TString& acod, TAssoc_saldi& saldi); void update_saldi(const TDate& data, bool use_dep, const TString& codmag, TAssoc_saldi& saldi); void rebuild_saldi(const TDate& data, bool use_dep, const TString& codmag, const TString& dacod, const TString& acod); public: virtual void main_loop(); }; void TSaldodata_app::reset_saldi(const TDate& data, const TString& codmag) { TFast_isamfile mag(LF_TABMOD); TString query; query = "USE &MAG"; if (codmag.full()) { query << "\nFROM CODTAB=" << codmag << "\nTO CODTAB=" << codmag; } TISAM_recordset recset(query); TProgind pi(recset.items(), TR("Azzeramento")); TRectype& rec = recset.cursor()->curr(); for (bool ok = recset.move_first(); ok; ok = recset.move_next()) { if (!pi.addstatus(1)) break; rec.zero("R0"); rec.zero("R1"); rec.put("D0", data); rec.rewrite(mag); } } void TSaldodata_app::init_saldi_iniziali(const TDate& data, bool use_dep, const TString& codmag, const TString& dacod, const TString& acod, TAssoc_saldi& saldi) { TEsercizi_contabili esc; const int esercizio_corrente = esc.date2esc(data); const int esercizio_scorso = esc.pred(esercizio_corrente); bool precedente_aperto = false; if (esercizio_scorso > 0) { const TDate chiusura = esc.esercizio(esercizio_scorso).chiusura_mag(); precedente_aperto = !chiusura.ok(); } if (precedente_aperto) // Esercizio aperto { TString limit; limit << "ANNOES=" << (data.year()-1); if (codmag.full()) limit << " CODMAG=" << codmag; limit << " CODART="; TString query; query << "USE " << LF_MAG << " KEY 2" << "\nFROM " << limit << dacod << "\nTO " << limit << acod; TISAM_recordset recset(query); TToken_string key; TProgind pi(recset.items(), TR("Saldi iniziali")); for (bool ok = recset.move_first(); ok; ok = recset.move_next()) { if (!pi.addstatus(1)) break; const real giac = recset.get(MAG_GIAC).as_real(); const real cl = recset.get(MAG_INCL).as_real() - recset.get(MAG_ACL).as_real(); if (!giac.is_zero() || !cl.is_zero()) { key = recset.get(MAG_CODMAG).as_string(); if (key.empty()) key.spaces(5); if (!use_dep) key.cut(3); key.add(recset.get(MAG_CODART).as_string()); key.add(recset.get(MAG_LIVELLO).as_string()); TSaldo_info& info = saldi.info(key); info._giac += giac; info._giac_eff += giac - cl; } } } } void TSaldodata_app::update_saldi(const TDate& data, bool use_dep, const TString& mag, TAssoc_saldi& saldi) { TString query; query << "USE MOVMAG KEY 2 SELECT BETWEEN(DATAREG,0," << data.date2ansi() << ')' << "\nFROM ANNOES=" << data.year() << "\nTO ANNOES=" << data.year(); TISAM_recordset recset(query); TProgind pi(recset.items(), TR("Scansione movimenti")); TToken_string key; for (bool ok = recset.move_first(); ok; ok = recset.move_next()) { if (!pi.addstatus(1)) break; const TString8 hcaus = recset.get(MOVMAG_CODCAUS).as_string(); key = recset.get(MOVMAG_NUMREG).as_string(); TRecord_array righe(key, LF_RMOVMAG); for (int i = righe.last_row(); i > 0; i = righe.pred_row(i)) { const TRectype& riga = righe.row(i); real qta = riga.get_real(RMOVMAG_QUANT); if (qta.is_zero()) continue; const TString& rcaus = riga.get(RMOVMAG_CODCAUS); const TCausale_magazzino& caus = cached_causale_magazzino(rcaus.full() ? rcaus : hcaus); const int sgn_giac = caus.sgn(s_giac); const int sgn_icl = caus.sgn(s_incl); const int sgn_acl = caus.sgn(s_acl); if ((sgn_giac != 0 || sgn_icl != 0 || sgn_acl != 0) && caus.update_qta()) { TString8 codmag = riga.get(RMOVMAG_CODMAG); if (codmag.empty()) codmag.spaces(5); if (!use_dep) codmag.cut(3); if (mag.full() && codmag != mag) continue; const TString80 codart = riga.get(RMOVMAG_CODART); const TString4 um = riga.get(RMOVMAG_UM); TArticolo& art = cached_article(codart); qta = art.convert_to_um(qta, EMPTY_STRING, um); key = codmag; key.add(codart); key.add(riga.get(RMOVMAG_LIVGIAC)); TSaldo_info& info = saldi.info(key); info._giac += qta * sgn_giac; info._giac_eff += qta * sgn_giac; info._giac_eff += qta * sgn_icl; info._giac_eff += qta * sgn_acl; } } } } void TSaldodata_app::rebuild_saldi(const TDate& data, bool use_dep, const TString& codmag, const TString& dacod, const TString& acod) { TAssoc_saldi saldi; init_saldi_iniziali(data, use_dep, codmag, dacod, acod, saldi); update_saldi(data, use_dep, codmag, saldi); TFast_isamfile mag(LF_TABMOD); TToken_string k; TString80 codtab; TProgind pi(saldi.items(), TR("Salvataggio giacenze")); FOR_EACH_ASSOC_OBJECT(saldi, hash, key, obj) { if (!pi.addstatus(1)) break; k = key; codtab.format("%-5s%-20s", k.get(0), k.get(1)); const char* liv = k.get(2); if (liv && *liv > ' ') codtab << liv; mag.put("MOD", "MG"); mag.put("COD", "MAG"); mag.put("CODTAB", codtab); if (mag.read() != NOERR) { mag.zero(); mag.put("MOD", "MG"); mag.put("COD", "MAG"); mag.put("CODTAB", codtab); mag.write(); } const TSaldo_info& info = *(const TSaldo_info*)obj; mag.put("S0", info._desc); mag.put("R0", info._giac); mag.put("R1", info._giac_eff); mag.put("S6", info._grmerc); mag.put("S7", info._um); mag.put("I0", info._billa.gruppo()); mag.put("I1", info._billa.conto()); mag.put("I2", info._billa.sottoconto()); mag.put("I3", info._billv.gruppo()); mag.put("I4", info._billv.conto()); mag.put("I5", info._billv.sottoconto()); mag.put("D0", data); if (mag.rewrite() != NOERR) { cantwrite_box(title()); break; } } } void TSaldodata_app::main_loop() { TSaldodata_mask m; while (m.run()==K_ENTER) { const TDate al = m.get(F_DATA); const bool use_dep = m.get_bool(F_USEDEP); const TString& mag = m.get(use_dep ? F_DEP : F_MAG); const TString& dacod = m.get(F_ARTINI); const TString& acod = m.get(F_ARTFIN); reset_saldi(al, mag); rebuild_saldi(al, use_dep, mag, dacod, acod); } } int mg1300(int argc, char* argv[]) { TSaldodata_app a; a.run(argc, argv, TR("Giacenza alla data")); return 0; }