#include "velib04.h" #include "velib04d.h" #include /////////////////////////////////////////////////////////// // TConsegna ordini mask /////////////////////////////////////////////////////////// class TConsegna_mask : public TAutomask { bool _ordina_per_codice; bool _ignora_descrizioni; const TDocumento* _doc; protected: virtual bool on_field_event(class TOperable_field& f, TField_event e, long jolly); public: void doc2mask(const TDocumento& doc, const TString & articolo); TConsegna_mask(int header_code = 0, bool per_codice = false, bool ignora_descrizioni = false); }; bool TConsegna_mask::on_field_event(class TOperable_field& f, TField_event e, long jolly) { bool update_row = false; switch (f.dlg()) { case S_QTADAEVADERE: if (e == fe_modify && jolly > 0) { TMask& m = f.mask(); const real qta_residua = m.get_real(S_QTARESIDUA); const real qta_daevadere = m.get_real(S_QTADAEVADERE); if (qta_daevadere > ZERO) { m.set(S_RIGACONSEGNATA, "X"); if (qta_daevadere >= qta_residua) { m.set(S_RIGAEVASA, "X"); m.disable(S_RIGAEVASA); } else m.enable(S_RIGAEVASA); } else { m.set(S_RIGAEVASA, " "); m.enable(S_RIGAEVASA); } update_row = !m.is_running(); } break; case S_RIGAEVASA: if (e == fe_modify && jolly > 0 && f.get().not_empty()) { TMask& m = f.mask(); const real qta_daevadere = m.get_real(S_QTADAEVADERE); if (qta_daevadere.is_zero()) { const TString& residuo = m.get(S_QTARESIDUA); m.set(S_QTADAEVADERE, residuo, true); update_row = !m.is_running(); } } break; case F_CONSEGNA: if (e == fe_button) { TSheet_field& s = sfield(F_ROWS); FOR_EACH_SHEET_ROW(s, n, row) if (!s.cell_disabled(n,S_RIGACONSEGNATA-FIRST_FIELD)) { bool select = true; const real residuo = row->get(S_QTARESIDUA-FIRST_FIELD); const real evaso = row->get(S_QTADAEVADERE-FIRST_FIELD); if (evaso == ZERO && residuo > ZERO) { row->add(residuo.string(), S_QTADAEVADERE-FIRST_FIELD); row->add("X", S_RIGAEVASA-FIRST_FIELD); s.disable_cell(n, S_RIGAEVASA-FIRST_FIELD); } if (evaso == ZERO && residuo == ZERO) { const int nriga = row->get_int(S_NUMRIGA-FIRST_FIELD); const TRiga_documento& rdoc = (*_doc)[nriga]; select = rdoc.quantita().is_zero(); } if (select) row->add("X", S_RIGACONSEGNATA-FIRST_FIELD); } s.force_update(); } break; case F_ROWS: if (e == se_query_add || e == se_query_del) return false; default:break; } if (update_row) { TSheet_field& s = sfield(F_ROWS); const int riga = s.selected(); s.update_row(riga); s.force_update(riga); } return true; } int rows_sort_func(TSheet_field& s, int i, int j) { const TToken_string& s1 = s.row(i); const TToken_string& s2 = s.row(j); TString80 ss1, ss2; TDate dd1, dd2; real rr1, rr2; const int fields[] = { S_CODART, S_LIVGIAC1, S_LIVGIAC2, S_LIVGIAC3, S_LIVGIAC4, S_CODMAG, S_CODDEP, S_RIGAEVASA, S_DATACONS, S_QTARESIDUA, -1 }; int ret = 0; for (short field = 0; fields[field] > 0; field++) { if (fields[field] == S_QTARESIDUA) { s1.get(fields[field]-FIRST_FIELD, rr1); s2.get(fields[field]-FIRST_FIELD, rr2); ret = rr2 < rr1 ? -1 : (rr2 > rr1 ? 1 : 0); } else { s1.get(fields[field]-FIRST_FIELD ,ss1); s2.get(fields[field]-FIRST_FIELD ,ss2); if (fields[field] == S_DATACONS) { dd1 = ss1; dd2 = ss2; ret = int (dd1.date2ansi() - dd2.date2ansi()); } else ret = ss1.compare(ss2); } if (ret != 0) break; } return ret; } void TConsegna_mask::doc2mask(const TDocumento& doc, const TString & articolo) { TWait_cursor hourglass; _doc = &doc; for (int n = fields()-1; n >= 0; n--) { TMask_field& f = fld(n); const TFieldref* fr = f.field(); if (fr) { const TString& val = doc.get(fr->name()); f.set(val); } } const bool show_evaded = doc.tipo().mostra_righe_evase_in_elaborazione(); TSheet_field& s = sfield(F_ROWS); s.destroy(); const int rows = doc.physical_rows(); int rowno = 0; for (int i = 0; i < rows; i++) { const TRiga_documento& rec = doc[i+1]; const real residuo = rec.qtaresidua(); const bool evasa = residuo.is_zero(); bool show_line = show_evaded || !evasa; if (rec.is_descrizione()) show_line = !_ignora_descrizioni; if ( show_line && (articolo.blank() || articolo == rec.get(RDOC_CODART)) ) { TToken_string& r = s.row(-1); r = " "; if (evasa) r.add(" "); else r.add(residuo.string()); r.add(" "); // Da evadere if (evasa) { s.disable_cell(rowno, -1); // Disbilita tutta la riga ... s.enable_cell(rowno, 0); // ... tranne il flag di consegna r.add("X"); // La considera evasa } else r.add(" "); r.add(rec.get(RDOC_CODMAG).left(3)); r.add(rec.get(RDOC_CODMAG).mid(3)); r.add(rec.get(RDOC_CODART)); const TString& livello = rec.get(RDOC_LIVELLO); for (int l = 1; l <= 4; l++) r.add(livelli_giacenza().unpack_grpcode(livello, l)); if (rec.get_date(RDOC_DATACONS).ok()) r.add(rec.get_date(RDOC_DATACONS)); else r.add(doc.get_date(DOC_DATACONS)); r.add(rec.get(RDOC_PREZZO), s.cid2index(S_PREZZO)); r.add(rec.get(RDOC_DESCR), s.cid2index(S_DESCR)); r.add(rec.get(RDOC_TIPORIGA), s.cid2index(S_TIPORIGA)); r.add(rec.get(RDOC_NRIGA),s.cid2index(S_NUMRIGA)); r.add(rec.get(RDOC_CODAGG1),s.cid2index(S_CODAGG1)); r.add(rec.get(RDOC_CODAGG2),s.cid2index(S_CODAGG2)); rowno++; } } if (_ordina_per_codice) s.sort(rows_sort_func); } TConsegna_mask::TConsegna_mask(int header_code, bool per_codice, bool ignora_descrizioni) : TAutomask("velib04d"), _ordina_per_codice(per_codice), _doc(NULL), _ignora_descrizioni(ignora_descrizioni) { TCodgiac_livelli cl; TSheet_field& s = sfield(F_ROWS); cl.set_sheet_columns(s, S_LIVGIAC1); if (header_code == 1) { s.set_column_header(S_QTARESIDUA, HR("Quantita'\nconsegnata")); s.sheet_mask().field(S_QTARESIDUA).set_prompt(PR("Q.ta' consegnata")); s.set_column_header(S_QTADAEVADERE, HR("Quantita'\nda fatturare")); s.sheet_mask().field(S_QTADAEVADERE).set_prompt(PR("Q.ta' da fatturare")); } else if (header_code == 2) { s.set_column_header(S_QTARESIDUA, HR("Residuo")); s.sheet_mask().field(S_QTARESIDUA).set_prompt(PR("Residuo ")); s.set_column_header(S_QTADAEVADERE, HR("Da evadere")); s.sheet_mask().field(S_QTADAEVADERE).set_prompt(PR("Da evadere ")); } TConfig c(CONFIG_DITTA, "ve"); for (int i = 1; i <= 2; i++) { TString8 n; n.format("CODAGG%d", i); if (c.exist(n)) { const short id = i == 1 ? S_CODAGG1 : S_CODAGG2; TString80 codagg = c.get(n); TMask_field& agg = s.sheet_mask().field(id); s.set_column_header(id, codagg); codagg.rpad(strlen(agg.prompt())); agg.set_prompt(codagg); } } } /////////////////////////////////////////////////////////// // TConsegna ordini /////////////////////////////////////////////////////////// bool TConsegna_ordini::calcola_ncolli_tara_pnetto(const TString& codart, const real& qta, real& ncolli, real& tara, real& pnetto) const { const TRectype& articolo = cache().get(LF_ANAMAG, codart); const real ppcollo = articolo.get_real(ANAMAG_PPCOLLO); if (ppcollo > ZERO) { ncolli = qta / ppcollo; ncolli.ceil(0); } else ncolli = ZERO; tara = ncolli * articolo.get_real(ANAMAG_TARA); pnetto = qta * articolo.get_real(ANAMAG_PESO); return true; } bool TConsegna_ordini::aggiorna_ncolli_tara_pnetto(TRiga_documento& r) const { const TString& codart = r.get(RDOC_CODARTMAG); TArticolo& articolo = cached_article(codart); const real qta = articolo.convert_to_um(r.quantita(), NULL, r.get(RDOC_UMQTA)); real ncolli, tara, pnetto; const bool ok = calcola_ncolli_tara_pnetto(codart, qta, ncolli, tara, pnetto); if (ok) { r.put(RDOC_NCOLLI, ncolli); r.put(RDOC_TARA, tara); r.put(RDOC_PNETTO, pnetto); } return ok; } bool TConsegna_ordini::genera_righe_riferimento(const TDocumento& indoc, TDocumento& outdoc, TSheet_field& s) const { // Determina ed eventualmente crea la riga di riferimento const int riga_rif = riferimenti_in_testa() ? 1 : outdoc.physical_rows()+1; if (riga_rif > outdoc.physical_rows()) { TRiga_documento& rout = outdoc.new_row(); rout.forza_sola_descrizione(); } TRiga_documento& rout = outdoc[riga_rif]; TString memo(1024); memo = rout.get(RDOC_DESCR); if (rout.get_bool(RDOC_DESCLUNGA)) memo << rout.get(RDOC_DESCEST); // Costruisce la stringa di riferimento TString rifrow(indoc.tipo().descrizione()); TString rifext; indoc.riferimento(rifext); const int posrif = rifext.find("[RIF]"); if (rifext.full() && posrif < 0) { rifrow = rifext; rifext.cut(0); } const TString4 numrif = num_riferimenti_in(); if (numrif.full()) { TAssoc_array doc_rows; TString riferimenti; FOR_EACH_SHEET_ROW(s, n, row) { const int r = row->get_int(s.cid2index(S_NUMRIGA)); if (row->get_char(0) > ' ') // E' da consegnare? { const TRiga_documento& rin = indoc[r]; TString query("USE RDOC KEY 4"); TString select; const char provv = rin.get_char(RDOC_PROVV); const int anno = rin.get_int(RDOC_ANNO); const TString4 codnum = rin.get(RDOC_CODNUM); const long ndoc = rin.get_long(RDOC_NDOC); const int idriga = rin.get_int(RDOC_IDRIGA); query << "\nSELECT CODNUM=\"" << numrif << '\"'; select.format("DAPROVV=\"%c\" DAANNO=%d DACODNUM=\"%s\" DANDOC=%ld DAIDRIGA=%d", provv, anno, (const char *) codnum, ndoc, idriga); query << "\nFROM " << select; query << "\nTO " << select; TISAM_recordset recset(query); for (bool ok = recset.move_first(); ok; ok = recset.move_next()) { const char provv = recset.get(RDOC_PROVV).as_string()[0]; const int anno = recset.get(RDOC_ANNO).as_int(); const TString4 codnum = recset.get(RDOC_CODNUM).as_string(); const long ndoc = recset.get(RDOC_NDOC).as_int(); TString doc_key; doc_key.format("%c|%d|%s|%ld", provv, anno, (const char *) codnum, ndoc); if (!doc_rows.is_key(doc_key)) { const TDocumento d(provv, anno, codnum, ndoc); TString rif; if (!d.empty()) { d.riferimento(rif); TString80 nrifin = d.get(DOC_NUMDOCRIF); if (nrifin.blank()) nrifin = d.get(DOC_DOC1); if (nrifin.blank()) nrifin = d.get(DOC_DOC2); if (nrifin.blank()) nrifin = d.get(DOC_DOC3); if (usa_doc_rif() && nrifin.full()) { rif << " n. " << nrifin; rif << " del " << d.get(DOC_DATADOCRIF); } else { rif << " n. " << d.numero(); rif << " del " << d.data().string(); } if (riferimenti.full()) riferimenti << '\n'; riferimenti << rif; } doc_rows.add(doc_key); } } } } memo.insert(riferimenti); } TString80 nrif = indoc.get(DOC_NUMDOCRIF); if (nrif.blank()) nrif = indoc.get(DOC_DOC1); if (nrif.blank()) nrif = indoc.get(DOC_DOC2); if (nrif.blank()) nrif = indoc.get(DOC_DOC3); if (usa_doc_rif() && nrif.full()) { rifrow << " n. " << nrif; rifrow << " del " << indoc.get(DOC_DATADOCRIF); } else { rifrow << " n. " << indoc.numero(); rifrow << " del " << indoc.data().string(); } if (memo.full()) memo << '\n'; if (rifext.blank()) memo << rifrow; else { if (posrif >= 0) { int i ; for (i = 0; rifext[posrif + i + 5] != '\0'; i++) rifext[posrif + i] = rifext[posrif + i + 5]; rifext[posrif + i] = '\0'; rifext.insert(rifrow, posrif); } memo << rifext; } rout.put(RDOC_DESCLUNGA, memo.len() > 50); rout.put(RDOC_DESCR, memo.left(50)); rout.put(RDOC_DESCEST, memo.mid(50)); rout.put("RIFR", "X"); return true; } bool TConsegna_ordini::elabora(TLista_documenti& doc_in, TLista_documenti& doc_out, const TDate& data_elab, bool interattivo) { const int items_in = doc_in.items(); const int items_out = doc_out.items(); CHECK(items_in > 0, "Nessun documento da elaborare"); CHECK(items_out> 0, "Nessun documento da generare"); CHECK(items_in == 1 || items_out == 1 || items_out == items_in, "Numero di documenti da elaborare 'strano'"); bool ok = false; // Ho elaborato almeno una riga? const int header_code = intestazioni_sheet(); TConsegna_mask m(header_code, ordina_per_codice(), get_bool("B3")); const int items_max = items_in > items_out ? items_in : items_out; const TString& articolo = params().get("ARTICOLO"); const bool multi_evasion = interattivo && articolo.full() && !real::is_null(params().get("QUANTITA")); pre_process_input(doc_in); for (int d = 0; d < items_max; d++) { TDocumento& indoc = doc_in[d < items_in ? d : 0]; TDocumento& outdoc = doc_out[d < items_out ? d : 0]; m.doc2mask(indoc, articolo); if (multi_evasion) { const TString& um = params().get("UM"); m.show(F_UMQTA); m.set(F_UMQTA, um); int dec = 5; TReal_field& fld_qta = (TReal_field&)m.efield(F_QTA); const TRectype& rum = cache().get("%UMS", um); if (!rum.empty() && rum.get_bool("B0")) dec = rum.get_int("I0"); fld_qta.set_decimals(dec); fld_qta.show(); fld_qta.set(params().get("QUANTITA")); } else { m.hide(F_UMQTA); m.hide(F_QTA); } if (m.run() != K_ENTER) break; TSheet_field& s = m.sfield(F_ROWS); bool one_checked = false; if (!s.empty()) { FOR_EACH_SHEET_ROW(s, n, row) { one_checked = row->get_char(0) > ' '; // E' da consegnare?; if (one_checked) break; } } if (!one_checked) continue; // Genera riferimenti solo se c'e' almeno una riga spuntata if (gestione_riferimenti()) genera_righe_riferimento(indoc, outdoc, s); TToken_string campi_riga(80); const bool ragg_rig = raggruppa_righe(); if (ragg_rig) { campi_riga = "CODART|LIVELLO|UMQTA"; // Uguali sempre // Uguali opzionalmente if (riga_uguale(0)) campi_riga.add("CODMAG"); if (riga_uguale(1)) campi_riga.add("CODIVA"); if (riga_uguale(2)) campi_riga.add("PREZZO|SCONTO"); } const bool evadi = outdoc.tipo().da_evadere(); TAssoc_array scarti; FOR_EACH_SHEET_ROW(s, n, row) { const int r = row->get_int(s.cid2index(S_NUMRIGA)); TRiga_documento& inrec = indoc[r]; if (row->get_char(0) > ' ') // E' da consegnare? { const real daeva = row->get(S_QTADAEVADERE - FIRST_FIELD); const bool eva = row->get_char(S_RIGAEVASA - FIRST_FIELD) > ' '; if (evadi && (daeva > ZERO || eva)) { ok = true; // Ho evaso almeno una riga! const char* fqe = inrec.field_qtaevasa(); inrec.add(fqe, daeva); // nuovo modo di incrementare inrec.put(RDOC_RIGAEVASA, eva ? "X" : ""); if (eva && calcola_scarti()) { real scarto = inrec.quantita() - inrec.qtaevasa(); if (scarto > ZERO) { const TString& articolo = inrec.get(RDOC_CODARTMAG); if (articolo.full()) { TToken_string* ska = (TToken_string*)scarti.objptr(articolo); if (ska == NULL) { ska = new TToken_string(inrec.get(RDOC_UMQTA)); ska->add(scarto.string(), 1); scarti.add(articolo, ska); } else { scarto = inrec.articolo().convert_to_um(scarto, inrec.get(RDOC_UMQTA), ska->get(0)); real s = ska->get(1); s += scarto; ska->add(s.string(), 1); } ska->add(r, 2); } } } } if (multi_evasion) { const TString4 um = inrec.get(RDOC_UMQTA); const real qta = inrec.articolo().convert_to_um(daeva, params().get("UM"), um); params().set("QUANTITA", params().get_real("QUANTITA") - qta); } bool elaborata = false; if (ragg_rig) { for (int i = 1; i <= outdoc.physical_rows(); i++) { TRiga_documento& outrec = outdoc[i]; if (outrec.sola_descrizione()) // Ignora le righe descrittive continue; if (inrec.raggruppabile(outrec, campi_riga)) // Se esiste una riga compatibile ... { if (!daeva.is_zero()) { const TString& qta_field = outrec.field_qta(); outrec.add(qta_field, daeva); // nuovo modo di incrementare real ncolli, tara, pnetto; calcola_ncolli_tara_pnetto(outrec.get(RDOC_CODARTMAG), daeva, ncolli, tara, pnetto); outrec.add(RDOC_NCOLLI, ncolli); outrec.add(RDOC_TARA, tara); outrec.add(RDOC_PNETTO, pnetto); outrec.dirty_fields(); // Forza ricalcolo formule } elaborata = true; // Ricorda di averla gia' elaborata break; } } } if (!elaborata) // Se la riga non e' stata gia' sommata ... { int j = outdoc.physical_rows(); const bool ordina_per_doc = ini_get_bool(CONFIG_DITTA, "ve", "ORDINA_PER_DOC", true); if (ordina_per_doc) { TToken_string key = inrec.get_rdoc_key(); key.add("",4); for (; j >= 1; j--) { TToken_string keyrow = outdoc[j].get_original_rdoc_key(); keyrow.add("",4); if (key == keyrow) break; } } const TString4 tiporiga = inrec.get(RDOC_TIPORIGA); TRiga_documento& outrec = j < 1 || j >= outdoc.physical_rows() ? outdoc.new_row(tiporiga) : outdoc.insert_row(j + 1, tiporiga); const TString& qta_field_orig = inrec.field_qta(); const TString& qta_field = outrec.field_qta(); const TString& qtaevasa_field = inrec.field_qtaevasa(); TDocumento::copy_data(outrec, inrec); if (qta_field_orig != RDOC_QTA) { outrec.put(RDOC_QTA, UNO); outrec.put(qta_field_orig, daeva); } else { outrec.put(qta_field, daeva); if (qta_field != RDOC_QTA) outrec.put(RDOC_QTA, UNO); } aggiorna_ncolli_tara_pnetto(outrec); if (kill_descrizione_estesa() && outrec.tipo().tipo() != RIGA_DESCRIZIONI) // Cancello eventualmente la descrizione estesa { outrec.zero(RDOC_DESCLUNGA); outrec.zero(RDOC_DESCEST); } outrec.dirty_fields(); // Forza ricalcolo peso etc. outrec.zero(qtaevasa_field); // Azzera quantita' evasa erroneamente copiata dall'ordine outrec.zero(RDOC_RIGAEVASA); // Azzera flag di evasa erroneamente copiata dall'ordine outrec.set_original_rdoc_key(inrec); if (reload_prices()) { outrec.zero(RDOC_CHECKED); const TString& codiva = outdoc.codesiva(); if (codiva.full()) outrec.put(RDOC_CODIVA, codiva); const TString& codart = outrec.get(RDOC_CODARTMAG); if (codart.full() && reload_descriptions()) { const TRectype& anamag = cache().get(LF_ANAMAG, codart); outrec.put(RDOC_DESCR, anamag.get(ANAMAG_DESCR)); // Euroforesi 12/01/2012 richiede anche descrizione aggiuntiva const TString& agg = anamag.get(ANAMAG_DESCRAGG); if (agg.full()) { outrec.put(RDOC_DESCLUNGA, true); outrec.put(RDOC_DESCEST, agg); } else { outrec.zero(RDOC_DESCLUNGA); outrec.zero(RDOC_DESCEST); } } } if (prezzo_da_ordine()) { //const bool doc_al_lordo = outdoc.tipo().calcolo_lordo(); const TString & codart = outrec.get(RDOC_CODARTMAG); const TRectype & anamag = cache().get(LF_ANAMAG, codart); if (!anamag.empty()) { const TString16 field_prezzo = outdoc.tipo().field_prezzo(); if (field_prezzo.full()) outrec.put(RDOC_PREZZO, anamag.get_real(field_prezzo)); else { const TString4 um = outrec.get(RDOC_UMQTA); if (um.full()) { TLocalisamfile umart(LF_UMART); umart.setkey(2); umart.put(UMART_CODART, codart); umart.put(UMART_UM, um); if (umart.read() == NOERR) outrec.put(RDOC_PREZZO, umart.get_real(UMART_PREZZO)); } } } } const int last_row = outdoc.physical_rows(); if (j > 0 && last_row > 0 && gestione_riferimenti()) { const TRiga_documento& last_rdoc = outdoc[last_row]; if (last_rdoc.is_descrizione() && last_rdoc.get("RIFR").full()) outdoc.destroy_row(last_row, true); } } } } // Inserisce le eventuali righe di scarto al posto giusto FOR_EACH_ASSOC_OBJECT(scarti, h, codart, obj) { TString4 tiporiga = "01"; // Riga merce standard int i = 0; // Cerca l'ultima riga del documento avente lo stesso articolo dello scarto for (i = outdoc.physical_rows(); i > 0; i--) { const TRiga_documento& or = outdoc[i]; if (or.get(RDOC_CODARTMAG) == codart && or.is_articolo()) { tiporiga = or.get(RDOC_TIPORIGA); // Memorizza tipo riga preferito dall'utente break; } } // Crea una nuova riga merce senza articolo e con sola descrizione, qta ed um TRiga_documento& outrec = outdoc.insert_row(i+1, tiporiga); TString descr; descr << TR("Scarto") << ' ' << codart; outrec.put(RDOC_DESCR, descr); TToken_string& ska = *(TToken_string*)obj; outrec.put(RDOC_UMQTA, ska.get(0)); outrec.put(RDOC_QTA, ska.get()); const TRiga_documento & inrec = indoc[ska.get_int()]; outrec.set_original_rdoc_key(inrec); } if (reload_prices()) { TDocumento_mask * m = new TDocumento_mask(outdoc.get(DOC_TIPODOC)); m->doc() = outdoc; m->doc2mask(); m->mask2doc(); outdoc = m->doc(); delete m; } if (nettifica()) { FOR_EACH_PHYSICAL_RDOC_BACK(indoc, i, rdoc) { TRiga_documento& inrec = *rdoc; const int nrow = inrec.get_int(RDOC_NRIGA); if (inrec.is_evasa()) indoc.destroy_row(i, true); else { const real evaso = inrec.qtaevasa(); const char* fq = inrec.field_qta(); const char* fqe = inrec.field_qtaevasa(); inrec.add(fq, -evaso); // nuovo modo di incrementare inrec.zero(fqe); } } } if (indoc.is_evaso()) indoc.stato(stato_finale_doc_iniziale()[0]); } if (ok) // Ho elaborato almeno una riga? { post_process_input(doc_in); post_process(doc_out, doc_in); } return ok; }