source: KernelRecordsMVC.Web/Controllers/AdminController.cs@ d2eccb3

main
Last change on this file since d2eccb3 was d2eccb3, checked in by mmilevski <markomilevski3@…>, 4 weeks ago

Minor fixes.

  • Property mode set to 100644
File size: 27.3 KB
RevLine 
[fa0fbaf]1using KernelRecordsMVC.Application.ViewModels;
[08aefc6]2using KernelRecordsMVC.Domain.Enums;
[d2eccb3]3using KernelRecordsMVC.Domain.Models;
[fa0fbaf]4using KernelRecordsMVC.Infrastructure.Data;
5using KernelRecordsMVC.Models;
6using Microsoft.AspNetCore.Mvc;
7using Microsoft.EntityFrameworkCore;
[08aefc6]8
[fa0fbaf]9namespace KernelRecordsMVC.Web.Controllers;
[08aefc6]10
11public class AdminController : Controller
12{
13 private readonly KernelRecordsContext _context;
14
15 public AdminController(KernelRecordsContext context)
16 {
17 _context = context;
18 }
19
20
[fa0fbaf]21 // =========================================================
[08aefc6]22 // ADMIN DASHBOARD
[fa0fbaf]23 // =========================================================
[08aefc6]24
25 [HttpGet]
26 public IActionResult Index()
27 {
28 if (!IsAdmin())
29 return Forbid();
30
[fa0fbaf]31
32 ViewBag.ProductCount =
33 _context.Products.Count();
34
35 ViewBag.ReleaseCount =
36 _context.Releases.Count();
37
38 ViewBag.OutOfStockCount =
39 _context.Products.Count(x =>
40 x.Stock <= 0);
41
42 ViewBag.LowStockCount =
43 _context.Products.Count(x =>
44 x.Stock > 0 &&
45 x.Stock <= 5);
46
47
[08aefc6]48 return View();
49 }
50
51
[fa0fbaf]52 // =========================================================
53 // PRODUCTS
54 // =========================================================
[08aefc6]55
56 [HttpGet]
[fa0fbaf]57 public IActionResult Products()
[08aefc6]58 {
59 if (!IsProductManager())
60 return Forbid();
61
[fa0fbaf]62
63 var products = _context.Products
64 .Include(p => p.Release)
65 .OrderBy(p => p.Release.Title)
66 .ThenBy(p => p.Format)
[08aefc6]67 .ToList();
68
[fa0fbaf]69
70 return View(products);
71 }
72
73
74 // =========================================================
75 // CREATE PRODUCT - GET
76 // =========================================================
77
78 [HttpGet]
79 public IActionResult CreateProduct()
80 {
81 if (!IsProductManager())
82 return Forbid();
83
84
85 LoadReleases();
86
87
88 return View(
89 new CreateProductViewModel());
[08aefc6]90 }
91
92
[fa0fbaf]93 // =========================================================
94 // CREATE PRODUCT - POST
95 // =========================================================
[08aefc6]96
97 [HttpPost]
98 [ValidateAntiForgeryToken]
99 public IActionResult CreateProduct(
100 CreateProductViewModel model)
101 {
102 if (!IsProductManager())
103 return Forbid();
104
[fa0fbaf]105
[08aefc6]106 if (!ModelState.IsValid)
107 {
108 LoadReleases();
[fa0fbaf]109
[08aefc6]110 return View(model);
111 }
112
113
114 var release = _context.Releases
115 .FirstOrDefault(x =>
116 x.ReleaseId == model.ReleaseId);
117
[fa0fbaf]118
[08aefc6]119 if (release == null)
120 {
121 ModelState.AddModelError(
[fa0fbaf]122 nameof(model.ReleaseId),
[08aefc6]123 "The selected release does not exist.");
124
[fa0fbaf]125
[08aefc6]126 LoadReleases();
[fa0fbaf]127
128
[08aefc6]129 return View(model);
130 }
131
132
[fa0fbaf]133 var alreadyExists =
134 _context.Products.Any(p =>
135 p.ReleaseId == model.ReleaseId &&
136 p.Format == model.Format);
137
[08aefc6]138
139 if (alreadyExists)
140 {
141 ModelState.AddModelError(
[fa0fbaf]142 nameof(model.Format),
[08aefc6]143 "This release already has a product in this format.");
144
[fa0fbaf]145
[08aefc6]146 LoadReleases();
[fa0fbaf]147
148
[08aefc6]149 return View(model);
150 }
151
152
[fa0fbaf]153 using var transaction =
154 _context.Database.BeginTransaction();
155
156
157 try
[08aefc6]158 {
[fa0fbaf]159 var product = new Product
160 {
161 ProductId =
162 GetNextProductId(),
163
164 ReleaseId =
165 model.ReleaseId,
[08aefc6]166
[fa0fbaf]167 Format =
168 model.Format,
[08aefc6]169
[fa0fbaf]170 Price =
171 model.Price,
[08aefc6]172
[fa0fbaf]173 ProductDescription =
174 model.ProductDescription,
[08aefc6]175
[fa0fbaf]176 Stock =
177 model.Stock
178 };
[08aefc6]179
180
[fa0fbaf]181 _context.Products.Add(product);
[08aefc6]182
[fa0fbaf]183 _context.SaveChanges();
[08aefc6]184
185
[fa0fbaf]186 CreateModification(
187 ModificationType.CREATE,
188 product.ProductId);
[08aefc6]189
190
[fa0fbaf]191 transaction.Commit();
[08aefc6]192
193
[fa0fbaf]194 TempData["Success"] =
195 $"{release.Title} ({product.Format}) was created successfully.";
[08aefc6]196
[fa0fbaf]197
198 return RedirectToAction(
199 nameof(Products));
200 }
201 catch
202 {
203 transaction.Rollback();
204
205 throw;
206 }
[08aefc6]207 }
208
209
[fa0fbaf]210 // =========================================================
211 // EDIT PRODUCT - GET
212 // =========================================================
[08aefc6]213
[fa0fbaf]214 [HttpGet]
215 public IActionResult EditProduct(long id)
[08aefc6]216 {
[fa0fbaf]217 if (!IsProductManager())
218 return Forbid();
219
220
221 var product = _context.Products
222 .Include(p => p.Release)
223 .FirstOrDefault(p =>
224 p.ProductId == id);
225
226
227 if (product == null)
228 return NotFound();
229
230
231 var model =
232 new EditProductViewModel
233 {
234 ProductId =
235 product.ProductId,
236
237 ReleaseId =
238 product.ReleaseId,
239
240 ReleaseTitle =
241 product.Release.Title,
242
243 Format =
244 product.Format,
245
246 Price =
247 product.Price,
248
249 ProductDescription =
250 product.ProductDescription,
251
252 Stock =
253 product.Stock,
254
255 ModificationType =
256 ModificationType.UPDATE
257 };
258
259
260 return View(model);
[08aefc6]261 }
262
263
[fa0fbaf]264 // =========================================================
265 // EDIT PRODUCT - POST
266 // =========================================================
267
268 [HttpPost]
269 [ValidateAntiForgeryToken]
270 public IActionResult EditProduct(
271 EditProductViewModel model)
[08aefc6]272 {
[fa0fbaf]273 if (!IsProductManager())
274 return Forbid();
[08aefc6]275
276
[fa0fbaf]277 var product = _context.Products
278 .Include(p => p.Release)
279 .FirstOrDefault(p =>
280 p.ProductId == model.ProductId);
281
282
283 if (product == null)
284 return NotFound();
285
286
287 // These values come from the database.
288 model.ReleaseId =
289 product.ReleaseId;
290
291 model.ReleaseTitle =
292 product.Release.Title;
293
294 model.Format =
295 product.Format;
296
297
298 // Display-only fields should not block
299 // validation of the submitted form.
300 ModelState.Remove(
301 nameof(model.ReleaseId));
302
303 ModelState.Remove(
304 nameof(model.ReleaseTitle));
305
306 ModelState.Remove(
307 nameof(model.Format));
308
309
310 // =====================================================
311 // DISCOUNT VALIDATION
312 // =====================================================
313
314 if (model.ModificationType ==
315 ModificationType.DISCOUNT)
316 {
317 if (!model.Discount.HasValue)
318 {
319 ModelState.AddModelError(
320 nameof(model.Discount),
321 "Please enter a discount percentage.");
322 }
323 else if (
324 model.Discount.Value <= 0 ||
325 model.Discount.Value >= 100)
326 {
327 ModelState.AddModelError(
328 nameof(model.Discount),
329 "Discount must be greater than 0 and less than 100.");
330 }
331 }
332
333
334 if (!ModelState.IsValid)
335 return View(model);
336
337
338 using var transaction =
339 _context.Database.BeginTransaction();
340
341
342 try
343 {
344 // =================================================
345 // APPLY DISCOUNT
346 // =================================================
347
348 if (model.ModificationType ==
349 ModificationType.DISCOUNT)
350 {
351 var discountPercentage =
352 model.Discount!.Value;
353
354
355 var oldPrice =
356 product.Price;
357
358
359 var discountAmount =
360 oldPrice *
361 (discountPercentage / 100m);
362
363
364 var newPrice =
365 oldPrice - discountAmount;
366
367
368 newPrice =
369 Math.Round(
370 newPrice,
371 2,
372 MidpointRounding.AwayFromZero);
373
374
375 // Product.Price becomes the
376 // actual current sale price.
377 product.Price =
378 newPrice;
379
380
381 _context.Products.Update(
382 product);
383
384 _context.SaveChanges();
385
386
387 CreateModification(
388 ModificationType.DISCOUNT,
389 product.ProductId,
390 discountPercentage);
391
392
393 transaction.Commit();
394
395
396 TempData["Success"] =
397 $"{discountPercentage:0.##}% discount applied. " +
398 $"Price changed from {oldPrice:C} to {newPrice:C}.";
399
400
401 return RedirectToAction(
402 nameof(Products));
403 }
404
405
406 // =================================================
407 // NORMAL UPDATE
408 // =================================================
409
410 product.Price =
411 model.Price;
412
413 product.ProductDescription =
414 model.ProductDescription;
415
416 product.Stock =
417 model.Stock;
418
419
420 _context.Products.Update(
421 product);
422
423 _context.SaveChanges();
424
425
426 CreateModification(
427 ModificationType.UPDATE,
428 product.ProductId);
429
430
431 transaction.Commit();
432
433
434 TempData["Success"] =
435 $"{product.Release.Title} was updated successfully.";
436
437
438 return RedirectToAction(
439 nameof(Products));
440 }
441 catch
442 {
443 transaction.Rollback();
444
445 throw;
446 }
[08aefc6]447 }
448
449
[fa0fbaf]450 // =========================================================
451 // CREATE RELEASE - GET
452 // =========================================================
453
454 [HttpGet]
455 public IActionResult CreateRelease()
[08aefc6]456 {
[fa0fbaf]457 if (!IsAdmin())
458 return Forbid();
459
460
461 LoadArtists();
[08aefc6]462
463
[fa0fbaf]464 var model =
465 new CreateReleaseViewModel
466 {
467 ReleaseDate =
468 DateTime.Today,
469
470 ReleaseType =
471 "ALBUM",
472
473 // Start an album with one empty track.
474 Tracks =
475 new List<CreateTrackViewModel>
476 {
477 new CreateTrackViewModel()
478 }
479 };
480
481
482 return View(model);
[08aefc6]483 }
484
485
[fa0fbaf]486 // =========================================================
487 // CREATE RELEASE - POST
488 // =========================================================
489
490 [HttpPost]
491 [ValidateAntiForgeryToken]
492 public IActionResult CreateRelease(
493 CreateReleaseViewModel model)
[08aefc6]494 {
[fa0fbaf]495 if (!IsAdmin())
496 return Forbid();
[08aefc6]497
[fa0fbaf]498
499 // =====================================================
500 // RELEASE TYPE VALIDATION
501 // =====================================================
502
503 if (model.ReleaseType != "ALBUM" &&
504 model.ReleaseType != "SINGLE")
505 {
506 ModelState.AddModelError(
507 nameof(model.ReleaseType),
508 "Please select Album or Single.");
509 }
510
511
512 // =====================================================
513 // MAIN ARTIST VALIDATION
514 // =====================================================
515
516 var mainArtistExists =
517 _context.Artists.Any(a =>
518 a.ArtistId ==
519 model.MainArtistId);
520
521
522 if (!mainArtistExists)
523 {
524 ModelState.AddModelError(
525 nameof(model.MainArtistId),
526 "Please select a valid main artist.");
527 }
528
529
530 // =====================================================
531 // FEATURED ARTISTS
532 // =====================================================
533
534 model.FeaturedArtistIds ??=
535 new List<long>();
536
537
538 model.FeaturedArtistIds =
539 model.FeaturedArtistIds
540 .Distinct()
541 .ToList();
542
543
544 // Do not allow the main artist
545 // to also be a featured artist.
546 model.FeaturedArtistIds.Remove(
547 model.MainArtistId);
548
549
550 // Validate that featured artists exist.
551 if (model.FeaturedArtistIds.Count > 0)
552 {
553 var validFeaturedArtistCount =
554 _context.Artists.Count(a =>
555 model.FeaturedArtistIds
556 .Contains(a.ArtistId));
557
558
559 if (validFeaturedArtistCount !=
560 model.FeaturedArtistIds.Count)
561 {
562 ModelState.AddModelError(
563 nameof(model.FeaturedArtistIds),
564 "One or more featured artists are invalid.");
565 }
566 }
567
568
569 // =====================================================
570 // SINGLE VALIDATION
571 // =====================================================
572
573 if (model.ReleaseType == "SINGLE")
574 {
575 if (string.IsNullOrWhiteSpace(
576 model.SingleDuration))
577 {
578 ModelState.AddModelError(
579 nameof(model.SingleDuration),
580 "Duration is required for a single.");
581 }
582 }
583
584
585 // =====================================================
586 // ALBUM VALIDATION
587 // =====================================================
588
589 if (model.ReleaseType == "ALBUM")
590 {
591 model.Tracks ??=
592 new List<CreateTrackViewModel>();
593
594
595 // Remove completely empty rows.
596 model.Tracks =
597 model.Tracks
598 .Where(t =>
599 !string.IsNullOrWhiteSpace(
600 t.SongName) ||
601 !string.IsNullOrWhiteSpace(
602 t.SongDuration))
603 .ToList();
604
605
606 if (model.Tracks.Count == 0)
607 {
608 ModelState.AddModelError(
609 nameof(model.Tracks),
610 "An album must contain at least one track.");
611 }
612
613
614 for (var i = 0;
615 i < model.Tracks.Count;
616 i++)
617 {
618 var track =
619 model.Tracks[i];
620
621
622 if (string.IsNullOrWhiteSpace(
623 track.SongName))
624 {
625 ModelState.AddModelError(
626 $"Tracks[{i}].SongName",
627 "Track name is required.");
628 }
629
630
631 if (string.IsNullOrWhiteSpace(
632 track.SongDuration))
633 {
634 ModelState.AddModelError(
635 $"Tracks[{i}].SongDuration",
636 "Track duration is required.");
637 }
638
639
640 track.ArtistIds ??=
641 new List<long>();
642
643
644 track.ArtistIds =
645 track.ArtistIds
646 .Distinct()
647 .ToList();
648
649
650 // Validate selected track artists.
651 if (track.ArtistIds.Count > 0)
652 {
653 var validTrackArtistCount =
654 _context.Artists.Count(a =>
655 track.ArtistIds.Contains(
656 a.ArtistId));
657
658
659 if (validTrackArtistCount !=
660 track.ArtistIds.Count)
661 {
662 ModelState.AddModelError(
663 $"Tracks[{i}].ArtistIds",
664 "One or more selected track artists are invalid.");
665 }
666 }
667 }
668 }
669
670
671 if (!ModelState.IsValid)
672 {
673 LoadArtists();
674
675 return View(model);
676 }
677
678
679 using var transaction =
680 _context.Database.BeginTransaction();
681
682
683 try
684 {
685 // =================================================
686 // CREATE RELEASE
687 // =================================================
688
689 var release =
690 new Release
691 {
692 ReleaseId =
693 GetNextReleaseId(),
694
695 Title =
696 model.Title.Trim(),
697
698 RecordLabel =
699 string.IsNullOrWhiteSpace(
700 model.RecordLabel)
701 ? null
702 : model.RecordLabel.Trim(),
703
704 Genre =
705 model.Genre.Trim(),
706
707 ReleaseDate =
708 model.ReleaseDate,
709
710 CoverPhoto =
711 model.CoverPhoto.Trim()
712 };
713
714
715 _context.Releases.Add(
716 release);
717
718 _context.SaveChanges();
719
720
721 // =================================================
722 // MAIN RELEASE ARTIST
723 // =================================================
724
725 var mainReleaseArtist =
726 new ReleaseArtist
727 {
728 ReleaseId =
729 release.ReleaseId,
730
731 ArtistId =
732 model.MainArtistId,
733
734 ReleaseOrdinal = 1,
735
736 Type =
737 ArtistReleaseType.MAIN
738 };
739
740
741 _context.ReleaseArtists.Add(
742 mainReleaseArtist);
743
744
745 // =================================================
746 // FEATURED RELEASE ARTISTS
747 // =================================================
748
749 long releaseOrdinal = 2;
750
751
752 foreach (var artistId
753 in model.FeaturedArtistIds)
754 {
755 var featuredArtist =
756 new ReleaseArtist
757 {
758 ReleaseId =
759 release.ReleaseId,
760
761 ArtistId =
762 artistId,
763
764 ReleaseOrdinal =
765 releaseOrdinal++,
766
767 Type =
768 ArtistReleaseType.FEATURE
769 };
770
771
772 _context.ReleaseArtists.Add(
773 featuredArtist);
774 }
775
776
777 _context.SaveChanges();
778
779
780 // =================================================
781 // ALBUM
782 // =================================================
783
784 if (model.ReleaseType == "ALBUM")
785 {
786 var album =
787 new Album
788 {
789 ReleaseId =
790 release.ReleaseId
791 };
792
793
794 _context.Albums.Add(
795 album);
796
797 _context.SaveChanges();
798
799
800 // =============================================
801 // TRACKS
802 // =============================================
803
804 foreach (var trackModel
805 in model.Tracks)
806 {
807 var song =
808 new Song
809 {
810 SongId =
811 GetNextSongId(),
812
813 SongName =
814 trackModel
815 .SongName
816 .Trim(),
817
818 SongDuration =
819 trackModel
820 .SongDuration
821 .Trim()
822 };
823
824
825 _context.Songs.Add(
826 song);
827
828 _context.SaveChanges();
829
830
831 // =========================================
832 // LINK SONG TO ALBUM
833 // =========================================
834
835 var albumSong =
836 new AlbumSong
837 {
838 AlbumId =
839 release.ReleaseId,
840
841 SongId =
842 song.SongId
843 };
844
845
846 _context.AlbumSongs.Add(
847 albumSong);
848
849
850 // =========================================
851 // SONG ARTISTS
852 // =========================================
853
854 var trackArtistIds =
855 trackModel.ArtistIds
856 .Distinct()
857 .ToList();
858
859
860 // If no track artists were selected,
861 // automatically use the release's
862 // main artist.
863 if (trackArtistIds.Count == 0)
864 {
865 trackArtistIds.Add(
866 model.MainArtistId);
867 }
868
869
870 long songOrdinal = 1;
871
872
873 foreach (var artistId
874 in trackArtistIds)
875 {
876 var songArtist =
877 new SongArtist
878 {
879 SongId =
880 song.SongId,
881
882 ArtistId =
883 artistId,
884
885 SongOrdinal =
886 songOrdinal++
887 };
888
889
890 _context.SongArtists.Add(
891 songArtist);
892 }
893
894
895 _context.SaveChanges();
896 }
897 }
898
899
900 // =================================================
901 // SINGLE
902 // =================================================
903
904 else
905 {
906 var single =
907 new SingleRelease
908 {
909 ReleaseId =
910 release.ReleaseId,
911
912 Duration =
913 model.SingleDuration!
914 .Trim()
915 };
916
917
918 _context.SingleReleases.Add(
919 single);
920
921 _context.SaveChanges();
922 }
923
924
925 transaction.Commit();
926
927
928 TempData["Success"] =
929 $"{release.Title} was created successfully.";
930
931
932 return RedirectToAction(
933 nameof(Index));
934 }
935 catch
936 {
937 transaction.Rollback();
938
939 throw;
940 }
[08aefc6]941 }
942
943
[fa0fbaf]944 // =========================================================
945 // AUTHORIZATION HELPERS
946 // =========================================================
947
948 private bool IsAdmin()
[08aefc6]949 {
[fa0fbaf]950 return HttpContext.Session
951 .GetString("Role") ==
952 "Admin";
[08aefc6]953 }
954
955
[fa0fbaf]956 private bool IsProductManager()
[08aefc6]957 {
[fa0fbaf]958 var role =
959 HttpContext.Session
960 .GetString("Role");
[08aefc6]961
[fa0fbaf]962 var adminType =
963 HttpContext.Session
964 .GetString("AdminType");
[08aefc6]965
966
[fa0fbaf]967 return role == "Admin" &&
968 (
969 adminType == "PRODUCT_MANAGER" ||
970 adminType == "SUPER_ADMIN"
971 );
972 }
[08aefc6]973
974
[fa0fbaf]975 // =========================================================
976 // CURRENT ADMIN ID
977 // =========================================================
[08aefc6]978
[fa0fbaf]979 private long? GetCurrentUserId()
980 {
981 var userId =
982 HttpContext.Session
983 .GetInt32("UserId");
[08aefc6]984
985
[fa0fbaf]986 if (!userId.HasValue)
987 return null;
[08aefc6]988
989
[fa0fbaf]990 return userId.Value;
991 }
[08aefc6]992
993
[fa0fbaf]994 // =========================================================
995 // LOAD RELEASES
996 // =========================================================
[08aefc6]997
[fa0fbaf]998 private void LoadReleases()
999 {
1000 ViewBag.Releases =
1001 _context.Releases
1002 .OrderBy(x =>
1003 x.Title)
1004 .ToList();
1005 }
[08aefc6]1006
1007
[fa0fbaf]1008 // =========================================================
1009 // LOAD ARTISTS
1010 // =========================================================
[08aefc6]1011
[fa0fbaf]1012 private void LoadArtists()
1013 {
1014 ViewBag.Artists =
1015 _context.Artists
1016 .OrderBy(a =>
1017 a.ArtistName)
1018 .ToList();
[08aefc6]1019 }
1020
1021
[fa0fbaf]1022 // =========================================================
1023 // NEXT PRODUCT ID
1024 // =========================================================
1025
1026 private long GetNextProductId()
[08aefc6]1027 {
[fa0fbaf]1028 var maxId =
1029 _context.Products
1030 .Select(x =>
1031 (long?)x.ProductId)
1032 .Max();
1033
[08aefc6]1034
1035 return (maxId ?? 0) + 1;
1036 }
1037
[fa0fbaf]1038
1039 // =========================================================
1040 // NEXT RELEASE ID
1041 // =========================================================
1042
1043 private long GetNextReleaseId()
[08aefc6]1044 {
[fa0fbaf]1045 var maxId =
1046 _context.Releases
1047 .Select(x =>
1048 (long?)x.ReleaseId)
1049 .Max();
[08aefc6]1050
1051
[fa0fbaf]1052 return (maxId ?? 0) + 1;
1053 }
[08aefc6]1054
1055
[fa0fbaf]1056 // =========================================================
1057 // NEXT SONG ID
1058 // =========================================================
1059
1060 private long GetNextSongId()
1061 {
1062 var maxId =
1063 _context.Songs
1064 .Select(x =>
1065 (long?)x.SongId)
1066 .Max();
1067
1068
1069 return (maxId ?? 0) + 1;
[08aefc6]1070 }
1071
1072
[fa0fbaf]1073 // =========================================================
1074 // NEXT MODIFICATION ID
1075 // =========================================================
[08aefc6]1076
[fa0fbaf]1077 private long GetNextModificationId()
[08aefc6]1078 {
[fa0fbaf]1079 var maxId =
1080 _context.Modifications
1081 .Select(x =>
1082 (long?)x.ModificationId)
1083 .Max();
[08aefc6]1084
[fa0fbaf]1085
1086 return (maxId ?? 0) + 1;
[08aefc6]1087 }
1088
1089
[fa0fbaf]1090 // =========================================================
1091 // CREATE MODIFICATION RECORD
1092 // =========================================================
[08aefc6]1093
[fa0fbaf]1094 private void CreateModification(
1095 ModificationType type,
1096 long productId,
1097 decimal? discount = null)
[08aefc6]1098 {
[fa0fbaf]1099 var adminId =
1100 GetCurrentUserId();
[08aefc6]1101
1102
[fa0fbaf]1103 if (adminId == null)
1104 {
1105 throw new InvalidOperationException(
1106 "The current admin could not be identified.");
[08aefc6]1107 }
1108
1109
[fa0fbaf]1110 var modification =
1111 new Modification
1112 {
1113 ModificationId =
1114 GetNextModificationId(),
1115
1116 AdminId =
1117 adminId.Value,
[08aefc6]1118
[fa0fbaf]1119 DateModified =
1120 DateTime.Today,
[08aefc6]1121
[fa0fbaf]1122 TypeOfModification =
1123 type,
[08aefc6]1124
[fa0fbaf]1125 Discount =
1126 discount
1127 };
[08aefc6]1128
1129
[fa0fbaf]1130 _context.Modifications.Add(
1131 modification);
[08aefc6]1132
[fa0fbaf]1133 _context.SaveChanges();
[08aefc6]1134
1135
[fa0fbaf]1136 var modificationProduct =
1137 new ModificationProduct
1138 {
1139 ModificationId =
1140 modification.ModificationId,
[08aefc6]1141
[fa0fbaf]1142 ProductId =
1143 productId
1144 };
[08aefc6]1145
1146
[fa0fbaf]1147 _context.ModificationProducts.Add(
1148 modificationProduct);
[08aefc6]1149
[fa0fbaf]1150 _context.SaveChanges();
1151 }
[08aefc6]1152}
Note: See TracBrowser for help on using the repository browser.