source: KernelRecordsMVC.Web/Controllers/OrderController.cs@ 6886d95

main
Last change on this file since 6886d95 was 1dcdb2c, checked in by mmilevski <markomilevski3@…>, 3 weeks ago

Changed controllers to include transactions, Implemented password hashing.

  • Property mode set to 100644
File size: 8.4 KB
Line 
1using KernelRecordsMVC.Application.ViewModels;
2using KernelRecordsMVC.Domain.Enums;
3using KernelRecordsMVC.Infrastructure.Data;
4using KernelRecordsMVC.Models;
5using Microsoft.AspNetCore.Mvc;
6using Microsoft.EntityFrameworkCore;
7
8namespace KernelRecordsMVC.Web.Controllers;
9
10public class OrderController : Controller
11{
12 private readonly KernelRecordsContext _context;
13
14 public OrderController(KernelRecordsContext context)
15 {
16 _context = context;
17 }
18
19
20 // ==========================================
21 // ADD PRODUCT TO ORDER
22 // UC007
23 // ==========================================
24
25 [HttpGet]
26 public IActionResult AddProduct(long id)
27 {
28 var userId = GetUserId();
29
30 if (userId == null)
31 return RedirectToAction(
32 "Login",
33 "Account");
34
35 var product = _context.Products
36 .Include(p => p.Release)
37 .FirstOrDefault(p => p.ProductId == id);
38
39 if (product == null)
40 return NotFound();
41
42 if (product.Stock <= 0)
43 {
44 TempData["Error"] =
45 "This product is currently out of stock.";
46
47 return RedirectToAction(
48 "Details",
49 "Release",
50 new { id = product.ReleaseId });
51 }
52
53
54 using var transaction =
55 _context.Database.BeginTransaction();
56
57 try
58 {
59 var order = _context.Orders
60 .Include(o => o.OrderProducts)
61 .FirstOrDefault(o =>
62 o.UserId == userId.Value &&
63 o.Status == OrderStatusType.PENDING);
64
65 if (order == null)
66 {
67 order = new Order
68 {
69 UserId = userId.Value,
70 PaymentMethod = PaymentMethodType.CARD,
71 PurchaseDate = DateTime.Today,
72 PointsEarned = 0,
73 PointsUsed = null,
74 Status = OrderStatusType.PENDING
75 };
76
77 _context.Orders.Add(order);
78
79 _context.SaveChanges();
80 }
81
82
83 var existingItem = order.OrderProducts
84 .FirstOrDefault(x =>
85 x.ProductId == product.ProductId);
86
87
88 if (existingItem != null)
89 {
90 if (existingItem.Quantity + 1 >
91 product.Stock)
92 {
93 TempData["Error"] =
94 "There is not enough stock available.";
95
96 transaction.Rollback();
97
98 return RedirectToAction(
99 "Details",
100 "Release",
101 new { id = product.ReleaseId });
102 }
103
104 existingItem.Quantity++;
105 }
106 else
107 {
108 var discount = _context.ModificationProducts
109 .Include(mp => mp.Modification)
110 .Where(mp =>
111 mp.ProductId == product.ProductId &&
112 mp.Modification.TypeOfModification ==
113 ModificationType.DISCOUNT &&
114 mp.Modification.Discount.HasValue &&
115 mp.Modification.Discount.Value > 0)
116 .Select(mp => mp.Modification)
117 .OrderByDescending(m => m.DateModified)
118 .FirstOrDefault();
119
120
121 var priceAtPurchase = product.Price;
122
123 if (discount != null)
124 {
125 priceAtPurchase =
126 product.Price -
127 (
128 product.Price *
129 discount.Discount!.Value /
130 100m
131 );
132
133 priceAtPurchase =
134 Math.Round(
135 priceAtPurchase,
136 2);
137 }
138
139
140 var orderProduct = new OrderProduct
141 {
142 OrderId = order.OrderId,
143
144 ProductId =
145 product.ProductId,
146
147 PriceAtPurchase =
148 priceAtPurchase,
149
150 Quantity = 1
151 };
152
153 _context.OrderProducts.Add(orderProduct);
154 }
155
156
157 _context.SaveChanges();
158
159 transaction.Commit();
160
161
162 return RedirectToAction(nameof(Cart));
163 }
164 catch
165 {
166 transaction.Rollback();
167 throw;
168 }
169 }
170
171
172 // ==========================================
173 // CART
174 // ==========================================
175
176 [HttpGet]
177 public IActionResult Cart()
178 {
179 var userId = GetUserId();
180
181 if (userId == null)
182 {
183 return RedirectToAction(
184 "Login",
185 "Account");
186 }
187
188
189 var order = _context.Orders
190 .Include(o => o.OrderProducts)
191 .ThenInclude(op => op.Product)
192 .ThenInclude(p => p.Release)
193 .FirstOrDefault(o =>
194 o.UserId == userId.Value &&
195 o.Status == OrderStatusType.PENDING);
196
197
198 var viewModel = new CartViewModel();
199
200
201 if (order != null)
202 {
203 viewModel.Items = order.OrderProducts
204 .Select(op => new CartItemViewModel
205 {
206 ProductId = op.ProductId,
207
208 ReleaseId =
209 op.Product.ReleaseId,
210
211 ReleaseTitle =
212 op.Product.Release.Title,
213
214 Format =
215 op.Product.Format.ToString(),
216
217 Price =
218 op.PriceAtPurchase,
219
220 Quantity =
221 op.Quantity,
222
223 Stock =
224 op.Product.Stock,
225
226 CoverPhoto =
227 op.Product.Release.CoverPhoto
228 })
229 .ToList();
230 }
231
232
233 return View(viewModel);
234 }
235
236
237 // ==========================================
238 // REMOVE PRODUCT
239 // ==========================================
240
241 [HttpPost]
242 [ValidateAntiForgeryToken]
243 public IActionResult RemoveProduct(long id)
244 {
245 var userId = GetUserId();
246
247 if (userId == null)
248 return RedirectToAction(
249 "Login",
250 "Account");
251
252
253 var item = _context.OrderProducts
254 .Include(x => x.Order)
255 .FirstOrDefault(x =>
256 x.ProductId == id &&
257 x.Order.UserId == userId.Value &&
258 x.Order.Status ==
259 OrderStatusType.PENDING);
260
261
262 if (item != null)
263 {
264 _context.OrderProducts.Remove(item);
265
266 _context.SaveChanges();
267 }
268
269
270 return RedirectToAction(nameof(Cart));
271 }
272
273
274 // ==========================================
275 // UPDATE QUANTITY
276 // ==========================================
277
278 [HttpPost]
279 [ValidateAntiForgeryToken]
280 public IActionResult UpdateQuantity(
281 long id,
282 long quantity)
283 {
284 var userId = GetUserId();
285
286 if (userId == null)
287 return RedirectToAction(
288 "Login",
289 "Account");
290
291
292 if (quantity <= 0)
293 {
294 return RemoveProduct(id);
295 }
296
297
298 var item = _context.OrderProducts
299 .Include(x => x.Order)
300 .Include(x => x.Product)
301 .FirstOrDefault(x =>
302 x.ProductId == id &&
303 x.Order.UserId == userId.Value &&
304 x.Order.Status ==
305 OrderStatusType.PENDING);
306
307
308 if (item == null)
309 return NotFound();
310
311
312 if (quantity > item.Product.Stock)
313 {
314 TempData["Error"] =
315 "The requested quantity exceeds available stock.";
316
317 return RedirectToAction(nameof(Cart));
318 }
319
320
321 item.Quantity = quantity;
322
323 _context.SaveChanges();
324
325
326 return RedirectToAction(nameof(Cart));
327 }
328
329
330 // ==========================================
331 // USER ID
332 // ==========================================
333
334 private long? GetUserId()
335 {
336 var userId =
337 HttpContext.Session.GetInt32("UserId");
338
339 if (userId.HasValue)
340 return userId.Value;
341
342 return null;
343 }
344}
Note: See TracBrowser for help on using the repository browser.