/* 备品智能化 ADD by dzk
   OPD计划备品借出明细页面
   同步报价产品按钮
*/
public without sharing class LexOPDPlanProdController {
     @AuraEnabled
    public static OPDPlan__c  init(String recordId){
        OPDPlan__c opd = new OPDPlan__c();
        try{
            opd = [SELECT Id,Status__c,Name,Related_Opportunity1_ID__c
                    FROM OPDPlan__c 
                    WHERE Id=:recordId];
            return opd;
        }
        catch(Exception e){
            System.debug(LoggingLevel.INFO, '*** e: ' + e);
            return null;
        }
    }

    @AuraEnabled(cacheable=true)
    public static OPDPlan__c  initOriginal(String recordId){
        OPDPlan__c opd = new OPDPlan__c();
        try{
            opd = [SELECT Id,Status__c,Name,Related_Opportunity1_ID__c,OriginalOpdPlanApplication__c
                    FROM OPDPlan__c 
                    WHERE Id=:recordId];
            return opd;
        }
        catch(Exception e){
            System.debug(LoggingLevel.INFO, '*** e: ' + e);
            return null;
        }
    }
    //2023-10-11 ADD by dzk Start 获取OPD计划的计划出借备品数据
    @AuraEnabled(cacheable=true)
    public static List<ProLine> initPRE(String recordId){
        try{
            System.debug('recordId' + recordId);
            List<ProLine> proList = new List<ProLine>();
            if (String.isBlank(recordId)) {
                return proList;
            }
            List<Plan_Rental_Equipment__c> planREList = new List<Plan_Rental_Equipment__c>();
            // 优化获取数据方案
            // 1.判断recordId属于哪个对象
            Id objId = recordId;
            SObjectType objType = objId.getSObjectType();
             //zzm 20240301 延期再延期后明细bug start
            if(objType.getDescribe().getName() == 'Event' && String.isNotBlank(recordId)) {
                List<Event> eventList = [select id ,OPD_Plan__c from Event where id=:recordId limit 1];
                if(eventList.size() > 0 ) {
                    recordId = eventList[0].OPD_Plan__c;
                    objId = recordId;
                    objType = objId.getSObjectType();
                }
            }
            //zzm 20240301 延期再延期后明细bug end
            String rcdType = objType != null ? objType.getDescribe().getName() : 'OPD_Plan__c'; // 如果取不到的话就用opd计划
            // 2.拼接soql
            String querySoql = '';
            querySoql += 'SELECT Id, Name, ProductCode__c, '; 
            querySoql += 'MDM_Model_No__c, FixtureModel__c, ';
            querySoql += 'Rental_Quantity__c, Rental_Equipment__c, ';
            querySoql += 'Quote_No__c, Quote__c ';
            querySoql += 'FROM Plan_Rental_Equipment__c ';
            querySoql += 'WHERE ';
            querySoql += rcdType == 'Campaign' ? 'Campaign__c' : rcdType == 'Event' ? 'Event_ID__c' : 'OPD_Plan__c';
            querySoql += ' = :recordId';
            System.debug('querySoql: ' + querySoql);
            planREList = Database.query(querySoql);
            System.debug('planREList: ' + planREList);
            // 3.补充行项目
            for(Plan_Rental_Equipment__c pre : planREList){
                ProLine pro = new ProLine();
                pro.Name = pre.Rental_Equipment__c;
                pro.Id = pre.Id;
                pro.Quantity = Integer.valueOf(pre.Rental_Quantity__c);
                pro.ProductCode = pre.ProductCode__c;
                pro.ProductModel = pre.MDM_Model_No__c;
                pro.QuoteNo = pre.Quote_No__c;
                pro.QuoteId = pre.Quote__c;
                pro.FixtureModel = pre.FixtureModel__c;
                proList.add(pro);
            }
            return proList;
        }
        catch(Exception e){
            System.debug(LoggingLevel.INFO, '*** e: ' + e  + e.getLineNumber() + '行');
        }
        return null;
    }
     //2023-10-11 ADD by dzk End 获取OPD计划的计划出借备品数据

    //2023-10-12 ADD by dzk Start 获取当前用户是否拥有OPD计划的编辑权限
    @AuraEnabled(cacheable=true)
    public static Boolean getEditPermission(String recordId){
        try{
            Boolean editPermission;
            UserRecordAccess useraccess = [SELECT recordId,HasEditAccess 
                                            FROM UserRecordAccess 
                                            WHERE userId = :UserInfo.getUserId() 
                                            AND recordId = :recordId];
            editPermission = useraccess.HasEditAccess;
            List<OPDPlan__c> recordList = [SELECT Id FROM OPDPlan__c WHERE Id = :recordId];
            // 判断是当前数据属于学会还是OPD计划
            if (!recordList.isEmpty()) {
                OPDPlan__c opdRecord = [SELECT Id,Status__c FROM OPDPlan__c WHERE Id = :recordId]; 
                // 状态为非草案中的场合,不允许操作数据页面
                if ((!('草案中').equals(opdRecord.Status__c)) && editPermission) {
                    editPermission = FALSE;
                }
            }else{
               Campaign camRecord = [SELECT Id,Status FROM Campaign WHERE Id = :recordId]; 
               // 状态为非草案中的场合,不允许操作数据页面
               if ((!('草案中').equals(camRecord.Status))) {
                    editPermission = FALSE;
                }else{
                    editPermission = TRUE; 
                }
               
            }
            return editPermission;
        }
        catch(Exception e){
            System.debug(LoggingLevel.INFO, '*** e: ' + e  + e.getLineNumber() + '行');
        }
        return null;
    }
    // 2023-10-11 ADD by dzk End 获取当前用户是否拥有OPD计划的编辑权限

    // 2023-10-14 ADD by dzk Start OPD或学会保存计划备品明细页面数据
    @AuraEnabled
    public static String  saveProductData(String recordId, String records){
        String planNotFromDetai = '';
        String planFromDetai = '';
        String planSysDetai = '';
        OPDPlan__c opdData = new OPDPlan__c();
        Campaign camData = new Campaign();
            
        List<Plan_Rental_Equipment__c> planREDeleteList = new List<Plan_Rental_Equipment__c>();
        List<Plan_Rental_Equipment__c> planREInsertList = new List<Plan_Rental_Equipment__c>();
        List<Plan_Rental_Equipment__c> planREList = new List<Plan_Rental_Equipment__c>();

        // 获取记录类型ID
        Id planRERecordTypeOtherId = Schema.SObjectType.Plan_Rental_Equipment__c.getRecordTypeInfosByDeveloperName().get('Other').getRecordTypeId();
        Id planRERecordTypeCampaignId = Schema.SObjectType.Plan_Rental_Equipment__c.getRecordTypeInfosByDeveloperName().get('campaign').getRecordTypeId();
        Map<String,ProLine> ProLineMap = new Map<String,ProLine>();
        Map<String,Plan_Rental_Equipment__c> planREMap = new Map<String,Plan_Rental_Equipment__c>();

        try{
            // 解析LWC页面传过来的数据
            List<ProLine> ProLineList = 
            (List<ProLine>)System.JSON.deserialize(records, List<ProLine>.class);
            List<OPDPlan__c> recordList = [SELECT Id FROM OPDPlan__c WHERE Id = :recordId];
                if (!recordList.isEmpty()) {
                    // 获取当前OPD计划中的计划出借备品数据
                    planREList = [SELECT Id,Name,MDM_Model_No__c,ProductCode__c,FixtureModel__c 
                                        FROM Plan_Rental_Equipment__c
                                        WHERE OPD_Plan__c =: recordId];
                    opdData = [SELECT Id,PlanProdDetail__c FROM OPDPlan__c WHERE Id =: recordId];

                }else{
                    // 获取当前学会中的计划出借备品数据
                    planREList = [SELECT Id,Name,MDM_Model_No__c,ProductCode__c,FixtureModel__c 
                                        FROM Plan_Rental_Equipment__c
                                        WHERE Campaign__c = :recordId];

                    camData = [SELECT Id,LoadNum__c FROM Campaign WHERE Id =: recordId];
                }
                
                // 判断是否存在报价
                for(ProLine pro : ProLineList){
                    ProLineMap.put(pro.ProductCode, pro);
                    if(pro.QuoteNo == null){
                        planNotFromDetai += pro.ProductModel + '*' + pro.Quantity + '; ';
                    }else{
                        planFromDetai += pro.ProductModel + '*' + pro.Quantity + '; ';
                    }
                    if(String.isNotBlank(pro.FixtureModel)){
                        planSysDetai += pro.FixtureModel + '*' + pro.Quantity + '; ';
                    }
                    
                }   
                for(Plan_Rental_Equipment__c planRE : planREList){
                    planREMap.put(planRE.ProductCode__c, planRE);
                }
               
                for(Plan_Rental_Equipment__c planRE : planREList){ 
                    if (ProLineMap.get(planRE.ProductCode__c) == null) {
                        Plan_Rental_Equipment__c planREDelete = new Plan_Rental_Equipment__c();
                        planREDelete.Id = planRE.Id;
                        planREDeleteList.add(planREDelete);
                    }   
                }
                Delete planREDeleteList;
                for(ProLine proInsert : ProLineList){
                    if (planREMap.get(proInsert.ProductCode) == null) {
                        Plan_Rental_Equipment__c planREInsert = new Plan_Rental_Equipment__c();
                        planREInsert.Name = proInsert.Name;
                        planREInsert.Rental_Equipment__c = proInsert.Name;
                        // 判断是当前数据属于学会还是OPD计划
                        if (!recordList.isEmpty()) {
                            planREInsert.OPD_Plan__c = recordId;
                            planREInsert.RecordTypeId = planRERecordTypeOtherId;
                        }else{
                            planREInsert.Campaign__c = recordId;
                            planREInsert.RecordTypeId = planRERecordTypeCampaignId;
                        }
                        planREInsert.ProductCode__c = proInsert.ProductCode;
                        planREInsert.MDM_Model_No__c = proInsert.ProductModel;
                        planREInsert.Rental_Quantity__c = '1';
                        planREInsert.FixtureModel__c = proInsert.FixtureModel;
                        planREInsertList.add(planREInsert);
                    }  
                }
                Insert planREInsertList;
                if (!recordList.isEmpty()) {
                    opdData.PlanProdDetail__c = planFromDetai + planNotFromDetai;
                    opdData.EquipmentNotFromOpp__c = planNotFromDetai;
                    opdData.EquipmentFromOpp__c = planFromDetai;
                    opdData.PlanProdDetailSys__c = planSysDetai;
                    opdData.PlanProdDetailSysT__c = planSysDetai.length() > 255 ? planSysDetai.substring(0, 255):planSysDetai; // 计划出借战略产品文本 add by ljh 20240302
                    update opdData;
                }else{
                    camData.LoadNum__c = planNotFromDetai + planFromDetai;
                    update camData;
                } 
            // }
            
            return '保存成功';
         }catch(Exception e){
            System.debug(LoggingLevel.INFO, '*** e: ' + e);
            return e.getMessage();
        }
    }
    // 2023-10-15 ADD by dzk End OPD或学会保存计划备品明细页面数据

    // 2023-11-20 ADD by dzk Start 获取符合出借备品条件的奥林巴斯产品
    @AuraEnabled
    public static List<ProLine>  getProductData(String recordId, String event_in,String records, String productmodel){//zzm 20240226 事件产品bug修复
        try{
            Set<String> proModelSet = new Set<String>();
            List<ProLine> proLineList = new List<ProLine>();
            List<Product2> proList = new  List<Product2>();
            //获取奥林巴斯产品记录类型ID
            Id productOlympusProductsRecordTypeId = Schema.SObjectType.Product2.getRecordTypeInfosByDeveloperName().get('OlympusProducts').getRecordTypeId();

            List<ProLine> ProLineNowList = 
            (List<ProLine>)System.JSON.deserialize(records, List<ProLine>.class);
            List<OPDPlan__c> recordList = [SELECT Id, RentalReson__c,
                                                  OriginalOpdPlanApplication__c,
                                                  OriginalOpdPlanApplication__r.RentalReson__c 
                                                  FROM OPDPlan__c WHERE Id =: recordId];
            String rentalReson;
            
            if(records != null){
                for(ProLine proNow : ProLineNowList){
                    proModelSet.add(proNow.ProductCode);
                } 
            }
    
            String query = 'SELECT Id,Name,ProductCode,Key_product_147P__c,Fixture_Model_No_T__c FROM Product2';
            query += ' WHERE RecordTypeId = \'' + productOlympusProductsRecordTypeId + '\'';
            query += ' AND Fixture_Model_No_F__c != null';
            query += ' AND ProductCode !=: proModelSet';
            query += ' AND Category5__c Not IN (\'虚拟\') ';
            query += ' AND IsActive = true';
           
            // 产品型号不为空时,查询。
            if(String.isNotBlank(productmodel)){
                 query += ' AND (Fixture_Model_No_T__c like \'%' + productmodel + '%\' OR ProductCode like \'%' + productmodel + '%\' OR Name like \'%' + productmodel + '%\')';
            }
            // 区分是来自OPD计划或者询价
            if (!recordList.isEmpty()) {
                if(recordList[0].RentalReson__c == '追加配套'){
                    rentalReson = recordList[0].OriginalOpdPlanApplication__r.RentalReson__c;
                }else{
                    rentalReson = recordList[0].RentalReson__c;
                }   
                
                // 区分OPD计划出借目的,查询。
                if(rentalReson == 'OPD' || rentalReson == '对应修理' ){
                    query += ' AND Loaner_categoryII__c NOT IN (\'模型\') ';
                    query += ' AND RentalSubject__c = true';
                    query += ' AND ((SFDA_Status__c Not IN (\'停止\') OR Manual_Entry__c = true) ';
                    query += ' OR (SFDA_Status__c IN (\'停止\') AND Manual_Entry__c = false AND Loaner_categoryII__c IN (\'台车\',\'监视器\',\'录像设备\')))';
                }else if(rentalReson == '模型出借'){
                    query += ' AND Loaner_categoryII__c IN (\'模型\') ';
                    query += ' AND RentalSubject__c = true';
                    query += ' AND ((SFDA_Status__c Not IN (\'停止\') OR Manual_Entry__c = true)) ';
                }else if(rentalReson == '演示' || rentalReson == '新产品评价'){
                    query += ' AND (Loaner_categoryII__c NOT IN (\'模型\') ';
                    query += ' AND RentalSubject__c = true)';
                } else {
                    query += ' AND RentalSubject__c = true';
                    query += ' AND Loaner_categoryII__c Not IN (\'模型\') ';
                    query += ' AND ((SFDA_Status__c Not IN (\'停止\') OR Manual_Entry__c = true) ';
                    query += ' OR (SFDA_Status__c IN (\'停止\') AND Manual_Entry__c = false AND Loaner_categoryII__c IN (\'台车\',\'监视器\',\'录像设备\')))';
                }
            }else if(event_in == 'event'){ //zzm 20240226 事件产品bug修复
                query += ' AND RentalSubject__c = true ';
                query += ' AND Loaner_categoryII__c NOT IN (\'模型\') '; 
                query += ' AND ((SFDA_Status__c Not IN (\'停止\') OR Manual_Entry__c = true) ';      
                query += ' OR (SFDA_Status__c IN (\'停止\') AND Manual_Entry__c = false AND Loaner_categoryII__c IN (\'台车\',\'监视器\',\'录像设备\')))';
            } else {
                query += ' AND (Loaner_categoryII__c Not IN (\'模型\') ';
                query += ' AND RentalSubject__c = true)';
            }
            query += ' Limit 150 ';
            System.debug('query-----------' + query);
            proList = Database.query(query);
            for(Product2 pro : proList){
                ProLine proline = new ProLine();
                proline.Name = pro.Name;
                proline.ProductCode = pro.ProductCode;
                proline.ProductModel = pro.Fixture_Model_No_T__c;
                proline.Id = pro.Id;
                proline.Quantity = 1;
                if(String.isNotBlank(pro.Key_product_147P__c)){
                    proline.FixtureModel = pro.Key_product_147P__c.substring(3);
                }
                proLineList.add(proline);
            }
            return proLineList;
        }
        catch(Exception e){
            System.debug(LoggingLevel.INFO, '*** e: ' + e + e.getLineNumber() + '行');
            return null;
        }
    }
    // 2023-10-20 ADD by dzk End 获取符合出借备品条件的奥林巴斯产品 

    // 2023-10-30 ADD by dzk Start 同步报价产品按钮
    // 获取OPD计划——询价——报价——报价行项目数据
    @AuraEnabled(cacheable=true)
    public static List<ProLine>  initGetQuoteProLine(String recordId){
        try{
            OPDPlan__c opdList = [SELECT Id,RentalReson__c,Related_Opportunity1_ID__r.Estimation_Id__c,OriginalOpdPlanApplication__r.RentalReson__c FROM OPDPlan__c WHERE Id =: recordId];
            Id productOlympusProductsRecordTypeId = Schema.SObjectType.Product2.getRecordTypeInfosByDeveloperName().get('OlympusProducts').getRecordTypeId();
            String rentalReson = opdList.RentalReson__c;
            if(opdList.RentalReson__c == '追加配套'){
                rentalReson = opdList.OriginalOpdPlanApplication__r.RentalReson__c;
            }

            List<ProLine> proList = new List<ProLine>();
            String query = 'SELECT Id, Quantity, Product2.Key_product_147P__c, Product2.Name, Product2.ProductCode, Product2.Fixture_Model_No_T__c, OppIsLendMark__c, Product2.RentalSubject__c, QuoteId,Quote.Quote_No__c FROM QuoteLineItem';
            query += ' WHERE Product2.RecordTypeId = \'' + productOlympusProductsRecordTypeId + '\'';
            query += ' AND Product2.Fixture_Model_No_F__c != null';
            query += ' AND QuoteId = \'' + opdList.Related_Opportunity1_ID__r.Estimation_Id__c + '\'';
            query += ' AND Product2.Category5__c Not IN (\'虚拟\') ';
            query += ' AND Product2.IsActive = true';
            // OPD计划出借目的为模型时,查询。
            if(rentalReson == 'OPD' ||rentalReson == '对应修理'){
                query += ' AND Product2.Loaner_categoryII__c NOT IN (\'模型\') ';
                query += ' AND Product2.RentalSubject__c = true';
                query += ' AND ((Product2.SFDA_Status__c Not IN (\'停止\') OR Product2.Manual_Entry__c = true) ';
                query += ' OR (Product2.SFDA_Status__c IN (\'停止\') AND Product2.Manual_Entry__c = false AND Product2.Loaner_categoryII__c IN (\'台车\',\'监视器\',\'录像设备\')))';
            }else if(rentalReson == '模型出借'){
                query += ' AND Product2.Loaner_categoryII__c IN (\'模型\') ';
                query += ' AND Product2.RentalSubject__c = true';
                query += ' AND ((Product2.SFDA_Status__c Not IN (\'停止\') OR Product2.Manual_Entry__c = true)) ';
             
            }else if(rentalReson == '演示' || rentalReson == '新产品评价'){
                query += ' AND (Product2.Loaner_categoryII__c NOT IN (\'模型\') ';
                query += ' AND Product2.RentalSubject__c = true)';
            }   

            System.debug('query-----------' + query);
            List<QuoteLineItem> quoteLineItemList = Database.query(query);

            for(QuoteLineItem quoLine : quoteLineItemList){
                ProLine pro = new ProLine();
                pro.Name = quoLine.Product2.Name;
                pro.Quantity = 1;
                pro.ProductCode = quoLine.Product2.ProductCode;
                pro.ProductModel = quoLine.Product2.Fixture_Model_No_T__c;
                pro.QuoteId = quoLine.QuoteId;
                pro.QuoteNo = quoLine.Quote.Quote_No__c;
                if(String.isNotBlank(quoLine.Product2.Key_product_147P__c)){
                    pro.FixtureModel = quoLine.Product2.Key_product_147P__c.substring(3);
                }
                proList.add(pro);
            }

            return proList;
        }
        catch(Exception e){
            System.debug(LoggingLevel.INFO, '*** e: ' + e);
            return null;
        }
    }
    // 2023-10-30 ADD by dzk End 同步报价产品按钮

    // 2023-10-30 ADD by dzk Start 同步报价产品
    // 清除OPD计划下的计划备品数据
    // 将勾选的报价行项目数据转换为OPD计划下的计划出借备品数据
    @AuraEnabled()
    public static String  createQuotePREData(String records, String recordId){
        try{
            Id planRentalEquipmentRecordTypeId = Schema.SObjectType.Plan_Rental_Equipment__c.getRecordTypeInfosByDeveloperName().get('Other').getRecordTypeId();
            List<Plan_Rental_Equipment__c> deletePlanREList = [SELECT Id ,MDM_Model_No__c,Rental_Quantity__c
                                                                FROM Plan_Rental_Equipment__c 
                                                                WHERE OPD_Plan__c =: recordId AND Quote_No__c != NULL];
            // 判断是否选中数据
            String quantityOld = '';
            if(deletePlanREList.size() > 0){
                // DB202402084477 20240305 by:zyh Start
                for (Plan_Rental_Equipment__c pre : deletePlanREList) {
                    quantityOld += pre.MDM_Model_No__c + '*' + pre.Rental_Quantity__c + '; ';
                }
                // DB202402084477 20240305 by:zyh Start
                Database.delete(deletePlanREList);
            }
            String quantity = '';
            String quantitySys = '';
            OPDPlan__c opdData = [SELECT Id,PlanProdDetail__c FROM OPDPlan__c WHERE Id =: recordId];
            // DB202402084477 20240305 by:zyh Start
            quantity = opdData.PlanProdDetail__c.replace(quantityOld,'');
            // DB202402084477 20240305 by:zyh Start
            List<Plan_Rental_Equipment__c> createPlanREList = new List<Plan_Rental_Equipment__c>(); 
            List<ProLine> ProLineList = 
            (List<ProLine>)System.JSON.deserialize(records, List<ProLine>.class);
            if(ProLineList.size() > 0){
                for(ProLine pro : ProLineList){
                    Plan_Rental_Equipment__c planRE = new Plan_Rental_Equipment__c();
                    planRE.Name = pro.Name;
                    planRE.Rental_Equipment__c = pro.Name;
                    planRE.Rental_Quantity__c = '1';
                    planRE.ProductCode__c = pro.ProductCode;
                    planRE.MDM_Model_No__c = pro.ProductModel;
                    planRE.OPD_Plan__c = recordId;
                    planRE.Quote__c = pro.QuoteId;
                    planRE.FixtureModel__c = pro.FixtureModel;
                    planRE.RecordTypeId = planRentalEquipmentRecordTypeId;
                    quantity += planRE.MDM_Model_No__c + '*' + planRE.Rental_Quantity__c + '; ';
                    if(String.isNotBlank(pro.FixtureModel)){
                        quantitySys += planRE.FixtureModel__c + '*' + planRE.Rental_Quantity__c + '; ';
                    }
                    createPlanREList.add(planRE);
                }
                
                insert createPlanREList;
                opdData.PlanProdDetail__c = quantity;
                opdData.EquipmentFromOpp__c = quantity;
                // DB202402084477 20240305 by:zyh Start
                // opdData.EquipmentNotFromOpp__c = '';
                // DB202402084477 20240305 by:zyh Start
                opdData.PlanProdDetailSys__c = quantitySys;
                opdData.PlanProdDetailSysT__c = quantitySys.length() > 255 ? quantitySys.substring(0, 255):quantitySys; // 计划出借战略产品文本 add by ljh 20240302
                update opdData;
            }
            return 'Success';
        }
        catch(Exception e){
            System.debug(LoggingLevel.INFO, '*** e: ' + e);
            return null;
        }
    }

    //检索下拉列表值
    @AuraEnabled(cacheable=true)
    public static List<Map<String,String>> getPicklistValues(String objstr, String fld){
        List<Map<String,String>> options = new List<Map<String,String>>();
        Map<String,String> space = new Map<String,String>();
        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();
        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;
    }
    // 2023-10-30 ADD by dzk Start 同步报价产品
    public class ProLine {
        @AuraEnabled
        public Id Id { get; set; } 
        @AuraEnabled
        public Id QuoteId { get; set; } 
        @AuraEnabled
        public Integer Quantity { get; set; } 
        @AuraEnabled
        public String Name { get; set; } 
        @AuraEnabled
        public String ProductCode { get; set; }  
        @AuraEnabled
        public String ProductModel { get; set; } 
        @AuraEnabled
        public String QuoteNo { get; set; } 
        @AuraEnabled
        public String FixtureModel { get; set; } 
        
} 

}