소스 검색

no message

ducnt 1 개월 전
부모
커밋
7e3e2890d8
44개의 변경된 파일3183개의 추가작업 그리고 2689개의 파일을 삭제
  1. BIN
      10102025_CMS_BalancePlus_Mytel (4).xlsx
  2. 2 3
      ApiWeb/ApiProcessToken/ApiProcessToken.csproj
  3. 458 5
      ApiWeb/ApiProcessToken/Controllers/balance.cs
  4. 0 748
      ApiWeb/ApiProcessToken/Controllers/webservice.cs
  5. 73 0
      ApiWeb/ApiProcessToken/Models/banlance/apiServiceObj.cs
  6. 313 7
      ApiWeb/ApiProcessToken/Models/banlance/balanceDataAccess.cs
  7. 8 0
      ApiWeb/ApiProcessToken/Models/banlance/serviceObj.cs
  8. 74 20
      ApiWeb/ApiProcessToken/Models/common/Queue.cs
  9. 0 318
      ApiWeb/ApiProcessToken/Models/webserviceDataAccess.cs
  10. 1 2
      ApiWeb/ApiProcessToken/Program.cs
  11. 3 3
      ApiWeb/ApiProcessToken/Properties/PublishProfiles/FolderProfile.pubxml
  12. 2 2
      ApiWeb/ApiProcessToken/Properties/launchSettings.json
  13. 12 11
      ApiWeb/ApiProcessToken/appsettings.json
  14. 1 1
      ApiWeb/CommonObj/CommonObj.csproj
  15. 0 170
      SuperAdmin/SuperAdmin/Connected Services/SvVsa/ConnectedService.json
  16. 0 1163
      SuperAdmin/SuperAdmin/Connected Services/SvVsa/Reference.cs
  17. 205 13
      SuperAdmin/SuperAdmin/Controllers/AdminController.cs
  18. 0 1
      SuperAdmin/SuperAdmin/Controllers/HomeController.cs
  19. 47 0
      SuperAdmin/SuperAdmin/Models/Http/ApiService.cs
  20. 38 0
      SuperAdmin/SuperAdmin/Models/Http/ApiServiceUpdate.cs
  21. 2 0
      SuperAdmin/SuperAdmin/Models/Http/Service.cs
  22. 36 0
      SuperAdmin/SuperAdmin/Models/Http/ServiceList.cs
  23. 5 3
      SuperAdmin/SuperAdmin/Properties/PublishProfiles/FolderProfile.pubxml
  24. 1 1
      SuperAdmin/SuperAdmin/Properties/launchSettings.json
  25. 6 0
      SuperAdmin/SuperAdmin/Source/CommonUtils.cs
  26. 19 17
      SuperAdmin/SuperAdmin/Timor_BPSuperAdmin.csproj
  27. 443 0
      SuperAdmin/SuperAdmin/Views/Admin/ApiWebserviceManagement.cshtml
  28. 298 8
      SuperAdmin/SuperAdmin/Views/Admin/CampaignManagement.cshtml
  29. 1 1
      SuperAdmin/SuperAdmin/Views/Admin/Dashboard.cshtml
  30. 1 1
      SuperAdmin/SuperAdmin/Views/Admin/Index.cshtml
  31. 2 2
      SuperAdmin/SuperAdmin/Views/Admin/ReportCampaign.cshtml
  32. 131 4
      SuperAdmin/SuperAdmin/Views/Admin/ServiceManagement.cshtml
  33. 42 38
      SuperAdmin/SuperAdmin/Views/Home/Login.cshtml
  34. 64 0
      SuperAdmin/SuperAdmin/Views/Partial/_ApiWebserviceManagement.cshtml
  35. 4 3
      SuperAdmin/SuperAdmin/Views/Partial/_Campaign.cshtml
  36. 103 24
      SuperAdmin/SuperAdmin/Views/Partial/_CampaignService.cshtml
  37. 151 0
      SuperAdmin/SuperAdmin/Views/Partial/_Menu - Copy.cshtml
  38. 20 7
      SuperAdmin/SuperAdmin/Views/Partial/_Menu.cshtml
  39. 37 1
      SuperAdmin/SuperAdmin/Views/Shared/_Layout.cshtml
  40. 3 24
      SuperAdmin/SuperAdmin/Views/Shared/_NothingLayout.cshtml
  41. 95 88
      SuperAdmin/SuperAdmin/appsettings.json
  42. 266 0
      SuperAdmin/SuperAdmin/wwwroot/css/login.css
  43. 216 0
      SuperAdmin/SuperAdmin/wwwroot/css/menu-custom.css
  44. BIN
      TÀI LIỆU NGHIỆP VỤ B+ MYTEL_V2_09102025.docx

BIN
10102025_CMS_BalancePlus_Mytel (4).xlsx


+ 2 - 3
ApiWeb/ApiProcessToken/ApiProcessToken.csproj

@@ -1,8 +1,7 @@
 <Project Sdk="Microsoft.NET.Sdk.Web">
  
   <PropertyGroup>
-    <TargetFramework>netcoreapp3.1</TargetFramework>
-	  <RuntimeFrameworkVersion>3.1.0</RuntimeFrameworkVersion>
+    <TargetFramework>net7.0</TargetFramework>
     <UserSecretsId>bef20c7e-0627-41ee-8414-1476a4d1aaba</UserSecretsId>
   </PropertyGroup>
 
@@ -27,7 +26,7 @@
     <PackageReference Include="log4net" Version="2.0.11" />
     <PackageReference Include="Microsoft.AspNetCore.Mvc.Formatters.Xml" Version="2.2.0" />
     <PackageReference Include="Newtonsoft.Json" Version="13.0.1" />
-    <PackageReference Include="Oracle.ManagedDataAccess.Core" Version="2.19.90" />
+    <PackageReference Include="Oracle.ManagedDataAccess.Core" Version="3.21.120" />
     <PackageReference Include="StackExchange.Redis" Version="2.2.88" />
   </ItemGroup>
 

+ 458 - 5
ApiWeb/ApiProcessToken/Controllers/balance.cs

@@ -3368,6 +3368,147 @@ namespace ApiProcess.Controllers
                         _obj.isActive = ds_regist.Tables[0].Rows[j]["IS_ACTIVE"].ToString();
                         _obj.isMyService = ds_regist.Tables[0].Rows[j]["IS_MYSERVICE"].ToString();
 
+                        _obj.serviceGroupName = ds_regist.Tables[0].Rows[j]["SERVICE_GROUP_NAME"].ToString();
+                        _obj.serviceGroupId = ds_regist.Tables[0].Rows[j]["SERVICE_GROUP_ID"].ToString();
+                        _obj.apiServiceId = ds_regist.Tables[0].Rows[j]["WEBSERVICE_ID"].ToString();
+
+                        response.list[j] = _obj;
+                    }
+
+                }
+
+
+
+
+            }
+            catch (Exception ex)
+            {
+                logger.Info("exception: " + ex.ToString());
+                response.responseCode = "-2";
+                response.responseMessage = "System upgrade";
+
+            }
+            logger.Info("Responase to web: " + response.ToString());
+            return Ok(response);
+        }
+
+        [HttpPost]
+        public IActionResult svGroupGetList([FromBody] dynamic sendData)
+        {
+
+            logger.Info("New request income svGroupGetList :" + sendData.ToString());
+            serviceObjList response = new serviceObjList();
+            response.responseCode = "-1";
+            response.responseMessage = "Err unknow";
+
+            try
+            {
+
+                var userObj = JObject.Parse(sendData.ToString());
+
+                string users = Convert.ToString(userObj["users"]);
+                string id = Convert.ToString(userObj["id"]);
+
+
+                //string name = Convert.ToString(userObj["name"]);
+
+                //string order = Convert.ToString(userObj["order"]);
+                //string rowsOnPage = Convert.ToString(userObj["rowsOnPage"]);
+                //string seqPage = Convert.ToString(userObj["seqPage"]);
+                //if (string.IsNullOrEmpty(name)) name = "-1";
+                //if (string.IsNullOrEmpty(order)) order = "asc";
+                //if (string.IsNullOrEmpty(rowsOnPage)) rowsOnPage = "1000000000000";
+                //if (string.IsNullOrEmpty(seqPage)) seqPage = "1";
+                //string isActive = Convert.ToString(userObj["isActive"]);
+                //if (string.IsNullOrEmpty(isActive)) isActive = "-1";
+
+
+                if (string.IsNullOrEmpty(users)) users = "-1";
+                if (string.IsNullOrEmpty(id)) id = "-1";
+
+
+                string token = Convert.ToString(userObj["token"]);
+                string channel = Convert.ToString(userObj["channel"]);
+                string language = Convert.ToString(userObj["language"]);
+                if (string.IsNullOrEmpty(language)) language = "-1";
+
+                string RedisIp = Common.GetValuesAppSetting("webConfig", "RedisIp");
+                string RedisPort = Common.GetValuesAppSetting("webConfig", "RedisPort");
+                string RedisPass = Common.GetValuesAppSetting("webConfig", "RedisPass");
+                var clientIp = HttpContext.Connection.RemoteIpAddress.ToString();
+
+
+                //---------------------Lay ra va luu mot redis tu cache-----------------------------
+                redisConnection _redis;
+                memoryCache.TryGetValue("redis", out _redis);
+                if (_redis == null)
+                {
+                    var cacheExpiryOptions = new MemoryCacheEntryOptions
+                    {
+                        AbsoluteExpiration = DateTime.Now.AddMonths(12),
+                        Priority = CacheItemPriority.High,
+                        SlidingExpiration = TimeSpan.FromMinutes(2),
+                        Size = 1024,
+                    };
+                    _redis = new redisConnection(RedisIp, RedisPort, RedisPass);
+                    _redis.connet();
+                    memoryCache.Set("redis", _redis, cacheExpiryOptions);
+                }
+                if (!_redis.isConnet())
+                {
+                    if (!_redis.connet())
+                    {
+                        logger.Info("Connect to redis false");
+                        response.responseCode = "-2";
+                        response.responseMessage = "System Update";
+                        logger.Info("confirmTicket response : " + response.ToString());
+                        return Ok(response);
+                    }
+                    else
+                    {
+                        var cacheExpiryOptions = new MemoryCacheEntryOptions
+                        {
+                            AbsoluteExpiration = DateTime.Now.AddMonths(12),
+                            Priority = CacheItemPriority.High,
+                            SlidingExpiration = TimeSpan.FromMinutes(2),
+                            Size = 1024,
+                        };
+                        memoryCache.Set("redis", _redis, cacheExpiryOptions);
+
+                    }
+                }
+                //----------------------Ket thuc lay redis tu cache -------------------------------------
+
+                tokenObj _tokenObj = null;
+                if (!CommonFunction.checkToken(clientIp, token, channel, _redis, logger, out _tokenObj))
+                {
+                    logger.Info("Authen token false");
+                    response.responseCode = "35";
+                    response.responseMessage = CommonObj.common.CommonFunction.getErrCodeObjFromRedis(_redis, channel, response.responseCode, language);
+                    logger.Info("confirmTicket response : " + response.ToString());
+                    return Ok(response);
+                }
+
+
+                DataSet ds_regist = balanceDataAccess.svGroupGetList(id, users);
+                logger.Info("Call database svGroupGetList success:");
+                response.responseCode = "0";
+                response.responseMessage = "Success";
+                if (ds_regist != null & ds_regist.Tables[0].Rows.Count > 0)
+                {
+
+
+                    response.list = new serviceObj[ds_regist.Tables[0].Rows.Count];
+                    for (int j = 0; j < ds_regist.Tables[0].Rows.Count; j++)
+                    {
+                        serviceObj _obj = new serviceObj();
+
+                        _obj.id = ds_regist.Tables[0].Rows[j]["ID"].ToString();
+                        _obj.code = ds_regist.Tables[0].Rows[j]["CODE"].ToString();
+                        _obj.name = ds_regist.Tables[0].Rows[j]["NAME"].ToString();
+                        
+                        _obj.isActive = ds_regist.Tables[0].Rows[j]["IS_ACTIVE"].ToString();
+
                         response.list[j] = _obj;
                     }
 
@@ -3424,6 +3565,8 @@ namespace ApiProcess.Controllers
                 string msgRegisterSuccess = Convert.ToString(userObj["msgRegisterSuccess"]);
                 string msgRegisterFlase = Convert.ToString(userObj["msgRegisterFlase"]);
                 string msgConfirm = Convert.ToString(userObj["msgConfirm"]);
+                string serviceGroupId = Convert.ToString(userObj["serviceGroupId"]);
+                string apiServiceId = Convert.ToString(userObj["apiServiceId"]);
 
                 if (string.IsNullOrEmpty(msgRegisterSuccess)) msgRegisterSuccess = "-1";
                 if (string.IsNullOrEmpty(msgRegisterFlase)) msgRegisterFlase = "-1";
@@ -3508,13 +3651,21 @@ namespace ApiProcess.Controllers
 
 
                 DataSet ds_regist = balanceDataAccess.svInsert(code, name, description, shortCode, command, contentEn, contentFr,
-                    contentLc,note, companyId, users, msgRegisterSuccess, msgRegisterFlase, msgConfirm);
+                    contentLc,note, companyId, users, msgRegisterSuccess, msgRegisterFlase, msgConfirm, serviceGroupId, apiServiceId);
                 logger.Info("Call database svInsert success:");
                 if (ds_regist != null & ds_regist.Tables[0].Rows.Count > 0)
                 {
                     logger.Info("Call database success svInsert not null");
                     response.responseCode = ds_regist.Tables[0].Rows[0]["status"].ToString();
                     response.responseMessage = ds_regist.Tables[0].Rows[0]["msg"].ToString(); ;
+                    //try
+                    //{
+                    //    balanceDataAccess.serviceUpdateGroupAndApiByCode(code, serviceGroupId, apiServiceId);
+                    //}
+                    //catch (Exception ex)
+                    //{
+                    //    logger.Info("serviceUpdateGroupAndApiByCode exception: " + ex.ToString());
+                    //}
                 }
                 else
                 {
@@ -3570,6 +3721,9 @@ namespace ApiProcess.Controllers
                 string note = Convert.ToString(userObj["note"]);
                 string companyId = Convert.ToString(userObj["companyId"]);
 
+                string serviceGroupId = Convert.ToString(userObj["serviceGroupId"]);
+                string apiServiceId = Convert.ToString(userObj["apiServiceId"]);
+
                 string type = Convert.ToString(userObj["type"]);
 
 
@@ -3582,6 +3736,7 @@ namespace ApiProcess.Controllers
                 string msgRegisterSuccess = Convert.ToString(userObj["msgRegisterSuccess"]);
                 string msgRegisterFlase = Convert.ToString(userObj["msgRegisterFlase"]);
                 string msgConfirm = Convert.ToString(userObj["msgConfirm"]);
+
                 if (string.IsNullOrEmpty(msgRegisterSuccess)) msgRegisterSuccess = "-1";
                 if (string.IsNullOrEmpty(msgRegisterFlase)) msgRegisterFlase = "-1";
 
@@ -3660,13 +3815,21 @@ namespace ApiProcess.Controllers
 
 
                 DataSet ds_regist = balanceDataAccess.svUpdate(id, code, name, description, shortCode, command, contentEn, contentFr,
-                    contentLc, note, companyId, users, type, msgRegisterSuccess, msgRegisterFlase, msgConfirm);
+                    contentLc, note, companyId, users, type, msgRegisterSuccess, msgRegisterFlase, msgConfirm, serviceGroupId, apiServiceId);
                 logger.Info("Call database svUpdate success:");
                 if (ds_regist != null & ds_regist.Tables[0].Rows.Count > 0)
                 {
                     logger.Info("Call database success svUpdate not null");
                     response.responseCode = ds_regist.Tables[0].Rows[0]["status"].ToString();
                     response.responseMessage = ds_regist.Tables[0].Rows[0]["msg"].ToString(); ;
+                    //try
+                    //{
+                    //    balanceDataAccess.serviceUpdateGroupAndApiById(id, serviceGroupId, apiServiceId);
+                    //}
+                    //catch (Exception ex)
+                    //{
+                    //    logger.Info("serviceUpdateGroupAndApiById exception: " + ex.ToString());
+                    //}
                 }
                 else
                 {
@@ -6927,6 +7090,7 @@ namespace ApiProcess.Controllers
                 
                 string ussdDisplay = Convert.ToString(userObj["ussdDisplay"]);
                 string keyRegister = Convert.ToString(userObj["keyRegister"]);
+                string msgConfirm = Convert.ToString(userObj["msgConfirm"]);
 
 
 
@@ -7014,7 +7178,7 @@ namespace ApiProcess.Controllers
 
 
                 DataSet ds_regist = balanceDataAccess.camAddInsert(campaignId, serviceAddId, note, users,
-                    ussdDisplay, keyRegister);
+                    ussdDisplay, keyRegister, msgConfirm);
                 logger.Info("Call database balInsert success:");
                 if (ds_regist != null & ds_regist.Tables[0].Rows.Count > 0)
                 {
@@ -7077,11 +7241,12 @@ namespace ApiProcess.Controllers
 
                 
                 string ussdDisplay = Convert.ToString(userObj["ussdDisplay"]);
+                string msgConfirm = Convert.ToString(userObj["msgConfirm"]);
+
 
 
 
 
-                
                 if (string.IsNullOrEmpty(id)) id = "-1";
                 if (string.IsNullOrEmpty(keyRegister)) keyRegister = "-1";
                 if (string.IsNullOrEmpty(type)) type = "0";
@@ -7155,7 +7320,7 @@ namespace ApiProcess.Controllers
                 }
 
 
-                DataSet ds_regist = balanceDataAccess.camAddUpdate(id, campaignId, serviceAddId, note, users, type, ussdDisplay, keyRegister);
+                DataSet ds_regist = balanceDataAccess.camAddUpdate(id, campaignId, serviceAddId, note, users, type, ussdDisplay, keyRegister, msgConfirm);
                 logger.Info("Call database comInsert success:");
                 if (ds_regist != null & ds_regist.Tables[0].Rows.Count > 0)
                 {
@@ -9044,6 +9209,294 @@ namespace ApiProcess.Controllers
         }
 
 
+        [HttpPost]
+        public IActionResult apiServiceLoad([FromBody] dynamic sendData)
+        {
+
+            logger.Info("New request income balanceGetList :" + sendData.ToString());
+            apiServiceObjList response = new apiServiceObjList();
+            response.responseCode = "-1";
+            response.responseMessage = "Err unknow";
+
+            try
+            {
+
+                var userObj = JObject.Parse(sendData.ToString());
+
+                string users = Convert.ToString(userObj["users"]);
+                string id = Convert.ToString(userObj["id"]);
+
+
+
+                string order = Convert.ToString(userObj["order"]);
+                string rowsOnPage = Convert.ToString(userObj["rowsOnPage"]);
+                string seqPage = Convert.ToString(userObj["seqPage"]);
+                if (string.IsNullOrEmpty(order)) order = "asc";
+                if (string.IsNullOrEmpty(rowsOnPage)) rowsOnPage = "1000000000000";
+                if (string.IsNullOrEmpty(seqPage)) seqPage = "1";
+                string isActive = Convert.ToString(userObj["isActive"]);
+                if (string.IsNullOrEmpty(isActive)) isActive = "-1";
+
+
+                if (string.IsNullOrEmpty(users)) users = "-1";
+                if (string.IsNullOrEmpty(id)) id = "-1";
+
+
+                string token = Convert.ToString(userObj["token"]);
+                string channel = Convert.ToString(userObj["channel"]);
+                string language = Convert.ToString(userObj["language"]);
+                if (string.IsNullOrEmpty(language)) language = "-1";
+
+                string RedisIp = Common.GetValuesAppSetting("webConfig", "RedisIp");
+                string RedisPort = Common.GetValuesAppSetting("webConfig", "RedisPort");
+                string RedisPass = Common.GetValuesAppSetting("webConfig", "RedisPass");
+                var clientIp = HttpContext.Connection.RemoteIpAddress.ToString();
+
+
+                //---------------------Lay ra va luu mot redis tu cache-----------------------------
+                redisConnection _redis;
+                memoryCache.TryGetValue("redis", out _redis);
+                if (_redis == null)
+                {
+                    var cacheExpiryOptions = new MemoryCacheEntryOptions
+                    {
+                        AbsoluteExpiration = DateTime.Now.AddMonths(12),
+                        Priority = CacheItemPriority.High,
+                        SlidingExpiration = TimeSpan.FromMinutes(2),
+                        Size = 1024,
+                    };
+                    _redis = new redisConnection(RedisIp, RedisPort, RedisPass);
+                    _redis.connet();
+                    memoryCache.Set("redis", _redis, cacheExpiryOptions);
+                }
+                if (!_redis.isConnet())
+                {
+                    if (!_redis.connet())
+                    {
+                        logger.Info("Connect to redis false");
+                        response.responseCode = "-2";
+                        response.responseMessage = "System Update";
+                        logger.Info("confirmTicket response : " + response.ToString());
+                        return Ok(response);
+                    }
+                    else
+                    {
+                        var cacheExpiryOptions = new MemoryCacheEntryOptions
+                        {
+                            AbsoluteExpiration = DateTime.Now.AddMonths(12),
+                            Priority = CacheItemPriority.High,
+                            SlidingExpiration = TimeSpan.FromMinutes(2),
+                            Size = 1024,
+                        };
+                        memoryCache.Set("redis", _redis, cacheExpiryOptions);
+
+                    }
+                }
+                //----------------------Ket thuc lay redis tu cache -------------------------------------
+
+                tokenObj _tokenObj = null;
+                if (!CommonFunction.checkToken(clientIp, token, channel, _redis, logger, out _tokenObj))
+                {
+                    logger.Info("Authen token false");
+                    response.responseCode = "35";
+                    response.responseMessage = CommonObj.common.CommonFunction.getErrCodeObjFromRedis(_redis, channel, response.responseCode, language);
+                    logger.Info("confirmTicket response : " + response.ToString());
+                    return Ok(response);
+                }
+
+
+
+                DataSet ds_regist = balanceDataAccess.apiServiceLoad(id, users, order, rowsOnPage, seqPage, isActive);
+                logger.Info("Call database apiServiceLoad success:");
+                response.responseCode = "0";
+                response.responseMessage = "Success";
+                if (ds_regist != null & ds_regist.Tables[0].Rows.Count > 0)
+                {
+
+
+                    response.rowsOnPage = ds_regist.Tables[0].Rows[0]["ROW_ON_PAGE"].ToString();
+                    response.seqPage = ds_regist.Tables[0].Rows[0]["SEQ_PAGE"].ToString();
+                    response.totalPage = ds_regist.Tables[0].Rows[0]["TOTAL_PAGE"].ToString();
+
+
+                    response.list = new apiServiceObj[ds_regist.Tables[0].Rows.Count];
+                    for (int j = 0; j < ds_regist.Tables[0].Rows.Count; j++)
+                    {
+                        apiServiceObj _obj = new apiServiceObj();
+
+                        _obj.ws_id = ds_regist.Tables[0].Rows[j]["WS_ID"].ToString();
+                        _obj.ws_name = ds_regist.Tables[0].Rows[j]["WS_NAME"].ToString();
+                        _obj.ws_code = ds_regist.Tables[0].Rows[j]["WS_CODE"].ToString();
+                        _obj.wsdl = ds_regist.Tables[0].Rows[j]["WSDL"].ToString();
+                        _obj.msg_template = ds_regist.Tables[0].Rows[j]["MSG_TEMPLATE"].ToString();
+                        _obj.error_tag = ds_regist.Tables[0].Rows[j]["ERROR_TAG"].ToString();
+
+                        _obj.isActive = ds_regist.Tables[0].Rows[j]["IS_ACTIVE"].ToString();
+
+                        response.list[j] = _obj;
+                    }
+
+                }
+
+
+
+
+            }
+            catch (Exception ex)
+            {
+                logger.Info("exception: " + ex.ToString());
+                response.responseCode = "-2";
+                response.responseMessage = "System upgrade";
+
+            }
+            logger.Info("Responase to web: " + response.ToString());
+            return Ok(response);
+        }
+
+
+        public IActionResult apiServiceInsertOrUpdate([FromBody] dynamic sendData)
+        {
+
+            logger.Info("New request income companyUpdate :" + sendData.ToString());
+            Response response = new Response();
+            response.responseCode = "-1";
+            response.responseMessage = "Err unknow";
+
+            try
+            {
+
+                var userObj = JObject.Parse(sendData.ToString());
+                string id = Convert.ToString(userObj["id"]);
+                string ws_name = Convert.ToString(userObj["ws_name"]);
+                string ws_code = Convert.ToString(userObj["ws_code"]);
+                string wsdl = Convert.ToString(userObj["wsdl"]);
+                string msg_template = Convert.ToString(userObj["msg_template"]);
+                string error_tag = Convert.ToString(userObj["error_tag"]);
+                string isActive = Convert.ToString(userObj["isActive"]);
+
+                string users = Convert.ToString(userObj["users"]);
+
+
+
+                if (string.IsNullOrEmpty(id)) id = "-1";
+                if (string.IsNullOrEmpty(ws_name)) ws_name = "";
+                if (string.IsNullOrEmpty(ws_code)) ws_code = "";
+                if (string.IsNullOrEmpty(wsdl)) wsdl = "";
+                if (string.IsNullOrEmpty(msg_template)) msg_template = "";
+                if (string.IsNullOrEmpty(error_tag)) error_tag = "";
+                if (string.IsNullOrEmpty(isActive)) isActive = "1";
+
+
+
+                if (string.IsNullOrEmpty(users)) users = "-1";
+
+                string token = Convert.ToString(userObj["token"]);
+                string channel = Convert.ToString(userObj["channel"]);
+                string language = Convert.ToString(userObj["language"]);
+                if (string.IsNullOrEmpty(language)) language = "-1";
+                /*
+                if (string.IsNullOrEmpty(requestId)) requestId = "";
+                if (string.IsNullOrEmpty(transIdByTicket)) transIdByTicket = "";
+                if (string.IsNullOrEmpty(paymentCode)) paymentCode = "";
+                if (string.IsNullOrEmpty(token)) token = "";
+                */
+
+                string RedisIp = Common.GetValuesAppSetting("webConfig", "RedisIp");
+                string RedisPort = Common.GetValuesAppSetting("webConfig", "RedisPort");
+                string RedisPass = Common.GetValuesAppSetting("webConfig", "RedisPass");
+                var clientIp = HttpContext.Connection.RemoteIpAddress.ToString();
+
+
+                //---------------------Lay ra va luu mot redis tu cache-----------------------------
+                redisConnection _redis;
+                memoryCache.TryGetValue("redis", out _redis);
+                if (_redis == null)
+                {
+                    var cacheExpiryOptions = new MemoryCacheEntryOptions
+                    {
+                        AbsoluteExpiration = DateTime.Now.AddMonths(12),
+                        Priority = CacheItemPriority.High,
+                        SlidingExpiration = TimeSpan.FromMinutes(2),
+                        Size = 1024,
+                    };
+                    _redis = new redisConnection(RedisIp, RedisPort, RedisPass);
+                    _redis.connet();
+                    memoryCache.Set("redis", _redis, cacheExpiryOptions);
+                }
+                if (!_redis.isConnet())
+                {
+                    if (!_redis.connet())
+                    {
+                        logger.Info("Connect to redis false");
+                        response.responseCode = "-2";
+                        response.responseMessage = "System Update";
+                        logger.Info("confirmTicket response : " + response.ToString());
+                        return Ok(response);
+                    }
+                    else
+                    {
+                        var cacheExpiryOptions = new MemoryCacheEntryOptions
+                        {
+                            AbsoluteExpiration = DateTime.Now.AddMonths(12),
+                            Priority = CacheItemPriority.High,
+                            SlidingExpiration = TimeSpan.FromMinutes(2),
+                            Size = 1024,
+                        };
+                        memoryCache.Set("redis", _redis, cacheExpiryOptions);
+
+                    }
+                }
+                //----------------------Ket thuc lay redis tu cache -------------------------------------
+
+                tokenObj _tokenObj = null;
+                if (!CommonFunction.checkToken(clientIp, token, channel, _redis, logger, out _tokenObj))
+                {
+                    logger.Info("Authen token false");
+                    response.responseCode = "35";
+                    response.responseMessage = CommonObj.common.CommonFunction.getErrCodeObjFromRedis(_redis, channel, response.responseCode, language);
+                    logger.Info("confirmTicket response : " + response.ToString());
+                    return Ok(response);
+                }
+
+
+                DataSet ds_regist;
+                if (id != null && id != "" && id != "-1")
+                {
+                    ds_regist = balanceDataAccess.apiServiceUpdate(id, ws_name, ws_code, wsdl, msg_template, error_tag, isActive, users);
+                    logger.Info("Call database apiServiceUpdate success:");
+                }
+                else
+                {
+                    ds_regist = balanceDataAccess.apiServiceInsert(ws_name, ws_code, wsdl, msg_template, error_tag, isActive, users);
+                    logger.Info("Call database apiServiceInsert success:");
+                }
+                if (ds_regist != null & ds_regist.Tables[0].Rows.Count > 0)
+                {
+                    logger.Info("Call database success apiServiceInsert/Update not null");
+                    response.responseCode = ds_regist.Tables[0].Rows[0]["status"].ToString();
+                    response.responseMessage = ds_regist.Tables[0].Rows[0]["msg"].ToString(); ;
+                }
+                else
+                {
+                    logger.Info("Call database success apiServiceInsert/Update is null");
+                    response.responseCode = "-1";
+                    response.responseMessage = "Err unknow";
+                }
+
+
+
+
+            }
+            catch (Exception ex)
+            {
+                logger.Info("exception: " + ex.ToString());
+                response.responseCode = "-2";
+                response.responseMessage = "System upgrade";
+
+            }
+            logger.Info("Responase to web: " + response.ToString());
+            return Ok(response);
+        }
 
 
 

+ 0 - 748
ApiWeb/ApiProcessToken/Controllers/webservice.cs

@@ -1,748 +0,0 @@
-using System;
-using System.Collections.Generic;
-using System.Linq;
-using System.Net;
-using System.Net.Http;
-
-using System.Xml;
-using System.Data;
-using ResfullApi.Models;
-using System.Configuration;
-using Microsoft.AspNetCore.Mvc;
-using Microsoft.Extensions.Configuration;
-using System.Xml.Linq;
-using ApiProcess.Process;
-
-namespace ApiProcess.Controllers
-{
-   
-   
-   
-    [Route("api/[controller]/[action]/data")]
-    [ApiController]
-   
-
-    public class webservice : ControllerBase
-    {
-        /*
-            http://10.226.40.11:8383/api/webservice/subRequest/data
-         * Nhan cac dang ky va huy qua SMS
-         * 
-         * 
-         * */
-
-        static readonly log4net.ILog logger = log4net.LogManager.GetLogger(typeof(webservice));
-
-
-
-
-        
-        [HttpPost]
-
-        //public string subRequest(HttpRequestMessage request)
-        // public HttpResponseMessage subRequest(HttpRequestMessage request)
-        //[Produces("text/xml")]
-        public IActionResult subRequest([FromBody] XElement xml1)
-        {
-            
-
-            string request = xml1.ToString();
-            logger.Info("Request subRequest from MPS:" + request);
-            string result = "";
-            //string username1 = xml1.GetElementsByTagName("username")[0].InnerText;
-            string ketqua = "0|success";
-            ////log4net.ILog logger = log4net.LogManager.GetLogger(System.Reflection.MethodBase.GetCurrentMethod().DeclaringType);
-            ////log4net.Config.XmlConfigurator.Configure();
-
-            try
-            {
-
-                //string ten = xml1.Element("username").Value;
-
-                //string prefix = ConfigurationSettings.AppSettings["PREFIX"];
-                string prefix = Common.GetValuesAppSetting("webConfig", "PREFIX");
-                XmlDocument xml = new XmlDocument();
-              
-                
-                //logger.Debug(request.Content.ReadAsStreamAsync().Result);
-                //xml.Load(request);
-                xml.LoadXml(request);
-                
-
-                string username = xml.GetElementsByTagName("username")[0].InnerText;
-                string password = xml.GetElementsByTagName("password")[0].InnerText;
-                string serviceid = xml.GetElementsByTagName("serviceid")[0].InnerText;
-                string msisdn = xml.GetElementsByTagName("msisdn")[0].InnerText;
-                string chargetime = xml.GetElementsByTagName("chargetime")[0].InnerText;
-                string paramss = xml.GetElementsByTagName("params")[0].InnerText;
-                string mode = xml.GetElementsByTagName("mode")[0].InnerText;
-                string amount = xml.GetElementsByTagName("amount")[0].InnerText;
-                string command = xml.GetElementsByTagName("command")[0].InnerText;
-                string transaction = xml.GetElementsByTagName("transaction")[0].InnerText;
-                
-                DataSet ds = webserviceDataAccess.ProcessSub(username,
-                                                    password,
-                                                    serviceid,
-                                                    msisdn,
-                                                    chargetime,
-                                                    paramss,
-                                                    mode,
-                                                    amount,
-                                                    command, prefix, transaction);
-
-
-                if (ds != null & ds.Tables[0].Rows.Count > 0)
-                {
-                    ketqua = ds.Tables[0].Rows[0][0].ToString();
-
-                }
-                logger.Debug("Process Request from MPS suceess");
-               
-            }
-            catch (Exception ex)
-            {
-                logger.Debug("Process sub err: " + ex.ToString());
-            }
-
-
-
-
-
-            result = result + @"<?xml version=""1.0""?> <S:Envelope xmlns:S=""http://schemas.xmlsoap.org/soap/envelope/"" >";
-            result = result + @"<S:Body>";
-            result = result + @"<subRequestResponse xmlns=""http://contentws/xsd"">";
-            result = result + @"<return>";
-            result = result + ketqua;
-            result = result + @"</return>";
-            result = result + @"</subRequestResponse>";
-            result = result + @"</S:Body>";
-            result = result + @"</S:Envelope>";
-            logger.Debug(result);
-            //return new HttpResponseMessage(HttpStatusCode.OK) { Content = new StringContent(result, System.Text.Encoding.UTF8, "text/xml") }; ;
-            Response.Headers.Add("Content-Type", "text/xml");
-            //return Ok(result);
-            return Content(result);
-
-        }
-
-
-
-        [HttpPost]
-
-        //public string subRequest(HttpRequestMessage request)
-        // public HttpResponseMessage subRequest(HttpRequestMessage request)
-        //[Produces("text/xml")]
-        public IActionResult subCheckBuy1Time([FromBody] XElement xml1)
-        {
-
-
-            string request = xml1.ToString();
-            logger.Info("Request subCheckBuy1Time to MPS:" + request);
-            string result = "";
-            //string username1 = xml1.GetElementsByTagName("username")[0].InnerText;
-            string ketqua = "0|success";
-            ////log4net.ILog logger = log4net.LogManager.GetLogger(System.Reflection.MethodBase.GetCurrentMethod().DeclaringType);
-            ////log4net.Config.XmlConfigurator.Configure();
-
-            try
-            {
-
-                //string ten = xml1.Element("username").Value;
-
-                //string prefix = ConfigurationSettings.AppSettings["PREFIX"];
-                string prefix = Common.GetValuesAppSetting("webConfig", "PREFIX");
-                XmlDocument xml = new XmlDocument();
-
-
-                //logger.Debug(request.Content.ReadAsStreamAsync().Result);
-                //xml.Load(request);
-                xml.LoadXml(request);
-
-
-                string username = xml.GetElementsByTagName("username")[0].InnerText;
-                string password = xml.GetElementsByTagName("password")[0].InnerText;
-                string serviceid = xml.GetElementsByTagName("serviceid")[0].InnerText;
-                string msisdn = xml.GetElementsByTagName("msisdn")[0].InnerText;
-                string chargetime = xml.GetElementsByTagName("chargetime")[0].InnerText;
-                string paramss = xml.GetElementsByTagName("params")[0].InnerText;
-                string mode = xml.GetElementsByTagName("mode")[0].InnerText;
-                string amount = xml.GetElementsByTagName("amount")[0].InnerText;
-                string command = xml.GetElementsByTagName("command")[0].InnerText;
-                string transaction = xml.GetElementsByTagName("transaction")[0].InnerText;
-
-                DataSet ds = webserviceDataAccess.ProcessCheckBuy1Time(username,
-                                                    password,
-                                                    serviceid,
-                                                    msisdn,
-                                                    chargetime,
-                                                    paramss,
-                                                    mode,
-                                                    amount,
-                                                    command, prefix, transaction);
-
-
-                if (ds != null & ds.Tables[0].Rows.Count > 0)
-                {
-                    ketqua = ds.Tables[0].Rows[0][0].ToString();
-
-                }
-                logger.Debug("Process Request from MPS suceess");
-
-            }
-            catch (Exception ex)
-            {
-                logger.Debug("Process sub err: " + ex.ToString());
-            }
-
-
-
-
-
-            result = result + @"<?xml version=""1.0""?> <S:Envelope xmlns:S=""http://schemas.xmlsoap.org/soap/envelope/"" >";
-            result = result + @"<S:Body>";
-            result = result + @"<subRequestResponse xmlns=""http://contentws/xsd"">";
-            result = result + @"<return>";
-            result = result + ketqua;
-            result = result + @"</return>";
-            result = result + @"</subRequestResponse>";
-            result = result + @"</S:Body>";
-            result = result + @"</S:Envelope>";
-            logger.Debug(result);
-            //return new HttpResponseMessage(HttpStatusCode.OK) { Content = new StringContent(result, System.Text.Encoding.UTF8, "text/xml") }; ;
-            Response.Headers.Add("Content-Type", "text/xml");
-            //return Ok(result);
-            return Content(result);
-
-        }
-
-
-
-
-
-
-
-        /*
-            http://10.226.40.11:8383/api/webservice/subUssdRequest/data
-         * Nhan cac dang ky va huy qua USSD
-         * 
-         * 
-         * */
-        [HttpPost]
-        //public string subRequest(HttpRequestMessage request)
-        //public HttpResponseMessage subUssdRequest(HttpRequestMessage request)
-        public IActionResult subUssdRequest([FromBody] XElement xml1)
-        {
-            string request = xml1.ToString();
-            logger.Info("Request subUssdRequest from MPS:" + request);
-            string result = "";
-            string ketqua = "0";
-            //log4net.ILog logger = log4net.LogManager.GetLogger(System.Reflection.MethodBase.GetCurrentMethod().DeclaringType);
-            //log4net.Config.XmlConfigurator.Configure();
-
-            try
-            {
-                //string prefix = ConfigurationSettings.AppSettings["PREFIX"];
-                string prefix = Common.GetValuesAppSetting("webConfig", "PREFIX");
-                XmlDocument xml = new XmlDocument();
-                
-                xml.LoadXml(request);
-
-
-                string username = xml.GetElementsByTagName("username")[0].InnerText;
-                string password = xml.GetElementsByTagName("password")[0].InnerText;
-                string servicename = xml.GetElementsByTagName("servicename")[0].InnerText;
-                string msisdn = xml.GetElementsByTagName("msisdn")[0].InnerText;
-                string chargetime = xml.GetElementsByTagName("chargetime")[0].InnerText;
-                string paramss = xml.GetElementsByTagName("params")[0].InnerText;
-                string mode = xml.GetElementsByTagName("mode")[0].InnerText;
-                string amount = xml.GetElementsByTagName("amount")[0].InnerText;
-                string transactionId = xml.GetElementsByTagName("transactionId")[0].InnerText;
-                string other_and_more = xml.GetElementsByTagName("other_and_more")[0].InnerText;
-                DataSet ds = webserviceDataAccess.ProcessSubUssd(username,
-                                                    password,
-                                                    servicename,
-                                                    msisdn,
-                                                    chargetime,
-                                                    paramss,
-                                                    mode,
-                                                    amount,
-                                                    transactionId,
-                                                    other_and_more,
-                                                    prefix);
-                if (ds != null & ds.Tables[0].Rows.Count > 0)
-                {
-                    ketqua = "0";
-
-                }
-                logger.Debug("Process Request from MPS suceess");
-
-            }
-            catch (Exception ex)
-            {
-                logger.Debug("Process sub err: " + ex.ToString());
-            }
-
-
-
-
-
-            result = result + @"<?xml version=""1.0""?> <S:Envelope xmlns:S=""http://schemas.xmlsoap.org/soap/envelope/"" >";
-            result = result + @"<S:Body>";
-            result = result + @"<subRequestResponse xmlns=""http://contentws/xsd"">";
-            result = result + @"<return>";
-            result = result + ketqua;
-            result = result + @"</return>";
-            result = result + @"</subRequestResponse>";
-            result = result + @"</S:Body>";
-            result = result + @"</S:Envelope>";
-            logger.Debug(result);
-            //return new HttpResponseMessage(HttpStatusCode.OK) { Content = new StringContent(result, System.Text.Encoding.UTF8, "text/xml") }; ;
-            //return result;
-            Response.Headers.Add("Content-Type", "text/xml");
-            //return Ok(result);
-            return Content(result);
-
-        }
-
-
-
-
-
-
-
-
-
-
-
-        /*
-            http://10.226.40.11:8383/api/webservice/resultRequest/data
-         * Nhan cac ket qua charge tu MPS
-         * 
-         * 
-         * */
-
-        [HttpPost]
-        //public string resultRequest(HttpRequestMessage request)
-        //public HttpResponseMessage resultRequest(HttpRequestMessage request)
-        public IActionResult resultRequest([FromBody] XElement xml1)
-        {
-            string request = xml1.ToString();
-            logger.Info("Request resultRequest from MPS:" + request);
-            string result = "";
-            string ketqua = "0|success";
-            //log4net.ILog logger = log4net.LogManager.GetLogger(System.Reflection.MethodBase.GetCurrentMethod().DeclaringType);
-            //log4net.Config.XmlConfigurator.Configure();
-
-            try
-            {
-
-
-                //string prefix = ConfigurationSettings.AppSettings["PREFIX"];
-                string prefix = Common.GetValuesAppSetting("webConfig", "PREFIX");
-                if (request == null)  logger.Debug("Request charge from MPS is null");
-
-             
-                XmlDocument xml = new XmlDocument();
-                xml.LoadXml(request);
-
-
-                string username = xml.GetElementsByTagName("username")[0].InnerText;
-                string password = xml.GetElementsByTagName("password")[0].InnerText;
-                string serviceid = xml.GetElementsByTagName("serviceid")[0].InnerText;
-                string msisdn = xml.GetElementsByTagName("msisdn")[0].InnerText;
-                string chargetime = xml.GetElementsByTagName("chargetime")[0].InnerText;
-                string paramss = xml.GetElementsByTagName("params")[0].InnerText;
-                string mode = xml.GetElementsByTagName("mode")[0].InnerText;
-                string amount = xml.GetElementsByTagName("amount")[0].InnerText;
-                string cmd = xml.GetElementsByTagName("command")[0].InnerText;
-                string transaction = xml.GetElementsByTagName("transaction")[0].InnerText;
-
-
-                chargeObj _obj=new chargeObj();
-                _obj.username = username;
-                _obj.password = password;
-                _obj.serviceid = serviceid;
-                _obj.msisdn = msisdn;
-                _obj.chargetime = chargetime;
-                _obj.paramss = paramss;
-                _obj.mode = mode;
-                _obj.amount = amount;
-                _obj.cmd = cmd;
-                _obj.transaction = transaction;
-                _obj.prefix = prefix;
-
-                Variable.chargerObj.Enqueue(_obj);
-
-
-                /*
-                DataSet ds = webserviceDataAccess.ProcessCharge(username,
-                                                    password,
-                                                    serviceid,
-                                                    msisdn,
-                                                    chargetime,
-                                                    paramss,
-                                                    mode,
-                                                    amount,
-                                                    prefix,cmd,transaction);
-
-                */
-                //if (ds != null & ds.Tables[0].Rows.Count > 0)
-                //{
-                //    ketqua = ds.Tables[0].Rows[0][0].ToString();
-
-                //}
-                logger.Debug("Input queu success");
-
-
-
-            }
-            catch (Exception ex)
-            {
-                logger.Debug("Process charge err: " + ex.ToString());
-            }
-
-
-            ketqua = "0";
-
-
-            result = result + @"<?xml version=""1.0""?> <S:Envelope xmlns:S=""http://schemas.xmlsoap.org/soap/envelope/"" >";
-            result = result + @"<S:Body>";
-            result = result + @"<subRequestResponse xmlns=""http://contentws/xsd"">";
-            result = result + @"<return>";
-            result = result + ketqua;
-            result = result + @"</return>";
-            result = result + @"</subRequestResponse>";
-            result = result + @"</S:Body>";
-            result = result + @"</S:Envelope>";
-            //return new HttpResponseMessage(HttpStatusCode.OK) { Content = new StringContent(result, System.Text.Encoding.UTF8, "text/xml") }; ;
-            logger.Debug(result);
-            Response.Headers.Add("Content-Type", "text/xml");
-            //return Ok(result);
-            return Content(result);
-
-        }
-
-
-
-        /*
-            http://10.226.40.11:8383/api/webservice/proKeyWord/data
-         * Xu ly cu phap tu MPS
-         * 
-         * 
-         * */
-
-        [HttpPost]
-        //public string resultRequest(HttpRequestMessage request)
-        //public HttpResponseMessage proKeyWord(HttpRequestMessage request)
-        public IActionResult proKeyWord([FromBody] XElement xml1)
-        {
-            string request = xml1.ToString();
-            logger.Info("Request proKeyWord from MPS:" + request);
-            string result = "";
-            string ketqua = "0|success";
-            //log4net.ILog logger = log4net.LogManager.GetLogger(System.Reflection.MethodBase.GetCurrentMethod().DeclaringType);
-            //log4net.Config.XmlConfigurator.Configure();
-
-            try
-            {
-
-
-                //string prefix = ConfigurationSettings.AppSettings["PREFIX"];
-                string prefix = Common.GetValuesAppSetting("webConfig", "PREFIX");
-                if (request == null) logger.Debug("Request proKeyWord from MPS is null");
-
-
-                XmlDocument xml = new XmlDocument();
-                xml.LoadXml(request);
-
-
-                string username = xml.GetElementsByTagName("username")[0].InnerText;
-                string password = xml.GetElementsByTagName("password")[0].InnerText;
-                string serviceid = xml.GetElementsByTagName("serviceid")[0].InnerText;
-                string msisdn = xml.GetElementsByTagName("msisdn")[0].InnerText;
-                string chargetime = xml.GetElementsByTagName("chargetime")[0].InnerText;
-                string paramss = xml.GetElementsByTagName("params")[0].InnerText;
-                string mode = xml.GetElementsByTagName("mode")[0].InnerText;
-                string amount = xml.GetElementsByTagName("amount")[0].InnerText;
-                string cmd = xml.GetElementsByTagName("command")[0].InnerText;
-                string transaction = xml.GetElementsByTagName("transaction")[0].InnerText;
-
-
-                DataSet ds = webserviceDataAccess.ProcessKeyWord(username,
-                                                    password,
-                                                    serviceid,
-                                                    msisdn,
-                                                    chargetime,
-                                                    paramss,
-                                                    mode,
-                                                    amount,
-                                                    prefix, cmd, transaction);
-                if (ds != null & ds.Tables[0].Rows.Count > 0)
-                {
-                    ketqua = ds.Tables[0].Rows[0][0].ToString();
-
-                }
-                logger.Debug("Process Charge from MPS suceess");
-
-            }
-            catch (Exception ex)
-            {
-                logger.Debug("Process charge err: " + ex.ToString());
-            }
-
-
-
-
-
-            result = result + @"<?xml version=""1.0""?> <S:Envelope xmlns:S=""http://schemas.xmlsoap.org/soap/envelope/"" >";
-            result = result + @"<S:Body>";
-            result = result + @"<subRequestResponse xmlns=""http://contentws/xsd"">";
-            result = result + @"<return>";
-            result = result + ketqua;
-            result = result + @"</return>";
-            result = result + @"</subRequestResponse>";
-            result = result + @"</S:Body>";
-            result = result + @"</S:Envelope>";
-            //return new HttpResponseMessage(HttpStatusCode.OK) { Content = new StringContent(result, System.Text.Encoding.UTF8, "text/xml") }; ;
-            logger.Debug(result);
-            //return result;
-            Response.Headers.Add("Content-Type", "text/xml");
-            //return Ok(result);
-            return Content(result);
-
-        }
-
-
-
-
-        [HttpPost]
-        //public string resultRequest(HttpRequestMessage request)
-        //public HttpResponseMessage contentRequest(HttpRequestMessage request)
-        public IActionResult contentRequest([FromBody] XElement xml1)
-        {
-            string request = xml1.ToString();
-            logger.Info("Request contentRequest from MPS:" + request);
-
-            string result = "";
-            string ketqua = "";
-            //log4net.ILog logger = log4net.LogManager.GetLogger(System.Reflection.MethodBase.GetCurrentMethod().DeclaringType);
-            //log4net.Config.XmlConfigurator.Configure();
-
-            try
-            {
-                //string prefix = ConfigurationSettings.AppSettings["PREFIX"];
-                string prefix = Common.GetValuesAppSetting("webConfig", "PREFIX");
-                XmlDocument xml = new XmlDocument();
-                xml.LoadXml(request);
-
-
-                string username = xml.GetElementsByTagName("username")[0].InnerText;
-                string password = xml.GetElementsByTagName("password")[0].InnerText;
-                string serviceid = xml.GetElementsByTagName("serviceid")[0].InnerText;
-                string msisdn = xml.GetElementsByTagName("msisdn")[0].InnerText;
-                
-                string paramss = xml.GetElementsByTagName("params")[0].InnerText;
-                string mode = xml.GetElementsByTagName("mode")[0].InnerText;
-                string amount = xml.GetElementsByTagName("amount")[0].InnerText;
-                string transid = xml.GetElementsByTagName("transid")[0].InnerText;
-
-
-                DataSet ds = webserviceDataAccess.ProcessGetContent(username,
-                                                    password,
-                                                    serviceid,
-                                                    msisdn,
-                                                    transid,
-                                                    paramss,
-                                                    mode,
-                                                    amount,
-                                                    prefix);
-                if (ds != null & ds.Tables[0].Rows.Count > 0)
-                {
-                    string status = ds.Tables[0].Rows[0]["status"].ToString();
-                    string msg = ds.Tables[0].Rows[0]["msg"].ToString();
-                    if (string.IsNullOrEmpty(msg))
-                        ketqua = "0";
-                    else
-                        ketqua = "0|" + msg;
-
-                }
-                logger.Debug("Process Charge from MPS suceess");
-
-            }
-            catch (Exception ex)
-            {
-                logger.Debug("Process charge err: " + ex.ToString());
-            }
-
-
-
-
-
-            result = result + @"<?xml version=""1.0""?> <S:Envelope xmlns:S=""http://schemas.xmlsoap.org/soap/envelope/"" >";
-            result = result + @"<S:Body>";
-            result = result + @"<contentRequestResponse  xmlns=""http://contentws/xsd"">";
-            result = result + @"<return>";
-            result = result + ketqua;
-            result = result + @"</return>";
-            result = result + @"</contentRequestResponse>";
-            result = result + @"</S:Body>";
-            result = result + @"</S:Envelope>";
-            logger.Debug(result);
-            //return new HttpResponseMessage(HttpStatusCode.OK) { Content = new StringContent(result, System.Text.Encoding.UTF8, "text/xml") }; ;
-            Response.Headers.Add("Content-Type", "text/xml");
-            //return Ok(result);
-            return Content(result);
-
-        }
-
-
-
-
-
-
-
-
-        [HttpPost]
-        //public HttpResponseMessage changeZodiacNew(HttpRequestMessage request)
-        public IActionResult changeZodiacNew([FromBody] XElement xml1)
-        {
-            string request = xml1.ToString();
-            logger.Info("Request changeZodiacNew from MPS:" + request);
-
-
-            string result = "";
-            string ketqua = "0|success";
-            //log4net.ILog logger = log4net.LogManager.GetLogger(System.Reflection.MethodBase.GetCurrentMethod().DeclaringType);
-            //log4net.Config.XmlConfigurator.Configure();
-
-            try
-            {
-                //string prefix = ConfigurationSettings.AppSettings["PREFIX"];
-                string prefix = Common.GetValuesAppSetting("webConfig", "PREFIX");
-                XmlDocument xml = new XmlDocument();
-                xml.LoadXml(request);
-
-
-                string username = xml.GetElementsByTagName("username")[0].InnerText;
-                string password = xml.GetElementsByTagName("password")[0].InnerText;
-                string serviceid = xml.GetElementsByTagName("subServiceId")[0].InnerText;
-                string msisdn = xml.GetElementsByTagName("msisdn")[0].InnerText;
-                string paramss = xml.GetElementsByTagName("params")[0].InnerText;
-
-
-                DataSet ds = webserviceDataAccess.changeZodiacNew(username,
-                                                    password,
-                                                    serviceid,
-                                                    msisdn,
-                                                    paramss
-                                                   );
-                if (ds != null & ds.Tables[0].Rows.Count > 0)
-                {
-                    ketqua = ds.Tables[0].Rows[0][0].ToString();
-
-                }
-                logger.Debug("Process Request change changeZodiacNew suceess");
-
-            }
-            catch (Exception ex)
-            {
-                logger.Debug("Process change Zodiac err: " + ex.ToString());
-            }
-
-
-
-
-
-            result = result + @"<?xml version=""1.0""?> <S:Envelope xmlns:S=""http://schemas.xmlsoap.org/soap/envelope/"" >";
-            result = result + @"<S:Body>";
-            result = result + @"<subRequestResponse xmlns=""http://contentws/xsd"">";
-            result = result + @"<return>";
-            result = result + ketqua;
-            result = result + @"</return>";
-            result = result + @"</subRequestResponse>";
-            result = result + @"</S:Body>";
-            result = result + @"</S:Envelope>";
-            logger.Debug(result);
-            //return new HttpResponseMessage(HttpStatusCode.OK) { Content = new StringContent(result, System.Text.Encoding.UTF8, "text/xml") }; ;
-            //return result;
-            Response.Headers.Add("Content-Type", "text/xml");
-            //return Ok(result);
-            return Content(result);
-
-        }
-
-
-
-
-
-        [HttpPost]
-        //public HttpResponseMessage changeZodiac(HttpRequestMessage request)
-        public IActionResult changeZodiac([FromBody] XElement xml1)
-        {
-            string request = xml1.ToString();
-            logger.Info("Request changeZodiac from MPS:" + request);
-
-            string result = "";
-            string ketqua = "0|success";
-            //log4net.ILog logger = log4net.LogManager.GetLogger(System.Reflection.MethodBase.GetCurrentMethod().DeclaringType);
-            //log4net.Config.XmlConfigurator.Configure();
-
-            try
-            {
-                //string prefix = ConfigurationSettings.AppSettings["PREFIX"];
-                string prefix = Common.GetValuesAppSetting("webConfig", "PREFIX");
-                XmlDocument xml = new XmlDocument();
-                xml.LoadXml(request);
-
-
-                string username = xml.GetElementsByTagName("username")[0].InnerText;
-                string password = xml.GetElementsByTagName("password")[0].InnerText;
-                string serviceid = xml.GetElementsByTagName("subServiceId")[0].InnerText;
-                string msisdn = xml.GetElementsByTagName("msisdn")[0].InnerText;
-                string paramss = xml.GetElementsByTagName("params")[0].InnerText;
-
-
-                DataSet ds = webserviceDataAccess.changeZodiac(username,
-                                                    password,
-                                                    serviceid,
-                                                    msisdn,
-                                                    paramss
-                                                   );
-                if (ds != null & ds.Tables[0].Rows.Count > 0)
-                {
-                    ketqua = ds.Tables[0].Rows[0][0].ToString();
-
-                }
-                logger.Debug("Process Request change Zodiac suceess");
-
-            }
-            catch (Exception ex)
-            {
-                logger.Debug("Process change Zodiac err: " + ex.ToString());
-            }
-
-
-
-
-
-            result = result + @"<?xml version=""1.0""?> <S:Envelope xmlns:S=""http://schemas.xmlsoap.org/soap/envelope/"" >";
-            result = result + @"<S:Body>";
-            result = result + @"<subRequestResponse xmlns=""http://contentws/xsd"">";
-            result = result + @"<return>";
-            result = result + ketqua;
-            result = result + @"</return>";
-            result = result + @"</subRequestResponse>";
-            result = result + @"</S:Body>";
-            result = result + @"</S:Envelope>";
-            logger.Debug(result);
-            //return new HttpResponseMessage(HttpStatusCode.OK) { Content = new StringContent(result, System.Text.Encoding.UTF8, "text/xml") }; ;
-            //return result;
-            Response.Headers.Add("Content-Type", "text/xml");
-            //return Ok(result);
-            return Content(result);
-        }
-
-
-
-    }
-}

+ 73 - 0
ApiWeb/ApiProcessToken/Models/banlance/apiServiceObj.cs

@@ -0,0 +1,73 @@
+using System;
+using System.Collections.Generic;
+using System.Linq;
+using System.Threading.Tasks;
+using ApiProcess.Models.bet;
+using CommonObj.model;
+using Newtonsoft.Json;
+namespace ApiProcess.Models.balance
+{
+    public class apiServiceObj
+    {
+        [JsonProperty("ws_id")]
+
+        public string ws_id { get; set; }
+
+        [JsonProperty("ws_name")]
+
+        public string ws_name { get; set; }
+
+        [JsonProperty("ws_code")]
+
+        public string ws_code { get; set; }
+
+        [JsonProperty("wsdl")]
+
+        public string wsdl { get; set; }
+
+        [JsonProperty("msg_template")]
+
+        public string msg_template { get; set; }
+
+        [JsonProperty("error_tag")]
+
+        public string error_tag { get; set; }
+
+
+        [JsonProperty("isActive")]
+        public string isActive { get; set; }
+
+        public override string ToString()
+        {
+            return JsonConvert.SerializeObject(this);
+        }
+    }
+
+    public class apiServiceObjList : Response
+    {
+        [JsonProperty("rowsOnPage")]
+        public string rowsOnPage { get; set; }
+
+        [JsonProperty("seqPage")]
+        public string seqPage { get; set; }
+
+        [JsonProperty("totalPage")]
+        public string totalPage { get; set; }
+
+        [JsonProperty("apiServiceObjList")]
+        public apiServiceObj[] list { get; set; }
+
+        public override string ToString()
+        {
+            return JsonConvert.SerializeObject(this);
+        }
+
+
+
+
+
+    }
+
+
+
+}

+ 313 - 7
ApiWeb/ApiProcessToken/Models/banlance/balanceDataAccess.cs

@@ -1,4 +1,5 @@
 using Oracle.ManagedDataAccess.Client;
+using StackExchange.Redis;
 using System;
 using System.Collections.Generic;
 using System.Data;
@@ -1117,11 +1118,29 @@ namespace ResfullApi.Models.balance
 
             return DataAccess.getDataFromProcedure(str, "", parms);
         }
+        public static DataSet svGroupGetList(string v_id, string v_users)
+        {
+
+            string str;
+            str = "";
+            str = "BALANCE_PKG.SVGROUP_GET";
+            OracleParameter[] parms;
+            parms = new OracleParameter[]
+                            {
+                                new OracleParameter("v_id", OracleDbType.NVarchar2),
+                                new OracleParameter("v_users", OracleDbType.NVarchar2),
+                                new OracleParameter("P_RESULT",OracleDbType.RefCursor,ParameterDirection.Output),
+            };
+            parms[0].Value = v_id;
+            parms[1].Value = v_users;
+
+            return DataAccess.getDataFromProcedure(str, "", parms);
+        }
 
 
         public static DataSet svInsert(string V_CODE, string V_NAME, string V_DESCRIPTION,
             string V_SHORT_CODE, string V_COMMAND_REGISTER, string V_CONTENT_EN, string V_CONTENT_FR, string V_CONTENT_LC, string V_NOTE,
-            string V_COMPANY_ID, string V_USERS, string msgRegisterSuccess, string msgRegisterFlase,string msgConfirm)
+            string V_COMPANY_ID, string V_USERS, string msgRegisterSuccess, string msgRegisterFlase,string msgConfirm,string serviceGroupId,string apiServiceId)
         {
 
             string str;
@@ -1149,6 +1168,8 @@ namespace ResfullApi.Models.balance
                                  new OracleParameter("V_USSD_MSG_REGISTER_SUC", OracleDbType.NVarchar2),
                                 new OracleParameter("V_USSD_MSG_REGISTER_FAIL", OracleDbType.NVarchar2),
                                 new OracleParameter("V_USSD_CONFIRM", OracleDbType.NVarchar2),
+                                new OracleParameter("V_SERVICE_GROUP_ID", OracleDbType.NVarchar2),
+                                new OracleParameter("V_API_SERVICE_ID", OracleDbType.NVarchar2),
                                 new OracleParameter("P_RESULT",OracleDbType.RefCursor,ParameterDirection.Output),
             };
             parms[0].Value = V_CODE;
@@ -1167,6 +1188,8 @@ namespace ResfullApi.Models.balance
             parms[11].Value = msgRegisterSuccess;
             parms[12].Value = msgRegisterFlase;
             parms[13].Value = msgConfirm;
+            parms[14].Value = serviceGroupId;
+            parms[15].Value = apiServiceId;
             return DataAccess.getDataFromProcedure(str, "", parms);
         }
 
@@ -1174,7 +1197,7 @@ namespace ResfullApi.Models.balance
 
         public static DataSet svUpdate(string V_ID,string V_CODE, string V_NAME, string V_DESCRIPTION,
             string V_SHORT_CODE, string V_COMMAND_REGISTER, string V_CONTENT_EN, string V_CONTENT_FR, string V_CONTENT_LC, string V_NOTE,
-            string V_COMPANY_ID, string V_USERS, string V_TYPE, string msgRegisterSuccess, string msgRegisterFlase,string msgConfirm)
+            string V_COMPANY_ID, string V_USERS, string V_TYPE, string msgRegisterSuccess, string msgRegisterFlase,string msgConfirm, string serviceGroupId, string apiServiceId)
         {
 
             string str;
@@ -1200,9 +1223,12 @@ namespace ResfullApi.Models.balance
 
                                 new OracleParameter("V_USERS", OracleDbType.NVarchar2),
                                 new OracleParameter("V_TYPE", OracleDbType.NVarchar2),
-                                 new OracleParameter("V_USSD_MSG_REGISTER_SUC", OracleDbType.NVarchar2),
+                                new OracleParameter("V_USSD_MSG_REGISTER_SUC", OracleDbType.NVarchar2),
                                 new OracleParameter("V_USSD_MSG_REGISTER_FAIL", OracleDbType.NVarchar2),
                                 new OracleParameter("V_USSD_CONFIRM", OracleDbType.NVarchar2),
+
+                                new OracleParameter("V_SERVICE_GROUP_ID", OracleDbType.NVarchar2),
+                                new OracleParameter("V_API_SERVICE_ID", OracleDbType.NVarchar2),
                                 new OracleParameter("P_RESULT",OracleDbType.RefCursor,ParameterDirection.Output),
             };
             parms[0].Value = V_ID;
@@ -1224,11 +1250,69 @@ namespace ResfullApi.Models.balance
             parms[13].Value = msgRegisterSuccess;
             parms[14].Value = msgRegisterFlase;
             parms[15].Value = msgConfirm;
+            parms[16].Value = serviceGroupId;
+            parms[17].Value = apiServiceId;
             return DataAccess.getDataFromProcedure(str, "", parms);
         }
 
 
 
+        public static void serviceUpdateGroupAndApiById(string id, string serviceGroupId, string apiServiceId)
+        {
+            if (string.IsNullOrEmpty(id)) return;
+            if (string.IsNullOrEmpty(serviceGroupId) && string.IsNullOrEmpty(apiServiceId)) return;
+            OracleConnection dbConnection = DataAccess.getPoolingConnection();
+            try
+            {
+                dbConnection.Open();
+                List<string> sets = new List<string>();
+                if (!string.IsNullOrEmpty(serviceGroupId)) sets.Add("SERVICE_GROUP_ID = :groupId");
+                if (!string.IsNullOrEmpty(apiServiceId)) sets.Add("API_SERVICE_ID = :apiId");
+                if (sets.Count == 0) return;
+                string sql = "UPDATE SERVICE SET " + string.Join(",", sets) + " WHERE ID = :id";
+                using (OracleCommand cmd = new OracleCommand(sql, dbConnection))
+                {
+                    if (!string.IsNullOrEmpty(serviceGroupId)) cmd.Parameters.Add(":groupId", OracleDbType.NVarchar2).Value = serviceGroupId;
+                    if (!string.IsNullOrEmpty(apiServiceId)) cmd.Parameters.Add(":apiId", OracleDbType.NVarchar2).Value = apiServiceId;
+                    cmd.Parameters.Add(":id", OracleDbType.NVarchar2).Value = id;
+                    cmd.ExecuteNonQuery();
+                }
+            }
+            finally
+            {
+                dbConnection.Close();
+            }
+        }
+
+        public static void serviceUpdateGroupAndApiByCode(string code, string serviceGroupId, string apiServiceId)
+        {
+            if (string.IsNullOrEmpty(code)) return;
+            if (string.IsNullOrEmpty(serviceGroupId) && string.IsNullOrEmpty(apiServiceId)) return;
+            OracleConnection dbConnection = DataAccess.getPoolingConnection();
+            try
+            {
+                dbConnection.Open();
+                List<string> sets = new List<string>();
+                if (!string.IsNullOrEmpty(serviceGroupId)) sets.Add("SERVICE_GROUP_ID = :groupId");
+                if (!string.IsNullOrEmpty(apiServiceId)) sets.Add("API_SERVICE_ID = :apiId");
+                if (sets.Count == 0) return;
+                string sql = "UPDATE SERVICE SET " + string.Join(",", sets) + " WHERE CODE = :code";
+                using (OracleCommand cmd = new OracleCommand(sql, dbConnection))
+                {
+                    if (!string.IsNullOrEmpty(serviceGroupId)) cmd.Parameters.Add(":groupId", OracleDbType.NVarchar2).Value = serviceGroupId;
+                    if (!string.IsNullOrEmpty(apiServiceId)) cmd.Parameters.Add(":apiId", OracleDbType.NVarchar2).Value = apiServiceId;
+                    cmd.Parameters.Add(":code", OracleDbType.NVarchar2).Value = code;
+                    cmd.ExecuteNonQuery();
+                }
+            }
+            finally
+            {
+                dbConnection.Close();
+            }
+        }
+
+
+
         public static DataSet svAddGetList(string v_id, string v_users, string v_name, string v_code, string v_fromDate, string v_toDate
             , string v_order, string v_rowsOnPage, string v_seqPage)
         {
@@ -2139,7 +2223,7 @@ namespace ResfullApi.Models.balance
 
 
         public static DataSet camAddInsert(string V_CAMPAING_ID, string V_SERVICE_ADD_ID, string V_NOTE, string V_USERS,
-            string ussdDisplay,string keyRegister)
+            string ussdDisplay,string keyRegister,string msgConfirm)
         {
 
             string str;
@@ -2157,6 +2241,7 @@ namespace ResfullApi.Models.balance
                                 new OracleParameter("V_USERS", OracleDbType.NVarchar2),
                                 new OracleParameter("V_USSD_DIS", OracleDbType.NVarchar2),
                                 new OracleParameter("V_KEY_REGIS", OracleDbType.NVarchar2),
+                                new OracleParameter("V_MSG_CONFIRM", OracleDbType.NVarchar2),
                                 
                                 new OracleParameter("P_RESULT",OracleDbType.RefCursor,ParameterDirection.Output),
             };
@@ -2166,6 +2251,7 @@ namespace ResfullApi.Models.balance
             parms[3].Value = V_USERS;
             parms[4].Value = ussdDisplay;
             parms[5].Value = keyRegister;
+            parms[6].Value = msgConfirm;
 
           
 
@@ -2175,7 +2261,7 @@ namespace ResfullApi.Models.balance
 
 
         public static DataSet camAddUpdate(string V_ID, string V_CAMPAING_ID, string V_SERVICE_ADD_ID, string V_NOTE, 
-            string V_USERS, string V_TYPE,string ussdDisplay,string keyRegister)
+            string V_USERS, string V_TYPE,string ussdDisplay,string keyRegister, string msgConfirm)
         {
 
             string str;
@@ -2196,8 +2282,8 @@ namespace ResfullApi.Models.balance
                                 new OracleParameter("V_TYPE", OracleDbType.NVarchar2),
                                 new OracleParameter("V_USSD_DIS", OracleDbType.NVarchar2),
                                 new OracleParameter("V_KEY_REGIS", OracleDbType.NVarchar2),
+                                new OracleParameter("V_MSG_CONFIRM", OracleDbType.NVarchar2),
 
-                               
 
                                 new OracleParameter("P_RESULT",OracleDbType.RefCursor,ParameterDirection.Output),
             };
@@ -2211,8 +2297,8 @@ namespace ResfullApi.Models.balance
             parms[5].Value = V_TYPE;
             parms[6].Value = ussdDisplay;
             parms[7].Value = keyRegister;
+            parms[8].Value = msgConfirm;
 
-           
 
             return DataAccess.getDataFromProcedure(str, "", parms);
         }
@@ -2623,6 +2709,226 @@ namespace ResfullApi.Models.balance
 
 
 
+        public static DataSet apiServiceLoad(string v_id, string v_users,string v_order, string v_rowsOnPage, string v_seqPage,string v_isactive)
+        {
+            DataSet ds = new DataSet();
+            OracleConnection dbConnection = DataAccess.getPoolingConnection();
+            try
+            {
+                dbConnection.Open();
+                
+                // Parse pagination parameters
+                int rowsOnPage = int.TryParse(v_rowsOnPage, out int r) ? r : 10;
+                int seqPage = int.TryParse(v_seqPage, out int s) ? s : 1;
+                
+                // Build base query for counting total records
+                string countSql = "SELECT COUNT(*) FROM WEBSERVICE WHERE 1=1";
+                string dataSql = "SELECT WS_ID, WS_NAME, WS_CODE, WSDL, MSG_TEMPLATE, ERROR_TAG, STATUS FROM WEBSERVICE WHERE 1=1";
+                
+                // Add filters
+                if (v_id != null && v_id != "-1")
+                {
+                    countSql += " AND WS_ID = :v_id";
+                    dataSql += " AND WS_ID = :v_id";
+                }
+                
+                if (v_isactive != null && v_isactive != "-1")
+                {
+                    countSql += " AND STATUS = :v_isactive";
+                    dataSql += " AND STATUS = :v_isactive";
+                }
+                
+                // Add ordering
+                dataSql += " ORDER BY WS_ID " + (v_order == "desc" ? "DESC" : "ASC");
+                
+                // Calculate pagination
+                OracleCommand countCmd = new OracleCommand(countSql, dbConnection);
+                countCmd.CommandType = CommandType.Text;
+                
+                if (v_id != null && v_id != "-1")
+                {
+                    countCmd.Parameters.Add(":v_id", OracleDbType.NVarchar2).Value = v_id;
+                }
+                
+                if (v_isactive != null && v_isactive != "-1")
+                {
+                    countCmd.Parameters.Add(":v_isactive", OracleDbType.NVarchar2).Value = v_isactive;
+                }
+                
+                int totalRows = Convert.ToInt32(countCmd.ExecuteScalar());
+                int totalPage = (int)Math.Ceiling((double)totalRows / rowsOnPage);
+                
+                // Get paginated data
+                int minRow = (seqPage - 1) * rowsOnPage;
+                dataSql = string.Format(@"SELECT * FROM (
+                    SELECT A.*, ROWNUM rnum FROM ({0}) A WHERE ROWNUM <= {1}
+                ) WHERE rnum > {2}", dataSql, minRow + rowsOnPage, minRow);
+                
+                OracleCommand dataCmd = new OracleCommand(dataSql, dbConnection);
+                dataCmd.CommandType = CommandType.Text;
+                
+                if (v_id != null && v_id != "-1")
+                {
+                    dataCmd.Parameters.Add(":v_id", OracleDbType.NVarchar2).Value = v_id;
+                }
+                
+                if (v_isactive != null && v_isactive != "-1")
+                {
+                    dataCmd.Parameters.Add(":v_isactive", OracleDbType.NVarchar2).Value = v_isactive;
+                }
+                
+                OracleDataAdapter dataAdapter = new OracleDataAdapter(dataCmd);
+                dataAdapter.Fill(ds);
+                
+                // Add pagination metadata to each row
+                if (ds.Tables[0].Columns.Contains("ROW_ON_PAGE"))
+                {
+                    ds.Tables[0].Columns.Remove("ROW_ON_PAGE");
+                }
+                if (ds.Tables[0].Columns.Contains("SEQ_PAGE"))
+                {
+                    ds.Tables[0].Columns.Remove("SEQ_PAGE");
+                }
+                if (ds.Tables[0].Columns.Contains("TOTAL_PAGE"))
+                {
+                    ds.Tables[0].Columns.Remove("TOTAL_PAGE");
+                }
+                
+                ds.Tables[0].Columns.Add("ROW_ON_PAGE", typeof(string));
+                ds.Tables[0].Columns.Add("SEQ_PAGE", typeof(string));
+                ds.Tables[0].Columns.Add("TOTAL_PAGE", typeof(string));
+                ds.Tables[0].Columns.Add("IS_ACTIVE", typeof(string));
+                
+                foreach (DataRow row in ds.Tables[0].Rows)
+                {
+                    row["ROW_ON_PAGE"] = rowsOnPage.ToString();
+                    row["SEQ_PAGE"] = seqPage.ToString();
+                    row["TOTAL_PAGE"] = totalPage.ToString();
+                    row["IS_ACTIVE"] = row["STATUS"].ToString();
+                }
+            }
+            catch (OracleException ex)
+            {
+                throw ex;
+            }
+            catch (Exception ex)
+            {
+                throw ex;
+            }
+            finally
+            {
+                dbConnection.Close();
+            }
+            
+            return ds;
+        }
+
+
+
+		public static DataSet apiServiceInsert(string ws_name, string ws_code, string wsdl, string msg_template, string error_tag, string isActive, string users)
+		{
+			DataSet ds = new DataSet();
+			DataTable tb = new DataTable();
+			tb.Columns.Add("status", typeof(string));
+			tb.Columns.Add("msg", typeof(string));
+			OracleConnection dbConnection = DataAccess.getPoolingConnection();
+			try
+			{
+				dbConnection.Open();
+				string sql = @"INSERT INTO WEBSERVICE(WS_ID, WS_NAME, WS_CODE, WSDL, MSG_TEMPLATE, ERROR_TAG, STATUS)
+							 VALUES(WEBSERVICE_SEQ.NEXTVAL, :ws_name, :ws_code, :wsdl, :msg_template, :error_tag, :status)";
+				using (OracleCommand cmd = new OracleCommand(sql, dbConnection))
+				{
+					cmd.CommandType = CommandType.Text;
+					cmd.Parameters.Add(":ws_name", OracleDbType.NVarchar2).Value = ws_name ?? "";
+					cmd.Parameters.Add(":ws_code", OracleDbType.NVarchar2).Value = ws_code ?? "";
+					cmd.Parameters.Add(":wsdl", OracleDbType.NVarchar2).Value = wsdl ?? "";
+					cmd.Parameters.Add(":msg_template", OracleDbType.NVarchar2).Value = msg_template ?? "";
+					cmd.Parameters.Add(":error_tag", OracleDbType.NVarchar2).Value = error_tag ?? "";
+					cmd.Parameters.Add(":status", OracleDbType.Int32).Value = (isActive == "0" ? 0 : 1);
+					int affected = cmd.ExecuteNonQuery();
+					// get generated id in this session
+					string newId = "";
+					try
+					{
+						using (OracleCommand idCmd = new OracleCommand("SELECT WEBSERVICE_SEQ.CURRVAL FROM DUAL", dbConnection))
+						{
+							object val = idCmd.ExecuteScalar();
+							newId = val == null ? "" : Convert.ToString(val);
+						}
+					}
+					catch { }
+					var row = tb.NewRow();
+					row["status"] = affected > 0 ? "0" : "-1";
+					row["msg"] = affected > 0 ? ("Success" + (newId!=""? ("|"+newId):"")) : "Insert failed";
+					tb.Rows.Add(row);
+				}
+			}
+			catch (Exception ex)
+			{
+				var row = tb.NewRow();
+				row["status"] = "-1";
+				row["msg"] = ex.Message;
+				tb.Rows.Add(row);
+			}
+			finally
+			{
+				dbConnection.Close();
+			}
+			ds.Tables.Add(tb);
+			return ds;
+		}
+
+		public static DataSet apiServiceUpdate(string id, string ws_name, string ws_code, string wsdl, string msg_template, string error_tag, string isActive, string users)
+		{
+			DataSet ds = new DataSet();
+			DataTable tb = new DataTable();
+			tb.Columns.Add("status", typeof(string));
+			tb.Columns.Add("msg", typeof(string));
+			OracleConnection dbConnection = DataAccess.getPoolingConnection();
+			try
+			{
+				dbConnection.Open();
+				string sql = @"UPDATE WEBSERVICE
+							SET WS_NAME = :ws_name,
+								WS_CODE = :ws_code,
+								WSDL = :wsdl,
+								MSG_TEMPLATE = :msg_template,
+								ERROR_TAG = :error_tag,
+								STATUS = :status
+							WHERE WS_ID = :id";
+				using (OracleCommand cmd = new OracleCommand(sql, dbConnection))
+				{
+					cmd.CommandType = CommandType.Text;
+					cmd.Parameters.Add(":ws_name", OracleDbType.NVarchar2).Value = ws_name ?? "";
+					cmd.Parameters.Add(":ws_code", OracleDbType.NVarchar2).Value = ws_code ?? "";
+					cmd.Parameters.Add(":wsdl", OracleDbType.NVarchar2).Value = wsdl ?? "";
+					cmd.Parameters.Add(":msg_template", OracleDbType.NVarchar2).Value = msg_template ?? "";
+					cmd.Parameters.Add(":error_tag", OracleDbType.NVarchar2).Value = error_tag ?? "";
+					cmd.Parameters.Add(":status", OracleDbType.Int32).Value = (isActive == "0" ? 0 : 1);
+					cmd.Parameters.Add(":id", OracleDbType.NVarchar2).Value = id ?? "";
+					int affected = cmd.ExecuteNonQuery();
+					var row = tb.NewRow();
+					row["status"] = affected > 0 ? "0" : "-1";
+					row["msg"] = affected > 0 ? "Success" : "Update failed";
+					tb.Rows.Add(row);
+				}
+			}
+			catch (Exception ex)
+			{
+				var row = tb.NewRow();
+				row["status"] = "-1";
+				row["msg"] = ex.Message;
+				tb.Rows.Add(row);
+			}
+			finally
+			{
+				dbConnection.Close();
+			}
+			ds.Tables.Add(tb);
+			return ds;
+		}
+
 
 
     }

+ 8 - 0
ApiWeb/ApiProcessToken/Models/banlance/serviceObj.cs

@@ -88,6 +88,14 @@ namespace ApiProcess.Models.balance
         [JsonProperty("isMyService")]
         public string isMyService { get; set; }
 
+        [JsonProperty("serviceGroupName")]
+        public string serviceGroupName { get; set; }
+        [JsonProperty("serviceGroupId")]
+        public string serviceGroupId { get; set; }
+
+        [JsonProperty("apiServiceId")]
+        public string apiServiceId { get; set; }
+
 
         public override string ToString()
         {

+ 74 - 20
ApiWeb/ApiProcessToken/Models/common/Queue.cs

@@ -1,8 +1,9 @@
-using System;
+using System;
 using System.Collections;
 using System.IO;
 using System.Runtime.Serialization;
 using System.Runtime.Serialization.Formatters.Binary;
+using System.Text.Json; // Cần thêm namespace này
 
 namespace ApiProcessToken.Models.common
 {
@@ -143,33 +144,86 @@ namespace ApiProcessToken.Models.common
             }
         }
 
-   
+
+        //public void SaveQueue(string file_name)
+        //{
+        //    if (File.Exists(file_name))
+        //    {
+        //        File.Delete(file_name);
+        //    }
+        //    Stream st = File.Create(file_name);
+        //    BinaryFormatter bf = new BinaryFormatter();
+        //    bf.Serialize(st, queueData);
+        //    st.Close();
+        //}
+
+        //public int LoadQueue(string file_name)
+        //{
+        //    if (File.Exists(file_name))
+        //    {
+        //        Stream st = File.OpenRead(file_name);
+        //        if (st.Length > 0)
+        //        {
+        //            BinaryFormatter bf = new BinaryFormatter();
+        //            queueData = (ArrayList)bf.Deserialize(st);
+        //        }
+        //        st.Close();
+        //        //File.Delete(file_name);
+        //    }
+        //    return queueData.Count;
+        //}
+
+
         public void SaveQueue(string file_name)
         {
-            if (File.Exists(file_name))
-            {
-                File.Delete(file_name);
-            }
-            Stream st = File.Create(file_name);
-            BinaryFormatter bf = new BinaryFormatter();
-            bf.Serialize(st, queueData);
-            st.Close();
+            // 1. Chuyển đổi đối tượng (queueData) thành chuỗi JSON.
+            // Dùng System.Text.Json.JsonSerializer.Serialize
+            string jsonString = JsonSerializer.Serialize(queueData);
+
+            // 2. Ghi chuỗi JSON đó vào tệp.
+            // File.WriteAllText tự động tạo tệp nếu nó không tồn tại hoặc ghi đè nếu đã tồn tại.
+            File.WriteAllText(file_name, jsonString);
         }
 
-        public int LoadQueue(string file_name)
+
+
+// Lưu ý: Thay vì gán trực tiếp, chúng ta sẽ trả về đối tượng đã tải.
+// Hãy điều chỉnh class chứa hàm này để nó có thể chấp nhận đối tượng trả về.
+
+    public static ArrayList LoadQueue(string file_name)
         {
-            if (File.Exists(file_name))
+            if (!File.Exists(file_name))
             {
-                Stream st = File.OpenRead(file_name);
-                if (st.Length > 0)
+                // Trả về một ArrayList rỗng nếu tệp không tồn tại.
+                return new ArrayList();
+            }
+
+            try
+            {
+                // 1. Đọc toàn bộ nội dung tệp thành chuỗi JSON.
+                string jsonString = File.ReadAllText(file_name);
+
+                // 2. Kiểm tra chuỗi JSON có rỗng không (thay cho st.Length > 0).
+                if (string.IsNullOrWhiteSpace(jsonString))
                 {
-                    BinaryFormatter bf = new BinaryFormatter();
-                    queueData = (ArrayList)bf.Deserialize(st);
+                    return new ArrayList();
                 }
-                st.Close();
-                //File.Delete(file_name);
+
+                // 3. Chuyển đổi chuỗi JSON trở lại thành đối tượng ArrayList.
+                // Cần truyền rõ ràng kiểu ArrayList
+                ArrayList loadedData = JsonSerializer.Deserialize<ArrayList>(jsonString);
+
+                // Trả về dữ liệu đã tải (hoặc một ArrayList rỗng nếu lỗi deserialize).
+                return loadedData ?? new ArrayList();
+            }
+            catch (Exception ex)
+            {
+                // Nên ghi lại lỗi (logging) ở đây để xử lý các vấn đề về định dạng tệp.
+                Console.WriteLine($"Lỗi khi tải queue từ JSON: {ex.Message}");
+                return new ArrayList();
             }
-            return queueData.Count;
         }
-    }
+
+
+}
 }

+ 0 - 318
ApiWeb/ApiProcessToken/Models/webserviceDataAccess.cs

@@ -1,318 +0,0 @@
-using System;
-using System.Collections.Generic;
-using System.Linq;
-using System.Web;
-using Oracle.ManagedDataAccess.Client;
-using System.Data;
-namespace ResfullApi.Models
-{
-    public class webserviceDataAccess
-    {
-        public webserviceDataAccess()
-        {
-
-        }
-
-
-      
-
-
-
-
-        public static DataSet ProcessSub(string username, string password, string serviceid, string msisdn,
-            string chargetime, string paramss, string mode, string amount, string command, string prefix, string transaction)
-        {
-            string str;
-            str = "";
-            str = "MPS_PKG.PROCESS_SMS_SUB ";
-            OracleParameter[] parms;
-            parms = new OracleParameter[] 
-							{
-                                new OracleParameter("v_username", OracleDbType.NVarchar2),
-                                new OracleParameter("v_password", OracleDbType.NVarchar2),
-                                new OracleParameter("v_serviceid", OracleDbType.NVarchar2),
-                                new OracleParameter("v_msisdn", OracleDbType.NVarchar2),
-                                new OracleParameter("v_chargetime", OracleDbType.NVarchar2),
-                                new OracleParameter("v_paramss", OracleDbType.NVarchar2),
-                                new OracleParameter("v_mode", OracleDbType.NVarchar2),
-                                new OracleParameter("v_amount", OracleDbType.NVarchar2),
-                                new OracleParameter("v_command", OracleDbType.NVarchar2),                       
-                                new OracleParameter("v_prefix", OracleDbType.NVarchar2),
-                                new OracleParameter("v_transaction", OracleDbType.NVarchar2),
-                     			new OracleParameter("P_RESULT ",OracleDbType.RefCursor,ParameterDirection.Output),
-			};
-            parms[0].Value = username;
-            parms[1].Value = password;
-            parms[2].Value = serviceid;
-            parms[3].Value = msisdn;
-            parms[4].Value = chargetime;
-            parms[5].Value = paramss;
-            parms[6].Value = mode;
-            parms[7].Value = amount;
-            parms[8].Value = command;
-            parms[9].Value = prefix;
-            parms[10].Value = transaction;
-
-
-            return DataAccess.getDataFromProcedure(str, "", parms);
-        }
-
-
-
-        public static DataSet ProcessCheckBuy1Time(string username, string password, string serviceid, string msisdn,
-            string chargetime, string paramss, string mode, string amount, string command, string prefix, string transaction)
-        {
-            string str;
-            str = "";
-            str = "MPS_PKG.PROCESS_SMS_SUB_CHECK";
-            OracleParameter[] parms;
-            parms = new OracleParameter[]
-                            {
-                                new OracleParameter("v_username", OracleDbType.NVarchar2),
-                                new OracleParameter("v_password", OracleDbType.NVarchar2),
-                                new OracleParameter("v_serviceid", OracleDbType.NVarchar2),
-                                new OracleParameter("v_msisdn", OracleDbType.NVarchar2),
-                                new OracleParameter("v_chargetime", OracleDbType.NVarchar2),
-                                new OracleParameter("v_paramss", OracleDbType.NVarchar2),
-                                new OracleParameter("v_mode", OracleDbType.NVarchar2),
-                                new OracleParameter("v_amount", OracleDbType.NVarchar2),
-                                new OracleParameter("v_command", OracleDbType.NVarchar2),
-                                new OracleParameter("v_prefix", OracleDbType.NVarchar2),
-                                new OracleParameter("v_transaction", OracleDbType.NVarchar2),
-                                 new OracleParameter("P_RESULT ",OracleDbType.RefCursor,ParameterDirection.Output),
-            };
-            parms[0].Value = username;
-            parms[1].Value = password;
-            parms[2].Value = serviceid;
-            parms[3].Value = msisdn;
-            parms[4].Value = chargetime;
-            parms[5].Value = paramss;
-            parms[6].Value = mode;
-            parms[7].Value = amount;
-            parms[8].Value = command;
-            parms[9].Value = prefix;
-            parms[10].Value = transaction;
-
-
-            return DataAccess.getDataFromProcedure(str, "", parms);
-        }
-
-
-
-        //For ALL
-        public static DataSet changeZodiacNew(string username, string password, string subServiceId, string msisdn,
-             string paramss)
-        {
-            string str;
-            str = "";
-            str = "HORO_PKG.HORO_CHANGE_ZODIAC ";
-            OracleParameter[] parms;
-            parms = new OracleParameter[] 
-							{
-                                new OracleParameter("v_username", OracleDbType.NVarchar2),
-                                new OracleParameter("v_password", OracleDbType.NVarchar2),
-                                new OracleParameter("v_subServiceId", OracleDbType.NVarchar2),
-                                new OracleParameter("v_msisdn", OracleDbType.NVarchar2),
-                                new OracleParameter("v_paramss", OracleDbType.NVarchar2),
-                                new OracleParameter("P_RESULT ",OracleDbType.RefCursor,ParameterDirection.Output),
-			};
-            parms[0].Value = username;
-            parms[1].Value = password;
-            parms[2].Value = subServiceId;
-            parms[3].Value = msisdn;
-            parms[4].Value = paramss;
-
-
-
-            return DataAccess.getDataFromProcedure(str, "", parms);
-        }
-
-
-        //For Natcom
-        public static DataSet changeZodiac(string username, string password, string subServiceId, string msisdn,
-             string paramss)
-        {
-            string str;
-            str = "";
-            str = "natcom_pkg.HORO_CHANGE_ZODIAC ";
-            OracleParameter[] parms;
-            parms = new OracleParameter[] 
-							{
-                                new OracleParameter("v_username", OracleDbType.NVarchar2),
-                                new OracleParameter("v_password", OracleDbType.NVarchar2),
-                                new OracleParameter("v_subServiceId", OracleDbType.NVarchar2),
-                                new OracleParameter("v_msisdn", OracleDbType.NVarchar2),
-                                new OracleParameter("v_paramss", OracleDbType.NVarchar2),
-                                new OracleParameter("P_RESULT ",OracleDbType.RefCursor,ParameterDirection.Output),
-			};
-            parms[0].Value = username;
-            parms[1].Value = password;
-            parms[2].Value = subServiceId;
-            parms[3].Value = msisdn;
-            parms[4].Value = paramss;
-           
-
-
-            return DataAccess.getDataFromProcedure(str, "", parms);
-        }
-
-
-
-
-
-
-
-
-
-        public static DataSet ProcessSubUssd(string username, string password, string serviceid, string msisdn,
-            string chargetime, string paramss, string mode, string amount, string transactionId, string other_and_more,string prefix)
-        {
-            string str;
-            str = "";
-            str = "MPS_PKG.PROCESS_USSD_SUB ";
-            OracleParameter[] parms;
-            parms = new OracleParameter[] 
-							{
-                                new OracleParameter("v_username", OracleDbType.NVarchar2),
-                                new OracleParameter("v_password", OracleDbType.NVarchar2),
-                                new OracleParameter("v_servicename", OracleDbType.NVarchar2),
-                                new OracleParameter("v_msisdn", OracleDbType.NVarchar2),
-                                new OracleParameter("v_chargetime", OracleDbType.NVarchar2),
-                                new OracleParameter("v_paramss", OracleDbType.NVarchar2),
-                                new OracleParameter("v_mode", OracleDbType.NVarchar2),
-                                new OracleParameter("v_amount", OracleDbType.NVarchar2),
-                                new OracleParameter("v_transactionId", OracleDbType.NVarchar2),
-                                new OracleParameter("v_other_and_more", OracleDbType.NVarchar2),                       
-                                new OracleParameter("v_prefix", OracleDbType.NVarchar2),
-                     			new OracleParameter("P_RESULT ",OracleDbType.RefCursor,ParameterDirection.Output),
-			};
-            parms[0].Value = username;
-            parms[1].Value = password;
-            parms[2].Value = serviceid;
-            parms[3].Value = msisdn;
-            parms[4].Value = chargetime;
-            parms[5].Value = paramss;
-            parms[6].Value = mode;
-            parms[7].Value = amount;
-            parms[8].Value = other_and_more;
-            parms[9].Value = prefix;
-
-            return DataAccess.getDataFromProcedure(str, "", parms);
-        }
-
-        public static DataSet ProcessCharge(string username, string password, string serviceid, string msisdn,
-            string chargetime, string paramss, string mode, string amount, string prefix,string cmd,string transaction)
-        {
-            string str;
-            str = "";
-            str = "MPS_PKG.PROCESS_SMS_CHARGE ";
-            OracleParameter[] parms;
-            parms = new OracleParameter[] 
-							{
-                                new OracleParameter("v_username", OracleDbType.NVarchar2),
-                                new OracleParameter("v_password", OracleDbType.NVarchar2),
-                                new OracleParameter("v_serviceid", OracleDbType.NVarchar2),
-                                new OracleParameter("v_msisdn", OracleDbType.NVarchar2),
-                                new OracleParameter("v_chargetime", OracleDbType.NVarchar2),
-                                new OracleParameter("v_paramss", OracleDbType.NVarchar2),
-                                new OracleParameter("v_mode", OracleDbType.NVarchar2),
-                                new OracleParameter("v_amount", OracleDbType.NVarchar2),
-                                new OracleParameter("v_prefix", OracleDbType.NVarchar2),    
-                                new OracleParameter("v_command", OracleDbType.NVarchar2),
-                                new OracleParameter("v_transaction", OracleDbType.NVarchar2),
-                     			new OracleParameter("P_RESULT ",OracleDbType.RefCursor,ParameterDirection.Output),
-			};
-            parms[0].Value = username;
-            parms[1].Value = password;
-            parms[2].Value = serviceid;
-            parms[3].Value = msisdn;
-            parms[4].Value = chargetime;
-            parms[5].Value = paramss;
-            parms[6].Value = mode;
-            parms[7].Value = amount;
-            parms[8].Value = prefix;
-            parms[9].Value = cmd;
-            parms[10].Value = transaction;
-
-
-            return DataAccess.getDataFromProcedure(str, "", parms);
-        }
-
-        public static DataSet ProcessKeyWord(string username, string password, string serviceid, string msisdn,
-            string chargetime, string paramss, string mode, string amount, string prefix, string cmd, string transaction)
-        {
-            string str;
-            str = "";
-            str = "MPS_PKG.PROCESS_SMS_KEYWORD ";
-            OracleParameter[] parms;
-            parms = new OracleParameter[] 
-							{
-                                new OracleParameter("v_username", OracleDbType.NVarchar2),
-                                new OracleParameter("v_password", OracleDbType.NVarchar2),
-                                new OracleParameter("v_serviceid", OracleDbType.NVarchar2),
-                                new OracleParameter("v_msisdn", OracleDbType.NVarchar2),
-                                new OracleParameter("v_chargetime", OracleDbType.NVarchar2),
-                                new OracleParameter("v_paramss", OracleDbType.NVarchar2),
-                                new OracleParameter("v_mode", OracleDbType.NVarchar2),
-                                new OracleParameter("v_amount", OracleDbType.NVarchar2),
-                                new OracleParameter("v_prefix", OracleDbType.NVarchar2),    
-                                new OracleParameter("v_command", OracleDbType.NVarchar2),
-                                new OracleParameter("v_transaction", OracleDbType.NVarchar2),
-                     			new OracleParameter("P_RESULT ",OracleDbType.RefCursor,ParameterDirection.Output),
-			};
-            parms[0].Value = username;
-            parms[1].Value = password;
-            parms[2].Value = serviceid;
-            parms[3].Value = msisdn;
-            parms[4].Value = chargetime;
-            parms[5].Value = paramss;
-            parms[6].Value = mode;
-            parms[7].Value = amount;
-            parms[8].Value = prefix;
-            parms[9].Value = cmd;
-            parms[10].Value = transaction;
-
-
-            return DataAccess.getDataFromProcedure(str, "", parms);
-        }
-
-        public static DataSet ProcessGetContent(string username, string password, string serviceid, string msisdn,
-            string trangId, string paramss, string mode, string amount, string prefix)
-        {
-            string str;
-            str = "";
-            str = "MPS_PKG.PROCESS_GET_CONTENT";
-            OracleParameter[] parms;
-            parms = new OracleParameter[] 
-							{
-                                new OracleParameter("v_username", OracleDbType.NVarchar2),
-                                new OracleParameter("v_password", OracleDbType.NVarchar2),
-                                new OracleParameter("v_serviceid", OracleDbType.NVarchar2),
-                                new OracleParameter("v_msisdn", OracleDbType.NVarchar2),
-                                new OracleParameter("v_trangId", OracleDbType.NVarchar2),
-                                new OracleParameter("v_paramss", OracleDbType.NVarchar2),
-                                new OracleParameter("v_mode", OracleDbType.NVarchar2),
-                                new OracleParameter("v_amount", OracleDbType.NVarchar2),
-                                new OracleParameter("v_prefix", OracleDbType.NVarchar2),    
-                                
-                     			new OracleParameter("P_RESULT ",OracleDbType.RefCursor,ParameterDirection.Output),
-			};
-            parms[0].Value = username;
-            parms[1].Value = password;
-            parms[2].Value = serviceid;
-            parms[3].Value = msisdn;
-            parms[4].Value = trangId;
-            parms[5].Value = paramss;
-            parms[6].Value = mode;
-            parms[7].Value = amount;
-            parms[8].Value = prefix;
-
-
-            return DataAccess.getDataFromProcedure(str, "", parms);
-        }
-
-
-
-
-    }
-}

+ 1 - 2
ApiWeb/ApiProcessToken/Program.cs

@@ -34,8 +34,7 @@ namespace ApiProcess
         //    webBuilder.UseStartup<Startup>();
         //    webBuilder.UseUrls("http://localhost:5003", "https://localhost:5004");
         //});
-
-
+        
 
         public static IHostBuilder CreateHostBuilder(string[] args) =>
              Host.CreateDefaultBuilder(args)

+ 3 - 3
ApiWeb/ApiProcessToken/Properties/PublishProfiles/FolderProfile.pubxml

@@ -10,12 +10,12 @@ https://go.microsoft.com/fwlink/?LinkID=208121.
     <LastUsedBuildConfiguration>Release</LastUsedBuildConfiguration>
     <LastUsedPlatform>Any CPU</LastUsedPlatform>
     <PublishProvider>FileSystem</PublishProvider>
-    <PublishUrl>D:\Viettech\Code\NetCore\ApiProcessToken\publish</PublishUrl>
+    <PublishUrl>D:\Code\Ex_publish\Mytel_BPlus\Apis</PublishUrl>
     <WebPublishMethod>FileSystem</WebPublishMethod>
     <SiteUrlToLaunchAfterPublish />
-    <TargetFramework>netcoreapp3.1</TargetFramework>
+    <TargetFramework>net7.0</TargetFramework>
     <ProjectGuid>7650609d-17bf-452b-80f0-ce9cd388829b</ProjectGuid>
     <SelfContained>true</SelfContained>
-    <RuntimeIdentifier>win-x64</RuntimeIdentifier>
+    <RuntimeIdentifier>linux-x64</RuntimeIdentifier>
   </PropertyGroup>
 </Project>

+ 2 - 2
ApiWeb/ApiProcessToken/Properties/launchSettings.json

@@ -14,7 +14,7 @@
       "environmentVariables": {
         "ASPNETCORE_ENVIRONMENT": "Development"
       },
-      "applicationUrl": "",
+      "applicationUrl": "http://localhost:8989",
       "nativeDebugging": true
     }
   },
@@ -23,7 +23,7 @@
     "windowsAuthentication": false,
     "anonymousAuthentication": true,
     "iisExpress": {
-      "applicationUrl": "http://localhost:41341",
+      "applicationUrl": "http://localhost:8989",
       "sslPort": 0
     }
   }

+ 12 - 11
ApiWeb/ApiProcessToken/appsettings.json

@@ -7,7 +7,7 @@
     "key": "VietNam#1980",
     "isCheckToken": "1",
     //"Connection": "Data Source=(DESCRIPTION=(ADDRESS=(PROTOCOL=TCP)(HOST=171.244.50.177)(PORT=1530))(CONNECT_DATA=(SERVICE_NAME=orcl)));User Id=LOTO_THAILAN;Password=loto098;Connection Timeout=120;",
-    "Connection": "Data Source=(DESCRIPTION=(ADDRESS=(PROTOCOL=TCP)(HOST=127.0.0.1)(PORT=1539))(CONNECT_DATA=(SERVICE_NAME=ORA12C)));User Id=BALANCE;Password=BALANCE;Connection Timeout=120;",
+    "Connection": "Data Source=(DESCRIPTION=(ADDRESS=(PROTOCOL=TCP)(HOST=127.0.0.1)(PORT=1539))(CONNECT_DATA=(SERVICE_NAME=ORA12C)));User Id=MYTEL_BLANCE;Password=123456;Connection Timeout=120;",
     //"Connection": "Data Source=(DESCRIPTION=(ADDRESS=(PROTOCOL=TCP)(HOST=10.225.5.163)(PORT=1521))(CONNECT_DATA=(SERVICE_NAME=vasnew)));User Id=luckycard;Password=V@sLuckY13#$68;Connection Timeout=120; Connection Lifetime=180;Pooling=true;Min Pool Size=1;Max Pool Size=100;Incr Pool Size=10;Validate Connection=true",
     "urlPostGetErrCodeMessage": "http://localhost:41341/api/luckyGame/executes/data",
     "keyPostGetErrCodeMessage": "jqB3Vi1fIlu+9a2ODQs65w==",
@@ -17,7 +17,7 @@
     //0=ko check mem,1=check mem
     "ischeckMemoryCache": "0",
     "url_vaa": "http://10.225.5.252:8180/RadiusGW/Radius?wsdl",
-    "chargeLogPath": "D:\\QuangTiep\\Code\\NetCore\\ApiProcessToken\\logCharge",
+    "chargeLogPath": "D:\\Code\\Telemor\\TimorBplus\\ApiWeb\\ApiProcessToken\\logChargeErr\\",
 
     //for B+
     /*
@@ -25,8 +25,8 @@
     "RedisPort": "6379",
     "RedisPass": "p@ss$12E45"
     */
-    "RedisIp": "27.71.225.61",
-    "RedisPort": "6379",
+    "RedisIp": "171.244.50.177",
+    "RedisPort": "9379",
     "RedisPass": "p@ss$12E45",
     "MPS_IP": "171.244.50.177",
 
@@ -34,13 +34,14 @@
     "isTest": "1"
 
   },
-  "Kestrel": {
-    "EndPoints": {
-      "Http": {
-        "Url": "http://*:8989"
-      }
-    }
-  }, "Logging": {
+  //"Kestrel": {
+  //  "EndPoints": {
+  //    "Http": {
+  //      "Url": "http://127.0.0.1:8989"
+  //    }
+  //  }
+  //}, 
+  "Logging": {
   "LogLevel": {
     "Default": "Information",
     "Microsoft": "Warning",

+ 1 - 1
ApiWeb/CommonObj/CommonObj.csproj

@@ -1,7 +1,7 @@
 <Project Sdk="Microsoft.NET.Sdk">
 
   <PropertyGroup>
-    <TargetFramework>netcoreapp3.1</TargetFramework>
+    <TargetFramework>net7.0</TargetFramework>
   </PropertyGroup>
 
   <ItemGroup>

+ 0 - 170
SuperAdmin/SuperAdmin/Connected Services/SvVsa/ConnectedService.json

@@ -1,170 +0,0 @@
-{
-  "ProviderId": "Microsoft.VisualStudio.ConnectedService.Wcf",
-  "Version": "15.0.40203.910",
-  "GettingStartedDocument": {
-    "Uri": "https://go.microsoft.com/fwlink/?linkid=858517"
-  },
-  "ExtendedData": {
-    "inputs": [
-      "http://154.73.105.33:8080/passportv3/passportWS?wsdl"
-    ],
-    "collectionTypes": [
-      "System.Array",
-      "System.Collections.Generic.Dictionary`2"
-    ],
-    "namespaceMappings": [
-      "*, SvVsa"
-    ],
-    "references": [
-      "ClosedXML, {ClosedXML, 0.95.4}",
-      "Dapper, {Dapper, 2.0.78}",
-      "DocumentFormat.OpenXml, {DocumentFormat.OpenXml, 2.7.2}",
-      "dotnet-aspnet-codegenerator-design, {Microsoft.VisualStudio.Web.CodeGeneration.Design, 3.1.5}",
-      "EPPlus, {EPPlus, 5.6.1}",
-      "ExcelNumberFormat, {ExcelNumberFormat, 1.0.10}",
-      "log4net, {log4net, 2.0.12}",
-      "Microsoft.AspNetCore.Authentication.Abstractions, {Microsoft.AspNetCore.Authentication.Abstractions, 2.2.0}",
-      "Microsoft.AspNetCore.Authentication.Core, {Microsoft.AspNetCore.Authentication.Core, 2.2.0}",
-      "Microsoft.AspNetCore.Authorization, {Microsoft.AspNetCore.Authorization, 2.2.0}",
-      "Microsoft.AspNetCore.Authorization.Policy, {Microsoft.AspNetCore.Authorization.Policy, 2.2.0}",
-      "Microsoft.AspNetCore.Hosting.Abstractions, {Microsoft.AspNetCore.Hosting.Abstractions, 2.2.0}",
-      "Microsoft.AspNetCore.Hosting.Server.Abstractions, {Microsoft.AspNetCore.Hosting.Server.Abstractions, 2.2.0}",
-      "Microsoft.AspNetCore.Html.Abstractions, {Microsoft.AspNetCore.Html.Abstractions, 2.2.0}",
-      "Microsoft.AspNetCore.Http, {Microsoft.AspNetCore.Http, 2.2.0}",
-      "Microsoft.AspNetCore.Http.Abstractions, {Microsoft.AspNetCore.Http.Abstractions, 2.2.0}",
-      "Microsoft.AspNetCore.Http.Extensions, {Microsoft.AspNetCore.Http.Extensions, 2.2.0}",
-      "Microsoft.AspNetCore.Http.Features, {Microsoft.AspNetCore.Http.Features, 2.2.0}",
-      "Microsoft.AspNetCore.Mvc.Abstractions, {Microsoft.AspNetCore.Mvc.Abstractions, 2.2.0}",
-      "Microsoft.AspNetCore.Mvc.Core, {Microsoft.AspNetCore.Mvc.Core, 2.2.5}",
-      "Microsoft.AspNetCore.Mvc.Razor.Extensions, {Microsoft.AspNetCore.Mvc.Razor.Extensions, 3.1.0}",
-      "Microsoft.AspNetCore.Mvc.Razor.RuntimeCompilation, {Microsoft.AspNetCore.Mvc.Razor.RuntimeCompilation, 3.1.0}",
-      "Microsoft.AspNetCore.Razor, {Microsoft.AspNetCore.Razor, 2.2.0}",
-      "Microsoft.AspNetCore.Razor.Language, {Microsoft.AspNetCore.Razor.Language, 3.1.0}",
-      "Microsoft.AspNetCore.Razor.Runtime, {Microsoft.AspNetCore.Razor.Runtime, 2.2.0}",
-      "Microsoft.AspNetCore.ResponseCaching.Abstractions, {Microsoft.AspNetCore.ResponseCaching.Abstractions, 2.2.0}",
-      "Microsoft.AspNetCore.Routing, {Microsoft.AspNetCore.Routing, 2.2.0}",
-      "Microsoft.AspNetCore.Routing.Abstractions, {Microsoft.AspNetCore.Routing.Abstractions, 2.2.0}",
-      "Microsoft.AspNetCore.WebUtilities, {Microsoft.AspNetCore.WebUtilities, 2.2.0}",
-      "Microsoft.CodeAnalysis, {Microsoft.CodeAnalysis.Common, 3.3.1}",
-      "Microsoft.CodeAnalysis.CSharp, {Microsoft.CodeAnalysis.CSharp, 3.3.1}",
-      "Microsoft.CodeAnalysis.CSharp.Workspaces, {Microsoft.CodeAnalysis.CSharp.Workspaces, 3.3.1}",
-      "Microsoft.CodeAnalysis.Razor, {Microsoft.CodeAnalysis.Razor, 3.1.0}",
-      "Microsoft.CodeAnalysis.Workspaces, {Microsoft.CodeAnalysis.Workspaces.Common, 3.3.1}",
-      "Microsoft.Extensions.Configuration, {Microsoft.Extensions.Configuration, 3.1.10}",
-      "Microsoft.Extensions.Configuration.Abstractions, {Microsoft.Extensions.Configuration.Abstractions, 3.1.10}",
-      "Microsoft.Extensions.Configuration.FileExtensions, {Microsoft.Extensions.Configuration.FileExtensions, 3.1.10}",
-      "Microsoft.Extensions.Configuration.Json, {Microsoft.Extensions.Configuration.Json, 3.1.10}",
-      "Microsoft.Extensions.DependencyInjection, {Microsoft.Extensions.DependencyInjection, 3.1.0}",
-      "Microsoft.Extensions.DependencyInjection.Abstractions, {Microsoft.Extensions.DependencyInjection.Abstractions, 3.1.0}",
-      "Microsoft.Extensions.DependencyModel, {Microsoft.Extensions.DependencyModel, 3.1.0}",
-      "Microsoft.Extensions.FileProviders.Abstractions, {Microsoft.Extensions.FileProviders.Abstractions, 3.1.10}",
-      "Microsoft.Extensions.FileProviders.Physical, {Microsoft.Extensions.FileProviders.Physical, 3.1.10}",
-      "Microsoft.Extensions.FileSystemGlobbing, {Microsoft.Extensions.FileSystemGlobbing, 3.1.10}",
-      "Microsoft.Extensions.Hosting.Abstractions, {Microsoft.Extensions.Hosting.Abstractions, 2.2.0}",
-      "Microsoft.Extensions.Logging.Abstractions, {Microsoft.Extensions.Logging.Abstractions, 2.2.0}",
-      "Microsoft.Extensions.ObjectPool, {Microsoft.Extensions.ObjectPool, 2.2.0}",
-      "Microsoft.Extensions.Options, {Microsoft.Extensions.Options, 2.2.0}",
-      "Microsoft.Extensions.PlatformAbstractions, {Microsoft.Extensions.PlatformAbstractions, 1.1.0}",
-      "Microsoft.Extensions.Primitives, {Microsoft.Extensions.Primitives, 3.1.10}",
-      "Microsoft.IO.RecyclableMemoryStream, {Microsoft.IO.RecyclableMemoryStream, 1.4.1}",
-      "Microsoft.Net.Http.Headers, {Microsoft.Net.Http.Headers, 2.2.0}",
-      "Microsoft.VisualStudio.Web.CodeGeneration, {Microsoft.VisualStudio.Web.CodeGeneration, 3.1.5}",
-      "Microsoft.VisualStudio.Web.CodeGeneration.Contracts, {Microsoft.VisualStudio.Web.CodeGeneration.Contracts, 3.1.5}",
-      "Microsoft.VisualStudio.Web.CodeGeneration.Core, {Microsoft.VisualStudio.Web.CodeGeneration.Core, 3.1.5}",
-      "Microsoft.VisualStudio.Web.CodeGeneration.EntityFrameworkCore, {Microsoft.VisualStudio.Web.CodeGeneration.EntityFrameworkCore, 3.1.5}",
-      "Microsoft.VisualStudio.Web.CodeGeneration.Templating, {Microsoft.VisualStudio.Web.CodeGeneration.Templating, 3.1.5}",
-      "Microsoft.VisualStudio.Web.CodeGeneration.Utils, {Microsoft.VisualStudio.Web.CodeGeneration.Utils, 3.1.5}",
-      "Microsoft.VisualStudio.Web.CodeGenerators.Mvc, {Microsoft.VisualStudio.Web.CodeGenerators.Mvc, 3.1.5}",
-      "Microsoft.Win32.Primitives, {Microsoft.Win32.Primitives, 4.3.0}",
-      "Nancy, {Nancy, 2.0.0}",
-      "Newtonsoft.Json, {Newtonsoft.Json, 12.0.2}",
-      "NuGet.Frameworks, {NuGet.Frameworks, 4.7.0}",
-      "Oracle.ManagedDataAccess, {Oracle.ManagedDataAccess.Core, 2.19.100}",
-      "System.AppContext, {System.AppContext, 4.3.0}",
-      "System.Collections, {System.Collections, 4.3.0}",
-      "System.Collections.Concurrent, {System.Collections.Concurrent, 4.3.0}",
-      "System.Collections.Immutable, {System.Collections.Immutable, 1.5.0}",
-      "System.Collections.NonGeneric, {System.Collections.NonGeneric, 4.3.0}",
-      "System.Collections.Specialized, {System.Collections.Specialized, 4.3.0}",
-      "System.ComponentModel, {System.ComponentModel, 4.3.0}",
-      "System.ComponentModel.Annotations, {System.ComponentModel.Annotations, 4.7.0}",
-      "System.ComponentModel.Primitives, {System.ComponentModel.Primitives, 4.3.0}",
-      "System.ComponentModel.TypeConverter, {System.ComponentModel.TypeConverter, 4.3.0}",
-      "System.Composition.AttributedModel, {System.Composition.AttributedModel, 1.0.31}",
-      "System.Composition.Convention, {System.Composition.Convention, 1.0.31}",
-      "System.Composition.Hosting, {System.Composition.Hosting, 1.0.31}",
-      "System.Composition.Runtime, {System.Composition.Runtime, 1.0.31}",
-      "System.Composition.TypedParts, {System.Composition.TypedParts, 1.0.31}",
-      "System.Configuration.ConfigurationManager, {System.Configuration.ConfigurationManager, 4.5.0}",
-      "System.Console, {System.Console, 4.3.0}",
-      "System.Data.Common, {System.Data.Common, 4.3.0}",
-      "System.Diagnostics.Debug, {System.Diagnostics.Debug, 4.3.0}",
-      "System.Diagnostics.DiagnosticSource, {System.Diagnostics.DiagnosticSource, 4.5.0}",
-      "System.Diagnostics.Tools, {System.Diagnostics.Tools, 4.3.0}",
-      "System.Diagnostics.Tracing, {System.Diagnostics.Tracing, 4.3.0}",
-      "System.Drawing.Common, {System.Drawing.Common, 4.7.1}",
-      "System.Globalization, {System.Globalization, 4.3.0}",
-      "System.Globalization.Calendars, {System.Globalization.Calendars, 4.3.0}",
-      "System.IO, {System.IO, 4.3.0}",
-      "System.IO.Compression, {System.IO.Compression, 4.3.0}",
-      "System.IO.Compression.ZipFile, {System.IO.Compression.ZipFile, 4.3.0}",
-      "System.IO.FileSystem, {System.IO.FileSystem, 4.3.0}",
-      "System.IO.FileSystem.Primitives, {System.IO.FileSystem.Primitives, 4.3.0}",
-      "System.IO.Packaging, {System.IO.Packaging, 4.0.0}",
-      "System.Linq, {System.Linq, 4.3.0}",
-      "System.Linq.Expressions, {System.Linq.Expressions, 4.3.0}",
-      "System.Net.Http, {System.Net.Http, 4.3.0}",
-      "System.Net.NameResolution, {System.Net.NameResolution, 4.3.0}",
-      "System.Net.Primitives, {System.Net.Primitives, 4.3.0}",
-      "System.Net.Sockets, {System.Net.Sockets, 4.3.0}",
-      "System.ObjectModel, {System.ObjectModel, 4.3.0}",
-      "System.Reflection, {System.Reflection, 4.3.0}",
-      "System.Reflection.Extensions, {System.Reflection.Extensions, 4.3.0}",
-      "System.Reflection.Metadata, {System.Reflection.Metadata, 1.6.0}",
-      "System.Reflection.Primitives, {System.Reflection.Primitives, 4.3.0}",
-      "System.Reflection.TypeExtensions, {System.Reflection.TypeExtensions, 4.3.0}",
-      "System.Resources.ResourceManager, {System.Resources.ResourceManager, 4.3.0}",
-      "System.Runtime, {System.Runtime, 4.3.0}",
-      "System.Runtime.CompilerServices.Unsafe, {System.Runtime.CompilerServices.Unsafe, 4.5.2}",
-      "System.Runtime.Extensions, {System.Runtime.Extensions, 4.3.0}",
-      "System.Runtime.Handles, {System.Runtime.Handles, 4.3.0}",
-      "System.Runtime.InteropServices, {System.Runtime.InteropServices, 4.3.0}",
-      "System.Runtime.InteropServices.RuntimeInformation, {System.Runtime.InteropServices.RuntimeInformation, 4.3.0}",
-      "System.Runtime.Numerics, {System.Runtime.Numerics, 4.3.0}",
-      "System.Security.AccessControl, {System.Security.AccessControl, 4.5.0}",
-      "System.Security.Claims, {System.Security.Claims, 4.3.0}",
-      "System.Security.Cryptography.Algorithms, {System.Security.Cryptography.Algorithms, 4.3.0}",
-      "System.Security.Cryptography.Encoding, {System.Security.Cryptography.Encoding, 4.3.0}",
-      "System.Security.Cryptography.Pkcs, {System.Security.Cryptography.Pkcs, 4.7.0}",
-      "System.Security.Cryptography.Primitives, {System.Security.Cryptography.Primitives, 4.3.0}",
-      "System.Security.Cryptography.X509Certificates, {System.Security.Cryptography.X509Certificates, 4.3.2}",
-      "System.Security.Permissions, {System.Security.Permissions, 4.5.0}",
-      "System.Security.Principal, {System.Security.Principal, 4.3.0}",
-      "System.Security.Principal.Windows, {System.Security.Principal.Windows, 4.5.0}",
-      "System.ServiceModel, {System.ServiceModel.Primitives, 4.4.4}",
-      "System.ServiceModel.Duplex, {System.ServiceModel.Duplex, 4.4.4}",
-      "System.ServiceModel.Http, {System.ServiceModel.Http, 4.4.4}",
-      "System.ServiceModel.NetTcp, {System.ServiceModel.NetTcp, 4.4.4}",
-      "System.ServiceModel.Primitives, {System.ServiceModel.Primitives, 4.4.4}",
-      "System.ServiceModel.Security, {System.ServiceModel.Security, 4.4.4}",
-      "System.Text.Encoding, {System.Text.Encoding, 4.3.0}",
-      "System.Text.Encoding.CodePages, {System.Text.Encoding.CodePages, 4.7.1}",
-      "System.Text.Encoding.Extensions, {System.Text.Encoding.Extensions, 4.3.0}",
-      "System.Text.Encodings.Web, {System.Text.Encodings.Web, 4.5.0}",
-      "System.Text.Json, {System.Text.Json, 4.7.0}",
-      "System.Text.RegularExpressions, {System.Text.RegularExpressions, 4.3.0}",
-      "System.Threading, {System.Threading, 4.3.0}",
-      "System.Threading.Tasks, {System.Threading.Tasks, 4.3.0}",
-      "System.Threading.Timer, {System.Threading.Timer, 4.3.0}",
-      "System.Xml.ReaderWriter, {System.Xml.ReaderWriter, 4.3.0}",
-      "System.Xml.XDocument, {System.Xml.XDocument, 4.3.0}",
-      "System.Xml.XmlDocument, {System.Xml.XmlDocument, 4.3.0}",
-      "System.Xml.XmlSerializer, {System.Xml.XmlSerializer, 4.3.0}",
-      "System.Xml.XPath, {System.Xml.XPath, 4.3.0}",
-      "System.Xml.XPath.XmlDocument, {System.Xml.XPath.XmlDocument, 4.3.0}"
-    ],
-    "sync": true,
-    "targetFramework": "netcoreapp3.1",
-    "typeReuseMode": "All"
-  }
-}

+ 0 - 1163
SuperAdmin/SuperAdmin/Connected Services/SvVsa/Reference.cs

@@ -1,1163 +0,0 @@
-//------------------------------------------------------------------------------
-// <auto-generated>
-//     This code was generated by a tool.
-//
-//     Changes to this file may cause incorrect behavior and will be lost if
-//     the code is regenerated.
-// </auto-generated>
-//------------------------------------------------------------------------------
-
-namespace SvVsa
-{
-    
-    
-    [System.CodeDom.Compiler.GeneratedCodeAttribute("Microsoft.Tools.ServiceModel.Svcutil", "2.0.2")]
-    [System.ServiceModel.ServiceContractAttribute(Namespace="http://passport.viettel.com/", ConfigurationName="SvVsa.passportWS")]
-    public interface passportWS
-    {
-        
-        // CODEGEN: Parameter 'return' requires additional schema information that cannot be captured using the parameter mode. The specific attribute is 'Microsoft.Xml.Serialization.XmlElementAttribute'.
-        [System.ServiceModel.OperationContractAttribute(Action="http://passport.viettel.com/passportWS/validateRequest", ReplyAction="http://passport.viettel.com/passportWS/validateResponse")]
-        [System.ServiceModel.XmlSerializerFormatAttribute(SupportFaults=true)]
-        [return: System.ServiceModel.MessageParameterAttribute(Name="return")]
-        SvVsa.validateResponse validate(SvVsa.validateRequest request);
-        
-        [System.ServiceModel.OperationContractAttribute(Action="http://passport.viettel.com/passportWS/validateRequest", ReplyAction="http://passport.viettel.com/passportWS/validateResponse")]
-        System.Threading.Tasks.Task<SvVsa.validateResponse> validateAsync(SvVsa.validateRequest request);
-        
-        // CODEGEN: Parameter 'return' requires additional schema information that cannot be captured using the parameter mode. The specific attribute is 'Microsoft.Xml.Serialization.XmlElementAttribute'.
-        [System.ServiceModel.OperationContractAttribute(Action="http://passport.viettel.com/passportWS/getAppFunctionsRequest", ReplyAction="http://passport.viettel.com/passportWS/getAppFunctionsResponse")]
-        [System.ServiceModel.XmlSerializerFormatAttribute(SupportFaults=true)]
-        [return: System.ServiceModel.MessageParameterAttribute(Name="return")]
-        SvVsa.getAppFunctionsResponse getAppFunctions(SvVsa.getAppFunctionsRequest request);
-        
-        [System.ServiceModel.OperationContractAttribute(Action="http://passport.viettel.com/passportWS/getAppFunctionsRequest", ReplyAction="http://passport.viettel.com/passportWS/getAppFunctionsResponse")]
-        System.Threading.Tasks.Task<SvVsa.getAppFunctionsResponse> getAppFunctionsAsync(SvVsa.getAppFunctionsRequest request);
-        
-        // CODEGEN: Parameter 'return' requires additional schema information that cannot be captured using the parameter mode. The specific attribute is 'Microsoft.Xml.Serialization.XmlElementAttribute'.
-        [System.ServiceModel.OperationContractAttribute(Action="http://passport.viettel.com/passportWS/validateIncludeIpRequest", ReplyAction="http://passport.viettel.com/passportWS/validateIncludeIpResponse")]
-        [System.ServiceModel.XmlSerializerFormatAttribute(SupportFaults=true)]
-        [return: System.ServiceModel.MessageParameterAttribute(Name="return")]
-        SvVsa.validateIncludeIpResponse validateIncludeIp(SvVsa.validateIncludeIpRequest request);
-        
-        [System.ServiceModel.OperationContractAttribute(Action="http://passport.viettel.com/passportWS/validateIncludeIpRequest", ReplyAction="http://passport.viettel.com/passportWS/validateIncludeIpResponse")]
-        System.Threading.Tasks.Task<SvVsa.validateIncludeIpResponse> validateIncludeIpAsync(SvVsa.validateIncludeIpRequest request);
-        
-        // CODEGEN: Parameter 'return' requires additional schema information that cannot be captured using the parameter mode. The specific attribute is 'Microsoft.Xml.Serialization.XmlElementAttribute'.
-        [System.ServiceModel.OperationContractAttribute(Action="http://passport.viettel.com/passportWS/getRolesOfAppRequest", ReplyAction="http://passport.viettel.com/passportWS/getRolesOfAppResponse")]
-        [System.ServiceModel.XmlSerializerFormatAttribute(SupportFaults=true)]
-        [return: System.ServiceModel.MessageParameterAttribute(Name="return")]
-        SvVsa.getRolesOfAppResponse getRolesOfApp(SvVsa.getRolesOfAppRequest request);
-        
-        [System.ServiceModel.OperationContractAttribute(Action="http://passport.viettel.com/passportWS/getRolesOfAppRequest", ReplyAction="http://passport.viettel.com/passportWS/getRolesOfAppResponse")]
-        System.Threading.Tasks.Task<SvVsa.getRolesOfAppResponse> getRolesOfAppAsync(SvVsa.getRolesOfAppRequest request);
-        
-        // CODEGEN: Parameter 'return' requires additional schema information that cannot be captured using the parameter mode. The specific attribute is 'Microsoft.Xml.Serialization.XmlElementAttribute'.
-        [System.ServiceModel.OperationContractAttribute(Action="http://passport.viettel.com/passportWS/changePassRequest", ReplyAction="http://passport.viettel.com/passportWS/changePassResponse")]
-        [System.ServiceModel.XmlSerializerFormatAttribute(SupportFaults=true)]
-        [System.ServiceModel.ServiceKnownTypeAttribute(typeof(validateIncludeIpResponse))]
-        [System.ServiceModel.ServiceKnownTypeAttribute(typeof(validateIncludeIp))]
-        [System.ServiceModel.ServiceKnownTypeAttribute(typeof(getAppFunctionsResponse))]
-        [System.ServiceModel.ServiceKnownTypeAttribute(typeof(getAppFunctions))]
-        [System.ServiceModel.ServiceKnownTypeAttribute(typeof(getRolesOfAppResponse))]
-        [System.ServiceModel.ServiceKnownTypeAttribute(typeof(getRolesOfApp))]
-        [System.ServiceModel.ServiceKnownTypeAttribute(typeof(changePassResponse))]
-        [System.ServiceModel.ServiceKnownTypeAttribute(typeof(changePass))]
-        [System.ServiceModel.ServiceKnownTypeAttribute(typeof(getAllowedAppResponse))]
-        [System.ServiceModel.ServiceKnownTypeAttribute(typeof(getAllowedApp))]
-        [System.ServiceModel.ServiceKnownTypeAttribute(typeof(validateResponse))]
-        [System.ServiceModel.ServiceKnownTypeAttribute(typeof(validate))]
-        [return: System.ServiceModel.MessageParameterAttribute(Name="return")]
-        SvVsa.changePassResponse1 changePass(SvVsa.changePassRequest request);
-        
-        [System.ServiceModel.OperationContractAttribute(Action="http://passport.viettel.com/passportWS/changePassRequest", ReplyAction="http://passport.viettel.com/passportWS/changePassResponse")]
-        System.Threading.Tasks.Task<SvVsa.changePassResponse1> changePassAsync(SvVsa.changePassRequest request);
-        
-        // CODEGEN: Parameter 'return' requires additional schema information that cannot be captured using the parameter mode. The specific attribute is 'Microsoft.Xml.Serialization.XmlElementAttribute'.
-        [System.ServiceModel.OperationContractAttribute(Action="http://passport.viettel.com/passportWS/getAllowedAppRequest", ReplyAction="http://passport.viettel.com/passportWS/getAllowedAppResponse")]
-        [System.ServiceModel.XmlSerializerFormatAttribute(SupportFaults=true)]
-        [System.ServiceModel.ServiceKnownTypeAttribute(typeof(validateIncludeIpResponse))]
-        [System.ServiceModel.ServiceKnownTypeAttribute(typeof(validateIncludeIp))]
-        [System.ServiceModel.ServiceKnownTypeAttribute(typeof(getAppFunctionsResponse))]
-        [System.ServiceModel.ServiceKnownTypeAttribute(typeof(getAppFunctions))]
-        [System.ServiceModel.ServiceKnownTypeAttribute(typeof(getRolesOfAppResponse))]
-        [System.ServiceModel.ServiceKnownTypeAttribute(typeof(getRolesOfApp))]
-        [System.ServiceModel.ServiceKnownTypeAttribute(typeof(changePassResponse))]
-        [System.ServiceModel.ServiceKnownTypeAttribute(typeof(changePass))]
-        [System.ServiceModel.ServiceKnownTypeAttribute(typeof(getAllowedAppResponse))]
-        [System.ServiceModel.ServiceKnownTypeAttribute(typeof(getAllowedApp))]
-        [System.ServiceModel.ServiceKnownTypeAttribute(typeof(validateResponse))]
-        [System.ServiceModel.ServiceKnownTypeAttribute(typeof(validate))]
-        [return: System.ServiceModel.MessageParameterAttribute(Name="return")]
-        SvVsa.getAllowedAppResponse1 getAllowedApp(SvVsa.getAllowedAppRequest request);
-        
-        [System.ServiceModel.OperationContractAttribute(Action="http://passport.viettel.com/passportWS/getAllowedAppRequest", ReplyAction="http://passport.viettel.com/passportWS/getAllowedAppResponse")]
-        System.Threading.Tasks.Task<SvVsa.getAllowedAppResponse1> getAllowedAppAsync(SvVsa.getAllowedAppRequest request);
-    }
-    
-    [System.Diagnostics.DebuggerStepThroughAttribute()]
-    [System.CodeDom.Compiler.GeneratedCodeAttribute("Microsoft.Tools.ServiceModel.Svcutil", "2.0.2")]
-    [System.ComponentModel.EditorBrowsableAttribute(System.ComponentModel.EditorBrowsableState.Advanced)]
-    [System.ServiceModel.MessageContractAttribute(WrapperName="validate", WrapperNamespace="http://passport.viettel.com/", IsWrapped=true)]
-    public partial class validateRequest
-    {
-        
-        [System.ServiceModel.MessageBodyMemberAttribute(Namespace="http://passport.viettel.com/", Order=0)]
-        [System.Xml.Serialization.XmlElementAttribute(Form=System.Xml.Schema.XmlSchemaForm.Unqualified)]
-        public string userName;
-        
-        [System.ServiceModel.MessageBodyMemberAttribute(Namespace="http://passport.viettel.com/", Order=1)]
-        [System.Xml.Serialization.XmlElementAttribute(Form=System.Xml.Schema.XmlSchemaForm.Unqualified)]
-        public string password;
-        
-        [System.ServiceModel.MessageBodyMemberAttribute(Namespace="http://passport.viettel.com/", Order=2)]
-        [System.Xml.Serialization.XmlElementAttribute(Form=System.Xml.Schema.XmlSchemaForm.Unqualified)]
-        public string domainCode;
-        
-        public validateRequest()
-        {
-        }
-        
-        public validateRequest(string userName, string password, string domainCode)
-        {
-            this.userName = userName;
-            this.password = password;
-            this.domainCode = domainCode;
-        }
-    }
-    
-    [System.Diagnostics.DebuggerStepThroughAttribute()]
-    [System.CodeDom.Compiler.GeneratedCodeAttribute("Microsoft.Tools.ServiceModel.Svcutil", "2.0.2")]
-    [System.ComponentModel.EditorBrowsableAttribute(System.ComponentModel.EditorBrowsableState.Advanced)]
-    [System.ServiceModel.MessageContractAttribute(WrapperName="validateResponse", WrapperNamespace="http://passport.viettel.com/", IsWrapped=true)]
-    public partial class validateResponse
-    {
-        
-        [System.ServiceModel.MessageBodyMemberAttribute(Namespace="http://passport.viettel.com/", Order=0)]
-        [System.Xml.Serialization.XmlElementAttribute(Form=System.Xml.Schema.XmlSchemaForm.Unqualified)]
-        public string @return;
-        
-        public validateResponse()
-        {
-        }
-        
-        public validateResponse(string @return)
-        {
-            this.@return = @return;
-        }
-    }
-    
-    [System.Diagnostics.DebuggerStepThroughAttribute()]
-    [System.CodeDom.Compiler.GeneratedCodeAttribute("Microsoft.Tools.ServiceModel.Svcutil", "2.0.2")]
-    [System.ComponentModel.EditorBrowsableAttribute(System.ComponentModel.EditorBrowsableState.Advanced)]
-    [System.ServiceModel.MessageContractAttribute(WrapperName="getAppFunctions", WrapperNamespace="http://passport.viettel.com/", IsWrapped=true)]
-    public partial class getAppFunctionsRequest
-    {
-        
-        [System.ServiceModel.MessageBodyMemberAttribute(Namespace="http://passport.viettel.com/", Order=0)]
-        [System.Xml.Serialization.XmlElementAttribute(Form=System.Xml.Schema.XmlSchemaForm.Unqualified)]
-        public string domainCode;
-        
-        public getAppFunctionsRequest()
-        {
-        }
-        
-        public getAppFunctionsRequest(string domainCode)
-        {
-            this.domainCode = domainCode;
-        }
-    }
-    
-    [System.Diagnostics.DebuggerStepThroughAttribute()]
-    [System.CodeDom.Compiler.GeneratedCodeAttribute("Microsoft.Tools.ServiceModel.Svcutil", "2.0.2")]
-    [System.ComponentModel.EditorBrowsableAttribute(System.ComponentModel.EditorBrowsableState.Advanced)]
-    [System.ServiceModel.MessageContractAttribute(WrapperName="getAppFunctionsResponse", WrapperNamespace="http://passport.viettel.com/", IsWrapped=true)]
-    public partial class getAppFunctionsResponse
-    {
-        
-        [System.ServiceModel.MessageBodyMemberAttribute(Namespace="http://passport.viettel.com/", Order=0)]
-        [System.Xml.Serialization.XmlElementAttribute(Form=System.Xml.Schema.XmlSchemaForm.Unqualified)]
-        public string @return;
-        
-        public getAppFunctionsResponse()
-        {
-        }
-        
-        public getAppFunctionsResponse(string @return)
-        {
-            this.@return = @return;
-        }
-    }
-    
-    [System.Diagnostics.DebuggerStepThroughAttribute()]
-    [System.CodeDom.Compiler.GeneratedCodeAttribute("Microsoft.Tools.ServiceModel.Svcutil", "2.0.2")]
-    [System.ComponentModel.EditorBrowsableAttribute(System.ComponentModel.EditorBrowsableState.Advanced)]
-    [System.ServiceModel.MessageContractAttribute(WrapperName="validateIncludeIp", WrapperNamespace="http://passport.viettel.com/", IsWrapped=true)]
-    public partial class validateIncludeIpRequest
-    {
-        
-        [System.ServiceModel.MessageBodyMemberAttribute(Namespace="http://passport.viettel.com/", Order=0)]
-        [System.Xml.Serialization.XmlElementAttribute(Form=System.Xml.Schema.XmlSchemaForm.Unqualified)]
-        public string userName;
-        
-        [System.ServiceModel.MessageBodyMemberAttribute(Namespace="http://passport.viettel.com/", Order=1)]
-        [System.Xml.Serialization.XmlElementAttribute(Form=System.Xml.Schema.XmlSchemaForm.Unqualified)]
-        public string password;
-        
-        [System.ServiceModel.MessageBodyMemberAttribute(Namespace="http://passport.viettel.com/", Order=2)]
-        [System.Xml.Serialization.XmlElementAttribute(Form=System.Xml.Schema.XmlSchemaForm.Unqualified)]
-        public string domainCode;
-        
-        [System.ServiceModel.MessageBodyMemberAttribute(Namespace="http://passport.viettel.com/", Order=3)]
-        [System.Xml.Serialization.XmlElementAttribute(Form=System.Xml.Schema.XmlSchemaForm.Unqualified)]
-        public string ipCheck;
-        
-        public validateIncludeIpRequest()
-        {
-        }
-        
-        public validateIncludeIpRequest(string userName, string password, string domainCode, string ipCheck)
-        {
-            this.userName = userName;
-            this.password = password;
-            this.domainCode = domainCode;
-            this.ipCheck = ipCheck;
-        }
-    }
-    
-    [System.Diagnostics.DebuggerStepThroughAttribute()]
-    [System.CodeDom.Compiler.GeneratedCodeAttribute("Microsoft.Tools.ServiceModel.Svcutil", "2.0.2")]
-    [System.ComponentModel.EditorBrowsableAttribute(System.ComponentModel.EditorBrowsableState.Advanced)]
-    [System.ServiceModel.MessageContractAttribute(WrapperName="validateIncludeIpResponse", WrapperNamespace="http://passport.viettel.com/", IsWrapped=true)]
-    public partial class validateIncludeIpResponse
-    {
-        
-        [System.ServiceModel.MessageBodyMemberAttribute(Namespace="http://passport.viettel.com/", Order=0)]
-        [System.Xml.Serialization.XmlElementAttribute(Form=System.Xml.Schema.XmlSchemaForm.Unqualified)]
-        public string @return;
-        
-        public validateIncludeIpResponse()
-        {
-        }
-        
-        public validateIncludeIpResponse(string @return)
-        {
-            this.@return = @return;
-        }
-    }
-    
-    [System.Diagnostics.DebuggerStepThroughAttribute()]
-    [System.CodeDom.Compiler.GeneratedCodeAttribute("Microsoft.Tools.ServiceModel.Svcutil", "2.0.2")]
-    [System.ComponentModel.EditorBrowsableAttribute(System.ComponentModel.EditorBrowsableState.Advanced)]
-    [System.ServiceModel.MessageContractAttribute(WrapperName="getRolesOfApp", WrapperNamespace="http://passport.viettel.com/", IsWrapped=true)]
-    public partial class getRolesOfAppRequest
-    {
-        
-        [System.ServiceModel.MessageBodyMemberAttribute(Namespace="http://passport.viettel.com/", Order=0)]
-        [System.Xml.Serialization.XmlElementAttribute(Form=System.Xml.Schema.XmlSchemaForm.Unqualified)]
-        public string domainCode;
-        
-        public getRolesOfAppRequest()
-        {
-        }
-        
-        public getRolesOfAppRequest(string domainCode)
-        {
-            this.domainCode = domainCode;
-        }
-    }
-    
-    [System.Diagnostics.DebuggerStepThroughAttribute()]
-    [System.CodeDom.Compiler.GeneratedCodeAttribute("Microsoft.Tools.ServiceModel.Svcutil", "2.0.2")]
-    [System.ComponentModel.EditorBrowsableAttribute(System.ComponentModel.EditorBrowsableState.Advanced)]
-    [System.ServiceModel.MessageContractAttribute(WrapperName="getRolesOfAppResponse", WrapperNamespace="http://passport.viettel.com/", IsWrapped=true)]
-    public partial class getRolesOfAppResponse
-    {
-        
-        [System.ServiceModel.MessageBodyMemberAttribute(Namespace="http://passport.viettel.com/", Order=0)]
-        [System.Xml.Serialization.XmlElementAttribute(Form=System.Xml.Schema.XmlSchemaForm.Unqualified)]
-        public string @return;
-        
-        public getRolesOfAppResponse()
-        {
-        }
-        
-        public getRolesOfAppResponse(string @return)
-        {
-            this.@return = @return;
-        }
-    }
-    
-    /// <remarks/>
-    [System.CodeDom.Compiler.GeneratedCodeAttribute("Microsoft.Tools.ServiceModel.Svcutil", "2.0.2")]
-    [System.Diagnostics.DebuggerStepThroughAttribute()]
-    [System.Xml.Serialization.XmlTypeAttribute(Namespace="http://passport.viettel.com/")]
-    public partial class response
-    {
-        
-        private errorCode errorCodeField;
-        
-        private object[] valuesField;
-        
-        /// <remarks/>
-        [System.Xml.Serialization.XmlElementAttribute(Form=System.Xml.Schema.XmlSchemaForm.Unqualified, Order=0)]
-        public errorCode errorCode
-        {
-            get
-            {
-                return this.errorCodeField;
-            }
-            set
-            {
-                this.errorCodeField = value;
-            }
-        }
-        
-        /// <remarks/>
-        [System.Xml.Serialization.XmlElementAttribute("values", Form=System.Xml.Schema.XmlSchemaForm.Unqualified, IsNullable=true, Order=1)]
-        public object[] values
-        {
-            get
-            {
-                return this.valuesField;
-            }
-            set
-            {
-                this.valuesField = value;
-            }
-        }
-    }
-    
-    /// <remarks/>
-    [System.CodeDom.Compiler.GeneratedCodeAttribute("Microsoft.Tools.ServiceModel.Svcutil", "2.0.2")]
-    [System.Diagnostics.DebuggerStepThroughAttribute()]
-    [System.Xml.Serialization.XmlTypeAttribute(Namespace="http://passport.viettel.com/")]
-    public partial class errorCode
-    {
-        
-        private int codeField;
-        
-        private string descriptionField;
-        
-        /// <remarks/>
-        [System.Xml.Serialization.XmlElementAttribute(Form=System.Xml.Schema.XmlSchemaForm.Unqualified, Order=0)]
-        public int code
-        {
-            get
-            {
-                return this.codeField;
-            }
-            set
-            {
-                this.codeField = value;
-            }
-        }
-        
-        /// <remarks/>
-        [System.Xml.Serialization.XmlElementAttribute(Form=System.Xml.Schema.XmlSchemaForm.Unqualified, Order=1)]
-        public string description
-        {
-            get
-            {
-                return this.descriptionField;
-            }
-            set
-            {
-                this.descriptionField = value;
-            }
-        }
-    }
-    
-    /// <remarks/>
-    [System.CodeDom.Compiler.GeneratedCodeAttribute("Microsoft.Tools.ServiceModel.Svcutil", "2.0.2")]
-    [System.Diagnostics.DebuggerStepThroughAttribute()]
-    [System.Xml.Serialization.XmlTypeAttribute(Namespace="http://passport.viettel.com/")]
-    public partial class validateIncludeIpResponse1
-    {
-        
-        private string returnField;
-        
-        /// <remarks/>
-        [System.Xml.Serialization.XmlElementAttribute(Form=System.Xml.Schema.XmlSchemaForm.Unqualified, Order=0)]
-        public string @return
-        {
-            get
-            {
-                return this.returnField;
-            }
-            set
-            {
-                this.returnField = value;
-            }
-        }
-    }
-    
-    /// <remarks/>
-    [System.CodeDom.Compiler.GeneratedCodeAttribute("Microsoft.Tools.ServiceModel.Svcutil", "2.0.2")]
-    [System.Diagnostics.DebuggerStepThroughAttribute()]
-    [System.Xml.Serialization.XmlTypeAttribute(Namespace="http://passport.viettel.com/")]
-    public partial class validateIncludeIp
-    {
-        
-        private string userNameField;
-        
-        private string passwordField;
-        
-        private string domainCodeField;
-        
-        private string ipCheckField;
-        
-        /// <remarks/>
-        [System.Xml.Serialization.XmlElementAttribute(Form=System.Xml.Schema.XmlSchemaForm.Unqualified, Order=0)]
-        public string userName
-        {
-            get
-            {
-                return this.userNameField;
-            }
-            set
-            {
-                this.userNameField = value;
-            }
-        }
-        
-        /// <remarks/>
-        [System.Xml.Serialization.XmlElementAttribute(Form=System.Xml.Schema.XmlSchemaForm.Unqualified, Order=1)]
-        public string password
-        {
-            get
-            {
-                return this.passwordField;
-            }
-            set
-            {
-                this.passwordField = value;
-            }
-        }
-        
-        /// <remarks/>
-        [System.Xml.Serialization.XmlElementAttribute(Form=System.Xml.Schema.XmlSchemaForm.Unqualified, Order=2)]
-        public string domainCode
-        {
-            get
-            {
-                return this.domainCodeField;
-            }
-            set
-            {
-                this.domainCodeField = value;
-            }
-        }
-        
-        /// <remarks/>
-        [System.Xml.Serialization.XmlElementAttribute(Form=System.Xml.Schema.XmlSchemaForm.Unqualified, Order=3)]
-        public string ipCheck
-        {
-            get
-            {
-                return this.ipCheckField;
-            }
-            set
-            {
-                this.ipCheckField = value;
-            }
-        }
-    }
-    
-    /// <remarks/>
-    [System.CodeDom.Compiler.GeneratedCodeAttribute("Microsoft.Tools.ServiceModel.Svcutil", "2.0.2")]
-    [System.Diagnostics.DebuggerStepThroughAttribute()]
-    [System.Xml.Serialization.XmlTypeAttribute(Namespace="http://passport.viettel.com/")]
-    public partial class getAppFunctionsResponse1
-    {
-        
-        private string returnField;
-        
-        /// <remarks/>
-        [System.Xml.Serialization.XmlElementAttribute(Form=System.Xml.Schema.XmlSchemaForm.Unqualified, Order=0)]
-        public string @return
-        {
-            get
-            {
-                return this.returnField;
-            }
-            set
-            {
-                this.returnField = value;
-            }
-        }
-    }
-    
-    /// <remarks/>
-    [System.CodeDom.Compiler.GeneratedCodeAttribute("Microsoft.Tools.ServiceModel.Svcutil", "2.0.2")]
-    [System.Diagnostics.DebuggerStepThroughAttribute()]
-    [System.Xml.Serialization.XmlTypeAttribute(Namespace="http://passport.viettel.com/")]
-    public partial class getAppFunctions
-    {
-        
-        private string domainCodeField;
-        
-        /// <remarks/>
-        [System.Xml.Serialization.XmlElementAttribute(Form=System.Xml.Schema.XmlSchemaForm.Unqualified, Order=0)]
-        public string domainCode
-        {
-            get
-            {
-                return this.domainCodeField;
-            }
-            set
-            {
-                this.domainCodeField = value;
-            }
-        }
-    }
-    
-    /// <remarks/>
-    [System.CodeDom.Compiler.GeneratedCodeAttribute("Microsoft.Tools.ServiceModel.Svcutil", "2.0.2")]
-    [System.Diagnostics.DebuggerStepThroughAttribute()]
-    [System.Xml.Serialization.XmlTypeAttribute(Namespace="http://passport.viettel.com/")]
-    public partial class getRolesOfAppResponse1
-    {
-        
-        private string returnField;
-        
-        /// <remarks/>
-        [System.Xml.Serialization.XmlElementAttribute(Form=System.Xml.Schema.XmlSchemaForm.Unqualified, Order=0)]
-        public string @return
-        {
-            get
-            {
-                return this.returnField;
-            }
-            set
-            {
-                this.returnField = value;
-            }
-        }
-    }
-    
-    /// <remarks/>
-    [System.CodeDom.Compiler.GeneratedCodeAttribute("Microsoft.Tools.ServiceModel.Svcutil", "2.0.2")]
-    [System.Diagnostics.DebuggerStepThroughAttribute()]
-    [System.Xml.Serialization.XmlTypeAttribute(Namespace="http://passport.viettel.com/")]
-    public partial class getRolesOfApp
-    {
-        
-        private string domainCodeField;
-        
-        /// <remarks/>
-        [System.Xml.Serialization.XmlElementAttribute(Form=System.Xml.Schema.XmlSchemaForm.Unqualified, Order=0)]
-        public string domainCode
-        {
-            get
-            {
-                return this.domainCodeField;
-            }
-            set
-            {
-                this.domainCodeField = value;
-            }
-        }
-    }
-    
-    /// <remarks/>
-    [System.CodeDom.Compiler.GeneratedCodeAttribute("Microsoft.Tools.ServiceModel.Svcutil", "2.0.2")]
-    [System.Diagnostics.DebuggerStepThroughAttribute()]
-    [System.Xml.Serialization.XmlTypeAttribute(Namespace="http://passport.viettel.com/")]
-    public partial class changePassResponse
-    {
-        
-        private response returnField;
-        
-        /// <remarks/>
-        [System.Xml.Serialization.XmlElementAttribute(Form=System.Xml.Schema.XmlSchemaForm.Unqualified, Order=0)]
-        public response @return
-        {
-            get
-            {
-                return this.returnField;
-            }
-            set
-            {
-                this.returnField = value;
-            }
-        }
-    }
-    
-    /// <remarks/>
-    [System.CodeDom.Compiler.GeneratedCodeAttribute("Microsoft.Tools.ServiceModel.Svcutil", "2.0.2")]
-    [System.Diagnostics.DebuggerStepThroughAttribute()]
-    [System.Xml.Serialization.XmlTypeAttribute(Namespace="http://passport.viettel.com/")]
-    public partial class changePass
-    {
-        
-        private string userNameField;
-        
-        private string oldPassField;
-        
-        private string newPassField;
-        
-        private string repeatPassField;
-        
-        /// <remarks/>
-        [System.Xml.Serialization.XmlElementAttribute(Form=System.Xml.Schema.XmlSchemaForm.Unqualified, Order=0)]
-        public string userName
-        {
-            get
-            {
-                return this.userNameField;
-            }
-            set
-            {
-                this.userNameField = value;
-            }
-        }
-        
-        /// <remarks/>
-        [System.Xml.Serialization.XmlElementAttribute(Form=System.Xml.Schema.XmlSchemaForm.Unqualified, Order=1)]
-        public string oldPass
-        {
-            get
-            {
-                return this.oldPassField;
-            }
-            set
-            {
-                this.oldPassField = value;
-            }
-        }
-        
-        /// <remarks/>
-        [System.Xml.Serialization.XmlElementAttribute(Form=System.Xml.Schema.XmlSchemaForm.Unqualified, Order=2)]
-        public string newPass
-        {
-            get
-            {
-                return this.newPassField;
-            }
-            set
-            {
-                this.newPassField = value;
-            }
-        }
-        
-        /// <remarks/>
-        [System.Xml.Serialization.XmlElementAttribute(Form=System.Xml.Schema.XmlSchemaForm.Unqualified, Order=3)]
-        public string repeatPass
-        {
-            get
-            {
-                return this.repeatPassField;
-            }
-            set
-            {
-                this.repeatPassField = value;
-            }
-        }
-    }
-    
-    /// <remarks/>
-    [System.CodeDom.Compiler.GeneratedCodeAttribute("Microsoft.Tools.ServiceModel.Svcutil", "2.0.2")]
-    [System.Diagnostics.DebuggerStepThroughAttribute()]
-    [System.Xml.Serialization.XmlTypeAttribute(Namespace="http://passport.viettel.com/")]
-    public partial class getAllowedAppResponse
-    {
-        
-        private string returnField;
-        
-        /// <remarks/>
-        [System.Xml.Serialization.XmlElementAttribute(Form=System.Xml.Schema.XmlSchemaForm.Unqualified, Order=0)]
-        public string @return
-        {
-            get
-            {
-                return this.returnField;
-            }
-            set
-            {
-                this.returnField = value;
-            }
-        }
-    }
-    
-    /// <remarks/>
-    [System.CodeDom.Compiler.GeneratedCodeAttribute("Microsoft.Tools.ServiceModel.Svcutil", "2.0.2")]
-    [System.Diagnostics.DebuggerStepThroughAttribute()]
-    [System.Xml.Serialization.XmlTypeAttribute(Namespace="http://passport.viettel.com/")]
-    public partial class getAllowedApp
-    {
-        
-        private string userNameField;
-        
-        /// <remarks/>
-        [System.Xml.Serialization.XmlElementAttribute(Form=System.Xml.Schema.XmlSchemaForm.Unqualified, Order=0)]
-        public string userName
-        {
-            get
-            {
-                return this.userNameField;
-            }
-            set
-            {
-                this.userNameField = value;
-            }
-        }
-    }
-    
-    /// <remarks/>
-    [System.CodeDom.Compiler.GeneratedCodeAttribute("Microsoft.Tools.ServiceModel.Svcutil", "2.0.2")]
-    [System.Diagnostics.DebuggerStepThroughAttribute()]
-    [System.Xml.Serialization.XmlTypeAttribute(Namespace="http://passport.viettel.com/")]
-    public partial class validateResponse1
-    {
-        
-        private string returnField;
-        
-        /// <remarks/>
-        [System.Xml.Serialization.XmlElementAttribute(Form=System.Xml.Schema.XmlSchemaForm.Unqualified, Order=0)]
-        public string @return
-        {
-            get
-            {
-                return this.returnField;
-            }
-            set
-            {
-                this.returnField = value;
-            }
-        }
-    }
-    
-    /// <remarks/>
-    [System.CodeDom.Compiler.GeneratedCodeAttribute("Microsoft.Tools.ServiceModel.Svcutil", "2.0.2")]
-    [System.Diagnostics.DebuggerStepThroughAttribute()]
-    [System.Xml.Serialization.XmlTypeAttribute(Namespace="http://passport.viettel.com/")]
-    public partial class validate
-    {
-        
-        private string userNameField;
-        
-        private string passwordField;
-        
-        private string domainCodeField;
-        
-        /// <remarks/>
-        [System.Xml.Serialization.XmlElementAttribute(Form=System.Xml.Schema.XmlSchemaForm.Unqualified, Order=0)]
-        public string userName
-        {
-            get
-            {
-                return this.userNameField;
-            }
-            set
-            {
-                this.userNameField = value;
-            }
-        }
-        
-        /// <remarks/>
-        [System.Xml.Serialization.XmlElementAttribute(Form=System.Xml.Schema.XmlSchemaForm.Unqualified, Order=1)]
-        public string password
-        {
-            get
-            {
-                return this.passwordField;
-            }
-            set
-            {
-                this.passwordField = value;
-            }
-        }
-        
-        /// <remarks/>
-        [System.Xml.Serialization.XmlElementAttribute(Form=System.Xml.Schema.XmlSchemaForm.Unqualified, Order=2)]
-        public string domainCode
-        {
-            get
-            {
-                return this.domainCodeField;
-            }
-            set
-            {
-                this.domainCodeField = value;
-            }
-        }
-    }
-    
-    [System.Diagnostics.DebuggerStepThroughAttribute()]
-    [System.CodeDom.Compiler.GeneratedCodeAttribute("Microsoft.Tools.ServiceModel.Svcutil", "2.0.2")]
-    [System.ComponentModel.EditorBrowsableAttribute(System.ComponentModel.EditorBrowsableState.Advanced)]
-    [System.ServiceModel.MessageContractAttribute(WrapperName="changePass", WrapperNamespace="http://passport.viettel.com/", IsWrapped=true)]
-    public partial class changePassRequest
-    {
-        
-        [System.ServiceModel.MessageBodyMemberAttribute(Namespace="http://passport.viettel.com/", Order=0)]
-        [System.Xml.Serialization.XmlElementAttribute(Form=System.Xml.Schema.XmlSchemaForm.Unqualified)]
-        public string userName;
-        
-        [System.ServiceModel.MessageBodyMemberAttribute(Namespace="http://passport.viettel.com/", Order=1)]
-        [System.Xml.Serialization.XmlElementAttribute(Form=System.Xml.Schema.XmlSchemaForm.Unqualified)]
-        public string oldPass;
-        
-        [System.ServiceModel.MessageBodyMemberAttribute(Namespace="http://passport.viettel.com/", Order=2)]
-        [System.Xml.Serialization.XmlElementAttribute(Form=System.Xml.Schema.XmlSchemaForm.Unqualified)]
-        public string newPass;
-        
-        [System.ServiceModel.MessageBodyMemberAttribute(Namespace="http://passport.viettel.com/", Order=3)]
-        [System.Xml.Serialization.XmlElementAttribute(Form=System.Xml.Schema.XmlSchemaForm.Unqualified)]
-        public string repeatPass;
-        
-        public changePassRequest()
-        {
-        }
-        
-        public changePassRequest(string userName, string oldPass, string newPass, string repeatPass)
-        {
-            this.userName = userName;
-            this.oldPass = oldPass;
-            this.newPass = newPass;
-            this.repeatPass = repeatPass;
-        }
-    }
-    
-    [System.Diagnostics.DebuggerStepThroughAttribute()]
-    [System.CodeDom.Compiler.GeneratedCodeAttribute("Microsoft.Tools.ServiceModel.Svcutil", "2.0.2")]
-    [System.ComponentModel.EditorBrowsableAttribute(System.ComponentModel.EditorBrowsableState.Advanced)]
-    [System.ServiceModel.MessageContractAttribute(WrapperName="changePassResponse", WrapperNamespace="http://passport.viettel.com/", IsWrapped=true)]
-    public partial class changePassResponse1
-    {
-        
-        [System.ServiceModel.MessageBodyMemberAttribute(Namespace="http://passport.viettel.com/", Order=0)]
-        [System.Xml.Serialization.XmlElementAttribute(Form=System.Xml.Schema.XmlSchemaForm.Unqualified)]
-        public SvVsa.response @return;
-        
-        public changePassResponse1()
-        {
-        }
-        
-        public changePassResponse1(SvVsa.response @return)
-        {
-            this.@return = @return;
-        }
-    }
-    
-    [System.Diagnostics.DebuggerStepThroughAttribute()]
-    [System.CodeDom.Compiler.GeneratedCodeAttribute("Microsoft.Tools.ServiceModel.Svcutil", "2.0.2")]
-    [System.ComponentModel.EditorBrowsableAttribute(System.ComponentModel.EditorBrowsableState.Advanced)]
-    [System.ServiceModel.MessageContractAttribute(WrapperName="getAllowedApp", WrapperNamespace="http://passport.viettel.com/", IsWrapped=true)]
-    public partial class getAllowedAppRequest
-    {
-        
-        [System.ServiceModel.MessageBodyMemberAttribute(Namespace="http://passport.viettel.com/", Order=0)]
-        [System.Xml.Serialization.XmlElementAttribute(Form=System.Xml.Schema.XmlSchemaForm.Unqualified)]
-        public string userName;
-        
-        public getAllowedAppRequest()
-        {
-        }
-        
-        public getAllowedAppRequest(string userName)
-        {
-            this.userName = userName;
-        }
-    }
-    
-    [System.Diagnostics.DebuggerStepThroughAttribute()]
-    [System.CodeDom.Compiler.GeneratedCodeAttribute("Microsoft.Tools.ServiceModel.Svcutil", "2.0.2")]
-    [System.ComponentModel.EditorBrowsableAttribute(System.ComponentModel.EditorBrowsableState.Advanced)]
-    [System.ServiceModel.MessageContractAttribute(WrapperName="getAllowedAppResponse", WrapperNamespace="http://passport.viettel.com/", IsWrapped=true)]
-    public partial class getAllowedAppResponse1
-    {
-        
-        [System.ServiceModel.MessageBodyMemberAttribute(Namespace="http://passport.viettel.com/", Order=0)]
-        [System.Xml.Serialization.XmlElementAttribute(Form=System.Xml.Schema.XmlSchemaForm.Unqualified)]
-        public string @return;
-        
-        public getAllowedAppResponse1()
-        {
-        }
-        
-        public getAllowedAppResponse1(string @return)
-        {
-            this.@return = @return;
-        }
-    }
-    
-    [System.CodeDom.Compiler.GeneratedCodeAttribute("Microsoft.Tools.ServiceModel.Svcutil", "2.0.2")]
-    public interface passportWSChannel : SvVsa.passportWS, System.ServiceModel.IClientChannel
-    {
-    }
-    
-    [System.Diagnostics.DebuggerStepThroughAttribute()]
-    [System.CodeDom.Compiler.GeneratedCodeAttribute("Microsoft.Tools.ServiceModel.Svcutil", "2.0.2")]
-    public partial class passportWSClient : System.ServiceModel.ClientBase<SvVsa.passportWS>, SvVsa.passportWS
-    {
-        
-        /// <summary>
-        /// Implement this partial method to configure the service endpoint.
-        /// </summary>
-        /// <param name="serviceEndpoint">The endpoint to configure</param>
-        /// <param name="clientCredentials">The client credentials</param>
-        static partial void ConfigureEndpoint(System.ServiceModel.Description.ServiceEndpoint serviceEndpoint, System.ServiceModel.Description.ClientCredentials clientCredentials);
-        
-        public passportWSClient() : 
-                base(passportWSClient.GetDefaultBinding(), passportWSClient.GetDefaultEndpointAddress())
-        {
-            this.Endpoint.Name = EndpointConfiguration.passportWSPort.ToString();
-            ConfigureEndpoint(this.Endpoint, this.ClientCredentials);
-        }
-        
-        public passportWSClient(EndpointConfiguration endpointConfiguration) : 
-                base(passportWSClient.GetBindingForEndpoint(endpointConfiguration), passportWSClient.GetEndpointAddress(endpointConfiguration))
-        {
-            this.Endpoint.Name = endpointConfiguration.ToString();
-            ConfigureEndpoint(this.Endpoint, this.ClientCredentials);
-        }
-        
-        public passportWSClient(EndpointConfiguration endpointConfiguration, string remoteAddress) : 
-                base(passportWSClient.GetBindingForEndpoint(endpointConfiguration), new System.ServiceModel.EndpointAddress(remoteAddress))
-        {
-            this.Endpoint.Name = endpointConfiguration.ToString();
-            ConfigureEndpoint(this.Endpoint, this.ClientCredentials);
-        }
-        
-        public passportWSClient(EndpointConfiguration endpointConfiguration, System.ServiceModel.EndpointAddress remoteAddress) : 
-                base(passportWSClient.GetBindingForEndpoint(endpointConfiguration), remoteAddress)
-        {
-            this.Endpoint.Name = endpointConfiguration.ToString();
-            ConfigureEndpoint(this.Endpoint, this.ClientCredentials);
-        }
-        
-        public passportWSClient(System.ServiceModel.Channels.Binding binding, System.ServiceModel.EndpointAddress remoteAddress) : 
-                base(binding, remoteAddress)
-        {
-        }
-        
-        [System.ComponentModel.EditorBrowsableAttribute(System.ComponentModel.EditorBrowsableState.Advanced)]
-        SvVsa.validateResponse SvVsa.passportWS.validate(SvVsa.validateRequest request)
-        {
-            return base.Channel.validate(request);
-        }
-        
-        public string validate(string userName, string password, string domainCode)
-        {
-            SvVsa.validateRequest inValue = new SvVsa.validateRequest();
-            inValue.userName = userName;
-            inValue.password = password;
-            inValue.domainCode = domainCode;
-            SvVsa.validateResponse retVal = ((SvVsa.passportWS)(this)).validate(inValue);
-            return retVal.@return;
-        }
-        
-        [System.ComponentModel.EditorBrowsableAttribute(System.ComponentModel.EditorBrowsableState.Advanced)]
-        System.Threading.Tasks.Task<SvVsa.validateResponse> SvVsa.passportWS.validateAsync(SvVsa.validateRequest request)
-        {
-            return base.Channel.validateAsync(request);
-        }
-        
-        public System.Threading.Tasks.Task<SvVsa.validateResponse> validateAsync(string userName, string password, string domainCode)
-        {
-            SvVsa.validateRequest inValue = new SvVsa.validateRequest();
-            inValue.userName = userName;
-            inValue.password = password;
-            inValue.domainCode = domainCode;
-            return ((SvVsa.passportWS)(this)).validateAsync(inValue);
-        }
-        
-        [System.ComponentModel.EditorBrowsableAttribute(System.ComponentModel.EditorBrowsableState.Advanced)]
-        SvVsa.getAppFunctionsResponse SvVsa.passportWS.getAppFunctions(SvVsa.getAppFunctionsRequest request)
-        {
-            return base.Channel.getAppFunctions(request);
-        }
-        
-        public string getAppFunctions(string domainCode)
-        {
-            SvVsa.getAppFunctionsRequest inValue = new SvVsa.getAppFunctionsRequest();
-            inValue.domainCode = domainCode;
-            SvVsa.getAppFunctionsResponse retVal = ((SvVsa.passportWS)(this)).getAppFunctions(inValue);
-            return retVal.@return;
-        }
-        
-        [System.ComponentModel.EditorBrowsableAttribute(System.ComponentModel.EditorBrowsableState.Advanced)]
-        System.Threading.Tasks.Task<SvVsa.getAppFunctionsResponse> SvVsa.passportWS.getAppFunctionsAsync(SvVsa.getAppFunctionsRequest request)
-        {
-            return base.Channel.getAppFunctionsAsync(request);
-        }
-        
-        public System.Threading.Tasks.Task<SvVsa.getAppFunctionsResponse> getAppFunctionsAsync(string domainCode)
-        {
-            SvVsa.getAppFunctionsRequest inValue = new SvVsa.getAppFunctionsRequest();
-            inValue.domainCode = domainCode;
-            return ((SvVsa.passportWS)(this)).getAppFunctionsAsync(inValue);
-        }
-        
-        [System.ComponentModel.EditorBrowsableAttribute(System.ComponentModel.EditorBrowsableState.Advanced)]
-        SvVsa.validateIncludeIpResponse SvVsa.passportWS.validateIncludeIp(SvVsa.validateIncludeIpRequest request)
-        {
-            return base.Channel.validateIncludeIp(request);
-        }
-        
-        public string validateIncludeIp(string userName, string password, string domainCode, string ipCheck)
-        {
-            SvVsa.validateIncludeIpRequest inValue = new SvVsa.validateIncludeIpRequest();
-            inValue.userName = userName;
-            inValue.password = password;
-            inValue.domainCode = domainCode;
-            inValue.ipCheck = ipCheck;
-            SvVsa.validateIncludeIpResponse retVal = ((SvVsa.passportWS)(this)).validateIncludeIp(inValue);
-            return retVal.@return;
-        }
-        
-        [System.ComponentModel.EditorBrowsableAttribute(System.ComponentModel.EditorBrowsableState.Advanced)]
-        System.Threading.Tasks.Task<SvVsa.validateIncludeIpResponse> SvVsa.passportWS.validateIncludeIpAsync(SvVsa.validateIncludeIpRequest request)
-        {
-            return base.Channel.validateIncludeIpAsync(request);
-        }
-        
-        public System.Threading.Tasks.Task<SvVsa.validateIncludeIpResponse> validateIncludeIpAsync(string userName, string password, string domainCode, string ipCheck)
-        {
-            SvVsa.validateIncludeIpRequest inValue = new SvVsa.validateIncludeIpRequest();
-            inValue.userName = userName;
-            inValue.password = password;
-            inValue.domainCode = domainCode;
-            inValue.ipCheck = ipCheck;
-            return ((SvVsa.passportWS)(this)).validateIncludeIpAsync(inValue);
-        }
-        
-        [System.ComponentModel.EditorBrowsableAttribute(System.ComponentModel.EditorBrowsableState.Advanced)]
-        SvVsa.getRolesOfAppResponse SvVsa.passportWS.getRolesOfApp(SvVsa.getRolesOfAppRequest request)
-        {
-            return base.Channel.getRolesOfApp(request);
-        }
-        
-        public string getRolesOfApp(string domainCode)
-        {
-            SvVsa.getRolesOfAppRequest inValue = new SvVsa.getRolesOfAppRequest();
-            inValue.domainCode = domainCode;
-            SvVsa.getRolesOfAppResponse retVal = ((SvVsa.passportWS)(this)).getRolesOfApp(inValue);
-            return retVal.@return;
-        }
-        
-        [System.ComponentModel.EditorBrowsableAttribute(System.ComponentModel.EditorBrowsableState.Advanced)]
-        System.Threading.Tasks.Task<SvVsa.getRolesOfAppResponse> SvVsa.passportWS.getRolesOfAppAsync(SvVsa.getRolesOfAppRequest request)
-        {
-            return base.Channel.getRolesOfAppAsync(request);
-        }
-        
-        public System.Threading.Tasks.Task<SvVsa.getRolesOfAppResponse> getRolesOfAppAsync(string domainCode)
-        {
-            SvVsa.getRolesOfAppRequest inValue = new SvVsa.getRolesOfAppRequest();
-            inValue.domainCode = domainCode;
-            return ((SvVsa.passportWS)(this)).getRolesOfAppAsync(inValue);
-        }
-        
-        [System.ComponentModel.EditorBrowsableAttribute(System.ComponentModel.EditorBrowsableState.Advanced)]
-        SvVsa.changePassResponse1 SvVsa.passportWS.changePass(SvVsa.changePassRequest request)
-        {
-            return base.Channel.changePass(request);
-        }
-        
-        public SvVsa.response changePass(string userName, string oldPass, string newPass, string repeatPass)
-        {
-            SvVsa.changePassRequest inValue = new SvVsa.changePassRequest();
-            inValue.userName = userName;
-            inValue.oldPass = oldPass;
-            inValue.newPass = newPass;
-            inValue.repeatPass = repeatPass;
-            SvVsa.changePassResponse1 retVal = ((SvVsa.passportWS)(this)).changePass(inValue);
-            return retVal.@return;
-        }
-        
-        [System.ComponentModel.EditorBrowsableAttribute(System.ComponentModel.EditorBrowsableState.Advanced)]
-        System.Threading.Tasks.Task<SvVsa.changePassResponse1> SvVsa.passportWS.changePassAsync(SvVsa.changePassRequest request)
-        {
-            return base.Channel.changePassAsync(request);
-        }
-        
-        public System.Threading.Tasks.Task<SvVsa.changePassResponse1> changePassAsync(string userName, string oldPass, string newPass, string repeatPass)
-        {
-            SvVsa.changePassRequest inValue = new SvVsa.changePassRequest();
-            inValue.userName = userName;
-            inValue.oldPass = oldPass;
-            inValue.newPass = newPass;
-            inValue.repeatPass = repeatPass;
-            return ((SvVsa.passportWS)(this)).changePassAsync(inValue);
-        }
-        
-        [System.ComponentModel.EditorBrowsableAttribute(System.ComponentModel.EditorBrowsableState.Advanced)]
-        SvVsa.getAllowedAppResponse1 SvVsa.passportWS.getAllowedApp(SvVsa.getAllowedAppRequest request)
-        {
-            return base.Channel.getAllowedApp(request);
-        }
-        
-        public string getAllowedApp(string userName)
-        {
-            SvVsa.getAllowedAppRequest inValue = new SvVsa.getAllowedAppRequest();
-            inValue.userName = userName;
-            SvVsa.getAllowedAppResponse1 retVal = ((SvVsa.passportWS)(this)).getAllowedApp(inValue);
-            return retVal.@return;
-        }
-        
-        [System.ComponentModel.EditorBrowsableAttribute(System.ComponentModel.EditorBrowsableState.Advanced)]
-        System.Threading.Tasks.Task<SvVsa.getAllowedAppResponse1> SvVsa.passportWS.getAllowedAppAsync(SvVsa.getAllowedAppRequest request)
-        {
-            return base.Channel.getAllowedAppAsync(request);
-        }
-        
-        public System.Threading.Tasks.Task<SvVsa.getAllowedAppResponse1> getAllowedAppAsync(string userName)
-        {
-            SvVsa.getAllowedAppRequest inValue = new SvVsa.getAllowedAppRequest();
-            inValue.userName = userName;
-            return ((SvVsa.passportWS)(this)).getAllowedAppAsync(inValue);
-        }
-        
-        public virtual System.Threading.Tasks.Task OpenAsync()
-        {
-            return System.Threading.Tasks.Task.Factory.FromAsync(((System.ServiceModel.ICommunicationObject)(this)).BeginOpen(null, null), new System.Action<System.IAsyncResult>(((System.ServiceModel.ICommunicationObject)(this)).EndOpen));
-        }
-        
-        public virtual System.Threading.Tasks.Task CloseAsync()
-        {
-            return System.Threading.Tasks.Task.Factory.FromAsync(((System.ServiceModel.ICommunicationObject)(this)).BeginClose(null, null), new System.Action<System.IAsyncResult>(((System.ServiceModel.ICommunicationObject)(this)).EndClose));
-        }
-        
-        private static System.ServiceModel.Channels.Binding GetBindingForEndpoint(EndpointConfiguration endpointConfiguration)
-        {
-            if ((endpointConfiguration == EndpointConfiguration.passportWSPort))
-            {
-                System.ServiceModel.BasicHttpBinding result = new System.ServiceModel.BasicHttpBinding();
-                result.MaxBufferSize = int.MaxValue;
-                result.ReaderQuotas = System.Xml.XmlDictionaryReaderQuotas.Max;
-                result.MaxReceivedMessageSize = int.MaxValue;
-                result.AllowCookies = true;
-                return result;
-            }
-            throw new System.InvalidOperationException(string.Format("Could not find endpoint with name \'{0}\'.", endpointConfiguration));
-        }
-        
-        private static System.ServiceModel.EndpointAddress GetEndpointAddress(EndpointConfiguration endpointConfiguration)
-        {
-            if ((endpointConfiguration == EndpointConfiguration.passportWSPort))
-            {
-                return new System.ServiceModel.EndpointAddress("http://154.73.105.33:8080/passportv3/passportWS");
-            }
-            throw new System.InvalidOperationException(string.Format("Could not find endpoint with name \'{0}\'.", endpointConfiguration));
-        }
-        
-        private static System.ServiceModel.Channels.Binding GetDefaultBinding()
-        {
-            return passportWSClient.GetBindingForEndpoint(EndpointConfiguration.passportWSPort);
-        }
-        
-        private static System.ServiceModel.EndpointAddress GetDefaultEndpointAddress()
-        {
-            return passportWSClient.GetEndpointAddress(EndpointConfiguration.passportWSPort);
-        }
-        
-        public enum EndpointConfiguration
-        {
-            
-            passportWSPort,
-        }
-    }
-}

+ 205 - 13
SuperAdmin/SuperAdmin/Controllers/AdminController.cs

@@ -1,23 +1,24 @@
-using System;
-using System.Collections.Generic;
-using System.Linq;
-using System.Threading.Tasks;
+using ClosedXML.Excel;
+using DocumentFormat.OpenXml.Drawing;
+using DocumentFormat.OpenXml.Wordprocessing;
 using Microsoft.AspNetCore.Hosting;
+using Microsoft.AspNetCore.Http;
 using Microsoft.AspNetCore.Mvc;
+using Microsoft.AspNetCore.Server.IISIntegration;
 using Microsoft.Extensions.Configuration;
+using Nancy;
+using OfficeOpenXml;
 using SuperAdmin.Models.Http;
-using SuperCms.Extensions;
+using SuperAdmin.Models.Object;
 using SuperAdmin.Source;
-using Microsoft.AspNetCore.Http;
-using ClosedXML.Excel;
+using SuperCms.Extensions;
+using System;
+using System.Collections.Generic;
 using System.IO;
-using OfficeOpenXml;
-using SuperAdmin.Models.Object;
+using System.Linq;
+using System.Threading.Tasks;
+using Timor_BPSuperAdmin.Models.Http;
 using static SuperAdmin.Source.CommonUtils;
-using DocumentFormat.OpenXml.Drawing;
-using Nancy;
-using Microsoft.AspNetCore.Server.IISIntegration;
-using DocumentFormat.OpenXml.Wordprocessing;
 
 namespace SuperAdmin.Controllers
 {
@@ -571,6 +572,150 @@ namespace SuperAdmin.Controllers
             }
         }
 
+        // ApiWebserviceManagement
+        public IActionResult ApiWebserviceManagement()
+        {
+            if (!CheckAuthToken())
+            {
+                return Redirect(GetParameter(UtilsController.Constant.SUB_DOMAIN) + "/Home/Login");
+            }
+            return View();
+        }
+
+        [HttpPost]
+        public IActionResult GetApiServices()
+        {
+            if (!CheckAuthToken())
+            {
+                return Json(new
+                {
+                    error = "-1",
+                    content = "Login first"
+                });
+            }
+
+            var req = new ApiServiceReq
+            {
+                rowsOnPage = "1000000",
+                seqPage = "1",
+                order = "desc"
+            };
+
+            string url = GetParameter(CommonUtils.WsType.ApiServiceLoad);
+            ApiServiceRes res = ApiServiceRes.Parse(SendPost(req, url));
+
+            if (res == null || res.list == null)
+            {
+                return Json(new
+                {
+                    error = "1",
+                    content = "No data found"
+                });
+            }
+
+            return Json(new
+            {
+                error = 0,
+                data = res.list
+            });
+        }
+
+
+        public IActionResult ApiServiceSearch(ApiServiceReq req)
+        {
+            if (!CheckAuthToken())
+            {
+                return Json(new
+                {
+                    error = "-1",
+                    content = "Login first"
+                });
+            }
+            req.rowsOnPage = "1000000";
+            req.seqPage = "1";
+            req.order = "desc";
+
+
+            String url = GetParameter(CommonUtils.WsType.ApiServiceLoad);
+            ApiServiceRes res = ApiServiceRes.Parse(SendPost(req, url));
+            HttpContext.Session.SetComplexData("apiServiceData", res.list);
+
+            return PartialView("../Partial/_ApiWebserviceManagement", res.list);
+        }
+
+
+        [HttpPost]
+        public JsonResult ApiServiceLoadInfo(ApiServiceReq request)
+        {
+            if (!CheckAuthToken())
+            {
+                return Json(new
+                {
+                    error = "-1",
+                    content = "Login first"
+                });
+            }
+            string account = HttpContext.Session.GetString("account");
+
+            // check update or add
+            string url = GetParameter(CommonUtils.WsType.ApiServiceLoad);
+            var res = ApiServiceRes.Parse(SendPost(request, url));
+
+            return Json(new
+            {
+                error = res.responseCode,
+                content = res.responseMessage,
+                data = res.list[0]
+            });
+
+        }
+
+        [HttpPost]
+        public JsonResult ApiServiceAddUpdate(ApiServiceUpdateReq request)
+        {
+            if (!CheckAuthToken())
+            {
+                return Json(new
+                {
+                    error = "-1",
+                    content = "Login first"
+                });
+            }
+            string account = HttpContext.Session.GetString("account");
+
+            // check update or add
+            string url = "";
+            if (request.id != null)
+            {
+                url = GetParameter(CommonUtils.WsType.ApiServiceUpdate);
+
+            }
+            else
+            {
+                // add
+                url = GetParameter(CommonUtils.WsType.ApiServiceInsert);
+            }
+            request.users = account;
+            var res = ApiServiceUpdateRes.Parse(SendPost(request, url));
+
+            // reload
+            PreLoadService();
+
+            return Json(new
+            {
+                error = res.responseCode,
+                content = res.responseMessage
+            });
+
+        }
+
+
+
+
+
+
+
+
         // SERVICE
         public IActionResult ServiceManagement()
         {
@@ -937,6 +1082,53 @@ namespace SuperAdmin.Controllers
                 return PartialView("../Partial/_CampaignService", null);
             }
         }
+        [HttpPost]
+        public IActionResult SvGroup(ServiceGroupReq req)
+        {
+            if (!CheckAuthToken())
+            {
+                return Redirect(GetParameter(UtilsController.Constant.SUB_DOMAIN) + "/Home/Login");
+            }
+
+            string url = GetParameter(CommonUtils.WsType.SvGroupGetList);
+            ServiceGroupRes res = ServiceGroupRes.Parse(SendPost(req, url));
+            HttpContext.Session.SetComplexData("serviceGroupData", res.list);
+
+            return Json(new { success = true }); 
+        }
+
+
+        [HttpPost]
+        public IActionResult SvGroupLoad(ServiceGroupReq req)
+        {
+            if (!CheckAuthToken())
+            {
+                return Json(new
+                {
+                    error = "-1",
+                    content = "Login first"
+                });
+            }
+
+            string url = GetParameter(CommonUtils.WsType.SvGroupGetList);
+            ServiceGroupRes res = ServiceGroupRes.Parse(SendPost(req, url));
+
+            if (res == null || res.list == null)
+            {
+                return Json(new
+                {
+                    error = "1",
+                    content = "No data found"
+                });
+            }
+
+            return Json(new
+            {
+                error = 0,
+                data = res.list
+            });
+        }
+
 
 
         // ReportCampaign

+ 0 - 1
SuperAdmin/SuperAdmin/Controllers/HomeController.cs

@@ -10,7 +10,6 @@ using SuperAdmin.Models.Object;
 //using SuperAdmin.Models.Vsa;
 using SuperAdmin.Source;
 using SuperCms.Extensions;
-using SvVsa;
 
 namespace SuperAdmin.Controllers
 {

+ 47 - 0
SuperAdmin/SuperAdmin/Models/Http/ApiService.cs

@@ -0,0 +1,47 @@
+using Newtonsoft.Json;
+using SuperAdmin.Models.Http;
+using SuperAdmin.Models.Object;
+using System;
+using System.Collections.Generic;
+
+namespace Timor_BPSuperAdmin.Models.Http
+{
+    public class ApiServiceReq : Posting
+    {
+        public string users { get; set; }
+        public string id { get; set; }
+        public string isActive { get; set; }
+        public string rowsOnPage { get; set; }
+        public string seqPage { get; set; }
+        public string order { get; set; }
+        public string language { get; set; }
+    }
+
+
+    public class ApiServiceRes
+    {
+        public string rowsOnPage { get; set; }
+        public string seqPage { get; set; }
+        public string totalPage { get; set; }
+        public List<ApiService> list { get; set; }
+        public string responseCode { get; set; }
+        public string responseMessage { get; set; }
+
+        public ApiServiceRes() { }
+
+        public static ApiServiceRes Parse(String json)
+        {
+            return JsonConvert.DeserializeObject<ApiServiceRes>(json);
+        }
+    }
+    public class ApiService {         
+        public string ws_id { get; set; }
+        public string ws_name { get; set; }
+        public string ws_code { get; set; }
+        public string wsdl { get; set; }
+        public string isActive { get; set; }
+        public string msg_template { get; set; }
+        public string error_tag { get; set; }
+
+    }
+}

+ 38 - 0
SuperAdmin/SuperAdmin/Models/Http/ApiServiceUpdate.cs

@@ -0,0 +1,38 @@
+using Newtonsoft.Json;
+using SuperAdmin.Models.Object;
+using System;
+using System.Collections.Generic;
+using System.Linq;
+using System.Threading.Tasks;
+
+namespace SuperAdmin.Models.Http
+{
+    public class ApiServiceUpdateReq : Posting
+    {
+        public string users { get; set; }
+        public string id { get; set; }
+        public string ws_name { get; set; }
+        public string ws_code { get; set; }
+        public string wsdl { get; set; }
+        public string isActive { get; set; }
+        public string msg_template { get; set; }
+        public string error_tag { get; set; }
+        public string serviceGroupId { get; set; }
+        public string apiServiceId { get; set; }
+        public string language { get; set; }
+        public ApiServiceUpdateReq() { }
+    }
+
+    public class ApiServiceUpdateRes
+    {
+        public string responseCode { get; set; }
+        public string responseMessage { get; set; }
+        public ApiServiceUpdateRes() { }
+
+        public static ApiServiceUpdateRes Parse(String json)
+        {
+            return JsonConvert.DeserializeObject<ApiServiceUpdateRes>(json);
+        }
+    }
+
+}

+ 2 - 0
SuperAdmin/SuperAdmin/Models/Http/Service.cs

@@ -25,6 +25,8 @@ namespace SuperAdmin.Models.Http
         public string msgRegisterSuccess { get; set; }
         public string msgRegisterFlase { get; set; }
         public string msgConfirm { get; set; }
+        public string serviceGroupId { get; set; }
+        public string apiServiceId { get; set; }
         public string language { get; set; }
         public ServiceUpdateReq() { }
     }

+ 36 - 0
SuperAdmin/SuperAdmin/Models/Http/ServiceList.cs

@@ -30,6 +30,7 @@ namespace SuperAdmin.Models.Http
         public string serviceId { get; set; }
         public string ussdDisplay { get; set; }
         public string keyRegister { get; set; }
+        public string msgConfirm { get; set; }
         public string note { get; set; }
         public string users { get; set; }
         public string type { get; set; }
@@ -65,6 +66,38 @@ namespace SuperAdmin.Models.Http
         public CampaignServiceListReq() { }
     }
 
+    public class ServiceGroupReq : Posting
+    {
+        public string id { get; set; }
+        public string users { get; set; }
+        public ServiceGroupReq() { }
+    }
+
+    public class ServiceGroupRes
+    {
+        public string rowsOnPage { get; set; }
+        public string seqPage { get; set; }
+        public string totalPage { get; set; }
+        public List<ServiceGroupData> list { get; set; }
+        public string responseCode { get; set; }
+        public string responseMessage { get; set; }
+
+        public ServiceGroupRes() { }
+
+        public static ServiceGroupRes Parse(String json)
+        {
+            return JsonConvert.DeserializeObject<ServiceGroupRes>(json);
+        }
+    }
+
+    public class ServiceGroupData
+    {
+        public string id { get; set; }
+        public string code { get; set; }
+        public string name { get; set; }
+        public string isActive { get; set; }
+    }
+
     public class CampaignServiceListRes
     {
         public string rowsOnPage { get; set; }
@@ -119,5 +152,8 @@ namespace SuperAdmin.Models.Http
         public string msgConfirm { get; set; }
         public string isActive { get; set; }
         public string isMyService { get; set; }
+        public string serviceGroupName { get; set; }
+        public string serviceGroupID { get; set; }
+        public string apiServiceId { get; set; }
     }
 }

+ 5 - 3
SuperAdmin/SuperAdmin/Properties/PublishProfiles/FolderProfile.pubxml

@@ -10,11 +10,13 @@ https://go.microsoft.com/fwlink/?LinkID=208121.
     <LastUsedBuildConfiguration>Release</LastUsedBuildConfiguration>
     <LastUsedPlatform>Any CPU</LastUsedPlatform>
     <PublishProvider>FileSystem</PublishProvider>
-    <PublishUrl>D:\Common\Publish</PublishUrl>
+    <PublishUrl>D:\Code\Ex_publish\Mytel_BPlus\cms</PublishUrl>
     <WebPublishMethod>FileSystem</WebPublishMethod>
     <SiteUrlToLaunchAfterPublish />
-    <TargetFramework>netcoreapp3.1</TargetFramework>
+    <TargetFramework>net7.0</TargetFramework>
     <ProjectGuid>000a9a28-ee22-4214-887d-108273a43763</ProjectGuid>
-    <SelfContained>false</SelfContained>
+    <SelfContained>true</SelfContained>
+    <RuntimeIdentifier>linux-x64</RuntimeIdentifier>
+    <PublishTrimmed>true</PublishTrimmed>
   </PropertyGroup>
 </Project>

+ 1 - 1
SuperAdmin/SuperAdmin/Properties/launchSettings.json

@@ -18,7 +18,7 @@
     "SuperAdmin": {
       "commandName": "Project",
       "launchBrowser": true,
-      "applicationUrl": "https://localhost:5001;http://localhost:5000",
+      "applicationUrl": "http://localhost:5001",
       "environmentVariables": {
         "ASPNETCORE_ENVIRONMENT": "Development"
       }

+ 6 - 0
SuperAdmin/SuperAdmin/Source/CommonUtils.cs

@@ -241,9 +241,15 @@ namespace SuperAdmin.Source
             public const String CamSvGetList = "wsCamSvGetList";
             public const String CamAddInsert = "wsCamAddInsert";
             public const String CamSvRemove = "wsCamSvRemove";
+            public const String SvGroupGetList = "svGroupGetList";
             public const String SvGetList = "wsSvGetList";
             public const String SvInsert = "wsSvInsert";
             public const String SvUpdate = "wsSvUpdate";
+
+            public const String ApiServiceLoad = "apiServiceLoad";
+            public const String ApiServiceInsert = "apiServiceInsert";
+            public const String ApiServiceUpdate = "apiServiceUpdate";
+
             // calendar
             public const String CalendarGetList = "wsCalendarGetList";
             // campaign

+ 19 - 17
SuperAdmin/SuperAdmin/Timor_BPSuperAdmin.csproj

@@ -1,7 +1,7 @@
-<Project Sdk="Microsoft.NET.Sdk.Web">
+<Project Sdk="Microsoft.NET.Sdk.Web">
 
   <PropertyGroup>
-    <TargetFramework>net5.0</TargetFramework>
+    <TargetFramework>net7.0</TargetFramework>
     <UserSecretsId>c3fe1f60-1c9f-4eb7-b25a-1a3892f4a80f</UserSecretsId>
   </PropertyGroup>
 
@@ -473,29 +473,30 @@
   </ItemGroup>
 
   <ItemGroup>
-    <PackageReference Include="ClosedXML" Version="0.95.4" />
-    <PackageReference Include="Dapper" Version="2.0.78" />
-    <PackageReference Include="EPPlus" Version="7.6.1" />
-    <PackageReference Include="log4net" Version="2.0.12" />
-    <PackageReference Include="Microsoft.AspNetCore.Mvc.Core" Version="2.3.0" />
-    <PackageReference Include="Microsoft.AspNetCore.Mvc.Razor.RuntimeCompilation" Version="3.1.0" />
-    <PackageReference Include="Microsoft.Extensions.ApiDescription.Client" Version="9.0.2">
+    <PackageReference Include="ClosedXML" Version="0.105.0" />
+    <PackageReference Include="Dapper" Version="2.1.66" />
+    <PackageReference Include="EPPlus" Version="8.2.1" />
+    <PackageReference Include="log4net" Version="3.2.0" />
+   
+    <PackageReference Include="Microsoft.Extensions.ApiDescription.Client" Version="9.0.10">
       <PrivateAssets>all</PrivateAssets>
       <IncludeAssets>runtime; build; native; contentfiles; analyzers; buildtransitive</IncludeAssets>
     </PackageReference>
-    <PackageReference Include="Microsoft.VisualStudio.Web.CodeGeneration.Design" Version="3.1.5" />
     <PackageReference Include="Nancy" Version="2.0.0" />
-    <PackageReference Include="Newtonsoft.Json" Version="13.0.3" />
-    <PackageReference Include="NSwag.ApiDescription.Client" Version="13.0.5">
+    <PackageReference Include="Newtonsoft.Json" Version="13.0.4" />
+    <PackageReference Include="NSwag.ApiDescription.Client" Version="14.6.1">
       <PrivateAssets>all</PrivateAssets>
       <IncludeAssets>runtime; build; native; contentfiles; analyzers; buildtransitive</IncludeAssets>
     </PackageReference>
-    <PackageReference Include="Oracle.ManagedDataAccess.Core" Version="23.7.0" />
+    <PackageReference Include="Oracle.ManagedDataAccess.Core" Version="23.26.0" />
     <PackageReference Include="System.Private.ServiceModel" Version="4.10.3" />
-    <PackageReference Include="System.ServiceModel.Duplex" Version="4.4.*" />
-    <PackageReference Include="System.ServiceModel.Http" Version="4.4.*" />
-    <PackageReference Include="System.ServiceModel.NetTcp" Version="4.4.*" />
-    <PackageReference Include="System.ServiceModel.Security" Version="4.4.*" />
+    <PackageReference Include="System.ServiceModel.Duplex" Version="6.0.0" />
+    <PackageReference Include="System.ServiceModel.Http" Version="8.1.2" />
+    <PackageReference Include="System.ServiceModel.NetTcp" Version="8.1.2" />
+    <PackageReference Include="System.ServiceModel.Security" Version="6.0.0" />
+	<PackageReference Include="Microsoft.AspNetCore.Mvc.Core" Version="2.3.0" />
+	<PackageReference Include="Microsoft.AspNetCore.Mvc.Razor.RuntimeCompilation" Version="7.0.20" />
+
   </ItemGroup>
 
   <ItemGroup>
@@ -503,6 +504,7 @@
   </ItemGroup>
 
   <ItemGroup>
+    <Folder Include="Connected Services\" />
     <Folder Include="Models\Vsa\" />
   </ItemGroup>
 

+ 443 - 0
SuperAdmin/SuperAdmin/Views/Admin/ApiWebserviceManagement.cshtml

@@ -0,0 +1,443 @@
+@{
+    ViewBag.Title = "Api Service Management";
+    Layout = "~/Views/Shared/_Layout.cshtml";
+}
+
+@using SuperAdmin.Models;
+@using SuperAdmin.Models.Http;
+@using SuperAdmin.Controllers;
+@using SuperAdmin.Source;
+
+
+<style>
+    img {
+        max-width: 100%;
+    }
+</style>
+
+<div class="content-header row">
+    <div class="content-header-left col-md-6 col-xs-12 mb-1">
+        <h2 class="content-header-title">Api Service Management</h2>
+    </div>
+    <div class="content-header-right breadcrumbs-right breadcrumbs-top col-md-6 col-xs-12">
+        <div class="breadcrumb-wrapper col-xs-12">
+            <ol class="breadcrumb">
+                <li class="breadcrumb-item">
+                    <a href="Index">Admin</a>
+                </li>
+                <li class="breadcrumb-item">
+                    <a href="#">Api Service Management</a>
+                </li>
+            </ol>
+        </div>
+    </div>
+</div>
+
+<div class="content-body">
+    <!-- Basic form layout section start -->
+    <section id="basic-form-layouts">
+        <div class="row service-height">
+            <div class="col-md-12">
+                <div class="card">
+                    <div class="card-header">
+                        <h4 class="card-title" id="basic-layout-form">Search</h4> 
+                    </div>
+                    <div class="card-content collapse show">
+                        <div class="card-body">
+                            <div class="card-block">
+                                <div class="form-body">
+                                    @Html.AntiForgeryToken()
+                                    <div class="row">
+                                        <div class="col-md-4 col-sm-4 col-6">
+                                            <div class="form-group">
+                                                <label>Status</label>
+                                                <select class="form-control" id="statusSearch" name="statusSearch">
+                                                    <option value="-1" >-- All --</option>
+                                                    <option value="1" selected>Active</option>
+                                                    <option value="0">Inactive</option>
+                                                </select>
+                                            </div>
+                                        </div>
+                                        <div style="padding-top: 27px;">
+                                            <div class="col-md-12">
+                                                <button type="button" class="btn btn-info" onclick="searchApi()" id="btnSearch">
+                                                    <i class="fa fa-search"></i> Search
+                                                </button>
+
+                                                <button type="button" class="btn btn-primary" onclick="add()" id="btnAdd">
+                                                    <i class="fa fa-plus"></i> Add
+                                                </button>
+
+                                            </div>
+                                        </div>
+                                        
+                                    </div>
+                                    @* <div class="row">
+                                        <div class="col-md-12">
+                                            <button type="button" class="btn btn-info" onclick="searchApi()" id="btnSearch">
+                                                <i class="fa fa-search"></i> Search
+                                            </button>
+
+                                            <button type="button" class="btn btn-primary" onclick="add()" id="btnAdd">
+                                                <i class="fa fa-plus"></i> Add
+                                            </button>
+
+                                        </div>
+                                    </div> *@
+                                </div>
+                            </div>
+                        </div>
+                    </div>
+                </div>
+            </div>
+
+            <div class="col-12">
+                <div class="card">
+                    <div class="card-content " id="partial-content">
+                    </div>
+                </div>
+            </div>
+
+
+        </div>
+    </section>
+    <!-- // Basic form layout section end -->
+</div>
+
+
+<div class="modal fade text-xs-left" id="modal-add-service" tabindex="-1" role="dialog" aria-labelledby="myModalLabel17" style="display: none;" aria-hidden="true">
+    <div class="modal-dialog modal-lg" role="document">
+        <div class="modal-content">
+            <div class="modal-header">
+                <h4 class="modal-title" id="modalLabelService">Api Service Information</h4>
+                <button type="button" class="close" data-dismiss="modal" aria-label="Close">
+                    <span aria-hidden="true">×</span>
+                </button>
+            </div>
+            <input type="hidden" id="id" />
+            <div class="modal-body">
+                <div class="row" id="div-info">
+                    <div class="col-md-6">
+                        <div class="form-group">
+                            <label for="date">ws_name</label>
+                            <input type="text" class="form-control" id="ws_name" name="ws_name">
+                        </div>
+                    </div>
+                    <div class="col-md-6">
+                        <div class="form-group">
+                            <label for="date">ws_code</label>
+                            <input type="text" class="form-control" id="ws_code" name="ws_code">
+                        </div>
+                    </div>
+                    <div class="col-md-6">
+                        <div class="form-group">
+                            <label for="date">wsdl</label>
+                            <input type="text" class="form-control" id="wsdl" name="wsdl">
+                        </div>
+                    </div>
+
+                    
+                    <div class="col-md-6">
+                        <div class="form-group">
+                            <label for="date">error_tag</label>
+                            <input type="text" class="form-control" id="error_tag" name="error_tag" >
+                        </div>
+                    </div>
+                    <div class="col-md-6">
+                        <div class="form-group">
+                            <label for="status">status</label>
+                            <select class="form-control" id="status" name="status">
+                                <option value="1">Active</option>
+                                <option value="0">Inactive</option>
+                            </select>
+                        </div>
+                    </div>
+                    <div class="col-md-6">
+                        <div class="form-group">
+                            <label for="wsName">msg_template</label>
+                            <textarea class="form-control" id="msg_template" name="msg_template" rows="6"></textarea>
+                        </div>
+                    </div>
+                    <input type="hidden" name="result" id="result" />
+
+                </div>
+                <div class="row" id="div-action">
+                    <div class="col-12">
+                        <label id="lblWarning" class="text-danger"></label>
+                    </div>
+                    <div class="col-12" style="text-align: right">
+                        <button type="button" id="btnAddUpdate" class="btn btn-outline-primary" onclick="addUpdateAction()">Add</button>
+                        <button type="button" class="btn grey btn-outline-secondary" data-dismiss="modal">Close</button>
+                    </div>
+                </div>
+            </div>
+        </div>
+        <div class="modal-footer">
+
+        </div>
+    </div>
+</div>
+
+
+@section Scripts {
+    <script>
+
+        var tableDetail;
+
+        $(document).ready(function () {
+            console.log("load tu dong");
+            if (typeof searchApi === 'function') {
+                searchApi();
+            }
+        });
+
+
+
+        function resetTableDetail() {
+            tableDetail = $("#grid_detail").DataTable({
+                orderCellsTop: true
+            });
+        }
+
+        function clearTable(table) {
+            if (table != null && table != undefined) {
+                table
+                    .clear()
+                    .destroy();
+            }
+        }
+        //resetTableDetail();
+
+        function add() {
+            // clear data
+            $("#id").val("");
+            $("#ws_name").val("");
+            $("#ws_code").val("");
+            $("#wsdl").val("");
+            $("#msg_template").val("");
+            $("#error_tag").val("");
+            $("#btnAddUpdate").html("Add");
+            showModal("modal-add-service");
+        }
+
+
+        function editApiService(id) {
+            $("#id").val(id);
+            $("#btnAddUpdate").html("Update");
+            loadApiServiceInfo(id);
+            showModal("modal-add-service");
+        }
+
+        function loadApiServiceInfo(id) {
+            $.ajax({
+                url: urlConfig('/Admin/ApiServiceLoadInfo'),
+                type: "POST",
+                data: {
+                    id: id
+                },
+                success: function (result) {
+                    console.log(result);
+                    if (result.error == '0') {
+                        var sv = result.data;
+                        $("#id").val(sv.ws_id);
+                        $("#ws_name").val(sv.ws_name);
+                        $("#ws_code").val(sv.ws_code);
+                        $("#wsdl").val(sv.wsdl);
+                        $("#msg_template").val(sv.msg_template);
+                        $("#error_tag").val(sv.error_tag);
+                        $("#status").val(sv.isActive);
+                    } else {
+                        console.log("error");
+                    }
+                },
+                error: function (err) {
+                    console.log(err);
+                }
+            });
+        }
+
+        function validateInput() {
+             // validate data
+            let ws_name = $("#ws_name").val();
+            let ws_code = $("#ws_code").val();
+            let wsdl = $("#wsdl").val();
+            let msg_template = $("#msg_template").val();
+
+            if (ws_name == null || ws_name == "") {
+                $("#ws_name").addClass('input-invalid');
+                $("#ws_name").focus();
+                return false;
+            }
+            if (ws_code == null || ws_code == "") {
+                $("#ws_code").addClass('input-invalid');
+                $("#ws_code").focus();
+                return false;
+            }
+            if (wsdl == null || wsdl == "") {
+                $("#wsdl").addClass('input-invalid');
+                $("#wsdl").focus();
+                return false;
+            }
+            if (msg_template == null || msg_template == "") {
+                $("#msg_template").addClass('input-invalid');
+                $("#msg_template").focus();
+                return false;
+            }
+            return true;
+        }
+
+        function addUpdateAction() {
+            startSpinner('btnAddUpdate');
+
+            if (!validateInput()) {
+                stopSpinner("btnAddUpdate");
+                $("#lblWarning").html("Require input");
+                return;
+            }
+
+            $.ajax({
+                url: urlConfig('/Admin/ApiServiceAddUpdate'),
+                type: "POST",
+                data: {
+                    id: $("#id").val(),
+                    ws_name: $("#ws_name").val(),
+                    ws_code: $("#ws_code").val(),
+                    wsdl: $("#wsdl").val(),
+                    msg_template: $("#msg_template").val(),
+                    error_tag: $("#error_tag").val(),
+                    isActive: $("#status").val()
+                },
+                success: function (result) {
+                    stopSpinner("btnAddUpdate");
+                    console.log("result: ");
+                    console.log(result);
+                    if (result.error == '0') {
+                        Swal.fire("Success!", "Success!", "success").
+                            then((result) => {
+                                hideModal("modal-add-service");
+                                searchApi();
+                            });
+                    } else {
+                        Swal.fire("Failed!", result.content, "error");
+                        //alert('Import failed: ' + result.content);
+                    }
+                },
+                error: function (err) {
+                    stopSpinner("btnAddUpdate");
+                    Swal.fire("Failed!", err.statusText, "error");
+                    //alert(err.statusText);
+                }
+            });
+        }
+
+        function searchApi() {
+            startSpinner('btnSearch');
+            clearTable(tableDetail);
+            $.ajax({
+                url: urlConfig("/Admin/ApiServiceSearch"),
+                data: {
+                    isActive: $("#statusSearch").val()
+                },
+                type: "POST",
+                success: function (data) {
+                    stopSpinner('btnSearch');
+
+                    $("#partial-content").html(data);
+                    //resetTableDetail();
+                    $("#grid_detail").DataTable({
+                        orderCellsTop: true
+                    });
+                },
+                error: function (data) {
+                    stopSpinner('btnSearch');
+                    console.log(data.error);
+                }
+            })
+        }
+
+
+        function exportExcel() {
+            console.log("Export data");
+            startSpinner('btnExportExcel');
+            $.ajax({
+                url: urlConfig("/Admin/ServiceExport"),
+                data: {
+                    fromDate: $("#fromDateSearch").val(),
+                    toDate: $("#toDateSearch").val(),
+                    status: $("#statusSearch").val()
+                },
+                type: "POST",
+                xhr: function () {
+                    var xhr = new XMLHttpRequest();
+                    xhr.onreadystatechange = function () {
+                        if (xhr.readyState == 2) {
+                            if (xhr.status == 200) {
+                                xhr.responseType = "blob";
+                                console.log("blob");
+                            } else {
+                                xhr.responseType = "text";
+                                console.log("text");
+                            }
+                        }
+                    };
+                    return xhr;
+                },
+                success: function (data, status, xhr) {
+
+                    stopSpinner('btnExportExcel');
+                    let filename = "";
+                    let disposition = xhr.getResponseHeader('Content-Disposition');
+                    if (disposition && disposition.indexOf('attachment') !== -1) {
+                        let filenameRegex = /filename[^;=\n]*=((['"]).*?\2|[^;\n]*)/;
+                        let matches = filenameRegex.exec(disposition);
+                        if (matches != null && matches[1]) filename = matches[1].replace(/['"]/g, '');
+                    }
+                    let a = document.createElement('a');
+                    let url = window.URL.createObjectURL(data);
+                    a.href = url;
+                    a.download = filename.replace('UTF-8', '');
+                    document.body.append(a);
+                    a.click();
+                    a.remove();
+                    window.URL.revokeObjectURL(url);
+                    $("#overlay").fadeOut(300);
+                },
+                error: function (data) {
+                    stopSpinner('btnExportExcel');
+                    console.log(data.error);
+                }
+            })
+        }
+
+        //function updateGridDataDetail(val) {
+        //    console.log(val);
+        //    $("#gridbody_detail").html("");
+        //    var html = "";
+        //    if (val != undefined) {
+        //        for (var i = 0; i < val.length; i++) {
+        //            var service = val[i];
+        //            html += "<tr>";
+        //            html += "<td scope='row'>" + (i + 1) + "</td>";
+        //            html += "<td class='text-center'>" + (service.timeRequest) + "</td>";
+        //            html += "<td class='text-center'>" + (service.acountSend) + "</td>";
+        //            html += "<td class='text-left'>" + (service.reqeustId) + "</td>";
+        //            html += "<td class='text-left'>" + (service.responseId) + "</td>";
+        //            html += "<td class='text-center'>" + (service.acountRecieve) + "</td>";
+        //            html += "<td class='text-left'>" + formatTransferType(service.channelPayment) + "</td>";
+        //            html += "<td class='text-right'>" + formatNumber(service.money) + "</td>";
+        //            html += "<td class='text-center'>" + formatStatus(service.status) + "</td>";
+        //            html += "</tr>";
+        //        }
+        //    }
+        //    $("#gridbody_detail").html(html);
+        //}
+
+        // clear error
+        $(".modal input").keyup(function() {
+            $("#lblWarning").html("");
+            $(this).removeClass("input-invalid");
+        })
+
+    </script>
+}
+

+ 298 - 8
SuperAdmin/SuperAdmin/Views/Admin/CampaignManagement.cshtml

@@ -17,6 +17,88 @@
     img {
         max-width: 100%;
     }
+    
+    .searchable-dropdown {
+        position: relative;
+        display: inline-block;
+        width: 100%;
+    }
+    
+    .searchable-input {
+        width: 100%;
+        padding: 8px 12px;
+        border: 1px solid #ddd;
+        border-radius: 4px;
+        font-size: 14px;
+        background-color: white;
+    }
+    
+    .searchable-input:focus {
+        border-color: #007bff;
+        box-shadow: 0 0 0 0.2rem rgba(0, 123, 255, 0.25);
+        outline: none;
+    }
+    
+    .searchable-input::placeholder {
+        color: #999;
+        font-style: italic;
+    }
+    
+    .dropdown-list {
+        position: absolute;
+        top: 100%;
+        left: 0;
+        right: 0;
+        background-color: white;
+        border: 1px solid #ddd;
+        border-top: none;
+        border-radius: 0 0 4px 4px;
+        max-height: 200px;
+        overflow-y: auto;
+        z-index: 1000;
+        box-shadow: 0 2px 4px rgba(0,0,0,0.1);
+    }
+    
+    .dropdown-item {
+        padding: 8px 12px;
+        cursor: pointer;
+        border-bottom: 1px solid #f0f0f0;
+        font-size: 14px;
+    }
+    
+    .dropdown-item:hover {
+        background-color: #f8f9fa;
+    }
+    
+    .dropdown-item:last-child {
+        border-bottom: none;
+    }
+    
+    .dropdown-item.highlighted {
+        background-color: #e3f2fd;
+    }
+    
+    .editable-field {
+        background-color: #fff !important;
+        border-color: #007bff !important;
+        cursor: text !important;
+    }
+    
+    .editable-field:focus {
+        border-color: #007bff !important;
+        box-shadow: 0 0 0 0.2rem rgba(0, 123, 255, 0.25) !important;
+    }
+    
+    .readonly-field {
+        background-color: #f8f9fa !important;
+        border-color: #dee2e6 !important;
+        cursor: not-allowed !important;
+    }
+    
+    .readonly-field:focus {
+        border-color: #dee2e6 !important;
+        box-shadow: none !important;
+    }
 </style>
 
 <div class="content-header row">
@@ -132,9 +214,7 @@
             <div class="col-12">
                 <div class="card">
                     <div class="card-content " id="partial-content">
-                        @*<div class="col-md-12 table-responsive" style="padding-top: 10px">
-                                @Html.Partial("_Campaigns")
-                            </div>*@
+                        
                     </div>
                 </div>
             </div>
@@ -211,6 +291,7 @@
             });
 
             search();
+            loadSvGroup();
         });
 
 
@@ -257,6 +338,14 @@
                     } else {
                         $("#campaign-info").html(result);
                         updateTotalChar();
+                        
+                        // Apply service type visibility rules after loading
+                        setTimeout(function() {
+                            toggleServiceTypeFields();
+                            // Don't clear search inputs when loading existing data
+                            // $(".searchable-input").val("");
+                        }, 100);
+                        
                         if (isEdit) {
                             enableElement();
                             $("#btnAddUpdate").html("Update");
@@ -282,15 +371,170 @@
             }
         }
 
+        function toggleServiceTypeFields() {
+            var serviceType = $("#addType").val();
+            console.log("Service Type changed to: " + serviceType);
+            
+            // Toggle header visibility
+            if (serviceType == "1" || serviceType == "2") {
+                $("#ussd-teaser-2-header").hide();
+                $("#key-2-header").hide();
+            } else if (serviceType == "3") {
+                $("#ussd-teaser-2-header").show();
+                $("#key-2-header").show();
+            }
+            
+            // Get all service rows
+            $("[name='campService']").each(function() {
+                var index = $(this).attr('id').split('-')[1];
+                toggleServiceFieldsByType(serviceType, index);
+            });
+        }
+
+        function toggleServiceFieldsByType(serviceType, index) {
+            var ussdTeaser2Col = $("#campService-" + index + " .col-md-3:nth-child(4)");
+            var key2Col = $("#campService-" + index + " .col-md-1:nth-child(5)");
+            var msgConfirmInput = $("#msgConfirm-" + index);
+            
+            if (serviceType == "1" || serviceType == "2") {
+                // Service Type 1 hoặc 2: chỉ hiển thị Title teaser và USSD Teaser 1
+                ussdTeaser2Col.hide();
+                key2Col.hide();
+                console.log("Hiding USSD Teaser 2 and Key 2 for service " + index);
+            } else if (serviceType == "3") {
+                // Service Type 3: hiển thị cả 4 ô và cho phép chỉnh sửa USSD Teaser 2
+                ussdTeaser2Col.show();
+                key2Col.show();
+                
+                // Store current value before making editable
+                var currentValue = msgConfirmInput.val();
+                
+                // Remove readonly attribute để có thể chỉnh sửa
+                msgConfirmInput.removeAttr('readonly');
+                msgConfirmInput.addClass('editable-field');
+                
+                // Restore the value if it exists (to preserve existing data)
+                if (currentValue && currentValue.trim() !== '') {
+                    msgConfirmInput.val(currentValue);
+                }
+                
+                console.log("Showing all fields for service " + index + " and making USSD Teaser 2 editable. Current value: " + currentValue);
+            }
+        }
+
+        function filterServiceOptions(index) {
+            var searchTerm = $("#serviceSearch-" + index).val().toLowerCase();
+            var selectedGroup = $("#serviceGroup-" + index).val();
+            var dropdownList = $("#serviceList-" + index);
+            var items = dropdownList.find(".dropdown-item");
+            
+            console.log("Filtering services for index " + index + " with term: " + searchTerm + " and group: " + selectedGroup);
+            
+            // Show/hide items based on search term and group
+            items.each(function() {
+                var itemText = $(this).text().toLowerCase();
+                var itemGroup = $(this).attr("data-group");
+                
+                var matchesSearch = itemText.includes(searchTerm) || searchTerm === "";
+                var matchesGroup = selectedGroup === "" || itemGroup === selectedGroup;
+                
+                if (matchesSearch && matchesGroup) {
+                    $(this).show();
+                } else {
+                    $(this).hide();
+                }
+            });
+            
+            // Show dropdown if there's a search term
+            if (searchTerm !== "") {
+                dropdownList.show();
+            }
+        }
+
+        function filterServicesByGroup(index) {
+            var selectedGroup = $("#serviceGroup-" + index).val();
+            var dropdownList = $("#serviceList-" + index);
+            var items = dropdownList.find(".dropdown-item");
+            
+            console.log("Filtering services by group for index " + index + " with group: " + selectedGroup);
+            
+            // Show/hide items based on group
+            items.each(function() {
+                var itemGroup = $(this).attr("data-group");
+                
+                if (selectedGroup === "" || itemGroup === selectedGroup) {
+                    $(this).show();
+                } else {
+                    $(this).hide();
+                }
+            });
+            
+            // Clear search input when group changes
+            $("#serviceSearch-" + index).val("");
+            
+            // Hide dropdown
+            dropdownList.hide();
+        }
+
+        function toggleDropdown(index) {
+            var dropdownList = $("#serviceList-" + index);
+            dropdownList.toggle();
+        }
+
+        function selectServiceOption(index, serviceId, ussd1, ussd2, displayText) {
+            // Set the input value to display text
+            $("#serviceSearch-" + index).val(displayText);
+            
+            // Set the hidden input value
+            $("#serviceAddId-" + index).val(serviceId);
+            
+            // Hide dropdown
+            $("#serviceList-" + index).hide();
+            
+            // Auto-fill both USSD Teaser 1 and 2 when selecting a service
+            $("#ussdDisplay-" + index).val(ussd1);
+            $("#msgConfirm-" + index).val(ussd2);
+            
+            console.log("Selected service " + serviceId + " for index " + index);
+        }
+
+        // Close dropdown when clicking outside
+        $(document).click(function(e) {
+            if (!$(e.target).closest('.searchable-dropdown').length) {
+                $('.dropdown-list').hide();
+            }
+        });
+
         function selectService(i) {
             let svId = $("#serviceAddId-" + i).val();
-            let ussd1 = $("#serviceAddId-" + i + " option:selected").attr("ussd1");
-            let ussd2 = $("#serviceAddId-" + i + " option:selected").attr("ussd2");
+            
+            // Find the selected service data from dropdown items
+            let selectedItem = $("#serviceList-" + i).find(".dropdown-item[data-value='" + svId + "']");
+            let ussd1 = selectedItem.attr("data-ussd1");
+            let ussd2 = selectedItem.attr("data-ussd2");
+            
             $("#ussdDisplay-" + i).val(ussd1);
+            
+            // Always auto-fill USSD Teaser 2 when selecting a service
+            // The readonly/editable state is controlled by toggleServiceFieldsByType
             $("#msgConfirm-" + i).val(ussd2);
-
         }
 
+        function loadSvGroup() {
+            $.ajax({
+                url: urlConfig("/Admin/SvGroup"),
+                data: {
+                    
+                },
+                type: "POST",
+                success: function (data) {
+                    console.log(data);
+                },
+                error: function (data) {
+                    console.log(data.error);
+                }
+            })
+        };
         function loadService(id) {
             $.ajax({
                 url: urlConfig("/Admin/CampaignService"),
@@ -310,6 +554,11 @@
                     $("#title").val(ussdDisplay[0]);
                     //
                     updateTotalChar();
+                    
+                    // Apply service type visibility rules after loading services
+                    setTimeout(function() {
+                        toggleServiceTypeFields();
+                    }, 100);
                 },
                 error: function (data) {
                     console.log(data.error);
@@ -441,6 +690,13 @@
                     // show all 
                     enableElement();
                     updateTotalChar();
+                    
+                    // Apply service type visibility rules to new service
+                    var serviceType = $("#addType").val();
+                    toggleServiceFieldsByType(serviceType, nextIndex);
+                    
+                    // Clear search input for new service
+                    $("#serviceSearch-" + nextIndex).val("");
 
                 },
                 error: function (data) {
@@ -451,9 +707,14 @@
 
         function disableElement() {
             $('#campaign-info').addClass('div-disabled');
-            $("#campaign-info").find('button').hide();
+            // Hide only action buttons, not all buttons
+            $("#campaign-info").find('.btn-add-service').hide();
             $("#campaign-info").find('.dynamic-control').hide();
             $("#btnAddUpdate").hide();
+            
+            // Make all inputs readonly for view mode
+            $("#campaign-info").find('input[type="text"], input[type="number"], textarea, select').prop('readonly', true);
+            $("#campaign-info").find('input[type="text"], input[type="number"], textarea, select').addClass('readonly-field');
         }
 
         function enableElement() {
@@ -461,6 +722,10 @@
             $("#campaign-info").find('button').show();
             $("#campaign-info").find('.dynamic-control').show();
             $("#btnAddUpdate").show();
+            
+            // Remove readonly from inputs for edit mode
+            $("#campaign-info").find('input[type="text"], input[type="number"], textarea, select').prop('readonly', false);
+            $("#campaign-info").find('input[type="text"], input[type="number"], textarea, select').removeClass('readonly-field');
         }
 
         function add() {
@@ -476,6 +741,13 @@
             $("#list-campListSub").html("");
             $("#btnAddUpdate").html("Add");
             addService(); 
+            
+            // Apply initial service type visibility rules
+            setTimeout(function() {
+                toggleServiceTypeFields();
+                // Clear search inputs only when adding new campaign
+                $(".searchable-input").val("");
+            }, 200);
              
             //
             //updateTotalChar();
@@ -550,7 +822,9 @@
                 let svId = $("#serviceAddId-" + i).val();
                 let ussdDisplay = $("#ussdDisplay-" + i).val();
                 let keyRegister = $("#keyRegister-" + i).val();
+                let msgConfirm = $("#msgConfirm-" + i).val();
                 let note = $("#serviceAddId-" + i + " option:selected").text();
+                
                 if(ussdDisplay == null || ussdDisplay == "") {
                     $("#ussdDisplay-" + i).addClass('input-invalid');
                     $("#ussdDisplay-" + i).focus();
@@ -563,11 +837,27 @@
                     isPass = false;
                     return;
                 }
+                
+                // Validate msgConfirm based on Service Type
+                var serviceType = $("#addType").val();
+                if (serviceType == "3" && (msgConfirm == null || msgConfirm == "")) {
+                    $("#msgConfirm-" + i).addClass('input-invalid');
+                    $("#msgConfirm-" + i).focus();
+                    isPass = false;
+                    return;
+                }
+                
                 // if (idx == 0) {
                 //     ussdDisplay = $("#title").val() + "\n" + ussdDisplay;
                 //     console.log("add title: " + ussdDisplay);
                 // }
-                services.push({ serviceId: svId, ussdDisplay: ussdDisplay, keyRegister: keyRegister, note: note });
+                services.push({ 
+                    serviceId: svId, 
+                    ussdDisplay: ussdDisplay, 
+                    keyRegister: keyRegister, 
+                    msgConfirm: msgConfirm,
+                    note: note 
+                });
                 idx++;
             });
             console.log(services);

+ 1 - 1
SuperAdmin/SuperAdmin/Views/Admin/Dashboard.cshtml

@@ -28,7 +28,7 @@
                                     <div class="col-md-4">
                                         <div class="form-group row">
                                             <div class="col-md-9">
-                                                <button type="submit" id="btnSearch" class="btn btn-info">Search</button>
+                                                <button type="submit" id="btnSearch" class="btn btn-info"><i class="fa fa-search"></i>Search</button>
                                             </div>
                                         </div>
                                     </div>

+ 1 - 1
SuperAdmin/SuperAdmin/Views/Admin/Index.cshtml

@@ -22,7 +22,7 @@
                     <div class="col-md-4">
                         <div class="form-group row">
                             <div class="col-md-9">
-                                <button type="button" id="btnSearch" class="btn btn-info" onclick="search();">Search</button>
+                                <button type="button" id="btnSearch" class="btn btn-info" onclick="search()"><i class="fa fa-search"></i>Search</button>
                             </div>
                         </div>
                     </div>

+ 2 - 2
SuperAdmin/SuperAdmin/Views/Admin/ReportCampaign.cshtml

@@ -81,10 +81,10 @@
                                     <div class="row">
                                         <div class="col-md-12">
                                             <button type="button" class="btn btn-info" onclick="search()" id="btnSearch">
-                                                <i class="icon-search"></i> Search
+                                                <i class="fa fa-search"></i> Search
                                             </button>
                                             <button type="button" class="btn btn-warning" onclick="exportExcel()" id="btnExportExcel">
-                                                <i class="icon-export"></i> Export Excel
+                                                <i class="fa fa-file-export"></i> Export Excel
                                             </button>
                                         </div>
                                     </div>

+ 131 - 4
SuperAdmin/SuperAdmin/Views/Admin/ServiceManagement.cshtml

@@ -7,10 +7,23 @@
 @using SuperAdmin.Models.Http;
 @using SuperAdmin.Controllers;
 @using SuperAdmin.Source;
-
+@using SuperAdmin.Models.Object
+@using SuperCms.Extensions;
+@using Timor_BPSuperAdmin.Models.Http
 
 @{
 
+    var serviceGroups = Context.Session.GetComplexData<List<ServiceGroupData>>("serviceGroupData");
+    if (serviceGroups == null)
+    {
+        serviceGroups = new List<ServiceGroupData>();
+    }
+    var apiServices = Context.Session.GetComplexData<List<ApiService>>("apiServiceData");
+                                                                        
+    if (apiServices == null)
+    {
+        apiServices = new List<ApiService>();
+    }
 }
 
 <style>
@@ -148,6 +161,23 @@
                             <input type="text" class="form-control" id="shortCode" name="shortCode">
                         </div>
                     </div>
+                    <div class="col-md-6">
+                        <div class="form-group">
+                            <label for="serviceGroupId">Service Group</label>
+                            <select class="form-control" id="serviceGroupId" name="serviceGroupId">
+                                <option value="">-- Select Group --</option>
+                            </select>
+                        </div>
+                    </div>
+
+                    <div class="col-md-6">
+                        <div class="form-group">
+                            <label for="apiServiceId">Api Service</label>
+                            <select class="form-control" id="apiServiceId" name="apiServiceId">
+                                <option value="">-- Select Api Service --</option>
+                            </select>
+                        </div>
+                    </div>
                     <div class="col-md-6">
                         <div class="form-group">
                             <label for="date">Command</label>
@@ -182,6 +212,8 @@
                         </div>
                     </div>
 
+                    
+
                     <input type="hidden" name="result" id="result" />
 
                 </div>
@@ -229,10 +261,62 @@
                 format: "DD/MM/YYYY",
                 defaultDate: moment().add(1, 'days')
             });
-
+            // loadSvGroup();
+            
+            // Load Api Services
+            loadApiServices();
+            // Load Service Groups
+            loadServiceGroups();
             search();
         });
 
+        function loadServiceGroups() {
+            $.ajax({
+                url: urlConfig("/Admin/SvGroupLoad"),
+                type: "POST",
+                success: function (result) {
+                    if (result.error == 0 && result.data && result.data.length > 0) {
+                        var select = $("#serviceGroupId");
+                        select.empty();
+                        select.append('<option value="">-- Select Service Group --</option>');
+                        for (var i = 0; i < result.data.length; i++) {
+                            select.append('<option value="' + result.data[i].id + '">' + result.data[i].name + '</option>');
+                        }
+                    } else if (result.error == "-1") {
+                        alert("Please login first!");
+                        window.location.href = "/Home/Login";
+                    } else {
+                        console.warn("⚠️ Không có dữ liệu Service Group");
+                    }
+                },
+                error: function (xhr, status, err) {
+                    console.error("❌ loadServiceGroups error:", err);
+                }
+            });
+        }
+
+        function loadApiServices() {
+            $.ajax({
+                url: urlConfig("/Admin/GetApiServices"), // GỌI endpoint mới
+                type: "POST",
+                success: function (result) {
+                    if (result.error == 0 && result.data && result.data.length > 0) {
+                        var select = $("#apiServiceId");
+                        select.empty();
+                        select.append('<option value="">-- Select API Service --</option>');
+                        for (var i = 0; i < result.data.length; i++) {
+                            select.append('<option value="' + result.data[i].ws_id + '">' + result.data[i].ws_name + '</option>');
+                        }
+                    } else {
+                        console.warn("⚠️ Không có dữ liệu API service");
+                    }
+                },
+                error: function (xhr, status, err) {
+                    console.error("❌ loadApiServices error:", err);
+                }
+            });
+        }
+
 
 
         function resetTableDetail() {
@@ -259,9 +343,35 @@
             $("#description").val("");
             $("#contentLc").val("");
             $("#msgConfirm").val("");
+            $("#serviceGroupId").val("");
+            $("#apiServiceId").val("");
             $("#btnAddUpdate").html("Add");
             showModal("modal-add-service");
         }
+
+        // function loadServiceGroups() {
+        //     var groups = @Html.Raw(Json.Serialize(serviceGroups));
+        //     if (groups && groups.length > 0) {
+        //         var select = $("#serviceGroupId");
+        //         select.empty();
+        //         select.append('<option value="">-- Select Group --</option>');
+        //         for (var i = 0; i < groups.length; i++) {
+        //             select.append('<option value="' + groups[i].id + '">' + groups[i].name + '</option>');
+        //         }
+        //     }
+        // }
+
+        // function loadApiServices() {
+        //     var list = @Html.Raw(Json.Serialize(apiServices));
+        //     var select = $("#apiServiceId");
+        //     select.empty();
+        //     select.append('<option value="">-- Select Api Service --</option>');
+        //     if (list && list.length > 0) {
+        //         for (var i = 0; i < list.length; i++) {
+        //             select.append('<option value="' + list[i].ws_id + '">' + list[i].ws_name + '</option>');
+        //         }
+        //     }
+        // }
          
 
         function edit(id) {
@@ -289,6 +399,8 @@
                         $("#description").val(sv.description);
                         $("#contentLc").val(sv.contentLc);
                         $("#msgConfirm").val(sv.msgConfirm);
+                        $("#serviceGroupId").val(sv.serviceGroupID || "");
+                        $("#apiServiceId").val(sv.apiServiceId || "");
                     } else {
                         console.log("error");
                     }
@@ -305,6 +417,8 @@
             let shortCode = $("#shortCode").val();
             let command = $("#command").val();
             let contentLc = $("#contentLc").val();
+            let serviceGroupId = $("#serviceGroupId").val();
+            let apiServiceId = $("#apiServiceId").val();
 
             if (name == null || name == "") {
                 $("#name").addClass('input-invalid');
@@ -326,6 +440,17 @@
                 $("contentLc").focus();
                 return false;
             }
+
+            if (serviceGroupId == null || serviceGroupId == "") {
+                $("#serviceGroupId").addClass('input-invalid');
+                $("serviceGroupId").focus();
+                return false;
+            }
+            if (apiServiceId == null || apiServiceId == "") {
+                $("#apiServiceId").addClass('input-invalid');
+                $("apiServiceId").focus();
+                return false;
+            }
             return true;
         }
 
@@ -348,7 +473,9 @@
                     command: $("#command").val(),
                     description: $("#description").val(),
                     contentLc: $("#contentLc").val(),
-                    msgConfirm: $("#msgConfirm").val()
+                    msgConfirm: $("#msgConfirm").val(),
+                    serviceGroupId: $("#serviceGroupId").val(),
+                    apiServiceId: $("#apiServiceId").val()
                 },
                 success: function (result) {
                     stopSpinner("btnAddUpdate");
@@ -440,7 +567,7 @@
                     let a = document.createElement('a');
                     let url = window.URL.createObjectURL(data);
                     a.href = url;
-                    a.download = filename.replace('UTF-8', '');;
+                    a.download = filename.replace('UTF-8', '');
                     document.body.append(a);
                     a.click();
                     a.remove();

+ 42 - 38
SuperAdmin/SuperAdmin/Views/Home/Login.cshtml

@@ -1,47 +1,51 @@
-
-@{
+@{
     ViewData["Title"] = "Login";
     Layout = "~/Views/Shared/_NothingLayout.cshtml";
 }
 
-<div class="app-content content">
-    <div class="content-wrapper">
-        <div class="content-header row">
+<link rel="stylesheet" href="~/css/login.css" />
+
+<div class="login-background"></div>
+<div class="login-grid"></div>
+<div class="glowing-orb orb-1"></div>
+<div class="glowing-orb orb-2"></div>
+<div class="glowing-orb orb-3"></div>
+
+<div class="login-container">
+    <div class="login-form-card">
+        <div class="login-header">
+            <div class="logo-circle">
+                <i class="ft-lock" style="font-size: 36px; color: #fff;"></i>
+            </div>
+            <h2 class="login-title">CMS B +</h2>
+            <p class="login-subtitle">Access Control System</p>
         </div>
-        <div class="content-body">
-            <section class="flexbox-container">
-                <div class="col-12 d-flex align-items-center justify-content-center">
-                    <div class="col-lg-4 col-md-8 col-10 box-shadow-2 p-0">
-                        <div class="card border-grey border-lighten-3 px-1 py-1 m-0">
-                            <div class="card-header border-0">
-                                <div class="card-title text-center">
-                                    LOGIN
-                                </div>
-                            </div>
-                            <div class="card-content">
-                                <div class="card-body">
-                                    <form class="form-horizontal" action="@ViewBag.MyConfig.MyValue/Home/LoginAction" method="post">
-                                        <fieldset class="form-group position-relative has-icon-left">
-                                            <input type="text" class="form-control" id="user-name" placeholder="Your Username" name="account" required>
-                                            <div class="form-control-position">
-                                                <i class="ft-user"></i>
-                                            </div>
-                                        </fieldset>
-                                        <fieldset class="form-group position-relative has-icon-left">
-                                            <input type="password" class="form-control" id="user-password" placeholder="Enter Password" name="password" required>
-                                            <div class="form-control-position">
-                                                <i class="fa fa-key"></i>
-                                            </div>
-                                        </fieldset>
-                                        <span class="text-danger"></span>
-                                        <button type="submit" class="btn btn-outline-primary btn-block"><i class="ft-unlock"></i> Login</button>
-                                    </form>
-                                </div>
-                            </div>
-                        </div>
-                    </div>
+        
+        <div class="form-section">
+            <form class="form-horizontal" action="@ViewBag.MyConfig.MyValue/Home/LoginAction" method="post">
+                <div class="input-wrapper">
+                    <input type="text" class="input-enhanced" id="user-name" placeholder="USERNAME" name="account" required>
+                    <i class="ft-user input-icon"></i>
+                </div>
+                
+                <div class="input-wrapper">
+                    <input type="password" class="input-enhanced" id="user-password" placeholder="PASSWORD" name="password" required>
+                    <i class="fa fa-key input-icon"></i>
                 </div>
-            </section>
+                
+                <div class="error-message">
+                    <span class="text-danger"></span>
+                </div>
+                
+                <button type="submit" class="btn-login">
+                    <i class="ft-unlock" style="margin-right: 8px;"></i>
+                    Login
+                </button>
+            </form>
+        </div>
+        
+        <div class="security-note">
+            ⚡ Protected Access - Authorized Personnel Only
         </div>
     </div>
 </div>

+ 64 - 0
SuperAdmin/SuperAdmin/Views/Partial/_ApiWebserviceManagement.cshtml

@@ -0,0 +1,64 @@
+@using SuperAdmin.Models;
+@using SuperAdmin.Models.Http;
+@using SuperAdmin.Controllers;
+@using SuperAdmin.Source;
+@using Timor_BPSuperAdmin.Models.Http
+
+@model List<ApiService>
+
+<div class="card-body">
+    <table class="table table-striped table-bordered zero-configuration " id="grid_detail">
+        <thead class="thead-inverse">
+            <tr>
+                <th scope="col">#</th>
+                <th scope="col" class="text-center" style="vertical-align:middle">ID</th>
+                <th scope="col" class="text-center" style="vertical-align:middle">ws_name</th>
+                <th scope="col" class="text-center" style="vertical-align:middle">ws_code</th>
+                <th scope="col" class="text-center" style="vertical-align:middle">wsdl</th>
+                <th scope="col" class="text-center" style="vertical-align:middle">msg_template</th>
+                <th scope="col" class="text-center" style="vertical-align:middle">error_tag</th>
+                <th scope="col" class="text-center" style="vertical-align:middle">Status</th>
+                <th scope="col" class="text-center" style="vertical-align:middle">Action</th>
+            </tr>
+        </thead>
+        <tbody id="gridbody_detail">
+            @if (Model != null)
+            {
+                for (int i = 0; i < Model.Count; i++)
+                {
+                    var ws = Model[@i];
+                    <tr>
+                        <td scope="row">@(i + 1)</td>
+                        <td class="text-left">@ws.ws_id</td>
+                        <td class="text-left">@ws.ws_name</td>
+                        <td class="text-left">@ws.ws_code</td>
+                        <td class="text-left">@ws.wsdl</td>
+                        <td class="text-left">@ws.msg_template</td>
+                        <td class="text-left">@ws.error_tag</td>
+                        <td class="text-center">
+                            @if (ws.isActive == "1")
+                            {
+                                <span class="badge badge-success">Active</span>
+                            }
+                            else
+                            {
+                                <span class="badge badge-danger">Inactive</span>
+                            }
+                        </td>
+                        <td class="text-center">
+                            <div class="btn-group" role="group">
+                                <button class="btn btn-sm btn-outline-primary" onclick="editApiService(@ws.ws_id)">Edit</button>
+                            </div>
+                        </td>
+                    </tr>
+                }
+            }
+            else
+            {
+                <tr>
+                    <td colspan="11">No data</td>
+                </tr>
+            }
+        </tbody>
+    </table>
+</div>

+ 4 - 3
SuperAdmin/SuperAdmin/Views/Partial/_Campaign.cshtml

@@ -66,7 +66,8 @@
     <div class="col-md-6">
         <div class="form-group">
             <label for="wsName">Service Type</label>
-            <select class="form-control" id="addType" name="addType" asp-for="addType">
+            <select class="form-control" id="addType" name="addType" asp-for="addType" onchange="toggleServiceTypeFields()">
+                <option value="1">Text</option>
                 <option value="2">1-Verification</option>
                 <option value="3">2-Verification</option>
             </select>
@@ -142,12 +143,12 @@
             </div>
         </div>
 
-        <div class="col-md-3">
+        <div class="col-md-3" id="ussd-teaser-2-header">
             <div class="">
                 <label for="date">USSD Teaser 2</label>
             </div>
         </div>
-        <div class="col-md-1">
+        <div class="col-md-1" id="key-2-header">
             <div class="">
                 <label for="date">Key 2</label>
             </div>

+ 103 - 24
SuperAdmin/SuperAdmin/Views/Partial/_CampaignService.cshtml

@@ -13,6 +13,7 @@
     {
         nextIndex = "0";
     }
+    var serviceGroupData = Context.Session.GetComplexData<List<ServiceGroupData>>("serviceGroupData");
 }
 
 @if (Model != null)
@@ -21,97 +22,175 @@
     {
         var campaignServiceObj = Model[i];
         <div class="row" name="campService" id="campService-@i">
+            <!-- Row 1: Service Group và Service -->
             <div class="col-md-3">
                 <div class="form-group">
-                    <select class="form-control" id="serviceAddId-@i" name="serviceAddId" onchange="selectService('@i')">
-                        @foreach (Service sv in listService)
+                    <label>Service Group</label>
+                    <select class="form-control" id="serviceGroup-@i" onchange="filterServicesByGroup('@i')">
+                        <option value="">-- All Groups --</option>
+                        @if (serviceGroupData != null)
                         {
-                            if (sv.id == campaignServiceObj.serviceAddId)
-                            {
-                                <option value="@sv.id" selected ussd1="@sv.contentLc" ussd2="@sv.msgConfirm">@sv.id - @sv.name</option>
-                            }
-                            else
+                            @foreach (ServiceGroupData group in serviceGroupData)
                             {
-                                <option value="@sv.id" ussd1="@sv.contentLc" ussd2="@sv.msgConfirm">@sv.id - @sv.name</option>
+                                <option value="@group.id">@group.name</option>
                             }
                         }
                     </select>
                 </div>
             </div>
+            <div class="col-md-6">
+                <div class="form-group">
+                    <label>Service</label>
+                    <div class="searchable-dropdown" id="serviceDropdown-@i">
+                        <input type="text" class="form-control searchable-input" id="serviceSearch-@i" 
+                               placeholder="Tìm kiếm và chọn service..." 
+                               onkeyup="filterServiceOptions('@i')" 
+                               onclick="toggleDropdown('@i')"
+                               autocomplete="off"
+                               value="@(campaignServiceObj.serviceObj != null ? campaignServiceObj.serviceObj.id + " - " + campaignServiceObj.serviceObj.name : "")">
+                        <div class="dropdown-list" id="serviceList-@i" style="display: none;">
+                            @foreach (Service sv in listService)
+                            {
+                                <div class="dropdown-item" data-value="@sv.id" data-ussd1="@sv.contentLc" data-ussd2="@sv.msgConfirm" data-group="@sv.serviceGroupID"
+                                     onclick="selectServiceOption('@i', '@sv.id', '@sv.contentLc', '@sv.msgConfirm', '@sv.id - @sv.name')">
+                                    @sv.id - @sv.name
+                                </div>
+                            }
+                        </div>
+                        <input type="hidden" id="serviceAddId-@i" name="serviceAddId" value="@campaignServiceObj.serviceAddId">
+                    </div>
+                </div>
+            </div>
             <div class="col-md-3">
                 <div class="form-group">
+                    <label>&nbsp;</label>
+                    <button onclick="removeService(@i);" class="btn btn-outline-danger btn-add-service form-control"><span class="fa fa-minus"></span> Remove</button>
+                </div>
+            </div>
+            
+            <!-- Row 2: USSD Teaser 1, Key 1, USSD Teaser 2, Key 2 -->
+            <div class="col-md-3">
+                <div class="form-group">
+                    <label>USSD Teaser 1</label>
                     <textarea class="hidden" id="ussdDisplayMulti-@i">@campaignServiceObj.ussdDisplay</textarea>
                     <input type="text" class="form-control" id="ussdDisplay-@i" name="ussdDisplay" onchange="updateTotalChar();" onkeyup="updateTotalChar();"
                            onkeypress="clearValidate('ussdDisplay-@i')"
                            value="@campaignServiceObj.ussdDisplay" >
                 </div>
             </div>
-            <div class="col-md-1">
+            <div class="col-md-2">
                 <div class="form-group">
+                    <label>Key 1</label>
                     <input type="text" class="form-control" id="keyRegister-@i" name="keyRegister" onkeypress="clearValidate('keyRegister-@i')"
                            value="@campaignServiceObj.keyRegister">
                 </div>
             </div>
-
             <div class="col-md-3">
                 <div class="form-group">
+                    <label>USSD Teaser 2</label>
                     <input type="text" class="form-control" id="msgConfirm-@i" value="@campaignServiceObj.serviceObj.msgConfirm" readonly>
                 </div>
             </div>
-            <div class="col-md-1">
+            <div class="col-md-2">
                 <div class="form-group">
-                    <input type="text" class="form-control"   value="1" readonly>
+                    <label>Key 2</label>
+                    <input type="text" class="form-control" value="1" readonly>
                 </div>
             </div>
-
-            <div class="col-md-1">
+            @* <div class="col-md-2">
                 <div class="form-group">
-                    <button onclick="removeService(@i);" class="btn btn-outline-danger btn-add-service"><span class="fa fa-minus"></span></button>
+                    <label>&nbsp;</label>
+                    <div class="form-control text-center" style="background-color: #f8f9fa; border: 1px solid #dee2e6;">
+                        <strong>Qty: 1</strong>
+                    </div>
                 </div>
-            </div>
+            </div> *@
         </div>
     }
 }
 else
 {
     <div class="row" name="campService" id="campService-@nextIndex">
+        <!-- Row 1: Service Group và Service -->
         <div class="col-md-3">
             <div class="form-group">
-                <select class="form-control" id="serviceAddId-@nextIndex" name="serviceAddId" onchange="selectService('@nextIndex')">
-                    @foreach (Service sv in listService)
+                <label>Service Group</label>
+                <select class="form-control" id="serviceGroup-@nextIndex" onchange="filterServicesByGroup('@nextIndex')">
+                    <option value="">-- All Groups --</option>
+                    @if (serviceGroupData != null)
                     {
-                        <option value="@sv.id" ussd1="@sv.contentLc" ussd2="@sv.msgConfirm">@sv.id - @sv.name</option>
+                        @foreach (ServiceGroupData group in serviceGroupData)
+                        {
+                            <option value="@group.id">@group.name</option>
+                        }
                     }
                 </select>
             </div>
         </div>
+        <div class="col-md-6">
+            <div class="form-group">
+                <label>Service</label>
+                <div class="searchable-dropdown" id="serviceDropdown-@nextIndex">
+                    <input type="text" class="form-control searchable-input" id="serviceSearch-@nextIndex" 
+                           placeholder="Tìm kiếm và chọn service..." 
+                           onkeyup="filterServiceOptions('@nextIndex')" 
+                           onclick="toggleDropdown('@nextIndex')"
+                           autocomplete="off">
+                    <div class="dropdown-list" id="serviceList-@nextIndex" style="display: none;">
+                        @foreach (Service sv in listService)
+                        {
+                            <div class="dropdown-item" data-value="@sv.id" data-ussd1="@sv.contentLc" data-ussd2="@sv.msgConfirm" data-group="@sv.serviceGroupID"
+                                 onclick="selectServiceOption('@nextIndex', '@sv.id', '@sv.contentLc', '@sv.msgConfirm', '@sv.id - @sv.name')">
+                                @sv.id - @sv.name
+                            </div>
+                        }
+                    </div>
+                    <input type="hidden" id="serviceAddId-@nextIndex" name="serviceAddId" value="">
+                </div>
+            </div>
+        </div>
         <div class="col-md-3">
             <div class="form-group">
+                <label>&nbsp;</label>
+                <button onclick="removeService(@nextIndex);" class="btn btn-outline-danger btn-add-service form-control"><span class="fa fa-minus"></span> Remove</button>
+            </div>
+        </div>
+        
+        <!-- Row 2: USSD Teaser 1, Key 1, USSD Teaser 2, Key 2 -->
+        <div class="col-md-3">
+            <div class="form-group">
+                <label>USSD Teaser 1</label>
                 <input type="text" class="form-control" id="ussdDisplay-@nextIndex" name="ussdDisplay" onchange="updateTotalChar();" onkeyup="updateTotalChar();"
                        onkeypress="clearValidate('ussdDisplay-@nextIndex')"
                        value="">
             </div>
         </div>
-        <div class="col-md-1">
+        <div class="col-md-2">
             <div class="form-group">
+                <label>Key 1</label>
                 <input type="text" class="form-control" id="keyRegister-@nextIndex" name="keyRegister" onkeypress="clearValidate('keyRegister-@nextIndex')"
                        value="">
             </div>
         </div>
         <div class="col-md-3">
             <div class="form-group">
+                <label>USSD Teaser 2</label>
                 <input type="text" class="form-control" id="msgConfirm-@nextIndex" readonly>
             </div>
         </div>
-        <div class="col-md-1">
+        <div class="col-md-2">
             <div class="form-group">
+                <label>Key 2</label>
                 <input type="text" class="form-control" value="1" readonly>
             </div>
         </div>
-        <div class="col-md-1">
+        @* <div class="col-md-2">
             <div class="form-group">
-                <button onclick="removeService(@nextIndex);" class="btn btn-outline-danger btn-add-service"><span class="fa fa-minus"></span></button>
+                <label>&nbsp;</label>
+                <div class="form-control text-center" style="background-color: #f8f9fa; border: 1px solid #dee2e6;">
+                    <strong>Qty: 1</strong>
+                </div>
             </div>
-        </div>
+        </div> *@
     </div>
 }

+ 151 - 0
SuperAdmin/SuperAdmin/Views/Partial/_Menu - Copy.cshtml

@@ -0,0 +1,151 @@
+@using Microsoft.AspNetCore.Http;
+@using SuperAdmin.Controllers;
+@using SuperAdmin.Models.Object;
+@using SuperCms.Extensions;
+@using SuperAdmin.Source;
+
+@{
+    UserRoles vsa = Context.Session.GetComplexData<UserRoles>("userInfo");
+    var serviceNameText = Context.Session.GetString("serviceName");
+
+    var listMenu = new List<String>();
+    if (vsa != null && vsa.function != null)
+    {
+        var listObj = vsa.function;
+        foreach (Function obj in listObj)
+        {
+            listMenu.Add(obj.link);
+        }
+    }
+}
+
+<ul class="navigation navigation-main" id="main-menu-navigation" data-menu="menu-navigation">
+    @{
+        if (BaseController.useVsa == "0" || listMenu.Contains("/Admin/Index"))
+        {
+            <li class=" nav-item">
+                <a class="nav-link" href="@ViewBag.MyConfig.MyValue/Admin/Index">
+                    <i class="feather icon-home"></i>
+                    <span class="menu-title">Home</span>
+                </a>
+            </li>
+        }
+        if (BaseController.useVsa == "0" || listMenu.Contains("/Admin/CampaignManagement"))
+        {
+            <li class=" nav-item">
+                <a class="nav-link" href="@ViewBag.MyConfig.MyValue/Admin/CampaignManagement">
+                    <i class="feather icon-bar-chart"></i>
+                    <span class="menu-title">Campaigns</span>
+                </a>
+            </li>
+        }
+        if (BaseController.useVsa == "0" || listMenu.Contains("/Admin/CampaignScheduler"))
+        {
+            <li class=" nav-item">
+                <a class="nav-link" href="@ViewBag.MyConfig.MyValue/Admin/CampaignScheduler">
+                    <i class="feather icon-bar-chart"></i>
+                    <span class="menu-title">Calendar</span>
+                </a>
+            </li>
+        }
+
+        if (BaseController.useVsa == "0" || listMenu.Contains("/Admin/CriteriaManagement"))
+        {
+            <li class=" nav-item">
+                <a class="nav-link" href="@ViewBag.MyConfig.MyValue/Criteria/CriteriaManagement">
+                    <i class="feather icon-bar-chart"></i>
+                    <span class="menu-title">Criteria</span>
+                </a>
+            </li>
+        }
+        if (BaseController.useVsa == "0" || listMenu.Contains("/Admin/ApiWebserviceManagement"))
+        {
+            <li class=" nav-item">
+                <a class="nav-link" href="@ViewBag.MyConfig.MyValue/Admin/ApiWebserviceManagement">
+                    <i class="feather icon-bar-chart"></i>
+                    <span class="menu-title">Api Service</span>
+                </a>
+            </li>
+        }
+
+        if (BaseController.useVsa == "0" || listMenu.Contains("/Admin/ServiceManagement"))
+        {
+            <li class=" nav-item">
+                <a class="nav-link" href="@ViewBag.MyConfig.MyValue/Admin/ServiceManagement">
+                    <i class="feather icon-bar-chart"></i>
+                    <span class="menu-title">Services</span>
+                </a>
+            </li>
+        }
+
+        if (BaseController.useVsa == "0" || listMenu.Contains("/File/ListSubManagement"))
+        {
+            <li class="nav-item has-sub">
+                <a href="#">
+                    <i class="feather icon-user"></i><span class="menu-title" data-i18n="nav.page_headers.main">Subs Management</span>
+                </a>
+                <ul class="menu-content" style="">
+                    <li class="is-shown">
+                        <a class="menu-item" href="@ViewBag.MyConfig.MyValue/File/WhitelistManagement"
+                           data-i18n="nav.page_headers.headers_breadcrumbs_basic">Whitelist</a>
+                    </li>
+                    <li class="is-shown">
+                        <a class="menu-item" href="@ViewBag.MyConfig.MyValue/File/BlacklistManagement"
+                           data-i18n="nav.page_headers.headers_breadcrumbs_top">Blacklist</a>
+                    </li>
+                </ul>
+            </li>
+
+            // <li class=" nav-item">
+            //     <a class="nav-link" href="@ViewBag.MyConfig.MyValue/File/ListSubManagement">
+            //         <i class="feather icon-user"></i>
+            //         <span class="menu-title">Subs Management</span>
+            //     </a>
+            // </li>
+        }
+
+
+        if (BaseController.useVsa == "0" || listMenu.Contains("/Admin/ParamManagement"))
+        {
+            <li class=" nav-item">
+                <a class="nav-link" href="@ViewBag.MyConfig.MyValue/Admin/ParamManagement">
+                    <i class="feather icon-settings"></i>
+                    <span class="menu-title">Params Config</span>
+                </a>
+            </li>
+        }
+
+
+        if (BaseController.useVsa == "0" || listMenu.Contains("/Admin/ServiceUnder"))
+        {
+            <li class=" nav-item">
+                <a class="nav-link" href="@ViewBag.MyConfig.MyValue/Admin/ServiceUnder">
+                    <i class="feather icon-lock"></i>
+                    <span class="menu-title">Service Ngam</span>
+                </a>
+            </li>
+        }
+
+
+        if (BaseController.useVsa == "0" || listMenu.Contains("/Admin/ReportCampaign"))
+        {
+            <li class=" nav-item">
+                <a class="nav-link" href="@ViewBag.MyConfig.MyValue/Admin/ReportCampaign">
+                    <i class="feather icon-bar-chart"></i>
+                    <span class="menu-title">Report Campaign</span>
+                </a>
+            </li>
+        }
+
+
+        if (BaseController.useVsa == "0" || listMenu.Contains("/Admin/Reload"))
+        {
+            <li class=" nav-item">
+                <a class="nav-link" href="@ViewBag.MyConfig.MyValue/Admin/Reload">
+                    <i class="feather icon-arrow-up-circle"></i>
+                    <span class="menu-title">Reload Config</span>
+                </a>
+            </li>
+        }
+    }
+</ul>

+ 20 - 7
SuperAdmin/SuperAdmin/Views/Partial/_Menu.cshtml

@@ -34,7 +34,7 @@
         {
             <li class=" nav-item">
                 <a class="nav-link" href="@ViewBag.MyConfig.MyValue/Admin/CampaignManagement">
-                    <i class="feather icon-bar-chart"></i>
+                    <i class="feather icon-flag"></i>
                     <span class="menu-title">Campaigns</span>
                 </a>
             </li>
@@ -43,7 +43,7 @@
         {
             <li class=" nav-item">
                 <a class="nav-link" href="@ViewBag.MyConfig.MyValue/Admin/CampaignScheduler">
-                    <i class="feather icon-bar-chart"></i>
+                    <i class="feather icon-calendar"></i>
                     <span class="menu-title">Calendar</span>
                 </a>
             </li>
@@ -53,17 +53,26 @@
         {
             <li class=" nav-item">
                 <a class="nav-link" href="@ViewBag.MyConfig.MyValue/Criteria/CriteriaManagement">
-                    <i class="feather icon-bar-chart"></i>
+                    <i class="feather icon-layers"></i>
                     <span class="menu-title">Criteria</span>
                 </a>
             </li>
         }
+        if (BaseController.useVsa == "0" || listMenu.Contains("/Admin/ApiWebserviceManagement"))
+        {
+            <li class=" nav-item">
+                <a class="nav-link" href="@ViewBag.MyConfig.MyValue/Admin/ApiWebserviceManagement">
+                    <i class="feather icon-globe"></i>
+                    <span class="menu-title">Api Service</span>
+                </a>
+            </li>
+        }
 
         if (BaseController.useVsa == "0" || listMenu.Contains("/Admin/ServiceManagement"))
         {
             <li class=" nav-item">
                 <a class="nav-link" href="@ViewBag.MyConfig.MyValue/Admin/ServiceManagement">
-                    <i class="feather icon-bar-chart"></i>
+                    <i class="feather icon-grid"></i>
                     <span class="menu-title">Services</span>
                 </a>
             </li>
@@ -78,11 +87,15 @@
                 <ul class="menu-content" style="">
                     <li class="is-shown">
                         <a class="menu-item" href="@ViewBag.MyConfig.MyValue/File/WhitelistManagement"
-                           data-i18n="nav.page_headers.headers_breadcrumbs_basic">Whitelist</a>
+                           data-i18n="nav.page_headers.headers_breadcrumbs_basic">
+                           <i class="feather icon-layers"></i> Whitelist
+                        </a>
                     </li>
                     <li class="is-shown">
                         <a class="menu-item" href="@ViewBag.MyConfig.MyValue/File/BlacklistManagement"
-                           data-i18n="nav.page_headers.headers_breadcrumbs_top">Blacklist</a>
+                           data-i18n="nav.page_headers.headers_breadcrumbs_top">
+                           <i class="feather icon-globe"></i> Blacklist
+                        </a>
                     </li>
                 </ul>
             </li>
@@ -122,7 +135,7 @@
         {
             <li class=" nav-item">
                 <a class="nav-link" href="@ViewBag.MyConfig.MyValue/Admin/ReportCampaign">
-                    <i class="feather icon-bar-chart"></i>
+                    <i class="feather icon-flag"></i>
                     <span class="menu-title">Report Campaign</span>
                 </a>
             </li>

+ 37 - 1
SuperAdmin/SuperAdmin/Views/Shared/_Layout.cshtml

@@ -60,6 +60,7 @@
     <link rel="stylesheet" type="text/css" href="@ViewBag.MyConfig.MyValue/css/tree.css">
     <link rel="stylesheet" type="text/css" href="@ViewBag.MyConfig.MyValue/css/spin.css">
     <link rel="stylesheet" type="text/css" href="@ViewBag.MyConfig.MyValue/css/css.css">
+    <link rel="stylesheet" type="text/css" href="~/css/menu-custom.css">
 
     @RenderSection("Styles", false)
 
@@ -186,7 +187,7 @@
     <footer class="footer footer-static footer-light navbar-border">
         <p class="clearfix blue-grey lighten-2 text-sm-center mb-0 px-2">
             <span class="float-md-left d-block d-md-inline-block">Copyright  &copy; @DateTime.Now.Year Viettech</span>
-            <span class="float-md-right d-none d-lg-block">Sungroup made with <i class="feather icon-heart pink"></i></span>
+            <span class="float-md-right d-none d-lg-block">You made with <i class="feather icon-heart pink"></i></span>
         </p>
     </footer>
 
@@ -502,9 +503,44 @@
                     $(this).parent().addClass("active");
                 }
             });
+            loadSvGroup();
+            searchApi();
         });
     </script>
     <script>
+        function searchApi() {
+            $.ajax({
+                url: urlConfig("/Admin/ApiServiceSearch"),
+                data: {
+                    isActive: "1"
+                },
+                type: "POST",
+                success: function (data) {
+                    
+                },
+                error: function (data) {
+                    console.log(data.error);
+                }
+            })
+        }
+
+        function loadSvGroup() {
+            $.ajax({
+                url: urlConfig("/Admin/SvGroup"),
+                data: {
+
+                },
+                type: "POST",
+                success: function (data) {
+                    console.log(data);
+                },
+                error: function (data) {
+                    console.log(data.error);
+                }
+            })
+        };
+
+
         function updateCampaignStatus(id, status) {
             $.ajax({
                 url: urlConfig("/Admin/UpdateCampaignStatus"),

+ 3 - 24
SuperAdmin/SuperAdmin/Views/Shared/_NothingLayout.cshtml

@@ -23,30 +23,9 @@
     @*<script src="@ViewBag.MyConfig.MyValue/lib/jquery/dist/jquery.js" type="text/javascript"></script>*@
     <script src="@ViewBag.MyConfig.MyValue/lib/jquery/dist/jquery.min.js" type="text/javascript"></script>
 
-    <!-- BEGIN: Vendor CSS-->
-    <link rel="stylesheet" type="text/css" href="@ViewBag.MyConfig.MyValue/css/vendors/vendors.min.css">
-    <link rel="stylesheet" type="text/css" href="@ViewBag.MyConfig.MyValue/css/vendors/datatable/datatables.min.css" />
-    <link rel="stylesheet" type="text/css" href="@ViewBag.MyConfig.MyValue/css/vendors/daterangepicker.css">
-    <link rel="stylesheet" type="text/css" href="@ViewBag.MyConfig.MyValue/css/vendors/bootstrap-datetimepicker.css">
-    <link rel="stylesheet" type="text/css" href="@ViewBag.MyConfig.MyValue/css/vendors/pickadate.css">
-    <link rel="stylesheet" type="text/css" href="@ViewBag.MyConfig.MyValue/css/daterange.min.css">
-    <link rel="stylesheet" type="text/css" href="@ViewBag.MyConfig.MyValue/css/vendors/climacons.min.css">
-    <link rel="stylesheet" type="text/css" href="@ViewBag.MyConfig.MyValue/css/fonts/meteocons-style.min.css">
-    <link rel="stylesheet" type="text/css" href="@ViewBag.MyConfig.MyValue/css/vendors/morris.css">
-    <link rel="stylesheet" type="text/css" href="@ViewBag.MyConfig.MyValue/css/bootstrap.min.css">
-    <link rel="stylesheet" type="text/css" href="@ViewBag.MyConfig.MyValue/css/bootstrap-extended.min.css">
-    <link rel="stylesheet" type="text/css" href="@ViewBag.MyConfig.MyValue/css/colors.min.css">
-    <link rel="stylesheet" type="text/css" href="@ViewBag.MyConfig.MyValue/css/components.min.css">
-    <link rel="stylesheet" type="text/css" href="@ViewBag.MyConfig.MyValue/css/horizontal-menu.min.css">
-    <link rel="stylesheet" type="text/css" href="@ViewBag.MyConfig.MyValue/css/palette-gradient.min.css">
-    <link rel="stylesheet" type="text/css" href="@ViewBag.MyConfig.MyValue/css/fonts/simple-line-icons-style.min.css">
-    <link rel="stylesheet" type="text/css" href="@ViewBag.MyConfig.MyValue/css/timeline.min.css">
-    <link rel="stylesheet" type="text/css" href="@ViewBag.MyConfig.MyValue/css/vendors/sweetalert.css">
-    <link rel="stylesheet" type="text/css" href="@ViewBag.MyConfig.MyValue/css/spin.css">
-    <link rel="stylesheet" type="text/css" href="@ViewBag.MyConfig.MyValue/css/main.css">
-    <link rel="stylesheet" type="text/css" href="@ViewBag.MyConfig.MyValue/css/model.css">
-    <link rel="stylesheet" type="text/css" href="@ViewBag.MyConfig.MyValue/css/style.css">
-    <link rel="stylesheet" type="text/css" href="@ViewBag.MyConfig.MyValue/css/tree.css">
+  
+    <link rel="stylesheet" type="text/css" href="@ViewBag.MyConfig.MyValue/css/login.css">
+
     <!-- END: Custom CSS-->
 
 </head>

+ 95 - 88
SuperAdmin/SuperAdmin/appsettings.json

@@ -13,100 +13,107 @@
   "PARENT_ID": "100207",
   "CountryCode": "509",
 
-  "usersadminlogin": "http://27.71.225.61:8300/api/balance/usersAdminLogin/data",
-  "wsCamGetList": "http://27.71.225.61:8300/api/balance/camGetList/data",
-  "wsCamUpdate": "http://27.71.225.61:8300/api/balance/camUpdate/data",
-  "wsCamInsert": "http://27.71.225.61:8300/api/balance/camInsert/data",
-  "wsTransferSearch": " http://27.71.225.61:8300/api/balance/getListConvertByUser/data",
-  "wsMsisdnExport": " http://27.71.225.61:8300/api/balance/rpSearchDetailTicketUniqueMsisdn/data",
-  "urlTermresult": " http://27.71.225.61:8300/api/luckyGame/getResultOfTerm/data",
-  "wsLkpwResultUpdate": "http://27.71.225.61:8300/api/balance/updateResultManua/data",
+  //"usersadminlogin": "http://127.0.0.1:8989/api/balance/usersAdminLogin/data",
+  "usersadminlogin": "http://127.0.0.1:8989/api/balance/usersAdminLogin/data",
+  "wsCamGetList": "http://127.0.0.1:8989/api/balance/camGetList/data",
+  "wsCamUpdate": "http://127.0.0.1:8989/api/balance/camUpdate/data",
+  "wsCamInsert": "http://127.0.0.1:8989/api/balance/camInsert/data",
+  "wsTransferSearch": " http://127.0.0.1:8989/api/balance/getListConvertByUser/data",
+  "wsMsisdnExport": " http://127.0.0.1:8989/api/balance/rpSearchDetailTicketUniqueMsisdn/data",
+  "urlTermresult": " http://127.0.0.1:8989/api/luckyGame/getResultOfTerm/data",
+  "wsLkpwResultUpdate": "http://127.0.0.1:8989/api/balance/updateResultManua/data",
   // Service
-  "wsCamSvGetList": "http://27.71.225.61:8300/api/balance/camAddGetList/data",
-  "wsCamAddInsert": "http://27.71.225.61:8300/api/balance/camAddInsert/data",
-  "wsCamSvRemove": "http://27.71.225.61:8300/api/balance/camAddUpdate/data",
-  "wsSvGetList": "http://27.71.225.61:8300/api/balance/svGetList/data",
-  "wsSvInsert": "http://27.71.225.61:8300/api/balance/svInsert/data",
-  "wsSvUpdate": "http://27.71.225.61:8300/api/balance/svUpdate/data",
-  "wsMsisdnSearch": "http://27.71.225.61:8300/api/balance/blacklistGetList/data",
-  "wsMsisdnAddUpdate": "http://27.71.225.61:8300/api/balance/blacklistInsertData/data",
+  "wsCamSvGetList": "http://127.0.0.1:8989/api/balance/camAddGetList/data",
+  "wsCamAddInsert": "http://127.0.0.1:8989/api/balance/camAddInsert/data",
+  "wsCamSvRemove": "http://127.0.0.1:8989/api/balance/camAddUpdate/data",
+  "svGroupGetList": "http://127.0.0.1:8989/api/balance/svGroupGetList/data",
+  "wsSvGetList": "http://127.0.0.1:8989/api/balance/svGetList/data",
+  "wsSvInsert": "http://127.0.0.1:8989/api/balance/svInsert/data",
+  "wsSvUpdate": "http://127.0.0.1:8989/api/balance/svUpdate/data",
+  "wsMsisdnSearch": "http://127.0.0.1:8989/api/balance/blacklistGetList/data",
+  "wsMsisdnAddUpdate": "http://127.0.0.1:8989/api/balance/blacklistInsertData/data",
+
+  "apiServiceLoad": "http://127.0.0.1:8989/api/balance/apiServiceLoad/data",
+  "apiServiceInsert": "http://127.0.0.1:8989/api/balance/apiServiceInsertOrUpdate/data",
+  "apiServiceUpdate": "http://127.0.0.1:8989/api/balance/apiServiceInsertOrUpdate/data",
+
   // param
-  "wsParamGetList": "http://27.71.225.61:8300/api/balance/paramGetList/data",
-  "wsParamUpdate": "http://27.71.225.61:8300/api/balance/paramUpdate/data",
-  "wsParamReload": "http://27.71.225.61:8300/api/balance/reload/data",
+  "wsParamGetList": "http://127.0.0.1:8989/api/balance/paramGetList/data",
+  "wsParamUpdate": "http://127.0.0.1:8989/api/balance/paramUpdate/data",
+  "wsParamReload": "http://127.0.0.1:8989/api/balance/reload/data",
   // calendar
-  "wsCalendarGetList": "http://27.71.225.61:8300/api/balance/calendarGetList/data",
+  "wsCalendarGetList": "http://127.0.0.1:8989/api/balance/calendarGetList/data",
   // under
-  "wsSvUnderGetList": "http://27.71.225.61:8300/api/balance/ngamGetList/data",
-  "wsSvUnderInsert": "http://27.71.225.61:8300/api/balance/ngamInsert/data",
-  "wsSvUnderUpdate": "http://27.71.225.61:8300/api/balance/gamUpdate/data",
+  "wsSvUnderGetList": "http://127.0.0.1:8989/api/balance/ngamGetList/data",
+  "wsSvUnderInsert": "http://127.0.0.1:8989/api/balance/ngamInsert/data",
+  "wsSvUnderUpdate": "http://127.0.0.1:8989/api/balance/gamUpdate/data",
   // report
-  "wsReportByCampaign": "http://27.71.225.61:8300/api/balance/reportByCampaign/data",
+  "wsReportByCampaign": "http://127.0.0.1:8989/api/balance/reportByCampaign/data",
   //criteria
-  "balanceGetList": "http://27.71.225.61:8300/api/balance/balanceGetList/data",
-  "balanceInsert": "http://27.71.225.61:8300/api/balance/balanceInsert/data",
-  "balanceUpdate": "http://27.71.225.61:8300/api/balance/balanceUpdate/data",
-  "expGetList": "http://27.71.225.61:8300/api/balance/expGetList/data",
-  "expInsert": "http://27.71.225.61:8300/api/balance/expInsert/data",
-  "expUpdate": "http://27.71.225.61:8300/api/balance/expUpdate/data",
-  "shortCodeGetList": "http://27.71.225.61:8300/api/balance/shortCodeGetList/data",
-  "camBalanceInsert": "http://27.71.225.61:8300/api/balance/camBalanceInsert/data",
-  "camBalanceUpdate": "http://27.71.225.61:8300/api/balance/camBalanceUpdate/data",
-  "camExpireInsert": "http://27.71.225.61:8300/api/balance/camExpireInsert/data",
-  "camExpireUpdate": "http://27.71.225.61:8300/api/balance/camExpireUpdate/data",
-  "camShortCodeInsert": "http://27.71.225.61:8300/api/balance/camShortCodeInsert/data",
-  "camShortCodeUpdate": "http://27.71.225.61:8300/api/balance/camShortCodeUpdate/data",
-  "camSubInsert": "http://27.71.225.61:8300/api/balance/camSubInsert/data",
-  "camSubUpdate": "http://27.71.225.61:8300/api/balance/camSubUpdate/data",
-  "camCopy": "http://27.71.225.61:8300/api/balance/camCopy/data",
+  "balanceGetList": "http://127.0.0.1:8989/api/balance/balanceGetList/data",
+  "balanceInsert": "http://127.0.0.1:8989/api/balance/balanceInsert/data",
+  "balanceUpdate": "http://127.0.0.1:8989/api/balance/balanceUpdate/data",
+  "expGetList": "http://127.0.0.1:8989/api/balance/expGetList/data",
+  "expInsert": "http://127.0.0.1:8989/api/balance/expInsert/data",
+  "expUpdate": "http://127.0.0.1:8989/api/balance/expUpdate/data",
+  "shortCodeGetList": "http://127.0.0.1:8989/api/balance/shortCodeGetList/data",
+  "camBalanceInsert": "http://127.0.0.1:8989/api/balance/camBalanceInsert/data",
+  "camBalanceUpdate": "http://127.0.0.1:8989/api/balance/camBalanceUpdate/data",
+  "camExpireInsert": "http://127.0.0.1:8989/api/balance/camExpireInsert/data",
+  "camExpireUpdate": "http://127.0.0.1:8989/api/balance/camExpireUpdate/data",
+  "camShortCodeInsert": "http://127.0.0.1:8989/api/balance/camShortCodeInsert/data",
+  "camShortCodeUpdate": "http://127.0.0.1:8989/api/balance/camShortCodeUpdate/data",
+  "camSubInsert": "http://127.0.0.1:8989/api/balance/camSubInsert/data",
+  "camSubUpdate": "http://127.0.0.1:8989/api/balance/camSubUpdate/data",
+  "camCopy": "http://127.0.0.1:8989/api/balance/camCopy/data",
   // list sub
-  "listSubGetList": "http://27.71.225.61:8300/api/balance/listSubGetList/data",
-  "listSubInsert": "http://27.71.225.61:8300/api/balance/listSubInsert/data",
-  "listSubUpdate": "http://27.71.225.61:8300/api/balance/listSubUpdate/data",
-  "listSubFileGetList": "http://27.71.225.61:8300/api/balance/listSubFileGetList/data",
-  "listSubFileInsert": "http://27.71.225.61:8300/api/balance/listSubFileInsert/data",
-  "listSubFileUpdate": "http://27.71.225.61:8300/api/balance/listSubFileUpdate/data",
-  "changeStatus": "http://27.71.225.61:8300/api/balance/changeStatus/data",
+  "listSubGetList": "http://127.0.0.1:8989/api/balance/listSubGetList/data",
+  "listSubInsert": "http://127.0.0.1:8989/api/balance/listSubInsert/data",
+  "listSubUpdate": "http://127.0.0.1:8989/api/balance/listSubUpdate/data",
+  "listSubFileGetList": "http://127.0.0.1:8989/api/balance/listSubFileGetList/data",
+  "listSubFileInsert": "http://127.0.0.1:8989/api/balance/listSubFileInsert/data",
+  "listSubFileUpdate": "http://127.0.0.1:8989/api/balance/listSubFileUpdate/data",
+  "changeStatus": "http://127.0.0.1:8989/api/balance/changeStatus/data",
 
   // real server
   "service_id": 1,
-  "newsGetById": "http://27.71.225.61:8300/api/newsWeb/newsGetById/data",
-  "newsGetByParentId": "http://27.71.225.61:8300/api/newsWeb/newsGetByParentId/data",
-  "newsInsert": "http://27.71.225.61:8300/api/newsWeb/newsInsert/data",
-  "newsUpdate": "http://27.71.225.61:8300/api/newsWeb/newsUpdate/data",
-  "usersGetProvice": "http://27.71.225.61:8300/api/userApi/usersGetProvice/data",
-  "usersGetTopic": "http://27.71.225.61:8300/api/userApi/usersGetTopic/data",
+  "newsGetById": "http://127.0.0.1:8989/api/newsWeb/newsGetById/data",
+  "newsGetByParentId": "http://127.0.0.1:8989/api/newsWeb/newsGetByParentId/data",
+  "newsInsert": "http://127.0.0.1:8989/api/newsWeb/newsInsert/data",
+  "newsUpdate": "http://127.0.0.1:8989/api/newsWeb/newsUpdate/data",
+  "usersGetProvice": "http://127.0.0.1:8989/api/userApi/usersGetProvice/data",
+  "usersGetTopic": "http://127.0.0.1:8989/api/userApi/usersGetTopic/data",
 
   // lumiloto
-  "wsGetTermList": "http://27.71.225.61:8300/api/luckyGameCms/getTermList/data",
-  "wsLkpwResultGetHis": "http://27.71.225.61:8300/api/luckyGameCms/lkpwResultGetHis/data",
-  "wsExportCreated": "http://27.71.225.61:8300/api/luckyGameCms/exportCreated/data",
-  "wsExportAction": "http://27.71.225.61:8300/api/luckyGameCms/exportAction/data",
-  "wsExportWinnerGetData": "http://27.71.225.61:8300/api/luckyGameCms/exportWinnerGetData/data",
-  "wsExportWinnerGetDataById": "http://27.71.225.61:8300/api/luckyGameCms/exportWinnerGetDataById/data",
-  "wsExportGetHis": "http://27.71.225.61:8300/api/luckyGameCms/exportGetHis/data",
-  "wsExportGetList": "http://27.71.225.61:8300/api/luckyGameCms/exportGetList/data",
-  "wsExportInsertData": "http://27.71.225.61:8300/api/luckyGameCms/exportInsertData/data",
-  "wsBlackInsertData": "http://27.71.225.61:8300/api/luckyGameCms/blackInsertData/data",
-  "wsBackListGetList": "http://27.71.225.61:8300/api/luckyGameCms/backListGetList/data",
-  "wsLockUser": "http://27.71.225.61:8300/api/luckyGameCms/cmsLockByMsisdn/data",
-  "wsGetTicketInfo": "http://27.71.225.61:8300/api/luckyGameCms/cmsGetInfoTicket/data",
-  "wsGetTrafficTotal": "http://27.71.225.61:8300/api/luckyGameCms/cmsGetTraficTotal/data",
-  "wsGetTopPlayer": "http://27.71.225.61:8300/api/luckyGameCms/cmsGetTop/data",
-  "wsExecutes": "http://27.71.225.61:8300/api/luckyGame/executes/data",
-  "urlReportByTerm": "http://27.71.225.61:8300/api/luckyGameCms/cmsTotalByTern/data",
-  "urlRevenueTotal": "http://27.71.225.61:8300/api/luckyGameCms/cmsRevenueTotal/data",
-  "urlRevenueDetail": "http://27.71.225.61:8300/api/luckyGameCms/cmsRevenueDetail/data",
-  "urlRewardTotal": "http://27.71.225.61:8300/api/luckyGameCms/cmsPaymentTotal/data",
-  "urlRewardDetail": "http://27.71.225.61:8300/api/luckyGameCms/cmsPaymentDetail/data",
+  "wsGetTermList": "http://127.0.0.1:8989/api/luckyGameCms/getTermList/data",
+  "wsLkpwResultGetHis": "http://127.0.0.1:8989/api/luckyGameCms/lkpwResultGetHis/data",
+  "wsExportCreated": "http://127.0.0.1:8989/api/luckyGameCms/exportCreated/data",
+  "wsExportAction": "http://127.0.0.1:8989/api/luckyGameCms/exportAction/data",
+  "wsExportWinnerGetData": "http://127.0.0.1:8989/api/luckyGameCms/exportWinnerGetData/data",
+  "wsExportWinnerGetDataById": "http://127.0.0.1:8989/api/luckyGameCms/exportWinnerGetDataById/data",
+  "wsExportGetHis": "http://127.0.0.1:8989/api/luckyGameCms/exportGetHis/data",
+  "wsExportGetList": "http://127.0.0.1:8989/api/luckyGameCms/exportGetList/data",
+  "wsExportInsertData": "http://127.0.0.1:8989/api/luckyGameCms/exportInsertData/data",
+  "wsBlackInsertData": "http://127.0.0.1:8989/api/luckyGameCms/blackInsertData/data",
+  "wsBackListGetList": "http://127.0.0.1:8989/api/luckyGameCms/backListGetList/data",
+  "wsLockUser": "http://127.0.0.1:8989/api/luckyGameCms/cmsLockByMsisdn/data",
+  "wsGetTicketInfo": "http://127.0.0.1:8989/api/luckyGameCms/cmsGetInfoTicket/data",
+  "wsGetTrafficTotal": "http://127.0.0.1:8989/api/luckyGameCms/cmsGetTraficTotal/data",
+  "wsGetTopPlayer": "http://127.0.0.1:8989/api/luckyGameCms/cmsGetTop/data",
+  "wsExecutes": "http://127.0.0.1:8989/api/luckyGame/executes/data",
+  "urlReportByTerm": "http://127.0.0.1:8989/api/luckyGameCms/cmsTotalByTern/data",
+  "urlRevenueTotal": "http://127.0.0.1:8989/api/luckyGameCms/cmsRevenueTotal/data",
+  "urlRevenueDetail": "http://127.0.0.1:8989/api/luckyGameCms/cmsRevenueDetail/data",
+  "urlRewardTotal": "http://127.0.0.1:8989/api/luckyGameCms/cmsPaymentTotal/data",
+  "urlRewardDetail": "http://127.0.0.1:8989/api/luckyGameCms/cmsPaymentDetail/data",
 
   //"service_id": 10,
-  //"newsGetById": "http://27.71.225.61:8300/api/enews/GetDataById",
-  //"newsGetByParentId": "http://27.71.225.61:8300/api/enews/GetDataByParentId",
-  //"newsInsert": "http://27.71.225.61:8300/api/enews/DataAdding",
-  //"newsUpdate": "http://27.71.225.61:8300/api/enews/DataEditing",
-  //"newsDelete": "http://27.71.225.61:8300/api/enews/DataDeleting",
-  //"usersadminlogin": "http://27.71.225.61:8300/api/enews/AdminLogin",
+  //"newsGetById": "http://127.0.0.1:8989/api/enews/GetDataById",
+  //"newsGetByParentId": "http://127.0.0.1:8989/api/enews/GetDataByParentId",
+  //"newsInsert": "http://127.0.0.1:8989/api/enews/DataAdding",
+  //"newsUpdate": "http://127.0.0.1:8989/api/enews/DataEditing",
+  //"newsDelete": "http://127.0.0.1:8989/api/enews/DataDeleting",
+  //"usersadminlogin": "http://127.0.0.1:8989/api/enews/AdminLogin",
 
   // test server
   //"service_id": 4,
@@ -120,7 +127,7 @@
 
 
   "serviceName": "Tree",
-  "pathOutside": "D:\\Common\\file_upload",
+  "pathOutside": "D:\\Code\\Telemor\\TimorBplus\\SuperAdmin\\file_upload\\",
   "pathContent": "/outside",
   "Logging": {
     "LogLevel": {
@@ -129,12 +136,12 @@
       "Microsoft.Hosting.Lifetime": "Information"
     }
   },
-  "Kestrel": {
-    "EndPoints": {
-      "Http": {
-        "Url": "http://localhost:8555"
-      }
-    }
-  },
+  //"Kestrel": {
+  //  "EndPoints": {
+  //    "Http": {
+  //      "Url": "http://*:8555"
+  //    }
+  //  }
+  //},
   "AllowedHosts": "*"
 }

+ 266 - 0
SuperAdmin/SuperAdmin/wwwroot/css/login.css

@@ -0,0 +1,266 @@
+body {
+    background: #0a0a0a !important;
+    overflow: hidden;
+}
+
+/* Futuristic Background */
+.login-background {
+    position: fixed;
+    top: 0;
+    left: 0;
+    width: 100%;
+    height: 100%;
+    background: radial-gradient(circle at 20% 50%, rgba(120, 119, 198, 0.3), transparent 50%),
+                radial-gradient(circle at 80% 80%, rgba(255, 119, 198, 0.3), transparent 50%),
+                radial-gradient(circle at 40% 20%, rgba(99, 215, 246, 0.2), transparent 50%);
+    background-size: 200% 200%;
+    animation: gradientShift 15s ease infinite;
+    z-index: 0;
+}
+
+.login-grid {
+    position: fixed;
+    top: 0;
+    left: 0;
+    width: 100%;
+    height: 100%;
+    background-image: 
+        linear-gradient(rgba(255, 255, 255, 0.03) 1px, transparent 1px),
+        linear-gradient(90deg, rgba(255, 255, 255, 0.03) 1px, transparent 1px);
+    background-size: 50px 50px;
+    z-index: 1;
+    pointer-events: none;
+}
+
+.glowing-orb {
+    position: absolute;
+    border-radius: 50%;
+    filter: blur(60px);
+    animation: float 20s ease-in-out infinite;
+    z-index: 1;
+}
+
+.orb-1 {
+    width: 400px;
+    height: 400px;
+    background: rgba(120, 119, 198, 0.4);
+    top: 10%;
+    left: 10%;
+    animation-delay: 0s;
+}
+
+.orb-2 {
+    width: 300px;
+    height: 300px;
+    background: rgba(255, 119, 198, 0.3);
+    top: 60%;
+    right: 15%;
+    animation-delay: 5s;
+}
+
+.orb-3 {
+    width: 350px;
+    height: 350px;
+    background: rgba(99, 215, 246, 0.3);
+    bottom: 10%;
+    left: 50%;
+    animation-delay: 10s;
+}
+
+.login-container {
+    position: relative;
+    display: flex;
+    justify-content: center;
+    align-items: center;
+    min-height: 100vh;
+    z-index: 2;
+    padding: 20px;
+}
+
+.login-form-card {
+    width: 100%;
+    max-width: 450px;
+    background: rgba(15, 23, 42, 0.8);
+    backdrop-filter: blur(20px);
+    border: 1px solid rgba(139, 92, 246, 0.3);
+    border-radius: 20px;
+    box-shadow: 
+        0 20px 60px rgba(0, 0, 0, 0.5),
+        inset 0 1px 0 rgba(255, 255, 255, 0.1);
+    overflow: hidden;
+}
+
+.login-header {
+    text-align: center;
+    padding: 40px 20px 20px;
+}
+
+.logo-circle {
+    width: 80px;
+    height: 80px;
+    margin: 0 auto 20px;
+    background: linear-gradient(135deg, #667eea 0%, #764ba2 100%);
+    border-radius: 50%;
+    display: flex;
+    align-items: center;
+    justify-content: center;
+    box-shadow: 0 10px 30px rgba(102, 126, 234, 0.5);
+    position: relative;
+}
+
+.logo-circle::before {
+    content: '';
+    position: absolute;
+    inset: -2px;
+    border-radius: 50%;
+    background: linear-gradient(45deg, #ff0000, #ff7f00, #ffff00, #00ff00, #0000ff, #4b0082, #8b00ff);
+    background-size: 400%;
+    animation: rainbow 3s ease infinite;
+    z-index: -1;
+}
+
+.login-title {
+    font-size: 28px;
+    font-weight: 800;
+    letter-spacing: 3px;
+    background: linear-gradient(135deg, #ec4899 0%, #8b5cf6 100%);
+    -webkit-background-clip: text;
+    -webkit-text-fill-color: transparent;
+    background-clip: text;
+    margin-bottom: 8px;
+}
+
+.login-subtitle {
+    font-size: 12px;
+    color: rgba(255, 255, 255, 0.6);
+    letter-spacing: 2px;
+    font-weight: 300;
+}
+
+.form-section {
+    padding: 30px 40px 40px;
+}
+
+.input-wrapper {
+    position: relative;
+    margin-bottom: 25px;
+}
+
+.input-enhanced {
+    width: 100%;
+    padding: 15px 15px 15px 50px;
+    background: rgba(30, 41, 59, 0.5);
+    border: 1px solid rgba(139, 92, 246, 0.2);
+    border-radius: 12px;
+    color: #fff;
+    font-size: 14px;
+    transition: all 0.3s ease;
+    font-family: inherit;
+    box-sizing: border-box;
+}
+
+.input-enhanced::placeholder {
+    color: rgba(255, 255, 255, 0.4);
+    text-transform: uppercase;
+    letter-spacing: 1px;
+    font-size: 11px;
+}
+
+.input-enhanced:focus {
+    outline: none;
+    border-color: rgba(139, 92, 246, 0.6);
+    box-shadow: 0 0 0 3px rgba(139, 92, 246, 0.1);
+    background: rgba(30, 41, 59, 0.7);
+}
+
+.input-icon {
+    position: absolute;
+    left: 18px;
+    top: 50%;
+    transform: translateY(-50%);
+    color: rgba(139, 92, 246, 0.7);
+    font-size: 16px;
+    z-index: 1;
+    pointer-events: none;
+}
+
+.input-enhanced:focus ~ .input-icon,
+.input-enhanced:focus + .input-icon {
+    color: #8b5cf6;
+    text-shadow: 0 0 10px rgba(139, 92, 246, 0.5);
+}
+
+.btn-login {
+    width: 100%;
+    padding: 16px;
+    background: linear-gradient(135deg, #8b5cf6 0%, #ec4899 100%);
+    border: none;
+    border-radius: 12px;
+    color: #fff;
+    font-weight: 700;
+    font-size: 14px;
+    letter-spacing: 2px;
+    text-transform: uppercase;
+    cursor: pointer;
+    transition: all 0.3s ease;
+    box-shadow: 0 10px 30px rgba(139, 92, 246, 0.4);
+    position: relative;
+    overflow: hidden;
+}
+
+.btn-login::before {
+    content: '';
+    position: absolute;
+    top: 0;
+    left: -100%;
+    width: 100%;
+    height: 100%;
+    background: linear-gradient(90deg, transparent, rgba(255, 255, 255, 0.3), transparent);
+    transition: left 0.5s;
+}
+
+.btn-login:hover::before {
+    left: 100%;
+}
+
+.btn-login:hover {
+    transform: translateY(-3px);
+    box-shadow: 0 15px 40px rgba(139, 92, 246, 0.6);
+}
+
+.btn-login:active {
+    transform: translateY(-1px);
+}
+
+.error-message {
+    color: #f43f5e;
+    font-size: 12px;
+    text-align: center;
+    margin-top: 10px;
+    min-height: 20px;
+}
+
+@keyframes gradientShift {
+    0%, 100% { background-position: 0% 50%; }
+    50% { background-position: 100% 50%; }
+}
+
+@keyframes float {
+    0%, 100% { transform: translate(0, 0); }
+    33% { transform: translate(30px, -30px); }
+    66% { transform: translate(-20px, 20px); }
+}
+
+@keyframes rainbow {
+    0%, 100% { background-position: 0% 50%; }
+    50% { background-position: 100% 50%; }
+}
+
+.security-note {
+    text-align: center;
+    margin-top: 20px;
+    padding-bottom: 30px;
+    font-size: 11px;
+    color: rgba(255, 255, 255, 0.3);
+    letter-spacing: 1px;
+}

+ 216 - 0
SuperAdmin/SuperAdmin/wwwroot/css/menu-custom.css

@@ -0,0 +1,216 @@
+/* Custom Menu Styles - Dark Theme với gradient purple/pink */
+
+/* Menu Container */
+.navigation-main {
+    background: linear-gradient(135deg, rgba(15, 23, 42, 0.95) 0%, rgba(30, 41, 59, 0.95) 100%);
+    backdrop-filter: blur(10px);
+    border-right: 1px solid rgba(139, 92, 246, 0.2);
+}
+
+/* Menu Items */
+.navigation-main .nav-item {
+    border-bottom: 1px solid rgba(139, 92, 246, 0.1);
+}
+
+.navigation-main .nav-item:last-child {
+    border-bottom: none;
+}
+
+/* Menu Links */
+.navigation-main .nav-link {
+    color: rgba(255, 255, 255, 0.7) !important;
+    padding: 12px 20px;
+    transition: all 0.3s ease;
+    position: relative;
+    overflow: hidden;
+}
+
+.navigation-main .nav-link::before {
+    content: '';
+    position: absolute;
+    left: 0;
+    top: 0;
+    height: 100%;
+    width: 3px;
+    background: linear-gradient(135deg, #8b5cf6 0%, #ec4899 100%);
+    transform: scaleY(0);
+    transition: transform 0.3s ease;
+}
+
+.navigation-main .nav-link:hover {
+    background: rgba(139, 92, 246, 0.15);
+    color: #fff !important;
+    padding-left: 28px;
+}
+
+.navigation-main .nav-link:hover::before {
+    transform: scaleY(1);
+}
+
+.navigation-main .nav-link:hover .menu-title {
+    color: #fff;
+    text-shadow: 0 0 10px rgba(139, 92, 246, 0.5);
+}
+
+/* Active Menu Item */
+.navigation-main .nav-item.active > .nav-link,
+.navigation-main .nav-link.active {
+    background: linear-gradient(90deg, rgba(139, 92, 246, 0.25) 0%, rgba(236, 72, 153, 0.15) 100%);
+    color: #fff !important;
+    padding-left: 28px;
+    border-left: 3px solid;
+    border-image: linear-gradient(135deg, #8b5cf6 0%, #ec4899 100%) 1;
+}
+
+.navigation-main .nav-item.active > .nav-link::before,
+.navigation-main .nav-link.active::before {
+    transform: scaleY(1);
+}
+
+/* Menu Icons */
+.navigation-main .nav-link i {
+    color: rgba(139, 92, 246, 0.8);
+    margin-right: 12px;
+    font-size: 18px;
+    width: 18px; /* reserve space so icons don't collapse */
+    min-width: 18px;
+    line-height: 1;
+    display: inline-block;
+    transition: all 0.3s ease;
+    display: inline-block;
+}
+
+.navigation-main .nav-link:hover i,
+.navigation-main .nav-item.active > .nav-link i,
+.navigation-main .nav-link.active i {
+    color: #8b5cf6 !important;
+    text-shadow: 0 0 15px rgba(139, 92, 246, 0.6);
+    transform: scale(1.1);
+}
+
+/* Menu Title */
+.navigation-main .menu-title {
+    font-size: 14px;
+    font-weight: 500;
+    letter-spacing: 0.5px;
+    transition: all 0.3s ease;
+}
+
+.navigation-main .nav-link:hover .menu-title,
+.navigation-main .nav-item.active > .nav-link .menu-title,
+.navigation-main .nav-link.active .menu-title {
+    background: linear-gradient(135deg, #ec4899 0%, #8b5cf6 100%);
+    -webkit-background-clip: text;
+    -webkit-text-fill-color: transparent;
+    background-clip: text;
+}
+
+/* Sub-menu */
+.navigation-main .menu-content {
+    background: rgba(0, 0, 0, 0.3);
+    border-left: 2px solid rgba(139, 92, 246, 0.3);
+    padding-left: 0;
+}
+
+.navigation-main .menu-item {
+    color: rgba(255, 255, 255, 0.6) !important;
+    padding: 10px 15px 10px 50px;
+    transition: all 0.3s ease;
+}
+
+.navigation-main .menu-item i {
+    margin-right: 8px;
+    font-size: 14px;
+    transition: all 0.3s ease;
+}
+
+.navigation-main .menu-item:hover {
+    background: rgba(139, 92, 246, 0.15);
+    color: #fff !important;
+    padding-left: 55px;
+}
+
+.navigation-main .menu-item:hover i {
+    color: #8b5cf6;
+    text-shadow: 0 0 10px rgba(139, 92, 246, 0.5);
+}
+
+/* Sub-menu Item */
+.navigation-main .menu-content li {
+    border-bottom: 1px solid rgba(139, 92, 246, 0.05);
+}
+
+.navigation-main .menu-content li:last-child {
+    border-bottom: none;
+}
+
+/* Has-sub menu arrow */
+.navigation-main .has-sub > a::after {
+    color: rgba(139, 92, 246, 0.6);
+    transition: all 0.3s ease;
+}
+
+.navigation-main .has-sub:hover > a::after,
+.navigation-main .has-sub.open > a::after {
+    color: #8b5cf6;
+    text-shadow: 0 0 10px rgba(139, 92, 246, 0.5);
+}
+
+/* Scrollbar customization */
+.navigation-main::-webkit-scrollbar {
+    width: 6px;
+}
+
+.navigation-main::-webkit-scrollbar-track {
+    background: rgba(15, 23, 42, 0.5);
+}
+
+.navigation-main::-webkit-scrollbar-thumb {
+    background: linear-gradient(135deg, #8b5cf6 0%, #ec4899 100%);
+    border-radius: 10px;
+}
+
+.navigation-main::-webkit-scrollbar-thumb:hover {
+    background: linear-gradient(135deg, #ec4899 0%, #8b5cf6 100%);
+}
+
+/* Animation for menu items */
+@keyframes menuSlideIn {
+    from {
+        opacity: 0;
+        transform: translateX(-20px);
+    }
+    to {
+        opacity: 1;
+        transform: translateX(0);
+    }
+}
+
+.navigation-main .nav-item {
+    animation: menuSlideIn 0.5s ease forwards;
+}
+
+/* Glass effect */
+.navigation-main {
+    position: relative;
+}
+
+.navigation-main::before {
+    content: '';
+    position: absolute;
+    top: 0;
+    left: 0;
+    right: 0;
+    bottom: 0;
+    background: 
+        radial-gradient(circle at 0% 0%, rgba(139, 92, 246, 0.1), transparent 50%),
+        radial-gradient(circle at 100% 100%, rgba(236, 72, 153, 0.1), transparent 50%);
+    pointer-events: none;
+    z-index: 0;
+}
+
+.navigation-main > * {
+    position: relative;
+    z-index: 1;
+}
+

BIN
TÀI LIỆU NGHIỆP VỤ B+ MYTEL_V2_09102025.docx