S-2210 CAT: comunicação de acidente de trabalho no eSocial
Como o Odoo registra e transmite o evento S-2210 (Comunicação de Acidente de Trabalho) ao eSocial, com integração SST e prazos legais do art. 22 da Lei 8.213.
Luis Felipe Miléo
S-2210 é a Comunicação de Acidente de Trabalho (CAT) no eSocial — a versão eletrônica do formulário de papel que sempre acompanhou a Lei 8.213/91. É um evento de SST (Saúde e Segurança do Trabalho) que precisa ser enviado mesmo quando o acidente não causa afastamento, e mesmo quando o acidentado é um terceirizado ou cooperado dentro do estabelecimento.
A folha CLT da KMEE (PR #277) inclui modelagem de eventos de SST e geração de XML do S-2210. Este post explica o que o Odoo precisa registrar e como transmite.
Quando enviar
Pela Lei 8.213, art. 22, o prazo é:
- Até o primeiro dia útil seguinte ao acidente — para casos comuns
- De imediato — em caso de óbito
Atrasar gera multa que varia entre o piso e o teto do salário-de-contribuição. O eSocial herdou esse prazo e o S-2210 é o canal exclusivo desde a obrigatoriedade.
Tipos de CAT
O leiaute distingue três tipos no campo tpCat:
- 1 — Inicial: o acidente em si
- 2 — Reabertura: quando o acidente já comunicado tem agravamento ou nova consequência
- 3 — Comunicação de óbito: quando a vítima vem a falecer em consequência do acidente
A reabertura referencia a CAT inicial pelo número do recibo, e o eSocial valida se a CAT original existe.
Estrutura do evento
evtCAT
├── ideEvento (tpAmb, procEmi, verProc)
├── ideEmpregador (tpInsc, nrInsc)
├── ideVinculo (cpfTrab, matricula, codCateg)
├── cat
│ ├── dtAcid (data do acidente)
│ ├── tpAcid (codigo CID)
│ ├── hrAcid (hora HHMM)
│ ├── hrsTrabAntesAcid
│ ├── tpCat (1, 2 ou 3)
│ ├── indCatObito
│ ├── dtObito
│ ├── indComunPolicia
│ ├── codSitGeradora (codigo da tabela 15)
│ ├── iniciatCAT (1=empregador, 2=ordem judicial, 3=outros)
│ ├── obsCAT
│ ├── localAcidente (tpLocal, dscLocal, codAmbExt, ...)
│ ├── parteAtingida (codParteAting, lateralidade)
│ ├── agenteCausador (codAgntCausador)
│ ├── atestado
│ │ ├── codCNES, emitente
│ │ ├── dtAtendimento, hrAtendimento
│ │ ├── indInternacao
│ │ ├── durTrat (dias)
│ │ ├── indAfast
│ │ ├── dscLesao (codigo)
│ │ ├── dscCompLesao
│ │ ├── diagProvavel
│ │ └── codCID
│ └── catOrigem (numCatOrig, dtCatOrig — apenas em reabertura)
São muitos códigos tabelados (parte do corpo, agente causador, situação geradora) que mudam entre versões do leiaute. A esociallib mantém esses enums atualizados conforme a tabela vigente do governo.
Mapping no Odoo
Acidente de trabalho não é folha — é SST. A KMEE cria um modelo dedicado:
class HrMedicalEvent(models.Model):
_name = "hr.medical.event"
_description = "Evento Medico/SST"
employee_id = fields.Many2one("hr.employee", required=True)
contract_id = fields.Many2one("hr.contract")
event_type = fields.Selection([
("cat", "CAT - Acidente de Trabalho"),
("aso", "ASO - Atestado Saude Ocupacional"),
("afast", "Afastamento"),
])
dt_acidente = fields.Datetime()
cid_id = fields.Many2one("hr.cid") # tabela CID-10
tp_cat = fields.Selection([("1", "Inicial"), ("2", "Reabertura"), ("3", "Obito")])
cod_sit_geradora = fields.Many2one("esocial.tabela.15")
parte_atingida_id = fields.Many2one("esocial.tabela.13")
agente_causador_id = fields.Many2one("esocial.tabela.14")
obito = fields.Boolean()
dt_obito = fields.Date()
comun_policia = fields.Boolean()
cat_origem_id = fields.Many2one("hr.medical.event") # so em reabertura
atestado_ids = fields.One2many("hr.medical.attestation", "event_id")
E o atestado médico é submodelo:
class HrMedicalAttestation(models.Model):
_name = "hr.medical.attestation"
cnes = fields.Char()
emitente_nome = fields.Char()
emitente_orgao_classe = fields.Selection([("1", "CRM"), ("2", "CRO"), ("3", "RMS")])
emitente_uf = fields.Many2one("res.country.state")
dt_atendimento = fields.Datetime()
internacao = fields.Boolean()
afastamento = fields.Boolean()
dur_tratamento = fields.Integer()
cid_id = fields.Many2one("hr.cid")
diag_provavel = fields.Char()
lesao_id = fields.Many2one("esocial.tabela.16")
A separação entre evento e atestado existe porque um único acidente pode gerar múltiplos atestados ao longo do tempo (atendimento inicial + retornos).
Geração do XML
from esociallib.s_2210 import EvtCAT
def gerar_s2210(self):
if self.event_type != "cat":
raise UserError("S-2210 so para evento tipo CAT")
evt = EvtCAT(
ide_evento={"tpAmb": self.company_id.tp_amb},
ide_empregador={"tpInsc": "1", "nrInsc": self.company_id.cnpj_cpf[:8]},
ide_vinculo={
"cpfTrab": self.employee_id.cpf,
"matricula": self.contract_id.matricula_esocial,
"codCateg": self.contract_id.cod_categ,
},
cat=self._build_cat_data(),
)
return sign_event(evt.to_xml(), self.company_id.certificate_id)
O _build_cat_data resolve as tabelas eSocial (parte atingida, agente causador, situação geradora) a partir dos Many2one do registro. Validação XSD acontece antes da assinatura.
Integração com afastamento (S-2230)
Quando o atestado indica afastamento, o S-2210 pode ser seguido de um S-2230 (Afastamento Temporário). O Odoo automatiza isso: ao confirmar uma CAT com afastamento=True e dur_tratamento > 15, o sistema sugere criar o S-2230 correspondente, com codMotAfast=01 (acidente do trabalho típico) e a data de início do afastamento alinhada com o atestado.
Os primeiros 15 dias são pagos pela empresa (auxílio-doença acidentário começa no 16º). A folha precisa tratar isso com rubrica específica que tem incidência de FGTS mesmo durante afastamento — particularidade do acidentário que difere do auxílio-doença comum.
Status no PR #277
S-2210 está modelado e com geração de XML implementada no PR #277, mas a transmissão automatizada e o fluxo completo de SST (incluindo S-2220 ASO e S-2240 Riscos Ambientais) ainda estão em desenvolvimento. O órgão público federal cliente da KMEE roda CAT em Odoo 8.0 hoje; a paridade total no Odoo 16 é prioridade do roadmap pós-merge.
O que pode dar errado
- CID inválido ou genérico — Receita rejeita códigos não-específicos como “outras causas”.
- CAT de reabertura sem
numCatOrig— campo condicional obrigatório. hrAcidem formato errado — eSocial exige HHMM (4 dígitos), não HH:MM.- Acidente sem comunicação à polícia em caso de fatalidade — quando aplicável,
indComunPoliciaprecisa ser true. - Atestado sem CNES quando emitido em estabelecimento de saúde — campo opcional vira obrigatório nesse contexto.
Conclusão
S-2210 conecta SST e folha no eSocial. O Odoo separa o evento médico do contrato, mantém histórico clínico independente, e gera XML válido. Veja mais em folha de pagamento Odoo e eSocial Odoo. Para comparação técnica com outras folhas, veja Odoo vs Senior.
Sobre o autor
Luis Felipe Miléo
Desenvolvedor Odoo · KMEE
Desenvolvedor especializado em localização fiscal e projetos open source no ecossistema Odoo/OCA, com foco em integrações para o mercado latino-americano.
Ver perfil no LinkedInArtigos relacionados
Open Finance regulado vs APIs proprietárias: qual usar para cada caso
7 de jul. de 2026
Gestão EmpresarialDDA no Odoo: contas a pagar 100% automatizadas
30 de jun. de 2026
Gestão EmpresarialTOTVS está descontinuando sua API bancária — Odoo é a alternativa neutra
9 de jun. de 2026