DECLARE @convertedValue VARCHAR(MAX) = (SELECT CONVERT(
VARCHAR(MAX),
CAST(N'' AS XML).value('xs:base64Binary(sql:column("base64Value"))', 'varbinary(max)')
)
FROM (SELECT @SuaVarNaBase64 base64Value) t);
Todos os campos alterados do formulário são rastreados e salvos quando o usuário clica no botão Salvar.
Se precisar pedir para o sistema ignorar, não rastrear um determinado campo ao salvar, adicione este método no Onload do form, passando o id do campo como parâmetro.
CopyFieldsFromParentForm(exceptions)
Namespace: CRMGT.Page.Util
Utilize esta função quando precisar copiar todos os campos da tela [pai] quando estiver criando um registro de [subGrid].
A função vai buscar todos os campos [iguais] da tela relacionada na tela pai.
Exemplo, você está editando um registro de [incident].
No final do formulário existe a seção [Anotações e Visão 360].
Uma das abas desta seção é o relacionamento da incident com ela mesma; o nome da aba está geralmente como [Chamados].
Quando você clicar para criar um novo chamado relacionado (botão [criar] do subGrid), neste ponto você pode precisar copiar todos os campos do chamado principal neste chamado relacionado.
A função [CopyFieldsFromParentForm] vai então fazer este mapeamento/cópia.
Se precisar pedir para a função [ignorar algum campo, ou vários], passe o nome dos campos no parâmetro [exceptions], separados por vírgula.
AutoSaveRecordAddingSubGridItem(value, refreshForm = false)
Namespace: CRMGT.Page.Util
Por padrão, ao adicionar um item em um dos sub-Grids no formulário, aparece a mensagem para o usuário salvar o registro principal do form para de fato salvar todos os itens inseridos.
Com esta opção de SDK podemos alterar este comportamento.
Passando o param [value] como true, dizemos para o sistema salvar automaticamente o registro principal a [cada] item inserido no sub-Grid.
Também é opcional se deseja dar um [refresh] no form (param refreshForm).
Note que, se o usuário estiver [criando um novo] registro principal, ao adicionar o [primeiro item] de um sub-Grid, o sistema faz o refresh automaticamente.
CryptographyValue(value)
Namespace: CRMGT.Page.Util
O valor passado como parâmetro é retornado como um valor criptografado (modelo de criptografia AES).
GetToken(organization, clientId, clientSecret, renewIfExpired)
Namespace: CRMGT.Page.Util
Retorna um Token para acesso ao Conector de Dados** do CRM-GT.
** veja em Funcionalidades -> Conector de Dados
Segue um exemplo de execução e o retorno do token:
Passe as credentiais (clientId e ClientSecret) convertidas na [base64 string], através da função BTOA conforme destacado na imagem acima.
Estas credenciais são criadas pelo [administrador] do sistema e repassada para os desenvolvedores/clientes.
O retorno é um JSON contendo o token, ou o detalhe do erro na tentativa de obtenção do token.
RenewToken(organization, clientId, clientSecret)
Namespace: CRMGT.Page.Util
Retorna um Token [renovado] para acesso ao conector do CRM-GT.
Utilize o exemplo da função [GetToken] acima para a execução do [RenewToken].
CheckAccessToken(data, organization, clientId, clientSecret)
Namespace: CRMGT.Page.Util
Para tratarmos falhas na execução da webAPI, por falha de Token, podemos usar a func [CheckAccessToken]
Então, dentro do callback [success] do ajax, você pode adicionar o seguinte código:
},
success: function (data, textStatus, jqXHR) {
let checkConnection = CRMGT.Page.Util.CheckAccessToken(data, organization, clientId, clientSecret);
if (checkConnection.IsInvalid) {
token = checkConnection.RenewedToken;
ReExecutaSuaFuncaoAqui();
}
Se o Token for inválido, a função traz um novo Token (RenewedToken).
Atualize sua variável de token com a nova e execute novamente sua função conforme indicado (ReExecutaSuaFuncaoAqui()).
GetParam(name, windowTop)
Namespace: CRMGT.Page.Util
Retorna o [valor] de um parâmetro da [Query String] da página corrente - ou da janela superior do navegador (window.top).
GetPageContentFromCurrentDialog()
Namespace: CRMGT.Page.Util
Retorna o contentDocument (DOM) de uma página HTML aberta pelo método ShowDialog (que é explicado em detalhes nesta documentação).
RefreshForm()
Namespace: CRMGT.Page.Util
Execute este método para dar um Refresh na página.
RefreshList()
Namespace: CRMGT.Page.Util
Execute este método para dar um Refresh em uma Lista de Registros.
Save(redirectToList = false)
Namespace: CRMGT.Page.Util
Execute este método para salvar o registro corrente.
Se precisar redirecionar a tela para a lista de registros após o Save, passe [true] para o parâmetro [redirectToList].
SaveAndNew()
Namespace: CRMGT.Page.Util
Execute este método para salvar o registro corrente e preparar a página para um novo cadastro.
SaveGridEdit(saveParent = false)
Namespace: CRMGT.Page.Util
Execute este método para salvar o registro de um [sub-Grid] relacionado em um registro principal.
Exemplo, podemos pedir para o sistema salvar uma [Linha de Contrato], fechar o popup e salvar o Form Pai (de Contrato)
CRMGT.Page.Util.SaveGridEdit(true);
ParseValueToDecimalString(value, numOfDecs, valueFormattedAs = "pt-BR", removeCommas = false)
Namespace: CRMGT.Page.Util
Execute este método para converter corretamente uma string para um valor decimal.
Por padrão, [pt-BR] é o formato usado. Para usar outro formato passe o desejado no parâmetro [valueFormattedAs].
Exemplo:
var pricelist = CRMGT.Page.Util.GetAttribute("pricelist");
var pricelistValue = CRMGT.Page.Util.ParseValueToDecimalString(pricelist.val(), 2);
FormatDecimalField(field, format = "#.##0,00", useReverse = true)
Namespace: CRMGT.Page.Util
Execute este método para adicionar uma [máscara] formatada no seu campo de valor
Por padrão, [#.##0,00] é a máscara usada. Para usar outra máscara passe o desejado no parâmetro [format].
Exemplo:
CRMGT.Page.Util.FormatDecimalField("totalamount");
GridViewButtonsOnClick(subGridId, btnType, funcName)
Namespace: CRMGT.Page.Util
Método que auxilia na inserção de função Javascript customizada, que será executada ao clicar nos botões [Criar], [Editar] ou [Excluir] da toolbar de uma [Sub-Grid].
Adicione este método no [OnLoad] do formulário.
Temos os seguintes parâmetros:
-
subGridId - representa o [id] do campo criado como tipo [Relacionamento N-N]
Por exemplo, na tabela de Oportunidade temos, na lista de campos criados, um do tipo [ComplexRelationship] chamado [opportunityproduct], que é um SubGrid de [Produtos da Oportunidade]. Portanto subGridId será "opportunityproduct".
- btnType - Representa o tipo de botão onde adicionaremos a chamada do JS customizado, onde podemos passar o valor [add], [edit] ou [delete]
- funcName - O nome da função desejada para ser executada ao clicar no botão
Exemplo, ao clicar no botão [Criar] de um sub-grid de produtos da oportunidade, precisamos executar um método JS chamado "CanCreateNewItem" (que deve estar localizado no [OnLoad] do form).
CRMGT.Page.Util.GridViewButtonsOnClick("opportunityproduct", "add", "CanCreateNewItem()");
Se desejarmos [interromper] a ação do [clique] do botão, podemos usar CRMGT.Page.Util.GridViewButtonResult(false); dentro do método customizado (no exemplo, dentro de "CanCreateNewItem")
Se precisarmos fazer uma pergunta de decisão, onde somente após o clique no botão [sim] é que poderemos abrir a tela popup do botão do sub-grid [criar], adicionamos no código:
-
CRMGT.Page.Util.GridViewButtonConfirmDialogMessage("Sua Mensagem de Confirmação");
-
CRMGT.Page.Util.GridViewButtonAdditionalFuncToRun("customFunc()");
Quando o usuário clicar no botão de confirmação [sim] você pode executar uma função sua customizada antes de abrir o popup.
Importante: No nosso exemplo, os métodos [GridViewButtonConfirmDialogMessage] e [GridViewButtonAdditionalFuncToRun] deverão ser adicionados dentro da função CanCreateNewItem
Se precisarmos atualizar o conteúdo de um subGrid (refresh), adicionamos no código:
-
CRMGT.Page.Util.ReloadGridView(relationshipTableId, fieldId, parentId, parentIdName);
Onde:
-
relationshipTableId - representa o Metadata ID da tabela associada ao subGrid (obtemos este id acessando a tabela interna do sistema chamada Entity, campo [entityId])
-
fieldId - representa o ID do subGrid (este id é obtido em Configurações -> Tabelas do Sistema, aba Campos, do tipo [complexrelationship])
-
parentId - representa o ID da tabela pai onde o subGrid está associado (por exemplo, temos um subGrid de Produtos da Oportunidade associado a tabela pai [Oportunidade]). Geralmente podemos obter este id executando CRMGT.Page.Util.GetEntityRecordId()
-
parentIdName - representa o nome do campo chave da tabela pai onde o subGrid está associado (no exemplo citado acima para o parâmetro parentId, teremos como parentIdName [opportunityid])
ToBoolean(value)
Namespace: CRMGT.Page.Util
-
Método para converter uma string em Boolean.
REST_GetString(url)
Namespace: CRMGT.Page.Util
-
Executa uma REST API e retorna o resultado da mesma.
DateDiff(datePart, startDate, endDate)
Namespace: CRMGT.Page.Util
-
Método para retornar a diferença entre duas datas.
-
No parâmetro [datePart] podemos passar como desejamos a diferença, sendo possível em:
Day
Month
Year
Hour
Minute
Second
IsNullOrEmpty(value)
Namespace: CRMGT.Page.Util
-
Método para verificar se o valor (ou objeto) passado como parâmetro está vazio ou nulo.
HasDuplicateDetection(entityName, jsonFields)
Namespace: CRMGT.Page.Util
-
Use esta função para bloquear um cadastro em duplicidade no sistema.
-
Informe a tabela desejada em os campos para busca no banco de dados.
-
Segue um exemplo de uso, no [OnSave] do formulário:
if (CRMGT.Page.Util.GetCanSaveRecord()) {
var _name = $("#name").val();
var _accountnumber = $("#accountnumber").val();
var jsonFields = [];
jsonFields.push({ "fieldname":"name", "fieldtype": "varchar", "fieldvalue": _name });
jsonFields.push({ "fieldname":"accountnumber", "fieldtype": "varchar", "fieldvalue": _accountnumber });
CRMGT.Page.Util.SetCanSaveRecord(true);
if (CRMGT.Page.Util.HasDuplicateDetection("account", JSON.stringify(jsonFields))) {
CRMGT.Page.Util.SetCanSaveRecord(false);
var msg = "Detecção de Duplicidade<br/><br/>";
msg += "Já existe uma Conta cadastrada com os valores:<br/>";
msg += "Nome: " + _name + "<br/>";
msg += "Número da Conta: " + _accountnumber + "<br/>";
ShowAlert(msg, 500, false, "font-size:18px;");
}
}
-
Neste exemplo, se existir um registro com o mesmo valor dos campos [name e accountNumber] o registro não é salvo (através do uso do método [SetCanSaveRecord] com o parâmetro "false").
RunAssociatedWorkflowsSynchronously(value [true|false])
Namespace: CRMGT.Page.Util
-
Método para ser usado no [OnLoad] do formulário.
-
Passando o parâmetro [true], ao salvar um [novo] registro, ou alterar um registro [existente], todos os Workflows associados ao registro serão executados imediatamente.
-
Lembrando que serão executados os workflows correspondentes ao [modo] em que o registro está sendo salvo.
-
Por exemplo, ao entrar em um registro existente, ao salvar, somente serão executados os workflows com a configuração de disparo (trigger) no modo [Atualização].
Se existirem subGrids associados no formulário, o sistema também vai executar os workflows (trigger de criação) relacionados as tabelas destes subGrids. Por exemplo, no formulário de Oportunidade vai existir um subGrid de Produtos da Oportunidade. Portanto os workflows associados na tabela [produto da oportunidade] serão também executados de forma síncrona.
GetAttachmentContentById(attachmentNoteId)
Namespace: CRMGT.Page.Util
-
Retorna o conteúdo de um anexo, como uma string na base64.
-
Passe como parâmetro o ID da AttachmentNote, que é a tabela que guarda os anexos.
HasFormAttachment()
Namespace: CRMGT.Page.Util
-
Retorna true|false se existe pelo menos 1 anexo no formulário.
HasTimeLineAttachment()
Namespace: CRMGT.Page.Util
-
Retorna true|false se existe pelo menos 1 anexo no componente [Time Line Annotation] do formulário.
BreakLineAfterAttribute(id, fromParentRecord [true|false])
Namespace: CRMGT.Page.Util
-
Adiciona uma quebra de linha, no formulário, [após] o campo especificado por parâmetro
Exemplo: Após o campo [endereço] reposicionar os próximos na próxima linha da tela:
SetAttributeEntireLine(id, entireLinePos [true|false], fromParentRecord [true|false])
Namespace: CRMGT.Page.Util
-
Mantém o campo (passado por parâmetro) como único na linha de campos do formulário
Exemplo:
HideSection(id, hide [true|false])
Namespace: CRMGT.Page.Util
-
Permite esconder/mostrar uma aba do formulário.
Passe como [id] a descrição da aba que deseja interagir.
HideAttribute(id, hide [true|false], fromParentRecord [true|false])
Namespace: CRMGT.Page.Util
- Permite esconder/mostrar um campo do formulário
- Para esconder um campo na área de [Business Process Flow] habilitada na tela, utilize HideBPFAttribute(id, hide)
- Para esconder um campo do tipo [richText] passe o id concatenado desta forma: "richTextArea_" + id
SetRequiredAttribute(id, required [true|false], fromParentRecord [true|false])
Namespace: CRMGT.Page.Util
- Altera o atributo [required] de um campo no formulário
DisableAttribute(id, disable [true|false], fromParentRecord [true|false])
Namespace: CRMGT.Page.Util
- Desabilita um campo no formulário
- Para desabilitar um campo na área de [Business Process Flow] habilitada na tela, utilize DisableBPFAttribute(id, disable)
DisableAllFormElements()
Namespace: CRMGT.Page.Util
- Desabilita todos os elementos do formulário, incluindo richText e ações nos subGrids.
SetAttributeLabel(id, label, fromParentRecord [true|false])
Namespace: CRMGT.Page.Util
- Altera o Label de um campo no formulário
SetLookupValue(lookupId, lookupValue, lookupLabel)
Namespace: CRMGT.Page.Util
- Preenche um lookup, com seu Guid/Texto
- Para preencher um lookup na área de [Business Process Flow] habilitada na tela, utilize SetBPFLookupValue(lookupId, lookupValue, lookupLabel)
-
Exemplo:
CRMGT.Page.Util.SetLookupValue("accountid", "4f0e7903-5e54-4a11-b596-816a4546fe54", "Conta LTDA");
SetMultiLookupValue(lookupId, lookupValue, lookupLabel)
Namespace: CRMGT.Page.Util
- Preenche um [Multi]Lookup, com seu Guid/Texto
[Name da Tabela do Lookup] + [|] + [Guid da Tabela do Lookup] + [|] + [Guid da Entidade do Lookup] + [,] + [...]
Exemplo: Conta Teste|13a3ef4f-d0de-40fb-a7a5-7568ae7ba542|585E0EEA-362F-423D-AEB3-131E8A956FC3,
O Guid [585E0EEA-362F-423D-AEB3-131E8A956FC3] representa o id da tabela [account] no Metadado do sistema.
Exemplo para busca deste id, via FetchData:
var aSearch = [];
var _entityId = "";
aSearch.push({ field: "EntityName", type: "varchar", value: "account" });
var data = CRMGT.Page.Util.FetchData("Entity", "Entityid", aSearch, null);
if (!CRMGT.Page.Util.IsNullOrEmpty(data)) {
_entityId = data[0].Entityid;
}
Separe esta combinação de valores usando a [,] para preencher o campo com múltiplos valores
Parâmetro lookupLabel - passe o nome que deverá aparecer no campo de texto do lookup. Para vários, separe-os por [,]
SetLookupOnChange(lookupId, fnOnChange)
Namespace: CRMGT.Page.Util
- Atribui um método para ser executado no OnChange do lookup
-
Exemplo:
CRMGT.Page.Util.SetLookupOnChange("accountid", "onChangeAccount([[id]], [[value]])");
Note que no método [onChangeAccount] foram preparados dois parâmetros, [[id]] e [[value]], com colchetes duplos.
Isto significa que o sistema vai passar o ID e o VALOR do Lookup que foi selecionado para seu método.
O uso deste mecanismo é [opcional].
- Para atribuir uma método em um lookup na área de [Business Process Flow] habilitada na tela, utilize SetBPFLookupOnChange(lookupId, fnOnChange)
SetTreeViewOnChange(treeviewId, fnOnChange)
Namespace: CRMGT.Page.Util
- Atribui um método para ser executado no OnChange do lookup do tipo TreeView
OnChange para campos diferentes de [Lookup]
-
Utilize JQuery para ativar o [change] de campos que são diferentes de lookup.
Exemplo de ativação para o campo [name]:
$("#name").unbind("change").change(function ()
{
// ADICIONE SEU CÓD AQUI...
});
ClearTreeViewLookup(treeviewId)
Namespace: CRMGT.Page.Util
- Limpa o conteúdo do lookup do tipo TreeView
GetLookup(lookupId, fromParentRecord [true|false])
Namespace: CRMGT.Page.Util
- Retorna todos os dados de um lookup, sendo:
- Id, que é o lookupId passado por parâmetro
- Label, que é o nome que aparece no campo do lookup
- Value, que é o GUID do lookup
-
Exemplo:
var accountId = CRMGT.Page.Util.GetLookup("accountid").Value;
- Para retornar os dados de um lookup na área de [Business Process Flow] habilitada na tela, utilize GetBPFLookup(lookupId)
FilterLookupValue(lookupId, value)
Namespace: CRMGT.Page.Util
- Permite filtrar o conteúdo do lookup, para restringir os dados que serão mostrados para o usuário
- Para filtrar o conteúdo do lookup na área de [Business Process Flow] habilitada na tela, utilize FilterBPFLookupValue(lookupId, value)
-
Exemplo 1 (relacionamento 1-N):
Filtra o lookup para mostrar somente os usuários de um determinado departamento (comercial)
O filter [type] usado abaixo exemplifica uma busca em uma tabela do tipo [1-N]. Desta forma, devemos informar [1nrelationship], depois o símbolo de pipe [|] e por fim o [schema da tabela].
var aFilter = [];
var filter = new Object();
filter.field = "department_481c97b9d13d_ids";
filter.type = "1nrelationship|department";
filter.value = "Comercial";
aFilter.push(filter);
CRMGT.Page.Util.FilterLookupValue("User_746bf8c2581a_id", aFilter);
Se precisar informar vários valores para [filter.value], passe da seguinte forma:
filter.value = ["a","b","c","d","e","f"];
-
Exemplo 2 (relacionamento N-N):
Filtra o lookup para mostrar somente as [Unidades] de uma determinada [Instituição]:
O filter [type] usado abaixo exemplifica uma busca em uma tabela do tipo [N-N]. Desta forma, devemos informar [nnrelationship], depois o símbolo de pipe [|] e por fim o [schema da tabela relacional], que no exemplo é a relação entre unidade e instituicao.
var instituicaoId = CRMGT.Page.Util.GetLookupObject("instituicao_a52bd16faf87_id").ObjectValue.val();
var aFilter = [];
var filter = new Object();
filter.field = "instituicoesid";
filter.type = "nnrelationship|unidade_instituicoes";
filter.value = instituicaoId;
aFilter.push(filter);
CRMGT.Page.Util.FilterLookupValue("unidade_874773c8a682_id", aFilter);
-
Exemplo 3 (relacionamento 1-1):
Filtra um lookup de [Atividades do Projeto] baseado no lookup de [Projetos]
O código abaixo deve ser adicionado no [OnLoad] do formulário
Os campos de lookup usados no exemplo abaixo (por exemplo [timesheetproject_87b12b2ec835_id]) são criados internamente desta maneira pelo sistema.
if (CRMGT.Page.Util.FormMode() == "edit") {
OnChangeProject();
}
CRMGT.Page.Util.SetLookupOnChange("timesheetproject_87b12b2ec835_id", "OnChangeProject()");
function OnChangeProject()
{
var projectId = CRMGT.Page.Util.GetLookup("timesheetproject_87b12b2ec835_id").Value;
if (CRMGT.Page.Util.IsNullOrEmpty(projectId)) {
CRMGT.Page.Util.FilterLookupValue("timesheetprojectactivity_de15ff33049c_id", null);
return;
}
var aFilter = [];
var filter1 = new Object();
filter1.field = "timesheetprojectid";
filter1.type = "uniqueidentifier";
filter1.value = projectId;
filter1.conditiontype = "OR"; /* AND, OR, sendo "AND" o padrao */;
filter1.operatortype = "="; /* =, !=, LIKE, etc..., sendo "=" o padrao */;
var filter2 = new Object();
filter2.field = "timesheetprojectid";
filter2.type = "uniqueidentifier";
filter2.value = "IS NOT NULL"; /* OU "IS NULL" */
filter2.conditiontype = "OR";
aFilter.push(filter1);
aFilter.push(filter2);
CRMGT.Page.Util.FilterLookupValue("timesheetprojectactivity_de15ff33049c_id", aFilter);
}
OBS: Note que o método [OnChangeProject()] é configurado na function [SetLookupOnChange] e executado também. Isto é importante quando estivermos editando um registro, para que os lookups fiquem corretamente relacionados.
-
Para o filter.type você pode usar os seguintes valores:
bit |
char |
nchar |
varchar |
nvarchar |
datetime |
int |
decimal |
text |
uniqueidentifier |
1nrelationship|Nome da tabela relacional 1-N |
nnrelationship|Nome da tabela relacional N-N |
GetLookupObject(lookupId, fromParentRecord)
Namespace: CRMGT.Page.Util
- Semelhante ao GetLookup, porém, retorna com mais informações para o desenvolvedor, sendo:
- EntityMetadataId, que é o GUID da [tabela do lookup] no metadado interno do sistema chamado [Entity]
- ObjectDiv, que representa o elemento DOM na tela
- ObjectLabel, que é o nome que aparece no campo do lookup
- ObjectValue, que é o GUID do lookup
-
Exemplo:
var accountId = CRMGT.Page.Util.GetLookupObject("accountid").ObjectValue.val();
IgnoreOnlyActiveRecordsInLookup(lookupId, ignore)
Namespace: CRMGT.Page.Util
-
Por padrão campos lookup sempre mostram os registros [ativos] na lista ou em uma pesquisa no campo.
Com este método podemos ignorar este comportamento, resultando em uma lista de resultado independente do status do registro.
Exemplo:
CRMGT.Page.Util.IgnoreOnlyActiveRecordsInLookup("unidade_874773c8a682_id", true)
GetAttribute(id, fromParentRecord = false, frameId = "")
Namespace: CRMGT.Page.Util
- Retorna, como objeto jQuery, um elemento do DOM especificado.
-
Exemplo:
var _name = CRMGT.Page.Util.GetAttribute("name").val();
- Para retornar um elemento na área de [Business Process Flow] habilitada na tela, utilize GetBPFAttribute(id)
GetAttributeLabel(id, fromParentRecord)
Namespace: CRMGT.Page.Util
- Retorna o texto (ou label) associado a um campo do form
SetAttributeValue(id, value, fromParentRecord = false, frameId = "")
Namespace: CRMGT.Page.Util
- Atualiza o valor de um elemento do DOM especificado.
- Para atualizar o valor de um elemento na área de [Business Process Flow] habilitada na tela, utilize SetBPFAttributeValue(id, value)
SetRichTextAttributeValue(id, value, fromParentRecord [true|false])
Namespace: CRMGT.Page.Util
- Atualiza o valor de um elemento [RichText] especificado.
GetRichTextAttributeValue(id, fromParentRecord [true|false])
Namespace: CRMGT.Page.Util
- Obtém o valor de um elemento [RichText] especificado.
IsRichTextAttributeValueEmpty(id, fromParentRecord [true|false])
Namespace: CRMGT.Page.Util
- Retorna true/false - Verifica se o conteúdo de um elemento [RichText] está vazio.
DisableRichTextAttribute(id, disable [true|false])
Namespace: CRMGT.Page.Util
- Habilita/Desabilita o campo [RichText] especificado.
FetchData(entityName, sqlFields, objSearchValue, orderBy)
Namespace: CRMGT.Page.Util
- Retorna um json com os registros da tabela especificada no parâmetro
-
Exemplo 1:
Faz um SELECT na tabela de [incident], retorna o campo [incidentStatusId]
onde o campo [originatingrecordid] seja igual a variável [incidentId]:
var incidentId = CRMGT.Page.Util.GetEntityRecordId();
var aSearch = [];
var search = new Object();
search.field = "originatingrecordid";
search.type = "uniqueidentifier";
search.value = incidentId;
aSearch.push(search);
var data = CRMGT.Page.Util.FetchData('incident', 'incidentStatusId', aSearch);
-
Para o search.type você pode usar os seguintes valores:
bit |
char |
nchar |
varchar |
nvarchar |
datetime |
int |
decimal |
text |
uniqueidentifier |
-
Exemplo 2:
Usa o FetchData para efetuar uma busca do registro mais atual (instrução [DESC LIMIT 1] do MySQL) e [extrair] parte de um valor do campo [numocorrencia] da tabela [incident]
var data = CRMGT.Page.Util.FetchData(
'incident',
'SUBSTR(numocorrencia, 1, LOCATE("/", numocorrencia) - 1) + 1 num',
null,
'num DESC LIMIT 1');
var nro = "1/" + (new Date()).getFullYear();
if (data && data.length > 0 && data[0].num != "") {
nro = data[0].num + "/" + (new Date()).getFullYear();
}
QueryExecData(xml)
Namespace: CRMGT.Page.Util
- Retorna um json como resultado da execução da QueryExec passada como parâmetro.
- Lembre-se que, se você precisar efetuar uma busca de dados em apenas uma tabela, não existe a necessidade de uso do QueryExecData, utilize o FetchData, que faz montagem do SELECT diretamente no código JS.
-
Exemplo:
OnLoad configurado para executar a QueryExec:
Depurando a execução e analisando o resultado:
-
Na execução de uma QueryExec de UPDATE, na passagem de parâmetros, informe o atributo [type]. Ele não é obrigatório quando o param é do ipo UniqueIdentifier.
Exemplo:
Estes types seguem o padrão já estabelecido no SDK, sendo:
bit |
char |
nchar |
varchar |
nvarchar |
datetime |
int |
decimal |
text |
uniqueidentifier |
GetEntityName()
Namespace: CRMGT.Page.Util
- Retorna o nome da tabela do formulário corrente
GetParentEntityName()
Namespace: CRMGT.Page.Util
- Retorna o nome da tabela [pai] do formulário corrente
GetEntityMetadataId()
Namespace: CRMGT.Page.Util
- Retorna o Guid da tabela do formulário corrente (no metadados do sistema)
GetEntityMetadataIdByName(entityName)
Namespace: CRMGT.Page.Util
- Retorna o Guid da tabela baseado no seu nome de Schema (no metadados do sistema)
GetEntityRecordId()
Namespace: CRMGT.Page.Util
- Retorna o Guid do Registro para a tabela corrente
GetParentEntityRecordId()
Namespace: CRMGT.Page.Util
- Retorna o Guid do Registro [pai] da tabela corrente
GetIndexRecordId()
Namespace: CRMGT.Page.Util
- Retorna o Guid do Registro para a tabela corrente, no formulário de LISTA de registros
GetIndexRecordListIds()
Namespace: CRMGT.Page.Util
- Retorna os Guids dos Registros [Selecionados] para a tabela corrente, no formulário de LISTA de registros
GetIndexEntityName()
Namespace: CRMGT.Page.Util
- Retorna o nome da tabela (schema name) a partir de uma LISTA de registros
GetCanSaveRecord()
Namespace: CRMGT.Page.Util
- True/false – Verifica se pode salvar um registro corrente no formulário
SetCanSaveRecord(value [true|false])
Namespace: CRMGT.Page.Util
- Determina se pode salvar um registro corrente no formulário
FormMode()
Namespace: CRMGT.Page.Util
- Retorna o Modo corrente do formulário:
- create
- add
- edit
- send
TriggerEnterActionOnField(id, value, frameId = "", eventName = "keydown")
Namespace: CRMGT.Page.Util
- Atribui um valor para um campo e logo em seguida executa um [Enter] nele.
- Por padrão, o comando vai usar o evento "keydown" do campo. Você pode especificar um evento diferente no parâmetro [eventName], como "keypress", por exemplo.
Dialogs
É possível utilizar diversos tipos de [dialogs] que fazem parte do Core do produto.
Não utilize estas funções com namespace, apenas faça referência direta ao nome das funções.
ShowDialog(action, _width, _height, _title, callFunc, closePreviousDialog, overflow, btns, fnCloseCallback)
- action - URL para visualização na Dialog
- _width, _height - valor númerico (em pixels)
- _title - Título da janela
- callFunc - Executa uma function quando a janela é Aberta. Passe o nome da function desejada neste parâmetro.
- closePreviousDialog - true|false - Fecha uma janela aberta (via ShowDialog) se existir
- overflow - Valores possíveis - visible, hidden, scroll e auto (valor padrão)
-
btns - Adiciona um conjunto de botões customizados.
Exemplo:
var btns = {};
btns["OK"] = function () {
MyFunc();
};
btns["Cancelar"] = function () {
CloseDialog();
};
-
fnCloseCallback - Executa uma function quando a tela é Fechada.
Passe o nome da function (ou anônima) desejada neste parâmetro.
Exemplo:
ShowDialog("/MyWebSite/Index", 850, 650, null, null, null, null, null, function () {
// My JS code...
});
ShowConfirmDialog(message, btnLabelYes, btnLabelNo, callbackFunc_Yes, callbackFunc_No, centerText, textFontSize, pWidth)
- message - Texto da mensagem
- btnLabelYes - Label para o botão [yes]
- btnLabelNo - Label para o botão [no]
- callbackFunc_Yes - Executa uma function quando o usuário clica no botão [yes]. Passe o nome da function desejada (ou anônima) neste parâmetro.
- callbackFunc_No - Executa uma function quando o usuário clica no botão [no]. Passe o nome da function desejada (ou anônima) neste parâmetro.
- centerText - true|false
- textFontSize - ex: "font-size:19px;"
- pWidth - ex: 400
-
Exemplo:
ShowConfirmDialog(
"Confirma a exclusão?",
"Sim",
"Não",
function () {
DeleteRecordById(_id);
},
function () {
CloseDialog();
}
);
ShowAlert(message, width, centerText, textFontSize, callbackFunc, imageType)
- message - Texto da mensagem
- width - largura da janela
- centerText - true|false
- textFontSize - Exemplo: font-size:12px; (O valor padrão é de 20px)
- callbackFunc - Executa uma function quando a janela é Fechada. Passe o nome da function desejada (ou anônima) neste parâmetro.
- imageType - warning (default), alert, error, success
-
Exemplo:
ShowAlert("Processo concluído...", 500, false, "font-size:15px;", function () {
MyFunc();
}, "success");
/TreeViewCheckBoxForm/Index
-
Utilize este componente se desejar efetuar um cadastro de informações na forma de uma [Árvore de Dados]
Por exemplo, dentro do cadastro de Produtos, você precisa informar os [Setores Industriais] para cada produto.
Os Setores possuem um cadastro na forma de árvore, onde cada setor possui seu registro [pai].
Então, para mostrar tudo isto de forma a continuar visualizando a árvore de setores e relacionar com o [Produto], faça o seguinte:
- Crie um campo do tipo [iFrame] no cadastro de Produtos
- Informe a seguinte URL no campo [src] do iframe (no OnLoad do formulário)
var sqlTreeViewStatement = "SELECT UPPER(IndustrialSectorId) id,";
sqlTreeViewStatement += " UPPER(PrimaryIndustrialSectorId) parent,";
sqlTreeViewStatement += " name as text,";
sqlTreeViewStatement += " (CASE WHEN PrimaryIndustrialSectorId = '#' THEN 'root' ELSE 'child' END) type";
sqlTreeViewStatement += " FROM IndustrialSector";
sqlTreeViewStatement += " ORDER BY name, PrimaryIndustrialSectorId";
var iFrameSrc = "/TreeViewCheckBoxForm/Index";
iFrameSrc += "?sqlTreeViewStatement=" + btoa(sqlTreeViewStatement);
iFrameSrc += "&parentIdFieldName=product_66dba258e5c4_id";
iFrameSrc += "&tableNameToStore=productIndustrialSector";
iFrameSrc += "&tableNameToStoreFieldName=industrialsector_47da919eba2f_id";
$("#industrialsector").attr("src", iFrameSrc);
- Onde:
- sqlTreeViewStatement - Informe o SELECT para preenchimento da árvore de dados
- parentIdFieldName - se refere ao campo de lookup de produto na tabela especificada no parâmetro [tableNameToStore]
- tableNameToStore - tabela de destino que conterá o [id] do [Produto] e do [Setor Industrial]
- tableNameToStoreFieldName - campo de lookup na tabela especificada no parâmetro [tableNameToStore]
Exemplo da configuração citada acima:
/TreeViewRegistration/Index
-
Utilize este componente se desejar efetuar um cadastro de informações na forma de uma [Árvore de Dados]
Por exemplo, se precisar cadastrar informações em uma tabela que posssui um relacionamento com ela mesma.
Imagine uma tabela de Setores Industriais. Cada registro pode ter um registro [pai], formando desta forma uma árvore de dados.
Então faça o seguinte:
- Entre em Configurações -> Áreas
- Escolha ou crie uma área e adicione um [Item da Área]
- Como Url informe:
- /TreeViewRegistration/Index?tableName=[NomedoEsquemaDaTabela]
- Ex: /TreeViewRegistration/Index?tableName=industrialsector
Exemplo da configuração citada acima:
Note que ao clicar em algum nó da árvore, podemos visualizar mais campos para edição.
Estes campos são lidos do metadados da tabela criada no sistema.
Execução de Código JavaScript ao Entrar no Sistema
Você pode executar um código JavaScript depois de logar no sistema. Isto é útil se precisar manipular algum dado na tela logo ao entrar, como por exemplo, esconder um item do menu de acordo com o perfil do usuário logado.
O exemplo abaixo faz isto, se o usuário tiver o perfil de [Vendedor], não poderá ver um [item do menu] chamado [Área do Gestor].
Para habilitar este recurso faça o seguinte:
- Crie um [Web Resource do tipo Script] e dê o nome de [RunScriptWhenLoadingMenu]
-
Adicione o código desejado:
var profile = CRMGT.UserConfig.Profile();
if (!CRMGT.Page.Util.IsNullOrEmpty(profile.userProfile)) {
if (profile.userProfile[0].departmentFunctionName.toLowerCase() == "vendedor") {
var _span = $("span").filter(function () {
return (this.innerText == "Área do Gestor");
});
_span.closest("div").css("display", "none");
}
}
Execução de Código JavaScript ao Entrar na Lista de Registros de Qualquer Tabela
Você pode executar um código JavaScript ao entrar na lista de registros de uma tabela. Isto é útil se precisar manipular algum objeto DOM nesta tela.
Para habilitar este recurso faça o seguinte:
- Crie um [Web Resource do tipo Script] e dê o nome de [RunScriptWhenLoadingGenFormIndex]
-
Adicione o código desejado.
Utilização de Built-In Procedures nas Query Execs
Algumas Stored Procedures foram criadas para facilitar a manipulação de dados do CRM-GT.
GetEmailsFromMultiLookupFieldValue
Retorna os emails de todos os valores de um MultiLookup (de usuário ou contato).
Exemplo: busca dos participantes (campo multiLookup) da tabela de [AppointmentActivity] e execução da procedure para obter os emails destes participantes.
SET @users = '';
SET @emails = '';
SELECT participants
FROM AppointmentActivity
WHERE AppointmentActivityId = '9BF0C60B-1FDF-48E9-B2F0-33438515A6FD'
INTO @users;
CALL GetEmailsFromMultiLookupFieldValue(@users, @emails);
SELECT @emails;
E o resultado:
gabriel001@gmail.com,mauricio@hotmail.com,gtezini@hotmail.com,
MultiLookup_GetLabels
Adiciona um registro de [trigger] de workflow programaticamente.
Exemplo: busca dos participantes (campo multiLookup) da tabela de [AppointmentActivity] e execução da procedure para obter os [nomes] destes participantes.
SET @users = '';
SET @labels = '';
SELECT participants
FROM AppointmentActivity
WHERE AppointmentActivityId = '9BF0C60B-1FDF-48E9-B2F0-33438515A6FD'
INTO @users;
CALL MultiLookup_GetLabels(@users, @labels);
SELECT @labels;
Resultado:
Gabriel Silva,Jose da Silva,gilberto
GetOriginatingRecordInfo
Retorna formatado o [name] do registro originador de uma determinada tabela.
Exemplo: Buscar o registro originador na qual uma [task] foi criada. Como resultado, veremos no exemplo abaixo, que a task foi criada a partir de uma [conta].
SET @originatingRecordInfo = '';
CALL GetOriginatingRecordInfo('task', '0cad354b-311a-42d0-a9a0-6b0e85dbdff0', @originatingRecordInfo);
SELECT @originatingRecordInfo;
Resultado:
SplitString
Efetua um Split em uma string e adiciona o resultado em uma TempTable.
Exemplo:
SET @value = 'slice1, slice2, slice3, slice4, slice5';
DROP TEMPORARY TABLE IF EXISTS temp;
CREATE TEMPORARY TABLE temp (rownumber INT, val VARCHAR(255));
CALL SplitString(@value, ",", "temp");
SELECT * FROM temp;
Resultado:
1 slice1
2 slice2
3 slice3
4 slice4
5 slice5
InsertIntoWorkflowTrigger
Adiciona um registro de [trigger] de workflow programaticamente.
Exemplo: Criar um gatilho para executar todos os workflows de [update] para a tabela de [incident], quando o campo [statuscode] mudar.
InsertIntoWorkflowTrigger('incident', 'update', @incidentId, 'statuscode,modifiedby', null, null, null, null, null);
Este método recebe os seguintes principais params:
1º - nome da Tabela (schema name)
2º - nome do Evento (create/update/delete/assign)
3º - RecordID (por ex, o id de um incident que foi atualizado diretamente no banco)
4º - Se precisar configurar o workflow para que seja executado somente quando campos específicos forem alterados, passe-os aqui, separados por vírgula, todos eles dentro de uma única aspas
Existem mais params, são opcionais (passe null por padrão), sendo:
5º - DeleteCurrentWorkflowTrigger (true/false) - default null
6º - CurrentWorkflowTriggerId (guid) - default null
7º - LastStepNotExecuted (usado internamente pelo sistema) - default null
8º - SpecificWorkflowDesignId (usado internamente pelo sistema) - default null
9º - WorkflowTriggerUserId (ID de um usuário do sistema, representando um usuário que iniciou o trigger de wk) - default null
-Importante:
- Se vc precisar Reprocessar [somente] um workflow específico, passe o Id para o parâmetro SpecificWorkflowDesignId e passe NULL para o 2º parâmetro (nome do evento)
-Por que isto é importante? Lembre-se que se o 2º parâmetro estiver preenchido, então o motor de workflow vai rodar [todos] os workflows do [evento] especificado (para o registro corrente).
Utilização de Built-In Functions nas Query Execs
Algumas Funções foram criadas para facilitar a manipulação de dados do CRM-GT.
cSec_to_Time
Retorna a conversão de segundos para Time.
Exemplo:
SELECT cSec_To_Time(1200)
cTime_to_Sec
Retorna a conversão de Time para Segundos.
Exemplo:
SELECT cTime_To_Sec("00:20:00")
GetUserDepartmentFunction
Retorna em quais Departamentos/Funções de Depto o usuário pertence
Exemplo:
SELECT GetUserDepartmentFunction('2d4485a8-5317-4537-8545-49ddd6af02b8')
DESIGN & ENGENHARIA (Cliente Portal),DESIGN & ENGENHARIA (VENDEDOR), Comercial / Regional Sul (VENDEDOR), Comercial / Regional Nordeste (VENDEDOR)