]> git.stg.codes - stg.git/commitdiff
Merge remote-tracking branch 'origin/stg-2.409' into ticket37
authorElena Mamontova <helenh463@gmail.com>
Tue, 6 Sep 2016 13:11:04 +0000 (16:11 +0300)
committerElena Mamontova <helenh463@gmail.com>
Tue, 6 Sep 2016 13:11:04 +0000 (16:11 +0300)
17 files changed:
include/stg/tariff.h
include/stg/tariff_conf.h
projects/stargazer/inst/var/02-alter-03.postgresql.sql [new file with mode: 0644]
projects/stargazer/inst/var/02-alter-03.sql [new file with mode: 0644]
projects/stargazer/plugins/configuration/rpcconfig/tariff_helper.cpp
projects/stargazer/plugins/configuration/rpcconfig/user_helper.cpp
projects/stargazer/plugins/configuration/rpcconfig/users_methods.cpp
projects/stargazer/plugins/configuration/sgconfig/parser_tariffs.cpp
projects/stargazer/plugins/configuration/sgconfig/parser_users.cpp
projects/stargazer/plugins/store/files/file_store.cpp
projects/stargazer/plugins/store/firebird/firebird_store_tariffs.cpp
projects/stargazer/plugins/store/mysql/mysql_store.cpp
projects/stargazer/plugins/store/postgresql/postgresql_store_tariffs.cpp
projects/stargazer/tariff_impl.cpp
projects/stargazer/tariff_impl.h
projects/stargazer/user_impl.cpp
tests/test_tariff.cpp

index 5d01cba08886be4087aced98c1305b072e16ef05..9bd9973eaa5cedebbe33f91b236e3a1df3de1995 100644 (file)
@@ -32,10 +32,15 @@ struct TARIFF_DATA;
 
 class TARIFF {
 public:
+    enum CHANGE_POLICY { ALLOW = 0, TO_CHEAP, TO_EXPENSIVE, DENY };
+
     enum PERIOD { DAY = 0, MONTH };
 
     enum TRAFF_TYPE { TRAFF_UP = 0, TRAFF_DOWN, TRAFF_UP_DOWN, TRAFF_MAX };
 
+    static std::string ChangePolicyToString(CHANGE_POLICY changePolicy);
+    static CHANGE_POLICY StringToChangePolicy(const std::string& value);
+
     static std::string PeriodToString(PERIOD period);
     static PERIOD StringToPeriod(const std::string& value);
 
@@ -53,6 +58,7 @@ public:
     virtual double  GetFee() const = 0;
     virtual double  GetFree() const = 0;
     virtual PERIOD  GetPeriod() const = 0;
+    virtual CHANGE_POLICY GetChangePolicy() const = 0;
 
     virtual const   std::string & GetName() const = 0;
     virtual void    SetName(const std::string & name) = 0;
@@ -61,8 +67,34 @@ public:
     virtual int64_t GetTraffByType(uint64_t up, uint64_t down) const = 0;
     virtual int     GetThreshold(int dir) const = 0;
     virtual const TARIFF_DATA & GetTariffData() const = 0;
+    virtual std::string TariffChangeIsAllowed(const TARIFF & to) const = 0;
 };
 
+inline
+std::string TARIFF::ChangePolicyToString(TARIFF::CHANGE_POLICY changePolicy)
+{
+switch (changePolicy)
+    {
+    case ALLOW: return "allow";
+    case TO_CHEAP: return "to_cheap";
+    case TO_EXPENSIVE: return "to_expensive";
+    case DENY: return "deny";
+    }
+return "allow"; // Classic behaviour.
+}
+
+inline
+TARIFF::CHANGE_POLICY TARIFF::StringToChangePolicy(const std::string& value)
+{
+if (strcasecmp(value.c_str(), "to_cheap") == 0)
+    return TO_CHEAP;
+if (strcasecmp(value.c_str(), "to_expensive") == 0)
+    return TO_EXPENSIVE;
+if (strcasecmp(value.c_str(), "deny") == 0)
+    return DENY;
+return ALLOW; // Classic behaviour.
+}
+
 inline
 std::string TARIFF::PeriodToString(TARIFF::PERIOD period)
 {
index fe94b6e533b54b2b9bc2e0a3520591d473214fda..cee3b4a5237d9f446caec2580cd6ef7c6fde54c2 100644 (file)
@@ -148,6 +148,7 @@ struct TARIFF_CONF
     double             passiveCost;
     std::string        name;
     TARIFF::PERIOD     period;
+    TARIFF::CHANGE_POLICY changePolicy;
 
     TARIFF_CONF()
         : fee(0),
@@ -155,7 +156,8 @@ struct TARIFF_CONF
           traffType(TARIFF::TRAFF_UP_DOWN),
           passiveCost(0),
           name(),
-          period(TARIFF::MONTH)
+          period(TARIFF::MONTH),
+          changePolicy(TARIFF::ALLOW)
         {}
 
     TARIFF_CONF(const std::string & n)
@@ -164,7 +166,8 @@ struct TARIFF_CONF
           traffType(TARIFF::TRAFF_UP_DOWN),
           passiveCost(0),
           name(n),
-          period(TARIFF::MONTH)
+          period(TARIFF::MONTH),
+          changePolicy(TARIFF::ALLOW)
         {}
 };
 //-----------------------------------------------------------------------------
@@ -176,7 +179,8 @@ struct TARIFF_CONF_RES
           traffType(),
           passiveCost(),
           name(),
-          period()
+          period(),
+          changePolicy()
         {}
 
     TARIFF_CONF_RES & operator=(const TARIFF_CONF & tc)
@@ -187,6 +191,7 @@ struct TARIFF_CONF_RES
         passiveCost = tc.passiveCost;
         name        = tc.name;
         period      = tc.period;
+        changePolicy = tc.changePolicy;
         return *this;
         }
 
@@ -199,6 +204,7 @@ struct TARIFF_CONF_RES
         passiveCost.maybeSet(tc.passiveCost);
         traffType.maybeSet(tc.traffType);
         period.maybeSet(tc.period);
+        changePolicy.maybeSet(tc.changePolicy);
         return tc;
         }
 
@@ -208,6 +214,7 @@ struct TARIFF_CONF_RES
     RESETABLE<double>             passiveCost;
     RESETABLE<std::string>        name;
     RESETABLE<TARIFF::PERIOD>     period;
+    RESETABLE<TARIFF::CHANGE_POLICY> changePolicy;
 };
 //-----------------------------------------------------------------------------
 struct TARIFF_DATA
@@ -248,6 +255,14 @@ struct TARIFF_DATA_RES
           dirPrice(DIR_NUM)
         {}
 
+    TARIFF_DATA_RES & operator=(const TARIFF_DATA & td)
+        {
+        tariffConf = td.tariffConf;
+        for (size_t i = 0; i < DIR_NUM; ++i)
+            dirPrice[i] = td.dirPrice[i];
+        return *this;
+        }
+
     TARIFF_DATA GetData() const
         {
         TARIFF_DATA td;
diff --git a/projects/stargazer/inst/var/02-alter-03.postgresql.sql b/projects/stargazer/inst/var/02-alter-03.postgresql.sql
new file mode 100644 (file)
index 0000000..a686aa6
--- /dev/null
@@ -0,0 +1,13 @@
+/*
+ *  DB migration from v02 to v03 (postgres)
+ */
+BEGIN;
+
+CREATE DOMAIN DM_TARIFF_CHANGE_POLICY AS TEXT NOT NULL
+    CONSTRAINT valid_value CHECK (VALUE IN ('allow', 'to_cheap', 'to_expensive', 'deny'));
+
+ALTER TABLE tb_tariffs ADD change_policy DM_TARIFF_CHANGE_POLICY DEFAULT 'allow';
+
+UPDATE tb_info SET version = 8;
+
+COMMIT;
diff --git a/projects/stargazer/inst/var/02-alter-03.sql b/projects/stargazer/inst/var/02-alter-03.sql
new file mode 100644 (file)
index 0000000..a019917
--- /dev/null
@@ -0,0 +1,10 @@
+/*
+ *  DB migration from v02 to v03 (firebird)
+ */
+
+CREATE DOMAIN DM_TARIFF_CHANGE_POLICY AS  VARCHAR(32) NOT NULL
+    CHECK (VALUE IN ('allow', 'to_cheap', 'to_expensive', 'deny'));
+
+ALTER TABLE tb_tariffs ADD change_policy DM_TARIFF_CHANGE_POLICY DEFAULT 'allow';
+
+UPDATE tb_info SET version = 2;
index 26b4e993b719067fae180f47b9c1d1792b1da204..c96b7d31cd58b025a83a52d3950f438d3389d67e 100644 (file)
@@ -13,6 +13,7 @@ structVal["freemb"] = xmlrpc_c::value_double(data.tariffConf.free);
 structVal["passivecost"] = xmlrpc_c::value_double(data.tariffConf.passiveCost);
 structVal["traffType"] = xmlrpc_c::value_int(data.tariffConf.traffType);
 structVal["period"] = xmlrpc_c::value_string(TARIFF::PeriodToString(data.tariffConf.period));
+structVal["changePolicy"] = xmlrpc_c::value_string(TARIFF::ChangePolicyToString(data.tariffConf.changePolicy));
 
 std::vector<xmlrpc_c::value> prices(DIR_NUM);
 
@@ -71,6 +72,11 @@ if ((it = structVal.find("period")) != structVal.end())
     data.tariffConf.period = TARIFF::StringToPeriod(xmlrpc_c::value_string(it->second));
     }
 
+if ((it = structVal.find("changePolicy")) != structVal.end())
+    {
+    data.tariffConf.changePolicy = TARIFF::StringToChangePolicy(xmlrpc_c::value_string(it->second));
+    }
+
 if ((it = structVal.find("dirprices")) != structVal.end())
     {
     std::vector<xmlrpc_c::value> prices(
index 89c41587f8527862de5932bbc4cbe52e63ab0c37..0e7ac9d66e13091d8ecf2091a2392400e6f317a0 100644 (file)
@@ -433,13 +433,27 @@ if ((it = structVal.find("tariff")) != structVal.end())
         tariff = tariff.substr(0, pos);
         }
 
-    if (tariffs->FindByName(tariff))
-        if (ptr->GetProperty().tariffName.Get() != tariff)
-            if (!ptr->GetProperty().tariffName.Set(tariff,
-                                               admin,
-                                               login,
-                                               &store))
-                return true;
+    const TARIFF * newTariff = tariffs->FindByName(tariff);
+    if (newTariff)
+        {
+        const TARIFF * currentTariff = ptr->GetTariff();
+        std::string message = currentTariff->TariffChangeIsAllowed(*newTariff);
+        if (message.empty())
+            {
+            if (ptr->GetProperty().tariffName.Get() != tariff)
+                {
+                if (!ptr->GetProperty().tariffName.Set(tariff,
+                                                   admin,
+                                                   login,
+                                                   &store))
+                    return true;
+                }
+            }
+        else
+            {
+            GetStgLogger()("Tariff change is prohibited for user %s. %s", ptr->GetLogin().c_str(), message.c_str());
+            }
+        }
 
     if (nextTariff != "" &&
         tariffs->FindByName(nextTariff))
index 5adbf44131905750cfa52fefbf1398b0842b2dd0..5a738d16d2b81220503c18177d63547b191a874e 100644 (file)
@@ -381,16 +381,29 @@ if (tariffs->FindByName(tariff))
         }
     else
         {
-        if (u->GetProperty().tariffName.Set(tariff,
+        const TARIFF * newTariff = tariffs->FindByName(tariff);
+        if (newTariff)
+            {
+            const TARIFF * currentTariff = u->GetTariff();
+            std::string message = currentTariff->TariffChangeIsAllowed(*newTariff);
+            if (message.empty())
+                {
+                if (u->GetProperty().tariffName.Set(tariff,
                                             admin,
                                             login,
                                             store,
                                             comment))
-            {
-            u->ResetNextTariff();
-            u->WriteConf();
-            *retvalPtr = xmlrpc_c::value_boolean(true);
-            return;
+                    {
+                    u->ResetNextTariff();
+                    u->WriteConf();
+                    *retvalPtr = xmlrpc_c::value_boolean(true);
+                    return;
+                    }
+                }
+            else
+                {
+                GetStgLogger()("Tariff change is prohibited for user %s. %s", u->GetLogin().c_str(), message.c_str());
+                }
             }
         }
     }
index 0607db6fb12fbde08147a0af3418250ae3743bb3..867181afda0e95631d1d6f459557e4f4b33351cf 100644 (file)
@@ -114,6 +114,7 @@ void GET_TARIFFS::CreateAnswer()
                   "<Free value=\"" + x2str(it->tariffConf.free) + "\"/>" +
                   "<TraffType value=\"" + TARIFF::TraffTypeToString(it->tariffConf.traffType) + "\"/>" +
                   "<Period value=\"" + TARIFF::PeriodToString(it->tariffConf.period) + "\"/>" +
+                  "<ChangePolicy value=\"" + TARIFF::ChangePolicyToString(it->tariffConf.changePolicy) + "\"/>" +
                   "</tariff>";
         }
 
@@ -170,7 +171,11 @@ int CHG_TARIFF::Start(void *, const char * el, const char ** attr)
     {
         if (strcasecmp(el, m_tag.c_str()) == 0)
         {
-            td.tariffConf.name = attr[1];
+            const TARIFF * tariff = m_tariffs.FindByName(attr[1]);
+            if (tariff != NULL)
+                td = tariff->GetTariffData();
+            else
+                return -1;
             return 0;
         }
     }
@@ -288,6 +293,12 @@ int CHG_TARIFF::Start(void *, const char * el, const char ** attr)
             td.tariffConf.period = TARIFF::StringToPeriod(attr[1]);
             return 0;
         }
+
+        if (strcasecmp(el, "ChangePolicy") == 0)
+        {
+            td.tariffConf.changePolicy = TARIFF::StringToChangePolicy(attr[1]);
+            return 0;
+        }
     }
     return -1;
 }
index 2e9d70872a82e3a7ac1ff92236c36c306060d582..8f15c491a0b3e553685bc0a80cb4bb11aee9366c 100644 (file)
@@ -594,11 +594,21 @@ int CHG_USER::ApplyChanges()
 
     if (!m_ucr.tariffName.empty())
     {
-        if (m_tariffs.FindByName(m_ucr.tariffName.const_data()))
+        const TARIFF * newTariff = m_tariffs.FindByName(m_ucr.tariffName.const_data());
+        if (newTariff)
         {
-            if (!u->GetProperty().tariffName.Set(m_ucr.tariffName.const_data(), &m_currAdmin, m_login, &m_store))
-                return -1;
-            u->ResetNextTariff();
+            const TARIFF * tariff = u->GetTariff();
+            std::string message = tariff->TariffChangeIsAllowed(*newTariff);
+            if (message.empty())
+            {
+                if (!u->GetProperty().tariffName.Set(m_ucr.tariffName.const_data(), &m_currAdmin, m_login, &m_store))
+                    return -1;
+                u->ResetNextTariff();
+            }
+            else
+            {
+                GetStgLogger()("Tariff change is prohibited for user %s. %s", u->GetLogin().c_str(), message.c_str());
+            }
         }
         else
         {
index 2a7eb6c131719cea07ff1b1a477026b979b15e7b..71f570717a208767404b7e6f3e2d98ae9a450f4b 100644 (file)
@@ -1465,6 +1465,11 @@ if (conf.ReadString("Period", &str, "month") < 0)
     td->tariffConf.period = TARIFF::MONTH;
 else
     td->tariffConf.period = TARIFF::StringToPeriod(str);
+
+if (conf.ReadString("ChangePolicy", &str, "allow") < 0)
+    td->tariffConf.changePolicy = TARIFF::ALLOW;
+else
+    td->tariffConf.changePolicy = TARIFF::StringToChangePolicy(str);
 return 0;
 }
 //-----------------------------------------------------------------------------
@@ -1526,6 +1531,7 @@ std::string fileName = storeSettings.GetTariffsDir() + "/" + tariffName + ".tf";
     cf.WriteDouble("Free", td.tariffConf.free);
     cf.WriteString("TraffType", TARIFF::TraffTypeToString(td.tariffConf.traffType));
     cf.WriteString("Period", TARIFF::PeriodToString(td.tariffConf.period));
+    cf.WriteString("ChangePolicy", TARIFF::ChangePolicyToString(td.tariffConf.changePolicy));
     }
 
 return 0;
index a7b719edb3eb5847e9191da4bb8aba6def298712..3e82e16f9728c5600517c3212931c783db436fd0 100644 (file)
@@ -150,36 +150,32 @@ try
     int32_t id;
     st->Get(1, id);
     st->Close();
+
+    std::string query = "update tb_tariffs set \
+                            fee = ?, \
+                            free = ?, \
+                            passive_cost = ?, \
+                            traff_type = ?";
+
+    if (schemaVersion > 0)
+        query += ", period = ?";
+    if (schemaVersion > 1)
+        query += ", change_policy = ?";
+
+    query += " where pk_tariff = ?";
+
+    st->Prepare(query);
+    st->Set(1, td.tariffConf.fee);
+    st->Set(2, td.tariffConf.free);
+    st->Set(3, td.tariffConf.passiveCost);
+    st->Set(4, td.tariffConf.traffType);
+
     if (schemaVersion > 0)
-        {
-        st->Prepare("update tb_tariffs set \
-                fee = ?, \
-                free = ?, \
-                passive_cost = ?, \
-                traff_type = ?, \
-                period = ? \
-                where pk_tariff = ?");
-        st->Set(1, td.tariffConf.fee);
-        st->Set(2, td.tariffConf.free);
-        st->Set(3, td.tariffConf.passiveCost);
-        st->Set(4, td.tariffConf.traffType);
         st->Set(5, TARIFF::PeriodToString(td.tariffConf.period));
-        st->Set(6, id);
-        }
-    else
-        {
-        st->Prepare("update tb_tariffs set \
-                fee = ?, \
-                free = ?, \
-                passive_cost = ?, \
-                traff_type = ? \
-                where pk_tariff = ?");
-        st->Set(1, td.tariffConf.fee);
-        st->Set(2, td.tariffConf.free);
-        st->Set(3, td.tariffConf.passiveCost);
-        st->Set(4, td.tariffConf.traffType);
-        st->Set(5, id);
-        }
+    if (schemaVersion > 1)
+        st->Set(6, TARIFF::ChangePolicyToString(td.tariffConf.changePolicy));
+
+    st->Set(7, id);
     st->Execute();
     st->Close();
 
@@ -286,6 +282,8 @@ try
     td->tariffConf.traffType = TARIFF::IntToTraffType(Get<int>(st, 6));
     if (schemaVersion > 0)
         td->tariffConf.period = TARIFF::StringToPeriod(Get<std::string>(st, 7));
+    if (schemaVersion > 1)
+        td->tariffConf.changePolicy = TARIFF::StringToChangePolicy(Get<std::string>(st, 8));
     st->Close();
     st->Prepare("select * from tb_tariffs_params where fk_tariff = ?");
     st->Set(1, id);
index 6b16a99daff8ca1ed337e5644c5d765c71d6a84a..f3539dd6fa2f1283bd7fe91f8b49895ae9cf50f9 100644 (file)
@@ -368,7 +368,8 @@ if(!IsTablePresent("tariffs",sock))
     
     res += "PassiveCost DOUBLE DEFAULT 0.0, Fee DOUBLE DEFAULT 0.0,"
         "Free DOUBLE DEFAULT 0.0, TraffType VARCHAR(10) DEFAULT '',"
-        "period VARCHAR(32) NOT NULL DEFAULT 'month')";
+        "period VARCHAR(32) NOT NULL DEFAULT 'month',"
+        "change_policy VARCHAR(32) NOT NULL DEFAULT 'allow')";
     
     if(MysqlQuery(res.c_str(),sock))
     {
@@ -422,7 +423,8 @@ if(!IsTablePresent("tariffs",sock))
     
     res += "PassiveCost=0.0, Fee=10.0, Free=0,"\
         "SinglePrice0=1, SinglePrice1=1,PriceDayA1=0.75,PriceDayB1=0.75,"\
-        "PriceNightA0=1.0,PriceNightB0=1.0,TraffType='up+down',period='month'";
+        "PriceNightA0=1.0,PriceNightB0=1.0,TraffType='up+down',period='month',"\
+        "change_policy='allow'";
     
     if(MysqlQuery(res.c_str(),sock))
     {
@@ -441,7 +443,7 @@ if(!IsTablePresent("tariffs",sock))
         mysql_close(sock);
         return -1;
     }
-    schemaVersion = 1;
+    schemaVersion = 2;
 }
 
 //users-----------------------------------------------------------------------
@@ -599,6 +601,26 @@ if (schemaVersion  < 1)
     schemaVersion = 1;
     logger("MYSQL_STORE: Updated DB schema to version %d", schemaVersion);
     }
+
+if (schemaVersion  < 2)
+    {
+    if (MysqlQuery("ALTER TABLE tariffs ADD change_policy VARCHAR(32) NOT NULL DEFAULT 'allow'", sock))
+        {
+        errorStr = "Couldn't update tariffs table to version 2. With error:\n";
+        errorStr += mysql_error(sock);
+        mysql_close(sock);
+        return -1;
+        }
+    if (MysqlQuery("UPDATE info SET version = 2", sock))
+        {
+        errorStr = "Couldn't update DB schema version to 2. With error:\n";
+        errorStr += mysql_error(sock);
+        mysql_close(sock);
+        return -1;
+        }
+    schemaVersion = 2;
+    logger("MYSQL_STORE: Updated DB schema to version %d", schemaVersion);
+    }
 return 0;
 }
 //-----------------------------------------------------------------------------
@@ -1639,6 +1661,26 @@ else
     td->tariffConf.period = TARIFF::MONTH;
     }
 
+if (schemaVersion > 1)
+{
+    str = row[6+8*DIR_NUM];
+    param = "ChangePolicy";
+
+    if (str.length() == 0)
+        {
+        mysql_free_result(res);
+        errorStr = "Cannot read tariff " + tariffName + ". Parameter " + param;
+        mysql_close(sock);
+        return -1;
+        }
+
+    td->tariffConf.changePolicy = TARIFF::StringToChangePolicy(str);
+    }
+else
+    {
+    td->tariffConf.changePolicy = TARIFF::ALLOW;
+    }
+
 mysql_free_result(res);
 mysql_close(sock);
 return 0;
@@ -1706,6 +1748,9 @@ res += " TraffType='" + TARIFF::TraffTypeToString(td.tariffConf.traffType) + "'"
 if (schemaVersion > 0)
     res += ", Period='" + TARIFF::PeriodToString(td.tariffConf.period) + "'";
 
+if (schemaVersion > 1)
+    res += ", change_policy='" + TARIFF::ChangePolicyToString(td.tariffConf.changePolicy) + "'";
+
 strprintf(&param, " WHERE name='%s' LIMIT 1", tariffName.c_str());
 res += param;
 
index 045411b1499f822400cfc860831a1ebd6661d1d9..c509c39c1f56dbb53be3ccdb09c8acfe1906410d 100644 (file)
@@ -317,6 +317,9 @@ int32_t id;
     if (version > 6)
         query << ", period = '" << TARIFF::PeriodToString(td.tariffConf.period) << "'";
 
+    if (version > 7)
+        query << ", change_policy = '" << TARIFF::ChangePolicyToString(td.tariffConf.changePolicy) << "'";
+
     query << " WHERE pk_tariff = " << id;
 
     result = PQexec(connection, query.str().c_str());
@@ -455,6 +458,9 @@ query << "SELECT pk_tariff, \
 if (version > 6)
     query << ", period";
 
+if (version > 7)
+    query << ", change_policy";
+
 query << " FROM tb_tariffs WHERE name = '" << ename << "'";
 
 result = PQexec(connection, query.str().c_str());
@@ -505,6 +511,9 @@ int id;
 if (version > 6)
     td->tariffConf.period = TARIFF::StringToPeriod(PQgetvalue(result, 0, 5));
 
+if (version > 7)
+    td->tariffConf.changePolicy = TARIFF::StringToChangePolicy(PQgetvalue(result, 0, 6));
+
 PQclear(result);
 
 query.str("");
index c6785cead85c26f71ea5e273014f0d71428a8d5f..34590975882045b607466e3c15bb048559b41868 100644 (file)
@@ -145,3 +145,24 @@ else
     return tariffData.dirPrice[dir].priceDayA;
 }
 //-----------------------------------------------------------------------------
+std::string TARIFF_IMPL::TariffChangeIsAllowed(const TARIFF & to) const
+{
+switch (GetChangePolicy())
+    {
+    case TARIFF::ALLOW:
+        return "";
+    case TARIFF::TO_CHEAP:
+        if (to.GetFee() < GetFee())
+            return "";
+        else
+            return "New tariff '" + to.GetName() + "' is more expensive than current tariff '" + GetName() + "'. The policy is '" + TARIFF::ChangePolicyToString(GetChangePolicy()) + "'.";
+    case TARIFF::TO_EXPENSIVE:
+        if (to.GetFee() > GetFee())
+            return "";
+        else
+            return "New tariff '" + to.GetName() + "' is more cheap than current tariff '" + GetName() + "'. The policy is '" + TARIFF::ChangePolicyToString(GetChangePolicy()) + "'.";
+    case TARIFF::DENY:
+        return "Current tariff '" + GetName() + "', new tariff '" + to.GetName() + "'. The policy is '" + TARIFF::ChangePolicyToString(GetChangePolicy()) + "'.";
+    }
+}
+//-----------------------------------------------------------------------------
index f2f84d2630889f73432e9a191459c8174c37adf3..788162cdd1c17ebe06f36efb6249ca67c8662e37 100644 (file)
@@ -72,6 +72,7 @@ public:
     double  GetFee() const { return tariffData.tariffConf.fee; }
     double  GetFree() const { return tariffData.tariffConf.free; }
     PERIOD  GetPeriod() const { return tariffData.tariffConf.period; }
+    CHANGE_POLICY GetChangePolicy() const { return tariffData.tariffConf.changePolicy; }
 
     void    Print() const;
 
@@ -87,6 +88,7 @@ public:
     TARIFF_IMPL & operator=(const TARIFF_IMPL & t);
     bool     operator==(const TARIFF_IMPL & rhs) const { return GetName() == rhs.GetName(); }
     bool     operator!=(const TARIFF_IMPL & rhs) const { return GetName() != rhs.GetName(); }
+    std::string TariffChangeIsAllowed(const TARIFF & to) const;
 
 private:
     TARIFF_DATA     tariffData;
index 55a0b197968756d7addf7eb6e8e2be0aad686ba0..aea25c781b43577c3bfd4b7fb50ea652f8b45210 100644 (file)
@@ -1178,10 +1178,24 @@ if (nextTariff.ConstData() != "")
     {
     const TARIFF * nt = tariffs->FindByName(nextTariff);
     if (nt == NULL)
+        {
         WriteServLog("Cannot change tariff for user %s. Tariff %s not exist.",
                      login.c_str(), property.tariffName.Get().c_str());
+        }
     else
-        property.tariffName.Set(nextTariff, sysAdmin, login, store);
+        {
+        std::string message = tariff->TariffChangeIsAllowed(*nt);
+        if (message.empty())
+            {
+            property.tariffName.Set(nextTariff, sysAdmin, login, store);
+            }
+        else
+            {
+            WriteServLog("Tariff change is prohibited for user %s. %s",
+                         login.c_str(),
+                         message.c_str());
+            }
+        }
     ResetNextTariff();
     WriteConf();
     }
index 7252a2378a13cb63e77083584363d00fe2b9f765..0969a490125ad556d9a99e11c65f7ad3d26d2334 100644 (file)
@@ -343,5 +343,113 @@ namespace tut
         ensure_equals("1101 == 0", tariff.GetPriceWithTraffType(0, 6 * 1024 * 1024, 0, 1286461245), 0); // Near 17:30, 6 > 4 DA (ignore night)
         ensure_equals("1110 == 0", tariff.GetPriceWithTraffType(0, 0 * 1024 * 1024, 0, 1286479245), 0); // Near 22:30, 0 < 4 DA (ignore night)
         ensure_equals("1111 == 0", tariff.GetPriceWithTraffType(0, 6 * 1024 * 1024, 0, 1286479245), 0); // Near 22:30, 6 > 4 DA (ignore night)
+   }
+
+    template<>
+    template<>
+    void testobject::test<7>()
+    {
+        set_test_name("Check changePolicy - ALLOW");
+
+        TARIFF_DATA td("test");
+        td.tariffConf.changePolicy = TARIFF::ALLOW;
+        td.tariffConf.fee = 100;
+        TARIFF_IMPL tariff(td);
+
+        td.tariffConf.fee = 50;
+        TARIFF_IMPL cheaper(td);
+
+        ensure_equals("Allow cheaper", tariff.TariffChangeIsAllowed(cheaper).empty(), true);
+
+        td.tariffConf.fee = 100;
+        TARIFF_IMPL equals(td);
+
+        ensure_equals("Allow equal", tariff.TariffChangeIsAllowed(equals).empty(), true);
+
+        td.tariffConf.fee = 150;
+        TARIFF_IMPL expensive(td);
+
+        ensure_equals("Allow expensive", tariff.TariffChangeIsAllowed(expensive).empty(), true);
+    }
+
+    template<>
+    template<>
+    void testobject::test<8>()
+    {
+        set_test_name("Check changePolicy - TO_CHEAP");
+
+        TARIFF_DATA td("test");
+        td.tariffConf.changePolicy = TARIFF::TO_CHEAP;
+        td.tariffConf.fee = 100;
+        TARIFF_IMPL tariff(td);
+
+        td.tariffConf.fee = 50;
+        TARIFF_IMPL cheaper(td);
+
+        ensure_equals("Allow cheaper", tariff.TariffChangeIsAllowed(cheaper).empty(), true);
+
+        td.tariffConf.fee = 100;
+        TARIFF_IMPL equals(td);
+
+        ensure_equals("Allow equal", !tariff.TariffChangeIsAllowed(equals).empty(), true);
+
+        td.tariffConf.fee = 150;
+        TARIFF_IMPL expensive(td);
+
+        ensure_equals("Allow expensive", !tariff.TariffChangeIsAllowed(expensive).empty(), true);
+    }
+
+    template<>
+    template<>
+    void testobject::test<9>()
+    {
+        set_test_name("Check changePolicy - TO_EXPENSIVE");
+
+        TARIFF_DATA td("test");
+        td.tariffConf.changePolicy = TARIFF::TO_EXPENSIVE;
+        td.tariffConf.fee = 100;
+        TARIFF_IMPL tariff(td);
+
+        td.tariffConf.fee = 50;
+        TARIFF_IMPL cheaper(td);
+
+        ensure_equals("Allow cheaper", !tariff.TariffChangeIsAllowed(cheaper).empty(), true);
+
+        td.tariffConf.fee = 100;
+        TARIFF_IMPL equals(td);
+
+        ensure_equals("Allow equal", !tariff.TariffChangeIsAllowed(equals).empty(), true);
+
+        td.tariffConf.fee = 150;
+        TARIFF_IMPL expensive(td);
+
+        ensure_equals("Allow expensive", tariff.TariffChangeIsAllowed(expensive).empty(), true);
+    }
+
+    template<>
+    template<>
+    void testobject::test<10>()
+    {
+        set_test_name("Check changePolicy - DENY");
+
+        TARIFF_DATA td("test");
+        td.tariffConf.changePolicy = TARIFF::DENY;
+        td.tariffConf.fee = 100;
+        TARIFF_IMPL tariff(td);
+
+        td.tariffConf.fee = 50;
+        TARIFF_IMPL cheaper(td);
+
+        ensure_equals("Allow cheaper", !tariff.TariffChangeIsAllowed(cheaper).empty(), true);
+
+        td.tariffConf.fee = 100;
+        TARIFF_IMPL equals(td);
+
+        ensure_equals("Allow equal", !tariff.TariffChangeIsAllowed(equals).empty(), true);
+
+        td.tariffConf.fee = 150;
+        TARIFF_IMPL expensive(td);
+
+        ensure_equals("Allow expensive", !tariff.TariffChangeIsAllowed(expensive).empty(), true);
     }
 }