#include #include #include #include #include #include #include "../mg/umart.h" #include "../ve/condv.h" #include "../ve/rcondv.h" #include "../ve/clifor.h" #include "halib.h" #include "ha0.h" #include "ha0300a.h" ////////////////////////////////////////////// // Maschera ////////////////////////////////////////////// class TDocumenti_premio_msk : public TAutomask { protected: bool find_prezzo_articolo(const TString& codart, real& prezzo, TString& um) const; virtual bool on_field_event(TOperable_field& o, TField_event e, long jolly); public: TDocumenti_premio_msk(); }; TDocumenti_premio_msk::TDocumenti_premio_msk() : TAutomask("ha0300a") { } bool TDocumenti_premio_msk::find_prezzo_articolo(const TString& codart, real& prezzo, TString& um) const { //1) contratto const long codcf = get_long(F_CODCF); const TString& codcontr = get(F_CODCONTR); TToken_string key_umart; key_umart.add(codart); key_umart.add(1); const TRectype& rec_umart = cache().get(LF_UMART, key_umart); um = rec_umart.get(UMART_UM); const real umart_prezzo = rec_umart.get_real(UMART_PREZZO); prezzo = umart_prezzo; //mal che vada sarà il prezzo di umart TToken_string key; //CONTRATTI: tipo=C|catven=|tipocf=C|codcf=codcf|cod=codcontr|tiporiga=A|codriga=codart|um=um key.add("C"); key.add(""); key.add("C"); key.add(codcf); key.add(codcontr); //per um è necessario se il contratto scelto ha la gestione delle um accesa (tanto per complicarsi la vita) const bool gestum_contr = cache().get(LF_CONDV, key, CONDV_GESTUM) == "X"; key.add("A"); key.add(codart); if (gestum_contr) key.add(um); const TRectype& rec_contratto = cache().get(LF_RCONDV, key); const real contratto_prezzo = rec_contratto.get(RCONDV_PREZZO); //2) non c'è un prezzo sul contratto, prova con il listino standard if (!contratto_prezzo.is_zero()) prezzo = contratto_prezzo; else { key.cut(0); //LISTINI: tipo=L|catven=catven|tipocf=|codcf=|cod=codlis|tiporiga=A|codriga=codart|um=um key.add("L"); //la catven se c'è è del cliente TToken_string key_cfven; key_cfven.add("C"); key_cfven.add(codcf); const TString& catven = cache().get(LF_CFVEN, key_cfven, CFV_CATVEN); key.add(catven); key.add(""); key.add(""); const TString& codlis = get(F_CODLIS); key.add(codlis); //per um è necessario se il listino scelto ha la gestione delle um accesa (tanto per complicarsi la vita) const bool gestum_list = cache().get(LF_CONDV, key, CONDV_GESTUM) == "X"; key.add("A"); key.add(codart); if (gestum_list) key.add(um); const TRectype& rec_listino = cache().get(LF_RCONDV, key); const real listino_prezzo = rec_listino.get(RCONDV_PREZZO); if (!listino_prezzo.is_zero()) prezzo = listino_prezzo; } return !prezzo.is_zero(); } bool TDocumenti_premio_msk::on_field_event(TOperable_field& o, TField_event e, long jolly) { switch (o.dlg()) { case F_TIPOCONTR: if (e == fe_init || e == fe_modify) { //all'inizio deve proporre una lista dei possibili numerazioni e tipi che stanno in configurazione TConfig config(CONFIG_DITTA, "ha"); TString4 codnum, tipodoc; switch (o.get()[0]) { case 'A': codnum = config.get("CoAntNum"); tipodoc = config.get("CoAntTip"); break; case 'R': codnum = config.get("CoRifaNum"); tipodoc = config.get("CoRifaTip"); break; default: codnum = config.get("CoPostNum"); tipodoc = config.get("CoPostTip"); break; } set(F_CODNUM, codnum); set(F_TIPODOC, tipodoc); } break; case S_CODART: if (e == fe_modify) { //caricamento del prezzo in fase modifica codart: sequenza contratto->listino->umart //non è possibile mettere un prezzo a mano alla cazzo! real prezzo; TString4 um; //se il prezzo l'ha trovato lo mette nel relativo campo if (find_prezzo_articolo(o.get(), prezzo, um)) { TMask& row_mask = o.mask(); row_mask.set(S_PREZZO, prezzo); row_mask.set(S_UMQTA, um); } else { TString msg; msg.format("Non esiste il prezzo per l'articolo %s nei listini selezionati!", (const char*)o.get()); return error_box(msg); } } break; default: break; }; return true; } ////////////////////////////////////////////// // Applicazione ////////////////////////////////////////////// class TDocumenti_premio : public TRelation_application { TRelation* _rel; TDocumenti_premio_msk* _msk; protected: virtual bool user_create(); virtual bool user_destroy(); virtual TMask* get_mask(int) {return _msk;} virtual TRelation* get_relation() const {return _rel;} void write_rows(const TMask& m); void read_rows(TMask& m); virtual bool get_next_key(TToken_string& key); virtual int write(const TMask& m); virtual int rewrite(const TMask& m); virtual int read(TMask& m); virtual void init_query_mode(TMask& m); virtual void init_insert_mode(TMask& m); virtual void init_modify_mode(TMask& m); }; //cerca il primo numero valido per NDOC bool TDocumenti_premio::get_next_key(TToken_string& key) { long n = 0; TLocalisamfile doc(LF_DOC); TRectype& curr = doc.curr(); const char provv = _msk->get(F_PROVV)[0]; const int anno = _msk->get_int(F_ANNO); const TString4 codnum = _msk->get(F_CODNUM); curr.put(DOC_PROVV, provv); curr.put(DOC_ANNO, anno); curr.put(DOC_CODNUM, codnum); curr.put(DOC_NDOC, 9999999L); const int err = doc.read(_isgreat); if (err != _isemptyfile) { if (err == NOERR) doc.prev(); if (curr.get_char(DOC_PROVV) == provv && curr.get_int(DOC_ANNO) == anno && curr.get(DOC_CODNUM) == codnum) n = curr.get_long(DOC_NDOC); } n++; key.cut(0); key.add(F_PROVV); key.add(provv); key.add(F_ANNO); key.add(anno); key.add(F_CODNUM); key.add(codnum); key.add(F_NDOC); key.add(n); return n > 0; } void TDocumenti_premio::read_rows(TMask& m) { //chiave delle righe (escluso nriga) basata sulla testata TToken_string rdoc_key; const char provv = m.get(F_PROVV)[0]; const int anno = m.get_int(F_ANNO); const TString& codnum = m.get(F_CODNUM); const long ndoc = m.get_long(F_NDOC); rdoc_key.add(codnum); rdoc_key.add(anno); rdoc_key.add(provv); rdoc_key.add(ndoc); //array con le righe che rispondono alla chiave di testata TRecord_array righedoc(rdoc_key, LF_RIGHEDOC); //sheet e maschera di riga dello sheet TSheet_field& sheet = m.sfield(F_RIGHE); TMask& sm = sheet.sheet_mask(); sheet.destroy(); //giro sulle righe documento for (int i = 1; i <= righedoc.rows(); i++) { const TRectype& rec = righedoc.row(i); //record con l'elemento riga dell'array const TString& tipo = rec.get(RDOC_TIPORIGA); //in base al tiporiga si devono fare operazioni diverse //se è un tipo riga merce -> va aggiunta allo sheet if (tipo == HARDY_TIPORIGA_MERCE || tipo.blank()) { TToken_string& row = sheet.row(-1); //aggiunge una riga vuota for (int i = sm.fields()-1; i >= 0; i--) //giro su tutti i campi della maschera di riga... { TMask_field& mf = sm.fld(i); //aggiunge solo quelli che hanno un field if ((mf.field() != NULL) && (mf.dlg() > 100)) //> 100 per evitare errori sui campi dlg_null { const int idx = sheet.cid2index(mf.dlg()); row.add(mf.field()->read(rec), idx); } } } else if (tipo == HARDY_TIPORIGA_SOMMA)//se invece è la riga con le somme anticipate/maturate (solo 1 per contratto!) -> va messa in testata { const real anticipato = rec.get(RCA_2_ANTICIPATO); const real maturato = rec.get(RCA_2_RESTITUITO); m.set(F_ANTICIPATO, anticipato); m.set(F_RESTITUITO, maturato); } } } void TDocumenti_premio::write_rows(const TMask& m) { //chiave delle righe basata sui campi di testata const char provv = m.get(F_PROVV)[0]; const int anno = m.get_int(F_ANNO); const TString& codnum = m.get(F_CODNUM); const long ndoc = m.get_long(F_NDOC); TRectype* key_rec = new TRectype(LF_RIGHEDOC); key_rec->put(RDOC_PROVV, provv); key_rec->put(RDOC_ANNO, anno); key_rec->put(RDOC_CODNUM, codnum); key_rec->put(RDOC_NDOC, ndoc); //recordarray con le righe che rispondono alla chiave di testata key_rec TRecord_array righedoc(LF_RIGHEDOC, RDOC_NRIGA); righedoc.set_key(key_rec); //sheet e maschera di riga dello sheet TSheet_field& sheet = m.sfield(F_RIGHE); TMask& sm = sheet.sheet_mask(); //giro sulle righe dello sheet (righe di tipo merce) FOR_EACH_SHEET_ROW(sheet, i, row) { TRectype& rec = righedoc.row(i+1, true); //record con l'elemento riga dell'array for (int i = sm.fields()-1; i >= 0; i--) //giro su tutti i campi della maschera di riga... { TMask_field& mf = sm.fld(i); //aggiunge solo quelli che hanno un field if ((mf.field() != NULL) && (mf.dlg() > 100)) //> 100 per evitare errori sui campi dlg_null { const int idx = sheet.cid2index(mf.dlg()); mf.field()->write(row->get(idx), rec); } } rec.put(RDOC_TIPORIGA, HARDY_TIPORIGA_MERCE); } //salva la riga di tipo somme anticipate/rimborsate (H02) che in realtà è in testata const int righedoc_items = righedoc.rows(); TRectype& last_rec = righedoc.row(righedoc_items + 1, true); const real anticipato = m.get_real(F_ANTICIPATO); const real maturato = m.get_real(F_RESTITUITO); last_rec.put(RCA_2_ANTICIPATO, anticipato); last_rec.put(RCA_2_RESTITUITO, maturato); last_rec.put(RDOC_TIPORIGA, HARDY_TIPORIGA_SOMMA); last_rec.put(RDOC_QTA, 1); //panegirico sul codice iva (che ci va sennò col cavolo che si riesce a contabilizzare il contratto) TString80 codspp; TConfig config(CONFIG_DITTA, "ha"); const char tipo_contr = m.get(F_TIPOCONTR)[0]; switch (tipo_contr) { case 'A': codspp = config.get("CoAntSpe"); break; case 'R': codspp = config.get("CoRifaSpe"); break; default: break; } last_rec.put(RDOC_CODART, codspp); //cerca se il cliente ha un'iva speciale (1 cliente su 1E+6, ma tant'è...) TCli_for clifo(m.get(F_TIPOCF)[0], m.get_long(F_CODCF)); TString4 codiva(clifo.vendite().get(CFV_ASSFIS)); //per i restanti 1E+6 - 1 clienti... if (!codiva.full()) codiva = cache().get("SPP", codspp, "S3"); last_rec.put(RDOC_CODIVA, codiva); //e alla fine della fiera scrive tutto ufficialmente righedoc.rewrite(); } void TDocumenti_premio::init_query_mode(TMask& m) { } void TDocumenti_premio::init_insert_mode(TMask& m) { //alla creazione di un nuovo contratto lo stato viene posto = 2 //questo x' il contratto è già stato stampato dal cliente in fase di stesura m.set(F_STATO, 2); } void TDocumenti_premio::init_modify_mode(TMask& m) { m.disable(F_TIPOCONTR); //non si può cambiare il tipo contratto una volta stabilito sennò non funziona + un cazzo } int TDocumenti_premio::write(const TMask& m) { const int err = TRelation_application::write(m); if (err == NOERR) write_rows(m); return err; } int TDocumenti_premio::rewrite(const TMask& m) { const int err = TRelation_application::rewrite(m); if (err == NOERR) write_rows(m); return err; } int TDocumenti_premio::read(TMask& m) { const int err = TRelation_application::read(m); if (err == NOERR) read_rows(m); return err; } bool TDocumenti_premio::user_create() { _rel = new TRelation(LF_DOC); _msk = new TDocumenti_premio_msk; return true; } bool TDocumenti_premio::user_destroy() { delete _rel; delete _msk; return true; } int ha0300(int argc, char* argv[]) { TDocumenti_premio a; a.run(argc, argv, TR("Documenti premio Hardy")); return 0; }