Apostila DEV 365FO
Apostila DEV 365FO
Apostila DEV 365FO
1
Índice
Conceitual............................................................................................................................................... 3
Segurança..............................................................................................................................................69
2
Conceitual
O Microsoft Dynamics AX é uma solução de Enterprise Resource Planning (ERP) ou
Planejamento de Recursos Empresariais para organizações de porte médio e grande
que ajuda as pessoas a trabalharem efetivamente, gerenciar alterações e competir
no mundo inteiro. O Microsoft Dynamics AX funciona de maneira semelhante e
integrada ao software da Microsoft e é uma solução que automatiza e simplifica
processos financeiros, de business intelligence e de cadeia de suprimentos de uma
forma que ajude você em seus negócios.
3
Diferenciando nuvem de arquitetura local
Implantação na nuvem
Implantação no local
Ao decidir qual tipo de implantação sua organização deve usar, você deve considerar
a abordagem geral da implementação e o gerenciamento da
infraestrutura. Considerações adicionais incluem as preferências organizacionais
para atender às necessidades normativas e de conformidade dos negócios. Nesses
tipos de situações, uma implantação local pode ser escolhida.
4
Ferramentas de desenvolvimento no Visual Studio
Explorador de Aplicações
5
6
O modelo de projeto
Até mesmo um aplicativo simples pode ter um grande número de elementos em seu
modelo. O modelo do Projeto de Operações foi adicionado ao Visual Studio para
ajudá-lo a organizar e gerenciar os elementos com os quais você está trabalhando
para um modelo. Você usará o projeto para projetar, construir e testar elementos de
modelo. É comum ter vários projetos em uma única solução do Visual Studio. A
ilustração a seguir mostra três projetos em uma solução do Visual Studio.
Designers de elementos
7
Editor de código
8
Elementos, modelos e pacotes
Todos os modelos pertencem a pacotes, que podem ser empacotados juntos para
criar um pacote implementável e, em seguida, implementados usando o LCS. Um
pacote implementável contém um ou vários pacotes que são usados para ambientes
de tempo de execução. Os assistentes no Visual Studio são usados para criar modelos
e projetos, e a janela do designer é usada para personalizar elementos dentro de
projetos e modelos.
Pacotes implantáveis são implantados em ambientes de finanças e operações. Esses
pacotes contêm modelos que, em muitos casos, representam os módulos visíveis na
interface do usuário Finanças e Operações, como Contas a pagar. Os modelos contêm
os elementos que representam todos os campos, menus e formulários encontrados
na interface do usuário. Esses elementos são criados e gerenciados no Visual Studio.
Portanto, o controle de origem é necessário para o desenvolvimento de finanças e
operações.
9
Conectando o Visual Studio ao Visual Studio Team Services
Depois que a máquina virtual for iniciada, verifique se ela tem acesso à Internet e se
você utilizou a ferramenta de aprovisionamento de usuários admin para associar
sua conta do Dynamics 365 FO à conta de administrador de Operações. Antes de
começar, especialmente ao trabalhar em equipe, devemos renomear a VM para fazer
são únicos em toda a nossa equipe, veja a seção há mais ... para detalhes sobre isso.
1. Crie uma pasta para seus projetos e, abaixo de uma subpasta com suas
iniciais, ou outros que tornam a pasta única, dentro de sua equipe; no meu
exemplo, utilizaremos C: ProjectsTFS.
2. Inicie o Visual Studio.
3. Você será presenteado com a página de licenciamento. Use a página para
fazer login na conta usada para criar o projeto dentro do VSTS. Qual poderia
ser o seu Conta da Microsoft ou conta de trabalho (D365FO).
4. Na barra de ferramentas superior, selecione Equipe e, em seguida, Gerenciar
conexões.
5. O Team Explorer será aberto, no layout padrão, no lado direito. Em neste
painel, selecione Gerenciar Conexões | Conecte-se ao Team Project:
10
7. Selecione seu projeto na parte inferior da caixa de diálogo, conforme
mostrado a seguir na captura de tela:
11
13. Pressione OK.
14. Você será informado que o espaço de trabalho foi modificado e, se desejar
obtenha o código mais recente. Qualquer opção não tem efeito se formos o
primeiro desenvolvedor, mas é um bom hábito sempre pressionar Sim.
12
Para criar um novo projeto, siga estas etapas:
13
4. Agora você pode criar um novo pacote ou selecionar qualquer pacote existente.
Poderíamos crie um novo pacote e selecione o pacote necessário como pacotes
referenciados:
14
Como você viu, houve mais uma etapa ao criar um modelo, selecionar pacotes
referenciados. Quando você cria seu próprio pacote, você pode selecionar um pacote
existente para adicioná-lo como referências em seu novo pacote. Você pode precisar
adicionar alguma referência de pacote padrão se você deseja adicioná-los à sua
personalização.
15
Formulários do tipo Dialogs
Introdução
Neste tópico, abordaremos vários aspectos do uso do Dynamics 365 for Finance e
Formulários de operações. Começamos criando diálogos do Dynamics 365 for
Finance and Operations, que são formas dinâmicas e depois explicam como lidar
com seus eventos. Também será mostrado como criar formulários dinâmicos, como
adicionar controles dinâmicos aos formulários existentes e como fazer formulários
modais.
16
clientes mostrados em diferentes grupos e guias para criar um novo registro. Haverá
duas páginas (Tab Page), Geral e Detalhes. A primeira página terá os controles de
entrada de conta de cliente e nome a segunda página será dividida em dois grupos,
Configuração e Pagamento, com campos relevantes dentro de cada grupo. O
registro real não será criado, pois está além do escopo deste exemplo. No entanto,
para fins de demonstração, as informações especificadas pelo usuário serão exibidas
no Janela de um infolog.
dialog = super();
dialog.caption("Informações do Cliente");
17
dialog.addTabPage("Detalhes");
groupCustomer = dialog.addGroup("Configuração");
fieldGroup = dialog.addField(extendedTypeStr(CustGroupId),"Grupo do Cliente");
fieldCurrency =dialog.addField(extendedTypeStr(CurrencyCode),"Moeda
Corrente");
groupPayment = dialog.addGroup("Pagamento");
fieldPaymTermId= dialog.addField(extendedTypeStr(CustPaymTermId),"Condição de
Pagamento");
fieldPaymMode = dialog.addField(extendedTypeStr(CustPaymMode),"Método de
Pagamento");
return dialog;
}
Agora, quando os usuários selecionam seus valores desejados, precisamos ler todos
eles para mostrar no infolog. Use getFromDialog para ler o valor de um campo de
diálogo:
Use o método run para fazer instruções Infolog, como no código a seguir:
if (myDialog.prompt())
{
myDialog.run();
}
}
18
3. Para testar a caixa de diálogo, clique com o botão direito do mouse nessa classe e
defina como projeto de inicialização.
4. Construa seu projeto. Agora, execute o projeto. O seguinte formulário aparecerá
no navegador de internet:
4. Clique na ficha de registro Detalhes; você verá uma tela semelhante à seguinte
captura de tela:
19
Entendendo nosso desenvolvimento:
Para tornar esta classe executável, o método main() estático deve ser criado. Aqui
nós criamos um novo objeto do tipo CustCreate invoca o diálogo de usuário
20
chamando o método prompt() Depois que o usuário terminar de inserir os detalhes
do cliente, clicando em OK, o método run() é invocado para processar os dados.
Nesta atividade, vamos criar uma caixa de diálogo semelhante ao anterior, mas em
vez de entrar o número do cliente, poderemos selecionar o número de uma lista
semelhando a um combobox. Quando o cliente estiver selecionado, o restante dos
campos será preenchido automaticamente pelo sistema a partir do cliente registro.
21
2. Crie um método de diálogo para capturar entradas do usuário de tempo de
execução para detalhes do cliente:
Object dialog()
{
Dialog dialog;
DialogGroup groupCustomer;
DialogGroup groupPayment;
dialog = super();
dialog.caption("Informações do Cliente")
dialog.allowUpdateOnSelectCtrl(true);
dialog.addTabPage("Detalhes");
groupCustomer = dialog.addGroup("Configuração");
fieldGroup = dialog.addField(extendedTypeStr(CustGroupId),"Grupo do Cliente");
fieldCurrency =dialog.addField(extendedTypeStr(CurrencyCode),"Moeda
Corrente");
fieldGroup.enabled(false);
fieldCurrency.enabled(false);
groupPayment = dialog.addGroup("Pagamento");
fieldPaymeTermId= dialog.addField(extendedTypeStr(CustPaymTermId),"Condição de
Pagamento");
fieldPaymMode = dialog.addField(extendedTypeStr(CustPaymMode),"Método de
Pagamento");
fieldPaymeTermId.enabled(false);
fieldPaymMode.enabled(false);
return dialog;
}
custTable = CustTable::find(fieldAccount.value());
fieldName.value(custTable.name());
fieldGroup.value(custTable.CustGroup);
fieldCurrency.value(custTable.Currency);
fieldPaymTermId.value(custTable.PaymTermId);
fieldPamMode.value(custTable.PaymMode);
}
if (myDialogSelect.prompt())
{
myDialogSelect.run();
}
}
22
3. Defina esta classe como Set as Startup Object (Objeto de início)
4. Salve todas as suas alterações e construa seu projeto. Agora execute o projeto. Os
seguintes formulários serão exibidos no browser.
5. Execute o projeto, selecione qualquer cliente da lista e mova o cursor para o
próximo controle. Observe como o restante dos campos serão preenchidos
automaticamente com as informações do cliente, conforme mostrado na captura
de tela a seguir:
23
6. Ao clicar na página da guia Detalhes, você verá mais informações sobre o cliente,
conforme mostrado na captura de tela a seguir:
24
Gerenciamento de Dados
Introdução
Entidades de dados
Na versão anterior do Dynamics 365 for Finance and Operations, há várias opções
como DIXF, Excel Add-ins e AIF para gerenciamento de dados. Entidades de dados
são introduzidos como parte do gerenciamento de dados para ser usado como uma
camada de abstração para facilmente entender usando conceitos de negócios. O
conceito de entidades de dados combina esses conceitos diferentes em um. Você
pode reutilizar dados entidades para um Excel Suplementos, Integração ou
Importação / Exportação. A tabela a seguir mostra os principais cenários de
gerenciamento de dados:
25
Criando uma entidade de dados
26
3. Adicione uma nova entidade de dados no projeto clicando com o botão direito do
mouse no menu da seguinte maneira:
27
5. Na próxima etapa, você deve escolher todos os campos obrigatórios, para esta
atividade vamos manter apenas alguns campos e marcá-los como é obrigatório
também. Uma vez feito, clique em Finish:
28
Adicione um novo registro da seguinte maneira e salve-o. Agora clique em Validar:
8. Vamos tentar importar dados para o PacktVendTable usando essa nova entidade
de dados. Agora vá de volta ao espaço de trabalho de gerenciamento de dados.
Carregue o arquivo do Excel que contém dados. Agora clique no botão Importar.
Você vai ter uma notificação assim que esta importação é feita. Para verificar,
navegue na tabela e verifique os dados inseridos.
29
Estruturas de dados
Tipos enumeradores
EDT (Extended Data Type)
Tabelas de configuração
Tabela de parâmetros
Tabelas de dados principais
Este tópico não cobre a criação de extensões de tipos padrão, mas cobre como criar
tipos que permitam que suas estruturas sejam extensíveis.
Tabelas em Dynamics 365 FO têm uma propriedade que define o tipo de tabela e
cada tipo é associado a um estilo particular de formulário para a interface do
usuário. Poderíamos, portanto, considerar esses tipos como padrões. Se pensarmos
neles como padrões, é muito mais fácil aplicar as receitas para nosso próprio
desenvolvimento.
A lista a seguir é dos tipos de tabelas comuns, listados com o design de formulário
usual e suas uso típico:
30
de lista simples e detalhes devem ser
usado para que os campos sejam
apresentados de uma maneira útil para
o usuário.
Main Mestre Detalhe Isso é usado para tabelas principais,
como clientes, fornecedores e itens.
Transaction Lista simples e Isso é usado para conjuntos de dados,
Header Detalhes com Guias como a fatura formulário de diário, que
Transaction Line padrão contém informações transacionais
dados com cabeçalho e linhas.
Transaction Lista simples e Isso é usado para tabelas, como o
Detalhes com Formulário de transação de Inventário,
padrão guias que contém dados transacionais, mas
em um único nível.
Worksheet header Detalhes Transação Isso é usado para conjuntos de dados de
Worksheet line entrada de dados, como a ordem de
compra, em que o conjunto de dados é
composto tabelas de cabeçalho e linha.
O padrão tem dois visualizações, uma
exibição de lista de registros de
cabeçalho e um detalhe veja onde o foco
são as linhas.
Worksheet Mestre Detalhe Este é um conjunto de dados de entrada
de dados de nível único, que são
raramente usados no Dynamics 365 FO.
Tipos enumeradores são semelhantes aos tipos de enumeradores em C#. Eles são
comumente referidos como Enums. É um inteiro referenciado como símbolo, que
pode ser usado no código para controlar a lógica. Também pode ser usado como um
campo em uma mesa que fornece uma lista suspensa fixa ao usuário. Quando usado
como um campo, ele tem a capacidade de fornecer etiquetas fáceis de usar para cada
símbolo.
Todos os Enums devem ser definidos no modelo de dados antes de usá-los e não
podem ser definidos dentro de uma classe ou método.
31
Adicionar valores a enums por meio de extensão:
Para adicionar novos valores a um enum, você deve estender o enum. Qualquer
enum que esteja marcado como Extensible ( IsExtensible = true ) pode ser estendido.
Você pode encontrar as informações de extensibilidade na janela Propriedades no
Microsoft Visual Studio, conforme mostrado na ilustração a seguir:
Normalmente, um enum extendido deve ter sua própria implementação onde quer
que seja usado. Procure todos os usos do enum e aproveite a implementação onde
for necessário.
Estendendo um enum
Crie um projeto que tenha uma referência de modelo onde você deseja a nova
extensão de enumeração. Clique com o botão direito do mouse no enum para
estender e selecione Criar extensão.
32
Clique com o botão direito do mouse no enum para estender e selecione Criar
extensão em novo projeto. Você é solicitado a selecionar o modelo no qual o enum
de extensão deve ser criado.
Symbol Value
None 0
Backorder 1
Delivered 2
Invoiced 3
Canceled 4
33
Dessa forma, podemos selecionar todos os pedidos de vendas, que ainda não foram
faturados, usando os seguintes linhas de código:
Os EDTs típicos que usamos para isso são mostrados na seguinte tabela:
34
Exemplos incluem o seguinte:
• Conta de cliente
• conta do fornecedor
Name String 60 Todos os campos de nome devem ser baseados
neste EDT, como nome, nome do cliente e assim
por diante. Este EDT pode ser usado como é, a
menos que desejemos especificar um rótulo e um
texto de ajuda.
Description String 30 Isso é usado como o campo de descrição nas
tabelas de grupos. Este EDT é geralmente usado
como está e geralmente não é estendido.
AmountMST Real Todos os EDTs de valor monetário que
armazenam a quantia em moeda local moeda
deve basear-se neste EDT. MST significa Norma
Monetária.
AmountCur Real Todos os EDTs de valor monetário que
armazenam o valor no A moeda da transação
deve ser baseada neste EDT.
Qty Real Todos os campos que armazenam uma
quantidade devem ser baseados neste EDT.
35
está sob a seção Aparência, mas ele
controla o tamanho dos campos
associados no base de dados.
Reference Table Para tipos usados como um campo de
chave primária em uma tabela,
propriedade deve ser preenchida.
Juntamente com as referências da
tabela, pode ser usado para criar a
relação de chave estrangeira em tabelas
filhas.
Property Value
Name PaymMode
ExtendedDataType CustPaymMode
36
O campo recém-criado é baseado no tipo de dados estendidos e portanto, herda
automaticamente sua relação. Para seguir as melhores práticas, todas as relações
devem estarem presentes.
Nota: EDT não deve ser utilizado para aplicar regra de negócio em customizações.
Nesta seção, criaremos uma tabela de grupos. Uma tabela de grupo é usada como
uma chave estrangeira na principal tabelas, como o grupo de clientes na tabela de
clientes e o grupo de fornecedores na tabela de fornecedores; as tabelas de clientes
e fornecedores são exemplos de tabelas principais. Tabelas de grupo tem pelo
menos dois campos, um ID e um campo Descrição, mas pode conter mais conforme
necessário. Nesse caso, para ajudar o fluxo, criaremos a tabela de grupos primeiro.
Vamos criar uma tabela de grupos de veículos. Nós não temos muita escolha sobre
o nome neste tem que começar com nosso prefixo e terminar com Group portanto
fica a sugestão ConWHSVehicleGroup. Para criar essa tabela, siga estas etapas:
Propriedade Valor
Name ConWHSVehicleGroupId
Label Vehicle group
Help Text Id do grupo de veículos
Extends SysGroup
37
7. Isso cria o campo com o mesmo nome que o EDT. Como esta é a nossa mesa,
devemos remover o prefixo e nomeá-lo como VehicleGroupId.
8. Agora podemos concluir nosso EDT, abrir o ConWHSVehicleGroupId EDT ou
selecione a guia se ela ainda estiver aberta) e insira ConWHSVehicleGroup na
Referência Propriedade da tabela.
9. Clique com o botão direito do mouse no nó Referências da Tabela e selecione Novo
| Referência de tabela.
10. Na folha de propriedades, selecione a propriedade Campo Relacionado e
selecione VehicleGroupId na lista suspensa.
11. Salve o EDT e feche seu designer. Isso deve tornar a guia ativa Designer de tabela
ConWHSVehicleGroup; se não, selecione novamente.
12. No Explorador de Aplicativos, que é aberto no menu Visualizar, expanda Tipos
de Dados e, em seguida, expanda Tipos de dados estendidos.
13. Localize o campo Descrição e arraste-o para o nó Campos de nossa tabela.
Uma tabela de parâmetros contém apenas um registro por empresa. A tabela contém
uma lista de campos, que podem ser padrões ou opções específicas da empresa
usadas no código para determinar o que deve acontecer. A tabela de parâmetros
geralmente é criada primeiro e os vários campos que atuam como parâmetros são
adicionados à medida que criamos a solução.
38
Para criar a tabela de parâmetros, siga estas etapas:
Propriedade Valor
Label Parâmetros de gerenciamento de veículos
Cache lookup Encontrado
Table Group Parameter
Created By Yes
Created Date Time
Modified By
Modified Date Time
Developer A tabela ConWHSVehicleParameters armazena os
Documentation parâmetros para a solução de gerenciamento de
veículos
39
registros de grupos de veículos, ou
um.
Relationship Association O registro de parâmetro está
Type associado a um registro do veículo. A
composição seria usada em conjuntos
de dados de cabeçalho / linhas, em
que Cabeçalho deve excluir os
registros de linhas.
On Delete Restricted Isso impedirá que um registro de
grupo de veículos seja excluído, se for
especificado nesta tabela.
Role Este é o papel da relação, e deve ser
único dentro desta tabela. Se
UseUniqueRoleNames for Sim,
somente precisa especificar isso se
tivermos dois chave estrangeira
relações com a mesma tabela.
40
15. Vamos usar uma declaração select ligeiramente diferente, onde podemos escrever o
select declaração na linha, o que significa que não temos que declarar o tipo como uma
variável, escreva o método Exist da seguinte forma:
public static boolean Exist()
{
return (select firstonly RecId
from ConWHSVehicleParameters).RecId != 0;
}
16. Queremos garantir que o registro não possa ser excluído. Então, vamos
substituir o Excluir o método. Pressione Return no início do método Find para criar
um espaço em branco linha no topo. Clique com o botão direito do mouse nessa linha
em branco e escolha Inserir Método de Substituição | Excluir. Altere o método para
que ele leia da seguinte maneira:
public void delete()
{
throw error("@SYS23721");
}
17. Nós definimos a propriedade Table Cache como EntireTable. Sempre que esta
tabela é atualizado, precisaremos liberar o cache para que o sistema use a
atualização valores. Substitua o método de atualização da seguinte maneira:
public void update()
{
super();
flush ConWHSVehicleParameters;
}
Fato relevante:
A operação de compilação validará e compilará o pacote em uma DLL. Isso deve ser
feito antes de sincronizarmos o banco de dados. Isso pode falhar, e nesta fase, é
normalmente devido a referências ausentes. No Explorador de Aplicativos, cada
elemento mostra o pacote para qual pertence. Devemos garantir que nossas
referências de modelo para todos os tipos que usamos dentro nosso projeto. Se não
o fizermos, obteremos erros de construção como este:
41
Para adicionar as referências necessárias, podemos seguir estas etapas:
1. Localize o tipo com o erro no Explorador de Aplicativos.
2. Observe o pacote em que está, entre colchetes.
3. Navegue para o Dynamics 365 | Gestão de Modelos | Atualize os parâmetros do
modelo ....
4. Selecione o modelo ConWHSVehicleManagement.
5. Clique em Next.
6. Verifique se o pacote necessário está marcado e, em seguida, pressione Avançar.
7. Pressione Concluir.
8. Navegue para o Dynamics 365 | Modelo de gerenciamento e selecione Atualizar
modelos.
9. Tente a operação de construção novamente; você pode precisar repetir isso como
um erro pode mascarar outro.
Para seguir essas etapas, os elementos criados anteriormente neste capítulo devem
ser criados.
Para criar a tabela de veículos, siga estes passos:
1. Crie o EDT ConWHSVehicleId com as seguintes propriedades:
Propriedade Valor
Name ConWHSVehicleId
Extends Num
Label Vehicle Id
Help Text Id do Veículo
42
2. Crie o EDT ConWHSVehRegNum com as seguintes propriedades:
Propriedade Valor
Name ConWHSVehRegNum
Size 10
Label Número de registro do veículo
Help Text Número de registro do veículo
Change case UpperCase
43
11. O campo GroupId de uma tabela principal geralmente tem um impacto na lógica,
e é geralmente obrigatório. Mesmo que isso não aconteça, ainda devemos criar o
campo VehicleGroupId obrigatório.
12. Não torne obrigatório o campo VehicleType.
13. Crie um índice exclusivo chamado VehicleIdx com o campo VehicleId.
14. Os campos de grupo são frequentemente usados para consultas de agregação ou
de pesquisa, portanto, devemos criar um índice chamado VehicleGroupIdx e
adicione o campo VehicleGroupId a ele, o índice não deve ser exclusivo.
15. Preencha as propriedades da tabela da seguinte forma:
Propriedade Valor
Label Vehicles
Title Field 1 VehicleId
Title Field 2 Description
Cache lookup Found
Clustered Index VehicleIdx
Primary Index VehicleIdx
Table Group Main
Created By Yes
Created Date Time
Modified By
Modified Date Time
Developer ConWHSVehicleTable contains vehicle records
Documentation
Form Ref This is blank until we have created the form
44
Relationship Type Association
On Delete Restricted
23. Em seguida, adicione os métodos Find e Exist usando o campo de chave primária
da tabela como habitual.
24. Finalmente, adicionaremos um método de validação de campo para garantir que
a data de aquisição não é antes de hoje. Substitua o método validateField e adicione
o seguinte código entre o código o ret = super (); linha e retorno ret ;:
switch (ret)
{
case fieldNum(ConWHSVehicleTable, AcquiredDate):
Timezone clientTimeZone = DateTimeUtil::getClientMachineTimeZone();
TransDate today =DateTimeUtil::getSystemDate(clientTimeZone);
if(this.AcquiredDate < today)
{
// The acquisition date must be today or later
ret = checkFailed("@ConWHS:ConWHS29");
}
break;
}
25. Crie um rótulo para a mensagem de erro retornada por checkFailed e substitua
o literal com o ID da etiqueta.
26. Depois de concluído, salve e feche o editor de código de tabela e as páginas da
guia designer.
Nota:
A instrução switch deve sempre ser usada no método validateField, mesmo se nós
só pretendo lidar com um caso. Uma declaração if pode parecer mais fácil, mas fará
o código menos passível de manutenção. Isso vale para qualquer cheque como este,
onde os casos têm a possibilidade de aumentar.
45
Interface do usuário
Estrutura do menu
Formulário de parâmetro
Itens de menu
Formulários de configuração
Formulário mestre (tabela principal)
Formulário de transação de detalhes (entrada de pedido)
Etiquetas (Label)
Ao criar formulários, devemos fornecer consistência aos usuários, e para ajudar com
isso, nós usaremos padrões de design de formulário. O padrão de design do
formulário é determinado pelo grupo de tabelas, Estruturas de Dados. Existem casos
especiais em que podemos ter variações, mas, para a parte principal, devemos nos
ater aos padrões sugeridos neste capítulo.
46
Cada menu aparece na opção Módulos, conforme mostrado na captura de tela a
seguir:
47
A estrutura atual agora está organizada da seguinte maneira:
O menu ainda precisa de uma estrutura comum para facilitar a localização dos
usuários opções mais facilmente, mas não estamos limitados a uma estrutura rígida.
Você pode argumentar que o menu não tem um nó de espaço de trabalho, isso é
porque isso foi adicionado através de um menu extensão, conforme mostrado na
captura de tela a seguir:
48
Vamos apenas precisar do nosso projeto aberto no Visual Studio:
Name Label
Workspaces @SYS:Platform_Menu_ColHeading_Workspaces
Vehicles Vehicles (new label)
ServiceOrders Service orders (new label)
PeriodicTasks @SYS76406
InquiriesAndReports @SYS3850
Setup @SYS333869
7. Podemos adicionar mais submenus para ajudar a organizar a estrutura, se esta for
requeridos.
8. Salve e feche o designer de menu.
9. Agora precisaremos estender o menu principal para que possamos navegar para
o nosso menu.
10. No Explorador de Aplicativos, navegue até AOT | Interface do usuário | Menus
11. Clique com o botão direito do mouse em MainMenu e escolha Criar extensão.
12. Renomeie o novo item em nosso projeto de MainMenu.Extension para
MainMenu.ConWHSVehicleManagement.
13. Abra MainMenu.ConWHSVehicleManagement.
14. Clique com o botão direito do mouse no nó raiz e escolha Novo | Referência de
menu.
15. Defina as propriedades Name e Menu Name como ConWHSVehicleManagement.
16. Salve e feche o designer.
49
Criando um formulário de parâmetro
Os formulários de parâmetros mostram as configurações em grupos de campos e
guias usando um índice forma de estilo. Eles também são usados para mostrar as
sequências numéricas configuradas para esse módulo. Estamos seguindo nossa
solução de amostra de gerenciamento de veículos, mas esse padrão pode ser
aplicado a qualquer tabela de parâmetros.
7. Vamos aplicar algumas propriedades básicas para o formulário, que são mantidas
contra o Design nó, como mostrado aqui:
50
Propriedade Valor Comentário
Caption Parâmetros de gerenciamento Isso é mostrado no título do
de veículos formulário e geralmente é o
nome da mesa.
Data Source ConWHSVehicleParameters Os nós filhos no formulário
usarão isso como a
propriedade padrão Data
Source.
Title Data Source ConWHSVehicleParameters Este formulário usará o
campo de título propriedades
da tabela e exibição no
formulário.
8. O nó Design indica que um padrão não está especificado, o que devemos fazer.
Para aplique o padrão de formulário principal, clique com o botão direito do mouse
no nó Design e escolha Aplicar Padrão | Índice.
9. O painel inferior muda para a guia Padrão e mostra o padrão requerido estrutura,
como mostrado na captura de tela a seguir:
Vamos nos referir a cada nó na estrutura padrão como um elemento padrão e, para
facilitar o design, nomeie os controles com base no nome do elemento padrão.
10. Isso nos permite adicionar um controle Tab, então clique com o botão direito do
mouse no nó Design e escolha Novo | Aba.
11. O erro é removido do painel Padrão, mas mostra que não temos páginas de guias
dentro do elemento padrão TOC Tabs (Tab).
12. Primeiro, renomeie o novo controle para ParameterTab e adicione uma nova
Página de guia por Clique com o botão direito do mouse sobre ele no painel Design
e selecione Nova página de guia.
13. A primeira guia geralmente é uma guia de configurações gerais, portanto, nomeie
esse novo controle GeneralTabPage.
14. Encontre um rótulo adequado para Geral e insira-o na propriedade Rótulo.
15. À medida que alteramos o design, o designer verificará continuamente se somos
em conformidade com o padrão. Encontrou os seguintes problemas com a ficha de
registro ao controle:
51
16. Devemos adicionar dois controles de Grupo, um para campos de título que
fornecem ajuda ao usuário, e o outro para os campos que desejamos mostrar nesta
página.
17. Clique com o botão direito do mouse no controle GeneralTabPage e selecione
New | Grupo.
18. Renomeie o novo controle de grupo para GeneralTitleGroup.
19. O painel de conformidade de padrão mostra que devemos ter um controle
StaticText para o título principal e 0 ou 1 controles StaticText para um título
secundário. Clique com o botão direito do mouse GeneralTitleGroup e escolha Novo
| Texto estático.
20. Mude o nome do novo controlo StaticText para GeneralTitleText.
21. Crie um novo rótulo para o texto Parâmetros gerais e insira o ID no Propriedade
de texto.
22. Selecione novamente o controle GeneralTitleGroup e verifique se os erros de
padrão desapareceram.
23. Selecione novamente o GeneralTabPage, pois agora temos um erro de padrão
para um grupo ausente. Adicione um novo controle de grupo.
24. O novo grupo de controle sabe que também deve ter um padrão aplicado,
indicado pelo padrão: texto <não especificado> após o nome do controle. Clique com
o botão direito do mouse controle e escolha Aplicar padrão | Campos e Grupos de
Campo.
25. Mude o nome do controlo para GeneralFields.
26. No painel de formulário, expanda Data Sources, ConWHSVehicleParameters e,
em seguida, Grupos de campo.
27. Arraste o grupo de campos Padrões para o controle GeneralFields no painel de
desenho, conforme mostrado na captura de tela a seguir:
52
28. Verifique cada nó quanto a erros de conformidade de padrão.
29. Finalmente, teremos uma tarefa especial para formulários de parâmetros; para
garantir que pelo menos existe um registro, clique no nó Métodos e escolha Override|
init.
30. Crie uma linha em branco antes da chamada para super() e digite a seguinte linha
de código:
ConWHSVehicleParameters::Find();
Nota:
Quando especificamos o padrão principal do design do formulário, somos guiados
para os controles que deve adicionar e onde. Isso nos ajuda a garantir que os
formulários que criamos sigam uma prática recomendada design de interface do
usuário, que, por sua vez, torna nossos formulários mais fáceis de usar, mais rápidos
de treinar e menos propenso a erro do usuário. Ainda podemos desativar o padrão
usando o padrão Personalizado; isso nos permite adicionar qualquer controle em
qualquer ordem. Isso deve ser evitado, e o design do formulário deve ser
redesenhado que ele usa padrões padrão.
O formulário é baseado na classe FormRun. Podemos ver isso abrindo (clique duas
vezes) classDeclaration para o formulário CustGroup:
public class ConWHSVehicleParameters extends FormRun
53
As fontes de dados são declaradas como variáveis globais para o formulário e
fornecem uma camada de funcionalidade entre o formulário e a tabela. Isso nos
permite controlar a interação entre os controles de formulário vinculados e a tabela.
Vamos sobrescrever o método init na fonte de dados e, em seguida, substituir o
modifiedField evento em um campo; o editor de código apresentará a alteração da
seguinte maneira:
[Form]
public class ConWHSVehicleParameters extends FormRun
{
public void init()
{
ConWHSVehicleParameters::Find();
super();
}
[DataSource]
class ConWHSVehicleParameters
{
public void init()
{
super();
}
[DataField]
class DefaultVehicleGroupId
{
public void modified()
{
super();
}
}
}
}
Ele adiciona a fonte de dados como uma classe na declaração de classe do formulário
e, em seguida, adiciona o campo como uma classe dentro da classe de fonte de dados.
Este é o único local em Operações onde este ocorre. Se a classe de fonte de dados
fosse uma classe, ela teria que estender FormDataSource. O Os atributos Form,
DataSource e DataField são uma pista do que está acontecendo aqui. Como tudo
código executável compila para os tipos CLR, o compilador usa esses atributos para
criar os tipos reais. A estrutura é escrita como tal para nossa conveniência como uma
apresentação de código.
Vamos pegar o método modifiedField. Este é um evento que ocorre após o O evento
validateField retorna true. A chamada super() chama o método modifiedField da
tabela. método. Podemos nos perguntar por que a chamada para super () não tem
parâmetro. Isso acontece por trás as cenas, e é útil que isso seja tratado por nós. Esse
padrão é seguido pelos seguintes métodos:
54
DataSource method Calls table method
validateWrite validateWrite
write write (in turn, insert or update)
initValue initValue
validateDelete validateDelete
delete delete
DataField.validateField validateField(FieldId)
DataField.modifiedField modifedField(FieldId)
55
As linhas de correspondência de tipo de link de origem de dados
Exist join de formulário existentes correspondem à tabela pai. Ele se
comporta como inner join, mas o diferente é uma vez que a linha
pai é correspondida com os registros filhos, em seguida, para o
processo e atualiza na grade, o D365FO não considera quantos
registros na tabela filha para a linha pai.
Não existe o tipo de link da fonte de dados do formulário de
Not exist join junção é um método totalmente oposto a existir. Ele retornará
os registros pai não correspondentes com registros filhos.
56
Embora esta atividade esteja listada isoladamente, ela deve sempre ser feita como
parte do processo.
Por exemplo, o processo de criação de uma tabela de parâmetros envolve quatro
etapas principais:
1. Crie a tabela
2. Crie o formulário
3. Crie o item de menu
4. Adicione o item de menu ao menu
Quase todas as tabelas que criamos em Operações terão um formulário usado para
mantê-lo. Então, a última parte do design da tabela é dizer ao design da tabela qual
formulário é utilizado para esse fim. É assim que a opção visualizar detalhes
funciona no cliente. A chave estrangeira é usada para determinar a tabela, e a
propriedade Form Ref da tabela é usada para determinar o formulário a ser usado.
Os detalhes da chave estrangeira são usados para filtrar o formulário. Todos isso
acontece automaticamente com base nos metadados. Itens de menu para
formulários e relatórios acionam o sistema para criar e executar o formulário ou
relatório definição. O formulário é renderizado no navegador usando um JavaScript
muito inteligente que interfaces com o servidor, e os relatórios são essencialmente
renderizados usando o SSRS. As classes devem tem um método de ponto de entrada
estático para ser chamado.
57
7. Aplique o padrão Simple List ao Design (clique com o botão direito e escolha Apply
Pattern | Lista Simples).
8. Adicione um controle ActionPane; renomear para FormActionPaneControl como
haverá apenas seja um neste formulário.
9. Selecione novamente o nó Design. O padrão destaca que precisamos de um filtro
personalizado Grupo, que é um controle de grupo. Então, adicione um novo controle
do tipo Group.
10. Renomeie o controle para CustomFilterGroup, para facilitar a referência.
11. Podemos ver que o novo controle de grupo precisa de um padrão; atribuir
personalizado e rápido Filtros
12. Agora teremos mais a fazer para esse controle. O padrão destaca que nós
devemos ter um QuickFilterControl. Clique com o botão direito no
CustomFilterGroup controle e escolha Novo | QuickFilterControl.
13. Clique com o botão direito do mouse no nó Design e selecione Novo | Grade.
14. Podemos renomear o controle para FormGridControl, pois haverá apenas uma
grade controle com este padrão.
15. A propriedade Data Source não herda do nó pai, e devemos especifique isso como
ConWHSVehicleGroup.
16. Criamos um grupo de campos Visão Geral para esta tabela, portanto, defina o
Grupo de Dados propriedade para Visão geral.
17. Volte para o controle QuickFilter e defina Target Control para o controle de grade
nome e Coluna Padrão para o controle padrão desejado do controle de destino.
18. Verifique novamente se há erros no painel de padrões e salve o formulário.
19. Em seguida, crie um item de menu usando o mesmo nome do formulário e o
mesmo rótulo nós usamos na propriedade Caption.
20. Preencha a propriedade Form Ref da tabela com o nome do item de menu.
21. Por fim, adicione o item de menu ao menu de configuração para que ele fique sob
os Parâmetros item do menu.
Nota:
As etapas foram semelhantes à forma de parâmetro, embora houvesse apenas mais
algumas para completo. Podemos ver que o padrão é na verdade uma lista de tarefas,
embora erros de padrão impedir que o projeto seja construído.
58
Se você quiser realmente testar o formulário, você pode fazer isso seguindo estas
etapas:
1. Crie o pacote usando o Dynamics 365 FO | Construa Modelos, selecione o
pacote de a lista.
2. Se adicionarmos tabelas ou campos desde a última sincronização do banco
de dados, sincronize os bancos de dados clicando com o botão direito do
mouse no projeto e escolhendo sincronizar <seu nome do projeto> com
banco de dados.
3. Abra as propriedades do projeto.
4. Defina a opção Tipo de objeto de inicialização como MenuItemDisplay.
5. Defina a opção Startup Object para o item de menu a ser aberto, por exemplo,
ConWHSVehicleGroup.
6. Especifique a empresa inicial; A USMF é uma empresa útil para quando
estamos usando a VM de desenvolvedor que usam os dados de demonstração
da Microsoft.
7. Feche o formulário de propriedades e pressione F5.
Também é assim que depuramos o código, e se um ponto de interrupção for
encontrado, o Visual Studio interromperá o processamento nos permitindo
analisar o ponto a ponto.
59
3. Nomeie o formulário conforme o nome da tabela; nesse caso,
ConWHSVehicleTable.
4. Arraste a tabela ConWHSVehicleTable do projeto para as origens de dados
nó do designer de formulários.
5. Selecione o Data Source ConWHSVehicleServiceTable e defina a
propriedades Insert If Empty e Insert At End para No.
6. Use o mesmo rótulo como a tabela para a propriedade Caption do nó Design.
7. Defina as propriedades Source Data Source e Data Sources para o nome da
tabela, ConWHSVehicleTable.
8. Aplique o padrão Details Master ao Design.
9. Conforme exigido pelo padrão, adicione um controle do Painel de Ação
chamado FormActionPane.
10. Adicione um controle de grupo chamado NavigationListGroup. Esta seção é
usada na visualização de detalhes para que o usuário possa alterar os
registros sem voltar para a lista Visão.
11. Sob o controle NavigationListGroup, crie um controle de Filtro Rápido e
nomeie-o como NavgationQuickFilter.
12. Em seguida, crie um controle de grade chamado NavigationGrid.
13. Defina a propriedade Data Source do controle de grade como
ConWHSVehicleTable e adicione os campos VehicleId e Description
arrastando-os dos campos nó da fonte de dados.
14. Complete o controle de filtro rápido com Target Control como controle de
grade e coluna Padrão conforme desejado.
15. Verificando os nós no e sob o nó Design, agora precisaremos criar um
Controle de tabulação para a guia Painel. Crie um controle de tabulação da
seguinte maneira:
Propriedade Valor
Name PanelTab
Arrange Method Vertical
60
20. O padrão agora afirma que precisaremos da Ação Padrão da Rede Principal,
que é um Controle de botão de comando. Adicionar botão de comando ao
ListPanelTabPage, definindo as propriedades, conforme mostrado na tabela
a seguir:
Propriedade Valor
Name ListGridDefaultButton
Command DetailsView
Propriedade Valor
Name DetailsHeaderTitle
Data Source ConWHSVehicleTable
Data Method TitleFields
View Edit Mode View
Skip Yes
Propriedade Valor
Name DetailsTab
Arrange Method Vertical
27. Vamos precisar criar o item de menu usando o mesmo rótulo da tabela, mas
nós precisaremos usar a opção de visualização de formulário como Grade
para que possamos obter a visualização de lista quando o formulário é
aberto.
61
28. Em seguida, preencha a propriedade FormRef da tabela
ConWHVehicleTable.
29. Finalmente, adicione o item de menu ao nosso menu.
62
Propriedade Valor
Caption Use the label from the table
Data Source ConWHSVehicleServiceTable
Title Data Source ConWHSVehicleServiceTable
11. Aplique o padrão Transação de Detalhes ao nó Design.
12. Adicione um controle de painel de ação chamado HeaderActionPane e, em
seguida, um grupo controle chamado NavigationListGroup sob o nó Design.
13. Adicione um controle de Filtro Rápido ao controle NavigationListGroup
chamado NavgationQuickFilter.
14. Em seguida, crie um controle de grade chamado NavigationGrid.
15. Defina a propriedade Data Source do controle de grade para
ConWHSVehicleServiceTable e adicione o ServiceId e Descrição campos da
fonte de dados ConWHSVehicleServiceTable.
16. Complete o controle de filtro rápido com Target Control como controle de
grade e Coluna Padrão conforme desejado.
17. Sob o nó Design, crie um controle Tab para a guia Painel. Crie uma nova guia
controle e nomeie-o MainTab. Defina Organizar Propriedade como vertical.
18. Adicione uma ficha de registro chamada DetailsPanelTabPage primeiro e
depois GridPanelTabPage.
19. Nós completaremos o controle GridPanelTabPage primeiro. Sob esse
controle, adicione um Controle de grupo chamado
GridPanelQuickFilterGroup e um controle de grade chamado ListGrid.
20. Preencha a propriedade Data Source do controle de grade e use o campo
Visão geral grupo para a propriedade Grupo de Dados.
21. Para GridPanelQuickFilterGroup, aplique os Filtros Personalizados e Rápidos
padrão para o controle. Em seguida, adicione um controle de Filtro rápido e
nomeie-o ListQuickFilter. Complete o controle referenciando-o ao controle
de grade que nós chamado ListGrid.
22. O padrão agora afirma que precisamos da ação padrão da grade principal,
que é um comando Controle de botão. Adicionar botão de comando ao
GridPanelTabPage chamado MainGridDefaultAction.
23. Defina a propriedade Command como DetailsView.
24. No controle MainGrid, insira MainGridDefaultAction para a ação padrão
propriedade.
25. Para concluir o elemento padrão do Painel de Detalhes (TabPage), selecione
novamente o DetailsPanelTabControle de página e adicione um controle de
grupo chamado DetailsPanelTitleGroup.
26. Adicione um controle String, definindo as propriedades da seguinte maneira:
Propriedade Valor
Name DetailsPanelHeaderTitle
Data Source ConWHSVehicleServiceLine
Data Method titleFields
View Edit Mode View
Skip Yes
27. Agora precisaremos completar o padrão Header and Line Panels (Tab)
elemento. Adicione um novo controle Tab ao DetailPanelTabPage, da
seguinte maneira:
63
Propriedade Valor
Name HeaderAndLinePanelTab
Arrange Method Vertial
28. Adicione uma nova aba para o Painel de Linhas usando as seguintes
propriedades:
Propriedade Valor
Name LinesPanelTabPage
Style DetailsFormDetails
Propriedade Valor
Name HeaderPanelTabPage
Style DetailsFormDetails
Propriedade Valor
Name LineViewHeaderTabPage
Label Vehicle service order header
Pattern Apply the Field and Field Groups
pattern
33. Adicione o elemento padrão Line View Lines (TabPage) usando as seguintes
propriedades:
Propriedade Valor
Name LineViewLines
Label SYS9664
34. Adicione o elemento de padrão Line View Line Details (TabPage) usando as
seguintes propriedades:
Propriedade Valor
Name LineViewLineDetailsTabPage
Label Vehicle Service order lines
Data Source ConWHSVehicleServiceLine
64
36. Clique com o botão direito do mouse no novo controle
LineActionRecordActions e selecione o Controle de grupo de botões sob este
chamado LineActionRecordActionsGroup.
37. Sob o grupo de botões LineActionRecordActionsGroup, adicione um
comando botão chamado LineActionAddLine.
38. Isso é para permitir que o usuário adicione linhas à grade de linhas. Defina as
seguintes propriedades:
40. Sob este grupo de botões, precisaremos de uma grade para as linhas.
Adicionar uma nova grade controle, definindo as seguintes propriedades:
Propriedade Valor
Name LinesGrid
Data Source @ConWHSVehicleServiceLine
Data Group Overview
Propriedade Valor
Name LineViewDetailsTab
Label @SYS23823
Data Source ConWHSVehicleServiceLine
Arrange Method Vertical
65
45. Agora, precisaremos concluir a visualização do cabeçalho do formulário, que
é regido por o elemento padrão do painel de cabeçalho. Clique com o botão
direito em HeaderPanelTabPage e escolha Novo | Tab e complete da seguinte
forma:
Propriedade Valor
Name HeaderDetailsTab
Arrange Method Vertical
Data Source ConWHSVehicleServiceTable
46. Normalmente teríamos muitos grupos de campo para adicionar, mas, neste
caso, apenas preciso de um. Crie um novo controle de página de guia
chamado HeaderDetailsTabDetails. Defina a propriedade Caption como
@ConWHS: Details.
47. Arraste os grupos de campos Details e ServiceDates do campo Fonte de dados
ConWHSVehicleServiceTable, mas renomeie-os, prefixados com
HeaderDetailsTabDetails.
48. Vamos precisar criar o item de menu usando o mesmo rótulo da tabela, mas
nós precisaremos usar a opção de visualização de formulário como Grade
para que possamos obter a visualização de lista quando o formulário é
aberto.
49. Em seguida, preencha a propriedade FormRef do
ConWHVehicleServiceTable mesa.
50. Finalmente, adicione o item de menu ao nosso menu.
66
Criando um arquivo de etiqueta (Label)
67
A criação é direta. O processo cria um arquivo de texto no disco que contém um
lista separada por tabulações de IDs e traduções de rótulos.
Quando um rótulo é selecionado em relação a um controle, ele receberá um ID
de arquivo de rótulo que garante que ele seja único. Em nosso exemplo, o ID do
arquivo de etiqueta era ConWHS. Quando criamos um rótulo, ele será dado os
IDs na sequência @ConWHS: ConWHS1, @ConWHS: ConWHS2 e assim por
diante.
Em nosso exemplo, os IDs de rótulo fornecidos ao controle serão @ConWHS:
ConWHS1. Isto parece desnecessariamente longo. Como, na verdade, podemos
especificar o ID do rótulo manualmente, podemos optar por inserir um ID menor
por rótulo, gerando um rótulo como @ConWHS: L001, ou digite um memorável
nome como um ID, onde o ID se tornaria @ConWHS: ItemNotExists.
Nota:
68
Segurança
Criar privilégios
Criar deveres
Criar funções de segurança
Criar Políticas
69
Com isso se deve resultar nos seguintes resultados:
Privilégios normalmente são criados para cada item de menu (exibição, saída ou
ação) para um acesso nível. Cada item de menu deve estar em um privilégio, mas
você pode adicionar mais de um item de menu a um privilégio se nunca devem
receber permissões diferentes, como itens de menu que aponte para o mesmo
formulário. Este é o nível mais granular, e será agrupado em deveres e papéis mais
tarde.
Como o privilégio atribui o nível de acesso, normalmente temos dois - para fornecer
apenas a visualização, e manter direitos de acesso (completos).
70
um usuário. Normalmente, adicionamos apenas pontos de entrada a um privilégio,
como itens de menu. Para conceder acesso ao usuário, o sistema aplica o nível de
acesso para formar controles e fontes de dados. Quando definimos a permissão
necessária propriedade em controles de formulário, pode ter o efeito de ocultar o
controle se o privilégio não conceder a permissão necessária.
Como não podemos estender os privilégios de segurança, sempre criamos um
privilégio. Isto é não é uma restrição real e ajuda a impor boas práticas; nós não
podemos ficar mais granular do que um privilégio, em termos de atribuir
permissões a um usuário. Nunca devemos sobrepor (personalizar) um privilégio de
segurança existente, já que não há necessidade de tarefas e funções extensível.
71
Criando funções de segurança (Roles)
72
Criando Políticas (Policies)
73