93f2f1bd3b
Major refactor replacing Sale/Order with ShopPO → Invoice → LoadingSheet flow. Removed legacy Sale/Order models and features; introduced ShopPO, ShopPOItem, Invoice, LoadingSheetOrder, and SysConfig models. Updated related entities, enums, repositories, and controllers. Added new migrations for schema changes and system config. Overhauled business logic and DI registrations. Updated documentation with migration plan.
67 lines
2.3 KiB
C#
67 lines
2.3 KiB
C#
using Distribution.Features.Invoice;
|
|
using Distribution.Infra.Authorization;
|
|
using Distribution.Infra.UoW;
|
|
using Distribution.Models;
|
|
|
|
namespace Distribution.Features.Payment;
|
|
|
|
public class PaymentService(
|
|
IPaymentRepository repo,
|
|
IInvoiceRepository invoiceRepo,
|
|
IUnitOfWork uow,
|
|
ICurrentUserService currentUser)
|
|
{
|
|
private static PaymentResponse ToResponse(Models.Payment p) =>
|
|
new(p.Id, p.FK_InvoiceId, p.Amount, p.Method, p.CollectedAt, p.CollectedBy, p.CreatedAt);
|
|
|
|
public async Task<List<PaymentResponse>?> GetByInvoiceIdAsync(Guid invoiceId)
|
|
{
|
|
var invoice = await invoiceRepo.GetByIdAsync(invoiceId);
|
|
if (invoice is null || !invoice.IsActive) return null;
|
|
|
|
var payments = await repo.GetByInvoiceIdAsync(invoiceId);
|
|
return payments.Select(ToResponse).ToList();
|
|
}
|
|
|
|
public async Task<PaymentResponse?> CreateAsync(Guid invoiceId, CreatePaymentRequest request, CancellationToken ct = default)
|
|
{
|
|
var invoice = await invoiceRepo.GetByIdAsync(invoiceId);
|
|
if (invoice is null || !invoice.IsActive) return null;
|
|
if (invoice.Status == InvoiceStatus.Finalized)
|
|
throw new InvalidOperationException("Cannot record a payment against a finalized invoice");
|
|
|
|
var userId = currentUser.UserId ?? request.CollectedByUserId
|
|
?? throw new InvalidOperationException("CollectedByUserId is required while auth is unavailable");
|
|
|
|
var payment = new Models.Payment
|
|
{
|
|
FK_InvoiceId = invoiceId,
|
|
Amount = request.Amount,
|
|
Method = request.Method,
|
|
CollectedAt = DateTime.Now,
|
|
CollectedBy = userId
|
|
};
|
|
|
|
await uow.BeginAsync(ct);
|
|
try
|
|
{
|
|
await repo.AddAsync(payment);
|
|
|
|
var allPayments = await repo.GetByInvoiceIdAsync(invoiceId);
|
|
var total = allPayments.Sum(p => p.Amount) + request.Amount;
|
|
|
|
invoice.PaymentStatus = total == 0
|
|
? PaymentStatus.Pending
|
|
: total < invoice.TotalAmount
|
|
? PaymentStatus.PartiallyPaid
|
|
: PaymentStatus.Paid;
|
|
|
|
invoiceRepo.Update(invoice);
|
|
await uow.CommitAsync(ct);
|
|
}
|
|
catch { await uow.RollbackAsync(ct); throw; }
|
|
|
|
return ToResponse(payment);
|
|
}
|
|
}
|