public IEnumerable<ResultMessageViewModel> ExecuteQualityAssuranceChain(QualityCheckingExecuteDataViewModel data)
        {
            var resultMessages = new List<ResultMessageViewModel>();

            if (data != null)
            {
                var qcChainConfiguration = MapTOChainConfiguration(data);

                var versioningHelper = new DataVersioningHelper(_wqDefaultValueProvider);
                var factory = new DataQualityCheckingToolFactory(versioningHelper, _relatedActionTypeRepository);
                var qualiltyChecker = new WaterQualityDataQualityChecker(qcChainConfiguration, factory, _wqDataRepository);

                var qcResults = qualiltyChecker.Check();

                var resultViewModels = Mapper.Map<IEnumerable<IQualityCheckingResult>, IEnumerable<ResultMessageViewModel>>(qcResults);

                resultMessages.AddRange(resultViewModels);
            }
            else
            {
                resultMessages.Add(new ResultMessageViewModel(ResultMessageViewModel.RESULT_LEVEL_FATAL, 
                                                              "QC request data is null. No QC process could be applied."));
            }

            return resultMessages;
            
        }
        public static void Main(string[] args)
        {
            var dbContext = new ODM2Entities();

            var relationActionTypeRepository = new Repository<CV_RelationshipType>(dbContext);
            var wqDataRepository = new WQDataRepository(dbContext);

            var staticWQDefaultValueProvider = new StaticWQDefaultValueProvider();
            staticWQDefaultValueProvider.Init();

            Console.WriteLine("Start Quality Checking Process...");

            var qcChainConfiguration = ConfigureQualityCheckingChain(true, wqDataRepository, "Test", false, "Water");

            var versioningHelper = new DataVersioningHelper(staticWQDefaultValueProvider);
            var factory = new DataQualityCheckingToolFactory(versioningHelper, relationActionTypeRepository);
            var qualiltyChecker = new WaterQualityDataQualityChecker(qcChainConfiguration, factory, wqDataRepository);

            var qcResults = qualiltyChecker.Check();

            foreach(var result in qcResults)
            {
                Console.WriteLine(string.Format("{0}: {1}", result.Level, result.Message));
            
            }

            Console.WriteLine("Press any keys to continue...");
            Console.ReadLine();
        }
        public ESDATDataDisplayViewModel GetSampleCollectionActionInESDAT(int Id, int? version = null)
        {
            var mappingHelper = new ESDATViewModelMappingHelper();
            var versionHelper = new DataVersioningHelper(_wqDefaultValueProvider);

            var matchedAction = _wqDataRepository.GetActionById(Id);

            var esdatModel = Mapper.Map<ESDATDataDisplayViewModel>(matchedAction);
            //no version function is applied to chemistry data yet
            esdatModel.ChemistryData = ESDATViewModelMappingHelper.MapActionToChemistryFileData(matchedAction, versionHelper);
            
            if (version.HasValue)
            {
                esdatModel.CurrentSampleDataVersion = version.Value;
                if(version.Value == 0)
                {
                    esdatModel.SampleFileData = ESDATViewModelMappingHelper.MapActionToSampleFileData(matchedAction);
                }
                else if(version.Value >= 1)
                {
                    while (version >= 1)
                    {
                        var nextVersion = versionHelper.GetNextVersionActionData(matchedAction);
                        if (nextVersion == null)
                        {
                            throw new ArgumentException();
                        }
                        matchedAction = nextVersion;
                        version--;
                    }
                }
                else
                {
                    throw new ArgumentException();
                }
               

                esdatModel.SampleFileData = ESDATViewModelMappingHelper.MapActionToSampleFileData(matchedAction);
            }
            else
            {
                //show the latest version data by default
                var numberOfSubversions = versionHelper.GetSubVersionCountOfAction(matchedAction);
                matchedAction = versionHelper.GetLatestVersionActionData(matchedAction);
                
                esdatModel.CurrentSampleDataVersion = numberOfSubversions;
                esdatModel.SampleFileData = ESDATViewModelMappingHelper.MapActionToSampleFileData(matchedAction);
            }

            return esdatModel;
            
        }
        public IEnumerable<StationAnalyteQueryViewModel> FetchStationData(FetchSiteAnalyteQueryViewModel queryViewModel)
        {
            var items = new List<StationAnalyteQueryViewModel>();
            var actions = _wqDataRepository.GetAllWQAnalyteDataActions();
            var versionHelper = new DataVersioningHelper(_wqDefaultValueProvider);

            if (queryViewModel.SelectedVariables != null && queryViewModel.SelectedSiteID != null)
            {
            foreach (var action in actions)
            {
                foreach (var analyte in queryViewModel.SelectedVariables)
                {
                    var latestAction = versionHelper.GetLatestVersionActionData(action);

                    var analyteResultViewModel = from featureAction in latestAction.FeatureActions
                                 from analyteResult in featureAction.Results
                                 where featureAction.SamplingFeatureID == queryViewModel.SelectedSiteID
                                 where analyteResult.VariableID == analyte
                                 select analyteResult;

                    var result = analyteResultViewModel.FirstOrDefault();

                    //var result = latestAction.FeatureActions.Where(x => x.SamplingFeatureID == queryViewModel.SelectedSiteID).FirstOrDefault().Results.Where(x => x.VariableID == analyte).FirstOrDefault();


                    if (result != null && result.ResultExtensionPropertyValues.Where(x => x.ExtensionProperty.PropertyName == "Result Type").FirstOrDefault().PropertyValue == "REG")
                    {
                        if (result.MeasurementResult != null && result.MeasurementResult.MeasurementResultValues.First().ValueDateTime <= queryViewModel.EndDate && result.MeasurementResult.MeasurementResultValues.First().ValueDateTime >= queryViewModel.StartDate)
                        {
                            var measurementValue = result.MeasurementResult.MeasurementResultValues.FirstOrDefault().DataValue;
                            var resultDateTime = latestAction.BeginDateTime;
                            var unitsName = result.Unit.UnitsName;
                            string prefix = null;
                            if (result.ResultExtensionPropertyValues.Where(x => x.ExtensionProperty.PropertyName == "Prefix").FirstOrDefault().PropertyValue != null)
                            {
                                prefix = result.ResultExtensionPropertyValues.Where(x => x.ExtensionProperty.PropertyName == "Prefix").FirstOrDefault().PropertyValue;
                            }
                            var variable = result.Variable.VariableDefinition;
                            double? detectionLimit = null;
                            if (result.ResultsDataQualities.Count > 0)
                            {
                                detectionLimit = result.ResultsDataQualities.Where(x => x.DataQuality.DataQualityTypeCV == "methodDetectionLimit").FirstOrDefault().DataQuality.DataQualityValue;
                            }
                            items.Add(new StationAnalyteQueryViewModel { DataValue = measurementValue, ResultDateTime = resultDateTime.ToString("MMM-dd-yyyy, HH:mm tt"), UnitsName = unitsName, Variable = variable, MethodDetectionLimit = detectionLimit, Prefix = prefix });
                        }
                    }
                }
            }
            }
            return items;
        }
        public void GetSubVersionCountOfActionTest()
        {
            var mockDefaultValueProvider = new Mock<IWQDefaultValueProvider>();
            mockDefaultValueProvider.Setup(x => x.ActionRelationshipTypeSubVersion).Returns("is new version of");

            var versionHelper = new DataVersioningHelper(mockDefaultValueProvider.Object);

            CreateTestAction(mockDefaultValueProvider.Object);

            var numberOfVersion = versionHelper.GetSubVersionCountOfAction(rootActionData);

            Assert.NotNull(numberOfVersion);
            Assert.AreEqual(3, numberOfVersion);
        }
        public ResultMessageViewModel QAQCChemistryData(IEnumerable<ChemistryQAQCDataEditViewModel> data)
        {
            var versioningHelper = new DataVersioningHelper(_wqDefaultValueProvider);
                        
            var items = from qaqcData in data
                        select new ChemistryValueCheckingRuleItem { 
                            ActionId = qaqcData.ActionId,
                            CorrectionValue = qaqcData.NewResultValue
                        };
            var rule = new ChemistryValueCheckingRule { 
                Items = items.ToList()
            };

            var dataFetchCriteria = new GetActionDataByIdsCriteria(_actionRepository, rule);

            var chemistryQAQCTool = new ChemistryValueCheckingTool(versioningHelper, _relatedActionTypeRepository);

            try
            { 
                //Check
                //var qaqcResult = chemistryQAQCTool.Check(dataFetchCriteria.FetchData(), rule);

                //Correct
                var qaqcResult = chemistryQAQCTool.Correct(dataFetchCriteria.FetchData(), rule);

                if(qaqcResult.NeedCorrection)
                {
                    var numberOfActionSaved = _actionRepository.SaveChanges();
                }

                if (qaqcResult.Level == QualityCheckingResultLevel.Info)
                {
                    var message = ConstructResultMessage(qaqcResult, "QA/QC data is saved.");
                    return new ResultMessageViewModel(ResultMessageViewModel.RESULT_LEVEL_INFO, message);
                }
                else
                {
                    var message = ConstructResultMessage(qaqcResult, "QA/QC data does not saved. Please check the result message for more detail.");
                    return new ResultMessageViewModel(ResultMessageViewModel.RESULT_LEVEL_FATAL, message);
                }
                
            }
            catch(Exception ex)
            {
                var message = "QA/QC data fail due to " + ex.StackTrace;
                return new ResultMessageViewModel(ResultMessageViewModel.RESULT_LEVEL_FATAL, message);
            }
            
        }
        public void GetLatestVersionDataTest()
        {
            var mockDefaultValueProvider = new Mock<IWQDefaultValueProvider>();
            mockDefaultValueProvider.Setup(x => x.ActionRelationshipTypeSubVersion).Returns("is new version of");

            var versionHelper = new DataVersioningHelper(mockDefaultValueProvider.Object);

            CreateTestAction(mockDefaultValueProvider.Object);

            var foundLatestVersionData = versionHelper.GetLatestVersionActionData(rootActionData);

            Assert.NotNull(foundLatestVersionData);
            Assert.AreEqual(foundLatestVersionData, grandActionData);
            Assert.AreEqual(3, foundLatestVersionData.ActionID);
        }
        public IEnumerable<ChemistryDataEditViewModel> GetChemistryAnalyteDataBySampleActionId(int Id)
        {
            var mappingHelper = new ESDATViewModelMappingHelper();
            var versionHelper = new DataVersioningHelper(_wqDefaultValueProvider);

            var matchedAction = _wqDataRepository.GetActionById(Id);

            if (matchedAction != null)
            {
                var viewModels = ESDATViewModelMappingHelper.MapActionToChemistryFileEditViewModel(matchedAction, versionHelper);
                return viewModels;
            }
            else
            {
                return null;
            }
        }