public IHttpActionResult Put(Guid id, FormTemplateDTO value)
        {
            if (id == Guid.Empty)
            {
                return(BadRequest("id is empty"));
            }

            var response = FormTemplatesService.Update(id, value);

            if (!response.Success)
            {
                if (response.Message.ToLower() == "not found")
                {
                    return(NotFound());
                }

                if (response.ValidationErrors.Any())
                {
                    return(BadRequest(response.Message));
                }

                return(BadRequest(response.Message));
            }

            var retVal = Mapper.Map <FormTemplateDTO>(response.ReturnValue);

            MemoryCacher.DeleteStartingWith(CACHE_KEY);

            return(Ok(retVal));
        }
        public IHttpActionResult Post(FormTemplateDTO value)
        {
            var formTemplate = Mapper.Map <FormTemplate>(value);

            ModelState.Clear();
            Validate(formTemplate);
            if (!ModelState.IsValid)
            {
                return(BadRequest(ModelState));
            }

            formTemplate.OrganisationId = Guid.Parse(value.Organisation.Id);
            formTemplate.ProjectId      = value.Project.Id;
            formTemplate.Discriminator  = FormTemplateDiscriminators.RegularThread;

            var response = FormTemplatesService.Create(formTemplate);

            if (!response.Success)
            {
                if (response.Message.ToLower() == "not found")
                {
                    return(NotFound());
                }

                if (response.ValidationErrors.Any())
                {
                    return(Content(HttpStatusCode.BadRequest, response));
                }

                return(BadRequest(response.Message));
            }

            MemoryCacher.DeleteStartingWith(CACHE_KEY);

            return(Ok(response.ReturnValue));
        }
        public OperationResult Update(Guid templateId, FormTemplateDTO model)
        {
            var result = new OperationResult();

            var surveyProvider = new SurveyProvider(OrgUser, UnitOfWork, onlyPublished: false);
            var form           = surveyProvider.GetAllFormTemplates().Where(f => f.Id == templateId).SingleOrDefault();

            if (form == null)
            {
                result.Success = false;
                result.Message = "Not found";

                return(result);
            }

            Mapper.Map(model, form);

            if (model.Organisation != null)
            {
                form.OrganisationId = Guid.Parse(model.Organisation.Id);
            }

            if (model.Project != null)
            {
                form.ProjectId = model.Project.Id;
            }

            // validate organisation. Project/Category organisations must match the selected organisation.

            UnitOfWork.FormTemplatesRepository.InsertOrUpdate(form);

            var groupOrder = 1;

            foreach (var valueGroup in model.MetricGroups)
            {
                var group = form.MetricGroups.SingleOrDefault(g => g.Id == valueGroup.Id);
                if (valueGroup.isDeleted && group != null)
                {
                    if (valueGroup.Metrics.Any(m => !m.isDeleted))
                    {
                        result.ValidationErrors.Add(new ValidationResult($"Group {group.Title} is not empty!", new string[] { group.Id.ToString() }));
                    }

                    //result.Errors.Add(group.Id.ToString(), $"Group {group.Title} is not empty!");
                }

                if (CurrentUser is OrgUser)
                {
                    group = valueGroup.Map(group, UnitOfWork, OrgUser.Organisation);
                }
                else if (CurrentUser is SuperUser)
                {
                    group = valueGroup.Map(group, UnitOfWork, form.Organisation);
                }

                group.FormTemplateId = form.Id;
                group.Order          = groupOrder++;

                var metricOrder = 1;
                foreach (var valueMetric in valueGroup.Metrics)
                {
                    var metric = group.Metrics.Where(m => m.Id == valueMetric.Id)
                                 .SingleOrDefault();

                    if (metric == null && valueMetric.isDeleted)
                    {
                        continue;
                    }

                    if (CurrentUser is OrgUser)
                    {
                        metric = valueMetric.Map(metric, UnitOfWork, OrgUser.Organisation);
                    }
                    else if (CurrentUser is SuperUser)
                    {
                        metric = valueMetric.Map(metric, UnitOfWork, form.Organisation);
                    }

                    if (valueMetric.isDeleted) // Delete
                    {
                        UnitOfWork.MetricsRepository.Delete(metric);
                    }
                    else
                    {   // Insert or update
                        metric.FormTemplateId = form.Id;
                        metric.MetricGroup    = group;
                        metric.Order          = metricOrder++;

                        // Validate metric
                        var validationResult = metric.Validate();
                        if (validationResult.Any())
                        {
                            validationResult.ToList().ForEach(res =>
                                                              result.ValidationErrors.Add(new ValidationResult(res.ErrorMessage, new string[] { metric.Id.ToString() })));

                            //validationResult.ToList().ForEach(res => result.Errors.Add(metric.Id.ToString(), res.ErrorMessage));
                        }

                        UnitOfWork.MetricsRepository.InsertOrUpdate(metric);
                    }
                }

                if (valueGroup.isDeleted && group != null)
                {
                    UnitOfWork.MetricGroupsRepository.Delete(group);
                }
                else
                {
                    UnitOfWork.MetricGroupsRepository.InsertOrUpdate(group);
                }
            }

            if (result.ValidationErrors.Any())
            {
                result.Success = false;
                result.Message = "Validation failed";

                return(result);
            }

            //result.Errors = new Dictionary<string, string>();
            var formErrors = form.Validate(new ValidationContext(form));

            if (formErrors.Any())
            {
                formErrors.ToList().ForEach(res => result.ValidationErrors.Add(new ValidationResult(res.ErrorMessage, new string[] { templateId.ToString() })));
                result.Success = false;
                result.Message = "Validation failed";

                return(result);
            }

            try
            {
                UnitOfWork.Save();

                result.Success     = true;
                result.Message     = "Form Templated updated";
                result.ReturnValue = form;
            }
            catch (DbEntityValidationException ex)
            {
                foreach (var entityError in ex.EntityValidationErrors)
                {
                    foreach (var validationError in entityError.ValidationErrors)
                    {
                        result.ValidationErrors.Add(
                            new ValidationResult(validationError.ErrorMessage, new string[] { (entityError.Entry.Entity as Entity)?.Id.ToString() ?? string.Empty }));
                    }
                }

                result.Success = false;
                result.Message = "Validation failed";
            }
            catch (DbUpdateException ex)
            {
                result.ValidationErrors.Add(new ValidationResult(ex.Message, new string[] { form.Id.ToString() }));
                result.Success = false;
                result.Message = ex.Message;
            }
            catch (Exception)
            {
                result.Success = false;
                result.Message = "Error occured updating form template";
            }

            return(result);
        }