public PerformedOnUserSendMessageRule( SendMessageRule singleUserSendMessageRule, Mapper <PerformedOnUserMessage, LegacyEvent> mapper) { this.singleUserSendMessageRule = singleUserSendMessageRule; this.mapper = mapper; }
public PerformedOnOfficeSendMessageRule( SendMessageRule singleOfficeSendMessageRule, Mapper <PerformedOnOfficeMessage, LegacyEvent> mapper) { this.singleOfficeSendMessageRule = singleOfficeSendMessageRule; this.mapper = mapper; }
public void DeleteSendMessageRule(SendMessageRule sendMessageRule) { DateTime utcNow = DateTime.UtcNow; if (ShouldWithhold(sendMessageRule.SendTimeType)) { // 補點 decimal point = sendMessageRule.TotalMessageCost; var userRepository = this.unitOfWork.Repository <ApplicationUser>(); var user = sendMessageRule.CreatedUser; user.SmsBalance += point; userRepository.Update(user); // 寫入交易明細 var tradeDetailRepository = this.unitOfWork.Repository <TradeDetail>(); var tradeDetail = new TradeDetail { TradeTime = utcNow, TradeType = TradeType.CoverOfSendMessage, Point = point, OwnerId = user.Id, TargetId = sendMessageRule.Id.ToString(), Remark = string.Format("{0}(簡訊編號:{1}),取消發送(共{2}筆收訊人),回補點數{3}點", AttributeHelper.GetColumnDescription(sendMessageRule.SendTimeType), sendMessageRule.Id, this.unitOfWork.Repository <MessageReceiver>().Count(p => p.SendMessageRuleId == sendMessageRule.Id), point) }; tradeDetailRepository.Insert(tradeDetail); // 自動補點與點數預警 //CheckCredit(user); // 20160507 Norman, 補點應該不需要確認 } }
public void SendIf(LegacyEvent legacyEvent, SendMessageRule sendMessageRule) { if (sendMessageRule.ShouldSend(legacyEvent)) { messagePublisher.Publish(sendMessageRule.GetMessage(legacyEvent)); } }
public HttpResponseMessage Get(int id) //public HttpResponseMessage Get(int id) { try { this.logService.Debug("BasicAuthApi::ReportController,Get({0})", id); int sendMessageRuleId = id; HttpResponseMessage returnVal = null; SendMessageRule sendMessageRule = context.Set <SendMessageRule>().Where(p => p.CreatedUserId == CurrentUser.Id && p.Id == sendMessageRuleId).FirstOrDefault(); if (sendMessageRule == null) { throw new Exception(string.Format("無法取得簡訊派送報表,目前使用者 {0} 沒有對應的簡訊識別碼 {1}", CurrentUserName, sendMessageRuleId)); } var result = context.Set <SendMessageHistory>().Where(p => p.SendMessageRuleId == sendMessageRuleId).Select(p => new { sendTime = p.SendTime, sendTitle = p.SendTitle, sendBody = p.SendBody, messageStatus = p.MessageStatusString, destinationAddress = p.DestinationAddress, createdTime = p.SendMessageResultCreatedTime, sentDate = p.SentDate, doneDate = p.DoneDate, deliveryStatus = p.DeliveryStatusString, price = p.MessageCost, delivered = p.Delivered, name = p.DestinationName, region = p.Region, }); returnVal = this.Request.CreateResponse(HttpStatusCode.OK, result); return(returnVal); } catch (Exception ex) { this.logService.Error(ex); return(this.Request.CreateResponse(HttpStatusCode.InternalServerError, new { ErrorMessage = ex.Message, })); } }
/// <summary> /// 處理取回派回結果後,根據派送成功或者失敗,決定是否回補點數。 /// </summary> private void HandleSendMessageHistory( SendMessageRule sendMessageRule, SendMessageQueue sendMessageQueue, SendMessageHistory sendMessageHistory) { if (sendMessageHistory.Delivered) { return; } if (sendMessageHistory.Price != 0) { return; // 如果簡訊商就算傳送失敗,但有收取簡訊費用,就不回補點數 } if (sendMessageHistory.ProviderName == SmsProviderType.Every8d.ToString()) { return; // Every8d 會重送,不需要回補點數 } DateTime utcNow = DateTime.UtcNow; // 補點 decimal point = sendMessageHistory.MessageCost; var userRepository = this.unitOfWork.Repository <ApplicationUser>(); var user = sendMessageRule.CreatedUser; user.SmsBalance += point; userRepository.Update(user); // 寫入交易明細 var tradeDetailRepository = this.unitOfWork.Repository <TradeDetail>(); var tradeDetail = new TradeDetail { TradeTime = utcNow, TradeType = TradeType.CoverOfSendMessage, Point = point, OwnerId = user.Id, TargetId = sendMessageHistory.Id.ToString(), Remark = string.Format("{0}(簡訊編號:{1},序列編號:{2}),收訊門號{3}發送失敗({4}),回補點數{5}點", AttributeHelper.GetColumnDescription(sendMessageRule.SendTimeType), sendMessageRule.Id, sendMessageQueue.Id, sendMessageHistory.DestinationAddress, //AttributeHelper.GetColumnDescription(sendMessageHistory.DeliveryStatus), sendMessageHistory.DeliveryStatusString, point) }; tradeDetailRepository.Insert(tradeDetail); // 自動補點與點數預警 // 回補點數,不用自動補點與點數預警 //CheckCredit(user); }
public HttpResponseMessage Delete(int id) //public HttpResponseMessage Delete(int id) { try { this.logService.Debug("BasicAuthApi::EraseBookingController,Delete({0})", id); int sendMessageRuleId = id; HttpResponseMessage returnVal = null; using (TransactionScope scope = context.CreateTransactionScope()) { //int sendMessageRuleId = id; SendMessageRule sendMessageRule = context.Set <SendMessageRule>().Where(p => p.CreatedUserId == CurrentUser.Id && p.Id == sendMessageRuleId).FirstOrDefault(); if (sendMessageRule == null) { throw new Exception(string.Format("無法刪除預約簡訊,目前使用者 {0} 沒有對應的簡訊識別碼 {1}", CurrentUserName, sendMessageRuleId)); } this.sendMessageRuleService.RemoveSendMessageRule(CurrentUser, sendMessageRuleId); var result = new { smsCount = sendMessageRule.TotalReceiverCount, // 刪除的筆數 price = sendMessageRule.TotalMessageCost, // 回補的點數 }; returnVal = this.Request.CreateResponse(HttpStatusCode.OK, result); scope.Complete(); } return(returnVal); } catch (Exception ex) { this.logService.Error(ex); return(this.Request.CreateResponse(HttpStatusCode.InternalServerError, new { ErrorMessage = ex.Message, })); } }
public void UpdateSendMessageRule(SendMessageRule sendMessageRule, decimal beforeTotalMessageCost, decimal afterTotalMessageCost) { DateTime utcNow = DateTime.UtcNow; // 只針對預先扣除的簡訊類型,對於打算要發送的內容進行扣點 if (ShouldWithhold(sendMessageRule.SendTimeType)) { // 扣點或補點 decimal point = afterTotalMessageCost - beforeTotalMessageCost; if (point == 0) { return; } var userRepository = this.unitOfWork.Repository <ApplicationUser>(); var user = sendMessageRule.CreatedUser; user.SmsBalance -= point; userRepository.Update(user); // 寫入交易明細 TradeType tradeType = (point > 0) ? TradeType.DeductionOfSendMessage : TradeType.CoverOfSendMessage; string remark = (point > 0) ? string.Format("{0}(簡訊編號:{1}),更新發送內容,追加差額點數{2}點", AttributeHelper.GetColumnDescription(sendMessageRule.SendTimeType), sendMessageRule.Id, Math.Abs(point)) : string.Format("{0}(簡訊編號:{1}),更新發送內容,回補差額點數{2}點", AttributeHelper.GetColumnDescription(sendMessageRule.SendTimeType), sendMessageRule.Id, Math.Abs(point)); var tradeDetailRepository = this.unitOfWork.Repository <TradeDetail>(); var tradeDetail = new TradeDetail { TradeTime = utcNow, TradeType = tradeType, Point = -1 * point, OwnerId = user.Id, TargetId = sendMessageRule.Id.ToString(), Remark = remark }; tradeDetailRepository.Insert(tradeDetail); // 自動補點與點數預警 CheckCredit(user); } }
/// <summary> /// 刪除收訊人回補點數 /// </summary> /// <param name="user">The user.</param> /// <param name="messageReceiver">The message receiver.</param> public void DeleteMessageReceiver(SendMessageRule sendMessageRule, MessageReceiver messageReceiver) { DateTime utcNow = DateTime.UtcNow; if (ShouldWithhold(sendMessageRule.SendTimeType)) { decimal point = messageReceiver.MessageCost; var userRepository = this.unitOfWork.Repository <ApplicationUser>(); var user = sendMessageRule.CreatedUser; user.SmsBalance += point; userRepository.Update(user); var sendMessageRuleRepository = this.unitOfWork.Repository <SendMessageRule>(); sendMessageRule.TotalReceiverCount -= 1; sendMessageRule.TotalMessageCost -= point; sendMessageRule.RemainingSmsBalance += point; sendMessageRuleRepository.Update(sendMessageRule); // 寫入交易明細 var tradeDetailRepository = this.unitOfWork.Repository <TradeDetail>(); var tradeDetail = new TradeDetail { TradeTime = utcNow, TradeType = TradeType.CoverOfSendMessage, Point = point, OwnerId = user.Id, TargetId = messageReceiver.Id.ToString(), Remark = string.Format("{0}(簡訊編號:{1}),刪除收訊人{2},回補{3}點", AttributeHelper.GetColumnDescription(sendMessageRule.SendTimeType), sendMessageRule.Id, messageReceiver.Mobile, messageReceiver.MessageCost) }; tradeDetailRepository.Insert(tradeDetail); // 自動補點與點數預警 CheckCredit(user); } }
/// <summary> /// 針對預先扣點的發送時間類型,進行黑名單的收訊者 - 退還點數 /// </summary> /// <param name="sendMessageRule"></param> public void HandleReceiversInBlackList(SendMessageRule sendMessageRule, IEnumerable <MessageReceiver> receiversInBlackList) { if (!receiversInBlackList.Any()) { return; } DateTime utcNow = DateTime.UtcNow; if (ShouldWithhold(sendMessageRule.SendTimeType)) { // 補點 decimal point = receiversInBlackList.Sum(p => p.MessageCost); var userRepository = this.unitOfWork.Repository <ApplicationUser>(); var user = sendMessageRule.CreatedUser; user.SmsBalance += point; userRepository.Update(user); // 寫入交易明細 var tradeDetailRepository = this.unitOfWork.Repository <TradeDetail>(); var tradeDetail = new TradeDetail { TradeTime = utcNow, TradeType = TradeType.CoverOfSendMessage, Point = point, OwnerId = user.Id, TargetId = sendMessageRule.Id.ToString(), Remark = string.Format("{0}(簡訊編號:{1}),退還黑名單點數(共{2}筆收訊人屬於黑名單),回補{3}點", AttributeHelper.GetColumnDescription(sendMessageRule.SendTimeType), sendMessageRule.Id, receiversInBlackList.Count(), point) }; tradeDetailRepository.Insert(tradeDetail); // 自動補點與點數預警 CheckCredit(user); } }
public void CreateSendMessageQueue(SendMessageRule sendMessageRule, SendMessageQueue sendMessageQueue) { DateTime utcNow = DateTime.UtcNow; // 只針對非預先扣除的簡訊類型,對於打算要發送的內容進行扣點 if (!ShouldWithhold(sendMessageRule.SendTimeType)) { // 扣點 decimal point = sendMessageQueue.TotalMessageCost; var userRepository = this.unitOfWork.Repository <ApplicationUser>(); var user = sendMessageRule.CreatedUser; user.SmsBalance -= point; userRepository.Update(user); // 寫入交易明細 var tradeDetailRepository = this.unitOfWork.Repository <TradeDetail>(); var tradeDetail = new TradeDetail { TradeTime = utcNow, TradeType = TradeType.DeductionOfSendMessage, Point = -1 * point, OwnerId = user.Id, TargetId = sendMessageRule.Id.ToString(), Remark = string.Format("{0}(簡訊編號:{1},序列編號:{2}),建立完成(共{3}筆收訊人),扣除{4}點", AttributeHelper.GetColumnDescription(sendMessageRule.SendTimeType), sendMessageRule.Id, sendMessageQueue.Id, this.unitOfWork.Repository <MessageReceiver>().Count(p => p.SendMessageRuleId == sendMessageRule.Id), point) }; tradeDetailRepository.Insert(tradeDetail); // 自動補點與點數預警 CheckCredit(user); } }
/// <summary> /// 在 GetDeliveryReport 之後,更新大表 SendMessageHistory /// </summary> public void UpdateSendMessageHistory(int sendMessageQueueId) { var sendMessageRuleRepository = this.unitOfWork.Repository <SendMessageRule>(); var sendMessageQueueRepository = this.unitOfWork.Repository <SendMessageQueue>(); var sendMessageHistoryRepository = this.unitOfWork.Repository <SendMessageHistory>(); SendMessageQueue sendMessageQueue = sendMessageQueueRepository.GetById(sendMessageQueueId); SendMessageRule sendMessageRule = sendMessageRuleRepository.GetById(sendMessageQueue.SendMessageRuleId); var clientTimezoneOffset = sendMessageRule.ClientTimezoneOffset; var messageReceivers = this.unitOfWork.Repository <MessageReceiver>().GetMany(p => p.SendMessageRuleId == sendMessageQueue.SendMessageRuleId && p.SendBody == sendMessageQueue.SendBody).ToList(); Every8d_SendMessageResult sendMessageResult = this.unitOfWork.Repository <Every8d_SendMessageResult>().Get(p => p.SourceTable == SourceTable.SendMessageQueue && p.SourceTableId == sendMessageQueueId); // if (SendMessageResult == null) return; 不應該為 null int?DepartmentId = null; if (sendMessageRule.CreatedUser.Department != null) { DepartmentId = sendMessageRule.CreatedUser.Department.Id; } string CreatedUserId = sendMessageRule.CreatedUser.Id; int SendMessageRuleId = sendMessageQueue.SendMessageRuleId; SendMessageType SendMessageType = sendMessageQueue.SendMessageType; DateTime SendTime = sendMessageQueue.SendTime; string SendTitle = sendMessageQueue.SendTitle; string SendBody = sendMessageQueue.SendBody; SendCustType SendCustType = sendMessageQueue.SendCustType; string RequestId = sendMessageResult.BATCH_ID; string ProviderName = this.Name; DateTime SendMessageResultCreatedTime = sendMessageResult.CreatedTime; List <Every8d_DeliveryReport> DeliveryReports = sendMessageResult.DeliveryReports.ToList(); //foreach (var DeliveryReport in DeliveryReports) for (var i = 0; i < DeliveryReports.Count; i++) { var DeliveryReport = DeliveryReports[i]; var messageReceiver = (0 <= i && i < messageReceivers.Count) ? messageReceivers[i] : null; string DestinationName = DeliveryReport.NAME; var entity = new SendMessageHistory(); //////////////////////////////////////// // 01 ~ 05 entity.DepartmentId = DepartmentId; entity.CreatedUserId = CreatedUserId; entity.SendMessageRuleId = SendMessageRuleId; entity.SendMessageQueueId = sendMessageQueueId; entity.SendMessageType = SendMessageType; //////////////////////////////////////// // 06 ~ 10 entity.SendTime = SendTime; entity.SendTitle = SendTitle; entity.SendBody = SendBody; entity.SendCustType = SendCustType; entity.RequestId = RequestId; //////////////////////////////////////// // 11 ~ 15 entity.ProviderName = ProviderName; entity.MessageId = null; entity.MessageStatus = MessageStatus.Unknown; entity.MessageStatusString = entity.MessageStatus.ToString(); entity.SenderAddress = sendMessageRule.SenderAddress; //////////////////////////////////////// // 16 ~ 20 // 20151106 Norman, Infobip 給的手機門號是 E164格式,但是沒有加上 "+",使用 【MobileUtil.GetE164PhoneNumber】會導致誤判 var destinationAddress = DeliveryReport.MOBILE; if (!destinationAddress.StartsWith("+", StringComparison.OrdinalIgnoreCase)) { destinationAddress = "+" + destinationAddress; } entity.DestinationAddress = MobileUtil.GetE164PhoneNumber(destinationAddress); entity.SendMessageResultCreatedTime = SendMessageResultCreatedTime; // TODO: 驗證 Every8d 回傳發送時間轉成 UTC 時間是否正確 //entity.SentDate = Converter.ToDateTime(DeliveryReport.SENT_TIME, Converter.Every8d_SentTime).Value; // 2010/03/23 12:05:29 //entity.DoneDate = Converter.ToDateTime(DeliveryReport.SENT_TIME, Converter.Every8d_SentTime).Value; // 2010/03/23 12:05:29,簡訊供應商沒有提供此資訊,因此設定與SentDate一致 entity.SentDate = Converter.ToDateTime(DeliveryReport.SENT_TIME, Converter.Every8d_SentTime).Value.ToUniversalTime(); // 2010/03/23 12:05:29 entity.DoneDate = Converter.ToDateTime(DeliveryReport.SENT_TIME, Converter.Every8d_SentTime).Value.ToUniversalTime(); // 2010/03/23 12:05:29,簡訊供應商沒有提供此資訊,因此設定與SentDate一致 entity.DeliveryStatus = (DeliveryReportStatus)Convert.ToInt32(DeliveryReport.STATUS); //////////////////////////////////////// // 21 ~ 25 entity.DeliveryStatusString = entity.DeliveryStatus.ToString(); entity.Price = Convert.ToDecimal(DeliveryReport.COST); entity.DeliveryReportCreatedTime = DeliveryReport.CreatedTime; entity.MessageCost = (new MessageCostInfo(entity.SendBody, entity.DestinationAddress).MessageCost); entity.Delivered = IsDelivered(entity.DeliveryStatus); //////////////////////////////////////// // 26 entity.DestinationName = DestinationName; entity.Region = MobileUtil.GetRegionName(entity.DestinationAddress); entity.CreatedTime = DateTime.UtcNow; entity.RetryMaxTimes = systemParameters.RetryMaxTimes; entity.RetryTotalTimes = 0; entity.SendMessageRetryHistoryId = null; entity.Email = messageReceiver != null ? messageReceiver.Email : string.Empty; entity = sendMessageHistoryRepository.Insert(entity); // 如果發送失敗,就回補點數 // 20151123 Norman, Eric 要求發送失敗不回補點數 //this.tradeService.HandleSendMessageHistory(sendMessageRule, sendMessageQueue, entity); } // (6) 出統計表 this.sendMessageStatisticService.AddOrUpdateSendMessageStatistic(sendMessageQueueId); }
/// <summary> /// 在 GetDeliveryReport 之後,更新大表 SendMessageHistory /// </summary> public void UpdateSendMessageHistory(int sendMessageQueueId) { var sendMessageRuleRepository = this.unitOfWork.Repository <SendMessageRule>(); var sendMessageQueueRepository = this.unitOfWork.Repository <SendMessageQueue>(); var sendMessageHistoryRepository = this.unitOfWork.Repository <SendMessageHistory>(); SendMessageQueue sendMessageQueue = sendMessageQueueRepository.GetById(sendMessageQueueId); SendMessageRule sendMessageRule = sendMessageRuleRepository.GetById(sendMessageQueue.SendMessageRuleId); Infobip_SendMessageResult sendMessageResult = this.unitOfWork.Repository <Infobip_SendMessageResult>().Get(p => p.SourceTable == SourceTable.SendMessageQueue && p.SourceTableId == sendMessageQueueId); if (sendMessageResult == null) { throw new Exception(string.Format("InfobipSmsProvider(smsProviderType = {0}),無法取得 Infobip_SendMessageResult(SendMessageQueueId:{1})", smsProviderType.ToString(), sendMessageQueueId)); } int?DepartmentId = null; if (sendMessageRule.CreatedUser.Department != null) { DepartmentId = sendMessageRule.CreatedUser.Department.Id; } string CreatedUserId = sendMessageRule.CreatedUser.Id; int SendMessageRuleId = sendMessageQueue.SendMessageRuleId; SendMessageType SendMessageType = sendMessageQueue.SendMessageType; DateTime SendTime = sendMessageQueue.SendTime; string SendTitle = sendMessageQueue.SendTitle; string SendBody = sendMessageQueue.SendBody; SendCustType SendCustType = sendMessageQueue.SendCustType; string RequestId = sendMessageResult.ClientCorrelator; string ProviderName = this.Name; DateTime SendMessageResultCreatedTime = sendMessageResult.CreatedTime; List <Infobip_SendMessageResultItem> SendMessageResults = sendMessageResult.SendMessageResults.ToList(); foreach (var SendMessageResult in SendMessageResults) { Infobip_DeliveryReport DeliveryReport = SendMessageResult.DeliveryReport; if (DeliveryReport == null) { continue; // 如果尚未取得派送報表,就忽略 } SendMessageHistory entity = this.unitOfWork.Repository <SendMessageHistory>().Get(p => p.MessageId == SendMessageResult.MessageId); if (entity == null) { continue; // 如果找不到對應 MessageId,就忽略 } string DestinationName = SendMessageResult.DestinationName; //////////////////////////////////////// // 01 ~ 05 entity.DepartmentId = DepartmentId; entity.CreatedUserId = CreatedUserId; entity.SendMessageRuleId = SendMessageRuleId; entity.SendMessageQueueId = sendMessageQueueId; entity.SendMessageType = SendMessageType; //////////////////////////////////////// // 06 ~ 10 entity.SendTime = SendTime; entity.SendTitle = SendTitle; entity.SendBody = SendBody; entity.SendCustType = SendCustType; entity.RequestId = RequestId; //////////////////////////////////////// // 11 ~ 15 entity.ProviderName = ProviderName; entity.MessageId = SendMessageResult.MessageId; entity.MessageStatus = (EFunTech.Sms.Schema.MessageStatus)((int)SendMessageResult.MessageStatus); entity.MessageStatusString = entity.MessageStatus.ToString(); entity.SenderAddress = SendMessageResult.SenderAddress; //////////////////////////////////////// // 16 ~ 20 // 20151106 Norman, Infobip 給的手機門號是 E164格式,但是沒有加上 "+",使用 【MobileUtil.GetE164PhoneNumber】會導致誤判 var destinationAddress = SendMessageResult.DestinationAddress; if (!destinationAddress.StartsWith("+", StringComparison.OrdinalIgnoreCase)) { destinationAddress = "+" + destinationAddress; } entity.DestinationAddress = MobileUtil.GetE164PhoneNumber(destinationAddress); entity.SendMessageResultCreatedTime = SendMessageResultCreatedTime; entity.SentDate = DeliveryReport.SentDate; entity.DoneDate = DeliveryReport.DoneDate; entity.DeliveryStatus = DeliveryReport.Status; //////////////////////////////////////// // 21 ~ 25 entity.DeliveryStatusString = entity.DeliveryStatus.ToString(); entity.Price = DeliveryReport.Price ?? (decimal)0.0; entity.DeliveryReportCreatedTime = DeliveryReport.CreatedTime; entity.MessageCost = (new MessageCostInfo(entity.SendBody, entity.DestinationAddress).MessageCost); entity.Delivered = IsDelivered(entity.DeliveryStatus); //////////////////////////////////////// // 26 entity.DestinationName = DestinationName; entity.Region = MobileUtil.GetRegionName(entity.DestinationAddress); sendMessageHistoryRepository.Update(entity); // 如果發送失敗,就回補點數 // 20151123 Norman, Eric 要求發送失敗不回補點數 //this.tradeService.HandleSendMessageHistory(sendMessageRule, sendMessageQueue, entity); } // (6) 出統計表 this.sendMessageStatisticService.AddOrUpdateSendMessageStatistic(sendMessageQueueId); }
/// <summary> /// 在 SendSMS 之後,建立大表 SendMessageHistory /// </summary> public void CreateSendMessageHistory(SendMessageQueue sendMessageQueue) { int sendMessageQueueId = sendMessageQueue.Id; var sendMessageRuleRepository = this.unitOfWork.Repository <SendMessageRule>(); var sendMessageQueueRepository = this.unitOfWork.Repository <SendMessageQueue>(); var sendMessageHistoryRepository = this.unitOfWork.Repository <SendMessageHistory>(); SendMessageRule sendMessageRule = sendMessageRuleRepository.GetById(sendMessageQueue.SendMessageRuleId); Infobip_SendMessageResult sendMessageResult = this.unitOfWork.Repository <Infobip_SendMessageResult>().Get(p => p.SourceTable == SourceTable.SendMessageQueue && p.SourceTableId == sendMessageQueueId); if (sendMessageResult == null) { throw new Exception(string.Format("InfobipSmsProvider(smsProviderType = {0}),無法取得 Infobip_SendMessageResult(SendMessageQueueId:{1})", smsProviderType.ToString(), sendMessageQueueId)); } int?DepartmentId = null; if (sendMessageRule.CreatedUser.Department != null) { DepartmentId = sendMessageRule.CreatedUser.Department.Id; } string CreatedUserId = sendMessageRule.CreatedUser.Id; int SendMessageRuleId = sendMessageQueue.SendMessageRuleId; SendMessageType SendMessageType = sendMessageQueue.SendMessageType; DateTime SendTime = sendMessageQueue.SendTime; string SendTitle = sendMessageQueue.SendTitle; string SendBody = sendMessageQueue.SendBody; SendCustType SendCustType = sendMessageQueue.SendCustType; string RequestId = sendMessageResult.ClientCorrelator; string ProviderName = this.Name; DateTime SendMessageResultCreatedTime = sendMessageResult.CreatedTime; List <Infobip_SendMessageResultItem> SendMessageResults = sendMessageResult.SendMessageResults.ToList(); foreach (var SendMessageResult in SendMessageResults) { string DestinationName = SendMessageResult.DestinationName; var entity = new SendMessageHistory(); //////////////////////////////////////// // 01 ~ 05 entity.DepartmentId = DepartmentId; entity.CreatedUserId = CreatedUserId; entity.SendMessageRuleId = SendMessageRuleId; entity.SendMessageQueueId = sendMessageQueueId; entity.SendMessageType = SendMessageType; //////////////////////////////////////// // 06 ~ 10 entity.SendTime = SendTime; entity.SendTitle = SendTitle; entity.SendBody = SendBody; entity.SendCustType = SendCustType; entity.RequestId = RequestId; //////////////////////////////////////// // 11 ~ 15 entity.ProviderName = ProviderName; entity.MessageId = SendMessageResult.MessageId; entity.MessageStatus = (EFunTech.Sms.Schema.MessageStatus)((int)SendMessageResult.MessageStatus); entity.MessageStatusString = entity.MessageStatus.ToString(); entity.SenderAddress = SendMessageResult.SenderAddress; //////////////////////////////////////// // 16 ~ 20 // 20151106 Norman, Infobip 給的手機門號是 E164格式,但是沒有加上 "+",使用 【MobileUtil.GetE164PhoneNumber】會導致誤判 var destinationAddress = SendMessageResult.DestinationAddress; if (!destinationAddress.StartsWith("+", StringComparison.OrdinalIgnoreCase)) { destinationAddress = "+" + destinationAddress; } entity.DestinationAddress = MobileUtil.GetE164PhoneNumber(destinationAddress); entity.SendMessageResultCreatedTime = SendMessageResultCreatedTime; entity.SentDate = null; entity.DoneDate = null; entity.DeliveryStatus = DeliveryReportStatus.MessageAccepted; //////////////////////////////////////// // 21 ~ 25 entity.DeliveryStatusString = entity.DeliveryStatus.ToString(); entity.Price = (decimal)0.0; // 尚未傳送完成 entity.DeliveryReportCreatedTime = null; entity.MessageCost = (new MessageCostInfo(entity.SendBody, entity.DestinationAddress).MessageCost); entity.Delivered = IsDelivered(entity.DeliveryStatus); //////////////////////////////////////// // 26 entity.DestinationName = DestinationName; entity.Region = MobileUtil.GetRegionName(entity.DestinationAddress); entity.CreatedTime = DateTime.UtcNow; entity.RetryMaxTimes = systemParameters.RetryMaxTimes; entity.RetryTotalTimes = 0; entity.SendMessageRetryHistoryId = null; entity.Email = SendMessageResult.Email; entity = sendMessageHistoryRepository.Insert(entity); } // (6) 出統計表 this.sendMessageStatisticService.AddOrUpdateSendMessageStatistic(sendMessageQueueId); }
public void SendSMS(int sendMessageRuleId, DateTime sendTime) { UniqueJob uniqueJob = null; try { uniqueJob = this.uniqueJobList.AddOrUpdate("SendSMS", sendMessageRuleId, sendTime); if (uniqueJob == null) { return; // Job 已經存在 } // 如果在 SendMessageQueue 中已經有對應資料,就忽略 if (this.unitOfWork.Repository <SendMessageQueue>().Any(p => p.SendMessageRuleId == sendMessageRuleId && p.SendTime == sendTime)) { return; } using (var scope = this.unitOfWork.CreateTransactionScope()) { SendMessageRule sendMessageRule = this.unitOfWork.Repository <SendMessageRule>().GetById(sendMessageRuleId); if (sendMessageRule == null) { this.logService.Error("sendMessageRule is null (sendMessageRuleId: {0})", sendMessageRuleId); return; } this.logService.Debug("CommonSmsService,發送簡訊(簡訊編號:{0},預定發送時間:{1},實際發送時間:{2})", sendMessageRule.Id, Converter.ToLocalTime(sendTime, sendMessageRule.ClientTimezoneOffset).ToString(Converter.Every8d_SentTime), Converter.ToLocalTime(DateTime.UtcNow, sendMessageRule.ClientTimezoneOffset).ToString(Converter.Every8d_SentTime)); ApplicationUser user = sendMessageRule.CreatedUser; if (sendMessageRule.SendMessageRuleStatus != SendMessageRuleStatus.Ready) { return; } // 此簡訊規則下,所有收訊者資訊 var ruleReceivers = this.unitOfWork.Repository <MessageReceiver>().GetMany(p => p.SendMessageRuleId == sendMessageRule.Id).ToList(); // 目前有效的黑名單手機號碼 (E164) var blackListMobiles = this.unitOfWork.Repository <Blacklist>() .GetMany(p => p.CreatedUser.Id == sendMessageRule.CreatedUser.Id && p.Enabled == true) .Select(p => p.Mobile) .Distinct() .ToList() .Select(p => MobileUtil.GetE164PhoneNumber(p)) .ToList(); // 在黑名單的收訊者 var ruleReceiversInBlackList = ruleReceivers .Where(p => blackListMobiles.Contains(MobileUtil.GetE164PhoneNumber(p.Mobile))) .ToList(); // 不在黑名單的收訊者 var ruleReceiversNotInBlackList = ruleReceivers .Where(p => !blackListMobiles.Contains(MobileUtil.GetE164PhoneNumber(p.Mobile))) .ToList(); this.logService.Debug("CommonSmsService,發送簡訊(簡訊編號:{0},預定發送名單:{1})", sendMessageRuleId, ExcelBugFix.GetInformation(ruleReceivers.Select(p => p.Mobile).ToList())); this.logService.Debug("CommonSmsService,發送簡訊(簡訊編號:{0},黑名單:{1})", sendMessageRuleId, ExcelBugFix.GetInformation(ruleReceiversInBlackList.Select(p => p.Mobile).ToList())); this.logService.Debug("CommonSmsService,發送簡訊(簡訊編號:{0},實際發送名單:{1})", sendMessageRuleId, ExcelBugFix.GetInformation(ruleReceiversNotInBlackList.Select(p => p.Mobile).ToList())); //List<string> detailInformations = new List<string>(); //detailInformations.AddRange(ExcelBugFix.GetDetailInformation(ruleReceivers.Select(p => p.Mobile).ToList()) // .Select(p => string.Format("CommonSmsService,發送簡訊(簡訊編號:{0},預定發送名單(全):{1})", sendMessageRuleId, p)) // .ToList()); //detailInformations.AddRange(ExcelBugFix.GetDetailInformation(ruleReceiversInBlackList.Select(p => p.Mobile).ToList()) // .Select(p => string.Format("CommonSmsService,發送簡訊(簡訊編號:{0},黑名單(全):{1})", sendMessageRuleId, p)) // .ToList()); //detailInformations.AddRange(ExcelBugFix.GetDetailInformation(ruleReceiversNotInBlackList.Select(p => p.Mobile).ToList()) // .Select(p => string.Format("CommonSmsService,發送簡訊(簡訊編號:{0},實際發送名單(全):{1})", sendMessageRuleId, p)) // .ToList()); //foreach (var detailInformation in detailInformations) //{ // this.logService.Debug(detailInformation); //} // 找出所有不同的發送內容 var sendBodies = ruleReceiversNotInBlackList.Select(p => p.SendBody).Distinct().ToList(); // 針對沒有執行預扣的簡訊規則,判斷是否有足夠點數進行簡訊發送作業 decimal totalMessageCost = ruleReceiversNotInBlackList.Sum(p => p.MessageCost); if (!this.tradeService.ShouldWithhold(sendMessageRule.SendTimeType)) { if (sendMessageRule.CreatedUser.SmsBalance < totalMessageCost) { string message = string.Format("執行{0}失敗(編號:{1}),使用者 {2} 點數不足,目前點數 {3} 點,發送所需點數 {4} 點", AttributeHelper.GetColumnDescription(sendMessageRule.SendTimeType), sendMessageRule.Id, sendMessageRule.CreatedUser.UserName, sendMessageRule.CreatedUser.SmsBalance, totalMessageCost); this.logService.Error(message); throw new Exception(message); } } // 找出可以使用的簡訊供應商(可連線且餘額足夠) SmsProviderType userSmsProviderType = user.SmsProviderType; ISmsProvider provider = GetProvider(userSmsProviderType, totalMessageCost); // 如果沒有找到,將會拋出例外 // 開始發送,將 SendMessageRule 狀態改變為 Sending (正在發送簡訊規則) sendMessageRule.SendMessageRuleStatus = SendMessageRuleStatus.Sending; sendMessageRule.CreatedUser = user; this.unitOfWork.Repository <SendMessageRule>().Update(sendMessageRule); foreach (var sendBody in sendBodies) { // 依據傳送內容分群,每個群組使用一個SendMessageQueue, // 此SendMessageQueue下,所有收訊者資訊 var queueReceivers = ruleReceiversNotInBlackList.Where(p => p.SendBody == sendBody).ToList(); var sendMessageQueue = new SendMessageQueue(); sendMessageQueue.SendMessageType = sendMessageRule.SendMessageType; sendMessageQueue.SendTime = sendTime.ToUniversalTime(); // 預定發送訊息的時間(SendSMS經由Hangfire傳遞過來的sendTime,會將DateTimeKind轉為 Local,必須再轉成 Utc) sendMessageQueue.SendTitle = sendMessageRule.SendTitle; sendMessageQueue.SendBody = sendBody; sendMessageQueue.SendCustType = sendMessageRule.SendCustType; sendMessageQueue.TotalReceiverCount = queueReceivers.Count(); sendMessageQueue.TotalMessageCost = queueReceivers.Sum(p => p.MessageCost); sendMessageQueue.SendMessageRuleId = sendMessageRule.Id; // 只針對非預先扣除的簡訊類型,對於打算要發送的內容進行扣點 this.tradeService.CreateSendMessageQueue(sendMessageRule, sendMessageQueue); sendMessageQueue = this.unitOfWork.Repository <SendMessageQueue>().Insert(sendMessageQueue); this.logService.Debug("CommonSmsService,發送簡訊(簡訊編號:{0},序列號碼:{1},發送名單:{2},發送內容:{3})", sendMessageRuleId, sendMessageQueue.Id, ExcelBugFix.GetInformation(queueReceivers.Select(p => p.Mobile).ToList()), sendBody); provider.SendSMS(sendMessageQueue.Id); // TODO: 在 EVA 測試, 要先註解這一行,避免發送簡訊 } // foreach (var sendBody in sendBodies) // 全部簡訊發送完畢,將 SendMessageRule 狀態改變為 Sending (簡訊規則已發送完畢) sendMessageRule.SendMessageRuleStatus = SendMessageRuleStatus.Sent; this.unitOfWork.Repository <SendMessageRule>().Update(sendMessageRule); // http://www.dotblogs.com.tw/rainmaker/archive/2015/08/19/153169.aspx // 檢查此簡訊規則是否任務完成, // 如果是的話,將狀態設為 Finish // 如果否的話,將狀態設為 Ready (等待下次週期簡訊發送) bool isFinish = !sendMessageRule.GetNextSendTime().HasValue; sendMessageRule.SendMessageRuleStatus = isFinish ? SendMessageRuleStatus.Finish : SendMessageRuleStatus.Ready; this.unitOfWork.Repository <SendMessageRule>().Update(sendMessageRule); // 針對預先扣點的發送時間類型,進行黑名單的收訊者 - 退還點數 this.tradeService.HandleReceiversInBlackList(sendMessageRule, ruleReceiversInBlackList); scope.Complete(); } //////////////////////////////////////// } catch (Exception ex) { this.logService.Error(ex); throw; } finally { if (uniqueJob != null) { this.uniqueJobList.Remove(uniqueJob); } } }