Ver Fonte

no message

ducnt há 1 mês atrás
pai
commit
be50a66abc
57 ficheiros alterados com 1889 adições e 1022 exclusões
  1. 1 1
      SicboSub/Common/Common.csproj
  2. 1 1
      SicboSub/Database/Database.csproj
  3. 12 3
      SicboSub/SicboSub.Api/Business/AuthBusinessImpl.cs
  4. 29 5
      SicboSub/SicboSub.Api/Business/ExchangeBusinessImpl.cs
  5. 20 15
      SicboSub/SicboSub.Api/Business/GameBusinessImpl.cs
  6. 1 1
      SicboSub/SicboSub.Api/Connected Services/SicboSubWss/ConnectedService.json
  7. 330 205
      SicboSub/SicboSub.Api/Connected Services/SicboSubWss/Reference.cs
  8. 1 0
      SicboSub/SicboSub.Api/DTO/GameDto.cs
  9. 1 1
      SicboSub/SicboSub.Api/Properties/PublishProfiles/FolderProfile.pubxml
  10. 2 2
      SicboSub/SicboSub.Api/SicboSub.Api.csproj
  11. 1 0
      SicboSub/SicboSub.Api/appsettings.json
  12. 1 1
      SicboSub/SicboSub.StartProcedure/Connected Services/SicboSubWss/ConnectedService.json
  13. 314 314
      SicboSub/SicboSub.StartProcedure/Connected Services/SicboSubWss/Reference.cs
  14. 31 3
      SicboSub/SicboSub.StartProcedure/Program.cs
  15. 1 1
      SicboSub/SicboSub.StartProcedure/Properties/PublishProfiles/FolderProfile.pubxml
  16. 35 12
      SicboSub/SicboSub.StartProcedure/RankingService.cs
  17. 7 4
      SicboSub/SicboSub.StartProcedure/SicboSub.StartProcedure.csproj
  18. 0 32
      SicboSub/SicboSub.StartProcedure/SicboSub.StartProcedure.csproj.Backup.tmp
  19. 68 17
      SicboSub/SicboSub.Web/Controllers/HomeController.cs
  20. 37 1
      SicboSub/SicboSub.Web/Language/Language.Designer.cs
  21. 13 1
      SicboSub/SicboSub.Web/Language/Language.resx
  22. 12 0
      SicboSub/SicboSub.Web/Language/Language.vi.resx
  23. 2 1
      SicboSub/SicboSub.Web/Models/HistoryModels.cs
  24. 1 1
      SicboSub/SicboSub.Web/Properties/PublishProfiles/FolderProfile.pubxml
  25. 1 1
      SicboSub/SicboSub.Web/SicboSub.Web.csproj
  26. 1 1
      SicboSub/SicboSub.Web/Views/Home/Account.cshtml
  27. 143 2
      SicboSub/SicboSub.Web/Views/Home/DailyRanking.cshtml
  28. 1 1
      SicboSub/SicboSub.Web/Views/Home/History.cshtml
  29. 99 37
      SicboSub/SicboSub.Web/Views/Home/Index.cshtml
  30. 118 2
      SicboSub/SicboSub.Web/Views/Home/MonthlyRanking.cshtml
  31. 2 2
      SicboSub/SicboSub.Web/Views/Home/Winner.cshtml
  32. 1 1
      SicboSub/SicboSub.Web/appsettings.json
  33. 275 29
      SicboSub/SicboSub.Web/wwwroot/css/sicbo-popup.css
  34. 161 3
      SicboSub/SicboSub.Web/wwwroot/css/sicbo-ranking.css
  35. BIN
      SicboSub/SicboSub.Web/wwwroot/img/message_error_bg.png
  36. BIN
      SicboSub/SicboSub.Web/wwwroot/img/xucto1.png
  37. BIN
      SicboSub/SicboSub.Web/wwwroot/img/xucto2.png
  38. BIN
      SicboSub/SicboSub.Web/wwwroot/img/xucto3.png
  39. 8 5
      SicboSubWs/SicboSubWs/src/com/vas/webservices/SicboSubWs.java
  40. 0 51
      SicboSubWs/etc/key/MINHA_VIBE_DAY/PrivateKeyCP.pem
  41. 0 14
      SicboSubWs/etc/key/MINHA_VIBE_DAY/PublicKeyCP.pem
  42. 0 14
      SicboSubWs/etc/key/MINHA_VIBE_DAY/PublicKeyVT.pem
  43. 0 51
      SicboSubWs/etc/key/MINHA_VIBE_MINUS/PrivateKeyCP.pem
  44. 0 14
      SicboSubWs/etc/key/MINHA_VIBE_MINUS/PublicKeyCP.pem
  45. 0 14
      SicboSubWs/etc/key/MINHA_VIBE_MINUS/PublicKeyVT.pem
  46. 0 51
      SicboSubWs/etc/key/MINHA_VIBE_MR_DAY/PrivateKeyCP.pem
  47. 0 14
      SicboSubWs/etc/key/MINHA_VIBE_MR_DAY/PublicKeyCP.pem
  48. 0 14
      SicboSubWs/etc/key/MINHA_VIBE_MR_DAY/PublicKeyVT.pem
  49. 0 51
      SicboSubWs/etc/key/MINHA_VIBE_WIN/PrivateKeyCP.pem
  50. 0 14
      SicboSubWs/etc/key/MINHA_VIBE_WIN/PublicKeyCP.pem
  51. 0 14
      SicboSubWs/etc/key/MINHA_VIBE_WIN/PublicKeyVT.pem
  52. 51 0
      SicboSubWs/etc/key/SICBO_DAILY/PrivateKeyCP.pem
  53. 14 0
      SicboSubWs/etc/key/SICBO_DAILY/PublicKeyCP.pem
  54. 14 0
      SicboSubWs/etc/key/SICBO_DAILY/PublicKeyVT.pem
  55. 51 0
      SicboSubWs/etc/key/SICBO_OTHER/PrivateKeyCP.pem
  56. 14 0
      SicboSubWs/etc/key/SICBO_OTHER/PublicKeyCP.pem
  57. 14 0
      SicboSubWs/etc/key/SICBO_OTHER/PublicKeyVT.pem

+ 1 - 1
SicboSub/Common/Common.csproj

@@ -1,7 +1,7 @@
 <Project Sdk="Microsoft.NET.Sdk">
 
   <PropertyGroup>
-    <TargetFramework>net8.0</TargetFramework>
+    <TargetFramework>net7.0</TargetFramework>
     <ImplicitUsings>enable</ImplicitUsings>
     <Nullable>enable</Nullable>
   </PropertyGroup>

+ 1 - 1
SicboSub/Database/Database.csproj

@@ -1,7 +1,7 @@
 <Project Sdk="Microsoft.NET.Sdk">
 
   <PropertyGroup>
-    <TargetFramework>net8.0</TargetFramework>
+    <TargetFramework>net7.0</TargetFramework>
     <ImplicitUsings>enable</ImplicitUsings>
     <Nullable>enable</Nullable>
   </PropertyGroup>

+ 12 - 3
SicboSub/SicboSub.Api/Business/AuthBusinessImpl.cs

@@ -35,14 +35,22 @@ namespace SicboSub.Api.Business
         private readonly ModelContext dbContext;
         private readonly IAuthService authService;
         private readonly IConfiguration configuration;
-
+        string wsUser;
+        string wsPass;
+        string packageDaily;
         public AuthBusinessImpl(ModelContext _dbContext, IAuthService _authService, IConfiguration _configuration)
         {
             dbContext = _dbContext;
             authService = _authService;
             configuration = _configuration;
+            wsUser = GetParameter("wsUser");
+            wsPass = GetParameter("wsPass");
+            packageDaily = GetParameter("PackageCodeDaily");
+        }
+        private string GetParameter(string key)
+        {
+            return configuration.GetSection(key).Value ?? "";
         }
-
         /// <summary>
         /// Đăng nhập bằng token từ URL
         /// Flow: 
@@ -103,7 +111,8 @@ namespace SicboSub.Api.Business
                 bool isRegistered = false;
                 RegInfoDto? regPkg = null;
                 
-                string productCode = "SICBO_DAY"; // Default
+                string productCode = packageDaily;
+                ; // Default
                 // Try to get from config if available (assuming ConfigManager has it, or just use default)
                 // var cfgCode = ConfigManager.Instance.GetConfigWebValue("PackageCodeDaily");
                 // if(!string.IsNullOrEmpty(cfgCode)) productCode = cfgCode;

+ 29 - 5
SicboSub/SicboSub.Api/Business/ExchangeBusinessImpl.cs

@@ -141,18 +141,41 @@ namespace SicboSub.Api.Business
                     );
                 }
 
-                // CHECK: Max withdrawal < 100 HTG/day
-                var totalWithdrawnToday = await dbContext.ExchangeHistories.AsNoTracking()
+                // Get dynamic limits from config
+                string limitUserStr = ConfigManager.Instance.GetConfigWebValue("EXCHANGE_USER_DAILY_LIMIT") ?? "100";
+                string limitSystemStr = ConfigManager.Instance.GetConfigWebValue("EXCHANGE_SYSTEM_DAILY_LIMIT") ?? "1000";
+                
+                decimal limitUser = decimal.TryParse(limitUserStr, out decimal parsedLimitUser) ? parsedLimitUser : 100;
+                decimal limitSystem = decimal.TryParse(limitSystemStr, out decimal parsedLimitSystem) ? parsedLimitSystem : 1000;
+
+                // CHECK 1: Max withdrawal < limitUser HTG/day per user
+                var totalWithdrawnTodayUser = await dbContext.ExchangeHistories.AsNoTracking()
                     .Where(h => h.Msisdn == request.msisdn && h.ExchangeTime >= today && h.Status >= 0)
                     .SumAsync(h => h.MoneyAdded ?? 0);
 
-                if (totalWithdrawnToday + (exchangeConfig.MoneyReceived ?? 0) >= 100)
+                if (totalWithdrawnTodayUser + (exchangeConfig.MoneyReceived ?? 0) > limitUser)
                 {
                     return DotnetLib.Http.HttpResponse.BuildResponse(
                         log, url, json,
                         CommonErrorCode.LimitExceeded, 
                         ConfigManager.Instance.GetConfigWebValue("EXCHANGE_DAILY_LIMIT_EXCEEDED", lang),
-                        new { currentDailyTotal = totalWithdrawnToday, limit = 100 }
+                        new { currentDailyTotal = totalWithdrawnTodayUser, limit = limitUser }
+                    );
+                }
+
+                // CHECK 2: Max withdrawal < limitSystem HTG/day for ALL users (System Limit)
+                var totalWithdrawnTodaySystem = await dbContext.ExchangeHistories.AsNoTracking()
+                    .Where(h => h.ExchangeTime >= today && h.Status >= 0)
+                    .SumAsync(h => h.MoneyAdded ?? 0);
+
+                if (totalWithdrawnTodaySystem + (exchangeConfig.MoneyReceived ?? 0) > limitSystem)
+                {
+                    log.Warn($"System Daily Exchange Limit Reached: {totalWithdrawnTodaySystem} + {exchangeConfig.MoneyReceived} > {limitSystem}");
+                    return DotnetLib.Http.HttpResponse.BuildResponse(
+                        log, url, json,
+                        CommonErrorCode.LimitExceeded,
+                        ConfigManager.Instance.GetConfigWebValue("EXCHANGE_SYSTEM_LIMIT_EXCEEDED", lang), // Add this key to config or generic msg
+                        new { limit = limitSystem }
                     );
                 }
 
@@ -167,7 +190,8 @@ namespace SicboSub.Api.Business
                 }
 
                 // 9. Generate new OTP
-                string otpCode = GenerateOtpCode();
+                //string otpCode = GenerateOtpCode();
+                string otpCode = "111111";
                 var now = DateTime.Now;
                 var expiredTime = now.AddMinutes(OTP_EXPIRE_MINUTES);
 

+ 20 - 15
SicboSub/SicboSub.Api/Business/GameBusinessImpl.cs

@@ -281,15 +281,19 @@ namespace SicboSub.Api.Business
                     );
                 }
 
-                // Query REGINFO
-                var query = dbContext.RegInfos.AsNoTracking()
-                    .Where(r => r.Msisdn == request.msisdn);
+                // Query REGINFO with LEFT JOIN to PACKG to get Fee
+                var query = from r in dbContext.RegInfos.AsNoTracking()
+                            join p in dbContext.Packgs.AsNoTracking() 
+                                on r.ProductName equals p.ProductName into packageGroup
+                            from pkg in packageGroup.DefaultIfEmpty()
+                            where r.Msisdn == request.msisdn
+                            select new { r, Fee = pkg.Fee }; 
                 
                 if (!string.IsNullOrEmpty(request.fromDate))
                 {
                     if (DateTime.TryParseExact(request.fromDate, "dd/MM/yyyy HH:mm:ss", null, System.Globalization.DateTimeStyles.None, out DateTime from))
                     {
-                        query = query.Where(r => r.RegisterTime >= from);
+                        query = query.Where(x => x.r.RegisterTime >= from);
                     }
                 }
 
@@ -297,7 +301,7 @@ namespace SicboSub.Api.Business
                 {
                     if (DateTime.TryParseExact(request.toDate, "dd/MM/yyyy HH:mm:ss", null, System.Globalization.DateTimeStyles.None, out DateTime to))
                     {
-                        query = query.Where(r => r.RegisterTime <= to);
+                        query = query.Where(x => x.r.RegisterTime <= to);
                     }
                 }
 
@@ -305,19 +309,20 @@ namespace SicboSub.Api.Business
                 int totalPages = (int)Math.Ceiling((double)totalCount / pageSize);
 
                 var items = await query
-                    .OrderByDescending(r => r.RegisterTime)
+                    .OrderByDescending(x => x.r.RegisterTime)
                     .Skip(pageNumber * pageSize)
                     .Take(pageSize)
-                    .Select(r => new PurchaseHistoryItem
+                    .Select(x => new PurchaseHistoryItem
                     {
-                        id = r.RegisterId,
-                        productName = r.ProductName ?? "",
-                        registerTime = r.RegisterTime ?? DateTime.MinValue,
-                        expireTime = r.ExpireTime ?? DateTime.MinValue,
-                        serviceId = r.ServiceId ?? 0, // Using ServiceId column which seems to store Fee based on model (NUMBER(10,2))
-                        channel = r.Channel ?? "",
-                        status = r.Status ,
-                        renew = r.Renew ?? 0
+                        id = x.r.RegisterId,
+                        productName = x.r.ProductName ?? "",
+                        registerTime = x.r.RegisterTime ?? DateTime.MinValue,
+                        expireTime = x.r.ExpireTime ?? DateTime.MinValue,
+                        serviceId = x.r.ServiceId ?? 0,
+                        channel = x.r.Channel ?? "",
+                        status = x.r.Status,
+                        renew = x.r.Renew ?? 0,
+                        fee = (int)(x.Fee ?? 0) // Fee from Packg table
                     })
                     .ToListAsync();
                 

+ 1 - 1
SicboSub/SicboSub.Api/Connected Services/SicboSubWss/ConnectedService.json

@@ -10,7 +10,7 @@
     "namespaceMappings": [
       "*, SicboSubWss"
     ],
-    "targetFramework": "net8.0",
+    "targetFramework": "net7.0",
     "typeReuseMode": "All"
   }
 }

Diff do ficheiro suprimidas por serem muito extensas
+ 330 - 205
SicboSub/SicboSub.Api/Connected Services/SicboSubWss/Reference.cs


+ 1 - 0
SicboSub/SicboSub.Api/DTO/GameDto.cs

@@ -96,6 +96,7 @@ namespace SicboSub.Api.DTO
         public string channel { get; set; } = null!;
         public byte status { get; set; }
         public int renew { get; set; }
+        public int fee { get; set; }
     }
 
     /// <summary>

+ 1 - 1
SicboSub/SicboSub.Api/Properties/PublishProfiles/FolderProfile.pubxml

@@ -8,7 +8,7 @@
     <LastUsedBuildConfiguration>Release</LastUsedBuildConfiguration>
     <LastUsedPlatform>Any CPU</LastUsedPlatform>
     <PublishProvider>FileSystem</PublishProvider>
-    <PublishUrl>D:\Code\Ex_publish\Natcom_SicboSub\apis</PublishUrl>
+    <PublishUrl>E:\Ex_publish\Natcom_SicboSub\apis</PublishUrl>
     <WebPublishMethod>FileSystem</WebPublishMethod>
     <_TargetId>Folder</_TargetId>
     <SiteUrlToLaunchAfterPublish />

+ 2 - 2
SicboSub/SicboSub.Api/SicboSub.Api.csproj

@@ -13,7 +13,7 @@
     <PackageReference Include="Microsoft.AspNetCore.OpenApi" Version="7.0.7" />
     <PackageReference Include="Microsoft.Data.SqlClient" Version="5.2.2" />
     <PackageReference Include="Swashbuckle.AspNetCore" Version="6.5.0" />
-    <PackageReference Include="System.IdentityModel.Tokens.Jwt" Version="8.0.1" />
+    <PackageReference Include="System.IdentityModel.Tokens.Jwt" Version="7.5.0" />
     <PackageReference Include="System.ServiceModel.Security" Version="6.0.0" />
     <PackageReference Include="System.ServiceModel.Duplex" Version="6.0.0" />
     <PackageReference Include="System.ServiceModel.NetTcp" Version="6.0.0" />
@@ -36,6 +36,6 @@
     </Reference>
   </ItemGroup>
   <ItemGroup>
-    <PackageReference Include="System.ServiceModel.Primitives" Version="8.*" />
+    <PackageReference Include="System.ServiceModel.Primitives" Version="6.*" />
   </ItemGroup>
 </Project>

+ 1 - 0
SicboSub/SicboSub.Api/appsettings.json

@@ -3,6 +3,7 @@
   "wsUrl": "http://127.0.0.1:8199/SicboSubWs?wsdl",
   "wsUser": "sicboSub",
   "wsPass": "123456a@",
+  "PackageCodeDaily": "SICBO_DAILY",
   "Kestrel": {
     "EndPoints": {
       "Http": {

+ 1 - 1
SicboSub/SicboSub.StartProcedure/Connected Services/SicboSubWss/ConnectedService.json

@@ -10,7 +10,7 @@
     "namespaceMappings": [
       "*, SicboSubWss"
     ],
-    "targetFramework": "net8.0",
+    "targetFramework": "net7.0",
     "typeReuseMode": "All"
   }
 }

Diff do ficheiro suprimidas por serem muito extensas
+ 314 - 314
SicboSub/SicboSub.StartProcedure/Connected Services/SicboSubWss/Reference.cs


+ 31 - 3
SicboSub/SicboSub.StartProcedure/Program.cs

@@ -50,7 +50,9 @@ namespace SicboSub.StartProcedure
             //   SicboSub.StartProcedure.exe monthly
             //   SicboSub.StartProcedure.exe 2025-01-18 daily
 
-            DateTime targetDate = DateTime.Now.AddDays(-1); // Mặc định: Ngày hôm qua
+            // 2. Phân tích tham số đầu vào
+            bool isDynamicDate = true;
+            DateTime targetDate = DateTime.Now.AddDays(-1); 
             string mode = "DAILY";
 
             if (args.Length > 0)
@@ -58,7 +60,11 @@ namespace SicboSub.StartProcedure
                 if (args[0].ToUpper() == "DAILY") mode = "DAILY";
                 else if (args[0].ToUpper() == "MONTHLY") mode = "MONTHLY";
                 else if (args[0].ToUpper() == "EXCHANGE") mode = "EXCHANGE";
-                else if (DateTime.TryParse(args[0], out DateTime parsedDate)) targetDate = parsedDate;
+                else if (DateTime.TryParse(args[0], out DateTime parsedDate)) 
+                {
+                    targetDate = parsedDate;
+                    isDynamicDate = false;
+                }
 
                 if (args.Length > 1)
                 {
@@ -69,7 +75,8 @@ namespace SicboSub.StartProcedure
             }
 
             log.Info($"Chế độ chạy: {mode}");
-            log.Info($"Ngày mục tiêu: {targetDate:yyyy-MM-dd}");
+            if (!isDynamicDate) log.Info($"Ngày mục tiêu (Fixed): {targetDate:yyyy-MM-dd}");
+            else log.Info($"Ngày mục tiêu (Dynamic): {targetDate:yyyy-MM-dd} (Yesterday)");
 
             // 3. Thực thi
             log.Info("Press Ctrl+C to stop...");
@@ -83,14 +90,35 @@ namespace SicboSub.StartProcedure
                 log.Info("Stop request received...");
             };
 
+            int lastMonthlyRunDay = -1;
+
             while (!cts.Token.IsCancellationRequested)
             {
+                // Update dynamic date
+                if (isDynamicDate) targetDate = DateTime.Now.AddDays(-1);
+
                 try 
                 {
                     // 3. Thực thi
                     if (mode == "DAILY")
                     {
                         await service.ExecuteDailyRankingAsync(targetDate);
+
+                        // AUTO MONTHLY TRIGGER (Only in Dynamic Mode)
+                        // Nếu là ngày mùng 1, tự động chạy thêm Monthly cho ngày hôm qua (tức là cuối tháng trước)
+                        if (isDynamicDate && DateTime.Now.Day == 1)
+                        {
+                            if (lastMonthlyRunDay != DateTime.Now.Day)
+                            {
+                                log.Info("[AUTO] Phát hiện ngày mùng 1 -> Kích hoạt chạy BXH Tháng (Monthly Ranking)...");
+                                await service.ExecuteMonthlyRankingAsync(targetDate);
+                                lastMonthlyRunDay = DateTime.Now.Day;
+                            }
+                        }
+                        else
+                        {
+                             if (DateTime.Now.Day != 1) lastMonthlyRunDay = -1;
+                        }
                     }
                     else if (mode == "MONTHLY")
                     {

+ 1 - 1
SicboSub/SicboSub.StartProcedure/Properties/PublishProfiles/FolderProfile.pubxml

@@ -4,7 +4,7 @@
   <PropertyGroup>
     <Configuration>Release</Configuration>
     <Platform>Any CPU</Platform>
-    <PublishDir>D:\Code\Ex_publish\Natcom_SicboSub\procedure</PublishDir>
+    <PublishDir>E:\Ex_publish\Natcom_SicboSub\procedure</PublishDir>
     <PublishProtocol>FileSystem</PublishProtocol>
     <_TargetId>Folder</_TargetId>
     <TargetFramework>net8.0</TargetFramework>

+ 35 - 12
SicboSub/SicboSub.StartProcedure/RankingService.cs

@@ -55,21 +55,34 @@ namespace SicboSub.StartProcedure
 
                 try
                 {
-                    // 1. Gọi Procedure: Sinh ra dữ liệu SNAPSHOT (Nếu đã chạy Success thì nó sẽ skip)
-                    var p = new DynamicParameters();
-                    p.Add("p_report_date", reportDate, DbType.Date, ParameterDirection.Input);
-                    p.Add("p_type", type, DbType.String, ParameterDirection.Input);
+                    // 1. KIỂM TRA ĐÃ CHẠY CHƯA (Tránh chạy lại Procedure nhiều lần nếu restart app)
+                    string sqlCheck = "SELECT COUNT(1) FROM RANKING_HISTORY WHERE RANK_TYPE = :type AND TRUNC(RANK_DATE) = TRUNC(:rDate)";
+                    int count = await conn.ExecuteScalarAsync<int>(sqlCheck, new { type = type, rDate = reportDate });
 
-                    await conn.ExecuteAsync("PRC_CALCULATE_RANKING", p, commandType: CommandType.StoredProcedure);
-                    log.Info(" -> Kiểm tra/Chạy Procedure hoàn tất.");
+                    if (count > 0)
+                    {
+                        log.Info($" -> Đã có dữ liệu BXH {type} cho ngày {reportDate:yyyy-MM-dd}. Bỏ qua bước tính toán (Procedure).");
+                    }
+                    else
+                    {
+                        var p = new DynamicParameters();
+                        p.Add("p_report_date", reportDate, DbType.Date, ParameterDirection.Input);
+                        p.Add("p_type", type, DbType.String, ParameterDirection.Input);
+
+                        await conn.ExecuteAsync("PRC_CALCULATE_RANKING", p, commandType: CommandType.StoredProcedure);
+                        log.Info(" -> Tính toán BXH (Procedure) hoàn tất.");
+                    }
 
                     // 2. QUÉT ALL PENDING (Kể cả những cái bị treo từ lần chạy cũ bị crash)
                     // Không chỉ lấy của ngày hôm nay mà lấy tất cả status=0 để xử lý triệt để
+                    // Join voi RANKING_HISTORY de lay thong tin RankType va Position
                     string sqlGetPending = @"
-                        SELECT ID, MSISDN, REWARD_VALUE, REWARD_UNIT, NOTE 
-                        FROM RANKING_REWARD_LOG 
-                        WHERE STATUS = 0
-                        ORDER BY ID ASC"; // FIFO
+                        SELECT t1.ID, t1.MSISDN, t1.REWARD_VALUE, t1.REWARD_UNIT, t1.NOTE,
+                               t2.RANK_TYPE, t2.RANK_POSITION
+                        FROM RANKING_REWARD_LOG t1
+                        JOIN RANKING_HISTORY t2 ON t1.RANKING_HISTORY_ID = t2.ID
+                        WHERE t1.STATUS = 0
+                        ORDER BY t1.ID ASC"; // FIFO
 
                     var pendingRewards = await conn.QueryAsync<RankingRewardLog>(sqlGetPending);
                     var rewardList = pendingRewards.ToList();
@@ -113,13 +126,21 @@ namespace SicboSub.StartProcedure
                 return;
             }
 
+            // CHECK YÊU CẦU ĐẶC BIỆT: Top 1 Monthly -> Không trả tự động, chuyển Status 4 (Thủ công)
+            if (reward.RANK_TYPE == "MONTHLY" && reward.RANK_POSITION == 1 && reward.REWARD_UNIT == "MONEY")
+            {
+                 log.Info($"    ! Monthly Top 1 Prize (User {reward.MSISDN}) - Bỏ qua Add Money, chuyển sang trạng thái 4 (Thủ công).");
+                 await conn.ExecuteAsync("UPDATE RANKING_REWARD_LOG SET STATUS = 4, CREATED_DATE = SYSDATE WHERE ID = :id", new { id = reward.ID });
+                 return;
+            }
+
             // BƯỚC 2: THỰC HIỆN TRẢ THƯỞNG (Payment Logic)
             log.Info($"    -> Đang xử lý ID {reward.ID} (User {reward.MSISDN}): {reward.REWARD_VALUE} {reward.REWARD_UNIT}...");
             bool isSuccess = await DistributeReward(conn, reward);
 
             // BƯỚC 3: CHỐT TRẠNG THÁI (1: Success, 2: Failed)
-            // Nếu thất bại, set về 2 (Failed) để admin check, hoặc set về 0 (Pending) để retry tự động tùy nghiệp vụ.
-            // Ở đây tôi set về 2 để tránh retry vô tận nếu lỗi logic.
+            // Theo yêu cầu: Trả thưởng thất bại sẽ set về 2 (Failed) để Admin kiểm tra thủ công.
+            // Hệ thống KHÔNG tự động retry các giao dịch lỗi này.
             int finalStatus = isSuccess ? 1 : 2; 
 
             string sqlFinalize = "UPDATE RANKING_REWARD_LOG SET STATUS = :s, CREATED_DATE = SYSDATE WHERE ID = :id";
@@ -196,5 +217,7 @@ namespace SicboSub.StartProcedure
         public decimal REWARD_VALUE { get; set; }
         public string REWARD_UNIT { get; set; } = "";
         public string NOTE { get; set; } = "";
+        public string RANK_TYPE { get; set; } = "";
+        public decimal RANK_POSITION { get; set; }
     }
 }

+ 7 - 4
SicboSub/SicboSub.StartProcedure/SicboSub.StartProcedure.csproj

@@ -2,7 +2,7 @@
 <Project Sdk="Microsoft.NET.Sdk">
   <PropertyGroup>
     <OutputType>Exe</OutputType>
-    <TargetFramework>net8.0</TargetFramework>
+    <TargetFramework>net7.0</TargetFramework>
     <ImplicitUsings>enable</ImplicitUsings>
     <Nullable>enable</Nullable>
   </PropertyGroup>
@@ -22,8 +22,11 @@
     </None>
   </ItemGroup>
   <ItemGroup>
-    <PackageReference Include="System.ServiceModel.Http" Version="8.*" />
-    <PackageReference Include="System.ServiceModel.NetTcp" Version="8.*" />
-    <PackageReference Include="System.ServiceModel.Primitives" Version="8.*" />
+	<PackageReference Include="System.ServiceModel.Http" Version="6.0.0" />
+	<PackageReference Include="System.ServiceModel.Security" Version="6.0.0" />
+	<PackageReference Include="System.ServiceModel.NetTcp" Version="6.0.0" />
+	<PackageReference Include="System.ServiceModel.Federation" Version="6.0.0" />
+	<PackageReference Include="System.ServiceModel.Duplex" Version="6.0.0" />
+	<PackageReference Include="System.ServiceModel.Primitives" Version="6.0.0" />
   </ItemGroup>
 </Project>

+ 0 - 32
SicboSub/SicboSub.StartProcedure/SicboSub.StartProcedure.csproj.Backup.tmp

@@ -1,32 +0,0 @@
-<?xml version="1.0" encoding="utf-8"?>
-<Project Sdk="Microsoft.NET.Sdk">
-  <PropertyGroup>
-    <OutputType>Exe</OutputType>
-    <TargetFramework>net8.0</TargetFramework>
-    <ImplicitUsings>enable</ImplicitUsings>
-    <Nullable>enable</Nullable>
-  </PropertyGroup>
-  <ItemGroup>
-    <Content Include="log4net.config">
-      <CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>
-      <ExcludeFromSingleFile>true</ExcludeFromSingleFile>
-      <CopyToPublishDirectory>PreserveNewest</CopyToPublishDirectory>
-    </Content>
-  </ItemGroup>
-  <ItemGroup>
-    <PackageReference Include="Oracle.ManagedDataAccess.Core" Version="3.21.140" />
-    <PackageReference Include="Dapper" Version="2.1.35" />
-    <PackageReference Include="Microsoft.Extensions.Configuration" Version="8.0.0" />
-    <PackageReference Include="Microsoft.Extensions.Configuration.Json" Version="8.0.0" />
-  </ItemGroup>
-  <ItemGroup>
-    <None Update="appsettings.json">
-      <CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>
-    </None>
-  </ItemGroup>
-  <ItemGroup>
-    <PackageReference Include="System.ServiceModel.Http" Version="8.*" />
-    <PackageReference Include="System.ServiceModel.NetTcp" Version="8.*" />
-    <PackageReference Include="System.ServiceModel.Primitives" Version="8.*" />
-  </ItemGroup>
-</Project>

+ 68 - 17
SicboSub/SicboSub.Web/Controllers/HomeController.cs

@@ -264,6 +264,8 @@ namespace SicboSub.Web.Controllers
             }
             var url = GetParameter("RedirectUrl") + "/?token=" + token;
             log.Info($"PlayUrl: url = " + url);
+            ClearCache();
+            // Không gọi ClearCache() để giữ session login khi user quay lại
             return Redirect(url);
         }
 
@@ -283,8 +285,8 @@ namespace SicboSub.Web.Controllers
 
                 var token = GetToken();
                 // 3 days ago
-                var fromDate = DateTime.Now.AddDays(-3).ToString("dd/MM/yyyy");
-                var toDate = DateTime.Now.ToString("dd/MM/yyyy");
+                var fromDate = DateTime.Now.AddDays(-3).ToString("dd/MM/yyyy 00:00:00");
+                var toDate = DateTime.Now.ToString("dd/MM/yyyy 23:59:59");
 
                 var request = new PlayHistoryReq
                 {
@@ -333,8 +335,8 @@ namespace SicboSub.Web.Controllers
             {
                 var token = GetToken();
                 // 30 days ago for purchase history
-                var fromDate = DateTime.Now.AddDays(-30).ToString("dd/MM/yyyy");
-                var toDate = DateTime.Now.ToString("dd/MM/yyyy");
+                var fromDate = DateTime.Now.AddDays(-30).ToString("dd/MM/yyyy 00:00:00");
+                var toDate = DateTime.Now.ToString("dd/MM/yyyy 23:59:59");
 
                 var request = new PurchaseHistoryReq
                 {
@@ -406,7 +408,7 @@ namespace SicboSub.Web.Controllers
         /// <summary>
         /// Helper to load ranking history
         /// </summary>
-        private async Task<List<RankingHistoryItem>> LoadRankingInternal(string rankType, string msisdn = null)
+        private async Task<List<RankingHistoryItem>> LoadRankingInternal(string rankType, string msisdn = null, string specificDate = null)
         {
             try 
             {
@@ -415,15 +417,62 @@ namespace SicboSub.Web.Controllers
                 string fromDate = "";
                 string toDate = DateTime.Now.ToString("dd/MM/yyyy");
 
-                if (rankType == "DAILY")
+                if (!string.IsNullOrEmpty(specificDate))
                 {
-                    // 7 days ago
-                    fromDate = DateTime.Now.AddDays(-7).ToString("dd/MM/yyyy");
+                    if (rankType == "MONTHLY")
+                    {
+                        // Expected input: yyyy-MM
+                        if (DateTime.TryParseExact(specificDate, "yyyy-MM", System.Globalization.CultureInfo.InvariantCulture, System.Globalization.DateTimeStyles.None, out DateTime parsedMonth))
+                        {
+                             var firstDay = new DateTime(parsedMonth.Year, parsedMonth.Month, 1);
+                             var lastDay = firstDay.AddMonths(1).AddDays(-1);
+                             
+                             fromDate = firstDay.ToString("dd/MM/yyyy 00:00:00");
+                             toDate = lastDay.ToString("dd/MM/yyyy 23:59:59");
+                        }
+                        else
+                        {
+                             // Fallback try basic parsing
+                             if (DateTime.TryParse(specificDate, out DateTime parsed)) {
+                                 var firstDay = new DateTime(parsed.Year, parsed.Month, 1);
+                                 var lastDay = firstDay.AddMonths(1).AddDays(-1);
+                                 fromDate = firstDay.ToString("dd/MM/yyyy 00:00:00");
+                                 toDate = lastDay.ToString("dd/MM/yyyy 23:59:59");
+                             }
+                        }
+                    }
+                    else 
+                    {
+                        // DAILY - Exact Date
+                        // Convert yyyy-MM-dd to dd/MM/yyyy HH:mm:ss
+                        // Input expected: yyyy-MM-dd (from HTML5 date input)
+                        if (DateTime.TryParseExact(specificDate, "yyyy-MM-dd", System.Globalization.CultureInfo.InvariantCulture, System.Globalization.DateTimeStyles.None, out DateTime parsedDate))
+                        {
+                            fromDate = parsedDate.ToString("dd/MM/yyyy 00:00:00");
+                            toDate = parsedDate.ToString("dd/MM/yyyy 23:59:59");
+                        }
+                        else
+                        {
+                            // Fallback: try to just append time if it looks like a date
+                            fromDate = specificDate + " 00:00:00";
+                            toDate = specificDate + " 23:59:59";
+                        }
+                    }
                 }
-                else if (rankType == "MONTHLY")
+                else
                 {
-                    // 3 months ago
-                    fromDate = DateTime.Now.AddMonths(-3).ToString("dd/MM/yyyy");
+                    if (rankType == "DAILY")
+                    {
+                        // 7 days ago
+                        fromDate = DateTime.Now.AddDays(-7).ToString("dd/MM/yyyy 00:00:00");
+                        toDate = DateTime.Now.ToString("dd/MM/yyyy 23:59:59");
+                    }
+                    else if (rankType == "MONTHLY")
+                    {
+                        // 3 months ago
+                        fromDate = DateTime.Now.AddMonths(-3).ToString("dd/MM/yyyy 00:00:00");
+                        toDate = DateTime.Now.ToString("dd/MM/yyyy 23:59:59");
+                    }
                 }
 
                 var request = new RankingHistoryReq
@@ -465,22 +514,24 @@ namespace SicboSub.Web.Controllers
             return new List<RankingHistoryItem>();
         }
 
-        public async Task<IActionResult> DailyRanking()
+        public async Task<IActionResult> DailyRanking(string date = null)
         {
             if (!IsAuthenticated()) return RedirectToLogin(_configuration);
             
             // For Global Daily Ranking, we don't pass MSISDN implies global list
-            var data = await LoadRankingInternal("DAILY", null);
+            var data = await LoadRankingInternal("DAILY", null, date);
             ViewData["RankingType"] = "DAILY";
+            ViewData["SelectedDate"] = date; 
             return View(data);
         }
 
-        public async Task<IActionResult> MonthlyRanking()
+        public async Task<IActionResult> MonthlyRanking(string date = null)
         {
             if (!IsAuthenticated()) return RedirectToLogin(_configuration);
             
-            var data = await LoadRankingInternal("MONTHLY", null);
+            var data = await LoadRankingInternal("MONTHLY", null, date);
             ViewData["RankingType"] = "MONTHLY";
+            ViewData["SelectedDate"] = date;
             return View(data);
         }
 
@@ -537,8 +588,8 @@ namespace SicboSub.Web.Controllers
             try
             {
                 // 2. Prepare request data
-                string msisdn = GetMsisdn();
-                string token = GetToken();
+                string? msisdn = GetMsisdn();
+                string? token = GetToken();
                 // Default package for daily registration
                 string packageCode = GetParameter("PackageCodeDaily"); 
                 // Default fallback if config missing

+ 37 - 1
SicboSub/SicboSub.Web/Language/Language.Designer.cs

@@ -78,6 +78,15 @@ namespace SicboSub.Web.Language {
             }
         }
         
+        /// <summary>
+        ///   Looks up a localized string similar to Buy Now.
+        /// </summary>
+        public static string Buynow {
+            get {
+                return ResourceManager.GetString("Buynow", resourceCulture);
+            }
+        }
+        
         /// <summary>
         ///   Looks up a localized string similar to Cancel.
         /// </summary>
@@ -232,7 +241,7 @@ namespace SicboSub.Web.Language {
         }
         
         /// <summary>
-        ///   Looks up a localized string similar to Do you confirm to buy the Daily Package?.
+        ///   Looks up a localized string similar to  &lt;p class=&quot;register-message&quot;&gt;Do you confirm&lt;br/&gt;to buy the&lt;br/&gt;&lt;span class=&quot;highlight-text&quot;&gt;Subscribe Daily Pack: 500 Coins/day – only 3 HTG (Free first day, auto-renew)&lt;/span&gt;?&lt;/p&gt;.
         /// </summary>
         public static string ConfirmDailyPackage {
             get {
@@ -429,6 +438,15 @@ namespace SicboSub.Web.Language {
             }
         }
         
+        /// <summary>
+        ///   Looks up a localized string similar to OTP Verification.
+        /// </summary>
+        public static string OTPVerification {
+            get {
+                return ResourceManager.GetString("OTPVerification", resourceCulture);
+            }
+        }
+        
         /// <summary>
         ///   Looks up a localized string similar to Package.
         /// </summary>
@@ -465,6 +483,15 @@ namespace SicboSub.Web.Language {
             }
         }
         
+        /// <summary>
+        ///   Looks up a localized string similar to Play Now.
+        /// </summary>
+        public static string PlayNow {
+            get {
+                return ResourceManager.GetString("PlayNow", resourceCulture);
+            }
+        }
+        
         /// <summary>
         ///   Looks up a localized string similar to Price.
         /// </summary>
@@ -564,6 +591,15 @@ namespace SicboSub.Web.Language {
             }
         }
         
+        /// <summary>
+        ///   Looks up a localized string similar to Failed.
+        /// </summary>
+        public static string StatusFailed {
+            get {
+                return ResourceManager.GetString("StatusFailed", resourceCulture);
+            }
+        }
+        
         /// <summary>
         ///   Looks up a localized string similar to Lost.
         /// </summary>

+ 13 - 1
SicboSub/SicboSub.Web/Language/Language.resx

@@ -166,7 +166,7 @@
     <value>Confirm</value>
   </data>
   <data name="ConfirmDailyPackage" xml:space="preserve">
-    <value>Do you confirm to buy the Daily Package?</value>
+    <value> &lt;p class="register-message"&gt;Do you confirm&lt;br/&gt;to buy the&lt;br/&gt;&lt;span class="highlight-text"&gt;Subscribe Daily Pack: 500 Coins/day – only 3 HTG (Free first day, auto-renew)&lt;/span&gt;?&lt;/p&gt;</value>
   </data>
   <data name="DailyPackage" xml:space="preserve">
     <value>Daily Package</value>
@@ -351,4 +351,16 @@
   <data name="Failed" xml:space="preserve">
     <value>Failed</value>
   </data>
+  <data name="StatusFailed" xml:space="preserve">
+    <value>Failed</value>
+  </data>
+  <data name="PlayNow" xml:space="preserve">
+    <value>Play Now</value>
+  </data>
+  <data name="Buynow" xml:space="preserve">
+    <value>Buy Now</value>
+  </data>
+  <data name="OTPVerification" xml:space="preserve">
+    <value>OTP Verification</value>
+  </data>
 </root>

+ 12 - 0
SicboSub/SicboSub.Web/Language/Language.vi.resx

@@ -351,4 +351,16 @@
   <data name="Failed" xml:space="preserve">
     <value>Failed</value>
   </data>
+  <data name="StatusFailed" xml:space="preserve">
+    <value>Thất bại</value>
+  </data>
+  <data name="PlayNow" xml:space="preserve">
+    <value>PlayNow</value>
+  </data>
+  <data name="Buynow" xml:space="preserve">
+    <value>Buy Now</value>
+  </data>
+  <data name="OTPVerification" xml:space="preserve">
+    <value>OTP Verification</value>
+  </data>
 </root>

+ 2 - 1
SicboSub/SicboSub.Web/Models/HistoryModels.cs

@@ -64,10 +64,11 @@ namespace SicboSub.Web.Models
         public string productName { get; set; } = null!;
         public DateTime registerTime { get; set; }
         public DateTime expireTime { get; set; }
-        public decimal serviceId { get; set; } // Fee
+        public decimal serviceId { get; set; }
         public string channel { get; set; } = null!;
         public int status { get; set; }
         public int renew { get; set; }
+        public int fee { get; set; } // Fee from Packg table
     }
 
     public class PurchaseHistoryRes : CommonResponse

+ 1 - 1
SicboSub/SicboSub.Web/Properties/PublishProfiles/FolderProfile.pubxml

@@ -8,7 +8,7 @@
     <LastUsedBuildConfiguration>Release</LastUsedBuildConfiguration>
     <LastUsedPlatform>Any CPU</LastUsedPlatform>
     <PublishProvider>FileSystem</PublishProvider>
-    <PublishUrl>D:\Code\Ex_publish\Natcom_SicboSub\web</PublishUrl>
+    <PublishUrl>E:\Ex_publish\Natcom_SicboSub\web</PublishUrl>
     <WebPublishMethod>FileSystem</WebPublishMethod>
     <_TargetId>Folder</_TargetId>
     <SiteUrlToLaunchAfterPublish />

+ 1 - 1
SicboSub/SicboSub.Web/SicboSub.Web.csproj

@@ -1,7 +1,7 @@
 <Project Sdk="Microsoft.NET.Sdk.Web">
 
   <PropertyGroup>
-    <TargetFramework>net8.0</TargetFramework>
+    <TargetFramework>net7.0</TargetFramework>
     <Nullable>enable</Nullable>
     <ImplicitUsings>enable</ImplicitUsings>
   </PropertyGroup>

+ 1 - 1
SicboSub/SicboSub.Web/Views/Home/Account.cshtml

@@ -50,7 +50,7 @@
                     <span class="info-label">@Language.TotalCoins</span>
                     <span class="info-value coins">@String.Format("{0:n0}", betCoin)</span>
                 </div>
-                <img class="settings-icon" src="~/img/042-settings.png" alt="Settings" style="cursor:pointer;" onclick="alert('Settings feature coming soon!')" />
+                @* <img class="settings-icon" src="~/img/042-settings.png" alt="Settings" style="cursor:pointer;" onclick="alert('Settings feature coming soon!')" /> *@
             </div>
 
             <!-- My Coins (Main Balance) -->

+ 143 - 2
SicboSub/SicboSub.Web/Views/Home/DailyRanking.cshtml

@@ -31,14 +31,151 @@
                 <img class="switch-icon" src="~/img/017-strategy.png" alt="" />
                 <span class="switch-text">@Language.SwitchToMonthly</span>
             </a>
+
+            <!-- Date Filter -->
+            <div class="ranking-date-container">
+                @{
+                    var selectedDateStr = ViewData["SelectedDate"] as string;
+                    var displayDate = DateTime.Now;
+                    if (!string.IsNullOrEmpty(selectedDateStr) && DateTime.TryParse(selectedDateStr, out DateTime parsed))
+                    {
+                        displayDate = parsed;
+                    }
+                }
+                <!-- Trigger Button -->
+                <div class="date-trigger-btn" onclick="openCalendar()">
+                    <span id="dateTriggerText" class="date-trigger-text">@displayDate.ToString("MM/dd/yyyy")</span>
+                    <svg class="date-trigger-icon" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round">
+                        <rect x="3" y="4" width="18" height="18" rx="2" ry="2"></rect>
+                        <line x1="16" y1="2" x2="16" y2="6"></line>
+                        <line x1="8" y1="2" x2="8" y2="6"></line>
+                        <line x1="3" y1="10" x2="21" y2="10"></line>
+                    </svg>
+                </div>
+            </div>
             
             <!-- Title -->
             <div class="ranking-title daily">
                 <span class="title-line">@Language.Daily</span>
-                <span class="title-line">@Language.Ranking</span>
+                <span class="title-line">@Language.Winner</span>
+            </div>
+        </div>
+
+        <!-- Custom Calendar Popup -->
+        <div id="calendarPopup" class="calendar-popup-overlay" style="display: none;">
+            <div class="calendar-popup">
+                <button class="calendar-close-btn" onclick="closeCalendar()">
+                    <svg width="24" height="24" viewBox="0 0 24 24" fill="none" stroke="white" stroke-width="3" stroke-linecap="round" stroke-linejoin="round">
+                        <line x1="18" y1="6" x2="6" y2="18"></line>
+                        <line x1="6" y1="6" x2="18" y2="18"></line>
+                    </svg>
+                </button>
+                
+                <div class="calendar-header">
+                    <button class="month-nav-btn" onclick="changeMonth(-1)">&lt;</button>
+                    <span id="currentMonthLabel" class="current-month-label">JANUARY 2026</span>
+                    <button class="month-nav-btn" onclick="changeMonth(1)">&gt;</button>
+                </div>
+                
+                <div class="calendar-grid">
+                    <div class="calendar-day-header">Mon</div>
+                    <div class="calendar-day-header">Tue</div>
+                    <div class="calendar-day-header">Wed</div>
+                    <div class="calendar-day-header">Thu</div>
+                    <div class="calendar-day-header">Fri</div>
+                    <div class="calendar-day-header">Sat</div>
+                    <div class="calendar-day-header sunday">Sun</div>
+                    
+                    <!-- Days will be injected here -->
+                    <div id="calendarDaysContainer" style="display: contents;"></div>
+                </div>
             </div>
         </div>
 
+        <script>
+            let currentCalendarDate = new Date('@displayDate.ToString("yyyy-MM-dd")');
+            let selectedDate = new Date('@displayDate.ToString("yyyy-MM-dd")');
+
+            function openCalendar() {
+                renderCalendar();
+                document.getElementById('calendarPopup').style.display = 'flex';
+            }
+
+            function closeCalendar() {
+                document.getElementById('calendarPopup').style.display = 'none';
+            }
+            
+            // Close on overlay click
+            document.getElementById('calendarPopup').addEventListener('click', function(e) {
+                if (e.target === this) closeCalendar();
+            });
+
+            function changeMonth(delta) {
+                currentCalendarDate.setMonth(currentCalendarDate.getMonth() + delta);
+                renderCalendar();
+            }
+
+            function renderCalendar() {
+                const year = currentCalendarDate.getFullYear();
+                const month = currentCalendarDate.getMonth();
+                const today = new Date();
+
+                // Update Header
+                const monthNames = ["JANUARY", "FEBRUARY", "MARCH", "APRIL", "MAY", "JUNE", "JULY", "AUGUST", "SEPTEMBER", "OCTOBER", "NOVEMBER", "DECEMBER"];
+                document.getElementById('currentMonthLabel').textContent = `${monthNames[month]} ${year}`;
+
+                const container = document.getElementById('calendarDaysContainer');
+                container.innerHTML = '';
+
+                // Get first day of month
+                const firstDay = new Date(year, month, 1);
+                // Adjust for Mon start (0 is Sun, 1 is Mon)
+                // We want Mon=0, Sun=6
+                let startDay = firstDay.getDay() - 1; 
+                if (startDay === -1) startDay = 6;
+
+                const daysInMonth = new Date(year, month + 1, 0).getDate();
+
+                // Empty slots
+                for (let i = 0; i < startDay; i++) {
+                    const empty = document.createElement('div');
+                    empty.className = 'calendar-day empty';
+                    container.appendChild(empty);
+                }
+
+                // Days
+                for (let i = 1; i <= daysInMonth; i++) {
+                    const dayEl = document.createElement('div');
+                    dayEl.className = 'calendar-day';
+                    dayEl.textContent = i;
+                    
+                    // Check if selected
+                    if (year === selectedDate.getFullYear() && 
+                        month === selectedDate.getMonth() && 
+                        i === selectedDate.getDate()) {
+                        dayEl.classList.add('selected');
+                    }
+
+                    dayEl.onclick = function() {
+                        selectDate(year, month, i);
+                    };
+
+                    container.appendChild(dayEl);
+                }
+            }
+
+            function selectDate(year, month, day) {
+                // Format yyyy-MM-dd for controller
+                // Javascript months are 0-indexed
+                const monthStr = (month + 1).toString().padStart(2, '0');
+                const dayStr = day.toString().padStart(2, '0');
+                const dateStr = `${year}-${monthStr}-${dayStr}`;
+                
+                // Redirect
+                window.location.href = '@Url.Action("DailyRanking", "Home")?date=' + dateStr;
+            }
+        </script>
+
         <!-- Table Header -->
         <div class="ranking-table-header">
             <div class="col-top">@Language.Top</div>
@@ -61,7 +198,11 @@
 
                     <div class="ranking-row @rowClass">
                         <div class="col-top">@item.rankPosition</div>
-                        <div class="col-player">@(string.IsNullOrEmpty(item.msisdn) ? "****" : item.msisdn)</div>
+                        @* <div class="col-player">@(string.IsNullOrEmpty(item.msisdn) ? "****" : item.msisdn)</div> *@
+                        <div class="col-player">
+                            @(string.IsNullOrEmpty(item.msisdn) ? "****" :
+                                                item.msisdn.Substring(0, 3) + "****" + item.msisdn.Substring(item.msisdn.Length - 3))
+                        </div>
                         <div class="col-player">@item.rankDate.ToString("dd/MM/yyyy")</div>
                         <div class="col-rewards">
                             <span class="reward-value">+@item.rewardValue.ToString("N0")</span> 

+ 1 - 1
SicboSub/SicboSub.Web/Views/Home/History.cshtml

@@ -120,7 +120,7 @@
                     <div class="table-row">
                         <div class="col-no">@(no++)</div>
                         <div class="col-time">@item.registerTime.ToString("dd/MM/yyyy HH:mm:ss")</div>
-                        <div class="col-value">@item.serviceId.ToString("N0") <span class="coins">@Language.HTG</span></div>
+                        <div class="col-value">@item.fee.ToString("N0") <span class="coins">@Language.HTG</span></div>
                         <div class="col-type">@item.productName</div>
                         @if (item.status == 1) // Assuming 1 is Success
                         {

+ 99 - 37
SicboSub/SicboSub.Web/Views/Home/Index.cshtml

@@ -4,6 +4,7 @@
     Layout = "_GameLayout";
     var packages = Context.Session.GetComplexData<List<SicboSub.Web.Models.PackageInfo>>("Packages");
     var isRegistered = Context.Session.GetComplexData<bool?>("isRegistered") ?? false;
+    var msisdn = Context.Session.GetComplexData<string>("msisdn") ?? "";
 }
 
 @section Styles {
@@ -28,7 +29,7 @@
             <div class="medal-parent">
                 <img class="hourglass-icon" src="~/img/021-medal-2.svg" alt="">
                 <div class="ranking-coin">@Language.Rankingcoin</div>
-                <b class="view-ranking-coin">@Language.ViewRankingCoin</b>
+                <a class="view-ranking-coin">@Language.ViewRankingCoin</a>
             </div>
             <div class="frame-group">
                 <div class="frame-container">
@@ -135,8 +136,8 @@
             
             <!-- Action Buttons -->
             <div class="popup-actions">
-                <button class="popup-btn cancel-btn" onclick="closePackagePopup()">@Language.Cancel</button>
-                <button class="popup-btn next-btn" onclick="handlePackageNext()">@Language.Next</button>
+                @* <button class="popup-btn cancel-btn" onclick="closePackagePopup()">@Language.Cancel</button> *@
+                <button class="popup-btn next-btn" onclick="handlePackageNext()">@Language.Buynow</button>
             </div>
         </div>
     </div>
@@ -158,14 +159,14 @@
             
             <!-- Confirm Content -->
             <div class="confirm-content">
-                <p class="confirm-message">@Language.DoYouWantToBuy</p>
-                <p class="confirm-coins"><span id="confirmCoinsAmount">100</span> <span class="coins-label">@Language.Coins</span></p>
-                <p class="confirm-price">Price <span id="confirmPriceAmount">1</span> <span class="htg-label">@Language.HTG</span></p>
+                @* <p class="confirm-message">@Language.DoYouWantToBuy</p> *@
+                <p class="confirm-coins"><span id="confirmCoinsAmount">100</span> <span class="coins-label">@Language.Coins</span>/ <span id="confirmPriceAmount">1</span> <span class="htg-label">@Language.HTG</span></p>
+                @* <p class="confirm-price">Price <span id="confirmPriceAmount">1</span> <span class="htg-label">@Language.HTG</span></p> *@
             </div>
             
             <!-- Action Buttons -->
             <div class="popup-actions">
-                <button class="popup-btn cancel-btn" onclick="closeConfirmPopup()">@Language.Cancel</button>
+                @* <button class="popup-btn cancel-btn" onclick="closeConfirmPopup()">@Language.Cancel</button> *@
                 <button class="popup-btn next-btn" onclick="handleConfirmBuy()">@Language.Confirm</button>
             </div>
         </div>
@@ -197,7 +198,8 @@
                     
                     <!-- Text Content -->
                     <div class="register-text">
-                        <p class="register-message">Do you confirm<br/>to buy the<br/><span class="highlight-text">@Language.DailyPackage</span>?</p>
+                        @Html.Raw(Language.ConfirmDailyPackage)
+                        @* @Language.ConfirmDailyPackage *@
                     </div>
                     
                     <!-- Confirm Button -->
@@ -223,7 +225,7 @@
                 <div class="withdraw-left">
                     <div class="withdraw-phone">
                         <span class="withdraw-label">@Language.PhoneNumber</span>
-                        <span class="withdraw-phone-number">0912 345 678</span>
+                        <span class="withdraw-phone-number">@msisdn</span>
                     </div>
                     
                     <div class="withdraw-balance-badge">@Language.MainBalance</div>
@@ -235,7 +237,7 @@
                     
                     <div class="withdraw-info">
                         <span class="withdraw-info-label">@Language.CoinAmount</span>
-                        <span class="withdraw-coin-amount">@String.Format("{0:n0}", ViewData["WinCoin"])</span>
+                        <span id="withdrawPopupCoinValue" class="withdraw-coin-amount">@String.Format("{0:n0}", ViewData["WinCoin"])</span>
                     </div>
                 </div>
                 
@@ -323,7 +325,7 @@
     <div id="otpPopup" class="popup-overlay" style="display: none;">
         <div class="popup-container otp-popup">
             <div class="popup-header">
-                <span class="popup-title">OTP Verification</span>
+                <span class="popup-title">@Language.OTPVerification</span>
             </div>
              <button class="popup-close-btn" onclick="closeOtpPopup()">
                 <svg width="24" height="24" viewBox="0 0 24 24" fill="white">
@@ -347,24 +349,46 @@
         </div>
     </div>
 
-    <!-- Message Popup (Success/Error) -->
+    <!-- Message Popup (Success/Error) - Redesigned -->
     <div id="messagePopup" class="popup-overlay" style="display: none;">
-        <div class="popup-container message-popup">
-            <!-- Close Button -->
-            <button class="popup-close-btn" onclick="closeMessagePopup()">
-                <svg width="24" height="24" viewBox="0 0 24 24" fill="white">
-                    <path d="M18.3 5.71a1 1 0 0 0-1.41 0L12 10.59 7.11 5.7a1 1 0 0 0-1.41 1.41L10.59 12l-4.89 4.89a1 1 0 1 0 1.41 1.41L12 13.41l4.89 4.89a1 1 0 0 0 1.41-1.41L13.41 12l4.89-4.89a1 1 0 0 0 0-1.4z"/>
+        <div id="messagePopupContainer" class="message-popup-container-custom">
+            <!-- Top Right Close Button (Red Circle) -->
+            <button class="message-close-btn-custom" onclick="closeMessagePopup()">
+                <svg width="20" height="20" viewBox="0 0 24 24" fill="none" stroke="white" stroke-width="4" stroke-linecap="round" stroke-linejoin="round">
+                    <line x1="18" y1="6" x2="6" y2="18"></line>
+                    <line x1="6" y1="6" x2="18" y2="18"></line>
                 </svg>
             </button>
+
+            <!-- Dice Decorations - Success -->
+            <div id="diceSuccess" class="dice-set" style="display: none;">
+                <img src="~/img/dice_success_1.png" alt="" class="message-dice-bottom-left" />
+                <img src="~/img/dice_success_2.png" alt="" class="message-dice-bottom-right" />
+                <img src="~/img/dice_success_1.png" alt="" class="message-dice-top-left" />
+                <img src="~/img/dice_success_2.png" alt="" class="message-dice-top-right" />
+            </div>
             
-            <div class="message-content">
-                <div id="messageIcon" class="message-icon">
-                    <!-- Icon injected via JS -->
-                </div>
-                <div id="messageText" class="message-text">
+            <!-- Dice Decorations - Error -->
+            <div id="diceError" class="dice-set" style="display: none;">
+                <img src="~/img/xucto1.png" alt="" class="message-dice-bottom-left" />
+                <img src="~/img/xucto2.png" alt="" class="message-dice-bottom-right" />
+                <img src="~/img/xucto1.png" alt="" class="message-dice-top-left" />
+                <img src="~/img/xucto2.png" alt="" class="message-dice-top-right" />
+            </div>
+
+            <!-- Content -->
+            <div class="message-content-custom">
+                <!-- Title -->
+                <div id="messageTitleCustom" class="message-title-custom">@Language.StatusSuccessful</div>
+                
+                <!-- Message -->
+                <div id="messageTextCustom" class="message-text-custom">
                     <!-- Message text injected via JS -->
                 </div>
-                <button class="popup-btn next-btn" onclick="closeMessagePopup()">OK</button>
+
+                <!-- Bottom Action Button -->
+
+                <button id="messageActionBtn" class="message-action-btn-custom" onclick="closeMessagePopup()">@Language.PlayNow</button>
             </div>
         </div>
     </div>
@@ -400,22 +424,42 @@
 
 @section Scripts {
     <script>
-        // Message Popup Logic
+        // Message Popup Logic (Redesigned)
         function showMessagePopup(type, message) {
             const popup = document.getElementById('messagePopup');
-            const iconContainer = document.getElementById('messageIcon');
-            const textContainer = document.getElementById('messageText');
+            const container = document.getElementById('messagePopupContainer');
+            const titleContainer = document.getElementById('messageTitleCustom');
+            const textContainer = document.getElementById('messageTextCustom');
+            const diceSuccess = document.getElementById('diceSuccess');
+            const diceError = document.getElementById('diceError');
+            const actionBtn = document.getElementById('messageActionBtn');
             
             // Set message
             textContainer.textContent = message;
             
-            // Set icon based on type
+            // Set title, background and dice based on type
             if (type === 'success') {
-                iconContainer.innerHTML = '✔'; 
-                iconContainer.className = 'message-icon success';
+                titleContainer.textContent = '@Language.StatusSuccessful';
+                if (actionBtn) {
+                    actionBtn.textContent = '@Language.PlayNow';
+                    actionBtn.onclick = function() {
+                        window.location.href = '/Home/Play';
+                    };
+                }
+                container.className = 'message-popup-container-custom success';
+                // Show success dice, hide error dice
+                diceSuccess.style.display = 'block';
+                diceError.style.display = 'none';
             } else {
-                iconContainer.innerHTML = '✖'; 
-                iconContainer.className = 'message-icon error';
+                titleContainer.textContent = '@Language.StatusFailed';
+                if (actionBtn) {
+                    actionBtn.textContent = '@Language.Close';
+                    actionBtn.onclick = closeMessagePopup;
+                }
+                container.className = 'message-popup-container-custom error';
+                // Show error dice, hide success dice
+                diceSuccess.style.display = 'none';
+                diceError.style.display = 'block';
             }
             
             popup.style.display = 'flex';
@@ -551,7 +595,13 @@
                        // Update coins
                        if(response.data) {
                            if(document.getElementById('betCoinVal')) document.getElementById('betCoinVal').textContent = Site.formatNumber(response.data.betCoin);
-                           if(document.getElementById('winCoinVal')) document.getElementById('winCoinVal').textContent = Site.formatNumber(response.data.winCoin);
+                           if(document.getElementById('winCoinVal')) {
+                               const formattedWinCoin = Site.formatNumber(response.data.winCoin);
+                               document.getElementById('winCoinVal').textContent = formattedWinCoin;
+                               if(document.getElementById('withdrawPopupCoinValue')) {
+                                    document.getElementById('withdrawPopupCoinValue').textContent = formattedWinCoin;
+                               }
+                           }
                        }
 
                        closeRegisterPopup();
@@ -690,8 +740,14 @@
                      if(response.data) {
                          if(document.getElementById('betCoinVal') && response.data.betCoin !== undefined) 
                              document.getElementById('betCoinVal').textContent = Site.formatNumber(response.data.betCoin);
-                         if(document.getElementById('winCoinVal') && response.data.winCoin !== undefined) 
-                             document.getElementById('winCoinVal').textContent = Site.formatNumber(response.data.winCoin);
+                         if(document.getElementById('winCoinVal') && response.data.winCoin !== undefined) {
+                             const formattedWinCoin = Site.formatNumber(response.data.winCoin);
+                             document.getElementById('winCoinVal').textContent = formattedWinCoin;
+                             // Update value in withdraw popup as well
+                             if(document.getElementById('withdrawPopupCoinValue')) {
+                                 document.getElementById('withdrawPopupCoinValue').textContent = formattedWinCoin;
+                             }
+                         }
                      }
                 } else {
                      Site.showError(response.message || 'Verification failed');
@@ -714,8 +770,8 @@
             const selectedPackage = document.querySelector('input[name="package"]:checked');
             if (selectedPackage) {
                 const packageCode = selectedPackage.value;
-                const coins = selectedPackage.getAttribute('data-coin');
-                const price = selectedPackage.getAttribute('data-price');
+                const coins = parseFloat(selectedPackage.getAttribute('data-coin'));
+                const price = parseFloat(selectedPackage.getAttribute('data-price'));
                 
                 selectedPackageCode = packageCode;
 
@@ -745,7 +801,13 @@
                      // Update coins
                      if(response.data) {
                          if(document.getElementById('betCoinVal')) document.getElementById('betCoinVal').textContent = Site.formatNumber(response.data.betCoin);
-                         if(document.getElementById('winCoinVal')) document.getElementById('winCoinVal').textContent = Site.formatNumber(response.data.winCoin);
+                         if(document.getElementById('winCoinVal')) {
+                             const formattedWinCoin = Site.formatNumber(response.data.winCoin);
+                             document.getElementById('winCoinVal').textContent = formattedWinCoin;
+                             if(document.getElementById('withdrawPopupCoinValue')) {
+                                  document.getElementById('withdrawPopupCoinValue').textContent = formattedWinCoin;
+                             }
+                         }
                      }
 
                      closeConfirmPopup();

+ 118 - 2
SicboSub/SicboSub.Web/Views/Home/MonthlyRanking.cshtml

@@ -32,13 +32,125 @@
                 <span class="switch-text">@Language.SwitchToDaily</span>
             </a>
             
+            <!-- Date Filter (Month) -->
+            <div class="ranking-date-container">
+                @{
+                    var selectedDateStr = ViewData["SelectedDate"] as string;
+                    var displayDate = DateTime.Now;
+                    // If yyyy-MM
+                    if (!string.IsNullOrEmpty(selectedDateStr))
+                    {
+                        if (DateTime.TryParseExact(selectedDateStr, "yyyy-MM", System.Globalization.CultureInfo.InvariantCulture, System.Globalization.DateTimeStyles.None, out DateTime parsed))
+                        {
+                            displayDate = parsed;
+                        }
+                    }
+                }
+                <!-- Trigger Button -->
+                <div class="date-trigger-btn" onclick="openMonthCalendar()">
+                    <span id="dateTriggerText" class="date-trigger-text">@displayDate.ToString("MM/yyyy")</span>
+                    <svg class="date-trigger-icon" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round">
+                         <rect x="3" y="4" width="18" height="18" rx="2" ry="2"></rect>
+                         <line x1="16" y1="2" x2="16" y2="6"></line>
+                         <line x1="8" y1="2" x2="8" y2="6"></line>
+                         <line x1="3" y1="10" x2="21" y2="10"></line>
+                    </svg>
+                </div>
+            </div>
+
             <!-- Title -->
             <div class="ranking-title monthly">
                 <span class="title-line">@Language.Monthly</span>
-                <span class="title-line">@Language.Ranking</span>
+                <span class="title-line">@Language.Winner</span>
+            </div>
+        </div>
+
+        <!-- Custom Month Popup -->
+        <div id="monthCalendarPopup" class="calendar-popup-overlay" style="display: none;">
+            <div class="calendar-popup">
+                <button class="calendar-close-btn" onclick="closeMonthCalendar()">
+                    <svg width="24" height="24" viewBox="0 0 24 24" fill="none" stroke="white" stroke-width="3" stroke-linecap="round" stroke-linejoin="round">
+                        <line x1="18" y1="6" x2="6" y2="18"></line>
+                        <line x1="6" y1="6" x2="18" y2="18"></line>
+                    </svg>
+                </button>
+                
+                <div class="calendar-header">
+                    <button class="month-nav-btn" onclick="changeYear(-1)">&lt;</button>
+                    <span id="currentYearLabel" class="current-month-label">2026</span>
+                    <button class="month-nav-btn" onclick="changeYear(1)">&gt;</button>
+                </div>
+                
+                <!-- Month Grid -->
+                <div class="calendar-grid" style="grid-template-columns: repeat(3, 1fr); gap: 12px;">
+                    <!-- Months injected here -->
+                    <div id="calendarMonthsContainer" style="display: contents;"></div>
+                </div>
             </div>
         </div>
 
+        <script>
+            let currentYear = new Date('@displayDate.ToString("yyyy-MM-01")').getFullYear();
+            let selectedMonthDate = new Date('@displayDate.ToString("yyyy-MM-01")');
+
+            function openMonthCalendar() {
+                renderMonthCalendar();
+                document.getElementById('monthCalendarPopup').style.display = 'flex';
+            }
+
+            function closeMonthCalendar() {
+                document.getElementById('monthCalendarPopup').style.display = 'none';
+            }
+            
+            // Close on overlay click
+            document.getElementById('monthCalendarPopup').addEventListener('click', function(e) {
+                if (e.target === this) closeMonthCalendar();
+            });
+
+            function changeYear(delta) {
+                currentYear += delta;
+                renderMonthCalendar();
+            }
+
+            function renderMonthCalendar() {
+                document.getElementById('currentYearLabel').textContent = currentYear;
+
+                const container = document.getElementById('calendarMonthsContainer');
+                container.innerHTML = '';
+                
+                const monthNames = ["JAN", "FEB", "MAR", "APR", "MAY", "JUN", "JUL", "AUG", "SEP", "OCT", "NOV", "DEC"];
+
+                for (let i = 0; i < 12; i++) {
+                    const monthEl = document.createElement('div');
+                    monthEl.className = 'calendar-day'; // reuse styles
+                    monthEl.style.borderRadius = '12px'; // slightly different shape
+                    monthEl.style.aspectRatio = '2/1';
+                    monthEl.textContent = monthNames[i];
+                    
+                    // Check if selected
+                    if (currentYear === selectedMonthDate.getFullYear() && 
+                        i === selectedMonthDate.getMonth()) {
+                        monthEl.classList.add('selected');
+                    }
+
+                    monthEl.onclick = function() {
+                        selectMonth(currentYear, i);
+                    };
+
+                    container.appendChild(monthEl);
+                }
+            }
+
+            function selectMonth(year, month) {
+                // Format yyyy-MM
+                const monthStr = (month + 1).toString().padStart(2, '0');
+                const dateStr = `${year}-${monthStr}`;
+                
+                // Redirect
+                window.location.href = '@Url.Action("MonthlyRanking", "Home")?date=' + dateStr;
+            }
+        </script>
+
         <!-- Table Header -->
         <div class="ranking-table-header">
             <div class="col-top">@Language.Top</div>
@@ -61,7 +173,11 @@
 
                     <div class="ranking-row @rowClass">
                         <div class="col-top">@item.rankPosition</div>
-                        <div class="col-player">@(string.IsNullOrEmpty(item.msisdn) ? "****" : item.msisdn)</div>
+                        @* <div class="col-player">@(string.IsNullOrEmpty(item.msisdn) ? "****" : item.msisdn)</div> *@
+                        <div class="col-player">
+                            @(string.IsNullOrEmpty(item.msisdn) ? "****" :
+                                                item.msisdn.Substring(0, 3) + "****" + item.msisdn.Substring(item.msisdn.Length - 3))
+                        </div>
                         <div class="col-player">@item.rankDate.ToString("dd/MM/yyyy")</div>
                         <div class="col-rewards">
                             <span class="reward-value">+@item.rewardValue.ToString("N0")</span> 

+ 2 - 2
SicboSub/SicboSub.Web/Views/Home/Winner.cshtml

@@ -39,7 +39,7 @@
             <!-- Title -->
             <div class="card-title daily-title">
                 <span class="title-line-1">@Language.Daily</span>
-                <span class="title-line-2">@Language.Ranking</span>
+                <span class="title-line-2">@Language.Winner</span>
             </div>
         </a>
 
@@ -66,7 +66,7 @@
             <!-- Title -->
             <div class="card-title monthly-title">
                 <span class="title-line-1">@Language.Monthly</span>
-                <span class="title-line-2">@Language.Ranking</span>
+                <span class="title-line-2">@Language.Winner</span>
             </div>
         </a>
     </div>

+ 1 - 1
SicboSub/SicboSub.Web/appsettings.json

@@ -9,7 +9,7 @@
   "Url": "http://127.0.0.1:9106",
   //"RedirectUrl": "http://149.28.132.56:8110",
   "RedirectUrl": "http://127.0.0.1:5042/?token=",
-  "PackageCodeDaily": "SICBO_DAY",
+  "PackageCodeDaily": "SICBO_DAILY",
   "Kestrel": {
     "EndPoints": {
       "Http": {

+ 275 - 29
SicboSub/SicboSub.Web/wwwroot/css/sicbo-popup.css

@@ -39,7 +39,7 @@
 }
 
 .popup-title {
-    font-size: 18px;
+    font-size: 28px;
     font-weight: 700;
     background: linear-gradient(180deg, #FFFFFF 0%, #ffe3aa 100%);
     -webkit-background-clip: text;
@@ -144,9 +144,9 @@
 
 .popup-btn {
     flex: 1;
-    padding: 8px 16px;
+    padding: 10px 16px;
     font-family: 'Kanit', sans-serif;
-    font-size: 16px;
+    font-size: 18px;
     font-weight: 700;
     border-radius: 20px;
     cursor: pointer;
@@ -185,6 +185,7 @@
    ======================================== */
 
 .confirm-popup {
+    width: 500px;
     text-align: center;
 }
 
@@ -193,7 +194,7 @@
 }
 
 .confirm-message {
-    font-size: 14px;
+    font-size: 18px;
     color: rgba(255, 255, 255, 0.8);
     margin: 0 0 8px 0;
 }
@@ -288,7 +289,8 @@
 /* Text Content - bottom left, on top of character */
 .register-text {
     position: absolute;
-    top: 80px;
+    /*    top: 80px*/
+    top: 30px;
     left: 10px;
     text-align: left;
     width: 60%;
@@ -466,8 +468,8 @@
     border-radius: 6px;
 }
 
-.withdraw-option input[type="radio"]:checked ~ .withdraw-option-coins,
-.withdraw-option input[type="radio"]:checked ~ .withdraw-option-htg {
+.withdraw-option input[type="radio"]:checked~.withdraw-option-coins,
+.withdraw-option input[type="radio"]:checked~.withdraw-option-htg {
     color: #ffe3aa;
 }
 
@@ -526,8 +528,16 @@
    ======================================== */
 
 .message-popup {
-    width: 280px; /* Consistent width */
+    width: 500px;
+    /* Match register-popup actual visual width */
+    min-height: 280px;
+    /* Match register-popup actual visual height */
+    padding: 20px 24px;
+    /* More padding for larger popup */
     text-align: center;
+    display: flex;
+    flex-direction: column;
+    justify-content: center;
 }
 
 .message-content {
@@ -563,9 +573,10 @@
    OTP Popup Styles
    ======================================== */
 .otp-popup {
-    width: 320px;
+    width: 500px;
     text-align: center;
-    background: #000; /* Ensure black background */
+    background: #000;
+    /* Ensure black background */
     border: 2px solid #c9a861;
 }
 
@@ -573,7 +584,7 @@
     display: flex;
     flex-direction: column;
     align-items: center;
-    gap: 20px;    
+    gap: 20px;
     padding: 10px 0;
 }
 
@@ -592,13 +603,13 @@
 }
 
 .otp-box {
-    width: 40px;
-    height: 50px;
+    width: 50px;
+    height: 60px;
     background: #000;
     border: 1px solid #c9a861;
     border-radius: 8px;
     color: #fff;
-    font-size: 24px;
+    font-size: 28px;
     font-weight: 700;
     text-align: center;
     outline: none;
@@ -642,7 +653,7 @@
     display: flex;
     justify-content: space-between;
     margin-bottom: 4px;
-    font-size: 14px;
+    font-size: 18px;
 }
 
 .detail-row:last-child {
@@ -666,18 +677,18 @@
     position: relative;
     width: 500px;
     height: 320px;
-    /* Placeholder for user background image. 
-       User should replace the URL below. */
-    background-color: #7b0d1e; 
-    background-image: url('../img/exchange_success_bg.png'); 
+    background-color: #7b0d1e;
+    background-image: url('../img/exchange_success_bg.png');
     background-size: cover;
     background-position: center;
     border-radius: 25px;
-    border: 3px solid #dac486; /* Gold/Beige border */
-    box-shadow: 0 10px 30px rgba(0, 0, 0, 0.8), inset 0 0 20px rgba(0,0,0,0.5);
+    border: 3px solid #dac486;
+    /* Gold/Beige border */
+    box-shadow: 0 10px 30px rgba(0, 0, 0, 0.8), inset 0 0 20px rgba(0, 0, 0, 0.5);
     display: flex;
     flex-direction: column;
-    justify-content: flex-end; /* Push content to bottom */
+    justify-content: flex-end;
+    /* Push content to bottom */
     padding-bottom: 30px;
     align-items: center;
     font-family: 'Kanit', sans-serif;
@@ -685,8 +696,15 @@
 }
 
 @keyframes popupPop {
-    0% { transform: scale(0.5); opacity: 0; }
-    100% { transform: scale(1); opacity: 1; }
+    0% {
+        transform: scale(0.5);
+        opacity: 0;
+    }
+
+    100% {
+        transform: scale(1);
+        opacity: 1;
+    }
 }
 
 /* Close Button (Top Right Red Circle) */
@@ -696,8 +714,10 @@
     right: -20px;
     width: 44px;
     height: 44px;
-    background: #ff0000; /* Bright red */
-    border: 3px solid #dac486; /* Gold border */
+    background: #ff0000;
+    /* Bright red */
+    border: 3px solid #dac486;
+    /* Gold border */
     border-radius: 50%;
     cursor: pointer;
     display: flex;
@@ -767,17 +787,243 @@
     border: 2px solid #000;
     border-radius: 12px;
     cursor: pointer;
-    box-shadow: 0 4px 0 #000, 0 5px 10px rgba(0,0,0,0.5);
+    box-shadow: 0 4px 0 #000, 0 5px 10px rgba(0, 0, 0, 0.5);
     transition: all 0.1s;
     text-transform: capitalize;
 }
 
 .exchange-action-btn-custom:hover {
     transform: translateY(2px);
-    box-shadow: 0 2px 0 #000, 0 3px 6px rgba(0,0,0,0.5);
+    box-shadow: 0 2px 0 #000, 0 3px 6px rgba(0, 0, 0, 0.5);
 }
 
 .exchange-action-btn-custom:active {
     transform: translateY(4px);
-    box-shadow: 0 0 0 #000, 0 0 0 rgba(0,0,0,0.5);
+    box-shadow: 0 0 0 #000, 0 0 0 rgba(0, 0, 0, 0.5);
+}
+
+/* ========================================
+   Custom Message Popup Styles (Redesigned)
+   Matches Exchange Success Popup design
+   ======================================== */
+
+.message-popup-container-custom {
+    position: relative;
+    width: 500px;
+    height: 320px;
+    /* Default background - User can replace with their own image */
+    background-color: #7b0d1e;
+    background-image: url('../img/message_popup_bg.png');
+    background-size: contain;
+    background-position: center;
+    background-repeat: no-repeat;
+    border-radius: 25px;
+    border: 3px solid #dac486;
+    /* Gold/Beige border */
+    box-shadow: 0 10px 30px rgba(0, 0, 0, 0.8), inset 0 0 20px rgba(0, 0, 0, 0.5);
+    display: flex;
+    flex-direction: column;
+    justify-content: center;
+    align-items: center;
+    padding: 30px;
+    font-family: 'Kanit', sans-serif;
+    animation: messagePopupPop 0.3s cubic-bezier(0.175, 0.885, 0.32, 1.275);
+}
+
+/* Success State - Green tinted background */
+.message-popup-container-custom.success {
+    background-color: #7b0d1e;
+    background-image: url('../img/exchange_success_bg.png');
+}
+
+/* Error State - Semi-transparent background */
+.message-popup-container-custom.error {
+    background-color: rgba(22, 20, 20, 0.85);
+    background-image: url('../img/message_error_bg.png');
+}
+
+@keyframes messagePopupPop {
+    0% {
+        transform: scale(0.5);
+        opacity: 0;
+    }
+
+    100% {
+        transform: scale(1);
+        opacity: 1;
+    }
+}
+
+/* Close Button (Top Right Red Circle) */
+.message-close-btn-custom {
+    position: absolute;
+    top: -20px;
+    right: -20px;
+    width: 44px;
+    height: 44px;
+    background: #E05F60;
+    /* Bright red */
+    border: 3px solid #dac486;
+    /* Gold border */
+    border-radius: 50%;
+    cursor: pointer;
+    display: flex;
+    align-items: center;
+    justify-content: center;
+    box-shadow: 0 4px 8px rgba(0, 0, 0, 0.5);
+    z-index: 10;
+    transition: transform 0.2s;
+}
+
+.message-close-btn-custom:hover {
+    transform: scale(1.1);
+}
+
+/* Dice Set Container - Ensure it doesn't affect flex layout */
+.dice-set {
+    position: absolute;
+    top: 0;
+    left: 0;
+    width: 100%;
+    height: 100%;
+    pointer-events: none;
+    z-index: 5;
+}
+
+/* Dice Decorations - Positioned as per design */
+.message-dice-bottom-left {
+    position: absolute;
+    bottom: 5px;
+    left: 5px;
+    width: 60px;
+    height: auto;
+    z-index: 5;
+    pointer-events: none;
+    filter: drop-shadow(2px 4px 6px rgba(0, 0, 0, 0.5));
+    transform: rotate(-15deg);
+}
+
+.message-dice-bottom-right {
+    position: absolute;
+    /* bottom: 5px; */
+    right: 5px;
+    width: 60px;
+    height: auto;
+    z-index: 5;
+    pointer-events: none;
+    filter: drop-shadow(2px 4px 6px rgba(0, 0, 0, 0.5));
+    transform: rotate(15deg);
+}
+
+.message-dice-top-left {
+    position: absolute;
+    top: 15px;
+    left: 50px;
+    width: 30px;
+    height: auto;
+    z-index: 5;
+    pointer-events: none;
+    filter: drop-shadow(2px 4px 6px rgba(0, 0, 0, 0.5));
+    transform: rotate(-25deg);
+}
+
+.message-dice-top-right {
+    position: absolute;
+    top: 30px;
+    right: 160px;
+    width: 25px;
+    height: auto;
+    z-index: 5;
+    pointer-events: none;
+    filter: drop-shadow(2px 4px 6px rgba(0, 0, 0, 0.5));
+    transform: rotate(15deg);
+}
+
+/* Content Container */
+.message-content-custom {
+    width: 100%;
+    height: 100%;
+    display: flex;
+    flex-direction: column;
+    align-items: center;
+    justify-content: flex-end;
+    text-align: center;
+    gap: 10px;
+    padding-bottom: 25px;
+    z-index: 10;
+}
+
+/* Icon */
+.message-icon-custom {
+    display: flex;
+    align-items: center;
+    justify-content: center;
+    margin-bottom: 5px;
+}
+
+.message-icon-custom svg {
+    filter: drop-shadow(0 2px 8px rgba(0, 0, 0, 0.5));
+}
+
+/* Title "Success!" or "Failed!" - Positioned at top-left */
+.message-title-custom {
+    position: absolute;
+    top: 60px;
+    left: 30px;
+    font-family: 'Kanit', sans-serif;
+    font-size: 36px;
+    font-weight: 900;
+    /* font-style: italic; */
+    background: linear-gradient(180deg, #fff8e7 0%, #dac486 100%);
+    -webkit-background-clip: text;
+    -webkit-text-fill-color: transparent;
+    background-clip: text;
+    color: #dac486;
+    -webkit-text-stroke: 1px #000;
+    filter: drop-shadow(2px 2px 0 #000);
+    line-height: 1;
+    text-transform: uppercase;
+    z-index: 15;
 }
+
+/* Message Text */
+.message-text-custom {
+    font-size: 16px;
+    font-weight: 600;
+    background: linear-gradient(180deg, #fff8e7 0%, #dac486 100%);
+    -webkit-background-clip: text;
+    -webkit-text-fill-color: transparent;
+    background-clip: text;
+    color: #dac486;
+    filter: drop-shadow(0 2px 4px rgba(0, 0, 0, 0.8));
+    max-width: 85%;
+    line-height: 1.4;
+}
+
+/* Bottom Action Button "OK" */
+.message-action-btn-custom {
+    min-width: 140px;
+    /* padding: 10px 30px; */
+    font-family: 'Kanit', sans-serif;
+    font-size: 22px;
+    font-weight: 800;
+    color: #000;
+    background: linear-gradient(180deg, #fff8e7 0%, #dac486 100%);
+    border: 2px solid #000;
+    border-radius: 12px;
+    cursor: pointer;
+    box-shadow: 0 4px 0 #000, 0 5px 10px rgba(0, 0, 0, 0.5);
+    transition: all 0.1s;
+    text-transform: uppercase;
+    margin-top: 10px;
+}
+
+.message-action-btn-custom:hover {
+    transform: translateY(2px);
+    box-shadow: 0 2px 0 #000, 0 3px 6px rgba(0, 0, 0, 0.5);
+}
+
+.message-action-btn-custom:active {
+    transform: translateY(4px);
+    box-shadow: 0 0 0 #000, 0 0 0 rgba(0, 0, 0, 0.5);
+}

+ 161 - 3
SicboSub/SicboSub.Web/wwwroot/css/sicbo-ranking.css

@@ -54,7 +54,7 @@
     text-decoration: none;
     cursor: pointer;
     transition: transform 0.2s ease;
-    margin-right: 30%;
+    margin-right: 16px;
 }
 
 .switch-button:hover {
@@ -73,11 +73,169 @@
     color: #000;
 }
 
+/* Date Filter Input */
+/* Date Filter Trigger - Image 1 Style */
+.ranking-date-container {
+    margin-left: 16px;
+    position: relative;
+    z-index: 10;
+}
+
+.date-trigger-btn {
+    display: flex;
+    align-items: center;
+    justify-content: space-between;
+    gap: 16px;
+    padding: 8px 16px;
+    min-width: 260px;
+    background: linear-gradient(180deg, #FFF8E7 0%, #E6CFA8 100%);
+    border: 3px solid #C9A861;
+    border-radius: 20px;
+    cursor: pointer;
+    box-shadow: 0 4px 4px rgba(0, 0, 0, 0.25);
+    transition: transform 0.2s;
+}
+
+.date-trigger-btn:hover {
+    transform: scale(1.02);
+}
+
+.date-trigger-text {
+    font-family: 'Kanit', sans-serif;
+    font-weight: 900;
+    font-size: 24px;
+    color: #000;
+    line-height: 1;
+}
+
+.date-trigger-icon {
+    width: 24px;
+    height: 24px;
+    stroke: #000;
+    stroke-width: 2;
+}
+
+/* Calendar Popup - Image 2 Style */
+.calendar-popup-overlay {
+    position: fixed;
+    top: 0;
+    left: 0;
+    width: 100%;
+    height: 100%;
+    background: rgba(0, 0, 0, 0.6);
+    z-index: 1000;
+    display: flex;
+    align-items: center;
+    justify-content: center;
+    backdrop-filter: blur(2px);
+}
+
+.calendar-popup {
+    width: 80%;
+    max-width: 360px;
+    background: #F0F0F0;
+    border-radius: 24px;
+    padding: 24px;
+    position: relative;
+    font-family: 'Inter', sans-serif;
+    box-shadow: 0 10px 25px rgba(0, 0, 0, 0.5);
+}
+
+.calendar-close-btn {
+    position: absolute;
+    top: -15px;
+    right: -15px;
+    width: 40px;
+    height: 40px;
+    background: #FF0000;
+    border: 2px solid #E1C59C;
+    border-radius: 50%;
+    display: flex;
+    align-items: center;
+    justify-content: center;
+    cursor: pointer;
+    box-shadow: 0 2px 5px rgba(0, 0, 0, 0.3);
+    z-index: 1001;
+}
+
+.calendar-header {
+    text-align: center;
+    margin-bottom: 20px;
+    display: flex;
+    align-items: center;
+    justify-content: space-between;
+}
+
+.month-nav-btn {
+    background: none;
+    border: none;
+    font-size: 20px;
+    cursor: pointer;
+    padding: 5px 10px;
+    font-weight: bold;
+    color: #333;
+}
+
+.current-month-label {
+    font-family: 'Kanit', sans-serif;
+    font-weight: 800;
+    font-size: 24px;
+    color: #000;
+    text-transform: uppercase;
+}
+
+.calendar-grid {
+    display: grid;
+    grid-template-columns: repeat(7, 1fr);
+    gap: 8px;
+    text-align: center;
+}
+
+.calendar-day-header {
+    font-weight: 600;
+    font-size: 14px;
+    color: #333;
+    padding-bottom: 8px;
+}
+
+.calendar-day-header.sunday {
+    color: #FF0000;
+}
+
+.calendar-day {
+    aspect-ratio: 1;
+    display: flex;
+    align-items: center;
+    justify-content: center;
+    font-weight: 600;
+    font-size: 16px;
+    color: #000;
+    cursor: pointer;
+    border-radius: 50%;
+    transition: all 0.2s;
+}
+
+.calendar-day:hover:not(.empty) {
+    background: rgba(0, 0, 0, 0.1);
+}
+
+.calendar-day.selected {
+    background: #FF3B30;
+    color: #FFF;
+    box-shadow: 0 2px 5px rgba(255, 59, 48, 0.4);
+}
+
+.calendar-day.empty {
+    cursor: default;
+}
+
 /* Ranking Title */
 .ranking-title {
     display: flex;
     flex-direction: column;
     text-align: left;
+    margin-left: auto;
+    /* Push to right */
 }
 
 .ranking-title .title-line {
@@ -91,7 +249,7 @@
     -webkit-text-fill-color: transparent;
     background-clip: text;
     -webkit-text-stroke: 1.5px #000;
-    filter: drop-shadow(2px 2px 2px rgba(0,0,0,0.8));
+    filter: drop-shadow(2px 2px 2px rgba(0, 0, 0, 0.8));
 }
 
 /* Table Header */
@@ -192,4 +350,4 @@
     z-index: 0;
     pointer-events: none;
     border-top-right-radius: 16px;
-}
+}

BIN
SicboSub/SicboSub.Web/wwwroot/img/message_error_bg.png


BIN
SicboSub/SicboSub.Web/wwwroot/img/xucto1.png


BIN
SicboSub/SicboSub.Web/wwwroot/img/xucto2.png


BIN
SicboSub/SicboSub.Web/wwwroot/img/xucto3.png


+ 8 - 5
SicboSubWs/SicboSubWs/src/com/vas/webservices/SicboSubWs.java

@@ -159,6 +159,9 @@ public class SicboSubWs extends WebserviceAbstract {
             // check existed
             AccountInfo accountInfo = db.iGetAccountByMsisdn(msisdn, productInfo.getProductName());
 //            UserProfile userProfile = db.iGetUserProfileByMsisdn(msisdn);
+            if (accountInfo.getMsisdn() == null || accountInfo.getMsisdn().isEmpty()) {
+                accountInfo = db.iGetAccount(msisdn);
+            }
             if (accountInfo == null) {
                 logger.error("Error check exist account: " + msisdn);
                 response.setErrorCode(Common.ErrorCode.QUERY_ERROR);
@@ -692,11 +695,11 @@ public class SicboSubWs extends WebserviceAbstract {
                         String REQ = reqDf.format(new Date()) + "1" + msisdn.substring(Common.COUNTRY_CODE.length());
                         logger.info("after get product info " + fee);
                         // right -----------------------------------------------
-//                        resultPaid = ws.requestMpsOtp(msisdn, fee, REQ, productInfo.getProductName());
+                        resultPaid = ws.requestMpsOtp(msisdn, fee, REQ, productInfo.getProductName());
                         
                         String errorCode = resultPaid.split("\\|")[0];
                         if (WSProcessor.LIST_SUCCESS_RES.contains(resultPaid)) {
-                            logger.info("Register success success " + msisdn + ", fee " + fee);
+//                            logger.info("Register success success " + msisdn + ", fee " + fee);
                             Timestamp expireTime = getExpireTime(productInfo);
                             // check registered
                             RegisterInfo reg;
@@ -1407,8 +1410,8 @@ public class SicboSubWs extends WebserviceAbstract {
                     String REQ = reqDf.format(new Date()) + "1" + msisdn.substring(Common.COUNTRY_CODE.length());
 
                     // charge
-//                  String resultPaid = ws.chargeFeeOtp(msisdn, moneyCharge, REQ);
-                    String resultPaid = "0";
+                  String resultPaid = ws.chargeFeeOtp(msisdn, moneyCharge, REQ);
+//                    String resultPaid = "0";
                     boolean registered = false;
                     List<RegisterInfo> listRegInday = null;
                     listRegInday = db.getRegisterInday(msisdn, productInfo.getProductName());
@@ -1690,7 +1693,7 @@ public class SicboSubWs extends WebserviceAbstract {
                     } else {
 
                         int money = Integer.parseInt(fee);
-//                        ws.addMoney(msisdn, money);
+                        ws.addMoney(msisdn, money);
 
                         ChargeLog chargeLog = new ChargeLog();
                         chargeLog.setFee(-money);

+ 0 - 51
SicboSubWs/etc/key/MINHA_VIBE_DAY/PrivateKeyCP.pem

@@ -1,51 +0,0 @@
------BEGIN RSA PRIVATE KEY-----
-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
------END RSA PRIVATE KEY-----

+ 0 - 14
SicboSubWs/etc/key/MINHA_VIBE_DAY/PublicKeyCP.pem

@@ -1,14 +0,0 @@
------BEGIN PUBLIC KEY-----
-MIICIjANBgkqhkiG9w0BAQEFAAOCAg8AMIICCgKCAgEAsHGJoswP7mrci9AzguWq
-DZW55iKwU7eC0277xM8WsIL2ghkxooKZtxFw49TgwHzN44+vn2XX1Cf517qz8Cmy
-rWGkUZbxcyanXIoa6tDFlPYnYpsmqRwKX0D6XKfg6uXELOKIp5pCe1j4bQpXNowF
-1YWJ8i7ATpXRit+hzalu92iCMDutVUC3wBYM31oJeciogzkeSfg/kaYi0ntbLRUR
-qncTxIQPOfLYvNspl5PCOBpQHSl+133furcOHh9o0xT23hTW6fvs3QY3WiGMSwWy
-T5F9D5K2x3VZLCZYLgJUZT/UpQW8cK9EJ9cHnw2aprHahNMEGKUFIExfVqDcts6O
-9TUGC6pFqkm3I6WkYMzxYLRqC5ZFC36hnE5LV3RYdF4MjoD8aDAfOtvw6mYTq+Fu
-+4YPrJP6wanAoQjm5Hg2dsvYJ+/rrf4KBLoPC/srWsfLQvtUurHs2pcftZ6IDlwi
-hwmY+mpFFs/W2/tFbbJ8OPH4XuWYP5jZeo8om76WamSazTE871ZBr1c8NfsnBcaH
-WxEM3bjeQyc5x5SQUcjiN3DnCp3SalrNkswvbsbIrObL3iT38Rq0gXPxiqv9Jf1A
-IeeU6knrq56IfvFnVxg+ZB5JOqE/LZLhr55SlkqCKhmWlZG45W9rqG/Pg8tGc1tm
-KMxL+sN/MfBhmtEa6GgaP50CAwEAAQ==
------END PUBLIC KEY-----

+ 0 - 14
SicboSubWs/etc/key/MINHA_VIBE_DAY/PublicKeyVT.pem

@@ -1,14 +0,0 @@
------BEGIN PUBLIC KEY-----
-MIICIjANBgkqhkiG9w0BAQEFAAOCAg8AMIICCgKCAgEAmkctXGmHzlg3HCLcOLEu
-089zvny1vo7Ayfu1ePKp19v3+BxAJJkgUU/3PUj3v03+LYDtVDslWBpWLUbsY5/B
-sNaSHZrzHecNYQ+zrYbAXD60e5ijB0FH+vkHJv0l97Q/2ncqQhZ/wthKNd1jj7fo
-kt6tAlRerjDg4tQ8o/DE+aCFgWo2sHIfuAzAm9GLNkpNHMsqyCkS7pnHf5Duhsbu
-kxEhEQenNytdrelZUJCWu+O/I2tAhyfryYvbez9L0snNETehzT2Y9c1gO0m7sPqw
-/EmZxOLrUc51OrZ8GEBMJhz7jbMRPmml2m0WQEQjHpFB8/Xhq8QxL3OlPwZVY8CO
-SGFNOGxbHezudOYghtAbz7aveGikWwG+Bc4eI9RCKzViUonEZKjThUs5on6HQy/X
-DovjHLfc8PERZkIKJ2Jm3lSr6I4A03kQltGyo7ew4sO6VI7RADeFGgYttuDQjgNs
-YVApnM+LcaAhCAZMDFflbm4mI0rmp05SlWZzxLJZNK9WftZbmDq6e3KKgdZdgCbb
-EML5Q/cHKLfljNMbK/v4RwsFUWkULng6HGSLcr7B74FW9EQYcQoJm4g0wA5Rzm4J
-KIv3+sZi+iVoROFubyHYdXAGbnyIWSiutdMmEDT0ZsUdQzVBGCN9UN16eRoUsmYW
-30W+j+UulNwyBmVbs9s9EuECAwEAAQ==
------END PUBLIC KEY-----

+ 0 - 51
SicboSubWs/etc/key/MINHA_VIBE_MINUS/PrivateKeyCP.pem

@@ -1,51 +0,0 @@
------BEGIN RSA PRIVATE KEY-----
-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
------END RSA PRIVATE KEY-----

+ 0 - 14
SicboSubWs/etc/key/MINHA_VIBE_MINUS/PublicKeyCP.pem

@@ -1,14 +0,0 @@
------BEGIN PUBLIC KEY-----
-MIICIjANBgkqhkiG9w0BAQEFAAOCAg8AMIICCgKCAgEArPcqAJqC3zFBE1yboaRl
-GHHaofaPoSOq2JYxDm/YfjmWY143kPxvsFgHbH0h7lB1EQdHXDuBmDokAPqgLmoA
-jU7Ug5SQTGsNW1uVmxkRQgSaYq/d3YedEXoO28AFTTkF0QIoR2Ue4nfGXlUlTLgp
-LyH24PiE5bWEtViKPOQnr+/im9tpo2QKPknkQhsiC0If1xO19EV9aGAkqLy8rBfu
-fqs3PdI3RFHzqP8suWrCpkC5730BRv63KUnjCRIzUbFXyYO0n2lTK1+ch/gYPqhb
-NjTmNEK/cVkJ9jLFwsr/tVTSpoLG7MVJ4CNguCCzGEvw+ObEzH1yG13gH1ItJSFR
-TfRmg71bDi+RLch3aRswnrGholQApxYqOQpWbI2KV11yHJX8TOpRd6AlGgSs9fmn
-M9MpzcF438rkYopRUbYTguCW11VPjoyGlHYTWywyUI8sh+YbNAwKvFn9NT1UvNO/
-IJ9xcjfOSpg5wI50xkjLwjEmIKtznjhcb4yJ19338QFSymnCyK8q41IZG+pyQFCV
-rvNxjj7DrD510+X5kgzV/EkFUWCed2CuBs0rtthzwFWtp9T2Mh86mEC5mOm7CExW
-YXVM0P6zYPKf6D+xKy9X1EwfaepmSznSS0tmklAbsujPF4ooUd/nxIDTU/5PXfHN
-9tWvHhphgKuwJpS9N/jB7LkCAwEAAQ==
------END PUBLIC KEY-----

+ 0 - 14
SicboSubWs/etc/key/MINHA_VIBE_MINUS/PublicKeyVT.pem

@@ -1,14 +0,0 @@
------BEGIN PUBLIC KEY-----
-MIICIjANBgkqhkiG9w0BAQEFAAOCAg8AMIICCgKCAgEAnSoC3XVY4MXmxnCy6ScI
-HKnKzI1JydKTkzlxubzrhMJcVj9/KmVdy04SM3ZdEzy2OT8OiTWakgz9LpQvIX6V
-iAa2Qd9KOai+WfoLdjGGbIbuP8mh+YEf67Hb15Sso/ZQ6rME4XZ91Klx5TTerYgi
-+8ecHb+KsgCXdl7M5BlPTambOOenM9mnjJPGJWAWpEluYfO9gN3gvDZGxOp2rf20
-fSaZ1Q0RdCMpwg0+sHj6qTLMimVu69ueu4XWzDwZ/N4cyCS355KrAu5arA3JohfN
-BlkOYVTGtxReDd+CiX6qjf8NNGeBjVUL2O0I8+lMGEnhXrJEzGvMcqHpbJAcriY+
-E4LRvtOC8i5tY0vZzo8KvxTrCyMFbvpnXGfDd0QTqYXWAUNdfqhE2MgFL2iFO555
-wlXmKJQuU51SA9oK0S6SpRs+MxXIEXU88OP3SQMlTmy9riNHeedWgCtG3bSahmY9
-ZN4pNnNTFtgx7NTM5aDAfYHnsIgIrMhQS7E42w+nJ/20MP7g1/J0pfLZS+iqbw1Y
-Qs1qBC9d73VSZOdQCYiO4DNOdlkchMhJVXOV1IHIsSwjqw2l5V7Z/WVl2rJVqd52
-C69aSFBDcml5TEFdj+bQUx6sv1bhb98sBOJ7CcfhZLSOgYR68cCe18NBBaoF1NlS
-WAf0eWIzuJ8ziIzaIBXRYZkCAwEAAQ==
------END PUBLIC KEY-----

+ 0 - 51
SicboSubWs/etc/key/MINHA_VIBE_MR_DAY/PrivateKeyCP.pem

@@ -1,51 +0,0 @@
------BEGIN RSA PRIVATE KEY-----
-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
------END RSA PRIVATE KEY-----

+ 0 - 14
SicboSubWs/etc/key/MINHA_VIBE_MR_DAY/PublicKeyCP.pem

@@ -1,14 +0,0 @@
------BEGIN PUBLIC KEY-----
-MIICIjANBgkqhkiG9w0BAQEFAAOCAg8AMIICCgKCAgEA3cSAqNc+HrbuzplyyaAl
-Bzw0ZyabkZO/TW3rFhaFJFzkr2oWMfXjOlOb5Hu8CC3HK85/tFeXkmLuUugu0c3I
-lqZIlWVbkCdCbVV5qC4UYqty145oF59PHSW3TekmTHoo8IPzzjNo8XRy7Y3P+Cy3
-gCAoAekcWMFgDVFzYudVjW3Jhj9MeHfnChCyu4wBZ5h6UV1ugcrFH9/2+yROiEzQ
-e+n5prpvHNFiKMvTKLU1pfbevQpUlsDaXAJAgtmhX9V/ZmJRX5cIE0Wk/+jF0l1Y
-4CDSgOE1zRGHA8Ulfyi52mtryYEfiyXb8YtvWGG1dM+MMmZbtpXiN7k647/uKu+5
-pj+rFE3WtLIb1WB7pcKGwX2kfqvOOlw2Q3C/i2aaRIHoKcPp/xqM1ayX2AuFdQyd
-sxRSnp1ru7F+RkjrhaKhuQKJvGPcMBYiVqvAorpI8XXEgPgnXcT+me8H0CljTrYj
-de/rokhpd8GVZxtsDjzkSvA7kI6dy5p8+ih6GaSI92x0ioqzdYuaeW2VTdWuWus0
-4AzD+x1NIMyHC3LP6rKQuxikm17tWr7Jisl12BvQQTD88SPituzO7A6klKUZ2ams
-ktoNx+u5mfbXKi10E17m+2ri5aj/W3NouY3Owu2MTtpnd1PdncQRd29fmddYVlxB
-9jSwlqrsQEXyMGu1baXTCmcCAwEAAQ==
------END PUBLIC KEY-----

+ 0 - 14
SicboSubWs/etc/key/MINHA_VIBE_MR_DAY/PublicKeyVT.pem

@@ -1,14 +0,0 @@
------BEGIN PUBLIC KEY-----
-MIICIjANBgkqhkiG9w0BAQEFAAOCAg8AMIICCgKCAgEA8SNlrDljnUYeIcCwtSuK
-c8CnQK95e5DvsKXHueLnOODYJVUTo+a630QOm031WNlHGbvrjipj8gU7OWQu0YrY
-H3UW74VDUxHS7kG0FDJF1G3ksZrzMG8iuT3r5BwuDJ+K7+fQLuU6Y2PUgVRkyd1m
-3yjoZ174MuZjJPGOQaeTJu9U4I59uYhl4vMw6KtGJSBBErEr5jALhHyMXPRIXv/C
-HUNSfiQZ98hcRd/sUc8wWsDzDK506higOYjMB9LKJC7E4YF72oadiWYM1tpo7nru
-RAXrz37g2Ynhu6DmYpfVPYYugBrAKlbSd5xszFDDnx5nMx8RnyymPY4wa5AyLx7z
-Gqa8MF/av7vINSuSFhQKfO2n1VmcjJpIl79BQ/5EmZQOgoMZAYC88hYAhWJoW9IK
-bqXwGsepmijxIDDvT8zwykfh69uLbF5hG2XjyRtuBiVCIBaq42bR1ECz4lOGE0RG
-dSaqt7R0Db2K+dwnJwcVZcZuFHJDtCwe3+kRZ0R7UkyMvNZIVxDs6KSNbDn5sDOT
-GZTaUeKkQQsksptjZzDGTVQwq5qE0EFrF//t83urTYfmawxIdQVNrkUVWOpkPt3/
-OyBRVmmfjVxsy7eUaywFJFTUvb+eBuMiuekMXTXv/+ptMDyXmba8ttmeeCnylApy
-qXC4ehU/DO8ec9TMt0QA++MCAwEAAQ==
------END PUBLIC KEY-----

+ 0 - 51
SicboSubWs/etc/key/MINHA_VIBE_WIN/PrivateKeyCP.pem

@@ -1,51 +0,0 @@
------BEGIN RSA PRIVATE KEY-----
-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
------END RSA PRIVATE KEY-----

+ 0 - 14
SicboSubWs/etc/key/MINHA_VIBE_WIN/PublicKeyCP.pem

@@ -1,14 +0,0 @@
------BEGIN PUBLIC KEY-----
-MIICIjANBgkqhkiG9w0BAQEFAAOCAg8AMIICCgKCAgEAwTwKbq4uChfLwVb+kIyB
-/IFvwyavKBstf3pgDRX9kMsgQL7Adrlb9Wx5/x3gzWDv+JZLneIZu/fCVBJCjZkZ
-NkUhieg2a3a2cNngFwBxC46+TI6MqMPMo6LO7CvBKwGq0vjiDq/3SHkEAVHaGrzn
-q6vTXyC6rolLKBgrOgTwAyxqMYSqB94h3jZbSowWNdoXShXi1grtGOHx9LMkb7Uk
-IypXKjht/YMwRPe1fsw/6zPZKqBzSWLPzION885JwwEg3fV91sPoEgBKSLkLeBw0
-F8j2ZwgnEvT3o8YeqblbN0VHJrfR1Xl8w077EHzJ3LqVDsqgrFFbUn20VPMDzR23
-gEZco95rLlwWPEhMrkAGxaPJLDLC5FiEHmk8u4yKUIEpglb4xGUICNmgwdPQj2Kd
-ceJILcgBmpafNxGQ27aDKCCxHxWowxKlNgjy6eZw5v7Mn2fHoZNcWKcMGA5Id9mz
-2vOoF1R/4ChW0kr9wUSpYpVIxxI8/eu5fw0SJwJNe/0rvSoBUTX13YnDGRtQ10+g
-qOU4dlScGb4zGlZM4OaeOwCXH/+b0fry2Mwk7qiBgJUTWZDYIjPwxFG80KS5uQqu
-479o881tpVJsbMrYk/sUML0a7Bt6rBUXFE5EhxUZCfYrOk8ZcoPBcx57ZEME5WSF
-F2MtEPfvPCFpuesCY8IXyesCAwEAAQ==
------END PUBLIC KEY-----

+ 0 - 14
SicboSubWs/etc/key/MINHA_VIBE_WIN/PublicKeyVT.pem

@@ -1,14 +0,0 @@
------BEGIN PUBLIC KEY-----
-MIICIjANBgkqhkiG9w0BAQEFAAOCAg8AMIICCgKCAgEAx1MLIkUAbZqMxMjKCwkO
-GW+08OWxOha5HwSLYZRzivTTZ87gT4cSsPqmPv2ec+g2tHSBiLRrvaY6x//NM+yz
-Cm9HCZhTD2uB+8XMLY8XcBGrXqIVROus8J+3k3hEsiAr74QshcejXA/eTQMnO1uh
-WDqrb58YUvX9BHO4Nhkq+BnvJUURv2xW6UM9kvoUPc+vU59jn2995wc8fF8QResn
-qfDdu8e489ckKmBnT/QXUyD6yjmBa2d5VtoMWeq7FpMULjtR6IuO+SONkQTA4LHT
-LrkyslmZpbX+DfNXDx/iNUL0w4oolxci+8UQL4rEOGbwLJ4TvNPQ1KrNiSExzRQw
-eScYXzmVfeKb1aUeQxsJ0hHMi0/c3N8X9VCWBuWNHKVKvJrDOwsvHTjBeigPA1KS
-TshY7q6moUikH/l4894IUEEB3uak77HOPlKWNjjGPHiDE9WbrcAYY4dURoZACl14
-eUQlirV1bMfOPp/tXcv4aWjfsvTl64PCenn9fOzYVvZXBzp27D1fynzW1fnCOvyb
-hIkY/gybpJHj1mn++zsoc2CsVrOPj7eKtKGiUigPirOMs0kS83a2iBLE10Ix1rVX
-SRxVJ7RJrFTOUWCMBuRz+px7GjTB23t26aHQIzrM9/G+i6rxgciqooBTFsjN7bWJ
-EpBX6Afh9/SMvxDl9pRzZ9UCAwEAAQ==
------END PUBLIC KEY-----

+ 51 - 0
SicboSubWs/etc/key/SICBO_DAILY/PrivateKeyCP.pem

@@ -0,0 +1,51 @@
+-----BEGIN RSA PRIVATE KEY-----
+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
+-----END RSA PRIVATE KEY-----

+ 14 - 0
SicboSubWs/etc/key/SICBO_DAILY/PublicKeyCP.pem

@@ -0,0 +1,14 @@
+-----BEGIN PUBLIC KEY-----
+MIICIjANBgkqhkiG9w0BAQEFAAOCAg8AMIICCgKCAgEAh1Z9EqVv57+ullnmc7ZG
+asUcl1L9INyG46aLT0798txVbHYMaSKYu3rwAKCzuK3WTRPX4PTYE8oVj9sau+5l
+3DQkzxEvmekEiyll5Wg5RcjCYOEtkXBMNBRpgxJsuucWlzFCVDK1beAHyLCTxD6O
+PzZV6BIkHsnk1BwoT6Mk1SP+nJXAMVQ90WCZbB6P1xC+VATjaFzPfOjeSYWeOtEl
+fWKFBMRfIw8ZDTSpisxggB+LTMwdobo0WU+ku068s69iWqlCq/Cky2crT43cIWeZ
+iO7hOsklWj+2x9vXzK/XmQ48xbzw9n5Hei1oqmaXQjoK8Ee42g94oxVM4Oofn9Pd
+AQ61eqzWOExOJkOOetrOQISKEK45fl9zlOf29vLiUrDtoZ3d36HFnhyIrYQSmWCi
+p1/Zw57gaQ+LZ1vb3DxTExsru1CC7VTrTWNZ1eREFY5RUzgAB1fCjD4BVY5o8uJo
+ud/5o+bOhOwo4icACLKzYuSZg7yXw59HAq2/KVO3ZCgF6rOXD3gHusmvcEXJvrpu
+mq3RlLbMvqhoTae4IyJizdetO8saxJHfYhfaV+m+SELYxulO55HvagKjh0byK8tX
+IJxQSZO2KIkW8fvhz8WCE80V8sT2dh2kU6g2+9lShUdgk73HvibyZhOXKqrGc8bJ
+P4msyzY6s9I2S1GZ8eta9FUCAwEAAQ==
+-----END PUBLIC KEY-----

+ 14 - 0
SicboSubWs/etc/key/SICBO_DAILY/PublicKeyVT.pem

@@ -0,0 +1,14 @@
+-----BEGIN PUBLIC KEY-----
+MIICIjANBgkqhkiG9w0BAQEFAAOCAg8AMIICCgKCAgEAhB27zgS7j/ENmOnKgzYv
+cYIjVIjVoekasFN5SOTtK70remPjPWJph7JNQffUVLQM3kEboSOMRmsb4ZKLMKgt
+3+isVk6Az8jn0wp7+MHFPPGrO+ebQoN5H/xHmjCxWePZIgyoKXZYRgpfE/tC77Sd
+rrYS8HG4rlYsxy+9tD1flkTHCz0juf8/w4BRYcS8ydnTrCfZ6u0xFycPkuwS6gEO
+2rRguNpJkWZfLf3r2KxBJ6PmDSiVbEAMg3agSnBJho/Xo0cZA4BceOmVv4u/nu/v
+jPLsaH1qSTf76pZyZ6vPOL+ORf3ZlSjAmfILBNU/E1/vpQNWYES1sftx8jG3UHMW
+E6PC358Acw0Nl0nbeq7UEl/Gb5RDrYnlY9tHxmwfRHWZwnOX5ZJ5tXukhWcgXFmf
+LNNFATADZGpReqW1jMiulMMv4sxMCgQniN5mR1UwJA5CEzSDgHyK3T/I50jT8fID
+woOAkhZbWIcVLuJPAsdGUfhqGYY6RUHGgKqlG8VADB+gS1LMbybhmId5Xg7i5oZv
+fuJTXFXoi/s4iM5ZoFYW/sDYfzuz+UoG6v0iukPRxK1kSAlK9elfpPhybSSQxVzJ
+1URIEtbH1ABaVsBi49+PEOJerMnk5zYlLnYG4So6mVqyiZ0TkxQwAyzv4Po4G7Bp
+r8W7iP+IwHLw7UIxp1+o4DcCAwEAAQ==
+-----END PUBLIC KEY-----

+ 51 - 0
SicboSubWs/etc/key/SICBO_OTHER/PrivateKeyCP.pem

@@ -0,0 +1,51 @@
+-----BEGIN RSA PRIVATE KEY-----
+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
+-----END RSA PRIVATE KEY-----

+ 14 - 0
SicboSubWs/etc/key/SICBO_OTHER/PublicKeyCP.pem

@@ -0,0 +1,14 @@
+-----BEGIN PUBLIC KEY-----
+MIICIjANBgkqhkiG9w0BAQEFAAOCAg8AMIICCgKCAgEAixlVLbyCKUbcIzx8BxFb
+kmBRSyv9WvY96eck2G8N1PsR574Sy9ZadZseXRp4957zU4YomPBDtz61v/UWNuEL
+Qk6g++iZWSZZtNEjqfC76R2jlWjpk9Z332VopoQeR6Ll4N2cloEunbt77PKem9n1
+yBWt5VFaxSV0eznIn7PiRG6dZFJviVWyXprDrtx8ZUNPVdHMGOvFJXcN2CWeW9HP
+7v3luP2rs0j+ecsSPiAxSZUgHWI7sTNzwnaJewwb/8SIZ+P3Ku8nkEI6St82iwZ3
+BGHOkL1CNvAjC2ZYwNVzGNECm2wYMHnR2/G2NsdSzihtHiOdjCD3q2orMuRo6D2A
+a7qUvSLotNiKtykjuEHx9dueTbDeBU/mjZMH1dt1RJNQ3LGfBbYFZ1V34TJXXXqR
+1GqpDj5Z5WQ5UDYOnFf2yUP2UNmhxuvZDmad039O18LCSft5MtgsvD0hUkuDr4Po
+YZTgE4U5WSJoVcGw2NO3gYmJGqCWpciRBVSHQtnbiybgP8QfU5DH8IKKzARDxnxd
+MYlMo+AZSrcDbsFpwsLX8u0OwpNKXn2T+myDzwUJPmf+t6TB4+ih8PLO2ZU99ntq
+pNUoDDSBHXlH6PWISQ7U8EgIZIFuSroUQVBxxR5tx/g6DtyVOwODJJWBziWFJbN8
+2YUw+880/2Rce/pyaiuW8GMCAwEAAQ==
+-----END PUBLIC KEY-----

+ 14 - 0
SicboSubWs/etc/key/SICBO_OTHER/PublicKeyVT.pem

@@ -0,0 +1,14 @@
+-----BEGIN PUBLIC KEY-----
+MIICIjANBgkqhkiG9w0BAQEFAAOCAg8AMIICCgKCAgEApyJN+KKq1z0xw85nyqdn
+8Ab/yQNz+whe36Ik1vVmORR4GxAs43sNQdqcusNYvA+7gbFzVgdFWTR/tpdevXGE
+bFzQ16oM1YZ2qvU6gElVDrZ4roBVrRsNhEmFbFEvlMSz02qM9SjVW02hCyYo1PVL
+agAJXeeXIdnr+RdnvSh2HeavkguksBlY1n9nm0dLX6VKQHemvH4Rk8b4swL3Qw7d
+5ypigaGXv/teo1J/w0QAmNBBblqD/UlakDIaNHXbvPVknbLEVMvFy5ZX03MC1BRW
+vNTEeruoQwLQsNvvRK0jxXj190UvZ4sRWgutgsqYQSxoUJPL3gM2Ih3WkajJefOS
+C3TNyAHbnMSQyktxH5hViF5y7Iut9WLaNuKHWi3eyM2PdQbzAM77INq/2oOiDaT2
+6qh9BSX0wORJHFxWdQ9x92tSzVg6LYQbO64qa4ldZoTLoD60/my7SuuGVx3ORbF+
+PPxhahW7O0Zd61HPGS4VWdcCO6/AOfHuPniZuC6kvdC8JPl8pAsPAjbGnyj6XFs9
+3N4dXCmzEmvj1T6wwAUd2f+6d6Mv4UgpNWJCZKDzv0rshscvzvUXxQGzJDbTR4C5
+O3kKTdaN/uN7NQ1w5Rg2cFTBBtMOMNLj/uD7u5k9sg0Lopw9oe8bvmIDAcEEmBcn
+nkJJZIW/WWxFub3spkepbz0CAwEAAQ==
+-----END PUBLIC KEY-----

Alguns ficheiros não foram mostrados porque muitos ficheiros mudaram neste diff