Você não pode selecionar mais de 25 tópicos Os tópicos devem começar com uma letra ou um número, podem incluir traços ('-') e podem ter até 35 caracteres.

259 linhas
11KB

  1. using System;
  2. using System.Collections.Generic;
  3. using System.IO;
  4. using System.Text;
  5. using OpenQA.Selenium;
  6. using OpenQA.Selenium.Chrome;
  7. using CSVDownloader.Code;
  8. using CSVDownloader.Store.CreditCSVData;
  9. using CSVDownloader.Exceptions;
  10. using ExpectedConditions = OpenQA.Selenium.Support.UI.ExpectedConditions;
  11. namespace CSVDownloader.Web {
  12. class ZeusController : WebController {
  13. private readonly String url_ = "https://linkpt.cardservice.co.jp/merchant/";
  14. private readonly int max_download_num_ = 20;
  15. private enum XpathKey {
  16. INPUT_LOGIN_USERNAME,
  17. INPUT_LOGIN_PASSWORD,
  18. BUTTON_CREDIT_KESSAI,
  19. CHECK_PARKING,
  20. RADIO_TARGET_SPAN,
  21. SELECT_TARGET_FROM_YYYY,
  22. SELECT_TARGET_FROM_MM,
  23. SELECT_TARGET_FROM_DD,
  24. SELECT_TARGET_TO_YYYY,
  25. SELECT_TARGET_TO_MM,
  26. SELECT_TARGET_TO_DD,
  27. BUTTON_DOWNLOAD_CSV,
  28. BUTTON_LOGOUT,
  29. SUBJECT,
  30. FRAME_MENU,
  31. FRAME_CONTENTS,
  32. };
  33. private static String search_form_xpath = "//*[@id='deny_double_click']";
  34. private IDictionary<XpathKey, string> xpath_map_ = new Dictionary<XpathKey, string>()
  35. {
  36. {XpathKey.INPUT_LOGIN_USERNAME,"//form[@name='loginForm']//input[@name='ID']" },
  37. {XpathKey.INPUT_LOGIN_PASSWORD,"//*[@id='password']"},
  38. {XpathKey.BUTTON_CREDIT_KESSAI,"//a[contains(@href,'batch_download_face')]" },
  39. {XpathKey.CHECK_PARKING,$"{search_form_xpath}//input[@name='bang_list']" },
  40. {XpathKey.RADIO_TARGET_SPAN,$"{search_form_xpath}//input[@name='date' and @value='period']" },
  41. {XpathKey.SELECT_TARGET_FROM_YYYY,$"{search_form_xpath}//select[@name='spfy']" },
  42. {XpathKey.SELECT_TARGET_FROM_MM,$"{search_form_xpath}//select[@name='spfm']" },
  43. {XpathKey.SELECT_TARGET_FROM_DD,$"{search_form_xpath}//select[@name='spfd']" },
  44. {XpathKey.SELECT_TARGET_TO_YYYY,$"{search_form_xpath}//select[@name='epfy']" },
  45. {XpathKey.SELECT_TARGET_TO_MM,$"{search_form_xpath}//select[@name='epfm']" },
  46. {XpathKey.SELECT_TARGET_TO_DD,$"{search_form_xpath}//select[@name='epfd']" },
  47. {XpathKey.BUTTON_DOWNLOAD_CSV,$"{search_form_xpath}//input[@type='submit']" },
  48. {XpathKey.BUTTON_LOGOUT,"//a[contains(@href,'logout')]" },
  49. {XpathKey.FRAME_MENU,"//frame[@name='MENULIST']" },
  50. {XpathKey.FRAME_CONTENTS,"//frame[@name='CONTENTS']" },
  51. };
  52. public ZeusController(ChromeDriver driver) : base(driver) {
  53. agent_ = CreditAgent.Zeus;
  54. }
  55. public override void SetParkingDic(IDictionary<String, String> dic) {
  56. dic_ = new Dictionary<String, String>();
  57. // IPコードと駐車場名を分離。プログラムではIPコードのみ利用する。
  58. foreach (var ele in dic) {
  59. if (ele.Key == "") {
  60. logger_.Warn($"検索キーが空白のためスキップ {ele.Value}");
  61. continue;
  62. }
  63. String parking_name = ele.Key.Split(" ")[0].Trim();
  64. dic_.Add(parking_name, ele.Value);
  65. }
  66. }
  67. public override ResultCode Login(LoginInfo info) {
  68. bool enter = true;
  69. try {
  70. driver_.Navigate().GoToUrl(url_);
  71. Send(xpath_map_[XpathKey.INPUT_LOGIN_USERNAME], info.user_name);
  72. Send(xpath_map_[XpathKey.INPUT_LOGIN_PASSWORD], info.password, enter);
  73. // ログイン後の「端末決済データダウンロード」が表示されることを確認する。
  74. SwitchToFrame(xpath_map_[XpathKey.FRAME_MENU]);
  75. wait_.Until(ExpectedConditions.ElementToBeClickable(By.XPath(xpath_map_[XpathKey.BUTTON_CREDIT_KESSAI])));
  76. SwitchToFrame();
  77. } catch (Exception e) {
  78. logger_.Error(e.Message);
  79. return ResultCode.NG;
  80. }
  81. return ResultCode.OK;
  82. }
  83. public override ResultCode Download(DateTime from, DateTime to) {
  84. // クレジットカード承認結果一覧画面に移行
  85. SwitchToFrame(xpath_map_[XpathKey.FRAME_MENU]);
  86. Click(xpath_map_[XpathKey.BUTTON_CREDIT_KESSAI]);
  87. SwitchToFrame();
  88. //期間のFrom-Toを入力
  89. SwitchToFrame(xpath_map_[XpathKey.FRAME_CONTENTS]);
  90. Click(xpath_map_[XpathKey.RADIO_TARGET_SPAN]);
  91. Select(xpath_map_[XpathKey.SELECT_TARGET_FROM_YYYY], from.ToString("yyyy"));
  92. Select(xpath_map_[XpathKey.SELECT_TARGET_FROM_MM], from.ToString("%M"));
  93. Select(xpath_map_[XpathKey.SELECT_TARGET_FROM_DD], from.ToString("%d"));
  94. Select(xpath_map_[XpathKey.SELECT_TARGET_TO_YYYY], to.ToString("yyyy"));
  95. Select(xpath_map_[XpathKey.SELECT_TARGET_TO_MM], to.ToString("%M"));
  96. Select(xpath_map_[XpathKey.SELECT_TARGET_TO_DD], to.ToString("%d"));
  97. // 駐車場一覧を取得
  98. var parking_list = driver_.FindElementsByXPath(xpath_map_[XpathKey.CHECK_PARKING]);
  99. var tmp_list = new List<IWebElement>();
  100. int count = 0;
  101. // 一定件数ごとにダウンロード
  102. foreach (var parking in parking_list) {
  103. tmp_list.Add(parking);
  104. if (!parking.Selected) {
  105. parking.Click();
  106. }
  107. if (tmp_list.Count == max_download_num_) {
  108. // ダウンロード処理
  109. String filename = $"zeus_{count}.csv";
  110. Click(xpath_map_[XpathKey.BUTTON_DOWNLOAD_CSV]);
  111. WaitForDownload(filename);
  112. // チェックを戻す
  113. foreach (var check in tmp_list) {
  114. if (check.Selected) {
  115. check.Click();
  116. }
  117. }
  118. // クリアー処理
  119. count++;
  120. tmp_list.Clear();
  121. }
  122. }
  123. if (tmp_list.Count != 0) {
  124. String filename = $"zeus_{count}.csv";
  125. Click(xpath_map_[XpathKey.BUTTON_DOWNLOAD_CSV]);
  126. WaitForDownload(filename);
  127. tmp_list.Clear();
  128. }
  129. SwitchToFrame();
  130. return ResultCode.OK;
  131. }
  132. public override ResultCode Logout() {
  133. SwitchToFrame(xpath_map_[XpathKey.FRAME_MENU]);
  134. Click(xpath_map_[XpathKey.BUTTON_LOGOUT]);
  135. return ResultCode.OK;
  136. }
  137. public override List<CreditCSVData> GetCreditCSVDataList() {
  138. var result_list = new List<CreditCSVData>();
  139. // csvファイルパスの取得
  140. var config = new CSVConfig() {
  141. header = true,
  142. };
  143. var dir = new DirectoryInfo(DriverFactory.GetDownloadDir());
  144. var sjis_enc = Encoding.GetEncoding("Shift-JIS");
  145. var list = new List<String[]>();
  146. foreach (var file in dir.GetFiles()) {
  147. var result = ReadCsv(file.FullName, config, sjis_enc);
  148. list.AddRange(result);
  149. }
  150. bool failed_flg = false;
  151. var failed_parking_name_hs_table = new HashSet<String>();
  152. foreach (var line in list) {
  153. // 決済金額は「-」でセットされている場合があるので
  154. // その際は0とする。
  155. var parking_name = line[(int)CreditCSVDataZeus.ColName.IP];
  156. try {
  157. int amount = 0;
  158. int.TryParse(line[(int)Store.CreditCSVData.CreditCSVDataZeus.ColName.Amount], out amount);
  159. result_list.Add(new Store.CreditCSVData.CreditCSVDataZeus() {
  160. spot_id = GetSpotID(line[(int)Store.CreditCSVData.CreditCSVDataZeus.ColName.IP]),
  161. use_datetime = DateTime.Parse(line[(int)Store.CreditCSVData.CreditCSVDataZeus.ColName.UseDatetime]),
  162. ip = line[(int)Store.CreditCSVData.CreditCSVDataZeus.ColName.IP],
  163. device_no = line[(int)Store.CreditCSVData.CreditCSVDataZeus.ColName.DeviceNo],
  164. receipt_no = line[(int)Store.CreditCSVData.CreditCSVDataZeus.ColName.ReceiptNo],
  165. certificate_no = line[(int)Store.CreditCSVData.CreditCSVDataZeus.ColName.CertificateNo],
  166. status = line[(int)Store.CreditCSVData.CreditCSVDataZeus.ColName.Status],
  167. error_message = line[(int)Store.CreditCSVData.CreditCSVDataZeus.ColName.ErrorMessage],
  168. amount = amount,
  169. card_no = line[(int)Store.CreditCSVData.CreditCSVDataZeus.ColName.CardNo],
  170. expiration_date = line[(int)Store.CreditCSVData.CreditCSVDataZeus.ColName.ExpirationDate],
  171. brand = line[(int)Store.CreditCSVData.CreditCSVDataZeus.ColName.Brand],
  172. payment_type = line[(int)Store.CreditCSVData.CreditCSVDataZeus.ColName.PaymentType],
  173. jis_info = line[(int)Store.CreditCSVData.CreditCSVDataZeus.ColName.JISInfo],
  174. test = line[(int)Store.CreditCSVData.CreditCSVDataZeus.ColName.Test],
  175. order_no = line[(int)Store.CreditCSVData.CreditCSVDataZeus.ColName.OrderNo],
  176. });
  177. } catch (ArgumentException) {
  178. failed_parking_name_hs_table.Add(parking_name);
  179. failed_flg = true;
  180. continue;
  181. }
  182. }
  183. if (failed_flg) {
  184. var error_list = new List<Store.ParkingCreditCardAgenciesSpotIDError>();
  185. logger_.Error("失敗駐車場名");
  186. foreach (var ele in failed_parking_name_hs_table) {
  187. error_list.Add(new Store.ParkingCreditCardAgenciesSpotIDError() {
  188. creditcard_agencies_id = CreditAgenciesMap.GetID(agent_),
  189. creditcard_agencies_spot_name = ele
  190. });
  191. logger_.Error($"駐車場 \"{ele}\"");
  192. }
  193. throw new SpotNameNotMatchException(error_list);
  194. }
  195. return result_list;
  196. }
  197. public override bool IsWorkDate() {
  198. /*
  199. * 金土日曜日のみに動作するように設定
  200. * 金曜日までに情報が確定するため。それ以前に誤ったデータを取得することを防ぐ
  201. */
  202. var week = DateTime.Now.DayOfWeek;
  203. return week == DayOfWeek.Friday || week == DayOfWeek.Saturday || week == DayOfWeek.Sunday;
  204. }
  205. }
  206. }