public async Task Should_Publish_Refund_Payment_Event() { // Arrange var request = new CreateEShopRefundInput { DisplayReason = "Reason", CustomerRemark = "Customer Remark", PaymentId = PaymentsTestData.Payment1, StaffRemark = "StaffRemark", RefundItems = new List <CreateEShopRefundItemInput> { new CreateEShopRefundItemInput { CustomerRemark = "CustomerRemark", OrderId = PaymentsTestData.Order1, StaffRemark = "StaffRemark", OrderLines = new List <OrderLineRefundInfoModel> { new OrderLineRefundInfoModel { OrderLineId = PaymentsTestData.OrderLine1, Quantity = 1, TotalAmount = 0 } } } } }; // Act & Assert await _refundAppService.CreateAsync(request); _testRefundPaymentEventHandler.IsEventPublished.ShouldBe(true); }
public virtual async Task CreateAsync(CreateEShopRefundInput input) { await AuthorizationService.CheckAsync(PaymentsPermissions.Refunds.Manage); var payment = await _paymentRepository.GetAsync(input.PaymentId); var createRefundInput = new CreateRefundInput { PaymentId = input.PaymentId, DisplayReason = input.DisplayReason, CustomerRemark = input.CustomerRemark, StaffRemark = input.StaffRemark }; foreach (var refundItem in input.RefundItems) { var order = await _orderAppService.GetAsync(refundItem.OrderId); var paymentItem = payment.PaymentItems.SingleOrDefault(x => x.ItemKey == refundItem.OrderId.ToString()); if (order.PaymentId != input.PaymentId || paymentItem == null) { throw new OrderIsNotInSpecifiedPaymentException(order.Id, payment.Id); } // Todo: Check if current user is an admin of the store. foreach (var orderLineRefundInfoModel in refundItem.OrderLines) { var orderLine = order.OrderLines.Single(x => x.Id == orderLineRefundInfoModel.OrderLineId); if (orderLine.RefundedQuantity + orderLineRefundInfoModel.Quantity > orderLine.Quantity) { throw new InvalidRefundQuantityException(orderLineRefundInfoModel.Quantity); } } createRefundInput.RefundItems.Add(new CreateRefundItemInput { PaymentItemId = paymentItem.Id, RefundAmount = refundItem.OrderLines.Sum(x => x.TotalAmount), CustomerRemark = refundItem.CustomerRemark, StaffRemark = refundItem.StaffRemark, ExtraProperties = new Dictionary <string, object> { { "StoreId", order.StoreId.ToString() }, { "OrderId", order.Id.ToString() }, { "OrderLines", _jsonSerializer.Serialize(refundItem.OrderLines) } } }); } await _distributedEventBus.PublishAsync(new RefundPaymentEto { TenantId = CurrentTenant.Id, CreateRefundInput = createRefundInput }); }
public Task CreateAsync(CreateEShopRefundInput input) { return(_service.CreateAsync(input)); }
public virtual async Task CreateAsync(CreateEShopRefundInput input) { await AuthorizationService.CheckAsync(PaymentsPermissions.Refunds.Manage); var payment = await _paymentRepository.GetAsync(input.PaymentId); if (payment.PendingRefundAmount != decimal.Zero) { throw new AnotherRefundTaskIsOnGoingException(payment.Id); } var createRefundInput = new CreateRefundInput { PaymentId = input.PaymentId, DisplayReason = input.DisplayReason, CustomerRemark = input.CustomerRemark, StaffRemark = input.StaffRemark }; foreach (var refundItem in input.RefundItems) { var order = await _orderAppService.GetAsync(refundItem.OrderId); var paymentItem = payment.PaymentItems.SingleOrDefault(x => x.ItemKey == refundItem.OrderId.ToString()); if (order.PaymentId != input.PaymentId || paymentItem == null) { throw new OrderIsNotInSpecifiedPaymentException(order.Id, payment.Id); } await AuthorizationService.CheckMultiStorePolicyAsync(paymentItem.StoreId, PaymentsPermissions.Refunds.Manage, PaymentsPermissions.Refunds.CrossStore); var refundAmount = refundItem.OrderLines.Sum(x => x.TotalAmount) + refundItem.OrderExtraFees.Sum(x => x.TotalAmount); if (refundAmount + paymentItem.RefundAmount > paymentItem.ActualPaymentAmount) { throw new InvalidRefundAmountException(payment.Id, paymentItem.Id, refundAmount); } foreach (var model in refundItem.OrderLines) { var orderLine = order.OrderLines.Find(x => x.Id == model.OrderLineId); if (orderLine is null) { throw new OrderLineNotFoundException(order.Id, model.OrderLineId); } if (orderLine.RefundedQuantity + model.Quantity > orderLine.Quantity) { throw new InvalidRefundQuantityException(model.Quantity); } } foreach (var model in refundItem.OrderExtraFees) { var orderExtraFee = order.OrderExtraFees.Find(x => x.Name == model.Name && x.Key == model.Key); if (orderExtraFee is null) { throw new OrderExtraFeeNotFoundException(order.Id, model.Name, model.Key); } } var eto = new CreateRefundItemInput { PaymentItemId = paymentItem.Id, RefundAmount = refundAmount, CustomerRemark = refundItem.CustomerRemark, StaffRemark = refundItem.StaffRemark }; eto.SetProperty(nameof(RefundItem.StoreId), order.StoreId); eto.SetProperty(nameof(RefundItem.OrderId), order.Id); eto.SetProperty(nameof(RefundItem.OrderLines), _jsonSerializer.Serialize(refundItem.OrderLines)); eto.SetProperty(nameof(RefundItem.OrderExtraFees), _jsonSerializer.Serialize(refundItem.OrderExtraFees)); createRefundInput.RefundItems.Add(eto); } await _distributedEventBus.PublishAsync(new RefundPaymentEto(CurrentTenant.Id, createRefundInput)); }