Files
PnvPanel/backend/src/PnvPanel.Application/Billing/SendRequisitesToTelegram/SendRequisitesToTelegramCommandHandler.cs
T
Leonid Pershin 5ff5224935
CI / Backend (build + test) (push) Successful in 1m19s
CI / Frontend (lint + typecheck + build) (push) Successful in 33s
Refactor payment request handling to support role change top-ups
- Updated the `PaymentRequest` model to include a new `Kind` property, distinguishing between `Subscription` and `RoleChangeTopUp` requests.
- Modified the `TelegramNotifier` to accommodate the new request type, ensuring accurate notifications for role change top-ups.
- Enhanced the `ConfirmPaymentRequestCommandHandler` to handle role change top-ups without extending the billing period, reflecting the new payment logic.
- Updated various application components and tests to support the new payment request structure and ensure proper functionality.
- Revised API documentation to clarify the behavior of role change top-ups and their impact on billing.
2026-07-19 16:45:17 +03:00

60 lines
2.2 KiB
C#

using Microsoft.EntityFrameworkCore;
using PnvPanel.Application.Auth;
using PnvPanel.Application.Common.Interfaces;
using PnvPanel.Application.Common.Messaging;
using PnvPanel.Application.Common.Models;
using PnvPanel.Application.Telegram;
using PnvPanel.Domain.Billing;
namespace PnvPanel.Application.Billing.SendRequisitesToTelegram;
public sealed class SendRequisitesToTelegramCommandHandler(
IAppDbContext dbContext,
IIdentityService identityService,
ITelegramNotifier telegramNotifier,
ICurrentUser currentUser
) : ICommandHandler<SendRequisitesToTelegramCommand, Result>
{
public async Task<Result> Handle(
SendRequisitesToTelegramCommand command,
CancellationToken cancellationToken
)
{
if (currentUser.UserId is not { } userId)
return Result.Failure(AuthErrors.Unauthorized);
var request = await dbContext
.PaymentRequests.AsNoTracking()
.FirstOrDefaultAsync(r => r.Id == command.RequestId && r.UserId == userId, cancellationToken);
if (request is null)
return Result.Failure(BillingErrors.RequestNotFound);
var linkInfo = await identityService.GetTelegramLinkInfoAsync(userId, cancellationToken);
if (!linkInfo.IsLinked)
return Result.Failure(TelegramErrors.NotLinked);
var settings = await dbContext
.BillingSettings.AsNoTracking()
.FirstOrDefaultAsync(cancellationToken);
var text =
$"💳 Реквизиты для оплаты ({DescribeRequest(request)}, {request.AmountSnapshot} ₽):\n{settings?.RequisitesText}";
await telegramNotifier.NotifyUserAsync(userId, text, null, cancellationToken);
return Result.Success();
}
private static string DescribeRequest(PaymentRequest request) =>
request.Kind == PaymentRequestKind.RoleChangeTopUp ? "доплата за смену роли" : PeriodLabel(request.Period!.Value);
private static string PeriodLabel(PaymentPeriod period) =>
period switch
{
PaymentPeriod.Quarter => "3 месяца",
PaymentPeriod.HalfYear => "полгода",
PaymentPeriod.Year => "год",
_ => period.ToString(),
};
}