HomeController.cs 46 KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273747576777879808182838485868788899091929394959697989910010110210310410510610710810911011111211311411511611711811912012112212312412512612712812913013113213313413513613713813914014114214314414514614714814915015115215315415515615715815916016116216316416516616716816917017117217317417517617717817918018118218318418518618718818919019119219319419519619719819920020120220320420520620720820921021121221321421521621721821922022122222322422522622722822923023123223323423523623723823924024124224324424524624724824925025125225325425525625725825926026126226326426526626726826927027127227327427527627727827928028128228328428528628728828929029129229329429529629729829930030130230330430530630730830931031131231331431531631731831932032132232332432532632732832933033133233333433533633733833934034134234334434534634734834935035135235335435535635735835936036136236336436536636736836937037137237337437537637737837938038138238338438538638738838939039139239339439539639739839940040140240340440540640740840941041141241341441541641741841942042142242342442542642742842943043143243343443543643743843944044144244344444544644744844945045145245345445545645745845946046146246346446546646746846947047147247347447547647747847948048148248348448548648748848949049149249349449549649749849950050150250350450550650750850951051151251351451551651751851952052152252352452552652752852953053153253353453553653753853954054154254354454554654754854955055155255355455555655755855956056156256356456556656756856957057157257357457557657757857958058158258358458558658758858959059159259359459559659759859960060160260360460560660760860961061161261361461561661761861962062162262362462562662762862963063163263363463563663763863964064164264364464564664764864965065165265365465565665765865966066166266366466566666766866967067167267367467567667767867968068168268368468568668768868969069169269369469569669769869970070170270370470570670770870971071171271371471571671771871972072172272372472572672772872973073173273373473573673773873974074174274374474574674774874975075175275375475575675775875976076176276376476576676776876977077177277377477577677777877978078178278378478578678778878979079179279379479579679779879980080180280380480580680780880981081181281381481581681781881982082182282382482582682782882983083183283383483583683783883984084184284384484584684784884985085185285385485585685785885986086186286386486586686786886987087187287387487587687787887988088188288388488588688788888989089189289389489589689789889990090190290390490590690790890991091191291391491591691791891992092192292392492592692792892993093193293393493593693793893994094194294394494594694794894995095195295395495595695795895996096196296396496596696796896997097197297397497597697797897998098198298398498598698798898999099199299399499599699799899910001001100210031004100510061007100810091010101110121013101410151016101710181019102010211022102310241025102610271028102910301031103210331034103510361037103810391040104110421043104410451046104710481049105010511052105310541055105610571058105910601061106210631064106510661067106810691070107110721073107410751076107710781079108010811082108310841085
  1. using System;
  2. using System.Collections.Generic;
  3. using System.Linq;
  4. using System.Globalization;
  5. using System.Threading;
  6. using System.Threading.Tasks;
  7. using LotteryWebApp.Common;
  8. using LotteryWebApp.Extensions;
  9. using LotteryWebApp.Languages;
  10. using LotteryWebApp.Models;
  11. using LotteryWebApp.Service;
  12. using Microsoft.AspNetCore.Hosting;
  13. using Microsoft.AspNetCore.Http;
  14. using Microsoft.AspNetCore.Mvc;
  15. using Microsoft.Extensions.Configuration;
  16. using Newtonsoft.Json;
  17. using LotteryWebApp.Controllers;
  18. namespace LotteryWebApp.Areas.Millions.Controllers
  19. {
  20. [Area("Millions")]
  21. [ResponseCache(Duration = 0, Location = ResponseCacheLocation.None, NoStore = true)]
  22. public class HomeController : BaseController
  23. {
  24. private static readonly log4net.ILog log = log4net.LogManager.GetLogger(typeof(Program));
  25. IConfiguration configuration;
  26. private readonly IWebHostEnvironment webHostEnvironment;
  27. APIFunctions api = new APIFunctions();
  28. public HomeController(IConfiguration _configuration, IWebHostEnvironment hostEnvironment)
  29. {
  30. configuration = _configuration;
  31. webHostEnvironment = hostEnvironment;
  32. }
  33. public String GetParameter(String key)
  34. {
  35. return configuration.GetSection(key).Value;
  36. }
  37. public async Task<IActionResult> Index(
  38. string termType,
  39. String uuid,
  40. String mcuid,
  41. String phonenumber,
  42. String token
  43. )
  44. {
  45. HomeIndex_ViewModel model = new HomeIndex_ViewModel();
  46. try
  47. {
  48. CultureInfo currentCulture = Thread.CurrentThread.CurrentCulture;
  49. String lang = currentCulture.Name;
  50. String msisdnAuto = null;
  51. if (!CheckAuthToken())
  52. {
  53. if (token != null)
  54. {
  55. AutoLoginRequest autoLoginRequest = new AutoLoginRequest { token = token };
  56. AutoLoginResponse autoLoginResponse = await api.AutoLoginApiAsync(configuration, autoLoginRequest);
  57. if (autoLoginResponse.code == Code.SUCCESS_CODE)
  58. {
  59. string msisdnReal = validateMsisdn(autoLoginResponse.data.msisdn.Substring(1));
  60. if (msisdnReal == "") return RedirectToAction("Login", "Account", new { area = "" });
  61. CheckAccountRequest checkAccountRequest = new CheckAccountRequest
  62. {
  63. msisdn = msisdnReal,
  64. channel = Constants.WEB_CHANNEL,
  65. language = lang == "en" ? "0" : "1"
  66. };
  67. CheckAccountResponse checkAccountResponse = api.CheckAccountApi(configuration, checkAccountRequest);
  68. if (checkAccountResponse.status == Code.SUCCESS)
  69. {
  70. string tokenGetReal = checkAccountResponse.token;
  71. HttpContext.Session.SetComplexData("msisdn", msisdnReal);
  72. CreateAuthToken();
  73. HttpContext.Session.SetComplexData("token", tokenGetReal);
  74. UserGetProfileRequest userGetProfileRequest = new UserGetProfileRequest { users = msisdnReal, token = tokenGetReal };
  75. Profile profileGet = api.UserLoadProfileApi(configuration, userGetProfileRequest);
  76. HttpContext.Session.SetComplexData("profile", profileGet);
  77. UserStatusRequest userStatusRequest = new UserStatusRequest { users = msisdnReal, token = tokenGetReal };
  78. UserStatus userStatusGet = api.GetUserStatusApi(configuration, userStatusRequest);
  79. HttpContext.Session.SetComplexData("userStatus", userStatusGet);
  80. }
  81. else
  82. {
  83. return RedirectToAction("Login", "Account", new { area = "" });
  84. }
  85. }
  86. }
  87. else if (uuid != null)
  88. {
  89. String res = await CheckAutoLogin(log, uuid);
  90. if (res != null)
  91. {
  92. dynamic json = JsonConvert.DeserializeObject(res);
  93. if (json["code"] == "200" && json["errorCode"] == "200")
  94. {
  95. msisdnAuto = json["data"]["msisdn"];
  96. }
  97. }
  98. String msisdnDetect = validateMsisdn(msisdnAuto.Substring(1));
  99. if (msisdnDetect != "")
  100. {
  101. RegisterRequest request = new RegisterRequest { Msisdn = msisdnDetect };
  102. RegisterResponse reset = api.UserForgotPasswordApi(configuration, request);
  103. if (reset.status == Code.SUCCESS)
  104. {
  105. HttpContext.Session.Remove("regInfos");
  106. HttpContext.Session.SetComplexData("msisdn", msisdnDetect);
  107. return RedirectToAction("Login", "Account", new { area = "", step = 2 });
  108. }
  109. }
  110. return RedirectToAction("Login", "Account", new { area = "" });
  111. }
  112. else if (phonenumber != null)
  113. {
  114. // simplified or same logic as original
  115. return RedirectToAction("Login", "Account", new { area = "" });
  116. }
  117. else
  118. {
  119. // If no token/uuid and not auth, verify existing session token
  120. var savedToken = HttpContext.Session.GetString("token");
  121. if (string.IsNullOrEmpty(savedToken))
  122. {
  123. return RedirectToAction("Login", "Account", new { area = "" });
  124. }
  125. }
  126. }
  127. Profile profile = HttpContext.Session.GetComplexData<Profile>("profile");
  128. UserStatus userStatus = HttpContext.Session.GetComplexData<UserStatus>("userStatus");
  129. model.termType = termType != null ? termType : Constants.Millions_CODE;
  130. model.userStatus = userStatus;
  131. model.profile = profile;
  132. model.listTerm = new List<Term>();
  133. String tokenGet = HttpContext.Session.GetComplexData<String>("token");
  134. String fromDate = DateTime.Now.AddDays(-2).ToString("dd/MM/yyyy");
  135. String toDate = DateTime.Now.ToString("dd/MM/yyyy");
  136. // Get Top Winner
  137. GetTopWinnerRequest getTopWinnerRequest = new GetTopWinnerRequest { type = lang == "en" ? "0" : "1", token = tokenGet };
  138. GetTopWininerResponse getTopWininerResponse = api.GetTopWinnerApi(configuration, getTopWinnerRequest);
  139. if (getTopWininerResponse.responseCode == Code.SUCCESS)
  140. {
  141. model.topWinner = getTopWininerResponse.list;
  142. HttpContext.Session.SetComplexData("topWinner", model.topWinner);
  143. }
  144. // Get Term Results
  145. //ResultOfTermRequest resultOfTermRequest = new ResultOfTermRequest
  146. //{
  147. // gameId = model.termType,
  148. // token = tokenGet,
  149. // type = Constants.TERM_HAS_NOT_RESULT_TYPE,
  150. // order = Constants.DECS,
  151. // fromDate = fromDate,
  152. // toDate = toDate,
  153. // rowsOnPage = Constants.ROW_ON_PAGE,
  154. // seqPage = "1",
  155. // id = Constants.ALL_DATA
  156. //};
  157. //ResultOfTermResponse result = api.GetResultOfTermApi(configuration, resultOfTermRequest);
  158. //if (result.responseCode == Code.SESSION_EXPIRED)
  159. //{
  160. // return RedirectToAction("Login", "Account", new { area = "" });
  161. //}
  162. //else if (result.responseCode == Code.SUCCESS)
  163. //{
  164. // model.listTerm = result.listTerm;
  165. //}
  166. if (!string.IsNullOrEmpty(termType))
  167. {
  168. HttpContext.Session.SetString("termType", termType);
  169. }
  170. }
  171. catch (Exception ex)
  172. {
  173. log.Error(ex);
  174. return RedirectToAction("Login", "Account", new { area = "" });
  175. }
  176. return View(model);
  177. }
  178. public async Task<IActionResult> GameHome(string termType)
  179. {
  180. HomeIndex_ViewModel model = new HomeIndex_ViewModel();
  181. try
  182. {
  183. var token = HttpContext.Session.GetComplexData<string>("token");
  184. if (string.IsNullOrEmpty(token) && !User.Identity.IsAuthenticated)
  185. {
  186. return RedirectToAction("Login", "Account", new { area = "" });
  187. }
  188. Profile profile = HttpContext.Session.GetComplexData<Profile>("profile");
  189. UserStatus userStatus = HttpContext.Session.GetComplexData<UserStatus>("userStatus");
  190. model.termType = termType != null ? termType : Constants.Millions_CODE;
  191. model.userStatus = userStatus;
  192. model.profile = profile;
  193. model.listTerm = new List<Term>();
  194. if (!string.IsNullOrEmpty(termType))
  195. {
  196. HttpContext.Session.SetString("termType", termType);
  197. }
  198. // Get Term Results for Jackpot
  199. string cachedBolet = HttpContext.Session.GetString("bolet");
  200. if (!string.IsNullOrEmpty(cachedBolet))
  201. {
  202. model.bolet = cachedBolet;
  203. model.lastResult = HttpContext.Session.GetString("lastResult");
  204. model.lastResultDate = HttpContext.Session.GetString("lastResultDate");
  205. model.nextRoundDate = HttpContext.Session.GetString("nextRoundDate");
  206. }
  207. else
  208. {
  209. String fromDate = DateTime.Now.AddDays(-2).ToString("dd/MM/yyyy");
  210. String toDate = DateTime.Now.ToString("dd/MM/yyyy");
  211. string lang = CultureInfo.CurrentCulture.Name;
  212. string langValue = (lang.StartsWith("en") || lang.StartsWith("fr")) ? "0" : "1";
  213. // Get Last Result
  214. ResultOfTermRequest resultOfTermRequest = new ResultOfTermRequest
  215. {
  216. gameId = model.termType,
  217. language = langValue,
  218. token = token,
  219. type = Constants.TERM_HAS_RESULT_TYPE,
  220. order = Constants.DECS,
  221. fromDate = fromDate,
  222. toDate = toDate,
  223. rowsOnPage = Constants.ROW_ON_PAGE,
  224. seqPage = "1",
  225. id = Constants.ALL_DATA
  226. };
  227. ResultOfTermResponse result = api.GetResultOfTermApi(configuration, resultOfTermRequest);
  228. if (result.responseCode == Code.SUCCESS && result.listTerm != null && result.listTerm.Count > 0)
  229. {
  230. model.bolet = result.listTerm[0].bolet;
  231. model.lastResult = result.listTerm[0].result;
  232. model.lastResultDate = result.listTerm[0].date_random;
  233. model.nextRoundDate = result.listTerm[0].date_end;
  234. HttpContext.Session.SetString("nextRoundDate", model.nextRoundDate ?? "");
  235. HttpContext.Session.SetString("bolet", model.bolet ?? "");
  236. HttpContext.Session.SetString("lastResult", model.lastResult ?? "");
  237. HttpContext.Session.SetString("lastResultDate", model.lastResultDate ?? "");
  238. }
  239. //// Get Next Round
  240. //ResultOfTermRequest nextRoundRequest = new ResultOfTermRequest
  241. //{
  242. // gameId = model.termType,
  243. // language = langValue,
  244. // token = token,
  245. // type = Constants.TERM_HAS_NOT_RESULT_TYPE,
  246. // order = Constants.ASC,
  247. // fromDate = DateTime.Now.ToString("dd/MM/yyyy"),
  248. // toDate = DateTime.Now.AddDays(7).ToString("dd/MM/yyyy"),
  249. // rowsOnPage = "1",
  250. // seqPage = "1",
  251. // id = Constants.ALL_DATA
  252. //};
  253. //ResultOfTermResponse nextResult = api.GetResultOfTermApi(configuration, nextRoundRequest);
  254. //if (nextResult.responseCode == Code.SUCCESS && nextResult.listTerm != null && nextResult.listTerm.Count > 0)
  255. //{
  256. // model.nextRoundDate = nextResult.listTerm[0].date_random;
  257. // HttpContext.Session.SetString("nextRoundDate", model.nextRoundDate ?? "");
  258. //}
  259. }
  260. }
  261. catch (Exception ex)
  262. {
  263. log.Error(ex);
  264. }
  265. return View(model);
  266. }
  267. public async Task<IActionResult> FAQ()
  268. {
  269. HomeIndex_ViewModel model = new HomeIndex_ViewModel();
  270. try
  271. {
  272. var token = HttpContext.Session.GetComplexData<string>("token");
  273. if (string.IsNullOrEmpty(token) && !User.Identity.IsAuthenticated)
  274. {
  275. return RedirectToAction("Login", "Account", new { area = "" });
  276. }
  277. Profile profile = HttpContext.Session.GetComplexData<Profile>("profile");
  278. UserStatus userStatus = HttpContext.Session.GetComplexData<UserStatus>("userStatus");
  279. model.userStatus = userStatus;
  280. model.profile = profile;
  281. }
  282. catch (Exception ex)
  283. {
  284. log.Error(ex);
  285. }
  286. return View(model);
  287. }
  288. public IActionResult More()
  289. {
  290. HomeIndex_ViewModel model = new HomeIndex_ViewModel();
  291. try
  292. {
  293. var token = HttpContext.Session.GetComplexData<string>("token");
  294. if (string.IsNullOrEmpty(token) && !User.Identity.IsAuthenticated)
  295. {
  296. return RedirectToAction("Login", "Account", new { area = "" });
  297. }
  298. Profile profile = HttpContext.Session.GetComplexData<Profile>("profile");
  299. UserStatus userStatus = HttpContext.Session.GetComplexData<UserStatus>("userStatus");
  300. model.userStatus = userStatus;
  301. model.profile = profile;
  302. }
  303. catch (Exception ex)
  304. {
  305. log.Error(ex);
  306. }
  307. return View(model);
  308. }
  309. public IActionResult Profile()
  310. {
  311. HomeIndex_ViewModel model = new HomeIndex_ViewModel();
  312. try
  313. {
  314. var token = HttpContext.Session.GetComplexData<string>("token");
  315. if (string.IsNullOrEmpty(token) && !User.Identity.IsAuthenticated)
  316. {
  317. return RedirectToAction("Login", "Account", new { area = "" });
  318. }
  319. Profile profile = HttpContext.Session.GetComplexData<Profile>("profile");
  320. UserStatus userStatus = HttpContext.Session.GetComplexData<UserStatus>("userStatus");
  321. model.userStatus = userStatus;
  322. model.profile = profile;
  323. }
  324. catch (Exception ex)
  325. {
  326. log.Error(ex);
  327. }
  328. return View(model);
  329. }
  330. [HttpPost]
  331. public IActionResult UserUpdateProfile(string fullName, string birthday)
  332. {
  333. try
  334. {
  335. string msisdn = HttpContext.Session.GetComplexData<string>("msisdn");
  336. string token = HttpContext.Session.GetComplexData<string>("token");
  337. if (string.IsNullOrEmpty(msisdn) || string.IsNullOrEmpty(token))
  338. {
  339. return Json(new { status = Code.ERROR, message = "Session expired" });
  340. }
  341. string birthdayFormat = birthday;
  342. if (!string.IsNullOrEmpty(birthday) && birthday.Contains("-"))
  343. {
  344. try {
  345. birthdayFormat = DateTime.ParseExact(birthday, "yyyy-MM-dd", CultureInfo.InvariantCulture).ToString("dd/MM/yyyy");
  346. } catch { }
  347. }
  348. UserUpdateProfileRequest request = new UserUpdateProfileRequest
  349. {
  350. users = msisdn,
  351. token = token,
  352. fullName = fullName,
  353. birthday = birthdayFormat
  354. };
  355. UserUpdateProfileResponse response = api.UserUpdateProfileApi(configuration, request);
  356. if (response.status == Code.SUCCESS)
  357. {
  358. // Update session profile
  359. Profile profile = HttpContext.Session.GetComplexData<Profile>("profile");
  360. if (profile != null)
  361. {
  362. profile.fullName = fullName;
  363. profile.birthday = birthdayFormat;
  364. HttpContext.Session.SetComplexData("profile", profile);
  365. }
  366. }
  367. return Json(response);
  368. }
  369. catch (Exception ex)
  370. {
  371. log.Error(ex);
  372. return Json(new { status = Code.ERROR, message = ex.Message });
  373. }
  374. }
  375. public IActionResult Rule()
  376. {
  377. HomeIndex_ViewModel model = new HomeIndex_ViewModel();
  378. try
  379. {
  380. var token = HttpContext.Session.GetComplexData<string>("token");
  381. if (string.IsNullOrEmpty(token) && !User.Identity.IsAuthenticated)
  382. {
  383. return RedirectToAction("Login", "Account", new { area = "" });
  384. }
  385. Profile profile = HttpContext.Session.GetComplexData<Profile>("profile");
  386. UserStatus userStatus = HttpContext.Session.GetComplexData<UserStatus>("userStatus");
  387. model.userStatus = userStatus;
  388. model.profile = profile;
  389. }
  390. catch (Exception ex)
  391. {
  392. log.Error(ex);
  393. }
  394. return View(model);
  395. }
  396. public IActionResult HowToPlay()
  397. {
  398. HomeIndex_ViewModel model = new HomeIndex_ViewModel();
  399. try
  400. {
  401. var token = HttpContext.Session.GetComplexData<string>("token");
  402. if (string.IsNullOrEmpty(token) && !User.Identity.IsAuthenticated)
  403. {
  404. return RedirectToAction("Login", "Account", new { area = "" });
  405. }
  406. Profile profile = HttpContext.Session.GetComplexData<Profile>("profile");
  407. UserStatus userStatus = HttpContext.Session.GetComplexData<UserStatus>("userStatus");
  408. model.userStatus = userStatus;
  409. model.profile = profile;
  410. }
  411. catch (Exception ex)
  412. {
  413. log.Error(ex);
  414. }
  415. return View(model);
  416. }
  417. public IActionResult Results(string termType, string fromDate, string toDate)
  418. {
  419. TermResultHistoryModel model = new TermResultHistoryModel();
  420. try
  421. {
  422. var token = HttpContext.Session.GetComplexData<string>("token");
  423. if (string.IsNullOrEmpty(token) && !User.Identity.IsAuthenticated)
  424. {
  425. return RedirectToAction("Login", "Account", new { area = "" });
  426. }
  427. Profile profile = HttpContext.Session.GetComplexData<Profile>("profile");
  428. UserStatus userStatus = HttpContext.Session.GetComplexData<UserStatus>("userStatus");
  429. model.termType = termType != null ? termType : (HttpContext.Session.GetString("termType") ?? Constants.Millions_CODE);
  430. // Set default dates if not provided (same as root implementation)
  431. string fromFormatted = fromDate != null ? fromDate : DateTime.Now.AddDays(-2).ToString("yyyy-MM-dd");
  432. string toFormatted = toDate != null ? toDate : DateTime.Now.ToString("yyyy-MM-dd");
  433. model.fromDate = fromFormatted;
  434. model.toDate = toFormatted;
  435. // Load initial results
  436. ResultOfTermRequest resultOfTermRequest = new ResultOfTermRequest
  437. {
  438. gameId = model.termType,
  439. token = token,
  440. type = Constants.TERM_HAS_RESULT_TYPE,
  441. order = Constants.DECS,
  442. fromDate = DateTime.ParseExact(fromFormatted, "yyyy-MM-dd", CultureInfo.InvariantCulture).ToString("dd/MM/yyyy"),
  443. toDate = DateTime.ParseExact(toFormatted, "yyyy-MM-dd", CultureInfo.InvariantCulture).ToString("dd/MM/yyyy"),
  444. rowsOnPage = Constants.ROW_ON_PAGE,
  445. seqPage = "1",
  446. id = Constants.ALL_DATA
  447. };
  448. ResultOfTermResponse result = api.GetResultOfTermApi(configuration, resultOfTermRequest);
  449. if (result.responseCode == Code.SUCCESS)
  450. {
  451. model.listTerm = result.listTerm ?? new List<Term>();
  452. }
  453. else
  454. {
  455. model.listTerm = new List<Term>();
  456. }
  457. }
  458. catch (Exception ex)
  459. {
  460. log.Error(ex);
  461. model.listTerm = new List<Term>();
  462. }
  463. return View(model);
  464. }
  465. public IActionResult TermResultHistory(string termType, string fromDate, string toDate)
  466. {
  467. TermResultHistoryModel model = new TermResultHistoryModel();
  468. try
  469. {
  470. var token = HttpContext.Session.GetComplexData<string>("token");
  471. if (string.IsNullOrEmpty(token)) return Json(new { status = "error", message = "Session expired" });
  472. string fromFormatted = fromDate != null ? fromDate : DateTime.Now.AddDays(-2).ToString("yyyy-MM-dd");
  473. string toFormatted = toDate != null ? toDate : DateTime.Now.ToString("yyyy-MM-dd");
  474. model.termType = termType;
  475. model.fromDate = fromFormatted;
  476. model.toDate = toFormatted;
  477. ResultOfTermRequest request = new ResultOfTermRequest
  478. {
  479. gameId = termType,
  480. token = token,
  481. type = Constants.TERM_HAS_RESULT_TYPE,
  482. order = Constants.DECS,
  483. fromDate = DateTime.ParseExact(fromFormatted, "yyyy-MM-dd", CultureInfo.InvariantCulture).ToString("dd/MM/yyyy"),
  484. toDate = DateTime.ParseExact(toFormatted, "yyyy-MM-dd", CultureInfo.InvariantCulture).ToString("dd/MM/yyyy"),
  485. rowsOnPage = Constants.ROW_ON_PAGE,
  486. seqPage = "1",
  487. id = Constants.ALL_DATA
  488. };
  489. ResultOfTermResponse result = api.GetResultOfTermApi(configuration, request);
  490. if (result.responseCode == Code.SUCCESS)
  491. {
  492. model.listTerm = result.listTerm ?? new List<Term>();
  493. }
  494. else
  495. {
  496. model.listTerm = new List<Term>();
  497. }
  498. }
  499. catch (Exception ex)
  500. {
  501. log.Error(ex);
  502. model.listTerm = new List<Term>();
  503. }
  504. return PartialView("_TermResultHistoryV2", model);
  505. }
  506. public IActionResult TermResultHistoryGrouped(string fromDate, string toDate)
  507. {
  508. try
  509. {
  510. var token = HttpContext.Session.GetComplexData<string>("token");
  511. if (string.IsNullOrEmpty(token)) return Json(new { status = "error", message = "Session expired" });
  512. string fromFormatted = fromDate != null ? fromDate : DateTime.Now.AddDays(-2).ToString("yyyy-MM-dd");
  513. string toFormatted = toDate != null ? toDate : DateTime.Now.ToString("yyyy-MM-dd");
  514. string[] gameIds = { Constants.Millions_CODE };
  515. var allTerms = new List<Term>();
  516. foreach (var gid in gameIds)
  517. {
  518. ResultOfTermRequest request = new ResultOfTermRequest
  519. {
  520. gameId = gid,
  521. token = token,
  522. type = Constants.TERM_HAS_RESULT_TYPE,
  523. order = Constants.DECS,
  524. fromDate = DateTime.ParseExact(fromFormatted, "yyyy-MM-dd", CultureInfo.InvariantCulture).ToString("dd/MM/yyyy"),
  525. toDate = DateTime.ParseExact(toFormatted, "yyyy-MM-dd", CultureInfo.InvariantCulture).ToString("dd/MM/yyyy"),
  526. rowsOnPage = "50",
  527. seqPage = "1",
  528. id = Constants.ALL_DATA
  529. };
  530. ResultOfTermResponse result = api.GetResultOfTermApi(configuration, request);
  531. if (result.responseCode == Code.SUCCESS && result.listTerm != null)
  532. {
  533. allTerms.AddRange(result.listTerm);
  534. }
  535. }
  536. // Group by date part of date_random
  537. var grouped = allTerms.GroupBy(x => {
  538. DateTime dt;
  539. if (DateTime.TryParse(x.date_random, out dt))
  540. return dt.Date;
  541. return DateTime.MinValue;
  542. })
  543. .Where(g => g.Key != DateTime.MinValue)
  544. .OrderByDescending(g => g.Key)
  545. .ToList();
  546. return PartialView("_TermResultHistoryGrouped", grouped);
  547. }
  548. catch (Exception ex)
  549. {
  550. log.Error(ex);
  551. return PartialView("_TermResultHistoryGrouped", new List<IGrouping<DateTime, Term>>());
  552. }
  553. }
  554. public IActionResult History(string termType, string status, string seqPage)
  555. {
  556. UserTicketHistoryModel model = new UserTicketHistoryModel();
  557. try
  558. {
  559. var token = HttpContext.Session.GetComplexData<string>("token");
  560. if (string.IsNullOrEmpty(token) && !User.Identity.IsAuthenticated)
  561. {
  562. return RedirectToAction("Login", "Account", new { area = "" });
  563. }
  564. string msisdn = HttpContext.Session.GetComplexData<string>("msisdn");
  565. model.termType = termType ?? Constants.Millions_CODE;
  566. model.status = status ?? Constants.ALL_DATA; // -1 for all, or 0, 1, 2
  567. model.seqPage = seqPage ?? "1";
  568. UserTicketRequest request = new UserTicketRequest
  569. {
  570. gameId = model.termType,
  571. msisdn = msisdn,
  572. token = token,
  573. type = model.status,
  574. order = Constants.DECS,
  575. rowsOnPage = Constants.ROW_ON_PAGE,
  576. seqPage = model.seqPage
  577. };
  578. UserTicketResponse result = api.GetUserTicketApi(configuration, request);
  579. if (result.responseCode == Code.SUCCESS)
  580. {
  581. model.listTicket = result.listTicket ?? new List<Ticket>();
  582. model.totalPage = result.totalPage;
  583. }
  584. else
  585. {
  586. model.listTicket = new List<Ticket>();
  587. model.totalPage = "0";
  588. }
  589. }
  590. catch (Exception ex)
  591. {
  592. log.Error(ex);
  593. model.listTicket = new List<Ticket>();
  594. }
  595. return View(model);
  596. }
  597. public IActionResult TermUserTicketHistory(string termType, string status, string seqPage)
  598. {
  599. UserTicketHistoryModel model = new UserTicketHistoryModel();
  600. try
  601. {
  602. var token = HttpContext.Session.GetComplexData<string>("token");
  603. if (string.IsNullOrEmpty(token)) return Json(new { status = "error", message = "Session expired" });
  604. string msisdn = HttpContext.Session.GetComplexData<string>("msisdn");
  605. model.termType = termType;
  606. model.status = status;
  607. model.seqPage = seqPage ?? "1";
  608. UserTicketRequest request = new UserTicketRequest
  609. {
  610. gameId = termType,
  611. msisdn = msisdn,
  612. token = token,
  613. type = status,
  614. order = Constants.DECS,
  615. rowsOnPage = Constants.ROW_ON_PAGE,
  616. seqPage = model.seqPage
  617. };
  618. UserTicketResponse result = api.GetUserTicketApi(configuration, request);
  619. if (result.responseCode == Code.SUCCESS)
  620. {
  621. model.listTicket = result.listTicket ?? new List<Ticket>();
  622. model.totalPage = result.totalPage;
  623. }
  624. else
  625. {
  626. model.listTicket = new List<Ticket>();
  627. model.totalPage = "0";
  628. }
  629. }
  630. catch (Exception ex)
  631. {
  632. log.Error(ex);
  633. model.listTicket = new List<Ticket>();
  634. }
  635. return PartialView("_TermUserTicketHistory", model);
  636. }
  637. [HttpPost]
  638. [ValidateAntiForgeryToken]
  639. public IActionResult TermResult(string termType)
  640. {
  641. try
  642. {
  643. var token = HttpContext.Session.GetComplexData<string>("token");
  644. if (string.IsNullOrEmpty(token)) return Json(new { responseCode = Code.SESSION_EXPIRED, responseMessage = "Session expired" });
  645. string lang = CultureInfo.CurrentCulture.Name;
  646. string langValue = (lang.StartsWith("en") || lang.StartsWith("fr")) ? "0" : "1";
  647. ResultOfTermRequest request = new ResultOfTermRequest
  648. {
  649. gameId = termType,
  650. language = langValue,
  651. token = token,
  652. type = Constants.TERM_HAS_NOT_RESULT_TYPE,
  653. order = Constants.DECS,
  654. rowsOnPage = "5",
  655. seqPage = "1",
  656. id = Constants.ALL_DATA
  657. };
  658. ResultOfTermResponse result = api.GetResultOfTermApi(configuration, request);
  659. return Json(result);
  660. }
  661. catch (Exception ex)
  662. {
  663. log.Error(ex);
  664. return Json(new { responseCode = Code.ERROR, responseMessage = ex.Message });
  665. }
  666. }
  667. [HttpPost]
  668. public IActionResult ConfirmTicketData([FromBody] ConfirmTicketDataRequest request)
  669. {
  670. try
  671. {
  672. var token = HttpContext.Session.GetComplexData<string>("token");
  673. var msisdn = HttpContext.Session.GetComplexData<string>("msisdn");
  674. if (string.IsNullOrEmpty(token)) return Json(new { responseCode = Code.SESSION_EXPIRED, responseMessage = "Session expired" });
  675. request.token = token;
  676. request.msisdn = msisdn;
  677. request.language = CultureInfo.CurrentCulture.Name.StartsWith("en") ? "0" : "1";
  678. request.requestId = Guid.NewGuid().ToString();
  679. // DEBUG: Log request data
  680. var ticketDebug = request.ticket != null ? string.Join("; ", request.ticket.Select(t => $"code={t.code}, money={t.money}")) : "NULL";
  681. log.Info($"[ConfirmTicketData] gameId={request.gameId}, msisdn={request.msisdn}, tickets=[{ticketDebug}]");
  682. ConfirmTicketDataResponse response = api.ConfirmTicketDataApi(configuration, request);
  683. // DEBUG: Log response
  684. log.Info($"[ConfirmTicketData] Response: code={response.responseCode}, msg={response.responseMessage}, transId={response.transId}");
  685. return Json(response);
  686. }
  687. catch (Exception ex)
  688. {
  689. log.Error(ex);
  690. return Json(new { responseCode = Code.ERROR, responseMessage = ex.Message });
  691. }
  692. }
  693. [HttpPost]
  694. public IActionResult ConfirmOTP([FromBody] ConfirmOTPRequest request)
  695. {
  696. try
  697. {
  698. var token = HttpContext.Session.GetComplexData<string>("token");
  699. var msisdn = HttpContext.Session.GetComplexData<string>("msisdn");
  700. if (string.IsNullOrEmpty(token)) return Json(new { responseCode = Code.SESSION_EXPIRED, responseMessage = "Session expired" });
  701. request.token = token;
  702. request.msisdn = msisdn;
  703. ConfirmOTPResponse response = api.ConfirmOTPApi(configuration, request);
  704. return Json(response);
  705. }
  706. catch (Exception ex)
  707. {
  708. log.Error(ex);
  709. return Json(new { responseCode = Code.ERROR, responseMessage = ex.Message });
  710. }
  711. }
  712. [HttpPost]
  713. public IActionResult SendOTP()
  714. {
  715. try
  716. {
  717. var token = HttpContext.Session.GetComplexData<string>("token");
  718. var msisdn = HttpContext.Session.GetComplexData<string>("msisdn");
  719. if (string.IsNullOrEmpty(token)) return Json(new { responseCode = Code.SESSION_EXPIRED, responseMessage = "Session expired" });
  720. SendOTPRequest request = new SendOTPRequest
  721. {
  722. msisdn = msisdn,
  723. token = token,
  724. language = CultureInfo.CurrentCulture.Name.StartsWith("en") ? "0" : "1",
  725. channel = configuration.GetSection("channel").Value
  726. };
  727. SendOTPResponse response = api.SendOTPApi(configuration, request);
  728. return Json(response);
  729. }
  730. catch (Exception ex)
  731. {
  732. log.Error(ex);
  733. return Json(new { responseCode = Code.ERROR, responseMessage = ex.Message });
  734. }
  735. }
  736. [HttpPost]
  737. public IActionResult ConfirmBuyingTicketV2([FromBody] ConfirmBuyingTicketRequest request)
  738. {
  739. try
  740. {
  741. var token = HttpContext.Session.GetComplexData<string>("token");
  742. var msisdn = HttpContext.Session.GetComplexData<string>("msisdn");
  743. if (string.IsNullOrEmpty(token)) return Json(new { responseCode = Code.SESSION_EXPIRED, responseMessage = "Session expired" });
  744. // Step 1: Verify OTP first
  745. ConfirmOTPRequest otpRequest = new ConfirmOTPRequest
  746. {
  747. otp = request.paymentCode,
  748. msisdn = msisdn,
  749. token = token,
  750. language = CultureInfo.CurrentCulture.Name.StartsWith("en") ? "0" : "1",
  751. channel = configuration.GetSection("channel").Value
  752. };
  753. ConfirmOTPResponse otpResponse = api.ConfirmOTPApi(configuration, otpRequest);
  754. if (otpResponse.responseCode != Code.SUCCESS)
  755. {
  756. return Json(new { responseCode = otpResponse.responseCode, responseMessage = otpResponse.responseMessage });
  757. }
  758. // Step 2: Proceed to Confirm buying
  759. request.token = token;
  760. request.msisdn = msisdn;
  761. request.requestId = Guid.NewGuid().ToString();
  762. request.language = CultureInfo.CurrentCulture.Name.StartsWith("en") ? "0" : "1";
  763. request.channel = configuration.GetSection("channel").Value;
  764. ConfirmBuyingTicketResponse response = api.ConfirmBuyingTicketApi(configuration, request);
  765. if (response.responseCode == Code.SUCCESS)
  766. {
  767. UpdateUserStatus(msisdn, token);
  768. }
  769. return Json(response);
  770. }
  771. catch (Exception ex)
  772. {
  773. log.Error(ex);
  774. return Json(new { responseCode = Code.ERROR, responseMessage = ex.Message });
  775. }
  776. }
  777. [HttpPost]
  778. public IActionResult ConfirmBuyingTicket([FromBody] ConfirmBuyingTicketRequest request)
  779. {
  780. try
  781. {
  782. var token = HttpContext.Session.GetComplexData<string>("token");
  783. var msisdn = HttpContext.Session.GetComplexData<string>("msisdn");
  784. if (string.IsNullOrEmpty(token)) return Json(new { responseCode = Code.SESSION_EXPIRED, responseMessage = "Session expired" });
  785. request.token = token;
  786. request.msisdn = msisdn;
  787. request.requestId = Guid.NewGuid().ToString();
  788. request.language = CultureInfo.CurrentCulture.Name.StartsWith("en") ? "0" : "1";
  789. request.channel = configuration.GetSection("channel").Value;
  790. ConfirmBuyingTicketResponse response = api.ConfirmBuyingTicketApi(configuration, request);
  791. if (response.responseCode == Code.SUCCESS)
  792. {
  793. UpdateUserStatus(msisdn, token);
  794. }
  795. return Json(new {
  796. responseCode = response.responseCode,
  797. responseMessage = response.responseMessage,
  798. transId = response.transId,
  799. orderId = response.orderId,
  800. userStatus = HttpContext.Session.GetComplexData<UserStatus>("userStatus")
  801. });
  802. }
  803. catch (Exception ex)
  804. {
  805. log.Error(ex);
  806. return Json(new { responseCode = Code.ERROR, responseMessage = ex.Message });
  807. }
  808. }
  809. public IActionResult BuyTicket(string termType)
  810. {
  811. try
  812. {
  813. var token = HttpContext.Session.GetComplexData<string>("token");
  814. if (string.IsNullOrEmpty(token) && !User.Identity.IsAuthenticated)
  815. {
  816. return RedirectToAction("Login", "Account", new { area = "" });
  817. }
  818. HomeIndex_ViewModel model = new HomeIndex_ViewModel();
  819. model.termType = termType ?? Constants.Millions_CODE;
  820. Profile profile = HttpContext.Session.GetComplexData<Profile>("profile");
  821. UserStatus userStatus = HttpContext.Session.GetComplexData<UserStatus>("userStatus");
  822. model.userStatus = userStatus;
  823. model.profile = profile;
  824. // Get active term
  825. ResultOfTermRequest request = new ResultOfTermRequest
  826. {
  827. gameId = model.termType,
  828. token = token,
  829. type = Constants.TERM_HAS_NOT_RESULT_TYPE,
  830. order = Constants.DECS,
  831. rowsOnPage = "1",
  832. seqPage = "1",
  833. id = Constants.ALL_DATA
  834. };
  835. ResultOfTermResponse result = api.GetResultOfTermApi(configuration, request);
  836. if (result.responseCode == Code.SUCCESS && result.listTerm != null && result.listTerm.Count > 0)
  837. {
  838. model.listTerm = result.listTerm;
  839. }
  840. else
  841. {
  842. model.listTerm = new List<Term>();
  843. }
  844. if (model.termType == Constants.PIC10_BIGSMALL_CODE || model.termType == Constants.PIC10_ODDEVEN_CODE)
  845. {
  846. ResultOfTermRequest pastRequest = new ResultOfTermRequest
  847. {
  848. gameId = model.termType,
  849. token = token,
  850. type = Constants.TERM_HAS_RESULT_TYPE,
  851. order = Constants.DECS,
  852. fromDate = DateTime.Now.AddDays(-10).ToString("dd/MM/yyyy"),
  853. toDate = DateTime.Now.ToString("dd/MM/yyyy"),
  854. rowsOnPage = "5",
  855. seqPage = "1",
  856. id = Constants.ALL_DATA
  857. };
  858. ResultOfTermResponse pastResult = api.GetResultOfTermApi(configuration, pastRequest);
  859. if (pastResult.responseCode == Code.SUCCESS && pastResult.listTerm != null)
  860. {
  861. var pastTerms = pastResult.listTerm.Take(5).ToList();
  862. pastTerms.Reverse(); // Display chronological order
  863. ViewBag.PastTerms = pastTerms;
  864. }
  865. else
  866. {
  867. ViewBag.PastTerms = new List<Term>();
  868. }
  869. }
  870. return View(model);
  871. }
  872. catch (Exception ex)
  873. {
  874. log.Error(ex);
  875. return RedirectToAction("GameHome", new { termType = termType });
  876. }
  877. }
  878. public IActionResult TransferWinMoney()
  879. {
  880. if (!CheckAuthToken())
  881. {
  882. return RedirectToAction("Login", "Account", new { area = "" });
  883. }
  884. HomeIndex_ViewModel model = new HomeIndex_ViewModel();
  885. model.profile = HttpContext.Session.GetComplexData<Profile>("profile");
  886. model.userStatus = HttpContext.Session.GetComplexData<UserStatus>("userStatus");
  887. return View(model);
  888. }
  889. [HttpPost]
  890. public IActionResult ConfirmTransfer(string otp, string phone, string amount, int channelPayment = 1)
  891. {
  892. try
  893. {
  894. var token = HttpContext.Session.GetComplexData<string>("token");
  895. var msisdn = HttpContext.Session.GetComplexData<string>("msisdn");
  896. if (string.IsNullOrEmpty(token)) return Json(new { status = Code.SESSION_EXPIRED, message = "Session expired" });
  897. var transferChannel = channelPayment == 2
  898. ? Constants.NATCASH_WALLET_TRANSFER
  899. : Constants.BASIC_WALLET_TRANSFER;
  900. // Step 1: Verify OTP
  901. ConfirmOTPRequest otpRequest = new ConfirmOTPRequest
  902. {
  903. otp = otp,
  904. msisdn = msisdn,
  905. token = token,
  906. language = CultureInfo.CurrentCulture.Name.StartsWith("en") ? "0" : "1",
  907. channel = configuration.GetSection("channel").Value
  908. };
  909. ConfirmOTPResponse otpResponse = api.ConfirmOTPApi(configuration, otpRequest);
  910. if (otpResponse.responseCode != Code.SUCCESS)
  911. {
  912. return Json(new { status = otpResponse.responseCode, message = otpResponse.responseMessage });
  913. }
  914. // Step 2: If OTP success, call Transfer Money Api
  915. TransferMoneyRequest xferRequest = new TransferMoneyRequest
  916. {
  917. msisdn = msisdn,
  918. msisdnReceive = phone,
  919. money = amount,
  920. otp = otp,
  921. token = token,
  922. channelPayment = transferChannel,
  923. language = CultureInfo.CurrentCulture.Name.StartsWith("en") ? "0" : "1",
  924. channel = configuration.GetSection("channel").Value
  925. };
  926. TransferMoneyResponse xferResponse = api.TransferMoneyApi(configuration, xferRequest);
  927. if (xferResponse.responseCode == Code.SUCCESS)
  928. {
  929. UpdateUserStatus(msisdn, token);
  930. }
  931. return Json(new {
  932. status = xferResponse.responseCode,
  933. message = xferResponse.responseMessage,
  934. paymentCode = xferResponse.paymentCode,
  935. responseCode = xferResponse.responseCode,
  936. userStatus = HttpContext.Session.GetComplexData<UserStatus>("userStatus")
  937. });
  938. }
  939. catch (Exception ex)
  940. {
  941. log.Error(ex);
  942. return Json(new { status = Code.ERROR, message = ex.Message });
  943. }
  944. }
  945. private void UpdateUserStatus(string msisdn, string token)
  946. {
  947. try
  948. {
  949. UserStatusRequest userStatusRequest = new UserStatusRequest { users = msisdn, token = token };
  950. UserStatus userStatusGet = api.GetUserStatusApi(configuration, userStatusRequest);
  951. if (userStatusGet != null)
  952. {
  953. HttpContext.Session.SetComplexData("userStatus", userStatusGet);
  954. }
  955. }
  956. catch (Exception ex)
  957. {
  958. log.Error("UpdateUserStatus Error: " + ex.Message);
  959. }
  960. }
  961. public IActionResult Logout()
  962. {
  963. ClearCache();
  964. return Redirect(GetParameter(Constants.SUB_DOMAIN) + "/Account/Login");
  965. }
  966. }
  967. }