public static void AddCannedRepliesForOneMerchant(long merchantId, bool cn) { var acr = new AddCannedReply(); List <CannedReply> cannedReplies = new List <CannedReply>(); var lst = cn ? crLstCn : crLstEn; lst.ForEach((cr) => { var cannedReply = new CannedReply { MerchantId = merchantId, UserId = null, CategoryName = cn ? "问候语" : "Greeting", ReplyContent = cr.ReplyContent, IsAutoReplyEnabled = true, Questions = cr.Questions, CreationTime = DateTimeOffset.UtcNow }; cannedReplies.Add(cannedReply); }); var task = acr.BulkPost(cannedReplies); task.Wait(); List <CannedReply.CannedReplyBulkResult> cbr = task.Result; File.WriteAllText($"d:\\logs\\{merchantId}.txt", JsonConvert.SerializeObject(cannedReplies)); File.WriteAllText($"d:\\logs\\{merchantId}.result.txt", JsonConvert.SerializeObject(cbr)); Console.Write(JsonConvert.SerializeObject(cannedReplies)); Console.Write(JsonConvert.SerializeObject(cbr)); }
public CannedReplyAnswer(CannedReply cannedReply) { //this.Id = cannedReply.Id; this.MerchantId = cannedReply.MerchantId; this.UserId = cannedReply.UserId; this.IsAutoReplyEnabled = cannedReply.IsAutoReplyEnabled; this.CategoryName = cannedReply.CategoryName; this.ReplyContent = cannedReply.ReplyContent; this.CreationTime = cannedReply.CreationTime; this.CannedReplyQuestions = new HashSet <CannedReplyQuestion>(); }
public async Task <CannedReply.CannedReplyBulkResult> Patch(long key, CannedReply cannedReply) { CannedReply.CannedReplyAnswerInternalResult res = await UpdateCannedReplyAnswerToDb(cannedReply); return(new CannedReply.CannedReplyBulkResult { Id = res.CannedReplyAnswer?.Id ?? -1, Status = res.Status, ErrorMessage = res.ErrorMessage, QuestionIds = res.QuestionIds }); }
private async Task <List <long> > AddQuestionsToAnswerAndNotSaveInDb(CannedReplyAnswer cannedReplyAnswer, HashSet <string> targetQuestions) { //these question ids in this lst will not be inserted List <long> specialQuestionIdLst = new List <long>(); if (targetQuestions != null) { foreach (var question in targetQuestions) { string csQuestion = CannedReply.GetMd5Hash(question); var crqFromDbId = await Db.CannedReplyQuestions.Where(c => c.CS_Question == csQuestion && c.MerchantId == cannedReplyAnswer.MerchantId && c.UserId == cannedReplyAnswer.UserId) .Where(c => c.Question == question) .Select(c => c.Id) .FirstOrDefaultAsync(); if (crqFromDbId == 0) { Db.CannedReplyQuestions.Add(new CannedReplyQuestion(cannedReplyAnswer, question)); } else { //Instead of update, we choose skip /* * if (crqFromDb.CannedReplyAnswerId != cannedReplyAnswer.Id) * { * crqFromDb.CannedReplyAnswerId = cannedReplyAnswer.Id; * } */ specialQuestionIdLst.Add(crqFromDbId); } //We don't need this line unless we choose update instead of skip //await Db.SaveChangesAsync(); } } return(specialQuestionIdLst); }
private async Task <CannedReply.CannedReplyAnswerInternalResult> UpdateCannedReplyAnswerToDb(CannedReply cannedReply) { var curMerchantIdFromDb = await Db.Merchants.Select(m => m.Id).FirstOrDefaultAsync(m => m == cannedReply.MerchantId); if (curMerchantIdFromDb == 0) { return(new CannedReply.CannedReplyAnswerInternalResult { CannedReplyAnswer = null, Status = "Error", ErrorMessage = "MerchantId is not valid or There is no such MerchantId in DB." }); } CannedReplyAnswer craFromDb = await Db.CannedReplyAnswers.Include(c => c.CannedReplyQuestions).SingleOrDefaultAsync(c => c.Id == cannedReply.Id); if (craFromDb == null) { return(new CannedReply.CannedReplyAnswerInternalResult { CannedReplyAnswer = null, Status = "Error", ErrorMessage = "record not found in DB" }); } craFromDb.ReplyContent = cannedReply.ReplyContent ?? craFromDb.ReplyContent; string csReplyContent = CannedReply.GetMd5Hash(craFromDb.ReplyContent); CannedReplyAnswer craFromDbWithSameAnswer = await Db.CannedReplyAnswers.Where(c => c.CS_ReplyContent == csReplyContent && c.MerchantId == craFromDb.MerchantId && c.UserId == craFromDb.UserId && c.Id != craFromDb.Id) .Include(c => c.CannedReplyQuestions) .FirstOrDefaultAsync(c => c.ReplyContent == craFromDb.ReplyContent); if (craFromDbWithSameAnswer == null) { craFromDb.IsAutoReplyEnabled = cannedReply.IsAutoReplyEnabled; craFromDb.CategoryName = cannedReply.CategoryName ?? craFromDb.CategoryName; try { if (cannedReply.Questions != null) { List <long> specialQuestionIdLst = await ForceAttachWithNewQuestionsToAnswerAndNotSaveInDb(craFromDb, cannedReply.Questions); await Db.SaveChangesAsync(); if (specialQuestionIdLst.Any()) { return(new CannedReply.CannedReplyAnswerInternalResult { CannedReplyAnswer = craFromDb, Status = "UpdatedWithSkip", ErrorMessage = $"Questions are skipped because this answer or other answers have these questions, questionIds: {string.Join(",", specialQuestionIdLst)}", //Status = "UpdateWithForceUpdate", //ErrorMessage = $"Questions are updated with this new answer, questionIds: {string.Join(",", specialQuestionIdLst)}", QuestionIds = specialQuestionIdLst }); } else { return(new CannedReply.CannedReplyAnswerInternalResult { CannedReplyAnswer = craFromDb, Status = "Updated", ErrorMessage = "" }); } } else { await Db.SaveChangesAsync(); return(new CannedReply.CannedReplyAnswerInternalResult { CannedReplyAnswer = craFromDb, Status = "Updated", ErrorMessage = "" }); } } catch (DbUpdateConcurrencyException ex) { if (!CannedReplyExists(cannedReply.Id)) { return(new CannedReply.CannedReplyAnswerInternalResult { CannedReplyAnswer = null, Status = "Error", ErrorMessage = "record not found in DB" }); } else { return(new CannedReply.CannedReplyAnswerInternalResult { CannedReplyAnswer = null, Status = "Error", ErrorMessage = ex.Message + ex.StackTrace }); } } catch (Exception ex) { ex = GetInnerException(ex); return(new CannedReply.CannedReplyAnswerInternalResult { CannedReplyAnswer = null, Status = "Error", ErrorMessage = ex.Message + ex.StackTrace }); } } else { cannedReply.CategoryName = cannedReply.CategoryName ?? craFromDb.CategoryName; if (cannedReply.Questions == null) { var mergeResult = await MergeExistingQuestionsToExistingAnswerInDb(craFromDb, craFromDbWithSameAnswer); Db.CannedReplyAnswers.Remove(craFromDb); await Db.SaveChangesAsync(); return(mergeResult); } else { Db.CannedReplyQuestions.RemoveRange(craFromDb.CannedReplyQuestions); Db.CannedReplyAnswers.Remove(craFromDb); await Db.SaveChangesAsync(); return(await MergeCannedReplyToExistingAnswerInDb(cannedReply, craFromDbWithSameAnswer)); } } }
private async Task <CannedReply.CannedReplyAnswerInternalResult> CreateCannedReplyAnswerToDb(CannedReply cannedReply) { var curMerchantIdFromDb = await Db.Merchants.Select(m => m.Id).FirstOrDefaultAsync(m => m == cannedReply.MerchantId); if (curMerchantIdFromDb == 0) { return(new CannedReply.CannedReplyAnswerInternalResult { CannedReplyAnswer = null, Status = "Error", ErrorMessage = "MerchantId is not valid or There is no such MerchantId in DB." }); } if (cannedReply.Questions == null || !cannedReply.Questions.Any()) { return(new CannedReply.CannedReplyAnswerInternalResult { CannedReplyAnswer = null, Status = "Error", ErrorMessage = "No questions to Add when creat canned Reply." }); } string csReplyContent = CannedReply.GetMd5Hash(cannedReply.ReplyContent); CannedReplyAnswer craFromDb = await Db.CannedReplyAnswers.Where(c => c.CS_ReplyContent == csReplyContent && c.MerchantId == cannedReply.MerchantId && c.UserId == cannedReply.UserId) .Include(c => c.CannedReplyQuestions) .FirstOrDefaultAsync(c => c.ReplyContent == cannedReply.ReplyContent); if (craFromDb != null) { cannedReply.CategoryName = cannedReply.CategoryName ?? ""; return(await MergeCannedReplyToExistingAnswerInDb(cannedReply, craFromDb)); } else { try { CannedReplyAnswer cannedReplyAnswer = new CannedReplyAnswer(cannedReply); Db.CannedReplyAnswers.Add(cannedReplyAnswer); await Db.SaveChangesAsync(); //these question ids in this lst will not be inserted List <long> specialQuestionIdLst = await AttachQuestionsToAnswerAndSaveInDb(cannedReplyAnswer, cannedReply.Questions); if (specialQuestionIdLst.Any()) { if (specialQuestionIdLst.Count == new HashSet <string>(cannedReply.Questions).Count) { //TODO: backend job to clean these answers if transaction failed Db.CannedReplyAnswers.Remove(cannedReplyAnswer); await Db.SaveChangesAsync(); return(new CannedReply.CannedReplyAnswerInternalResult { CannedReplyAnswer = null, Status = "Error", ErrorMessage = "No questions to Add or all questions are duplicated when creating canned Reply." }); } return(new CannedReply.CannedReplyAnswerInternalResult { CannedReplyAnswer = cannedReplyAnswer, Status = "CreatedWithSkip", ErrorMessage = $"Questions are skipped because this answer or other answers have these questions, questionIds: {string.Join(",", specialQuestionIdLst)}", //Status = "CreatedWithUpdate", //ErrorMessage = $"Questions are updated to be attached with this new answer, questionIds: {string.Join(",", specialQuestionIdLst)}", QuestionIds = specialQuestionIdLst }); } else { return(new CannedReply.CannedReplyAnswerInternalResult { CannedReplyAnswer = cannedReplyAnswer, Status = "Created", ErrorMessage = "" }); } } catch (Exception ex) { ex = GetInnerException(ex); return(new CannedReply.CannedReplyAnswerInternalResult { CannedReplyAnswer = null, Status = "Error", ErrorMessage = ex.Message + ex.StackTrace }); } } }
private async Task <CannedReply.CannedReplyAnswerInternalResult> MergeCannedReplyToExistingAnswerInDb(CannedReply cannedReply, CannedReplyAnswer craFromDb) { craFromDb.IsAutoReplyEnabled = cannedReply.IsAutoReplyEnabled; craFromDb.CategoryName = cannedReply.CategoryName ?? craFromDb.CategoryName; //don't use this if we have changes on CannedReply's dependency, //we may lose info in the CannedReply after it's dependency get changed by this operation. //Here I remove it just because it is no needed, //await Db.SaveChangesAsync(); List <long> specialQuestionIdLst = await AttachQuestionsToAnswerAndSaveInDb(craFromDb, cannedReply.Questions); if (specialQuestionIdLst.Any()) { return(new CannedReply.CannedReplyAnswerInternalResult { CannedReplyAnswer = craFromDb, Status = "UpdatedWithSkip", ErrorMessage = $"Merged Questions to Answer {craFromDb.Id}. Questions are skipped because this answer or other answers have these questions, questionIds: {string.Join(",", specialQuestionIdLst)}", //Status = "UpdateWithForceUpdate", //ErrorMessage = $"Questions are updated with this new answer, questionIds: {string.Join(",", specialQuestionIdLst)}", QuestionIds = specialQuestionIdLst }); } else { return(new CannedReply.CannedReplyAnswerInternalResult { CannedReplyAnswer = craFromDb, Status = "Updated", ErrorMessage = $"Merged Questions to Answer {craFromDb.Id}" }); } }