public async Task <IActionResult> PutSpecificItem([FromRoute] string guildid, [FromRoute] string modcaseid, [FromBody] ModCaseForPutDto newValue, [FromQuery] bool sendNotification = true, [FromQuery] bool handlePunishment = true)
        {
            logger.LogInformation($"{HttpContext.Request.Method} {HttpContext.Request.Path} | Incoming request.");
            Identity currentIdentity = await identityManager.GetIdentity(HttpContext);

            User currentUser = await currentIdentity.GetCurrentDiscordUser();

            if (currentUser == null)
            {
                logger.LogInformation($"{HttpContext.Request.Method} {HttpContext.Request.Path} | 401 Unauthorized.");
                return(Unauthorized());
            }
            if (!await currentIdentity.HasModRoleOrHigherOnGuild(guildid, this.database) && !config.Value.SiteAdminDiscordUserIds.Contains(currentUser.Id))
            {
                logger.LogInformation($"{HttpContext.Request.Method} {HttpContext.Request.Path} | 401 Unauthorized.");
                return(Unauthorized());
            }
            // ========================================================

            GuildConfig guildConfig = await database.SelectSpecificGuildConfig(guildid);

            if (guildConfig == null)
            {
                logger.LogInformation($"{HttpContext.Request.Method} {HttpContext.Request.Path} | 400 Guild not registered.");
                return(BadRequest("Guild not registered."));
            }

            ModCase modCase = await database.SelectSpecificModCase(guildid, modcaseid);

            if (modCase == null)
            {
                logger.LogInformation($"{HttpContext.Request.Method} {HttpContext.Request.Path} | 404 ModCase not found.");
                return(NotFound());
            }
            ModCase oldModCase = (ModCase)modCase.Clone();

            modCase.Title       = newValue.Title;
            modCase.Description = newValue.Description;
            modCase.UserId      = newValue.UserId;
            if (newValue.OccuredAt.HasValue)
            {
                modCase.OccuredAt = newValue.OccuredAt.Value;
            }
            modCase.Punishment     = newValue.Punishment;
            modCase.Labels         = newValue.Labels.Distinct().ToArray();
            modCase.Others         = newValue.Others;
            modCase.PunishmentType = newValue.PunishmentType;
            modCase.PunishedUntil  = newValue.PunishedUntil;
            if (modCase.PunishmentType == PunishmentType.None)
            {
                modCase.PunishedUntil    = null;
                modCase.PunishmentActive = false;
            }
            if (modCase.PunishedUntil == null)
            {
                modCase.PunishmentActive = modCase.PunishmentType != PunishmentType.None && modCase.PunishmentType != PunishmentType.Kick;
            }
            else
            {
                modCase.PunishmentActive = modCase.PunishedUntil > DateTime.UtcNow && modCase.PunishmentType != PunishmentType.None && modCase.PunishmentType != PunishmentType.Kick;
            }

            modCase.Id                = oldModCase.Id;
            modCase.CaseId            = oldModCase.CaseId;
            modCase.GuildId           = oldModCase.GuildId;
            modCase.Username          = oldModCase.Username;
            modCase.Discriminator     = oldModCase.Discriminator;
            modCase.Nickname          = oldModCase.Nickname;
            modCase.CreatedAt         = oldModCase.CreatedAt;
            modCase.LastEditedAt      = DateTime.UtcNow;
            modCase.LastEditedByModId = currentUser.Id;

            if (oldModCase.UserId != modCase.UserId)  // if user id got updated, update nickname and username
            {
                var currentReportedUser = await discord.FetchUserInfo(modCase.UserId, true);

                if (currentReportedUser == null)
                {
                    logger.LogInformation($"{HttpContext.Request.Method} {HttpContext.Request.Path} | 400 Invalid Discord UserId.");
                    return(BadRequest("Invalid Discord UserId."));
                }
                if (currentReportedUser.Bot)
                {
                    logger.LogInformation($"{HttpContext.Request.Method} {HttpContext.Request.Path} | 400 Cannot create cases for bots.");
                    return(BadRequest("Cannot create cases for bots."));
                }
                if (config.Value.SiteAdminDiscordUserIds.Contains(currentReportedUser.Id))
                {
                    logger.LogInformation($"{HttpContext.Request.Method} {HttpContext.Request.Path} | 400 Cannot create cases for site admins.");
                    return(BadRequest("Cannot create cases for site admins."));
                }
                modCase.Username      = currentReportedUser.Username; // update to new username
                modCase.Discriminator = currentReportedUser.Discriminator;

                var currentReportedMember = await discord.FetchMemberInfo(guildid, modCase.UserId, true);

                if (currentReportedMember != null)
                {
                    if (currentReportedMember.Roles.Contains(guildConfig.ModRoleId) || currentReportedMember.Roles.Contains(guildConfig.AdminRoleId))
                    {
                        logger.LogInformation($"{HttpContext.Request.Method} {HttpContext.Request.Path} | 400 Cannot create cases for team members.");
                        return(BadRequest("Cannot create cases for team members."));
                    }
                    modCase.Nickname = currentReportedMember.Nick;  // update to new nickname if no member anymore leave old fetched nickname
                }
            }

            database.UpdateModCase(modCase);
            await database.SaveChangesAsync();

            if (handlePunishment)
            {
                if (oldModCase.UserId != modCase.UserId || oldModCase.PunishmentType != modCase.PunishmentType || oldModCase.PunishedUntil != modCase.PunishedUntil)
                {
                    try {
                        logger.LogInformation($"{HttpContext.Request.Method} {HttpContext.Request.Path} | Handling punishment.");
                        await punishmentHandler.UndoPunishment(oldModCase, database);

                        if (modCase.PunishmentActive || (modCase.PunishmentType == PunishmentType.Kick && oldModCase.PunishmentType != PunishmentType.Kick))
                        {
                            if (modCase.PunishedUntil == null || modCase.PunishedUntil > DateTime.UtcNow)
                            {
                                await punishmentHandler.ExecutePunishment(modCase, database);
                            }
                        }
                    }
                    catch (Exception e) {
                        logger.LogError(e, "Failed to handle punishment for modcase.");
                    }
                }
            }

            logger.LogInformation($"{HttpContext.Request.Method} {HttpContext.Request.Path} | Sending notification.");
            try {
                await discordAnnouncer.AnnounceModCase(modCase, RestAction.Edited, currentUser, sendNotification);
            }
            catch (Exception e) {
                logger.LogError(e, "Failed to announce modcase.");
            }

            logger.LogInformation($"{HttpContext.Request.Method} {HttpContext.Request.Path} | 200 Resource updated.");
            return(Ok(new { id = modCase.Id, caseid = modCase.CaseId }));
        }
        public async Task <IActionResult> PutSpecificItem([FromRoute] ulong guildId, [FromRoute] int caseId, [FromBody] ModCaseForPutDto newValue, [FromQuery] bool sendNotification = true, [FromQuery] bool handlePunishment = true)
        {
            await RequirePermission(guildId, caseId, APIActionPermission.Edit);

            Identity currentIdentity = await GetIdentity();

            if (!await currentIdentity.HasPermissionToExecutePunishment(guildId, newValue.PunishmentType))
            {
                throw new UnauthorizedException();
            }

            var repo = ModCaseRepository.CreateDefault(_serviceProvider, currentIdentity);

            ModCase modCase = await repo.GetModCase(guildId, caseId);

            modCase.Title       = newValue.Title;
            modCase.Description = newValue.Description;
            modCase.UserId      = newValue.UserId;
            if (newValue.OccuredAt.HasValue)
            {
                modCase.OccuredAt = newValue.OccuredAt.Value;
            }
            modCase.Labels            = newValue.Labels.Distinct().ToArray();
            modCase.Others            = newValue.Others;
            modCase.PunishmentType    = newValue.PunishmentType;
            modCase.PunishedUntil     = newValue.PunishedUntil;
            modCase.LastEditedByModId = currentIdentity.GetCurrentUser().Id;

            modCase = await repo.UpdateModCase(modCase, handlePunishment, sendNotification);

            return(Ok(modCase));
        }