Grande correção do filtro de veiculos na area de consolidação

This commit is contained in:
2026-07-03 09:58:59 -03:00
parent 83310e9e66
commit eca6df39eb
17 changed files with 681 additions and 41 deletions

View File

@@ -0,0 +1,38 @@
# Snapshot do veículo em cada pilar da consolidação. O veículo vive só na tabela
# externa de rastreio (db_reem_simplerout_2026), acessível via tracking_id. Guardar
# uma cópia aqui permite fechar/consolidar POR VEÍCULO sem N+1 e mantém o histórico
# estável mesmo que a base externa mude depois. Lançamentos sintéticos (apontamento
# 100% manual "MAN-*" e entrega de termo "TERMO-*") não têm veículo na rastreio e
# ficam NULL — o agrupamento trata NULL como "(sem veículo)".
class AddVehicleToConsolidacaoEntregas < ActiveRecord::Migration[7.1]
def up
unless column_exists?(:consolidacao_entregas, :vehicle)
add_column :consolidacao_entregas, :vehicle, :string
add_index :consolidacao_entregas, %i[consolidacao_id motorista_nome vehicle],
name: 'idx_consolidacao_entrega_veiculo'
end
# Backfill dos lançamentos já existentes a partir da rastreio. Só roda onde a
# tabela externa existe (dev/prod) — no banco de teste ela é isolada, então
# pulamos para não quebrar o db:migrate.
return unless connection.table_exists?('db_reem_simplerout_2026')
say_with_time 'backfill vehicle em consolidacao_entregas' do
execute(<<~SQL.squish)
UPDATE consolidacao_entregas ce
SET vehicle = e.vehicle
FROM db_reem_simplerout_2026 e
WHERE e.tracking_id = ce.tracking_id
AND ce.vehicle IS NULL
SQL
end
end
def down
if index_exists?(:consolidacao_entregas, %i[consolidacao_id motorista_nome vehicle],
name: 'idx_consolidacao_entrega_veiculo')
remove_index :consolidacao_entregas, name: 'idx_consolidacao_entrega_veiculo'
end
remove_column :consolidacao_entregas, :vehicle if column_exists?(:consolidacao_entregas, :vehicle)
end
end

View File

@@ -0,0 +1,61 @@
# Unidade de FECHAMENTO por veículo dentro de uma consolidação. Espelha o padrão de
# consolidacao_motoristas (arquivamento reversível + valor_total), mas o que ela
# controla é o estado "fechado/consolidado" de cada carro — o PAGAMENTO continua no
# motorista (consolidacao_motoristas). Assim dá para consolidar um veículo pronto
# sem esperar os outros. O bucket sem veículo (termo/apontamento manual legado) usa
# o sentinel '(sem veículo)' para que o índice único funcione (NULL quebraria).
class CreateConsolidacaoVeiculos < ActiveRecord::Migration[7.1]
SEM_VEICULO = '(sem veículo)'
def up
unless table_exists?(:consolidacao_veiculos)
create_table :consolidacao_veiculos do |t|
t.references :consolidacao, null: false, foreign_key: { to_table: :consolidacoes }
t.string :motorista_nome, null: false
t.string :vehicle, null: false
t.decimal :valor_total, precision: 10, scale: 2, default: 0
t.datetime :fechado_em # NULL = aberto (ainda não consolidado)
t.integer :fechado_por
t.datetime :arquivado_em # NULL = ativo
t.integer :arquivado_por
t.timestamps
end
add_index :consolidacao_veiculos, %i[consolidacao_id motorista_nome vehicle],
unique: true, name: 'idx_consolidacao_veiculo_unique'
add_index :consolidacao_veiculos, :arquivado_em
end
# Backfill: uma linha por (consolidação · motorista · veículo) já classificado,
# somando o valor (desconto = tipo 3 subtrai). Consolidações já finalizadas
# (status 1) nascem FECHADAS, herdando quem/quando finalizou — para não
# "reabrir" o que já foi pago.
say_with_time 'backfill consolidacao_veiculos a partir das entregas' do
execute(<<~SQL.squish)
INSERT INTO consolidacao_veiculos
(consolidacao_id, motorista_nome, vehicle, valor_total,
fechado_em, fechado_por, created_at, updated_at)
SELECT ce.consolidacao_id,
ce.motorista_nome,
COALESCE(NULLIF(ce.vehicle, ''), '#{SEM_VEICULO}') AS vehicle,
COALESCE(SUM(CASE WHEN ce.tipo = 3
THEN -ce.valor_aplicado
ELSE ce.valor_aplicado END), 0) AS valor_total,
CASE WHEN c.status = 1 THEN c.finalizado_em END AS fechado_em,
CASE WHEN c.status = 1 THEN c.finalizado_por END AS fechado_por,
NOW(), NOW()
FROM consolidacao_entregas ce
JOIN consolidacoes c ON c.id = ce.consolidacao_id
GROUP BY ce.consolidacao_id, ce.motorista_nome,
COALESCE(NULLIF(ce.vehicle, ''), '#{SEM_VEICULO}'),
c.status, c.finalizado_em, c.finalizado_por
SQL
end
end
def down
drop_table :consolidacao_veiculos if table_exists?(:consolidacao_veiculos)
end
end