// Author: Fu,Yu
// Created Date: 2023/08/07
// Purpose: get page layout and record data
// Test Class: lexNewQuoteEntryControllerTest
public class lexNewQuoteEntryController{
    public static Integer quoteEntryMaxLine;
    public static List<QELine> activities;
    public static List<QELine> tmpactivities;
    public static List<QuoteLineItem> CheckItem;
    public static Boolean WinOrDecideAlert;
    public static Boolean errorflg;
    public static String errormessage;
    public static String errormessagewarn;
    public static Map<Id, Product2> prd2LatestValMap;
    public static Boolean productStatusUpdated;
    public static Opportunity opp;
    public static Quote quo;
    public static Boolean enableSales;
    public static String quoId;
    public static String oppId;
    public static Boolean newQuoteFlag;
    public static Boolean changedAfterPrint;
    public static string quoteGurantee_Period;
    public static string quotemultiYearWarranty;
    public static Pricebook2 standardPricebook;  
    public static Boolean detail;  
    public static String selection_hp;
    public static String  quoIdreturn;
    public static String  trade;
    public static String searchMode; 
    public static Boolean filg;
    public static Integer flglastbuy;
    public static String errorProductmodel;
    public static Boolean SkipQuotefilg;
    public static Boolean QuoteDecision;
    //字段报错标识 start
    public static Boolean dfpp = false;
    public static Boolean qname = false;
    public static Boolean qacc = false;
    public static Boolean qaapc = false;
    public static Boolean Agency1 = false;
    public static Boolean nAgency1 = false;
    public static Boolean oapp = false;
    public static Boolean noapp = false;
    public static Boolean Agency2 = false;
    public static Boolean nAgency2 = false;
    public static Boolean aapp = false;
    public static Boolean naapp = false;
    //字段报错标识 end
    public static Boolean hongzi = false;
    @AuraEnabled
    //根据报价Id检索报价
    public static  Quote selectQuoteById(String quoId){
        Quote quo = new Quote();
        
            if(String.isNotBlank(quoId)){
                List<Quote> quoList =
                [ SELECT Id, Name, Cancel_Decide__c, CreatedDate, PriceRefreshDate__c, Quote_Print_Date__c,QuotationChange__c,MainEngineWithoutMonitor__c,Interdepartmental__c,
                  Dealer_Final_Price__c, TotalPrice__c, Estimation_List_Price__c, QuoteNumber,
                  QuoteToName, Quote_Expiration_Date__c, Quote_Comment__c, Stocking_Price__c, Unit_Price__c,
                  Offer_Amount__c, TOTAL__c, Discount__c, Pricing__c, Preferential_Trading_Price__c, Contract__c,
                  Agency1__c, OCM_Agent1_Price__c, Agency1_Profit__c, Agency1_Profit_Rate__c, Print_HP_Name__c,
                  Agency2__c, Agent1_Agent2_Price__c, Agency2_Profit__c, Agency2_Profit_Rate__c, Quote_No__c,
                  Quote_Adjust_Amount__c, Quote_Adjust_Calculate__c, Discount_Amount__c, Discount_Amount_Calculate__c, Installation_location__c,
                  QuoteTotal_Page__c, Dealer_Final_Price_Page__c, Quote_Adjust_Amount_Page__c, OCM_Agent1_Price_Page__c, Agent1_Agent2_Price_Page__c
                  , AgencyDiscount__c,OCM_Sales_Forecast__c//预测金额修改 fy
                  , Gurantee_Period__c , multiYearWarranty__c, MultiYearWarrantyTotalPrice__c,
                  Preferential_Gurantee_Period__c,LineItemCount 
                   ,IsQuoteTrial__c,OpportunityId,Opportunity.RecordType.DeveloperName
                  FROM Quote Where Id = :quoId];
                quo = quoList[0];
            }
        
        return quo;
    }
    //检索报价行项目行数
    @AuraEnabled
    public static  List<Quote> selectQuoteListLineItemCount(String quoId,String oppId,String copyid){
        List<Quote> quoList = new  List<Quote>();
        if(String.isBlank(oppId)){
            if(String.isNotBlank(quoId)){
                quoList = [select Id, OpportunityId, Opportunity.RecordType.DeveloperName,LineItemCount From Quote Where Id = :quoId];
            }
        }else{
            if(String.isBlank(copyid)){
                quoList =[select Id, OpportunityId,LineItemCount From Quote Where OpportunityId = :oppId];
            }
        }
        return quoList;
    }
    //检索报价行项目
    @AuraEnabled
    public static  String selectQuoteLineItem(String quoId,String copyid){
        List<QuoteLineItem> items =
            [Select Id, Asset_Model_No__c, SFDA_Status__c, Product_Sales_Possibility__c,
             Name__c, BSS_Category__c, Quote.Quote_Print_Date__c,PricebookEntry.Product2.VenderName__c,PricebookEntry.Product2.CanNotCancelledGurantee__c,PricebookEntry.Product2.Is_DangerousChemicals__c,
             Qty_Unit__c, Cost__c, UnitPrice__c, ListPrice__c, Quantity, TotalPrice__c,
             PricebookEntry.Product2.SFDA_Status__c, ProductCode__c, Product_Cost__c, Product_ListPrice__c, PricebookEntry.Product2.Sales_Possibility__c, PricebookEntry.Product2.Name,
             PricebookEntryId, PricebookEntry.Product2Id, UnitPrice_Page__c, PricebookEntry.Product2.Packing_list_manual__c, PricebookEntry.Product2.StorageStatus__c
             , AgencyUnitPrice__c, AgencySubtotal__c, Present__c
             , multiYearWarranty__c , If_Cancel_Guarantee__c , GuaranteePeriod__c,
             ServicePrice__c , GuranteePrice__c, ProductEntend_gurantee_period_all__c,
             ProductGuranteePrice__c,  GuranteeType__c,
             warrantyType__c, productServicePrice__c, NoDiscountTotal__c
             , provistonPeriod__c
             , PricebookEntry.Product2.Entend_gurantee_period_all__c
             , PricebookEntry.Product2.Intra_Trade_Gurantee_RMB__c
             , PricebookEntry.Product2.Intra_Trade_Service_RMB__c
             , PricebookEntry.Product2.GuranteeType__c
             , PricebookEntry.Product2.Maintenance_Price_Year__c
             , Maintenance_Price_Year__c
             ,PricebookEntry.Product2.Repair_Contract_USD__c
             ,PricebookEntry.Product2.Intra_Trade_Foreign_RMB__c
             ,PricebookEntry.Product2.NoDiscount_Foreign__c 
             ,PricebookEntry.Product2.LastbuyProductFLG__c
             //chenjingwu DB202308355043 2023.8.25 start
             ,PricebookEntry.Product2.Category5__c
             //chenjingwu DB202308355043 2023.8.25 end
             ,Quote.Opportunity.Trade__c 
             ,PricebookEntry.Product2.Estimated_ConsumptionDueDate__c
             From QuoteLineItem where Quoteid = :quoId Order by Item_Order__c, Id];
        activities = new List<QELine>();
        QELine cle = new QELine();
        Integer i = 0;
        if (items.size() > 0) {
            for (QuoteLineItem olt : items) {
                i++;
                cle = new QELine(olt,i, copyid);
                activities.add(cle);
            }
        }
        return JSON.serialize(activities)+'---'+JSON.serialize(items);
    }
    //检索登录人信息
    @AuraEnabled
    public static  User selecUser(){
        User usobj =new User();
        List<User> us = new List<User>();
        String userid = UserInfo.getUserId();
        if (userid != null) {
            us = [Select Quote_Correct__c, Quote_Special_Operation__c, Cost_Referable__c, ViewSpecialAgencyAmout__c From User Where Id = :userid];
            if (us.size() > 0) {
                usobj = us[0];
            }
        }
        return usobj;
    }
    @AuraEnabled
    public static Boolean getquoDes() {
      Schema.DescribeSObjectResult quoteDesc = Quote.SObjectType.getDescribe();
      return quoteDesc.isUpdateable();
    }
    @AuraEnabled
    public static  Boolean QuotCalfagAss(){
      String ProfileId= UserInfo.getProfileId().subString(0,15);
      String QuotationCalculationPermission = System.Label.QuotationCalculationPermission;
        return QuotationCalculationPermission.contains(ProfileId);
    }
    //根据询价Id检索询价
    @AuraEnabled
    public static Opportunity selectOpportunityById(String oppId){
        Opportunity opp = new Opportunity();
        List<Opportunity> oppList =[SELECT Account.Name, Account.RecordType.DeveloperName,
               CLBIC_Category__c, HP_Name__c, Name, CurrencyIsoCode, Wholesale_Price__c, Department_Name__c,
               Direct_Separate__c, Trade__c, AccountId, New_Opportunity__c, Estimation_Decision__c, SAP_Send_OK__c, Sales_Root__c,
               Agency1__c, Agency2__c, Stocking_Price__c, Purchasing_Cost__c, Opportunity_No__c, StageName,
               Agency1__r.Special__c, Agency2__r.Special__c, Account.Parent.Special__c
               , Authorized_DB_No__c, Authorized_Finish_Sales__c, If_Need_Authorize__c
               , Gurantee_Period__c , multiYearWarranty__c, MultiYearWarrantyTotalPrice__c
               , Hospital__c, Department_Class__c
               ,Is_Corrosion__c,
               If_Need_PriceApply__c
               ,CelonOpportunity__c 
               , If_Account_Change__c 
               , Salesdepartment_Owner__c 
               ,Opportunity_Category__c
               FROM Opportunity Where Id = :oppId];
        if (oppList.size() > 0) {
            opp = oppList[0];
        }
        return opp;
    }
    //检索询价行项目
    // @AuraEnabled
    // public static  String selectOpportunityLineItem(String oppId){
    //     List<OpportunityLineItem> items = New List<OpportunityLineItem>();
    //     items = [Select Id, Asset_Model_No__c, SFDA_Status__c, Name__c, ProductCode__c, PricebookEntry.Product2.StorageStatus__c,
    //              Qty_Unit__c, Cost__c, UnitPrice, ListPrice__c, Quantity, BSS_Category__c, TotalPrice,PricebookEntry.Product2.VenderName__c,PricebookEntry.Product2.CanNotCancelledGurantee__c,PricebookEntry.Product2.Is_DangerousChemicals__c,
    //              PricebookEntry.Product2.SFDA_Status__c, Product_Cost__c, Product_ListPrice__c, PricebookEntry.Product2.Sales_Possibility__c, PricebookEntry.Product2.Name,
    //              PricebookEntryId, PricebookEntry.Product2Id, Opportunity.Trade__c, PricebookEntry.Product2.Intra_Trade_List_RMB__c, PricebookEntry.Product2.Intra_Trade_Cost_RMB__c,
    //              PricebookEntry.Product2.Foreign_Trade_List_US__c, PricebookEntry.Product2.Packing_list_manual__c, PricebookEntry.Product2.Foreign_Trade_Cost_US__c, UnitPrice__c, TotalPrice__c
    //              , AgencyUnitPrice__c, AgencySubtotal__c, Present__c
    //              , multiYearWarranty__c , If_Cancel_Guarantee__c , GuaranteePeriod__c,
    //              ServicePrice__c , GuranteePrice__c,
    //              ProductEntend_gurantee_period_all__c,
    //              ProductGuranteePrice__c, GuranteeType__c,
    //              warrantyType__c, productServicePrice__c,
    //              NoDiscountTotal__c
    //              , provistonPeriod__c
    //              , PricebookEntry.Product2.Entend_gurantee_period_all__c
    //              , PricebookEntry.Product2.Intra_Trade_Gurantee_RMB__c
    //              , PricebookEntry.Product2.Intra_Trade_Service_RMB__c
    //              , PricebookEntry.Product2.GuranteeType__c
    //              , PricebookEntry.Product2.Maintenance_Price_Year__c
    //              , Maintenance_Price_Year__c
    //              ,PricebookEntry.Product2.Repair_Contract_USD__c
    //              ,PricebookEntry.Product2.Intra_Trade_Foreign_RMB__c
    //              ,PricebookEntry.Product2.NoDiscount_Foreign__c
    //             ,PricebookEntry.Product2.Estimated_ConsumptionDueDate__c
    //              From OpportunityLineItem
    //              Where OpportunityId = :oppId Order by Item_Order__c, Id];

    //     activities = new List<QELine>();
    //     QELine cle = new QELine();
    //     if (items.size() > 0) {
    //         for(OpportunityLineItem otlt : items) {
    //            cle = new QELine(otlt);
    //            activities.add(cle);
    //         }
    //     }
    //     return JSON.serialize(activities);
    // }
    //检索客户
    @AuraEnabled
    public static  List<Account> selectAccountById(String accountid){
        List<Account> accs2 = [Select Id, RecordType.DeveloperName, Hospital__c, Agent_Ref__c From Account Where Id = :accountid];
        List<Account> accs = new List<Account>();
        if (accs2.size() > 0) {
            if (accs2[0].RecordType.DeveloperName != 'AgencyContract') {
            accs = [Select Id, Name, Site, Alias_Name2__c From Account Where Id = :accs2[0].Hospital__c];
            } else {
            accs = [Select Id, Name, Site, Alias_Name2__c From Account Where Id = :accs2[0].Agent_Ref__c];
            }
        }
        return accs;
    }
    //检索下拉列表值
    @AuraEnabled
    public static List<Map<String,String>> getPicklistValues(String objstr, String fld ,Boolean ifempty){
        List<Map<String,String>> options = new List<Map<String,String>>();
        Map<String,String> space = new Map<String,String>();
        if(ifempty){
            space.put('label', '--无--');
            space.put('value', '');
            options.add(space);
        }

        Schema.sObjectType objType = Schema.getGlobalDescribe().get(objstr);
        Schema.DescribeSObjectResult objDescribe = objType.getDescribe();
        map<String, Schema.SObjectField> fieldMap = objDescribe.fields.getMap();
        list<Schema.PicklistEntry> values = fieldMap.get(fld).getDescribe().getPickListValues();
        system.debug(objstr + '=' + values);
        for (Schema.PicklistEntry a : values)
        {
            if (!a.isActive()) continue;
            Map<String,String> ses = new Map<String,String>();
            ses.put('label', a.getLabel());
            ses.put('value', a.getValue());
            options.add(ses);
        }
        return options;
    }
    //保存报价
    @AuraEnabled
    public static Map<String,String> SaveQuote(String activitiesCan,
                                  String CheckItemCan ,
                                  boolean WinOrDecideAlertc,
                                  boolean productStatusUpdatedc,
                                  String oppInfoc,
                                  boolean enableSalesc,
                                  String quoc,
                                  String oppIdc,
                                  String quoIdc,
                                  boolean newQuoteFlagc,
                                  Boolean changedAfterPrintc,
                                  String quoteGurantee_Periodc,
                                  String quotemultiYearWarrantyc,
                                  String selection_hpc,
                                  Boolean SkipQuotefilgc,
                                  Boolean quoteflg){
        errorflg = false;
        errormessage = null;
        errormessagewarn = null;
        oppId = oppIdc;
        quoId = quoIdc;
        System.debug('quoId+'+quoId);
        System.debug('quoteflg+'+quoteflg);
        System.debug('quoc:' + quoc);
        WinOrDecideAlert = WinOrDecideAlertc;
        productStatusUpdated = productStatusUpdatedc;
        newQuoteFlag  = newQuoteFlagc;
        changedAfterPrint = changedAfterPrintc;
        quoteGurantee_Period = quoteGurantee_Periodc;
        quotemultiYearWarranty = quotemultiYearWarrantyc;
        selection_hp = selection_hpc;
        SkipQuotefilg = SkipQuotefilgc;
        opp = (Opportunity)JSON.deserialize(oppInfoc,Opportunity.class); 
        quo = (Quote)JSON.deserialize(quoc,Quote.class); 
        if(String.isNotBlank(activitiesCan)){
          activities = (List<QELine>)JSON.deserialize(activitiesCan,List<QELine>.class);
        }else {
          activities = null;
        }
        if(String.isNotBlank(CheckItemCan)){
          CheckItem = (List<QuoteLineItem>)JSON.deserialize(CheckItemCan,List<QuoteLineItem>.class);
        }else {
          CheckItem = null;
        }
        enableSales = enableSalesc;
        // errorMessagechack = null;
        setOppFromOppInfo();
        Savepoint sp = Database.setSavepoint();
        Map<String,String> result = new Map<String,String>();
        try {
            //chenjingwu DB202308355043 2023.8.25 start
            if(quoteflg){
              if(checkVirtual('包含虚拟产品，无法报价计算')){
                result.put('errormessage', errormessage);
                return result;
              }
            }
            //chenjingwu DB202308355043 2023.8.25 start
            if (!dataCheck()) { 
                result.put('errormessage', errormessage);
                result = resultFlag(result);
                return result;
            }
            if (dataEntry() == false) {
                result.put('errormessage', errormessage);
                return result;
            } else {
                result.put('success', System.Label.Message_002);
                if(String.isBlank(quoId)){
                  result.put('quoId',quoIdreturn);
                }
                if(String.isNotBlank(quo.Quote_No__c)){
                  result.put('QuoteNo',quo.Quote_No__c);
                }
                if(errormessagewarn != null){
                  result.put('warn', errormessagewarn);
                  String act = JSON.serialize(activities);
                  result.put('act', act);
                }
                return result;
            }
        } catch (DmlException de) {
            Database.rollback(sp);
            // errormessage = de.getLineNumber()+'行'+de.getDmlMessage(0);
            errormessage = de.getDmlMessage(0);
            result.put('errormessage', errormessage);
            return result; 
            // system.debug(Logginglevel.ERROR, de.getMessage());
            // system.debug(Logginglevel.ERROR, de.getStackTraceString());
        } catch (Exception e) {
            Database.rollback(sp);
            // errormessage = e.getLineNumber()+'行'+e.getMessage();
            errormessage = e.getMessage();
            result.put('errormessage',errormessage);
            return result;
            // system.debug(Logginglevel.ERROR, e.getMessage());
            // system.debug(Logginglevel.ERROR, e.getStackTraceString());
        }
    }
    public static Map<String,String> resultFlag(Map<String,String> result){
      if(dfpp){
        result.put('dfpp', 'dfpp');
      }
      if(qname){
        result.put('qname', 'qname');
      }
      if(qacc){
        result.put('qacc', 'qacc');
      }
      if(qaapc){
        result.put('qaapc', 'qaapc');
      }
      if(Agency1){
        result.put('Agency1', 'Agency1');
      }
      if(nAgency1){
        result.put('nAgency1', 'nAgency1');
      }
      if(oapp){
        result.put('oapp', 'oapp');
      }
      if(noapp){
        result.put('noapp', 'noapp');
      }
      if(Agency2){
        result.put('Agency2', 'Agency2');
      }
      if(nAgency2){
        result.put('nAgency2', 'nAgency2');
      }
      if(aapp){
        result.put('aapp', 'aapp');
      }
      if(naapp){
        result.put('naapp', 'naapp');
      }
      return result;
    }
    //打印按钮保存报价
    @AuraEnabled
    public static Map<String,String> Print(String activitiesCan,
                                      String CheckItemCan ,
                                      boolean WinOrDecideAlertc,
                                      boolean productStatusUpdatedc,
                                      String oppInfoc,
                                      boolean enableSalesc,
                                      String quoc,
                                      String oppIdc,
                                      String quoIdc,
                                      boolean newQuoteFlagc,
                                      Boolean changedAfterPrintc,
                                      String quoteGurantee_Periodc,
                                      String quotemultiYearWarrantyc,
                                      String selection_hpc,
                                      Boolean SkipQuotefilgc,
                                      Boolean QuoteDecisionc) {
      oppId = oppIdc;
      quoId = quoIdc;
      System.debug('quoId+'+quoId);
      WinOrDecideAlert = WinOrDecideAlertc;
      productStatusUpdated = productStatusUpdatedc;
      newQuoteFlag  = newQuoteFlagc;
      changedAfterPrint = changedAfterPrintc;
      quoteGurantee_Period = quoteGurantee_Periodc;
      quotemultiYearWarranty = quotemultiYearWarrantyc;
      selection_hp = selection_hpc;
      SkipQuotefilg = SkipQuotefilgc;
      opp = (Opportunity)JSON.deserialize(oppInfoc,Opportunity.class); 
      quo = (Quote)JSON.deserialize(quoc,Quote.class); 
      if(String.isNotBlank(activitiesCan)){
        activities = (List<QELine>)JSON.deserialize(activitiesCan,List<QELine>.class);
      }else {
        activities = null;
      }
      if(String.isNotBlank(CheckItemCan)){
        CheckItem = (List<QuoteLineItem>)JSON.deserialize(CheckItemCan,List<QuoteLineItem>.class);
      }else {
        CheckItem = null;
      }
      enableSales = enableSalesc;
      QuoteDecision = QuoteDecisionc;
      Savepoint sp = Database.setSavepoint();
      Map<String,String> result = new Map<String,String>();
      try {
        if(checkVirtual('包含虚拟产品，无法打印')){
            result.put('errormessage', errormessage);
            return result;
        }
        setOppFromOppInfo();
        errorflg = false;
        errormessage = null;
        errormessagewarn = null;
        //Decide前or後
        if (QuoteDecision == true) {
          //NoSave
        } else {
          if (dataCheck() == false ) {
            result.put('errormessage', errormessage);
            result = resultFlag(result);
            return result;
          }
  
          if (dataEntry() == false) {
            result.put('errormessage', errormessage);
            return result;
          }
        }
        List<Opportunity> opps = new List<Opportunity>();
        if (String.isBlank(oppId)) {
        } else {
          opps = [Select Id
                  From Opportunity Where Id = : oppId];
          if (opps.size() > 0) {
            List<Quote> quos = New List<Quote>();
            //ligthing bug 修改 fy start
            // if (String.isBlank(quoId)) {
            // } else {
              // quos = [Select Id, 
              //         Quote_Print_Date__c, Quote_Date__c From Quote Where Id = : quoId];
            if(String.isNotBlank(quoId)||(String.isBlank(quoId) && String.isNotBlank(quoIdreturn))){
              String quoIds  = String.isNotBlank(quoId) ? quoId : quoIdreturn;
              quos = [Select Id, 
                      Quote_Print_Date__c, Quote_Date__c From Quote Where Id = : quoIds];
            //ligthing bug 修改 fy end
              if (quos.size() > 0) {
                //优惠成交价
                quos[0].Preferential_Trading_Price__c = quo.Preferential_Trading_Price__c;
                //优惠折扣
                quos[0].Discount__c = quo.Discount__c;
                //优惠价格
                quos[0].Pricing__c = quo.Pricing__c;
                //单价
                quos[0].Unit_Price__c = quo.Unit_Price__c;
                //报价金额
                quos[0].Offer_Amount__c = quo.Offer_Amount__c;
                //Total
                quos[0].TOTAL__c = quo.TOTAL__c;
                //契約内容
                quos[0].Contract__c = quo.Contract__c;
                //多年保修 start
                quos[0].Preferential_Gurantee_Period__c = quo.Preferential_Gurantee_Period__c;
                //多年保修 end
                if (quos[0].Quote_Date__c == null) {
                  quos[0].Quote_Date__c = date.Today();
                  opps[0].Estimation_Proposal_Date__c = date.Today();
                  StaticParameter.EscapeOppandStaTrigger = true;
                  update opps[0];
                  StaticParameter.EscapeOppandStaTrigger = false;
                }
                quos[0].Quote_Print_Date__c = date.Today();
                ControllerUtil.updQuote(quos[0]);
              }
            }
          }
        }
        // pageArrange();
        result.put('success', System.Label.Message_002);
        if(String.isBlank(quoId)){
          result.put('quoId',quoIdreturn);
        }
        if(errormessagewarn != null){
          result.put('warn', errormessagewarn);
        }
        return result;
      } catch (DmlException de) {
        Database.rollback(sp);
        errorflg = true;
        errormessage = de.getDmlMessage(0);   
        result.put('errormessage', errormessage);
        return result;
        // system.debug(Logginglevel.ERROR, de.getMessage());
        // system.debug(Logginglevel.ERROR, de.getStackTraceString());
      } catch (Exception e) {
        Database.rollback(sp);
        errorflg = true;
        errormessage = e.getMessage();
        result.put('errormessage', errormessage);
        return result;
        // system.debug(Logginglevel.ERROR, e.getMessage());
        // system.debug(Logginglevel.ERROR, e.getStackTraceString());
      }
    }
    // oppに画面の値を設定
    public static  void setOppFromOppInfo() {
      opp.Agency1__c = quo.Agency1__c;
      opp.Agency2__c = quo.Agency2__c;
    }
    //保存chaeck
    public static Boolean dataCheck() {
      errorflg = false;
      errormessage = null;
      errormessagewarn = null;
      Boolean error = false;
      Boolean error1 = false;
      integer Gcnt = 0;
      if (activities == null || activities.size() <= 0) {
        errorflg = true;
        errorMessage = '不允许保存空的报价单，请选择产品';
        return false;
      }
      if (WinOrDecideAlert && (!productStatusUpdated)) {
          errorflg = true;
          errorMessage = '产品状态发生变化，请更新';
          return false;
      }
      if (!checkSFDAStatus1(false)) {
          errorflg = true;
          errormessage = '请更新不可销售的产品。';
          return false;
      }
      List<String> product2Ids = new List<String>();
      if (activities.size() > 0) {
        for (QELine a : activities) {
          if (!String.isBlank(a.pageObject.Id__c)) {
            product2Ids.add(a.pageObject.Id__c);
          }
        }
        Map<String, String> loopMap = new Map<String, String>();
        if (CheckItem != null) {
          Gcnt = CheckItem.size();
          if (CheckItem.size() > 0) {
            for (QuoteLineItem qli : CheckItem) {
              loopMap.put(qli.PricebookEntry.Product2Id, qli.SFDA_Status__c);
            }
          }
        }
        prd2LatestValMap = new Map<Id, Product2>();
        integer cntPrd2 = 0;
        for (Product2 prd2 : [Select Id, Estimation_Entry_Possibility__c, SFDA_Status__c, Packing_list_manual__c,LastbuyProductFLG__c
                              From Product2 Where Id IN :product2Ids]) {
          cntPrd2 = cntPrd2   +   1;
          if (prd2.Estimation_Entry_Possibility__c != '○') {
            error1 = true;
          }
          if (prd2.Estimation_Entry_Possibility__c == 'M') {
            error1 = false;
          }
          if (prd2.SFDA_Status__c != loopMap.get(prd2.Id)) {
            WinOrDecideAlert    =   true;
          }
  
          prd2LatestValMap.put(prd2.Id, prd2);
        }
        if (cntPrd2  !=  Gcnt) {
          WinOrDecideAlert    =   false;
        }
  
      }
      if(ContractAmountLimitJudge()){
        return false;
      }
      if (error1 == true && WinOrDecideAlert == false) {
        // PageArrange();
        errorflg = true;
        errorMessage = System.Label.Error_Message37;
        return false;
      }
  
      if (checkAgentsDeleteFlag() == false) {
        return false;
      }
      if (enableSales == true && opp.Trade__c == '内貿') {
          Map<Id, String> proMap = new Map<Id, String>();
          if (activities.size() > 0) {
              for (QELine qli : activities) {
                  if (qli.Asset_Model != null && qli.Asset_Model != '') {
                      proMap.put(qli.pageObject.Id__c, qli.pageObject.Name__c);
                  }
              }
          }
          Map<String, String> chkMap = OpportunityWebService.MapCheckProRegisterDecide(proMap, opp.Agency1__c, '');
          if (chkMap.size() > 0) {
              errorflg = true;
              if (chkMap.containsKey('agency')&&!opp.Is_Corrosion__c) {
                errorflg = true;
                errormessage = '第一经销商没有有效的医疗器械经营许可证。';
                // return false;
              }
              Integer inerr = 0;
              if (activities.size() > 0) {
                  for (QELine s : activities) {
                      if (s.Asset_Model != null && s.Asset_Model != '') {
                          s.haveno_Register = false;
                          s.wrong_Register = false;
                          if (chkMap.containsKey(s.pageObject.Id__c)) {
                              if (chkMap.get(s.pageObject.Id__c) == '1') {
                                  s.haveno_Register = true;
                                  inerr ++;
                              } else if (chkMap.get(s.pageObject.Id__c) == '2') {
                                  s.wrong_Register = true;
                                  inerr ++;
                              }
                          }
                      }
                  }
              }
              if (inerr > 0) {
                  errorflg = true;
                  errormessagewarn  = '请检查红字内容（NMPA状态红字，不可销售产品；产品名称红字，超过经销商经营范围）。';
                  // errorMessagechack = '请检查红字内容（NMPA状态红字，不可销售产品；产品名称红字，超过经销商经营范围）。';
              }
          }
          Boolean isDangerError = false;
          Boolean isNotDangerError = false;
          if (activities.size() > 0) {
              for (QELine qli : activities) {
                  if (qli.Asset_Model != null && qli.Asset_Model != '') {
                      if (opp.Is_Corrosion__c) {
                          if(!qli.Is_DangerousChemicals){
                              isNotDangerError =true;
                              qli.wrong_Register = true;
                          }
                      }else{
                          if(qli.Is_DangerousChemicals){
                              isDangerError =true;
                              qli.wrong_Register = true;
                          }
                      }
                  }
              }
          }
          if (opp.Is_Corrosion__c) {
              String str = OpportunityWebService.checkDangerItem(opp.agency1__c);
              if (str != 'OK') {
                errorflg = true;
                errorMessage = str;
                return false;
              } 
              if(isNotDangerError){
                  errorflg = true;
                  errormessage = '当阿西塞多时，行项目的产品必须全选择危化品。';
                  return false;
              }
          }else{
              if(isDangerError){
                  errorflg = true;
                  errormessage = '当询价不是阿西塞多时，行项目的产品不能选择危化品。';
                  return false;
              }
          }
      }
      detail = false;
      if ((quo.QuoteName__c == null) || (quo.QuoteName__c == '')) {
        // quo.QuoteName__c.addError(System.Label.Error_Message3);
        String label = Schema.SObjectType.Quote.fields.QuoteName__c.label;
        error = true;
        qname = true;
        errormessage = label+':'+System.Label.Error_Message3;
      }
      if (quo.Quote_Adjust_Calculate__c == null) {
        // quo.Quote_Adjust_Calculate__c.addError(System.Label.Error_Message3);
        String label = Schema.SObjectType.Quote.fields.Quote_Adjust_Calculate__c.label;
        error = true;
        qacc = true;
        errormessage = label+':'+System.Label.Error_Message3;
      }
      if (quo.Quote_Adjust_Amount_Page__c == null) {
        // quo.Quote_Adjust_Amount__c.addError(System.Label.Error_Message3);
        String label = Schema.SObjectType.Quote.fields.Quote_Adjust_Amount__c.label;
        error = true;
        qaapc = true;
        errormessage = label+':'+System.Label.Error_Message3;
      }
      if (quo.Quote_Expiration_Date__c == null) {
        // quo.Quote_Expiration_Date__c.addError(System.Label.Error_Message3);
        String label = Schema.SObjectType.Quote.fields.Quote_Expiration_Date__c.label;
        error = true;
        errormessage = label+':'+System.Label.Error_Message3;
      }
      //decimal temSalesAmount1 = 0; // 2018/09/28 CHAN-B4YAB8 经销商小计合计 end
      system.debug('activities++++----****2'+activities);
      for (QELine a : activities) {
        if ((a.Asset_Model != null) && (a.Asset_Model != '')) {
          if (a.pageObject.Quantity__c == null || a.pageObject.Quantity__c == 0) {
            // a.pageObject.Quantity__c.addError(System.Label.Error_Message3);
            String label = Schema.SObjectType.QuoteLineItem.fields.Quantity__c.label;
            error = true;
            errormessage = label+':'+System.Label.Error_Message3;
          }
          if (a.pageObject.UnitPrice_Page__c == null) {
            // a.pageObject.UnitPrice__c.addError(System.Label.Error_Message3);
            String label = Schema.SObjectType.QuoteLineItem.fields.UnitPrice__c.label;
            error = true;
            errormessage = label+':'+System.Label.Error_Message3;
          }
          if (a.pageObject.AgencyUnitPrice__c == null) {
            // a.pageObject.AgencyUnitPrice__c.addError(System.Label.Error_Message3);
            String label = Schema.SObjectType.QuoteLineItem.fields.AgencyUnitPrice__c.label;
            error = true;
            errormessage = label+':'+System.Label.Error_Message3;
          }
          if (a.pageObject.PricebookEntryId == null) {
            error = true;
            errormessage = System.Label.Error_Message27;
          }
          detail = true;
        }
      }
      if (enableSales == true) {
        // LHJ Start
        system.debug('errormessage==='+errormessage);
        if (quo.Agency1__c == null) {
          // quo.Agency1__c.addError(System.Label.Error_Message3);
          Agency1 = true;
          String label = Schema.SObjectType.Quote.fields.Agency1__c.label;
          error = true;
          if(String.isNotBlank(errormessage)){
            errormessage +='\n'+ label+':'+System.Label.Error_Message3;
          }else {
            errormessage = label+':'+System.Label.Error_Message3;
          }
        }
        system.debug('errormessage==='+errormessage);
        // LHJ End
        if (quo.OCM_Agent1_Price_Page__c == null) {
          // quo.OCM_Agent1_Price__c.addError(System.Label.Error_Message3);
          oapp = true;
          String label = Schema.SObjectType.Quote.fields.OCM_Agent1_Price__c.label;
          error = true;
          errormessage =label+':'+System.Label.Error_Message3;
        } else {
    
        }
      } else {
    
        if (opp.Agency1__c != null) {
          // opp.Agency1__c.addError(System.Label.Error_Message30);
          String label = Schema.SObjectType.Opportunity.fields.Agency1__c.label;
          error = true;
          nAgency1 = true;
          if(String.isNotBlank(errormessage)){
            errormessage +='\n'+ label+':'+System.Label.Error_Message30;
          }else {
            errormessage = label+':'+System.Label.Error_Message30;
          }
        }
        system.debug('errormessage==='+errormessage);
        if (quo.OCM_Agent1_Price_Page__c != null) {
          // quo.OCM_Agent1_Price__c.addError(System.Label.Error_Message30);
          noapp = true;
          String label = Schema.SObjectType.Quote.fields.OCM_Agent1_Price__c.label;
          error = true;
          errormessage =label+':'+System.Label.Error_Message30;
        }
        if (opp.Agency2__c != null) {
          // opp.Agency2__c.addError(System.Label.Error_Message30);
          nAgency2 = true;
          String label = Schema.SObjectType.Opportunity.fields.Agency2__c.label;
          error = true;
          errormessage = label+':'+System.Label.Error_Message30;
        }
        if (quo.Agent1_Agent2_Price_Page__c != null) {
          // quo.Agent1_Agent2_Price__c.addError(System.Label.Error_Message30);
          naapp = true;
          String label = Schema.SObjectType.Quote.fields.Agent1_Agent2_Price__c.label;
          error = true;
          errormessage = label+':'+System.Label.Error_Message30;
        }
    
      }
      if (quo.Agency1_Profit_Rate__c >= 1000 || quo.Agency1_Profit_Rate__c <= -1000) {
        error = true;
        errormessage = System.Label.Error_Message38;
      }
      if (quo.Agency2_Profit_Rate__c >= 1000 || quo.Agency2_Profit_Rate__c <= -1000) {
        error = true;
        errormessage = System.Label.Error_Message38;
      }
      if (error == true) {
        errorflg = true;
        return false;
      }
      // PageArrange();
      errorflg = false;
      errorMessage = null;
      return true;
    }
    // 产品状态判断
    public static boolean checkSFDAStatus1(boolean dodecide) {
      for (QELine a : activities) {
        if ((a.Asset_Model != null) && (a.Asset_Model != '')) {
          if (a.pageObject.SFDA_Status__c != '有効' &&
              a.pageObject.SFDA_Status__c != '有効（再申請中）' &&
              a.pageObject.SFDA_Status__c != '不要' &&
              a.pageObject.SFDA_Status__c != '失効（期限内生産済在庫対応）' &&
              // LHJ CBPR 20181221 Start
              (a.pageObject.SFDA_Status__c != '暂停出库（长期）') &&
              (a.pageObject.SFDA_Status__c != '暂停出库（短期）') &&
              // LHJ CBPR 20181221 End
              (a.pageObject.SFDA_Status__c != '失効（再申請中）' || dodecide != false)
             ) {
            return false;
          }
        }
      }
      return true;
    }
    //报价合同金额增加限制
    public static boolean ContractAmountLimitJudge(){
      if(opp.Sales_Root__c =='OCM直接销售'){
        return false;
      }
      Boolean error = false;
      Double AccrualTotal=0;
      Double sumContractAmount =0;
      for(QELine aaa :activities){
        // 2022-06-14 紧急修复 ssm
        if (String.isBlank(aaa.Asset_Model)) {
          continue;
        }
        if(aaa.pageObject.PricebookEntry.Product2Id!=null){
          if(aaa.GuranteePrice==null){
            aaa.GuranteePrice=0;
          }
          AccrualTotal += aaa.pageObject.Quantity__c*aaa.GuranteePrice;
        }
      }
      if(quo.MultiYearWarrantyTotalPrice__c==null){
        quo.MultiYearWarrantyTotalPrice__c=0;
      }
      sumContractAmount = AccrualTotal+quo.MultiYearWarrantyTotalPrice__c;
      if(quo.OCM_Agent1_Price_Page__c<=sumContractAmount){
        error = true;
        errorflg = true;
        errormessage = '预测金额为负数，请正确填写合同金额。';
      }
      if(quo.multiYearWarranty__c){
        if(quo.OCM_Agent1_Price_Page__c<=0){
          error = true;
          errorflg = true;
          errormessage = '预测金额为负数，请正确填写合同金额。';
        }
      }
      return error;
    }
    //
    public static  Boolean checkAgentsDeleteFlag() {
      // Check Agents
      List<Id> accIds = new List<Id>();
      if (opp.Agency1__c != null) {
        accIds.add(opp.Agency1__c);
      }
      if (opp.Agency2__c != null) {
        accIds.add(opp.Agency2__c);
      }
      if (accIds.size() > 0) {
        List<Account> agentAccs = [SELECT Id, Delete_Flag__c, Is_Active_Formula__c, Sales_Shop_Class__c FROM Account WHERE Id IN :accIds];
        String activeFormula1 = null, activeFormula2 = null;
        for (Account local : agentAccs) {
          if (local.Sales_Shop_Class__c == '医疗修理经销商') {
            // PageArrange();
            errorflg = true;
            if (local.Id == opp.Agency1__c) {
              errorMessage = '请确认第一经销商的经销商资质';
              return false;
            }
          }
          if (local.Id == opp.Agency1__c) {
            activeFormula1 = local.Is_Active_Formula__c;
          }
        }
        for (Account local : agentAccs) {
          if (local.Id == opp.Agency2__c) {
            activeFormula2 = local.Is_Active_Formula__c;
          }
        }
        if (activeFormula1 == '无效' && activeFormula2 == '无效') {
          // PageArrange();
          errorflg = true;
          errorMessage = System.Label.Agent1_and_Agent2_were_Deleted;
          return false;
        } else if (activeFormula1 == '无效') {
          // PageArrange();
          errorflg = true;
          errorMessage = System.Label.Agent1_was_Deleted;
          return false;
        } else if (activeFormula2 == '无效') {
          // PageArrange();
          errorflg = true;
          errorMessage = System.Label.Agent2_was_Deleted;
          return false;
        }
      }
       // 内貿の場合Check Agency1
      if (opp.Agency1__c != null && opp.Trade__c == '内貿') {
        Account acc = [select Sales_Shop_Class__c, Business_Authorization_No__c, Business_Paper_Expiration_Date__c,
                      Tax_Practice_No__c, Tax_Practice_Expiration_Date__c, Medical_Equipment_Num__c, Is_Active_Formula__c,
                      Medical_Equipment_Expiration_Date__c from Account where Id = :opp.Agency1__c];
        //经销商分类只有特约、一级或者集中采购才可以进行报价
        List<String> salesClazz = new List<String> {'特約販売店（区域）', '特約販売店（製品）', '特約販売店（製品+区域）', '一級販売店', '集采经销商'};
        // 有效/无效（公式）!= 有效
        if (acc.Is_Active_Formula__c != '有效') {
          // PageArrange();
          errorflg = true;
          errorMessage = '请选择有效的经销商';
          return false;
        }
        else if(!salesClazz.contains(acc.Sales_Shop_Class__c)){
          // PageArrange();
          errorflg = true;
          errorMessage = '经销商1的经销商分类为：特约，一级，集中采购才可以报价';
          return false;
        }else if (!(String.isBlank(acc.Tax_Practice_No__c) == false
                  && (acc.Tax_Practice_Expiration_Date__c == null || acc.Tax_Practice_Expiration_Date__c >= Date.today())
                  
                  && String.isBlank(acc.Business_Authorization_No__c) == false
                  && acc.Business_Paper_Expiration_Date__c != null && acc.Business_Paper_Expiration_Date__c >= Date.today())
                ) {
          // PageArrange();
          errorflg = true;
          errorMessage = '请确认第一经销商的经销商资质';
          return false;
        }else {}
      }
      return true;
    }
    //保存逻辑
    public static boolean dataEntry() {
      system.debug('activities++++----****3'+activities);
      Boolean ifdecide=checkIsDecide();
      standardPricebook = ControllerUtil.getStandardPricebook();
      if(!ifdecide){
        
        List<Quote> maxQuote_No = [select Quote_No__c From Quote Where OpportunityId = :oppid and (not Quote_No__c like '%Old') order by Quote_No_last2__c desc NULLS LAST limit 1];
        String oppNo;
        Integer l = 1;
        if (maxQuote_No.size() > 0) {
          try {
            oppNo = maxQuote_No[0].Quote_No__c;
            l = Integer.valueOf(oppNo.substring(oppNo.length() - 2)) + 1;
          } catch (System.TypeException e) {
            system.debug('maxQuote_No Error: quote.id=' + maxQuote_No[0].id);
          }
        } else {
          system.debug('first Quote');
        }
        oppNo = '00' + String.valueof(l);
        oppNo = oppNo.substring(oppNo.length() - 2);
  
        Quote q = New Quote();
        if (changedAfterPrint) {
          system.debug('id空1：');
          quoId = null;
          SkipQuotefilg = true;
        }
        // CHAN-AVG3PW 询价报价画面规则变更
        if (newQuoteFlag) {
          system.debug('id空3：');
          quoId = null;
          SkipQuotefilg = true;
        }
        System.debug('quoteGurantee_Period: ' + quoteGurantee_Period);
        System.debug('quo.Gurantee_Period__c: ' + quo.Gurantee_Period__c);
        System.debug('quotemultiYearWarranty: ' + quotemultiYearWarranty);
        System.debug('quo.multiYearWarranty__c: ' + quo.multiYearWarranty__c);
        if ((quoteGurantee_Period != null &&
          !quoteGurantee_Period.equals(quo.Gurantee_Period__c))
          ||
          (quotemultiYearWarranty != null &&
          !quotemultiYearWarranty.equals('' + quo.multiYearWarranty__c))
        ) {
          system.debug('id空5：');
          quoId = null;
          SkipQuotefilg = true;
        }
        if (String.isBlank(quoId)) {
          q = New Quote();
          q.OpportunityId = oppId;
          if (detail == true) {
            if (standardPricebook == null) {
              errormessage = System.Label.Error_Message27;
              errorflg = true;
              return false;
            } else {
              q.Pricebook2Id = standardPricebook.Id;
            }
          }
        } else {
          List<Quote> qs = New List<Quote>();
          qs = [select Id, OpportunityId, CreatedDate, Pricebook2Id, Name, Estimation_List_Price__c, Dealer_Final_Price__c,QuotationChange__c,MainEngineWithoutMonitor__c,Interdepartmental__c,
                Stocking_Price__c, Discount_Amount__c, Discount_Amount_Calculate__c, Quote_Adjust_Amount__c, Quote_Adjust_Calculate__c,
                Agency1__c, OCM_Agent1_Price__c, Agency1_Profit__c, Agency1_Profit_Rate__c, Quote_No__c,
                Agency2__c, Agent1_Agent2_Price__c, Agency2_Profit__c, Agency2_Profit_Rate__c,
                Preferential_Trading_Price__c, Discount__c, Pricing__c, Unit_Price__c, Offer_Amount__c, TOTAL__c,
                Contract__c, Print_HP_Name__c, Quote_Expiration_Date__c, Quote_Comment__c, OCM_Sales_Forecast__c, Installation_location__c, HasType3Machine__c
                , Gurantee_Period__c , multiYearWarranty__c, MultiYearWarrantyTotalPrice__c
                , Preferential_Gurantee_Period__c
                ,IsQuoteTrial__c 
                From Quote Where Id = :quoId];
          if (qs.size() > 0) {
            q = qs[0];
          }
          if (q.Pricebook2Id == null) {
            if (detail == true) {
              if (standardPricebook == null) {
                errormessage = System.Label.Error_Message27;
                errorflg = true;
                return false;
              } else {
                q.Pricebook2Id = standardPricebook.Id;
              }
            }
          }
        }
        if (String.isBlank(quoId)) {
          q.Quote_No__c = opp.Opportunity_No__c + '-' + oppNo;
          q.PriceRefreshDate__c = Date.today();
        }
        if (productStatusUpdated) {
          q.PriceRefreshDate__c = Date.today();
        }
        List<String> pIds = new List<String>();
        system.debug('activities++++----****1'+activities);
        for (QELine s : activities) {
          if (String.isBlank(s.pageObject.Id__c) == false) {
            pIds.add(s.pageObject.Id__c);
          }
        }
        List<Product2> pList = [select Id from Product2 where Id in :pids and Category3__c = '主机'];
        if (pList.size() > 0) q.HasType3Machine__c = true;
        q.Name = quo.QuoteName__c;
        q.Estimation_List_Price__c = quo.Estimation_List_Price__c;
        q.Dealer_Final_Price__c =  quo.Dealer_Final_Price_Page__c;
        q.OCM_Sales_Forecast__c = quo.OCM_Sales_Forecast__c;//预测金额修改 fy
        q.Stocking_Price__c = quo.Stocking_Price__c;
        q.Quote_Adjust_Amount__c = quo.Quote_Adjust_Amount_Page__c;
        q.Quote_Adjust_Calculate__c = quo.Quote_Adjust_Calculate__c;
        q.Discount_Amount__c = quo.Discount_Amount__c;
        q.Discount_Amount_Calculate__c = quo.Discount_Amount_Calculate__c;
        q.Agency1__c = opp.Agency1__c;
        q.OCM_Agent1_Price__c = quo.OCM_Agent1_Price_Page__c;
        q.Agency1_Profit__c = quo.Agency1_Profit__c;
        q.AgencyDiscount__c  = quo.AgencyDiscount__c;
        q.Gurantee_Period__c = quo.Gurantee_Period__c;
        q.multiYearWarranty__c = quo.multiYearWarranty__c;
        q.MultiYearWarrantyTotalPrice__c = quo.MultiYearWarrantyTotalPrice__c;
        q.quoteSavedDate__c = Date.today();
        q.Agency1_Profit_Rate__c = quo.Agency1_Profit_Rate__c;
        q.Agency2__c = opp.Agency2__c;
        q.Agent1_Agent2_Price__c = quo.Agent1_Agent2_Price_Page__c;
        q.Agency2_Profit__c = quo.Agency2_Profit__c;
        q.Agency2_Profit_Rate__c = quo.Agency2_Profit_Rate__c;
        q.Print_HP_Name__c = selection_hp;
        q.Quote_Expiration_Date__c = quo.Quote_Expiration_Date__c;
        q.Quote_Comment__c = quo.Quote_Comment__c;
        q.Installation_location__c = quo.Installation_location__c;
        q.QuotationChange__c = quo.QuotationChange__c;
        q.MainEngineWithoutMonitor__c = quo.MainEngineWithoutMonitor__c;
        q.Interdepartmental__c = quo.Interdepartmental__c;
        if(!quo.IsQuoteTrial__c){
          q.IsQuoteTrial__c = quo.IsQuoteTrial__c;
        }
        //chenjingwu DB202308355043 2023.8.25 start
        List<Id> idList = new List<Id>();
        for (QELine s : activities) {
          if (String.isNotBlank(s.pageObject.PricebookEntryId)) {
            idList.add(s.pageObject.PricebookEntryId);
          }
        }
        List<PricebookEntry> pb = [select Id from PricebookEntry where Product2.Category5__c = '虚拟' and Id in: idList];
        q.Have_Virtual__c = false;
        if(pb.size() > 0){
          q.Have_Virtual__c = true;
        }
      //chenjingwu DB202308355043 2023.8.25 end
        if (String.isBlank(quoId)) {
          insert q;
          quo.Quote_No__c = q.Quote_No__c;
          // quo.IsQuoteTrial__c = q.IsQuoteTrial__c;
          // isQuoteTrialOnInit = q.IsQuoteTrial__c;
        } else {
          update q;
        }
        List<QuoteLineItem> qlist = New List<QuoteLineItem>();
        qlist = [Select Id From QuoteLineItem Where QuoteId = :quoId];
        if (qlist.size() > 0) {
          delete qlist;
        }
        qlist = New List<QuoteLineItem>();
        List<String> product_lines = new List<String>();
        Boolean Is_Eng2_Opp = false;
        Integer i = 1;
        if (activities.size() > 0) {
          system.debug('activities++++----****'+activities);
          for (QELine s : activities) {
            if (s.Asset_Model != null && s.Asset_Model != '') {
              if (s.pageObject.PricebookEntryId != null) {
                QuoteLineItem ql = s.pageObject.clone();
                ql.Quantity = ql.Quantity__c;
                ql.UnitPrice = 0;         
                ql.QuoteId = q.Id;
                ql.Name__c = s.pageObject.Name__c;
                ql.Cost__c = s.Cost_c;
                ql.Cost_Subtotal__c = s.Cost_Subtotal_c;
                // s.pageObject.Cost__c = s.Cost_c;
                // s.pageObject.Cost_Subtotal__c = s.Cost_Subtotal_c;
                ql.UnitPrice__c = ql.UnitPrice_Page__c;
                ql.UnitPrice_Page__c = 0;
                ql.ListPrice__c = s.ListPrice_Page;
                ql.GuranteePrice__c        = s.GuranteePrice;
                ql.ProductGuranteePrice__c = s.ProductGuranteePrice;
                ql.Maintenance_Price_Year__c = s.Maintenance_Price_Year;
                ql.CanNotCancelFlag__c = s.CanNotCancelledGurantee;
                ql.Item_Order__c = i;//预测金额修改 fy
                if (s.pageObject.Subtotal__c != null && quo.OCM_Agent1_Price_Page__c != null && quo.QuoteTotal_Page__c != null) {
                  if (s.pageObject.Subtotal__c > 0 && quo.QuoteTotal_Page__c > 0) {//预测金额修改 fy
                    ql.OCM_Sales_Forecast__c =  quo.OCM_Agent1_Price_Page__c * (s.pageObject.Subtotal__c / quo.QuoteTotal_Page__c);
                  }
                }
                qlist.add(ql);
                product_lines.add(s.pageObject.PricebookEntryId);
                i++;
              }
            }
          }
          system.debug('qlist+++---+++'+qlist);
          insert qlist;
        }
        system.debug('○○○○○Save2○○○○○');
        List<PricebookEntry> entrys = product_lines!= null && product_lines.size() > 0 ? [select Id from PricebookEntry where Id in :product_lines and Product2.ENG_New__c = 'ENG2'] : null;
        Is_Eng2_Opp = entrys != null && entrys.size() > 0 ? true : false;
        Opportunity o = New Opportunity();
        List<Opportunity> os = New List<Opportunity>();
        os = [select Id, Estimation_List_Price__c, Dealer_Final_Price__c, Estimation_List_Price_Without_Tax__c,
              Agency1__c, OCM_Agent1_Price__c, Agency1_Profit__c, Agency1_Profit_Rate__c, Stocking_Price__c,
              Agency2__c, Agent1_Agent2_Price__c, Agency2_Profit__c, Agency2_Profit_Rate__c, Quote_Update_Sum__c , Hospital__c,Is_Corrosion__c 
              ,StageName ,OlyNumberHosts__c
              From Opportunity Where Id = :oppid];
        if (os.size() > 0) {
          o = os[0];
          o.Estimation_List_Price__c = quo.Estimation_List_Price__c;
          o.Wholesale_Price__c = q.OCM_Sales_Forecast__c;//预测金额修改 fy
          o.Dealer_Final_Price__c = quo.Dealer_Final_Price_Page__c;
          o.Agency1__c = opp.Agency1__c;
          o.OCM_Agent1_Price__c = quo.OCM_Agent1_Price_Page__c;
          o.Agency1_Profit__c = quo.Agency1_Profit__c;
          o.Agency1_Profit_Rate__c = quo.Agency1_Profit_Rate__c;
          o.Agency2__c = opp.Agency2__c;
          o.Agent1_Agent2_Price__c = quo.Agent1_Agent2_Price_Page__c;
          o.Agency2_Profit__c = quo.Agency2_Profit__c;
          o.Agency2_Profit_Rate__c = quo.Agency2_Profit_Rate__c;
          o.Stocking_Price__c = quo.Stocking_Price__c;
          o.Estimation_No__c = q.Quote_No__c;
          o.Estimation_Name__c = q.Name;
          o.Estimation_Id__c = q.Id;
          o.Installation_location__c = q.Installation_location__c;
          o.HasType3Machine__c = q.HasType3Machine__c;
          o.AgencyDiscount__c  = quo.AgencyDiscount__c;
          o.Gurantee_Period__c              = quo.Gurantee_Period__c ;
          o.multiYearWarranty__c            = quo.multiYearWarranty__c ;
          o.MultiYearWarrantyTotalPrice__c  = quo.MultiYearWarrantyTotalPrice__c ;
          o.quoteSavedDate__c = Date.today();
          o.OlyNumberHosts__c = 0;
          List<String> oppIds = New List<String>();
          List<String> product2Ids = New List<String>();
          Map<String,Decimal> product2IdsMap = new Map<String,Decimal>();
          if (activities.size() > 0) {
            for (QELine a : activities) {
              if(String.isBlank(a.pageObject.Id__c) == false) {
                product2Ids.add(a.pageObject.Id__c);
                product2IdsMap.put(a.pageObject.Id__c,a.pageObject.Quantity__c);
              }
            }
            for (Product2 prod : [Select Id,ProductClass__c From Product2 Where Id IN :product2Ids]) {
              if(o.StageName == '引合' || o.StageName == '注残' || o.StageName == '出荷' || o.StageName == '完了'){
                if(prod.ProductClass__c == '主机'){
                  if(product2IdsMap.containsKey(prod.Id)){
                    o.OlyNumberHosts__c += product2IdsMap.get(prod.Id);
                    oppIds.add(o.Id);
                    ControllerUtil.UpdateBiddingFlag(oppIds);
                  }
                }else{
                  o.OlyNumberHosts__c += 0;
                }
              }
            }
          }
          if (o.Quote_Update_Sum__c == null) {
            o.Quote_Update_Sum__c = 1;
          } else {
            o.Quote_Update_Sum__c = o.Quote_Update_Sum__c + 1;
          }
          o.ENG2_Opp__c = Is_Eng2_Opp;
          StaticParameter.EscapeOppandStaTrigger = true;
          update o;

    
          //OpportunityLineItem--------------------------------------------
          List<OpportunityLineItem> ols = New List<OpportunityLineItem>();
          OpportunityLineItem ol = New OpportunityLineItem();
          ols = [select Id, Quantity from OpportunityLineItem Where OpportunityId = :oppid];
          if (ols.size() > 0) {
            ControllerUtil.delOppLine(ols);
          }
          i = 1;
          ols = New List<OpportunityLineItem>();
          if (activities.size() > 0) {
            for (QELine s : activities) {
              if (s.Asset_Model != null && s.Asset_Model != '') {
                if (s.pageObject.PricebookEntryId != null) {
                  ol = New OpportunityLineItem();
                  ol.OpportunityId = oppid;
                  ol.Id__c = s.pageObject.Id__c;
                  ol.SFDA_Status__c = s.pageObject.SFDA_Status__c;
                  ol.Name__c = s.pageObject.Name__c;
                  ol.ListPrice__c = s.ListPrice_Page;
                  ol.Quantity = s.pageObject.Quantity__c;
                  ol.UnitPrice = 0;
                  ol.UnitPrice__c = s.pageObject.UnitPrice_Page__c;
                  ol.AgencyUnitPrice__c =  s.pageObject.AgencyUnitPrice__c;
                  ol.Present__c =  s.pageObject.Present__c;
                  ol.AgencySubtotal__c =  s.pageObject.AgencySubtotal__c;
                  ol.GuaranteePeriod__c =  s.pageObject.GuaranteePeriod__c;
                  if (opp.CurrencyIsoCode != null ) {
                    ol.multiYearWarranty__c =  s.pageObject.multiYearWarranty__c;
                    ol.ServicePrice__c =  s.pageObject.ServicePrice__c;
                    ol.If_Cancel_Guarantee__c =  s.pageObject.If_Cancel_Guarantee__c;
                    ol.ProductEntend_gurantee_period_all__c
                      =  s.pageObject.ProductEntend_gurantee_period_all__c;
                    ol.GuranteeType__c =  s.pageObject.GuranteeType__c;
                    ol.NoDiscountTotal__c =  s.pageObject.NoDiscountTotal__c;
                    ol.warrantyType__c =  s.pageObject.warrantyType__c;
                    ol.productServicePrice__c =  s.pageObject.productServicePrice__c;
                    ol.GuranteePrice__c        = s.GuranteePrice;
                    ol.ProductGuranteePrice__c = s.ProductGuranteePrice;
                    ol.Maintenance_Price_Year__c = s.Maintenance_Price_Year;
                    ol.provistonPeriod__c = s.pageObject.provistonPeriod__c;
                  }
                  ol.Qty_Unit__c = s.pageObject.Qty_Unit__c;
                  ol.Cost__c = s.pageObject.Cost__c;
                  ol.BSS_Category__c = s.pageObject.BSS_Category__c;
                  ol.CanNotCancelFlag__c = s.CanNotCancelledGurantee;//预测金额修改 fy
                  if (s.pageObject.Subtotal__c != null && o.Wholesale_Price__c != null && quo.QuoteTotal_Page__c != null) {
                    if (s.pageObject.Subtotal__c > 0 && quo.QuoteTotal_Page__c > 0) {//预测金额修改 fy
                      ol.OCM_Sales_Forecast__c =  o.Wholesale_Price__c * (s.pageObject.Subtotal__c / quo.QuoteTotal_Page__c);
                    }
                  }
                  ol.PricebookEntryId = s.pageObject.PricebookEntryId;
                  ol.Item_Order__c = i;
                  ols.add(ol);
                  i++;
                }
              }
            }
            ControllerUtil.insOppLine(ols);
          }
  
        } else {
          system.debug('*****SystemError OpportunityId is Null*****');
        }
        if (String.isBlank(quoId)) {
          quoIdreturn = q.Id;
          // newQuoteFlag = false;
        } 
      }else{
        errorflg = true;
        errormessage = '该询价已经decide，不可再修改';
        return false;
      }
      return true;
    }
    //防止多开页面加验证查询
    private static boolean checkIsDecide() {
      List<Opportunity> oppsde = [Select Id, Estimation_Decision__c From Opportunity Where Id = : oppId];
      if (oppsde.size() > 0) {
        if(oppsde[0].Estimation_Decision__c){
          return true;
        }
      }
      return false;
    }
    //检索新建报价产品
    @AuraEnabled
    public static List<PricebookEntry> serContact(String tradec,String SearchName,String celon){
        trade = tradec;
        String x = '×';
        String searchSql = 'select Id,Product2Id,Product2.Name,Product2.ProductCode,Product2.StorageStatus__c,Product2.OT_CODE_no_link__c, Product2.Alternative_Products__c, '
                        + 'Product2.Foreign_Trade_Cost_US__c, Product2.Foreign_Trade_List_US__c, Product2.Intra_Trade_Cost_RMB__c, Product2.Intra_Trade_List_RMB__c, '
                        + 'Product2.Asset_Model_No__c, Product2.Serial_Lot_No__c, Product2.Sales_Possibility__c, Product2.Estimation_Entry_Possibility__c, '
                        + 'Product2.SFDA_Status__c, Product2.Qty_Unit__c, Product2.BSSCategory__c, Product2.Asset_loaner_category__c, Product2.Packing_list_manual__c '
                        + ' ,Product2.Extend_new_product_gurantee_MD__c , Product2.Extend_new_product_gurantee__c , Product2.Entend_gurantee_period_all__c , '
                        + '  Product2.Intra_Trade_Gurantee_RMB__c  '
                        + ',Product2.Intra_Trade_Foreign_RMB__c,Product2.NoDiscount_Foreign__c,Product2.Repair_Contract_USD__c '
                        + ' , Product2.Intra_Trade_Service_RMB__c,Product2.CanNotCancelledGurantee__c,Product2.Is_DangerousChemicals__c '
                        + ' , Product2.GuranteeType__c , product2.VenderName__c , product2.Maintenance_Price_Year__c '
                        + ' , Product2.suitDepartment__c '
                        //chenjingwu DB202308355043 2023.8.25 start
                        + ' , Product2.Category5__c '
                        //chenjingwu DB202308355043 2023.8.25 end
                        + ' , Product2.Estimated_ConsumptionDueDate__c '
                        + 'FROM PricebookEntry ';
        String whereStr = 'Where Product2.Asset_Model_No__c != null And Product2.Manual_Entry__c = false And Product2.Estimation_Entry_Possibility__c !=' + '\'' + x + '\' '
                        + 'AND CurrencyIsoCode =' + '\'' + String.escapeSingleQuotes(trade) + '\' '
                        + 'AND IsActive = true ';
        String whereSql = '';
        if (searchMode == 'CS') {
            whereSql += 'and Product2.Asset_loaner_category__c = \'为耗材管理\' ';
        }
        if (SearchName != null && SearchName != '') {
            String likename = String.escapeSingleQuotes(SearchName);
            String prdcd = String.escapeSingleQuotes(SearchName);
            if (likename.indexOf('*') >= 0) {
                likename = likename.replace('*', '%');
            } else {
                likename = '%' + likename + '%';
            }
            whereSql += 'and (Product2.Name Like ' + '\'' + likename + '\' or Product2.ProductCode = ' + '\'' + prdcd + '\' or Product2.Asset_Model_No__c Like ' + '\'' + likename + '\') ';
        }
        celon = String.isNotBlank(celon) ? celon : null;
        whereSql += ' and Product2.Celon_Product__c = :celon ';
        searchSql = searchSql + whereStr + whereSql;
        searchSql += ' order by Product2.Asset_Model_No__c Limit 450';
        List<PricebookEntry> pbes = Database.query(searchSql);
        return pbes;
    }
    //检索产品配套
    @AuraEnabled
    public static List<Product_Set__c> serSetContact(String SearchName,String SearchCode,String filterName){
      String searchSql = 'Select id, name, Price__c, Product_Set_CD__c, Quantity__c,Valid_Status__c,Quote_Select_Info__c From Product_Set__c ';
      String whereStr = 'Where Valid_Status__c = true ';
      String whereSql = '';
      if(SearchName != null && SearchName != ''){
        whereSql += 'and name Like ' + '\'%' + SearchName + '%\' ';
      }
      if(filterName != null && filterName != ''){
        whereSql += 'and Applicable_Department__c =\'' + filterName + '\'';
      }
      if(SearchCode != null && SearchCode != ''){
        whereSql += 'and Product_Set_CD__c like ' + '\'%' + SearchCode + '%\' ';
      }
      searchSql = searchSql + whereStr + whereSql;
      searchSql += ' order by Product_Set_CD__c limit 500';
      List<Product_Set__c> cl = Database.query(searchSql);
      return cl;
    }
    //产品检索配套赋值
    @AuraEnabled
    public static String setProductEntry(String setProduct_text,
                                        String activitiesCan,
                                        String oppInfoc,
                                        String quoc) {
      if(String.isNotBlank(activitiesCan)){
        activities = (List<QELine>)JSON.deserialize(activitiesCan,List<QELine>.class);
      }else {
        activities = null;
      }
      quo = (Quote)JSON.deserialize(quoc,Quote.class); 
      opp = (Opportunity)JSON.deserialize(oppInfoc,Opportunity.class); 
      setOppFromOppInfo();
      List<String> productIDLIST = new List<String>();
      if (setProduct_text == null) {
        // PageArrange();
        return JSON.serialize(activities);
      } else {
        productIDLIST = setProduct_text.split(',');
      }
      System.debug('productIDLIST-c++'+productIDLIST);
      List<Id> productIds = null;
      List<Product_Set_Detail__c> productSetDetails = [SELECT Id, Product__c, Quantity__c, Product_Set__r.Name,Product__r.VenderName__c,Product__r.CanNotCancelledGurantee__c,Product__r.Is_DangerousChemicals__c FROM Product_Set_Detail__c Where Product_Set__c in :productIDLIST];
      if (productSetDetails.size() == 0) {
        // PageArrange();
        return JSON.serialize(activities);
      } else {
        productIds = new List<Id>();
        for (Product_Set_Detail__c local : productSetDetails) {
          productIds.add(local.Product__c);
        }
      }
      System.debug('productIds++'+productIds);
      System.debug('activities++'+activities);
      tmpactivities = activities;
      activities = new List<QELine>();
      boolean lineflg = false;
      Map<Id, Product2> items = new Map<Id, Product2>();
      List<Product2> products = [select Id, Name, ProductCode,
                                 Foreign_Trade_Cost_US__c, Foreign_Trade_List_US__c, Intra_Trade_Cost_RMB__c, Intra_Trade_List_RMB__c,
                                 Asset_Model_No__c, Sales_Possibility__c, Estimation_Entry_Possibility__c,VenderName__c,
                                 SFDA_Status__c, Qty_Unit__c, BSSCategory__c, Packing_list_manual__c, StorageStatus__c
                                 , Entend_gurantee_period_all__c
                                 , Intra_Trade_Gurantee_RMB__c
                                 , Intra_Trade_Service_RMB__c
                                 , GuranteeType__c
                                 , Maintenance_Price_Year__c
                                 ,CanNotCancelledGurantee__c
                                 ,Is_DangerousChemicals__c
                                 ,Repair_Contract_USD__c
                                 ,LastbuyProductFLG__c
                                 ,Intra_Trade_Foreign_RMB__c
                                 ,NoDiscount_Foreign__c
                                 //chenjingwu DB202308355043 2023.8.25 start
                                 ,Category5__c
                                 //chenjingwu DB202308355043 2023.8.25 end
                                ,Estimated_ConsumptionDueDate__c
                                 FROM Product2 Where Id IN :productIds
                                 And Manual_Entry__c = false];
      for (Product2 product : products) {
        items.put(product.Id, product);
      }
      System.debug('items++'+items);
      Map<Id, PricebookEntry> entries = new Map<Id, PricebookEntry>();
      List<PricebookEntry> workEntries = [
                                           SELECT Id, Product2Id
                                           FROM PricebookEntry Where Product2Id IN :productIds
                                           AND CurrencyIsoCode = :(opp.Trade__c == '外貿' ? 'USD' : 'CNY')
                                               AND IsActive = true
                                         ];
      for (PricebookEntry workEntry : workEntries) {
        entries.put(workEntry.Product2Id, workEntry);
      }
      System.debug('entries-c++'+entries);
      Integer i = 1;
      Integer rightcnt = 0;
      for (QELine t : tmpactivities) {
        QELine a = New QELine();
        a.lineNo = i;
        System.debug('i-c++'+i);
          a = t;
          a.lineNo = i;
          activities.add(a);
  
        i++;
      }
      if (items.size() > 0) {
        System.debug('productSetDetails-c++'+productSetDetails);
        for (Integer l = 0; l < productSetDetails.size(); l++) {
          Product_Set_Detail__c nowDetail = productSetDetails[l];
          Product2 prd = items.get(nowDetail.product__c);
          PricebookEntry pbe = entries.get(nowDetail.product__c);
          if (pbe == null) {
          } else {
            QELine c = null;
            Integer Quantity_c = nowDetail.Quantity__c > 0 ? Integer.valueOf(nowDetail.Quantity__c) : 1;
            if (opp.Trade__c == '外貿') {
              if (prd.Foreign_Trade_List_US__c > 0 && prd.Foreign_Trade_Cost_US__c > 0) {
                c = new QELine(i, prd.Is_DangerousChemicals__c,prd.CanNotCancelledGurantee__c,prd.VenderName__c,
                              prd.Estimated_ConsumptionDueDate__c,
                              pbe.Id, prd.Asset_Model_No__c, prd.StorageStatus__c,
                               prd.ProductCode, nowDetail.product__c, prd.SFDA_Status__c,
                               prd.Sales_Possibility__c, prd.Name, prd.BSSCategory__c,
                               Quantity_c, prd.Foreign_Trade_List_US__c,
                               prd.Foreign_Trade_List_US__c, prd.Foreign_Trade_Cost_US__c,
                               prd.Packing_list_manual__c
                               , prd.Entend_gurantee_period_all__c
                               , prd.Intra_Trade_Foreign_RMB__c
                               , prd.GuranteeType__c
                               , prd.NoDiscount_Foreign__c, prd.Repair_Contract_USD__c
                               //chenjingwu DB202308355043 2023.8.25 start
                               , prd.Category5__c
                               //chenjingwu DB202308355043 2023.8.25 end
                              );
              } else {
                continue;
              }
            } else if (opp.Trade__c == '内貿') {
              if (prd.Intra_Trade_List_RMB__c > 0 && prd.Intra_Trade_Cost_RMB__c > 0) {
                c = new QELine(i,prd.Is_DangerousChemicals__c,prd.CanNotCancelledGurantee__c,prd.VenderName__c, 
                              prd.Estimated_ConsumptionDueDate__c,
                              pbe.Id, prd.Asset_Model_No__c, prd.StorageStatus__c,
                               prd.ProductCode, nowDetail.product__c, prd.SFDA_Status__c,
                               prd.Sales_Possibility__c, prd.Name, prd.BSSCategory__c,
                               Quantity_c, prd.Intra_Trade_List_RMB__c,
                               prd.Intra_Trade_List_RMB__c, prd.Intra_Trade_Cost_RMB__c,
                               prd.Packing_list_manual__c
                               , prd.Entend_gurantee_period_all__c
                               , prd.Intra_Trade_Gurantee_RMB__c
                               , prd.GuranteeType__c
                               , prd.Intra_Trade_Service_RMB__c
                               , prd.Maintenance_Price_Year__c
                               //chenjingwu DB202308355043 2023.8.25 start
                               , prd.Category5__c
                               //chenjingwu DB202308355043 2023.8.25 end
                              );
              } else {
                continue;
              }
            } else {
              continue;
            }
            activities.add(c);
            i++;
            rightcnt++;
            lineflg = true;
          }
        }
      }
      // PageArrange();
      if (productSetDetails.size() > 0) {
        errorflg = true;
        errormessage = productSetDetails[0].Product_Set__r.Name + ' 导入结束，导入 ' + productSetDetails.size() + ' 件，成功' + rightcnt + ' 件';
      }
      System.debug('activities-to++'+activities);
      return errormessage + '---' + JSON.serialize(activities);
    }
    //excelImport
    @AuraEnabled
    public static String excelImport(String excel_text,
                                    String activitiesCan,
                                    String oppInfoc,
                                    String quoc) {
      
      if(String.isNotBlank(activitiesCan)){
          activities = (List<QELine>)JSON.deserialize(activitiesCan,List<QELine>.class);
      }else {
          activities = null;
      }
      quo = (Quote)JSON.deserialize(quoc,Quote.class); 
      opp = (Opportunity)JSON.deserialize(oppInfoc,Opportunity.class); 
      setOppFromOppInfo();
      errorflg = false;
      errormessage = '';
      Integer j = 0;
      tmpactivities = activities;
      activities = new List<QELine>();
      Integer i = 0;
      Integer xlscnt = 0;
      Integer rightcnt = 0;

      string[] xlslists = excel_text.split('\n', -1);
      List<string> xlslist = New list<string>();
      List<string> codelist = New List<string>();
      List<Integer> Quantitylist = New List<Integer>();
      //String str ;

      Map<String, Integer> mp = new Map<String, Integer>();
      string xlscode;
      Integer xlsQuantity;

      try {
        for (string xls : xlslists) {
          if (xls == null || xls == '') {
          } else {
            xlscode = null;
            xlsQuantity = null;
            xlslist = xls.split('\t', -1);
            system.debug('xlslist+++'+xlslist);
            for (String s : xlslist) {
              //odd number or even number
              if (math.mod(i, 2) != 0) {
                system.debug('xlslist1+++'+s);
                //odd number
                if (s == '' || s == null) {
                  errorflg = true;
                  errormessage = System.Label.Error_Message31;
                  activities = tmpactivities;
                  // pageArrange();
                  return errormessage+'---'+JSON.serialize(activities);
                } else {
                  s = s.trim();
                  xlsQuantity = Integer.valueOf(s);
                  Quantitylist.add(xlsQuantity);
                }
              } else {
                system.debug('xlslist2+++'+s);
                //even number
                if (s == '' || s == null) {
                  errorflg = true;
                  errormessage = System.Label.Error_Message31;
                  activities = tmpactivities;
                  // pageArrange();
                  return errormessage+'---'+JSON.serialize(activities);
                } else {
                  s = s.trim();
                  codelist.add(s);
                  xlscode = s;
                }
              }
              i++;
            }
            //mp.put(xlscode, xlsQuantity);
            xlscnt++;
          }
        }
      } catch (Exception ex) {
        system.debug('xlslist3+++'+xlscnt);
        activities = tmpactivities;
        errorflg = true;
        errormessage = System.Label.Error_Message31;
        // pageArrange();
        return errormessage+'---'+JSON.serialize(activities);
      }

      system.debug(j);
      system.debug('xlscnt:::::' + xlscnt);

      if (codelist.size() == 0 || Quantitylist.size() == 0) {
        activities = tmpactivities;
        errorflg = true;
        system.debug('codelist+++'+codelist);
        system.debug('Quantitylist+++'+Quantitylist);
        errormessage = System.Label.Error_Message31;
        // pageArrange();
        return errormessage+'---'+JSON.serialize(activities);
      }


      i = 1;
      boolean lineflg = false;
      for (QELine t : tmpactivities) {
        QELine a = New QELine();
          a = t;
          a.lineNo = i;
          activities.add(a);
          i++;
      }
      Map<String, Product2> mpProduct2 = new Map<String, Product2>();
      String celon_type = String.isNotBlank(opp.CelonOpportunity__c) ? opp.CelonOpportunity__c : null;
      List<Product2> items = [select Id, Name, ProductCode,
                              Foreign_Trade_Cost_US__c, Foreign_Trade_List_US__c, Intra_Trade_Cost_RMB__c, Intra_Trade_List_RMB__c,
                              Asset_Model_No__c, Sales_Possibility__c, Estimation_Entry_Possibility__c,VenderName__c,
                              SFDA_Status__c, Qty_Unit__c, BSSCategory__c, Packing_list_manual__c, StorageStatus__c
                              , Entend_gurantee_period_all__c
                              , Intra_Trade_Gurantee_RMB__c
                              , Intra_Trade_Service_RMB__c
                              , GuranteeType__c
                              ,  Maintenance_Price_Year__c
                            ,CanNotCancelledGurantee__c
                            ,Is_DangerousChemicals__c
                            ,Repair_Contract_USD__c
                            ,Intra_Trade_Foreign_RMB__c
                            ,NoDiscount_Foreign__c
                            //chenjingwu DB202308355043 2023.8.25 start
                            ,Category5__c
                            //chenjingwu DB202308355043 2023.8.25 end
                            ,Estimated_ConsumptionDueDate__c
                              FROM Product2 Where ProductCode In :codelist
                              And Celon_Product__c = :celon_type 
                              And Manual_Entry__c = false];
      for (Product2 prd : items) {
        system.debug('prd.ProductCode:::::' + prd.ProductCode);
        mpProduct2.put(prd.ProductCode, prd);
      }
      Map<String, PricebookEntry> entries = new Map<String, PricebookEntry>();            // keyがProductCodeです。
      List<PricebookEntry> pbes = [
                                    select Id, PricebookEntry.Product2.ProductCode
                                    FROM PricebookEntry Where PricebookEntry.Product2.ProductCode IN :codelist
                                    AND CurrencyIsoCode = :(opp.Trade__c == '外貿' ? 'USD' : 'CNY')
                                        AND IsActive = true];
      for (PricebookEntry pbe : pbes) {
        system.debug('pbe.Product2.ProductCode:::::' + pbe.Product2.ProductCode);
        entries.put(pbe.Product2.ProductCode, pbe);
      }

      for (Integer l = 0; l < codelist.size(); l++) {
        system.debug('codelist[l]:::::' + codelist[l]);
        Product2 prd = mpProduct2.get(codelist[l]);
        if (prd != null) {
          PricebookEntry pbe = entries.get(codelist[l]);
          QELine c = null;
          if (pbe != null && (opp.Trade__c == '外貿' || opp.Trade__c == '内貿')) {
            if (opp.Trade__c == '外貿') {
              if (prd.Foreign_Trade_List_US__c > 0 && prd.Foreign_Trade_Cost_US__c > 0) {
                c = new QELine(i,prd.Is_DangerousChemicals__c,prd.CanNotCancelledGurantee__c, prd.VenderName__c,
                                prd.Estimated_ConsumptionDueDate__c,
                                pbe.Id, prd.Asset_Model_No__c, prd.StorageStatus__c, prd.ProductCode, prd.Id, prd.SFDA_Status__c, prd.Sales_Possibility__c, prd.Name, prd.BSSCategory__c,
                                Quantitylist[l], prd.Foreign_Trade_List_US__c, prd.Foreign_Trade_List_US__c, prd.Foreign_Trade_Cost_US__c, prd.Packing_list_manual__c
                              , prd.Entend_gurantee_period_all__c
                              , prd.Intra_Trade_Foreign_RMB__c
                              , prd.GuranteeType__c
                              , prd.NoDiscount_Foreign__c,
                              prd.Repair_Contract_USD__c
                              //chenjingwu DB202308355043 2023.8.25 start
                              , prd.Category5__c
                              //chenjingwu DB202308355043 2023.8.25 end
                              );

              } else {
                continue;
              }
            } else {
              if (prd.Intra_Trade_List_RMB__c > 0 && prd.Intra_Trade_Cost_RMB__c > 0) {
                c = new QELine(i,prd.Is_DangerousChemicals__c,prd.CanNotCancelledGurantee__c,prd.VenderName__c, 
                              prd.Estimated_ConsumptionDueDate__c,
                              pbe.Id, prd.Asset_Model_No__c, prd.StorageStatus__c, prd.ProductCode, prd.Id, prd.SFDA_Status__c, prd.Sales_Possibility__c, prd.Name, prd.BSSCategory__c,
                              Quantitylist[l], prd.Intra_Trade_List_RMB__c, prd.Intra_Trade_List_RMB__c, prd.Intra_Trade_Cost_RMB__c, prd.Packing_list_manual__c
                              , prd.Entend_gurantee_period_all__c
                              , prd.Intra_Trade_Gurantee_RMB__c
                              , prd.GuranteeType__c
                              , prd.Intra_Trade_Service_RMB__c
                              , prd.Maintenance_Price_Year__c
                              //chenjingwu DB202308355043 2023.8.25 start
                              , prd.Category5__c
                              //chenjingwu DB202308355043 2023.8.25 end
                              );

              } else {
                continue;
              }
            }
          } else {
            continue;
          }
          activities.add(c);
          i++;
          rightcnt++;
        }
      }
      // messageを出す
      errorflg = true;
      errormessage = '数据导入结束，导入 ' + codelist.size() + ' 件，成功' + rightcnt + ' 件';
      // pageArrange();

      return errormessage+'---'+JSON.serialize(activities);

    }
    //decide按钮
    @AuraEnabled
    public static Map<String,String> QuoteDecision(String activitiesCan,
                                                    String CheckItemCan ,
                                                    boolean WinOrDecideAlertc,
                                                    boolean productStatusUpdatedc,
                                                    String oppInfoc,
                                                    boolean enableSalesc,
                                                    String quoc,
                                                    String oppIdc,
                                                    String quoIdc,
                                                    boolean newQuoteFlagc,
                                                    Boolean changedAfterPrintc,
                                                    String quoteGurantee_Periodc,
                                                    String quotemultiYearWarrantyc,
                                                    String selection_hpc,
                                                    Boolean SkipQuotefilgc) {
      oppId = oppIdc;
      quoId = quoIdc;
      System.debug('quoId+'+quoId);
      WinOrDecideAlert = WinOrDecideAlertc;
      productStatusUpdated = productStatusUpdatedc;
      newQuoteFlag  = newQuoteFlagc;
      changedAfterPrint = changedAfterPrintc;
      quoteGurantee_Period = quoteGurantee_Periodc;
      quotemultiYearWarranty = quotemultiYearWarrantyc;
      selection_hp = selection_hpc;
      SkipQuotefilg = SkipQuotefilgc;
      opp = (Opportunity)JSON.deserialize(oppInfoc,Opportunity.class); 
      quo = (Quote)JSON.deserialize(quoc,Quote.class); 
      if(String.isNotBlank(activitiesCan)){
        activities = (List<QELine>)JSON.deserialize(activitiesCan,List<QELine>.class);
      }else {
          activities = null;
      }
      if(String.isNotBlank(CheckItemCan)){
        CheckItem = (List<QuoteLineItem>)JSON.deserialize(CheckItemCan,List<QuoteLineItem>.class);
      }else {
        CheckItem = null;
      }
      enableSales = enableSalesc;
      Savepoint sp = Database.setSavepoint();
      Map<String,String> result = new Map<String,String>();
      try {
        setOppFromOppInfo();
        errorflg = false;
        errormessage = null;
        errormessagewarn = null;
        if (!(opp.If_Account_Change__c != null ? opp.If_Account_Change__c : false)) {
          if(!ReservedProductVerification()){
            if(flglastbuy==1){
              errorflg = true;
              errormessage =  '预留产品表中没有该询价，请通过本部窗口联系营业管理课' ;
              result.put('errormessage', errormessage);
              return result;
            }else if(flglastbuy==2){
              errorflg = true;
              errormessage =  errorProductmodel+'产品数量不可超过产品预留数量' ;
              result.put('errormessage', errormessage);
              return result;
            }else if(flglastbuy==3){
              errorflg = true;
              errormessage =  '预留产品'+errorProductmodel+'未录入预留产品表';
              result.put('errormessage', errormessage);
              return result;
            }
          }
        }
        //chenjingwu DB202308355043 2023.8.25 start
        if(checkVirtual('包含虚拟产品，无法进行decide')){
          errorflg = true;
          result.put('errormessage', errormessage);
          return result;
        }
        //chenjingwu DB202308355043 2023.8.25 end
        if (checkIsQuoteTrial()) {
          errorflg = true;
          result.put('errormessage', errormessage);
          return result;
        }
        if (enableSales == true) {
          if (dataCheckDecide() == false) {
            result.put('errormessage', errormessage);
            result = resultFlag(result);
            if(hongzi){
              String act = JSON.serialize(activities);
              result.put('act', act);
            }
          return result;
          }
        }
        if (checkSFDAStatus2(true) == false) {
          errorflg = true;
          errormessage = '请更新不可销售的产品。';
          result.put('errormessage', errormessage);
          return result;
        }
        if (dataCheck() == false) {
          result.put('errormessage', errormessage);
          result = resultFlag(result);
          return result;
        }
        System.debug('oppId++'+oppId);
        if (dataEntry() == false) {
          result.put('errormessage', errormessage);
          return result;
        }
        if(SkipQuotefilg){
          errorflg = true;
          errormessage =  '产品配置或者经销商信息发生变化，已经生成新的报价单，请重新操作报价计算';
          quo.IsQuoteTrial__c = false;
          result.put('errormessage', errormessage);
          return result;
        }
        if (String.isBlank(oppId)) {
        } else {
          List<Opportunity> opps = [Select Id, Estimation_Decision__c From Opportunity Where Id = : oppId];

          if (opps.size() > 0) {
            opps[0].Estimation_Decision__c = true;
            StaticParameter.EscapeOppandStaTrigger = true;
            update opps[0];
            StaticParameter.EscapeOppandStaTrigger = false;
          }

          Quote q = new Quote();
          if(String.isBlank(quoId)){
            q = [select Id from Quote where Id = :quoIdreturn];
          }else{
            q = [select Id from Quote where Id = :quoId];
          }
          q.Quote_Decision_Date__c = date.Today();
          update q;
          result.put('success', System.Label.Message_002);
          if(String.isBlank(quoId)){
            result.put('quoId',quoIdreturn);
          }
          if(errormessagewarn != null){
            result.put('warn', errormessagewarn);
            String act = JSON.serialize(activities);
            result.put('act', act);
          }
          return result;
          
          // pageArrange();
        }
      } catch (DmlException de) {
        Database.rollback(sp);
        errorflg = true;
        errormessage = de.getDmlMessage(0);
        result.put('errormessage', errormessage);
        return result;
      } catch (Exception e) {
        Database.rollback(sp);
        errorflg = true;
        errormessage = e.getLineNumber()+':'+e.getMessage();
        result.put('errormessage', errormessage);
        return result;
      }

      return null;
    }
    //decide检查
    private static boolean dataCheckDecide() {
      Boolean error = false;
      errorflg = false;
      errormessage = null;
      errormessagewarn = null;
      if (quo.Dealer_Final_Price_Page__c == null) {
        // quo.Dealer_Final_Price__c.addError(System.Label.Error_Message3);
        String label = Schema.SObjectType.Quote.fields.Dealer_Final_Price__c.label;
        dfpp = true;
        error = true;
        errormessage = label+':'+System.Label.Error_Message3;
      }
      if (checkAgentsDeleteFlag() == false) {
        return false;
      }
      if (WinOrDecideAlert && (!productStatusUpdated)) {
        // PriceStatusUpdate();
      }
      if (opp.Agency1__c == null) {
        // opp.Agency1__c.addError(System.Label.Error_Message3);
        String label = Schema.SObjectType.Opportunity.fields.Agency1__c.label;
        error = true;
        Agency1 = true;
        errormessage = label+':'+System.Label.Error_Message3;
      }
      if (quo.OCM_Agent1_Price_Page__c == null || quo.OCM_Agent1_Price_Page__c == 0) {
        // quo.OCM_Agent1_Price__c.addError(System.Label.Error_Message3);
        String label = Schema.SObjectType.Quote.fields.OCM_Agent1_Price__c.label;
        error = true;
        oapp = true;
        errormessage = label+':'+System.Label.Error_Message3;
      }
      if (opp.Agency2__c == null && quo.Agent1_Agent2_Price_Page__c != null) {
        // opp.Agency2__c.addError(System.Label.Error_Message3);
        String label = Schema.SObjectType.Opportunity.fields.Agency2__c.label;
        error = true;
        Agency2 = true;
        errormessage = label+':'+System.Label.Error_Message3;
      }
      if (opp.Agency2__c != null && quo.Agent1_Agent2_Price_Page__c == null) {
        // quo.Agent1_Agent2_Price__c.addError(System.Label.Error_Message3);
        String label = Schema.SObjectType.Opportunity.fields.Agent1_Agent2_Price__c.label;
        error = true;
        aapp = true;
        errormessage = label+':'+System.Label.Error_Message3;
      }

      if (opp.If_Need_Authorize__c == true) {
        ID tmpid = opp.Agency2__c == null ? opp.Agency1__c : opp.Agency2__c;
        List<Account> accName = [select name from Account where id = : tmpid];
        if (accName[0].name != opp.Authorized_Finish_Sales__c) {
          error = true;
          errormessage =  '经销商未授权或授权未完成，请先授权。' ;
        }
      }
      if (opp.Trade__c == '内貿') {
        Map<Id, String> proMap = new Map<Id, String>();
        if (activities.size() > 0) {
          for (QELine qli : activities) {
            if (qli.Asset_Model != null && qli.Asset_Model != '') {
              proMap.put(qli.pageObject.Id__c, qli.PageObject.Name__c);
            }
          }
        }
        Map<String, String> chkMap = new Map<String, String>();
        if(!opp.Is_Corrosion__c){
          chkMap = OpportunityWebService.MapCheckProRegisterDecide(proMap, opp.Agency1__c, '');
        }
        System.debug('chkMap++'+chkMap);
        if (chkMap.size() > 0) {
          errorflg = true;
          error = true;
          if (chkMap.containsKey('agency')) {
            errormessage = '第一经销商没有有效的医疗器械经营许可证。';
          }
          Integer inerr = 0;
          if (activities.size() > 0) {
            for (QELine s : activities) {
              if (s.Asset_Model != null && s.Asset_Model != '') {
                if (chkMap.containsKey(s.PageObject.Id__c)) {
                  if (chkMap.get(s.PageObject.Id__c) == '1') {
                    s.haveno_Register = true;
                    inerr ++;
                  } else if (chkMap.get(s.PageObject.Id__c) == '2') {
                    s.wrong_Register = true;
                    inerr ++;
                  }
                }
              }
            }
          }
          if (inerr > 0) {
            errormessage = '请检查红字内容（NMPA状态红字，不可销售产品；产品名称红字，超过经销商经营范围）。';
            hongzi = true;
          }
          return false;
        }
        Boolean isDangerError = false;
        Boolean isNotDangerError = false;
        if (activities.size() > 0) {
          for (QELine qli : activities) {
            if (qli.Asset_Model != null && qli.Asset_Model != '') {
                if (opp.Is_Corrosion__c) {
                    if(!qli.Is_DangerousChemicals){
                      isNotDangerError =true;
                      qli.wrong_Register = true;
                    }

                }else{
                  if(qli.Is_DangerousChemicals){
                      isDangerError =true;
                      qli.wrong_Register = true;
                  }
                }
            }
          }
        }
        if (enableSales == true&&opp.Is_Corrosion__c&&opp.Trade__c == '内貿') {
          String str = OpportunityWebService.checkDangerItem(opp.agency1__c);
          if (str != 'OK') {
            error = true;
            errormessage = str;
          }
          if(isNotDangerError){
            error = true;
            errormessage = '当阿西塞多时，行项目的产品必须全选择危化品。';
          }
        }else if(!opp.Is_Corrosion__c){
          if(isDangerError){
            error = true;
            errormessage = '当询价不是阿西塞多时，行项目的产品不能选择危化品。';
          }
        }
      }
      if (error == true) {
        // PageArrange();
        errorflg = true;
        return false;
      } else {
        return true;
      }
    }
    //检查是否报价计算
    private static boolean checkIsQuoteTrial() {
      Boolean error = false;
      errorflg = false;
      errormessage = null;
      if(opp.If_Need_PriceApply__c){
        if(!quo.IsQuoteTrial__c){
          error = true;
          errormessage =  'decide报价还没进行报价试算，请先报价试算！' ;   
        }
        if(quoId !=null){
          boolean IsActivePsp = true;
          String errorPsp ='';
          List<PromotionSalesProducts__c> promotionSalesProductsList =[select id,PromotionSales__c,QuantityId__c,PromotionSales__r.name,PromotionSales__r.IsPolicyEffective__c,recordTypeName__c from PromotionSalesProducts__c where QuantityId__c=:  quoId];
          if(promotionSalesProductsList.size()>0){
            for(PromotionSalesProducts__c psp :promotionSalesProductsList){
              if(psp.PromotionSales__r.IsPolicyEffective__c == '无效'&&psp.recordTypeName__c!='NormalProduct'){
                  IsActivePsp =false;
                  errorPsp = psp.PromotionSales__r.name;
                  break;
              }
            }
          }
          if(!IsActivePsp){
            error = true;
            errormessage =  '报价试算中，选择的促销政策:'+errorPsp+',不在有效期内，请检查！' ;
          }
        }
      }
      return error;
    }
    //lastbuy检查
    public static boolean ReservedProductVerification() {
      filg=true;
      Map<string,QuoteLineItem> quotlinitMap = new Map<string,QuoteLineItem>();
      List<Id> lastProductFLGListId = new List<Id>();
      List<QuoteLineItem> lastProductFLGList = new List<QuoteLineItem>();
      List<QuoteLineItem> act = new List<QuoteLineItem>();
      List<QuoteLineItem> act2 = new List<QuoteLineItem>();
      for(QELine aaa :activities){
        if(aaa.pageObject.PricebookEntry.Product2Id!=null){
          act.add(aaa.pageObject);
        }
      }
      act2=act.deepClone();
      Map<String,QuoteLineItem> map1 = new Map<String,QuoteLineItem>();
      System.debug('activities1111111111112为所当为多多!!!'+activities);
      integer i =0;
      for(QuoteLineItem pspsc :act2){
        if(pspsc.PricebookEntry.Product2Id!=null){
          if(map1.containsKey(pspsc.PricebookEntry.Product2Id)){
            QuoteLineItem quoteLine = map1.get(pspsc.PricebookEntry.Product2Id);
            quoteLine.Quantity__c =quoteLine.Quantity__c+pspsc.Quantity__c;
            map1.put(pspsc.PricebookEntry.Product2Id,quoteLine);
          }else{
            map1.put(pspsc.PricebookEntry.Product2Id,pspsc);
          }
          System.debug('34499879!!!'+activities);
        }
      }
      System.debug('3434343!!!'+activities);
      System.debug('5656565!!!'+map1);
      for (QuoteLineItem value : map1.values()) {
        if(value.PricebookEntry.Product2.LastbuyProductFLG__c){
          lastProductFLGListId.add(value.PricebookEntry.Product2Id);
          quotlinitMap.put(value.PricebookEntry.Product2Id,value);
          lastProductFLGList.add(value);
        }
      }
      System.debug('activities++++!!!'+activities);
      System.debug('activities!!!'+map1.values());
      System.debug('oppId!!!'+oppId);
      System.debug('lastProductFLGList!!!'+lastProductFLGListId);
      if(lastProductFLGListId!=null&&lastProductFLGListId.size()!=0){
          List<LastbuyProduct__c> LastbuyObjList=[select id,LastbuyQuantity__c,InquiryCode__c,ProductName__c,effectiveFLG__c from LastbuyProduct__c where InquiryCode__c= : oppId and ProductName__c in :lastProductFLGListId and effectiveFLG__c = true];
          Map<string,LastbuyProduct__c> LastbuyObjMap = new Map<string,LastbuyProduct__c>();
          System.debug('LastbuyObjList+++++!!!'+LastbuyObjList);
          if(LastbuyObjList!=null&&LastbuyObjList.size()!=0){
            for(LastbuyProduct__c lastbuypr :LastbuyObjList){
              LastbuyObjMap.put(lastbuypr.ProductName__c,lastbuypr);
            }
          }else{
            flglastbuy=1;
            filg=false;
            return filg;
          }
          System.debug('LastbuyObjMap!!!'+LastbuyObjMap);
          System.debug('lastProductFLGList+++++++!!!'+lastProductFLGList);
          if(lastProductFLGList!=null&&lastProductFLGList.size()!=0){
            for(QuoteLineItem lastbuypr :lastProductFLGList){
              Decimal quoteLItemNum=0;
              if(LastbuyObjMap.containsKey(lastbuypr.PricebookEntry.Product2Id)){
                  quoteLItemNum=LastbuyObjMap.get(lastbuypr.PricebookEntry.Product2Id).LastbuyQuantity__c;
                  System.debug('quoteLItemNum!!!'+quoteLItemNum);
                  System.debug('lastbuypr.pageObject.Quantity__c+++!!!'+lastbuypr.Quantity__c);
                  if(lastbuypr.Quantity__c>quoteLItemNum){
                    errorProductmodel=lastbuypr.Asset_Model_No__c;
                    flglastbuy=2;
                    filg=false;
                    break;
                  }
              }else{
                errorProductmodel=lastbuypr.Asset_Model_No__c;
                flglastbuy=3;
                filg=false;
                break;
              }
            }
          }
      }
      system.debug('filg====='+filg);
      return filg;
    }
    // CHAN-AVG3PW 询价报价画面规则变更
    // 报价创建日超过三个月时，如产品停产或CFDA失效，不可以保存，提示“请更新停止销售的产品”
    //             做DECIDE时，如产品停产或CFDA失效，不可以保存，提示“请更新停止销售的产品”
    private static boolean checkSFDAStatus2(boolean dodecide) {
      for (QELine a : activities) {
        if ((a.Asset_Model != null) && (a.Asset_Model != '')) {
          if (a.PageObject.SFDA_Status__c != '有効' &&
              a.PageObject.SFDA_Status__c != '有効（再申請中）' &&
              a.PageObject.SFDA_Status__c != '不要' &&
              a.PageObject.SFDA_Status__c != '暂停出库（短期）' &&
              a.PageObject.SFDA_Status__c != '失効（期限内生産済在庫対応）'
            ) {
            return false;
          }
        }
      }
      return true;
    }
    // DB202307431108 报价单】经销商1合同金额默认值规则修改 fy start
    public static String getValueFromJSONStringPlus(String jsonstring,String key,String key1) {
      if (String.isNotBlank(jsonstring)) {
        Map<String, Object> map1 = (Map<String, Object>) JSON.deserializeUntyped(jsonstring);
        Map<String, Map<String,Object>> mapping = new Map<String, Map<String,Object>>();
        for (String str : map1.keySet()) {
          Map<String,Object> mapvalue = (Map<String,Object>) map1.get(str);
          mapping.put(str, mapvalue);
        }
        return mapping.get(key) != null ? (mapping.get(key).get(key1) !=null ? String.valueOf(mapping.get(key).get(key1)) :( mapping.get(key).get('Other') !=null ? String.valueOf(mapping.get(key).get('Other')):null)) : (mapping.get('Default') != null ? (mapping.get('Default').get(key1) !=null ? String.valueOf(mapping.get('Default').get(key1)) : (mapping.get('Default').get('Other') != null ? String.valueOf(mapping.get('Default').get('Other')):null)): null);
      }
      return null;
    }
    //下拉列表值获取共通
    @AuraEnabled
    public static InitData getModulus(String oppInfoc){
      opp = (Opportunity)JSON.deserialize(oppInfoc,Opportunity.class); 
      InitData res = new InitData();
      String str_rate_hospital = ControllerUtil.getValueFromJSONString(System.Label.Quote_HospitalAmount_Rate, opp.Salesdepartment_Owner__c);
      String str_rate_agency1 = lexNewQuoteEntryController.getValueFromJSONStringPlus(System.Label.Quote_Agency1Amount_Rate, opp.Salesdepartment_Owner__c,opp.Opportunity_Category__c);
      res.rate_hospital = String.isNotBlank(str_rate_hospital) ? Decimal.valueOf(str_rate_hospital) : 1.0;
      res.rate_agency1 = String.isNotBlank(str_rate_agency1) ? Decimal.valueOf(str_rate_agency1) : 1.0;
      return res;
    }
    //chenjingwu DB202308355043 2023.8.25 start
    public static Boolean checkVirtual(String message){
      
      List<String> idList = new List<String>();
      for (QELine s : activities) {
        if (String.isNotBlank(s.Category5) && s.Category5 == '虚拟') {
          idList.add(s.Category5);
        }
        System.debug('Category5+'+s.Category5);
      }
      if(idList.size() > 0){
        errorMessage = message;
        return true;
      }
      return false;
    }
    //chenjingwu DB202308355043 2023.8.25 end
    public class InitData{
      @AuraEnabled
      public Decimal rate_hospital;
      @AuraEnabled
      public Decimal rate_agency1;
    }
    //行项目自定义结构
    //行项目原值
    public class QELinelatestInfo {
        public String ProductCode { get; set; }
        public String ProductName { get; set; }
        public String SFDA_Status { get; set; }
        public String Sales_Possibility { get; set; }
        public Decimal ListPrice { get; set; }
        public Decimal Cost { get; set; }
        public Integer Specifications {get; set;}
        public string GuranteeType {get; set;}
        public Decimal Intra_Trade_Gurantee {get; set;}
        public Decimal ProductEntend_gurantee_period_all {get; set;}
        public Decimal Intra_Trade_Service {get; set;}
        public Decimal Maintenance_Price_Year {get; set;}
        public Boolean CanNotCancelledGurantee {get; set;}
        public Boolean Is_DangerousChemicals {get; set;}
    }
    //行项目新值
    public class QELine {
        public Integer lineNo;   
        public String Asset_Model;
        public String Sales_Possibility;          
        public QuoteLineItem pageObject;              
        public Decimal Cost_c;
        public Decimal Cost_Subtotal_c;
        public Decimal ListPrice_Page;
        public String StorageStatus;
        public Integer Specifications;
        public String VenderName;
        public Boolean CanNotCancelledGurantee;
        public Boolean Is_DangerousChemicals;
        public QELinelatestInfo latestInfo;
        public boolean changed_name;
        public boolean changed_sfda;
        public boolean changed_list;
        public boolean changed_cost;
        public boolean haveno_Register;
        public boolean wrong_Register;
        public String Estimated_ConsumptionDueDate;
        public Decimal GuranteePrice;
        public Decimal ProductGuranteePrice;
        public decimal Maintenance_Price_Year;
        public String Category5;
        public QELine(){}
        public QELine(QuoteLineItem qli, Integer i, String copyQuoId) {
            this.lineNo = i;
            pageObject = qli.clone();
            pageObject.Id__c = qli.PricebookEntry.Product2Id;
            pageObject.Quantity__c = qli.Quantity;
            if (String.isNotBlank(copyQuoId)) {
              pageObject.SFDA_Status__c = qli.PricebookEntry.Product2.SFDA_Status__c;
              pageObject.Name__c = qli.PricebookEntry.Product2.Name;
            }
            //chenjingwu DB202308355043 2023.8.25 start
            Category5 = qli.PricebookEntry.Product2.Category5__c;
            //chenjingwu DB202308355043 2023.8.25 end
            this.Asset_Model = qli.Asset_Model_No__c;
            if (qli.Cost__c > 0 && qli.Quantity > 0) {
              this.Cost_Subtotal_c = qli.Cost__c * qli.Quantity;
            }
            this.VenderName = qli.PricebookEntry.Product2.VenderName__c;
            if(qli.PricebookEntry.Product2.Estimated_ConsumptionDueDate__c != null){
              this.Estimated_ConsumptionDueDate = NFMUtil.formatDate2StrSpo(qli.PricebookEntry.Product2.Estimated_ConsumptionDueDate__c).replaceAll('-','/');
            }else{
              this.Estimated_ConsumptionDueDate = '';
            }
            if(VenderName==null||VenderName==''){
                this.VenderName =' 无 ';
            }
            this.CanNotCancelledGurantee = qli.PricebookEntry.Product2.CanNotCancelledGurantee__c;
            this.Is_DangerousChemicals = qli.PricebookEntry.Product2.Is_DangerousChemicals__c;
            this.StorageStatus = qli.PricebookEntry.Product2.StorageStatus__c;
            this.ListPrice_Page = qli.ListPrice__c;
            this.Cost_c = qli.Cost__c;
            pageObject.Subtotal__c = qli.TotalPrice__c;
            pageObject.UnitPrice_Page__c = qli.UnitPrice__c;
            latestInfo = new QELinelatestInfo();
            latestInfo.ProductCode = qli.ProductCode__c;
            latestInfo.ProductName = qli.PricebookEntry.Product2.Name;
            latestInfo.SFDA_Status = qli.PricebookEntry.Product2.SFDA_Status__c;
            latestInfo.ProductEntend_gurantee_period_all    =  qli.PricebookEntry.Product2.Entend_gurantee_period_all__c;
            if(qli.Quote.Opportunity.Trade__c == '内貿'){
              latestInfo.Intra_Trade_Gurantee             =  qli.PricebookEntry.Product2.Intra_Trade_Gurantee_RMB__c;
              latestInfo.Intra_Trade_Service             =  qli.PricebookEntry.Product2.Intra_Trade_Service_RMB__c;
              if(qli.PricebookEntry.Product2.Maintenance_Price_Year__c == null){
                latestInfo.Maintenance_Price_Year = 0;
              }else{
                latestInfo.Maintenance_Price_Year = qli.PricebookEntry.Product2.Maintenance_Price_Year__c;
              }
            }else if(qli.Quote.Opportunity.Trade__c == '外貿'){
                latestInfo.Intra_Trade_Gurantee             =  qli.PricebookEntry.Product2.Intra_Trade_Foreign_RMB__c;
                latestInfo.Intra_Trade_Service              =  qli.PricebookEntry.Product2.NoDiscount_Foreign__c;
                if(qli.PricebookEntry.Product2.Maintenance_Price_Year__c == null){
                  latestInfo.Maintenance_Price_Year = 0;
                }else{
                  latestInfo.Maintenance_Price_Year = qli.PricebookEntry.Product2.Repair_Contract_USD__c;
                }
            }
            latestInfo.GuranteeType                         =  qli.PricebookEntry.Product2.GuranteeType__c;
            latestInfo.CanNotCancelledGurantee  = qli.PricebookEntry.Product2.CanNotCancelledGurantee__c;
            this.Maintenance_Price_Year                     = qli.Maintenance_Price_Year__c;
            this.GuranteePrice                              =  qli.GuranteePrice__c;
            this.ProductGuranteePrice                       =  qli.ProductGuranteePrice__c;
            latestInfo.Sales_Possibility = qli.PricebookEntry.Product2.Sales_Possibility__c;
            if (qli.PricebookEntry.Product2.Packing_list_manual__c != null) {
              latestInfo.Specifications = integer.valueof(qli.PricebookEntry.Product2.Packing_list_manual__c + '');
            }
            latestInfo.ListPrice = qli.Product_ListPrice__c;
            latestInfo.Cost = qli.Product_Cost__c;
            if (qli.PricebookEntry.Product2.Packing_list_manual__c != null) {
              this.Specifications = integer.valueof(qli.PricebookEntry.Product2.Packing_list_manual__c + '');
            }
            this.changed_name = false;
            this.changed_sfda = false;
            this.changed_list = false;
            this.changed_cost = false;
            this.haveno_Register = false;
            this.wrong_Register  = false;
        }
        public QELine(Integer i,Boolean Is_DangerousChemicals,Boolean CanNotCancelledGurantee,String VenderName,
                  Date Estimated_ConsumptionDueDate,
                  String PricebookEntryId,
                  String Asset_Model, String StorageStatus,
                  String ProductCode, String Id_c,
                  String SFDA_Status_c, String Sales_Possibility_c,
                  String Name_c, String BSS_Category_c,
                  Integer Quantity, Decimal ListPrice_c,
                  Decimal UnitPrice_c, Decimal Cost_c,
                  Decimal Packing_list_manual
                  , Decimal Entend_gurantee_period_all
                  , decimal ProductGuranteePrice
                  , string GuranteeType
                  , Decimal productServicePrice
                  , Decimal productMaintenance_Price_Year
                  //chenjingwu DB202308355043 2023.8.25 start
                  ,String Category5
                  //chenjingwu DB202308355043 2023.8.25 end
                 ) {
            pageObject = New QuoteLineItem();
            pageObject.Quantity__c = Quantity;
            this.lineNo = i;
            this.Asset_Model = Asset_Model;
            this.Sales_Possibility = Sales_Possibility_c;
            if(Estimated_ConsumptionDueDate != null){
              this.Estimated_ConsumptionDueDate = NFMUtil.formatDate2StrSpo(Estimated_ConsumptionDueDate).replaceAll('-','/');
            }else{
              this.Estimated_ConsumptionDueDate = '';
            }
            this.StorageStatus = StorageStatus;
            pageObject.Id__c = Id_c;
            pageObject.SFDA_Status__c = SFDA_Status_c;
            pageObject.Name__c = Name_c;
            pageObject.BSS_Category__c = BSS_Category_c;
            this.ListPrice_Page = ListPrice_c;
            pageObject.UnitPrice_Page__c = UnitPrice_c;
            pageObject.Subtotal__c = UnitPrice_c * Quantity;
            //chenjingwu DB202308355043 2023.8.25 start
            Category5 = Category5;
            //chenjingwu DB202308355043 2023.8.25 end
            if(VenderName==null||VenderName==''){
                this.VenderName =' 无 ';
            }else{
                this.VenderName = VenderName;
            }
            this.CanNotCancelledGurantee = CanNotCancelledGurantee;
            this.Is_DangerousChemicals = Is_DangerousChemicals;
            pageObject.ProductEntend_gurantee_period_all__c = Entend_gurantee_period_all;
            pageObject.productServicePrice__c               = productServicePrice;
            pageObject.GuranteeType__c                      = GuranteeType;
            this.ProductGuranteePrice                       =  ProductGuranteePrice;
            this.Maintenance_Price_Year                     = productMaintenance_Price_Year;
            this.Cost_c = Cost_c;
            this.Cost_Subtotal_c = Cost_c * Quantity;
            pageObject.PricebookEntryId = PricebookEntryId;
            latestInfo = New QELinelatestInfo();
            latestInfo.ProductCode = ProductCode;
            latestInfo.ProductName = Name_c;
            latestInfo.SFDA_Status = SFDA_Status_c;
            latestInfo.Sales_Possibility = Sales_Possibility_c;
            latestInfo.ListPrice = this.ListPrice_Page;
            latestInfo.Cost = pageObject.Cost__c;
            latestInfo.ProductEntend_gurantee_period_all    =  Entend_gurantee_period_all;
            latestInfo.Intra_Trade_Gurantee             =  ProductGuranteePrice;
            latestInfo.Intra_Trade_Service              =  productServicePrice;
            latestInfo.GuranteeType                         =  GuranteeType;
            latestInfo.Maintenance_Price_Year               =  productMaintenance_Price_Year;
            latestInfo.CanNotCancelledGurantee = CanNotCancelledGurantee;
            latestInfo.Is_DangerousChemicals = Is_DangerousChemicals;
            if (Packing_list_manual != null) {
              latestInfo.Specifications = integer.valueof('' + Packing_list_manual);
            }
            if (Packing_list_manual != null) {
              this.Specifications = integer.valueof('' + Packing_list_manual);
            }
            this.changed_name = false;
            this.changed_sfda = false;
            this.changed_list = false;
            this.changed_cost = false;
            this.haveno_Register = false;
            this.wrong_Register  = false;
          }
    }
}