# Fluxo Funcional

<div class="pw" id="bkmrk-"><div class="ph"></div></div>Passo a passo de uma requisição, validações e tratamento de erros.

## Diagrama de sequência

<div class="pw" id="bkmrk-fullstore-isnapp-run"><figure id="bkmrk-fullstore-sequencia" style="margin: 1.25em 0;"><svg aria-label="Sequência completa de uma chamada getVendas" font-family="system-ui, Segoe UI, Roboto, sans-serif" role="img" style="max-width: 100%; height: auto; background: #fff; border: 1px solid #e2e8f0; border-radius: 10px;" viewbox="0 0 1080 390" xmlns="http://www.w3.org/2000/svg"> <defs> <marker id="bkmrk--1" markerheight="10" markerwidth="10" orient="auto" refx="9" refy="3"> <path d="M0,0 L10,3 L0,6 z" fill="#334155"></path> </marker> </defs> <rect fill="#e0f2fe" height="58" rx="10" stroke="#0284c7" stroke-width="1.5" width="140" x="26" y="44"></rect> <text fill="#0c4a6e" font-size="14" font-weight="700" x="46" y="78">FullStore</text> <rect fill="#f1f5f9" height="82" rx="10" stroke="#64748b" stroke-width="1.5" width="180" x="256" y="32"></rect> <text fill="#1e293b" font-size="14" font-weight="700" x="280" y="62">isnapp</text> <text fill="#475569" font-size="11" x="280" y="82">run() + validação</text> <rect fill="#dcfce7" height="58" rx="10" stroke="#16a34a" stroke-width="1.5" width="160" x="536" y="44"></rect> <text fill="#14532d" font-size="14" font-weight="700" x="562" y="78">MySQL OSK</text> <rect fill="#fef3c7" height="58" rx="10" stroke="#d97706" stroke-width="1.5" width="210" x="806" y="44"></rect> <text fill="#78350f" font-size="14" font-weight="700" x="830" y="78">SQL Server Linx/BI</text> <line marker-end="url(#arr-cap03-seq)" stroke="#334155" stroke-width="2.2" x1="166" x2="252" y1="73" y2="73"></line> <text fill="#475569" font-size="11" x="176" y="60">POST getVendas</text> <rect fill="#fff" height="58" rx="8" stroke="#64748b" stroke-width="1.3" width="180" x="256" y="150"></rect> <text fill="#334155" font-size="12" font-weight="700" x="274" y="174">Normaliza período</text> <text fill="#475569" font-size="11" x="274" y="192">verifica limite 200 dias</text> <line marker-end="url(#arr-cap03-seq)" stroke="#334155" stroke-width="2" x1="346" x2="346" y1="114" y2="146"></line> <rect fill="#fff" height="76" rx="8" stroke="#16a34a" stroke-width="1.3" width="160" x="536" y="142"></rect> <text fill="#14532d" font-size="12" font-weight="700" x="554" y="166">PDV / Trocas</text> <text fill="#166534" font-size="11" x="554" y="184">Omni + filiais</text> <text fill="#166534" font-size="11" x="554" y="202">consultas MySQL</text> <line marker-end="url(#arr-cap03-seq)" stroke="#334155" stroke-width="2" x1="436" x2="532" y1="180" y2="180"></line> <rect fill="#fff" height="76" rx="8" stroke="#d97706" stroke-width="1.3" width="210" x="806" y="142"></rect> <text fill="#78350f" font-size="12" font-weight="700" x="826" y="166">E-commerce</text> <text fill="#92400e" font-size="11" x="826" y="184">W\_BI\_FAT\_VENDEDOR...</text> <text fill="#92400e" font-size="11" x="826" y="202">placeholders por filial</text> <line marker-end="url(#arr-cap03-seq)" stroke="#334155" stroke-width="2" x1="696" x2="802" y1="180" y2="180"></line> <path d="M 806 218 C 720 268, 548 272, 436 218" fill="none" marker-end="url(#arr-cap03-seq)" stroke="#334155" stroke-width="2"></path> <text fill="#475569" font-size="11" x="562" y="276">mapeia vendas\_ecommerce</text> <rect fill="#ede9fe" height="58" rx="8" stroke="#7c3aed" stroke-width="1.3" width="180" x="256" y="290"></rect> <text fill="#4c1d95" font-size="12" font-weight="700" x="276" y="314">Monta JSON</text> <text fill="#5b21b6" font-size="11" x="276" y="332">vendas / trocas / omni</text> <line marker-end="url(#arr-cap03-seq)" stroke="#334155" stroke-width="2" x1="346" x2="346" y1="208" y2="286"></line> <path d="M 256 320 C 184 320, 128 206, 96 106" fill="none" marker-end="url(#arr-cap03-seq)" stroke="#334155" stroke-width="2"></path> <text fill="#64748b" font-size="12" x="34" y="372">Figura 3 - Sequencia completa de uma chamada a acao getVendas.</text> </svg></figure></div>## Diagrama de fluxo (decisões)

<div class="pw" id="bkmrk-post-getvendas-a%C3%A7%C3%A3o-"><figure id="bkmrk-fullstore-decisoes" style="margin: 1.25em 0;"><svg aria-label="Fluxo de decisão completo do endpoint" font-family="system-ui, Segoe UI, Roboto, sans-serif" role="img" style="max-width: 100%; height: auto; background: #fff; border: 1px solid #e2e8f0; border-radius: 10px;" viewbox="0 0 1080 440" xmlns="http://www.w3.org/2000/svg"> <defs> <marker id="bkmrk--2" markerheight="10" markerwidth="10" orient="auto" refx="9" refy="3"> <path d="M0,0 L10,3 L0,6 z" fill="#334155"></path> </marker> </defs> <rect fill="#e0f2fe" height="56" rx="10" stroke="#0284c7" stroke-width="1.5" width="180" x="42" y="28"></rect> <text fill="#0c4a6e" font-size="13" font-weight="700" x="66" y="62">POST getVendas</text> <polygon fill="#fef3c7" points="340,26 456,58 340,90 224,58" stroke="#d97706" stroke-width="1.5"></polygon> <text fill="#78350f" font-size="12" font-weight="700" x="284" y="62">ação válida?</text> <rect fill="#fee2e2" height="56" rx="10" stroke="#dc2626" stroke-width="1.5" width="180" x="548" y="28"></rect> <text fill="#7f1d1d" font-size="12" font-weight="700" x="572" y="53">success:false</text> <text fill="#991b1b" font-size="11" x="572" y="71">Acao nao encontrada</text> <polygon fill="#fef3c7" points="340,124 476,160 340,196 204,160" stroke="#d97706" stroke-width="1.5"></polygon> <text fill="#78350f" font-size="12" font-weight="700" x="262" y="156">parâmetros</text> <text fill="#78350f" font-size="12" font-weight="700" x="286" y="174">preenchidos?</text> <rect fill="#fee2e2" height="56" rx="10" stroke="#dc2626" stroke-width="1.5" width="230" x="548" y="132"></rect> <text fill="#7f1d1d" font-size="12" font-weight="700" x="572" y="157">success:false</text> <text fill="#991b1b" font-size="11" x="572" y="175">O parametro {campo} é obrigatorio</text> <polygon fill="#fef3c7" points="340,230 484,268 340,306 196,268" stroke="#d97706" stroke-width="1.5"></polygon> <text fill="#78350f" font-size="12" font-weight="700" x="268" y="264">dentro de</text> <text fill="#78350f" font-size="12" font-weight="700" x="266" y="282">200 dias?</text> <rect fill="#fee2e2" height="56" rx="10" stroke="#dc2626" stroke-width="1.5" width="270" x="548" y="240"></rect> <text fill="#7f1d1d" font-size="12" font-weight="700" x="572" y="265">success:false</text> <text fill="#991b1b" font-size="11" x="572" y="283">fallback interno não exposto</text> <rect fill="#dcfce7" height="56" rx="10" stroke="#16a34a" stroke-width="1.5" width="288" x="196" y="350"></rect> <text fill="#14532d" font-size="12" font-weight="700" x="220" y="375">consulta quatro canais</text> <text fill="#166534" font-size="11" x="220" y="393">se algum canal tem dados: success:true</text> <line stroke="#334155" stroke-width="2" x1="222" x2="220" y1="58" y2="58"></line> <line marker-end="url(#arr-cap03-dec)" stroke="#334155" stroke-width="2" x1="42" x2="220" y1="56" y2="58"></line> <line marker-end="url(#arr-cap03-dec)" stroke="#334155" stroke-width="2" x1="456" x2="544" y1="58" y2="58"></line> <text fill="#64748b" font-size="10" x="474" y="48">não</text> <line marker-end="url(#arr-cap03-dec)" stroke="#334155" stroke-width="2" x1="340" x2="340" y1="90" y2="120"></line> <text fill="#64748b" font-size="10" x="350" y="110">sim</text> <line marker-end="url(#arr-cap03-dec)" stroke="#334155" stroke-width="2" x1="476" x2="544" y1="160" y2="160"></line> <text fill="#64748b" font-size="10" x="494" y="150">não</text> <line marker-end="url(#arr-cap03-dec)" stroke="#334155" stroke-width="2" x1="340" x2="340" y1="196" y2="226"></line> <text fill="#64748b" font-size="10" x="350" y="216">sim</text> <line marker-end="url(#arr-cap03-dec)" stroke="#334155" stroke-width="2" x1="484" x2="544" y1="268" y2="268"></line> <text fill="#64748b" font-size="10" x="500" y="258">não</text> <line marker-end="url(#arr-cap03-dec)" stroke="#334155" stroke-width="2" x1="340" x2="340" y1="306" y2="346"></line> <text fill="#64748b" font-size="10" x="350" y="330">sim</text> <text fill="#64748b" font-size="12" x="42" y="426">Figura 4 - Fluxo de decisão completo do endpoint.</text> </svg></figure></div>## Passo a passo detalhado

<div class="pw" id="bkmrk-recebimento-da-requi">1. **Recebimento da requisição**  
    Recebemos o payload via `run(array $params)`. O parâmetro `acao` deve ser `'getVendas'`; qualquer outro valor resulta em erro imediato.
2. **Validação de parâmetros**  
    Validamos via `validarParametrosObrigatorios()`: `dataInicio`, `dataFim` e `cnpjLoja` — presença e valor não vazio. Se algum faltar, lançamos uma exception com o nome do campo faltante.
3. **Normalização do período**  
    Via `normalizarPeriodo()`, adicionamos horários às datas: início fica `dataInicio 00:00:00` e fim `dataFim 23:59:59`, garantindo cobertura integral dos dias extremos.
4. **Verificação do limite**  
    Via `periodoExcedeLimite()`, checamos se alguma das datas está além de 200 dias no passado. Se sim, `getVendasConsolidadas()` monta arrays vazios e um objeto `fallback`, mas `run()` ainda trata o resultado como nenhum registro encontrado e retorna erro ao consumidor.
5. **Vendas PDV**  
    Executamos query com 2 CTEs nas tabelas `movimentacao + movimentacao_detalhe + movimentacao_nfe`. Retornamos uma linha por item e depois agrupamos por `identificador` via `agruparItensDasVendas()`, gerando o sub-array `itens`.
6. **Trocas**  
    Buscamos movimentações de entrada com `tipo_estoque = 'TROCA'`, vinculando à venda original via `movimentacao_movimentacao`. Consolidamos múltiplas trocas do mesmo documento somando valores em `agruparTrocasPorDocumento()`.
7. **Omni**  
    Buscamos pedidos omni criados pelo vendedor na loja (orçamentos com `tipo_estoque = 'ORCAMENTO'` e situação Confirmado/Finalizado), vinculados à venda real via `movimentacao_movimentacao`.
8. **E-commerce**  
    Em dois sub-passos: (1) resolvemos os códigos de filial ativas via MySQL/CNPJ; (2) consultamos a view SQL Server com placeholders paramétricos dinâmicos para cada filial.
9. **Resposta**  
    Montamos o objeto `data` com os quatro arrays e retornamos via `setSubmit(true, 'Vendas retornadas com sucesso!', $data)`.

</div>## Tratamento de erros

<div class="pw" id="bkmrk-situa%C3%A7%C3%A3o-comportamen"><div class="tw"><table><thead><tr><th>Situação</th><th>Comportamento</th><th>success</th></tr></thead><tbody><tr><td>Parâmetro obrigatório ausente</td><td>Mensagem com nome do campo faltante</td><td><span class="badge br">false</span></td></tr><tr><td>Ação inválida (≠ getVendas)</td><td>Mensagem de ação não encontrada</td><td><span class="badge br">false</span></td></tr><tr><td>Período além de 200 dias</td><td>Fallback interno é montado, mas a resposta final atual é erro de nenhum registro</td><td><span class="badge br">false</span></td></tr><tr><td>CNPJ sem filiais ativas no MySQL</td><td>`vendas_ecommerce` vazio; se os demais canais também estiverem vazios, retorna erro de nenhum registro</td><td><span class="badge bo">Depende</span></td></tr><tr><td>Falha no SQL Server</td><td>Exception capturada → retorno `false`</td><td><span class="badge br">false</span></td></tr><tr><td>Parâmetro `falha` enviado</td><td>Força erro (uso em testes)</td><td><span class="badge br">false</span></td></tr></tbody></table>

</div><div class="ib">**Logs automáticos de requisição** Toda chamada — mesmo as que resultam em erro — é salva automaticamente nas tabelas `wosk_webservice*` do banco integrador. Em caso de disputa ou diagnóstico, basta consultar `wosk_webservice_retorno` pelo timestamp.</div>  
</div>