public async Task <Unit> Handle(CancelPaymentCommand request, CancellationToken cancellationToken)
        {
            var entity = await _context.Payments
                         .SingleOrDefaultAsync(i => i.Id == request.Id && i.CustomerId == _currentUser.UserId, cancellationToken);

            if (entity == null)
            {
                throw new ValidationException("Id", "Invalid payment id.");
            }

            if (entity.Status == PaymentStatus.Processed)
            {
                throw new ValidationException("Status", "Payment has been processed already.");
            }

            if (entity.Status == PaymentStatus.Closed)
            {
                return(Unit.Value);
            }

            entity.Status  = PaymentStatus.Closed;
            entity.Comment = request.Reason;
            await _context.SaveChangesAsync(cancellationToken);

            await _mediator.Publish(new PaymentCancelled
            {
                PaymentId = entity.Id,
                Reason    = request.Reason
            }, cancellationToken);

            return(Unit.Value);
        }
        public async Task <Guid> Handle(CreatePaymentCommand request, CancellationToken cancellationToken)
        {
            var customer = await _mediator.Send(new GetCustomerQuery { Id = _currentUser.UserId }, cancellationToken);

            if (customer == null)
            {
                throw new ValidationException("CustomerId", "Invalid customer id.");
            }

            var hasSufficientBalance = customer.Balance >= request.Amount;

            var entity = new Payment
            {
                Amount     = request.Amount,
                Comment    = hasSufficientBalance ? "" : "Not enough funds",
                CustomerId = _currentUser.UserId,
                Date       = request.Date,
                Status     = hasSufficientBalance ? PaymentStatus.Pending : PaymentStatus.Closed,
            };

            await _context.Payments.AddAsync(entity, cancellationToken);

            await _context.SaveChangesAsync(cancellationToken);

            await _mediator.Publish(new PaymentCreated { Amount = request.Amount, PaymentId = entity.Id }, cancellationToken);

            return(entity.Id);
        }
        public async Task <bool> Handle(ReduceBalanceCommand request, CancellationToken cancellationToken)
        {
            var entity = await _context.Customers.SingleOrDefaultAsync(i => i.Id == _currentUser.UserId, cancellationToken);

            if (entity == null)
            {
                throw new ValidationException("Id", "Invalid customer id.");
            }

            if (entity.Balance < request.ReduceAmount)
            {
                return(false);
            }

            entity.Balance -= request.ReduceAmount;
            await _context.SaveChangesAsync(cancellationToken);

            return(true);
        }
Exemple #4
0
        public async Task <Unit> Handle(ProcessPaymentCommand request, CancellationToken cancellationToken)
        {
            var entity = await _context.Payments
                         .SingleOrDefaultAsync(i => i.Id == request.Id && i.CustomerId == _currentUser.UserId, cancellationToken);

            if (entity == null)
            {
                throw new ValidationException("Id", "Invalid payment id.");
            }

            if (entity.Status == PaymentStatus.Closed)
            {
                throw new ValidationException("Status", "Can't process the closed payment.");
            }

            if (entity.Status == PaymentStatus.Processed)
            {
                return(Unit.Value);
            }

            var balanceReduced = await _mediator.Send(new ReduceBalanceCommand { ReduceAmount = entity.Amount }, cancellationToken);

            if (!balanceReduced)
            {
                entity.Status  = PaymentStatus.Closed;
                entity.Comment = "Not enough funds";
            }
            else
            {
                entity.Status = PaymentStatus.Processed;
            }

            await _context.SaveChangesAsync(cancellationToken);

            await _mediator.Publish(new PaymentProcessed { PaymentId = entity.Id }, cancellationToken);

            return(Unit.Value);
        }