/// <summary>
        /// 验证销售单,当在执行预售送货时,或在收款单变更了销售单明细时,需要调用此接口更新销售单
        /// </summary>
        /// <param name="User"></param>
        /// <param name="DeliveryInfo"></param>
        /// <param name="ErrorInfo"></param>
        /// <returns></returns>
        public static int SaleOut_Update(UserInfo User, Delivery DeliveryInfo, out string ErrorInfo)
        {
            ErrorInfo = "";
            LogWriter.WriteLog("PBMIFService.SaleOut_Update:UserName="******",DeliveryInfo=" + JsonConvert.SerializeObject(DeliveryInfo));

            if (DeliveryInfo.ID == 0) { ErrorInfo = "销售单不存在,请先新增销售单!"; return -1; }

            PBM_DeliveryBLL bll = new PBM_DeliveryBLL(DeliveryInfo.ID);
            if (bll.Model == null) { ErrorInfo = "销售单不存在,请先新增销售单!"; return -1; }
            if (bll.Model.State > 3 || bll.Model.ApproveFlag == 1) { ErrorInfo = "销售单状态不允许执行此操作!"; return -1; }

            if (bll.Model.Supplier == 0) bll.Model.Supplier = DeliveryInfo.Supplier;
            if (bll.Model.Client == 0) bll.Model.Client = DeliveryInfo.Client;

            //如果有送货车辆,默认出货仓库为该车辆所关联仓库
            if (DeliveryInfo.DeliveryVehicle != 0 && DeliveryInfo.SupplierWareHouse == 0)
            {
                CM_Vehicle v = new CM_VehicleBLL(DeliveryInfo.DeliveryVehicle).Model;
                if (v == null) { ErrorInfo = "送货车辆无效!"; return -1; }

                DeliveryInfo.SupplierWareHouse = v.RelateWareHouse;
            }

            //默认业务人员为当前员工
            if (DeliveryInfo.SalesMan == 0) DeliveryInfo.SalesMan = User.StaffID;

            #region 必填字段校验
            if (bll.Model.Supplier == 0) { ErrorInfo = "无效的供货客户!"; return -2; }
            if (User.OwnerType == 3 && bll.Model.Supplier != User.ClientID) { ErrorInfo = "无效的供货客户!"; return -2; }
            if (bll.Model.Client == 0) { ErrorInfo = "无效的购买客户!"; return -2; }

            if (DeliveryInfo.SupplierWareHouse == 0) { ErrorInfo = "无效的供货仓库!"; return -2; }
            if (DeliveryInfo.Items == null || DeliveryInfo.Items.Count == 0) { ErrorInfo = "无销售产品明细!"; return -10; }
            #endregion

            #region 保存销售单头信息
            bll.Model.SalesMan = DeliveryInfo.SalesMan;
            bll.Model.DeliveryVehicle = DeliveryInfo.DeliveryVehicle;
            bll.Model.SupplierWareHouse = DeliveryInfo.SupplierWareHouse;
            bll.Model.WipeAmount = DeliveryInfo.WipeAmount;

            bll.Model.WorkList = DeliveryInfo.WorkList;
            bll.Model.Remark = DeliveryInfo.Remark;
            #endregion

            #region 循环处理每个订单明细
            foreach (Delivery.DeliveryDetail item in DeliveryInfo.Items)
            {
                if (item.Product == 0) continue;
                if (item.DeliveryQuantity <= 0 && item.SignInQuantity <= 0)
                {
                    if (item.DetailID == 0)
                        continue;
                    else
                        bll.DeleteDetail(item.DetailID);
                }

                string lotnumber = item.LotNumber.Trim();

                int quantity = 0;
                if (bll.Model.State == 1)
                    quantity = item.DeliveryQuantity == 0 ? item.SignInQuantity : item.DeliveryQuantity;
                else
                    quantity = item.SignInQuantity;

                string remark = item.Remark;

                PDT_ProductBLL productbll = new PDT_ProductBLL(item.Product);
                if (productbll.Model == null) { ErrorInfo = "无效产品项,产品ID:" + item.Product; return -11; }
                PDT_ProductExtInfo extinfo = productbll.GetProductExtInfo(bll.Model.Supplier);
                if (productbll.Model == null) { ErrorInfo = "产品不在销售商的经营目录中," + productbll.Model.FullName; return -11; }

                if (bll.Model.Classify != 2)
                {
                    //不为退货单时,判断车库存是否够销售
                    int inv_quantity = INV_InventoryBLL.GetProductQuantity(bll.Model.SupplierWareHouse, item.Product, lotnumber);
                    if (quantity > inv_quantity)
                    {
                        ErrorInfo = "产品[" + productbll.Model.FullName + "]库存不足,当前库存:" + inv_quantity.ToString();
                        return -11;
                    }
                }

                if (item.DetailID > 0)
                {
                    PBM_DeliveryDetail d = bll.GetDetailModel(item.DetailID);

                    if (bll.Model.State == 1) d.DeliveryQuantity = quantity;
                    d.SignInQuantity = item.SignInQuantity;
                    d.LotNumber = lotnumber;
                    d.Remark = item.Remark;
                    bll.UpdateDetail(d);
                }
                else
                {
                    #region 新增商品明细品项
                    PBM_DeliveryDetail d = new PBM_DeliveryDetail();

                    d.Product = item.Product;
                    d.LotNumber = lotnumber;
                    d.SalesMode = item.SalesMode == 0 ? 1 : item.SalesMode;     //默认为“销售”

                    d.Price = PDT_StandardPriceBLL.GetSalePrice(bll.Model.Client, bll.Model.Supplier, d.Product);
                    if (d.SalesMode == 1)
                        d.DiscountRate = (item.DiscountRate <= 0 || item.DiscountRate > 1) ? 1 : item.DiscountRate;
                    else
                        d.DiscountRate = 0;

                    d.ConvertFactor = productbll.Model.ConvertFactor == 0 ? 1 : productbll.Model.ConvertFactor;
                    d.DeliveryQuantity = item.DeliveryQuantity;
                    d.SignInQuantity = d.DeliveryQuantity;
                    d.Remark = item.Remark;

                    bll.AddDetail(d);
                    #endregion
                }
            }
            #endregion

            //计算折扣金额
            bll.Model.DiscountAmount = bll.Items.Sum(p => (1 - p.DiscountRate) *
                Math.Round(p.Price * p.ConvertFactor, 2) * p.SignInQuantity / p.ConvertFactor);

            //计算实际销售金额
            bll.Model.ActAmount = Math.Round((bll.Model.Classify == 2 ? -1 : 1) *
                bll.Items.Sum(p => p.DiscountRate * Math.Round(p.Price * p.ConvertFactor, 2) * p.SignInQuantity / p.ConvertFactor)
                - bll.Model.WipeAmount, 2);

            int ret = bll.Update();
            if (ret < 0) { ErrorInfo = "销售单保存失败!"; return ret; }

            return 0;
        }