# Clientes - Integracoes com Donc Documentacao das integracoes ativas com ERPs de cada cliente. Cada cliente tem regras, fluxos e comportamentos unicos no sistema Donc. ## Tabela Comparativa | Cliente | ContratoSaasId | Integracao | APP Code | ERP | Fechamento | Feature Unica | |---------|---------------|------------|----------|-----|------------|---------------| | Berlanda | 1028 | Task Scheduler (pull Oracle) | 10215 | Oracle | 03:00 diario | Triangulacao filiais, valores especiais | | Koerich | 1004 | API V2 | 1113 | - | Nenhum | Bypass status 1700, gatilho duplo | | Lojas MM Atacado | 1067 | Fila/API V2 + SSW | Nao usa APP | SSW | Via webhook SSW | Sem APP, SSW como parceiro, deploy dual | | Lojas MM Fisicas | 1074 | API V2 | 6857442 | - | 03:00 diario | Re-save por descricao, gatilho por estabelecimento | | Multiloja | 1053 | API V2 | 2928355 | - | 03:00 diario | Re-save por descricao, gatilho por estabelecimento | | Osirnet | 1060 | WebHub + API V2 | 4423021 | Voalle | Nenhum | Validacao cidade, provisioning ONU, finalizacao condicional | | Cybelar | 1073 | Servico IntegraCybelar (pull JWT) | 6699331 | Proprio (API REST) | Proporcional no APP | TpNota→TipoJob, FaixaCEP, multipla escolha cria nova OS | --- ## Berlanda (ContratoSaasId: 1028) - **Tipo integracao**: Task Scheduler -- Donc puxa dados do Oracle da Berlanda (Berlanda NAO envia) - **Admin**: adminberlanda.donc.com.br - **APP Code**: 10215 - **ERP**: Oracle (banco proprio da Berlanda) - **Intervalo pull Oracle**: a cada 15 minutos (servico rodando no servidor) - **Fechamento financeiro**: 03:00 diario (processo separado -- GerarGanhoProfissional + CobrancaGsrParaEstabelecimento) ### Fluxo de dados ``` Task Scheduler (servidor Donc) -> Query Oracle (v_entrega_montagem_crowds) -> ImportarLojaV2 (por loja, filtra CodigoFilial = CodigoManual) -> Checagem triangulacao (CodigoFilial != CodigoLoja?) -> Checagem duplicatas (mesmo CodigoPedido + EstabelecimentoId em Saidas?) -> Avaliacao status Oracle (99/90 = cancela, 12/14/15/20... = importa) -> Criacao OS (depende de JuntarOrdens) -> Auto-alocacao (1 parceiro ativo com skill = auto) -> APP profissional (10215) -> Triggers (StatusChangedAsync -> PostSchedule -> ERP) -> Fechamento 03:00 (GerarGanhoProfissional -> CobrancaGsrParaEstabelecimento) ``` ### Triangulacao de filiais - Se `CodigoFilial != CodigoLoja`, identifica a filial real de saida - **Filial 021 (Matriz)**: lookup dinamico -- busca loja por `CodigoLoja`, sobrescreve `estabelecimentoId`, `valorTaxa`, `juntarOs` ### Calculo de valores **Filiais especiais (227, 245, 255, 267)** -- metodo `AtualizarValoresFiliaisEspecificas` (sobrescreve apos import): - TipoJobId 42 (Entrega): `ValorPagarProfissional = ValorFreteOriginal` (direto do Oracle, sem divisao) - TipoJobId 43 (Montagem): `ValorPagarProfissional = SUM(ValorUnitario x ValorTaxa%)` para itens com `PossuiMontagem = true`; `ValorCobrarPeloServico = SUM(todos os produtos)` - TipoJobId 45 (Entrega+Montagem): `ValorPagarProfissional = ValorFreteOriginal + SUM(montagem)` - Vigencia: a partir de 23/07/2025 **Filiais diferenciadas (028, 28, 229, 103, 238)** -- `GetValorLojaDiferenciada()` durante import: - `ValorPagar = ValorFrete / 1.3` com calculo diferenciado - Lojas 028/28: se Frete = R$30, transforma para R$60; `ValorCobrar = SUM(produtos) + valor transformado` (NAO inclui frete no ValorCobrar) **Filiais padrao**: - `ValorPagar = ValorFrete / 1.3` (remove markup comercial de 30%) - Montagem: `SUM(ValorUnitario x QtdItens x ValorTaxa%)` - `ValorCobrar = SUM(produtos) + (ValorFrete / 1.3)` **Hierarquia de aplicacao**: 1) regras padrao/diferenciadas no import; 2) se filial especial (227/245/255/267), sobrescreve via `AtualizarValoresFiliaisEspecificas` ### Criacao de OS - **JuntarOrdens = true**: OS unica consolidada - TipoJobId 42 = Entrega (se frete > 0) - TipoJobId 45 = Entrega + Montagem - TipoJobId 43 = Montagem apenas - **JuntarOrdens = false**: OSs separadas por tipo (42 para entrega, 43 para montagem) - **Duracao**: `(quantidade montagem x 40) + 30 minutos` ### JsonValorSeparado - Campo JSON na tabela `Pedido` (banco Go4You) que discrimina valor por tipo de servico (Entrega e/ou Montagem) - NAO vem do Oracle -- calculado pelo C# (`BerlandaManager`) durante `InserirJobBerlanda` - Fluxo: Oracle (`COMMERCE.v_entrega_montagem_crowds`) -> C# -> Go4You (`Pedido.JsonValorSeparado`) - Campos Oracle: `VL_UNIT` -> `ValorUnitario`, `MONTAGEM_SN` -> `PossuiMontagem`, `VL_FRETE_PEDIDO` -> `ValorFrete` - `valorMontagem = VL_UNIT x QtdItens x (valorTaxa / 100)` -- apenas se `PossuiMontagem = true` - `valorEntrega = VL_FRETE_PEDIDO / 1.3` - Valor montagem zero quando: todos itens com `MONTAGEM_SN = 'N'`, ou `VL_UNIT = 0`, ou `valorTaxa = 0` ### Outros - **Auto-alocacao**: 1 parceiro ativo com skill correspondente = auto-atribuido; senao = manual via tela de Rotas - **Triggers**: `StatusChangedAsync` -> `PostSchedule` -> ERP Berlanda (a cada mudanca de status) - **Fechamento**: 03:00 diario, sem reprocessamento automatico - **WebHookService.cs**: handler dos triggers --- ## Koerich (ContratoSaasId: 1004) - **Tipo integracao**: API V2 - **Admin**: adminkoerich.donc.com.br - **APP Code**: 1113 - **Modelo**: 1 Parceiro : 1 Profissional ### Fluxo de dados ``` Sistema Koerich -> POST JobsNovo_SalvarValidandoCodigoDuplicado (auth: api_key) -> Checagem status 1700 (bypass?) -> Validacao duplicatas -> Criacao OS (com ou sem profissional) -> APP profissional (1113) -> Trigger 1: StatusChangedAsync -> PostSchedule -> ERP -> Trigger 2: Relato problema -> notificacao imediata ao ERP ``` ### Regras especiais - **Bypass Status 1700** (exclusivo Koerich): OS cancelada (status 1700) salva direto no banco sem nenhuma validacao de regras de negocio - **Dois gatilhos**: 1. Padrao: `StatusChangedAsync` -> `PostSchedule` -> ERP (a cada mudanca de status) 2. Exclusivo: relato de problema -> notificacao imediata ao ERP (independente de status) - **Sem fechamento financeiro**: Koerich nao usa o processo de fechamento - **Diagnostico**: JSON das requisicoes disponivel na tabela `ApiLog` (campo `Json`) - **Token**: Admin -> Setup -> Integracao -> Token (`adminkoerich.donc.com.br/Apps/Relatorios/Tokens.aspx`) - **Tela de Rotas**: Grid mode (seleciona Parceiro + Profissional independente) ou Edit mode (seleciona Parceiro, modelo 1:1 infere profissional) --- ## Lojas MM Atacado (ContratoSaasId: 1067) - **Tipo integracao**: Fila via API V2 + ERP SSW - **Admin**: adminlojasmm.donc.com.br - **NAO usa APP Donc** -- execucao em campo gerenciada pelo ERP SSW - **ERP**: SSW ### Fluxo de dados (3 partes independentes) **Parte 1 -- Criacao de OS:** ``` MM envia batch -> POST api/JobsNovo/SalvarProcessamentoFila -> ProcessaFilaIntegracao (a cada 10 min, ContratoSaasId 1067) -> Regra exclusiva: ERP SSW mapeado como parceiro (if especifico para contrato 1067) -> Nota fiscal salva em tabela NotaFiscal (exclusiva Lojas MM) -> IntegrarAutomaticoLojasMM (NAO usa PostSchedule) -> So envia quando StatusCalculadoId = 550 (Encaminhada) -> Validacoes: protocolo nao existe, NF presente, estabelecimento != 923, NomeEquipeVoalle preenchido -> SSW API: POST https://ssw.inf.br/api/generateToken -> POST https://ssw.inf.br/api/notfis -> Sucesso: protocolo retornado e salvo em tabela Protocoloes ``` **Parte 2 -- Atualizacao de status:** ``` AtualizaStatusSSWDonc (a cada 10 min) -> ConsultarRastreamentoAsync -> POST https://ssw.inf.br/api/trackingdest -> Atualiza status da OS no Donc ``` **Parte 3 -- Fechamento e fotos (SSW Webhook Controller):** ``` SSW ERP chama /cte -> metodo Baixa -> atualiza ValorFretePagarPeloServico, salva em NotaFiscal SSW ERP chama /ocorrencias -> anexa fotos de entrega a OS ``` ### Regras criticas - **Deploy DUAL obrigatorio**: qualquer alteracao em `SSWWebhookController` deve ser publicada em AMBOS: - `apiv2.donc.com.br` - `api.lojasmm.donc.com.br` - **Credenciais SSW**: armazenadas em `Parceiro.NomeEquipeVoalle` (formato: `domain;username;password`, separador `;`, exatamente 3 partes, sem espacos) - **Adicionar nova transportadora**: zero codigo -- basta preencher `NomeEquipeVoalle` no Admin - **Campo invalido/vazio**: falha silenciosa (nenhuma NF transmitida), erro logado - **Tabela NotaFiscal**: exclusiva Lojas MM - **Estabelecimento 923**: excluido (ambiente de teste) - **Header SSW**: `authorization` (minusculo obrigatorio) - **EF Core**: queries devem incluir `.Include(p => p.Saida.Parceiro)` para evitar NullReferenceException - **URL exclusiva**: `https://api.lojasmm.donc.com.br/api/internal/webhooks/ssw/cte` (separada para evitar reconfig no lado SSW) - **Arquivos alterados**: `SSWService.cs` e `SSWWebhookController.cs` - **Logs**: `F:\DoncLogs\LogsIntegracao\FilaIntegracao\1067` e `F:\DoncLogs\LogsIntegracao\Cliente\SSW\AutoLojasMM\` --- ## Lojas MM Fisicas (ContratoSaasId: 1074) - **Tipo integracao**: API V2 - **Admin**: adminlojasmm.donc.com.br (mesmo do Atacado) - **APP Code**: 6857442 - **Fechamento**: 03:00 diario ### Fluxo de dados ``` Sistema Lojas MM -> POST SalvarProcessamentoFila (auth: api_key) -> Checagem descricao (OS existe e descricao difere?) -> Se sim: reprocessa via SalvarJob -> Se nao: fluxo normal de criacao -> APP profissional (6857442) -> Trigger por estabelecimento (StatusChangedAsync -> PostSchedule -> ERP) -> Fechamento 03:00 (GerarGanhoProfissional -> CobrancaGsrParaEstabelecimento) ``` ### Regras especiais - **Re-save por descricao** (exclusivo ContratoSaasId 1074): se uma OS duplicada chega com descricao diferente (comparacao case-insensitive, ignora espacos), a OS existente e reprocessada inteiramente via `SalvarJob` - **Gatilho por estabelecimento** (nao global): se um estabelecimento para de receber notificacoes, verificar o gatilho especifico daquele estabelecimento em Admin -> Setup -> Integracao -> Gatilhos - **Fechamento 03:00**: janela unica diaria, sem reprocessamento automatico; OSs finalizadas apos 03:00 entram no ciclo do dia seguinte - **Pendencia**: campo "Ajudante no Servico" -- ainda nao implementado - **Diagnostico fechamento**: `adminlojasmm.donc.com.br/Apps/Relatorios/RelatorioJobsPorParceiro.aspx` --- ## Multiloja (ContratoSaasId: 1053) - **Tipo integracao**: API V2 - **Admin**: adminmultiloja.donc.com.br - **APP Code**: 2928355 - **Modelo**: 1:1 parceiro-profissional - **Fechamento**: 03:00 diario ### Fluxo de dados ``` Sistema Multiloja -> POST JobsNovo_SalvarValidandoCodigoDuplicado (auth: api_key) -> Checagem descricao (mesma logica de Lojas MM Fisicas) -> Criacao OS (modelo 1:1: seleciona Parceiro, infere Profissional) -> APP profissional (2928355) -> Trigger por estabelecimento -> Fechamento 03:00 ``` ### Regras especiais - **Re-save por descricao** (exclusivo ContratoSaasId 1053): logica identica a de Lojas MM Fisicas (1074) - **Gatilho por estabelecimento** (nao global) - **Fechamento 03:00**: mesmo comportamento de Lojas MM Fisicas - **Modelo 1:1**: parceiro-profissional (selecionar parceiro automaticamente define o profissional) - **Pendencia**: campo "Ajudante no Servico" -- ainda nao implementado - **Diagnostico fechamento**: `adminmultiloja.donc.com.br/Apps/Relatorios/RelatorioJobsPorParceiro.aspx` --- ## Osirnet (ContratoSaasId: 1060) - **Tipo integracao**: WebHub + API V2 - **Admin**: osirnetadmin.donc.com.br - **APP Code**: 4423021 - **ERP**: Voalle ### Fluxo de dados (duas vias de entrada) **Fluxo A -- Sem agendamento:** ``` Voalle gera evento OS -> POST /v1/WebHook -> OS criada sem profissional ``` **Fluxo B -- Com agendamento:** ``` Voalle gera evento OS -> ConsultarDisponibilidadePorTipo via API V2 (tipoServico: 890 fixo) -> ReservarAgendamento (salva em tabela ReservaAgendamento) -> POST /v1/WebHook (com data e profissional definidos) ``` **Apos entrada:** ``` Determinacao endereco (prioridade: 1) Api Contrato, 2) Etiqueta, 3) jsonPayload) -> Validacao cidade (BuscaEstabelecimentoCidade via ErpVoalleEstabelecimentosXRegiao) -> Cidade nao encontrada? OS NAO criada (verificar Admin -> Setup -> Cidade X Regiao) -> Cidade encontrada? OS criada -> APP profissional (4423021) -> Provisioning (Estoque/API Yellow -- registro ONU online) -> Checklist (obrigatorio para finalizacao) -> Finalizacao condicional ``` ### Validacao de cidade - Usa tabela `ErpVoalleEstabelecimentosXRegiao` - **Match exato de texto** -- sensivel a acentos e grafia - Cidade com typo ou acento diferente = OS NAO criada - Configuracao: `osirnetadmin.donc.com.br/Apps/Configuracoes/CidadeXRegiao/Grid.aspx` ### Provisioning (exclusivo Osirnet) - Estoque/Provisioning via API Yellow (registro ONU online) - Erros no provisioning: tecnico entra em contato com call center Osirnet ### Finalizacao condicional (exclusivo ContratoSaasId 1060) 1. Voalle envia `statusEncerramento = 4` 2. Donc verifica: OS ja finalizada? Se sim -> evento descartado 3. Se nao finalizada, verifica condicoes: - **Condicao A**: pelo menos 1 item de checklist preenchido OU arquivo anexado - **Condicao B**: historico mostra transicao 1500 -> 500 (reabertura) 4. Se nenhuma condicao atendida -> OS permanece aberta (evento registrado internamente) 5. Se condicao atendida -> OS finalizada no Donc, PDF gerado via `osir.webhub.donc.com.br` ### Pontos de atencao - **ReservaAgendamento**: chave e o NOME do cliente -- nomes duplicados causam conflito - **Relatorio de erros de alocacao**: `osirnetadmin.donc.com.br/Apps/Relatorios/RelatorioErroAlocacao.aspx` - **Logs**: `F:\DoncLogs\...\Osirnet\` - **Tabelas**: `ReservaAgendamento`, `ErpVoalleEstabelecimentosXRegiao`, `PostSchedule` --- ## Cybelar (ContratoSaasId: 1073) - **Tipo integracao**: Servico IntegraCybelar -- Donc puxa dados da API Cybelar (triggered por status "entregue" da Intelipost) - **Admin**: admincybelar.donc.com.br - **APP Code**: 6699331 - **ERP**: API REST propria da Cybelar - **API base**: `https://integracao.cybelar.com.br/montagem/` ### Autenticacao - **Metodo**: JWT via `POST /authentication/login` - **Credenciais**: username + password (configurados no servico) - **Expiracao**: 600 segundos (10 minutos) - **Restricao**: IP fixo do servidor Donc deve estar liberado na Cybelar ### Fluxo de dados ``` Intelipost marca pedido como "entregue" -> Servico IntegraCybelar (polling periodico) -> POST /authentication/login (JWT, 600s) -> GET /pedidos (lista pedidos pendentes) -> Para cada pedido: -> Classificacao TpNota -> TipoJobId -> Checagem duplicatas (3 camadas) -> Resolucao estabelecimento (FaixaCEP) -> Criacao OS (status 500, sem profissional) -> APP profissional (6699331) -> Checklist com multipla escolha -> Resposta especifica? -> Cria nova OS automaticamente -> Fechamento proporcional (calculado no APP) ``` ### Mapeamento TpNota → TipoJobId | TpNota | codMontagem | TipoJobId | Descricao | |--------|-------------|-----------|-----------| | 336 | - | 1646 | Montagem cliente | | 55 | - | 1680 | Montagem mostruario | | 335 | 1 | 1679 | Desmontagem | | 335 | 2 | - | Ignorado (nao importa) | | Outros | - | - | Ignorado | ### Checagem de duplicatas (3 camadas) 1. **IntegracaoJobs**: verifica se o codigo do pedido ja existe na tabela de integracao 2. **Pedidoes**: busca por codigo do pedido na tabela principal 3. **Nome + Endereco**: valida se ja existe OS com mesmo nome de cliente e endereco (previne reprocessamento) ### Resolucao de estabelecimento (FaixaCEP) Prioridade: 1. `CodigoManual == codFilial` do pedido -> match direto 2. CEP do endereco dentro de uma faixa cadastrada na tabela `FaixaCEP` 3. Estabelecimento padrao (fallback) ### Criacao de OS - **Status inicial**: 500 (Aguardando Profissional) - **Profissional**: NAO alocado na criacao (alocacao manual via tela de Rotas) - **DataInicio**: DataPedido + 3 dias - **DataLimite**: DataPedido + 6 dias - **Origem**: 2 (integracao) ### Atualizacao de OS - Somente OSs com `StatusCalculadoId = 500` sao atualizadas - OSs em qualquer outro status sao ignoradas pelo servico ### Checklist com multipla escolha (exclusivo Cybelar) - Determinadas respostas no checklist (multipla escolha) criam automaticamente uma **nova OS** - A nova OS e criada **sem profissional alocado** (status 500) - Isso NAO e um relato de problema -- e uma feature especifica de criacao de OS derivada - A nova OS herda dados da OS original (parceiro, estabelecimento) ### Fechamento proporcional - Valor de fechamento calculado proporcionalmente no APP (6699331) - Logica de calculo proporcional ao servico executado ### Referencias tecnicas - **Servico**: `Servico.Cybelar.Services.CybelarJobService` - **API Client**: `Servico.Cybelar.Endpoints.CybelarApiClient` - **Repository**: `Servico.Cybelar.Database.JobRepository` - **Logs**: `F:\DoncLogs\LogsIntegracao\Cliente\Cybelar\` - **Tabelas**: `IntegracaoJobs`, `FaixaCEP`, `PostSchedule`, `ProdutoComercial`