DrillDown
Este documento descreve o mecanismo de drill-down para entidades relacionadas.
Conceitos
O mecanismo de drill-down para entidades relacionadas é uma forma de navegar para a view de edit (default) da entidade relacionada.
O ícone do menu de contexto está visível sempre que o campo permite edição, mesmo quando o campo não tem focus ou hover.
Um campo permite que seja feito drill-down quando está preenchido com um valor válido de uma chave estrangeira para outra entidade, e essa entidade tem uma service operation do tipo DisplayAndEdit (Presentation Model).

Na imagem anterior, o campo Buyer Customer Party efetua a ligação entre a Fatura e o Cliente.
Existem as seguintes possibilidades para fazer drill-down:
- Quando um campo está preenchido e não está disabled, ou seja, quando ainda é possível alterar o seu conteúdo, é possível efetuar drill-down através do menu de contexto do campo, carregando na opção record ou carregando na descrição (caso tenha):
- Quando um campo está preenchido e está disabled, o próprio texto do campo é clicável:
Listas
No modelo Presentation é também possível definir para as entidades relacionadas, a possibilidade de efetuar drill-down numa coluna através da propriedade “Lookup drill-down” (ver Presentation Designer).

Na lista de Faturas, foi definido para a coluna Buyer Name, a possibilidade de efetuar drill-down.
O nome do cliente passa a ser uma hiperligação que permite fazer a navegação para view desse registo em modo de visualização.
Modelação
Drill down em campo de registos
Para que um campo seja de drill-down é necessário que, no modelo de entidades, o atributo correspondente seja do tipo view.
Drill-down em campo de listas
Para definir um campo de uma lista como permitindo drill-down é necessário aceder ao modelo presentation, aceder à list view e selecionar o campo pretendido, colocando a propriedade "Drill Down" a true.

Implementação
HTML
Numa view que tenha um campo que efetue a ligação a uma entidade relacionada, é gerado no HTML o seguinte código:
<pri-search-field
activator="dashboardActivator"
create-state="Patterns_CreatePartyBase"
datasource="simpleSales.invoices"
datatabstop="3"
drill-down="drillDown"
edit-state="Patterns_EditPartyBase"
entitydescription="model.buyerCustomerPartyDescription"
fieldsize="col-lg-12 col-md-12 col-sm-12 col-xs-12"
go-to-insert="goToInsert"
go-to-list="goToList"
hasdescription="true"
heading="@RES_LBL_Invoice_BuyerCustomerParty_Description"
id="BuyerCustomerParty"
labelsize="col-lg-12 col-md-12 col-sm-12 col-xs-12"
modelid="model.id"
ng-model="model.buyerCustomerParty"
placeholder="@ResolveResource("res_buyercustomerparty")"
popovercaption="@InsertOperationTitle"
property="buyerCustomerParty"
search-method="searchMethod"
sourceentity="customerParties"
sourcemodule="simpleBusinessCore"
sourcestate="modelState.buyerCustomerParty"
update="updateMasterField">
</pri-search-field>
As propriedades usadas pelo mecanismo são as propriedades drill-down, a propriedade edit-state e a propriedade property.
Diretiva
A diretiva pri-search-field implementa a lógica necessária para desenhar o link nos cenários apresentados anteriormente. Quando é clicado nesse link é executado o seguinte código da diretiva:
scope.onDrillDown = function () {
scope.drillDown(scope.editState, scope.property);
};
Esta função, apenas executa a função do controller.js da view que está binded à propriedade drill-down, usando como parâmetros, o estado de edit para este campo e qual a propriedade que o despoletou.
Exemplo:
Ao clicarmos na chave “SOFRIO” da imagem acima, é executada a função com os parâmetros scope.edit-state: “Patterns-EditPartyBase” e scope.property: “buyerCustomerParty”.
Controller JS
No controller.js da view é gerada a seguinte função:
/**
* provides a way to drill-down to the related entity.
* @param {string} state - angular state of the related entity. (e.g.: Patterns_EditPartyBase).
* @param {string} property - related entity property name. (e.g.: buyerCustomerParty, item).
*/
$scope.drillDown = function (state, property) {
// Check if the entity we are navigating to, has a BaseEntityId.
// e.g.: SalesItem, BuyerCustomerParty.
var propertyId = $scope.model[property + "BaseEntityId"];
// If it doesn't have a BaseEntityId use the property Id.
if (angular.isUndefined(propertyId)) {
propertyId = $scope.model[property + "Id"];
}
$state.go(state, { id: propertyId });
};
Esta função verifica se o modelo tem uma propriedade com o nome
Caso este valor não esteja definido, tenta obter o valor da propriedade
Após obter o Id, efetua a navegação para o estado definido no HTML, usando como parâmetro o Id da entidade preenchida.
Grelhas de Detalhes
Numa grelha de detalhes o mecanismo é semelhante, mas a função de drill-down é gerada no scope da linha, permitindo assim saber qual a coleção do modelo e o índice da linha:
/**
* provides a way to drill-down to the related entity.
* @param {string} state - angular state of the related entity. (e.g.: Patterns_EditPartyBase).
* @param {string} property - related entity property name. (e.g.: buyerCustomerParty, item).
*/
var drillDown = function (state, property) {
// Check if the entity we are navigating to, has a BaseEntityId.
// e.g.: SalesItem, BuyerCustomerParty.
var propertyId = $scope.model.documentLines[model.index][property + "BaseEntityId"];
// If it doesn't have a BaseEntityId use the property Id.
if (angular.isUndefined(propertyId)) {
propertyId = $scope.model.documentLines[model.index][property + "Id"];
}
$state.go(state, { id: propertyId });
};
Listas
Para a navegação nas listas é gerado na definição da coluna da lista o URI que permite efetuar o drill-down:

Na TVF que fornece os dados, quando é incluída uma propriedade de uma entidade relacionada, é incluída a coluna com o Id da entidade relacionada.

