public async Task <IActionResult> CreateGroupAsync([FromBody] GroupCreateModel model)
        {
            if (string.IsNullOrWhiteSpace(model.Name))
            {
                throw new IsRequiredException("name");
            }

            if (model.Name.Length > 150)
            {
                throw new NameIsInvalidException();
            }

            if (await _groupRepository.AnyByNameAsync(model.Name))
            {
                throw new AlreadyExistsException("name");
            }

            DateTime now = DateTime.Now;

            var accountId = CurrentAccountId;

            var group = new Group
            {
                Name        = model.Name,
                CreatedDate = now,
                CreatedBy   = accountId,
                UpdatedDate = now,
                UpdatedBy   = accountId
            };

            await _groupRepository.CreateGroupAsync(group);

            return(Ok(GroupDTO.GetFrom(group)));
        }
        public async Task <IActionResult> UpdateGroupAsync([FromRoute] int groupId, [FromBody] GroupUpdateModel model)
        {
            var currentAccount = await _accountRepository.GetAccountByIdAsync(CurrentAccountId);

            if (currentAccount.GroupId > groupId)
            {
                throw new ForbiddenException(); // the lower the group id, the higher the authority; can only delete the group with authority lower than the current group
            }

            var group = await _groupRepository.GetGroupByIdAsync(groupId);

            if (group == null)
            {
                throw new NotFound404Exception("group");
            }

            if (string.IsNullOrWhiteSpace(model.Name))
            {
                throw new IsRequiredException("name");
            }

            if (model.Name.Length > 50)
            {
                throw new NameIsInvalidException();
            }

            if (await _groupRepository.AnyByNameAsync(model.Name) && !group.Name.Equals(model.Name))
            {
                throw new AlreadyExistsException("name");
            }

            // bind data
            group.Name        = model.Name;
            group.UpdatedDate = DateTime.Now;
            group.UpdatedBy   = CurrentAccountId;

            await _groupRepository.UpdateGroupAsync(group);

            return(Ok(GroupDTO.GetFrom(group)));
        }
        public async Task <IActionResult> GetGroupByIdAsync([FromRoute] int groupId)
        {
            var currentFunctionCodes = GetCurrentAccountFunctionCodes();

            if (!currentFunctionCodes.Contains("Group_Full") && !currentFunctionCodes.Contains("Group_Read_All"))
            {
                var currentAccount = await _accountRepository.GetAccountByIdAsync(CurrentAccountId);

                if (currentAccount.GroupId != groupId)
                {
                    throw new ForbiddenException();
                }
            }

            var group = await _groupRepository.GetGroupByIdAsync(groupId);

            if (group == null)
            {
                throw new NotFound404Exception("group");
            }

            return(Ok(GroupDTO.GetFrom(group)));
        }
        public async Task <IActionResult> DeleteGroupAsync([FromRoute] int groupId)
        {
            var group = await _groupRepository.GetGroupByIdAsync(groupId);

            var currentAccount = await _accountRepository.GetAccountByIdAsync(CurrentAccountId);

            if (currentAccount.GroupId > groupId)
            {
                throw new ForbiddenException(); // the lower the group id, the higher the authority; can only delete the group with authority lower than the current group
            }

            if (group == null)
            {
                throw new NotFound404Exception("group");
            }

            group.IsDeleted   = true;
            group.UpdatedDate = DateTime.Now;
            group.UpdatedBy   = CurrentAccountId;

            await _groupRepository.UpdateGroupAsync(group);

            return(Ok(GroupDTO.GetFrom(group)));
        }