From 291f9cd48d7b83e5e956cd7b602e3f5865dda258 Mon Sep 17 00:00:00 2001 From: Tiago Santos Bittencourt Date: Wed, 12 Aug 2026 15:00:56 -0300 Subject: [PATCH] feat: cruzamento de estagios mensal com shema --- .../contratos_dbt/silver/estagios_mensal.sql | 136 ++++++++++++++++++ .../models/contratos_dbt/silver/schema.yml | 84 +++++++++++ 2 files changed, 220 insertions(+) create mode 100644 airflow_lappis/dags/dbt/mir/models/contratos_dbt/silver/estagios_mensal.sql create mode 100644 airflow_lappis/dags/dbt/mir/models/contratos_dbt/silver/schema.yml diff --git a/airflow_lappis/dags/dbt/mir/models/contratos_dbt/silver/estagios_mensal.sql b/airflow_lappis/dags/dbt/mir/models/contratos_dbt/silver/estagios_mensal.sql new file mode 100644 index 0000000..4996eca --- /dev/null +++ b/airflow_lappis/dags/dbt/mir/models/contratos_dbt/silver/estagios_mensal.sql @@ -0,0 +1,136 @@ +{{ config(materialized="table") }} + +with + + parsed_estagios as ( + select + right(ne_ccor, 12) as ne, + case when emissao_dia like '000/%' then true else false end as eh_rap, + case + when emissao_dia like '000/%' + then '01' + else substring(emissao_dia, '\/(\d{2})\/') + end as mes_lancamento, + right(emissao_mes, 4) as ano_lancamento, + ne_ccor_favorecido as cnpj_cpf, + substring(ne_info_complementar, '(^[0-9]+)') as info_complementar, + ne_num_processo, + despesas_empenhadas as valor_empenhado, + despesas_liquidadas as valor_liquidado, + despesas_pagas as valor_pago, + restos_a_pagar_inscritos as restos_a_pagar, + restos_a_pagar_pagos as restos_a_pagar_pago, + dt_ingest + from {{ ref("empenhos_tesouro") }} + where true and ne_ccor != 'Total' + ), + + grouped_estagios as ( + select + ne, + eh_rap, + ano_lancamento::integer as ano_lancamento, + mes_lancamento, + cnpj_cpf, + max(info_complementar) as info_complementar, + max(ne_num_processo) as num_processo, + sum(valor_empenhado) as valor_empenhado, + sum(valor_liquidado) as valor_liquidado, + sum(valor_pago) as valor_pago, + sum(restos_a_pagar) as restos_a_pagar, + sum(restos_a_pagar_pago) as restos_a_pagar_pago, + max(dt_ingest) as dt_ingest + from parsed_estagios + group by 1, 2, 3, 4, 5 + order by 1, 2 + ), + + processo_fixed as ( + select + ne, + cnpj_cpf, + info_complementar, + eh_rap, + mes_lancamento, + ano_lancamento, + case + when eh_rap + then array[ano_lancamento - 1, ano_lancamento] + else array[ano_lancamento] + end as ano_efetivo, + min(num_processo) over (partition by ne) as num_processo, + valor_empenhado, + valor_liquidado, + valor_pago, + restos_a_pagar, + restos_a_pagar_pago, + dt_ingest + from grouped_estagios + ), + + unnest_rap as ( + select + ne, + cnpj_cpf, + info_complementar, + eh_rap, + mes_lancamento, + ano_lancamento, + unnest(ano_efetivo) as ano_efetivo, + num_processo, + valor_empenhado, + valor_liquidado, + valor_pago, + restos_a_pagar, + restos_a_pagar_pago, + dt_ingest + from processo_fixed + ), + + fix_data as ( + select + ne, + cnpj_cpf, + info_complementar, + eh_rap, + case + when ano_efetivo = ano_lancamento then mes_lancamento else '12' + end as mes_lancamento, + ano_lancamento, + ano_efetivo, + num_processo, + valor_empenhado, + valor_liquidado, + valor_pago, + case + when ano_efetivo = ano_lancamento + then restos_a_pagar + else - restos_a_pagar + end as restos_a_pagar, + restos_a_pagar_pago, + dt_ingest + from unnest_rap + ), + + results as ( + select + ne, + cnpj_cpf, + info_complementar, + num_processo, + to_date( + ano_efetivo || '-' || mes_lancamento || '-01', 'YYYY-MM-DD' + ) as mes_lancamento, + valor_empenhado, + valor_liquidado, + valor_pago, + restos_a_pagar, + restos_a_pagar_pago, + dt_ingest + from fix_data + ) + +-- +select * +from results +order by ne, cnpj_cpf, mes_lancamento diff --git a/airflow_lappis/dags/dbt/mir/models/contratos_dbt/silver/schema.yml b/airflow_lappis/dags/dbt/mir/models/contratos_dbt/silver/schema.yml new file mode 100644 index 0000000..7452a50 --- /dev/null +++ b/airflow_lappis/dags/dbt/mir/models/contratos_dbt/silver/schema.yml @@ -0,0 +1,84 @@ +version: 2 + +models: + # ---------------------------------------------------------------------------- + # Estágios mensais (SIAFI) + # ---------------------------------------------------------------------------- + - name: estagios_mensal + description: > + Camada silver que discrimina, mês a mês, os estágios da despesa (empenhado, + liquidado, pago e restos a pagar) extraídos do SIAFI a partir da bronze + empenhos_tesouro. Faz o parse de ne_ccor (nota de empenho), emissao_dia/ + emissao_mes (mês e ano de lançamento), ne_ccor_favorecido (CNPJ/CPF) e + ne_info_complementar, agregando os valores por ne, cnpj_cpf e mês/ano de + lançamento. + + Tratamento de Restos a Pagar (RAP): registros inscritos em RAP são + identificados pelo prefixo '000/' em emissao_dia e desdobrados entre o ano + de lançamento (mês original) e o ano de origem (mês 12), com o valor de + restos_a_pagar invertido no ano de origem para refletir a baixa da inscrição. + Replica a lógica validada no pipeline IPEA. Base do cruzamento + contratos_estagios do domínio de Contratos. + meta: + tags: + - silver + columns: + - name: ne + description: > + Número da nota de empenho padronizado, extraído das 12 últimas posições + de ne_ccor. + - name: cnpj_cpf + description: "CNPJ ou CPF do favorecido do empenho (ne_ccor_favorecido)." + - name: info_complementar + description: > + Informação complementar do empenho, extraída do prefixo numérico de + ne_info_complementar. + - name: num_processo + description: > + Número do processo administrativo associado ao empenho (menor + ne_num_processo observado para a NE). + - name: mes_lancamento + description: > + Mês de referência do lançamento (primeiro dia do mês), já com o + desdobramento de RAP aplicado entre ano de lançamento e ano de origem. + - name: valor_empenhado + description: "Soma das despesas empenhadas no mês para a NE." + - name: valor_liquidado + description: "Soma das despesas liquidadas no mês para a NE." + - name: valor_pago + description: "Soma das despesas pagas no mês para a NE." + - name: restos_a_pagar + description: > + Soma dos restos a pagar inscritos no mês para a NE. No ano de origem de + um RAP o valor é registrado com sinal invertido. + - name: restos_a_pagar_pago + description: "Soma dos restos a pagar já quitados no mês para a NE." + - name: dt_ingest + description: > + Data e hora (UTC-3 Brasília) mais recente de ingestão dos dados da fonte + utilizada neste modelo. + tests: + - verificacao_tipagem: + nome_tabela: 'contratos_dbt.estagios_mensal' + nome_coluna: 'mes_lancamento' + tipo_esperado: 'date' + - verificacao_tipagem: + nome_tabela: 'contratos_dbt.estagios_mensal' + nome_coluna: 'valor_empenhado' + tipo_esperado: 'numeric' + - verificacao_tipagem: + nome_tabela: 'contratos_dbt.estagios_mensal' + nome_coluna: 'valor_liquidado' + tipo_esperado: 'numeric' + - verificacao_tipagem: + nome_tabela: 'contratos_dbt.estagios_mensal' + nome_coluna: 'valor_pago' + tipo_esperado: 'numeric' + - verificacao_tipagem: + nome_tabela: 'contratos_dbt.estagios_mensal' + nome_coluna: 'restos_a_pagar' + tipo_esperado: 'numeric' + - verificacao_tipagem: + nome_tabela: 'contratos_dbt.estagios_mensal' + nome_coluna: 'dt_ingest' + tipo_esperado: 'timestamp with time zone'