/// <summary>
        /// 初始化枚举字段
        /// </summary>
        /// <param name="input"></param>
        /// <param name="order"></param>
        private async Task InitOrderEnumField(CreateOrUpdateOrderInput input, Order order)
        {
            order.OrderType      = input.OrderType.HasValue ? input.OrderType.Value : OrderType.PayOnDelivery;
            order.OrderSource    = input.OrderSource.HasValue ? input.OrderSource.Value : OrderSource.Self;
            order.OrderStatus    = input.OrderStatus.HasValue ? input.OrderStatus.Value : OrderStatus.WaitConfirm;
            order.PaymentStatus  = input.PaymentStatus.HasValue ? input.PaymentStatus.Value : PaymentStatus.Pending;
            order.ShippingStatus = input.ShippingStatus.HasValue ? input.ShippingStatus.Value : ShippingStatus.NotYetShipped;
            order.PaymentType    = order.OrderType == OrderType.PayOnDelivery ? PaymentType.PayOnDelivery : PaymentType.PayOnline;

            if (input.OrderSource.HasValue)
            {
                order.OrderSource = input.OrderSource.Value;
            }
            else
            {
                var store = await _storeManager.GetByIdAsync(input.StoreId);

                if (store != null)
                {
                    order.OrderSource = store.OrderSource;
                }
                else
                {
                    order.OrderSource = OrderSource.Self;
                }
            }
        }
        private async Task <EntityDto <long> > UpdateOrderAsync(CreateOrUpdateOrderInput input)
        {
            var order = await _orderManager.GetByIdAsync(input.Id);

            await _orderManager.OrderRepository.EnsureCollectionLoadedAsync(order, o => o.Items);

            ObjectMapper.Map(input, order);

            if (order.OrderNumber.IsNullOrWhiteSpace())
            {
                order.GenerateOrderNumber();
            }

            InitOrderAmount(input, order);

            await InitOrderEnumField(input, order);

            await UpdateAddressInfo(input, order);

            await CreateOrUpdateOrderItem(input, order);

            await _orderManager.UpdateAsync(order);

            return(new EntityDto <long>(order.Id));
        }
        /// <summary>
        /// 添加或者修改Order的公共方法
        /// </summary>
        /// <param name="input"></param>
        /// <returns></returns>

        public async Task CreateOrUpdate(CreateOrUpdateOrderInput input)
        {
            if (!string.IsNullOrEmpty(input.Order.Id))
            {
                await Update(input.Order);
            }
            else
            {
                await Create(input.Order);
            }
        }
 /// <summary>
 /// 初始订单金额
 /// </summary>
 /// <param name="input"></param>
 /// <param name="order"></param>
 private void InitOrderAmount(CreateOrUpdateOrderInput input, Order order)
 {
     order.DiscountAmount             = input.DiscountAmount ?? 0;
     order.RefundedAmount             = input.RefundedAmount ?? 0;
     order.RewardAmount               = input.RewardAmount ?? 0;
     order.ShippingAmount             = input.ShippingAmount ?? 0;;
     order.SubtotalAmount             = input.SubtotalAmount ?? 0;
     order.SubTotalDiscountAmount     = input.SubTotalDiscountAmount ?? 0;
     order.TotalAmount                = input.TotalAmount ?? 0;
     order.PaymentMethodAdditionalFee = input.PaymentMethodAdditionalFee ?? 0;
 }
 /// <summary>
 /// 添加或者修改Order的公共方法
 /// </summary>
 /// <param name="input"></param>
 /// <returns></returns>
 public async Task CreateOrUpdateOrder(CreateOrUpdateOrderInput input)
 {
     if (input.Order.Id.HasValue)
     {
         await UpdateOrderAsync(input.Order);
     }
     else
     {
         await CreateOrderAsync(input.Order);
     }
 }
        /// <summary>
        /// 更新地址信息
        /// </summary>
        /// <param name="input"></param>
        /// <param name="order"></param>
        /// <returns></returns>
        private async Task UpdateAddressInfo(CreateOrUpdateOrderInput input, Order order)
        {
            var province = await _stateManager.GetProvinceByIdAsync(input.ShippingProvinceId);

            var city = await _stateManager.GetCityByIdAsync(input.ShippingCityId);

            var district = await _stateManager.GetDistrictByIdAsync(input.ShippingDistrictId);

            order.ShippingProvince = province?.Name ?? string.Empty;
            order.ShippingCity     = city?.Name ?? string.Empty;
            order.ShippingDistrict = district?.Name ?? string.Empty;
        }
        /// <summary>
        /// 创建或更新订单
        /// </summary>
        /// <param name="input"></param>
        /// <returns></returns>
        public async Task <EntityDto <long> > CreateOrUpdateOrder(CreateOrUpdateOrderInput input)
        {
            if (input.Id > 0)
            {
                await UpdateOrderAsync(input);

                return(new EntityDto <long>()
                {
                    Id = input.Id
                });
            }
            else
            {
                return(await CreateOrderAsync(input));
            }
        }
        private async Task <EntityDto <long> > CreateOrderAsync(CreateOrUpdateOrderInput input)
        {
            var order = ObjectMapper.Map <Order>(input);

            order.GenerateOrderNumber();

            InitOrderAmount(input, order);

            await InitOrderEnumField(input, order);

            await UpdateAddressInfo(input, order);

            await CreateOrUpdateOrderItem(input, order);

            await _orderManager.CreateAsync(order);

            await CurrentUnitOfWork.SaveChangesAsync();

            return(new EntityDto <long>(order.Id));
        }
        /// <summary>
        /// 创建或更新子订单
        /// </summary>
        /// <param name="input"></param>
        /// <param name="order"></param>
        /// <returns></returns>
        private async Task CreateOrUpdateOrderItem(CreateOrUpdateOrderInput input, Order order)
        {
            if (input.Id == 0)
            {
                order.Items = new Collection <OrderItem>();
            }
            else
            {
                var existItemIds   = input.Items.Select(i => i.Id).ToList();
                var itemsId2Remove = order.Items.Where(i => !existItemIds.Contains(i.Id)).ToList();

                //删除不存在的属性
                foreach (var item in itemsId2Remove)
                {
                    item.IsDeleted = true;
                    order.Items.Remove(item);
                }
            }

            foreach (var oderItemDto in input.Items)
            {
                OrderItem orderItem = null;

                if (oderItemDto.Id > 0)
                {
                    orderItem = order.Items.FirstOrDefault(oi => oi.Id == oderItemDto.Id);
                    ObjectMapper.Map(oderItemDto, orderItem);
                }
                else
                {
                    orderItem = ObjectMapper.Map <OrderItem>(oderItemDto);;
                }

                var product = await _productManager.GetByIdAsync(oderItemDto.ProductId);

                await _productManager.ProductRepository.EnsureCollectionLoadedAsync(product, t => t.Attributes);

                await _productManager.ProductRepository.EnsureCollectionLoadedAsync(product, t => t.AttributeCombinations);

                var jsonAttributeList    = oderItemDto.Attributes.GetAttributesJson(product, _productAttributeManager);
                var jsonAttributesString = JsonConvert.SerializeObject(jsonAttributeList);

                orderItem.ProductName = product.Name;
                orderItem.Weight      = product.Weight;
                orderItem.Volume      = product.GetVolume();
                if (!oderItemDto.Attributes.IsNullOrEmpty())
                {
                    var combin = product.AttributeCombinations.FirstOrDefault(c => c.AttributesJson == jsonAttributesString);

                    if (combin != null)
                    {
                        orderItem.AttributesJson       = jsonAttributesString;
                        orderItem.AttributeDescription = await _productAttributeFormatter.FormatAttributesAsync(product, jsonAttributeList);
                    }
                }

                if (orderItem.OrderItemNumber.IsNullOrWhiteSpace())
                {
                    orderItem.GenerateOrderItemNumber();
                }
                if (orderItem.Id <= 0)
                {
                    order.Items.Add(orderItem);
                }

                order.TotalAmount    += product.Price;
                order.SubtotalAmount += product.Price;
            }
        }