module.exports=[416384,e=>{"use strict";var t=e.i(15270);async function a(e,o,r="dia"){try{let a;switch(r){case"dia":default:a="day";break;case"mes":a="month";break;case"año":a="year"}return(await t.prisma.$queryRaw`
      SELECT 
        DATE_TRUNC(${a}, 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 <= ${o}
        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 o(e,a){try{let[o]=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 <= ${a}
        AND estado = 'completada'
    `,r=Math.ceil((a.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(o?.total_ventas||0),d=Number(s?.total_ventas||0),l=c-d;return{total_ventas:c,cantidad_transacciones:Number(o?.cantidad_transacciones||0),ticket_promedio:Number(o?.ticket_promedio||0),total_descuentos:Number(o?.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,a,o=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 <= ${a}
        AND v.estado = 'completada'
      GROUP BY p.id, p.codigo, p.nombre
      ORDER BY cantidad_vendida DESC
      LIMIT ${o}
    `).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,a){try{let o=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 <= ${a}
          AND v.estado = 'completada'
        ))
      GROUP BY mp.nombre
      ORDER BY total DESC
    `,r=o.reduce((e,t)=>e+Number(t.total),0);return o.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,a){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 <= ${a}
        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,a=Number(e.stock_actual),o=Number(e.stock_minimo),r=e.stock_maximo?Number(e.stock_maximo):null,n=a*Number(e.precio_unitario);return t=0===a?"critico":a<o?"bajo":r&&a>=r?"exceso":"normal",{id:e.id,codigo:e.codigo,nombre:e.nombre,stock_actual:a,stock_minimo:o,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 a=new Date,o=new Date;return o.setDate(o.getDate()+e),(await t.prisma.lotes_productos.findMany({where:{estado:"disponible",fecha_vencimiento:{gte:a,lte:o}},include:{producto:{select:{nombre:!0}}},orderBy:{fecha_vencimiento:"asc"}})).map(e=>{let t=Math.ceil((new Date(e.fecha_vencimiento).getTime()-a.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,a,o=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 <= ${a}
      GROUP BY c.id, c.nombre, c.apellido, c.tipo_cliente
      ORDER BY total_compras DESC
      LIMIT ${o}
    `).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,a,o=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 <= ${a}
        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 ${o}
    `).map(e=>{let t=Number(e.ingresos),a=Number(e.costo_produccion),o=t-a;return{producto_id:e.producto_id,nombre:e.nombre,cantidad_vendida:Number(e.cantidad_vendida),ingresos:t,costo_produccion:a,margen_ganancia:o,porcentaje_margen:t>0?o/t*100:0}})}catch(e){throw console.error("❌ Error al obtener productos rentables:",e),Error("Error al obtener productos rentables")}}async function p(e,a,o=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 <= ${a}
        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 ${o}
    `).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",()=>o,"getLotesProximosVencer",()=>c,"getProductosMasVendidos",()=>r,"getProductosRentables",()=>u,"getProductosSinCostos",()=>p,"getProductosStockCritico",()=>s,"getValorizacionInventario",()=>d,"getVentasPorHora",()=>i,"getVentasPorMetodoPago",()=>n,"getVentasPorPeriodo",()=>a])},321540,e=>{"use strict";var t=e.i(747909),a=e.i(174017),o=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 h=e.i(600220),R=e.i(89171),C=e.i(757660),b=e.i(199150),O=e.i(416384),f=e.i(322632);let g=f.z.object({fecha_inicio:f.z.string(),fecha_fin:f.z.string(),limit:f.z.string().nullable().optional().transform(e=>e?parseInt(e):10)});async function S(e){try{let t=await (0,C.getServerSession)(b.authOptions);if(!t?.user)return R.NextResponse.json({error:"No autenticado"},{status:401});let a=e.nextUrl.searchParams,o=g.parse({fecha_inicio:a.get("fecha_inicio"),fecha_fin:a.get("fecha_fin"),limit:a.get("limit")}),r=new Date(o.fecha_inicio),n=new Date(o.fecha_fin);if(isNaN(r.getTime())||isNaN(n.getTime()))return R.NextResponse.json({error:"Fechas inválidas"},{status:400});let i=await (0,O.getProductosRentables)(r,n,o.limit),s=await (0,O.getProductosSinCostos)(r,n,o.limit),c=i.reduce((e,t)=>e+t.ingresos,0),d=i.reduce((e,t)=>e+t.costo_produccion,0),l=c-d;return R.NextResponse.json({success:!0,data:{periodo:{inicio:r.toISOString(),fin:n.toISOString()},productos_rentables:i,productos_sin_costos:s,resumen:{total_ingresos:c,total_costos:d,margen_total:l,porcentaje_margen:c>0?l/c*100:0}}})}catch(e){if(console.error("❌ Error en GET /api/reportes/rentabilidad:",e),e instanceof f.z.ZodError)return R.NextResponse.json({error:"Parámetros inválidos",details:e.errors},{status:400});return R.NextResponse.json({error:"Error al obtener reporte de rentabilidad",details:e instanceof Error?e.message:"Error desconocido"},{status:500})}}e.s(["GET",()=>S],757230);var A=e.i(757230);let w=new t.AppRouteRouteModule({definition:{kind:a.RouteKind.APP_ROUTE,page:"/api/reportes/rentabilidad/route",pathname:"/api/reportes/rentabilidad",filename:"route",bundlePath:""},distDir:".next",relativeProjectDir:"",resolvedPagePath:"[project]/app/api/reportes/rentabilidad/route.ts",nextConfigOutput:"standalone",userland:A}),{workAsyncStorage:T,workUnitAsyncStorage:D,serverHooks:M}=w;function y(){return(0,o.patchFetch)({workAsyncStorage:T,workUnitAsyncStorage:D})}async function L(e,t,o){w.isDev&&(0,r.addRequestMeta)(e,"devRequestTimingInternalsEnd",process.hrtime.bigint());let R="/api/reportes/rentabilidad/route";R=R.replace(/\/index$/,"")||"/";let C=await w.prepare(e,t,{srcPage:R,multiZoneDraftMode:!1});if(!C)return t.statusCode=400,t.end("Bad Request"),null==o.waitUntil||o.waitUntil.call(o,Promise.resolve()),null;let{buildId:b,params:O,nextConfig:f,parsedUrl:g,isDraftMode:S,prerenderManifest:A,routerServerContext:T,isOnDemandRevalidate:D,revalidateOnlyGenerated:M,resolvedPathname:y,clientReferenceManifest:L,serverActionsManifest:U}=C,I=(0,c.normalizeAppPath)(R),x=!!(A.dynamicRoutes[I]||A.routes[y]),P=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&&!S){let e=!!A.routes[y],t=A.dynamicRoutes[I];if(t&&!1===t.fallback&&!e){if(f.experimental.adapterPath)return await P();throw new N.NoFallbackError}}let k=null;!x||w.isDev||S||(k="/index"===(k=y)?"/":k);let $=!0===w.isDev||!x,H=x&&!$;U&&L&&(0,i.setReferenceManifestsSingleton)({page:R,clientReferenceManifest:L,serverActionsManifest:U,serverModuleMap:(0,s.createServerModuleMap)({serverActionsManifest:U})});let F=e.method||"GET",q=(0,n.getTracer)(),B=q.getActiveScopeSpan(),G={params:O,prerenderManifest:A,renderOpts:{experimental:{authInterrupts:!!f.experimental.authInterrupts},cacheComponents:!!f.cacheComponents,supportsDynamicResponse:$,incrementalCache:(0,r.getRequestMeta)(e,"incrementalCache"),cacheLifeProfiles:f.cacheLife,waitUntil:o.waitUntil,onClose:e=>{t.on("close",e)},onAfterTaskError:void 0,onInstrumentationRequestError:(t,a,o)=>w.onRequestError(e,t,o,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 a=q.getRootSpanAttributes();if(!a)return;if(a.get("next.span_type")!==u.BaseServerSpan.handleRequest)return void console.warn(`Unexpected root span type '${a.get("next.span_type")}'. Please report this Next.js issue https://github.com/vercel/next.js`);let o=a.get("next.route");if(o){let t=`${F} ${o}`;e.setAttributes({"next.route":o,"http.route":o,"next.span_name":t}),e.updateName(t)}else e.updateName(`${F} ${R}`)}),s=!!(0,r.getRequestMeta)(e,"minimalMode"),c=async r=>{var n,c;let d=async({previousCacheEntry:a})=>{try{if(!s&&D&&M&&!a)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&&o.waitUntil&&(o.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 a=void 0!==G.renderOpts.collectedRevalidate&&!(G.renderOpts.collectedRevalidate>=_.INFINITE_CACHE)&&G.renderOpts.collectedRevalidate,o=void 0===G.renderOpts.collectedExpire||G.renderOpts.collectedExpire>=_.INFINITE_CACHE?void 0:G.renderOpts.collectedExpire;return{value:{kind:h.CachedRouteKind.APP_ROUTE,status:n.status,body:Buffer.from(await e.arrayBuffer()),headers:t},cacheControl:{revalidate:a,expire:o}}}}catch(t){throw(null==a?void 0:a.isStale)&&await w.onRequestError(e,t,{routerKind:"App Router",routePath:R,routeType:"route",revalidateReason:(0,p.getRevalidateReason)({isStaticGeneration:H,isOnDemandRevalidate:D})},T),t}},l=await w.handleResponse({req:e,nextConfig:f,cacheKey:k,routeKind:a.RouteKind.APP_ROUTE,isFallback:!1,prerenderManifest:A,isRoutePPREnabled:!1,isOnDemandRevalidate:D,revalidateOnlyGenerated:M,responseGenerator:d,waitUntil:o.waitUntil,isMinimalMode:s});if(!x)return null;if((null==l||null==(n=l.value)?void 0:n.kind)!==h.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"),S&&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 q.withPropagatedContext(e.headers,()=>q.trace(u.BaseServerSpan.handleRequest,{spanName:`${F} ${R}`,kind:n.SpanKind.SERVER,attributes:{"http.method":F,"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],321540)}];

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