none
CRM 2011 - Dúvida sobre relacionamento N:N RRS feed

  • Pergunta

  • Preciso de fazer um desenvolvimento e dentro deste desenv. preciso identificar quando o registro de Concorrente é relacionado com a Oportunidade.

    Eu acho que o objeto que exibe os registros de Concorrente no formulário de Oportunidade é um Grid e se for mesmo talvez eu possa contar as linhas de resgistro...

    Alguém pode me ajudar?


    quarta-feira, 5 de setembro de 2012 15:57

Respostas

  • Bom, como não acostumo trabalhar com  plugin mas, gostaria muito, venho propor um ajuda via JS.

    O que temos que ter em mente e que no relacionamento de NxN o sistema cria uma terceira entidade para armazenar este relacionamento, assim, temos que fazer a consulta direto nesta terceira entidade, no meu entender a consulta ficaria assim.

    ==> consulta nesta terceira entidade e trazer todos os Id dos concorrentes que o campo opportunityid e igual a "IdOportunidade";

    em outra palavra ficaria assim

    ==> consultar em "opportunitycompetitors" e trazer todos os "competitorid" onde "opportunityid" e igual a "342434-42434-4243f-3424";

    utilizando SOAP a consulta retornaria um XML com todos os "competitorid", ai e só ler os Ids e tomar a decisão necessária.

    Ex:

    var fetchMapping = "logical";
        var entityName = "opportunitycompetitors";
        var firstColumn = "competitorid";	
        var linkEntity = "opportunity";
        var linkEntityTo ="opportunityid";
        var filterType = "and";
        var conditionAttribute = "opportunityid";
        var operator = "eq";
        var value = Xrm.Page.data.entity.getId();//pega o id da oportunidade aberta
        var authenticationHeader = GenerateAuthenticationHeader();
        var xml = "<?xml version='1.0' encoding='utf-8'?>"+ 
        "<soap:Envelope xmlns:soap='http://schemas.xmlsoap.org/soap/envelope/'"+
        " xmlns:xsi='http://www.w3.org/2001/XMLSchema-instance'"+
        " xmlns:xsd='http://www.w3.org/2001/XMLSchema'>"+ 
        authenticationHeader+ 
        "<soap:Body>"+ 
        "<Fetch xmlns='http://schemas.microsoft.com/crm/2007/WebServices'>"+ 
        "<fetchXml>&lt;fetch mapping='"+fetchMapping+"'&gt;"+ 
        "&lt;entity name='"+entityName+"'&gt;"+ 
        "&lt;attribute name='"+firstColumn+"'/&gt;"+	
        "&lt;link-entity name='"+linkEntity+"' to='"+linkEntityTo+"'&gt;"+ 
        "&lt;filter type='"+filterType+"'&gt;"+ 
        "&lt;condition attribute='"+conditionAttribute+"'"+
        " operator='"+operator+"' value='"+value+"'/&gt;"+ 
        "&lt;/filter&gt;"+ 
        "&lt;/link-entity&gt;"+ 
        "&lt;/entity&gt;"+ 
        "&lt;/fetch&gt;</fetchXml>"+ 
        "</Fetch>"+ 
        "</soap:Body>"+ 
        "</soap:Envelope>";
        var xHReq = new ActiveXObject("Msxml2.XMLHTTP");
        xHReq.Open("POST", "/mscrmservices/2007/CrmService.asmx", false);
        xHReq.setRequestHeader("SOAPAction","http://schemas.microsoft.com/crm/2007/WebServices/Fetch");
        xHReq.setRequestHeader("Content-Type", "text/xml; charset=utf-8");
        xHReq.setRequestHeader("Content-Length", xml.length);
        xHReq.send(xml);
        var resultXml = xHReq.responseXML;
        var errorCount = resultXml.selectNodes('//error').length;
        if (errorCount != 0)
        {
            var msg = resultXml.selectSingleNode('//description').nodeTypedValue;
            alert(msg);
            return false;
        }
        else
        {
            var resultSet = new String();
            resultSet = resultXml.text;
            resultSet.replace('&lt;','<');
            resultSet.replace('&gt;','>');
            var oXmlDoc = new ActiveXObject("Microsoft.XMLDOM");
            oXmlDoc.async = false; 
            oXmlDoc.loadXML(resultSet);
            var results = oXmlDoc.getElementsByTagName('result');   
            var resultadoConsulta;
            try
            {      
                resultadoConsulta = results[0].selectSingleNode("./competitorid").nodeTypedValue;           
                return resultadoConsulta;   
            }catch(e)
            {
                return resultadoConsulta = "SEM DADOS" ;  
            }
        }

    quinta-feira, 6 de setembro de 2012 15:24
  • Willer,

    Precisa usar um plugin que funcionará no relacionamento NxN entre as entidades, por default esta opção está desabilitada, se sua versão for onPremises, poderá executar um script e desbloquear a ação, veja:

    USE SUAORGANIZACAO_MSCRM
    GO
    
    
    DECLARE @DisassociateEntitiesFilterId uniqueidentifier
    DECLARE @AssociateEntitiesFilterId uniqueidentifier
    SET @DisassociateEntitiesFilterId = (SELECT SdkMessageId FROM SdkMessageBase WHERE [Name] = 'DisassociateEntities')
    SET @AssociateEntitiesFilterId = (SELECT SdkMessageId FROM SdkMessageBase WHERE [Name] = 'AssociateEntities')
    
    UPDATE SdkMessageFilterBase SET IsCustomProcessingStepAllowed = 1 WHERE SdkMessageId = @DisassociateEntitiesFilterId AND PrimaryObjectTypeCode = 0
    UPDATE SdkMessageFilterBase SET IsCustomProcessingStepAllowed = 1 WHERE SdkMessageId = @AssociateEntitiesFilterId AND PrimaryObjectTypeCode = 0
    

    Com isso você conseguirá criar uma message "AssociateEntities", não coloque nada na primary e secund entity, terá que "dizer" qual entidade/relacionamento no próprio plugin, veja:

    if (contextoPluginVO.Context.InputParameters["RelationshipName"].ToString() == "RELACIONAMENTO_NxN")...

    Depois implemente sua lógica, registre o plugin e teste.

    Att,


    Tiago Michelini Cardoso MVP - MCC - MCTS
    https://tiagomcardoso.wordpress.com/

    quinta-feira, 6 de setembro de 2012 13:27
    Moderador

Todas as Respostas

  • Voce pode fazer uma localização avançada partindo da entidade oportunidade e relacionar com concorrente. adicione os campos e depois execute a localizacao. 


    Atenciosamente,
    Rodrigo Hentz - MCP.MCPS.MCNPS.MCTS.MBSS.MBSP.MCITP
    Profile
    Blog

    quarta-feira, 5 de setembro de 2012 16:35
    Moderador
  • Novamente vou tentar me expressar melhor:

    "Preciso de fazer um desenvolvimento e dentro deste desenv. preciso identificar quando o registro de Concorrente está relacionado com a Oportunidade..."

    "... se ele estiver relacionado ( aparecendo na exibição/('Grid') ) quero que faça alguma coisa."

    "Eu acho que o objeto: "

    "que exibe o relacionamento é um 'Grid' que tem registros, tendo registros(linha de registros), então fazer alguma coisa, se não faz outra."

    Sera que isso é possível???

    quarta-feira, 5 de setembro de 2012 17:49
  • Qual a ação que você tem que fazer?

    Atenciosamente,
    Rodrigo Hentz - MCP.MCPS.MCNPS.MCTS.MBSS.MBSP.MCITP
    Profile
    Blog

    quarta-feira, 5 de setembro de 2012 17:52
    Moderador
  • Eu tenho que identificar se existe o relacionamento de Oportunidade com Concorrente, por exemplo, eu tenho que saber se a Oportunidade X tem algum concorrente se tiver, eu faço um calculo se eu não tiver eu faço outro calculo.

    quarta-feira, 5 de setembro de 2012 17:58
  • Willer, em que momento vc quer saber se existe concorrente.

    ==> no  onload do formulario da Oportunidade

    ==> no onSave do formulario da cotação

    Eu partiria para um JS, mas em que momento este JS deveria ser executado?

    quarta-feira, 5 de setembro de 2012 18:02
  • Se o seu cálculo for para atualizar algum campo em tela, utilize JavaScript para fazer a consulta. com o retorno de linhas você faz ou não o cálculo. se for para atualizar algum campo que também pode ser ativado por alguma outra entidade ou fluxo use um plugin.

    no plugin mesma coisa, faz a consulta e se tiver dados faz o cálculo.

    para javascript usando REST e JSON de uma olhada neste link http://sliong.wordpress.com/2011/05/17/crm-2011-rest-endpoints-json-jquery-javascript-form/ 

    para plugins de uma olhada no SDK do CRM. neste link um exemplo de query http://crmbusiness.wordpress.com/2011/04/20/crm-2011-how-to-select-an-id-in-a-queryexpression/



    Atenciosamente,
    Rodrigo Hentz - MCP.MCPS.MCNPS.MCTS.MBSS.MBSP.MCITP
    Profile
    Blog

    quarta-feira, 5 de setembro de 2012 18:10
    Moderador
  • Daniel.

    O momento é no OnSave.

    quarta-feira, 5 de setembro de 2012 18:18
  • Blz,

    Elabora um Script que faz consulta a este grid, se não me engano e possível ate descobrir quantos concorrentes existem, de acordo com a resposta da consulta você toma a decisão.

    quarta-feira, 5 de setembro de 2012 18:28
  • Você sabe como eu faço essa consulta?
    quarta-feira, 5 de setembro de 2012 18:33
  • sim, 

    Você pode dar uma olhada no link abaixo:

    http://sliong.wordpress.com/2011/05/17/crm-2011-rest-endpoints-json-jquery-javascript-form/

    Mas, se não conseguir daqui a pouco posto um exemplo.

    quarta-feira, 5 de setembro de 2012 18:39
  • Blz eu espero você postar
    quarta-feira, 5 de setembro de 2012 18:46
  • Senhores,

    Apenas uma dica. O fórum está aqui para proporcionar ajuda e orientação as pessoas, exemplos prontos em muitos momentos não é a melhor opção para ajudar outra pessoa. 

    A resposta do Rodrigo resolve certamente o problema, vejam novamente, por favor:

    "

    Se o seu cálculo for para atualizar algum campo em tela, utilize JavaScript para fazer a consulta. com o retorno de linhas você faz ou não o cálculo. se for para atualizar algum campo que também pode ser ativado por alguma outra entidade ou fluxo use um plugin.

    no plugin mesma coisa, faz a consulta e se tiver dados faz o cálculo.

    para javascript usando REST e JSON de uma olhada neste link http://sliong.wordpress.com/2011/05/17/crm-2011-rest-endpoints-json-jquery-javascript-form/ 

    para plugins de uma olhada no SDK do CRM. neste link um exemplo de query http://crmbusiness.wordpress.com/2011/04/20/crm-2011-how-to-select-an-id-in-a-queryexpression/

    "

    Att,


    Tiago Michelini Cardoso MVP - MCC - MCTS
    https://tiagomcardoso.wordpress.com/

    quarta-feira, 5 de setembro de 2012 20:06
    Moderador
  • Esse relacionamento é um relacionamento N:N, nativo do CRM. :

    Esse relacionamento é o mesmo para Oportunidade e:

    "Cotações, Pedidos e Faturas".

    Não consigo identificar pelos GUID (ID), por exemplo, não encontro "xyz" da oportunidade em nenhuma das quatro entidades e o inverso também não rola.



    quinta-feira, 6 de setembro de 2012 13:02
  • Willer,

    Precisa usar um plugin que funcionará no relacionamento NxN entre as entidades, por default esta opção está desabilitada, se sua versão for onPremises, poderá executar um script e desbloquear a ação, veja:

    USE SUAORGANIZACAO_MSCRM
    GO
    
    
    DECLARE @DisassociateEntitiesFilterId uniqueidentifier
    DECLARE @AssociateEntitiesFilterId uniqueidentifier
    SET @DisassociateEntitiesFilterId = (SELECT SdkMessageId FROM SdkMessageBase WHERE [Name] = 'DisassociateEntities')
    SET @AssociateEntitiesFilterId = (SELECT SdkMessageId FROM SdkMessageBase WHERE [Name] = 'AssociateEntities')
    
    UPDATE SdkMessageFilterBase SET IsCustomProcessingStepAllowed = 1 WHERE SdkMessageId = @DisassociateEntitiesFilterId AND PrimaryObjectTypeCode = 0
    UPDATE SdkMessageFilterBase SET IsCustomProcessingStepAllowed = 1 WHERE SdkMessageId = @AssociateEntitiesFilterId AND PrimaryObjectTypeCode = 0
    

    Com isso você conseguirá criar uma message "AssociateEntities", não coloque nada na primary e secund entity, terá que "dizer" qual entidade/relacionamento no próprio plugin, veja:

    if (contextoPluginVO.Context.InputParameters["RelationshipName"].ToString() == "RELACIONAMENTO_NxN")...

    Depois implemente sua lógica, registre o plugin e teste.

    Att,


    Tiago Michelini Cardoso MVP - MCC - MCTS
    https://tiagomcardoso.wordpress.com/

    quinta-feira, 6 de setembro de 2012 13:27
    Moderador
  • Bom, como não acostumo trabalhar com  plugin mas, gostaria muito, venho propor um ajuda via JS.

    O que temos que ter em mente e que no relacionamento de NxN o sistema cria uma terceira entidade para armazenar este relacionamento, assim, temos que fazer a consulta direto nesta terceira entidade, no meu entender a consulta ficaria assim.

    ==> consulta nesta terceira entidade e trazer todos os Id dos concorrentes que o campo opportunityid e igual a "IdOportunidade";

    em outra palavra ficaria assim

    ==> consultar em "opportunitycompetitors" e trazer todos os "competitorid" onde "opportunityid" e igual a "342434-42434-4243f-3424";

    utilizando SOAP a consulta retornaria um XML com todos os "competitorid", ai e só ler os Ids e tomar a decisão necessária.

    Ex:

    var fetchMapping = "logical";
        var entityName = "opportunitycompetitors";
        var firstColumn = "competitorid";	
        var linkEntity = "opportunity";
        var linkEntityTo ="opportunityid";
        var filterType = "and";
        var conditionAttribute = "opportunityid";
        var operator = "eq";
        var value = Xrm.Page.data.entity.getId();//pega o id da oportunidade aberta
        var authenticationHeader = GenerateAuthenticationHeader();
        var xml = "<?xml version='1.0' encoding='utf-8'?>"+ 
        "<soap:Envelope xmlns:soap='http://schemas.xmlsoap.org/soap/envelope/'"+
        " xmlns:xsi='http://www.w3.org/2001/XMLSchema-instance'"+
        " xmlns:xsd='http://www.w3.org/2001/XMLSchema'>"+ 
        authenticationHeader+ 
        "<soap:Body>"+ 
        "<Fetch xmlns='http://schemas.microsoft.com/crm/2007/WebServices'>"+ 
        "<fetchXml>&lt;fetch mapping='"+fetchMapping+"'&gt;"+ 
        "&lt;entity name='"+entityName+"'&gt;"+ 
        "&lt;attribute name='"+firstColumn+"'/&gt;"+	
        "&lt;link-entity name='"+linkEntity+"' to='"+linkEntityTo+"'&gt;"+ 
        "&lt;filter type='"+filterType+"'&gt;"+ 
        "&lt;condition attribute='"+conditionAttribute+"'"+
        " operator='"+operator+"' value='"+value+"'/&gt;"+ 
        "&lt;/filter&gt;"+ 
        "&lt;/link-entity&gt;"+ 
        "&lt;/entity&gt;"+ 
        "&lt;/fetch&gt;</fetchXml>"+ 
        "</Fetch>"+ 
        "</soap:Body>"+ 
        "</soap:Envelope>";
        var xHReq = new ActiveXObject("Msxml2.XMLHTTP");
        xHReq.Open("POST", "/mscrmservices/2007/CrmService.asmx", false);
        xHReq.setRequestHeader("SOAPAction","http://schemas.microsoft.com/crm/2007/WebServices/Fetch");
        xHReq.setRequestHeader("Content-Type", "text/xml; charset=utf-8");
        xHReq.setRequestHeader("Content-Length", xml.length);
        xHReq.send(xml);
        var resultXml = xHReq.responseXML;
        var errorCount = resultXml.selectNodes('//error').length;
        if (errorCount != 0)
        {
            var msg = resultXml.selectSingleNode('//description').nodeTypedValue;
            alert(msg);
            return false;
        }
        else
        {
            var resultSet = new String();
            resultSet = resultXml.text;
            resultSet.replace('&lt;','<');
            resultSet.replace('&gt;','>');
            var oXmlDoc = new ActiveXObject("Microsoft.XMLDOM");
            oXmlDoc.async = false; 
            oXmlDoc.loadXML(resultSet);
            var results = oXmlDoc.getElementsByTagName('result');   
            var resultadoConsulta;
            try
            {      
                resultadoConsulta = results[0].selectSingleNode("./competitorid").nodeTypedValue;           
                return resultadoConsulta;   
            }catch(e)
            {
                return resultadoConsulta = "SEM DADOS" ;  
            }
        }

    quinta-feira, 6 de setembro de 2012 15:24