#include #include #include #include #include #include #include /////////////////////////////////////////////////////////// // DowJones /////////////////////////////////////////////////////////// class TDowJones : public TFile_cache { struct TExchangeData : public TObject { real _chg; // Cambio int _dec; // Decimali per gli importi normali int _dec_prices; // Decimali per i prezzi unitari int _dec_change; // Decimali per i cambi bool _is_euro; // E' l'EURO in persona public: const TExchangeData& operator=(const TExchangeData& d) { _chg = d._chg; _dec = d._dec; _dec_prices = d._dec_prices; _is_euro = d._is_euro; return d; } TExchangeData() : _chg(UNO), _dec(0), _dec_prices(0), _is_euro(false) { } }; long _codditta; TString4 _firm_val, _euro_val; protected: virtual TObject* rec2obj(const TRectype& rec) const; void test_cache(); const TExchangeData& get(const char* key); public: const TString& get_firm_val(); const TString& get_euro_val(); void force_firm_val(const char* val); const char* expand_value(const char* val); const char* normalize_value(const char* val, const real& chg); real exchange(const real& num, const char* fromval, const real& fromchg, const char* toval, const real& tochg, int price = 0); real exchange(const real& num, const TExchange& frval, const TExchange& toval, int price = 0); int get_dec(const char* val, bool prices = FALSE); const real& get_change(const char* val); virtual void flush(); TDowJones() : TFile_cache("%VAL"), _codditta(0) { } virtual ~TDowJones() { } } DowJones; TObject* TDowJones::rec2obj(const TRectype& rec) const { TExchangeData* data = new TExchangeData; const TString4 codval = rec.get("CODTAB"); data->_chg = rec.get_real("S4"); if (data->_chg <= ZERO) { data->_chg = rec.get_real("R10"); if (data->_chg <= ZERO) { #ifdef DBG if (codval.not_empty() && codval != _firm_val) { TString msg = TR("Codice valuta senza cambio"); msg << ": " << codval; statbar_set_title(TASK_WIN, msg); } #endif data->_chg = UNO; } } if (codval.full()) { data->_dec = rec.get_int("I0"); data->_dec_prices = rec.get_int("I1"); if (data->_dec_prices < data->_dec) data->_dec_prices = data->_dec; data->_dec_change = rec.get_int("I2"); data->_is_euro = rec.get_bool("B0"); } return data; } void TDowJones::flush() { _firm_val.cut(0); _euro_val.cut(0); kill_file(); } void TDowJones::test_cache() { // Controllo se e' cambiata la ditta const long newfirm = prefix().get_codditta(); if (newfirm != _codditta) { _codditta = newfirm; _firm_val = prefix().firm().codice_valuta(); } if (_euro_val.empty()) { fill(); FOR_EACH_ASSOC_OBJECT(_cache, hash, key, obj) if (*key) { const TExchangeData& data = *(const TExchangeData*)obj; if (data._is_euro && _euro_val.empty()) _euro_val = key; } if (_euro_val.empty()) // Si son dimenticati dell'EURO? { TExchangeData* euro = new TExchangeData; euro->_chg = UNO; euro->_dec = euro->_dec_prices = 2; euro->_is_euro = true; _euro_val = "EUR"; _cache.add(_euro_val, euro); } _firm_val = prefix().firm().codice_valuta(); } } const char* TDowJones::expand_value(const char* val) { if (val && (*val > ' ' || *val < '\0')) { if (*val == '_') { if (xvt_str_compare_ignoring_case(val, "_FIRM") == 0) val = get_firm_val(); else if (xvt_str_compare_ignoring_case(val, "_EURO") == 0) val = get_euro_val(); } else { // Leave code as is } } else val = get_firm_val(); return val; } const TDowJones::TExchangeData& TDowJones::get(const char* val) { test_cache(); return (const TExchangeData&)query(expand_value(val)); } const TString& TDowJones::get_firm_val() { test_cache(); return _firm_val; } const TString& TDowJones::get_euro_val() { test_cache(); return _euro_val; } void TDowJones::force_firm_val(const char* val) { test_cache(); _firm_val = val; } real TDowJones::exchange(const real& num, // Importo da convertire const char* frval, // Dalla valuta const real& frchg, // Dal cambio const char* toval, // Alla valuta const real& tochg, // Al cambio int price) // e' un prezzo ? { real n = num; if (!n.is_zero()) { const TExchangeData& datafr = get(frval); const TExchangeData& datato = get(toval); real fr = frchg; if (fr <= ZERO) fr = datafr._chg; real to = tochg; if (to <= ZERO) to = datato._chg; n = n * to / fr; // Nuovo modo if (price == 0 || price == 1) // Arrotonda solo in caso normale n.round(price ? datato._dec_prices : datato._dec); } return n; } real TDowJones::exchange(const real& num, // Importo da convertire const TExchange& frval, // Dalla valuta const TExchange& toval, // Alla valuta int price) // e' un prezzo ? { const real& frch = frval.get_change(); const real& toch = toval.get_change(); return exchange(num, frval.get_value(), frch, toval.get_value(), toch, price); } int TDowJones::get_dec(const char* val, bool price) { const TExchangeData& data = get(val); return price ? data._dec_prices : data._dec; } const real& TDowJones::get_change(const char* val) { const TExchangeData& data = get(val); return data._chg; } const char* TDowJones::normalize_value(const char* val, const real& /*exch*/) { return expand_value(val); } /////////////////////////////////////////////////////////// // TExchange /////////////////////////////////////////////////////////// void TExchange::copy(const TExchange& exc) { strcpy(_val, exc._val); _exchange = exc._exchange; } const real& TExchange::get_change() const { if (_exchange.is_zero()) return DowJones.get_change(_val); return _exchange; } int TExchange::compare(const TSortable& obj) const { const TExchange& exc = (const TExchange&)obj; int cmp = strcmp(_val, exc._val); if (cmp == 0) { const real diff = get_change() - exc.get_change(); cmp = diff.sign(); } return cmp; } bool TExchange::same_value_as(const TExchange& exc) const { return strcmp(_val, exc._val) == 0; } bool TExchange::is_firm_value() const { return DowJones.get_firm_val() == _val; } bool TExchange::is_euro_value() const { return DowJones.get_euro_val() == _val; } int TExchange::decimals(bool price) const { return DowJones.get_dec(_val, price); } void TExchange::set(const char* val, const real& chg) { val = DowJones.normalize_value(val, chg); strncpy(_val, val, 4); _val[3] = '\0'; _exchange = chg; } void TExchange::set(const TRectype& rec) { const TString4 codval = rec.get("CODVAL"); const real chg = rec.get_real("CAMBIO"); set(codval, chg); } TExchange::TExchange(const char* val, const real& chg) { set(val, chg); } TExchange::TExchange(const TRectype& rec) { set(rec); } /////////////////////////////////////////////////////////// // TCurrency /////////////////////////////////////////////////////////// const TString& TCurrency::get_firm_val() { return DowJones.get_firm_val(); } const TString& TCurrency::get_euro_val() { return DowJones.get_euro_val(); } int TCurrency::get_firm_dec(bool price) { return DowJones.get_dec(get_firm_val(), price); } int TCurrency::get_euro_dec(bool price) { return DowJones.get_dec(get_euro_val(), price); } void TCurrency::force_firm_val(const char* val) { DowJones.force_firm_val(val); } void TCurrency::force_cache_update() { DowJones.flush(); } void TCurrency::force_value(const char* newval, const real& newchange) { _chg.set(newval, newchange); } void TCurrency::change_value(const TExchange& exc) { if (!_num.is_zero() && _chg != exc) _num = DowJones.exchange(_num, _chg, exc, is_price()); _chg = exc; } void TCurrency::change_value(const char* val, const real& newchange) { const TExchange exc(val, newchange); change_value(exc); } int TCurrency::decimals() const { return DowJones.get_dec(get_value(), is_price()); } int TCurrency::compare(const TSortable& s) const { const TCurrency& cur = (const TCurrency&)s; if (same_value_as(cur)) { return _num == cur._num ? 0 : (_num > cur._num ? +1 : -1); } TCurrency curr(cur); curr.change_value(get_value()); return _num == curr._num ? 0 : (_num > curr._num ? +1 : -1); } void TCurrency::copy(const TCurrency& cur) { _chg = cur._chg; _num = cur._num; _price = cur._price; } const char* TCurrency::string(bool dotted) const { if (dotted) { TString16 picture; picture.format(".%d", decimals()); return _num.string(picture); } return _num.stringa(0, decimals()); } TCurrency& TCurrency::operator+=(const TCurrency& cur) { CHECK(is_price() == cur.is_price(), "Somma di pere e mele!"); if (!cur._num.is_zero()) { if (same_value_as(cur)) { _num += cur._num; } else { real n = DowJones.exchange(cur._num, cur._chg, _chg, is_price()); _num += n; } } return *this; } TCurrency TCurrency::operator+(const TCurrency& num) const { TCurrency cur(*this); cur += num; return cur; } TCurrency& TCurrency::operator-=(const TCurrency& cur) { CHECK(is_price() == cur.is_price(), "Sottrazione di pere e mele!"); if (same_value_as(cur)) _num -= cur._num; else { real n = DowJones.exchange(cur._num, cur._chg, _chg, is_price()); _num -= n; } return *this; } TCurrency TCurrency::operator-(const TCurrency& num) const { TCurrency cur(*this); cur -= num; return cur; } TCurrency& TCurrency::operator*=(const real& num) { _num *= num; _num.round(decimals()); return *this; } TCurrency TCurrency::operator*(const real& num) const { TCurrency cur(*this); cur *= num; return cur; } TCurrency TCurrency::abs() const { if (_num.sign() < 0) { TCurrency k(-_num, _chg, is_price()); return k; } return *this; } bool TCurrency::is_firm_value() const { return _chg.is_firm_value(); } TCurrency::TCurrency(const real& num, const char* val, const real& exchg, bool price) : _num(num), _price(price) { force_value(val, exchg); _num.round(decimals()); } TCurrency::TCurrency(const real& num, const TExchange& exc, bool price) : _chg(exc), _num(num), _price(price) { _num.round(decimals()); } bool same_values(const char * valuea, const char * valueb) { if (valuea == NULL || *valuea <= ' ') valuea = TCurrency::get_firm_val(); if (valueb == NULL || *valueb <= ' ') valueb = TCurrency::get_firm_val(); return xvt_str_compare_ignoring_case(valuea, valueb) == 0; } real change_currency(const real& num, const char* fromval, const real& fromchg, const char* toval, const real& tochg, int price) { return DowJones.exchange(num, fromval, fromchg, toval, tochg, price); }