Páginas filhas
  • Recebimento

Versões comparadas

Chave

  • Esta linha foi adicionada.
  • Esta linha foi removida.
  • A formatação mudou.

...

Deck of Cards
idExemplo - Recebimento de Grupo de Produto - StockGroup
Card
labelAdapter

A classe de Adapter poderá herdar de diferentes classes base de adapter EAI.

                Para o Recebimento temos EAIAdapterDataServerObjBase, EAIAdapterSimpleBase, EAIAdapterProcessBase

Na utilização do EAIAdapterDataServerObjBase para recebimento utilizando um Model (Muito utilizado em cadastros), e com utilização de DataServer, temos:

1 - Criar um Model que represente o Envio e Recebimento da Mensagem que pode ser trafegada em JSon ou XML.

2 - Definir a Herança como Type do Model criado.

                 Exemplo: StockGroup_Receive_1000 : EAIAdapterDataServerObjBase<StockGroup_Model_V1_BusinessContent>

3 - Informar no cabeçalho da Classe os atributos para Nome Versão, e Descrição com Resource (Tradução) do Adapter.

                 [AdapterAttr(typeof(Properties.Resources), "sEstAdapterGrupoDeProdutoName", "STOCKGROUP", "1.000")]

4 - O método DoGetPrimaryKeysByBusinessContent se implementado possibilitara que um registro seja recebido e processado, mesmo que o registro já exista e seu De/Para não exista. Utilizado por exemplo para entidades que já vem com informações na Base de Dados como é o caso das Unidades de Médida. Neste exemplo de Grupo de Produto também foi implementado por se achar interessante, visto que é uma entidade simples, de chave simples.

5 - É recomentado a utilização do método DoPrepareDataset para atribuição dos valores a classe já possui a propriedade BusinessContent que representa o Model já carregado com as informações recebendo como parâmetro o DataSet já com a linha carregada, caso exista o registro, ou com um registro com valores default caso seja uma inclusão.

6 - O método DoGetInfoTableDePara define a chave primeira e estrangeiras que são utilizadas na tabela, para definição do de/para do registro e para definição de recuperação de de/paras referente a chave estrangeira. Em situações especiais, caso o padrão da LIB não consiga resolver e popular os respectivos valores dos campos relacionados a chaves estrangeiras, podemos sobrescrever o método DoBuildKeys adaptando-o de acordo com o XML. Observer o trecho de código abaixo utilizado no adapter de recebimento.

Bloco de código
languagec#
firstline100
titleDoBuildKeys
	protected override ListInfoTableDePara DoGetInfoTableDePara()
    {
      ListInfoTableDePara lstTable = new ListInfoTableDePara();
      lstTable.Add(GetInfoFKsBusinessContent());
      lstTable.Add(GetInfoCustoEquipamento());
      return lstTable;
    }
	
	private InfoTableDePara GetInfoFKsBusinessContent()
    {
      InfoTableDePara itemTable = new InfoTableDePara(TableName, "BUSINESSCONTENT");
      itemTable.DescriptionName = "BUSINESSCONTENT";

      InfoColumnDePara itemColumn = new InfoColumnDePara("COMPANYINTERNALID", "CODCOLIGADA|CODFILIAL", "GFILIAL");
      itemColumn.ForeignKeyDePara = true;
      itemTable.ColumnsName.Add(itemColumn);

      InfoColumnDePara AssetColumn = new InfoColumnDePara("ASSETINTERNALID", "|IDPATRIMONIO", "IPATRIMONIO");
      AssetColumn.ConsistirForeignKeyDePara = true;
      AssetColumn.ForeignKeyDePara = true;
      itemTable.ColumnsName.Add(AssetColumn);

      return itemTable;
    }

    private InfoTableDePara GetInfoCustoEquipamento()
    {
      InfoTableDePara itemTable = new InfoTableDePara(TableName, "ASSETMONTHLYUNDIRECTCOSTS");
      itemTable.DescriptionName = Properties.Resources.sPrjCustoDiretoEquipamento;

      InfoColumnDePara internalid = new InfoColumnDePara(EAIConsts.ctINTERNALID, "CODCOLIGADA|IDPRJ|MESANO|IDPATRIMONIO|CODCCUSTOBEM", TableName);
      internalid.ForeignKeyDePara = false;
      itemTable.ColumnsName.Add(internalid);

      InfoColumnDePara ccustoColumn = new InfoColumnDePara("COSTCENTERINTERNALID", "|CODCCUSTO", "GCCUSTO");
      // ccustoTable.InternalIdForeignKeyObrigatorio = true;
      // ccustoTable.ConsistirForeignKeyDePara = true;
      ccustoColumn.FieldsForeignKey = "|CODCCUSTOBEM";
      ccustoColumn.ForeignKeyDePara = true;
      itemTable.ColumnsName.Add(ccustoColumn);

      return itemTable;
    }
    
	protected override void DoBuildKeys(ref EAIPrepareDataServerObjResult parms, object businessContent)
    {
      // Obtém Rows[0] pois esta mensagem está preparada para somente uma linha (não possui lista).
      DataRow dr = parms.DataSet.Tables[TableName].Rows[0];
      
      BusinessContentIndirectCost indirectCost = BusinessContent.ListOfIndirectCost.FirstOrDefault(
        item => string.Equals(item.InternalId, RMSConvert.ToString(dr[EAIConsts.ctINTERNALID])));

      if (indirectCost != null)
      {
        // Percorre todas as colunas do BusinessContent efetuando o BuildKeys
        this.BuildDePara(this.InfoTableAdapter.GetValue("BUSINESSCONTENT"), BusinessContent, dr);

        // Percorre todas as colunas do DirectCost efetuando o BuildKeys
        this.BuildDePara(this.InfoTableAdapter.GetValue("ASSETMONTHLYUNDIRECTCOSTS"), indirectCost, dr);
      }
    }


7 - No método ValidateLevelCompanyBranch fica definido os Compartilhamentos que serão respeitados pela Entidade. No exemplo abaixo o cadastro de Grupo de Produto não permite a configuração do sistema externo de maneira exclusiva por Filial, uma vez que a tabela da entidade não comporta tal situação.

Bloco de código
languagec#
themeEclipse
titleAdapter
using RM.Eai.TotvsMessage.Adapter;
using RM.Eai.TotvsMessage.IService;
using RM.Eai.TotvsMessage.Lib;
using RM.Lib;
using System;
using System.Collections.Generic;
using System.Data;
using System.Linq;
using System.Reflection;

namespace RM.Est.TotvsMessage.Adapter.Adapter.GrupoDeProduto
{
  /// <summary>
  /// Adapter de recebimento de grupo de produto.
  /// </summary>
  [AdapterAttr(typeof(Properties.Resources), "sEstAdapterGrupoDeProdutoName", "STOCKGROUP", "1.000")]
  public class StockGroup_Receive_1000 : EAIAdapterDataServerObjBase<StockGroup_Model_V1_BusinessContent>
  {
    protected override void DoInitializeDataServer()
    {
      base.AdapterName = "STOCKGROUP";
      base.TableName = "TTB2";
      base.DataserverName = "EstTb2Data";
      base.CodigoSistema = Lib.CodSistema.Est;
      base.ColumnsToReplicate = new RMRegisterColumnsReplicate("CODCOLIGADA", "");
    }

    protected override void DoGetPrimaryKeysByBusinessContent(ref EAIPrimaryKeysDataServerResult result)
    {
      EAIMsgDeParaItem deParaColigada = this.APIDeParaReceive.GetDeParaByInternalId("GFILIAL", this.BusinessContent.CompanyInternalId, this.AdapterContext.ContextItem.CurrentRoute.IdApp).FirstOrDefault();

      if (deParaColigada != null)
      {
        result.ListPrimaryKeys[0].PrimaryKeyRM = new object[] { deParaColigada.GetValorRM("CODCOLIGADA"), BusinessContent.Code };
      }
    }
   
    //Método para atribuição de Valores Recebidos do Model no DataSet que será salvo.
    protected override void DoPrepareDataset(ref EAIPrepareDataServerObjResult parms)
    {
      base.DoPrepareDataset(ref parms);
      
      //Obtém Rows[0] pois esta mensagem está preparada para somente uma linha (não possui lista).
      DataRow row = parms.DataSet.Tables[TableName].Rows[0];

      row["DESCRICAO"] = BusinessContent.Description;
      row["CAMPOLIVRE"] = BusinessContent.FamilyClassificationCode;
      if (row["INATIVO"] == DBNull.Value)
        row["INATIVO"] = 0;
    }

    /// <summary>
    /// Define estrutura da tabela.
    /// </summary>
    /// <returns></returns>
    protected override ListInfoTableDePara DoGetInfoTableDePara()
    {
      ListInfoTableDePara lstTable = new ListInfoTableDePara();

      InfoTableDePara itemTable = new InfoTableDePara("TTB2", "STOCKGROUP");
      itemTable.DescriptionName = Properties.Resources.sEstAdapterGrupoDeProdutoName;

      InfoColumnDePara itemColumn = new InfoColumnDePara("COMPANYINTERNALID",
        "CODCOLIGADA|CODFILIAL", "GFILIAL");

      itemTable.ColumnsName.Add(itemColumn);

      InfoColumnDePara column = new InfoColumnDePara(EAIConsts.ctINTERNALID,
        "CODCOLIGADA|CODTB2FAT", "TTB2");
      column.ForeignKeyDePara = false;
      itemTable.ColumnsName.Add(column);

      lstTable.Add(itemTable);

      return lstTable;
    }

    /// <summary>
    /// Valida niveis de compartilhamento.
    /// </summary>
    /// <param name="parms"></param>
    /// <param name="result"></param>
    /// <param name="sharedModeEmpresa"></param>
    /// <param name="sharedModeFilial"></param>
    /// <returns></returns>
    public override EAIValidatedSharedModeResult ValidateLevelCompanyBranch(
      EAIValidatedSharedModeParams parms, EAIValidatedSharedModeResult result,
      SharingModeEnum sharedModeEmpresa, SharingModeEnum sharedModeFilial)
    {
      if (sharedModeFilial != SharingModeEnum.smCompartilhado)
      {
        result.Validated = false;
        result.ValidationMessage += Properties.Resources.sEstConfigGrupoProdutoFilial;
      }
      return result;
    }
  }
}

Card
labelModel

O Model é a classe que representa o recebimento e envio das mensagens, que pode ser em XML ou JSon.

Uma dica ao iniciar a implementação desta classe é pegar um XML, com todos os campos preenchidos e utilizar a opção de geração de classe do Visual Studio.


  • Ao definir uma propriedade que não é obrigatória ela deve ser nulabled pois se não é carregado o valor default.

Exemplo:

Bloco de código
titleExemplo - Propriedade
    public DateTime? BaseDate { get; set; }
  • As propriedades do tipo valor defem ser definidas com seus respectivos tipos, para evitar falhas na serialização e deserialização.
    • Obs.: Já foi verificado que alguns sistemas possuem a serialização incorreta de alguns campos, por exemplo se o ValorTotal é decimal, o mesmo deve receber uma tag do tipo <\ValorTotal> e não <ValorTotal></ValorTotal> pois esta segunda alternativa representa uma string, neste caso o sistema que esta enviando a mensagem devera ser ajustado.

Bloco de código
titleExemplo - Propriedade
    public decimal ValorTotal { get; set; }

Caso se trabalhe com o não envio de campos devera ser declarado no Model uma propriedade para identificação do não envio da coluna, exemplo abaixo, para conseguir se distinguir o recebimento de uma coluna nula ou o não recebimento da coluna. Pois ao se receber uma coluna nula o campo deve ser atribuido como Null, pois entendi-se que sua informação foi apagada, e caso não se receba o campo não é alterado.


Bloco de código
titleExemplo - Propriedade
    public decimal ValorTotal { get; set; }
    
    [JsonIgnore]
    public bool ValorTotalSpecified {get;set;}


Exemplo de Adapter de Recebimento de Grupo de Produto

Bloco de código
languagec#
themeEclipse
titleModel
linenumberstrue
[System.SerializableAttribute()]
  [System.ComponentModel.DesignerCategoryAttribute("code")]
  [System.Xml.Serialization.XmlTypeAttribute(AnonymousType = true)]
  [System.Xml.Serialization.XmlRootAttribute(ElementName = "BusinessContent", IsNullable = false)]
  [MessageContentTypeAttr("STOCKGROUP", 1, MessageTypeEnum.tmBusinessMessage)]
  public partial class StockGroup_Model_V1_BusinessContent : EAIBusinessContentModelBase
  {
    public string InternalId { get; set; }

    public string CompanyInternalId { get; set; }

    public string Code { get; set; }

    public int Inativo { get; set; }

    public string Description { get; set; }

    public string FamilyClassificationCode { get; set; }
  }

  [System.SerializableAttribute()]
  [System.ComponentModel.DesignerCategoryAttribute("code")]
  [System.Xml.Serialization.XmlTypeAttribute(AnonymousType = true)]
  [System.Xml.Serialization.XmlRootAttribute(ElementName = "ReturnContent", IsNullable = false)]
  [MessageContentTypeAttr("STOCKGROUP", 1, MessageTypeEnum.tmResponseMessage)]
  public partial class StockGroup_V1_ReturnContent : EAIReturnContentWithListModelBase
  {
  }





...