profileShare

rasmusjy / splitapp-backend-modular-monolith

Read-only snapshot

No repository description.

main default branch 418 files Expires Sep 13, 2026, 9:06 AM
WishlistService.cs 5,592 bytes
1 using SplitApp.WebApp.Application.DTO;
2 using SplitApp.WebApp.Application.Mappers;
3 using SplitApp.Modules.Trips.Domain.Entities;
4 using SplitApp.Modules.Trips.Domain.Enums;
5 using SplitApp.Modules.Expenses.Domain.Entities;
6 using SplitApp.Modules.Expenses.Domain.Enums;
7 using SplitApp.Modules.Users.Domain.Entities;
8 using SplitApp.WebApp.Application.Contracts;
9
10 namespace SplitApp.WebApp.Application.Services;
11
12 public class WishlistService : IWishlistService
13 {
14 private readonly IAppUnitOfWork _uow;
15
16 public WishlistService(IAppUnitOfWork uow)
17 {
18 _uow = uow;
19 }
20
21 public async Task<List<TripWishlistItemBllDto>> GetByTripIdAsync(Guid tripId, Guid userId)
22 {
23 if (!await _uow.TripParticipants.IsParticipantAsync(tripId, userId))
24 return new List<TripWishlistItemBllDto>();
25 var items = await _uow.TripWishlistItems.GetByTripIdAsync(tripId);
26 return WishlistBllDtoFactory.CreateList(items);
27 }
28
29 public async Task<TripWishlistItemBllDto?> GetByIdAsync(Guid id, Guid userId)
30 {
31 var item = await _uow.TripWishlistItems.GetByIdAsync(id);
32 if (item == null) return null;
33 if (!await _uow.TripParticipants.IsParticipantAsync(item.TripId, userId)) return null;
34 return WishlistBllDtoFactory.Create(item);
35 }
36
37 public async Task<TripWishlistItemBllDto?> GetByIdRawAsync(Guid id)
38 {
39 var item = await _uow.TripWishlistItems.GetByIdAsync(id);
40 return item == null ? null : WishlistBllDtoFactory.Create(item);
41 }
42
43 public async Task<(TripWishlistItemBllDto? item, string? errorCode)> CreateAsync(TripWishlistItemBllDto item, Guid userId)
44 {
45 if (!await _uow.TripParticipants.IsParticipantAsync(item.TripId, userId))
46 return (null, "forbidden");
47
48 var entity = WishlistBllDtoFactory.ToEntity(item);
49 if (entity.Id == Guid.Empty) entity.Id = Guid.NewGuid();
50 entity.AddedByUserId = userId;
51 _uow.TripWishlistItems.Add(entity);
52 await _uow.SaveChangesAsync();
53
54 var reloaded = await _uow.TripWishlistItems.GetByIdAsync(entity.Id);
55 return (reloaded == null ? null : WishlistBllDtoFactory.Create(reloaded), null);
56 }
57
58 public async Task<(bool success, string? errorCode)> UpdateAsync(Guid id, TripWishlistItemBllDto incoming, Guid userId)
59 {
60 var existing = await _uow.TripWishlistItems.GetByIdAsync(id);
61 if (existing == null) return (false, "notfound");
62
63 if (!await _uow.TripParticipants.IsParticipantAsync(existing.TripId, userId))
64 return (false, "forbidden");
65
66 if (existing.AddedByUserId != userId) return (false, "forbidden");
67
68 existing.Title = incoming.Title;
69 existing.Description = incoming.Description;
70 existing.Category = incoming.Category;
71 existing.Priority = incoming.Priority;
72 existing.EstimatedCost = incoming.EstimatedCost;
73 existing.Url = incoming.Url;
74 existing.Location = incoming.Location;
75
76 _uow.TripWishlistItems.Update(existing);
77 await _uow.SaveChangesAsync();
78 return (true, null);
79 }
80
81 public async Task<(bool success, string? errorCode)> DeleteAsync(Guid id, Guid userId)
82 {
83 var existing = await _uow.TripWishlistItems.GetByIdAsync(id);
84 if (existing == null) return (false, "notfound");
85
86 if (!await _uow.TripParticipants.IsParticipantAsync(existing.TripId, userId))
87 return (false, "forbidden");
88
89 if (existing.AddedByUserId != userId) return (false, "forbidden");
90
91 var voteRepo = _uow.GetRepository<TripWishlistVote>();
92 var allVotes = (await voteRepo.GetAllAsync()).Where(v => v.WishlistItemId == id).ToList();
93 foreach (var vote in allVotes)
94 {
95 await voteRepo.RemoveAsync(vote.Id);
96 }
97
98 await _uow.TripWishlistItems.RemoveAsync(id);
99 await _uow.SaveChangesAsync();
100 return (true, null);
101 }
102
103 public async Task<(bool success, string? errorCode)> ToggleVoteAsync(Guid id, Guid userId)
104 {
105 var existing = await _uow.TripWishlistItems.GetByIdAsync(id);
106 if (existing == null) return (false, "notfound");
107
108 if (!await _uow.TripParticipants.IsParticipantAsync(existing.TripId, userId))
109 return (false, "forbidden");
110
111 var voteRepo = _uow.GetRepository<TripWishlistVote>();
112 var allVotes = (await voteRepo.GetAllAsync()).ToList();
113 var existingVote = allVotes.FirstOrDefault(v => v.WishlistItemId == id && v.UserId == userId);
114
115 if (existingVote != null)
116 {
117 await voteRepo.RemoveAsync(existingVote.Id);
118 }
119 else
120 {
121 voteRepo.Add(new TripWishlistVote
122 {
123 Id = Guid.NewGuid(),
124 WishlistItemId = id,
125 UserId = userId,
126 IsInterested = true
127 });
128 }
129
130 await _uow.SaveChangesAsync();
131 return (true, null);
132 }
133
134 public async Task<(bool success, string? errorCode)> ToggleCompleteAsync(Guid id, Guid userId)
135 {
136 var existing = await _uow.TripWishlistItems.GetByIdAsync(id);
137 if (existing == null) return (false, "notfound");
138
139 if (!await _uow.TripParticipants.IsParticipantAsync(existing.TripId, userId))
140 return (false, "forbidden");
141
142 existing.IsCompleted = !existing.IsCompleted;
143 existing.CompletedAt = existing.IsCompleted ? DateTime.UtcNow : null;
144
145 _uow.TripWishlistItems.Update(existing);
146 await _uow.SaveChangesAsync();
147 return (true, null);
148 }
149 }
150