Trigger to Consult CNPJ in Protheus

Trigger to consult CNPJ in the registration of customers or suppliers in Protheus using ADVPL and the CNPJ.ws API with data from Receita Federal, Sintegra, and Suframa.

Registering customers or suppliers in Protheus can be easier if we consult the CNPJ in the CNPJ.ws API.

With the integration, we can use the API to query the address, state registration, registration status, CNAE, and many other information that may be important when registering a customer or supplier.

We have already created a class in ADVPL to integrate Protheus with CNPJ.ws in the post: Consult CNPJ with ADVPL (Protheus).

In this post, we will use this ADVPL class to develop a trigger that we will use both in the customer registration and in the supplier registration. Remember that you can use our free API to consult CNPJ, but with a limitation of 3 queries per minute, or you can purchase one of our commercial plans.

Function getCNPJ

Let's start by creating a user function that we will call in our triggers. Note that it receives two parameters:

  • cTab: SA1 or SA2, indicating whether we are working with customers or suppliers

  • cCNPJ: the CNPJ number

We also handled the case using the isBlind function in case the trigger is called via execauto, without the user interface. And we used the FWMsgRun function so that the user has visual feedback and not just a "frozen" screen while the process is running.

#include 'totvs.ch'

user function getCNPJ(cTab,cCNPJ)
	local aArea:= getArea()
	local cRet := ''

	default cTab := 'SA1'
	default cCNPJ:= ''

	cCNPJ:= allTrim(cCNPJ)

	if !empty(cTab) .and. len(cCNPJ) == 14
		if isBlind()
			cRet:= consulta(cTab,cCNPJ)
		else
			FWMsgRun(,{||cRet:= consulta(cTab,cCNPJ)},'CNPJ.ws','Consultando...')
		endif
	endif

	restArea(aArea)

return cRet

Let's create a static function that will be responsible for communicating with CNPJ.ws. You should review this code carefully to meet your company's needs. Here, I filled in all the fields that came to mind, but feel free to make changes:

static function consulta(cTab,cCNPJ)
	local oCNPJws:= CNPJws():new()
	local oJSON  := nil
	local nX     := 1
	local cRet   := ''
	local lJob   := isBlind()
	local oModel := nil

	default cTab := 'SA1'
	default cCNPJ:= ''

	if oCNPJws:consultarCNPJ(cCNPJ)
		oJSON:= oCNPJws:getResponse()

		cRet:= oJSON['razao_social']

		if oJSON['estabelecimento']['situacao_cadastral'] <> 'Ativa'
			if lJob
				conout(cCNPJ + ': A situação cadastral da empresa junto a SEFAZ é ' + oJSON['estabelecimento']['situacao_cadastral'])
			else
				alert('A situação cadastral da empresa junto a SEFAZ é ' + oJSON['estabelecimento']['situacao_cadastral'])
			endif
		endif

		if cTab == 'SA1'

			M->A1_MSBLQL:= if(oJSON['estabelecimento']['situacao_cadastral'] == 'Ativa','2','1')
			If ExistTrigger('A1_MSBLQL')
				RunTrigger(1,Nil,Nil,,'A1_MSBLQL')
			Endif

			M->A1_CNAE:= oJSON['estabelecimento']['atividade_principal']['id']

			CC3->(dbSetOrder(1))
			if !CC3->(dbSeek(xFilial('CC3')+M->A1_CNAE))
				reclock('CC3',.t.)
				CC3->CC3_FILIAL	:= xFilial('CC3')
				CC3->CC3_COD		:= oJSON['estabelecimento']['atividade_principal']['id']
				CC3->CC3_DESC		:= upper(oJSON['estabelecimento']['atividade_principal']['descricao'])
				CC3->CC3_CSECAO	:= oJSON['estabelecimento']['atividade_principal']['secao']
				CC3->CC3_CDIVIS	:= oJSON['estabelecimento']['atividade_principal']['divisao']
				CC3->CC3_CGRUPO	:= strTran(oJSON['estabelecimento']['atividade_principal']['grupo'],'.')
				CC3->CC3_CCLASS	:= strTran(strTran(oJSON['estabelecimento']['atividade_principal']['classe'],'.'),'-')
				CC3->(msUnlock())
			endif
			If ExistTrigger('A1_CNAE')
				RunTrigger(1,Nil,Nil,,'A1_CNAE')
			Endif

			M->A1_PESSOA	:= 'J'
			If ExistTrigger('A1_PESSOA')
				RunTrigger(1,Nil,Nil,,'A1_CNAE')
			Endif

			if !empty(oJSON['estabelecimento']['pais']['id'])
				CCH->(dbSetOrder(1))
				if CCH->(dbSeek(xFilial('CCH')+ '0' + oJSON['estabelecimento']['pais']['id'] ))
					M->A1_CODPAIS	:=  CCH->CCH_CODIGO
					If ExistTrigger('A1_CODPAIS')
						RunTrigger(1,Nil,Nil,,'A1_CODPAIS')
					Endif
				endif

				SYA->(dbSetOrder(2))
				if SYA->(dbSeek(xFilial('SYA')+ upper(oJSON['estabelecimento']['pais']['nome'])))
					M->A1_PAIS	:= SYA->YA_CODGI
					If ExistTrigger('A1_PAIS')
						RunTrigger(1,Nil,Nil,,'A1_PAIS')
					Endif
				endif
			endif

			M->A1_NREDUZ := oJSON['estabelecimento']['nome_fantasia']

			if empty(M->A1_NREDUZ) //Caso nao possua nome fantasia
				M->A1_NREDUZ := avKey(cRet, 'A1_NREDUZ')
			endif

			If ExistTrigger('A1_NREDUZ')
				RunTrigger(1,Nil,Nil,,'A1_NREDUZ')
			Endif

			M->A1_CEP		:= oJSON['estabelecimento']['cep']
			If ExistTrigger('A1_CEP')
				RunTrigger(1,Nil,Nil,,'A1_CEP')
			Endif

			M->A1_EST		:= oJSON['estabelecimento']['estado']['sigla']
			If ExistTrigger('A1_EST')
				RunTrigger(1,Nil,Nil,,'A1_EST')
			Endif

			M->A1_COD_MUN:= substring(cValToChar(oJSON['estabelecimento']['cidade']['ibge_id']),3,5)
			If ExistTrigger('A1_COD_MUN')
				RunTrigger(1,Nil,Nil,,'A1_COD_MUN')
			Endif

			M->A1_BAIRRO := oJSON['estabelecimento']['bairro']
			If ExistTrigger('A1_BAIRRO')
				RunTrigger(1,Nil,Nil,,'A1_BAIRRO')
			Endif

			M->A1_END    := oJSON['estabelecimento']['logradouro'] + ', ' + oJSON['estabelecimento']['numero']
			If ExistTrigger('A1_END')
				RunTrigger(1,Nil,Nil,,'A1_END')
			Endif

			M->A1_COMPLEM:= oJSON['estabelecimento']['complemento']
			If ExistTrigger('A1_COMPLEM')
				RunTrigger(1,Nil,Nil,,'A1_COMPLEM')
			Endif

			M->A1_DDD		:= oJSON['estabelecimento']['ddd1']
			If ExistTrigger('A1_DDD')
				RunTrigger(1,Nil,Nil,,'A1_DDD')
			Endif

			M->A1_TEL		:= oJSON['estabelecimento']['telefone1']
			If ExistTrigger('A1_TEL')
				RunTrigger(1,Nil,Nil,,'A1_TEL')
			Endif

			M->A1_FAX		:= oJSON['estabelecimento']['ddd_fax']+oJSON['estabelecimento']['fax']
			If ExistTrigger('A1_FAX')
				RunTrigger(1,Nil,Nil,,'A1_FAX')
			Endif

			M->A1_EMAIL	:= oJSON['estabelecimento']['email']
			If ExistTrigger('A1_EMAIL')
				RunTrigger(1,Nil,Nil,,'A1_EMAIL')
			Endif

			if valType(oJSON['simples']) == 'J'
				M->A1_SIMPNAC:= if(oJSON['simples']['simples'] == 'Sim', '1', '2')
			else
				M->A1_SIMPNAC:= '2'
			endif
			If ExistTrigger('A1_SIMPNAC')
				RunTrigger(1,Nil,Nil,,'A1_SIMPNAC')
			Endif

			for nX:=1 to len(oJSON['estabelecimento']['inscricoes_estaduais'])
				if oJSON['estabelecimento']['estado']['id'] == oJSON['estabelecimento']['inscricoes_estaduais'][nX]['estado']['id']
					M->A1_INSCR:= oJSON['estabelecimento']['inscricoes_estaduais'][nX]['inscricao_estadual']
					If ExistTrigger('A1_INSCR')
						RunTrigger(1,Nil,Nil,,'A1_INSCR')
					Endif
					EXIT
				endif
			next

		elseIf cTab == 'SA2'

			//MATA020 está em MVC
			oModel := FWModelActive()

			oModel:SetValue('SA2MASTER','A2_MSBLQL' ,if(oJSON['estabelecimento']['situacao_cadastral'] == 'Ativa','2','1'))

			CC3->(dbSetOrder(1))
			if !CC3->(dbSeek(xFilial('CC3')+oJSON['estabelecimento']['atividade_principal']['id']))
				reclock('CC3',.t.)
				CC3->CC3_FILIAL	:= xFilial('CC3')
				CC3->CC3_COD		:= oJSON['estabelecimento']['atividade_principal']['id']
				CC3->CC3_DESC		:= upper(oJSON['estabelecimento']['atividade_principal']['descricao'])
				CC3->CC3_CSECAO	:= oJSON['estabelecimento']['atividade_principal']['secao']
				CC3->CC3_CDIVIS	:= oJSON['estabelecimento']['atividade_principal']['divisao']
				CC3->CC3_CGRUPO	:= strTran(oJSON['estabelecimento']['atividade_principal']['grupo'],'.')
				CC3->CC3_CCLASS	:= strTran(strTran(oJSON['estabelecimento']['atividade_principal']['classe'],'.'),'-')
				CC3->(msUnlock())
			endif

			oModel:SetValue('SA2MASTER','A2_CNAE',oJSON['estabelecimento']['atividade_principal']['id'])

			oModel:SetValue('SA2MASTER','A2_TIPO', 'J')

			if !empty(oJSON['estabelecimento']['pais']['id'])
				CCH->(dbSetOrder(1))
				if CCH->(dbSeek(xFilial('CCH') + '0' + oJSON['estabelecimento']['pais']['id']))
					oModel:SetValue('SA2MASTER','A2_CODPAIS', allTrim(CCH->CCH_CODIGO))
				endif

				SYA->(dbSetOrder(2))
				if SYA->(dbSeek(xFilial('SYA')+ upper(oJSON['estabelecimento']['pais']['nome'])))
					oModel:SetValue('SA2MASTER','A2_PAIS', allTrim(SYA->YA_CODGI))
				endif
			endif

			if !empty(oJSON['estabelecimento']['nome_fantasia'])
				oModel:SetValue('SA2MASTER','A2_NREDUZ',oJSON['estabelecimento']['nome_fantasia'])
			else
				oModel:SetValue('SA2MASTER','A2_NREDUZ',avKey(cRet, 'A2_NREDUZ'))
			endif

			oModel:SetValue('SA2MASTER','A2_CEP', oJSON['estabelecimento']['cep'])

			oModel:SetValue('SA2MASTER','A2_EST', oJSON['estabelecimento']['estado']['sigla'])

			oModel:SetValue('SA2MASTER','A2_COD_MUN', substring(cValToChar(oJSON['estabelecimento']['cidade']['ibge_id']),3,5))

			oModel:SetValue('SA2MASTER','A2_BAIRRO', oJSON['estabelecimento']['bairro'])

			oModel:SetValue('SA2MASTER','A2_END',oJSON['estabelecimento']['logradouro'] + ', ' + oJSON['estabelecimento']['numero'])

			oModel:SetValue('SA2MASTER','A2_COMPLEM', oJSON['estabelecimento']['complemento'])

			oModel:SetValue('SA2MASTER','A2_DDD', oJSON['estabelecimento']['ddd1'])

			oModel:SetValue('SA2MASTER','A2_TEL', oJSON['estabelecimento']['telefone1'])

			oModel:SetValue('SA2MASTER','A2_FAX', oJSON['estabelecimento']['ddd_fax']+oJSON['estabelecimento']['fax'])

			oModel:SetValue('SA2MASTER','A2_EMAIL', oJSON['estabelecimento']['email'])

			if valType(oJSON['simples']) == 'J'
				oModel:SetValue('SA2MASTER','A2_SIMPNAC', if(oJSON['simples']['simples'] == 'Sim', '1', '2'))
			else
				oModel:SetValue('SA2MASTER','A2_SIMPNAC', '2')
			endif

			for nX:=1 to len(oJSON['estabelecimento']['inscricoes_estaduais'])
				if oJSON['estabelecimento']['estado']['id'] == oJSON['estabelecimento']['inscricoes_estaduais'][nX]['estado']['id']
					oModel:SetValue('SA2MASTER','A2_INSCR', oJSON['estabelecimento']['inscricoes_estaduais'][nX]['inscricao_estadual'])
					EXIT
				endif
			next
		endif

	else
		if lJob
			conout('Erro ao consultar CNPJ: ' + oCNPJws:getError())
		else
			alert('Erro ao consultar CNPJ: ' + oCNPJws:getError())
		endif
	endif

return cRet

Trigger A1_CGC

Below is the configuration of the trigger for the A1_CGC field, where we call the user function u_getcnpj passing as parameters SA1 and the CNPJ:

Trigger A2_CGC

Below is the configuration of the trigger for the A2_CGC field, where we call the user function u_getcnpj passing as parameters SA2 and the CNPJ:

Conclusion

The result should be as shown in the gif below. When you type the CNPJ, Protheus will query CNPJ.ws and automatically fill in the fields:

You can check the source code of this project on GitHub, the mentioned class is also in this repository.

To learn more about our plans and payment methods, visit CNPJ.ws.

See you soon!

Last updated

Was this helpful?