#include #include #include #include #include #include #include #include #include #include #include #include #include "pg0388200a.h" #include "../mg/mglib.h" #include "../ve/velib.h" #include "../sv/svlib09.h" #include "../mg/mag.h" //--------------------------------- // TAutomask //--------------------------------- class TImpBol0388_mask : public TAutomask { protected: bool on_field_event(TOperable_field& o, TField_event e, long jolly); bool select_file_ext(const char* ext, TFilename& filename); public: TImpBol0388_mask(); virtual ~TImpBol0388_mask(){}; }; TImpBol0388_mask::TImpBol0388_mask() :TAutomask ("pg0388200a") { } bool TImpBol0388_mask::select_file_ext(const char* ext, TFilename& filename) { TArray_sheet as(-1, -1, 72, 20, TR("Selezione file"), "File@48"); TFilename path = get(F_PATH); path.add("*"); path.ext(ext); list_files(path, as.rows_array()); TFilename name; FOR_EACH_ARRAY_ROW(as.rows_array(), i, row) { name = *row; *row = name.name(); } bool ok = as.run() == K_ENTER; if (ok) { filename = as.row(as.selected()); } return ok; } bool TImpBol0388_mask::on_field_event(TOperable_field& f, TField_event e, long jolly) { switch (f.dlg()) { //giochetto per avere la lista dei files validi nella directory di trasferimento! case F_NAMEBOL: if (e == fe_button) { TFilename name; if (select_file_ext("txt", name)) f.set(name); } break; case F_NAMEINV: if (e == fe_button) { TFilename name; if (select_file_ext("csv", name)) f.set(name); } break; default: break; } return true; } //-------------------------------- // TFile_text //-------------------------------- class TImpBol0388_file: public TFile_text { protected: virtual void validate(TCursor& cur,TRecord_text &rec, TToken_string &val, TString& str); public: TImpBol0388_file(const TString& file_name, char tipo); virtual ~TImpBol0388_file() { } }; TImpBol0388_file::TImpBol0388_file(const TString& file_name, char tipo) : TFile_text(file_name, tipo == 'B' ? "pg0388200a.ini" : "pg0388200b.ini"){} void TImpBol0388_file::validate(TCursor& cur,TRecord_text &rec, TToken_string &s, TString& str) { const TString code(s.get(0)); TString valore = str; if (code == "_UPPERCASE") { valore.upper(); } else NFCHECK("Macro non definita: %s", (const char *)code); str = valore; } //---------------------------------- // TDocumento_cache //---------------------------------- //classe necessaria per avere una lista di documenti in RAM di dimensione limitata class TDocumento_cache : public TArray { public: void flush(); TDocumento& doc(const int anno, const char* codnum, const long ndoc); }; TDocumento& TDocumento_cache::doc(const int anno, const char* codnum, const long ndoc) { TDocumento* doc = NULL; for (int i = 0; i < items(); i++) { TDocumento& d = (TDocumento&)operator[](i); if (d.get(DOC_CODNUM) == codnum) { if (d.get_int(DOC_ANNO) != anno || d.get_long(DOC_NDOC) != ndoc) { const TString& tipodoc = d.get(DOC_TIPODOC); if (tipodoc.full()) d.write(); destroy(i, true); } else doc = &d; break; } } if (doc == NULL) { doc = new TDocumento('D', anno, codnum, ndoc); add(doc); } return *doc; } void TDocumento_cache::flush() { for (int i = 0; i < items(); i++) { const TDocumento& d = (const TDocumento&)operator[](i); const TString& tipodoc = d.get(DOC_TIPODOC); if (tipodoc.full()) d.write(); } destroy(); } //---------------------------------- // TSkeleton_application //---------------------------------- class TImpBol0388 : public TSkeleton_application { TImpBol0388_mask* _msk; TImpBol0388_file* _trasfile; TConfig* _configfile; TDocumento_cache _doc; TRelation* _rel; TCursor* _cur; TProgind* _prog; TString4 _numbol, _tipobol, _numord; int _statobol; long _forbidden_ndoc, _lastbol; TString8 _codmag, _codmag_st; virtual const char * extra_modules() const {return "ba";} protected: void mask2ini(); void ini2mask(); bool transfer(); void transfer_testata(const TRecord_text& curr, TLog_report& log); void transfer_righe(const TRecord_text& curr); void evasione(TRiga_documento& riga_doc, const real& qta) const; int crea_riga_bolla(const TRecord_text& curr, TDocumento& bol, bool is_omaggio); bool transfer_inventario(); public: virtual bool create(); virtual bool destroy(); virtual void main_loop(); TImpBol0388() {} }; TImpBol0388& app() { return (TImpBol0388&) main_app(); } ///////////////////////////////////////////////// // Trasferimento bolle e aggiornamento ordini ///////////////////////////////////////////////// bool TImpBol0388::transfer() { _forbidden_ndoc = 0L; //file da trasferire //costruire il nome del file con path TFilename file = _msk->get(F_PATH); file.add(_msk->get(F_NAMEBOL)); file.ext("txt"); _trasfile = new TImpBol0388_file(file, 'B'); _trasfile->open(file,'r'); //preparazione del log TLog_report log(TR("Trasferimento bolle")); const long dimension = fsize(file); TProgind pi(dimension,TR("Importazione bolle in corso...")); int err = NOERR; TRecord_text curr; //parametri dei documenti da creare ed aggiornare _numbol = _msk->get(F_NUMBOL); _tipobol = _msk->get(F_TIPOBOL); _numord = _msk->get(F_NUMORD); _statobol = _msk->get_int(F_STATOBOL); while (_trasfile->read(curr) == NOERR && !pi.iscancelled() && err == NOERR) { pi.setstatus(_trasfile->read_file()->tellg()); //in base al tipo record scandisce tetate o righe con il relativo tracciato sul .ini const TString& tipo_rec = curr.type(); if (tipo_rec == "TB01") { transfer_testata(curr, log); } if (tipo_rec == "RB01") { transfer_righe(curr); } } _trasfile->close(); delete _trasfile; _doc.flush(); //accoppa la TDocumento_cache TReport_book buc; buc.add(log); buc.preview(); return true; } void TImpBol0388::transfer_testata(const TRecord_text& curr, TLog_report& log) { const long num_bol = atol(curr.get(1)); const TDate datadoc = curr.get(2); const int anno_ord = atoi(curr.get(4)); const long num_ord = atol(curr.get(5)); // creo il documento, se esiste cancello le righe perche' le ricreo successivamente TDocumento& bol = _doc.doc(datadoc.year(), _numbol, num_bol); const bool isnew = bol.rows() == 0; const TString8 causmag = bol.tipo().caus_mov(); _codmag = _codmag_st; if (causmag.full()) { TCausale_magazzino causale(causmag); const TString & magdep = causale.default_magdep(); if (magdep.full()) _codmag = magdep; bol.put(DOC_CAUSMAG, causmag); } if (isnew) { _forbidden_ndoc = 0L; bol.put(DOC_TIPODOC, _tipobol); bol.put(DOC_DATADOC, datadoc); bol.put(DOC_STATO, _statobol); bol.put("DAANNO", anno_ord); bol.put("DANDOC", num_ord); //legge la testata dell'ordine per avere il clifo TDocumento& ordine = _doc.doc(anno_ord, _numord, num_ord); const char tipocf = ordine.get_char(DOC_TIPOCF); const long codcf = ordine.get_int(DOC_CODCF); bol.put(DOC_TIPOCF, tipocf); bol.put(DOC_CODCF, codcf); //codice pagamento e coordinate bancarie TToken_string key; key.add(tipocf); key.add(codcf); const TRectype& rec_clifo = cache().get(LF_CLIFO, key); bol.put(DOC_CODPAG, rec_clifo.get(CLI_CODPAG)); bol.put(DOC_CODABIA, rec_clifo.get_long(CLI_CODABI)); bol.put(DOC_CODCABA, rec_clifo.get_long(CLI_CODCAB)); _lastbol = num_bol; //aggiorna l'indicatore dell'ultima bolla trasferita } else { _forbidden_ndoc = num_bol; TString msg; msg.format(FR("La bolla %ld e' gia' stata trasferita"), num_bol); log.log(1, msg); } } void TImpBol0388::evasione(TRiga_documento& riga_doc, const real& qta) const { const real quantita = riga_doc.quantita(); const real qtaevasa = riga_doc.qtaevasa() + qta; riga_doc.put(riga_doc.field_qtaevasa(), qta); const bool evasa = qtaevasa >= quantita; if (evasa) riga_doc.put(RDOC_RIGAEVASA, evasa); } int TImpBol0388::crea_riga_bolla(const TRecord_text& curr, TDocumento& bol, bool is_omaggio) { //carica i valori dal file di testo... //intanto la quantita', sia fatturata che omaggio const real qta = curr.get(is_omaggio ? 8 : 7); //se la quantita' e' vuota e' inutile proseguire (sara' una riga descrizione trattata a parte) if (qta <= ZERO) return 0; //il numero riga dell'ordine e' aumentato di 1 se omaggio const int nriga_ord = atoi(curr.get(4)) + (is_omaggio ? 1 : 0); TString16 codart = curr.get(5); codart.trim(); TString16 strdata_scad = curr.get(10); strdata_scad.trim(); const TDate data_scad(strdata_scad); const long lotto = atol(curr.get(11)); //TRiga_documento& rdoc = bol.new_row(is_omaggio ? "09" : "01"); TRiga_documento& rdoc = bol.new_row("01"); //legge l'ordine originario della bolla sfruttando i dati noti const int ord_anno = bol.get_int("DAANNO"); const long ord_ndoc = bol.get_long("DANDOC"); TDocumento& ordine = _doc.doc(ord_anno, _numord, ord_ndoc); const int righe_ordine = ordine.physical_rows(); bool da_ordine = nriga_ord > 0 && nriga_ord <= righe_ordine; if (da_ordine) { const TRiga_documento& rdocord = ordine[nriga_ord]; da_ordine = rdocord.get(RDOC_CODART) == codart; // rdocord.get(RDOC_TIPORIGA) == rdoc.get(RDOC_TIPORIGA); } //righe merce da ordine if (da_ordine) { TRiga_documento& rdocord = ordine[nriga_ord]; //copia la riga dell'ordine originale nella riga della bolla, in modo da avere gia'.. //..una parte dei campi completata, e dover solo aggiornare le quantita TDocumento::copy_data(rdoc, rdocord); //Evasione della riga ordine originaria evasione(rdocord, qta); } else //righe merce non da ordine { const TString& codiva = cache().get(LF_ANAMAG, codart, ANAMAG_CODIVA); rdoc.put(RDOC_CODIVA, codiva); TToken_string key; key.format("%s|1", (const char*) codart); const TRectype& rec_umart = cache().get(LF_UMART, key); const TString& um = rec_umart.get(UMART_UM); rdoc.put(RDOC_UMQTA, um); const real prezzo = rec_umart.get(UMART_PREZZO); rdoc.put(RDOC_CODMAG, _codmag); rdoc.put(RDOC_PREZZO, prezzo); rdoc.put(RDOC_CODART, codart); } rdoc.put(RDOC_DESCR, curr.get(6)); rdoc.put(RDOC_QTA, qta); rdoc.put(RDOC_CODAGG1, data_scad); rdoc.put(RDOC_CODAGG2, lotto); if (is_omaggio) { rdoc.put(RDOC_GENERATA, "X"); rdoc.put(RDOC_SCONTO, "100"); } return rdoc.get_int(RDOC_NRIGA); } void TImpBol0388::transfer_righe(const TRecord_text& curr) { const long numbol = atol(curr.get(1)); const TDate datadoc = curr.get(2); const int nriga = atoi(curr.get(3)); if (numbol != _forbidden_ndoc) //non puo' riscrivere righe di una bolla esistente! { // crea la bolla della testata TDocumento& bol = _doc.doc(datadoc.year(), _numbol, numbol); /***prima versione dei file da importare con sottorighe descrizione //deve distinguere le righe speciali di descrizione TString8 str_numriga = curr.get(4); const int riga_descr = atoi(str_numriga.left(3)); const int riga_ord = atoi(str_numriga.mid(3)); if (riga_descr > 0 || codart == "**") //il codart e' comunque lungo 10 { switch (riga_descr) { case 0: break; case 1: { TRiga_documento& rdoc = bol.new_row("05"); rdoc.put(RDOC_DESCR, curr.get(6)); } break; default: { TRiga_documento& rdoc = bol[bol.rows()]; TString descest = rdoc.get(RDOC_DESCEST); descest << "\n" << curr.get(6); rdoc.put(RDOC_DESCEST, descest); rdoc.put(RDOC_DESCLUNGA, 'X'); } break; } } //if (riga_descr > 0...*/ //versione attuale TString16 codart = curr.get(5); codart.trim(); //riga descrizione if (codart.blank()) { TRiga_documento& rdoc = bol.new_row("05"); rdoc.put(RDOC_DESCR, curr.get(6)); } else //e' riga merce o omaggio... { crea_riga_bolla(curr, bol, false); // Crea eventuale riga merce crea_riga_bolla(curr, bol, true); // Crea eventuale riga omaggio } } //if (numbol != _forbidden_ndoc... } ////////////////////////////////////// // Trasferimento inventario ////////////////////////////////////// bool TImpBol0388::transfer_inventario() { //file da trasferire //costruire il nome del file con path TFilename file = _msk->get(F_PATH); file.add(_msk->get(F_NAMEINV)); file.ext("csv"); _trasfile = new TImpBol0388_file(file, 'I'); _trasfile->open(file,'r'); //preparazione del log TLog_report log(TR("Trasferimento inventario")); const long dimension = fsize(file); TProgind pi(dimension,TR("Importazione inventario in corso...")); int err = NOERR; TRecord_text curr; TLocalisamfile mag_file(LF_MAG); TString80 last_codart; TAssoc_array last_codmag; while (_trasfile->read(curr) == NOERR && !pi.iscancelled() && err == NOERR) { pi.setstatus(_trasfile->read_file()->tellg()); //acquisizione dati dal record del file csv TString80 codart = curr.get(0); codart.strip("\""); //campi senza destinazione, per ora /* TString80 lotto = curr.get(1); lotto.strip("\""); TString16 str_data = curr.get(2); str_data.strip("\""); TDate data(str_data);*/ TString16 str_giac = curr.get(3); str_giac.strip("\""); real giac(str_giac); TString8 codmag = curr.get(4); codmag.strip("\""); //scrittura dei record if (codart == last_codart && last_codmag.objptr(codmag) != NULL) { real& tot_giac = *(real*)last_codmag.objptr(codmag); tot_giac += giac; mag_file.put(MAG_RIM, tot_giac); mag_file.put(MAG_GIAC, tot_giac); mag_file.rewrite(); } else { mag_file.put(MAG_CODMAG, codmag); mag_file.put(MAG_CODART, codart); mag_file.put(MAG_NRIGA, 1); mag_file.put(MAG_RIM, giac); mag_file.put(MAG_GIAC, giac); last_codart = codart; last_codmag.destroy(); last_codmag.add(codmag, giac); //precauzione nel caso venga reimportato un record simile if (mag_file.write() != NOERR) mag_file.rewrite(); } } _trasfile->close(); delete _trasfile; TReport_book buc; buc.add(log); buc.preview(); return true; } //////////////////////////// // Parte comune //////////////////////////// void TImpBol0388::mask2ini() { //aggiorna il numero dell'ultima bolla trasferita _msk->set(F_LASTBOL, _lastbol); //carica i parametri del file di configurazione _configfile->set_paragraph("RICEZIONE"); for (int i = 0; i < _msk->fields() ; i++) { TMask_field& f = _msk->fld(i); const TFieldref* fr = f.field(); if (fr != NULL) _configfile->set(fr->name(), f.get()); } } void TImpBol0388::ini2mask() { //carica i parametri del file di configurazione _configfile->set_paragraph("RICEZIONE"); _lastbol = atol(_configfile->get("LASTBOL")); for (int i = 0; i < _msk->fields() ; i++) { TMask_field& f = _msk->fld(i); const TFieldref* fr = f.field(); if (fr != NULL) { const TString& val = _configfile->get(fr->name()); f.set(val); } } } bool TImpBol0388::create() { _configfile = new TConfig("pg0388conf.ini"); _msk = new TImpBol0388_mask(); open_files(LF_DOC, LF_RIGHEDOC, 0); TMagazzini mags; _codmag_st = mags.standardmag(); _codmag_st.left_just(3); _codmag_st << mags.standarddep(); return TSkeleton_application::create(); } bool TImpBol0388::destroy() { delete _msk; delete _configfile; return TApplication::destroy(); } void TImpBol0388::main_loop() { KEY tasto; ini2mask(); tasto = _msk->run(); if (tasto == K_ENTER) { if (_msk->get_bool(F_IMPBOL)) { if (transfer()) message_box(TR("Importazione bolle completata")); } if (_msk->get_bool(F_IMPINV)) { if (transfer_inventario()) message_box(TR("Importazione inventario completata")); } mask2ini(); } } int pg0388200 (int argc, char* argv[]) { TImpBol0388 main_app; main_app.run(argc, argv, TR("Importazione Bolle")); return TRUE; }