示例#1
0
        public IEnumerable <ConfigureCommandOption> GetOptions()
        {
            yield return(new ConfigureCommandOption(
                             "jiraIsEnabled=",
                             "Set whether Jira Integration is enabled.",
                             v =>
            {
                var isEnabled = bool.Parse(v);
                jiraConfiguration.Value.SetIsEnabled(isEnabled);
                systemLog.Info($"Jira Integration IsEnabled set to: {isEnabled}");
            }));

            yield return(new ConfigureCommandOption(
                             "jiraBaseUrl=",
                             JiraConfigurationResource.JiraBaseUrlDescription,
                             v =>
            {
                jiraConfiguration.Value.SetBaseUrl(v);
                systemLog.Info($"Jira Integration base Url set to: {v}");
            }));

            yield return(new ConfigureCommandOption(
                             "jiraConnectAppUrl=",
                             "Set the URL for the Jira Connect App",
                             v =>
            {
                jiraConfiguration.Value.SetConnectAppUrl(v);
                systemLog.Info($"Jira Integration ConnectAppUrl set to: {v}");
            },
                             true));
        }
        public SystemResources(
            SystemResource[] systemResources,
            ISystemLog systemLog)
        {
            _systemLog       = systemLog;
            _systemResources = systemResources;

            _systemLog.Info("Created System Resources");
            _systemLog.Info(GetSystemSummary());
        }
        public async Task <IResultFromExtension <JiraIssue[]> > GetIssues(string[] workItemIds)
        {
            var workItemQuery = $"id in ({string.Join(", ", workItemIds.Select(x => x.ToUpper()))})";

            // WARNING: while the Jira API documentation says that validateQuery values of true/false are deprecated,
            // that is only valid for Jira Cloud. Jira Server only supports true/false
            var content = JsonConvert.SerializeObject(
                new
                { jql = workItemQuery, fields = new[] { "summary", "comment" }, maxResults = 10000, validateQuery = "false" });

            string errorMessage;

            try
            {
                using var response = await httpClient.PostAsync($"{baseUrl}/{baseApiUri}/search", new StringContent (content, Encoding.UTF8, "application/json"));

                if (response.IsSuccessStatusCode)
                {
                    var result = await GetResult <JiraSearchResult>(response);

                    if (result == null)
                    {
                        systemLog.Info("Jira Work Item data not found in response body");
                        return(ResultFromExtension <JiraIssue[]> .Failed("Jira Work Item data not found in response body"));
                    }

                    systemLog.Info($"Retrieved Jira Work Item data for work item ids {string.Join(", ", result.Issues.Select(wi => wi.Key))}");
                    return(ResultFromExtension <JiraIssue[]> .Success(result.Issues));
                }

                if (response.StatusCode == HttpStatusCode.Unauthorized || response.StatusCode == HttpStatusCode.Forbidden)
                {
                    systemLog.Info("Authentication failure, check the Jira access token is valid and has permissions to read work items");
                    return(ResultFromExtension <JiraIssue[]> .Failed("Authentication failure, check the Jira access token is valid and has permissions to read work items"));
                }

                var errorResult = await GetResult <JiraErrorResult>(response);

                errorMessage = $"Failed to retrieve Jira issues from {baseUrl}. Response Code: {response.StatusCode}{(errorResult?.ErrorMessages.Any() == true ? $" (Errors: {string.Join(", ", errorResult.ErrorMessages)})" : "")}";
            }
            catch (HttpRequestException e)
            {
                errorMessage = $"Failed to retrieve Jira issues '{string.Join(", ", workItemIds)}' from {baseUrl}. (Reason: {e.Message})";
            }
            catch (TaskCanceledException e)
            {
                errorMessage = $"Failed to retrieve Jira issues '{string.Join(", ", workItemIds)}' from {baseUrl}. (Reason: {e.Message})";
            }

            systemLog.Warn(errorMessage);

            return(ResultFromExtension <JiraIssue[]> .Failed(errorMessage));
        }
示例#4
0
        protected void ConnectionExecuteWithLog(
            Action <SqlConnection> connectionAction,
            string logSql)
        {
            using (var sqlConnection = new SqlConnection(DefaultConnectionString))
            {
                SystemLog.Info("Executing: " + logSql);

                sqlConnection.Open();
                connectionAction(sqlConnection);
                sqlConnection.Close();
            }
        }
        /// <summary>
        /// 刪除可受理案件
        /// </summary>
        /// <param name="log"></param>
        /// <param name="account"></param>
        /// <returns></returns>
        public Boolean RemoveAwaitAcceptLog(string CompCd, string Sn)
        {
            //using (DataBase.SETENG_Entities db = new DataBase.SETENG_Entities())
            //{
            //    db.Configuration.LazyLoadingEnabled = false;

            //    //var technicians = db.TVenderTechnician
            //    //                    .Include("TCALLOG")
            //    //                    .Where(x => x.TCALLOG.Any(g => g.Sn == Sn && g.Comp_Cd == CompCd));

            //    //if (technicians == null || technicians.Count() == 0)
            //    //    throw new NullReferenceException("[ERROR]=>技師刪除可受理案件時,找不到技師資訊");

            //    //technicians?.ForEach(x =>
            //    //{

            //    //    var rmLog = x.TCALLOG.SingleOrDefault(y => y.Sn == Sn && y.Comp_Cd == CompCd);

            //    //    x.TCALLOG.Remove(rmLog);

            //    //});

            //    var callog = db.TCALLOG
            //                   .Include("TVenderTechnician")
            //                   .Where(x => x.Sn == Sn && x.Comp_Cd == CompCd).SingleOrDefault();

            //    callog.TVenderTechnician = null;

            //    return db.SaveChanges() > 0;

            //}

            _logger.Info($"直接刪除TCallLogClaims,公司別:{CompCd},案件編號{Sn}");
            //直接刪除TCallLogClaims
            ExecuteNonQuery(@"Delete TCallLogClaims where Sn = @Sn AND CompCdTcallog = @CompCd"
                            , new SqlParameter("@Sn", Sn)
                            , new SqlParameter("@CompCd", CompCd));

            object DataCount = ExecuteScalar(@"SELECT count(*) From TCallLogClaims where Sn = @Sn AND CompCdTcallog = @CompCd"
                                             , new SqlParameter("@Sn", Sn)
                                             , new SqlParameter("@CompCd", CompCd));

            if (Convert.ToInt32(DataCount) == 0)
            {
                return(true);
            }
            else
            {
                return(false);
            }
        }
示例#6
0
        public void ConnectionExecuteWithLog(
            string connectionString,
            Action <SqlConnection> connectionAction,
            string logSql)
        {
            using (var sqlConnection = new SqlConnection(connectionString))
            {
                _systemLog.Info("Executing: " + logSql);

                sqlConnection.Open();
                connectionAction(sqlConnection);
                sqlConnection.Close();
            }
        }
        /// <summary>
        /// 认可技師
        /// </summary>
        /// <param name="data"></param>
        /// <returns></returns>
        public Boolean ConfirmTechnician(TvenderTechnician data)
        {
            _logger.Info($"認可技師-技師帳號:{data.Account}");

            //using (TransactionScope scope = new TransactionScope())
            //{

            //    _logger.Info($"認可技師-準備更新資料");

            //    var con = new Conditions<DataBase.TVenderTechnician>();

            //    con.And(g => g.Account == data.Account);
            //    con.And(g => g.Comp_Cd == data.CompCd);
            //    con.And(g => g.Vender_Cd == data.VenderCd);


            //    con.Allow(g => g.IsHQCheck,
            //              g => g.IsHQCheckRemark,
            //              g => g.HQCheckTime);

            //    _technicianRepo.Update(con, data);


            //    scope.Complete();
            //}

            return(true);
        }
        public IEnumerable <ConfigureCommandOption> GetOptions()
        {
            yield return(new ConfigureCommandOption("GitHubIsEnabled=", "Set whether GitHub issue tracker integration is enabled.", v =>
            {
                var isEnabled = bool.Parse(v);
                gitHubConfiguration.Value.SetIsEnabled(isEnabled);
                systemLog.Info($"GitHub Issue Tracker integration IsEnabled set to: {isEnabled}");
            }));

            yield return(new ConfigureCommandOption("GitHubBaseUrl=", GitHubConfigurationResource.GitHubBaseUrlDescription, v =>
            {
                gitHubConfiguration.Value.SetBaseUrl(v);
                systemLog.Info($"GitHub Issue Tracker integration base Url set to: {v}");
            }));
        }
        public TType GetDataFromJsonUrl <TType>(
            string targetUrl)
        {
            const int fiveMinutes = 300000;

            _systemLog.Info("Calling web service: " + targetUrl);

            var request = WebRequest.Create(targetUrl);

            request.Credentials = CredentialCache.DefaultCredentials;
            request.Timeout     = fiveMinutes;

            request.Method = "GET";

            var jsonData = "";

            using (var s = request.GetResponse().GetResponseStream())
            {
                using (var sr = new StreamReader(s))
                {
                    jsonData = sr.ReadToEnd();
                }
            }

            _javaScriptSerializer.MaxJsonLength = Int32.MaxValue;

            var models = _javaScriptSerializer.Deserialize <TType>(
                jsonData);

            return(models);
        }
示例#10
0
 public IEnumerable <ConfigureCommandOption> GetOptions()
 {
     yield return(new ConfigureCommandOption("AzureDevOpsIsEnabled=", "Set whether Azure DevOps issue tracker integration is enabled.",
                                             v =>
     {
         var isEnabled = bool.Parse(v);
         azureDevOpsConfiguration.Value.SetIsEnabled(isEnabled);
         systemLog.Info($"Azure DevOps Issue Tracker integration IsEnabled set to: {isEnabled}");
     }));
 }
        public bool ClaimResources(
            BankProcess bankProcess)
        {
            lock (_lockObject)
            {
                foreach (var systemResource in _systemResources)
                {
                    var resourceMaxAmount = bankProcess.GetResourceMaxAmount(systemResource.Name);

                    if (resourceMaxAmount > systemResource.CurrentAmount)
                    {
                        _systemLog.Info(string.Format("Not enought resources for {0}", bankProcess.ProcessName));
                        _systemLog.Info(GetSystemSummary());
                        return(false);
                    }
                }

                foreach (var systemResource in _systemResources)
                {
                    var resourceMaxAmount = bankProcess.GetResourceMaxAmount(systemResource.Name);

                    systemResource.ClaimResourceCount(resourceMaxAmount);
                }

                _systemLog.Info(string.Format("Claimed Resources for {0}", bankProcess.ProcessName));
                _systemLog.Info(GetSystemSummary());

                return(true);
            }
        }
        public override void Execute()
        {
            var doc = configurationStore.Get <GitHubConfiguration>(GitHubConfigurationStore.SingletonId);

            if (doc != null)
            {
                return;
            }

            systemLog.Info("Initializing GitHub integration settings");
            doc = new GitHubConfiguration();
            configurationStore.Create(doc);
        }
        public CitiMonthlyReturnsDataFileRecord[] ReadFile(
            string filePath)
        {
            var parser = SetupParserForCsv(filePath);

            var records = new List <CitiMonthlyReturnsDataFileRecord>();

            SkipHeaderRow(parser);

            while (!parser.EndOfData)
            {
                var parseFields = parser.ReadFields();

                var r = CreateFileRecordModel(parseFields);

                records.Add(r);
            }

            _systemLog.Info(string.Format("Closing file: '{0}'", filePath));

            return(records.ToArray());
        }
示例#14
0
 public string ToPlainText(string html)
 {
     try
     {
         var sb  = new StringBuilder();
         var doc = new HtmlDocument();
         doc.LoadHtml(html);
         // Custom traversal because HtmlAgilityPack's InnerText doesn't handle entities correctly or convert whitespace
         AppendPlainText(sb, doc.DocumentNode);
         return(sb.ToString());
     }
     catch (Exception ex)
     {
         systemLog.Info(ex, "Unable to convert Azure DevOps work item comment HTML to plain text.");
         return(html);
     }
 }
示例#15
0
        string?GetPersonalAccessToken(AdoProjectUrls adoUrl)
        {
            try
            {
                var azureDevOpsConnection = store.GetMostQualifiedConnection(adoUrl);

                systemLog.Info(azureDevOpsConnection?.PersonalAccessToken?.Value != null
                    ? $"Found the PersonalAccessToken for {adoUrl.ProjectUrl ?? adoUrl.OrganizationUrl}"
                    : $"Could not find a PersonalAccessToken for {adoUrl.ProjectUrl ?? adoUrl.OrganizationUrl}");

                return(azureDevOpsConnection?.PersonalAccessToken?.Value);
            }
            catch
            {
                return(null);
            }
        }
示例#16
0
        /// <summary>
        /// 單一推播
        /// </summary>
        /// <param name="data"></param>
        /// <returns></returns>
        public Boolean Exucte(JPushRequest data)
        {
            _logger.Info($"---------準備執行單一推播,公司:{data.CompCd},廠商:{data.VendorCd}----------");

            #region 找到技師資訊

            var con = new Conditions <DataBase.TVenderTechnician>();

            con.And(x => x.Comp_Cd == data.CompCd &&
                    x.Vender_Cd == data.VendorCd);


            con.And(x => data.Accounts.Contains(x.Account));

            var technicians = _technicianRepo.GetList(con);

            if (technicians == null || technicians.Count == 0)
            {
                _logger.Info($"[INFO]=>單一推播時,找不到技師群資訊");
                return(false);
            }

            #endregion

            #region 推播

            bool bo = _notifyRepo.Push(data.Content, data.Extras, RegIds(technicians));
            if (bo)
            {
                //推播給誰,需要紀錄
                technicians.ForEach(x =>
                {
                    if (x.RegistrationID == string.Empty)
                    {
                        this.Record(data.CompCd, data.Sn, x.Account, $"案件編號:{data.Sn},因為沒有推播ID,無法推播。");
                    }
                    else
                    {
                        this.Record(data.CompCd, data.Sn, x.Account, data.Content);
                    }
                });
            }
            #endregion

            return(true);
        }
示例#17
0
        public ActionResult TechnicianNotifyForChange(string Technician, string Sn)
        {
            try
            {
                if (Technician == null)
                {
                    throw new Exception("未選擇推播技師");
                }
                if (Sn == string.Empty)
                {
                    throw new Exception("未選擇案件");
                }

                string[]      CallogSn = Sn.Split(',');
                var           _user    = ((PtcIdentity)this.User.Identity).currentUser;
                List <string> NotifySn = new List <string>(); //Sn

                //Dictionary<string, string> Account = new Dictionary<string, string>(); //key:技師帳號、value:技師RegId
                Dictionary <string, string> OldAccount     = new Dictionary <string, string>(); //key:技師帳號、value:技師RegId
                TvenderTechnician           Techniciandata = new TvenderTechnician();
                #region 驗證技師資料
                Conditions <DataBase.TVenderTechnician> conTechnician = new Conditions <DataBase.TVenderTechnician>();

                _logger.Info($"廠商:{_user.VenderCd},開始驗證技師資料,被驗證的技師有{Technician}");
                conTechnician.And(x => x.Comp_Cd == _user.CompCd);          //公司別
                conTechnician.And(x => x.Vender_Cd == _user.VenderCd);      //廠商
                conTechnician.And(x => x.Enable == true);                   //啟用
                conTechnician.And(x => x.Account == Technician);            //廠商帳號
                TvenderTechnician TvenderTechniciandata = _TvenderTechnicianRepo.Get(conTechnician);
                if (TvenderTechniciandata == null)
                {
                    _logger.Info($"查無技師資料:{Technician}");
                    throw new Exception("勾選的技師驗證後無資料");
                }
                else
                {
                    _logger.Info($"加入推播,帳號:{Technician}");
                    //Account.Add(itemTechnician, data.RegistrationID);
                    Techniciandata = TvenderTechniciandata;
                }


                #endregion

                #region 檢查叫修編號狀態
                Conditions <DataBase.TCALLOG>           conCallog      = new Conditions <DataBase.TCALLOG>();
                Conditions <DataBase.TVenderTechnician> conTechniciang = new Conditions <DataBase.TVenderTechnician>();
                foreach (string itemSn in CallogSn)
                {
                    _logger.Info($"廠商:{_user.VenderCd},開始驗證案件資料,被驗證的案件有{itemSn}");
                    conCallog.And(x => x.Comp_Cd == _user.CompCd);
                    conCallog.And(x => x.Sn == itemSn);
                    conCallog.And(x => x.TAcceptedLog.Sn != null);
                    conCallog.Include(x => x.TAcceptedLog);
                    Tcallog data = _tcallogRepo.Get(conCallog);
                    if (data == null)
                    {
                        _logger.Info($"查無案件資料:{itemSn}");
                    }
                    else if (data.CloseSts > (byte)CloseSts.process)
                    {
                        _logger.Info($"案件:{itemSn},已經銷案。");
                    }
                    else
                    {
                        conTechniciang.And(x => x.Account == data.TacceptedLog.Account);
                        conTechniciang.And(x => x.Comp_Cd == data.CompCd);
                        conTechniciang.And(x => x.Vender_Cd == data.VenderCd);
                        var Techniciang = _TvenderTechnicianRepo.Get(conTechniciang);
                        _logger.Info($"加入推播,案件:{itemSn}");
                        //判斷若該案件的舊技師為新技師就不寫入NotifySn
                        if (TvenderTechniciandata.Account != data.TacceptedLog.Account)
                        {
                            NotifySn.Add(itemSn);
                            if (!OldAccount.Keys.Contains(data.TacceptedLog.Account))
                            {
                                OldAccount.Add(data.TacceptedLog.Account, Techniciang.RegistrationID);
                            }
                        }
                    }
                    conCallog      = new Conditions <DataBase.TCALLOG>();
                    conTechniciang = new Conditions <DataBase.TVenderTechnician>();
                }
                #endregion


                if (NotifySn.Count == 0)
                {
                    throw new Exception("勾選的案件驗證後無資料,請重新整理");
                }

                #region 更新案件技師資訊+推播
                var isSuccess = _callogService.ChangeNotificationForWeb(_user, NotifySn, Techniciandata, OldAccount);
                #endregion
                return(Json(new JsonResult()
                {
                    Data = new
                    {
                        IsSuccess = isSuccess,
                        Message = $"改派案件:{(isSuccess ? "成功" : "失敗")}"
                    }
                }));
            }
            catch (Exception ex)
            {
                _logger.Error(ex.Message);
                if (ex.InnerException != null)
                {
                    _logger.Error(ex.InnerException.Message);
                    if (ex.InnerException.InnerException != null)
                    {
                        _logger.Error(ex.InnerException.InnerException.Message);
                    }
                }
                return(Json(new JsonResult()
                {
                    Data = new
                    {
                        IsSuccess = false,
                        Message = $"改派案件失敗,原因:{ex.Message}"
                    }
                }));
            }
        }
示例#18
0
        /// <summary>
        /// [client]技師登入
        /// </summary>
        /// <param name="Account"></param>
        /// <param name="Password"></param>
        /// <returns></returns>
        public TvenderTechnician VendorLogin(string Account, string Password, string UUID)
        {
            _logger.Info($"APP登入-帳號:{Account},密碼:{Password},UUID:{UUID}");

            #region 取得技師資訊

            var con = new Conditions <DataBase.TVenderTechnician>();

            con.And(x => x.Account == Account);
            con.And(x => x.Password == Password);
            con.Include(x => x.TVENDER);
            con.And(x => x.TVENDER.Comp_Cd == "711");
            TvenderTechnician result = _technicianRepo.Get(con);

            #endregion 檢核技師相關欄位

            #region 相關驗證

            if (result == null)
            {
                _logger.Info("帳號或密碼不存在");
                throw new NullReferenceException($"登入失敗");
            }


            if (!result.Enable)
            {
                _logger.Info("帳號尚未啟用");
                throw new InvalidProgramException($"帳號尚未啟用");
            }

            var ConTusrven = new Conditions <DataBase.TUSRVENRELATION>();
            ConTusrven.And(x => x.Comp_Cd == result.CompCd);
            ConTusrven.And(x => x.Vender_Cd == result.VenderCd);
            var Tusrven = _tusrvenrelationRepo.Get(ConTusrven);

            if (Tusrven == null)
            {
                _logger.Info("廠商未服務711");
                throw new InvalidProgramException($"廠商未服務711");
            }

            //2018/06/19因為廠商輸入密碼錯誤6次會造成帳號被關閉且技師無法登入APP,經與玉萍討論,在決定檢核廠商的規則前,暫時不進行檢核 by 天生
            //if (_venderFactory.CheckVender(result.CompCd, Tusrven.User_Id) == false)
            //{
            //    _logger.Info("廠商已被關閉");
            //    throw new InvalidProgramException($"廠商已被關閉");
            //}

            if (!string.IsNullOrEmpty(result.DeviceID) && result.DeviceID != UUID)
            {
                _logger.Info("UUID重複");
                throw new ArgumentOutOfRangeException($"已經有其他設備登入過,是否強制登入?");
            }


            #endregion

            #region 寫入相關資訊

            _logger.Info($"APP登入-準備更新資訊");

            con.Allow(x => x.LastLoginTime);
            con.Allow(x => x.DeviceID);

            if (!_technicianRepo.Update(con, new TvenderTechnician()
            {
                Account = Account,
                Password = Password,
                DeviceID = UUID,
                LastLoginTime = DateTime.Now
            }))
            {
                throw new Exception("登入失敗");
            }

            #endregion

            return(result);
        }
示例#19
0
        /// <summary>
        /// 新增群組信息
        /// </summary>
        /// <param name="Data"></param>
        /// <param name="Accounts"></param>
        /// <returns></returns>
        public Boolean CreateTechnicianGroup(TtechnicianGroup Data, String[] Accounts)
        {
            //_logger.Info($"新增群組-群組名稱:{Data.GroupName}");

            #region 檢核群組信息是否重复

            var con = new Conditions <DataBase.TTechnicianGroup>();

            con.And(x => x.CompCd == Data.CompCd &&
                    x.VendorCd == Data.VendorCd &&
                    x.GroupName == Data.GroupName);

            //if (_technicianGroupRepo.IsExist(con))
            //    throw new IndexOutOfRangeException("[ERROR]=>新增群組,檢核已有該群組存在");

            #endregion

            using (TransactionScope scope = new TransactionScope())
            {
                _logger.Info($"新增群組-準備更新資料");

                #region 新增群組
                if (_technicianGroupRepo.IsExist(con))
                {
                    throw new Exception("群組名稱相同");
                }

                _technicianGroupRepo.Add(con, Data);

                var seq = _technicianGroupRepo.Get(con).Seq;

                #endregion

                #region 新增技師至群組

                if (Accounts != null)
                {
                    foreach (String account in Accounts)
                    {
                        TtechnicianGroupClaims technicianGroupClaims = new TtechnicianGroupClaims()
                        {
                            Seq      = seq,
                            CompCd   = Data.CompCd,
                            VendorCd = Data.VendorCd,
                            Account  = account
                        };

                        var cond = new Conditions <DataBase.TTechnicianGroupClaims>();
                        cond.And(x => x.Seq == seq &&
                                 x.CompCd == Data.CompCd &&
                                 x.VendorCd == Data.VendorCd &&
                                 x.Account == account);
                        if (!_technicianGroupClaimsRepo.Add(cond, technicianGroupClaims))
                        {
                            throw new Exception("[ERROR]=>新增技師至群組時,新增失敗");
                        }
                    }
                }

                #endregion

                scope.Complete();
            }
            return(true);
        }
示例#20
0
        /// <summary>
        /// 自動通知技師:
        /// 通常在立案當下呼叫的
        /// </summary>
        /// <param name="Comp_Cd"></param>
        /// <param name="Sn"></param>
        /// <returns></returns>
        public Boolean AutoNotification(string Comp_Cd, string Sn)
        {
            _logger.Info($"立案自動通知-公司別:{Comp_Cd},案件編號:{Sn}");

            #region 驗證與取得資訊

            //取得案件
            Tcallog callog = base.GetCallog(Comp_Cd, Sn);

            //取得廠商及底下的技師群組
            var venderCon = new Conditions <DataBase.TVENDER>();

            venderCon.And(x => x.Comp_Cd == callog.CompCd &&
                          x.Vender_Cd == callog.VenderCd);

            _logger.Info($"立案自動通知-公司別:{callog.CompCd}");
            _logger.Info($"立案自動通知-廠商別:{callog.VenderCd}");


            venderCon.Include(x => x.TTechnicianGroup
                              .Select(g => g.TTechnicianGroupClaims
                                      .Select(y => y.TVenderTechnician)));

            Tvender vender = _venderRepo.Get(venderCon);

            if (vender == null)
            {
                _logger.Error($"查無廠商-廠商別:{callog.VenderCd}");
                throw new Exception($"查無廠商");
            }

            #endregion

            //找到可以被自動推播的群組
            IEnumerable <TtechnicianGroup> groups    = vender.TTechnicianGroup;
            List <TtechnicianGroup>        techGroup = new List <TtechnicianGroup>();
            techGroup.AddRange(groups.Where(x => x.Responsible_Do.Contains(callog.Do)).ToList());
            if (groups.Where(x => x.Responsible_Do.Contains(callog.Do)).Count() == 0)
            {
                //沒有對應的課群組才撈區群組
                techGroup.AddRange(groups.Where(x => x.Responsible_Zo.Contains(callog.Zo)).ToList());
            }
            techGroup = techGroup.Distinct().ToList();

            //取出群組內技師並過濾
            Dictionary <string, string> accounts = new Dictionary <string, string>();

            //確認廠商是否有建立技師
            var venderTech = new Conditions <DataBase.TVenderTechnician>();
            venderTech.And(x => x.Comp_Cd == callog.CompCd &&
                           x.Vender_Cd == callog.VenderCd);
            var technicians = _technicianRepo.GetList(venderTech);

            //有建立技師,沒有建立群組則自動建立進行推播


            if (technicians.Count != 0 && groups.ToList().Count == 0)
            {
                _logger.Error($"查無群組自動建立-廠商別:{callog.VenderCd}");
                //取得廠商所負責的區域
                var venderZO = new Conditions <DataBase.TVNDZO>();
                venderZO.And(x => x.Comp_Cd == callog.CompCd &&
                             x.Vender_Cd == callog.VenderCd);
                var vndzos = _vndzoRepo.GetList(venderZO);

                string ZO = "";
                string DO = "";

                vndzos?.ForEach(vndzo =>
                {
                    ZO += "," + vndzo.Zo;
                    //取得各區對應的課別
                    var ZOCODE = new Conditions <DataBase.TZOCODE>();
                    ZOCODE.And(x => x.Comp_Cd == vndzo.CompCd &&
                               x.Z_O == vndzo.Zo &&
                               x.Upkeep_Sts == "Y");
                    var zocodes = _zocodeRepo.GetList(ZOCODE);
                    zocodes?.ForEach(zocode =>
                    {
                        DO += "," + zocode.DoCd;
                    });
                });

                //新增群組
                var con = new Conditions <DataBase.TTechnicianGroup>();
                con.And(x => x.CompCd == callog.CompCd);
                con.And(x => x.VendorCd == callog.VenderCd);
                TtechnicianGroup TGroup = new TtechnicianGroup();
                TGroup.CompCd         = callog.CompCd;
                TGroup.VendorCd       = callog.VenderCd;
                TGroup.GroupName      = "系統產生";
                TGroup.Responsible_Zo = ZO.Substring(1);
                TGroup.Responsible_Do = DO.Substring(1);

                if (!_technicianGroupRepo.Add(con, TGroup))
                {
                    throw new Exception("[ERROR]=>自動新增群組時,新增失敗");
                }
                else
                {
                    //重新取得群組
                    vender = _venderRepo.Get(venderCon);
                    TtechnicianGroup group = vender.TTechnicianGroup.SingleOrDefault();

                    _logger.Info($"自動新增技師群組對應主檔開始");
                    var Claimscon = new Conditions <DataBase.TTechnicianGroupClaims>();
                    TtechnicianGroupClaims TClaims = new TtechnicianGroupClaims();
                    TClaims.Seq      = group.Seq;
                    TClaims.CompCd   = callog.CompCd;
                    TClaims.VendorCd = callog.VenderCd;
                    //新增技師群組對應主檔
                    technicians?.ForEach(technician =>
                    {
                        Claimscon.And(x => x.Seq == group.Seq);
                        Claimscon.And(x => x.CompCd == group.CompCd);
                        Claimscon.And(x => x.VendorCd == group.VendorCd);
                        Claimscon.And(x => x.Account == technician.Account);
                        TClaims.Account = technician.Account;
                        try
                        {
                            _technicianGroupClaimsRepo.Add(Claimscon, TClaims);
                        }
                        catch (Exception)
                        {
                            _logger.Error($"自動新增技師群組對應主檔時新增失敗-公司別:{callog.CompCd},廠商別:{callog.VenderCd},技師帳號:{technician.Account}");
                        }
                        Claimscon = new Conditions <DataBase.TTechnicianGroupClaims>();
                    });
                    _logger.Info($"自動新增技師群組對應主檔結束");


                    technicians?.ForEach(claim =>
                    {
                        var current = claim;

                        _logger.Info($"立案自動通知-組合物件-尋覽技師名稱:{current.Account}");

                        //啟用
                        if (current.Enable)
                        {
                            try
                            {
                                if (!accounts.Keys.Contains(current.Account))
                                {
                                    accounts.Add(current.Account, current.RegistrationID);
                                }
                            }
                            catch (Exception ex)
                            {
                                _logger.Error($"立案自動通知-技師帳號:{current.Account},放入推播清單錯誤,原因:{ex.Message}");
                            }
                        }
                    });
                }
            }
            else
            {
                techGroup?.ForEach(group =>
                {
                    _logger.Info($"立案自動通知-組合物件-尋覽群組代號:{group.Seq}");

                    group.TTechnicianGroupClaims?.ForEach(claim =>
                    {
                        var current = claim.TVenderTechnician;

                        _logger.Info($"立案自動通知-組合物件-尋覽技師名稱:{current.Account}");

                        //啟用
                        if (current.Enable)
                        {
                            try
                            {
                                if (!accounts.Keys.Contains(current.Account))
                                {
                                    accounts.Add(current.Account, current.RegistrationID);
                                }
                            }
                            catch (Exception ex)
                            {
                                _logger.Error($"立案自動通知-技師帳號:{current.Account},放入推播清單錯誤,原因:{ex.Message}");
                            }
                        }
                    });
                });
            }

            //更新TCALLOG.TimePoint
            //var callogcon = new Conditions<DataBase.TCALLOG>();
            //callogcon.And(x => x.Comp_Cd == callog.CompCd);
            //callogcon.And(x => x.Sn == callog.Sn);
            //callogcon.Allow(x => x.TimePoint);

            //if (!_callogRepo.Update(callogcon, new Tcallog()
            //{
            //    TimePoint = 1
            //}))
            //    throw new Exception("更新TCALLOG.TimePoint失敗");


            if (callog.TacceptedLog == null)
            {
                //準備通知-寫入待認養
                accounts.ForEach(account =>
                {
                    try
                    {
                        _logger.Info($"準備通知-寫入待認養 帳號:{account.Key}");

                        #region 更新資料

                        _technicianProvider.AddAwaitAcceptLog(callog.CompCd, callog.Sn, account.Key);

                        #endregion
                    }
                    catch (Exception ex)
                    {
                        _logger.Error($"準備通知-寫入待認養 帳號:{account},通知發生錯誤,原因:{ex.Message}");
                        if (ex.InnerException != null)
                        {
                            _logger.Error(ex.InnerException.Message);
                            if (ex.InnerException.InnerException != null)
                            {
                                _logger.Error(ex.InnerException.InnerException.Message);
                            }
                        }
                        _logger.Error(ex.StackTrace);
                    }
                });

                //準備推播
                accounts.ForEach(account =>
                {
                    try
                    {
                        _logger.Info($"準備推播 帳號:{account.Key}");

                        string storeName = getStoreName(callog.CompCd, callog.StoreCd);
                        string CallLevel = callog.CallLevel == "1" ? "普通" : "緊急";

                        #region 推播訊息

                        _notifyFactory.Exucte(new JPushRequest(
                                                  callog.CompCd,
                                                  callog.VenderCd)
                        {
                            Sn      = callog.Sn,
                            Content = $"您有一筆新案件待認養,案件編號:{callog.Sn} 店名:{storeName} 叫修等級:{CallLevel}",
                            Title   = "認養案件",
                            Extras  = new Dictionary <string, string>()
                            {
                                { "FeatureName", "VenderAccept" }
                            }
                        }, account.Key, account.Value);
                        #endregion
                    }
                    catch (Exception ex)
                    {
                        _logger.Error($"準備推播 帳號:{account},通知發生錯誤,原因:{ex.Message}");
                        if (ex.InnerException != null)
                        {
                            _logger.Error(ex.InnerException.Message);
                            if (ex.InnerException.InnerException != null)
                            {
                                _logger.Error(ex.InnerException.InnerException.Message);
                            }
                        }
                        _logger.Error(ex.StackTrace);
                    }
                });
            }

            return(true);
        }
        public ActionResult TechnicianNotify(string[] Technician, string Sn)
        {
            try
            {
                if (Technician == null)
                {
                    throw new Exception("未選擇推播技師");
                }
                if (Sn == string.Empty)
                {
                    throw new Exception("未選擇案件");
                }

                string[] CallogSn = Sn.Split(',');
                var      _user    = ((PtcIdentity)this.User.Identity).currentUser;
                if (_user.CompCd == "")
                {
                    _user.CompCd = "711";
                }
                List <string> NotifySn = new List <string>();                            //Sn
                Dictionary <string, string> Account = new Dictionary <string, string>(); //key:技師帳號、value:技師RegId

                #region 驗證技師資料
                Conditions <DataBase.TVenderTechnician> conTechnician = new Conditions <DataBase.TVenderTechnician>();
                foreach (string itemTechnician in Technician)
                {
                    _logger.Info($"廠商:{_user.VenderCd},開始驗證技師資料,被驗證的技師有{itemTechnician}");
                    conTechnician.And(x => x.Comp_Cd == _user.CompCd);           //公司別
                    conTechnician.And(x => x.Vender_Cd == _user.VenderCd);       //廠商
                    conTechnician.And(x => x.Enable == true);                    //啟用
                    conTechnician.And(x => x.Account == itemTechnician);         //帳號
                    TvenderTechnician data = _TvenderTechnicianRepo.Get(conTechnician);
                    if (data == null)
                    {
                        _logger.Info($"查無技師資料:{itemTechnician}");
                    }
                    else
                    {
                        _logger.Info($"加入推播,帳號:{itemTechnician}");
                        Account.Add(itemTechnician, data.RegistrationID);
                    }
                    conTechnician = new Conditions <DataBase.TVenderTechnician>();
                }
                #endregion

                #region 檢查叫修編號狀態
                Conditions <DataBase.TCALLOG> conCallog = new Conditions <DataBase.TCALLOG>();
                foreach (string itemSn in CallogSn)
                {
                    _logger.Info($"廠商:{_user.VenderCd},開始驗證案件資料,被驗證的案件有{itemSn}");
                    conCallog.And(x => x.Comp_Cd == _user.CompCd);
                    conCallog.And(x => x.Sn == itemSn);
                    conCallog.And(x => x.TAcceptedLog.Sn == null);
                    Tcallog data = _tcallogRepo.Get(conCallog);
                    if (data == null)
                    {
                        _logger.Info($"查無案件資料:{itemSn}(可能已經被認養)");
                    }
                    else if (data.CloseSts > (byte)CloseSts.process)
                    {
                        _logger.Info($"案件:{itemSn},已經銷案。");
                    }
                    else
                    {
                        _logger.Info($"加入推播,案件:{itemSn}");
                        NotifySn.Add(itemSn);
                    }
                    conCallog = new Conditions <DataBase.TCALLOG>();
                }
                #endregion

                if (Account.Count == 0)
                {
                    throw new Exception("勾選的技師驗證後無資料");
                }
                if (NotifySn.Count == 0)
                {
                    throw new Exception("勾選的案件驗證後無資料,請重新整理");
                }

                #region 更新待受理案件+推播
                var isSuccess = _callogService.NotificationForWeb(_user, NotifySn, Account);
                #endregion
                return(Json(new JsonResult()
                {
                    Data = new
                    {
                        IsSuccess = isSuccess,
                        Message = $"推播通知:{(isSuccess ? "成功" : "失敗")}"
                    }
                }));
            }
            catch (Exception ex)
            {
                _logger.Error(ex.Message);
                if (ex.InnerException != null)
                {
                    _logger.Error(ex.InnerException.Message);
                    if (ex.InnerException.InnerException != null)
                    {
                        _logger.Error(ex.InnerException.InnerException.Message);
                    }
                }
                return(Json(new JsonResult()
                {
                    Data = new
                    {
                        IsSuccess = false,
                        Message = $"推播通知失敗,原因:{ex.Message}"
                    }
                }));
            }
        }