profileShare

rasmusjy / splitapp-backend-clean-onion

Read-only snapshot

No repository description.

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