{callout color="#ef4d4d"}
由于无法指定组织只能采取登录组织方式
{/callout}
dll名:AutoGenerateConfirmBillBPProxy
dll位置:C:\yonyou\U9V60\Portal\ApplicationServer\Libs\UFIDA.U9.AP.APBP.Agent.dll

            AutoGenerateConfirmBillBPProxy proxy = new AutoGenerateConfirmBillBPProxy();
            PayReqFundDocType payReqFundDocType = PayReqFundDocType.Finder.Find(string.Format("code = '{0}'","001"));
            PayReqFundDocType payReqFundDocType1 = PayReqFundDocType.Finder.Find(string.Format("code = '{0}'","002"));
            Entity.EntityList<PayReqFundHead> entityList = PayReqFundHead.Finder.FindAll(
                string.Format("DocStatus = 2 and DocumentType != '{1}' and DocumentType!= '{2}' and Org = {0}",
                    Context.LoginOrg.ID,payReqFundDocType.ID,payReqFundDocType1.ID));
            //string.Format("DocStatus = 1 and Org.Code = '10' and DocNo = '10-0012412200007'"));
            try {
                foreach (PayReqFundHead payReqFundHead in entityList) {
                    proxy.PayReqHeadKey = payReqFundHead.ID;
                    if (!string.IsNullOrEmpty(payReqFundHead.PayReqFundUses[0].OppAccBkAccount)) {
                        BankAccount bankAccount =
                            BankAccount.FindByCode(payReqFundHead.PayReqFundUses[0].OppAccBkAccount);
                        if (bankAccount != null) {
                            proxy.BankAccount = bankAccount.ID;
                        }
                        //proxy.SubBankAccount = bankAccount.PayBkSubAccount;
                    }
                    else {
                        logger.LogInfo("创建请款确认单失败:付款银行账户为空 : 单号:" + payReqFundHead.DocNo + "组织:"
                                       + payReqFundHead.Org.Code);
                        continue;
                    }

                    // CashAccount cashAccount =
                    //     CashAccount.Finder.Find(string.Format("code = '{0}'", "01090699000120109050014"));
                    // proxy.CashAccount = 0;
                    proxy.IsUnApprove = true;
                    proxy.IsCanInputInfo = false;
                    proxy.PayDate = payReqFundHead.ExpectPayDate;
                    AccountPeriod accountPeriod = AccountPeriod.Finder.Find(string.Format(
                        "Year = '{0}' and Month = '{1}'", DateTime.Now.Year, DateTime.Now.Month));
                    // 会计记账期间
                    proxy.PostPeriod = accountPeriod.ID;
                    proxy.PayCurrency = payReqFundHead.ReqFundAC.ID;
                    proxy.ERType = payReqFundHead.ERType.Value;
                    proxy.ExRate = payReqFundHead.PCToMCXR;
                    if (payReqFundHead.PayReqFundUses != null && payReqFundHead.PayReqFundUses.Count > 0 &&
                        payReqFundHead.PayReqFundUses[0].SttlMethod != null) {
                        proxy.SettlementMethod = payReqFundHead.PayReqFundUses[0].SttlMethod.ID;
                    }

                    proxy.Currency = payReqFundHead.ReqFundAC.ID;
                    //proxy.CashAccount = cashAccount.ID;
                    //proxy.BankReturnDate = payReqFundHead.PayReqFundUses[0].TradeDate;
                    //proxy.NoteNo = payReqFundHead.PayReqFundUses[0].NoteNo;
                    proxy.IsMerge = true;
                    proxy.ConfirmDate = DateTime.Now;
                    // if (payReqFundHead.PayReqFundUses[0].RFCashierCfmDate != null)
                    // {
                    //     proxy.ConfirmDate = payReqFundHead.PayReqFundUses[0].RFCashierCfmDate;
                    // }
                    // else
                    // {
                    //     proxy.ConfirmDate = DateTime.Now;
                    // }

                    proxy.PayReqHeadList = new List<long> {
                        payReqFundHead.ID
                    };
                    proxy.Do();
                }
            }
            catch (Exception e) {
                logger.LogError("创建请款确认单BP报错:\t\n" + e);
                throw new ApplicationException(e.Message);
            }


DLL:UFIDA.U9.ISV.Supplier.Agent.dll
DLL位置: C:\yonyou\U9V60\Portal\ApplicationServer\Libs\UFIDA.U9.ISV.Supplier.Agent.dll

            List<ISV.Supplier.SupplierDTOData> supplierDTOList = new List<ISV.Supplier.SupplierDTOData>();
            ISV.Supplier.SupplierDTOData supplierInfo = new ISV.Supplier.SupplierDTOData();
            supplierInfo.Code = model.data.supplier_no; //供应商编号
            supplierInfo.Name = model.data.enterprise_name; //供应商名称
            supplierInfo.Org =
                new CommonArchiveDataDTOData(Context.LoginOrg.ID, Context.LoginOrg.Code, Context.LoginOrg.Name);
            //supplierInfo.ContactObject = new CBO.Pub.Controller.CommonArchiveDataDTOData();
            //supplierInfo.ContactObject.Code = "";
            supplierInfo.DescFlexField = new DescFlexSegmentsData();
            supplierInfo.DescFlexField.PrivateDescSeg1 = model.data.contacts; //联系人
            supplierInfo.DescFlexField.PrivateDescSeg3 = model.data.phone_number; //移动电话
            supplierInfo.DescFlexField.PrivateDescSeg4 = model.data.enterprise_fax; //传真
            supplierInfo.DescFlexField.PrivateDescSeg6 = model.data.email_address; //邮件地址
            supplierInfo.DescFlexField.PrivateDescSeg7 = model.data.bank_name; //银行开户行
            supplierInfo.DescFlexField.PrivateDescSeg8 = model.data.bank_account; //银行汇款账号

            //状态是否生效
            supplierInfo.Effective = new EffectiveData();
            supplierInfo.Effective.IsEffective = true;
            supplierInfo.Effective.EffectiveDate = Convert.ToDateTime("2000-01-01");
            supplierInfo.Effective.DisableDate = Convert.ToDateTime("9999-12-31");

            supplierInfo.IsPriceListModify = true; //价目表可改
            supplierInfo.IsReceiptRuleEditable = true; // 收货原则可改
            supplierInfo.IsPaymentTermModify = true; // 付款条件可改
            supplierInfo.IsAPConfirmTermEditable = true; //立账条件可改

            // 收货原则
            RcvBy receiptRule = RcvBy.FindByCode("G1");
            if (receiptRule != null) {
                supplierInfo.ReceiptRule =
                    new CommonArchiveDataDTOData(receiptRule.ID, receiptRule.Code, receiptRule.Name);
            }

            //供应商分类、税组合、立账条件、付款条件要效验编码  lirh  2025-02-17
            if (!string.IsNullOrEmpty(model.data.supplier_classify_number)) {
                SupplierCategory suppcate = SupplierCategory.Finder.Find(string.Format(
                    "Org.ID='{0}' and Code='{1}'", Context.LoginOrg.ID.ToString(),
                    model.data.supplier_classify_number));
                if (suppcate != null) {
                    supplierInfo.Category = new CommonArchiveDataDTOData();
                    supplierInfo.Category.ID = suppcate.ID;
                    supplierInfo.Category.Code = suppcate.Code;
                    supplierInfo.Category.Name = suppcate.Name;
                }
                else {
                    throw new ApplicationException(string.Format("供应商分类编码:{0}在U9 系统不存在,请检查",
                        model.data.supplier_classify_number));
                }
            }

            if (!string.IsNullOrEmpty(model.data.tax_code)) {
                int index = model.data.tax_code.IndexOf('-');
                string result = index >= 0 ? model.data.tax_code.Substring(0, index) : model.data.tax_code;
                TaxSchedule tax = TaxSchedule.Finder.Find(string.Format("Code='{0}'", result));
                if (tax != null) {
                    supplierInfo.TaxSchedule = new CommonArchiveDataDTOData();
                    supplierInfo.TaxSchedule.ID = tax.ID;
                    supplierInfo.TaxSchedule.Code = tax.Code;
                    supplierInfo.TaxSchedule.Name = tax.Name;
                }
                else {
                    throw new ApplicationException(string.Format("税组合编码:{0}在U9 系统不存在,请检查", result));
                }
            }

            if (!string.IsNullOrEmpty(model.data.accounting_code)) {
                APAccrueTerm apterm = APAccrueTerm.Finder.Find(string.Format("Code='{0}' and Org.ID='{1}'",
                    model.data.accounting_code, Context.LoginOrg.ID.ToString()));
                if (apterm != null) {
                    supplierInfo.APConfirmTerm = new CommonArchiveDataDTOData();
                    supplierInfo.APConfirmTerm.ID = apterm.ID;
                    supplierInfo.APConfirmTerm.Code = apterm.Code;
                    supplierInfo.APConfirmTerm.Name = apterm.Name;
                }
                else {
                    throw new ApplicationException(string.Format("立账条件编码:{0}在U9 系统不存在,请检查",
                        model.data.accounting_code));
                }
            }

            if (!string.IsNullOrEmpty(model.data.pay_term)) {
                PayTerm parterm = PayTerm.Finder.Find(string.Format("Name='{0}' and Org.ID='{1}'",
                    model.data.pay_term, Context.LoginOrg.ID.ToString()));
                if (parterm != null) {
                    supplierInfo.PaymentTerm = new CommonArchiveDataDTOData();
                    supplierInfo.PaymentTerm.ID = parterm.ID;
                    supplierInfo.PaymentTerm.Code = parterm.Code;
                    supplierInfo.PaymentTerm.Name = parterm.Name;
                }
                else {
                    throw new ApplicationException(string.Format("付款条件编码:{0}在U9 系统不存在,请检查", model.data.pay_term));
                }
            }

            //(分类\付款条件\税组合\立账条件\)交易币种、固话、供应商地址、国税号、经营范围、简称未传值  lirh  2025-02-17
            //币种
            if (!string.IsNullOrEmpty(model.data.currency_type)) {
                Currency curry = Currency.Finder.Find(string.Format("Code='{0}'", model.data.currency_type));
                if (curry != null) {
                    supplierInfo.TradeCurrency = new CommonArchiveDataDTOData();
                    supplierInfo.TradeCurrency.ID = curry.ID;
                    supplierInfo.TradeCurrency.Code = curry.Code;
                    supplierInfo.TradeCurrency.Name = curry.Name;
                }
                else {
                    throw new ApplicationException(string.Format("交易币种编码:{0}在U9 系统不存在,请检查",
                        model.data.currency_type));
                }
            }

            //固话
            supplierInfo.DescFlexField.PrivateDescSeg2 = model.data.enterprise_tel; //
            //供应商地址
            supplierInfo.DescFlexField.PrivateDescSeg9 = model.data.address; //
            //国税号
            supplierInfo.StateTaxNo = model.data.credit_code;
            //经营范围
            supplierInfo.DescFlexField.PrivateDescSeg11 = model.data.enterprise_profiles; //
            //简称
            supplierInfo.ShortName = model.data.shorter_name;
            //成立日期

            supplierDTOList.Add(supplierInfo);
            BatchCreateSupplierByDTOSVProxy proxy = new BatchCreateSupplierByDTOSVProxy();
            proxy.SupplierDTOs = supplierDTOList;
            List<SupplierData> listResult = proxy.Do();

使用session修改
销售退货修改数量

private WMSResultDataDTOData ProcessReceivement(string docNo, RTNHeadData rtnHeadData) {
    var resultData = new WMSResultDataDTOData();
    Receivement receivement =
        Receivement.Finder.Find(string.Format("DocNo = '{0}' and Org = {1}", docNo, Context.LoginOrg.ID));
    if (receivement == null)
        throw new Exception("找不到销售退回收货单据,DocNo=" + docNo);
    foreach (RTNLineData rtnLineData in rtnHeadData.SoRcvLineList) {
        int docLineNo = int.Parse(rtnLineData.DocLineNo);
        decimal newQty = decimal.Parse(rtnLineData.Qty);
        using (Session session = Session.Open()) {
            for (var i = 0; i < receivement.RcvLines.Count; i++) {
                if (receivement.RcvLines[i].DocLineNo == docLineNo) {
                    _logger.LogInfo(string.Format("[退货处理] - 更新到货数量:DocNo={0}, LineNo={1}, 原数量={2}, 新数量={3}",
                        docNo, docLineNo, receivement.RcvLines[i].ArriveQtyTU, newQty));
                    //数量为0则删除该行
                    if (newQty == decimal.Zero) {
                        receivement.RcvLines.RemoveAt(i);
                        continue;
                    }

                    #region 我自己的

                    receivement.RcvLines[i].ArriveQtyTU = receivement.RcvLines[i].EyeballingQtyTU =
                        receivement.RcvLines[i].RcvQtyTU = Math.Round(Convert.ToDecimal(newQty), 4);
                    receivement.RcvLines[i].ArriveQtyPU = receivement.RcvLines[i].EyeballingQtyPU =
                        receivement.RcvLines[i].RcvQtyPU = Math.Round(Convert.ToDecimal(newQty), 4);
                    receivement.RcvLines[i].ArriveQtySU = receivement.RcvLines[i].EyeballingQtySU =
                        receivement.RcvLines[i].RcvQtySU = Math.Round(Convert.ToDecimal(newQty), 4);
                    receivement.RcvLines[i].ArriveQtyCU = receivement.RcvLines[i].EyeballingQtyCU =
                        receivement.RcvLines[i].RcvQtyCU = Math.Round(Convert.ToDecimal(newQty), 4);
                    receivement.RcvLines[i].ArriveQtyTBU = receivement.RcvLines[i].EyeballingQtyTBU =
                        receivement.RcvLines[i].RcvQtyTBU = 0;


                    //拒收数量
                    receivement.RcvLines[i].RejectQtyTU = Decimal.Zero;
                    receivement.RcvLines[i].RejectQtyTBU = Decimal.Zero;
                    receivement.RcvLines[i].RejectQtySU = Decimal.Zero;
                    receivement.RcvLines[i].RejectQtyPU = Decimal.Zero;
                    receivement.RcvLines[i].RejectQtyCU = Decimal.Zero;
                    //可立账数量
                    receivement.RcvLines[i].CanAPConfirmQtyTU = Math.Round(Convert.ToDecimal(newQty), 4);
                    receivement.RcvLines[i].CanAPConfirmQtyPU = Math.Round(Convert.ToDecimal(newQty), 4);
                    receivement.RcvLines[i].CanAPConfirmQtyCU = Math.Round(Convert.ToDecimal(newQty), 4);
                    receivement.RcvLines[i].CanAPConfirmQtySU = Math.Round(Convert.ToDecimal(newQty), 4);
                    receivement.RcvLines[i].CanAPConfirmQtyTBU = 0;
                    //退补数量
                    receivement.RcvLines[i].RtnFillQtySU = Decimal.Zero;
                    receivement.RcvLines[i].RtnFillQtyTBU = Decimal.Zero;
                    receivement.RcvLines[i].RtnFillQtyTU = Decimal.Zero;
                    receivement.RcvLines[i].RtnFillQtyPU = Decimal.Zero;
                    receivement.RcvLines[i].RtnFillQtyCU = Decimal.Zero;
                    //拒收价税合计
                    receivement.RcvLines[i].RejectMnyAC = Decimal.Zero;
                    receivement.RcvLines[i].RejectMnyFC = Decimal.Zero;
                    receivement.RcvLines[i].RejectMnyTC = Decimal.Zero;
                    //拒收未税金额
                    receivement.RcvLines[i].RejectNetMnyAC = Decimal.Zero;
                    receivement.RcvLines[i].RejectNetMnyTC = Decimal.Zero;
                    receivement.RcvLines[i].RejectNetMnyFC = Decimal.Zero;
                    //拒收税额
                    receivement.RcvLines[i].RejectTaxMnyAC = Decimal.Zero;
                    receivement.RcvLines[i].RejectTaxMnyTC = Decimal.Zero;
                    receivement.RcvLines[i].RejectTaxMnyFC = Decimal.Zero;

                    if (receivement.RcvLines[i].IsPriceIncludeTax == true) {
                        //未税金额 = 含税单价 × 数量 ÷(1 + 税率)
                        receivement.RcvLines[i].ArriveTotalNetMnyTC = Math.Round(
                            receivement.RcvLines[i].FinallyPriceTC * Convert.ToDecimal(newQty) /
                            (1 + receivement.RcvLines[i].TaxRate), 2);
                        //Math.Round(Convert.ToDecimal(arrqty) * receivement.RcvLines[i].FinallyPriceTC / (decimal.Parse(receivement.RcvLines[i].TaxRate.ToString())), 2);//实到未税额 
                        receivement.RcvLines[i].ArriveTotalNetMnyAC =
                            receivement.RcvLines[i].ArriveTotalNetMnyTC; //实到未税额 
                        receivement.RcvLines[i].ArriveTotalNetMnyFC =
                            receivement.RcvLines[i].ArriveTotalNetMnyTC; //实到未税额 
                        //
                        receivement.RcvLines[i].ArriveTotalTaxFC = Math.Round(
                            receivement.RcvLines[i].ArriveTotalNetMnyTC * receivement.RcvLines[i].TaxRate, 2);
                        //Math.Round(Convert.ToDecimal(arrqty) * receivement.RcvLines[i].FinallyPriceTC / (decimal.Parse(receivement.RcvLines[i].TaxRate.ToString())) * (decimal.Parse(receivement.RcvLines[i].TaxRate.ToString())), 2);//实到税额 
                        receivement.RcvLines[i].ArriveTotalTaxTC =
                            receivement.RcvLines[i].ArriveTotalTaxFC; //实到税额 
                        receivement.RcvLines[i].ArriveTotalTaxAC =
                            receivement.RcvLines[i].ArriveTotalTaxFC; //实到税额 

                        receivement.RcvLines[i].ArriveTotalMnyTC = receivement.RcvLines[i].ArriveTotalNetMnyTC +
                                                                   receivement.RcvLines[i]
                                                                       .ArriveTotalTaxFC; //实到价税合计 
                        receivement.RcvLines[i].ArriveTotalMnyAC =
                            receivement.RcvLines[i].ArriveTotalMnyTC; //实到价税合计 
                        receivement.RcvLines[i].ArriveTotalMnyFC =
                            receivement.RcvLines[i].ArriveTotalMnyTC; //实到价税合计 


                        //实收未税额
                        receivement.RcvLines[i].TotalNetMnyTC = Math.Round(
                            receivement.RcvLines[i].FinallyPriceTC * Convert.ToDecimal(newQty) /
                            (1 + receivement.RcvLines[i].TaxRate), 2);
                        receivement.RcvLines[i].TotalNetMnyAC = receivement.RcvLines[i].TotalNetMnyTC;
                        receivement.RcvLines[i].TotalNetMnyFC = receivement.RcvLines[i].TotalNetMnyTC;

                        //实收税额
                        receivement.RcvLines[i].TotalTaxFC = Math.Round(
                            (receivement.RcvLines[i].TotalNetMnyTC * receivement.RcvLines[i].TaxRate), 2);
                        receivement.RcvLines[i].TotalTaxAC = receivement.RcvLines[i].TotalTaxFC;
                        receivement.RcvLines[i].TotalTaxTC = receivement.RcvLines[i].TotalTaxFC;
                        //实收价税合计
                        receivement.RcvLines[i].TotalMnyTC = receivement.RcvLines[i].ArriveTotalNetMnyTC +
                                                             receivement.RcvLines[i].ArriveTotalTaxFC; //实到价税合计 
                        receivement.RcvLines[i].TotalMnyAC = receivement.RcvLines[i].TotalMnyTC;
                        receivement.RcvLines[i].TotalMnyFC = receivement.RcvLines[i].TotalMnyTC;
                    }
                    else {
                        //未税金额 = 含税单价 × 数量 ÷(1 + 税率)
                        receivement.RcvLines[i].ArriveTotalNetMnyTC =
                            Math.Round(receivement.RcvLines[i].FinallyPriceTC * Convert.ToDecimal(newQty), 2);
                        //Math.Round(Convert.ToDecimal(arrqty) * receivement.RcvLines[i].FinallyPriceTC / (decimal.Parse(receivement.RcvLines[i].TaxRate.ToString())), 2);//实到未税额 
                        receivement.RcvLines[i].ArriveTotalNetMnyAC =
                            receivement.RcvLines[i].ArriveTotalNetMnyTC; //实到未税额 
                        receivement.RcvLines[i].ArriveTotalNetMnyFC =
                            receivement.RcvLines[i].ArriveTotalNetMnyTC; //实到未税额 
                        //
                        receivement.RcvLines[i].ArriveTotalTaxFC = Math.Round(
                            receivement.RcvLines[i].ArriveTotalNetMnyTC * receivement.RcvLines[i].TaxRate, 2);
                        //Math.Round(Convert.ToDecimal(arrqty) * receivement.RcvLines[i].FinallyPriceTC / (decimal.Parse(receivement.RcvLines[i].TaxRate.ToString())) * (decimal.Parse(receivement.RcvLines[i].TaxRate.ToString())), 2);//实到税额 
                        receivement.RcvLines[i].ArriveTotalTaxTC =
                            receivement.RcvLines[i].ArriveTotalTaxFC; //实到税额 
                        receivement.RcvLines[i].ArriveTotalTaxAC =
                            receivement.RcvLines[i].ArriveTotalTaxFC; //实到税额 

                        receivement.RcvLines[i].ArriveTotalMnyTC = receivement.RcvLines[i].ArriveTotalNetMnyTC +
                                                                   receivement.RcvLines[i]
                                                                       .ArriveTotalTaxFC; //实到价税合计 
                        receivement.RcvLines[i].ArriveTotalMnyAC =
                            receivement.RcvLines[i].ArriveTotalMnyTC; //实到价税合计 
                        receivement.RcvLines[i].ArriveTotalMnyFC =
                            receivement.RcvLines[i].ArriveTotalMnyTC; //实到价税合计 


                        //实收未税额
                        receivement.RcvLines[i].TotalNetMnyTC =
                            Math.Round(receivement.RcvLines[i].FinallyPriceTC * Convert.ToDecimal(newQty), 2);
                        receivement.RcvLines[i].TotalNetMnyAC = receivement.RcvLines[i].TotalNetMnyTC;
                        receivement.RcvLines[i].TotalNetMnyFC = receivement.RcvLines[i].TotalNetMnyTC;

                        //实收税额
                        receivement.RcvLines[i].TotalTaxFC = Math.Round(
                            (receivement.RcvLines[i].TotalNetMnyTC * receivement.RcvLines[i].TaxRate), 2);
                        receivement.RcvLines[i].TotalTaxAC = receivement.RcvLines[i].TotalTaxFC;
                        receivement.RcvLines[i].TotalTaxTC = receivement.RcvLines[i].TotalTaxFC;
                        //实收价税合计
                        receivement.RcvLines[i].TotalMnyTC = receivement.RcvLines[i].ArriveTotalNetMnyTC +
                                                             receivement.RcvLines[i].ArriveTotalTaxFC; //实到价税合计 
                        receivement.RcvLines[i].TotalMnyAC = receivement.RcvLines[i].TotalMnyTC;
                        receivement.RcvLines[i].TotalMnyFC = receivement.RcvLines[i].TotalMnyTC;
                    }


                    if (receivement.RcvLines[i].RcvTaxs.Count > 0) {
                        foreach (RcvTax item2 in receivement.RcvLines[i].RcvTaxs) {
                            if (item2.TaxMnyType == UFIDA.U9.CBO.FI_SCM.DTOs.TaxMnyTypeEnum.ArriveTax) {
                                item2.TaxMnyTC = receivement.RcvLines[i].ArriveTotalTaxFC;
                                item2.TaxMnyAC = receivement.RcvLines[i].ArriveTotalTaxFC;
                                item2.TaxMnyFC = receivement.RcvLines[i].ArriveTotalTaxFC;
                            }
                        }

                        foreach (RcvTax item2 in receivement.RcvLines[i].RcvTaxs) {
                            if (item2.TaxMnyType == UFIDA.U9.CBO.FI_SCM.DTOs.TaxMnyTypeEnum.ReceiveTax) {
                                item2.TaxMnyTC = receivement.RcvLines[i].ArriveTotalTaxFC;
                                item2.TaxMnyAC = receivement.RcvLines[i].ArriveTotalTaxFC;
                                item2.TaxMnyFC = receivement.RcvLines[i].ArriveTotalTaxFC;
                            }
                        }
                    }

                    #endregion 我自己的
                    
                    // 修改存储地点
                    if (receivement.RcvLines[i].DocLineNo == docLineNo &&
                        receivement.RcvLines[i].Wh.Code != rtnLineData.WhCode) {
                        Warehouse warehouse = Warehouse.FindByCode(receivement.Org, rtnLineData.WhCode);
                        if (warehouse == null) {
                            throw new ApplicationException($"编码为:{rtnLineData.WhCode}的存储地点不存在");
                        }

                        receivement.RcvLines[i].Wh = warehouse;
                    }

                    if (receivement.RcvLines[i].Wh.IsBin) {
                        if (receivement.RcvLines[i].RcvLineLocations.Count > 0) {
                            Bin bin = Bin.Finder.Find(string.Format(
                                "Org.ID='{0}'  and Warehouse.Code='{1}' and Code = '{2}'",
                                Context.LoginOrg.ID.ToString(), receivement.RcvLines[i].Wh.Code, "A1"));
                            if (bin != null) {
                                receivement.RcvLines[i].RcvLineLocations[0].Location = bin;
                                receivement.RcvLines[i].RcvLineLocations[0].LocationQtySU =
                                    receivement.RcvLines[i].ArriveQtySU;
                                receivement.RcvLines[i].RcvLineLocations[0].LocationQtyTU =
                                    receivement.RcvLines[i].ArriveQtySU;
                            }
                        }
                        else {
                            Bin bin = Bin.Finder.Find(string.Format(
                                "Org.ID='{0}'  and Warehouse.Code='{1}' and Code = '{2}'",
                                Context.LoginOrg.ID.ToString(), receivement.RcvLines[i].Wh.Code, "A1"));

                            RcvLineLocation rcvbin = RcvLineLocation.Create(receivement.RcvLines[i]);
                            rcvbin.ItemInfo.ItemCode = receivement.RcvLines[i].ItemInfo.ItemCode;
                            rcvbin.CurrentOrg = Context.LoginOrg;
                            rcvbin.Location = new CBO.SCM.Bin.Bin();
                            rcvbin.Location = bin;
                            rcvbin.LocationQtySU = receivement.RcvLines[i].ArriveQtySU;
                            rcvbin.LocationQtyTU = receivement.RcvLines[i].ArriveQtySU;
                            receivement.RcvLines[i].Wh = bin.Warehouse;
                            receivement.RcvLines[i].RcvLineLocations.Add(rcvbin);
                        }
                    }
                    else {
                        if (receivement.RcvLines[i].RcvLineLocations.Count > 0) {
                            receivement.RcvLines[i].RcvLineLocations[0] = null;
                        }
                    }
                }
            }

            session.Commit();
        }
    }

    ApproveRCV(receivement);
    _logger.LogInfo("修改成功");
    resultData.Code = "200";
    resultData.Message = "成功";
    resultData.DocNo = docNo;
    return resultData;
}

采购退货修改数量

private WMSResultDataDTOData ProcessRtn(string docNo, RTNHeadData rtnHeadData) {
    var resultData = new WMSResultDataDTOData();
    Receivement rec =
        Receivement.Finder.Find(string.Format("DocNo = '{0}' and Org = {1}", docNo, Context.LoginOrg.ID));
    if (rec == null)
        throw new Exception("找不到采购退货单据,DocNo=" + docNo);

    foreach (RTNLineData rtnLineData in rtnHeadData.SoRcvLineList) {
        int rtnLineNo = int.Parse(rtnLineData.DocLineNo);
        decimal newQty = decimal.Parse(rtnLineData.Qty);
        using (Session session = Session.Open()) {
            foreach (RcvLine rcvLine in rec.RcvLines) {
                if (rcvLine.DocLineNo == rtnLineNo) {
                    _logger.LogInfo(string.Format("[退货处理] - 更新退货数量:DocNo={0}, LineNo={1}, 原数量={2}, 新数量={3}",
                        docNo,
                        rtnLineNo, rcvLine.RejectQtyTU, newQty));

                    #region 我自己的
                    rcvLine.ArriveQtyTU = rcvLine.EyeballingQtyTU = rcvLine.RcvQtyTU = Decimal.Zero;
                    rcvLine.ArriveQtyPU = rcvLine.EyeballingQtyPU = rcvLine.RcvQtyPU = Decimal.Zero;
                    rcvLine.ArriveQtySU = rcvLine.EyeballingQtySU = rcvLine.RcvQtySU = Decimal.Zero;
                    rcvLine.ArriveQtyCU = rcvLine.EyeballingQtyCU = rcvLine.RcvQtyCU = Decimal.Zero;
                    rcvLine.ArriveQtyTBU = rcvLine.EyeballingQtyTBU = rcvLine.RcvQtyTBU = 0;
                    if (rcvLine.RtnDeductQtyTU > 0) {
                        // 拒收数量
                        rcvLine.RejectQtyTU = Math.Round(Convert.ToDecimal(newQty), 4);
                        rcvLine.RejectQtyCU = Math.Round(Convert.ToDecimal(newQty), 4);
                        rcvLine.RejectQtyPU = Math.Round(Convert.ToDecimal(newQty), 4);
                        rcvLine.RejectQtySU = Math.Round(Convert.ToDecimal(newQty), 4);
                        rcvLine.RejectQtyTBU = 0;
                        rcvLine.RtnFillQtyTU = 0;
                        rcvLine.RtnFillQtyCU = 0;
                        rcvLine.RtnFillQtyPU = 0;
                        rcvLine.RtnFillQtySU = 0;
                        rcvLine.RtnFillQtyTBU = 0;
                        rcvLine.RtnDeductQtyTU = Math.Round(Convert.ToDecimal(newQty), 4);
                        rcvLine.RtnDeductQtyCU = Math.Round(Convert.ToDecimal(newQty), 4);
                        rcvLine.RtnDeductQtyPU = Math.Round(Convert.ToDecimal(newQty), 4);
                        rcvLine.RtnDeductQtySU = Math.Round(Convert.ToDecimal(newQty), 4);
                        rcvLine.RtnDeductQtyTBU = decimal.Zero;
                        // 价税合计
                        rcvLine.RejectMnyAC =
                            Math.Round(Math.Round(Convert.ToDecimal(newQty), 4) * rcvLine.FinallyPriceTC, 2);
                        rcvLine.RejectMnyFC =
                            Math.Round(Math.Round(Convert.ToDecimal(newQty), 4) * rcvLine.FinallyPriceTC, 2);
                        rcvLine.RejectMnyTC =
                            Math.Round(Math.Round(Convert.ToDecimal(newQty), 4) * rcvLine.FinallyPriceTC, 2);
                        // 未税金额 = 含税金额 / (1 + 税率)
                        rcvLine.RejectNetMnyAC = Math.Round(rcvLine.RejectMnyAC / (1 + rcvLine.TaxRate), 2);
                        rcvLine.RejectNetMnyFC = Math.Round(rcvLine.RejectMnyAC / (1 + rcvLine.TaxRate), 2);
                        rcvLine.RejectNetMnyTC = Math.Round(rcvLine.RejectMnyAC / (1 + rcvLine.TaxRate), 2);
                        // 税额 = 价税合计-未税金额
                        rcvLine.RejectTaxMnyAC = Math.Round(rcvLine.RejectMnyAC - rcvLine.RejectNetMnyAC, 2);
                        rcvLine.RejectTaxMnyFC = Math.Round(rcvLine.RejectMnyAC - rcvLine.RejectNetMnyAC, 2);
                        rcvLine.RejectTaxMnyTC = Math.Round(rcvLine.RejectMnyAC - rcvLine.RejectNetMnyAC, 2);


                        rcvLine.RtnDeductMnyTC = rcvLine.RejectMnyAC;
                        rcvLine.RtnDeductMnyFC = rcvLine.RejectMnyAC;
                        rcvLine.RtnDeductMnyAC = rcvLine.RejectMnyAC;

                        rcvLine.RtnDeductNetMnyTC = rcvLine.RejectNetMnyAC;
                        rcvLine.RtnDeductNetMnyFC = rcvLine.RejectNetMnyAC;
                        rcvLine.RtnDeductNetMnyAC = rcvLine.RejectNetMnyAC;


                        rcvLine.RtnDeductTaxAC = rcvLine.RejectTaxMnyAC;
                        rcvLine.RtnDeductTaxFC = rcvLine.RejectTaxMnyAC;
                        rcvLine.RtnDeductTaxTC = rcvLine.RejectTaxMnyAC;
                        if (rcvLine.RcvTaxs.Count > 0) {
                            foreach (RcvTax item2 in rcvLine.RcvTaxs) {
                                if (item2.TaxMnyType == UFIDA.U9.CBO.FI_SCM.DTOs.TaxMnyTypeEnum.RejectTax) {
                                    item2.TaxMnyTC = rcvLine.RejectTaxMnyAC;
                                    item2.TaxMnyAC = rcvLine.RejectTaxMnyAC;
                                    item2.TaxMnyFC = rcvLine.RejectTaxMnyAC;
                                }

                                if (item2.TaxMnyType == UFIDA.U9.CBO.FI_SCM.DTOs.TaxMnyTypeEnum.RtnDeductTax) {
                                    item2.TaxMnyTC = rcvLine.RejectTaxMnyAC;
                                    item2.TaxMnyAC = rcvLine.RejectTaxMnyAC;
                                    item2.TaxMnyFC = rcvLine.RejectTaxMnyAC;
                                }
                            }
                        }
                    }
                    else {
                        // 拒收数量
                        rcvLine.RejectQtyTU = Math.Round(Convert.ToDecimal(newQty), 4);
                        rcvLine.RejectQtyCU = Math.Round(Convert.ToDecimal(newQty), 4);
                        rcvLine.RejectQtyPU = Math.Round(Convert.ToDecimal(newQty), 4);
                        rcvLine.RejectQtySU = Math.Round(Convert.ToDecimal(newQty), 4);
                        rcvLine.RejectQtyTBU = 0;
                        rcvLine.RtnFillQtyTU = Math.Round(Convert.ToDecimal(newQty), 4);
                        rcvLine.RtnFillQtyCU = Math.Round(Convert.ToDecimal(newQty), 4);
                        rcvLine.RtnFillQtyPU = Math.Round(Convert.ToDecimal(newQty), 4);
                        rcvLine.RtnFillQtySU = Math.Round(Convert.ToDecimal(newQty), 4);
                        rcvLine.RtnFillQtyTBU = 0;
                        rcvLine.RtnDeductQtyTU = decimal.Zero;
                        rcvLine.RtnDeductQtyCU = decimal.Zero;
                        rcvLine.RtnDeductQtyPU = decimal.Zero;
                        rcvLine.RtnDeductQtySU = decimal.Zero;
                        rcvLine.RtnDeductQtyTBU = decimal.Zero;
                        // 价税合计
                        rcvLine.RejectMnyAC =
                            Math.Round(Math.Round(Convert.ToDecimal(newQty), 4) * rcvLine.FinallyPriceTC, 2);
                        rcvLine.RejectMnyFC =
                            Math.Round(Math.Round(Convert.ToDecimal(newQty), 4) * rcvLine.FinallyPriceTC, 2);
                        rcvLine.RejectMnyTC =
                            Math.Round(Math.Round(Convert.ToDecimal(newQty), 4) * rcvLine.FinallyPriceTC, 2);
                        // 未税金额 = 含税金额 / (1 + 税率)
                        rcvLine.RejectNetMnyAC = Math.Round(rcvLine.RejectMnyAC / (1 + rcvLine.TaxRate), 2);
                        rcvLine.RejectNetMnyFC = Math.Round(rcvLine.RejectMnyAC / (1 + rcvLine.TaxRate), 2);
                        rcvLine.RejectNetMnyTC = Math.Round(rcvLine.RejectMnyAC / (1 + rcvLine.TaxRate), 2);
                        // 税额 = 价税合计-未税金额
                        rcvLine.RejectTaxMnyAC = Math.Round(rcvLine.RejectMnyAC - rcvLine.RejectNetMnyAC, 2);
                        rcvLine.RejectTaxMnyFC = Math.Round(rcvLine.RejectMnyAC - rcvLine.RejectNetMnyAC, 2);
                        rcvLine.RejectTaxMnyTC = Math.Round(rcvLine.RejectMnyAC - rcvLine.RejectNetMnyAC, 2);
                        if (rcvLine.RcvTaxs.Count > 0) {
                            foreach (RcvTax item2 in rcvLine.RcvTaxs) {
                                if (item2.TaxMnyType == UFIDA.U9.CBO.FI_SCM.DTOs.TaxMnyTypeEnum.RejectTax) {
                                    item2.TaxMnyTC = rcvLine.RejectTaxMnyAC;
                                    item2.TaxMnyAC = rcvLine.RejectTaxMnyAC;
                                    item2.TaxMnyFC = rcvLine.RejectTaxMnyAC;
                                }
                            }
                        }
                    }


                    // 修改存储地点
                    if (rcvLine.DocLineNo == rtnLineNo &&
                        rcvLine.Wh.Code != rtnLineData.WhCode) {
                        Warehouse warehouse = Warehouse.FindByCode(rcvLine.CurrentOrg, rtnLineData.WhCode);
                        if (warehouse == null) {
                            throw new ApplicationException($"编码为:{rtnLineData.WhCode}的存储地点不存在");
                        }
                        rcvLine.Wh = warehouse;
                    }
                    if (rcvLine.Wh.IsBin) {
                        if (rcvLine.RcvLineLocations.Count > 0) {
                            Bin bin = Bin.Finder.Find(string.Format(
                                "Org.ID='{0}'  and Warehouse.Code='{1}' and Code = '{2}'",
                                Context.LoginOrg.ID.ToString(), rcvLine.Wh.Code, "A1"));
                            if (bin != null) {
                                rcvLine.RcvLineLocations[0].Location = bin;
                                rcvLine.RcvLineLocations[0].LocationQtySU = rcvLine.ArriveQtySU;
                                rcvLine.RcvLineLocations[0].LocationQtyTU = newQty;
                            }
                        }
                        else {
                            Bin bin = Bin.Finder.Find(string.Format(
                                "Org.ID='{0}'  and Warehouse.Code='{1}' and Code = '{2}'",
                                Context.LoginOrg.ID.ToString(), rcvLine.Wh.Code, "A1"));

                            RcvLineLocation rcvbin = RcvLineLocation.Create(rcvLine);
                            rcvbin.ItemInfo.ItemCode = rcvLine.ItemInfo.ItemCode;
                            rcvbin.CurrentOrg = Context.LoginOrg;
                            rcvbin.Location = new CBO.SCM.Bin.Bin();
                            rcvbin.Location = bin;
                            rcvbin.LocationQtySU = rcvLine.ArriveQtySU;
                            rcvbin.LocationQtyTU = newQty;
                            rcvLine.Wh = bin.Warehouse;
                            rcvLine.RcvLineLocations.Add(rcvbin);
                        }
                    }
                    else {
                        if (rcvLine.RcvLineLocations.Count > 0) {
                            rcvLine.RcvLineLocations[0] = null;
                        }
                    }
                }

                #endregion 我自己的
            }

            session.Commit();
        }
    }
}

✅ 1. 什么是 Swap?

Swap(交换空间) 是 Linux 系统中用于辅助物理内存(RAM)的一种虚拟内存。它在物理内存不足时,将部分数据临时存储在磁盘上的专用空间中,从而缓解内存压力,防止系统崩溃。

  • 物理内存(RAM): 系统主要运行数据的临时存储区域,速度快。
  • 交换空间(Swap): 当物理内存不足时,Linux 将部分数据换出到 Swap 中,释放 RAM 以供其他进程使用。

✅ 作用

  • 防止内存溢出:当内存不够时,使用 Swap 避免程序崩溃。
  • 支持休眠:休眠时,RAM 数据写入到 Swap 中。
  • 系统性能优化:适当的 Swap 可提高系统稳定性。

✅ 缺点

  • 速度慢:磁盘 I/O 速度远低于 RAM,频繁使用 Swap 会显著降低性能。
  • 磁盘磨损:在 SSD 上使用 Swap 可能会影响寿命。

🔥 2. 查看当前 Swap 信息

在 Linux 中,常用以下命令查看 Swap 使用情况:

# 查看 Swap 使用情况
free -h

# 查看 Swap 分区信息
swapon --show

# 查看 Swap 空间大小和使用率
cat /proc/swaps

# 使用 htop 查看内存和 Swap 信息
htop

✅ 示例输出

$ free -h
              total        used        free      shared  buff/cache   available
Mem:          7.8Gi       2.5Gi       4.3Gi       237Mi       1.0Gi       4.8Gi
Swap:         2.0Gi       512Mi       1.5Gi
  • total:总内存大小。
  • used:已使用的 Swap 空间。
  • free:可用 Swap 空间。

⚙️ 3. 创建 Swap 空间

如果你的系统没有 Swap 分区或想要扩展 Swap 空间,可以手动创建:

🛠️ 3.1 创建 Swap 文件

1️⃣ 创建一个新的 Swap 文件

sudo fallocate -l 2G /swapfile       # 创建 2G Swap 文件
# 如果 fallocate 不支持,可以使用 dd 命令
# sudo dd if=/dev/zero of=/swapfile bs=1M count=2048

2️⃣ 设置正确权限

sudo mkswap /swapfile

3️⃣ 格式化为 Swap 格式

sudo mkswap /swapfile

4️⃣ 启用 Swap 文件

sudo swapon /swapfile

5️⃣ 验证 Swap 状态

swapon --show

✅ 示例输出

NAME      TYPE      SIZE USED PRIO
/swapfile file        2G   0B   -2

6️⃣ 永久生效 将 Swap 文件添加到 /etc/fstab:

echo '/swapfile swap swap defaults 0 0' | sudo tee -a /etc/fstab

🛠️ 4. 调整 Swap 大小

如果你想扩展或缩小现有的 Swap 空间:

1️⃣ 禁用当前 Swap

sudo swapoff /swapfile

2️⃣ 调整 Swap 大小

sudo fallocate -l 4G /swapfile   # 扩展为 4G
sudo chmod 600 /swapfile
sudo mkswap /swapfile

3️⃣ 重新启用

sudo swapon /swapfile

⚙️ 5. 删除 Swap 空间

如果不再需要 Swap 文件,可以删除:

1️⃣ 禁用 Swap

sudo swapoff /swapfile

2️⃣ 移除配置 编辑 /etc/fstab 文件,删除相关行:

/swapfile swap swap defaults 0 0

3️⃣ 删除 Swap 文件

sudo rm /swapfile

🔧 6. 调优 Swap 设置

Linux 使用 swappiness 参数控制内核在内存不足时使用 Swap 的倾向:

  • 0:尽量避免使用 Swap,仅在 RAM 不足时使用。
  • 1-100:数值越大,越倾向于使用 Swap。

    • 一般服务器推荐值:10-30
    • 桌面系统推荐值:60

✅ 查看当前 swappiness

cat /proc/sys/vm/swappiness

✅ 临时修改 swappiness

sudo sysctl vm.swappiness=10

✅ 永久修改 swappiness 编辑 /etc/sysctl.conf:

sudo nano /etc/sysctl.conf

添加:

vm.swappiness=10

保存后生效:

sudo sysctl -p

📊 7. Swap 与性能优化建议

  • 服务器环境

    • Swap 文件大小:物理内存的 1~2 倍。
    • swappiness:10~30,减少对磁盘的依赖。
  • 桌面环境

    • Swap 文件大小:等于物理内存大小。
    • swappiness:60~80,保证内存溢出时不崩溃。
  • 特殊情况

    • 如果使用 SSD,尽量减少 Swap,以减少磁盘磨损。
    • 使用 ZRAM 压缩 Swap,提高性能:
    sudo apt install zram-tools
    sudo systemctl enable --now zramswap

✅ 8. 总结

  • Swap 是 Linux 系统在内存不足时使用的虚拟内存。
  • 你可以使用 Swap 分区或 Swap 文件。
  • 调整 swappiness 参数可优化系统性能。
  • 小心使用 Swap 于 SSD,避免频繁读写带来磁盘损耗。
  • 在性能敏感的服务器环境中,尽量减少 Swap 的使用。