public async Task <ActionResult <LootListEntryUpdateDto> > PutEntry(long entryId, [FromBody] LootListEntrySubmissionDto dto) { var entry = await _context.LootListEntries.FindAsync(entryId); if (entry is null) { return(NotFound()); } await _context.Entry(entry).Reference(e => e.LootList).LoadAsync(); var authorizationResult = await _authorizationService.AuthorizeAsync(User, entry.LootList.CharacterId, AppPolicies.CharacterOwnerOrAdmin); if (!authorizationResult.Succeeded) { return(Unauthorized()); } if (entry.LootList.Status != LootListStatus.Editing) { return(Problem("Loot List cannot be edited.")); } if (dto.EntryId == dto.SwapEntryId) { return(Problem("Swap entry is the same entry as the target.")); } if (entry.DropId.HasValue) { return(Problem("Loot List entry has already been won and may not be changed.")); } if (entry.ItemId == dto.ItemId && entry.Justification == dto.Justification) { return(Problem("Entry is already set to the specified item.")); } var returnDto = new LootListEntryUpdateDto { EntryId = entryId, ItemId = dto.ItemId, EntryJustification = dto.Justification, SwapEntryId = dto.SwapEntryId }; bool allowed; string?reason; if (dto.SwapEntryId.HasValue) { var swapEntry = await _context.LootListEntries.FindAsync(dto.SwapEntryId); if (swapEntry is null) { return(NotFound()); } await _context.Entry(swapEntry).Reference(e => e.LootList).LoadAsync(); if ((entry.LootList.CharacterId, entry.LootList.Phase) != (swapEntry.LootList.CharacterId, swapEntry.LootList.Phase)) { return(Problem("Swap entry is not part of the same list as the target entry.")); } if (swapEntry.DropId.HasValue) { return(Problem("Loot List entry has already been won and may not be changed.")); } var oldItemId = entry.ItemId; var oldJustification = entry.Justification; entry.ItemId = dto.ItemId; entry.Justification = dto.Justification; swapEntry.ItemId = oldItemId; swapEntry.Justification = oldJustification; await _context.Entry(entry).Collection(e => e.Passes).LoadAsync(); await _context.Entry(swapEntry).Collection(e => e.Passes).LoadAsync(); var swapPasses = swapEntry.Passes.ToList(); foreach (var pass in entry.Passes) { pass.LootListEntryId = swapEntry.Id; } foreach (var pass in swapPasses) { pass.LootListEntryId = entry.Id; } (allowed, reason) = await CheckAllowedAsync(entry, swapEntry, dto.RemoveIfInvalid); if (!allowed) { return(Problem(reason)); } returnDto.SwapItemId = swapEntry.ItemId; returnDto.SwapEntryJustification = swapEntry.Justification; } else { entry.ItemId = dto.ItemId; entry.Justification = dto.Justification; (allowed, reason) = await CheckAllowedAsync(entry, null, dto.RemoveIfInvalid); if (!allowed) { return(Problem(reason)); } } (allowed, reason) = await CheckValidAsync(entry, dto); if (!allowed) { return(Problem(reason)); } await _context.SaveChangesAsync(); _telemetry.TrackEvent("LootListEntryUpdated", User, props => { props["EntryId"] = entry.Id.ToString(); props["CharacterId"] = entry.LootList.CharacterId.ToString(); props["Phase"] = entry.LootList.Phase.ToString(); }); return(returnDto); }
private async Task <(bool allowed, string?reason)> CheckValidAsync(LootListEntry entry, LootListEntrySubmissionDto dto) { if (entry.ItemId.HasValue) { var item = await _context.Items .AsNoTracking() .Where(i => i.Id == entry.ItemId.Value) .Select(i => new { i.Id, i.Name, i.Phase, i.RewardFromId, QuestId = (uint?)i.RewardFrom !.QuestId, MaxCount = (!i.IsUnique && (i.Slot == InventorySlot.Trinket || i.Slot == InventorySlot.Finger || i.Slot == InventorySlot.OneHand)) ? 2 : 1 })