////////////////////////////////////////////////////////////// // Rifatturazione cover ////////////////////////////////////////////////////////////// #include #include #include #include #include #include #include #include #include #include #include "velib.h" #include "sconti.h" #include "vec1100.h" class TRifatturazione: public TSkeleton_application { TMask * _m; //maschera di input dati TString _codnum; // codice di numerazione del documento int _anno; // anno della documentazione long _codcli; // codice del cliente TDate _dadata, _adata; // estremi di data dei documenti TRelation * _rel; TCursor * _cur; protected: static bool date_handler(TMask_field& f, KEY k); virtual bool create(); virtual bool destroy(); virtual void main_loop(); public: void select_docs(); real get_price (const TString& codart, TString& um, real& quantita); // metodo per ricavare la variazione di prezzo void add_line (TDocumento& doc, const TRiga_documento & old_row, const TString& um, real& quantita, real& price); // metodo per compilare le righe del nuovo documento TRifatturazione() {}; virtual ~TRifatturazione() {}; }; // handler delle date della maschera di input bool TRifatturazione::date_handler(TMask_field& f, KEY k) { bool rt = TRUE; TMask& m = f.mask(); if (f.to_check(k) && k == K_ENTER) { TDate dadata = m.get_date(F_DA_DATADOC); TDate adata = m.get_date(F_A_DATADOC); const int anno = m.get_int(F_ANNO); int anno1 = dadata.year(); int anno2 = adata.year(); if (anno1 != anno || anno2 != anno) // le date devono avere anno coincidente con quello selezionato nella maschera { f.error_box ("Gli anni delle date iniziale e finale devono essere uguali all'anno selezionato"); rt = FALSE; } } return rt; } // create della classe TRifatturazione (stanziamento degli oggetti principali) bool TRifatturazione::create() { open_files(LF_DOC, LF_RIGHEDOC, LF_CFVEN, LF_ANAMAG, LF_UMART, LF_CONDV, LF_RCONDV, 0); _m = new TMask ("vec1100a"); _rel = new TRelation (LF_DOC); _cur = new TCursor( _rel, "", 2); _m -> set_handler (F_ANNO, date_handler); //prende i dati dalla maschera per controllarli return TSkeleton_application::create(); } // destroy della classe TRifatturazione (distrugge ció che la create genera) bool TRifatturazione::destroy() { delete _cur; delete _rel; delete _m; return TSkeleton_application::destroy(); } // main loop della classe TRifatturazione (essenzialmente carica la maschera) void TRifatturazione::main_loop() { KEY key; while ((key = _m -> run()) != K_QUIT) { select_docs(); } } void TRifatturazione::select_docs() // applica la relation ed il cursor sul file LF_DOC (non li crea perché lo ha giá fatto la create()!!) e setta il filtro { TString16 f; f.format("CODNUM==\"%s\"", (const char *) _m->get(F_CODNUM)); // DEVI SEMPRE usare (const char *) nelle format !!!! TRectype darec(LF_DOC),arec(LF_DOC); // Record estremi filtro darec.put(DOC_TIPOCF,"C"); // Setta i parametri del primo record darec.put(DOC_CODCF, _m->get(F_CODCF)); darec.put(DOC_PROVV, "D"); darec.put(DOC_ANNO, _m->get(F_ANNO)); darec.put(DOC_DATADOC, _m->get(F_DA_DATADOC)); arec.put(DOC_TIPOCF,"C"); // ..e quelli dell'ultimo (cambia solo la data!!) arec.put(DOC_CODCF, _m->get(F_CODCF)); arec.put(DOC_PROVV, "D"); arec.put(DOC_ANNO, _m->get(F_ANNO)); arec.put(DOC_DATADOC, _m->get(F_A_DATADOC)); _cur->setfilter(f); _cur->setregion(darec,arec); const long items = _cur->items(); _cur -> freeze(); // applica la freeze per 'congelare' il file al momento dell'applicazione del cursore // va qui! prima di cominciare la scansione ma appena dopo la definizione degli items TDocumento* indoc = new TDocumento; // creo indoc in modo da non perdere traccia del documento _cur->file().set_curr (indoc); // cosí ogni record principale del cursore é un documento TProgind pi(items,"Elaborazione in corso..",TRUE,TRUE); // barra di progressione TDate datadoc = _m->get(F_DATADOC); TDocumento doc; // doc su cui scriverá!! *_cur=0; // preparo la testata del nuovo documento facendola uguale a quella del primo doc.put(DOC_PROVV, "D"); // documento (tanto devono essere tutti uguali) doc.put(DOC_ANNO,datadoc.year()); doc.put(DOC_CODNUM, _m->get(F_CODNUM)); doc.copy_data(doc, _cur->curr()); // copia la testata del record sul quale si é posizionato doc.put(DOC_DATADOC, datadoc); // assegna al nuovo documento la data che veniva dalla maschera doc.put(DOC_STATO, "1"); // e mette lo stato iniziale for (*_cur=0; _cur->pos() < items; ++(*_cur)) { pi.addstatus(1); // barra di progressione if (pi.iscancelled()) break; // é possibile interrompere l'elaborazione for ( int r =1; r <= indoc->rows(); r++) // cicla sulle righe del documento selezionato { const TRiga_documento& row = (*indoc)[r]; if (row.is_merce()) // lavora solo se la riga é di tipo merce { TString80 codart(row.get(RDOC_CODARTMAG)); // crea una stringa con il codice articolo if (codart.not_empty()) { TString16 um(row.get(RDOC_UMQTA)); // ed una con l'unitá di misura che trova nella riga real quantita = row.get(RDOC_QTA); // e una con la quantitá della riga real price = get_price (codart,um,quantita); // trova la variazione di prezzo per l'articolo, la sua um (di base) e la quantitá in um(base) if (price > 0) add_line(doc,row,um,quantita,price); // compila le righe del documento } } } } if (doc.rows() > 0) { doc.write(); } _cur->file().set_curr(new TRectype(LF_DOC)); _cur->freeze(FALSE); } real TRifatturazione::get_price (const TString& codart, TString& um, real& quantita) { TString codlist = _m->get(F_LISTINO); // prende il codice listino TToken_string chiave; // crea la chiave di lettura del file LF_RCONDV; una volta creata la chiave chiave.add("L"); // ha i parametri per trovare il prezzo nel corrispondente record (non viene chiave.add(""); // utilizzato un TRectype per esigenze di velocitá) chiave.add(""); chiave.add(""); chiave.add(codlist); chiave.add("A"); chiave.add(codart); // chiave.add(um_base); const TRectype& rcondv = cache().get(LF_RCONDV, chiave); const real old_price = rcondv.get("PREZZO"); // devi prendere il PREZZO dalle righe listino del listino con codice codlist real new_price; if (old_price != ZERO) { TArticolo articolo(codart); // crea un oggetto TArticolo con il codice codart quantita = articolo.convert_to_um (quantita,NULL,um); // converte la quantita in um base real perc = _m->get(F_PERCENT); // dalla maschera prendi la % di sovrapprezzo new_price = perc / 100 * old_price; // mi serve il solo sovrapprezzo um = articolo.um()[1].get(UMART_UM); // deve prendere l'unitá di misura base dell'articolo (lo prende come primo record delle unitá di misura) } return new_price; } void TRifatturazione::add_line (TDocumento& doc, const TRiga_documento & old_row, const TString& um, real& quantita, real& price) { int tot_lines = doc.rows(); for ( int i = 1; i <= tot_lines; i++) { const TRiga_documento & riga = doc[i]; TString codartmag = riga.get(RDOC_CODARTMAG); TString codart = old_row.get(RDOC_CODARTMAG); if (codartmag == codart) break; } if (i > tot_lines) // se non ha trovato il codart... // mette nella riga (che copia da quella del documento originale) // codart, quantitá, prezzo, um e azzera alcuni campi { TRiga_documento & new_row = doc.new_row(old_row.tipo().codice()); // copia la riga del documento originale (stesso tiporiga) TDocumento::copy_data(new_row, old_row); new_row.zero(RDOC_GENERATA); new_row.put(RDOC_PREZZO, price); new_row.put(RDOC_UMQTA, um); new_row.put(RDOC_QTA, quantita); new_row.zero(RDOC_QTAEVASA); new_row.zero(RDOC_QTAGG1); new_row.zero(RDOC_QTAGG2); new_row.zero(RDOC_QTAGG3); new_row.zero(RDOC_QTAGG4); new_row.zero(RDOC_QTAGG5); new_row.zero(RDOC_RIGAEVASA); new_row.zero(RDOC_SCONTO); new_row.zero(RDOC_PERCPROV); new_row.zero(RDOC_IMPFISSO); new_row.zero(RDOC_IMPFISUN); new_row.set_original_rdoc_key(old_row); // metodo per prendere i valori dei campi chiave nella riga originale e metterli // nei campi di tipo DA.. del file RDOC ('mmazza!!) } else // se ha trovato il codart... // mette nella riga del nuovo documento solo la quantitá, aggiungendola a quella che esiste giá { TRiga_documento & riga = doc[i]; real qta = riga.get(RDOC_QTA); qta += quantita; riga.put(RDOC_QTA,qta); } } // Do all the work! int vec1100(int argc, char* argv[]) { TRifatturazione a; a.run(argc, argv, "Rifatturazione"); return (0); }