diff --git a/Moonlight/App/Services/Store/StoreGiftService.cs b/Moonlight/App/Services/Store/StoreGiftService.cs new file mode 100644 index 0000000..58f5900 --- /dev/null +++ b/Moonlight/App/Services/Store/StoreGiftService.cs @@ -0,0 +1,60 @@ +using Microsoft.EntityFrameworkCore; +using Moonlight.App.Database.Entities; +using Moonlight.App.Database.Entities.Store; +using Moonlight.App.Exceptions; +using Moonlight.App.Repositories; + +namespace Moonlight.App.Services.Store; + +public class StoreGiftService +{ + private readonly IServiceScopeFactory ServiceScopeFactory; + + public StoreGiftService(IServiceScopeFactory serviceScopeFactory) + { + ServiceScopeFactory = serviceScopeFactory; + } + + public async Task Redeem(User u, string code) + { + using var scope = ServiceScopeFactory.CreateScope(); + var giftCodeRepo = scope.ServiceProvider.GetRequiredService>(); + var userRepo = scope.ServiceProvider.GetRequiredService>(); + + var user = userRepo + .Get() + .Include(x => x.GiftCodeUses) + .ThenInclude(x => x.GiftCode) + .FirstOrDefault(x => x.Id == u.Id); + + if(user == null) + throw new DisplayException("Unsafe value detected. Please reload the page to proceed"); + + var giftCode = giftCodeRepo + .Get() + .FirstOrDefault(x => x.Code == code); + + if (giftCode == null) + throw new DisplayException("The gift code does not exist"); + + if (giftCode.Amount < 1) + throw new DisplayException("The gift code can no longer be used as it has exceeded the max use amount"); + + if (user.GiftCodeUses.Any(x => x.GiftCode.Id == giftCode.Id)) + throw new DisplayException("The gift code has already been used on this account"); + + giftCode.Amount--; + giftCodeRepo.Update(giftCode); + + var giftCardUse = new GiftCodeUse() + { + GiftCode = giftCode + }; + + user.GiftCodeUses.Add(giftCardUse); + userRepo.Update(user); + + var transactionService = scope.ServiceProvider.GetRequiredService(); + await transactionService.Add(u, giftCode.Value, $"Redeemed gift code '{giftCode.Code}'"); + } +} \ No newline at end of file diff --git a/Moonlight/App/Services/Store/StorePaymentService.cs b/Moonlight/App/Services/Store/StorePaymentService.cs new file mode 100644 index 0000000..ed3c5eb --- /dev/null +++ b/Moonlight/App/Services/Store/StorePaymentService.cs @@ -0,0 +1,14 @@ +using Moonlight.App.Models.Abstractions; + +namespace Moonlight.App.Services.Store; + +public class StorePaymentService +{ + public readonly List Gateways = new(); + + public Task RegisterGateway(PaymentGateway gateway) + { + Gateways.Add(gateway); + return Task.CompletedTask; + } +} \ No newline at end of file diff --git a/Moonlight/App/Services/Store/StoreService.cs b/Moonlight/App/Services/Store/StoreService.cs index 4f5c4fa..007db86 100644 --- a/Moonlight/App/Services/Store/StoreService.cs +++ b/Moonlight/App/Services/Store/StoreService.cs @@ -8,16 +8,11 @@ public class StoreService public StoreAdminService Admin => ServiceProvider.GetRequiredService(); public StoreOrderService Order => ServiceProvider.GetRequiredService(); - public readonly List Gateways = new(); + public StorePaymentService Payment => ServiceProvider.GetRequiredService(); + public StoreGiftService Gift => ServiceProvider.GetRequiredService(); public StoreService(IServiceProvider serviceProvider) { ServiceProvider = serviceProvider; } - - public Task RegisterGateway(PaymentGateway gateway) - { - Gateways.Add(gateway); - return Task.CompletedTask; - } } \ No newline at end of file diff --git a/Moonlight/Program.cs b/Moonlight/Program.cs index 1c39bbe..ee5e3d0 100644 --- a/Moonlight/Program.cs +++ b/Moonlight/Program.cs @@ -51,9 +51,11 @@ builder.Services.AddScoped(); builder.Services.AddScoped(); // Services / Store -builder.Services.AddSingleton(); +builder.Services.AddScoped(); builder.Services.AddScoped(); builder.Services.AddScoped(); +builder.Services.AddScoped(); +builder.Services.AddSingleton(); builder.Services.AddScoped(); // Services / Users diff --git a/Moonlight/Shared/Views/Account/Payments.razor b/Moonlight/Shared/Views/Account/Payments.razor index 59b6d07..f5c0c17 100644 --- a/Moonlight/Shared/Views/Account/Payments.razor +++ b/Moonlight/Shared/Views/Account/Payments.razor @@ -3,33 +3,52 @@ @using Moonlight.App.Services @using Moonlight.App.Database.Entities.Store @using BlazorTable +@using Moonlight.App.Models.Abstractions @using Moonlight.App.Services.Store @inject IdentityService IdentityService @inject ConfigService ConfigService @inject StoreService StoreService +@inject ToastService ToastService +@inject NavigationManager Navigation
-
- +
+
+

Redeem gift code

+
+
+
+ + +
+
-
- @foreach (var gateway in StoreService.Gateways) +
+ +
+
+ @foreach (var gateway in StoreService.Payment.Gateways) { }
+
+
+ +
+
@@ -39,7 +58,7 @@

Transactions

- + x.Id) + .ToArray(); + } + + private async Task RedeemGiftCode() + { + if (string.IsNullOrEmpty(GiftCode)) + return; + + await StoreService.Gift.Redeem(IdentityService.CurrentUser, GiftCode); + + GiftCode = ""; + await ToastService.Success("Successfully applied gift code"); + await LazyLoader.Reload(); + } + + private async Task SelectGateway(PaymentGateway gateway) + { + SelectedGateway = gateway; + await InvokeAsync(StateHasChanged); + } + + private async Task LaunchPayment() + { + if (SelectedGateway == null) + return; + + var url = await SelectedGateway.Start(Amount); + Navigation.NavigateTo(url, true); } } \ No newline at end of file