Árvore de páginas

Integrando VENDAS

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 CHEF;
  • 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).

Atualização na API do TOTVS FOOD - Novas Regras de Busca de Vendas

Com a mais recente atualização na API do TOTVS FOOD, foram implementadas novas regras na busca de vendas para aprimorar a eficiência e a confiabilidade do sistema.
Por favor, atente-se às seguintes diretrizes para o processo de venda no campo de Configuração :

  1. Intervalo de Tempo para Busca de Vendas:

    • As buscas de vendas devem ser realizadas em intervalos regulares de 30 minutos default, configurado na Tag: tempBuscaVenda.
    • Reprocessamentos de vendas com erro podem ocorrer entre 00:00 e 06:00, com a possibilidade de intervalos menores, configurados nas Tags: horaReproceInicio e horaReproceFinal.
  2. Busca de Vendas por Loja:

    • Cada busca de venda por loja deve respeitar um intervalo de 15 segundos antes de iniciar uma nova busca para outra loja.

Para obter informações detalhadas sobre essas atualizações e garantir a integração eficaz com a API, consulte a documentação fornecida pela equipe do TOTVS FOOD: API - Capa Venda

IMPORTANTE: Para que não ocorra bloqueios por consumo indevido, as chamadas na API devem ter intervalos mínimos de 30 minutos entre cada chamada e o período de d - 7 máximo. Caso seja recorrente o consumo da base histórica, poderá acarretar em consumo indevido e bloqueio do uso da API. Isto ocorrendo é necessário realizar a abertura de uma chamado para o time TOTVS FOOD.


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.

  • Por Data de Movimentaçã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']",
	"regraChef": true,
	"horaReproceInicio": "00:00",
	"horaReproceFinal": "05:55",
	"tempBuscaVenda": "00:30:00" 
}

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)",
    "Online": "1"
}


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])), '' )"
		}
	]
}

Observações

  • As tags L1_FILIAL, L2_FILIAL e L4_FILIAL são preenchidas pelo Protheus, então devem ficar com o conteúdo vazio.

Dica!

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

Caso a integração seja executada antes deste período será apresentada a mensagem:

    • 20/12/23 15:46:48  - [VENDA] Busca não será executada, intervalo de tempo mínimo(00:30:00) não 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

Reprocessamento de Venda

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
}

API - CAPA VENDA

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:



Fluxo de integração

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.

Cancelamento de venda.

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.

Desconto na venda

Os valores de desconto nos totalizadores da venda devem vir rateados nos itens.

"TotalizadorVenda": {
  "ValorTotalDescontoFiscal": 0.01,
  "ValorTotalDescontoSistema": 0.01,

"Produto": {
                "Codigo": 5,
                "Nome": "PRODUTO TESTE",
            },
            "Quantidade": 1,
            "ValorUnitario": 1,
            "ValorDesconto": 0.01,

Monitor de integração de vendas!

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



  • Sem rótulos