import { prisma } from '../lib/prisma'; import { CreateOrderInput, AddItemOrderInput, UpdateItemStatusInput, UpdateOrderInput, PayOrderInput } from '../schemas/order.schema'; export interface ListOrdersFilter { statuses?: string[]; dataInicio?: string; dataFim?: string; } export async function listOrders(filter?: ListOrdersFilter) { const where: any = {}; if (filter?.statuses?.length) { where.status = { in: filter.statuses }; } if (filter?.dataInicio || filter?.dataFim) { where.criadoEm = {}; if (filter.dataInicio) where.criadoEm.gte = new Date(filter.dataInicio); if (filter.dataFim) { const end = new Date(filter.dataFim); end.setHours(23, 59, 59, 999); where.criadoEm.lte = end; } } return prisma.comanda.findMany({ where, orderBy: { criadoEm: 'desc' }, include: { itens: { include: { produto: true } } } }); } export async function createOrder(data: CreateOrderInput) { return prisma.comanda.create({ data: { identificador: data.identificador, nomeCliente: data.nomeCliente, status: 'ABERTA', total: 0, }, }); } export async function addItemToOrder(comandaId: string, data: AddItemOrderInput) { const produto = await prisma.produto.findUnique({ where: { id: data.produtoId }, }); if (!produto) { throw new Error('Produto não encontrado'); } if (produto.estoqueAtual < data.quantidade) { throw new Error(`Estoque insuficiente. Disponível: ${produto.estoqueAtual}`); } const precoTotalItem = produto.preco * data.quantidade; const [, itemPedido] = await prisma.$transaction([ prisma.produto.update({ where: { id: data.produtoId }, data: { estoqueAtual: { decrement: data.quantidade } }, }), prisma.itemPedido.create({ data: { quantidade: data.quantidade, observacao: data.observacao, precoUnitario: produto.preco, produtoId: data.produtoId, comandaId: comandaId, status: 'PENDENTE', }, }), prisma.comanda.update({ where: { id: comandaId }, data: { total: { increment: precoTotalItem } }, }), ]); return itemPedido; } export async function listKitchenBarItems(itemCozinha?: boolean, status?: string) { const filter: any = {}; if (status) { filter.status = status; } if (typeof itemCozinha === 'boolean') { filter.produto = { itemCozinha, }; } return prisma.itemPedido.findMany({ where: filter, include: { produto: true, comanda: true, }, }); } export async function updateItemStatus(itemId: string, data: UpdateItemStatusInput) { return prisma.itemPedido.update({ where: { id: itemId }, data: { status: data.status, }, }); } export async function payOrder(comandaId: string, data?: PayOrderInput) { const comanda = await prisma.comanda.findUnique({ where: { id: comandaId }, }); if (!comanda) { throw new Error('Comanda não encontrada'); } if (comanda.status !== 'ABERTA') { throw new Error('Comanda não está aberta para pagamento'); } return prisma.comanda.update({ where: { id: comandaId }, data: { status: 'PAGA', fechadoEm: new Date(), formaPagamento: data?.formaPagamento, }, }); } export async function updateOrder(comandaId: string, data: UpdateOrderInput) { const comanda = await prisma.comanda.findUnique({ where: { id: comandaId }, }); if (!comanda) { throw new Error('Comanda não encontrada'); } const updateData: any = {}; if (data.identificador !== undefined) updateData.identificador = data.identificador; if (data.nomeCliente !== undefined) updateData.nomeCliente = data.nomeCliente; if (data.status !== undefined) updateData.status = data.status; if (data.desconto !== undefined) updateData.desconto = data.desconto; if (data.acrescimo !== undefined) updateData.acrescimo = data.acrescimo; if (data.taxaServico !== undefined) updateData.taxaServico = data.taxaServico; if (data.motivoCancelamento !== undefined) updateData.motivoCancelamento = data.motivoCancelamento; if (data.status === 'PAGA' && comanda.status !== 'PAGA') { updateData.fechadoEm = new Date(); } return prisma.comanda.update({ where: { id: comandaId }, data: updateData, include: { itens: { include: { produto: true } } } }); } export async function deleteItemFromOrder(itemId: string) { const item = await prisma.itemPedido.findUnique({ where: { id: itemId }, include: { comanda: true } }); if (!item) { throw new Error('Item do pedido não encontrado'); } if (item.comanda.status !== 'ABERTA') { throw new Error('Não é possível remover itens de uma comanda fechada/paga/cancelada'); } const precoTotalItem = item.precoUnitario * item.quantidade; const [comanda] = await prisma.$transaction([ prisma.itemPedido.delete({ where: { id: itemId } }), prisma.produto.update({ where: { id: item.produtoId }, data: { estoqueAtual: { increment: item.quantidade } }, }), prisma.comanda.update({ where: { id: item.comandaId }, data: { total: { decrement: precoTotalItem } }, }), ]); return prisma.comanda.findUnique({ where: { id: item.comandaId }, include: { itens: { include: { produto: true } } }, }); }