public async Task <IActionResult> GetMealOrderDetailForTransferAsync(string orderGuid)
        {
            var orderBiz       = new MealOrderBiz();
            var orderDetailBiz = new MealOrderDetailBiz();
            var orderModel     = await orderBiz.GetModelAsync(orderGuid);

            if (orderModel == null)
            {
                return(Failed(ErrorCode.Empty, "无此订单数据"));
            }
            if (orderModel.OrderStatus != MealOrderStatusEnum.Paided.ToString())
            {
                var enumStatus = (MealOrderStatusEnum)Enum.Parse(typeof(MealOrderStatusEnum), orderModel.OrderStatus);
                return(Failed(ErrorCode.UserData, $"当店订单状态为[{enumStatus.GetDescription()}]不支持转让"));
            }
            else if (orderModel.MealEndTime < DateTime.Now)
            {
                return(Failed(ErrorCode.UserData, $"当店订单已过用餐时间,无法转让"));
            }
            var orderDetails = await orderDetailBiz.GetModelsByOrderGuidAsync(orderGuid);

            var response = orderModel.ToDto <GetMealOrderDetailResponseDto>();

            response.Dishees = orderDetails?.Select(a => a.ToDto <GetMealOrderDetailResponseDto.MealOrderDetailDishesDto>()).ToList();
            return(Success(response));
        }
        public async Task <IActionResult> AcceptTransferedMealOrderAsync([FromBody] AcceptTransferedMealOrderRequestDto requestDto)
        {
            var orderGuid      = requestDto.OrderGuid;
            var orderBiz       = new MealOrderBiz();
            var orderDetailBiz = new MealOrderDetailBiz();

            #region 检测待转让订单是否能被转让
            var orderModelOld = await orderBiz.GetModelAsync(orderGuid);

            if (orderModelOld == null)
            {
                return(Failed(ErrorCode.Empty, "无此订单数据"));
            }
            if (orderModelOld.OrderStatus != MealOrderStatusEnum.Paided.ToString())
            {
                var enumStatus = (MealOrderStatusEnum)Enum.Parse(typeof(MealOrderStatusEnum), orderModelOld.OrderStatus);
                return(Failed(ErrorCode.UserData, $"当店订单状态为[{enumStatus.GetDescription()}]不支持转让"));
            }
            else if (orderModelOld.MealEndTime < DateTime.Now)
            {
                return(Failed(ErrorCode.UserData, $"当店订单已过用餐时间,无法转让"));
            }
            else if (orderModelOld.UserGuid == UserID)
            {
                return(Failed(ErrorCode.UserData, $"不能接收来自自己的转让订单"));
            }
            #endregion

            //获取转让订单去向用户的钱包账户
            var accountModels = await new MealAccountBiz().GetModelsByUserIdAsync(UserID, orderModelOld.HospitalGuid);
            if (!accountModels.Any())
            {
                return(Failed(ErrorCode.UserData, "未检测到钱包账户,请先充值"));
            }

            //获取待转让订单的订单明细数据
            var orderDetailsOld = await orderDetailBiz.GetModelsByOrderGuidAsync(orderGuid);

            MealOrderModel orderInsert = new MealOrderModel();                                                //新增订单记录
            MealOrderModel orderUpdate = new MealOrderModel();                                                //更新订单记录
            List <MealOrderDetailModel>   orderDetails   = new List <MealOrderDetailModel>();                 //新增点餐订单明细列表
            List <MealAccountDetailModel> accountDetails = new List <MealAccountDetailModel>();               //新增点餐钱包流水列表
            var tradeModels = new List <MealAccountTradeModel>();                                             //点餐交易流水列表
            List <MealAccountTradeDetailModel> tradeDetailsModels = new List <MealAccountTradeDetailModel>(); //点餐订单交易流水明细列表

            //创建新订单
            var orderModelNew = orderModelOld.Clone() as MealOrderModel;
            orderModelNew.OrderGuid       = Guid.NewGuid().ToString("N");
            orderModelNew.UserGuid        = UserID;
            orderModelNew.CreatedBy       = UserID;
            orderModelNew.CreationDate    = DateTime.Now;
            orderModelNew.LastUpdatedBy   = UserID;
            orderModelNew.LastUpdatedDate = DateTime.Now;
            orderModelNew.TransferredFrom = orderModelOld.OrderGuid;

            //修改旧订单
            orderModelOld.TransferredTo   = orderModelNew.OrderGuid;
            orderModelOld.OrderStatus     = MealOrderStatusEnum.Transferred.ToString();
            orderModelOld.LastUpdatedBy   = UserID;
            orderModelOld.LastUpdatedDate = DateTime.Now;

            orderInsert = orderModelNew;
            orderUpdate = orderModelOld;

            //创建新的订单详情
            for (int i = 0; i < orderDetailsOld.Count; i++)
            {
                var od = orderDetailsOld[i];
                od.OrderDetailGuid = Guid.NewGuid().ToString("N");
                od.OrderGuid       = orderModelNew.OrderGuid;
                od.CreatedBy       = UserID;
                od.CreationDate    = DateTime.Now;
                od.LastUpdatedBy   = UserID;
                od.LastUpdatedDate = DateTime.Now;
            }
            orderDetails.AddRange(orderDetailsOld);

            #region 旧订单退款:创建钱包退款流水、订单退款交易流水

            //退款-订单交易记录
            var refundTradeModels = new MealAccountTradeModel
            {
                AccountTradeGuid        = Guid.NewGuid().ToString("N"),
                OrderGuid               = orderModelOld.OrderGuid,
                AccountTradeType        = (sbyte)MealAccountTradeTypeEnum.Refund,
                AccountTradeFee         = orderModelOld.TotalPrice,
                AccountTradeDescription = string.Empty,
                CreatedBy               = UserID,
                LastUpdatedBy           = UserID,
                OrgGuid = string.Empty
            };
            tradeModels.Add(refundTradeModels);
            //退款-订单交易明细
            var tradeDetal_TransferFrom = await new MealAccountTradeDetailBiz().GetModelsByOrderGuidAsync(orderModelOld.OrderGuid, 0);
            foreach (var td in tradeDetal_TransferFrom)
            {
                var item = td.Clone() as MealAccountTradeDetailModel;
                item.AccountTradeDetailGuid = Guid.NewGuid().ToString("N");
                item.AccountTradeGuid       = refundTradeModels.AccountTradeGuid;
                item.CreatedBy       = UserID;
                item.CreationDate    = DateTime.Now;
                item.LastUpdatedBy   = UserID;
                item.LastUpdatedDate = DateTime.Now;
                tradeDetailsModels.Add(item);
            }
            //退款-钱包账户流水
            var sourceUserAccountModels = await new MealAccountBiz().GetModelsByUserIdAsync(orderModelOld.UserGuid, orderModelOld.HospitalGuid);
            if (!sourceUserAccountModels.Any())
            {
                return(Failed(ErrorCode.UserData, "未检测到钱包账户"));
            }
            accountDetails.AddRange(tradeDetal_TransferFrom.Select(a => new MealAccountDetailModel
            {
                AccountDetailGuid        = Guid.NewGuid().ToString("N"),
                AccountGuid              = a.AccountGuid,
                AccountDetailType        = MealAccountDetailTypeEnum.Refund.ToString(),
                AccountDetailIncomeType  = (sbyte)MealAccountDetailIncomeTypeEnum.Income,
                AccountDetailBeforeFee   = (sourceUserAccountModels.FirstOrDefault(p => p.AccountGuid == a.AccountGuid)?.AccountBalance ?? 0M),
                AccountDetailFee         = a.AccountTradeFee,
                AccountDetailAfterFee    = (sourceUserAccountModels.FirstOrDefault(p => p.AccountGuid == a.AccountGuid)?.AccountBalance ?? 0M) + a.AccountTradeFee,
                AccountDetailDescription = $"订单转让退款:订单号[{orderModelOld.OrderNo}]",
                CreatedBy     = UserID,
                LastUpdatedBy = UserID,
                OrgGuid       = string.Empty
            }).ToList());

            #endregion

            #region 新订单扣款、创建钱包流水、创建订单交易流水
            var accountToal = accountModels.Sum(a => a.AccountBalance);
            var orderTotal  = orderModelNew.TotalPrice;
            if (accountToal < orderTotal)
            {
                return(Failed(ErrorCode.UserData, "余额不足,请先充值"));
            }
            var rechargeAccount = accountModels.FirstOrDefault(a => a.AccountType == MealAccountTypeEnum.Recharge.ToString());
            var grantAccount    = accountModels.FirstOrDefault(a => a.AccountType == MealAccountTypeEnum.Grant.ToString());

            var newOrderTradeModel = new MealAccountTradeModel
            {
                AccountTradeGuid        = Guid.NewGuid().ToString("N"),
                OrderGuid               = orderModelNew.OrderGuid,
                AccountTradeType        = (sbyte)MealAccountTradeTypeEnum.Consumer,
                AccountTradeFee         = orderModelNew.TotalPrice,
                AccountTradeDescription = string.Empty,
                CreatedBy               = UserID,
                LastUpdatedBy           = UserID,
                OrgGuid = string.Empty
            };
            tradeModels.Add(newOrderTradeModel);

            var paidMoney = orderTotal;
            //创建钱包流水记录
            if (grantAccount != null && grantAccount.AccountBalance > 0)
            {
                var grantPaid = grantAccount.AccountBalance > paidMoney ? paidMoney : grantAccount.AccountBalance;
                accountDetails.Add(new MealAccountDetailModel
                {
                    AccountDetailGuid        = Guid.NewGuid().ToString("N"),
                    AccountGuid              = grantAccount.AccountGuid,
                    AccountDetailType        = MealAccountDetailTypeEnum.Consume.ToString(),
                    AccountDetailIncomeType  = (sbyte)MealAccountDetailIncomeTypeEnum.Expenditure,
                    AccountDetailBeforeFee   = grantAccount.AccountBalance,
                    AccountDetailFee         = grantPaid,
                    AccountDetailAfterFee    = grantAccount.AccountBalance - grantPaid,
                    AccountDetailDescription = "订单消费",
                    CreatedBy     = UserID,
                    LastUpdatedBy = UserID,
                    OrgGuid       = string.Empty
                });
                var orderPaid = grantPaid > orderModelNew.TotalPrice ? orderModelNew.TotalPrice : grantPaid;
                tradeDetailsModels.Add(new MealAccountTradeDetailModel
                {
                    AccountTradeDetailGuid = Guid.NewGuid().ToString("N"),
                    AccountGuid            = grantAccount.AccountGuid,
                    AccountTradeGuid       = newOrderTradeModel.AccountTradeGuid,
                    AccountTradeFee        = orderPaid,
                    CreatedBy     = UserID,
                    LastUpdatedBy = UserID,
                    OrgGuid       = string.Empty
                });
                paidMoney -= grantPaid;
            }
            if (paidMoney > 0 && rechargeAccount != null && rechargeAccount.AccountBalance > 0)
            {
                accountDetails.Add(new MealAccountDetailModel
                {
                    AccountDetailGuid        = Guid.NewGuid().ToString("N"),
                    AccountGuid              = rechargeAccount.AccountGuid,
                    AccountDetailType        = MealAccountDetailTypeEnum.Consume.ToString(),
                    AccountDetailIncomeType  = (sbyte)MealAccountDetailIncomeTypeEnum.Expenditure,
                    AccountDetailBeforeFee   = rechargeAccount.AccountBalance,
                    AccountDetailFee         = paidMoney,
                    AccountDetailAfterFee    = rechargeAccount.AccountBalance - paidMoney,
                    AccountDetailDescription = "订单消费",
                    CreatedBy     = UserID,
                    LastUpdatedBy = UserID,
                    OrgGuid       = string.Empty
                });
                tradeDetailsModels.Add(new MealAccountTradeDetailModel
                {
                    AccountTradeDetailGuid = Guid.NewGuid().ToString("N"),
                    AccountGuid            = rechargeAccount.AccountGuid,
                    AccountTradeGuid       = newOrderTradeModel.AccountTradeGuid,
                    AccountTradeFee        = paidMoney,
                    CreatedBy     = UserID,
                    LastUpdatedBy = UserID,
                    OrgGuid       = string.Empty
                });
            }
            #endregion

            var result = await orderBiz.AcceptTransferedMealOrderAsync(orderInsert, orderUpdate, orderDetails, accountDetails, tradeModels, tradeDetailsModels);

            return(result ? Success() : Failed(ErrorCode.DataBaseError, "订单转让操作失败,请重试"));
        }