#include #include "../ve/ve0100.h" #include "../ve/veini.h" #include "../ve/veuml.h" #include "../ve/veuml3.h" #include "../ve/verig.h" #include "../ve/vepriv.h" #include "lvlib.h" #include "lvcondv.h" #include "lvrcondv.h" #include "lvrconsplan.h" #include "../mg/clifogiac.h" #include "../ve/rcondv.h" #define FOR_EACH_DOC_ROW_BACK(d, r, row) const TRiga_documento* row = NULL; for (int r = d.rows(); r > 0 && (row = &d[r]) != NULL; r--) ////////////////////////////////////////// //// CLASSE TGESTIONE_BOLLE_MSK //// ////////////////////////////////////////// //Definizione della classe della maschera class TGestione_bolle_msk : public TDocumento_mask { long _stcodcf; long _stcodcont; protected: static void arrotonda(const TMask& msk, real& quantita); static void dettaglio_causale(TSheet_field& ss); //hanlder di documento: static bool lv_data_handler(TMask_field& f, KEY k); static bool lv_contratto_handler(TMask_field& f, KEY k); static bool lv_dataprco_handler(TMask_field& f, KEY k); static bool lv_bolla_handler(TMask_field& f, KEY k); //handler di riga: static bool lv_ritirato_handler(TMask_field& f, KEY k); static bool lv_consegnato_handler(TMask_field& f, KEY k); static bool lv_codart_handler(TMask_field& f, KEY k); static bool lv_causale_handler(TMask_field& f, KEY k); static bool lv_codmag_handler(TMask_field& f, KEY k); static bool lv_datatmp_handler(TMask_field& f, KEY k); static bool ss_notify(TSheet_field& ss, int r, KEY key); static bool ss_handler(TMask_field& f, KEY key); virtual void on_idle(); public: virtual void user_set_handler( short fieldid, int index); virtual void user_set_row_handler(TMask& rm, short field, int index); void reset_var_mask() {_stcodcf = 0; _stcodcont = 0;} TDate proponi_dataprco() const; TGestione_bolle_msk(const char* tipodoc); int _autoselect; }; ////////////////////////////////////////// //// CLASSE TGESTIONE_BOLLE_APP //// ////////////////////////////////////////// // Definizione della classe dell'applicazione motore class TGestione_bolle_app : public TMotore_application { TGiac_per_cli _giac; protected: virtual TMask* get_mask( int mode ); virtual int write( const TMask& m ); virtual int rewrite( const TMask& m ); virtual int read ( TMask& m ); virtual void init_insert_mode( TMask& m ); virtual void init_modify_mode( TMask& m ); void elimina_vuote( const TMask& m); void salva_conguaglio( const TMask& m); void date_dotmp( const TMask& m); virtual const char * query_mask_name() { return "lv3100a"; } public: TGiac_per_cli& giacenza(); TGestione_bolle_app() {} }; inline TGestione_bolle_app& gbapp() { return (TGestione_bolle_app &)main_app(); }; ////////////////////////////////////////// //// CLASSE TGESTIONE_BOLLE_MSK //// ////////////////////////////////////////// //ARROTONDA: metodo che arrotonda la quantità che gli passo se è previsto sul contratto void TGestione_bolle_msk::arrotonda(const TMask& msk, real& quantita) { int perarr = ini_get_int(CONFIG_DITTA, "lv", "Perarr"); const TString& codart = msk.get(FR_CODART); //instanzio una cache sulla tabella del magazzino const TRectype& anamag = cache().get(LF_ANAMAG,codart); //recupero i dati di interesse dall'anagrafica di magazzino const long ppconf = anamag.get_long(ANAMAG_PPCONF); if (ppconf > 0) { TDocumento_mask& dmsk = (TDocumento_mask&) msk.get_sheet()->mask(); //recupero dal documento i dati di interesse per recuperare... //...i dati dalla riga contratto const long codcf = dmsk.get_long(F_CODCF); const int indsped = dmsk.get_int(F_CODINDSP); TDate datadoc = dmsk.get_date(F_DATADOC); if (!datadoc.ok()) datadoc = TODAY; const TLaundry_contract cont(codcf, indsped, datadoc); //leggo la riga del contratto per l'articolo corrente const TRectype& rcont = cont.row(codart); //recupero i dati di interesse dalla riga del contratto if (rcont.get_int(LVRCONDV_CALCCONS) == 1) { //calcolo di quanti pezzi sforo long arr = quantita.integer() % ppconf; //calcolo quanti pezzi in più o in meno gli devo dare e aggiorno la quantità if (arr > ppconf * perarr / 100) //arr <= ppconf*perarr/100 -> formula calcolo congualgio di Tassan { arr = ppconf - arr; quantita += arr; } else quantita -= arr; } } } //DETTAGLIO_CAUSALE: metodo che setta esplode la causale negli appositi campi void TGestione_bolle_msk::dettaglio_causale(TSheet_field& ss) { TGestione_bolle_msk& dmsk = (TGestione_bolle_msk&) ss.mask(); TString4 causale = ss.cell(ss.selected(),ss.cid2index(FR_CODAGG1)); //instanzio una cache sulle causali const TCausale_lavanderie cau(causale); //esplodo la causale dmsk.set(F_LVCODCAU, cau.codice()); dmsk.set(F_LVDESCAU, cau.descr()); } //PROPONI_DATAPRCO: metodo che propone la prima data di prevista consegna TDate TGestione_bolle_msk::proponi_dataprco() const { const TDate dadata = get(F_DATADOC); TDate dataprco(0,0,0); if (dadata.ok()) { TDate adata = dadata; adata.addmonth(1); TString query = "USE LVRCONSPLAN KEY 3\n"; query << "FROM CODCF=" << get(F_CODCF) << " CODCONT=" << get(F_LVCODCONT) << " DTCONS=" << dadata << "\n"; query << "TO CODCF=" << get(F_CODCF) << " CODCONT=" << get(F_LVCODCONT) << " DTCONS=" << adata << "\n"; TISAM_recordset consegne(query); if (consegne.items() >= 2) { consegne.move_to(1); dataprco = consegne.get(LVRCONSPLAN_DTCONS).as_date(); } } return dataprco; } //////////////////////////// // HANDLER DI DOCUMENTO // //////////////////////////// void TGestione_bolle_msk:: on_idle() { TDocumento_mask::on_idle(); if (_autoselect >= 0) { TSheet_field& s = sfield(F_SHEET); if (_autoselect < s.items()) { //per ora 4 fisso perchè non sappiamo calcolare la colonna del ritirato s.set_focus_cell_id(_autoselect, FR_QTAGG1); dettaglio_causale(s); } _autoselect = -1; } } //magico metodo per settare, al cambio riga dello sheet, il focus sul campo desiderato (il campo in questione è.. //..definito nella on_idle(); ricordarsi la set_notify() nel costruttore della maschera senno' viene eseguito l'ss_notify().. //..standard e non questo qui ridefinito. Allah! bool TGestione_bolle_msk::ss_notify(TSheet_field& ss, int r, KEY key) { TGestione_bolle_msk& dmsk = (TGestione_bolle_msk&) ss.mask(); if (key == K_TAB && dmsk._autoselect < 0 && dmsk.is_running()) dmsk._autoselect = r; //riga per settare il focus return TDocumento_mask::ss_notify(ss, r, key); } //SS_HANDLER: handler che mi peremette di evitare la registrazione in caso di documento //senza righe valide (cioè con quantità diverese da zero) bool TGestione_bolle_msk::ss_handler(TMask_field& f, KEY key) { if ((key == K_ENTER) && f.mask().insert_mode()) { TSheet_field& ss = (TSheet_field&)f; bool vuote = true; if (ss.items() > 0) vuote = false; if(!vuote) { vuote = true; FOR_EACH_SHEET_ROW(ss, r, row) { if (row->get_int(ss.cid2index(FR_QTA)) != 0 || row->get_int(ss.cid2index(FR_QTAGG1)) != 0) vuote = false; } } if (!app().is_transaction() && vuote) return error_box(TR("Il documento e' privo di righe valide e pertanto verrà ignorato")); } return TDocumento_mask::ss_handler(f, key); } //LV_DATA_HANDLER: handler che si occupa di decodificare i campi data in testata bool TGestione_bolle_msk::lv_data_handler(TMask_field& f, KEY k) { bool ok = true; switch(f.dlg()) { case F_DATADOC: ok = data_hndl( f, k ); break; default: break; } TGestione_bolle_msk& dmsk = (TGestione_bolle_msk&)f.mask(); TDate oggi(TODAY); TDate primo = oggi; primo.set_day(1); if (dmsk.get_date(F_DATADOC) != oggi) { oggi = dmsk.get_date(F_DATADOC); primo = oggi; primo.set_day(1); } //decodifica del giorno della settimana dmsk.set(F_LVGIORNO, itow(oggi.wday())); //settimana del mese = settimana(oggi) - settimana(primo del mese) + 1 long tmp = oggi.week() - primo.week() + 1; TString4 settimana; settimana << tmp; dmsk.set(F_LVSETTIMANA, settimana); return ok; } //LV_CONTRATTO_HANDLER: handler che si occupa di riempire il campo contratto in testata bool TGestione_bolle_msk::lv_contratto_handler(TMask_field& f, KEY k) { TGestione_bolle_msk& dmsk = (TGestione_bolle_msk&)f.mask(); const long codcf = dmsk.get_long(F_CODCF); const int indsped = dmsk.get_int(F_CODINDSP); TDate datadoc = dmsk.get_date(F_DATADOC); if (!datadoc.ok()) datadoc = TODAY; const int anno = datadoc.year(); if (codcf <= 0) return true; long codcont = lv_find_contract(codcf, indsped, datadoc); if (codcont <= 0) { warning_box(TR("Non ci sono contratti in essere alla data indicata")); return true; } else { TString16 tmp; tmp << codcont; dmsk.set(F_LVCODCONT, tmp); const TDate dataprco = dmsk.proponi_dataprco(); if (dataprco.ok() && dmsk.field(F_LVDATAPRCO).empty()) dmsk.set(F_LVDATAPRCO, dataprco); } TDocumento& doc = dmsk.doc(); doc.put(DOC_CODCONT, codcont); return true; } //LV_DATAPRCO_HANDLER: handler che si occupa della gestione del campo "data di prevista consegna" bool TGestione_bolle_msk::lv_dataprco_handler(TMask_field& f, KEY k) { //se sto leggendo o generando un buono di ritiro, abilito questo campo if (k == K_TAB) { TGestione_bolle_msk& dmsk = (TGestione_bolle_msk&)f.mask(); TDocumento& doc = dmsk.doc(); //se la data viene modificata a mano, controlla se è una data di previsto passaggio; //se non lo è chiedi conferma se si desidera mantenre la data indicata manualmente o se //è meglio riproporre la data di previsto passaggio if (!f.empty() && f.focusdirty() && doc.get_date("DATAPRCO") != (TDate)f.get()) { doc.put("DATAPRCO", f.get()); TString query1 = "USE LVRCONSPLAN KEY 3\n"; query1 << "FROM CODCF=" << dmsk.get(F_CODCF) << " CODCONT=\"" << dmsk.get(F_LVCODCONT) << "\" DTCONS=" << f.get() << "\n"; query1 << "TO CODCF=" << dmsk.get(F_CODCF) << " CODCONT=\"" << dmsk.get(F_LVCODCONT) << "\" DTCONS=" << f.get() << "\n"; TISAM_recordset consegne(query1); if (!consegne.move_first()) { f.set_focusdirty(false); if (!yesno_box(TR("Non è previsto nessun passaggio per questa data, confermi lo stesso?"))) { const TDate dataprco = dmsk.proponi_dataprco(); if (dataprco.ok()) { f.set(dataprco); doc.put("DATAPRCO", dataprco); } } } } } return true; } //LV_BOLLA_HANDLER: handler di bolla, carica le righe contratto sulle bolle, preparando la struttura del documento bool TGestione_bolle_msk::lv_bolla_handler(TMask_field& f, KEY k) { bool ok = true; switch(f.dlg()) { case F_CODCF: ok = TDocumento_mask::clifo_handler( f, k ); break; default: break; } TGestione_bolle_msk& dmsk = (TGestione_bolle_msk&)f.mask(); if (ok && k == K_TAB && ((dmsk.insert_mode() && f.to_check(k, true)) || f.focusdirty()) && dmsk.mode() != MODE_MOD ) { f.set_focusdirty(false); TDocumento& doc = dmsk.doc(); TSheet_field& sheet = dmsk.sfield(F_SHEET); int nrighe = sheet.items(); const long codcf = dmsk.get_long(F_CODCF); const int indsped = dmsk.get_int(F_CODINDSP); TDate datadoc = dmsk.get_date(F_DATADOC); if (!datadoc.ok()) datadoc = TODAY; const int anno = datadoc.year(); if (codcf <= 0) return true; const long codcont = lv_find_contract(codcf,indsped,datadoc); if (codcont <= 0) { warning_box(TR("Non ci sono contratti in essere alla data indicata")); return true; } else { doc.put(DOC_CODCF, codcf); doc.put(DOC_DATADOC, datadoc); doc.put(DOC_CODINDSP, indsped); doc.put(DOC_CODCONT, codcont); const TDate dataprco = dmsk.proponi_dataprco(); if (dataprco.ok() && dmsk.field(F_LVDATAPRCO).empty()) doc.put("DATAPRCO", dataprco); } if (dmsk._stcodcf == codcf && dmsk._stcodcont == codcont && nrighe > 0) return true; dmsk.mask2doc(); dmsk._stcodcf = codcf; dmsk._stcodcont = codcont; //elimino tutte le righe del documento doc.destroy_rows(); //tipo riga const TString& tprig = dmsk.get(F_LBTIPORIGA); //instanzio una cache sulla tabella dei contratti const TLaundry_contract tcont(codcf, codcont); //estraggo i dati di interesse dalla cache const int tplis = tcont.get_int(LVCONDV_TIPOLIS); //tipo listino //instanzio un recordset sulle righe del contratto considerato TISAM_recordset rcont("USE LVRCONDV\nFROM CODCF=#CODCF CODCONT=#CODCONT\nTO CODCF=#CODCF CODCONT=#CODCONT"); rcont.set_var("#CODCF",codcf); rcont.set_var("#CODCONT",codcont); //leggo dalla configurazione i codici magazzino e deposito standard TString8 codmag; codmag << ini_get_string(CONFIG_DITTA, "lv", "CODMAG") << ini_get_string(CONFIG_DITTA, "lv", "CODMAGC"); //per ogni riga estraggo l'articolo, il relativo prezzo e l'eventaule sconto da applicare, //...riportati in bolla solo se necessario for (bool ok = rcont.move_first(); ok; ok = rcont.move_next()) { //creo una nuova riga documento TRiga_documento& rdoc = doc.new_row(tprig); //recupero i dati di interesse dalla riga del contratto e li inserisco sullo sheet const TString80 codart = rcont.get(LVRCONDV_CODART).as_string(); TString4 causale = rcont.get(LVRCONDV_CAUSLAV).as_string(); if (causale.blank() || atoi(causale) == 0) causale = ini_get_string(CONFIG_DITTA, "lv", "CAUSLAV"); //instanzio una cache sulle anagrafice di magazzino const TRectype& anamag = cache().get(LF_ANAMAG,codart); TToken_string key; key.add(codart); key.add(1); const TRectype& umart = cache().get(LF_UMART, key); rdoc.put(RDOC_CODART,codart); rdoc.put(RDOC_CODARTMAG,codart); rdoc.put(RDOC_CHECKED,'X'); rdoc.put(RDOC_DESCR, anamag.get(ANAMAG_DESCR)); rdoc.put(RDOC_UMQTA, umart.get(UMART_UM)); rdoc.put(RDOC_CODAGG1,causale); rdoc.put(RDOC_CODIVA,anamag.get(ANAMAG_CODIVA)); TString8 codmagold = rdoc.get(RDOC_CODMAG); if (codmagold.empty()) { const TCausale_lavanderie cau(causale); const TCausale_magazzino rit = cau.causale_ritiro(); const TCausale_magazzino con = cau.causale_consegna(); TString8 magazzino; TString8 magazzinoc; if(rit.get("S10").full()) magazzino = rit.get("S10").mid(0,5); else magazzino << ini_get_string(CONFIG_DITTA, "lv", "CODMAG") << ini_get_string(CONFIG_DITTA, "lv", "CODMAGN"); if(con.get("S10").full()) magazzinoc = con.get("S10").mid(0,5); else magazzinoc << ini_get_string(CONFIG_DITTA, "lv", "CODMAG") << ini_get_string(CONFIG_DITTA, "lv", "CODMAGC"); rdoc.put(RDOC_CODMAG, magazzino); rdoc.put(RDOC_CODMAGC, magazzinoc); } //gestione campi dotazione odierna e dotazione temporanea TGiac_per_cli& giac = gbapp().giacenza(); giac.preset(doc); real dotod = giac.giac_att(rdoc, true); rdoc.put("DOTOD", dotod); real dotmp = giac.giac_att(rdoc, false); rdoc.put("DOTMP", dotmp); //elaborazione per il prezzo: o lo prendo dalle righe contratto, o dall'anagrafica magazzino const TString& sconto = rcont.get(LVRCONDV_SCONTPERC).as_string(); rdoc.put(RDOC_SCONTO, sconto); //controllo da dove devo prendere il prezzo real prezzo; if (tplis == 0) prezzo = rcont.get(LVRCONDV_PREZZO).as_real(); else prezzo = anamag.get_real(ANAMAG_COSTSTD); rdoc.put(RDOC_PREZZO, prezzo); } // dmsk.doc2mask(false); const int righe = doc.physical_rows(); sheet.destroy( ); for (int i = 1; i <= righe; i++) { TRiga_documento& r = doc[i]; doc[i].autoload(sheet); sheet.check_row(i - 1, 0x3); } FOR_EACH_MASK_FIELD(dmsk, i, f) { if (f->has_check()) f->check(STARTING_CHECK); if (f->is_edit()) f->on_hit(); } dmsk._autoselect = 0; } return ok; } /////////////////////// // HANDLER DI RIGA // /////////////////////// //LV_RITIRATO_HANDLER: handler sul campo ritirato, che copia nel campo consegnato //lo stesso valore eventualmente arrotondato e aggiorna il campo "dotazione odierna" (sempre) //e il campo "dotazione temporanea" (se la causale è giusta) bool TGestione_bolle_msk::lv_ritirato_handler(TMask_field& f, KEY k) { if (f.to_check(k)) { //maschera di riga TMask& msk = f.mask(); //maschera di documento TSheet_field* sheet = msk.get_sheet(); TDocumento_mask& dmask = (TDocumento_mask&)sheet->mask(); const long codcf = dmask.get_long(F_CODCF); const int indsped = dmask.get_int(F_CODINDSP); TDate datadoc = dmask.get_date(F_DATADOC); if (!datadoc.ok()) datadoc = TODAY; //recupero i valori della dotazione iniziale dal magazzino del cliente TLocalisamfile magcli(LF_CLIFOGIAC); magcli.put(CLIFOGIAC_ANNOES, datadoc.year()); magcli.put(CLIFOGIAC_TIPOCF, 'C'); magcli.put(CLIFOGIAC_CODCF, codcf); magcli.put(CLIFOGIAC_INDSPED, indsped); magcli.put(CLIFOGIAC_CODART, msk.get(FR_CODART)); magcli.put(CLIFOGIAC_NRIGA, 1); //leggo il record corrispondente magcli.read(); long dotin = magcli.get_long(CLIFOGIAC_DOTIN); real ritirato = f.get(); real dotod = msk.get_real(FR_JOLLY1); if (ritirato > dotod && f.dirty() && dotin > 0) warning_box(TR("ATTENZIONE: stai ritirando un quantitativo maggiore della dotazione!")); TDocumento& doc = dmask.doc(); TRiga_documento& rdoc = dmask.doc()[sheet->selected()+1]; rdoc.put(RDOC_QTAGG1,ritirato); if (msk.field(FR_QTA).enabled() && msk.field(FR_QTA).empty() && !msk.field(FR_QTA).focusdirty()) { real consegnato = ritirato; arrotonda(msk, consegnato); msk.set(FR_QTA, consegnato, 0x3); return true; } //gestione campi dotazione odierna e dotazione temporanea TGiac_per_cli& giac = gbapp().giacenza(); dotod = giac.giac_att(rdoc, true); msk.set(FR_JOLLY1, dotod); rdoc.put("DOTOD", dotod); //scrivo la dotazione temporanea solo se esistono le date di dotazione temporanea e questa non è scaduta if (rdoc.get_date("DADATATMP").ok() && rdoc.get_date("ADATATMP").ok() && rdoc.get_date("ADATATMP") >= doc.get_date(DOC_DATADOC)) { real dotmp = giac.giac_att(rdoc, false); msk.set(FR_JOLLY2, dotmp); rdoc.put("DOTMP", dotmp); } } return true; } //LV_CONSEGNATO_HANDLER: per adesso è solo un segna - posto bool TGestione_bolle_msk::lv_consegnato_handler(TMask_field& f, KEY k) { bool ok = true; switch(f.dlg()) { case FR_QTA: ok = qta_handler( f, k ); break; default: break; } if (f.to_check(k)) { TMask& msk = f.mask(); real consegnato = f.get(); //gestione campi dotazione odierna e dotazione temporanea TSheet_field* sheet = msk.get_sheet(); TDocumento_mask& dmask = (TDocumento_mask&)sheet->mask(); TDocumento& doc = dmask.doc(); TRiga_documento& rdoc = dmask.doc()[sheet->selected()+1]; rdoc.put(RDOC_QTA, consegnato); TGiac_per_cli& giac = gbapp().giacenza(); real dotod = giac.giac_att(rdoc, true); msk.set(FR_JOLLY1, dotod); rdoc.put("DOTOD", dotod); //scrivo la dotazione temporanea solo se esistono le date di dotazione temporanea e questa non è scaduta if (rdoc.get_date("DADATATMP").ok() && rdoc.get_date("ADATATMP").ok() && rdoc.get_date("ADATATMP") >= doc.get_date(DOC_DATADOC)) { real dotmp = giac.giac_att(rdoc, false); msk.set(FR_JOLLY2, dotmp); rdoc.put("DOTMP", dotmp); } } return ok; } //LV_CODART_HANDLER: handler sul campo codice articolo, che carica la causale relativa all'articolo //e controlla se l'articolo che si sta inserendo fa parte della dotazione del cliente bool TGestione_bolle_msk::lv_codart_handler(TMask_field& f, KEY k) { bool ok = true; switch(f.dlg()) { case FR_CODART: ok = codart_handler( f, k ); break; default: break; } //if (ok && (k == K_ENTER || k == K_TAB)) if (ok && f.to_check(k)) { TMask& msk = f.mask(); const TString& codart = msk.get(FR_CODART); if (codart.full()) { TGestione_bolle_msk& dmsk = (TGestione_bolle_msk&) msk.get_sheet()->mask(); TSheet_field* sheet = msk.get_sheet(); TRiga_documento& rdoc = dmsk.doc()[sheet->selected()+1]; rdoc.put(RDOC_CODART, codart); //recupero dal documento i dati di interesse per recuperare... //...i dati dalla riga contratto const long codcf = dmsk.get_long(F_CODCF); const int indsped = dmsk.get_int(F_CODINDSP); TDate datadoc = dmsk.get_date(F_DATADOC); if (!datadoc.ok()) datadoc = TODAY; TLaundry_contract cont(codcf, indsped, datadoc); const TRectype& rcont = cont.row(codart); //cerco la causale relativa all'articolo; se non la trovo prendo quella standard TString4 causale = rcont.get(LVRCONDV_CAUSLAV); if (causale.blank() || atoi(causale) == 0 ) causale = ini_get_string(CONFIG_DITTA, "lv", "CAUSLAV"); if (rdoc.get("DOTOD").empty()) { //gestione campi dotazione odierna e dotazione temporanea TGiac_per_cli& giac = gbapp().giacenza(); giac.preset(dmsk.doc()); real dotod = giac.giac_att(rdoc, true); rdoc.put("DOTOD", dotod); TString16 tmp; tmp << dotod; msk.field(FR_JOLLY1).set(tmp); } if (rdoc.get(RDOC_CODAGG1).empty()) msk.set(FR_CODAGG1, causale); if (k == K_ENTER && rcont.get_int(LVRCONDV_CALCCONS) == 1) { TSheet_field* sheet = msk.get_sheet(); TRiga_documento rdoc = dmsk.doc()[sheet->selected()+1]; const real ritor = rdoc.get_real(RDOC_QTAGG4); const real conor = rdoc.get_real(RDOC_QTAGG3); const real ritat = msk.get_real(FR_QTAGG1); const real conat = msk.get_real(FR_QTA); //instanzio una cache sulle causali causale = sheet->cell(sheet->selected(),sheet->cid2index(FR_CODAGG1)); const TCausale_lavanderie cau(causale); if (cau.movcong() && (ritor != ritat || conor != conat) && ini_get_bool(CONFIG_DITTA, "lv", "Aggcong")) { const real congor = rcont.get_real(LVRCONDV_QTACONG); const real congat = conat - conor - ritat + ritor + congor; msk.set(FR_QTAGG5, congat); } } if (rcont.empty()) { real prezzo; //PROPONI PREZZO TToken_string key; key.add('C'); key.add(codcf); const TRectype& cfven = cache().get(LF_CFVEN, key); bool trvlst = false; if (!cfven.empty()) { //se è settata la categoria merceologica, leggo sia il listino che la cat merc, altrimenti solo il listino TString8 codlis = cfven.get(CFV_CODLIST); TString8 catven; if (!ini_get_bool(CONFIG_DITTA, "ve", "GESLISCV")) catven = ""; else catven = cfven.get(CFV_CATVEN); //cerco il prezzo sul listino key.cut(0); key.add('L'); //tipo key.add(catven); //catven key.add(""); //tipocf key.add(""); //codcf key.add(codlis); //codlis key.add('A'); //tiporiga key.add(codart); //codriga key.add(""); //um key.add(""); //nscagl const TRectype& rcondv = cache().get(LF_RCONDV, key); if (!rcondv.empty()) { prezzo = rcondv.get_real(RCONDV_PREZZO); trvlst = true; } } //se non ho trovato un listino, o se non c'è un listino impostato //propongo come prezzo il valore convenzionale if (!trvlst) { key.cut(0); key.add(codart); key.add(1); const TRectype& umart = cache().get(LF_UMART, key); prezzo = umart.get_real(UMART_PREZZO); if (umart.get(UMART_PREZZO).full()) trvlst = true; } rdoc.put(RDOC_PREZZO, prezzo); } //controllo se si vuole aggiungere un eventuale nuovo articolo al contratto if (cont.get_int(LVCONDV_CODCONT) <= 0) warning_box(TR("ATTENZIONE: stai generando una bolla per un cliente che non ha nessun contratto in essere")); else if (k == K_ENTER && f.dirty() && msk.get(FR_CODARTMAG).full() && rcont.empty() && yesno_box(TR("L'articolo in esame non fa parte della dotazione standard di questo cliente." "Si desidera aggiungerla ai contratti?"))) { cont.add_row(codart); //questo pezzo sostituisce il metodo edit TFilename ininame; ininame.temp(); { TConfig ini(ininame, "Transaction"); ini.set("Action", "LINK"); ini.set_paragraph("168"); ini.set(LVCONDV_CODCF, codcf); ini.set(LVCONDV_CODCONT, cont.get_int(LVCONDV_CODCONT)); } TString app = "lv0 -3"; app << " -i" << ininame; app << " -c" << codart; TExternal_app a(app); ok = a.run() == 0; } } } return ok; } //LV_CAUSALE_HANDLER: handler che abilita e/o disabilita i campi di consegnato e ritirato in base alla causale //e tenendo conto se l'articolo è bloccato o meno bool TGestione_bolle_msk::lv_causale_handler(TMask_field& f, KEY k) { if (f.to_check(k, true)) { //leggo la causale che ho scritto nella riga corrente dello sheet TString4 causale = f.get(); if (causale.full()) { TMask& msk = f.mask(); //leggo il codart che ho scritto nella riga corrente delle sheet const TString& codart = msk.get(FR_CODART); //srcrivo nel documento la causale TGestione_bolle_msk& dmsk = (TGestione_bolle_msk&) msk.get_sheet()->mask(); TSheet_field& sheet = dmsk.sfield(F_SHEET); //esplodo la descrizione della causale dettaglio_causale(sheet); TDocumento& doc = dmsk.doc(); TRiga_documento& rdoc = doc[msk.get_sheet()->selected()+1]; TString4 codmag(doc.clifor().vendite().get(CFV_CODMAG)); TString4 coddep(doc.clifor().vendite().get(CFV_CODDEP)); TString4 codmagcoll(codmag); TString4 coddepcoll(coddep); rdoc.put(RDOC_CODAGG1, causale); const TCausale_lavanderie cau(causale); const TCausale_magazzino rit = cau.causale_ritiro(); const TCausale_magazzino con = cau.causale_consegna(); TString8 magazzino; TString8 magazzinoc; if(rit.get("S10").full()) magazzino = rit.get("S10").mid(0,5); else magazzino << ini_get_string(CONFIG_DITTA, "lv", "CODMAG") << ini_get_string(CONFIG_DITTA, "lv", "CODMAGN"); if(con.get("S10").full()) magazzinoc = con.get("S10").mid(0,5); else magazzinoc << ini_get_string(CONFIG_DITTA, "lv", "CODMAG") << ini_get_string(CONFIG_DITTA, "lv", "CODMAGC"); rdoc.put(RDOC_CODMAG, magazzino); rdoc.put(RDOC_CODMAGC, magazzinoc); msk.field(FR_CODAGG1).set(causale); msk.field(FR_CODMAG).set(magazzino.left(3)); msk.field(FR_CODDEP).set(magazzino.mid(3,2)); msk.field(FR_CODMAGC).set(magazzinoc.left(3)); msk.field(FR_CODDEPC).set(magazzinoc.mid(3,2)); //recupero i dati di interesse dalla testata per poter trovare il contratto const long codcf = dmsk.get_long(F_CODCF); const int indsped = dmsk.get_int(F_CODINDSP); TDate datadoc = dmsk.get_date(F_DATADOC); if (!datadoc.ok()) datadoc = TODAY; //trovo il contratto utlizzato e la riga contratto specifica che mi serve const TLaundry_contract cont(codcf, indsped, datadoc); const TRectype& rcont = cont.row(codart); //movimento o meno la dotazione temporanea/odierna a seconda di cosa prevede la causale int sgn_rit = 0; int sgn_con = 0; if (cau.is_ritiro()) { const TCausale_magazzino& rit = cau.causale_ritiro(); if (codmagcoll.blank() && rit.has_default_mag()) { codmagcoll = rit.default_mag(); coddepcoll = rit.default_dep(); } sgn_rit = rit.sgn(s_dottm); } if (cau.is_consegna()) { const TCausale_magazzino& con = cau.causale_consegna(); if (codmag.blank() && con.has_default_mag()) { codmag = con.default_mag(); coddep = con.default_dep(); } sgn_con = con.sgn(s_dottm); } //setto il valore della dotazione temporanea TGiac_per_cli& giac = gbapp().giacenza(); giac.preset(doc); real dotmp = giac.giac_att(rdoc, false); rdoc.put("DOTMP", dotmp); TString16 tmp; tmp << dotmp; if(msk.field(FR_TIPORIGA).get_long() != 22) { msk.field(FR_JOLLY2).set(tmp); //setto le date di inizio e fine della dotazione temporanea TDate dadata = rcont.get_date(LVRCONDV_INDTTMP); TDate adata = rcont.get_date(LVRCONDV_FIDTTMP); bool fdotmp = false; //disabilito i campi di dotazione temporanea se la causale non prevede la loro movimentazione if (sgn_rit == 0 && sgn_con == 0) { msk.field(FR_JOLLY3).disable(); msk.field(FR_JOLLY4).disable(); } else { msk.field(FR_JOLLY3).enable(); msk.field(FR_JOLLY4).enable(); fdotmp = true; } if (dadata.ok() || fdotmp) { TLocalisamfile rcondv(LF_LVRCONDV); rcondv.put(LVRCONDV_CODCF,codcf); rcondv.put(LVRCONDV_CODCONT,cont.get_int(LVCONDV_CODCONT)); rcondv.put(LVRCONDV_CODART,msk.get(FR_CODART)); if (rdoc.get_date("DADATATMP").empty()) { if (!dadata.ok() && rcondv.read() == NOERR) { rcondv.put(LVRCONDV_INDTTMP, datadoc); rcondv.rewrite(); rdoc.put("DADATATMP", datadoc); msk.field(FR_JOLLY3).set(datadoc); } else { rdoc.put("DADATATMP", dadata); msk.field(FR_JOLLY3).set(dadata); } } if (rdoc.get_date("ADATATMP").empty()) { if (adata.ok() && adata <= datadoc) { rdoc.put("ADATATMP", adata); msk.field(FR_JOLLY4).set(adata); } else { //instanzio in TRecordset sui giri TISAM_recordset giri("USE LVRCONSPLAN KEY 3\nSELECT DTCONS>#DATADOC\nFROM CODCF=#CODCF CODCONT=#CODCONT\nTO CODCF=#CODCF CODCONT=#CODCONT"); giri.set_var("#DATADOC", datadoc); giri.set_var("#CODCF", codcf); giri.set_var("#CODCONT", cont.get_long(LVCONDV_CODCONT)); if (giri.move_first()) { rdoc.put("ADATATMP", giri.get(LVRCONSPLAN_DTCONS).as_date()); msk.field(FR_JOLLY4).set(giri.get(LVRCONSPLAN_DTCONS).as_date()); if (rcondv.read() == NOERR) { rcondv.put(LVRCONDV_FIDTTMP, giri.get(LVRCONSPLAN_DTCONS).as_date()); rcondv.rewrite(); } } } } } } //abilito o disabilito azzerandolo il campo "Ritirato" a seconda di cosa prevede la causale if (cau.is_ritiro()) { msk.field(FR_QTAGG1).enable(true); /*if (codmagcoll.blank()) { codmagcoll = codmagdef; msk.field(FR_CODMAGC).set(codmagcoll); } if (coddepcoll.blank()) { coddepcoll = coddepdef; //magazzino del circolante msk.field(FR_CODDEPC).set(coddepcoll); } */ } else { msk.field(FR_QTAGG1).set(""); msk.field(FR_QTAGG1).disable(); } //abilito o disabilito azzerandolo il campo "Consegnato" a seconda di cosa prevede la causale //ATTENZIONE: questo campo risulta sempre disabilitato se l'articolo è bloccato if (cau.is_consegna() && rcont.get(LVRCONDV_ARTBLOC).empty()) { msk.field(FR_QTA).enable(true); /*if (codmag.blank()) { codmag = codmagdef; msk.field(FR_CODMAG).set(codmag); } if (coddep.blank()) { coddep = coddepdef; msk.field(FR_CODDEP).set(coddep); }*/ } else { msk.field(FR_QTA).set(""); msk.field(FR_QTA).disable(); } } } return true; } //LV_CODMAG_HANDLER: handler che limita l'esecuzione bool TGestione_bolle_msk::lv_codmag_handler(TMask_field& f, KEY k) { bool ok = true; if (f.to_check(k, true)) { TMask& msk = f.mask(); const TString& causale = msk.get(FR_CAULAV); if (causale.full()) { switch(f.dlg()) { case FR_CODMAG: ok = codmag_handler( f, k ); break; default: break; } } } return ok; } bool TGestione_bolle_msk::lv_datatmp_handler(TMask_field& f, KEY k) { if (k == K_ENTER) { TMask& msk = f.mask(); //leggo il codart che ho scritto nella riga corrente dello sheet const TString& codart = msk.get(FR_CODART); const TDate& dadata = msk.get_date(FR_JOLLY3); const TDate& adata = msk.get_date(FR_JOLLY4); TGestione_bolle_msk& dmsk = (TGestione_bolle_msk&) msk.get_sheet()->mask(); //recupero il documento e modifico le date sulla riga documento TDocumento& doc = dmsk.doc(); TRiga_documento& rdoc = doc[msk.get_sheet()->selected()+1]; rdoc.put("DADATATMP", dadata); rdoc.put("ADATATMP", adata); //recupero i dati di interesse dalla testata per poter trovare il contratto const long codcf = dmsk.get_long(F_CODCF); const int indsped = dmsk.get_int(F_CODINDSP); TDate datadoc = dmsk.get_date(F_DATADOC); //trovo il contratto utlizzato e la riga contratto specifica che mi serve const TLaundry_contract cont(codcf, indsped, datadoc); TLocalisamfile rcondv(LF_LVRCONDV); rcondv.put(LVRCONDV_CODCF,codcf); rcondv.put(LVRCONDV_CODCONT,cont.get_int(LVCONDV_CODCONT)); rcondv.put(LVRCONDV_CODART,msk.get(FR_CODART)); if (rcondv.read() == NOERR) { rcondv.put(LVRCONDV_INDTTMP, dadata); rcondv.put(LVRCONDV_FIDTTMP, adata); rcondv.rewrite(); } msk.field(FR_JOLLY3).set_focusdirty(false); msk.field(FR_JOLLY4).set_focusdirty(false); } return true; } //metodo che setta gli handler sui campi di riga void TGestione_bolle_msk::user_set_row_handler(TMask& rm, short field, int index) { switch(index) { case 4101: rm.set_handler(field, lv_ritirato_handler); break; case 4102: rm.set_handler(field, lv_consegnato_handler); break; case 4103: rm.set_handler(field, lv_codart_handler); break; case 4104: rm.set_handler(field, lv_causale_handler); break; case 4105: rm.set_handler(field, lv_codmag_handler); break; case 4106: rm.set_handler(field, lv_datatmp_handler); break; default : TDocumento_mask::user_set_row_handler(rm, field, index); break; } } //metodo che setta l'handler di bolla void TGestione_bolle_msk::user_set_handler( short fieldid, int index) { switch(index) { case 4101: set_field_handler(fieldid, lv_data_handler); break; case 4102: set_field_handler(fieldid, lv_contratto_handler); break; case 4103: set_field_handler(fieldid, lv_bolla_handler); break; case 4105: set_field_handler(fieldid, lv_dataprco_handler); break; default : TDocumento_mask::user_set_handler(fieldid, index); break; } } TGestione_bolle_msk::TGestione_bolle_msk(const char* tipodoc) : TDocumento_mask(tipodoc), _autoselect(-1) { if (ini_get_bool(CONFIG_DITTA, "lv", "Datafissa")) field(F_DATADOC).disable(); sfield(F_SHEET).set_nav_column(FR_QTA, FR_QTAGG1); sfield(F_SHEET).set_auto_append(false); sfield(F_SHEET).set_handler( ss_handler ); sfield(F_SHEET).set_notify( ss_notify ); } ////////////////////////////////////////// //// CLASSE TGESTIONE_BOLLE_APP //// ////////////////////////////////////////// //ridefinisco il metodo get_mask delle TMotore_application TMask* TGestione_bolle_app::get_mask( int mode ) { if (mode == MODE_INS || mode == MODE_MOD) { TString4 tipodoc; if (mode == MODE_MOD) tipodoc = get_relation()->curr().get(DOC_TIPODOC); // Lo prendo dalla relazione (Gelai) else tipodoc = TMotore_application::get_mask(MODE_QUERY)->get(F_TIPODOC); if (_doc_masks.objptr(tipodoc) == NULL) { TGestione_bolle_msk* m = new TGestione_bolle_msk(tipodoc); TSheet_field& sheet = m->sfield(F_SHEET); if (sheet.exist_column(FR_JOLLY1)) { //setto l'allineamento a destra dei campi incriminati e pure criminali sheet.set_column_justify(sheet.cid2index(FR_JOLLY1), true); sheet.set_column_justify(sheet.cid2index(FR_JOLLY2), true); } _doc_masks.add(tipodoc, m); const TTipo_documento& tdoc = m->doc().tipo(); const TString_array& handlers = tdoc.handlers(); FOR_EACH_ARRAY_ROW(handlers, i, row) { m->user_set_handler( row->get_int( 0 ), row->get_int( 1 ) ); } } } return TMotore_application::get_mask(mode); } void TGestione_bolle_app::elimina_vuote( const TMask& m) { TDocumento_mask& mask = (TDocumento_mask&) m; TDocumento& d = mask.doc(); TSheet_field& sheet = mask.sfield(F_SHEET); FOR_EACH_DOC_ROW_BACK(d, r, row) { if (row->is_articolo() && row->get_int(RDOC_QTA) == 0 && row->get_int(RDOC_QTAGG1) == 0) d.destroy_row(r,true); } } void TGestione_bolle_app::salva_conguaglio( const TMask& m) { if (ini_get_bool(CONFIG_DITTA, "lv", "Aggcong")) { TDocumento_mask& mask = (TDocumento_mask&) m; TDocumento& d = mask.doc(); TSheet_field& sheet = mask.sfield(F_SHEET); const long codcf = mask.get_long(F_CODCF); const int indsped = mask.get_int(F_CODINDSP); TDate datadoc = mask.get_date(F_DATADOC); const TLaundry_contract cont(codcf, indsped, datadoc); const int codcont = cont.get_int(LVCONDV_CODCONT); TLocalisamfile rcondv(LF_LVRCONDV); FOR_EACH_DOC_ROW_BACK(d, r, row) { TRiga_documento& rdoc = (TRiga_documento&)*row; rcondv.put(LVRCONDV_CODCF,codcf); rcondv.put(LVRCONDV_CODCONT, codcont); rcondv.put(LVRCONDV_CODART, rdoc.get(RDOC_CODART)); if (rcondv.read() == NOERR) rcondv.put(LVRCONDV_QTACONG, rdoc.get_real(RDOC_QTAGG5)); const real ritat = rdoc.get_real(RDOC_QTAGG1); const real conat = rdoc.get_real(RDOC_QTA); rdoc.put(RDOC_QTAGG4, ritat); rdoc.put(RDOC_QTAGG3, conat); } rcondv.rewrite(); } } void TGestione_bolle_app::date_dotmp( const TMask& m) { TDocumento_mask& mask = (TDocumento_mask&) m; TDocumento& d = mask.doc(); TSheet_field& sheet = mask.sfield(F_SHEET); const long codcf = mask.get_long(F_CODCF); const int indsped = mask.get_int(F_CODINDSP); TDate datadoc = mask.get_date(F_DATADOC); const TLaundry_contract cont(codcf, indsped, datadoc); const int codcont = cont.get_int(LVCONDV_CODCONT); TLocalisamfile rcondv(LF_LVRCONDV); FOR_EACH_DOC_ROW_BACK(d, r, row) { TRiga_documento& rdoc = (TRiga_documento&)*row; if(rdoc.get_date("DADATATMP").ok()) { bool to_write = false; rcondv.put(LVRCONDV_CODCF,codcf); rcondv.put(LVRCONDV_CODCONT, codcont); rcondv.put(LVRCONDV_CODART, rdoc.get(RDOC_CODART)); if (rcondv.read() == NOERR) { const TDate da_data_contr = rcondv.get_date(LVRCONDV_INDTTMP); const TDate da_data_bolla = rdoc.get_date("DADATATMP"); if(da_data_contr > da_data_bolla) { rcondv.put(LVRCONDV_INDTTMP, da_data_bolla); to_write = true; } const TDate a_data_contr = rcondv.get_date(LVRCONDV_FIDTTMP); const TDate a_data_bolla = rdoc.get_date("ADATATMP"); if(a_data_contr < a_data_bolla) { rcondv.put(LVRCONDV_FIDTTMP, a_data_bolla); to_write = true; } if (to_write) rcondv.rewrite(); } } } } //ridefinisco il metodo write delle TMotore_application int TGestione_bolle_app::write( const TMask& m ) { elimina_vuote(m); salva_conguaglio(m); date_dotmp(m); return TMotore_application::write(m); } //ridefinisco il metodo rewrite delle TMotore_application int TGestione_bolle_app::rewrite( const TMask& m ) { elimina_vuote(m); salva_conguaglio(m); date_dotmp(m); return TMotore_application::rewrite(m); } //ridefinisco il metodo read della TMotore_application int TGestione_bolle_app::read(TMask& m) { m.sfield(F_SHEET).destroy(); const int err = TMotore_application::read(m); if (err == NOERR) { TGestione_bolle_msk& mask = (TGestione_bolle_msk&) m; TDocumento& d = mask.doc(); _giac.reset(d); FOR_EACH_DOC_ROW_BACK(d, r, row) { TRiga_documento& rdoc = (TRiga_documento&)*row; _giac.load_row(rdoc, true, true); real dotod = _giac.giac_att(rdoc, true); real dotmp = _giac.giac_att(rdoc, false); } mask.doc2mask(); mask._autoselect = 0; } return err; } //ridefinisco il metodo init_insert_mode della TMotore_application void TGestione_bolle_app::init_insert_mode(TMask &m) { TGestione_bolle_msk& mask = (TGestione_bolle_msk&) m; TDocumento& d = mask.doc(); _giac.reset(d); //se sto leggendo o generando un buono di ritiro, abilito questo campo bool enable_dataprco = mask.get(F_CODNUM) == ini_get_string(CONFIG_DITTA, "lv", "NUM_RIT(0)") && mask.get(F_TIPODOC) == ini_get_string(CONFIG_DITTA, "lv", "TIPODOC_RIT(0)"); mask.field(F_LVDATAPRCO).enable(enable_dataprco); mask.reset_var_mask(); mask.first_focus(F_CODCF, false); return TMotore_application::init_insert_mode(m); } //ridefinisco il metodo init_query_mode della TMotore_application void TGestione_bolle_app::init_modify_mode(TMask &m) { TGestione_bolle_msk& mask = (TGestione_bolle_msk&) m; //se sto leggendo o generando un buono di ritiro, abilito questo campo bool enable_dataprco = mask.get(F_CODNUM) == ini_get_string(CONFIG_DITTA, "lv", "NUM_RIT(0)") && mask.get(F_TIPODOC) == ini_get_string(CONFIG_DITTA, "lv", "TIPODOC_RIT(0)"); mask.field(F_LVDATAPRCO).enable(enable_dataprco); mask.first_focus(F_CODCF, false); return TMotore_application::init_modify_mode(m); } //metodo che mi restituisce la giac TGiac_per_cli& TGestione_bolle_app::giacenza() { return _giac; } int lv3100( int argc, char* argv[]) { TGestione_bolle_app a; a.run( argc, argv, TR("Documenti di Trasporto")); return 0; }