Add contribution payment options to registries
- Added support for single and amount-specific QR codes. - Updated `RegistrySettings` model and database schema. - Enhanced `RegistryAdmin` to configure payment options. - Introduced `RegistryContributionAmount` for partial fulfillment. - Updated `RegistryPublic` to display contribution progress. - Added new models for payment methods and QR code handling. - Improved privacy by limiting contributor visibility.
This commit is contained in:
@@ -4,6 +4,7 @@ using BirthList.Web.Data;
|
||||
using Microsoft.EntityFrameworkCore;
|
||||
using System.Security.Cryptography;
|
||||
using System.Text;
|
||||
using System.Text.Json;
|
||||
|
||||
namespace BirthList.Web.Features.Registries;
|
||||
|
||||
@@ -210,6 +211,8 @@ internal sealed class RegistryService(RegistryDbContext registryDbContext, Appli
|
||||
BankAccountBic = settings?.BankAccountBic,
|
||||
BankAccountDisplayName = settings?.BankAccountDisplayName,
|
||||
ShowBankAccountName = settings?.ShowBankAccountName ?? false,
|
||||
ContributionQrCodeUrl = settings?.ContributionQrCodeUrl,
|
||||
ContributionAmountQrCodes = ParseContributionAmountQrCodes(settings?.ContributionAmountQrCodesJson),
|
||||
CurrentUserId = userId,
|
||||
IsAdmin = isAdmin,
|
||||
Items = registry.Items
|
||||
@@ -289,7 +292,9 @@ internal sealed class RegistryService(RegistryDbContext registryDbContext, Appli
|
||||
BankAccountIban = settings?.BankAccountIban,
|
||||
BankAccountBic = settings?.BankAccountBic,
|
||||
BankAccountDisplayName = settings?.BankAccountDisplayName,
|
||||
ShowBankAccountName = settings?.ShowBankAccountName ?? false
|
||||
ShowBankAccountName = settings?.ShowBankAccountName ?? false,
|
||||
ContributionQrCodeUrl = settings?.ContributionQrCodeUrl,
|
||||
ContributionAmountQrCodes = ParseContributionAmountQrCodes(settings?.ContributionAmountQrCodesJson).ToList()
|
||||
};
|
||||
}
|
||||
|
||||
@@ -325,10 +330,68 @@ internal sealed class RegistryService(RegistryDbContext registryDbContext, Appli
|
||||
settings.BankAccountBic = string.IsNullOrWhiteSpace(model.BankAccountBic) ? null : model.BankAccountBic.Trim();
|
||||
settings.BankAccountDisplayName = string.IsNullOrWhiteSpace(model.BankAccountDisplayName) ? null : model.BankAccountDisplayName.Trim();
|
||||
settings.ShowBankAccountName = model.ShowBankAccountName;
|
||||
settings.ContributionQrCodeUrl = string.IsNullOrWhiteSpace(model.ContributionQrCodeUrl) ? null : model.ContributionQrCodeUrl.Trim();
|
||||
settings.ContributionAmountQrCodesJson = SerializeContributionAmountQrCodes(model.ContributionAmountQrCodes);
|
||||
|
||||
await registryDbContext.SaveChangesAsync(cancellationToken).ConfigureAwait(false);
|
||||
}
|
||||
|
||||
private static IReadOnlyList<ContributionAmountQrCodeModel> ParseContributionAmountQrCodes(string? json)
|
||||
{
|
||||
if (string.IsNullOrWhiteSpace(json))
|
||||
{
|
||||
return [];
|
||||
}
|
||||
|
||||
try
|
||||
{
|
||||
var items = JsonSerializer.Deserialize<List<ContributionAmountQrCodeModel>>(json);
|
||||
if (items is null)
|
||||
{
|
||||
return [];
|
||||
}
|
||||
|
||||
return items
|
||||
.Where(x => x.Amount > 0 && !string.IsNullOrWhiteSpace(x.QrCodeUrl))
|
||||
.Select(x => new ContributionAmountQrCodeModel
|
||||
{
|
||||
Amount = x.Amount,
|
||||
QrCodeUrl = x.QrCodeUrl.Trim()
|
||||
})
|
||||
.OrderBy(x => x.Amount)
|
||||
.ToList();
|
||||
}
|
||||
catch (JsonException)
|
||||
{
|
||||
return [];
|
||||
}
|
||||
}
|
||||
|
||||
private static string? SerializeContributionAmountQrCodes(IEnumerable<ContributionAmountQrCodeModel>? amountQrCodes)
|
||||
{
|
||||
if (amountQrCodes is null)
|
||||
{
|
||||
return null;
|
||||
}
|
||||
|
||||
var normalized = amountQrCodes
|
||||
.Where(x => x.Amount > 0 && !string.IsNullOrWhiteSpace(x.QrCodeUrl))
|
||||
.Select(x => new ContributionAmountQrCodeModel
|
||||
{
|
||||
Amount = x.Amount,
|
||||
QrCodeUrl = x.QrCodeUrl.Trim()
|
||||
})
|
||||
.OrderBy(x => x.Amount)
|
||||
.ToList();
|
||||
|
||||
if (normalized.Count == 0)
|
||||
{
|
||||
return null;
|
||||
}
|
||||
|
||||
return JsonSerializer.Serialize(normalized);
|
||||
}
|
||||
|
||||
public async Task<IReadOnlyList<RegistryItemEditModel>> GetRegistryItemsAsync(Guid registryId, CancellationToken cancellationToken)
|
||||
{
|
||||
var items = await registryDbContext.RegistryItems
|
||||
|
||||
Reference in New Issue
Block a user