R-010 — Fila de emissão prioriza filiações vencendo no mês corrente

TLDR: Membership.with_profile_approved_card_processing (aba “Em Emissão” do admin) coloca no topo da fila as filiações cujo valid_until cai dentro do mês corrente, independente da data de aprovação; fora desse grupo, a ordem continua sendo por user_profiles.admin_approved_at ASC NULLS LAST, como antes.

Given / When / Then

Dado que a filiação sai automaticamente da fila de emissão quando vence — with_profile_approved_card_processing filtra por valid_gte_today Quando a pessoa só consegue ter a documentação aprovada no mesmo mês em que a filiação está vencendo, inclusive no último dia do mês Então essa filiação aparece no topo da fila, à frente de aprovações mais antigas com vencimento distante, para que o emissor a identifique e conclua antes da virada do mês

Tabela de decisão

valid_until da filiação Posição na fila
Dentro do mês corrente (até o fim do dia do último dia do mês) Grupo prioritário — vem antes de qualquer filiação fora desse grupo
Fora do mês corrente Grupo normal — ordenado por user_profiles.admin_approved_at ASC NULLS LAST, mesmo comportamento de antes desta regra

Dentro de cada grupo, o desempate é sempre user_profiles.admin_approved_at ASC NULLS LAST.

Restrições

  • O limite do mês (Date.current.end_of_month) é calculado em Ruby, no fuso da aplicação (Brasilia), e não com current_date do Postgres (UTC). Calcular no banco faria o grupo prioritário virar para o mês errado horas antes da meia-noite local, no fim do mês.
  • O scope continua filtrando por valid_gte_today — uma filiação vencida presa em processing ainda some da fila na virada do mês. Esta regra reduz a janela de erro (prioriza enquanto ainda está vigente), não a elimina.
  • A regra vale só para with_profile_approved_card_processing (aba “Em Emissão”). with_profile_approved_not_issued (aba “Pagas e não emitidas”) tem o mesmo reorder antigo e não foi alterada.
  • A ordenação por clique nas colunas do admin continua bloqueada nesse scope (app/admin/memberships.rb, set_explicit_order) — a prioridade é regra de negócio, não depende do emissor lembrar de aplicar um filtro.

Código

app/models/membership.rb

ruby scope :with_profile_approved_card_processing, -> { paid.card_in_processing.with_profile_approved.valid_gte_today .reorder(Arel.sql(sanitize_sql_array([ "CASE WHEN memberships.valid_until <= ? THEN 0 ELSE 1 END ASC, " \ "user_profiles.admin_approved_at ASC NULLS LAST", Date.current.end_of_month ]))) }

Teste vinculado

test/models/membership_test.rb: - “with_profile_approved_card_processing prioritizes a membership due this month over one approved earlier but due later” - “with_profile_approved_card_processing orders two memberships due this month by admin_approved_at ascending” - “with_profile_approved_card_processing orders two memberships due in future months by admin_approved_at ascending” - “with_profile_approved_card_processing includes a membership due on the last day of the current month in the priority group” - “with_profile_approved_card_processing excludes a membership due on the first day of next month from the priority group”

Relacionados