public async Task Execute(SaveSurveyAnswers command) { var questionStorageMap = await repos.GetQuestionStorageMap(command.SurveyId); var currentAnswers = await repos.Get(new GetSurveyAnswers { CaseId = command.CaseId, SurveyId = command.SurveyId, ProfileId = command.ProfileId, OutbreakId = command.OutbreakId }); //unwrap jArrays to complex types SurveyAnswerBindingHelpers.Bind(command.Answers); var answers = command.Answers.ToDictionary(entry => entry.Key.ToUpper(), entry => entry.Value); //get only the differences var deltas = SurveyAnswerHelpers.GetDeltas(currentAnswers, answers); //if no delta, exit if (!deltas.Any()) { return; } var writer = COR <SurveyAnswerWriteContext> .CreateChain( new SymptomWriteHandler(), new TravelHistoryWriteHandler(), new MappedWriteHandler(dataServices), new RepeaterWriteHandler(), new MultipleWriteHandler(), new DefaultWriteHandler()); var allkeys = deltas .Select(delta => delta.Key) .ToList(); var storageMapping = writeContext.SurveyObjectMapping .Where(mapping => mapping.CdMappingtype == "TARGETDS") .Where(mapping => allkeys.Contains(mapping.IdQuestion)) .ToDictionary(mapping => mapping.IdQuestion.ToUpper()); var surveyInstanceId = await repos.GetSurveyInstanceId(command.ProfileId, command.CaseId, command.OutbreakId); var connection = writeContext.Database.GetDbConnection().EnsureOpen(); using (var transaction = writeContext.Database.BeginTransaction().GetDbTransaction()) { //TODO: This needs better DB design //if no survey instance, create one if (surveyInstanceId == 0) { surveyInstanceId = (int)await sequencerGenerator.GetNextAsync(SequenceType.SurveyInstance); var instance = new SurveyInstance { IdSurveyInstance = surveyInstanceId.Value, IdProfile = command.ProfileId, }; if (command.OutbreakId != null) { instance.CdEntityType = "O"; instance.IdEntity = command.OutbreakId; } if (command.CaseId != null) { instance.CdEntityType = "C"; instance.IdEntity = command.CaseId; } await writeContext.SurveyInstance.AddAsync(instance); await writeContext.SaveChangesAsync(); } //end var context = new SurveyAnswerWriteContext { DB = writeContext, CaseId = command.CaseId, ProfileId = command.ProfileId, OutbreakId = command.OutbreakId, SurveyInstanceId = surveyInstanceId.Value, //should be assigned a value by this point UserId = usernameProvider.GetUsername(), Timestamp = DateTime.Now, QuestionStorageMap = questionStorageMap }; context.Transaction = transaction; context.Connection = connection; //apply the changes foreach (var delta in deltas) { context.Delta = delta; await writer.HandleAsync(context); //need to mark question as answered if (SurveyAnswerBindingHelpers.IsQuestion(delta.Key)) { var param = new { questionId = delta.Key }; try { string sql = @"update survey_question_bank set IN_ANSWERED = 1 where id_question = @questionId and IN_ANSWERED = 0;"; await connection.ExecuteAsync(sql, param, 1, transaction); } catch (Exception e) { //do nothing for now } } } transaction.Commit(); } }
public async Task <Dictionary <string, object> > Get(GetSurveyAnswers query) { //need to build a chain here var answerReader = COR <SurveyAnswerReadContext> .CreateChain( new EpiLinksReadHandler(), new HealthCareVisitsReadHandler(), new LabResultReadHandler(), new LabSummaryReadHandler(), new SymptomReadHandler(), new TravelHistoryReadHandler(), new MappedReadHandler(dataServices), new ReadOnlyReadHandler("Outbreak Lab List"), new RepeaterReadHandler(), new DefaultReadHandler()); //need to build the AnswerDictionary var existingLayout = await readContext.SurveyLayout .FirstOrDefaultAsync(layout => layout.Surveys .Any(survey => survey.UID == query.SurveyId)); var items = JsonConvert.DeserializeObject <IList <LayoutItemDto> >(existingLayout.JsLayout) .GetAll("control", "question", "repeatingQuestionsGroup"); var answers = new Dictionary <string, object>(); foreach (var item in items) { if (item.QuestionType == QuestionType.Check) { answers[item.Id.ToUpper()] = new List <string>(); } else { answers[item.Id.ToUpper()] = string.Empty; } } //need to get the survey instance ID var surveyInstanceId = await GetSurveyInstanceId(query.ProfileId, query.CaseId, query.OutbreakId); var handlingContext = new SurveyAnswerReadContext { DB = readContext, CaseId = query.CaseId, ProfileId = query.ProfileId, OutbreakId = query.OutbreakId, QuestionStorageMap = await GetQuestionStorageMap(query.SurveyId), SurveyInstanceId = surveyInstanceId.Value, Answers = answers }; var connection = readContext.Database.GetDbConnection().EnsureOpen(); handlingContext.Connection = connection; foreach (var item in items) { handlingContext.CurrentKey = item.Id.ToUpper(); handlingContext.CurrentItem = item; await answerReader.HandleAsync(handlingContext); } return(answers); }