Páginas filhas
  • Chave Interna (InternalId)

Versões comparadas

Chave

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

...

  • Empresa Logix 23 == Empresa Protheus 50|10    ou 10   ou seja, a empresa 23 do Logix corresponde a empresa 50 e filial 10 do Protheus.

...

Esta tag deverá estar localizada logo abaixo dos campos da mensagem, que fazem parte da sua composição. O exemplo a seguir é um trecho do schema RefundReason_1_000.json.

Bloco de código
titleExemplo
collapsetrue
(...)


				<xs:element name="Code" type="xs:string" minOccurs="0" maxOccurs="1">
	<xs:annotation>
		<xs:documentation>Codigo do departamento</xs:documentation>
	</xs:annotation>
</xs:element>
<xs:element name="InternalId" type="xs:string" minOccurs="0" maxOccurs="1">
	<xs:annotation>
		<xs:documentation>InternalId do Code</xs:documentation>
	</xs:documentation>
</xs:element>

Bloco de código
titleExemplo
CompanyId: "23"
Code: "123"
InternalId: "23|123"

...

: {

					"description": "Código do Motivo",

					"type": "string",

					"x-totvs": [

						{

							"product": "PROTHEUS",

							"field": "G8P.G8P_CODIGO",

							"required": true,

							"type": "Char",

							"length": "4",

							"note": "",

							"available": true,

							"canUpdate": false

						}

					]

				},

				"InternalId": {

					"description": "InternalId do Motivo",

					"type": "string",

					"x-totvs": [

						{

							"product": "PROTHEUS",

							"field": "cEmpAnt+G8P.G8P_FILIAL+G8P.G8P_CODIGO",

							"required": true,

							"type": "Char",

							"length": "136",

							"note": "",

							"available": true,

							"canUpdate": false

						}

					]

				},

(...)

Suponhamos que em um cenário tenhamos CompanyId com valor 23 e Code com valor 50. O internalId trafegado seguiria então a seguinte lógica:

Bloco de código
titleExemplo
"CompanyId": "23"
"Code": "50"
"InternalId": "23|50"


Toda mensagem de evento (quando for UpSert) deverá conter em seu conteúdo de retorno <ReturnContent> campos de InternalId para armazenar a chave interna do gerador do evento e a chave interna gerada no recebedor do evento. A necessidade disso é para que o recebedor da mensagem de evento e o gerador da mensagem de evento tenham conhecimento da chave interna gerada em cada produto. O fluxo abaixo exemplifica este funcionamento, para o cenário de inclusão de um novo Cliente.



Image Added


Desta forma, a tag <ReturnContent> da mensagem (ainda utilizando RefundReason_1_000.json como exemplo) seria construída da seguinte forma:

Bloco de código
titleExemplo
(...)


		"ReturnContentType": {

			"type": "object",

			"properties": {

				"ListOfInternalId": {

					"type": "array",

					"items": {

						"$ref": "https://raw.githubusercontent.com/totvs/ttalk-standard-message/master/jsonschema/schemas/types/ListOfInternalId_1_000.json#/definitions/ListOfInternalIdType",

						"type": "object"

					}

				}

			}

		}


ListOfInternalIdType está definido em um arquivo a parte e está estruturado conforme o exemplo abaixo:


Bloco de código
titleExemplo
(...)


"definitions": {

		"ReturnContentWithModelType": {

			"type": "object",

			"properties": {

				"ListOfInternalId": {

					"type": "object",

					"$ref": "#/definitions/ListOfInternalIdType"

				}

			}

		},

		"ListOfInternalIdType": {

			"type": "array",

			"items": {

				"$ref": "#/definitions/InternalIdType",

				"type": "object"

			}

		},

		"InternalIdType": {

			"type": "object",

			"properties": {

				"name": {

					"description": "Nome da InternalId, este nome será padronizado entre todas as linhas e  corresponderá ao nome da própria transação. Exemplo: City, Item, CustomerVendor. Observação: em outras partes da mensagem, que não sejam a tag ListOfInternalId, a regra pode ser diferente. Para mais informações, consulte  http://tdn.totvs.com/pages/viewpage.action?pageId=181142263",

					"type": "string"

				},

				"origin": {

					"description": "InternalId da origem",

					"type": "string"

				},

				"destination": {

					"description": "InternalId do destino",

					"type": "string"

				}

			}

		}

	}


(...)


Como este retorno representa a resposta de uma mensagem enviada, deve-se entender a tag "origin" como a InternalId do produto que enviou a mensagem (a origem), e "destination" como a InternalId do produto que foi o destino da mensagem.


Regra para chave estrangeira


A utilização da InternalId se aplica também para chaves estrangeiras. Porém, neste caso a regra é que para cada Tag que representar uma chave estrangeira também exista uma Tag InternalId correspondente.


Bloco de código
titleExemplo
Mensagem Warehouse


	Code

	Description

	InternalId






Mensagem Item


	Code


	InternalId


	Description


	Status


	RegisterDate


	WarehouseCode


	WarehouseInternalId


Assim a InternalId de chave estrangeira terá o mesmo nome da tag normal – Warehouse para WarehouseCode – mas usando o termo InternalId em vez de Code.


Em qualquer posição que ocorra (sendo chave primária ou estrangeira), a tag InternalId sempre será uma tag type=”xs:string” sem tamanho definido.


Bloco de código
titleExemplo
collapsetrue
<xs:element name="WarehouseInternalId" type="xs:string">


   <xs:annotation>


      <xs:documentation>InternalId do WarehouseCode</xs:documentation>


   </xs:annotation>


</xs:element>



Para a chave estrangeira o adapter também deverá dar prioridade em resolver o relacionamento pela InternalId. Ou seja, ao receber uma mensagem de Item (seguindo o exemplo), este deve primeiro consultar no seu ferramental de de/para se existe registro correspondente para o WarehouseInternaId recebido, pois este valor já irá fornecer a chave completa correspondente no produto.


Utilização no Adapter


É sabido que cada mensagem única terá um único adapter/versão nos produtos. Com o objetivo de centralizar a regra para composição da chave da InternalId é interessante que cada adapter seja responsável por receber os valores das chaves e concatena-los para a composição da InternalId. Se isto ficar a cargo de cada programa ou adapter que for utilizar o valor, este poderá correr o risco de ser concatenado de formas diferentes em cada ponto em que seja necessário, o que irá prejudicar completamente o funcionamento do recurso.


Ou seja, o adapter da mensagem Item deverá ter um método que recebe os valores da chave e retorne estes concatenados. Ao mesmo tempo que deverá ter um método que recebe o valor da InternalId e retorna o valor correspondente a uma informação da composição desta. Todos os adapters de mensagens que tenham o Item como chave estrangeira utilizarão esta mesma função.


Desta forma, utilizando sempre este mesmo mecanismo onde for necessário, será garantido que o valor será composto sempre da mesma forma e devolvido sempre da mesma forma também.


Exemplo em pseudocódigo (consulte o manual de cada produto para conhecer as funções reais):

Bloco de código
titleExemplo
Adapter da mensagem Item



AdapterItem.Get_InternalId(cod_empresa, cod_filial, item)


Retorna Empresa + “|” + Filial + “|” + Código


Uso: AdapterItem.Get_InternalId(50,10,123456) =  “50|10|123456”




AdapterItem.Get_InternalId_Value(InternalId, Campo)


Retorna <retorna o valor correspondente a posição de “Campo”>


Uso: AdapterItem.Get_InternalId_Value(“50|10|123456”,”cod_empresa”) == “123456”




"definitions": {

"ReturnContentWithModelType": {

"type": "object",

"properties": {

"ListOfInternalId": {

"type": "object",

"$ref": "#/definitions/ListOfInternalIdType"

}

}

},

"ListOfInternalIdType": {

"type": "array",

"items": {

"$ref": "#/definitions/InternalIdType",

"type": "object"

}

},

"InternalIdType": {

"type": "object",

"properties": {

"name": {

"description": "Nome da InternalId, este nome será padronizado entre todas as linhas e corresponderá ao nome da própria transação. Exemplo: City, Item, CustomerVendor. Observação: em outras partes da mensagem, que não sejam a tag ListOfInternalId, a regra pode ser diferente. Para mais informações, consulte http://tdn.totvs.com/pages/viewpage.action?pageId=181142263",

"type": "string"

},

"origin": {

"description": "InternalId da origem",

"type": "string"

},

"destination": {

"description": "InternalId do destino",

"type": "string"

}

}

}

}

Image Removed

Desta forma, na tag <ReturnContent> da mensagem as seguintes tags deverão ser criadas:

Bloco de código
titleExemplo
<xs:include schemaLocation="../types/ListOfInternalId_1_000.xsd"/>


[...]


<xs:element name="ReturnContent" substitutionGroup="AbstractReturnContent">
	<xs:complexType>
		<xs:sequence>
			<xs:element name="ListOfInternalId" type="ListOfInternalIdType" maxOccurs="1" minOccurs="0"/>
		</xs:sequence>
	</xs:complexType>
</xs:element>

ListOfInternalIdType está definido em um arquivo a parte e está estruturado conforme o exemplo abaixo:

Bloco de código
titleExemplo
<ReturnContent>
	<ListOfInternalId>
		<InternalId>
			<Name>[NomeDaMensagem]</Name> <!-- Considerando a InternalId da mensagem (PK) -->
			<Origin>01|123</Origin>
			<Destination>55|11|ABC</Destination>
		</InternalId>
	</ListOfInternalId>
</ReturnContent>

Como este retorno representa a resposta de uma mensagem enviada, deve-se entender a tag <Origin> como a InternalId do produto que enviou a mensagem (a origem), e <Destination> como a InternalId do produto que foi o destino da mensagem.

Regra para chave estrangeira

A utilização da InternalId se aplica também para chaves estrangeiras. Porém, neste caso a regra é que para cada Tag que representar uma chave estrangeira também exista uma Tag InternalId correspondente.

Bloco de código
titleExemplo
Mensagem Warehouse


	Code

	Description


	InternalId






Mensagem Item


	Code


	InternalId


	Description


	Status


	RegisterDate


	WarehouseCode


	WarehouseInternalId

Assim a InternalId de chave estrangeira terá o mesmo nome da tag normal – Warehouse para WarehouseCode – mas usando o termo InternalId em vez de Code.

Em qualquer posição que ocorra (sendo chave primária ou estrangeira), a tag InternalId sempre será uma tag type=”xs:string” sem tamanho definido.

Bloco de código
titleExemplo
collapsetrue
<xs:element name="WarehouseInternalId" type="xs:string">


   <xs:annotation>


      <xs:documentation>InternalId do WarehouseCode</xs:documentation>


   </xs:annotation>


</xs:element>

Para a chave estrangeira o adapter também deverá dar prioridade em resolver o relacionamento pela InternalId. Ou seja, ao receber uma mensagem de Item (seguindo o exemplo), este deve primeiro consultar no seu ferramental de de/para se existe registro correspondente para o WarehouseInternaId recebido, pois este valor já irá fornecer a chave completa correspondente no produto.

Utilização no Adapter

É sabido que cada mensagem única terá um único adapter/versão nos produtos. Com o objetivo de centralizar a regra para composição da chave da InternalId é interessante que cada adapter seja responsável por receber os valores das chaves e concatena-los para a composição da InternalId. Se isto ficar a cargo de cada programa ou adapter que for utilizar o valor, este poderá correr o risco de ser concatenado de formas diferentes em cada ponto em que seja necessário, o que irá prejudicar completamente o funcionamento do recurso.

Ou seja, o adapter da mensagem Item deverá ter um método que recebe os valores da chave e retorne estes concatenados. Ao mesmo tempo que deverá ter um método que recebe o valor da InternalId e retorna o valor correspondente a uma informação da composição desta. Todos os adapters de mensagens que tenham o Item como chave estrangeira utilizarão esta mesma função.

Desta forma, utilizando sempre este mesmo mecanismo onde for necessário, será garantido que o valor será composto sempre da mesma forma e devolvido sempre da mesma forma também.

Exemplo em pseudocódigo (consulte o manual de cada produto para conhecer as funções reais):

...

titleExemplo

...