Beispiel #1
0
        public static DataTable parseFile(string fileName)
        {
            QuestionParser  questionParser = new QuestionParser();
            List <Question> questions      = new List <Question>();

            string path = Path.Combine(Environment.CurrentDirectory, @"QuestionFiles\", fileName);

            //Skipping first line since it's version block
            string[] lines = File.ReadAllLines(path).Skip(1).ToArray();

            QuestionPart questionPart = QuestionPart.StartOfFile;

            foreach (var line in lines)
            {
                if (line != string.Empty || (line == string.Empty && questionPart != QuestionPart.QuestionDescription))
                {
                    questionPart = questionParser.identifyQuestionPart(line, questionPart);
                    questionParser.parseLine(line, questionPart);

                    if (questionPart == QuestionPart.QuestionDescription)
                    {
                        questions.Add(questionParser.ParsedQuestion);
                        questionParser.resetQuestion();
                    }
                }
            }

            return(CreateDataTable(questions));
        }
Beispiel #2
0
        /// <summary>
        /// Removes a set question option from the specified question part
        /// </summary>
        /// <param name="part"></param>
        /// <param name="name"></param>
        /// <param name="language">Null to remove all instances, otherwise remove a specific label</param>
        public void RemoveQuestionOption(QuestionPart part, int optionId, string language = null)
        {
            var  option  = part.QuestionOptions.SingleOrDefault(c => c.Id == optionId);
            bool removed = false;

            if (language == null)
            {
                part.QuestionOptions.Remove(option);
                removed = true;
            }
            else
            {
                option?.QuestionOptionLabels.Remove(
                    option.QuestionOptionLabels.SingleOrDefault(v => v.Language == language));
                if (option?.QuestionOptionLabels.Count == 0)
                {
                    part.QuestionOptions.Remove(option);
                    removed = true;
                }
            }
            //Update order if fully removed
            if (removed)
            {
                foreach (var remainingOption in part.QuestionOptions)
                {
                    if (remainingOption.Order > option.Order)
                    {
                        remainingOption.Order--;
                    }
                }
            }
        }
Beispiel #3
0
 /// <summary>
 ///
 /// </summary>
 /// <param name="survey"></param>
 /// <param name="question"></param>
 /// <param name="respondent"></param>
 /// <param name="responseData"></param>
 /// <param name="response"></param>
 internal void SaveIntegerResponse(Survey survey, QuestionPart question, JObject responseData, SurveyResponse response)
 {
     if (response.ResponseValues.Count == 0)
     {
         response.ResponseValues.Add(new IntegerResponse());
     }
     (response.ResponseValues[0] as IntegerResponse).Value = responseData.GetValue("value").ToObject <int> ();
 }
Beispiel #4
0
 /// <summary>
 ///
 /// </summary>
 /// <param name="survey"></param>
 /// <param name="question"></param>
 /// <param name="respondent"></param>
 /// <param name="responseData"></param>
 /// <param name="response"></param>
 internal void SaveDecimalResponse(Survey survey, QuestionPart question, JObject responseData, SurveyResponse response)
 {
     if (response.ResponseValues.Count == 0)
     {
         //response.ResponseValues = new List<ResponseValue>();
         response.ResponseValues.Add(new DecimalResponse());
     }
     (response.ResponseValues[0] as DecimalResponse).Value = responseData.GetValue("value").ToObject <double> ();
 }
Beispiel #5
0
        public void parseLine(string line, QuestionPart questionPart)
        {
            //if(line != string.Empty)
            //{
            switch (questionPart)
            {
            case QuestionPart.QuestionName:
                parseQuestionName(line);
                break;

            case QuestionPart.PictureSpeechName:
                parsePictureSpeechName(line);
                break;

            case QuestionPart.DifficultyFlagsRefs:
                parseDifficultyFlagsRefs(line);
                break;

            case QuestionPart.Dates:
                parseDates(line);
                break;

            case QuestionPart.QuestionText:
                ParsedQuestion.Text = line;
                break;

            case QuestionPart.QuestionAnswer1:
                parseAnswer(line, 1);
                break;

            case QuestionPart.QuestionAnswer2:
                parseAnswer(line, 2);
                break;

            case QuestionPart.QuestionAnswer3:
                parseAnswer(line, 3);
                break;

            case QuestionPart.QuestionAnswer4:
                parseAnswer(line, 4);
                break;

            case QuestionPart.QuestionAnswer5:
                parseAnswer(line, 5);
                break;

            case QuestionPart.QuestionDescription:
                ParsedQuestion.Description = line;
                break;

            default:
                break;
            }
            //}
        }
Beispiel #6
0
        /// <summary>
        /// Sets a question option value on the specified question part. If langauge is null then the default label is used, otherwise
        /// the value data is set on the matched langauge label.
        /// </summary>
        /// <param name="questionPart"></param>
        /// <param name="name"></param>
        /// <param name="value"></param>
        /// <param name="language"></param>
        public QuestionOption SetQuestionOptionLabel(QuestionPart questionPart, int id, string code, string name, string value, string language = null)
        {
            var option = questionPart.QuestionOptions.SingleOrDefault(o => o.Id == id);

            if (option != null)
            {
                if (language == null)
                {
                    language = option.QuestionOptionLabels.First().Language;
                }
                // replace code if different and unique from other codes
                if (option.Code != code)
                {
                    var allCodes = questionPart.QuestionOptions.Select(o => o.Code);
                    if (!allCodes.Contains(code))
                    {
                        option.Code = code;
                    }
                    else
                    {
                        throw new ArgumentException("Cannot have duplicate options!");
                    }
                }
                var optionLabel = option.QuestionOptionLabels.FirstOrDefault(v => v.Language == language);
                if (optionLabel == null)
                {
                    option.QuestionOptionLabels.Add(new QuestionOptionLabel()
                    {
                        Language       = language,
                        Value          = value,
                        QuestionOption = option
                    });
                }
                else
                {
                    var allLabels = questionPart.QuestionOptions.Where(q => q.Name == name && q.Id != id).SelectMany(o => o.QuestionOptionLabels.Where(q => q.Language == language).Select(l => l.Value));
                    if (!allLabels.Contains(value))
                    {
                        optionLabel.Value = value;
                    }
                    else
                    {
                        throw new ArgumentException("Cannot have duplicate options");
                    }
                }

                return(option);
            }
            else
            {
                return(this.AddQuestionOption(questionPart, code, name, value, language));
            }
        }
Beispiel #7
0
        public void ReOrderOptions(QuestionPart part, List <QuestionOption> newOrder)
        {
            Dictionary <int, int> newOrderDict = newOrder.ToDictionary(r => r.Id, r => r.Order);

            foreach (var option in part.QuestionOptions)
            {
                if (newOrderDict.ContainsKey(option.Id))
                {
                    option.Order = newOrderDict[option.Id];
                }
            }
        }
Beispiel #8
0
 public void UpdateQuestionPartName(int surveyId, QuestionPart qp, string newName)
 {
     //name update doesn't require any other updates (with part ID being used for question reference)
     if (qp != null)
     {
         if (this._unitOfWork.Surveys.QuestionNameIsUnique(surveyId, newName, qp.Name))
         {
             qp.Name = newName;
         }
         else
         {
             throw new ArgumentException("Question name must be unique.");
         }
     }
 }
Beispiel #9
0
        /// <summary>
        ///
        /// </summary>
        /// <param name="survey"></param>
        /// <param name="question"></param>
        /// <param name="respondent"></param>
        /// <param name="responseData"></param>
        /// <returns></returns>
        internal void SaveLocationResponse(Survey survey, QuestionPart question, JObject responseData, SurveyResponse response)
        {
            if (response.ResponseValues.Count == 0)
            {
                //response.ResponseValues = new List<ResponseValue>();
                response.ResponseValues.Add(new LocationResponse());
            }
            var value = responseData.ToObject <LocationResponse> ();

            (response.ResponseValues[0] as LocationResponse).Latitude  = value.Latitude;
            (response.ResponseValues[0] as LocationResponse).Longitude = value.Longitude;
            (response.ResponseValues[0] as LocationResponse).Address   = value.Address;

            //LocationResponse locationResponseValue = responseData.ToObject<LocationResponse>();

            return;
        }
Beispiel #10
0
        public void Test_SetQuestionConfiguration()
        {
            Survey survey = new Survey()
            {
                //      Title = "Test Survey",
            };

            var view = this._surveyBuilderService.AddSurveyView(survey, "View");

            var questionPart = new QuestionPart();

            this._surveyBuilderService.AddQuestionPart(view, new DAL.Models.Questions.QuestionPart(), null);

            this._surveyBuilderService.SetQuestionConfiguration(questionPart, "cat", "dog");

            Assert.True(true);
        }
Beispiel #11
0
        public QuestionPart identifyQuestionPart(string line, QuestionPart previousPart)
        {
            switch (previousPart)
            {
            case QuestionPart.QuestionName:
                return(QuestionPart.PictureSpeechName);

            case QuestionPart.PictureSpeechName:
                return(QuestionPart.DifficultyFlagsRefs);

            case QuestionPart.DifficultyFlagsRefs:
                return(QuestionPart.Dates);

            case QuestionPart.Dates:
                if (line != string.Empty)
                {
                    return(QuestionPart.QuestionText);
                }
                else
                {
                    return(QuestionPart.QuestionAnswer5);
                }

            case QuestionPart.QuestionText:
                return(QuestionPart.QuestionAnswer1);

            case QuestionPart.QuestionAnswer1:
                return(QuestionPart.QuestionAnswer2);

            case QuestionPart.QuestionAnswer2:
                return(QuestionPart.QuestionAnswer3);

            case QuestionPart.QuestionAnswer3:
                return(QuestionPart.QuestionAnswer4);

            case QuestionPart.QuestionAnswer4:
                return(QuestionPart.QuestionAnswer5);

            case QuestionPart.QuestionAnswer5:
                return(QuestionPart.QuestionDescription);

            default:
                return(QuestionPart.QuestionName);
            }
        }
Beispiel #12
0
        /// <summary>
        ///
        /// </summary>
        /// <param name="survey"></param>
        /// <param name="question"></param>
        /// <param name="respondent"></param>
        /// <param name="responseData"></param>
        /// <param name="response"></param>
        internal void SaveOptionSelectResponse(Survey survey, QuestionPart question, JObject responseData, SurveyResponse response)
        {
            response.ResponseValues.Clear();

            var values = responseData["values"].ToObject <List <OptionSelectResponse> > ();

            foreach (var val in values)
            {
                response.ResponseValues.Add(new OptionSelectResponse()
                {
                    Value = val.Value,
                    Name  = val.Name,
                    Code  = val.Code
                });
            }

            return;
        }
Beispiel #13
0
        /// <summary>
        /// Sets a configuration value for the specified question part
        /// </summary>
        /// <param name="questionPart"></param>
        /// <param name="name"></param>
        /// <param name="value"></param>
        public QuestionConfiguration SetQuestionConfiguration(QuestionPart questionPart, string name, object value)
        {
            var configuration = questionPart.QuestionConfigurations.SingleOrDefault(c => c.Name == name);

            if (configuration == null)
            {
                QuestionConfiguration qc = new QuestionConfiguration()
                {
                    Name      = name,
                    Value     = value.ToString(),
                    ValueType = this._questions.QuestionTypeDefinitions[questionPart.QuestionType].QuestionConfigurations[name].ValueType
                };
                questionPart.QuestionConfigurations.Add(qc);
                return(qc);
            }

            configuration.Value = value.ToString();
            return(configuration);
        }
Beispiel #14
0
        public void SetQuestionOptionConditionals(QuestionPart question, List <QuestionOptionConditional> conditionals)
        {
            List <QuestionOptionConditional> newSource    = new List <QuestionOptionConditional>();
            List <QuestionOptionConditional> updateSource = new List <QuestionOptionConditional>();
            List <QuestionOptionConditional> newTarget    = new List <QuestionOptionConditional>();
            List <QuestionOptionConditional> updateTarget = new List <QuestionOptionConditional>();

            conditionals.ForEach(conditional =>
            {
                if (conditional.SourceQuestionId == question.Id)
                {
                    if (conditional.Id == 0)
                    {
                        newSource.Add(conditional);
                    }
                    else
                    {
                        updateSource.Add(conditional);
                    }
                }
                else
                {
                    if (conditional.Id == 0)
                    {
                        newTarget.Add(conditional);
                    }
                    else
                    {
                        updateTarget.Add(conditional);
                    }
                }
            });

            this._unitOfWork.QuestionOptionConditionals.DeleteSourceConditionals(question.Id, updateSource.Select(c => c.Id).ToList());
            this._unitOfWork.QuestionOptionConditionals.DeleteTargetConditionals(question.Id, updateTarget.Select(c => c.Id).ToList());

            this._unitOfWork.QuestionOptionConditionals.AddRange(newSource);
            this._unitOfWork.QuestionOptionConditionals.AddRange(newTarget);
            this._unitOfWork.QuestionOptionConditionals.UpdateRange(updateSource);
            this._unitOfWork.QuestionOptionConditionals.UpdateRange(updateTarget);
        }
Beispiel #15
0
        /// <summary>
        /// Adds a question part to the specified SurveyView - this creates a new QuestionPartView from the part
        /// </summary>
        /// <param name="view"></param>
        /// <param name="part"></param>
        /// <param name="position">0-index order, position of the qustion</param>
        /// <returns>A reference to the created QuestionPartView</returns>
        public QuestionPartView AddQuestionPart(SurveyView view, QuestionPart part, QuestionTypeDefinition definition,
                                                int position = -1)
        {
            QuestionPartView questionPartView = new QuestionPartView
            {
                QuestionPart = part
            };

            if (position >= 0)
            {
                questionPartView.Order = position;
                (view.QuestionPartViews as List <QuestionPartView>)?.Insert(position, questionPartView);
            }
            else
            {
                (view.QuestionPartViews as List <QuestionPartView>)?.Add(questionPartView);
                questionPartView.Order = view.QuestionPartViews.Count - 1;
            }

            return(questionPartView);
        }
Beispiel #16
0
 /// <summary>
 ///
 /// </summary>
 /// <param name="question"></param>
 /// <param name="respondent"></param>
 /// <param name="repeat"></param>
 /// <returns></returns>
 private async Task <SurveyResponse> GenerateSurveyResponse(QuestionPart question, SurveyRespondent respondent, int repeat)
 {
     return(await this._unitOfWork.SurveyResponses.GetMostRecentResponseForQuestionByRespondentAsync(question.Id,
                                                                                                     (SurveyRespondent)respondent, repeat));
 }
Beispiel #17
0
        /// <summary>
        ///
        /// </summary>
        /// <param name="survey"></param>
        /// <param name="question"></param>
        /// <param name="respondent"></param>
        /// <param name="responseData"></param>
        /// <param name="repeat"></param>
        /// <returns></returns>
        public async Task <bool> SaveResponse(Survey survey, QuestionPart question, SurveyRespondent respondent, JObject responseData, int repeat)
        {
            var type = this._questionTypeManager.QuestionTypeDefinitions[question.QuestionType];

            if (type.ResponseValidator != null)
            {
                var responseDataUnwrapped = this.UnwrapResponseData(type.ResponseType, responseData);
                if (!type.ResponseValidator.ValidateResponse(responseDataUnwrapped, question.QuestionConfigurations.Cast <IQuestionConfiguration> ().ToHashSet()))
                {
                    return(false);
                }
            }

            var surveyResponse = await this._unitOfWork.SurveyResponses.GetMostRecentResponseForQuestionByRespondentAsync(question.Id,
                                                                                                                          (SurveyRespondent)respondent, repeat);

            if (surveyResponse == null ||
                (
                    surveyResponse.SurveyAccessRecord.AccessDateTime < ((PrimaryRespondent)respondent).SurveyAccessRecords.First().AccessDateTime))
            {
                surveyResponse = new SurveyResponse()
                {
                    QuestionPart       = question,
                    Respondent         = respondent,
                    SurveyAccessRecord = ((PrimaryRespondent)respondent).SurveyAccessRecords.First(),
                    Repeat             = repeat
                };
                this._unitOfWork.SurveyResponses.Add(surveyResponse);
            }

            // surveyResponse.Repeat = repeat;

            switch (type.ResponseType)
            {
            case QuestionResponseType.String:
                SaveStringResponse(survey, question, responseData, surveyResponse);
                break;

            case QuestionResponseType.Decimal:
                SaveDecimalResponse(survey, question, responseData, surveyResponse);
                break;

            case QuestionResponseType.Integer:
                SaveIntegerResponse(survey, question, responseData, surveyResponse);
                break;

            case QuestionResponseType.DateTime:
                SaveDateTimeResponse(surveyResponse, responseData);
                break;

            case QuestionResponseType.Path:
                SavePathResponse(surveyResponse, responseData);
                break;

            case QuestionResponseType.Json:
                SaveJsonResponse(surveyResponse, responseData);
                break;

            case QuestionResponseType.Location:
                SaveLocationResponse(survey, question, responseData, surveyResponse);
                break;

            case QuestionResponseType.Timeline:
                SaveTimelineResponse(surveyResponse, responseData);
                break;

            case QuestionResponseType.OptionSelect:
                //
                SaveOptionSelectResponse(survey, question, responseData, surveyResponse);
                break;
            }
            try {
                await this._unitOfWork.SaveChangesAsync();
            } catch (Exception e) {
                this._logger.LogError(e, "Error saving response.");
                return(false);
            }

            return(true);
        }
Beispiel #18
0
 /// <summary>
 ///
 /// </summary>
 /// <param name="part"></param>
 /// <param name="definition"></param>
 public void AddQuestionPartChild(QuestionPart part, QuestionTypeDefinition definition)
 {
     part.QuestionType = definition.TypeName;
     part.QuestionPartChildren.Add(part);
 }
Beispiel #19
0
 /// <summary>
 /// Returns the set of question options associated with this question part.
 /// </summary>
 /// <param name="questionPart"></param>
 /// <param name="language">Specify a main label language</param>
 /// <returns></returns>
 public IEnumerable <QuestionOption> GetQuestionOptions(QuestionPart questionPart, string language = null)
 {
     return(questionPart.QuestionOptions);
 }
Beispiel #20
0
 /// <summary>
 /// Retrieves the list of question configurations associated with this question part. Only values that differ
 /// from default values will be returned (default values are not stored).
 /// </summary>
 /// <param name="questionPart"></param>
 /// <returns></returns>
 public IEnumerable <QuestionConfiguration> GetQuestionConfigurations(QuestionPart questionPart)
 {
     return(questionPart.QuestionConfigurations);
 }
Beispiel #21
0
 /// <summary>
 /// Removes a configuration value (resets to default) from the specified QuestionPart.
 /// </summary>
 /// <param name="part"></param>
 /// <param name="name"></param>
 public void RemoveQuestionConfiguration(QuestionPart part, string name)
 {
     part.QuestionConfigurations.Remove(part.QuestionConfigurations.SingleOrDefault(c => c.Name == name));
 }
Beispiel #22
0
        /// <summary>
        /// Imports options into question part from stream
        /// </summary>
        /// <param name="questionPart">Question part</param>
        /// <param name="name">Option Group Name</param>
        /// <param name="language"></param>
        /// <param name="fileStream">File stream of csv file</param>
        /// <returns></returns>
        public List <(string, string, string)> ImportQuestionOptions(QuestionPart questionPart, string name, string language, IFormFile file)
        {
            try
            {
                //check if the option has a value / allows multiple
                List <(string, string, string)> errorList = new List <(string, string, string)>();


                var definition = this._questions.QuestionTypeDefinitions[questionPart.QuestionType];

                if (definition != null)
                {
                    if (definition.QuestionOptions.Keys.Contains(name))
                    {
                        int startOptionOrderIndex = questionPart.QuestionOptions.Count(o => o.Name == name);

                        IEnumerable <QuestionOptionData> optionData;
                        using (var fileStream = new StreamReader(file.OpenReadStream()))
                        {
                            var reader = new CsvReader(fileStream);
                            reader.Configuration.RegisterClassMap <QuestionOptionMap>();
                            reader.Configuration.PrepareHeaderForMatch = header => Regex.Replace(header, @"\s", string.Empty);
                            optionData = reader.GetRecords <QuestionOptionData>().ToList();
                        }

                        // get unique codes from input list
                        var allCodes = questionPart.QuestionOptions.Select(o => o.Code);

                        var importCodes          = optionData.Select(o => o.Code).ToList();
                        var duplicateImportCodes = importCodes.GroupBy(c => c).Where(g => g.Count() > 1).Select(c => c.Key).ToList();

                        var duplicateCodes = importCodes.Intersect(allCodes).Union(duplicateImportCodes).ToList();

                        // get unique labels from input list for question option group
                        var allLabels = questionPart.QuestionOptions.Where(q => q.Name == name).SelectMany(o => o.QuestionOptionLabels.Where(q => q.Language == language).Select(l => l.Value));

                        var importLabels          = optionData.Select(o => o.Label).ToList();
                        var duplicateImportLabels = importLabels.GroupBy(c => c).Where(g => g.Count() > 1).Select(c => c.Key).ToList();

                        var duplicateLabels = importLabels.Intersect(allLabels).Union(duplicateImportLabels).ToList();

                        foreach (var option in optionData)
                        {
                            bool duplicateCode  = duplicateCodes.Contains(option.Code);
                            bool duplicateLabel = duplicateLabels.Contains(option.Label);
                            if (duplicateCode || duplicateLabel)
                            {
                                string reason = duplicateCode && duplicateLabel ? "Duplicate option" : (duplicateCode ? "Duplicate Code" : "Duplicate Label");
                                errorList.Add((option.Code, option.Label, reason));
                            }
                            else
                            {
                                var newOption = new QuestionOption()
                                {
                                    Name  = name,
                                    Code  = option.Code,
                                    Order = startOptionOrderIndex++,
                                    QuestionOptionLabels = new LabelCollection <QuestionOptionLabel>()
                                    {
                                        new QuestionOptionLabel()
                                        {
                                            Language = language ?? "en",
                                            Value    = option.Label
                                        }
                                    }
                                };
                                if (definition.QuestionOptions[name].IsMultipleAllowed)
                                {
                                    questionPart.QuestionOptions.Add(newOption);
                                }
                                else if (newOption.Order == 0)
                                {
                                    questionPart.QuestionOptions.Add(newOption);
                                }
                                else
                                {
                                    throw new InvalidOperationException("Cannot assign new question option, remove first.");
                                }
                            }
                        }
                    }
                    else
                    {
                        throw new ArgumentException("Question Option does not exist for this question type.");
                    }
                }
                else
                {
                    throw new ArgumentException("Question Type does not exist.");
                }
                return(errorList);
            } catch (ValidationException exception)
            {
                if (exception.Message.StartsWith("Header"))
                {
                    throw new ArgumentException("Error in CSV file.  Must contain 'Code' and 'Label' header row");
                }
                else
                {
                    throw new Exception("Error during import");
                }
            }
        }
Beispiel #23
0
        /// <summary>
        ///
        /// </summary>
        /// <param name="part"></param>
        /// <param name="name"></param>
        /// <param name="language"></param>
        public QuestionOption AddQuestionOption(QuestionPart part, string code, string name, string value, string language = null)
        {
            //check if the option has a value / allows multiple

            var definition =
                this._questions.QuestionTypeDefinitions[part.QuestionType];

            if (definition != null)
            {
                if (definition.QuestionOptions.Keys.Contains(name))
                {
                    //ensure code hasn't been used already
                    var allCodes = part.QuestionOptions.Select(o => o.Code);
                    if (allCodes.Contains(code))
                    {
                        throw new ArgumentException("Cannot have duplicate options");
                    }

                    var allLabels = part.QuestionOptions.Where(q => q.Name == name).SelectMany(o => o.QuestionOptionLabels.Where(q => q.Language == language).Select(l => l.Value));
                    if (allLabels.Contains(value))
                    {
                        throw new ArgumentException("Cannot have duplicate options");
                    }
                    var newOption = new QuestionOption()
                    {
                        Name  = name,
                        Code  = code,
                        Order = part.QuestionOptions.Count(o => o.Name == name),
                        QuestionOptionLabels = new LabelCollection <QuestionOptionLabel>()
                        {
                            new QuestionOptionLabel()
                            {
                                Language = language ?? "en",
                                Value    = value
                            }
                        }
                    };
                    if (definition.QuestionOptions[name].IsMultipleAllowed)
                    {
                        part.QuestionOptions.Add(newOption);
                    }
                    else if (newOption.Order == 0)
                    {
                        part.QuestionOptions.Add(newOption);
                    }
                    else
                    {
                        throw new InvalidOperationException("Cannot assign new question option, remove first.");
                    }
                    return(newOption);
                }
                else
                {
                    throw new ArgumentException("Question Option does not exist for this question type.");
                }
            }
            else
            {
                throw new ArgumentException("Question Type does not exist.");
            }
        }