Esempio n. 1
0
    public virtual async Task HandleEventAsync(RefundOrderEto eventData)
    {
        var refundAmount = eventData.OrderLines.Sum(x => x.TotalAmount) +
                           eventData.OrderExtraFees.Sum(x => x.TotalAmount);

        var payment = await _paymentRepository.GetAsync(eventData.PaymentId);

        var paymentItem = payment.PaymentItems.Single(x => x.ItemKey == eventData.OrderId.ToString());

        var createRefundItemInput = new CreateRefundItemInput
        {
            PaymentItemId  = paymentItem.Id,
            RefundAmount   = refundAmount,
            CustomerRemark = eventData.CustomerRemark,
            StaffRemark    = eventData.StaffRemark
        };

        createRefundItemInput.SetProperty(nameof(RefundItem.StoreId), eventData.StoreId);
        createRefundItemInput.SetProperty(nameof(RefundItem.OrderId), eventData.OrderId);
        createRefundItemInput.SetProperty(nameof(RefundItem.OrderLines),
                                          _jsonSerializer.Serialize(eventData.OrderLines));
        createRefundItemInput.SetProperty(nameof(RefundItem.OrderExtraFees),
                                          _jsonSerializer.Serialize(eventData.OrderExtraFees));

        var eto = new RefundPaymentEto(eventData.TenantId, new CreateRefundInput
        {
            PaymentId      = eventData.PaymentId,
            DisplayReason  = eventData.DisplayReason,
            CustomerRemark = eventData.CustomerRemark,
            StaffRemark    = eventData.StaffRemark,
            RefundItems    = new List <CreateRefundItemInput> {
                createRefundItemInput
            }
        });

        await _distributedEventBus.PublishAsync(eto);
    }
Esempio n. 2
0
        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));
        }