#include #include #include #include #include #include #include #include #include "lvlib.h" #include "../mg/clifogiac.h" #include "../ve/velib.h" #include "clifo.h" #include "lvcondv.h" #include "lvrcondv.h" #include "lvrconsplan.h" #include "lv3400a.h" ////////////////////////////// //// TQUANTITA_RIGA //// ////////////////////////////// //Classe TQuantita_riga class TQuantita_riga: public TObject { int _nriga; bool _evaso; real _qtarit; real _qtadacon; real _qtacon; int _pacchi; public: int get_nriga() const; bool get_evaso() const; real get_qta_rit() const; real get_qta_da_con() const; real get_qta_con() const; int get_pacchi() const; void set_nriga(const int nriga); void set_evaso(const bool evaso); void set_qta_rit(const real qta); void set_qta_da_con(const real qta); void set_qta_con(const real qta); void set_pacchi(const int pacchi); void add_qta_con(const real qta); void add_pacchi(const int pacchi = 1); TQuantita_riga(bool evaso = false, long qtadc = 0, long qtac = 0, int pacchi = 0); }; //GET_NRIGA: metodo che restituisce il numero di riga int TQuantita_riga::get_nriga() const { return _nriga; } //GET_EVASO: metodo che restituisce il booleano evaso bool TQuantita_riga::get_evaso() const { return _evaso; } //GET_QTA_RIT: metodo che restituisce la qunatita ritirata real TQuantita_riga::get_qta_rit() const { return _qtarit; } //GET_QTA_DA_CON: metodo che restituisce la quantità da consegnare real TQuantita_riga::get_qta_da_con() const { return _qtadacon; } //GET_QTA_CON: metodo che restituisce la quantità consegnata real TQuantita_riga::get_qta_con() const { return _qtacon; } //GET_PACCHI: metodo che restituisce il humero dei pacchi consegnati int TQuantita_riga::get_pacchi() const { return _pacchi; } //SET_NRIGA: metodo che setta il numero di riga void TQuantita_riga::set_nriga(const int nriga) { _nriga = nriga; } //SET_EVASO: metodo che setta il booleano evaso void TQuantita_riga::set_evaso(const bool evaso) { _evaso = evaso; } //SET_QTA_RIT: metodo che setta la quantità ritirata void TQuantita_riga::set_qta_rit(const real qta) { _qtarit = qta; } //SET_QTA_DA_CON: metodo che setta la quantità da consegnare void TQuantita_riga::set_qta_da_con(const real qta) { _qtadacon = qta; } //SET_QTA_CON: metodo che setta la quantità consegnata void TQuantita_riga::set_qta_con(const real qta) { _qtacon = qta; } //SET_PACCHI: metodo che setta il hnumero di pacchi consegnato void TQuantita_riga::set_pacchi(const int pacchi) { _pacchi = pacchi; } //ADD_QTA_CON: metodo che aggiunge un quantitativo di roba alla quantità consegnata void TQuantita_riga::add_qta_con(const real qta) { _qtacon += qta; } //ADD_PACCHI: metodo che aggiunge un certo numero di pacchi a quelli consegnati (default = 1) void TQuantita_riga::add_pacchi(const int pacchi) { _pacchi += pacchi; } //metodo costruttore TQuantita_riga::TQuantita_riga(bool evaso, long qtadc, long qtac, int pacchi) { set_evaso(evaso); set_qta_da_con(qtadc); set_qta_con(qtac); set_pacchi(pacchi); } //////////////////////////// //// TRIGHE_ARRAY //// //////////////////////////// //Classe TRighe_array class TRighe_array: public TAssoc_array { public: TQuantita_riga* quantita(TString& codart, TDate& data, TString& cau, bool create); }; //QUANTITA: metodo che cerca nel TAssoc_array le quantità della riga interessata in base ai parametri passati //e lo crea in automatico se il parametro create vale "true" TQuantita_riga* TRighe_array::quantita(TString& codart, TDate& data, TString& cau, bool create) { TToken_string key; key.add(codart); key.add(data); key.add(cau); TQuantita_riga* qr = (TQuantita_riga*)objptr(key); if(qr == NULL && create) { qr = new TQuantita_riga(); add(key, qr); } return qr; } ///////////////////////////////// //// TEVASIONE_TER_MSK //// ///////////////////////////////// //Classe TEvasione_ter_msk class TEvasione_ter_msk: public TAutomask { int _autoselect; TString4 _tpev; TAssoc_array _pacchi; TRighe_array _ra; protected: void campi_cliente(); bool precarica_righe(); void genera_buono(); void evadi(); void registra(); void riempi_sheet(); int arrotonda(int quantita); void spezza_riga(); bool controlla(); void evadi_da_terminale(); virtual void on_idle(); virtual bool on_key(KEY key); virtual bool on_field_event(TOperable_field& o, TField_event e, long jolly); public: TEvasione_ter_msk(); }; //ON_KEY: metodo che gestisce i tatsi funzione bool TEvasione_ter_msk::on_key(KEY key) { if (key >= K_F3 && key <= K_F7) { FOR_EACH_MASK_FIELD(*this, i, f) { if (f->is_kind_of(CLASS_BUTTON_TOOL) && f->active()) { TButton_tool& tf = (TButton_tool&)*f; if (tf.exit_key() == key) { send_key(K_SPACE, f->dlg()); return true; } } } } return TAutomask::on_key(key); } //PRECARICA_RIGHE: metodo che carica in un TAssoc_array le righe fisiche del documento bool TEvasione_ter_msk::precarica_righe() { TDoc_key kdoc(get_int(F_TANNO), ini_get_string(CONFIG_DITTA, "lv", "NUM_PRE", NULL, 0), get_long(F_TNDOC)); TBuono_prelievo doc(kdoc); if (doc.empty()) { warning_box(TR("Il documento cercato è inesistente")); return false; } TLocalisamfile fdoc(LF_DOC); int err = doc.read(fdoc, _isequal, _testandlock); if(err != NOERR) { warning_box(TR("Il documento è già in uso")); return false; } const TString4 stato = cache().get("%TIP", ini_get_string(CONFIG_DITTA, "lv", "TIPODOC_PRE", NULL, 0), "S2").mid(2,1); if (doc.get(DOC_STATO) == stato) { TString str; str << "Il documento " << get_long(F_TNDOC) << " è già stato evaso"; warning_box(str); reset(F_TCHIAVE); return false; } TDate oggi(TODAY); FOR_EACH_PHYSICAL_RDOC(doc, i, row) { TBuono_prelievo_row rdoc(*row); TString80 codart = rdoc.codart(); if (codart.blank()) continue; if (rdoc.qta_dacons() > 0) { TString4 cau = rdoc.causale(); TQuantita_riga* qr = _ra.quantita(codart, oggi, cau, true); qr->set_nriga(i); qr->set_evaso(rdoc.evaso()); qr->set_qta_rit(rdoc.qta_ritirata()); qr->set_qta_da_con(rdoc.qta_dacons()); qr->set_qta_con(rdoc.qta_consegnata()); qr->set_pacchi(rdoc.num_pacchi()); } else rdoc.set_evaso(true); } return true; } //GENERA_BUONO: metodo che genera il buono di consegna partendo dal buono di ritiro void TEvasione_ter_msk::genera_buono() { //per prima cosa salva il buono di prelievo registra(); TDoc_key kdoc(get_date(F_TDATADOC).year(), ini_get_string(CONFIG_DITTA, "lv", "NUM_PRE", NULL, 0), get_long(F_TNDOC)); TBuono_prelievo bpre(kdoc); const long codcf = bpre.codcf(); const int codcont = bpre.codcont(); TLaundry_contract cont(codcf, codcont); //leggo se devo scrivere il prezzo sulla bolla //const bool prinbo = cont.get_bool(LVCONDV_STPRZBOL); const bool prinbo = true; //sempre a true; verrà gestita a video in futuro (27/10/2009) //dati documento da generare TString4 codnum = ini_get_string(CONFIG_DITTA, "lv", "NUM_GEN"); TString4 tipodoc = ini_get_string(CONFIG_DITTA, "lv", "TIPODOC_GEN"); char stato = cache().get("%TIP", tipodoc, "S2").left(1)[0]; const TDate databpre = bpre.datadoc(); const TDate databolla = get_date(F_TDATADOC); const TDate datagen(TODAY); TDate dadata = databpre; TDate adata = datagen; if(ini_get_bool(CONFIG_DITTA, "lv", "DataBcon")) dadata = databolla; adata.addmonth(); //recupero i dati di interesse dal planning TString query1 = "USE LVRCONSPLAN KEY 3\n"; query1 << "FROM CODCF=" << codcf << " CODCONT=" << codcont << " DTCONS=#DADATA\n"; query1 << "TO CODCF=" << codcf << " CODCONT=" << codcont << " DTCONS=#ADATA\n"; TISAM_recordset consegne(query1); consegne.set_var("#DADATA", ++dadata); consegne.set_var("#ADATA", adata); consegne.move_first(); const TDate dataprco = consegne.get(LVRCONSPLAN_DTCONS).as_date(); const int coditi = consegne.get(LVRCONSPLAN_CODITI).as_int(); TString8 codaut = consegne.get(LVRCONSPLAN_CODAUT).as_string().right(5); codaut.trim(); //recupero il codpag e i codici banca TToken_string key; key.add('C'); key.add(codcf); const TRectype& clifo = cache().get(LF_CLIFO, key); const TString4 codpag = clifo.get(CLI_CODPAG); const long codabi = clifo.get_long(CLI_CODABI); const long codcab = clifo.get_long(CLI_CODCAB);const TString80 iban = clifo.get(CLI_IBAN); //reupero la cuasale di magazzino di testata const TString8 causmag = cache().get("%TIP", tipodoc, "S9"); //recupero i dati di interesse dal file CFVEN const TRectype& cfven = cache().get(LF_CFVEN, key); const long codabipr = cfven.get_long(CFV_CODABIPR); const long codcabpr = cfven.get_long(CFV_CODCABPR); const bool ragdoc = cfven.get_bool(CFV_RAGGDOC); const int codindsp = cfven.get_int(CFV_CODINDSP); const TString8 codag1 = cfven.get(CFV_CODAG1); const TString4 codmez = cfven.get(CFV_CODSPMEZZO); const TString4 codporto = cfven.get(CFV_CODPORTO); const TString4 codnote1 = cfven.get(CFV_CODNOTESP1); const TString4 codnote2 = cfven.get(CFV_CODNOTESP2); const TString4 codnote = cfven.get(CFV_CODNOTE); const TString8 codvet1 = cfven.get(CFV_CODVETT1); const TString8 codvet2 = cfven.get(CFV_CODVETT2); const TString8 codvet3 = cfven.get(CFV_CODVETT3); const real speseinc = cfven.get_real(CFV_PERCSPINC); const TString4 catven = cfven.get(CFV_CATVEN); const bool addbolli = cfven.get_bool(CFV_ADDBOLLI); const TString8 codlist = cfven.get(CFV_CODLIST); const TString4 codzona = cfven.get(CFV_CODZONA); if(codaut.empty()) codaut = cfven.get(CFV_CODAG); //gestione sconto TString sconto; const char tpgest = ini_get_string(CONFIG_DITTA, "ve", "GESSCO")[0]; switch(tpgest) { case 'P': sconto = cfven.get(CFV_SCONTO); break; //Percentuale su anagrafica cliente case 'T': sconto = cache().get("%SCC", cfven.get(CFV_CODSCC), "S1"); break; //Gestione tabella sconti case 'A': //Gestione archivio sconti { TConfig ditta(CONFIG_DITTA, "ve"); TLocalisamfile sconti(LF_SCONTI); sconti.put("TIPO", "I"); if(ditta.get_bool("SCOKEY", "ve", 1)) sconti.put("CODCAT", cfven.get(CFV_CATVEN)); TString16 cod; if(ditta.get_bool("SCOKEY", "ve", 2)) cod.format("%-2s", (const char*)cfven.get(CFV_CODSCC)); else cod = " "; if(ditta.get_bool("SCOKEY", "ve", 3)) { TString8 tmp; tmp.format("%-2s", (const char*)cfven.get(CFV_CODZONA)); cod << tmp; } else cod << " "; if(ditta.get_bool("SCOKEY", "ve", 4)) cod << clifo.get(CLI_CODPAG); sconti.put("CODART", cod); if (sconti.read() == NOERR) sconto = sconti.get("SCONTO"); } case 'N': //sconto non gestito default: break; } //preparo la testata del documento TDocumento doc('D', kdoc.anno(), codnum, 0); doc.put(DOC_TIPODOC, tipodoc); doc.put(DOC_STATO, stato); if(ini_get_bool(CONFIG_DITTA, "lv", "DataBcon")) { doc.put(DOC_DATADOC, datagen); doc.put(DOC_DATAPART, databolla); } else doc.put(DOC_DATADOC, databolla); doc.put(DOC_TIPOCF, 'C'); doc.put(DOC_CODCF, codcf); doc.put(DOC_CODCONT, codcont); if(codindsp > 0) doc.put(DOC_CODINDSP, codindsp); doc.put(DOC_CODPAG, codpag); doc.put(DOC_CODABIA, codabi); doc.put(DOC_CODCABA, codcab); doc.put(DOC_IBAN, iban); doc.put(DOC_CODABIP, codabipr); doc.put(DOC_CODCABP, codcabpr); doc.put(DOC_CODAG, codaut); doc.put(DOC_CODAGVIS, codag1); doc.put(DOC_CODSPMEZZO, codmez); doc.put(DOC_ZONA, codzona); doc.put(DOC_CODPORTO, codporto); doc.put(DOC_CODNOTESP1, codnote1); doc.put(DOC_CODNOTESP2, codnote2); doc.put(DOC_CODNOTE, codnote); doc.put(DOC_CODVETT1, codvet1); doc.put(DOC_CODVETT2, codvet2); doc.put(DOC_CODVETT3, codvet3); doc.put(DOC_CATVEN, catven); doc.put(DOC_CODLIST, codlist); doc.put(DOC_CAUSMAG, causmag); doc.put(DOC_PERCSPINC, speseinc); doc.put(DOC_ADDBOLLI, addbolli); doc.put(DOC_SCONTOPERC, sconto); doc.put("DATAGEN", datagen); //data generazione del documento doc.put("DATAPRCO", dataprco); //data prevista consegna doc.put("CODITI", coditi); //codice itinerario for (int i = 1; i <= bpre.rows(); i++) { TRiga_documento& row = bpre[i]; TBuono_prelievo_row rbpre(row); //nella bolla ci vanno solo le righe evase e non associate if (!rbpre.evaso()) continue; TDoc_key kbuono = rbpre.rifbcon(); if (kbuono.full()) continue; const TString80 codart = rbpre.codart(); TString descr = rbpre.desart(); const TRectype& rcont = cont.row(codart); //recupero i valori delle dotazione temporanea dal magazzino del cliente TArticolo_lavanderie& artrec = cached_article_laundry(codart, 'C', codcf, 0); //fisso l'anno esercizio TEsercizi_contabili& esc = esercizi(); const int last_esc = esc.last(); //estraggo il record corrispondente su LF_CLIFOGIAC const TRecmag_lavanderie& reclav = artrec.find_rec(last_esc); real dotod = reclav.get_real(CLIFOGIAC_DOTOD); real dottmp = reclav.get_real(CLIFOGIAC_DOTTM); //recupero l'unità di misura principale di quest'articolo TToken_string key; key.add(codart); key.add(1); const TString4 um = cache().get(LF_UMART, key, UMART_UM); //creo la nuova riga documento TRiga_documento& rdoc = doc.new_row("21"); TDocumento::copy_data(rdoc, row); rdoc.put(RDOC_CODART, codart); rdoc.put(RDOC_CODARTMAG,codart); rdoc.put(RDOC_CHECKED,'X'); rdoc.put(RDOC_GENERATA, true); if(descr.len() <= 50) rdoc.put(RDOC_DESCR, descr); else { rdoc.put(RDOC_DESCR, descr.left(50)); rdoc.put(RDOC_DESCEST, descr.sub(50)); rdoc.put(RDOC_DESCLUNGA, true); } rdoc.put(RDOC_QTA, rbpre.qta_consegnata()); //consegnato rdoc.put(RDOC_QTAGG1, rbpre.qta_ritirata()); //ritirato dotod += (rbpre.qta_consegnata() - rbpre.qta_ritirata()); rdoc.put("DOTOD", dotod); const bool dtmp = datagen >= rcont.get_date(LVRCONDV_INDTTMP) && datagen <= rcont.get_date(LVRCONDV_FIDTTMP); if (dtmp) { rdoc.put("DOTMP", dottmp); rdoc.add("DOTMP", rbpre.qta_consegnata() - rbpre.qta_ritirata()); } const TCausale_lavanderie cau(rbpre.causale()); rdoc.put(RDOC_CODAGG1, cau.codice()); const TRectype& anamag = cache().get(LF_ANAMAG, codart); //gestione prezzo if (prinbo) { real prezzo; if (cont.get_int(LVCONDV_TIPOLIS) == 0) prezzo = rcont.get_real(LVRCONDV_PREZZO); else prezzo = anamag.get_real(ANAMAG_COSTSTD); rdoc.put(RDOC_PREZZO, prezzo); rdoc.put(RDOC_SCONTO, rcont.get(LVRCONDV_SCONTPERC)); //sconto } rdoc.put(RDOC_UMQTA, um); rdoc.put(RDOC_CODIVA, anamag.get(ANAMAG_CODIVA)); //scrivo il magazzino TCausale_magazzino rit(cau.causale_ritiro()); TCausale_magazzino con(cau.causale_consegna()); TString8 magazzino, 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); // Aggiorna conguaglio 28/05/2012 const real diff = rbpre.qta_consegnata() - rbpre.qta_dacons(); if (!diff.is_zero() && ini_get_bool(CONFIG_DITTA, "lv", "Aggcong")) { TLocalisamfile lvrcondv(LF_LVRCONDV); TRectype& rcondv = (TRectype&)rcont; rcondv.add(LVRCONDV_QTACONG, diff); rcondv.rewrite(lvrcondv); } } //salva la bolla solo se ha almeno una riga int err = 1; if (doc.rows() > 0) { TToken_string orderkey; orderkey.add(RDOC_CODART); doc.sort_rows(orderkey); err = doc.write(); for (int i = 1; i <= bpre.rows(); i++) { TRiga_documento& row = bpre[i]; TBuono_prelievo_row rbpre(row); //nella bolla ci vanno solo le righe evase e non associate if (!rbpre.evaso()) continue; TDoc_key kbuono = rbpre.rifbcon(); if (kbuono.full()) continue; //salvo i riferimenti TDoc_key rifbcon(datagen.year(), codnum, doc.get_long(DOC_NDOC)); rbpre.set_rifbcon(rifbcon); } if (controlla()) { const TString4 stato = cache().get("%TIP", ini_get_string(CONFIG_DITTA, "lv", "TIPODOC_PRE", NULL, 0), "S2").mid(2,1); bpre.put(DOC_STATO, stato); } bpre.rewrite(); } if (err == NOERR && yesno_box(TR("Il buono di consegna è stato generato correttamente; si desidera stamparlo?"))) { //stampa automatica TFilename tmp; tmp.temp("", "ini"); // Ensure that the ofstream is well closed before ve1 call if (tmp.full()) // dummy test { ofstream outf(tmp); outf << "[Transaction]" << endl; // Transaction header outf << "Action=S" << endl; // 'S'tampa o 'A'nteprima outf << "Mode=D" << endl; // Definitive (always?) outf << "NoPrintDlg=X" << endl; // Dont' prompt the user with the print dialog outf << endl; outf << "[33]" << endl; // Transaction body outf << "Doc(0)="; outf << "D|" << datagen.year() << '|' << codnum << '|' << doc.get_long(DOC_NDOC) << endl; } if (tmp.exist()) { TString cmdline; cmdline << "ve1 -2 -i" << tmp; TExternal_app app(cmdline); app.run(); tmp.fremove(); } } else warning_box(TR("Non è stato possibile generare nessun documento")); //riazzero ndoc set(F_TNDOC, 0L, 1); //nascondo i campi che non mi servono reset(F_TCODCF); hide(F_TCODCF); reset(F_TRAGSOC); hide(F_TRAGSOC); reset(F_TBARCODE); hide(F_TBARCODE); reset(F_TPACCHI); hide(F_TPACCHI); reset(F_TQTAPACCO); hide(F_TQTAPACCO); reset(F_TQTACON); hide(F_TQTACON); reset(F_TQTADACON); hide(F_TQTADACON); reset(F_CODART); hide(F_CODART); //mostro i campi che servono per la selezione del documento show(F_TCODNUM); show(F_TTPDOC); show(F_TDESCR); show(F_TCHIAVE); reset(F_TCHIAVE); show(F_TANNO); show(F_TDATAPRCO); //disabilito i bottoni disable(DLG_SELECT); disable(DLG_PREVIEW); disable(DLG_ELABORA); disable(DLG_SAVEREC); disable(DLG_CANCEL); enable(F_TNDOC); } //EVADI: metodo che setta a evaso tutte le righe del documento void TEvasione_ter_msk::evadi() { FOR_EACH_ASSOC_OBJECT(_ra, obj, key, itm) { TQuantita_riga* qr = (TQuantita_riga*)itm; qr->set_evaso(true); } } //REGISTRA: metodo che salva il buono di prelievo così com'è void TEvasione_ter_msk::registra() { TDoc_key kdoc(get_date(F_TDATADOC).year(), ini_get_string(CONFIG_DITTA, "lv", "NUM_PRE", NULL, 0), get_long(F_TNDOC)); TBuono_prelievo doc(kdoc); TDate oggi(TODAY); FOR_EACH_ASSOC_OBJECT(_ra, obj, key, itm) { TQuantita_riga* qr = (TQuantita_riga*)itm; int nriga = qr->get_nriga(); //se nriga > 0 vuol dire che si è aggiornata una riga già esistente; //altrimenti significa che ho spezzato una riga if (nriga > 0) { TRiga_documento& row = doc[nriga]; TBuono_prelievo_row rdoc(row); rdoc.set_evaso(qr->get_evaso()); rdoc.set_qta_ritirata(qr->get_qta_rit()); rdoc.set_qta_consegnata(qr->get_qta_con()); rdoc.set_qta_dacons(qr->get_qta_da_con()); rdoc.set_num_pacchi(qr->get_pacchi()); rdoc.set_dataeva(oggi); } else { //trovo la riga con quel codart TToken_string chiave(key); TString80 codart = chiave.get(0); int i; for(i = 1; i <= doc.rows(); i++) { TRiga_documento& row = doc[i]; if(codart == row.get(RDOC_CODART)) break; } //creo una copia di questa riga TRiga_documento& row1 = doc[i]; TRiga_documento& row2 = doc.new_row("24"); TDocumento::copy_data(row2, row1); TBuono_prelievo_row rdoc(row2); //setto le quantità corrette rdoc.set_evaso(qr->get_evaso()); rdoc.set_qta_ritirata(qr->get_qta_rit()); rdoc.set_qta_consegnata(qr->get_qta_con()); rdoc.set_qta_dacons(qr->get_qta_da_con()); rdoc.set_num_pacchi(qr->get_pacchi()); rdoc.set_dataeva(oggi); } } for (int i = 1; i <= doc.rows(); i++) { TRiga_documento& row = doc[i]; TBuono_prelievo_row rdoc(row); if (rdoc.qta_dacons() <= ZERO) { rdoc.set_evaso(true); rdoc.set_dataeva(oggi); } } doc.rewrite(); //visto che sto evadendo tramite barcode quando salvo salvo anche tutti i pacchi associati //generando i movimenti di magazzino di scarico TLocalisamfile pacchi(LF_PACCHI); TLocalisamfile movi(LF_MOVMAG); //cerco l'ultimo numero di chiave in movmag TISAM_recordset mov("USE MOVMAG"); long nummov = 0; if(mov.move_last()) nummov += mov.get(MOVMAG_NUMREG).as_int(); const TCausale_magazzino causale((ini_get_string(CONFIG_DITTA, "lv", "CAUSCARMAG"))); TString8 magazzino; magazzino << ini_get_string(CONFIG_DITTA, "lv", "CODMAG") << ini_get_string(CONFIG_DITTA, "lv", "CODMAGP"); TEsercizi_contabili es; int annoes = es.date2esc(oggi); TMov_mag movmag(++nummov); movmag.put(MOVMAG_ANNOES, annoes); movmag.put(MOVMAG_DATAREG, oggi); movmag.put(MOVMAG_CODCAUS, causale.codice()); FOR_EACH_ASSOC_OBJECT(_pacchi, o, codpacco, rifdoc) { TToken_string& tmp = *(TToken_string*)rifdoc; TDoc_key kdoc(tmp.get_int(0), tmp.get(1), tmp.get_long(2)); TRiga_pacco rp(codpacco); const TString80 codart = rp.articolo(); const long qta = rp.quantita().integer(); //recupero l'unità di misura principale di quest'articolo TToken_string key; key.add(codart); key.add(1); const TString4 um = cache().get(LF_UMART, key, UMART_UM); rp.set_rigabolla(kdoc.anno(), kdoc.codnum(), kdoc.ndoc(), 0); //SOLUZIONE MOMENTANEA PER VEDERE SE FUNZIONA TUTTO rp.rewrite(pacchi); //faccio la nuova riga del movimento di magazzino TRectype& rmovmag = movmag.new_row(); rmovmag.put(RMOVMAG_CODMAG, magazzino); rmovmag.put(RMOVMAG_CODART, codart); rmovmag.put(RMOVMAG_UM, um); rmovmag.put(RMOVMAG_QUANT, qta); } movmag.write(movi); } //RIEMPI_SHEET: metodo che riempie lo sheet di riepilogo delle righe documento ancora da evadere void TEvasione_ter_msk::riempi_sheet() { TSheet_field& sheet = sfield(F_TRIGHE); sheet.destroy(); FOR_EACH_ASSOC_OBJECT(_ra, obj, key, itm) { TToken_string chiave(key); TQuantita_riga& qr = *(TQuantita_riga*)itm; if(!qr.get_evaso()) { TToken_string& riga = sheet.row(-1); riga.add(chiave.get(0), 0); riga.add(qr.get_qta_da_con().string(), 1); riga.add(qr.get_qta_con().string(), 2); } } sheet.force_update(); } int TEvasione_ter_msk::arrotonda(const int quantita) { int qta = quantita; const TString& codart = 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) { //recupero dal documento i dati di interesse per recuperare... //...i dati dalla riga contratto const long codcf = get_long(F_TCODCF); const TDate data = get_date(F_TDATADOC); TToken_string key; key.add('C'); key.add(codcf); const int codindsp = atoi(cache().get(LF_CFVEN, key, CFV_CODINDSP)); const TLaundry_contract cont(codcf, codindsp, data); const long codcn = cont.get_int(LVCONDV_CODCONT); //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) { const int perarr = ini_get_int(CONFIG_DITTA, "lv", "Perarr"); //calcolo di quanti pezzi sforo long arr = quantita % 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; qta += arr; } else qta -= arr; } } return qta; } //SPEZZA_RIGHE: metodo che spezza le righe documento se richiesto void TEvasione_ter_msk::spezza_riga() { const TDate oggi(TODAY); const TDate nulla(NULLDATE); FOR_EACH_ASSOC_OBJECT(_ra, obj, key, itm) { TToken_string chiave(key); TQuantita_riga& qr = *(TQuantita_riga*)itm; if(TDate(chiave.get()) == oggi && !qr.get_evaso()) { real qtarit = qr.get_qta_rit(); real qtadacon = qr.get_qta_da_con(); real qtacon = qr.get_qta_con(); real pacchi = qr.get_pacchi(); qr.set_evaso(true); qr.set_qta_da_con(qtacon); qr.set_qta_rit(qtacon); TToken_string chiave1; chiave1.add(chiave.get(0), 0); chiave1.add(nulla, 1); TQuantita_riga qr1; qr1.set_evaso(false); qr1.set_qta_rit(qtadacon - qtacon); qr1.set_qta_da_con(arrotonda(qtadacon.integer() - qtacon.integer())); qr1.set_qta_con(ZERO); qr1.set_pacchi(0); _ra.add(chiave1, qr1); } } } //CONTROLLA: metodo che controlla se tutte le righe del buono sono evase bool TEvasione_ter_msk::controlla() { bool evaso = true; FOR_EACH_ASSOC_OBJECT(_ra, obj, key, itm) { TQuantita_riga* qr = (TQuantita_riga*)itm; if(!qr->get_evaso()) { evaso = false; break; } } return evaso; } //EVADI_DA_TERMINALE: metodo che somma alla riga corretta un pacco (quello pistolato) e lo assegna a un cliente, //sottraendolo dal magazzino del pulito void TEvasione_ter_msk::evadi_da_terminale() { const TString80 codpacco = get(F_TBARCODE); if (codpacco.full()) { TRiga_pacco rp(codpacco); if (rp.empty()) { warning_box(TR("Il pacco %s non esiste a magazzino"), (const char*)codpacco); warning_box(TR("Non è stato possibile sommare il pacco a nessuna riga del buono")); } else { if (rp.rigabolla().full()) { TToken_string riga = rp.rigabolla(); int numdoc = riga.get_int(3); if (numdoc > 0) { TString msg; msg << "Il pacco risulta già associato al buono numero " << numdoc; warning_box(msg); return; } else if (numdoc < 0) { TString msg; msg << "Il pacco non risulta disponibile a magazzino"; warning_box(msg); return; } } const TDate oggi(TODAY); const TString80 codart = rp.articolo(); const real qtapacco = rp.quantita(); TToken_string key; key.add(codart); key.add(oggi); TToken_string kdoc; kdoc.add(get_date(F_TDATADOC).year()); kdoc.add(ini_get_string(CONFIG_DITTA, "lv", "NUM_PRE", NULL, 0)); kdoc.add(get_int(F_TNDOC)); //se il pacco è già stato pistolettato lo tolgo dai pacchi da evadere, altrimenti cerco di sommarlo //a una riga documento esistente if (_pacchi.is_key(codpacco)) { if(yesno_box(TR("Si desidera annullare il pacco selezionato?"))) { TToken_string& tmp = *(TToken_string*)_pacchi.objptr(codpacco); key.add(tmp.get(3)); _pacchi.remove(codpacco); if (_ra.is_key(key)) { TQuantita_riga& qr = *(TQuantita_riga*)_ra.objptr(key); qr.add_pacchi(-1); qr.add_qta_con(-1 * qtapacco); if (qr.get_evaso()) qr.set_evaso(false); set(F_TPACCHI, qr.get_pacchi()); set(F_TQTAPACCO, qtapacco); set(F_TQTACON, qr.get_qta_con()); set(F_TQTADACON, qr.get_qta_da_con()); set(F_CODART, rp.articolo()); } } else return; } else { bool trovato = false; bool trovato2 = false; bool associato = false; bool evaso1 = false; bool evaso2 = false; TToken_string chiave1; TToken_string chiave2; FOR_EACH_ASSOC_OBJECT(_ra, obj, key, itm) { chiave1 = key; //se trovo una riga di quell'artticolo allora TString cod = chiave1.get(0); if(cod == codart) { trovato = true; TQuantita_riga& qr = *(TQuantita_riga*)_ra.objptr(key); //se la riga trovata non è già evasa e manca da consegnare almeno la qta //di un pacco, allora lo associo evaso1 = qr.get_evaso(); if (!evaso1 && qr.get_qta_da_con() >= qtapacco) { associato = true; qr.add_pacchi(); qr.add_qta_con(qtapacco); if(qr.get_qta_con() == qr.get_qta_da_con()) qr.set_evaso(true); kdoc.add(chiave1.get(2)); _pacchi.add(codpacco, kdoc); set(F_TPACCHI, qr.get_pacchi()); set(F_TQTAPACCO, qtapacco); set(F_TQTACON, qr.get_qta_con()); set(F_TQTADACON, qr.get_qta_da_con()); set(F_CODART, rp.articolo()); break; } break; } } //se ho trovato la riga di quell'articolo ma non l'ho associato, //cerco un eventuale altra riga per quell'articolo if(trovato && !associato) { FOR_EACH_ASSOC_OBJECT(_ra, obj, key, itm) { chiave2 = key; const TString80 codart2 = chiave2.get(0); //se trovo una riga di quell'articolo allora if(codart2 == codart && chiave1 != chiave2) { trovato2 = true; TQuantita_riga& qr = *(TQuantita_riga*)_ra.objptr(key); //se la riga trovata non è già evasa e manca da consegnare almeno la qta //di un pacco, allora lo associo evaso2= qr.get_evaso(); if (!evaso2 && qr.get_qta_da_con() >= qtapacco) { associato = true; qr.add_pacchi(); qr.add_qta_con(qtapacco); if(qr.get_qta_con() == qr.get_qta_da_con()) qr.set_evaso(true); kdoc.add(chiave2.get(2)); _pacchi.add(codpacco, kdoc); set(F_TPACCHI, qr.get_pacchi()); set(F_TQTAPACCO, qtapacco); set(F_TQTACON, qr.get_qta_con()); set(F_TQTADACON, qr.get_qta_da_con()); set(F_CODART, rp.articolo()); break; } } } } //se risulta ancora trovato, ma non associato, allora lo associo alla riga non ancora evasa if(trovato2 && !associato) { if(!evaso1) { TQuantita_riga& qr = *(TQuantita_riga*)_ra.objptr(chiave1); kdoc.add(chiave1.get(2)); qr.add_pacchi(); qr.add_qta_con(qtapacco); if(qr.get_qta_con() >= qr.get_qta_da_con()) qr.set_evaso(true); _pacchi.add(codpacco, kdoc); set(F_TPACCHI, qr.get_pacchi()); set(F_TQTAPACCO, qtapacco); set(F_TQTACON, qr.get_qta_con()); set(F_TQTADACON, qr.get_qta_da_con()); set(F_CODART, rp.articolo()); } else if(!evaso2) { TQuantita_riga& qr = *(TQuantita_riga*)_ra.objptr(chiave2); kdoc.add(chiave2.get(2)); qr.add_pacchi(); qr.add_qta_con(qtapacco); if(qr.get_qta_con() >= qr.get_qta_da_con()) qr.set_evaso(true); _pacchi.add(codpacco, kdoc); set(F_TPACCHI, qr.get_pacchi()); set(F_TQTAPACCO, qtapacco); set(F_TQTACON, qr.get_qta_con()); set(F_TQTADACON, qr.get_qta_da_con()); set(F_CODART, rp.articolo()); } } //se non è ancora associato e entrambe le righe risultano evase oppure c'è una riga sola //allora sommo alla prima (o unica) riga se l'utente lo desidera if(!associato && ((evaso1 && evaso2) || (!trovato2 && trovato))) { if(yesno_box(TR("Si desidera sommare il pacco ad un riga già evasa?"))) { TQuantita_riga& qr = *(TQuantita_riga*)_ra.objptr(chiave1); kdoc.add(chiave1.get(2)); qr.add_pacchi(); qr.add_qta_con(qtapacco); if(qr.get_qta_con() >= qr.get_qta_da_con()) qr.set_evaso(true); _pacchi.add(codpacco, kdoc); set(F_TPACCHI, qr.get_pacchi()); set(F_TQTAPACCO, qtapacco); set(F_TQTACON, qr.get_qta_con()); set(F_TQTADACON, qr.get_qta_da_con()); set(F_CODART, rp.articolo()); } else return; } if(!trovato) { TDoc_key kdoc(get_date(F_TDATADOC).year(), ini_get_string(CONFIG_DITTA, "lv", "NUM_PRE", NULL, 0), get_long(F_TNDOC)); TBuono_prelievo bpre(kdoc); const long codcf = bpre.codcf(); const int codcont = bpre.codcont(); TLaundry_contract cont(codcf, codcont); const TRectype& rcont = cont.row(rp.articolo()); if (rcont.empty()) { TString msg; msg << "L'articolo " << rp.articolo() << " non è previsto per questo cliente"; warning_box(msg); } else { TString msg; msg << "L'articolo " << rp.articolo() << " non è previsto sul buono in evasione"; warning_box(msg); } } } } } } //ON_FIELD_EVENT: metodo che gestisce gli eventi sui campi della maschera bool TEvasione_ter_msk::on_field_event(TOperable_field& f, TField_event e, long jolly) { //a seconda del bottone premuto esegui un metodo diverso switch (f.dlg()) { case DLG_SELECT: if (e == fe_button) { if(yesno_box(TR("ATTENZIONE: non tutte le righe sono evase. Si desidera continuare ugualmente?"))) { evadi(); genera_buono(); } return false; } break; case DLG_PREVIEW: if (e == fe_button) { hide(F_TBARCODE); hide(F_TPACCHI); hide(F_TQTAPACCO); hide(F_TQTACON); hide(F_TQTADACON); hide(F_CODART); show(F_TRIGHE); disable(DLG_SELECT); disable(DLG_ELABORA); riempi_sheet(); return false; } break; case DLG_ELABORA: if (e == fe_button) if (controlla()) genera_buono(); else { if(yesno_box(TR("ATTENZIONE: non tutte le righe sono evase. Si desidera continuare ugualmente?"))) { if(yesno_box(TR("Si desidera considerare evase tutte le righe?" "(in caso contrario le righe evase parzialmente verranno spezzate su due righe)"))) { evadi(); genera_buono(); } else { spezza_riga(); genera_buono(); } } else send_key(K_SPACE, DLG_CANCEL); } return false; break; case DLG_CANCEL: if (e == fe_button && jolly == 0) { if(field(F_TRIGHE).shown()) { show(F_TBARCODE); show(F_TPACCHI); show(F_TQTAPACCO); show(F_TQTACON); show(F_TQTADACON); show(F_CODART); enable(DLG_SELECT); enable(DLG_ELABORA); hide(F_TRIGHE); field(F_TBARCODE).set_focus(); _autoselect = 1; return false; } else { TDoc_key kdoc(get_int(F_TANNO), ini_get_string(CONFIG_DITTA, "lv", "NUM_PRE", NULL, 0), get_long(F_TNDOC)); TBuono_prelievo doc(kdoc); TLocalisamfile fdoc(LF_DOC); int err = doc.read(fdoc); show(F_TCHIAVE); show(F_TCODNUM); show(F_TDESCR); show(F_TTPDOC); show(F_TANNO); show(F_TDATAPRCO); reset(F_TCODCF); hide(F_TCODCF); reset(F_TRAGSOC); hide(F_TRAGSOC); reset(F_TBARCODE); hide(F_TBARCODE); reset(F_TPACCHI); hide(F_TPACCHI); reset(F_TQTAPACCO); hide(F_TQTAPACCO); reset(F_TQTACON); hide(F_TQTACON); reset(F_TQTADACON); hide(F_TQTADACON); reset(F_CODART); hide(F_CODART); disable(DLG_SELECT); disable(DLG_PREVIEW); disable(DLG_ELABORA); disable(DLG_SAVEREC); disable(DLG_CANCEL); reset(F_TDATADOC); reset(F_TNDOC); reset(F_TCHIAVE); enable(F_TNDOC); _ra.destroy(); field(F_TCHIAVE).set_focus(); return false; } } break; case DLG_SAVEREC: if (e == fe_button) { registra(); return false; } break; case F_TCHIAVE: { if (e == fe_modify) { TString kdoc = f.get(); if (kdoc.full()) { set(F_TANNO, atol(kdoc.left(4))); set(F_TNDOC, atol(kdoc.mid(4))); field(F_TNDOC).check(); if(!precarica_righe()) return false; hide(F_TCODNUM); hide(F_TTPDOC); hide(F_TDESCR); hide(F_TANNO); hide(F_TDATAPRCO); show(F_TCODCF); show(F_TRAGSOC); show(F_TBARCODE); show(F_TPACCHI); show(F_TQTAPACCO); show(F_TQTACON); show(F_TQTADACON); show(F_CODART); enable(DLG_SELECT); enable(DLG_PREVIEW); enable(DLG_ELABORA); enable(DLG_SAVEREC); enable(DLG_CANCEL); disable(F_TNDOC); _autoselect = 1; field(F_TBARCODE).set_focus(); f.hide(); } } } break; case F_TNDOC: { if (e == fe_modify) if (f.get_long() != 0 && get(F_TCHIAVE).empty()) { field(F_TNDOC).check(); if(!precarica_righe()) return false; hide(F_TCODNUM); hide(F_TTPDOC); hide(F_TDESCR); hide(F_TANNO); hide(F_TDATAPRCO); hide(F_TCHIAVE); show(F_TCODCF); show(F_TRAGSOC); show(F_TBARCODE); show(F_TPACCHI); show(F_TQTAPACCO); show(F_TQTACON); show(F_TQTADACON); show(F_CODART); enable(DLG_SELECT); enable(DLG_PREVIEW); enable(DLG_ELABORA); enable(DLG_SAVEREC); enable(DLG_CANCEL); disable(F_TNDOC); _autoselect = 1; field(F_TBARCODE).set_focus(); } else { show(F_TCHIAVE); show(F_TCODNUM); show(F_TDESCR); show(F_TTPDOC); show(F_TANNO); show(F_TDATAPRCO); reset(F_TCODCF); hide(F_TCODCF); reset(F_TRAGSOC); hide(F_TRAGSOC); reset(F_TBARCODE); hide(F_TBARCODE); reset(F_TPACCHI); hide(F_TPACCHI); reset(F_TQTAPACCO); hide(F_TQTAPACCO); reset(F_TQTACON); hide(F_TQTACON); reset(F_TQTADACON); hide(F_TQTADACON); reset(F_CODART); hide(F_CODART); disable(DLG_SELECT); disable(DLG_PREVIEW); disable(DLG_ELABORA); disable(DLG_SAVEREC); disable(DLG_CANCEL); reset(F_TDATADOC); enable(F_TNDOC); _ra.destroy(); } } break; case F_TBARCODE: { if (e == fe_modify && f.get().full()) { _autoselect = 1; evadi_da_terminale(); if (controlla()) send_key(K_SPACE, DLG_ELABORA); } } break; default:break; } return true; } void TEvasione_ter_msk:: on_idle() { TMask::on_idle(); if (_autoselect >= 0 && get(F_TBARCODE).full()) { reset(F_TBARCODE); field(F_TBARCODE).set_focus(); _autoselect = -1; } } TEvasione_ter_msk::TEvasione_ter_msk():TAutomask("lv3400a") { //precarico i campi fissi set(F_TCODNUM, ini_get_string(CONFIG_DITTA, "lv", "NUM_PRE", NULL, 0)); set(F_TTPDOC, ini_get_string(CONFIG_DITTA, "lv", "TIPODOC_PRE", NULL, 0)); const TRectype& tpdoc = cache().get("%NUM", ini_get_string(CONFIG_DITTA, "lv", "TIPODOC_PRE", NULL, 0)); set(F_TDESCR, tpdoc.get("S0")); TDate data(TODAY); TEsercizi_contabili es; int annoes = es.date2esc(data); set(F_TANNO, annoes); hide(F_TCODCF); hide(F_TRAGSOC); hide(F_TBARCODE); hide(F_TPACCHI); hide(F_TQTAPACCO); hide(F_TQTACON); hide(F_TQTADACON); hide(F_CODART); hide(F_TRIGHE); disable(DLG_SELECT); disable(DLG_PREVIEW); disable(DLG_ELABORA); disable(DLG_SAVEREC); disable(DLG_CANCEL); } ///////////////////////////////// //// TEVASIONE_TER_APP //// ///////////////////////////////// //classe TEvasione_ter_app class TEvasione_ter_app : public TSkeleton_application { TEvasione_ter_msk* _msk; protected: virtual bool create(); virtual bool destroy(); public: bool transfer(); virtual void main_loop(); }; //CREATE: metodo costruttore bool TEvasione_ter_app::create() { _msk = new TEvasione_ter_msk(); open_files(LF_DOC, LF_RIGHEDOC); return TSkeleton_application::create(); } //DESTROY: metodo distruttore bool TEvasione_ter_app::destroy() { delete _msk; return TApplication::destroy(); } //TRANSFER: metodo che scorre i campi nome e, se sono pieni, richiama il metodo //ELABORA_FILE(), che effettivamente fa l'elaborazione bool TEvasione_ter_app::transfer() { return true; } void TEvasione_ter_app::main_loop() { while (_msk->run() == K_ENTER) transfer(); } int lv3400(int argc, char *argv[]) { TEvasione_ter_app a; a.run (argc, argv, "Evasione Buoni di Prelievo"); return TRUE; }