+
+
+
+
+
+
+
+
+
+
+
diff --git a/Imagens para correção /Imagem colada (9).png b/Imagens para correção /Imagem colada (9).png
new file mode 100644
index 0000000..3349e2a
Binary files /dev/null and b/Imagens para correção /Imagem colada (9).png differ
diff --git a/app/models/entrega.rb b/app/models/entrega.rb
index 8b14b82..3495f8b 100644
--- a/app/models/entrega.rb
+++ b/app/models/entrega.rb
@@ -40,15 +40,19 @@ class Entrega < ApplicationRecord
}
# Filtra pela(s) conta(s) configurada(s) em DB_EXISTING_ACCOUNT_ID.
- # A coluna account_id é TEXTO e pode vir vazia, então comparamos como string.
+ # A coluna account_id é TEXTO e pode vir vazia/NULL, então comparamos como string.
+ # IMPORTANTE: o valor é uma LISTA separada por vírgula — NÃO um trecho de SQL.
# Aceita: "95907" (uma) | "95907,12345" (várias) | "all" ou vazio (sem filtro).
- # Use "95907," (com vírgula) para incluir também os registros de conta vazia.
+ # Use "95907," (vírgula no fim) para incluir também registros de conta vazia/NULL.
scope :da_conta_gade, -> {
contas = ENV.fetch('DB_EXISTING_ACCOUNT_ID', '95907').to_s.strip
if contas.empty? || contas.casecmp?('all')
all
else
- where(account_id: contas.split(',', -1).map(&:strip))
+ valores = contas.split(',', -1).map(&:strip)
+ # Token vazio (ex.: "95907,") → inclui também as linhas sem conta (NULL).
+ valores << nil if valores.any?(&:empty?)
+ where(account_id: valores)
end
}
diff --git a/app/models/user.rb b/app/models/user.rb
index 74f623f..22738ec 100644
--- a/app/models/user.rb
+++ b/app/models/user.rb
@@ -27,6 +27,10 @@ class User < ApplicationRecord
validate :pin_unico_para_motoristas, if: :motorista?
+ # E-mail em branco vira NULL: evita colisão no índice único quando vários
+ # motoristas são criados sem e-mail (no Postgres NULLs são distintos entre si).
+ before_validation :normalizar_email_em_branco
+
# Motoristas podem não ter e-mail (login via PIN)
def email_required?
!motorista?
@@ -65,6 +69,10 @@ class User < ApplicationRecord
private
+ def normalizar_email_em_branco
+ self.email = nil if email.blank?
+ end
+
def pin_unico_para_motoristas
return if pin_code.blank?
diff --git a/app/views/dashboard/index.html.erb b/app/views/dashboard/index.html.erb
index 9450f19..51b0622 100644
--- a/app/views/dashboard/index.html.erb
+++ b/app/views/dashboard/index.html.erb
@@ -1,6 +1,12 @@
<%# app/views/dashboard/index.html.erb %>
<%# Fase 3: Dashboard com cards, gráfico Chart.js e cálculo ao vivo %>
+<%# Não cachear no Turbo: o snapshot congelava o gráfico/calendário (DOM já
+<%# alterado pelo JS, sem reexecutar scripts) e só voltava com F5. %>
+<% content_for :head do %>
+
+<% end %>
+
<%# Header + filtro por faixa de datas %>
@@ -196,6 +202,10 @@
const ctx = document.getElementById('grafico-diario');
if (!ctx || typeof Chart === 'undefined') return;
+ // Destrói gráfico anterior preso ao mesmo canvas (evita "Canvas is already
+ // in use" quando o Turbo reexecuta o script ao navegar).
+ Chart.getChart(ctx)?.destroy();
+
const labels = <%= raw @grafico_diario[:labels].to_json %>;
const valores = <%= raw @grafico_diario[:valores].to_json %>;
const qtds = <%= raw @grafico_diario[:qtds].to_json %>;
diff --git a/db/migrate/20260616000003_allow_null_email_for_motoristas.rb b/db/migrate/20260616000003_allow_null_email_for_motoristas.rb
new file mode 100644
index 0000000..031385f
--- /dev/null
+++ b/db/migrate/20260616000003_allow_null_email_for_motoristas.rb
@@ -0,0 +1,20 @@
+# Motoristas fazem login por PIN/QR e podem não ter e-mail. A coluna email era
+# NOT NULL com default "" e índice único — então criar o 2º motorista sem e-mail
+# colidia em "" (RecordNotUnique → 500 ao salvar pela tela de usuários).
+#
+# Solução: permitir NULL e converter os "" existentes em NULL. No Postgres o
+# índice único trata múltiplos NULL como distintos, então vários motoristas sem
+# e-mail convivem sem conflito.
+class AllowNullEmailForMotoristas < ActiveRecord::Migration[7.1]
+ def up
+ change_column_null :users, :email, true
+ change_column_default :users, :email, from: '', to: nil
+ execute "UPDATE users SET email = NULL WHERE email = ''"
+ end
+
+ def down
+ execute "UPDATE users SET email = '' WHERE email IS NULL"
+ change_column_default :users, :email, from: nil, to: ''
+ change_column_null :users, :email, false
+ end
+end