diff --git a/Imagens para correção /Imagem colada (10).png b/Imagens para correção /BKP/Imagem colada (10).png similarity index 100% rename from Imagens para correção /Imagem colada (10).png rename to Imagens para correção /BKP/Imagem colada (10).png diff --git a/Imagens para correção /Imagem colada (11).png b/Imagens para correção /BKP/Imagem colada (11).png similarity index 100% rename from Imagens para correção /Imagem colada (11).png rename to Imagens para correção /BKP/Imagem colada (11).png diff --git a/Imagens para correção /Imagem colada (12).png b/Imagens para correção /BKP/Imagem colada (12).png similarity index 100% rename from Imagens para correção /Imagem colada (12).png rename to Imagens para correção /BKP/Imagem colada (12).png diff --git a/Imagens para correção /Imagem colada (13).png b/Imagens para correção /BKP/Imagem colada (13).png similarity index 100% rename from Imagens para correção /Imagem colada (13).png rename to Imagens para correção /BKP/Imagem colada (13).png diff --git a/Imagens para correção /Imagem colada (14).png b/Imagens para correção /BKP/Imagem colada (14).png similarity index 100% rename from Imagens para correção /Imagem colada (14).png rename to Imagens para correção /BKP/Imagem colada (14).png diff --git a/Imagens para correção /Imagem colada (15).png b/Imagens para correção /BKP/Imagem colada (15).png similarity index 100% rename from Imagens para correção /Imagem colada (15).png rename to Imagens para correção /BKP/Imagem colada (15).png diff --git a/Imagens para correção /Imagem colada (16).png b/Imagens para correção /BKP/Imagem colada (16).png similarity index 100% rename from Imagens para correção /Imagem colada (16).png rename to Imagens para correção /BKP/Imagem colada (16).png diff --git a/Imagens para correção /Imagem colada (17).png b/Imagens para correção /BKP/Imagem colada (17).png similarity index 100% rename from Imagens para correção /Imagem colada (17).png rename to Imagens para correção /BKP/Imagem colada (17).png diff --git a/Imagens para correção /Imagem colada (2).png b/Imagens para correção /BKP/Imagem colada (2).png similarity index 100% rename from Imagens para correção /Imagem colada (2).png rename to Imagens para correção /BKP/Imagem colada (2).png diff --git a/Imagens para correção /Imagem colada (3).png b/Imagens para correção /BKP/Imagem colada (3).png similarity index 100% rename from Imagens para correção /Imagem colada (3).png rename to Imagens para correção /BKP/Imagem colada (3).png diff --git a/Imagens para correção /Imagem colada (4).png b/Imagens para correção /BKP/Imagem colada (4).png similarity index 100% rename from Imagens para correção /Imagem colada (4).png rename to Imagens para correção /BKP/Imagem colada (4).png diff --git a/Imagens para correção /Imagem colada (5).png b/Imagens para correção /BKP/Imagem colada (5).png similarity index 100% rename from Imagens para correção /Imagem colada (5).png rename to Imagens para correção /BKP/Imagem colada (5).png diff --git a/Imagens para correção /Imagem colada (6).png b/Imagens para correção /BKP/Imagem colada (6).png similarity index 100% rename from Imagens para correção /Imagem colada (6).png rename to Imagens para correção /BKP/Imagem colada (6).png diff --git a/Imagens para correção /Imagem colada (7).png b/Imagens para correção /BKP/Imagem colada (7).png similarity index 100% rename from Imagens para correção /Imagem colada (7).png rename to Imagens para correção /BKP/Imagem colada (7).png diff --git a/Imagens para correção /Imagem colada (8).png b/Imagens para correção /BKP/Imagem colada (8).png similarity index 100% rename from Imagens para correção /Imagem colada (8).png rename to Imagens para correção /BKP/Imagem colada (8).png diff --git a/Imagens para correção /Imagem colada (9).png b/Imagens para correção /BKP/Imagem colada (9).png similarity index 100% rename from Imagens para correção /Imagem colada (9).png rename to Imagens para correção /BKP/Imagem colada (9).png diff --git a/Imagens para correção /BKP/Imagem colada.png b/Imagens para correção /BKP/Imagem colada.png new file mode 100644 index 0000000..bafc59f Binary files /dev/null and b/Imagens para correção /BKP/Imagem colada.png differ diff --git a/Imagens para correção /Imagem colada.png b/Imagens para correção /Imagem colada.png index bafc59f..0134e75 100644 Binary files a/Imagens para correção /Imagem colada.png and b/Imagens para correção /Imagem colada.png differ diff --git a/app/controllers/consolidacao_entregas_controller.rb b/app/controllers/consolidacao_entregas_controller.rb index d4bb843..c0c4742 100644 --- a/app/controllers/consolidacao_entregas_controller.rb +++ b/app/controllers/consolidacao_entregas_controller.rb @@ -13,7 +13,7 @@ class ConsolidacaoEntregasController < ApplicationController def validar authorize @consolidacao, :show? @motorista = params[:motorista] - @veiculo = params[:vehicle].presence # filtro "fechar por carro" (opcional) + @veiculos_sel = veiculos_param(params[:vehicle]) # filtro por veículo(s) — multi-seleção # Entregas atendidas do período no banco existente (read-only): sucesso + # insucesso, pois o motorista foi ao local e a entrega precisa constar. @@ -24,7 +24,7 @@ class ConsolidacaoEntregasController < ApplicationController .do_motorista(@motorista) @entregas = @entregas.da_veiculo(@consolidacao.vehicle_ids) if @consolidacao.vehicle_ids.present? @entregas = @entregas.da_operacoes(@consolidacao.operacoes) if @consolidacao.operacoes.present? - @entregas = filtrar_por_veiculo(@entregas, @veiculo) if @veiculo + @entregas = filtrar_por_veiculo(@entregas, @veiculos_sel) if @veiculos_sel.any? @entregas = @entregas.order(:checkout) # Classificações já feitas — agrupadas por tracking_id (uma entrega pode ter @@ -36,10 +36,10 @@ class ConsolidacaoEntregasController < ApplicationController # Status "fechado" por veículo (filtro + acompanhamento) e totais com escopo: # quando um carro está selecionado, a barra reflete só aquele carro. @veiculos_status = veiculos_status(@motorista) - if @veiculo - atual = @veiculos_status.find { |v| v[:vehicle] == @veiculo } - @total_entregas = atual ? atual[:eligible] : 0 - @classificadas = atual ? atual[:classificadas] : 0 + if @veiculos_sel.any? + sel = @veiculos_status.select { |v| @veiculos_sel.include?(v[:vehicle]) } + @total_entregas = sel.sum { |v| v[:eligible] } + @classificadas = sel.sum { |v| v[:classificadas] } else @total_entregas = @consolidacao.entregas_elegiveis_count(@motorista) @classificadas = @consolidacao.classificadas_count(@motorista) @@ -97,7 +97,7 @@ class ConsolidacaoEntregasController < ApplicationController respond_to do |format| format.json do - render json: resumo_json(params[:motorista], vehicle: params[:vehicle].presence).merge( + render json: resumo_json(params[:motorista], vehicles: params[:vehicle]).merge( ativo: ativo, tracking_id: params[:tracking_id], tipo: params[:tipo] ) end @@ -116,8 +116,8 @@ class ConsolidacaoEntregasController < ApplicationController return render_nao_elegivel unless motorista_na_consolidacao?(motorista) - # Recorte por veículo (fechar um carro de cada vez). Sem veículo = todos. - elegiveis = tracking_ids_elegiveis(motorista, params[:vehicle].presence) + # Recorte por veículo(s) selecionado(s). Sem veículo = todos. + elegiveis = tracking_ids_elegiveis(motorista, params[:vehicle]) # Sem tracking_ids = todas as elegíveis do período/veículo (botão "todos"). # Com tracking_ids → mantém só as que de fato são elegíveis para o motorista. tracking_ids = tracking_ids.empty? ? elegiveis : (tracking_ids & elegiveis) @@ -148,10 +148,10 @@ class ConsolidacaoEntregasController < ApplicationController qtd: tracking_ids.size, motorista: motorista }) respond_to do |format| - format.json { render json: resumo_json(motorista, vehicle: params[:vehicle].presence) } + format.json { render json: resumo_json(motorista, vehicles: params[:vehicle]) } format.html do verbo = remover ? 'desmarcadas de' : 'marcadas como' - redirect_to validar_consolidacao_consolidacao_entregas_path(@consolidacao, motorista: motorista, vehicle: params[:vehicle].presence), + redirect_to validar_consolidacao_consolidacao_entregas_path(@consolidacao, motorista: motorista, vehicle: veiculos_param(params[:vehicle]).presence), notice: "#{tracking_ids.size} entregas #{verbo} #{tipo.humanize}." end end @@ -347,9 +347,20 @@ class ConsolidacaoEntregasController < ApplicationController rel.pluck(:tracking_id) end - # Recorte por um único veículo (trata o grupo "sem veículo"). - def filtrar_por_veiculo(rel, veiculo) - veiculo == SEM_VEICULO ? rel.where(vehicle: [nil, '']) : rel.da_veiculo(veiculo) + # Normaliza o parâmetro de veículo (string única OU array vindo de vehicle[]) + # numa lista limpa de selecionados. + def veiculos_param(raw) + Array(raw).reject(&:blank?) + end + + # Recorte por um OU MAIS veículos (trata o grupo "sem veículo"). Lista vazia + # = sem recorte (todos os veículos). + def filtrar_por_veiculo(rel, veiculos) + lista = veiculos_param(veiculos) + return rel if lista.empty? + valores = lista.reject { |v| v == SEM_VEICULO } + valores += [nil, ''] if lista.include?(SEM_VEICULO) + rel.where(vehicle: valores) end # Status "fechado" por veículo do motorista: lista de @@ -447,21 +458,28 @@ class ConsolidacaoEntregasController < ApplicationController rel_manual.where.not(tipo: ConsolidacaoEntrega.tipos[:termo]).distinct.count(:tracking_id) end - # `vehicle` (opcional): quando presente, `classificadas_escopo` reflete só aquele - # carro (para a barra de progresso por veículo). `veiculos_status` acompanha o - # payload para o front atualizar os chips sem recarregar. - def resumo_json(motorista, vehicle: nil) + # `vehicles` (opcional, string ou array): quando presente, TODO o resumo + # (barra de progresso, contagem por pilar e valor total) reflete apenas o(s) + # veículo(s) selecionado(s). `veiculos_status` acompanha o payload para o front + # atualizar os chips sem recarregar. + def resumo_json(motorista, vehicles: nil) + lista = veiculos_param(vehicles) classificacoes = @consolidacao.consolidacao_entregas.where(motorista_nome: motorista) status = veiculos_status(motorista) - classificadas = classificacoes.distinct.count(:tracking_id) - escopo = if vehicle.present? - (status.find { |v| v[:vehicle] == vehicle } || {})[:classificadas] || 0 - else - classificadas - end + classificadas_motorista = classificacoes.distinct.count(:tracking_id) + + if lista.any? + # Recorta as classificações às NFs dos veículos selecionados. + ids = tracking_ids_elegiveis(motorista, lista) + classificacoes = classificacoes.where(tracking_id: ids) + escopo = status.select { |v| lista.include?(v[:vehicle]) }.sum { |v| v[:classificadas] } + else + escopo = classificadas_motorista + end + { ok: true, - classificadas: classificadas, + classificadas: classificadas_motorista, classificadas_escopo: escopo, manuais: contar_manuais(classificacoes.where(manual: true)), por_tipo: classificacoes.group(:tipo).sum(:quantidade), diff --git a/app/javascript/controllers/validacao_controller.js b/app/javascript/controllers/validacao_controller.js index 1fce06e..3e34c95 100644 --- a/app/javascript/controllers/validacao_controller.js +++ b/app/javascript/controllers/validacao_controller.js @@ -18,7 +18,7 @@ export default class extends Controller { massaUrl: String, // POST classificar_em_massa motorista: String, total: Number, - veiculo: String, // veículo selecionado (filtro "fechar por carro") + veiculos: Array, // veículo(s) selecionado(s) — filtro multi-seleção precoExtraordinaria: Number // preço padrão sugerido no prompt } @@ -51,7 +51,7 @@ export default class extends Controller { tracking_id: tracking, tipo: tipo, motorista: this.motoristaValue, - vehicle: this.veiculoValue, + vehicle: this.veiculosValue, valor: valor }) // resp.ativo indica se o pilar ficou ligado ou desligado (toggle) @@ -101,7 +101,7 @@ export default class extends Controller { const resp = await this.post(this.massaUrlValue, { tipo: tipo, motorista: this.motoristaValue, - vehicle: this.veiculoValue, + vehicle: this.veiculosValue, tracking_ids: ids, acao: remover ? "remover" : "adicionar", valor: valor @@ -212,12 +212,13 @@ export default class extends Controller { if (total) total.textContent = dados.eligible if (check) check.textContent = dados.fechado ? "✓" : "" - // Estado de cor determinístico: verde (fechado) > laranja (selecionado) > neutro. + // Estado de cor determinístico: laranja (selecionado) > verde (fechado) > neutro. + // Seleção tem prioridade para o usuário sempre enxergar quais carros somam. chip.classList.remove(...VERDE, ...LARANJA, ...NEUTRO) - if (dados.fechado) { - chip.classList.add(...VERDE) - } else if (chip.dataset.vehicle === this.veiculoValue) { + if (this.veiculosValue.includes(chip.dataset.vehicle)) { chip.classList.add(...LARANJA) + } else if (dados.fechado) { + chip.classList.add(...VERDE) } else { chip.classList.add(...NEUTRO) } diff --git a/app/views/consolidacao_entregas/validar.html.erb b/app/views/consolidacao_entregas/validar.html.erb index a0eb4d7..cef8dbc 100644 --- a/app/views/consolidacao_entregas/validar.html.erb +++ b/app/views/consolidacao_entregas/validar.html.erb @@ -6,7 +6,7 @@ data-validacao-massa-url-value="<%= classificar_em_massa_consolidacao_consolidacao_entregas_path(@consolidacao) %>" data-validacao-motorista-value="<%= @motorista %>" data-validacao-total-value="<%= @total_entregas %>" - data-validacao-veiculo-value="<%= @veiculo %>" + data-validacao-veiculos-value="<%= @veiculos_sel.to_json %>" data-validacao-preco-extraordinaria-value="<%= @precos[:extraordinaria] %>"> <%# Cabeçalho + controles fixos no topo (no desktop); só a lista de NFs rola. %> @@ -31,7 +31,7 @@