Example #1
0
        /// <summary>
        /// 驗證問卷填答規則
        /// </summary>
        /// <param name="answer">問卷填答資料</param>
        /// <param name="questionEntity">問卷資料</param>
        /// <returns>驗證結果</returns>
        public Dictionary <string, string> ValidateRule(QuestionnaireAnswerEntity answer,
                                                        QuestionnaireEntity questionEntity)
        {
            Dictionary <string, string>      validateResult   = new Dictionary <string, string>();
            IEnumerable <AnswerDetailEntity> answerDetailList = null;
            string errorMsg = null;


            foreach (QuestDefineEntity questDefineEntity in questionEntity.QuestDefineEntities)
            {
                errorMsg         = null;
                answerDetailList = null;

                answerDetailList = answer.AnswerDetailEntities.
                                   Where(x => x.QuestionId == questDefineEntity.QuestionId);


                if (!ValidateNeedAnswer(questDefineEntity, answerDetailList, answer.AnswerDetailEntities))
                {
                    errorMsg = $"此題必須填答!";
                }
                else if (!ValidateMinMultipleAnswers(questDefineEntity, answerDetailList))
                {
                    errorMsg = $"此題至少須勾選{questDefineEntity.MinMultipleAnswers}個項目!";
                }
                else if (!ValidateMaxMultipleAnswers(questDefineEntity, answerDetailList))
                {
                    errorMsg = $"此題至多僅能勾選{questDefineEntity.MaxMultipleAnswers}個項目!";
                }
                else if (!ValidateSingleAnswerCondition(questDefineEntity, answerDetailList,
                                                        answer.AnswerDetailEntities))
                {
                    errorMsg = $"此題僅能勾選1個項目!";
                }
                else if (!ValidateOtherAnswer(questDefineEntity, answerDetailList))
                {
                    errorMsg = $"請輸入其他說明文字!";
                }

                if (!String.IsNullOrEmpty(errorMsg))
                {
                    validateResult.Add(questDefineEntity.QuestionId, errorMsg);
                }
            }

            return(validateResult);
        }
        public void ValidateRule_When_OtherAnswer_Then_Fail()
        {
            //Arrange
            var answer = new QuestionnaireAnswerEntity()
            {
                AnswerDetailEntities = new List <AnswerDetailEntity>()
                {
                    new AnswerDetailEntity()
                    {
                        QuestionId = "Q1", AnswerCode = "A", OtherAnswer = "", Score = null,
                    },
                    new AnswerDetailEntity()
                    {
                        QuestionId = "Q2", AnswerCode = "A", OtherAnswer = "", Score = null,
                    },
                    new AnswerDetailEntity()
                    {
                        QuestionId = "Q3", AnswerCode = "A", OtherAnswer = "", Score = null,
                    },
                    new AnswerDetailEntity()
                    {
                        QuestionId = "Q3", AnswerCode = "E", OtherAnswer = "", Score = null,
                    },
                    new AnswerDetailEntity()
                    {
                        QuestionId = "Q4", AnswerCode = "A", OtherAnswer = "", Score = null,
                    },
                    new AnswerDetailEntity()
                    {
                        QuestionId = "Q5", AnswerCode = "A", OtherAnswer = "", Score = null,
                    },
                },
            };

            var question = new QuestionnaireEntity()
            {
                ScoreKind           = "",
                QuestScore          = null,
                NeedScore           = "N",
                QuestDefineEntities = new List <QuestDefineEntity>()
                {
                    new QuestDefineEntity()
                    {
                        Uid = Guid.Empty, QuestUid = Guid.Empty, QuestionId = "Q1", QuestionContent = "請輸入您的手機號碼(格式為0912345678,將作為活動通知使用)", NeedAnswer = "Y", AllowNaCondition = "", AnswerType = "F", MinMultipleAnswers = null, MaxMultipleAnswers = null, SingleAnswerCondition = "", CountScoreType = "", Memo = "", OrderSn = 10, CreateUserId = "", CreateTime = null, ModifyUserId = "", ModifyTime = null, AnswerDefineEntities = new List <AnswerDefineEntity>()
                        {
                            new AnswerDefineEntity()
                            {
                                AnswerCode = " ", AnswerContent = "旅遊行程(例如:來回機票、住宿券)", Memo = "", HaveOtherAnswer = "Y", NeedOtherAnswer = "Y", Score = null, OrderSn = 10,
                            },
                        }
                    },
                    new QuestDefineEntity()
                    {
                        Uid = Guid.Empty, QuestUid = Guid.Empty, QuestionId = "Q2", QuestionContent = "下列哪種活動贈品最吸引您參加活動?", NeedAnswer = "Y", AllowNaCondition = "", AnswerType = "M", MinMultipleAnswers = 1, MaxMultipleAnswers = null, SingleAnswerCondition = "", CountScoreType = "", Memo = "", OrderSn = 20, CreateUserId = "", CreateTime = null, ModifyUserId = "", ModifyTime = null, AnswerDefineEntities = new List <AnswerDefineEntity>()
                        {
                            new AnswerDefineEntity()
                            {
                                AnswerCode = "A", AnswerContent = "3C產品(例如:手機、平板電腦、相機)", Memo = "", HaveOtherAnswer = "N", NeedOtherAnswer = "N", Score = null, OrderSn = 10,
                            },
                            new AnswerDefineEntity()
                            {
                                AnswerCode = "B", AnswerContent = "禮券(例如:知名百貨、量販店、便利商店禮券)", Memo = "", HaveOtherAnswer = "N", NeedOtherAnswer = "N", Score = null, OrderSn = 20,
                            },
                            new AnswerDefineEntity()
                            {
                                AnswerCode = "C", AnswerContent = "簡訊", Memo = "", HaveOtherAnswer = "N", NeedOtherAnswer = "N", Score = null, OrderSn = 30,
                            }
                        }
                    },
                    new QuestDefineEntity()
                    {
                        Uid = Guid.Empty, QuestUid = Guid.Empty, QuestionId = "Q3", QuestionContent = "您最喜歡透過下列何種方式收到行銷優惠資訊?", NeedAnswer = "Y", AllowNaCondition = "", AnswerType = "M", MinMultipleAnswers = 1, MaxMultipleAnswers = null, SingleAnswerCondition = "", CountScoreType = "", Memo = "", OrderSn = 30, CreateUserId = "", CreateTime = null, ModifyUserId = "", ModifyTime = null, AnswerDefineEntities = new List <AnswerDefineEntity>()
                        {
                            new AnswerDefineEntity()
                            {
                                AnswerCode = "A", AnswerContent = "電子DM", Memo = "", HaveOtherAnswer = "N", NeedOtherAnswer = "N", Score = null, OrderSn = 10,
                            },
                            new AnswerDefineEntity()
                            {
                                AnswerCode = "B", AnswerContent = "實體DM", Memo = "", HaveOtherAnswer = "N", NeedOtherAnswer = "N", Score = null, OrderSn = 20,
                            },
                            new AnswerDefineEntity()
                            {
                                AnswerCode = "C", AnswerContent = "即時通訊軟體(例如:LINE、what’s app)", Memo = "", HaveOtherAnswer = "N", NeedOtherAnswer = "N", Score = null, OrderSn = 30,
                            },
                            new AnswerDefineEntity()
                            {
                                AnswerCode = "D", AnswerContent = "其他", Memo = "", HaveOtherAnswer = "N", NeedOtherAnswer = "N", Score = null, OrderSn = 40,
                            },
                            new AnswerDefineEntity()
                            {
                                AnswerCode = "E", AnswerContent = "臨櫃", Memo = "", HaveOtherAnswer = "Y", NeedOtherAnswer = "Y", Score = null, OrderSn = 50,
                            },
                        }
                    },
                    new QuestDefineEntity()
                    {
                        Uid = Guid.Empty, QuestUid = Guid.Empty, QuestionId = "Q4", QuestionContent = "下列哪一項通路服務是您最常使用的?(一個月至少使用3次以上)", NeedAnswer = "Y", AllowNaCondition = "", AnswerType = "S", MinMultipleAnswers = null, MaxMultipleAnswers = null, SingleAnswerCondition = "", CountScoreType = "", Memo = "", OrderSn = 40, CreateUserId = "", CreateTime = null, ModifyUserId = "", ModifyTime = null, AnswerDefineEntities = new List <AnswerDefineEntity>()
                        {
                            new AnswerDefineEntity()
                            {
                                AnswerCode = "A", AnswerContent = "ATM", Memo = "", HaveOtherAnswer = "N", NeedOtherAnswer = "N", Score = null, OrderSn = 10,
                            },
                            new AnswerDefineEntity()
                            {
                                AnswerCode = "B", AnswerContent = "網站", Memo = "", HaveOtherAnswer = "N", NeedOtherAnswer = "N", Score = null, OrderSn = 20,
                            },
                            new AnswerDefineEntity()
                            {
                                AnswerCode = "C", AnswerContent = "行動APP", Memo = "", HaveOtherAnswer = "N", NeedOtherAnswer = "N", Score = null, OrderSn = 30,
                            },
                            new AnswerDefineEntity()
                            {
                                AnswerCode = "D", AnswerContent = "都沒有", Memo = "", HaveOtherAnswer = "N", NeedOtherAnswer = "N", Score = null, OrderSn = 40,
                            },
                            new AnswerDefineEntity()
                            {
                                AnswerCode = "E", AnswerContent = "1分", Memo = "", HaveOtherAnswer = "N", NeedOtherAnswer = "N", Score = null, OrderSn = 50,
                            },
                        }
                    },
                    new QuestDefineEntity()
                    {
                        Uid = Guid.Empty, QuestUid = Guid.Empty, QuestionId = "Q5", QuestionContent = "您對我們的服務滿意度1至5分是?", NeedAnswer = "Y", AllowNaCondition = "{\"Conditions\":[{\"QuestionId\": \"Q4\", \"AnswerCode\": [\"E\"]}]}", AnswerType = "S", MinMultipleAnswers = null, MaxMultipleAnswers = null, SingleAnswerCondition = "", CountScoreType = "", Memo = "", OrderSn = 50, CreateUserId = "", CreateTime = null, ModifyUserId = "", ModifyTime = null, AnswerDefineEntities = new List <AnswerDefineEntity>()
                        {
                            new AnswerDefineEntity()
                            {
                                AnswerCode = "A", AnswerContent = "2分", Memo = "", HaveOtherAnswer = "N", NeedOtherAnswer = "N", Score = null, OrderSn = 10,
                            },
                            new AnswerDefineEntity()
                            {
                                AnswerCode = "B", AnswerContent = "3分", Memo = "", HaveOtherAnswer = "N", NeedOtherAnswer = "N", Score = null, OrderSn = 20,
                            },
                            new AnswerDefineEntity()
                            {
                                AnswerCode = "C", AnswerContent = "4分", Memo = "", HaveOtherAnswer = "N", NeedOtherAnswer = "N", Score = null, OrderSn = 30,
                            },
                            new AnswerDefineEntity()
                            {
                                AnswerCode = "D", AnswerContent = "5分", Memo = "", HaveOtherAnswer = "N", NeedOtherAnswer = "N", Score = null, OrderSn = 40,
                            },
                            new AnswerDefineEntity()
                            {
                                AnswerCode = "E", AnswerContent = "", Memo = "", HaveOtherAnswer = "N", NeedOtherAnswer = "N", Score = null, OrderSn = 50,
                            },
                        }
                    },


                    new QuestDefineEntity()
                    {
                        Uid = Guid.Parse("F9DD6938-2DBD-48AF-9D44-428DCB2AC5D6"), QuestionId = "Q001", CountScoreType = "2", NeedAnswer = "N", AnswerType = "S", MinMultipleAnswers = null, MaxMultipleAnswers = null, SingleAnswerCondition = "", AllowNaCondition = "", AnswerDefineEntities = new List <AnswerDefineEntity>()
                        {
                            new AnswerDefineEntity()
                            {
                                AnswerCode = "1", Score = 1,
                            },
                            new AnswerDefineEntity()
                            {
                                AnswerCode = "2", Score = 2,
                            },
                            new AnswerDefineEntity()
                            {
                                AnswerCode = "3", Score = 3,
                            },
                            new AnswerDefineEntity()
                            {
                                AnswerCode = "4", Score = 4,
                            },
                            new AnswerDefineEntity()
                            {
                                AnswerCode = "5", Score = 5,
                            },
                        }
                    },
                }
            };


            Dictionary <string, string> expected = new Dictionary <string, string>()
            {
                { "Q3", "請輸入其他說明文字!" },
            };

            //Actual
            Dictionary <string, string> actual = new QuestionnaireService().ValidateRule(answer, question);


            //Assert
            CollectionAssert.AreEqual(expected, actual);
        }
Example #3
0
        /// <summary>
        /// 計算問卷得分,回傳問卷得分類別
        /// </summary>
        /// <param name="answer">問卷填答資料</param>
        /// <param name="questionEntity">問卷定義資料</param>
        /// <returns>問卷得分類別</returns>
        public CalculateScoreEntity CalculateScore(QuestionnaireAnswerEntity answer,
                                                   QuestionnaireEntity questionEntity)
        {
            List <AnswerDetailEntity> answerFullDetailList = new List <AnswerDetailEntity>();

            int        actualScore       = 0;
            List <int> questionScoreList = new List <int>();

            IEnumerable <AnswerDetailEntity> answerDetailList = null;
            AnswerDetailEntity answerDetail    = null;
            AnswerDefineEntity answerDefine    = null;
            IEnumerable <int>  answerScoreList = null;

            foreach (QuestDefineEntity questDefine in questionEntity.QuestDefineEntities)
            {
                answerDetailList = null;
                answerDetail     = null;
                answerDefine     = null;
                answerScoreList  = null;

                answerDetailList = answer.AnswerDetailEntities.
                                   Where(x => (x.QuestionId == questDefine.QuestionId) &&
                                         !String.IsNullOrEmpty(x.AnswerCode));

                if (questDefine.AnswerType == "S")
                {
                    if (answerDetailList.Count() == 0)
                    {
                        continue;
                    }
                    else if (answerDetailList.Count() > 1)
                    {
                        var ex = new InvalidOperationException("answerCode not the only");
                        ex.Data["questDefine.QuestionId"] = questDefine.QuestionId;
                        ex.Data["answerCodeList"]         = String.Join(",", answerDetailList);
                        throw ex;
                    }

                    answerDetail = answerDetailList.First();

                    answerDefine = questDefine.AnswerDefineEntities.
                                   FirstOrDefault(x => x.AnswerCode == answerDetail.AnswerCode);

                    if (answerDefine == null)
                    {
                        var ex = new InvalidOperationException("answerDefine not found");
                        ex.Data["answerDetail.AnswerCode"] = answerDetail.AnswerCode;
                        throw ex;
                    }

                    answerFullDetailList.Add(new AnswerDetailEntity
                    {
                        QuestionUid = questDefine.Uid,
                        Score       = answerDefine.Score,

                        QuestionId  = answerDetail.QuestionId,
                        AnswerCode  = answerDetail.AnswerCode,
                        OtherAnswer = answerDetail.OtherAnswer,
                    });
                }
                else if (questDefine.AnswerType == "M")
                {
                    foreach (AnswerDetailEntity answerDetailEntity in answerDetailList)
                    {
                        answerDefine = null;

                        answerDefine = questDefine.AnswerDefineEntities.
                                       FirstOrDefault(x => x.AnswerCode == answerDetailEntity.AnswerCode);

                        if (answerDefine == null)
                        {
                            var ex = new InvalidOperationException("answerDefine not found");
                            ex.Data["questDefine.QuestionId"]        = questDefine.QuestionId;
                            ex.Data["answerDetailEntity.AnswerCode"] = answerDetailEntity.AnswerCode;
                            throw ex;
                        }

                        answerFullDetailList.Add(new AnswerDetailEntity
                        {
                            QuestionUid = questDefine.Uid,
                            Score       = answerDefine.Score,

                            QuestionId  = answerDetailEntity.QuestionId,
                            AnswerCode  = answerDetailEntity.AnswerCode,
                            OtherAnswer = answerDetailEntity.OtherAnswer,
                        });
                    }
                }
                else if (questDefine.AnswerType == "F")
                {
                    if (answerDetailList.Count() == 0)
                    {
                        var ex = new InvalidOperationException("answerCode not the only");
                        ex.Data["questDefine.QuestionId"] = questDefine.QuestionId;
                        throw ex;
                    }
                    else if (answerDetailList.Count() != 1)
                    {
                        var ex = new InvalidOperationException("answerCode not the only");
                        ex.Data["questDefine.QuestionId"] = questDefine.QuestionId;
                        ex.Data["answerCodeList"]         = String.Join(",", answerDetailList);
                        throw ex;
                    }

                    answerDetail = answerDetailList.First();

                    IEnumerable <AnswerDefineEntity> answerDefineList = questDefine.AnswerDefineEntities.
                                                                        Where(x => x.AnswerCode == String.Empty);

                    if (answerDefineList.Count() == 0)
                    {
                        var ex = new InvalidOperationException("answerDefineList not found");
                        ex.Data["questDefine.QuestionId"] = questDefine.QuestionId;
                        throw ex;
                    }
                    else if (answerDefineList.Count() != 1)
                    {
                        var ex = new InvalidOperationException("answerDefineList not the only");
                        ex.Data["questDefine.QuestionId"] = questDefine.QuestionId;
                        throw ex;
                    }

                    answerDefine = answerDefineList.First();

                    answerFullDetailList.Add(new AnswerDetailEntity
                    {
                        QuestionUid = questDefine.Uid,
                        Score       = answerDefine.Score,

                        QuestionId  = answerDetail.QuestionId,
                        AnswerCode  = null,
                        OtherAnswer = answerDetail.AnswerCode,
                    });
                }


                if (questionEntity.NeedScore == "Y")
                {
                    answerScoreList = answerFullDetailList.
                                      Where(x => (x.QuestionId == questDefine.QuestionId) && (x.Score != null)).
                                      Select(x => x.Score.Value);

                    if ((answerScoreList == null) ||
                        (answerScoreList.Count() == 0))
                    {
                        var ex = new InvalidOperationException("answerScoreList not found");
                        ex.Data["questDefine.QuestionId"] = questDefine.QuestionId;
                        throw ex;
                    }

                    switch (questDefine.CountScoreType)
                    {
                    case "1":
                        questionScoreList.Add(answerScoreList.Sum());
                        break;

                    case "2":
                        questionScoreList.Add(answerScoreList.Max());
                        break;

                    case "3":
                        questionScoreList.Add(answerScoreList.Min());
                        break;

                    case "4":
                        questionScoreList.Add(Convert.ToInt32(Math.
                                                              Round(answerScoreList.Average(), 0, MidpointRounding.AwayFromZero)));
                        break;

                    default:

                        var ex = new InvalidOperationException("countScoreType not found");
                        ex.Data["questDefine.QuestionId"]     = questDefine.QuestionId;
                        ex.Data["questDefine.CountScoreType"] = questDefine.CountScoreType;
                        throw ex;
                    }
                }
            }

            if (questionEntity.NeedScore == "Y")
            {
                if (questionEntity.ScoreKind == "1")
                {
                    actualScore = questionScoreList.Sum();
                }

                if ((questionEntity.QuestScore != null) &&
                    (actualScore > questionEntity.QuestScore.Value))
                {
                    actualScore = questionEntity.QuestScore.Value;
                }
            }

            return(new CalculateScoreEntity()
            {
                ActualScore = actualScore,
                FullAnswerDetailList = answerFullDetailList,
            });
        }
Example #4
0
        /// <summary>
        /// 計算問卷填答得分
        /// </summary>
        /// <param name="answer">問卷填答資料</param>
        /// <returns>問卷填答評分結果</returns>
        public QuestionnaireResultEntity Calculate(QuestionnaireAnswerEntity answer)
        {
            QuestionnaireResultEntity questionResultEntity = null;
            QuestionnaireAnswerDO     questionAnswerDO     = null;

            if (answer == null)
            {
                throw new ArgumentNullException("沒有提供問卷填答資料");
            }

            QuestionnaireEntity questionEntity = GetQuestionnaire(answer.QuestUid);
            DateTime            currentTime    = DateTime.Now;

            if ((questionEntity == null) ||
                (questionEntity.Ondate >= currentTime) ||
                (questionEntity.Offdate != null) && (questionEntity.Offdate <= currentTime))
            {
                var ex = new InvalidOperationException("問卷資料不存在或沒有有效的問卷資料");
                ex.Data["QuestionUis"] = answer.QuestUid;
                throw ex;
            }


            Dictionary <string, string> validateResult = ValidateRule(answer, questionEntity);

            if (validateResult == null)
            {
                throw new InvalidOperationException("validateResult not found");
            }


            Dictionary <string, string> riskResult = null;
            string dialogMsg = null;


            if (validateResult.Count == 0)
            {
                CalculateScoreEntity calculateResult = CalculateScore(answer, questionEntity);

                if (calculateResult == null)
                {
                    throw new InvalidOperationException("calculateResult not found");
                }

                riskResult = calculateResult.FullAnswerDetailList.
                             Where(x => !String.IsNullOrEmpty(x.AnswerCode)).
                             GroupBy(x => x.QuestionId).
                             Select(group => new
                {
                    group.Key,
                    Value = String.Join(",", group.Select(item => item.AnswerCode))
                }).ToDictionary(x => x.Key, x => x.Value);

                if (riskResult == null)
                {
                    throw new InvalidOperationException("riskResult not found");
                }

                questionAnswerDO = SaveQuestionAnswer(questionEntity, calculateResult,
                                                      answer.UserId);

                if (questionAnswerDO == null)
                {
                    throw new InvalidOperationException("questionAnswerDO not found");
                }

                if (questionEntity.NeedScore != "Y")
                {
                    dialogMsg = "您的問卷己填答完畢,謝謝您的參與";
                }
            }


            questionResultEntity = new QuestionnaireResultEntity()
            {
                QuestionnaireEntity  = questionEntity,
                AnswerDetailEntities = answer.AnswerDetailEntities,
                ValidateFailInfo     = validateResult,
                RiskResult           = riskResult,
                QuestionnaireMessage = dialogMsg,
            };

            if (questionAnswerDO != null)
            {
                questionResultEntity.Uid           = questionAnswerDO.Uid;
                questionResultEntity.QuestUid      = questionAnswerDO.QuestUid;
                questionResultEntity.QuestAnswerId = questionAnswerDO.QuestAnswerId;
                questionResultEntity.TesteeId      = questionAnswerDO.TesteeId;
                questionResultEntity.QuestScore    = questionAnswerDO.QuestScore;
                questionResultEntity.ActualScore   = questionAnswerDO.ActualScore;
                questionResultEntity.TesteeSource  = questionAnswerDO.TesteeSource;
                questionResultEntity.CreateUserId  = questionAnswerDO.CreateUserId;
                questionResultEntity.CreateTime    = questionAnswerDO.CreateTime;
                questionResultEntity.ModifyUserId  = questionAnswerDO.ModifyUserId;
                questionResultEntity.ModifyTime    = questionAnswerDO.ModifyTime;
            }

            return(questionResultEntity);
        }