public with sharing class NFM202Controller {

    public static boolean isRunning = false;
    public static String debug_msg = '';
    public static String status;
    
    public class AgencyInfo {
        public String agencyCode_1;
        public String agencyCode_2;
        public Decimal price;
    }

    public class Quotations_element {
        public NFMUtil.Monitoring Monitoring;
        public Quotation_element[] GeData;
    }

    public class Quotation_element {
        public String InquiryCode;
        public String Quote_Code;
        public String SalesPoint;
        public String Province;
        public String City;
        public String HPCode;
        public String OwnerDepartment;
        public String Trade;
        public Boolean SpecialLanhai;
        public Boolean GroupPurchase;
        public Boolean STMSPackage;
        // CHAN-BZD8M6 XHL Start
        public Boolean EnergyHost;//能量主机
        // CHAN-BZD8M6 XHL End
        public String SubmitUser;
        public String SalesMethod;
        public String SalesRoot;
        public String SpecialDealerCode;
        public String SpeciaDealerCode_2;
        public String SalesType;
        public String OwnerNo;
        public String DepartmentCode;
        public String OppCategory;
        public Decimal Cost;
        public Decimal Agent12Price;
        public String Situation;
        public String TransType;
        public Decimal ListPrice;
        public Decimal DealerFinalPrice;
        public Decimal ContractPrice;
        public String Authorized_DB_No;
        public Boolean Special170;
        public Boolean SpecialAohui;
        public String OrderType;     // 耗材订单类型
        public String TermContractNo;   // 协议编码
        // LHJ 多年保修 20190812 Start
        public Decimal ServicePrice;       // ServicePrice
        public String ContractPeriod;     // 保修期限
        public Boolean IfCancelGuarantee;   // 是否除掉多年保修
        // LHJ 多年保修 20190812 End
        public String SFDC_DataID;
        public Detail_element[] Items;
    //报价试算
        public ProductDetais[] ProductDetais; //报价试算行
        //20200810 ljh add start
        //public String IsCorrosion;
        //20200810 ljh add end
        //阿西赛多 wql 20210331
        public Boolean IsAcecide;

        // CHAN-C9P5WM 20211216 ssm 增加科室名 start
        public String DepartmentName;
        // CHAN-C9P5WM 20211216 ssm 增加科室名 end
    }

    public class Detail_element {
        public String ProductCode;
        public Decimal Quantity;
        public Decimal MasterPrice;
        public String RegistrationNo;
        public String ProductionCompany;
        public String SalesPackagingUnit_c;
        // LHJ 多年保修 20190812 Start
        public Decimal SerPrice;           // ServicePrice
        public String GuaranteeType;      // 保修类别
        public Decimal GuaranteePeriod;   // 保修年限
        // LHJ 多年保修 20190812 End
        // LHJ SWAG-C9F9P8  20211206 增加规格 Start
        public Decimal Packing;        // 产品规格
        public String GuaranteeTypePro;
        // LHJ SWAG-C9F9P8  20211206 增加规格 End
        // CHAN-C9P5WM 20211216 ssm 增加产品型号和产品名称 start
        public String ModelNo;
        public String productName;
        // CHAN-C9P5WM 20211216 ssm 增加产品型号和产品名称 end

        //lt 20220223 CHAN-CBW9FX 特殊交货期影响的对应  start
        public String DeliveryDate;
        //lt 20220223 CHAN-CBW9FX 特殊交货期影响的对应  end

    }

    /* 
     报价试算
    */
    public class ProductDetais{
        public String CID;                      //促销方案ID
        public String PriceStrategyType;       //策略类型
        public String ProductCode;              //产品编码（指OTｃｏｄｅ）
        public Decimal CXNum;                   //促销数量
        public Decimal OneCXPrice;              //单次促销方案价格
        public Decimal UseCount;                //使用次数
        public Decimal ContractPrice;            //合同价格
        public Decimal  DiscountRate;                            //折扣
    }

    /**
     * NFM202の送信処理
     *
     * @param iflog_Id           ログテーブルのId
     * @param oppIds             送信対象取引先
     * @param transTypeMap       1:第一次询价 2:第二次询价 
     */
    @future (callout=true)
    public static void callout(String iflog_Id, List<String> oppIds, Map<String, String> transTypeMap) {

        if (oppIds == null || oppIds.size() == 0) {
            return;
        }

        // MessageGroupNumber の取得
        List<BatchIF_Log__c> iflogList = [Select Id, Name, Log__c, ErrorLog__c from BatchIF_Log__c where Id = :iflog_Id];
        BatchIF_Log__c iflog = null;
        if (iflogList.size() > 0) {
            iflog = iflogList.get(0);
            iflog.ErrorLog__c = '';
        } else {
            // データ取れってないとは、rollbackされていることです
            return;
        }

        String logstr = iflog.Log__c + '\nNumberOfRecord=' + oppIds.size() + ' ';

        // Monitoringの設定
        Datetime nowDT = Datetime.now();
        String nowStr = nowDT.format('yyyyMMddHHmm');
        Quotations_element quotations = new Quotations_element();
        quotations.Monitoring = new NFMUtil.Monitoring();
        quotations.Monitoring.Tag                  = 'MSGH';
        quotations.Monitoring.Sender               = 'SFDC';
        quotations.Monitoring.Receiver             = 'SPO';
        quotations.Monitoring.MessageType          = 'NFM202';
        quotations.Monitoring.MessageGroupNumber   = iflog.Name;
        quotations.Monitoring.NumberOfRecord       = '' + oppIds.size();
        quotations.Monitoring.TransmissionDateTime = nowStr;
        quotations.Monitoring.Text = ''; 

        BatchIF_Log__c rowData = null;
        
        // BatchIF転送表 から、コード変換のMapを作成
        Map<String, String> transferMap = new Map<String, String>();
        List<BatchIF_Transfer__c> transferList = [select Table__c,
                                                         Column__c,
                                                         External_value__c,
                                                         Internal_value__c
                                                    from BatchIF_Transfer__c
                                                   where Dropped_Flag__c = false
                                                     and Table__c = 'Opportunity'];
        for (BatchIF_Transfer__c t : transferList) {
            transferMap.put(t.Column__c + t.Internal_value__c, t.External_value__c);
        }

        try {
            // 根据询价ID取得报价询价相关信息
            List<Opportunity> oppList = [select id,
                                          Estimation_No__c,
                                          Estimation_List_Price__c,
                                          Dealer_Final_Price_F__c,
                                          OCM_Agent1_Price__c,
                                          Agent1_Agent2_Price__c,
                                          Stocking_Price__c,
                                          Agency1__r.Management_Code__c,
                                          Agency2__r.Management_Code__c,
                                          Opportunity_No__c,
                                          SAP_Province__c,
                                          State__c,
                                          City__c,
                                          HP_Management_Code__c,
                                          Owner_Salesdepartment__c,
                                          Trade__c,
                                          Special_Opp_lanhai__c,
                                          Group_purchase_PCL__c,
                                          STMS_Package_Sale__c,
                                          EnergyHost__c,
                                          Sales_Method__c,
                                          Sales_Root__c,
                                          Direct_Separate__c,
                                          Owner_System__r.Employee_No__c,
                                          Account.Management_Code__c,
                                          Opportunity_Category__c,
                                          Opp_situation__c,
                                          Authorized_DB_No__c,
                                          Estimation_Id__c,
                                          If_Have_170__c,
                                          If_Have_AH__c,
                                          Opp_order_Type__c,
                                          Account.Term_Contract_No__c,
                                          // CHAN-BGZ394 start
                                          SalesdepartmentForecast__c,
                                          Account.Salesdepartment_Dept__c,
                                          // CHAN-BGZ394 end
                                          // LHJ 多年保修 20190627 Start
                                          multiYearWarranty__c,
                                          Gurantee_Period__c,
                                          //外贸多年保修 精琢技术 wql 2021/03/23 start
                                          DecideQuoteDate__c,
                                          //外贸多年保修 精琢技术 wql 2021/03/23 start
                                          // MultiYearWarrantyTotalPrice__c,
                                          // LHJ 多年保修 20190627 End
                                          //20200810 ljh 阿西赛多 add start
                                          Is_Corrosion__c,
                                          //20200810 ljh 阿西赛多 add end
                                          // CHAN-C9P5WM 20211216 ssm 增加科室名 start
                                          Department_Name__c,
                                          // CHAN-C9P5WM 20211216 ssm 增加科室名 end
                                          Account.RecordType.DeveloperName

                                    from  Opportunity
                                    where id in :oppIds];

            // 根据询价ID取得询价产品信息
            List<OpportunityLineItem> itemList = [select id, 
                                                         OpportunityId, 
                                                         ProductCode__c, 
                                                         Register_alleffective__c, 
                                                         UnitPrice__c, 
                                                         Product_ListPrice__c, 
                                                         PricebookEntry.Product2.ProduceCompany_F__c,
                                                         //生产企业 增加检索
                                                         PricebookEntry.Product2.ProduceCompany__c,
                                                         //生产企业 增加检索
                                                         PricebookEntry.Product2.SalesPackagingUnit_Chinese__c,
                                                         Item_Order__c,
                                                         PricebookEntry.Product2.Intra_Trade_Cost_RMB__c,
                                                         PricebookEntry.Product2.Foreign_Trade_Cost_US__c,
                                                         ListPrice__c,
                                                         // LHJ 多年保修 20190627 Start
                                                         latestServicePrice__c,
                                                         latestWarrantyType__c,
                                                         lastestGuaranteePeriod__c,
                                                         lastestIf_Cancel_Guarantee__c,
                                                         // LHJ 多年保修 20190627 End
                                                         Quantity ,
                                                         // CHAN-C9P5WM 20211216 ssm 增加科室名 start
                                                         Name__c,
                                                         Asset_Model_No__c,
                                                         // CHAN-C9P5WM 20211216 ssm 增加科室名 end
                                                         PricebookEntry.Product2.Packing_list_manual__c,
                                                         PricebookEntry.Product2.GuranteeType__c

                                                         //lt 20220223 CHAN-CBW9FX 特殊交货期影响的对应  start
                                                         ,DeliveryDate__c
                                                         //lt 20220223 CHAN-CBW9FX 特殊交货期影响的对应  end

                                                    from OpportunityLineItem 
                                                   where OpportunityId in :oppIds];
            
            Map<String, List<OpportunityLineItem>> oppIDMap = new Map<String, List<OpportunityLineItem>>();
            for (OpportunityLineItem oppItem : itemList) {
                if (!oppIDMap.containsKey(oppItem.OpportunityId)) {
                    oppIDMap.put(oppItem.OpportunityId, new List<OpportunityLineItem>());
                }
                oppIDMap.get(oppItem.OpportunityId).add(oppItem);
            }
            //报价试算 通过询价找到报价id，检索报价试算行 制作map start------------------------------------------
            //报价id list
            List<String>  quoIdList = new List<String>();
            Map<String,PromotionSalesProducts__c> promotionSalesMap = new Map<String,PromotionSalesProducts__c>();
            //报价试算产品行
            List<PromotionSalesProducts__c> psList =new List<PromotionSalesProducts__c>();
            //报价试算选择方案
            List<PromotionSales__c> promotionList =new List<PromotionSales__c>();
            //询价不为空
            if(oppList.size()>0){
                //根据询价找到报价id
                for(Opportunity opp1 : oppList){
                    if(opp1.Estimation_Id__c !=null){
                        quoIdList.add(opp1.Estimation_Id__c);
                    }

                }
                //报价id不为空 检索试算行
                if(quoIdList.size()>0){
                    /* 检索报价试算行的 id,促销方案，促销方案SPOid，促销方案分类，otcode，数量，经销商小计，使用次数，报价id */
                    psList  = [select id,PromotionSales__c,PromotionSales__r.PromotionHead__r.SpoId__c,PromotionSales__r.Category__c,Asset_Model_No__c,Quantity__c,AgencyUnitPrice__c,AgencySubtotal__c,UseCount__c,QuantityId__c,Product2__r.ProductCode,Product2__r.MDM_Model_No__c,PromotionNo__c,DiscountRate__c from PromotionSalesProducts__c where QuantityId__c in:quoIdList];
                    // if(psList.size()>0){
                    //     for (PromotionSalesProducts__c p : psList) {
                    //         promotionSalesMap.put(p.QuantityId__c,p);
                    //     }
                    // }
                    promotionList = [select id,contractPrice__c,itemCounts__c,PromotionHead__r.PromotionNo__c,PromotionHead__r.SpoId__c from PromotionSales__c where Quote__c in:quoIdList];
                }
            }
            //报价试算 通过询价找到报价id，检索报价试算行 制作map end--------------------------------------------
            // 取得当前操作用户
            String userId = UserInfo.getUserId();
            List<user> userList = [select Employee_No__c from user where id = :userId];
            String strEmpNo = '';
            if (!userList.isEmpty()) {
                strEmpNo = userList[0].Employee_No__c;
            } 
            //报价试算 start
            List<String> cateClass = new List<String>{'促销方案','一般产品', '经销商固定折扣'};
            Map<String, String> transferMapCU = new Map<String, String>();
            List<BatchIF_Transfer__c> transferListCU = [select Table__c,
                                                        Column__c,
                                                        External_value__c,
                                                        Internal_value__c
                                                        from BatchIF_Transfer__c
                                                        where Dropped_Flag__c = false
                                                                and Table__c = 'PromotionSales__c'];
            for (BatchIF_Transfer__c t : transferListCU) {
                transferMapCU.put(t.External_value__c,t.Internal_Value__c);
            }
            //构建map 促销方案、一般产品 传实际主数据数量  start
            Map<String,Decimal> PromotionMap = new Map<String,Decimal>();
            //构建map 促销方案、一般产品 传实际促销包价钱之和
            Map<String,Decimal> priceMap = new Map<String,Decimal>();
            if(psList.size()>0){
                List<String> PromotionNoList = new List<String>();

                for(PromotionSalesProducts__c psps : psList){
                    if(psps.PromotionNo__c!=null){
                        PromotionNoList.add(psps.PromotionNo__c);
                        //每一行小计/使用次数  =  小计之和/次数
                        Decimal dec = psps.AgencySubtotal__c/psps.UseCount__c;
                        if(priceMap.get(psps.PromotionNo__c)!=null){
                            Decimal decSum = dec+priceMap.get(psps.PromotionNo__c);
                            priceMap.put(psps.PromotionNo__c,decSum.setScale(2, RoundingMode.HALF_UP) );
                        }else{
                            priceMap.put(psps.PromotionNo__c, dec.setScale(2, RoundingMode.HALF_UP));
                        }
                    }
                }
                //构建map 促销方案、一般产品 传实际主数据数量  start
                if(PromotionNoList.size()>0){
                    List<PromotionProduct__c> ppList =[select id,PromotionHead__c,PromotionHead__r.PromotionNo__c,Quantity__c,Asset_Model_No__c from PromotionProduct__c where PromotionHead__r.PromotionNo__c in:PromotionNoList];
                    if(ppList.size()>0){
                        for(PromotionProduct__c pp :ppList){
                            PromotionMap.put(pp.PromotionHead__r.PromotionNo__c+pp.Asset_Model_No__c,pp.Quantity__c);
                        }
                    }
                }
                //构建map 促销方案、一般产品 传实际主数据数量  end
            }
            //构建map 促销方案、一般产品 传手输后的促销价格合计  start
            Map<String,Decimal> PromotionSaleMap = new Map<String,Decimal>();
            //构建map 促销方案、一般产品 新增传输字段
            Map<String,Decimal> PromotionSalePriceMap = new Map<String,Decimal>();

            if(promotionList.size()>0){
                for(PromotionSales__c promotion:promotionList){
                    if(promotion.contractPrice__c!=null &&promotion.itemCounts__c!=null){
                        Decimal rounded = promotion.contractPrice__c /Integer.valueOf(promotion.itemCounts__c);
                        PromotionSaleMap.put(promotion.PromotionHead__r.SpoId__c,rounded.setScale(2, RoundingMode.HALF_UP) );
                        PromotionSalePriceMap.put(promotion.PromotionHead__r.SpoId__c, promotion.contractPrice__c);
                    }
                }
            }
            //报价试算 end
            // データの設定
            quotations.GeData = new List<Quotation_element>();

            for (Opportunity opp : oppList) {
                logstr += '询价区分：' + transTypeMap.get(opp.id) + '\n';
                List<AgencyInfo> agencyList = new List<AgencyInfo>();
                AgencyInfo agencyInfo = new AgencyInfo();

                //外贸多年保修 精琢技术 wql 2021/03/23 start
                //上线前decide的询价标识
                Boolean oldDecideDateUSD = false;
                //已经decide 并且在上线前decide
                if(opp.DecideQuoteDate__c== null ||(opp.DecideQuoteDate__c!= null &&opp.DecideQuoteDate__c < Date.valueOf(Label.GuaranteeUSD)&&opp.Trade__c == '外貿')){
                    oldDecideDateUSD = true;
                }else{
                    oldDecideDateUSD = false;
                }
                //外贸多年保修 精琢技术 wql 2021/03/23 end

                // 经销商1的金额设置到MAP
                agencyInfo.agencyCode_1 = opp.Agency1__r.Management_Code__c; 
                agencyInfo.agencyCode_2 = opp.Agency2__r.Management_Code__c;   
                agencyInfo.price = opp.OCM_Agent1_Price__c;
                agencyList.add(agencyInfo);

                for (AgencyInfo agency: agencyList) {

                    Quotation_element quotation = new Quotation_element();
                    quotations.GeData.add(quotation);

                    logstr += opp.Opportunity_No__c + '\n' ;

                    // 将询价报价信息设置到rowdate中
                    quotation.SFDC_DataID = opp.ID;
                    quotation.TransType = transTypeMap.get(opp.id);               // 询价区分
                    quotation.InquiryCode = opp.Opportunity_No__c;    // 询价编码
                    quotation.Quote_Code = opp.Estimation_No__c;                       // 报价编码
                    quotation.SalesPoint = opp.SAP_Province__c;   // SAP上传省
                    quotation.Province = opp.State__c;                // 省份
                    quotation.City = opp.City__c;                     // 市/地区
                    quotation.HPCode = opp.HP_Management_Code__c;     // 医院代码
                    quotation.SubmitUser = strEmpNo;                // 授权提交人
                    if (opp.Account.RecordType.DeveloperName == 'AgencyContract') {
                        quotation.TermContractNo = opp.Account.Term_Contract_No__c;
                    }
                    quotation.OrderType = opp.Opp_order_Type__c; // 耗材订单类型
                    quotation.OwnerDepartment = opp.Owner_Salesdepartment__c;     // 询价所有人本部
                    // CHAN-BGZ394 销售本部（预测）为能量时, 上传客户所在省本部 start
                    if(opp.SalesdepartmentForecast__c!= null &&
                      opp.SalesdepartmentForecast__c.equals('7.能量') &&
                      opp.Account.Salesdepartment_Dept__c != ''){
                        quotation.OwnerDepartment =
                        opp.Account.Salesdepartment_Dept__c;
                    }
                    // CHAN-BGZ394 销售本部（预测）为能量时, 上传客户所在省本部 end
                    quotation.SpecialLanhai = opp.Special_Opp_lanhai__c;        // 蓝海询价
                    quotation.GroupPurchase = opp.Group_purchase_PCL__c;        // 集中采购课负责的询价
                    // LHJ 取消能量 - 全部设为false Start
                    if (transTypeMap.get(opp.id) == '1') {
                      quotation.STMSPackage = opp.STMS_Package_Sale__c;// 授权时能量打包
                      // CHAN-BZD8M6 XHL Start
                      quotation.EnergyHost = opp.EnergyHost__c; // 授权时能量主机
                      // CHAN-BZD8M6 XHL End
                    } else {
                      quotation.STMSPackage = false;         // 合同申请时能量打包为false
                      // CHAN-BZD8M6 XHL Start
                      quotation.EnergyHost = false; // 合同申请时能量主机为false
                      // CHAN-BZD8M6 XHL End
                    }
                    //quotation.STMSPackage = false;         // 能量打包
                    // LHJ 取消能量 - 全部设为false End
                    quotation.SalesMethod = opp.Sales_Method__c;              // 招标方式
                    quotation.SalesType = opp.Direct_Separate__c;           // 销售渠道 经销商/OCM直接销售
                    quotation.OwnerNo = opp.Owner_System__r.Employee_No__c;                   // SFDC担当人
                    quotation.DepartmentCode = opp.Account.Management_Code__c;   // 客户管理编码(科室代码)
                    quotation.OppCategory = NFMUtil.getMapValue(transferMap, 
                            'Opportunity_Category__c', opp.Opportunity_Category__c, iflog);  // 战略科室(对应SFDC的GBIC分类.转送表IF)
                    quotation.SalesRoot = NFMUtil.getMapValue(transferMap, 
                            'Sales_Root__c__SPO', opp.Sales_Root__c, iflog);  // 销售途径（直销/分销）
                    quotation.Trade = NFMUtil.getMapValue(transferMap, 
                            'Trade__c', opp.Trade__c, iflog);                   // 内贸/外贸

                    // 报价
                    quotation.SpecialDealerCode = agency.agencyCode_1;              // 经销商CODE
                    quotation.SpeciaDealerCode_2 = agency.agencyCode_2;              // 二级经销商CODE
                    quotation.DealerFinalPrice = opp.Dealer_Final_Price_F__c; // 最终用户成交价格
                    quotation.Agent12Price = opp.Agent1_Agent2_Price__c;       // 一级经销商和二级经销商之间的价格
                    quotation.Authorized_DB_No = opp.Authorized_DB_No__c;  // DB授权编码
                    quotation.Special170 = opp.If_Have_170__c;  //包含170
                    quotation.SpecialAohui = opp.If_Have_AH__c;  // 包含奥辉
                    // LHJ 多年保修 20190627 Start
                    //外贸多年保修 精琢技术 wql 2021/03/23 start
                    // if(!oldDecideDateUSD){
                      quotation.IfCancelGuarantee = opp.multiYearWarranty__c;
                      quotation.ContractPeriod = opp.Gurantee_Period__c;
                    // }else{
                    //   quotation.IfCancelGuarantee = false;
                    //   quotation.ContractPeriod = null;

                    // }
                    //外贸多年保修 精琢技术 wql 2021/03/23 end
                    // LHJ 多年保修 20190627 End
                    //阿西赛多
                    quotation.IsAcecide = opp.Is_Corrosion__c;

                    // CHAN-C9P5WM 20211216 ssm 增加科室名 start
                    quotation.DepartmentName = opp.Department_Name__c;
                    // CHAN-C9P5WM 20211216 ssm 增加科室名 end

                    // 产品
                    List<OpportunityLineItem> oppLineList = oppIDMap.get(opp.id);
                    quotation.Items = new List<Detail_element>();

                    //报价试算 start 授权不需要传---------------------------------------------------------
                    if(transTypeMap.get(opp.id).equals('2')){
                        quotation.ProductDetais = new List<ProductDetais>();
                        if(psList.size()>0){
                            for(PromotionSalesProducts__c psp : psList){
                                //如果是同一个报价
                                if(opp.Estimation_Id__c.equals(psp.QuantityId__c)){
                                    ProductDetais dqe = new ProductDetais();
                                    quotation.ProductDetais.add(dqe);

                                    
                                    //是否需要处理SFDC系统的SPOID后，传给SPO
                                    //截取id部分
                                    // Pattern p = Pattern.compile('([\u0800-\u9fa5()（）]+)');
                                    // Matcher pm = p.matcher(dqe.CID);
                                    // if( pm.find() ){
                                    //     system.debug('123');
                                    //     dqe.CID = dqe.CID.replace(pm.group(0),'');
                                    // }
                                    //策略类型
                                    dqe.PriceStrategyType = psp.PromotionSales__r.Category__c;
                                    
                                    if(!cateClass.contains(psp.PromotionSales__r.Category__c)&&psp.PromotionSales__r.Category__c!=null){
                                        dqe.CID = transferMapCU.get(psp.PromotionSales__r.Category__c);
                                        dqe.PriceStrategyType = '一般固定折扣';
                                         //一般固定折扣 传实际值
                                        dqe.CXNum =psp.Quantity__c;
                                        //一般折扣 传小计
                                        dqe.OneCXPrice =psp.AgencySubtotal__c;
                                        // 外贸场合直接传美元 Start
                                        // if(opp.Trade__c == '外貿'){
                                        //     dqe.OneCXPrice =psp.AgencySubtotal__c*Decimal.valueOf(Label.Account_Exc);
                                        // }
                                        // 外贸场合直接传美元 End
                                        //使用的折扣
                                        dqe.DiscountRate = psp.DiscountRate__c;
                                        
                                    }else if(psp.PromotionSales__r.Category__c ==null){
                                        dqe.CID = '';
                                         //分类为空也传实际值
                                        dqe.CXNum =psp.Quantity__c;
                                    }
                                    else{
                                        //促销方案ID
                                        dqe.CID =psp.PromotionSales__r.PromotionHead__r.SpoId__c;
                                        if(psp.PromotionSales__r.Category__c=='促销方案'||psp.PromotionSales__r.Category__c=='一般产品'){
                                            if(PromotionMap!=null){
                                               //一般产品和促销方案选择主数据上值
                                               dqe.CXNum =PromotionMap.get(psp.PromotionNo__c+psp.Asset_Model_No__c);
                                               if(dqe.CXNum==null){
                                                dqe.CXNum =PromotionMap.get(psp.PromotionNo__c+psp.Product2__r.MDM_Model_No__c );
                                               }
                                               //单次促销方案价格
                                            //    dqe.OneCXPrice =PromotionSaleMap.get(psp.PromotionSales__r.PromotionHead__r.SpoId__c);
                                                if(priceMap.get(psp.PromotionNo__c)!=null){
                                                    dqe.OneCXPrice =priceMap.get(psp.PromotionNo__c);
                                                }
                                               dqe.ContractPrice =PromotionSalePriceMap.get(psp.PromotionSales__r.PromotionHead__r.SpoId__c);
                                               // 外贸场合直接传美元 Start
                                               // if(opp.Trade__c == '外貿'){
                                               //  // dqe.OneCXPrice =PromotionSaleMap.get(psp.PromotionSales__r.PromotionHead__r.SpoId__c)*Decimal.valueOf(Label.Account_Exc);
                                               //  if(priceMap.get(psp.PromotionNo__c)!=null){
                                               //      dqe.OneCXPrice =priceMap.get(psp.PromotionNo__c)*Decimal.valueOf(Label.Account_Exc);
                                               //  }
                                               //  dqe.ContractPrice =PromotionSalePriceMap.get(psp.PromotionSales__r.PromotionHead__r.SpoId__c)*Decimal.valueOf(Label.Account_Exc);
                                               // }
                                               // 外贸场合直接传美元 End
                                           }
                                        }else{
                                            //特约经销商 传实际值
                                            dqe.CXNum =psp.Quantity__c;
                                            //使用的折扣
                                            dqe.DiscountRate = psp.DiscountRate__c;
                                            //特约经销商 传小计
                                            dqe.OneCXPrice =psp.AgencySubtotal__c;
                                            // 外贸场合直接传美元 Start
                                            // if(opp.Trade__c == '外貿'){
                                            //     dqe.OneCXPrice =psp.AgencySubtotal__c*Decimal.valueOf(Label.Account_Exc);
                                            // }
                                            // 外贸场合直接传美元 End
                                        }
                                        
                                    }
                                    //产品编码
                                    dqe.ProductCode = psp.Product2__r.ProductCode;
                                    
                                    //使用次数
                                    dqe.UseCount =psp.UseCount__c;
                                }
                            }
                        }
                    }
                    //报价试算 end 授权不需要传---------------------------------------------------------
                    
                    Decimal Con_price = 0.00;
                    Decimal Cost_price = 0.00;
                    Decimal List_price = 0.00;
                    Decimal Cost_line = 0.00;
                    Decimal Service_Line = 0.00;
                    Boolean CancelFlg = false;
                    for (OpportunityLineItem oppLine : oppLineList) {

                        Detail_element detail = new Detail_element();
                        quotation.Items.add(detail);
                        // 产品OTCode
                        detail.ProductCode = oppLine.ProductCode__c;  // 产品编码（指OTCode）;
                        // 数量
                        detail.Quantity = oppLine.Quantity;

                        //lt 20220223 CHAN-CBW9FX 特殊交货期影响的对应   交货期 start 
                        detail.DeliveryDate = oppLine.DeliveryDate__c;
                        //lt 20220223 CHAN-CBW9FX 特殊交货期影响的对应  end

                        // LHJ SWAG-C9F9P8  20211206 增加规格 Start
                        // 规格
                        detail.Packing = oppLine.PricebookEntry.Product2.Packing_list_manual__c;
                        detail.GuaranteeTypePro = oppLine.PricebookEntry.Product2.GuranteeType__c;
                        // LHJ SWAG-C9F9P8  20211206 增加规格 End
                        // List价
                        detail.MasterPrice = oppLine.Product_ListPrice__c;
                        // 注册证号
                        if (String.isBlank(oppLine.Register_alleffective__c)) {
                            detail.RegistrationNo = 'FYL';
                        } else {
                            detail.RegistrationNo = oppLine.Register_alleffective__c;
                        }
                        //生产企业 WLIG-BZ699Z 精琢技术 wql 2021/03/19 start
                        //生产企业 注释源代码
                        // 生产企业
                        //detail.ProductionCompany = oppLine.PricebookEntry.Product2.ProduceCompany_F__c;
                        if(oppLine.PricebookEntry.Product2.ProduceCompany__c !=null){
                          detail.ProductionCompany = getProduceCompanyName(oppLine.PricebookEntry.Product2.ProduceCompany__c);
                        }
                        //生产企业 WLIG-BZ699Z 精琢技术 wql 2021/03/19 end
                        // 产品单位
                        if (oppLine.Item_Order__c != null
                                && String.isblank(oppLine.PricebookEntry.Product2.SalesPackagingUnit_Chinese__c)) {
                            detail.SalesPackagingUnit_c = '件';
                        } else {
                            detail.SalesPackagingUnit_c = oppLine.PricebookEntry.Product2.SalesPackagingUnit_Chinese__c;
                        }
                        // 合同金额
                        Con_price += oppLine.Quantity * oppLine.UnitPrice__c;
                        // 成本金额
                        if (opp.Trade__c == '外貿') {
                            Cost_line = (oppLine.PricebookEntry.Product2.Foreign_Trade_Cost_US__c == null) ? 0 : oppLine.PricebookEntry.Product2.Foreign_Trade_Cost_US__c;
                        } else {
                            Cost_line = (oppLine.PricebookEntry.Product2.Intra_Trade_Cost_RMB__c == null) ? 0 : oppLine.PricebookEntry.Product2.Intra_Trade_Cost_RMB__c;
                        }
                        Cost_price += oppLine.Quantity * Cost_line;
                        List_price += oppLine.Quantity * oppLine.Product_ListPrice__c;

                        //外贸多年保修 精琢技术 wql 2021/03/23 start
                        //保修年限 外贸多年保修 字段里做4.1切换 
                        detail.GuaranteePeriod = oppLine.lastestGuaranteePeriod__c;
                        if(!oldDecideDateUSD){
                              // LHJ 多年保修 20190627 Start
                              Service_Line += oppLine.Quantity * oppLine.latestServicePrice__c  ;
                              detail.SerPrice = oppLine.latestServicePrice__c;
                              detail.GuaranteeType = oppLine.latestWarrantyType__c;
                              detail.GuaranteePeriod = oppLine.lastestGuaranteePeriod__c;
                              if(oppLine.lastestIf_Cancel_Guarantee__c == true){
                                  CancelFlg = true;
                              }
                        // LHJ 多年保修 20190627 End
                        }else{
                              //外贸多年保未上线前  传0
                              Service_Line = 0;
                              //外贸多年保未上线前 传0
                              detail.SerPrice = 0;
                              //外贸多年保未上线前 传null
                              detail.GuaranteeType=null;
                              //detail.GuaranteePeriod = null;
                              CancelFlg = false;
                        }
                        
                        //外贸多年保修 精琢技术 wql 2021/03/23 end

                        // CHAN-C9P5WM 20211216 ssm 增加产品型号和产品名称 start
                        String nowName = oppLine.Name__c != null && !''.equals(oppLine.Name__c) ? oppLine.Name__c : '';
                        detail.ModelNo = '';
                        detail.productName = nowName;
                        if (oppLine.Asset_Model_No__c == 'N/A'){
                            detail.ModelNo = '';
                        } else if (nowName.indexOf(':') >= 0) {
                            detail.ModelNo = nowName.subString(0, nowName.indexOf(':'));
                            detail.productName = nowName.subString(nowName.indexOf(':') + 1);
                        } else if (nowName.indexOf('：') >= 0) {
                            detail.ModelNo = nowName.subString( 0, nowName.indexOf('：'));
                            detail.productName = nowName.subString( nowName.indexOf('：') + 1);
                        }
                        // CHAN-C9P5WM 20211216 ssm 增加产品型号和产品名称 end
                    }
                    if (String.IsNotBLank(opp.Estimation_Id__c) && opp.Estimation_Id__c.startsWith('a2K')) {
                        // 消耗品
                        quotation.ContractPrice = Con_price;  // 合同金额
                    } else {
                        quotation.ContractPrice = (agency.price == null) ? opp.Dealer_Final_Price_F__c : agency.price ;
                    }
                    // LHJ 多年保修  Start
                    //quotation.IfCancelGuarantee = CancelFlg;
                    // LHJ 多年保修  End

                    quotation.Cost = Cost_price;            // Cost成本（总价）
                    quotation.ListPrice = List_price;      // List Price公开价（总价）
                    quotation.ServicePrice = Service_Line;    // ServicePrice
                }   
            }
            if (quotations.GeData.size() > 0) {
                        
                NFMUtil.Monitoring Monitoring   = new NFMUtil.Monitoring();
                Monitoring.Tag                  = quotations.Monitoring.Tag;
                Monitoring.Sender               = quotations.Monitoring.Sender;
                Monitoring.Receiver             = quotations.Monitoring.Receiver;
                Monitoring.MessageType          = quotations.Monitoring.MessageType;
                Monitoring.MessageGroupNumber   = quotations.Monitoring.MessageGroupNumber;
                Monitoring.NumberOfRecord       = quotations.Monitoring.NumberOfRecord;
                Monitoring.TransmissionDateTime = quotations.Monitoring.TransmissionDateTime;
                Monitoring.Text = '';
                
                rowData = NFMUtil.makeRowData(Monitoring, 'NFM202', quotations);
                execute(rowData, iflog);
            } 
            logstr +='Status:' + status;
            logstr += '\n end';

        } catch (Exception ex) {
            // エラーが発生した場合
            System.debug(Logginglevel.ERROR, 'NFM202_' + iflog.Name + ':' + ex.getMessage());
            System.debug(Logginglevel.ERROR, 'NFM202_' + iflog.Name + ':' + ex.getStackTraceString());
            logstr += ex.getMessage();
            iflog.ErrorLog__c += ex.getMessage() + '\n';
            iflog.ErrorLog__c += ex.getStackTraceString() + '\n';
        }

        if (rowData != null) {
            upsert rowData;
        }

        System.debug(Logginglevel.DEBUG, 'NFM202_' + iflog.Name + ' end');
        iflog.Log__c = logstr;
        upsert iflog;
    }

    public static void execute(BatchIF_Log__c rowData, BatchIF_Log__c iflog) {

        Integer batch_retry_max_cnt = Integer.valueOf(System.Label.batch_retry_max_cnt);
        String rowDataStr = NFMUtil.getRowDataStr(rowData);
        Quotations_element quotations = (Quotations_element) JSON.deserialize(rowDataStr, Quotations_element.class);

        String logstr = quotations.Monitoring.MessageGroupNumber + ' start\n';
        Boolean needUpdateIflog = false;
        
        if  (iflog == null) {
            needUpdateIflog = true;
            iflog = new BatchIF_Log__c();
            iflog.Type__c = 'NFM202';
            iflog.MessageGroupNumber__c = quotations.Monitoring.MessageGroupNumber;
            iflog.Log__c = logstr;
            iflog.ErrorLog__c = '';
            //insert iflog;
            //iflog = [Select Id, Name, Log__c, ErrorLog__c from BatchIF_Log__c where Id = :iflog.Id];
        } else {
            logstr = iflog.Log__c;
        }

        try{
            // 向SPO送信
            // NFMUtil.sendToSpo(rowDataStr, NFMUtil.NFM202_ENDPOINT);
            status = NFMUtil.sendToSpoRet(rowDataStr, NFMUtil.NFM202_ENDPOINT);
            if (status == 'OK') {
                rowData.retry_cnt__c=0;
            } else {
                // 20210602 CHAN-C3JCLN start
                Http http = new Http();
                HttpRequest req = new HttpRequest();
                HTTPResponse res;
                String resb;

                req.setEndpoint('http://cbpr.olympuschina.com/conn.html');
                req.setMethod('GET');
                res = http.send(req);
                resb = res.getBody();
                status += '\nconn StatusCode:'+ res.getStatusCode() 
                + '\nconn status:' +  res.getStatus()  ;
                 // 20210602 CHAN-C3JCLN end
                if (rowData.retry_cnt__c == null) rowData.retry_cnt__c = 0;
                if (rowData.retry_cnt__c < batch_retry_max_cnt) {
                    rowData.retry_cnt__c++;
                    LogAutoSendSchedule.assignOneMinute();
                }
                if (rowData.retry_cnt__c >= batch_retry_max_cnt) {
                    rowData.ErrorLog__c = status+'错误次数已经超过自动送信设定的最大次数，请手动送信';
                }
            }
        } catch (Exception ex) {
            // TODO IOException
            // エラーが発生した場合
            System.debug(Logginglevel.ERROR, 'NFM001_' + iflog.Name + ':' + ex.getMessage());
            System.debug(Logginglevel.ERROR, 'NFM001_' + iflog.Name + ':' + ex.getStackTraceString());
            logstr += ex.getMessage();
            // 20210602 CHAN-C3JCLN start
            Http http = new Http();
            HttpRequest req = new HttpRequest();
            HTTPResponse res;
            String resb;

            req.setEndpoint('http://cbpr.olympuschina.com/conn.html');
            req.setMethod('GET');
            try{
            res = http.send(req);
            }catch (Exception ex1) {}
            status += res == null? '11':( '\nconn StatusCode:'+ res.getStatusCode() 
            + '\nconn status:' +  res.getStatus()+'\n');
            // 20210602 CHAN-C3JCLN end
            iflog.ErrorLog__c += status + ex.getMessage() + '\n';
            iflog.ErrorLog__c += ex.getStackTraceString() + '\n';

            //---Gaozw---add
            if (rowData.retry_cnt__c == null) rowData.retry_cnt__c = 0;
            if (rowData.retry_cnt__c < batch_retry_max_cnt) {
                rowData.retry_cnt__c++;
                LogAutoSendSchedule.assignOneMinute();
            }
            if (rowData.retry_cnt__c >= batch_retry_max_cnt) {
                rowData.ErrorLog__c = ex.getMessage() + '\n' + ex.getStackTraceString() + '\n' + rowData.ErrorLog__c+'错误次数已经超过自动送信设定的最大次数，请手动送信';
            }
        }
        iflog.Log__c = logstr;
        System.debug('logdate2' + rowData);
        if (needUpdateIflog) {
            upsert iflog;
            update rowData;
        }
    }
    //生产企业 WLIG-BZ699Z 精琢技术 wql 2021/03/19 start
    //产品主数据生产企业 获取企业名称 (生产企业)
    private static String getProduceCompanyName(String produceCompany){
        //获取企业名称 (生产企业，注册证状态)
        //getProduceCompanyName(String produceCompany,String sfdaApprobatedStatus)
        //取前一部分 eg： 生产企业名称 ：
        //String firstHalf = '';

        //①统一中英文符号  找不到就返回原数据
        String tempProduceCompany = produceCompany.replace('；', ';');
        tempProduceCompany = tempProduceCompany.replace('：', ':');

        //②先截取第一个分号前的数据
        if(tempProduceCompany.indexOf(';')>0){
                 tempProduceCompany = tempProduceCompany.substring(0, tempProduceCompany.indexOf(';'));
            }

        
        //③截取第一个分号前 冒号后 分号前的数据
        if(tempProduceCompany.indexOf(':') > 0){
            //如果需要传入注册证状态的话 再拼接前一部分
            //firstHalf = tempProduceCompany.substring(0, tempProduceCompany.indexOf(':')+1);

            tempProduceCompany = tempProduceCompany.substring(tempProduceCompany.indexOf(':')+1, tempProduceCompany.length());
        }
        
        
        //④正则 只取出中文 不包括 全角符号  # %  不包括英文名
        //[\u4E00-\u9FA5\\s]+ 多个汉字，包括空格
        //[\u4E00-\u9FA5]+ 多个汉字，不包括空格
        //[\u4E00-\u9FA5] 一个汉字
        ///u0800-/u4e00 日文
        //输出中日文
        Pattern p = Pattern.compile('[\u0800-\u9fa5()（）]{2,}');
        Matcher pm = p.matcher(tempProduceCompany);
        if( pm.find() ){
            system.debug('123');
             tempProduceCompany = pm.group(0);
        }
        //如果注册证等于不要 拼接前一部分
        // if(sfdaApprobatedStatus == '不要'){
        //     //如果前半部分不为空 则拼接上前半部分
        //     if(firstHalf!= ''){
        //         tempProduceCompany = firstHalf +tempProduceCompany;
        //     }
        // }
        return tempProduceCompany;
    }
    //生产企业 WLIG-BZ699Z 精琢技术 wql 2021/03/19 end
    @TestVisible
    public static void testI() {
        integer i = 0;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
    }
}