V10 RecursosGuias
RecursosGuias
Guias
Voltar | Lista de artigos

Como implementar uma Smart Action do tipo Função de Extensibilidade?

Última alteração a 13/07/2026

É possível implementar uma Smart Action do tipo Função de Extensibilidade no ERP Primavera com o Visual Studio. Uma Smart Action de Extensibilidade permite injetar os seus próprios dados e prompt na chamada ao Pulse, bem como tratar a resposta do Pulse, tudo através da sua assembly de extensibilidade. Tem total controlo sobre o contexto enviado ao Pulse e o que acontece com o resultado.

Pré-Requisitos

  • ERP Primavera instalado.
  • Visual Studio e .NET Framework 4.7.
  • Ambiente de desenvolvimento configurado.

Passo 1: Criar Projeto

  1. Após abrir o Visual Studio, selecionar Ficheiro | Novo | Projeto;
  2. Na janela apresentada, na árvore à esquerda, escolher a linguagem C#;
  3. Selecionar o tipo de projeto Class Library (.NET Framework);
  4. Atribuir o nome CustomSmartAction ao projeto e clicar em OK.

Passo 2: Referências

Após criar o projeto, é necessário adicionar referências à plataforma de extensibilidade e aos módulos com que irá trabalhar:

•	Primavera.Extensibility.CustomSmartAction.dll
•	Primavera.Extensibility.Integration.dll
•	Primavera.Extensibility.BusinessEntities.dll
•	ErpBS100.dll
•	StdPlatBS100.dll

Passo 3: Criar Classe

  1. Renomear a classe de cs para SmartAction.cs;
  2. Adicionar os namespaces necessários no início do ficheiro com a diretiva using;
  3. A seguir ao nome da classe, adicionar CustomSmartAction. Este passo indica que a classe passa a herdar da classe base da API CustomSmartAction todos os métodos, propriedades e atributos — como por exemplo o PSO (acesso à plataforma) e o BSO (acesso aos módulos).
  4. Implementar os dois métodos de extensão obrigatórios (ver tabela abaixo);
  5. Compilar a solução em Build | Build Solution.
  6. Registar a assembly conforme descrito no artigo de apoio.

Métodos

MétodoQuando é chamadoFinalidade
BeforeExecution(string smartActionName, T businessEntity)Antes da chamada ao PulseConstrói e devolve o pedido: contextos e prompt
AfterExecution(string smartActionName, string result)Após a chamada ao PulseTrata o resultado gerado pelo Pulse

1. BeforeExecution

Utilize o parâmetro smartActionName para encaminhar para a Smart Action correta e faça cast de businessEntity para o tipo de entidade de negócio (BE) esperado. Devolva um CustomSmartActionRequest preenchido com:

  • `Contexts`: lista de CustomSmartActionContext cada um com:
    • Background: descrição em texto simples dos dados fornecidos (ajuda o Pulse a interpretá-los).
    • Data: DataTable com as linhas de dados.
  • `Prompt`: a questão ou instrução enviada ao Pulse.

Para nomes de Smart Action não reconhecidos devolva new CustomSmartActionRequest() vazio.

2. AfterExecution

Recebe o nome da Smart Action e a resposta gerada pelo Pulse. Utilize este método para apresentar o resultado ao utilizador, escrever num campo, registar em log, ou desencadear qualquer lógica subsequente

Exemplo

using Primavera.Extensibility.BusinessEntities.Data;    
using System;    
using System.Collections.Generic;    
using System.Data;    
using System.Globalization;    
     
namespace MyCompany.Extensibility    
{    
    public class SmartAction : Primavera.Extensibility.CustomSmartAction.CustomSmartAction    
    {    
        public override CustomSmartActionRequest BeforeExecution(string smartActionName, T businessEntity)    
        {    
            if (smartActionName.Equals("Artigo", StringComparison.InvariantCultureIgnoreCase)    
                && businessEntity is BasBE100.BasBEArtigo artigo)    
            {    
                var data = new DataTable();    
                data.Columns.AddRange(new[]    
                {    
                    new DataColumn("Artigo"),    
                    new DataColumn("Descricao"),    
                    new DataColumn("Preco")    
                });    
                data.Rows.Add("A0001", "Item 1", "40.60");    
                data.Rows.Add("A0002", "Item 2", "20.33");    
                data.Rows.Add("A0003", "Item 3", "55.50");    
                data.Rows.Add("A0004", "Item 4", "35.20");    
     
                return new CustomSmartActionRequest()    
                {    
                    Contexts = new List()    
                    {    
                        new CustomSmartActionContext()    
                        {    
                            Background = "Lista de artigos com preços em euros.",    
                            Data = data    
                        }    
                    },    
                    Prompt = "Qual é o artigo mais caro e qual é o seu preço?"    
                };    
            }    
     
            if (smartActionName.Equals("DocumentoVenda", StringComparison.InvariantCultureIgnoreCase)    
                && businessEntity is VndBE100.VndBEDocumentoVenda documentoVenda)    
            {    
                return new CustomSmartActionRequest()    
                {    
                    Contexts = new List()    
                    {    
                        new CustomSmartActionContext()    
                        {    
                            Background = "Documento de venda com dados do cliente, datas, totais e lista de artigos vendidos.",    
                            Data = BuildSalesDocumentTable(documentoVenda)    
                        }    
                    },    
                    Prompt = "Com base neste documento de venda, forneça uma análise do cliente, volume de vendas, descontos aplicados e valor final."    
                };    
            }    
     
            return new CustomSmartActionRequest();    
        }    
     
        public override void AfterExecution(string smartActionName, string result)    
        {    
            this.PSO.MensagensDialogos.MostraAviso(    
                "Resultado da Smart Action",    
                StdBE100.StdBETipos.IconId.PRI_Informativo,    
                result);    
        }    
     
        private DataTable BuildSalesDocumentTable(VndBE100.VndBEDocumentoVenda doc)    
        {    
            var dt = new DataTable();    
            dt.Columns.AddRange(new[]    
            {    
                new DataColumn("TipoDoc"),        new DataColumn("Serie"),          new DataColumn("NumDoc"),    
                new DataColumn("Cliente"),         new DataColumn("Data"),           new DataColumn("TotalMercadoria"),    
                new DataColumn("TotalDesconto"),   new DataColumn("TotalIVA"),       new DataColumn("OutrosEncargos"),    
                new DataColumn("TotalDocumento"),  new DataColumn("NumLinha"),       new DataColumn("Artigo"),    
                new DataColumn("Descricao"),       new DataColumn("Quantidade"),     new DataColumn("PrecUnit"),    
                new DataColumn("Desconto1"),       new DataColumn("Desconto2"),      new DataColumn("Desconto3")    
            });    
     
            int numLinha = 0;    
            foreach (VndBE100.VndBELinhaDocumentoVenda linha in doc.Linhas)    
            {    
                numLinha++;    
                dt.Rows.Add(    
                    doc.Tipodoc, doc.Serie,    
                    doc.NumDoc.ToString(CultureInfo.InvariantCulture),    
                    doc.Entidade,    
                    doc.DataDoc.ToString("yyyy-MM-dd", CultureInfo.InvariantCulture),    
                    doc.TotalMerc.ToString("0.00", CultureInfo.InvariantCulture),    
                    doc.TotalDesc.ToString("0.00", CultureInfo.InvariantCulture),    
                    doc.TotalIva.ToString("0.00", CultureInfo.InvariantCulture),    
                    doc.TotalOutros.ToString("0.00", CultureInfo.InvariantCulture),    
                    doc.TotalDocumento.ToString("0.00", CultureInfo.InvariantCulture),    
                    numLinha.ToString(CultureInfo.InvariantCulture),    
                    linha.Artigo, linha.Descricao,    
                    linha.Quantidade.ToString("0.00", CultureInfo.InvariantCulture),    
                    linha.PrecUnit.ToString("0.00", CultureInfo.InvariantCulture),    
                    linha.Desconto1.ToString("0.00", CultureInfo.InvariantCulture),    
                    linha.Desconto2.ToString("0.00", CultureInfo.InvariantCulture),    
                    linha.Desconto3.ToString("0.00", CultureInfo.InvariantCulture)    
                );    
            }    
     
            return dt;    
        }    
    }    

Passo 4: Configurar Smart Action no ERP

Após implementar e registar a assembly de extensibilidade, crie a Smart Action diretamente a partir do formulário alvo:

  1. Abrir o formulário onde a Smart Action deve aparecer;
  2. Aceder à opção Smart Actions do formulário e criar uma Smart Action;
  3. Definir o tipo como Função de Extensibilidade;
  4. Definir o Nome com o valor que o método BeforeExecution verifica no parâmetro smartActionName (por exemplo: "Artigo", "DocumentoVenda").

Nota: o nome é a chave que encaminha a chamada para o bloco correto no método BeforeExecution — deve corresponder exatamente. A comparação deverá ser insensível a maiúsculas/minúsculas por convenção, conforme demonstrado no exemplo.

Checklist

Preparamos a seguinte checklist com todos os passos necessários para auxiliá-lo neste processo:

  1. Assembly de extensibilidade implementada e registada.
  2. Classe herda de Extensibility.CustomSmartAction.CustomSmartAction.
  3. BeforeExecution devolve um CustomSmartActionRequest preenchido para cada nome de Smart Action tratado.
  4. AfterExecution trata o resultado do Pulse para cada nome de Smart Action.
  5. Smart Action criada a partir do formulário alvo com o tipo Função de Extensibilidade e o nome correspondente.
  6. Um projeto base com exemplos de implementação está disponível no GitHub da Primavera.
Adicionar aos favoritos ou partilhar este artigo
Esta página foi útil?
Obrigado pelo seu voto.
Artigos Relacionados
Começar a Usar Como criar um projeto de integração com Visual Studio? Como criar um projeto de extensibilidade de interface (PEX) com Visual Studio? Como criar um projeto de extensibilidade de API (Motor) com Visual Studio? Como criar separadores do utilizador com Visual Studio?