Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
@@ -0,0 +1,100 @@
-- 1. Criação da tabela de vigência de preços de refeição
CREATE TABLE IF NOT EXISTS "meal_pricing_policies" (
"id" TEXT NOT NULL,
"startDate" TIMESTAMP(3) NOT NULL,
"endDate" TIMESTAMP(3),
"price" DOUBLE PRECISION NOT NULL,
"description" TEXT,
"restaurantId" TEXT,
"createdAt" TIMESTAMP(3) NOT NULL DEFAULT CURRENT_TIMESTAMP,
"updatedAt" TIMESTAMP(3) NOT NULL DEFAULT CURRENT_TIMESTAMP,

CONSTRAINT "meal_pricing_policies_pkey" PRIMARY KEY ("id")
);

-- 2. Índice para consultas rápidas por faixa de data
CREATE INDEX IF NOT EXISTS "meal_pricing_policies_startDate_endDate_idx"
ON "meal_pricing_policies"("startDate", "endDate");

-- 3. Foreign key opcional para restaurante
DO $$
BEGIN
IF NOT EXISTS (
SELECT 1 FROM pg_constraint WHERE conname = 'meal_pricing_policies_restaurantId_fkey'
) THEN
ALTER TABLE "meal_pricing_policies"
ADD CONSTRAINT "meal_pricing_policies_restaurantId_fkey"
FOREIGN KEY ("restaurantId") REFERENCES "restaurants"("id") ON DELETE CASCADE ON UPDATE CASCADE;
END IF;
END $$;

-- 4. Adicionar coluna unitPrice na tabela food_orders (se ainda não existir)
DO $$
BEGIN
IF NOT EXISTS (
SELECT 1 FROM information_schema.columns
WHERE table_name = 'food_orders' AND column_name = 'unitPrice'
) THEN
ALTER TABLE "food_orders" ADD COLUMN "unitPrice" DOUBLE PRECISION;
END IF;
END $$;

-- 5. Inserir políticas de preço padrão (idempotente)
-- Vigência de 20/08 a 31/08: R$ 4,00
INSERT INTO "meal_pricing_policies" ("id", "startDate", "endDate", "price", "description", "updatedAt")
VALUES (
'policy_2026_08_vigencia_4',
'2026-08-20 00:00:00.000',
'2026-08-31 23:59:59.999',
4.00,
'Vigência de 20/08 a 31/08: R$ 4,00 por refeição',
CURRENT_TIMESTAMP
)
ON CONFLICT ("id") DO UPDATE
SET "startDate" = EXCLUDED."startDate",
"endDate" = EXCLUDED."endDate",
"price" = EXCLUDED."price",
"description" = EXCLUDED."description",
"updatedAt" = CURRENT_TIMESTAMP;

-- Vigência a partir de 01/09: R$ 7,00 (endDate NULL = vigente)
INSERT INTO "meal_pricing_policies" ("id", "startDate", "endDate", "price", "description", "updatedAt")
VALUES (
'policy_2026_09_vigencia_7',
'2026-09-01 00:00:00.000',
NULL,
7.00,
'Vigência a partir de 01/09: R$ 7,00 por refeição',
CURRENT_TIMESTAMP
)
ON CONFLICT ("id") DO UPDATE
SET "startDate" = EXCLUDED."startDate",
"endDate" = EXCLUDED."endDate",
"price" = EXCLUDED."price",
"description" = EXCLUDED."description",
"updatedAt" = CURRENT_TIMESTAMP;

-- 6. Backfill nos pedidos já existentes (FoodOrder.unitPrice):
-- Pedidos com orderDate anterior a 01/09/2026 -> R$ 4,00 (ou o valor gravado no cardápio caso seja diferente de null)
UPDATE "food_orders"
SET "unitPrice" = 4.00
WHERE "orderDate" < '2026-09-01 00:00:00.000'
AND ("unitPrice" IS NULL OR "unitPrice" != 4.00);

-- Pedidos com orderDate a partir de 01/09/2026 -> R$ 7,00
UPDATE "food_orders"
SET "unitPrice" = 7.00
WHERE "orderDate" >= '2026-09-01 00:00:00.000'
AND ("unitPrice" IS NULL OR "unitPrice" != 7.00);

-- Caso exista algum pedido com data anterior ao corte que ficou NULL, preenche com o preço do menuItem
UPDATE "food_orders" fo
SET "unitPrice" = COALESCE(mi.price, 4.00)
FROM "menu_items" mi
WHERE fo."menuItemId" = mi.id
AND fo."unitPrice" IS NULL;

-- 7. Atualizar o preço dos itens de menu ativos para R$ 7,00 (novo valor do cardápio padrão)
UPDATE "menu_items"
SET "price" = 7.00, "updatedAt" = CURRENT_TIMESTAMP
WHERE "price" = 4.00;
21 changes: 19 additions & 2 deletions prisma/schema.prisma
Original file line number Diff line number Diff line change
Expand Up @@ -535,8 +535,9 @@ model Restaurant {
createdAt DateTime @default(now())
updatedAt DateTime @updatedAt
filial Filial? @relation(fields: [filialId], references: [id], onDelete: SetNull)
orders FoodOrder[]
menuItems MenuItem[]
orders FoodOrder[]
menuItems MenuItem[]
pricingPolicies MealPricingPolicy[]

@@index([filialId])
@@map("restaurants")
Expand Down Expand Up @@ -598,6 +599,7 @@ model FoodOrder {
orderTime DateTime
status OrderStatus @default(PENDING)
observations String?
unitPrice Float? // Snapshot do valor unitário da refeição na data do pedido
createdAt DateTime @default(now())
updatedAt DateTime @updatedAt
menuItem MenuItem @relation(fields: [menuItemId], references: [id], onDelete: Cascade)
Expand All @@ -609,6 +611,21 @@ model FoodOrder {
@@map("food_orders")
}

model MealPricingPolicy {
id String @id @default(cuid())
startDate DateTime // Início da vigência (inclusivo)
endDate DateTime? // Fim da vigência (null = em aberto)
price Float // Valor por refeição
description String? // Ex: "Vigência Agosto 2026"
restaurantId String? // Opcional para regras específicas de restaurante
createdAt DateTime @default(now())
updatedAt DateTime @updatedAt
restaurant Restaurant? @relation(fields: [restaurantId], references: [id], onDelete: Cascade)

@@index([startDate, endDate])
@@map("meal_pricing_policies")
}

model OrderOptionSelection {
id String @id @default(cuid())
orderId String
Expand Down
104 changes: 104 additions & 0 deletions scripts/sql/backfill-meal-pricing.sql
Original file line number Diff line number Diff line change
@@ -0,0 +1,104 @@
BEGIN;

CREATE TABLE IF NOT EXISTS "meal_pricing_policies" (
"id" TEXT NOT NULL,
"startDate" TIMESTAMP(3) NOT NULL,
"endDate" TIMESTAMP(3),
"price" DOUBLE PRECISION NOT NULL,
"description" TEXT,
"restaurantId" TEXT,
"createdAt" TIMESTAMP(3) NOT NULL DEFAULT CURRENT_TIMESTAMP,
"updatedAt" TIMESTAMP(3) NOT NULL DEFAULT CURRENT_TIMESTAMP,

CONSTRAINT "meal_pricing_policies_pkey" PRIMARY KEY ("id")
);

CREATE INDEX IF NOT EXISTS "meal_pricing_policies_startDate_endDate_idx"
ON "meal_pricing_policies"("startDate", "endDate");

DO $$
BEGIN
IF NOT EXISTS (
SELECT 1 FROM pg_constraint WHERE conname = 'meal_pricing_policies_restaurantId_fkey'
) THEN
ALTER TABLE "meal_pricing_policies"
ADD CONSTRAINT "meal_pricing_policies_restaurantId_fkey"
FOREIGN KEY ("restaurantId") REFERENCES "restaurants"("id") ON DELETE CASCADE ON UPDATE CASCADE;
END IF;
END $$;

DO $$
BEGIN
IF NOT EXISTS (
SELECT 1 FROM information_schema.columns
WHERE table_name = 'food_orders' AND column_name = 'unitPrice'
) THEN
ALTER TABLE "food_orders" ADD COLUMN "unitPrice" DOUBLE PRECISION;
END IF;
END $$;

INSERT INTO "meal_pricing_policies" ("id", "startDate", "endDate", "price", "description", "updatedAt")
VALUES (
'policy_2026_08_vigencia_4',
'2026-08-20 00:00:00.000',
'2026-08-31 23:59:59.999',
4.00,
'Vigência de 20/08 a 31/08: R$ 4,00 por refeição',
CURRENT_TIMESTAMP
)
ON CONFLICT ("id") DO UPDATE
SET "startDate" = EXCLUDED."startDate",
"endDate" = EXCLUDED."endDate",
"price" = EXCLUDED."price",
"description" = EXCLUDED."description",
"updatedAt" = CURRENT_TIMESTAMP;

INSERT INTO "meal_pricing_policies" ("id", "startDate", "endDate", "price", "description", "updatedAt")
VALUES (
'policy_2026_09_vigencia_7',
'2026-09-01 00:00:00.000',
NULL,
7.00,
'Vigência a partir de 01/09: R$ 7,00 por refeição',
CURRENT_TIMESTAMP
)
ON CONFLICT ("id") DO UPDATE
SET "startDate" = EXCLUDED."startDate",
"endDate" = EXCLUDED."endDate",
"price" = EXCLUDED."price",
"description" = EXCLUDED."description",
"updatedAt" = CURRENT_TIMESTAMP;

UPDATE "food_orders"
SET "unitPrice" = 4.00
WHERE "orderDate" < '2026-09-01 00:00:00.000'
AND ("unitPrice" IS NULL OR "unitPrice" != 4.00);

UPDATE "food_orders"
SET "unitPrice" = 7.00
WHERE "orderDate" >= '2026-09-01 00:00:00.000'
AND ("unitPrice" IS NULL OR "unitPrice" != 7.00);

UPDATE "food_orders" fo
SET "unitPrice" = COALESCE(mi.price, 4.00)
FROM "menu_items" mi
WHERE fo."menuItemId" = mi.id
AND fo."unitPrice" IS NULL;

UPDATE "menu_items"
SET "price" = 7.00, "updatedAt" = CURRENT_TIMESTAMP
WHERE "price" = 4.00;

COMMIT;

SELECT
CASE
WHEN "orderDate" < '2026-09-01 00:00:00.000' THEN 'Até 31/08 (R$ 4,00)'
ELSE 'A partir de 01/09 (R$ 7,00)'
END AS periodo,
"unitPrice",
COUNT(*) AS total_pedidos,
SUM("unitPrice") AS valor_total
FROM "food_orders"
GROUP BY 1, 2
ORDER BY 1, 2;
48 changes: 48 additions & 0 deletions scripts/verify-meal-pricing.mjs
Original file line number Diff line number Diff line change
@@ -0,0 +1,48 @@
import { PrismaClient } from "@prisma/client"

const db = new PrismaClient()

async function main() {
console.log("=== VERIFICAÇÃO DE POLÍTICAS DE PREÇO ===")
const policies = await db.mealPricingPolicy.findMany({
orderBy: { startDate: "asc" },
})
console.log(policies)

console.log("\n=== VERIFICAÇÃO DE PEDIDOS POR PERÍODO E VALOR ===")
const breakdown = await db.$queryRaw`
SELECT
CASE
WHEN "orderDate" < '2026-09-01 00:00:00.000' THEN 'Até 31/08 (R$ 4,00)'
ELSE 'A partir de 01/09 (R$ 7,00)'
END AS periodo,
"unitPrice",
COUNT(*)::int AS total_pedidos,
ROUND(SUM("unitPrice")::numeric, 2) AS valor_total
FROM food_orders
GROUP BY 1, 2
ORDER BY 1, 2;
`
console.log(breakdown)

const nullOrdersCount = await db.foodOrder.count({
where: { unitPrice: null },
})
console.log(`\nPedidos com unitPrice nulo: ${nullOrdersCount}`)

console.log("\n=== PREÇO MÉDIO DOS ITENS DE MENU ===")
const menuItemsSummary = await db.menuItem.aggregate({
_avg: { price: true },
_min: { price: true },
_max: { price: true },
_count: true,
})
console.log(menuItemsSummary)
}

main()
.then(() => process.exit(0))
.catch((err) => {
console.error(err)
process.exit(1)
})
4 changes: 2 additions & 2 deletions src/app/(authenticated)/admin/food/_components/orders-tab.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -227,7 +227,7 @@ export default function OrdersTab({
const nome = `${user?.firstName ?? ""} ${user?.lastName ?? ""}`.trim()
const empresa = user?.enterprise ?? undefined
const setor = user?.setor ?? null
const valor = order.menuItem?.price ?? 0
const valor = order.unitPrice ?? order.menuItem?.price ?? 0
let resumo = resumoPorUsuario[email]
if (!resumo) {
resumo = {
Expand Down Expand Up @@ -925,7 +925,7 @@ export default function OrdersTab({
)}
</div>
<div className="text-right space-y-2">
<p className="font-medium">R$ {order.menuItem.price.toFixed(2)}</p>
<p className="font-medium">R$ {(order.unitPrice ?? order.menuItem.price).toFixed(2)}</p>
<Badge className={getStatusColor(order.status)}>
{getStatusText(order.status)}
</Badge>
Expand Down
Loading
Loading