Abaixo iremos mostrar como configurar o Processo de Venda no Protheus visando realizar a integração de vendas entre Protheus x Totvs Chef. Siga o Passo a Passo.

As vendas compatíveis: NFC-e, SAT e ECF

Não existe integração de ficha técnica. A integração da venda é realizada utilizando as rotinas padrão do Venda Assistida, atualmente não existe no padrão a funcionalidade de baixa de estoque por ficha técnica. 

Não existe integração de Impostos. Os dados de impostos devem ser complementados na camada do TOTVS CH

EF.

Não existe integração de Inutilização de documento NFC-e

Não existe integração de Troca/Devolução de Venda

Não existe integração de venda com pagamento em NCC (Crédito)

Cadastrando o Processo VENDA

Para integrarmos as vendas do Totvs Chef com o Protheus é necessário primeiramente realizar o cadastro do processo VENDA no Protheus.


1- No módulo 12 (Controle de Lojas), acesse Atualizações/ RMI/ Cadastros/ Processos.

2- No Browse clique em Incluir e preencha os campos:

Processo: VENDA

Tabela: SL1

Chave: L1_FILIAL+L1_NUM

3- Na guia Tabelas Secundárias preencha os campos :

Tabela: SL2

Descrição: Preenchido automaticamente com o nome da tabela informada

Chave: L2_FILIAL+L2_NUM

4- Ainda na guia Tabelas Secundárias adicione uma nova linha e preencha os campos:

Tabela: SL4

Descrição: Preenchido automaticamente com o nome da tabela informada

Chave: L4_FILIAL+L4_NUM


Exemplo do cadastro de Processo do VENDA:


Vinculando o Processo VENDA ao Assinante CHEF


1- No módulo 12 (Controle de Lojas), acesse Atualizações/ RMI/ Cadastros/ Assinantes.

2- Com o assinante CHEF previamente cadastrado, posicione no assinante CHEF e clique em alterar.

3- Na guia Assinantes x Processos, preencha os seguintes campos:

Processo: Venda

Ativo: Sim

Tipo Process: Busca

Filiais Proc: Informe o código das filiais que deseja integrar a Venda: Lembre-se que deve ter sido realizado o De/Para entre o código da loja do Totvs Chef e a Filial correspondente no Protheus:  Cadastro de De/Para.

Esta disponível para busca de venda dois tipos de Api: Por Data de Movimento Por Data de Integração.

Configuração:  Preencha este campo de acordo com a sua URL da API  Capa Venda, como mostra o exemplo abaixo:

{
    "url":"http://{url_do_servidor}/api/CapaVenda/ListPorDataMovimento",
    "SL2":"self:oRegistro['Itens']",
    "SL4":"self:oRegistro['Pagamentos']"
}

Layout Envio: Preencha este campo de acordo com o exemplo abaixo: 

{
	"CodigoLoja": "&self:aArrayFil[self:nFil][1]",
	"notasinutilizadas": 1,
	"DataMovimentoInicial": "&Str( Year(dDatabase), 4) +'-'+  StrZero( Month(dDatabase), 2) +'-'+ StrZero( Day(dDatabase), 2)",
	"DataMovimentoFinal": "&Str( Year(dDatabase), 4) +'-'+  StrZero( Month(dDatabase), 2) +'-'+ StrZero( Day(dDatabase), 2)"

}


Layout Publicação: Preencha este campo de acordo com o exemplo abaixo:

{
	"L1_FILIAL": "",
	"L1_CLIENTE": "&SuperGetMV('MV_CLIPAD',.F.,'000001', self:DePara('SM0', cValToChar(self:oRegistro['Loja']['Codigo']), 1, 0, .F., 'CHEF'))",
	"L1_LOJA": "&SuperGetMV('MV_LOJAPAD',.F., '01', self:DePara('SM0', cValToChar(self:oRegistro['Loja']['Codigo']), 1, 0, .F., 'CHEF'))",
	"L1_OPERADO": "&self:DePara('SA6', cValToChar(self:oRegistro['Loja']['Codigo']) + '|' + cValToChar(self:oRegistro['Caixa']['Operador']['Codigo']), 2, 0, .F., 'CHEF')",
	"L1_TROCO1": "&self:oRegistro['TotalizadorVenda']['ValorTroco']",
	"L1_EMISSAO": "&self:oRegistro['DataMovimento']",
	"L1_EMISNF": "&self:oRegistro['DataMovimento']",
	"L1_DTLIM": "&self:oRegistro['DataMovimento']",
	"L1_NUMMOV": "&SubStr(cValToChar(self:oRegistro['Caixa']['NumeroFechamento']),1,2)",
	"L1_NUMCFIS": "&cValToChar(self:oRegistro['NumeroCupom'])",
	"L1_DOC": "&cValToChar(self:oRegistro['NumeroNota'])",
	"L1_SERIE": "&self:LayEstAutoChef('LG_SERIE')",
	"L1_SERPDV": "&self:oRegistro['SerieECF']",
	"L1_SERSAT": "&self:oRegistro['SerieSAT']",
	"L1_KEYNFCE": "&self:oRegistro['ChaveSefaz']",
	"L1_PRONFCE": "&self:oRegistro['ProtocoloAutorizacaoSefaz']",
	"L1_COMIS": 0,
	"L1_ORIGEM": "N",
	"L1_VLRTOT": "&self:oRegistro['TotalizadorVenda']['ValorTotal']",
	"L1_VALBRUT": "&self:oRegistro['TotalizadorVenda']['ValorSubTotal']",
	"L1_VLRLIQ": "&self:oRegistro['TotalizadorVenda']['ValorSubTotal']",
	"L1_VALMERC": "&self:oRegistro['TotalizadorVenda']['ValorSubTotal']",
	"L1_DESCONT": "&self:oRegistro['TotalizadorVenda']['ValorTotalDescontoSistema']",
	"L1_DESCFIN": "&self:oRegistro['TotalizadorVenda']['ValorTotalDescontoFiscal']",
	"L1_VALICM": "&self:oRegistro['TotalizadorVenda']['ValorTotalICMS']",
	"L1_VALPIS": "&self:oRegistro['TotalizadorVenda']['ValorTotalPIS']",
	"L1_VALCOFI": "&self:oRegistro['TotalizadorVenda']['ValorTotalCOFINS']",
	"L1_CGCCLI": "&IIF(self:oRegistro['Cliente'] <> Nil, self:oRegistro['Cliente']['Documento'], '')",
	"L1_CONDPG": "CN",
	"L1_SITUA": "IP",
	"L1_TIPO": "V",
	"L1_TIPOCLI": "F",
	"L1_ESPECIE": "&IIF(self:oRegistro['ModeloFiscal'] == 1,'SATCE',IIF(self:oRegistro['ModeloFiscal'] == 2,'NFCE','ECF'))",
	"L1_PDV": "&self:LayEstAutoChef('LG_PDV')",
	"SL2": [
		{
			"L2_FILIAL": "",
			"L2_PRODUTO": "&cValToChar(self:oRegistro['Itens'][nItem]['Produto']['Codigo'])",
			"L2_DESCRI": "&self:oRegistro['Itens'][nItem]['Produto']['Nome']",
			"L2_QUANT": "&self:oRegistro['Itens'][nItem]['Quantidade']", 			
			"L2_VRUNIT": "&self:oRegistro['Itens'][nItem]['ValorUnitario'] - (self:oRegistro['Itens'][nItem]['ValorDesconto'] /self:oRegistro['Itens'][nItem]['Quantidade']) ",
		    "L2_VLRITEM": "&self:oRegistro['Itens'][nItem]['ValorTotal']",
			"L2_PRCTAB": "&self:oRegistro['Itens'][nItem]['ValorUnitario']",
		    "L2_LOCAL": "&SuperGetMV('MV_LOCPAD',.F., '01', self:DePara('SM0', cValToChar(self:oRegistro['Loja']['Codigo']), 1, 0, .F., 'CHEF'))",
			"L2_UM": "&self:oRegistro['Itens'][nItem]['Produto']['Unidade']",
			"L2_VALDESC": "&self:oRegistro['Itens'][nItem]['ValorDesconto']",
			"L2_TES": "&SuperGetMV('MV_TESSAI', .F., '501', self:DePara('SM0', cValToChar(self:oRegistro['Loja']['Codigo']), 1, 0, .F., 'CHEF'))",
			"L2_CF": "&self:oRegistro['Itens'][nItem]['Cfop']",
			"L2_PICM": "&self:oRegistro['Itens'][nItem]['Icms']['Aliquota']",
			"L2_BASEICM": "&self:oRegistro['Itens'][nItem]['Icms']['BaseCalculo']",
			"L2_VALICM": "&self:oRegistro['Itens'][nItem]['Icms']['Valor']",
			"L2_EMISSAO": "&self:oRegistro['DataMovimento']",
			"L2_CSTPIS": "&self:oRegistro['Itens'][nItem]['Pis']['Cst']",
			"L2_CSTCOF": "&self:oRegistro['Itens'][nItem]['Cofins']['Cst']"
		}
	],
	"SL4": [
		{
			"L4_FILIAL": "",
			"L4_DATA": "&self:oRegistro['DataMovimento']",
			"L4_VALOR": "&IIF(self:oRegistro['Pagamentos'][nItem]['Descricao'] == 'DINHEIRO',self:oRegistro['Pagamentos'][nItem]['ValorRecebido']+self:oRegistro['TotalizadorVenda']['ValorTroco'],self:oRegistro['Pagamentos'][nItem]['ValorRecebido'])",
			"L4_ADMINIS": "&IIF(self:oRegistro['Pagamentos'][nItem]['Descricao'] <> 'DINHEIRO',Substr(self:DePara('SAE',self:oRegistro['Pagamentos'][nItem]['Descricao'], 2, 0, .F., 'CHEF'),1,20),'')",
			"L4_TROCO": "&IIF(self:oRegistro['Pagamentos'][1] <> nil .and. self:oRegistro['Pagamentos'][1]['ValorRecebido'] > 0 .and. self:oRegistro['Pagamentos'][nItem]['Descricao'] == 'DINHEIRO',self:oRegistro['TotalizadorVenda']['ValorTroco'],0)",
			"L4_FORMA": "&self:DePara('SX5',IIF(cValToChar(self:oRegistro['Pagamentos'][nItem]['TipoFormaPagamento']) == '3',self:oRegistro['Pagamentos'][nItem]['Descricao'],cValToChar(self:oRegistro['Pagamentos'][nItem]['TipoFormaPagamento'])), 2, 0, .F., 'CHEF')",
			"L4_NSUTEF": "&IIF(self:oRegistro['Pagamentos'][nItem]['FormaPagamentoCartao'] <> nil .and. cValToChar(self:oRegistro['Pagamentos'][nItem]['FormaPagamentoCartao']['TipoTransacao']) == '1',self:oRegistro['Pagamentos'][nItem]['FormaPagamentoCartao']['DadosTEF']['NSUTEF'],'')",
			"L4_DOCTEF": "&IIF(self:oRegistro['Pagamentos'][nItem]['FormaPagamentoCartao'] <> nil .and. cValToChar(self:oRegistro['Pagamentos'][nItem]['FormaPagamentoCartao']['TipoTransacao']) == '1',self:oRegistro['Pagamentos'][nItem]['FormaPagamentoCartao']['DadosTEF']['NSUHost'],'')",
			"L4_DATATEF": "&IIF(self:oRegistro['Pagamentos'][nItem]['FormaPagamentoCartao'] <> nil .and. cValToChar(self:oRegistro['Pagamentos'][nItem]['FormaPagamentoCartao']['TipoTransacao']) == '1',StrTran(Substr(self:oRegistro['DataRecebimento'],1, AT('T',self:oRegistro['DataRecebimento']) -1),'-',''),'  /  /  ')",
			"L4_HORATEF": "&IIF(self:oRegistro['Pagamentos'][nItem]['FormaPagamentoCartao'] <> nil .and. cValToChar(self:oRegistro['Pagamentos'][nItem]['FormaPagamentoCartao']['TipoTransacao']) == '1',StrTran(Substr(self:oRegistro['DataRecebimento'],AT('T',self:oRegistro['DataRecebimento']) +1 ,8),':',''),'')",
			"L4_BANDEIR": "&IIF(self:oRegistro['Pagamentos'][nItem]['FormaPagamentoCartao'] <> nil .and. cValToChar(self:oRegistro['Pagamentos'][nItem]['FormaPagamentoCartao']['TipoTransacao']) == '1',self:oRegistro['Pagamentos'][nItem]['FormaPagamentoCartao']['DadosTEF']['CodigoBandeiraTexto'],'')",
			"L4_AUTORIZ": "&IIF( self:oRegistro['Pagamentos'][nItem]['FormaPagamentoCartao'] <> Nil, IIF(self:oRegistro['Pagamentos'][nItem]['FormaPagamentoCartao']['DadosTEF'] <> Nil .and. !Empty(self:oRegistro['Pagamentos'][nItem]['FormaPagamentoCartao']['DadosTEF']['CodigoAutorizacao']), self:oRegistro['Pagamentos'][nItem]['FormaPagamentoCartao']['DadosTEF']['CodigoAutorizacao'], StrZero(nItem, TamSx3('L4_FORMAID')[1])), '' )"
		}
	]
}
  • As tags L1_FILIAL, L2_FILIAL e L4_FILIAL são preenchidas pelo Protheus, então devem ficar com o conteúdo vazio.

Foi disponibilizada a rotina com a nova regra para consumo da API capaVenda, agora só será permitida a integração com intervalos de no minimo 30 minutos.

Caso a integração seja executada antes deste periodo será apresentada a mensagem:

    • 20/12/23 15:46:48  - [VENDA] Busca nao sera executada, intervalo de tempo minimo(00:30:00) nao foi atingido. Intervalo atual: 00:01:25

Para o caso de reprocessamento, caso seja executada antes do periodo será apresentada a mensagem:

    • 20/12/23 15:46:49 RMIREPROCESSA - Reprocessamento da integracao com o FOOD nao executado, pois esta fora do horario permitido: 00:00 as 06:00

Para Reprocessar vendas com erro é necessário incluir tags de controle no layout de envio:

  • DataReprocessamento: Data de controle para inicialização do mecanismo de reprocessamento. Essa dava deve ser preenchida com um dia antes da data atual da maquina onde o serviço RMIBUSCA esta configurado.
  • UltimodiaReprocessado: Data de controle para saber qual foi o ultimo dia reprocessado automaticamente pelo sistema.
  • DiasRetroceder: dias definido pelo usuário para controle da DataReprocessamento. 

Exemplo:

    "DataReprocessamento": "20230515",

    "UltimodiaReprocessado": "20230515",   

    "DiasRetroceder": 10


Como será inicializado o reprocessamento?

O serviço RMIBUSCA verifica se a data da maquina onde se encontra o mesmo é maior que a data contida na tag DataReprocessamento. Caso seja será inicializado o reprocessamento seguindo as considerações abaixo:

A data inicial do reprocessamento será realizada através do calculo:

UltimodiaReprocessado - DiasRetroceder = 05/05/2023

Com isso o reprocessamento se busca as vendas do dia 05/10/2023 até o dia 14/05/2023.

As tags DataReprocessamento e UltimodiaReprocessado são atualizadas após cada execução com isso não será mais necessário realizar essa alteração manualmente.

Neste cenário começará a partir de 05/05/23 e terminará na data atual;

Com isso o Layout de Envio deve estar com essa estrutura.

{
    "CodigoLoja": "&self:aArrayFil[self:nFil][1]",
    "notasinutilizadas": 1,
    "DataMovimentoInicial": "&Str( Year(dDatabase), 4) +'-'+  StrZero( Month(dDatabase), 2) +'-'+ StrZero( Day(dDatabase), 2)",
    "DataMovimentoFinal": "&Str( Year(dDatabase), 4) +'-'+  StrZero( Month(dDatabase), 2) +'-'+ StrZero( Day(dDatabase), 2)",

    "DataReprocessamento": "20230515",

    "UltimodiaReprocessado": "20230515",   

    "DiasRetroceder": 10
}

Para mais informações referente à campos na API do FOOD acesse: API - FOOD CAPA VENDA.

TipoFormaPagamento = 3 é para identificar as formas de pagamento do tipo cartão.

Exemplo da configuração do Processo VENDA no assinante CHEF:




Vinculando o Processo VENDA ao Assinante PROTHEUS


1- No módulo 12 (Controle de Lojas), acesse Atualizações/ RMI/ Cadastros/ Assinantes.

2- Com o assinante PROTHEUS previamente cadastrado, posicione no assinante PROTHEUS e clique em alterar.

3- Na guia Assinantes x Processos, preencha os seguintes campos:

Processo: Venda

Ativo: Sim

Tipo Process: Envio

Filiais Proc: Informe o código das filiais que deseja realizar o Processo

Configuração: Vazio

Layout Envio: Vazio

Layout Publi: Vazio


Exemplo da configuração do Processo VENDA no assinante Protheus:



Após ter realizado as configurações acima a integração da VENDA seguirá o seguinte fluxo:

Serviço RMIBUSCA: Neste serviço o Protheus irá realizar a busca das vendas no sistema Totvs Chef, e grava-las na tabela MHQ - Mensagens Publicadas.  

Serviço RMIDISTRIB: Após as mensagens serem publicadas na tabela MHQ, o serviço RMIDISTRIB se encarregará de distribuir as vendas para seus assinantes, neste caso as mensagens serão distribuídas para o assinante Protheus, neste processo será gravado as distribuições na tabela MHR - Mensagens Distribuição  

Serviço RMIENVIA: Com as mensagens distribuídas para o assinante Protheus o serviço RMIENVIA é responsável por gerar a venda de cada mensagem distribuída. Neste momento é gravado as tabelas SL1, SL2 e SL4(Tabelas responsáveis pela venda) e caso a venda seja gerada com sucesso será gravado o numero da mesma no campo MHR_RETORN. Caso o seja encontrado algum erro no momento da geração da venda no Protheus, no campo MHR_ENVIO é gravado os dados que foram passados para gerar a venda e no campo MHR_RETORN é gravado o motivo da inconsistência na geração da venda.

Serviço RMICONTROL: Com as vendas geradas nas tabelas SL1, SL2 e SL4,  o campo L1_SITUA deve estar com o conteúdo IP (Integração Pendente), para que o serviço RMICONTROL realize as validações da venda. Caso seja encontrado alguma inconsistência na venda o campo L1_SITUA sera atualizado para IR (Integração com erro) e será gravado um log do motivo desta inconsistência na tabela MHL - Logs de Integração. Caso a venda seja validada com sucesso o campo L1_SITUA é atualizado para RX (Recebido pelo Server).

Serviço do GravaBacth:  Para as vendas que estejam campo L1_SITUA = RX, este serviço tem como objetivo: Gerar financeiro, Baixa de estoque, Livros fiscais etc. Caso seja encontrado alguma inconsistência no processamento deste serviço o campo L1_SITUA é atualizado para ER. Caso o processamento da venda seja finalizado com sucesso o campo L1_SITUA é atualizado para OK.

O Cancelamento de Venda seguirá o seguinte fluxo:

Serviço RMIBUSCA: Neste serviço é realizado a busca das vendas no Totvs Chef, o serviço identifica se a tag StatusVenda (Api Capa venda) é igual a 2, Caso seja significa que se trata de um cancelamento, com isso é gravado um registro na tabela MHQ - Mensagens Publicadas com o campo MHQ_EVENTO = 2 (Exclusão).

Serviço RMIDISTRIB: Após a Publicação do cancelamento o serviço RMIDISTRIB se encarregará de distribuir o cancelamento da venda  para o assinante Protheus, gerando um registro na tabela MHR - Mensagens Distribuição.

Serviço RMIENVIA: Realizado a distribuição, o serviço RMIENVIA inclui as informações do cancelamento da venda na tabela SLX - Log Cancelamento x Devolução.

Serviço RMICONTROL: Com as informações do cancelamento inseridos na tabela SLX - Log Cancelamento x Devolução este serviço realiza a leitura das informações e em seguida é executado a rotina padrão de cancelamento LOJA140, com isso realizando o cancelamento da venda no Protheus.


A Devolução não esta implementada nesta integração, caso tenha alguma devolução no sistema Totvs Chef, a devolução devera ser realizada manualmente no Protheus. Não existe integração de venda com NCC.

É possível monitorar a integração e processamento das vendas e cancelamento de vendas através do: Monitor de integração de Vendas.