#include #include #include #include #include #include "../ve/velib04.h" #include "../ve/condv.h" #include "../ve/rcondv.h" #include "halib.h" #include "ha0.h" #include "ha0300a.h" ////////////////////////////////////////////// // Maschera ////////////////////////////////////////////// class TDocumenti_premio_query_msk : public TAutomask { protected: virtual bool on_field_event(TOperable_field& o, TField_event e, long jolly); public: TDocumenti_premio_query_msk() : TAutomask("ha0300b") {} }; bool TDocumenti_premio_query_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 'N': codnum = config.get("CoNoloNum"); tipodoc = config.get("CoNoloTip"); 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); } default: break; } return true; } class TDocumenti_premio_msk : public TAutomask { protected: char find_prezzo_articolo(const TString& codart, real& prezzo, TString& um) const; virtual bool on_field_event(TOperable_field& o, TField_event e, long jolly); virtual bool on_key(KEY key); public: const TString& find_contabilizzazione() const; TDocumenti_premio_msk(const char* name = "ha0300a") : TAutomask(name) {} }; //metodo standard per far funzionare il shift+f12 in modo da poter cambiare lo stato bool TDocumenti_premio_msk::on_key(KEY key) { if (key == K_SHIFT + K_F12) { enable(F_STATO); return true; } return TAutomask::on_key(key); } char TDocumenti_premio_msk::find_prezzo_articolo(const TString& codart, real& prezzo, TString& um) const { //1) contratto (listino cliente) long codcf = get_long(F_CODCFATT); if (codcf <= 0) 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(UMART_PREZZO); char origine_prezzo = 'A'; //'A'nagrafica 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; origine_prezzo = 'C'; } 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; origine_prezzo = 'L'; } } return origine_prezzo; } const TString& TDocumenti_premio_msk::find_contabilizzazione() const { TISAM_recordset eld("USE %ELD SELECT (I0=\"3\")&&(S5=#CODNUM)&&(S7[1,1]=#STATO)"); eld.set_var("#CODNUM", get(F_CODNUM)); eld.set_var("#STATO", get(F_STATO)); if (eld.move_first()) { CHECKD(eld.items() == 1, "Troppe contabilizzazioni:", eld.items()); return eld.get("CODTAB").as_string(); } return EMPTY_STRING; } bool TDocumenti_premio_msk::on_field_event(TOperable_field& o, TField_event e, long jolly) { switch (o.dlg()) { case S_CODART: if ((e == fe_init || e == fe_close) && !o.empty()) { //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 find_prezzo_articolo(o.get(), prezzo, um); if (!prezzo.is_zero()) { TMask& row_mask = o.mask(); row_mask.set(S_PREZZO, prezzo); row_mask.set(S_UMQTA, um); } } break; case F_COLLEGA: if (e == fe_button) { const long numreg_cg = get_long(F_NUMREG); if (numreg_cg > 0) { TRectype mov(LF_MOV); mov.put(MOV_NUMREG, numreg_cg); mov.edit(); } } break; case DLG_ELABORA: if (e == fe_button && edit_mode()) { const TString8 cod_eld = find_contabilizzazione(); if (cod_eld.full()) { TContabilizzazione eld(cod_eld); TLista_documenti doc_in, doc_out; TRelation_application& app = (TRelation_application&)main_app(); TDocumento* doc = new TDocumento(app.get_relation()->curr()); doc_in.add(doc); if (eld.elabora(doc_in, doc_out, TDate(TODAY))) autoload(*app.get_relation()); } else return error_box(TR("Contratto non valido per la contabilizzazione")); } break; default: break; }; return true; } ////////////////////////////////////////////// // Applicazione ////////////////////////////////////////////// class TDocumenti_premio : public TRelation_application { TRelation* _rel; // Relazione principale su DOC TDocumenti_premio_query_msk* _qmsk; // Maschera query TDocumenti_premio_msk* _cmsk; // Maschera contratti "normali" TDocumenti_premio_msk* _nmsk; // Maschera contratti noleggio protected: virtual bool user_create(); virtual bool user_destroy(); virtual TMask* get_mask(int m); virtual bool changing_mask(int) { return true; } 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 bool remove(); virtual void init_query_mode(TMask& m); virtual void init_insert_mode(TMask& m); virtual void init_modify_mode(TMask& m); }; TMask* TDocumenti_premio::get_mask(int m) { if (m < MODE_INS) return _qmsk; const TString& tipo = _qmsk->get(F_TIPOCONTR); return tipo == "N" ? _nmsk : _cmsk; } //cerca il primo numero valido per NDOC bool TDocumenti_premio::get_next_key(TToken_string& key) { const TMask& m = curr_mask(); const char provv = m.get(F_PROVV)[0]; const int anno = m.get_int(F_ANNO); const TString& codnum = m.get(F_CODNUM); TLocalisamfile doc(LF_DOC); TRectype& curr = doc.curr(); curr.put(DOC_PROVV, provv); curr.put(DOC_ANNO, anno); curr.put(DOC_CODNUM, codnum); curr.put(DOC_NDOC, 9999999L); long n = 1; 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); } 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 true; } 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 j = sm.fields()-1; j >= 0; j--) //giro su tutti i campi della maschera di riga... { const TMask_field& mf = sm.fld(j); //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); } } //aggiorna al volo la riga (serve per aggiornare il prezzo prendendolo dal listino cliente; funziona perchè legato alla on_field di S_CODART.. //..in modalità fe_init) sheet.check_row(sheet.items()-1); } else if (tipo == HARDY_TIPORIGA_SOMMA) //se invece è la riga con le somme anticipate/maturate (solo 1 per contratto!) -> va messa in testata { if (m.id2pos(F_ANTICIPATO) >= 0) { const real anticipato = rec.get(RCA_2_ANTICIPATO); const real maturato = rec.get(RCA_2_RESO_STORICO); m.set(F_ANTICIPATO, anticipato); m.set(F_RESO_STORICO, maturato); } } } //for (int i = 1;... } 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... { const TMask_field& mf = sm.fld(i); //aggiunge solo quelli che hanno un field if ((mf.dlg() > 100) && (mf.field() != NULL)) //> 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 // questo vale solo per i contratti di Anticip/Rifatturazione (lo fa solo se l'anticipo è > 0) const char tipo_contr = m.get(F_TIPOCONTR)[0]; if (tipo_contr == 'A' || tipo_contr == 'R') { const real anticipato = m.get_real(F_ANTICIPATO); if (anticipato > ZERO) { const int righedoc_items = righedoc.rows(); TRectype& last_rec = righedoc.row(righedoc_items + 1, true); const real maturato = m.get_real(F_RESO_STORICO); last_rec.put(RCA_2_ANTICIPATO, anticipato); last_rec.put(RCA_2_RESO_STORICO, 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; switch (tipo_contr) { case 'A': codspp = ini_get_string(CONFIG_DITTA, "ha", "CoAntSpe"); break; case 'R': codspp = ini_get_string(CONFIG_DITTA, "ha", "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.blank()) 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); if (m.id2pos(DLG_ELABORA) >= 0) m.disable(DLG_ELABORA); const TString& codpag = ini_get_string(CONFIG_DITTA, "ha", "CodPagNac", "015"); m.set(F_CODPAG, codpag); } void TDocumenti_premio::init_modify_mode(TMask& m) { TDocumenti_premio_msk& dpm = (TDocumenti_premio_msk&)m; dpm.disable(F_TIPOCONTR); //non si può cambiare il tipo contratto una volta stabilito sennò non funziona + un cazzo if (m.id2pos(DLG_ELABORA) >= 0) dpm.enable(DLG_ELABORA, dpm.find_contabilizzazione().full()); } bool TDocumenti_premio::remove() { TDocumenti_premio_msk& dpm = (TDocumenti_premio_msk&)curr_mask(); TSheet_field& righe = dpm.sfield(F_RIGHE); if (dpm.id2pos(F_ANTICIPATO) >= 0) dpm.reset(F_ANTICIPATO); righe.destroy(); write_rows(dpm); return TRelation_application::remove(); } 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); _qmsk = new TDocumenti_premio_query_msk; _cmsk = new TDocumenti_premio_msk("ha0300a"); _nmsk = new TDocumenti_premio_msk("ha0300c"); return true; } bool TDocumenti_premio::user_destroy() { delete _nmsk; delete _cmsk; delete _qmsk; delete _rel; return true; } int ha0300(int argc, char* argv[]) { TDocumenti_premio prizedocs; prizedocs.run(argc, argv, TR("Gestione contratti premio")); return 0; }