using System; using System.Collections.Generic; using System.IO; using System.Text; using OpenQA.Selenium; using OpenQA.Selenium.Chrome; using CSVDownloader.Code; using CSVDownloader.Store.CreditCSVData; using CSVDownloader.Exceptions; using ExpectedConditions = OpenQA.Selenium.Support.UI.ExpectedConditions; namespace CSVDownloader.Web { class ZeusController : WebController { private readonly String url_ = "https://linkpt.cardservice.co.jp/merchant/"; private readonly int max_download_num_ = 20; private enum XpathKey { INPUT_LOGIN_USERNAME, INPUT_LOGIN_PASSWORD, BUTTON_CREDIT_KESSAI, CHECK_PARKING, RADIO_TARGET_SPAN, SELECT_TARGET_FROM_YYYY, SELECT_TARGET_FROM_MM, SELECT_TARGET_FROM_DD, SELECT_TARGET_TO_YYYY, SELECT_TARGET_TO_MM, SELECT_TARGET_TO_DD, BUTTON_DOWNLOAD_CSV, BUTTON_LOGOUT, SUBJECT, FRAME_MENU, FRAME_CONTENTS, }; private static String search_form_xpath = "//*[@id='deny_double_click']"; private IDictionary xpath_map_ = new Dictionary() { {XpathKey.INPUT_LOGIN_USERNAME,"//form[@name='loginForm']//input[@name='ID']" }, {XpathKey.INPUT_LOGIN_PASSWORD,"//*[@id='password']"}, {XpathKey.BUTTON_CREDIT_KESSAI,"//a[contains(@href,'batch_download_face')]" }, {XpathKey.CHECK_PARKING,$"{search_form_xpath}//input[@name='bang_list']" }, {XpathKey.RADIO_TARGET_SPAN,$"{search_form_xpath}//input[@name='date' and @value='period']" }, {XpathKey.SELECT_TARGET_FROM_YYYY,$"{search_form_xpath}//select[@name='spfy']" }, {XpathKey.SELECT_TARGET_FROM_MM,$"{search_form_xpath}//select[@name='spfm']" }, {XpathKey.SELECT_TARGET_FROM_DD,$"{search_form_xpath}//select[@name='spfd']" }, {XpathKey.SELECT_TARGET_TO_YYYY,$"{search_form_xpath}//select[@name='epfy']" }, {XpathKey.SELECT_TARGET_TO_MM,$"{search_form_xpath}//select[@name='epfm']" }, {XpathKey.SELECT_TARGET_TO_DD,$"{search_form_xpath}//select[@name='epfd']" }, {XpathKey.BUTTON_DOWNLOAD_CSV,$"{search_form_xpath}//input[@type='submit']" }, {XpathKey.BUTTON_LOGOUT,"//a[contains(@href,'logout')]" }, {XpathKey.FRAME_MENU,"//frame[@name='MENULIST']" }, {XpathKey.FRAME_CONTENTS,"//frame[@name='CONTENTS']" }, }; public ZeusController(ChromeDriver driver) : base(driver) { agent_ = CreditAgent.Zeus; } public override void SetParkingDic(IDictionary dic) { dic_ = new Dictionary(); // IPコードと駐車場名を分離。プログラムではIPコードのみ利用する。 foreach (var ele in dic) { if (ele.Key == "") { logger_.Warn($"検索キーが空白のためスキップ {ele.Value}"); continue; } String parking_name = ele.Key.Split(" ")[0].Trim(); dic_.Add(parking_name, ele.Value); } } public override ResultCode Login(LoginInfo info) { bool enter = true; try { driver_.Navigate().GoToUrl(url_); Send(xpath_map_[XpathKey.INPUT_LOGIN_USERNAME], info.user_name); Send(xpath_map_[XpathKey.INPUT_LOGIN_PASSWORD], info.password, enter); // ログイン後の「端末決済データダウンロード」が表示されることを確認する。 SwitchToFrame(xpath_map_[XpathKey.FRAME_MENU]); wait_.Until(ExpectedConditions.ElementToBeClickable(By.XPath(xpath_map_[XpathKey.BUTTON_CREDIT_KESSAI]))); SwitchToFrame(); } catch (Exception e) { logger_.Error(e.Message); return ResultCode.NG; } return ResultCode.OK; } public override ResultCode Download(DateTime from, DateTime to) { // クレジットカード承認結果一覧画面に移行 SwitchToFrame(xpath_map_[XpathKey.FRAME_MENU]); Click(xpath_map_[XpathKey.BUTTON_CREDIT_KESSAI]); SwitchToFrame(); //期間のFrom-Toを入力 SwitchToFrame(xpath_map_[XpathKey.FRAME_CONTENTS]); Click(xpath_map_[XpathKey.RADIO_TARGET_SPAN]); Select(xpath_map_[XpathKey.SELECT_TARGET_FROM_YYYY], from.ToString("yyyy")); Select(xpath_map_[XpathKey.SELECT_TARGET_FROM_MM], from.ToString("%M")); Select(xpath_map_[XpathKey.SELECT_TARGET_FROM_DD], from.ToString("%d")); Select(xpath_map_[XpathKey.SELECT_TARGET_TO_YYYY], to.ToString("yyyy")); Select(xpath_map_[XpathKey.SELECT_TARGET_TO_MM], to.ToString("%M")); Select(xpath_map_[XpathKey.SELECT_TARGET_TO_DD], to.ToString("%d")); // 駐車場一覧を取得 var parking_list = driver_.FindElementsByXPath(xpath_map_[XpathKey.CHECK_PARKING]); var tmp_list = new List(); int count = 0; // 一定件数ごとにダウンロード foreach (var parking in parking_list) { tmp_list.Add(parking); if (!parking.Selected) { parking.Click(); } if (tmp_list.Count == max_download_num_) { // ダウンロード処理 String filename = $"zeus_{count}.csv"; Click(xpath_map_[XpathKey.BUTTON_DOWNLOAD_CSV]); WaitForDownload(filename); // チェックを戻す foreach (var check in tmp_list) { if (check.Selected) { check.Click(); } } // クリアー処理 count++; tmp_list.Clear(); } } if (tmp_list.Count != 0) { String filename = $"zeus_{count}.csv"; Click(xpath_map_[XpathKey.BUTTON_DOWNLOAD_CSV]); WaitForDownload(filename); tmp_list.Clear(); } SwitchToFrame(); return ResultCode.OK; } public override ResultCode Logout() { SwitchToFrame(xpath_map_[XpathKey.FRAME_MENU]); Click(xpath_map_[XpathKey.BUTTON_LOGOUT]); return ResultCode.OK; } public override List GetCreditCSVDataList() { var result_list = new List(); // csvファイルパスの取得 var config = new CSVConfig() { header = true, }; var dir = new DirectoryInfo(DriverFactory.GetDownloadDir()); var sjis_enc = Encoding.GetEncoding("Shift-JIS"); var list = new List(); foreach (var file in dir.GetFiles()) { var result = ReadCsv(file.FullName, config, sjis_enc); list.AddRange(result); } bool failed_flg = false; var failed_parking_name_hs_table = new HashSet(); foreach (var line in list) { // 決済金額は「-」でセットされている場合があるので // その際は0とする。 var parking_name = line[(int)CreditCSVDataZeus.ColName.IP]; try { int amount = 0; int.TryParse(line[(int)Store.CreditCSVData.CreditCSVDataZeus.ColName.Amount], out amount); result_list.Add(new Store.CreditCSVData.CreditCSVDataZeus() { spot_id = GetSpotID(line[(int)Store.CreditCSVData.CreditCSVDataZeus.ColName.IP]), use_datetime = DateTime.Parse(line[(int)Store.CreditCSVData.CreditCSVDataZeus.ColName.UseDatetime]), ip = line[(int)Store.CreditCSVData.CreditCSVDataZeus.ColName.IP], device_no = line[(int)Store.CreditCSVData.CreditCSVDataZeus.ColName.DeviceNo], receipt_no = line[(int)Store.CreditCSVData.CreditCSVDataZeus.ColName.ReceiptNo], certificate_no = line[(int)Store.CreditCSVData.CreditCSVDataZeus.ColName.CertificateNo], status = line[(int)Store.CreditCSVData.CreditCSVDataZeus.ColName.Status], error_message = line[(int)Store.CreditCSVData.CreditCSVDataZeus.ColName.ErrorMessage], amount = amount, card_no = line[(int)Store.CreditCSVData.CreditCSVDataZeus.ColName.CardNo], expiration_date = line[(int)Store.CreditCSVData.CreditCSVDataZeus.ColName.ExpirationDate], brand = line[(int)Store.CreditCSVData.CreditCSVDataZeus.ColName.Brand], payment_type = line[(int)Store.CreditCSVData.CreditCSVDataZeus.ColName.PaymentType], jis_info = line[(int)Store.CreditCSVData.CreditCSVDataZeus.ColName.JISInfo], test = line[(int)Store.CreditCSVData.CreditCSVDataZeus.ColName.Test], order_no = line[(int)Store.CreditCSVData.CreditCSVDataZeus.ColName.OrderNo], }); } catch (ArgumentException) { failed_parking_name_hs_table.Add(parking_name); failed_flg = true; continue; } } if (failed_flg) { var error_list = new List(); logger_.Error("失敗駐車場名"); foreach (var ele in failed_parking_name_hs_table) { error_list.Add(new Store.ParkingCreditCardAgenciesSpotIDError() { creditcard_agencies_id = CreditAgenciesMap.GetID(agent_), creditcard_agencies_spot_name = ele }); logger_.Error($"駐車場 \"{ele}\""); } throw new SpotNameNotMatchException(error_list); } return result_list; } public override bool IsWorkDate() { /* * 金土日曜日のみに動作するように設定 * 金曜日までに情報が確定するため。それ以前に誤ったデータを取得することを防ぐ */ var week = DateTime.Now.DayOfWeek; return week == DayOfWeek.Friday || week == DayOfWeek.Saturday || week == DayOfWeek.Sunday; } } }