/// <summary>
        /// Get all Records for a project
        /// </summary>
        /// <param name="id">ProjectId</param>
        /// <returns></returns>
        public async Task <IActionResult> RecordsPerProject(Guid id, bool withOnlyGeometries = false)
        {
            User user = Helpers.UserHelper.GetCurrentUser(User, db);

            List <Project> projects           = new List <Project>();
            List <Project> erfassendeProjects = new List <Project>();

            if (User.IsInRole("DM"))
            {
                projects = await DB.Helpers.ProjectManager.UserProjectsAsync(db, user, RoleEnum.DM);
            }

            if (User.IsInRole("EF"))
            {
                erfassendeProjects = await DB.Helpers.ProjectManager.UserProjectsAsync(db, user, RoleEnum.EF);
            }
            if (User.IsInRole("PK"))
            {
                projects.AddRange(await DB.Helpers.ProjectManager.UserProjectsAsync(db, user, RoleEnum.PK));
            }
            if (User.IsInRole("PL"))
            {
                projects.AddRange(await DB.Helpers.ProjectManager.UserProjectsAsync(db, user, RoleEnum.PL));
            }

            projects.AddRange(await DB.Helpers.ProjectManager.UserProjectsAsync(db, user, RoleEnum.LE));
            projects.AddRange(erfassendeProjects);

            Project p = await db.Projects
                        .Include(m => m.ProjectGroups).ThenInclude(pg => pg.Records).ThenInclude(u => u.TextData).ThenInclude(td => td.FormField)
                        .Include(m => m.ProjectGroups).ThenInclude(pg => pg.Records).ThenInclude(u => u.NumericData).ThenInclude(td => td.FormField)
                        .Include(m => m.ProjectGroups).ThenInclude(pg => pg.Records).ThenInclude(u => u.BooleanData).ThenInclude(td => td.FormField)
                        .Include(m => m.ProjectGroups).ThenInclude(pg => pg.Records).ThenInclude(u => u.Form).ThenInclude(f => f.FormFormFields).ThenInclude(fff => fff.FormField)
                        .Include(m => m.ProjectGroups).ThenInclude(pg => pg.Records).ThenInclude(u => u.Form).ThenInclude(f => f.FormFormFields).ThenInclude(fff => fff.FormField).ThenInclude(mo => mo.PublicMotherFormField)
                        .Include(m => m.ProjectGroups).ThenInclude(pg => pg.Records).ThenInclude(u => u.ProjectGroup.Group)
                        .Include(m => m.ProjectGroups).ThenInclude(pg => pg.Records).ThenInclude(u => u.Geometry)
                        .Include(m => m.ProjectGroups).ThenInclude(pg => pg.Records).ThenInclude(u => u.RecordChangeLogs).ThenInclude(rcl => rcl.ChangeLog).ThenInclude(cl => cl.User)
                        .Include(m => m.ProjectGroups).ThenInclude(pg => pg.Records).Where(pg => pg.StatusId != StatusEnum.deleted)
                        .Where(m => m.ProjectId == id)
                        .Where(m => m.StatusId != StatusEnum.deleted).FirstOrDefaultAsync();

            if (p == null)
            {
                return(StatusCode(500));
            }
            if (!projects.Any(m => m.ProjectId == p.ProjectId))
            {
                return(RedirectToAction("NotAllowed", "Home"));
            }

            ProjectViewModel pvm = new ProjectViewModel()
            {
                Project = p
            };

            pvm.Records = new List <RecordViewModel>();

            List <Group> myGroups = await db.Groups.Where(m => m.GroupUsers.Any(u => u.UserId == user.UserId)).ToListAsync();

            foreach (ProjectGroup g in p.ProjectGroups)
            {
                List <Record> records = g.Records.Where(m => m.StatusId != StatusEnum.deleted && m.Geometry == null).ToList();
                if (withOnlyGeometries)
                {
                    records = g.Records.Where(m => m.StatusId != StatusEnum.deleted && m.Geometry != null).ToList();
                }

                foreach (Record r in records)
                {
                    bool isReadOnly = true;
                    if ((g.GroupStatusId != GroupStatusEnum.Gruppendaten_gueltig) && (g.GroupStatusId != GroupStatusEnum.Gruppendaten_erfasst))
                    {
                        if (myGroups.Where(m => m.GroupId == g.GroupId).Count() > 0)
                        {
                            isReadOnly = false;
                        }
                    }

                    RecordViewModel rvm = new RecordViewModel()
                    {
                        Record = r
                    };

                    List <PropertyVm> dynamicForm = new List <PropertyVm>();

                    // BDC Guid
                    PropertyVm dynamicFieldGUID = new PropertyVm(typeof(string), "Field_" + r.RecordId);
                    dynamicFieldGUID.DisplayName         = "BDCGuid";
                    dynamicFieldGUID.Value               = r.BDCGuid;
                    dynamicFieldGUID.GetCustomAttributes = () => new object[] { new Helpers.FormFactory.GuidAttribute() };
                    dynamicForm.Add(dynamicFieldGUID);

                    if (r.Form != null)
                    {
                        foreach (FormField ff in r.Form.FormFormFields.Select(fff => fff.FormField).OrderBy(m => m.Order))
                        {
                            FormField origFormField = ff;
                            if (ff.PublicMotherFormField != null)
                            {
                                origFormField = ff.PublicMotherFormField;
                            }

                            if (origFormField.FieldTypeId == FieldTypeEnum.Text)
                            {
                                PropertyVm dynamicField = new PropertyVm(typeof(string), "Field_" + ff.FormFieldId.ToString());
                                dynamicField.DisplayName = origFormField.Title;
                                TextData td = r.TextData.Where(m => m.FormField == ff).FirstOrDefault();
                                if (td != null)
                                {
                                    dynamicField.Value = td.Value;
                                }

                                dynamicField.NotOptional = ff.Mandatory;
                                dynamicForm.Add(dynamicField);
                            }
                            else if (origFormField.FieldTypeId == FieldTypeEnum.DateTime)
                            {
                                PropertyVm dynamicField = new PropertyVm(typeof(DateTime), "Field_" + ff.FormFieldId.ToString());
                                dynamicField.DisplayName = origFormField.Title;
                                TextData td   = r.TextData.Where(m => m.FormField == ff).FirstOrDefault();
                                DateTime myDT = new DateTime();
                                try
                                {
                                    myDT = DateTime.ParseExact(td.Value.Replace("{0:", " ").Replace("}", ""), formats, CultureInfo.InvariantCulture, DateTimeStyles.None);
                                }
                                catch (Exception e)
                                {
                                }

                                if (td != null)
                                {
                                    dynamicField.Value = myDT;
                                }

                                dynamicField.NotOptional = ff.Mandatory;
                                dynamicForm.Add(dynamicField);
                            }
                            else if (origFormField.FieldTypeId == FieldTypeEnum.Choice)
                            {
                                PropertyVm dynamicField = new PropertyVm(typeof(string), "Field_" + ff.FormFieldId.ToString());
                                dynamicField.DisplayName = origFormField.Title;
                                TextData td = r.TextData.Where(m => m.FormField == ff).FirstOrDefault();
                                if (td != null)
                                {
                                    dynamicField.Value = td.Value;
                                }
                                await db.Entry(origFormField).Collection(m => m.FieldChoices).LoadAsync();

                                if (origFormField.FieldChoices != null)
                                {
                                    List <string> choices = new List <string>();
                                    foreach (FieldChoice fc in origFormField.FieldChoices.OrderBy(m => m.Order))
                                    {
                                        choices.Add(fc.Text);
                                    }
                                    dynamicField.Choices = choices;
                                }
                                dynamicField.NotOptional = ff.Mandatory;
                                dynamicForm.Add(dynamicField);
                            }
                            else if (origFormField.FieldTypeId == FieldTypeEnum.Boolean)
                            {
                                PropertyVm dynamicField = new PropertyVm(typeof(bool), "Field_" + ff.FormFieldId.ToString());
                                dynamicField.DisplayName = origFormField.Title;
                                BooleanData bd = r.BooleanData.Where(m => m.FormField == origFormField).FirstOrDefault();
                                if (bd != null)
                                {
                                    dynamicField.Value = bd.Value;
                                }
                                dynamicField.NotOptional         = ff.Mandatory;
                                dynamicField.GetCustomAttributes = () => new object[] { new FormFactory.Attributes.LabelOnRightAttribute() };
                                dynamicForm.Add(dynamicField);
                            }
                        }

                        PropertyVm dynamicHiddenField = new PropertyVm(typeof(string), "RecordId");
                        dynamicHiddenField.Value       = r.RecordId.ToString();
                        dynamicHiddenField.NotOptional = true;
                        dynamicHiddenField.IsHidden    = true;
                        dynamicForm.Add(dynamicHiddenField);

                        if (isReadOnly)
                        {
                            foreach (PropertyVm pv in dynamicForm)
                            {
                                pv.Readonly = true;
                            }
                        }
                        rvm.Readonly    = isReadOnly;
                        rvm.DynamicForm = dynamicForm;
                        rvm.Group       = r.ProjectGroup.Group;
                        pvm.Records.Add(rvm);
                    }
                }
            }
            ViewData["withOnlyGeometries"] = withOnlyGeometries;
            if (!erfassendeProjects.Contains(p))
            {
                ViewData["ReadOnly"] = true;
            }
            else
            {
                ViewData["ReadOnly"] = false;
            }
            if (withOnlyGeometries)
            {
                return(View("RecordsPerProjectPerGeometry", pvm));
            }
            return(View(pvm));
        }
        public static async Task CreateDynamicView(BioDivContext db, ReferenceGeometry rg, ProjectGroup g, List <Group> myGroups, GeometrieViewModel gvm)
        {
            foreach (Record r in rg.Records.Where(m => m.StatusId != StatusEnum.deleted))
            {
                bool isReadOnly = true;
                if (g == null)
                {
                    isReadOnly = false;
                }
                else if ((g.GroupStatusId != GroupStatusEnum.Gruppendaten_gueltig) && (g.GroupStatusId != GroupStatusEnum.Gruppendaten_erfasst))
                {
                    if (myGroups.Where(m => m.GroupId == r.ProjectGroupGroupId).Count() > 0)
                    {
                        isReadOnly = false;
                    }
                }

                RecordViewModel rvm = new RecordViewModel()
                {
                    Record = r
                };

                List <PropertyVm> dynamicForm = new List <PropertyVm>();

                // BDC Guid
                PropertyVm dynamicFieldGUID = new PropertyVm(typeof(string), "Field_" + r.RecordId);
                dynamicFieldGUID.DisplayName         = "BDCGuid";
                dynamicFieldGUID.Value               = r.BDCGuid;
                dynamicFieldGUID.GetCustomAttributes = () => new object[] { new Helpers.FormFactory.GuidAttribute() };
                dynamicForm.Add(dynamicFieldGUID);

                if (r.Form != null)
                {
                    foreach (FormField ff in r.Form.FormFormFields.Select(fff => fff.FormField).OrderBy(m => m.Order))
                    {
                        FormField origFormField = ff;
                        if (ff.PublicMotherFormField != null)
                        {
                            origFormField = ff.PublicMotherFormField;
                        }

                        if (origFormField.FieldTypeId == FieldTypeEnum.Text)
                        {
                            PropertyVm dynamicField = new PropertyVm(typeof(string), "Field_" + ff.FormFieldId.ToString());
                            dynamicField.DisplayName = origFormField.Title;
                            TextData td = r.TextData.Where(m => m.FormField == ff).FirstOrDefault();
                            if (td != null)
                            {
                                dynamicField.Value = td.Value;
                            }

                            dynamicField.NotOptional = ff.Mandatory;
                            dynamicForm.Add(dynamicField);
                        }
                        else if (origFormField.FieldTypeId == FieldTypeEnum.DateTime)
                        {
                            PropertyVm dynamicField = new PropertyVm(typeof(DateTime), "Field_" + ff.FormFieldId.ToString());
                            dynamicField.DisplayName = origFormField.Title;
                            TextData td   = r.TextData.Where(m => m.FormField == ff).FirstOrDefault();
                            DateTime myDT = new DateTime();
                            try
                            {
                                myDT = DateTime.ParseExact(td.Value.Replace("{0:", " ").Replace("}", ""), formats, CultureInfo.InvariantCulture, DateTimeStyles.None);
                            }
                            catch (Exception e)
                            {
                            }

                            if (td != null)
                            {
                                dynamicField.Value = myDT;
                            }

                            dynamicField.NotOptional = ff.Mandatory;
                            dynamicForm.Add(dynamicField);
                        }
                        else if (origFormField.FieldTypeId == FieldTypeEnum.Choice)
                        {
                            PropertyVm dynamicField = new PropertyVm(typeof(string), "Field_" + ff.FormFieldId.ToString());
                            dynamicField.DisplayName = origFormField.Title;
                            TextData td = r.TextData.Where(m => m.FormField == ff).FirstOrDefault();
                            if (td != null)
                            {
                                dynamicField.Value = td.Value;
                            }

                            await db.Entry(origFormField).Collection(m => m.FieldChoices).LoadAsync();

                            if (origFormField.FieldChoices != null)
                            {
                                List <string> choices = new List <string>();
                                foreach (FieldChoice fc in origFormField.FieldChoices.OrderBy(m => m.Order))
                                {
                                    choices.Add(fc.Text);
                                }
                                dynamicField.Choices = choices;
                            }
                            dynamicField.NotOptional = ff.Mandatory;
                            dynamicForm.Add(dynamicField);
                        }
                        else if (origFormField.FieldTypeId == FieldTypeEnum.Boolean)
                        {
                            PropertyVm dynamicField = new PropertyVm(typeof(bool), "Field_" + ff.FormFieldId.ToString());
                            dynamicField.DisplayName = origFormField.Title;
                            BooleanData bd = r.BooleanData.Where(m => m.FormField == ff).FirstOrDefault();
                            if (bd != null)
                            {
                                dynamicField.Value = bd.Value;
                            }
                            dynamicField.NotOptional         = ff.Mandatory;
                            dynamicField.GetCustomAttributes = () => new object[] { new FormFactory.Attributes.LabelOnRightAttribute() };
                            dynamicForm.Add(dynamicField);
                        }
                    }

                    PropertyVm dynamicHiddenField = new PropertyVm(typeof(string), "RecordId");
                    dynamicHiddenField.Value       = r.RecordId.ToString();
                    dynamicHiddenField.NotOptional = true;
                    dynamicHiddenField.IsHidden    = true;
                    dynamicForm.Add(dynamicHiddenField);

                    if (isReadOnly)
                    {
                        foreach (PropertyVm pv in dynamicForm)
                        {
                            pv.Readonly = true;
                        }
                    }
                    rvm.Readonly    = isReadOnly;
                    rvm.DynamicForm = dynamicForm;
                    rvm.Group       = r.ProjectGroup.Group;
                    gvm.Records.Add(rvm);
                }
            }

            return;
        }
        /// <summary>
        /// Get all Records for a project and show it as a table
        /// </summary>
        /// <param name="id">ProjectId</param>
        /// <returns></returns>
        public async Task <IActionResult> RecordsPerProjectAsTable(Guid id)
        {
            User user = Helpers.UserHelper.GetCurrentUser(User, db);

            List <Project> projects           = new List <Project>();
            List <Project> erfassendeProjects = new List <Project>();

            if (User.IsInRole("DM"))
            {
                projects = await DB.Helpers.ProjectManager.UserProjectsAsync(db, user, RoleEnum.DM);
            }

            if (User.IsInRole("EF"))
            {
                erfassendeProjects = await DB.Helpers.ProjectManager.UserProjectsAsync(db, user, RoleEnum.EF);
            }
            if (User.IsInRole("PK"))
            {
                projects.AddRange(await DB.Helpers.ProjectManager.UserProjectsAsync(db, user, RoleEnum.PK));
            }
            if (User.IsInRole("PL"))
            {
                projects.AddRange(await DB.Helpers.ProjectManager.UserProjectsAsync(db, user, RoleEnum.PL));
            }

            projects.AddRange(await DB.Helpers.ProjectManager.UserProjectsAsync(db, user, RoleEnum.LE));
            projects.AddRange(erfassendeProjects);

            Project p = await db.Projects
                        .Include(m => m.ProjectGroups).ThenInclude(pg => pg.Records).ThenInclude(u => u.TextData).ThenInclude(td => td.FormField)
                        .Include(m => m.ProjectGroups).ThenInclude(pg => pg.Records).ThenInclude(u => u.NumericData).ThenInclude(td => td.FormField)
                        .Include(m => m.ProjectGroups).ThenInclude(pg => pg.Records).ThenInclude(u => u.BooleanData).ThenInclude(td => td.FormField)
                        .Include(m => m.ProjectGroups).ThenInclude(pg => pg.Records).ThenInclude(u => u.Form).ThenInclude(f => f.FormFormFields).ThenInclude(fff => fff.FormField)
                        .Include(m => m.ProjectGroups).ThenInclude(pg => pg.Records).ThenInclude(u => u.Form).ThenInclude(f => f.FormFormFields).ThenInclude(fff => fff.FormField).ThenInclude(mo => mo.PublicMotherFormField)
                        .Include(m => m.ProjectGroups).ThenInclude(pg => pg.Records).ThenInclude(u => u.ProjectGroup.Group)
                        .Include(m => m.ProjectGroups).ThenInclude(pg => pg.Records).ThenInclude(u => u.Geometry)
                        .Include(m => m.ProjectGroups).ThenInclude(pg => pg.Records).ThenInclude(u => u.RecordChangeLogs).ThenInclude(rcl => rcl.ChangeLog).ThenInclude(cl => cl.User)
                        .Include(m => m.ProjectGroups).ThenInclude(pg => pg.Records).Where(pg => pg.StatusId != StatusEnum.deleted)
                        .Where(m => m.ProjectId == id)
                        .Where(m => m.StatusId != StatusEnum.deleted).FirstOrDefaultAsync();

            if (p == null)
            {
                return(StatusCode(500));
            }
            if (!projects.Any(m => m.ProjectId == p.ProjectId))
            {
                return(RedirectToAction("NotAllowed", "Home"));
            }

            ProjectViewModel pvm = new ProjectViewModel()
            {
                Project = p
            };

            pvm.Records = new List <RecordViewModel>();
            pvm.Forms   = new List <Form>();

            List <Group> myGroups = await db.Groups.Where(m => m.GroupUsers.Any(u => u.UserId == user.UserId)).ToListAsync();

            foreach (ProjectGroup g in p.ProjectGroups)
            {
                List <Record> records = g.Records.Where(m => m.StatusId != StatusEnum.deleted && m.Geometry?.StatusId != StatusEnum.deleted).ToList();
                foreach (Record r in records)
                {
                    bool isReadOnly = true;
                    if ((g.GroupStatusId != GroupStatusEnum.Gruppendaten_gueltig) && (g.GroupStatusId != GroupStatusEnum.Gruppendaten_erfasst))
                    {
                        if (myGroups.Where(m => m.GroupId == g.GroupId).Count() > 0)
                        {
                            isReadOnly = false;
                        }
                    }
                    RecordViewModel rvm = new RecordViewModel()
                    {
                        Record = r
                    };
                    rvm.Readonly = isReadOnly;
                    if (!pvm.Forms.Any(m => m.FormId == r.FormId))
                    {
                        pvm.Forms.Add(r.Form);
                    }
                    pvm.Records.Add(rvm);
                }
            }
            if (!erfassendeProjects.Contains(p))
            {
                ViewData["ReadOnly"] = true;
            }
            else
            {
                ViewData["ReadOnly"] = false;
            }
            return(View(pvm));
        }