Entity Extensions
Este documento descreve a implementação das extensões na Framework Elevation 300.
Modelo de Entidades

POCOs
A classe que representa a entidade SalesItem tem como base a classe “ExtensionBusinessEntityBase” e implementa a interface “IEntityExtension”.
public class SalesItem : ExtensionBusinessEntityBase, IEntityExtension { }
Resources
A classe que representa a resource SalesItem tem como base a classe “ExtensionBusinessResourceBase”.
public partial class SalesItemResource : ExtensionBusinessResourceBase
ControllersApp
Create
O serviço de create da extensão recebe como parâmetro o id da base (parentId).
[Route("{parentId}/new")]
[HttpGet]
CreateSalesItemResource(Guid parentId)
{
}
Neste serviço é feita a validação se já existe um draft da extensão para a respetiva entidade base:
- Se existir, é retornado esse draft;
- Se não existir, é criado um novo draft para a extensão que referencia a respetiva entidade base.
Submit
O controllerApp da extensão implementa a interface ISupportsExtension.
public interface ISupportsExtension
{
Task Submit(Guid id);
}
No momento do submit da entidade base, o DraftService é responsável por executar o submit de todas as extensões associadas.
Delete base and extensions
O manager da extensão implementa a interface ISupportsDelete.
public interface ISupportsDelete
{
Task Delete(Guid id);
}
No momento do delete da entidade base, o DraftService é responsável por executar o delete de todas as extensões associadas.
Ativar e desativar extensão
O serviço de ativar e desativar extensão recebe como parâmetro o id da base (parentId) e o valor para ativar e desativar a extensão.
[Route("~/app/{tenantKey}/{orgKey}/simpleBusinessCore/customerParty/{baseId}/active")]
[HttpPut]
[ResponseType(typeof(bool))]
public virtual async Task<bool> UpdateExtensionState(Guid baseId, [FromBody] bool value)
O serviço é responsável por alterar o estado do draft para ativo ou não. No momento do submit o estado do draft da extensão é refletido na entidade e submetido na base de dados.
Nota: A rota é gerada com o nome da extensão (no exemplo “customerParty”) pois para cada extensão existe apenas um serviço e existe uma limitação na arquitetura atual que na construção dos tabuladores não é possível obter o nome do serviço para uma dada extensão.
DraftService
O draft da extensão tem uma referência para o draft base (ParentId) bem como o FullName da classe do respetivo controllerApp (que implementa a interface ISupportsExtension).

DraftModel<TResource> GetExtension<TResource>(Guid id, Guid? schemaEntity)
Task ProcessExtensions(Guid parentId);
- GetExtension: retorna o draft de uma extensão (schemaEntity) para uma determinada base (id),
- ProcessExtensions: usado no momento de gravação da entidade base para gravar também as respetivas extensões.
Cliente
A view da extensão é modelada de forma independente da view da entidade base.
Quando o utilizador acede às operações da entidade base, é feita a validação se existem extensões, sendo estas incluídas em runtime.
Views
Sempre que uma entidade tem extensões associadas, são gerados no topo da view os respetivos tabuladores.
O tabulador da entidade base tem o nome “General”, sendo que o das extensões tem a caption definida no PresentationModel.
As extensões que não estão ativas aparecem no drop down.

Caso a extensão fique ativa é acrescentado um tab da extensão.

Caso se desative a extensão, o ‘Sales Item’ volta para a drop down, e o respetivo tab é removido. No entanto, se desativar uma extensão e voltar a ativá-la, a mesma fica com o estado prévio.
O HTML/Javascript da entidade base é carregado logo que se acede à operação.
Quanto ao HTML/Javascript da extensão, é carregado apenas no momento em que se acede ao respetivo tabulador.
A diretiva responsável por este comportamento:
<pri-extension-view statecreate="createState"
stateupdate="updateState"
…>
</pri-extension-view>
Config (state)
Cada extensão regista o respetivo estado no config do módulo onde é definida. Estes estados não têm parente definido.
$stateProvider
.state('createExtensionSimpleBusinessCoreSalesItem', {
parent: '',
templateUrl: function ($stateParams) {…},
params: { callback: null },
controller: 'BusinessCore.SalesItemCreateSalesItemController',
resolve: {
promiseObj: function ($q, $rootScope) {…}
}
});