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
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.rubricadiz 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.
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