#include "../ve/ve0100.h" #include "../ve/veini.h" #include "../ve/veuml.h" #include "../ve/verig.h" #include "../ve/vepriv.h" #include "lv0.h" #include "lvlib.h" #include "lvcondv.h" #include "lvrcondv.h" #include "../mg/clifogiac.h" //////////////////////////////////// //// CLASSE TGIAC_PER_CLI //// //////////////////////////////////// //Definizione della classe Giacenza per Cliente class TGiac_per_cli : public TObject { private: TAssoc_array _odierna; //TAssoc_array che conterrà le dotazioni odierne TAssoc_array _temporanea; //TAssoc_array che conterrà le dotazioni temporanee long _clifo; //variabile che conterrà il cliente selezionato long _cont; //variabile che conterrà il contratto selezionato int _year; //variabile che conterrà l'anno documento long _indsped; //variabile che conterrà l'indirizzo di spedizione protected: real& giacart_od(const TString& codart); //restituisce un puntatore al valore della dot. od. salvato real& giacart_tmp(const TString& codart); //restituisce un puntatore al valore valore della dot. temp. salvato long giac_in_mag(const TString& codart, bool odierna) const; //restituisce il valore salvato nel magazzino public: bool reset(const TDocumento& doc); //svuota i TAssoc_array e carica cli e cont bool load_row(const TRiga_documento& rdoc); //popola i TAssoc_array real giac_att(TRiga_documento& rdoc, bool odierna); //restituisce le quantità attuali di dotazione TGiac_per_cli(); //costruttore }; //GIACART_OD: metodo che restituisce un puntatore al real che contiene il valore //della dotazione odierna per un determinato articolo real& TGiac_per_cli::giacart_od(const TString& codart) { real *giac = (real*)_odierna.objptr(codart); if (giac == NULL) { giac = new real(giac_in_mag(codart, true)); _odierna.add(codart,giac); } return *giac; }; //GIACART_TMP: metodo che restituisce un puntatore al real che contiene il valore //della dotazione temporanea per un determinato articolo real& TGiac_per_cli::giacart_tmp(const TString& codart) { real *giac = (real*)_temporanea.objptr(codart); if (giac == NULL) { giac = new real(giac_in_mag(codart, false)); _temporanea.add(codart,giac); } return *giac; }; //GIAC_IN_MAG: questo metodo restituisce le quantità presenti sul file 166 (clifogiac) //restituendo il valore salvato in dotazione odierna se odierna == true, //oppure il valore salvato in dotazione temporanea se odierna = false long TGiac_per_cli::giac_in_mag(const TString& codart, bool odierna) const { //recupero i valori delle dotazioni odierne e temporanee dal magazzino del cliente TLocalisamfile magcli(LF_CLIFOGIAC); magcli.put(CLIFOGIAC_ANNOES, _year); magcli.put(CLIFOGIAC_TIPOCF, 'C'); magcli.put(CLIFOGIAC_CODCF, _clifo); magcli.put(CLIFOGIAC_INDSPED, _indsped); magcli.put(CLIFOGIAC_CODART, codart); //leggo il record corrispondente if (magcli.read() == NOERR) return magcli.get_long( odierna ? CLIFOGIAC_DOTOD : CLIFOGIAC_DOTTM); return 0; } //RESET: metodo che distrugge i due TAssoc_array e carica la coppia cliente - contratto bool TGiac_per_cli::reset(const TDocumento& doc) { //estraggo i dati di interesse dal documento _clifo = doc.get_long(DOC_CODCF); _cont = doc.get_long(DOC_CODCONT); _year = doc.get_date(DOC_DATADOC).year(); _indsped = doc.get_long(DOC_CODINDSP); //distruggo i due TAssoc_array _odierna.destroy(); _temporanea.destroy(); return true; } //LOAD_ROW: questo metodo popola e aggiorna i TAssoc_array bool TGiac_per_cli::load_row(const TRiga_documento& rdoc) { //recupero il documento e la sua maschera a partire dalla riga documento const TDocumento& doc = rdoc.doc(); real vardot; real vartmp; //se sul documento leggo o il cliente o il contratto o l'indirizzo di spedizione //diversi da quelli che avevo salvato vuol dire che ho cambiato uno dei due, //e quindi le giacenze non vanno più bene; in tal caso resetto i TAssoc_array e riparto if (doc.get_long(DOC_CODCF) != _clifo || doc.get_long(DOC_CODCONT) != _cont || doc.get_long(DOC_CODINDSP) != _indsped) reset(doc); real& dotazione = giacart_od(rdoc.get(RDOC_CODART)); real& dotmp = giacart_tmp(rdoc.get(RDOC_CODART)); //instanzio una cache sulla tabella delle causali TString4 causale = rdoc.get(RDOC_CODAGG1); const TRectype& cau = cache().get("&CAU", causale); //movimento o meno la dotazione temporanea a seconda di cosa prevede la causale if (cau.get_bool("B0")) { const TCausale_magazzino & rit = cached_causale_magazzino(cau.get("S1")); const real & ritirato = rdoc.get_real(RDOC_QTAGG1); int st = rit.sgn(s_dottm); int so = rit.sgn(s_dotod); vartmp += real(st) * ritirato; vardot += real(so) * ritirato; } if (cau.get_bool("B1")) { const TCausale_magazzino & con = cached_causale_magazzino(cau.get("S2")); const real & consegnato = rdoc.get_real(RDOC_QTA); int st = con.sgn(s_dottm); int so = con.sgn(s_dotod); vartmp += real(st) * consegnato; vardot += real(so) * consegnato; } if (rdoc.get_int(RDOC_MOVMAG) != ZERO) { dotmp -= vartmp; dotazione -= vardot; } return true; } //GIAC_ATT: questo metodo restituisce il valore della dotazione da scrivere a video in base ai valori //di consegnato e ritirato; ATTENZIONE: restituisce la dotazione odierna se odierna = true, //restituisce la dotazione temporanea se odierna = false real TGiac_per_cli::giac_att(TRiga_documento& rdoc, bool odierna) { const TString& codart = rdoc.get(RDOC_CODART); real giac = odierna ? giacart_od(codart) : giacart_tmp(codart); real saldo; //instanzio una cache sulla tabella delle causali TString4 causale = rdoc.get(RDOC_CODAGG1); const TRectype& cau = cache().get("&CAU", causale); //movimento o meno la dotazione temporanea/odierna a seconda di cosa prevede la causale if (cau.get_bool("B0")) { const TCausale_magazzino & rit = cached_causale_magazzino(cau.get("S1")); const int s = rit.sgn(odierna ? s_dotod : s_dottm); saldo += real(s) * rdoc.get_real(RDOC_QTAGG1); } if (cau.get_bool("B1")) { const TCausale_magazzino & con = cached_causale_magazzino(cau.get("S2")); const int s = con.sgn(odierna ? s_dotod : s_dottm); saldo += real(s) * rdoc.get_real(RDOC_QTA); } giac += saldo; return giac; } //costruttore TGiac_per_cli::TGiac_per_cli() { _clifo = 0; _cont = 0; _year = 0; _indsped = 0; } ////////////////////////////////////////// //// 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 ); public: TGiac_per_cli& giacenza(); TGestione_bolle_app() {} }; inline TGestione_bolle_app& gbapp() { return (TGestione_bolle_app &)main_app(); }; ////////////////////////////////////////// //// CLASSE TGESTIONE_BOLLE_MSK //// ////////////////////////////////////////// //Definizione della classe della maschera class TGestione_bolle_msk : public TDocumento_mask { long _stcodcf; long _stcodcont; int _autoselect; TToken_string _rigaoriginale; protected: static void arrotonda(const TMask& msk, real& quantita); //hanlder di documento: 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); 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;} TGestione_bolle_msk(const char* tipodoc); }; //ARROTONDA: metodo che arrotonda la quantità che gli passo se è previsto sul contratto void TGestione_bolle_msk::arrotonda(const TMask& msk, real& quantita) { TConfig* configlv = new TConfig(CONFIG_DITTA,"lv"); int perarr = configlv->get_int("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_bool(LVRCONDV_ARROT)) { //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; } } } //////////////////////////// // HANDLER DI DOCUMENTO // //////////////////////////// void TGestione_bolle_msk:: on_idle() { TDocumento_mask::on_idle(); if (_autoselect >= 0) { TSheet_field& s = sfield(F_SHEET); //per ora 4 fisso perchè non sappiamo calcolare la colonna del ritirato s.set_focus_cell(_autoselect,4); _autoselect = -1; } } //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; case F_DATADOC: ok = data_hndl( f, k ); break; default: break; } TGestione_bolle_msk& dmsk = (TGestione_bolle_msk&)f.mask(); TDate oggi(TODAY); if (!dmsk.field(F_DATADOC).enabled() && dmsk.insert_mode()) dmsk.set(F_DATADOC,oggi); TSheet_field& sheet = dmsk.sfield(F_SHEET); if (ok && k == K_TAB && ((dmsk.insert_mode() && f.to_check(k, true)) || f.focusdirty())) { f.set_focusdirty(false); TDocumento& doc = dmsk.doc(); 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; } 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); //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) { TConfig* configlv = new TConfig(CONFIG_DITTA,"lv"); causale = configlv->get("CAUSLAV"); } //instanzio una cache sulle anagrafice di magazzino const TRectype& anamag = cache().get(LF_ANAMAG,codart); 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,rcont.get(LVRCONDV_UM).as_string()); rdoc.put(RDOC_CODAGG1,causale); rdoc.put(RDOC_CODIVA,anamag.get(ANAMAG_CODIVA)); //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); 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) && !f.empty()) { TMask& msk = f.mask(); real ritirato = f.get(); TSheet_field* sheet = msk.get_sheet(); TDocumento_mask& dmask = (TDocumento_mask&)sheet->mask(); TRiga_documento& rdoc = dmask.doc()[sheet->selected()+1]; rdoc.put(RDOC_QTAGG1,ritirato); if (msk.field(FR_QTA).enabled() && msk.field(FR_QTA).empty()) { 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(); real dotod = giac.giac_att(rdoc, true); real dotmp = giac.giac_att(rdoc, false); msk.set(FR_JOLLY1, dotod); msk.set(FR_JOLLY2, 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(); 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); real dotmp = giac.giac_att(rdoc, false); msk.set(FR_JOLLY1, dotod); msk.set(FR_JOLLY2, 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)) { 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(); //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); 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 ) { TConfig* configlv = new TConfig(CONFIG_DITTA,"lv"); causale = configlv->get("CAUSLAV"); } msk.set(FR_CODAGG1, causale); if (k == K_ENTER && rcont.get_bool(LVRCONDV_ARROT)) { 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); if (ritor != ritat || conor != conat) { const real congor = rcont.get_real(LVRCONDV_QTACONG); const real congat = conat - ritat + congor; rdoc.put(RDOC_QTAGG5, congat); //conguaglio dopo modifica manuale TLocalisamfile rcondv(LF_LVRCONDV); rcondv.put(LVRCONDV_CODCF,codcf); rcondv.put(LVRCONDV_CODCONT,cont.get_int(LVCONDV_CODCONT)); rcondv.put(LVRCONDV_CODART,codart); if (rcondv.read() == NOERR) { rcondv.put(LVRCONDV_QTACONG,congat); rcondv.rewrite(); } } } //controllo se si vuole aggiungere un eventuale nuovo articolo al contratto if (rcont.empty() && yesno_box(TR("L'articolo in esame non fa parte della dotazione standard di questo cliente." "Si desidera aggiungerla ai contratti?"))) cont.edit(); } } 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); //recupero i dati di interesse dalla testata per poter trovare il contratto TDocumento_mask& dmsk = (TDocumento_mask&) msk.get_sheet()->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; //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); //instanzio una cache sulla tabella delle causali const TRectype& cau = cache().get("&CAU", causale); //abilito o disabilito azzerandolo il campo "Ritirato" a seconda di cosa prevede la causale if (cau.get_bool("B0")) msk.field(FR_QTAGG1).enable(true); else { msk.field(FR_QTAGG1).set((long)0); 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.get_bool("B1") && rcont.get(LVRCONDV_ARTBLOC).empty()) msk.field(FR_QTA).enable(true); else { msk.field(FR_QTA).set((long)0); msk.field(FR_QTA).disable(); } } } 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; 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_bolla_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) { TConfig* configlv = new TConfig(CONFIG_DITTA,"lv"); char dtfs = configlv->get_char("Datafissa"); if (dtfs == 'X') field(F_DATADOC).disable(); sfield(F_SHEET).set_nav_column(FR_QTA, FR_QTAGG1); sfield(F_SHEET).set_auto_append(); } ////////////////////////////////////////// //// 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); _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); } #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--) //ridefinisco il metodo write delle TMotore_application int TGestione_bolle_app::write( const TMask& m ) { TDocumento_mask& mask = (TDocumento_mask&) m; TDocumento& d = mask.doc(); FOR_EACH_DOC_ROW_BACK(d, r, row) { if (row->get_int(RDOC_QTA) == 0 && row->get_int(RDOC_QTAGG1) == 0) d.destroy_row(r,true); } return TMotore_application::write(m); } //ridefinisco il metodo rewrite delle TMotore_application int TGestione_bolle_app::rewrite( const TMask& m ) { TDocumento_mask& mask = (TDocumento_mask&) m; TDocumento& d = mask.doc(); FOR_EACH_DOC_ROW_BACK(d, r, row) { if (row->get_int(RDOC_QTA) == 0 && row->get_int(RDOC_QTAGG1) == 0) d.destroy_row(r,true); } return TMotore_application::rewrite(m); } //ridefinisco il metodo read della TMotore_application int TGestione_bolle_app::read(TMask& m) { const int err = TMotore_application::read(m); TDocumento_mask& mask = (TDocumento_mask&) m; TDocumento& d = mask.doc(); _giac.reset(d); FOR_EACH_DOC_ROW_BACK(d, r, row) _giac.load_row((TRiga_documento&)*row); 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); mask.reset_var_mask(); return TMotore_application::init_insert_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; }