Voltar ao Blog Gestão Empresarial

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

Luis Felipe Miléo

· 5 min de leitura

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.
  • hrAcid em 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, indComunPolicia precisa 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.

#folha #esocial

Compartilhar

Sobre o autor

Luis Felipe Miléo

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 LinkedIn