Voltar ao Blog Gestão Empresarial

S-1200 remuneração RGPS: como o Odoo monta itens_remun a partir das rubricas

Como o módulo l10n_br_hr_payroll_esocial transforma rubricas hr.salary.rule em nodes itens_remun do evento S-1200, com mapping para natureza.rubrica do S-1010.

Luis Felipe Miléo

Luis Felipe Miléo

· 5 min de leitura

S-1200 é o evento de remuneração mensal do colaborador no eSocial. Cada folha mensal vira um S-1200 por trabalhador, contendo a lista de itens_remun: cada rubrica paga ou descontada com valor, código e natureza. Implementar S-1200 corretamente exige que o sistema de folha tenha catálogo de rubricas alinhado com o S-1010 (tabela de rubricas) que foi enviado antes.

A folha CLT do Odoo doada à OCA (PR #277) faz esse mapping de forma explícita: cada hr.salary.rule aponta para um natureza.rubrica do leiaute S-1.3, e o evento S-1200 é montado iterando os hr.payslip.line da folha mensal. Este post mostra como.

A estrutura de itens_remun

Dentro do evtRmnRPPS ou evtRemun (S-1200 para RGPS), o nó dmDev (demonstrativo de valores devidos) contém um ou mais infoPerApur, e dentro deles a lista itensRemun:

<dmDev>
  <ideDmDev>1</ideDmDev>
  <codCateg>101</codCateg>
  <infoPerApur>
    <ideEstabLot>
      <tpInsc>1</tpInsc>
      <nrInsc>12345678</nrInsc>
      <codLotacao>0001</codLotacao>
      <itensRemun>
        <codRubr>1001</codRubr>
        <ideTabRubr>RUBR-2026</ideTabRubr>
        <qtdRubr>220.00</qtdRubr>
        <fatorRubr>1.00</fatorRubr>
        <vrUnit>20.00</vrUnit>
        <vrRubr>4400.00</vrRubr>
      </itensRemun>
      <itensRemun>
        <codRubr>2001</codRubr>
        <ideTabRubr>RUBR-2026</ideTabRubr>
        <vrRubr>396.00</vrRubr>
      </itensRemun>
      ...
    </ideEstabLot>
  </infoPerApur>
</dmDev>

Cada itensRemun é uma rubrica. O codRubr identifica a rubrica na tabela do empregador, o ideTabRubr identifica qual versão da tabela foi usada (S-1010 versionada), e os campos numéricos detalham quantidade, fator e valor.

A tabela de rubricas (S-1010)

Antes de transmitir qualquer S-1200, a empresa precisa ter enviado o S-1010 — tabela de rubricas. Cada rubrica do S-1010 declara:

  • codRubr — código interno da rubrica (texto livre)
  • ideTabRubr — identificador da versão da tabela
  • dscRubr — descrição
  • natRubr — natureza da rubrica (catálogo fechado de 200+ códigos: 1000=salário, 1003=hora extra, 1010=adicional noturno, …)
  • tpRubr — tipo: 1=provento, 2=desconto, 3=informativa, 4=informativa dedutora
  • codIncCP — incidência sobre INSS (cód. 11=base mensal, 21=base 13o, 91=não incidência, …)
  • codIncIRRF — incidência sobre IRRF
  • codIncFGTS — incidência sobre FGTS

O natRubr é a peça mais importante. É catálogo da Receita, definido na Tabela 3 do S-1.3, com centenas de códigos. Errar o natRubr é dizer ao governo que aquela rubrica é outra coisa — afeta cálculo de DCTF, cruzamento com DIRF, e auditoria.

O modelo natureza.rubrica

A folha do Odoo importa toda a Tabela 3 oficial em um modelo natureza.rubrica:

class NaturezaRubrica(models.Model):
    _name = "natureza.rubrica"
    _description = "Tabela 3 eSocial - Natureza das Rubricas"

    code = fields.Char(required=True, index=True)  # ex: "1000"
    name = fields.Char(required=True)  # ex: "Salario / Vencimento / Soldo"
    tipo = fields.Selection([
        ("vencimento", "Verba de natureza remuneratoria"),
        ("indenizatorio", "Verba indenizatoria"),
        ("desconto_legal", "Desconto legal"),
        ("desconto_obrigacao", "Desconto por obrigacao do trabalhador"),
        ("informativo", "Informativo"),
    ])
    incide_inss = fields.Boolean()
    incide_irrf = fields.Boolean()
    incide_fgts = fields.Boolean()

Essa tabela é populada por dados/master via XML do módulo no boot. Quando o eSocial atualiza a Tabela 3, basta atualizar o módulo.

O hr.salary.rule brasileiro

O modelo nativo hr.salary.rule ganha campos:

class HrSalaryRule(models.Model):
    _inherit = "hr.salary.rule"

    cod_rubr = fields.Char(string="Codigo Rubrica eSocial")
    ide_tab_rubr = fields.Char(string="Identificador da Tabela")
    natureza_rubrica_id = fields.Many2one("natureza.rubrica")
    base_inss = fields.Boolean()
    base_irrf = fields.Boolean()
    base_fgts = fields.Boolean()
    cod_inc_cp = fields.Selection(...)  # codigo eSocial calculado
    cod_inc_irrf = fields.Selection(...)
    cod_inc_fgts = fields.Selection(...)

Quando o usuário cria uma rubrica nova (ex: “Adicional de Insalubridade 20%”), seleciona a natureza_rubrica_id no catálogo. O sistema preenche automaticamente os flags de incidência conforme a Tabela 3, mas permite override (a regra da empresa pode ser mais restritiva que o catálogo).

Geração do S-1010

Cada vez que a empresa cria, altera ou inativa rubricas, é preciso gerar S-1010 (inclusão), S-1010 (alteração) ou S-1010 (exclusão). O Odoo controla isso via versionamento: cada hr.salary.rule tem version e state, e o módulo l10n_br_hr_payroll_esocial cria registros esocial.evento.s1010 automaticamente quando o usuário marca a rubrica como “publicar no eSocial”.

Geração do S-1200 a partir da folha mensal

A folha mensal do Odoo (hr.payslip) gera linhas (hr.payslip.line) — uma por rubrica calculada. O módulo eSocial transforma essas linhas em itensRemun:

def _build_itens_remun(self, payslip):
    """Constroi lista de itensRemun para um hr.payslip."""
    itens = []
    for line in payslip.line_ids.filtered(lambda l: l.salary_rule_id.cod_rubr):
        rule = line.salary_rule_id
        itens.append({
            "codRubr": rule.cod_rubr,
            "ideTabRubr": rule.ide_tab_rubr,
            "qtdRubr": str(line.quantity) if line.quantity else None,
            "fatorRubr": str(line.rate / 100) if line.rate != 100 else None,
            "vrUnit": str(line.amount_unit) if line.amount_unit else None,
            "vrRubr": str(abs(line.total).quantize(Decimal("0.01"))),
        })
    return itens

Note o filtered: regras sem cod_rubr (ex: regras técnicas internas como “Total Bruto”) não viram itensRemun. Isso é proposital — o eSocial quer ver as rubricas que importam para o trabalhador, não cálculos intermediários.

Validação de incidência

Antes de transmitir, o módulo valida coerência entre folha e tabela:

  • Se a regra é base INSS, mas a natureza.rubrica diz que a natureza não incide CP, alerta.
  • Se a soma dos itens base INSS não bate com a base usada no cálculo, alerta.
  • Se há rubrica na folha que não está em S-1010 publicada, bloqueia transmissão.

Esses cruzamentos pegam os erros mais comuns antes de o evento ser rejeitado pela Receita.

O que ainda falta

A KMEE doou S-2200, S-2299, S-1010 e S-1200 funcionais à OCA. Faltam (no roadmap):

  • S-1210 — pagamentos de rendimentos (registra quando e quanto foi efetivamente pago)
  • S-1299 — fechamento dos eventos do mês
  • S-2210 — comunicação de acidente de trabalho (CAT)
  • Totalizadores S-5001/S-5002/S-5003 — recebimento dos retornos da Receita com bases consolidadas
  • S-5011/S-5012/S-5013 — fechamento e bases para a GFIP/DCTFWeb

São os próximos sprints de quem contribuir. O PR #277 está aberto para revisão e contribuições.

Conclusão

S-1200 é a tradução fiel da folha mensal do Odoo para a linguagem do eSocial — e a qualidade desse mapeamento depende de duas coisas: catálogo de natureza de rubricas correto e versionamento da tabela S-1010. A KMEE entrega ambos no PR #277. Veja mais sobre folha Odoo.

#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