#include "tp0100.h" #include "../ve/velib.h" #include "../mg/codcorr.h" /////////////////////////////////////////////////////////// // Cache articoli /////////////////////////////////////////////////////////// class TCache_art : public TCache_tp { TLocalisamfile _anamag; protected: virtual TObject* key2obj(const char* key); virtual const TString& decode(const TToken_string& tok); bool get_extra_info(const char* key, TString& pc, TString& cc) const; public: const TRectype& articolo(); TCache_art(TPack_ddt* ddt) : TCache_tp(ddt), _anamag(LF_ANAMAG) {} }; bool TCache_art::get_extra_info(const char* key, TString& pc, TString& cc) const { TString qry(512); qry << query_header(); qry << "SELECT Paper_Composition_Group.CompDesc, Mag_Existing_Article.ArticleCustCode\n" << "FROM Mag_Existing_Article, Articles_Composition, Paper_Composition_Group\n" << "WHERE (Mag_Existing_Article.ArtCode='" << key << "') AND " << "(Mag_Existing_Article.ArticleCode=Articles_composition.ArticleCode) AND " << "(Articles_Composition.CompCode=Paper_Composition_Group.CompCode);"; TODBC_recordset paperset(qry); const bool ok = paperset.move_first(); if (ok) { pc = paperset.get(0u).as_string(); // Paper composition cc = paperset.get(1).as_string(); // Customer code if (cc.full()) { int righe = 0; bool found = false; { //per far chiudere il file CODCORR TISAM_recordset alternative("USE CODCORR\nFROM CODART=#COD\nTO CODART=#COD"); alternative.set_var("#COD", TVariant(key)); righe = alternative.items(); for (bool ok = alternative.move_first(); ok && !found; ok = alternative.move_next()) found = alternative.get(CODCORR_CODARTALT).as_string() == cc; } if (!found) { TLocalisamfile codcorr(LF_CODCORR); codcorr.zero(); codcorr.put(CODCORR_CODART, key); codcorr.put(CODCORR_NRIGA, righe+1); codcorr.put(CODCORR_TIPO, 'C'); codcorr.put(CODCORR_CODARTALT, cc); test_write(codcorr); } } } return ok; } TObject* TCache_art::key2obj(const char* key) { if (key && *key > ' ') // Non salvo i codici vuoti presenti nelle righe descrizione { _anamag.put(ANAMAG_CODART, key); if (_anamag.read() != NOERR) { _anamag.zero(); _anamag.put(ANAMAG_CODART, key); const TString& desc = get_str("ArtDesc"); _anamag.put(ANAMAG_DESCR, desc); const TString& conai_class = get_str("ClassCode"); if (conai_class.full()) { const TString& conai_field = config().get(conai_class, "CONAI"); if (conai_field.full()) _anamag.put(conai_field, get_real_str("WeightETUnit")); } const long gruconto = get_long("AccountCode"); const long sottoconto = get_long("AccountSubCode"); _anamag.put(ANAMAG_GRUPPOV, gruconto / 1000); _anamag.put(ANAMAG_CONTOV, gruconto % 1000); _anamag.put(ANAMAG_SOTTOCV, sottoconto); test_write(_anamag); } // Non memorizzo permanentemente questi dati ma li rendo disponibili TString paper_composition, customer_code; if (get_extra_info(key, paper_composition, customer_code)) { _anamag.put(ANAMAG_USER10, paper_composition); _anamag.put(ANAMAG_USER9, customer_code); } } else _anamag.zero(); return _anamag.curr().dup(); } const TRectype& TCache_art::articolo() { TString80 codart = get_str("ArtCode"); if (codart.empty()) // Se non ho un codice articolo lo creo in base al conto { const long gruconto = get_long("AccountCode"); const long sottoconto = get_long("AccountSubCode"); if (gruconto > 0 && sottoconto > 0) codart << "*" << gruconto << '*' << sottoconto; } return *(const TRectype*)objptr(codart); } const TString& TCache_art::decode(const TToken_string& tok) { const TRectype& rec = *(const TRectype*)objptr(tok); return rec.get(ANAMAG_CODART); } /////////////////////////////////////////////////////////// // Cache unita' di misura degli articoli /////////////////////////////////////////////////////////// class TCache_umart : public TCache_tp { protected: virtual TObject* key2obj(const char* key); public: const TString& decode(const TToken_string& key) { return *(const TString*)objptr(key); } TCache_umart(TPack_transfer* pt) : TCache_tp(pt) {} }; TObject* TCache_umart::key2obj(const char* key) { TToken_string code(key); TString80 codart; code.get(0, codart); TString4 um; code.get(1, um); TISAM_recordset umart("USE UMART\nFROM CODART=#COD\nTO CODART=#COD"); umart.set_var("#COD", TVariant(codart)); bool found = false; TRecnotype i = 0; for (i = 0; umart.move_to(i) && !found; i++) found = umart.get("UM").as_string() == um; if (!found) { TLocalisamfile umart(LF_UMART); umart.put(UMART_CODART, codart); umart.put(UMART_NRIGA, i+1); umart.put(UMART_UM, um); umart.put(UMART_FC, 1); test_write(umart); } return code.dup(); } /////////////////////////////////////////////////////////// // TPack_ddt /////////////////////////////////////////////////////////// bool TPack_ddt::signal_row_error(const char* m) { const long numrig = get_long("CDocRow"); TString msg; msg << m << TR(" sulla riga ") << numrig; return log_error(msg); } bool TPack_ddt::get_tipodoc(TString& codnum, TString& tipodoc) { bool ok = true; const TString& book = get_str("ReceiptBook"); if (book.full()) { codnum = config().get(book, "CODNUM"); if (codnum.blank()) { TString msg; msg << TR("Non esite una numerazione corrispondente al codice ") << book; ok = log_error(msg); } } else ok = log_error("Impossibile determinare la numerazione"); if (codnum.blank()) codnum = "B01"; // Uso la prima numerazione che mi viene in mente const TString& tipo = get_str("StoreDocType"); if (tipo.full()) { tipodoc = config().get(tipo, "TIPODOC"); if (tipodoc.blank()) { TString msg; msg << TR("Non esite un tipo documento corrispondente al codice ") << tipo; ok = log_error(msg); } } else ok = log_error("Impossibile determinare il tipo del documento"); if (tipodoc.blank()) tipodoc = codnum; return ok; } bool TPack_ddt::get_um_qta(TString& um, real& qta) { const long flag_um = get_long("FlagUMPrice"); const char* field_um = NULL; const char* field_qta = NULL; switch (flag_um) { case 0: field_qta = "Quantity1"; field_um = "UMDesc1"; break; case 2: field_qta = "Quantity2"; field_um = "UMDesc2"; break; default: field_qta = "Quantity"; field_um = "UMDesc"; break; } um = decode_field("%UMS", field_um); qta = recordset().get(field_qta).as_real(); const bool ok = um.full(); if (!ok) signal_row_error(TR("Impossibile determinare l'unita' di misura")); return ok; } const TRectype& TPack_ddt::get_articolo(TString& um, real& qta, TString& custcode) { if (_art == NULL) _art = new TCache_art(this); const TRectype& rec = _art->articolo(); get_um_qta(um, qta); custcode = rec.get(ANAMAG_USER9); if (!rec.empty() && um.full()) { if (_umart == NULL) _umart = new TCache_umart(this); TToken_string key; key = rec.get(ANAMAG_CODART); key.add(um); _umart->decode(key); } return rec; } bool TPack_ddt::save_doc(TDocumento* &doc, const int doccode) { bool ok = false; if (doc != NULL) { if (write_enabled()) { CHECK(doccode != 0, "Codice documento nullo"); const int err = doc->write(); if (err == NOERR) { ok = true; TString cmd; cmd << "UPDATE PDdT_Header SET StatusFlag=0 WHERE DocCode=" << doccode; odbc_exec(cmd); } else { TString msg; msg.format("Errore %d durante la scrittura del documento", err); ok = log_error(msg); } } delete doc; doc = NULL; } return ok; } bool TPack_ddt::get_clifo(char& tipocf, long& codcf) { tipocf = ' '; codcf = 0; const char flag = get_str("FlagCustSupp")[0]; TToken_string code = get_str("CodContab"); switch (flag) { case 'D': case 'C': tipocf = 'C'; code.get(0, codcf); break; case 'N': case 'S': tipocf = 'F'; code.get(0, codcf); break; default : break; } if (codcf > 0 && (tipocf == 'C' || tipocf == 'F')) return true; return log_error(TR("Impossibile determinare il codice del cliente/fornitore")); } const TString& TPack_ddt::get_indsped() const { TToken_string cod_ind = get_str("DestCodContab"); return get_tmp_string() = cod_ind.get(1); } void TPack_ddt::activate_customer_code(bool cc) { _cust_code = cc && !cache().get("%TRI", "14").empty(); } const TString& TPack_ddt::get_codice_iva() { TString4 codiva; TString qry(256); qry << query_header(); qry << "SELECT * FROM IVA WHERE IVACode=#CODIVA"; TODBC_recordset iva(qry); const TString& codivani = get_str("CodIvaNI"); if (codivani.full() && codivani != "0") { iva.set_var("#CODIVA", TVariant(codivani)); if (iva.move_first()) { const TVariant& percent = iva.get("IVAValue"); if (percent.is_empty()) codiva = codivani; } } if (codiva.blank()) { codiva = get_str("IVACode"); iva.set_var("#CODIVA", TVariant(codiva)); if (iva.move_first()) { const TVariant& v = iva.get("xCode"); if (!v.is_empty()) v.as_string(codiva); } } return decode_value("%TPI", codiva); } const TString& TPack_ddt::get_customer_reference() const { const TString& rcr = get_str("RowCustReference"); // Provo a leggerlo dalla riga if (rcr.full()) return rcr; const TString& hcr = get_str("CustReference"); // Provo a leggerlo dalla testata return hcr; } bool TPack_ddt::trasferisci() { const char* query = "SELECT DISTINCT " "PDdT_Header.DocCode, PDdT_Header.StoreDocType, PDdT_Header.DocRefNumber, " "PDdT_Header.DocDate, Store_Year.SyReferenceYear, PDdT_Header.CustSuppCode, " "Customers_Suppliers.FlagCustSupp, Customers_Suppliers.CodContab, Customers_Suppliers.CategoryCode, Customers_Suppliers.ZoneCode, " "Customers_Suppliers_1.CodContab AS AgentCode, " "PDdT_Header.Change, CAMPOCurrencies.UMDesc AS Currency, " "PDdT_Header.PaymentCode, PDdT_Header.ApplyEnvTax, PDdT_Header.DiscountOnPayment, " "CausaliTrasporto.Code AS CodTrasporto, Porto.Code AS CodResa, CausaliTrasporto.Description1 AS TipoTrasporto, " "Porto.Description1 AS TipoResa, PDdT_Header.Appearance, PDdT_Header.GrossWeight, PDdT_Header.NetWeight, " "PDdT_Header.ShiverNumber, (select case when [PDdT_Header].[BankDesc] is null Or [PDdT_Header].[BankDesc]<>''then " "[PDdT_Header].[BankDesc] else [customers_suppliers].[bankname] end) AS BankDesc, PDdT_Header.CodIvaNI, " "Customers_Suppliers_2.CustSuppCode AS DestCode, Customers_Suppliers_2.FlagCustSupp AS FlagDestCode, " "Customers_Suppliers_2.CodContab AS DestCodContab, " "Customers_Suppliers_2.TradeName1, Customers_Suppliers_2.Address, Customers_Suppliers_2.Locality, " "Customers_Suppliers_2.ZipCode, Customers_Suppliers_2.Region, PDdT_Row.DocRow, PDdT_Row.ArtCode, " "PDdT_Row.ArtDesc, PDdT_Row.CDocNumber, PDdT_Row.CDocRow, CDoc_Rows.CustReference AS RowCustReference ,CDoc_Header.CustReference, PDdT_Row.Provv, " "PDdT_Row.DiscountRowDesc, PDdT_Row.Quantity, Unit_Measure.UMDesc, PDdT_Row.Quantity1, Unit_Measure_1.UMDesc AS UMDesc1, " "PDdT_Row.Quantity2, Unit_Measure_2.UMDesc AS UMDesc2, PDdT_Row.AdvanceSale, PDdT_Row.Price, " "PDdT_Row.DefPrice, PDdT_Row.PriceNet, PDdT_Row.PriceNetDef, PDdT_Row.AmountNet, PDdT_Row.AmountNetDef, " "PDdT_Row.Amount, PDdT_Row.AmountDef, PDdT_Row.FlagUMPrice, IVA.IVACode, PDdT_Row.AccountCode, " "PDdT_Row.AccountSubCode, PDdT_Row.WeightETUnit, PDdT_Row.ClassCode, PDdT_Row.SubclassCode, " "PDdT_Row.DDTRowType, PDdT_Header.StatusFlag, PDdT_Row.Report, " "Mag_Existing_Article.ArtType, Mag_Existing_Article.Height, Mag_Existing_Article.Width, Mag_Existing_Article.Lenght, " "(select case when [Modalità Fornitura Bancali].[Value1] is null then 1 else [Modalità Fornitura Bancali].[Value1] end) AS FornituraBancali, " "PDdT_Header.InvoicingType, PDdT_Header.DocProvv, PDdT_Header.ReceiptBook\n" "FROM ((((((PDdT_Header LEFT JOIN Customers_Suppliers ON PDdT_Header.CustSuppCode = Customers_Suppliers.CustSuppCode) " "LEFT JOIN Unit_Measure AS CAMPOCurrencies ON (CAMPOCurrencies.UMcode=PDdT_Header.CurrencyCode AND CAMPOCurrencies.UMType='9') " "LEFT JOIN Customers_Suppliers AS Customers_Suppliers_1 ON PDdT_Header.AgentCode = Customers_Suppliers_1.CustSuppCode) " "LEFT JOIN Porto ON PDdT_Header.PortCode = Porto.Code) " "LEFT JOIN Store_Year ON PDdT_Header.DocYear = Store_Year.SyCode) " "LEFT JOIN Customers_Suppliers AS Customers_Suppliers_2 ON PDdT_Header.DestCode = Customers_Suppliers_2.CustSuppCode) " "LEFT JOIN CausaliTrasporto ON PDdT_Header.DocCausalCode = CausaliTrasporto.Code) " "RIGHT JOIN (Mag_Existing_Article RIGHT JOIN ((CDoc_Header " "RIGHT JOIN (((IVA RIGHT JOIN (((CDoc_Rows RIGHT JOIN PDdT_Row ON (CDoc_Rows.DocNumber = PDdT_Row.CDocNumber) " "AND (CDoc_Rows.RowNumber = PDdT_Row.CDocRow)) " "LEFT JOIN Unit_Measure ON PDdT_Row.UMQty = Unit_Measure.UMCode) " "LEFT JOIN [Modalità Fornitura Bancali] ON PDdT_Row.DeliveryPalletType = [Modalità Fornitura Bancali].Code) " "ON IVA.IVACode = PDdT_Row.IVACode) LEFT JOIN Unit_Measure AS Unit_Measure_1 ON PDdT_Row.UMQta1 = Unit_Measure_1.UMCode) " "LEFT JOIN Unit_Measure AS Unit_Measure_2 ON PDdT_Row.UMQta2 = Unit_Measure_2.UMCode) " "ON CDoc_Header.DocNumber = CDoc_Rows.DocNumber) " "LEFT JOIN CDoc_Rows_Detail ON (CDoc_Rows.RowNumber = CDoc_Rows_Detail.RowNumber) AND " "(CDoc_Rows.DocNumber = CDoc_Rows_Detail.DocNumber)) " "ON Mag_Existing_Article.ArtCode = PDdT_Row.ArtCode) ON PDdT_Header.DocCode = PDdT_Row.DocCode\n" "WHERE (((PDdT_Row.DDTRowType)='0' Or (PDdT_Row.DDTRowType)='2') AND " "((PDdT_Header.StatusFlag)='1' OR (PDdT_Header.StatusFlag)='2' Or (PDdT_Header.StatusFlag)='3') AND " "((select case when [Modalità Fornitura Bancali].[Value1] is null then 1 else [Modalità Fornitura Bancali].[Value1] end)=1) AND " "((PDdT_Header.InvoicingType) Is Not Null) AND ((PDdT_Header.DocProvv)<>-1))"; TRecordset& recset = create_recordset(query); TDocumento* doc = NULL; long curr_ndoc = 0; // Numero in Campo long curr_code = 0; // Numero in Pack TString str; // jolly TString last_custref; TPack_iterator ri(this); while (++ri) { const long code = get_long("DocCode"); const long ndoc = get_long("DocRefNumber"); const TDate datadoc = recset.get("DocDate").as_date(); if (_data_limite.ok() && datadoc > _data_limite) continue; if (ndoc != curr_ndoc) { log(""); str.format(FR("Importazione documento %ld del %s"), ndoc, datadoc.string()); log(str); save_doc(doc, curr_code); curr_ndoc = ndoc; curr_code = code; last_custref.cut(0); // Azzera documento di riferimento TString4 codnum, tipodoc; get_tipodoc(codnum, tipodoc); doc = new TDocumento('D', datadoc.year(), codnum, ndoc); const bool isnew = doc->rows() == 0; if (isnew) { doc->put(DOC_TIPODOC, tipodoc); doc->put(DOC_STATO, 1); doc->put(DOC_DATADOC, datadoc); } else doc->body().destroy_rows(); char tipocf = ' '; long codcf = 0; if (get_clifo(tipocf, codcf)) { doc->put(DOC_TIPOCF, tipocf); doc->put(DOC_CODCF, codcf); doc->put(DOC_CODINDSP, get_indsped()); if (isnew) { TToken_string tok; tok.add(tipocf); tok.add(codcf); const TRectype& cfven = cache().get(LF_CFVEN, tok); doc->put(DOC_RAGGR, cfven.get(CFV_RAGGDOC)); doc->put(DOC_RAGGREFF, cfven.get(CFV_RAGGEFF)); doc->put(DOC_ADDBOLLI, cfven.get(CFV_ADDBOLLI)); doc->put(DOC_PERCSPINC, cfven.get(CFV_PERCSPINC)); const TRectype& clifo = cache().get(LF_CLIFO, tok); doc->put(DOC_CODABIA, clifo.get(CLI_CODABI)); doc->put(DOC_CODCABA, clifo.get(CLI_CODCAB)); } } doc->put(DOC_ZONA, decode_field("ZON", "ZoneCode")); // Crea anche la zona se necessario TToken_string forn_age = get_str("AgentCode"); doc->put(DOC_CODAG, forn_age.get(1)); doc->put(DOC_SCONTOPERC, get_real_str("DiscountOnPayment")); const TString& codval = get_str("Currency"); if (is_firm_value(codval)) { doc->zero(DOC_CODVAL); doc->zero(DOC_CAMBIO); } else { doc->put(DOC_CODVAL, codval); doc->put(DOC_CAMBIO, get_real_str("Change")); } doc->put(DOC_CODPAG, get_str("PaymentCode")); // Il codice pagamento va' gia' bene cosi' doc->put(DOC_CODPORTO, decode_field("%TPP", "PortCode")); // Codice porto decodificato tremite %TPP doc->put(DOC_CODSPMEZZO, decode_field("%TPM", "CodTrasporto")); // Codice porto decodificato tremite %TPM } if (_cust_ref) { const TString& custref = get_customer_reference(); // Aggiungi una riga di descrizione col riferimento cliente se e' cambiato if (custref.full() && custref != last_custref) { last_custref = custref; TRiga_documento& rdoc = doc->new_row("05"); // Crea una riga descrizione rdoc.put(RDOC_DESCR, custref); } } TString4 um; real qta; TString custcode; const TRectype& art = get_articolo(um, qta, custcode); TString4 rowtype = "01"; // Riga merce bool bIsMerce = true; if (qta.is_zero()) { rowtype = "05"; // Se la qta e' nulla allora e' una descrizione bIsMerce = false; } else { if (_cust_code && custcode.full()) rowtype = "14"; } TRiga_documento& rdoc = doc->new_row(rowtype); // Crea una riga del tipo appropriato TString descr = get_str("ArtDesc"); const bool bIsSingleSheet = bIsMerce && get_long("ArtType") == 4; // Foglio singolo? if (bIsSingleSheet && descr.find('(') < 0) // E' un foglio singolo senza dimensioni? { TString80 misure; misure << get_str("Height") << " x " << get_str("Width"); if (misure[0] > '0') descr << " (" << misure << ')'; } if (descr.len() <= 50) rdoc.put(RDOC_DESCR, descr); else { rdoc.put(RDOC_DESCR, descr.left(50)); rdoc.put(RDOC_DESCLUNGA, "X"); rdoc.put(RDOC_DESCEST, descr.mid(50)); } if (bIsMerce) // Ho creato una riga articolo? { const TString& codart = art.get(ANAMAG_CODART); if (codart.full()) // Esistono righe merce senza articolo { rdoc.put(RDOC_CODART, rowtype == "01" ? codart : custcode); rdoc.put(RDOC_CODARTMAG, codart); } rdoc.put(RDOC_CHECKED, "X"); rdoc.put(RDOC_UMQTA, um); rdoc.put(RDOC_QTA, qta); rdoc.put(RDOC_CODIVA, get_codice_iva()); rdoc.put(RDOC_PREZZO, get_real_str("Price")); rdoc.put(RDOC_SCONTO, get_real_str("DiscountRowDesc")); rdoc.put(RDOC_PERCPROV, get_real_str("Provv")); rdoc.put(RDOC_QTAGG1, get_real_str("WeightETUnit")); rdoc.zero(RDOC_QTAGG2); // Azzera percentuale indetraibilita' CONAI if (bIsSingleSheet) rdoc.put(RDOC_QTAGG3, get_real_str("Quantity")); const TString& conai_class = get_str("ClassCode"); rdoc.put(RDOC_CODAGG1, conai_class); rdoc.put(RDOC_CODAGG2, get_str("SubclassCode")); const TString& conai_cfv = config().get(conai_class, "CFV_CONAI"); if (conai_cfv.full()) { TToken_string tok; tok.add(doc->get(DOC_TIPOCF)); tok.add(doc->get(DOC_CODCF)); const TRectype& cfven = cache().get(LF_CFVEN, tok); const real perc = cfven.get(conai_cfv); rdoc.put(RDOC_QTAGG2, perc); } } TString info; if (_paper_info) { info << art.get(ANAMAG_USER10); if (info.full()) info.insert("\n"); TString80 misure; misure << get_str("Height") << 'x' << get_str("Width") << 'x'<< get_str("Lenght"); if (misure[0] > '0') info << "\nMISURE: " << misure; } if (_ref_info) { TString80 docnum = get_str("CDocNumber"); docnum.trim(); if (docnum.full()) info << "\nNS.ORD: " << docnum << '.' << get_str("CDocRow"); const TString& custref = get_customer_reference(); if (custref.full()) info << "\nVS.ORD: " << custref; } if (info.full()) { TString descest; descest << rdoc.get(RDOC_DESCEST) << info; rdoc.put(RDOC_DESCLUNGA, "X"); rdoc.put(RDOC_DESCEST, descest); } if (_cms_ref) { TString ref = get_str("CustReference").before(' '); // Leggo inizio testata es: "1203 DEL 16 02 2006" if (ref.full()) { const TString& r_ref = get_str("RowCustReference"); // Leggo dalla riga if (r_ref.full()) ref << '/' << r_ref << '/' << art.get(ANAMAG_USER9); rdoc.put(RDOC_CODCMS, ref); } } } save_doc(doc, curr_code); return write_enabled(); } TPack_ddt::TPack_ddt() : _art(NULL), _umart(NULL), _cust_ref(false), _paper_info(false), _ref_info(true), _cust_code(false) { } TPack_ddt::~TPack_ddt() { if (_umart != NULL) delete _umart; if (_art != NULL) delete _art; }