public async Task <int> CreateTeacher(CreateEditTeacherInputModel model)
        {
            var groupIds = model.Groups.Where(x => x.Selected).Select(x => x.Id).ToArray();
            var groupsToAssignToTeacher = this.db.Groups.Where(x => groupIds.Contains(x.Id)).ToArray();
            var levelsIds       = model.Levels.Where(x => x.Selected).Select(x => x.Id).ToArray();
            var qualifiedLevels = this.db.Levels.Where(x => levelsIds.Contains(x.Id)).ToArray();

            //user side creation
            //User config = //https://stackoverflow.com/questions/34343599/how-to-seed-users-and-roles-with-code-first-migration-using-identity-asp-net-cor
            var user = new ApplicationUser
            {
                Email              = model.Email,
                NormalizedEmail    = model.Email.ToUpper(),
                UserName           = model.Username,
                NormalizedUserName = model.Username.ToUpper(),
                EmailConfirmed     = true,
                SecurityStamp      = Guid.NewGuid().ToString("D")
            };

            var passwordHasher = new PasswordHasher <ApplicationUser>();
            var hashedPassword = passwordHasher.HashPassword(user, model.Password);

            user.PasswordHash = hashedPassword;

            var userStore = new UserStore <ApplicationUser>(this.db);
            var result    = await userStore.CreateAsync(user);

            var roles = new string[] { "TEACHER" };
            await base.AssignRoles(user.NormalizedUserName, roles);


            //business side creation
            DateTime hiringDate = model.HiringDate ?? DateTime.Now;

            var teacher = new Teacher
            {
                FirstName       = model.FirstName,
                LastName        = model.LastName,
                Gender          = model.Gender,
                HiringDate      = hiringDate,
                DismissalDate   = model.DismissalDate,
                Salary          = model.Salary,
                PhoneNumber     = model.PhoneNumber,
                ProfilePicURI   = model.ProfileImage == null ? Constants.defaultProfPicURL : await this.cloudinaryService.UploadPicASync(model.ProfileImage, null),
                Groups          = groupsToAssignToTeacher,
                QualifiedLevels = qualifiedLevels.Select(ql => new LevelTeacher {
                    Level = ql
                }).ToArray(),
                Status            = groupsToAssignToTeacher.Length == 0 ? TeacherStatus.Initial:TeacherStatus.Active,
                ApplicationUserId = user.Id,
            };

            await this.db.Teachers.AddAsync(teacher);

            await this.db.SaveChangesAsync();

            return(teacher.Id);
        }
        public IActionResult Create()
        {
            var levelsList = this.levelsService.GetAllForSelection();
            var groupsList = this.groupsService.GetAllForSelection(false); //the int? argument is for adding only empty groups to the teacher or other teacher's groups
            var model      = new CreateEditTeacherInputModel()
            {
                Levels = levelsList.ToList(),
                Groups = groupsList.ToList()
            };

            return(this.View(model));
        }
        public async Task EditInfo(CreateEditTeacherInputModel model)
        {
            DateTime hiringDate = model.HiringDate ?? DateTime.Now;

            var teacher = await this.db.Teachers
                          .FirstOrDefaultAsync(x => x.Id == model.Id);

            teacher.FirstName     = model.FirstName;
            teacher.LastName      = model.LastName;
            teacher.Gender        = model.Gender;
            teacher.Salary        = model.Salary;
            teacher.HiringDate    = hiringDate;
            teacher.DismissalDate = model.DismissalDate;
            teacher.PhoneNumber   = model.PhoneNumber;
            teacher.ProfilePicURI = model.ProfileImage == null ? Constants.defaultProfPicURL : await this.cloudinaryService.UploadPicASync(model.ProfileImage, null);
        }
        public async Task <IActionResult> EditInfo(CreateEditTeacherInputModel model)
        {
            model.ProfilePicURI = this.TempData["profilePicUri"].ToString();
            this.TempData.Keep("profilePicUri");

            if (ModelState.IsValid == false)
            {
                return(await Task.Run(() => this.View(model)));
            }

            int teacherId = await CheckTeacherId(this.TempData["teacherId"]);

            model.Id = teacherId;
            await this.teachersService.EditInfo(model);

            return(await Task.Run(() => this.RedirectToAction("Details", new { teacherId = model.Id })));
        }
        public async Task <IActionResult> Create(CreateEditTeacherInputModel model)
        {
            if (ModelState.IsValid == false)
            {
                model.Levels = this.levelsService.GetAllForSelection().ToList();
                model.Groups = this.groupsService.GetAllForSelection(false).ToList();
                return(await Task.Run(() => this.View(model)));
            }

            if (await this.teachersService.UserExists(model.Username))
            {
                return(this.Json("Existing Username"));
            }                                                                                                      //todo error page User Exists and in a separate method

            var newTeacherId = await this.teachersService.CreateTeacher(model);

            return(RedirectToAction("Details", new { teacherId = newTeacherId }));
        }
        public async Task <CreateEditTeacherInputModel> GetInfoForEdit(int teacherId)
        {
            var teacher = await this.db.Teachers
                          .FirstOrDefaultAsync(x => x.Id == teacherId);

            var model = new CreateEditTeacherInputModel
            {
                FirstName     = teacher.FirstName,
                LastName      = teacher.LastName,
                Gender        = teacher.Gender,
                Salary        = teacher.Salary,
                HiringDate    = teacher.HiringDate,
                DismissalDate = teacher.DismissalDate,
                PhoneNumber   = teacher.PhoneNumber,
                ProfilePicURI = teacher.ProfilePicURI,
            };

            return(model);
        }