Histórico da Página
Índice |
---|
...
Objetivo e formas de uso
O objetivo da Mensagem Padronizada TOTVS (TOTVS Standard Message - TSM) é estabelecer padrões que devem ser seguidos por todos os aplicativos que participam da integração. Estes padrões definem os tipos de mensagens suportadas bem como informações obrigatórias que devem fazer parte do seu conteúdo.
...
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.
...
Bloco de código | ||||
---|---|---|---|---|
| ||||
{ "CompanyId": "1", "BranchId": "B1", "CompanyInternalId": "CompanyInternalId", "InternalId": "InternalId", "Code": "Code", "Description": "Description", "NatureType": "NatureType", "UseCategory": "UseCategory", "Blocked": 0 } |
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. |
...
- 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.
...
Bloco de código | ||||
---|---|---|---|---|
| ||||
"info": { ... "x-totvs": { "messageDocumentation": { "name": "StockTurnOver", "description": "Baixa de estoque", "segment": "Construção e Projetos", "domain": "Planejamento" }, "productInformation": [ { "product": "RM", "contact": "Bruno Barbosa de Souza", "note": "GDP Inovação Const. e Proj.", "adapter": "MovMovimentoData" }, { "product": "Protheus", "contact": "Eduardo de Souza", "note": "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" } } } } |
...
Contém nome, descrição e agrupador da mensagem (esse último definido através da propriedade das propriedades segment e domain)
Campo Obrigatório
Aviso |
---|
O campo Os campos "segment" e "domain" deve devem ser preenchido 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 segmento que você quer adicionar está escrito. |
...
Aviso |
---|
O campo "product" deve ser preenchido de forma coerente com o que já está em uso nos outros schemas de nosso repositório (sem ao menos diferenciação de casepor exemplo, mantendo o mesmo "case"). Para isso, visite o API Reference e verifique como o produto que você quer adicionar está escrito. |
...
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
...
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
...