| name | operando-ssw |
| description | Operacoes de ESCRITA no SSW via Playwright. Usar quando o usuario pede: "cadastre unidade CGR", "importar cidades da rota", "cadastrar CNPJ como fornecedor", "registrar transportadora", "criar comissao 408", "cotar frete na 002", "simular frete SSW", "cotacao SSW", "gerar CSV 408 por cidade", "importar precos por cidade", "importar comissao por cidade no SSW", "importar CSV 408", "exportar cidades todas UFs", "CSV 402 completo", "exportar comissao cidade todas unidades", "baixar CSV 408", "merge CSVs", "consolidar CSVs exportados", "POP-A10", "nova rota completa", "vincular unidade a transportadora", "emitir CT-e", "emitir CTE", "gerar CT-e fracionado", "enviar SEFAZ", "consultar CTRC", "consultar CT-e", "status do CT-e", "baixar DACTE", "baixar XML CT-e", "cancelar CT-e", "gerar fatura SSW", "faturar CTRC", "fatura 437", "opcao 437", "emitir CT-e com medidas moto", "emitir CT-e com dimensoes", "cubagem moto", "emitir CT-e complementar", "CTE complementar", "opcao 222", "complementar valor frete", "complementar ICMS", "ajustar CTe", "complementar CTRC", "grossing up complementar". Requer --dry-run obrigatorio na primeira execucao e confirmacao do usuario antes da execucao real (exceto consultar_ctrc_101.py que e read-only). NAO USAR QUANDO: - Consultar/navegar SSW sem alterar, usar acessando-ssw - Cotacao de frete INTERNA Nacom, usar cotando-frete - Navegar SSW sem operacao especifica, usar browser tools |
| allowed-tools | Read, Bash, Glob, Grep |
operando-ssw
Executa operacoes de ESCRITA no SSW via scripts Playwright standalone.
Separada de acessando-ssw (apenas consulta/documentacao).
REGRAS CRITICAS
--dry-run e OBRIGATORIO na primeira execucao — preview sem submeter
- Screenshot capturado antes de qualquer submit — evidencia do formulario
- Agente DEVE usar AskUserQuestion para confirmar antes de executar sem --dry-run
- Ordem obrigatoria para nova rota: 401 → 402 → 478 → 485 → 408
- NUNCA inventar campos nao fornecidos — usar defaults do
ssw_defaults.json
- NUNCA executar sem --dry-run na PRIMEIRA chamada, mesmo que o usuario peca
ANTI-ALUCINACAO
- Campos nao fornecidos: Campos que o usuario nao informou DEVEM vir do
ssw_defaults.json (CNPJ CarVia, IE, banco, endereco fiscal). NAO inventar valores.
- Cotacao 002 — CEP origem: Se
coletar=N, CEP origem e AUTOMATICAMENTE o CEP CarVia (06530581). NAO perguntar ao usuario. Se coletar=S, PERGUNTAR o CEP de coleta.
- Tipo de unidade: T=Terceiro, F=Filial, M=Matriz. Se usuario diz "parceiro" ou "terceiro", usar T. NAO assumir F.
- 402 cidades: Para alterar >3 cidades, SEMPRE recomendar workflow CSV (exportar → modificar → importar). cadastrar_cidades_402.py so funciona com 1-3 cidades no viewport (virtual scroll).
- 478 inclusao=S: Fornecedor com
inclusao=S nao esta finalizado. 408 REJEITA esse CNPJ. Verificar sucesso da 478 antes de prosseguir.
- 485 multiplas filiais: Se CNPJ tem N filiais no SSW, PES retorna lista (nao form). Script da timeout. Informar ao usuario.
- Resultados do script: Apresentar EXATAMENTE o que o JSON de saida retorna. NAO inferir campos que nao existem no output.
- CT-e filial DEVE ser CAR: Emissao (004) e consulta (101) DEVEM usar filial CAR. NAO usar MTZ. Script troca automaticamente, mas agente deve confirmar.
- Fatura 437 filial DEVE ser MTZ: Faturamento (437) DEVE usar filial MTZ. NAO usar CAR. Script troca automaticamente.
- Medidas moto em METROS:
--medidas aceita dimensoes em metros. Se os dados vierem de carvia_modelos_moto (CM), dividir por 100 ANTES de passar ao script. O SswEmissaoService faz isso automaticamente.
- CT-e chave NF-e = 44 digitos exatos: Se usuario fornecer chave com menos ou mais digitos, REJEITAR. NAO completar com zeros. NAO remover digitos.
- Consulta 101 e READ-ONLY:
consultar_ctrc_101.py NAO altera dados. NAO pedir confirmacao nem --dry-run. Executar diretamente.
- CT-e Complementar filial: Script 222 detecta filial do CTe pai automaticamente do formato CTRC
FILIAL-NUMERO-DV. NAO passar filial manualmente.
- CT-e Complementar valor:
--valor-outros OU --valor-base — um obrigatorio, mutuamente exclusivos. --valor-base aciona grossing up automatico via consulta 101 do pai (extrai ICMS real e aplica valor_base / 0.9075 / (1 - icms/100)).
- CT-e Complementar unid_emit: Pode vir readonly no SSW — SSW decide filial do complementar baseado na carga. Script respeita e loga
unid_emit_readonly: true. NAO tentar forcar.
- CT-e Complementar CTRC formato:
[id="2"] espera numero+dv SEM hifen. Ex: CTRC CAR-113-9 → [id="2"]="1139". Script faz essa conversao automaticamente.
TRATAMENTO DE ERROS
| Erro | Causa | Acao |
|---|
TargetClosedError na 408 | Popup fechou = SUCESSO | Reportar sucesso, nao erro |
| Timeout na 485 | CNPJ com multiplas filiais | Informar usuario, tentar com CNPJ mais especifico |
| "Sigla ja existe" na 401 | Unidade ja cadastrada | Verificar se e a mesma, nao criar duplicata |
| CSV 402 vazio | UF sem cidades cadastradas | Normal para UFs novas, prosseguir |
| "Nao inclusas" no import CSV | Valores IDENTICOS ao existente | NAO e erro — SSW reporta 3 contadores: Incluidas/Alteradas/Nao inclusas |
| Placa nao encontrada na 004 | Placa invalida ou nao cadastrada | Usar ARMAZEM para fracionado, placa real para carga direta |
| "Chave nao localizada" na 004 | Chave NF-e errada ou NF nao importada | Verificar 44 digitos, confirmar com usuario |
| Timeout na consulta 101 | CTRC nao existe ou filial errada | Confirmar numero CTRC e filial CAR |
| SEFAZ rejeicao na 007 | Dados inconsistentes no CT-e | Cancelar pre-CTRC e reemitir com dados corretos |
| "Cliente nao encontrado" na 437 | CNPJ tomador nao cadastrado no SSW | Verificar CNPJ com usuario (14 digitos sem formatacao) |
| Grid vazio na 437 (APO) | CTe nao disponivel para faturamento | Verificar se CTe foi autorizado no SEFAZ antes de faturar |
| Fatura nao gerada (nro_fatura vazio) | Erro ao apontar documento na 437 | Verificar CTe selecionado no grid, tentar novamente |
| "Nao conseguiu consultar ICMS do CTe pai" no 222 | Consulta 101 do pai retornou erro | Passar --valor-outros manual (valor final pos-grossing up) |
| "Aliquota ICMS invalida" no 222 | Frete ou ICMS do pai zerado na 101 | Verificar CTe pai manualmente na 101, usar --valor-outros |
| Loop "Continuar" no 222 | Multiplos avisos CFOP/ICMS/GNRE | Normal — script clica todos via loop MAX=5x |
errorpanel bloqueia click em ► no 004 | Overlay invisivel sem pointer-events: none | Script ja usa _clicar_simular() com fallback JS (native → lnk_env → onclick_calculafrete) |
| Match "Gravar" nao encontra no 004 | SSW renderiza como "1. Gravar", "1.Gravar", "Gravar" | Script usa re.compile(r"Gravar", re.IGNORECASE) — se falhar, usa fallback JS concluindo('C') |
Decision Tree
Cadastrar unidade parceira (tipo T)?
→ cadastrar_unidade_401.py --sigla X --tipo T --razao-social "..." --dry-run
Exportar cidades atendidas (402, TODAS as 27 UFs de uma vez)?
→ exportar_todas_cidades_402.py [--ufs AC,BA] [--output-dir /tmp/402_export_all/] --dry-run
→ Depois: agrupar_csvs.py --input-dir /tmp/402_export_all/ --output /tmp/402_todas_cidades.csv --pattern "*_402_export.csv"
Alterar/importar cidades na 402 (qualquer quantidade)?
→ PREFERIR CSV: exportar_cidades_402.py --uf XX → modificar → importar_cidades_402.py --csv /tmp/cidades.csv --dry-run [--timeout 30]
Cadastrar 1-3 cidades VISIVEIS na grid 402?
→ cadastrar_cidades_402.py --uf XX --unidade XXX --cidades '[...]' --dry-run
(LIMITACAO: so funciona com cidades no viewport da virtual scroll)
Cadastrar/ativar fornecedor (478)?
→ cadastrar_fornecedor_478.py --cnpj X --nome "..." --especialidade TRANSPORTADORA --dry-run
Cadastrar transportadora (485)?
→ cadastrar_transportadora_485.py --cnpj X --nome "..." --dry-run
Criar comissao de unidade (408, geral)?
→ criar_comissao_408.py --unidade XXX --cnpj X --dry-run
Gerar CSVs comissao por cidade (408, em lote)?
→ gerar_csv_comissao_408.py --excel /tmp/backup_vinculos.xlsx [--unidades BVH,CGR] --dry-run
Exportar CSVs comissao por cidade do SSW (408, todas as unidades)?
→ exportar_comissao_cidade_408.py [--unidades MAO,CGR] [--output-dir /tmp/408_export/] --dry-run
→ Depois: agrupar_csvs.py --input-dir /tmp/408_export/ --output /tmp/408_todas_comissoes.csv --pattern "*_408_export.csv"
Importar CSVs comissao por cidade no SSW (408)?
→ importar_comissao_cidade_408.py --csv-dir /tmp/ssw_408_csvs/ [--unidades BVH,CGR] --dry-run
Cotar frete no SSW (002)?
→ Perguntar: CNPJ pagador, CEP destino, peso, valor, coletar(S/N), entregar(S/N)
→ Se coletar=N: script auto-resolve CEP origem = CEP CarVia (06530581)
→ Se coletar=S: perguntar CEP origem (local de coleta)
→ cotar_frete_ssw_002.py --cnpj-pagador X --cep-destino X --peso X --valor X [--coletar N] [--entregar S] --dry-run
→ Exibir parametros_assumidos antes de confirmar
Emitir CT-e fracionado (004)?
→ Perguntar: chave NF-e (44 digitos), frete peso (R$), placa (ARMAZEM=fracionado)
→ Com motos? Perguntar: medidas por modelo [{comp_m, larg_m, alt_m, qtd}]
→ Dimensoes de carvia_modelos_moto em CM — dividir por 100 para metros
→ emitir_cte_004.py --chave-nfe "..." --frete-peso 600 --placa ARMAZEM [--medidas '[...]'] --dry-run
→ OPERACAO FISCAL — apos confirmar: --enviar-sefaz --consultar-101 [--baixar-dacte] [--baixar-xml]
→ Detalhes: [SCRIPTS.md](SCRIPTS.md) | POP-C01 (fracionado) / POP-C02 (carga direta)
Gerar fatura SSW (437)?
→ Perguntar: CNPJ tomador (14 digitos), numero CTRC, data vencimento (DDMMYY)
→ gerar_fatura_ssw_437.py --cnpj-tomador "..." --ctrc 94 --data-vencimento "150426" --dry-run
→ IMPORTANTE: filial DEVE ser MTZ (nao CAR). Script troca automaticamente.
→ Apos confirmar: --baixar-pdf
→ Detalhes: [SCRIPTS.md](SCRIPTS.md)
Emitir CT-e + fatura completo (via API)?
→ Endpoint: POST /carvia/api/nfs/<nf_id>/emitir-cte-ssw (assincrono via RQ)
→ Body: {placa, cnpj_tomador, frete_valor, data_vencimento, medidas}
→ Polling: GET /carvia/api/emissao-cte/<id>/status (a cada 5s)
→ Executa: 004 (emitir) → 007 (SEFAZ) → 101 (consultar+XML) → 437 (fatura) → importar
→ Lote: POST /carvia/api/emitir-cte-ssw/lote (max 20 NFs)
Consultar CTRC / CT-e (101)?
→ consultar_ctrc_101.py --ctrc 94 [--baixar-xml] [--baixar-dacte]
→ OU: consultar_ctrc_101.py --nf 35714 [--baixar-xml] [--baixar-dacte]
→ READ-ONLY: executar diretamente, sem --dry-run nem confirmacao
→ Detalhes: [SCRIPTS.md](SCRIPTS.md)
Emitir CT-e complementar (222)?
→ Perguntar: CTRC pai (formato FILIAL-NUM-DV, ex: CAR-113-9), motivo (C/D/V/E/R), valor (bruto ou final)
→ Com valor bruto (auto-calc via ICMS do pai):
emitir_cte_complementar_222.py --ctrc-pai CAR-113-9 --motivo D --valor-base 200.00 --dry-run
(script consulta 101 do pai → extrai ICMS → grossing up `valor_base / 0.9075 / (1 - icms/100)`)
→ Com valor final ja calculado:
emitir_cte_complementar_222.py --ctrc-pai CAR-113-9 --motivo D --valor-outros 227.90 --dry-run
→ OPERACAO FISCAL — apos confirmar: --enviar-sefaz (+ baixa auto XML/DACTE via 101)
→ GOTCHA: CTRC [id="2"] sem hifen (CAR-113-9 → "1139"). unid_emit pode vir readonly (SSW decide filial).
→ Detalhes: [SCRIPTS.md](SCRIPTS.md) | POP-C03 (emitir CT-e complementar)
Cancelar CT-e autorizado (004)?
→ cancelar_cte_004.py --ctrc 66 --serie "CAR 68-0" --motivo "NF vinculada incorretamente" --dry-run
→ OPERACAO FISCAL IRREVERSIVEL — prazo 7 dias SEFAZ
→ Verificar antes: manifesto cancelado, mercadoria nao embarcada
→ Detalhes: [SCRIPTS.md](SCRIPTS.md) | POP-C06: pops/POP-C06-cancelar-cte.md
Consultar/navegar SSW (sem alterar)?
→ NAO usar esta skill. Usar acessando-ssw
Arquitetura
Agente Web
1. Le ssw_defaults.json (campos padronizados CarVia)
2. AskUserQuestion (campos variaveis: sigla, UF, razao social)
3. Monta parametros completos (defaults + respostas)
4. Executa script --dry-run → preview
5. AskUserQuestion ("Confirmar execucao?")
6. Executa script sem --dry-run → submete de verdade
Scripts sao standalone (Playwright headless), NAO dependem do Flask app.
Padrao interno: FIELD_MAP → FIELD_LIMITS → VALID_OPTIONS → validar_campos() → montar_campos() → loop FIELD_MAP → gerar_saida().
Scripts
| # | Script | Opcao | Proposito |
|---|
| 0 | ssw_common.py | — | Funcoes Playwright compartilhadas (login, popup, campos) |
| 1 | cadastrar_unidade_401.py | 401 | Cadastrar unidade operacional (31 campos) |
| 2 | cadastrar_cidades_402.py | 402 | Cadastrar 1-3 cidades visiveis na grid (ATU limitado) |
| 3 | exportar_cidades_402.py | 402 | Exportar CSV de cidades atendidas (passo 1 workflow CSV) |
| 4 | importar_cidades_402.py | 402 | Importar cidades via CSV (PREFERIDO para bulk) |
| 5 | cadastrar_fornecedor_478.py | 478 | Cadastrar fornecedor (12 campos, prerequisito 485/408) |
| 6 | cadastrar_transportadora_485.py | 485 | Cadastrar transportadora (3 campos) |
| 7 | criar_comissao_408.py | 408 | Criar comissao unidade↔transportadora (5 campos, geral) |
| 8 | gerar_csv_comissao_408.py | 408 | Gerar CSVs comissao por cidade (238 cols, lote) |
| 9 | importar_comissao_cidade_408.py | 408 | Importar CSVs de comissao por cidade no SSW |
| 10 | cotar_frete_ssw_002.py | 002 | Cotar frete no SSW (simular proposta) |
| 11 | exportar_todas_cidades_402.py | 402 | Exportar CSV de cidades para TODAS as 27 UFs (batch) |
| 12 | agrupar_csvs.py | — | Merge generico de CSVs (reutilizavel 402 e 408) |
| 13 | exportar_comissao_cidade_408.py | 408 | Exportar CSV comissao por cidade para todas as unidades |
| 14 | cancelar_cte_004.py | 004 | Cancelar CT-e autorizado (SEFAZ, irreversivel, POP-C06) |
| 15 | emitir_cte_004.py | 004 | Emitir CT-e completo (004 → 007 → 101) |
| 16 | consultar_ctrc_101.py | 101 | Consultar CTRC/CT-e + baixar DACTE/XML (read-only) |
| 17 | gerar_fatura_ssw_437.py | 437 | Gerar fatura SSW (filial MTZ) + download PDF |
| 18 | emitir_cte_complementar_222.py | 222 | Emitir CT-e complementar (222 → 007 → 101) com auto-calc ICMS via 101 do pai |
References (carregar sob demanda)
| Quando o agente precisa de... | Ler |
|---|
| Cadastrar unidade/cidade/fornecedor/transportadora (401, 402, 478, 485) | CADASTROS.md |
| Criar comissao, gerar/importar CSV 408 | COMISSOES.md |
| Cotar frete na 002 (params, workflow, gotchas) | COTACAO.md |
| Funcoes ssw_common, defaults, batch, mapeamento | SSW_COMMON.md |
| Emitir, consultar, cancelar CT-e ou gerar fatura (params, retornos) | SCRIPTS.md |
| CT-e gotchas, FIELD_MAP, dimensoes moto, workflow completo | CTE.md |
| Cadastrar unidade passo-a-passo | POP-A02-cadastrar-unidade-parceira.md |
| Cadastrar cidades passo-a-passo | POP-A03-cadastrar-cidades.md |
| Implantar rota completa | POP-A10-implantar-nova-rota.md |
Fluxo Completo: Nova Rota (POP-A10)
- 401 — Cadastrar unidade parceira
- 402 — Cadastrar cidades atendidas
- 403 — Cadastrar rota CAR → [SIGLA] (manual / futuro)
- 478 — Cadastrar fornecedor
- 485 — Cadastrar transportadora
- 408 — Cadastrar comissao de unidade
- 420 — Cadastrar tabelas de preco (futuro)
- 002 — Verificar cotacao (
cotar_frete_ssw_002.py)