Histórico da Página
Índice |
---|
Objetivo e formas de uso
O objetivo
...
da Mensagem Padronizada TOTVS
...
A Mensagem Padronizada TOTVS estabelece alguns (TOTVS Standard Message - TSM) é estabelecer padrões que devem ser seguidos por todos os aplicativos que participam da integração. Estes padrões estabelecem alguns definem os tipos de mensagens suportadas bem como informações obrigatórias que devem fazer parte do seu conteúdo.
A composição do conteúdo de cada uma das mensagens de negócio será definida em conjunto com especialistas de negócio e não faz parte do escopo deste documento.A anatomia básica de uma mensagem de negócio permite que dentro de uma mensagem específica seja definido se defina apenas o modelo do conteúdo de negócio e retorno. Entretanto, mas quando a mensagem completa for trafegar for necessário um maior controle das mensagens trafegadas entre os produtos, todas as informações citadas acima também façam parte da estrutura da mensagem.
Veja abaixo um exemplo do JSON de uma mensagem padronizada completo (incluindo header para controle da camada de EAI):
No caso de JSON simplificado para API, trabalhamos apenas com o contéudo da propriedade "content", desconsiderando o header.
Veja abaixo o exemplo do mesmo JSON definido acima, porém simplificado como modelo de request/response de uma API.
é possível acrescentar modelos adicionais (como o modelo de dado para retorno de status de processamento), de forma todas as informações necessárias façam parte de uma única estrutura de mensagem.
A composição do conteúdo da mensagem no que diz respeito ao negócio será definida em conjunto com especialistas de negócio e não faz parte do escopo deste documento.
As orientações descritas neste documento, portanto, visam atender os dois modelos de integração existentes: API e Transactions.
Veja abaixo um exemplo de mensagem padronizada completa, em formato JSON, (incluindo header para controle da camada de EAI), trafegada no modelo Transactions:
Clique aqui para obter mais informações sobre o modelo de integração Transactions
No caso de conteúdo trafegado no modelo para API, apenas com o conteúdo da propriedade "Content" será utilizado, desconsiderando o header.
Veja abaixo o exemplo do mesmo JSON definido acima, porém atendendo ao modelo de request/response de uma API.
Bloco de código | ||||
---|---|---|---|---|
| ||||
{ "CompanyId": "1", "BranchId": "B1", "CompanyInternalId": "CompanyInternalId", "InternalId": "InternalId", "Code": "Code", "Description": "Description", "NatureType": "NatureType", "UseCategory": "UseCategory", "Blocked": 0 } |
Exemplo de um JSON de resposta de processamento sem erros (Através da camada de EAI):
Clique aqui para obter mais informações sobre integração via API
Nota | ||
---|---|---|
| ||
É obrigatório que, ao utilizar os dois modelos de integração disponíveis, o modelo de dados definido para retorno da API seja compatível com a definição da propriedade "Content", do modelo Transactions. |
Definição da Mensagem no modelo JsonSchema
Abaixo encontram-se as regras para definir uma mensagem padronizada.
- Seguir a especificação do formato JsonSchema (draft 4 ou superior)
- Clique aqui para visualizar exemplos
- Seguir a definição de campos especificada
- Especificar propriedade X-Totvs de acordo com a documentação, incluindo quais ERPs implementam aquela mensagem e os campos relacionados.
- Sempre que possível, utilizar padrões internacionais. Para saber se já existe uma mensagem de conta contábil, por exemplo, pesquise no Google usando "account xsd oasis repository".
- Mensagens criadas para atender uma exigência legal devem se ater estritamente ao que é definido pela legislação. Nestes casos, o nome da mensagem e dos campos podem ser em português, se a legislação exigir.
Âncora | ||||
---|---|---|---|---|
|
Cabeçalho (Info)
Nesse tópico entraremos em maiores detalhes da propriedade x-totvs de dentro da info (cabeçalho). Caso queira entender sobre os outros campos da info do schema, visite nosso Guia de APIs e/ou verifique como a info foi descrita em outros schemas.
O objetivo do x-totvs da info é especificar quais produtos Totvs implementaram uma determinada mensagem, e trazer outras informações sobre a mesma.
Bloco de código | ||||||
---|---|---|---|---|---|---|
| ||||||
"info": {
...
"x-totvs": {
| ||||||
Bloco de código | ||||||
| ||||||
{ "Header" : { "UUID" : "a1b2c3d4-e5f6-g7h8-i9j0-k1l2m3n4o5p6", "Type" : "Response", "SubType" : "event", "Transaction" : "CostCenter", "Version" : "2.000", "SourceApplication" : "LGX12", "ProductName" : "LOGIX", "ProductVersion" : "12.1.15", "GeneratedOn" : "2017-11-14T11:47:15-03:00", "DeliveryType": "async" }, "Content" : { "ReceivedMessagemessageDocumentation" : { "UUID" : "d6bbfa63-ca27-e2ac-0b14-101970f59a5bname": "StockTurnOver", "SentBydescription" : "P1299Baixa de estoque", "Eventsegment" : "upsert"Construção e Projetos", "domain": "Planejamento" }, "ProcessingInformationproductInformation" : {[ "ProcessedOn" : "2017-11-14T11:47:15-03:00", { "Status" : "Ok" "product": "RM", }, "ReturnContentcontact" : {"Bruno Barbosa de Souza", "ListOfInternalIDnote" : [ "GDP Inovação Const. e Proj.", { "adapter": "MovMovimentoData" "Name" : "BankInternalId", }, "Origin" : "01|99|123", { "Destinationproduct" : "01|99|abcProtheus", } "contact": "Eduardo de Souza", ] } } } |
Exemplo de um JSON de resposta de processamento com erros:
Bloco de código | ||||||
---|---|---|---|---|---|---|
| ||||||
<?xml version="1.0note": encoding="UTF-8" ?> <TOTVSMessage xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:noNamespaceSchemaLocation="xmlschema/general/events/Bank_1_000.xsd"> <MessageInformation version="1.000"> <UUID>25121218-a5c8-e581-b010-0a139a59f4bf</UUID> <Type>Response</Type> <Transaction>Bank</Transaction> <StandardVersion>1.0</StandardVersion> <SourceApplication>Logix</SourceApplication> <Product name="LOGIX" version="12.1.19"/> <GeneratedOn>2001-12-31T12:00:00</GeneratedOn> </MessageInformation> <ResponseMessage> <ReceivedMessage> <SentBy>dts11</SentBy> <UUID>24121218-a5c8-e581-b010-0a139a59f4bf</UUID> <Event>upsert</Event> </ReceivedMessage> <ProcessingInformation> <ProcessedOn>2001-12-31T12:00:00</ProcessedOn> <Status>error</Status> <ListOfMessages> <Message type="warning" code="254">Messagem de Aviso</Message> <Message type="error" code="-25">Messagem de erro</Message> <Message type="error" code="EAI30">Mensagem de Teste3</Message> </ListOfMessages> </ProcessingInformation> </ResponseMessage> </TOTVSMessage> |
...
As mensagens TOTVS possuem um segmento chamado MessageInformation que possui as principais informações utilizadas para identificação e roteamento da mensagem. Exemplo:
Onde:
- MessageInformation version: Identifica qual a versão daquela mensagem de negócio. Uma mensagem de Item, por exemplo, pode sofrer alterações no decorrer do tempo, sendo que cada uma destas alterações irá afetar esta informação.
- UUID: Identificador único desta mensagem e que não pode ser igual ao UUID de qualquer outra mensagem em qualquer um dos aplicativos participantes da integração.
- Type: Identifica o tipo da mensagem (BusinessMessage, ReceiptMessage ou ResponseMessage).
- Transaction: Identificador do tipo de transação da mensagem. Esta informação será utilizada pelos aplicativos para definir como os dados serão processados no recebimento.
- StandardVersion: Identifica a versão do padrão TOTVS, ou seja, do formato utilizado nas áreas genéricas da mensagem TOTVS. Caso o padrão TOTVS seja alterado, este valor será alterado.
- SourceApplication: Identifica a instancia dos aplicativos TOTVS que gerou a mensagem. Uma instância representa uma instalação/configuração daquele aplicativo/produto. Caso duas instancia do mesmo aplicativo participem da mesma integração, cada um deverá ser identificado de forma única.
- CompanyId/BranchId/UserId: Identificador da empresa/filial e usuário que gerou a mensagem. Esta informação é apenas documental e não deve ser utilizada para o processamento da mensagem já que não existe garantia da sua existência na mensagem. Quando a informação for relevante para o negócio, é preciso buscar esta informação do conteúdo da mensagem de negócio.
- Product: Identifica o produto e versão que originou a mensagem. Neste caso, o valor pode ser o igual, mesmo em instâncias diferentes do mesmo aplicativo.
- GeneratedOn: Identifica o timestamp de geração desta mensagem.
- DeliveryType: Forma de envio da mensagem, podendo ser sync ou async, ou seja, síncrono ou assíncrono.
Tipos de Mensagens
O padrão de mensagem TOTVS estabelece quatro tipos de mensagens: BusinessMessage, ResponseMessage e ReceiptMessage.
BusinessMessage
Uma mensagem do tipo BusinessMessage são aquelas que iniciam qualquer processo de troca de mensagens entre os aplicativos. Sempre que um aplicativo A quiser enviar ou solicitar informações do aplicativo B, ele enviará uma BusinessMessage que será processada pelo aplicativo destinatário.
As BusinessMessages podem assumir dois tipos:
- Event: As mensagens de evento são aquelas cujo objetivo é notificar outros aplicativos da ocorrência de um evento. Estas mensagens são normalmente utilizadas para fins de replicação de dados, quando um dos aplicativos (cadastro master) envia para os demais (slaves) sobre a inclusão, alteração ou eliminação de um registro.
- Request: As mensagens de solicitação são utilizadas para consumir um serviço de um aplicativo remoto. Pode ser entendido por serviço qualquer processamento feito pelo aplicativo chamado com base nas informações passadas pelo aplicativo chamador. As mensagens de request são normalmente enviadas por aplicativos-clientes aos aplicativos-servidores para iniciar um processamento (como a consulta do saldo de um item, por exemplo).
A tabela abaixo apresenta um comparativo entre mensagens de evento e de solicitação:
...
Objetivo
...
Replicação de Dados
...
Compartilhar Lógicas
...
Quem Gera (normalmente)
...
Um (cadastro Master)
...
Vários (clientes que precisam da lógica)
...
Quem Responde
(normalmente)
...
Vários (cadastros replicados)
...
Um (detentor da lógica)
...
Uso + comum
...
Síncrono (Envia e aguarda)
...
Assíncrono (envia e esquece)
...
Exemplo
...
Upsert UnitOfMeasure
...
getCashAvailableOnDate
"GDP de Materiais",
"adapter": "MATI241"
},
{
"product": "PIMS",
"contact": "José Alberto da Silva",
"note": "",
"adapter": ""
}
],
"transactionDefinition": {
"subType": "event",
"businessContentType": {
"$ref": "#/definitions/BusinessContentType",
"type": "object"
},
"returnContentType": {
"$ref": "#/definitions/ReturnContentType",
"type": "object"
}
}
}
} |
MessageDocumentation
Contém nome, descrição e agrupador da mensagem (esse último definido através das propriedades segment e domain)
Campo Obrigatório
Aviso |
---|
Os campos "segment" e "domain" devem ser preenchidos de forma coerente com o que já está em uso nos outros schemas e APIs de nossa base (por exemplo, deve-se manter o "case" em uso, evitando variações como "HealthCare" em uma mensagem, e "Healthcare" em outra). Para isso, visite o API Reference e verifique como o que você quer adicionar está escrito. |
Clique aqui para verificar os valores disponíveis para a propriedade segment
ProductInformation
- product: produto ao qual aquelas informações do "productInformation" se referem;
- contact: contato do desenvolvedor do schema;
- note: observações referente ao produto, como regras específicas;
- adapter: adapter correspondente ao schema.
Contém lista com nomes dos produtos em que essa mensagem foi implementada, qual o seu adapter correspondente e responsável.
Campo Obrigatório
TransactionDefinition
Esse campo deve ser definido para ativar a integração dessa mensagem via transaction (EAI)
Ele contém a informação do subtype (event ou request), e quais objetos do schema correspondem ao businessContentType e returnContentType.
Ao ativá-lo dessa maneira, a propriedade "Header" será preenchida automaticamente pelo EAI, enquanto a propriedade "Content" será substituída pelo objeto configurado.
Clique aqui se existem dúvidas sobre integração via transaction
Campo Opcional
Corpo/Propriedades
O objetivo dessa propriedade é especificar quais produtos Totvs implementaram uma determinada propriedade da mensagem, e trazer informações específicas sobre aquele campo em um determinado produto.
Segue exemplo abaixo:
Bloco de código | ||||
---|---|---|---|---|
| ||||
Code": {
"type": "string",
"description": "Código do País",
"x-totvs": [
{
"product": "Logix",
"field": "paises.cod_pais",
"required": true,
"type": "Char",
"length": "3",
"note": "some info...",
"available": true,
"canUpdate": false
},
{
"product": "RMS",
"field": "AA1CPAIS.PAIS_COD",
"required": true,
"type": "integer",
"length": "6",
"note": "some info...",
"available": true,
"canUpdate": false
}
]
}, |
product
Produto a que se refere essa informação.
Exemplos |
---|
product: “Protheus” ou product: “RM” |
Aviso |
---|
O campo "product" deve ser preenchido de forma coerente com o que já está em uso nos outros schemas de nosso repositório (por exemplo, mantendo o mesmo "case"). Para isso, visite o API Reference e verifique como o produto que você quer adicionar está escrito. |
Campo Obrigatório
field
A qual tabela e campo do produto o campo da mensagem se refere.
Quando não for possível ou não for conveniente referenciar o campo, pode-se referenciar o atributo de um modelo conceitual ou intermediário.
Caso no produto este campo possa estar em mais tabela (ou modelo), explicar o funcionamento.
Exemplos |
---|
field: “clientes.cod_cliente” ou field: “cliente.cod_cliente para Type=Customer ou fornecedor.cod_fornecedor para Type=Vendor” |
Campo Obrigatório
required
Obrigatoriedade do campo no modelo de dados. Caso haja alguma condição deve ser descrito no campo note.
Exemplos |
---|
required: true required: false |
Campo Obrigatório
type
Tipo de dado do campo no produto. Importante declarar aqui o tipo de dado do campo como é conhecido no produto.
Exemplos |
---|
type: ‘char’ type: ‘varchar’ type: ‘number’ type: ‘decimal’ type: ‘integer’ type: ‘boolean’ |
Campo Obrigatório
length
Tamanho do campo no produto, pode ser informado apenas o tamanho ou outro texto que descreva como este tamanho funciona.
Exemplos |
---|
length: ‘20’ length: ‘8,2’ length: ’sempre implantado como 20, mas o cliente pode usar até 50’ |
Campo Obrigatório
note
Complemento de informações sobre o campo se for o caso, como por exemplo formato da informação, vínculo entre mensagens, escopo de dados (deve ser informado para campos que precisam respeitar uma relação específica de valores no produto, podendo ser informado aqui: 'lista fixa' ou 'valores da tabela [tabela.campo]').
Exemplos |
---|
"note": "1=CEI;2=CNPJ;3=CPF;4=INCRA" "note": "Campo obrigatório para o processo fiscal/TAF." "note":"Segmento Principal" |
Caso na mensagem tenha sido definida lista fixa, informar aqui a relação dos valores da mensagem com os valores do produto ou qualquer outra informação importante para descrever a representação deste conteúdo no produto em questão.
Campo Opcional
available
Indica se o campo esta implementado para o produto, para a determinada mensagem. Recebe um valor booleano:
Exemplos |
---|
available: true available: false |
Campo Obrigatório
canUpdate
Indica se o valor do campo pode ser atualizado na tabela. Recebe um valor booleano:
Exemplos |
---|
canUpdate: true canUpdate: false |
Campo Obrigatório
Segmentação do modelo de dados
Partindo de um jsonSchema como base, veremos a seguir um exemplo de uma possível implementação de API usando segmentação do modelo de dados.
O modelo de dados em JsonSchema será compartilhado no repositório do Github da TOTVS e deve ser referenciado na documentação da API pela sua URL, conforme apresentado no exemplo da sessão anterior.
Para este exemplo será utilizado o modelo Contract_2_000.json, representado graficamente a seguir (clique na imagem para expandir).
Convertendo este modelo "como ele é" para o formato Json Schema, teríamos o seguinte documento (alguns elementos previstos para documentação da mensagem padronizada foram omitidos para melhor compreensão):
Bloco de código | ||||
---|---|---|---|---|
| ||||
{
"$schema": "https://raw.githubusercontent.com/totvs/ttalk-standard-message/master/jsonschema/schemas/events/contract_2_000.json#",
(...),
"definitions": {
"Contract": {
"type": "object",
"properties": {
"CompanyId": {
"type": "string"
},
"BranchId": {
"type": "string"
},
"CompanyInternalId": {
"type": "string"
},
"InternalId": {
"type": "string"
},
"ContractNumber": {
"type": "string"
},
"ContractReview": {
"type": "string"
},
"ProjectInternalId": {
"type": "string"
},
"BeginDate": {
"type": "string",
"format": "date-time"
},
"FinalDate": {
"type": "string",
"format": "date-time"
},
"CustomerCode": {
"type": "string"
},
"CustomerInternalId": {
"type": "string"
},
"ContractTotalValue": {
"type": "number",
"format": "float"
},
"ContractTypeCode": {
"type": "string"
},
"ContractTypeInternalId": {
"type": "string"
},
"ListOfSheet": {
"type": "array",
"items": {
"type": "object",
"properties": {
"SheetNumber": {
"type": "string"
},
"SheetTypePoperty": {
"type": "string"
},
"UnitPrice": {
"type": "number",
"format": "float"
},
"SheetTotalValue": {
"type": "number",
"format": "float"
},
"ListOfItem": {
"type": "array",
"items": {
"type": "object",
"properties": {
"ItemCode": {
"type": "string"
},
"ItemInternalId": {
"type": "string"
},
"AccountantAcountCode": {
"type": "string"
},
"AccountantAcountInternalId": {
"type": "string"
},
"CostCenterCode": {
"type": "string"
},
"CostCenterInternalId": {
"type": "string"
},
"AccountingItemCode": {
"type": "string"
},
"AccountingItemInternalId": {
"type": "string"
},
"ClassValueCode": {
"type": "string"
},
"ClassValueInternalId": {
"type": "string"
},
"ItemQuantity": {
"type": "number",
"format": "float"
},
"ItemUnitPrice": {
"type": "number",
"format": "float"
},
"ItemTotalValue": {
"type": "number",
"format": "float"
},
"PercentageOfDiscount": {
"type": "number",
"format": "float"
}
}
}
}
}
}
}
},
"description": "Contrato"
}
}
} |
Entretanto, utilizar o modelo desta forma tem vários problemas como, por exemplo, na modificação do contrato, onde teríamos que enviar também as páginas (Sheet) do contrato e os itens das páginas.
Por isso, a segmentação do modelo de dados é permitida, desde que mantenha a estrutura e atributos do modelo JSON original.
Nosso modelo Json Schema poderia ser segmentado em 3 submodelos:
- ContractModel, correspondente ao cabeçalho do contrato.
- SheetModel, correspondente às folhas do contrato.
- ItemModel, correspondente aos itens vinculados às folhas do contrato.
Convertendo isso para o modelo Json Schema, teríamos o seguinte, lembrando que elementos como as tags de documentação foram omitidos por questões didáticas.
Bloco de código | ||||
---|---|---|---|---|
| ||||
{
"$schema": "https://raw.githubusercontent.com/totvs/ttalk-standard-message/master/jsonschema/schemas/events/contract_2_000.json#",
(...),
"definitions": {
"ContractModel": {
"type": "object",
"properties": {
"CompanyId": {
"type": "string"
},
"BranchId": {
"type": "string"
},
"CompanyInternalId": {
"type": "string"
},
"InternalId": {
"type": "string"
},
"ContractNumber": {
"type": "string"
},
"ContractReview": {
"type": "string"
},
"ProjectInternalId": {
"type": "string"
},
"BeginDate": {
"type": "string",
"format": "date-time"
},
"FinalDate": {
"type": "string",
"format": "date-time"
},
"CustomerCode": {
"type": "string"
},
"CustomerInternalId": {
"type": "string"
},
"ContractTotalValue": {
"type": "number",
"format": "float"
},
"ContractTypeCode": {
"type": "string"
},
"ContractTypeInternalId": {
"type": "string"
},
"ListOfSheet": {
"type": "array",
"items": {
"$ref": "#/definitions/SheetModel"
}
}
},
"description": "Contrato"
},
"SheetModel": {
"type": "object",
"properties": {
"SheetNumber": {
"type": "string"
},
"SheetTypePoperty": {
"type": "string"
},
"UnitPrice": {
"type": "number",
"format": "float"
},
"SheetTotalValue": {
"type": "number",
"format": "float"
},
"ListOfItem": {
"type": "array",
"items": {
"$ref": "#/definitions/ItemModel"
}
}
}
},
"ItemModel": {
"type": "object",
"properties": {
"ItemCode": {
"type": "string"
},
"ItemInternalId": {
"type": "string"
},
"AccountantAcountCode": {
"type": "string"
},
"AccountantAcountInternalId": {
"type": "string"
},
"CostCenterCode": {
"type": "string"
},
"CostCenterInternalId": {
"type": "string"
},
"AccountingItemCode": {
"type": "string"
},
"AccountingItemInternalId": {
"type": "string"
},
"ClassValueCode": {
"type": "string"
},
"ClassValueInternalId": {
"type": "string"
},
"ItemQuantity": {
"type": "number",
"format": "float"
},
"ItemUnitPrice": {
"type": "number",
"format": "float"
},
"ItemTotalValue": {
"type": "number",
"format": "float"
},
"PercentageOfDiscount": {
"type": "number",
"format": "float"
}
}
}
}
} |
Consequentemente, esta segmentação será refletida nos endpoints das APIs. Tomando por base a divisão realizada, teríamos o seguinte template:
Bloco de código | ||
---|---|---|
| ||
/api/{agrupador}/v1/contracts/{ContractUniqueId}/sheets/{SheetNumber}/items/{ItemCode} |
Neste template, temos as seguintes considerações:
- O item ContractUniqueId deve ser um identificador único, já que a entidade Contract prevê uma chave composta. A forma como esta chave será representada ficará a cargo da área de negócio definir. Neste exemplo específico, poderiamos assumir a concatenação dos atributos ContractNumber e ContractReview, separados por "|". Ex: 1|1.
- No nível de contracts utilizamos o submodelo ContractModel. Nos atributos ListOfSheet e ListOfItem, utilizamos os submodelos SheetModele ItemModel quando os mesmos forem expandidos.
- No nível de sheets, utilizamos apenas o submodelo SheetModel. O modelo ItemModel será utilizado quando o atributo ListOfItem for expandido.
- No nível de items, utilizamos apenas o submodelo ItemModel.
- Observe a equivalencia entre o item do modelo e o item de path correspondente:
- ListOfSheet (atributo de ContractModel) equivale a sheets.
- ListOfItem (atributo de SheetModel) equivale a items.
Nos exemplos a seguir veremos a utilização dos possíveis endpoints e seus respectivos modelos:
Inclusão de um contrato de forma completa
Bloco de código | ||||||
---|---|---|---|---|---|---|
| ||||||
{
"CompanyId": "1",
"BranchId": "1",
"CompanyInternalId": "1",
"InternalId": "1|1|1",
"ContractNumber": "1",
"ContractReview": "1",
"ProjectInternalId": "1|1",
"BeginDate": "2018-07-25T14:24:00",
"FinalDate": "2019-07-25T14:24:00",
"CustomerCode": "1",
"CustomerInternalId": "1",
"ContractTotalValue": 1.0,
"ContractTypeCode": "1",
"ContractTypeInternalId": "1",
"ListOfSheet": [{
"SheetNumber": "1",
"SheetTypePoperty": "1",
"UnitPrice": 1.0,
"SheetTotalValue": 1.0,
"ListOfItem": [{
"ItemCode": "1",
"ItemInternalId": "1|1",
"AccountantAcountCode": "0001",
"AccountantAcountInternalId": "1|0001",
"CostCenterCode": "1",
"CostCenterInternalId": "1|1",
"AccountingItemCode": "111",
"AccountingItemInternalId": "1|111",
"ClassValueCode": "001",
"ClassValueInternalId": "1|001",
"ItemQuantity": 1.0,
"ItemUnitPrice": 1.0,
"ItemTotalValue": 1.0,
"PercentageOfDiscount": 0.0
}
]
}
]
} |
Inclusão de um contrato sem folhas (se a regra de negócio permitir)
Bloco de código | ||||||
---|---|---|---|---|---|---|
| ||||||
{
"CompanyId": "1",
"BranchId": "1",
"CompanyInternalId": "1",
"InternalId": "1|1|1",
"ContractNumber": "1",
"ContractReview": "1",
"ProjectInternalId": "1|1",
"BeginDate": "2018-07-25T14:24:00",
"FinalDate": "2019-07-25T14:24:00",
"CustomerCode": "1",
"CustomerInternalId": "1",
"ContractTotalValue": 1.0,
"ContractTypeCode": "1",
"ContractTypeInternalId": "1",
"ListOfSheet": []
} |
Recuperando contratos (apenas cabeçalho, 1a página, até o limite de uma página)
Bloco de código | ||||||
---|---|---|---|---|---|---|
| ||||||
{
"hasNext": false,
"items": [{
"_expandables": ["ListOfSheet"],
"CompanyId": "1",
"BranchId": "1",
"CompanyInternalId": "1",
"InternalId": "1|1|1",
"ContractNumber": "1",
"ContractReview": "1",
"ProjectInternalId": "1|1",
"BeginDate": "2018-07-25T14:24:00",
"FinalDate": "2019-07-25T14:24:00",
"CustomerCode": "1",
"CustomerInternalId": "1",
"ContractTotalValue": 1.0,
"ContractTypeCode": "1",
"ContractTypeInternalId": "1",
"ListOfSheet": []
}
]
} |
Recuperando um contrato, expandindo os atributos ListOfSheet e ListOfItem
Bloco de código | ||||||
---|---|---|---|---|---|---|
| ||||||
{
"_expandables": ["ListOfSheet"],
"CompanyId": "1",
"BranchId": "1",
"CompanyInternalId": "1",
"InternalId": "1|1|1",
"ContractNumber": "1",
"ContractReview": "1",
"ProjectInternalId": "1|1",
"BeginDate": "2018-07-25T14:24:00",
"FinalDate": "2019-07-25T14:24:00",
"CustomerCode": "1",
"CustomerInternalId": "1",
"ContractTotalValue": 1.0,
"ContractTypeCode": "1",
"ContractTypeInternalId": "1",
"ListOfSheet": [{
"_expandable": ["ListOfItem"],
"SheetNumber": "1",
"SheetTypePoperty": "1",
"UnitPrice": 1.0,
"SheetTotalValue": 1.0,
"ListOfItem": [{
"ItemCode": "1",
"ItemInternalId": "1|1",
"AccountantAcountCode": "0001",
"AccountantAcountInternalId": "1|0001",
"CostCenterCode": "1",
"CostCenterInternalId": "1|1",
"AccountingItemCode": "111",
"AccountingItemInternalId": "1|111",
"ClassValueCode": "001",
"ClassValueInternalId": "1|001",
"ItemQuantity": 1.0,
"ItemUnitPrice": 1.0,
"ItemTotalValue": 1.0,
"PercentageOfDiscount": 0.0
}
]
}
]
} |
Incluindo uma folha no contrato
Bloco de código | ||||||
---|---|---|---|---|---|---|
| ||||||
{
"SheetNumber": "1",
"SheetTypePoperty": "1",
"UnitPrice": 1.0,
"SheetTotalValue": 1.0,
"ListOfItem": [{
"ItemCode": "1",
"ItemInternalId": "1|1",
"AccountantAcountCode": "0001",
"AccountantAcountInternalId": "1|0001",
"CostCenterCode": "1",
"CostCenterInternalId": "1|1",
"AccountingItemCode": "111",
"AccountingItemInternalId": "1|111",
"ClassValueCode": "001",
"ClassValueInternalId": "1|001",
"ItemQuantity": 1.0,
"ItemUnitPrice": 1.0,
"ItemTotalValue": 1.0,
"PercentageOfDiscount": 0.0
}
]
} |
Incluindo um item de uma folha do contrato
Bloco de código | ||||||
---|---|---|---|---|---|---|
| ||||||
{
"ItemCode": "1",
"ItemInternalId": "1|1",
"AccountantAcountCode": "0001",
"AccountantAcountInternalId": "1|0001",
"CostCenterCode": "1",
"CostCenterInternalId": "1|1",
"AccountingItemCode": "111",
"AccountingItemInternalId": "1|111",
"ClassValueCode": "001",
"ClassValueInternalId": "1|001",
"ItemQuantity": 1.0,
"ItemUnitPrice": 1.0,
"ItemTotalValue": 1.0,
"PercentageOfDiscount": 0.0
} |
Eliminando um item de uma folha
- DELETE /v1/contracts/1|1/sheets/1/items/1
Eliminando uma folha de um contrato
- DELETE /v1/contracts/1|1/sheets/1
Âncora | ||||
---|---|---|---|---|
|
Json Schema da Mensagem Branch 2.001 : https://raw.githubusercontent.com/totvs/ttalk-standard-message/master/jsonschema/schemas/Branch_2_001.json
Outros Json Schemas aprovados: https://github.com/totvs/ttalk-standard-message/tree/master/jsonschema/schemas
Exemplos Oficiais site json-schema: https://json-schema.org/learn/miscellaneous-examples.html
Âncora | ||||
---|---|---|---|---|
|
http://docs.oasis-open.org/ubl/prd1-UBL-2.1/UBL-2.1.html
http://docs.oasis-open.org/ubl/UBL-2.1-JSON/v1.0/cnd02/UBL-2.1-JSON-v1.0-cnd02.html
http://docs.oasis-open.org/ubl/UBL-2.1-JSON/v1.0/cnd02/json-schema/maindoc/
http://www.unece.org/cefact/brs/brs_index.html
BusinessMessage – Event
As mensagens de eventos de negócio basicamente descrevem o evento ocorrido, como no exemplo abaixo:
Onde:
- Entity: Identifica qual foi a entidade de negócio que sofreu o evento
- Event: Qual foi o evento associado à mensagem (pode ser upsert – inclusão/alteração – ou delete – eliminação).
- Identification/Keys: Campos-chave para identificação do registro impactado pela alteração
- BusinessContent: XML com informações sobre o evento, normalmente contendo todas as informações pertinentes àquela entidade
BusinessMessage – Request
As mensagens de request descrevem qual função se deseja executar e os parâmetros necessários, como no exemplo abaixo:
Onde:
- Operation: Identifica qual a operação que se deseja executar
- BusinessContent: XML com informações necessárias para o processamento, normalmente parâmetros de entrada
...
Uma ResponseMessage representa o resultado do processamento de uma BusinessMessage pelo aplicativo que a recebeu e o seu conteúdo pode variar de acordo com o tipo de mensagem e com o resultado do processamento.
Todas as respostas geradas por uma BusinessMessage devem ser associadas à mensagem original e mantidas pelo aplicativo-origem, como forma de rastrear quem processou aquela mensagem e qual o resultado do processamento.
A mensagem de resposta contém informações sobre o resultado do processamento de uma BusinessMessage, como no exemplo abaixo:
Bloco de código | ||||||
---|---|---|---|---|---|---|
| ||||||
<ResponseMessage>
<ReceivedMessage>
<SentBy>PROTHEUS</SentBy>
<UUID>25121218-a5c8-e581-b010-0a139a59f4bf</UUID>
<Event>upsert</Event>
<MessageContent>
<![CDATA[
... mensagem original...
]]>
</MessageContent>
</ReceivedMessage>
<ProcessingInformation>
<ProcessedOn>2011-06-23T17:04:16</ProcessedOn>
<Status>error</Status>
<ListOfMessages>
<Message type="warning" code="254">Mensagem de aviso</Message>
<Message type="error" code="-25">Mensagem de erro</Message>
<Message type="error" code="EAI30">Mensagem de Teste3</Message>
</ListOfMessages>
</ProcessingInformation>
<ReturnContent>
...
</ReturnContent>
</ResponseMessage> |
Onde:
- ReceivedMessage: Segmento com informações sobre a mensagem original (BusinessMessage) que deu origem a esta resposta.
- SentBy: Indica qual foi a instancia que gerou a mensagem original
- UUID: Identificador universal da mensagem de origem
- Event: Qual foi o evento associado à mensagem (pode ser upsert – inclusão/alteração – ou delete – eliminação).
- MessageContent: XML da mensagem original (opcional).
- ProcessingInformation: Segmento com informações sobre o resultado do processamento
- ProcessedOn: Timestamp de quando a mensagem foi processada pelo destino
- Status: Situação final do processamento (ok ou error)
- ListOfMessages: Lista de mensagens (erro ou aviso) retornadas no processamento.
- ReturnContent: XML com as informações de negócio retornadas no processamento
Obs: Consultar Catalogo de Erros
...
Uma ReceiptMessage representa a confirmação de recebimento de uma BusinessMessage pelo aplicativo destino.
Diferente da ResponseMessage, uma ReceiptMessage não irá conter qualquer informação relevante sobre o processamento da mensagem, uma vez que se entende que, se o aplicativo destino retornou um Receipt, ele não processou a mensagem naquele momento (comunicação assíncrona).
Quando a mensagem for processada pelo aplicativo-destino, uma mensagem de resposta (ResponseMessage) será gerada e encaminhada ao aplicativo que originou a BusinessMessage.
As informações contidas nas mensagens de recibo são genéricas e focam especificamente nos dados de recebimento da mensagem.
Onde:
- ReceivedMessage: Segmento com informações sobre a mensagem original (BusinessMessage) que deu origem a esta resposta.
- SentBy: Indica qual foi a instancia que gerou a mensagem original
- UUID: Identificador universal da mensagem de origem
- MessageContent: XML da mensagem original (opcional).
- ReceiptData: Segmento com informações sobre o recebimento da mensagem
- ReceivedOn: Timestamp do recebimento da mensagem.
Quando uma BusinessMessage é recebida é ela for síncrona, ela deverá ser processada e receberá como resposta uma ResponseMessage,
Quando uma BusinessMessage é recebida é ela for assíncrona, ela receberá como resposta, no momento da recepção uma ReceiptMessage, e posteriormente quando for processada será enviada uma ResponseMessage para esta mensagem
Exemplo(s)
Explicar regras de propriedades a partir do(s) exemplo(s)