#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 "lv3200a.h" ///////////////////////////// //// TEVASIONE_MSK //// ///////////////////////////// //classe TEvasione_msk class TEvasione_msk: public TAutomask { TDocumento _buonori; //int _ndoc; int _autoselect; TString4 _tpev; TAssoc_array _pacchi; protected: void setta_campi_data(); void setta_campi_cliente(); void carica_righe(); void riordina_righe(); void genera_documento(); void evadi_tutto(); int arrotonda(const int quantita); void spezza_riga(); void salva(); void annulla_operazioni(); bool controlla(); void sistema_quantita(); void sistema_pacchi(); void evadi_da_barcode(); virtual void on_idle(); virtual bool on_field_event(TOperable_field& o, TField_event e, long jolly); public: TEvasione_msk(); }; //SORT_BY_QTA_EVASA: è la rows_comapre_function, cioè la funzione che viene utilizzata //dal metodo sort degli sheet per riordinare le righe secondo le quantità evase static int sort_by_qta_evasa(TSheet_field& sheet, int r1, int r2) { TToken_string& row1 = sheet.row(r1); TToken_string& row2 = sheet.row(r2); const int qta1 = row1.get_int(6); const int qta2 = row2.get_int(6); int dif = qta1 - qta2; if (dif == 0) { const TString& codart1 = row1.get(1); const TString& codart2 = row2.get(1); dif = codart1.compare(codart2); } return dif; } //SORT_BY_CODART: è la rows_comapre_function, cioè la funzione che viene utilizzata //dal metodo sort degli sheet per riordinare le righe secondo i codart e le qta evase static int sort_by_codart(TSheet_field& sheet, int r1, int r2) { TToken_string& row1 = sheet.row(r1); TToken_string& row2 = sheet.row(r2); const TString& codart1 = row1.get(1); const TString& codart2 = row2.get(1); int dif = codart1.compare(codart2); if (dif == 0) { const int qta1 = row1.get_int(6); const int qta2 = row2.get_int(6); dif = qta2 - qta1; } return dif; } //SETTA_CAMPI_DATA: metodo che compila tutti i campi legati alla data void TEvasione_msk::setta_campi_data() { TDate data = get_date(F_DATADOC); if (data.ok()) { TDate primo = data; primo.set_day(1); TEsercizi_contabili es; int annoes = es.date2esc(data); set(F_ANNO, annoes); //decodifica del giorno della settimana set(F_GIORNO, itow(data.wday())); //settimana del mese = settimana(oggi) - settimana(primo del mese) + 1 long tmp = data.week() - primo.week() + 1; TString4 settimana; settimana << tmp; set(F_SETTIMANA, settimana); } else { TString8 str = data.string(); if (str.empty()) { reset(F_GIORNO); reset(F_SETTIMANA); } else warning_box(TR("Data non valida!")); } } //SETTA_CAMPI_CLIENTE: metodo che compila tutti i campi legati al cliente void TEvasione_msk::setta_campi_cliente() { const long codcf = get_int(F_CODCF); const TDate data = get_date(F_DATADOC); if (codcf > 0) { TToken_string key; key.add('C'); key.add(codcf); const int codindsp = atoi(cache().get(LF_CFVEN, key, CFV_CODINDSP)); TLaundry_contract cont(codcf, codindsp, data); //se trovo un contratto, allora scrivo il codice contratto e cerco itinerario e data di prevista consegna //se no avviso che non c'è neanche un contratto valido e svuoto i campi interassati if(!cont.empty()) { set(F_CODCONT, cont.get_int(LVCONDV_CODCONT)); TDate adata = data; adata.addmonth(1); TString query = "USE LVRCONSPLAN KEY 3\n"; query << "FROM CODCF=" << get(F_CODCF) << " CODCONT=" << get(F_CODCONT) << " DTCONS=" << data << "\n"; query << "TO CODCF=" << get(F_CODCF) << " CODCONT=" << get(F_CODCONT) << " DTCONS=" << adata << "\n"; TISAM_recordset consegne(query); if (consegne.items() >= 2) { consegne.move_to(1); set(F_DATAPRCO, consegne.get(LVRCONSPLAN_DTCONS).as_date()); set(F_CODITI, consegne.get(LVRCONSPLAN_CODITI).as_int()); } else { reset(F_DATAPRCO); reset(F_CODITI); } if (get(F_RAGSOC).empty()) { TToken_string key; key.add('C'); key.add(codcf); const TRectype& clifo = cache().get(LF_CLIFO, key); set(F_RAGSOC, clifo.get(CLI_RAGSOC)); set(F_RICALT, clifo.get(CLI_RICALT)); } } else { TString msg; msg << "ATTENZIONE: nessun contratto in essere per il cliente " << codcf << " alla data " << data; warning_box(msg); reset(F_CODCONT); reset(F_DATAPRCO); reset(F_CODITI); } } else { reset(F_RICALT); reset(F_RAGSOC); reset(F_CODCONT); reset(F_DATAPRCO); reset(F_CODITI); } } //CARICA_RIGHE: metodo che carica sullo sheet le righe di un documento selezionato void TEvasione_msk::carica_righe() { TDoc_key kdoc(get_int(F_ANNO), get(F_CODNUM), get_long(F_NDOC)); TBuono_prelievo doc(kdoc); const TString4 stato = doc.get(DOC_STATO); const TString4 steva = cache().get("%TIP", ini_get_string(CONFIG_DITTA, "lv", "TIPODOC_PRE", NULL, 0), "S2").mid(2,1); if (stato == steva) { TString str; str << "Il documento " << get_long(F_NDOC) << " è già stato evaso"; warning_box(str); set(F_NDOC, 0L, 1); return; } set(F_STATO, stato); disable(F_STATO); const TDate oggi(TODAY); if(ini_get_bool(CONFIG_DITTA, "lv", "DataBcon")) set(F_DATABOLLA, oggi); else set(F_DATABOLLA, doc.get_date(DOC_DATADOC)); set(F_DATADOC, doc.get_date(DOC_DATADOC)); setta_campi_data(); set(F_CODCF, doc.get_long(DOC_CODCF)); setta_campi_cliente(); field(F_CODCF).set_dirty(); _buonori = doc; _pacchi.destroy(); if(doc.rows() > 0) { enable(DLG_SELECT); enable(DLG_PREVIEW); if(stato == "2") enable(DLG_ELABORA); enable(DLG_SAVEREC); enable(DLG_CANCEL); show(F_RIGHE); } TSheet_field& sheet = sfield(F_RIGHE); for(int i = 1; i <= doc.rows(); i++) { TRiga_documento& row = doc[i]; TBuono_prelievo_row rdoc(row); if (rdoc.qta_dacons() > 0) { TToken_string& riga = sheet.row(-1); riga.add(rdoc.evaso() ? "X" : "", sheet.cid2index(S_EVASO)); riga.add(rdoc.codart(), sheet.cid2index(S_CODART)); riga.add(rdoc.desart(), sheet.cid2index(S_ARTDESCR)); riga.add(rdoc.causale(), sheet.cid2index(S_CAUSALE)); riga.add(rdoc.qta_ritirata().string(), sheet.cid2index(S_RITIRATO)); riga.add(rdoc.qta_dacons().string(), sheet.cid2index(S_DACONS)); riga.add(rdoc.qta_consegnata().string(), sheet.cid2index(S_CONSEGNATO)); const TRectype& anamag = cache().get(LF_ANAMAG, rdoc.codart()); //recupero i dati di interesse dall'anagrafica di magazzino const long ppconf = anamag.get_long(ANAMAG_PPCONF); if (ppconf > 0) riga.add(rdoc.num_pacchi(), sheet.cid2index(S_PACCHI)); else { riga.add(0, sheet.cid2index(S_PACCHI)); sheet.disable_cell(i, sheet.cid2index(S_PACCHI)); } riga.add(rdoc.cong_pre(), sheet.cid2index(S_CONGPRE)); riga.add(rdoc.cong_att(), sheet.cid2index(S_CONGATT)); riga.add(rdoc.rifbcon(), sheet.cid2index(S_RIFBCON)); riga.add(row.get(RDOC_IDRIGA), sheet.cid2index(S_NROW)); } else rdoc.set_evaso(true); } doc.rewrite(); sheet.sort(sort_by_codart); FOR_EACH_SHEET_ROW(sheet, r, row) { if (row->get_char(0) == 'X') sheet.disable_row(r); } sheet.force_update(); } //RIORDINA_RIGHE: metodo che riordina le righe dello sheet in base alle quota di evasione void TEvasione_msk::riordina_righe() { TSheet_field& sheet = sfield(F_RIGHE); sheet.sort(sort_by_qta_evasa); sheet.force_update(); } //GENERA_DOCUMENTO: metodo che genera il buono di consegna partendo dal buono di ritiro void TEvasione_msk::genera_documento() { //per prima cosa salva il buono di prelievo salva(); TDoc_key kdoc(get_int(F_ANNO), get(F_CODNUM), get_long(F_NDOC)); 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; TString4 tipodoc; if (cont.get(LVCONDV_CODNUM).empty()) { codnum = ini_get_string(CONFIG_DITTA, "lv", "NUM_GEN"); tipodoc = ini_get_string(CONFIG_DITTA, "lv", "TIPODOC_GEN"); } else { codnum = cont.get(LVCONDV_CODNUM); tipodoc = cont.get(LVCONDV_TPDOC); } char stato = cache().get("%TIP", tipodoc, "S2").left(1)[0]; const TDate databpre = bpre.datadoc(); const TDate databolla = get_date(F_DATABOLLA); const TDate datagen(TODAY); TDate dadata = databpre; TDate adata = datagen; adata.addmonth(); /*if(_ndoc == 0) { TString query2; query2 << "USE DOC\n" << "FROM PROVV=\"D\" ANNO=" << datagen.year() << " CODNUM=\"" << codnum << "\"\n" << "TO PROVV=\"D\" ANNO=" << datagen.year() << " CODNUM=\"" << codnum << "\""; TISAM_recordset bolle(query2); if (bolle.move_last()) _ndoc = bolle.get(DOC_NDOC).as_int(); }*/ 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 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 TString16 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); doc.put(DOC_DATADOC, databolla); if(ini_get_bool(CONFIG_DITTA, "lv", "DataBcon")) doc.put(DOC_DATAPART, databpre); doc.put(DOC_TIPOCF, 'C'); doc.put(DOC_CODCF, codcf); doc.put(DOC_CODCONT, codcont); doc.put(DOC_CODPAG, codpag); if(codindsp > 0) doc.put(DOC_CODINDSP, codindsp); 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 TLocalisamfile magcli(LF_CLIFOGIAC); magcli.put(CLIFOGIAC_ANNOES, datagen.year()); magcli.put(CLIFOGIAC_TIPOCF, 'C'); magcli.put(CLIFOGIAC_CODCF, codcf); magcli.put(CLIFOGIAC_INDSPED, 0); //in realtà è da leggere dal contratto magcli.put(CLIFOGIAC_CODART, codart); magcli.put(CLIFOGIAC_NRIGA, 1); //leggo il record corrispondente magcli.read(); real dottmp = magcli.get_real(CLIFOGIAC_DOTTM); real dotod = magcli.get_real(CLIFOGIAC_DOTOD); //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); 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); bool dtmp = false; if (datagen >= rcont.get_date(LVRCONDV_INDTTMP) && datagen <= rcont.get_date(LVRCONDV_FIDTTMP)) dtmp = true; 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; 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); } //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); set(F_STATO, stato); } bpre.rewrite(); } if (err == NOERR) { if (yesno_box(TR("Il documento è stato generato; si desiderla stamparlo?"))) { //stampa automatica TString80 str; str << "ve1 -2 " << codnum << ' ' << datagen.year() << " D " << doc.get_long(DOC_NDOC) << " S D"; TExternal_app stampa(str); stampa.run(); } } else warning_box(TR("Non è stato possibile generare nessun documento")); //azzera i campi e rimettiti nella condizione iniziale set(F_NDOC, 0L, 1); } //EVADI_TUTTO: metodo che forza a "evaso" tutte le righe e lancia la generazione del buono di consegna associato void TEvasione_msk::evadi_tutto() { TSheet_field& sheet = sfield(F_RIGHE); const int posevaso = sheet.cid2index(S_EVASO); FOR_EACH_SHEET_ROW(sheet, r, riga) { riga->add("X", posevaso); sheet.disable_row(r); } genera_documento(); } int TEvasione_msk::arrotonda(const int quantita) { int perarr = ini_get_int(CONFIG_DITTA, "lv", "Perarr"); 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_CODCF); const long codcn = get_long(F_CODCONT); const TLaundry_contract cont(codcf, codcn); //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 % 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_RIGA: metodo che spezza una riga del buono in due righe, una per la quota evasa e una per la quota da evadere void TEvasione_msk::spezza_riga() { TSheet_field& sheet = sfield(F_RIGHE); FOR_EACH_SHEET_ROW_BACK(sheet, r, riga1) { char flgev = riga1->get_char(sheet.cid2index(S_EVASO)); if (flgev != 'X') { TToken_string& riga2 = sheet.row(-1); riga2 = *riga1; int idriga2 = riga2.get_int(sheet.cid2index(S_NROW)); idriga2 *= -1; //scrivi le quantità sulla seconda riga const int dacons2 = arrotonda(riga2.get_int(sheet.cid2index(S_RITIRATO)) - riga2.get_int(sheet.cid2index(S_CONSEGNATO))); riga2.add(dacons2, sheet.cid2index(S_RITIRATO)); riga2.add(dacons2, sheet.cid2index(S_DACONS)); riga2.add(0L, sheet.cid2index(S_CONSEGNATO)); riga2.add(0L, sheet.cid2index(S_PACCHI)); riga2.add(idriga2, sheet.cid2index(S_NROW)); //scrivi le quantità sulla prima riga const int dacons1 = riga1->get_int(sheet.cid2index(S_RITIRATO)) - riga1->get_int(sheet.cid2index(S_CONSEGNATO)); riga1->add(riga1->get_int(sheet.cid2index(S_CONSEGNATO)), sheet.cid2index(S_RITIRATO)); riga1->add(riga1->get_int(sheet.cid2index(S_CONSEGNATO)), sheet.cid2index(S_DACONS)); riga1->add("X", sheet.cid2index(S_EVASO)); //blocca i campi sulla prima riga sheet.disable_row(r); } } sheet.sort(sort_by_codart); sheet.force_update(); } //SALVA: metodo che salva il buono di prelievo così com'è, senza compiere altre operazioni void TEvasione_msk::salva() { TDoc_key kdoc(get_int(F_ANNO), get(F_CODNUM), get_long(F_NDOC)); TBuono_prelievo doc(kdoc); TDate datadoc = doc.get_date(DOC_DATADOC); TLaundry_contract cont(get_long(F_CODCF), get_long(F_CODCONT)); TSheet_field& sheet = sfield(F_RIGHE); //riordino lo sheet sheet.sort(sort_by_codart); sheet.force_update(); //per ogni riga dello sheet genero una riga documento FOR_EACH_SHEET_ROW(sheet, r, riga) { const int rowid = riga->get_int(sheet.cid2index(S_NROW)); const TRiga_documento* riori = doc.get_row_id(abs(rowid)); int nriga = riori ? riori->get_int(RDOC_NRIGA) : -1; if (rowid < 0) { TRiga_documento& row = doc.new_row("24"); if (riori != NULL) TDocumento::copy_data(row, *riori); nriga = row.get_int(RDOC_NRIGA); } TBuono_prelievo_row rdoc(doc[nriga]); const char flgev = riga->get(sheet.cid2index(S_EVASO))[0]; bool flag; if (flgev == 'X') flag = true; else flag = false; const TString80 codart = riga->get(sheet.cid2index(S_CODART)); rdoc.set_evaso(flag); rdoc.set_codart(codart); rdoc.set_desart(riga->get(sheet.cid2index(S_ARTDESCR))); rdoc.set_causale(riga->get(sheet.cid2index(S_CAUSALE))); rdoc.set_qta_ritirata(riga->get_int(sheet.cid2index(S_RITIRATO))); rdoc.set_qta_dacons(riga->get_int(sheet.cid2index(S_DACONS))); rdoc.set_qta_consegnata(riga->get_int(sheet.cid2index(S_CONSEGNATO))); rdoc.set_num_pacchi(riga->get_int(sheet.cid2index(S_PACCHI))); rdoc.set_cong_att(riga->get_int(sheet.cid2index(S_CONGPRE))); rdoc.set_cong_pre(riga->get_int(sheet.cid2index(S_CONGATT))); rdoc.set_rifbcon(riga->get(sheet.cid2index(S_RIFBCON))); //recupero l'unità di misura principale di quest'articolo TToken_string key; key.add(codart); key.add(1); const TRectype& umart = cache().get(LF_UMART, key); rdoc.set_um(umart.get(UMART_UM)); //recupero il codiva di quest'articolo const TRectype& anamag = cache().get(LF_ANAMAG, codart); const TRectype& rcont = cont.row(codart); //controllo da dove devo prendere il prezzo real prezzo; if (cont.get_int(LVCONDV_TIPOLIS) == 0) prezzo = rcont.get_real(LVRCONDV_PREZZO); else prezzo = anamag.get_real(ANAMAG_COSTSTD); rdoc.set_prezzo(prezzo); //scrivo il magazzino TString8 magazzino; TString8 magazzinoc; magazzino << ini_get_string(CONFIG_DITTA, "lv", "CODMAG") << ini_get_string(CONFIG_DITTA, "lv", "CODMAGN"); magazzinoc << ini_get_string(CONFIG_DITTA, "lv", "CODMAG") << ini_get_string(CONFIG_DITTA, "lv", "CODMAGC"); rdoc.set_mag(magazzino); rdoc.set_magc(magazzinoc); } doc.sort_rows(RDOC_CODART "|" RDOC_QTA); doc.rewrite(); //se sto evadendo tramite barcode quando salvo salvo anche tutti i pacchi associati //generando i movimenti di magazzino di scarico if (_tpev == "B") { 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(datadoc); TMov_mag movmag(++nummov); movmag.put(MOVMAG_ANNOES, annoes); movmag.put(MOVMAG_DATAREG, datadoc); movmag.put(MOVMAG_CODCAUS, causale.codice()); FOR_EACH_ASSOC_OBJECT(_pacchi, o, codpacco, rifdoc) { TDoc_key kdoc = *(TToken_string*)rifdoc; 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); } } //ANNULLA_OPERAZIONI: metodo elimina tutte le quantità scritte durante l'ultima evasione //e libera i pacchi eventualmente allocati void TEvasione_msk::annulla_operazioni() { //ANNULLA PACCHI _pacchi.destroy(); //elimino lo sheet senza salvarlo TSheet_field& sheet = sfield(F_RIGHE); sheet.destroy(); for(int i = 1; i <= _buonori.rows(); i++) { TRiga_documento& row = _buonori[i]; TBuono_prelievo_row rdoc(row); TToken_string& riga = sheet.row(-1); riga.add(rdoc.evaso() ? "X" : "", sheet.cid2index(S_EVASO)); riga.add(rdoc.codart(), sheet.cid2index(S_CODART)); riga.add(rdoc.desart(), sheet.cid2index(S_ARTDESCR)); riga.add(rdoc.causale(), sheet.cid2index(S_CAUSALE)); riga.add(rdoc.qta_ritirata().string(), sheet.cid2index(S_RITIRATO)); riga.add(rdoc.qta_dacons().string(), sheet.cid2index(S_DACONS)); riga.add(rdoc.qta_consegnata().string(), sheet.cid2index(S_CONSEGNATO)); const TRectype& anamag = cache().get(LF_ANAMAG, rdoc.codart()); //recupero i dati di interesse dall'anagrafica di magazzino const long ppconf = anamag.get_long(ANAMAG_PPCONF); if (ppconf > 0) riga.add(rdoc.num_pacchi(), sheet.cid2index(S_PACCHI)); else { riga.add(0, sheet.cid2index(S_PACCHI)); sheet.disable_cell(i, sheet.cid2index(S_PACCHI)); } riga.add(rdoc.cong_pre(), sheet.cid2index(S_CONGPRE)); riga.add(rdoc.cong_att(), sheet.cid2index(S_CONGATT)); riga.add(rdoc.rifbcon(), sheet.cid2index(S_RIFBCON)); } sheet.force_update(); } //CONTROLLA: metodo che controlla se tutte le righe sono evase bool TEvasione_msk::controlla() { TSheet_field& sheet = sfield(F_RIGHE); bool evaso = true; FOR_EACH_SHEET_ROW(sheet, r, row) { const char flgev = row->get(sheet.cid2index(S_EVASO))[0]; if (flgev != 'X') evaso = false; } return evaso; } //SISTEMA_QUANTITA: metodo che mantiene allineate le quantita consegnate e il numero //dei pacchi, moltiplicando il numero dei pacchi per i pezzi per pacco; se scrivo una quantità //a mano ed è prevista una evasione a pacchi, allora aggiorno il numero dei pacchi void TEvasione_msk::sistema_quantita() { TMask& msk = sfield(F_RIGHE).sheet_mask(); TString80 codart = msk.get(S_CODART); 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) { int pacchi = msk.get_int(S_PACCHI); int qta_consegnata = pacchi * ppconf; msk.set(S_CONSEGNATO, qta_consegnata); } } void TEvasione_msk::sistema_pacchi() { TMask& msk = sfield(F_RIGHE).sheet_mask(); TString80 codart = msk.get(S_CODART); 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) { int qta_consegnata = msk.get_int(S_CONSEGNATO); int pacchi = qta_consegnata / ppconf; if (qta_consegnata % ppconf > 0) pacchi += 1; msk.set(S_PACCHI, pacchi); } } //EVADI_DA_BARCODE: metodo che somma alla riga corretta un pacco (quello pistolato) e lo assegna a un cliente, //sottraendolo dal magazzino del pulito void TEvasione_msk::evadi_da_barcode() { TString80 codpacco = get(F_BARCODE); if (codpacco.full()) { const TRiga_pacco rp(codpacco); const TString80 codart = rp.articolo(); const long qtapacco = rp.quantita().integer(); TSheet_field& sheet = sfield(F_RIGHE); const int pospa = sheet.cid2index(S_PACCHI); const int posco = sheet.cid2index(S_CONSEGNATO); //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)) { _pacchi.remove(codpacco); FOR_EACH_SHEET_ROW(sheet, r, riga) { const TString80 scodart = riga->get(sheet.cid2index(S_CODART)); const char sevaso = riga->get_char(sheet.cid2index(S_EVASO)); if (scodart == codart) { if (yesno_box(TR("ATTENZIONE: il pacco risulta già conteggato; si desidera annularlo?"))) { int qtadacon = riga->get_int(sheet.cid2index(S_DACONS)); int pacchi = riga->get_int(pospa); pacchi -= 1; int qtacon = riga->get_int(posco); qtacon -= qtapacco; riga->add(pacchi, pospa); riga->add(qtacon, posco); if(qtacon < qtadacon && sevaso == 'X') { riga->add("", sheet.cid2index(S_EVASO)); sheet.enable_row(r); } break; } else break; } } } else { TDoc_key kdoc(get_int(F_ANNO), get(F_CODNUM), get_int(F_NDOC)); bool trovato = false; //cerco la prima riga non evasa di quell'articolo FOR_EACH_SHEET_ROW(sheet, r, riga) { const TString80 scodart = riga->get(sheet.cid2index(S_CODART)); if (scodart == codart) trovato = true; } if(trovato) { trovato = false; FOR_EACH_SHEET_ROW(sheet, r, riga) { const TString80 scodart = riga->get(sheet.cid2index(S_CODART)); const char sevaso = riga->get_char(sheet.cid2index(S_EVASO)); if (scodart == codart && sevaso != 'X') { int qtadacon = riga->get_int(sheet.cid2index(S_DACONS)); int pacchi = riga->get_int(pospa); pacchi += 1; int qtacon = riga->get_int(posco); qtacon += qtapacco; riga->add(pacchi, pospa); riga->add(qtacon, posco); if (qtacon > qtadacon) { warning_box(TR("ATTENZIONE: si sta consegnando un quantitativo maggiore al dovuto")); riga->add('X', sheet.cid2index(S_EVASO)); } if (qtacon == qtadacon) riga->add('X', sheet.cid2index(S_EVASO)); trovato = true; _pacchi.add(codpacco, kdoc); } } if (!trovato) { if(yesno_box(TR("Si desidera provare a sommare il pacco a una riga già evasa?"))) { FOR_EACH_SHEET_ROW(sheet, r, riga) { const TString80 scodart = riga->get(sheet.cid2index(S_CODART)); if (scodart == codart) { int pacchi = riga->get_int(pospa); pacchi += 1; int qtacon = riga->get_int(posco); qtacon += qtapacco; riga->add(pacchi, pospa); riga->add(qtacon, posco); trovato = true; _pacchi.add(codpacco, kdoc); } } } } if (!trovato) warning_box(TR("Non è stato possibile sommare il pacco a nessuna riga del buono")); } } } } void TEvasione_msk:: on_idle() { TMask::on_idle(); if (_autoselect >= 0 && get(F_BARCODE).full()) { reset(F_BARCODE); field(F_BARCODE).set_focus(); _autoselect = -1; } } //ON_FIELD_EVENT: metodo che gestisce gli eventi sui campi della maschera bool TEvasione_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) evadi_tutto(); } break; case DLG_PREVIEW: { riordina_righe(); } break; case DLG_ELABORA: { if (e == fe_button) if (controlla()) genera_documento(); 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_tutto(); else { spezza_riga(); genera_documento(); } } else riordina_righe(); } } break; case DLG_SAVEREC: { if (e == fe_button) salva(); } break; case DLG_CANCEL: { if (e == fe_button && jolly == 0) { annulla_operazioni(); return false; } } break; case F_NDOC: { if (e == fe_modify) if (f.get_long() > 0) carica_righe(); else { sfield(F_RIGHE).destroy(); disable(DLG_SELECT); disable(DLG_PREVIEW); disable(DLG_ELABORA); disable(DLG_SAVEREC); disable(DLG_CANCEL); reset(F_STATO); reset(F_DATADOC); setta_campi_data(); reset(F_CODCF); setta_campi_cliente(); hide(F_RIGHE); } } break; case F_DATADOC: { if (e == fe_modify) setta_campi_data(); } break; case F_CODCF: { if (e == fe_modify) setta_campi_cliente(); } break; case F_BARCODE: { if (e == fe_modify && f.get().full()) { _autoselect = 1; evadi_da_barcode(); sfield(F_RIGHE).force_update(); if (controlla()) send_key(K_SPACE, DLG_ELABORA); } } break; case S_CONSEGNATO: { if (e == fe_modify) { TSheet_field& sheet = sfield(F_RIGHE); TMask& msk = sheet.sheet_mask(); //la riga risulta evasa se la quantità consegnata è maggiore o uguale alla quantità da consegnare if(msk.get_long(S_CONSEGNATO) > msk.get_long(S_DACONS)) { warning_box(TR("ATTENZIONE: si sta consegnando un quantitativo maggiore al dovuto")); msk.set(S_EVASO, "X"); TToken_string& riga = sheet.row(sheet.selected()); riga.add("X", sheet.cid2index(S_EVASO)); sheet.disable_row(sheet.selected()); } else if (msk.get_long(S_CONSEGNATO) == msk.get_long(S_DACONS)) { msk.set(S_EVASO, "X"); TToken_string& riga = sheet.row(sheet.selected()); riga.add("X", sheet.cid2index(S_EVASO)); sheet.disable_row(sheet.selected()); } sistema_pacchi(); if (controlla()) send_key(K_SPACE, DLG_ELABORA, &f); } } break; case S_PACCHI: { if (e == fe_modify) sistema_quantita(); } break; default:break; } return true; } //metodo costruttore che precarica i campi di interesse sulla maschera TEvasione_msk::TEvasione_msk():TAutomask("lv3200a") { //precarico i campi fissi set(F_CODNUM, ini_get_string(CONFIG_DITTA, "lv", "NUM_PRE", NULL, 0)); set(F_TPDOC, 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_DESCR, tpdoc.get("S0")); TDate data(TODAY); TEsercizi_contabili es; int annoes = es.date2esc(data); set(F_ANNO, annoes); _tpev = main_app().argv(2); if (_tpev == "B") { _autoselect = 1; show(F_BARCODE); } else { _autoselect = -1; hide(F_BARCODE); } hide(F_RIGHE); disable(DLG_SELECT); disable(DLG_PREVIEW); disable(DLG_ELABORA); disable(DLG_SAVEREC); disable(DLG_CANCEL); //_ndoc = 0; } ///////////////////////////// //// TEVASIONE_APP //// ///////////////////////////// //classe TEvasione_app class TEvasione_app : public TSkeleton_application { TEvasione_msk* _msk; protected: virtual bool create(); virtual bool destroy(); public: bool transfer(); virtual void main_loop(); }; //CREATE: metodo costruttore bool TEvasione_app::create() { _msk = new TEvasione_msk; open_files(LF_DOC, LF_RIGHEDOC); return TSkeleton_application::create(); } //DESTROY: metodo distruttore bool TEvasione_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_app::transfer() { return true; } void TEvasione_app::main_loop() { while (_msk->run() == K_ENTER) transfer(); } int lv3200(int argc, char *argv[]) { TEvasione_app a; a.run (argc, argv, "Evasione Buoni di Prelievo"); return TRUE; }