• fdssvds cfdsfcds
  • -2 Points
  • Member since 2022

  • Chatter
  • 0
    Best Answers
  • 0
    Likes Received
  • 0
    Likes Given
  • 0
  • 2
Class Controller:
public with sharing class controllerquoteVisual {
    public String title {get;set;}
    public Quote quote {get;set;}
    public List<quoteLineItem> qliList {get;set;}
    //public List<Product2> products {get; set;}
    //Capturar Nombre de familia y lista de productos
    public Map<String,List<ObjectWrapper>> mapFamily {get;set;}
    //public Map<String,List<QuoteLineItem>> mapFamilyqli {get;set;}
    //Captutar Nombre de familia y recuento de Productos que se mostrarán
    public Map<String, Integer> FamilyCountMap{get;set;}
	//Capturar Lista de nombres de familia de productos 
    public List<String> FamilyList {get;set;}
    //ProductList o products ya con los productos que se requieren mostrar
    public controllerquoteVisual(){
        Id id = ApexPages.currentPage().getParameters().get('id');
        //Obtener quote mediante el Id que arroja la visualforce desde quote
        quote = [SELECT Id, Name, TotalPrice, GrandTotal, ExpirationDate, AccountId, Total_Hours__c, OpportunityId, QuoteNumber   
                FROM quote WHERE Id=:id LIMIT 1];
        Opportunity opportunity = [SELECT Name FROM Opportunity WHERE Id=:quote.OpportunityId LIMIT 1];
        title = opportunity.Name.split('\\|')[0] + opportunity.Name.split('\\|')[1];
        Apexpages.currentPage().getHeaders().put('content-disposition', 'inline; filename='+title+ ' - ' +quote.QuoteNumber );
        //Obtener lista de quoteLineItems de la actual quote
        qliList = [SELECT Id, Product2Id, Quantity  
                    FROM quoteLineItem WHERE quoteId=:Id];
        //Separar productos por tipo de familia 
        mapFamily = new Map<String, List<ObjectWrapper>>(); 
        FamilyCountMap = new Map<String, Integer>();
        FamilyList = new List<String>();
        List<quoteLineItem> finalqliList = new List<QuoteLineItem>();
        finalqliList = qliList;
        //Agrupar por nombre de familia y preparar los map
        for(QuoteLineItem qq: finalqliList){
            Product2 famObj = [SELECT Id, Name, Family, Description
                   FROM Product2 WHERE Id=:qq.Product2Id];
            if(famObj.Family == null){
                famObj.Family= 'Sin clasificación';
            //List<QuoteLineItem> qq = qliList;
            List<ObjectWrapper> proList = new List<ObjectWrapper>();
            //Verificar si el map ya contiene el mismo nombre por familia
            	//Recuperar lista de productos existentes
            	proList = mapFamily.get(famObj.Family);
            	//Meter el nuevo producto a la lista
                proList.add(new ObjectWrapper(qq, famObj));
                mapFamily.put(famObj.Family, proList);
                //Almacenar filas por nombre de familia
                FamilyCountMap.put(famObj.Family, proList.size());
            	//crear nuevo map del nombre de familia //.fammily,name,etc
                proList.add(new ObjectWrapper(qq, famObj));
                mapFamily.put(famObj.Family, proList); 
                //Almacenar filas por nombre de familia
                FamilyCountMap.put(famObj.Family, proList.size());
        	FamilyList = new List<String>(mapFamily.keySet());
    public class ObjectWrapper{
        //Campos QuoteLineItems
        //Public Id QliId{get;set;}
        Public Decimal Quantity{get;set;}
        //Campos Producto
        Public String Name{get;set;}
        Public String Family{get;set;}
        Public String Description{get;set;}
        public ObjectWrapper(QuoteLineItem ql, Product2 pr){
            //this.QliId = ql.Id;
            this.Quantity = ql.Quantity;
            this.Name = pr.Name;
            this.Family = pr.Family;
            this.Description = pr.Description;

Test Class (68%, wrapper class is missing)
public class TestControllerquoteVisual{
    static void testControllerVFP(){
        Pricebook2 pb = new Pricebook2(Name = 'Standard Price Book', 
                                       Description = 'Price Book Products', IsActive = true );
        insert pb;
        Product2 prod = new Product2(Name = 'Test Product', Description = 'Descripción Test', 
                                     Family = 'Salesforce Service Cloud', IsActive = true);
        insert prod;
        List<Pricebook2> standardPbList = [select id, name, isActive from Pricebook2 
                                           where IsStandard = true ];
    	List<PricebookEntry> listPriceBook = new List<PricebookEntry>();
     	for(Pricebook2 p : standardPbList ){
      		PricebookEntry pbe = New PricebookEntry ();
      		pbe = new PricebookEntry(Pricebook2Id = p.Id, Product2Id = prod.Id, 
                                     UnitPrice = 10000, IsActive = true, UseStandardPrice = false);
        insert listPriceBook;
        Opportunity opp = new Opportunity(Name = 'Test Opportunity', 
                                          StageName = 'Discovery', Product_Families__c='Salesforce Service Cloud' ,CloseDate = system.today());
        insert opp;
        Quote quttest = new Quote (Name = 'Quote Test' , OpportunityId = opp.id , Pricebook2Id = pb.id );
        insert quttest;
        List<QuoteLineItem> listval = new List<QuoteLineItem>();
        for(PricebookEntry pricebook : listPriceBook){
            QuoteLineItem qutlineitemtest = new QuoteLineItem ();
            qutlineitemtest = new QuoteLineItem(QuoteId = quttest.id, Quantity = 3.00,UnitPrice = 12, PricebookEntryId = pricebook.id);
        insert listval;    
        QuoteLineItem qlitem = new QuoteLineItem(Quantity = 3.00, UnitPrice = 12 );
            ApexPages.currentPage().getParameters().put('id', String.valueOf(quttest.Id));
            controllerquoteVisual controllerVfp= new controllerquoteVisual();
            //controllerVfp = new controllerquoteVisual();
            controllerquoteVisual.ObjectWrapper wrapper = new controllerquoteVisual.ObjectWrapper(qlitem, prod);
            wrapper.Quantity = 3.00;
            wrapper.Name = prod.Name;
            wrapper.Description = prod.Description;
            wrapper.Family = prod.Family;



I are trying to get sObject name corresponding to selected CDC entity from PlatformEventChannelMember::fullName when getting response for MetadataAPI::listMetadata call.

Refer below link to know more about fullname.

For custom sobject as CDC selected entity we get fullName like : ChangeEvents_<CUSTOM_SOBJECT_NAME>_ChangeEvent
Ex : <fullName>ChangeEvents_Patient_ChangeEvent</fullName>

For standard sobject as CDC selected entity we get fullName like : ChangeEvents_<STANDARD_SOBJECT_NAME>ChangeEvent
Ex : <fullName>ChangeEvents_AccountChangeEvent</fullName>

fullName returned from listMetadata (soap based api) of MetadataAPI for type PlatformEventChannelMember does not start with ChangeEvents_ instead starts with CM_. And fullName also not ends with  ChangeEvent for User (standard sobject).

For User (standard sobject) as selected entities, I am getting fullName like : <fullName>CM_ChangeEvents_User</fullName>
This is causing issue to me since fullName does not start with ChangeEvents_ but starts with CM_ and also not ends with  ChangeEvent

1. What does "CM_" mean in prefix of "User" entity fullName? Is this pattern expected ?
Refer below link to know more about fullname. 

2. When getting response from MetadataAPI::listMetadata api call for type PlatformEventChannelMember, can fullName start with something like "CM_" for User (standard sobject) ?

3. Why fullName isn't ending with "ChangeEvent" for "User" entity which is a standard sObject?
Refer below link
for quick view  
"The change event name of an entity selected for Change
Data Capture notifications. For example, for the Account standard object, the
name is AccountChangeEvent, or for a custom object MyObject__c, the name is