module.exports=[416384,e=>{"use strict";var t=e.i(15270);async function o(e,a,r="dia"){try{let o;switch(r){case"dia":default:o="day";break;case"mes":o="month";break;case"año":o="year"}return(await t.prisma.$queryRaw`
      SELECT 
        DATE_TRUNC(${o}, v.fecha_venta) as periodo,
        COALESCE(SUM(v.total), 0)::DECIMAL as total_ventas,
        COUNT(v.id)::INTEGER as cantidad_ventas,
        COALESCE(AVG(v.total), 0)::DECIMAL as ticket_promedio
      FROM ventas v
      WHERE v.fecha_venta >= ${e}
        AND v.fecha_venta <= ${a}
        AND v.estado = 'completada'
      GROUP BY periodo
      ORDER BY periodo ASC
    `).map(e=>({...e,total_ventas:Number(e.total_ventas),ticket_promedio:Number(e.ticket_promedio)}))}catch(e){throw console.error("❌ Error al obtener ventas por período:",e),Error("Error al obtener ventas por período")}}async function a(e,o){try{let[a]=await t.prisma.$queryRaw`
      SELECT 
        COALESCE(SUM(total), 0) as total_ventas,
        COUNT(id) as cantidad_transacciones,
        COALESCE(AVG(total), 0) as ticket_promedio,
        COALESCE(SUM(descuento), 0) as total_descuentos
      FROM ventas
      WHERE fecha_venta >= ${e}
        AND fecha_venta <= ${o}
        AND estado = 'completada'
    `,r=Math.ceil((o.getTime()-e.getTime())/864e5),n=new Date(e);n.setDate(n.getDate()-r);let i=new Date(e);i.setDate(i.getDate()-1);let[s]=await t.prisma.$queryRaw`
      SELECT 
        COALESCE(SUM(total), 0) as total_ventas
      FROM ventas
      WHERE fecha_venta >= ${n}
        AND fecha_venta <= ${i}
        AND estado = 'completada'
    `,c=Number(a?.total_ventas||0),d=Number(s?.total_ventas||0),l=c-d;return{total_ventas:c,cantidad_transacciones:Number(a?.cantidad_transacciones||0),ticket_promedio:Number(a?.ticket_promedio||0),total_descuentos:Number(a?.total_descuentos||0),comparacion_periodo_anterior:{diferencia_ventas:l,porcentaje_cambio:d>0?l/d*100:0}}}catch(e){throw console.error("❌ Error al obtener estadísticas de ventas:",e),Error("Error al obtener estadísticas de ventas")}}async function r(e,o,a=10){try{return(await t.prisma.$queryRaw`
      SELECT 
        p.id as producto_id,
        p.codigo,
        p.nombre,
        COALESCE(SUM(dv.cantidad), 0)::DECIMAL as cantidad_vendida,
        COALESCE(SUM(dv.subtotal), 0)::DECIMAL as total_ingresos,
        COUNT(DISTINCT v.id)::INTEGER as veces_vendido
      FROM productos p
      INNER JOIN detalle_ventas dv ON dv.producto_id = p.id
      INNER JOIN ventas v ON v.id = dv.venta_id
      WHERE v.fecha_venta >= ${e}
        AND v.fecha_venta <= ${o}
        AND v.estado = 'completada'
      GROUP BY p.id, p.codigo, p.nombre
      ORDER BY cantidad_vendida DESC
      LIMIT ${a}
    `).map(e=>({...e,cantidad_vendida:Number(e.cantidad_vendida),total_ingresos:Number(e.total_ingresos)}))}catch(e){throw console.error("❌ Error al obtener productos más vendidos:",e),Error("Error al obtener productos más vendidos")}}async function n(e,o){try{let a=await t.prisma.$queryRaw`
      SELECT 
        mp.nombre as metodo_pago,
        COALESCE(SUM(
          CASE 
            WHEN (SELECT SUM(monto) FROM pagos_venta WHERE venta_id = v.id) > 0
            THEN v.total * (pv.monto / (SELECT SUM(monto) FROM pagos_venta WHERE venta_id = v.id))
            ELSE 0
          END
        ), 0) as total,
        COUNT(DISTINCT pv.venta_id) as cantidad_transacciones
      FROM metodos_pago mp
      LEFT JOIN pagos_venta pv ON pv.metodo_pago_id = mp.id
      LEFT JOIN ventas v ON v.id = pv.venta_id
      WHERE mp.activo = true
        AND (v.fecha_venta IS NULL OR (
          v.fecha_venta >= ${e}
          AND v.fecha_venta <= ${o}
          AND v.estado = 'completada'
        ))
      GROUP BY mp.nombre
      ORDER BY total DESC
    `,r=a.reduce((e,t)=>e+Number(t.total),0);return a.map(e=>({metodo_pago:e.metodo_pago,total:Number(e.total),cantidad_transacciones:Number(e.cantidad_transacciones),porcentaje:r>0?Number(e.total)/r*100:0}))}catch(e){throw console.error("❌ Error al obtener ventas por método de pago:",e),Error("Error al obtener ventas por método de pago")}}async function i(e,o){try{return(await t.prisma.$queryRaw`
      SELECT 
        EXTRACT(HOUR FROM fecha_venta)::INTEGER as hora,
        COALESCE(SUM(total), 0) as total_ventas,
        COUNT(id) as cantidad_ventas
      FROM ventas
      WHERE fecha_venta >= ${e}
        AND fecha_venta <= ${o}
        AND estado = 'completada'
      GROUP BY hora
      ORDER BY hora ASC
    `).map(e=>({hora:e.hora,total_ventas:Number(e.total_ventas),cantidad_ventas:Number(e.cantidad_ventas)}))}catch(e){throw console.error("❌ Error al obtener ventas por hora:",e),Error("Error al obtener ventas por hora")}}async function s(){try{return(await t.prisma.productos.findMany({where:{activo:!0,OR:[{stock_actual:0},{stock_actual:{lt:t.prisma.productos.fields.stock_minimo}}]},select:{id:!0,codigo:!0,nombre:!0,stock_actual:!0,stock_minimo:!0,stock_maximo:!0,precio_unitario:!0},orderBy:{stock_actual:"asc"}})).map(e=>{let t,o=Number(e.stock_actual),a=Number(e.stock_minimo),r=e.stock_maximo?Number(e.stock_maximo):null,n=o*Number(e.precio_unitario);return t=0===o?"critico":o<a?"bajo":r&&o>=r?"exceso":"normal",{id:e.id,codigo:e.codigo,nombre:e.nombre,stock_actual:o,stock_minimo:a,stock_maximo:r,valor_total:n,estado:t}})}catch(e){throw console.error("❌ Error al obtener productos con stock crítico:",e),Error("Error al obtener productos con stock crítico")}}async function c(e=30){try{let o=new Date,a=new Date;return a.setDate(a.getDate()+e),(await t.prisma.lotes_productos.findMany({where:{estado:"disponible",fecha_vencimiento:{gte:o,lte:a}},include:{producto:{select:{nombre:!0}}},orderBy:{fecha_vencimiento:"asc"}})).map(e=>{let t=Math.ceil((new Date(e.fecha_vencimiento).getTime()-o.getTime())/864e5);return{id:e.id,codigo_lote:e.codigo_lote,producto_nombre:e.producto?.nombre||"Desconocido",cantidad:Number(e.cantidad),fecha_vencimiento:e.fecha_vencimiento,dias_restantes:t}})}catch(e){throw console.error("❌ Error al obtener lotes próximos a vencer:",e),Error("Error al obtener lotes próximos a vencer")}}async function d(){try{let[e]=await t.prisma.$queryRaw`
      SELECT 
        COUNT(id) as total_productos,
        COALESCE(SUM(stock_actual * precio_unitario), 0) as valor_total,
        SUM(CASE WHEN activo = true THEN 1 ELSE 0 END) as productos_activos
      FROM productos
    `;return{total_productos:Number(e?.total_productos||0),valor_total:Number(e?.valor_total||0),productos_activos:Number(e?.productos_activos||0)}}catch(e){throw console.error("❌ Error al obtener valorización de inventario:",e),Error("Error al obtener valorización de inventario")}}async function l(e,o,a=10){try{return(await t.prisma.$queryRaw`
      SELECT 
        c.id,
        CONCAT(c.nombre, ' ', COALESCE(c.apellido, '')) as nombre_completo,
        c.tipo_cliente,
        COALESCE(SUM(v.total), 0) as total_compras,
        COUNT(v.id) as cantidad_compras,
        MAX(v.fecha_venta) as ultima_compra,
        COALESCE(AVG(v.total), 0) as ticket_promedio
      FROM clientes c
      LEFT JOIN ventas v ON v.cliente_id = c.id AND v.estado = 'completada'
      WHERE v.fecha_venta >= ${e}
        AND v.fecha_venta <= ${o}
      GROUP BY c.id, c.nombre, c.apellido, c.tipo_cliente
      ORDER BY total_compras DESC
      LIMIT ${a}
    `).map(e=>({id:e.id,nombre_completo:e.nombre_completo,tipo_cliente:e.tipo_cliente,total_compras:Number(e.total_compras),cantidad_compras:Number(e.cantidad_compras),ultima_compra:e.ultima_compra,ticket_promedio:Number(e.ticket_promedio)}))}catch(e){throw console.error("❌ Error al obtener clientes top:",e),Error("Error al obtener clientes top")}}async function u(e,o,a=10){try{return(await t.prisma.$queryRaw`
      SELECT 
        p.id as producto_id,
        p.nombre,
        COALESCE(SUM(dv.cantidad), 0) as cantidad_vendida,
        COALESCE(SUM(dv.subtotal), 0) as ingresos,
        COALESCE(SUM(dv.cantidad * dv.costo_unitario), 0) as costo_produccion
      FROM productos p
      INNER JOIN detalle_ventas dv ON dv.producto_id = p.id
      INNER JOIN ventas v ON v.id = dv.venta_id
      WHERE v.fecha_venta >= ${e}
        AND v.fecha_venta <= ${o}
        AND v.estado = 'completada'
        AND dv.costo_unitario IS NOT NULL
      GROUP BY p.id, p.nombre
      HAVING COALESCE(SUM(dv.subtotal), 0) > 0
        AND COALESCE(SUM(dv.cantidad * dv.costo_unitario), 0) > 0
      ORDER BY (COALESCE(SUM(dv.subtotal), 0) - COALESCE(SUM(dv.cantidad * dv.costo_unitario), 0)) DESC
      LIMIT ${a}
    `).map(e=>{let t=Number(e.ingresos),o=Number(e.costo_produccion),a=t-o;return{producto_id:e.producto_id,nombre:e.nombre,cantidad_vendida:Number(e.cantidad_vendida),ingresos:t,costo_produccion:o,margen_ganancia:a,porcentaje_margen:t>0?a/t*100:0}})}catch(e){throw console.error("❌ Error al obtener productos rentables:",e),Error("Error al obtener productos rentables")}}async function p(e,o,a=10){try{return(await t.prisma.$queryRaw`
      SELECT 
        p.id as producto_id,
        p.nombre,
        COALESCE(SUM(dv.cantidad), 0) as cantidad_vendida,
        COALESCE(SUM(dv.subtotal), 0) as ingresos
      FROM productos p
      INNER JOIN detalle_ventas dv ON dv.producto_id = p.id
      INNER JOIN ventas v ON v.id = dv.venta_id
      WHERE v.fecha_venta >= ${e}
        AND v.fecha_venta <= ${o}
        AND v.estado = 'completada'
        AND dv.costo_unitario IS NULL
      GROUP BY p.id, p.nombre
      HAVING COALESCE(SUM(dv.subtotal), 0) > 0
      ORDER BY ingresos DESC
      LIMIT ${a}
    `).map(e=>({producto_id:e.producto_id,nombre:e.nombre,cantidad_vendida:Number(e.cantidad_vendida),ingresos:Number(e.ingresos)}))}catch(e){throw console.error("❌ Error al obtener productos sin costos:",e),Error("Error al obtener productos sin costos")}}e.s(["getClientesTop",()=>l,"getEstadisticasVentas",()=>a,"getLotesProximosVencer",()=>c,"getProductosMasVendidos",()=>r,"getProductosRentables",()=>u,"getProductosSinCostos",()=>p,"getProductosStockCritico",()=>s,"getValorizacionInventario",()=>d,"getVentasPorHora",()=>i,"getVentasPorMetodoPago",()=>n,"getVentasPorPeriodo",()=>o])},32903,e=>{"use strict";var t=e.i(747909),o=e.i(174017),a=e.i(996250),r=e.i(759756),n=e.i(561916),i=e.i(114444),s=e.i(837092),c=e.i(869741),d=e.i(316795),l=e.i(487718),u=e.i(995169),p=e.i(47587),v=e.i(666012),E=e.i(570101),m=e.i(626937),_=e.i(10372),N=e.i(193695);e.i(52474);var R=e.i(600220),h=e.i(89171),C=e.i(757660),b=e.i(199150),O=e.i(416384),S=e.i(322632);let g=S.z.object({dias_vencimiento:S.z.string().nullable().optional().transform(e=>e?parseInt(e):30)});async function f(e){try{let t=await (0,C.getServerSession)(b.authOptions);if(!t?.user)return h.NextResponse.json({error:"No autenticado"},{status:401});let o=e.nextUrl.searchParams,a=g.parse({dias_vencimiento:o.get("dias_vencimiento")}),[r,n,i]=await Promise.all([(0,O.getProductosStockCritico)(),(0,O.getLotesProximosVencer)(a.dias_vencimiento),(0,O.getValorizacionInventario)()]);return h.NextResponse.json({success:!0,data:{valorizacion:i,productos_stock_critico:r,lotes_proximos_vencer:n,resumen:{productos_criticos:r.filter(e=>"critico"===e.estado).length,productos_bajo_stock:r.filter(e=>"bajo"===e.estado).length,lotes_por_vencer:n.length}}})}catch(e){if(console.error("❌ Error en GET /api/reportes/inventario:",e),e instanceof S.z.ZodError)return h.NextResponse.json({error:"Parámetros inválidos",details:e.errors},{status:400});return h.NextResponse.json({error:"Error al obtener reporte de inventario",details:e instanceof Error?e.message:"Error desconocido"},{status:500})}}e.s(["GET",()=>f],697909);var A=e.i(697909);let w=new t.AppRouteRouteModule({definition:{kind:o.RouteKind.APP_ROUTE,page:"/api/reportes/inventario/route",pathname:"/api/reportes/inventario",filename:"route",bundlePath:""},distDir:".next",relativeProjectDir:"",resolvedPagePath:"[project]/app/api/reportes/inventario/route.ts",nextConfigOutput:"standalone",userland:A}),{workAsyncStorage:T,workUnitAsyncStorage:D,serverHooks:M}=w;function y(){return(0,a.patchFetch)({workAsyncStorage:T,workUnitAsyncStorage:D})}async function L(e,t,a){w.isDev&&(0,r.addRequestMeta)(e,"devRequestTimingInternalsEnd",process.hrtime.bigint());let h="/api/reportes/inventario/route";h=h.replace(/\/index$/,"")||"/";let C=await w.prepare(e,t,{srcPage:h,multiZoneDraftMode:!1});if(!C)return t.statusCode=400,t.end("Bad Request"),null==a.waitUntil||a.waitUntil.call(a,Promise.resolve()),null;let{buildId:b,params:O,nextConfig:S,parsedUrl:g,isDraftMode:f,prerenderManifest:A,routerServerContext:T,isOnDemandRevalidate:D,revalidateOnlyGenerated:M,resolvedPathname:y,clientReferenceManifest:L,serverActionsManifest:U}=C,I=(0,c.normalizeAppPath)(h),x=!!(A.dynamicRoutes[I]||A.routes[y]),k=async()=>((null==T?void 0:T.render404)?await T.render404(e,t,g,!1):t.end("This page could not be found"),null);if(x&&!f){let e=!!A.routes[y],t=A.dynamicRoutes[I];if(t&&!1===t.fallback&&!e){if(S.experimental.adapterPath)return await k();throw new N.NoFallbackError}}let P=null;!x||w.isDev||f||(P="/index"===(P=y)?"/":P);let $=!0===w.isDev||!x,H=x&&!$;U&&L&&(0,i.setReferenceManifestsSingleton)({page:h,clientReferenceManifest:L,serverActionsManifest:U,serverModuleMap:(0,s.createServerModuleMap)({serverActionsManifest:U})});let q=e.method||"GET",F=(0,n.getTracer)(),B=F.getActiveScopeSpan(),G={params:O,prerenderManifest:A,renderOpts:{experimental:{authInterrupts:!!S.experimental.authInterrupts},cacheComponents:!!S.cacheComponents,supportsDynamicResponse:$,incrementalCache:(0,r.getRequestMeta)(e,"incrementalCache"),cacheLifeProfiles:S.cacheLife,waitUntil:a.waitUntil,onClose:e=>{t.on("close",e)},onAfterTaskError:void 0,onInstrumentationRequestError:(t,o,a)=>w.onRequestError(e,t,a,T)},sharedContext:{buildId:b}},j=new d.NodeNextRequest(e),V=new d.NodeNextResponse(t),W=l.NextRequestAdapter.fromNodeNextRequest(j,(0,l.signalFromNodeResponse)(t));try{let i=async e=>w.handle(W,G).finally(()=>{if(!e)return;e.setAttributes({"http.status_code":t.statusCode,"next.rsc":!1});let o=F.getRootSpanAttributes();if(!o)return;if(o.get("next.span_type")!==u.BaseServerSpan.handleRequest)return void console.warn(`Unexpected root span type '${o.get("next.span_type")}'. Please report this Next.js issue https://github.com/vercel/next.js`);let a=o.get("next.route");if(a){let t=`${q} ${a}`;e.setAttributes({"next.route":a,"http.route":a,"next.span_name":t}),e.updateName(t)}else e.updateName(`${q} ${h}`)}),s=!!(0,r.getRequestMeta)(e,"minimalMode"),c=async r=>{var n,c;let d=async({previousCacheEntry:o})=>{try{if(!s&&D&&M&&!o)return t.statusCode=404,t.setHeader("x-nextjs-cache","REVALIDATED"),t.end("This page could not be found"),null;let n=await i(r);e.fetchMetrics=G.renderOpts.fetchMetrics;let c=G.renderOpts.pendingWaitUntil;c&&a.waitUntil&&(a.waitUntil(c),c=void 0);let d=G.renderOpts.collectedTags;if(!x)return await (0,v.sendResponse)(j,V,n,G.renderOpts.pendingWaitUntil),null;{let e=await n.blob(),t=(0,E.toNodeOutgoingHttpHeaders)(n.headers);d&&(t[_.NEXT_CACHE_TAGS_HEADER]=d),!t["content-type"]&&e.type&&(t["content-type"]=e.type);let o=void 0!==G.renderOpts.collectedRevalidate&&!(G.renderOpts.collectedRevalidate>=_.INFINITE_CACHE)&&G.renderOpts.collectedRevalidate,a=void 0===G.renderOpts.collectedExpire||G.renderOpts.collectedExpire>=_.INFINITE_CACHE?void 0:G.renderOpts.collectedExpire;return{value:{kind:R.CachedRouteKind.APP_ROUTE,status:n.status,body:Buffer.from(await e.arrayBuffer()),headers:t},cacheControl:{revalidate:o,expire:a}}}}catch(t){throw(null==o?void 0:o.isStale)&&await w.onRequestError(e,t,{routerKind:"App Router",routePath:h,routeType:"route",revalidateReason:(0,p.getRevalidateReason)({isStaticGeneration:H,isOnDemandRevalidate:D})},T),t}},l=await w.handleResponse({req:e,nextConfig:S,cacheKey:P,routeKind:o.RouteKind.APP_ROUTE,isFallback:!1,prerenderManifest:A,isRoutePPREnabled:!1,isOnDemandRevalidate:D,revalidateOnlyGenerated:M,responseGenerator:d,waitUntil:a.waitUntil,isMinimalMode:s});if(!x)return null;if((null==l||null==(n=l.value)?void 0:n.kind)!==R.CachedRouteKind.APP_ROUTE)throw Object.defineProperty(Error(`Invariant: app-route received invalid cache entry ${null==l||null==(c=l.value)?void 0:c.kind}`),"__NEXT_ERROR_CODE",{value:"E701",enumerable:!1,configurable:!0});s||t.setHeader("x-nextjs-cache",D?"REVALIDATED":l.isMiss?"MISS":l.isStale?"STALE":"HIT"),f&&t.setHeader("Cache-Control","private, no-cache, no-store, max-age=0, must-revalidate");let u=(0,E.fromNodeOutgoingHttpHeaders)(l.value.headers);return s&&x||u.delete(_.NEXT_CACHE_TAGS_HEADER),!l.cacheControl||t.getHeader("Cache-Control")||u.get("Cache-Control")||u.set("Cache-Control",(0,m.getCacheControlHeader)(l.cacheControl)),await (0,v.sendResponse)(j,V,new Response(l.value.body,{headers:u,status:l.value.status||200})),null};B?await c(B):await F.withPropagatedContext(e.headers,()=>F.trace(u.BaseServerSpan.handleRequest,{spanName:`${q} ${h}`,kind:n.SpanKind.SERVER,attributes:{"http.method":q,"http.target":e.url}},c))}catch(t){if(t instanceof N.NoFallbackError||await w.onRequestError(e,t,{routerKind:"App Router",routePath:I,routeType:"route",revalidateReason:(0,p.getRevalidateReason)({isStaticGeneration:H,isOnDemandRevalidate:D})}),x)throw t;return await (0,v.sendResponse)(j,V,new Response(null,{status:500})),null}}e.s(["handler",()=>L,"patchFetch",()=>y,"routeModule",()=>w,"serverHooks",()=>M,"workAsyncStorage",()=>T,"workUnitAsyncStorage",()=>D],32903)}];

//# sourceMappingURL=_761f403b._.js.map