"use strict";(()=>{var e={};e.id=8813,e.ids=[8813],e.modules={72934:e=>{e.exports=require("next/dist/client/components/action-async-storage.external.js")},54580:e=>{e.exports=require("next/dist/client/components/request-async-storage.external.js")},45869:e=>{e.exports=require("next/dist/client/components/static-generation-async-storage.external.js")},20399:e=>{e.exports=require("next/dist/compiled/next-server/app-page.runtime.prod.js")},30517:e=>{e.exports=require("next/dist/compiled/next-server/app-route.runtime.prod.js")},78893:e=>{e.exports=require("buffer")},84770:e=>{e.exports=require("crypto")},76162:e=>{e.exports=require("stream")},21764:e=>{e.exports=require("util")},13208:(e,t,a)=>{a.r(t),a.d(t,{originalPathname:()=>x,patchFetch:()=>w,requestAsyncStorage:()=>p,routeModule:()=>m,serverHooks:()=>f,staticGenerationAsyncStorage:()=>A});var r={};a.r(r),a.d(r,{GET:()=>l});var n=a(49303),s=a(88716),o=a(60670),i=a(87070),u=a(95456),d=a(8194),c=a(45239);async function l(e){try{let t=await (0,u.ts)();if(!t)return i.NextResponse.json({error:"Unauthorized"},{status:401});if(!(0,u.MH)(t.role,["owner","admin","manager"]))return i.NextResponse.json({error:"Forbidden"},{status:403});let a=await (0,c.F)(t.tenantId,"advanced_analytics");if(a)return a;let r=e.nextUrl.searchParams.get("storeId"),n=e.nextUrl.searchParams.get("period")||"30d",s=30;"7d"===n&&(s=7),"90d"===n&&(s=90);let o=new Date;o.setDate(o.getDate()-s);let l=new Date;l.setDate(l.getDate()-2*s);let m={tenantId:t.tenantId};t.storeId?m.storeId=t.storeId:r&&(m.storeId=r);let p=t.tenantId,A=t.storeId||r,f=A?"AND o.storeId = ?":"",x=A?[p,o,A]:[p,o],w=await d._.$queryRawUnsafe(`SELECT
        AVG(TIMESTAMPDIFF(MINUTE, o.createdAt, o.updatedAt)) as avgMinutes
      FROM orders o
      WHERE o.tenantId = ?
        AND o.status = 'completed'
        AND o.createdAt >= ?
        ${f}`,...x),N=A?[p,l,o,A]:[p,l,o],I=A?"AND o.storeId = ?":"",R=await d._.$queryRawUnsafe(`SELECT
        AVG(TIMESTAMPDIFF(MINUTE, o.createdAt, o.updatedAt)) as avgMinutes
      FROM orders o
      WHERE o.tenantId = ?
        AND o.status = 'completed'
        AND o.createdAt >= ?
        AND o.createdAt < ?
        ${I}`,...N),E=Math.round(Number(w[0]?.avgMinutes||0)),h=Math.round(Number(R[0]?.avgMinutes||0)),D=await d._.$queryRawUnsafe(`SELECT
        HOUR(o.createdAt) as hour,
        COUNT(*) as orders
      FROM orders o
      WHERE o.tenantId = ?
        AND o.status = 'completed'
        AND o.createdAt >= ?
        ${f}
      GROUP BY HOUR(o.createdAt)
      ORDER BY hour ASC`,...x),M=new Map;for(let e=0;e<24;e++)M.set(e,0);for(let e of D)M.set(Number(e.hour),Number(e.orders));let v=Array.from(M.entries()).map(([e,t])=>({hour:e,orders:t})),O=(await d._.$queryRawUnsafe(`SELECT
        t.id as tableId,
        COALESCE(t.name, CONCAT('Meja ', t.number)) as tableName,
        t.number as tableNumber,
        COUNT(r.id) as reservations
      FROM \`tables\` t
      INNER JOIN stores s ON s.id = t.storeId
      LEFT JOIN reservations r
        ON r.tableId = t.id
        AND r.status NOT IN ('cancelled', 'no_show')
        AND r.date >= ?
      WHERE t.isActive = 1
        AND s.tenantId = ?
        ${A?"AND t.storeId = ?":""}
      GROUP BY t.id, t.name, t.number
      ORDER BY reservations DESC`,...A?[o,p,A]:[o,p])).map(e=>{let t=Number(e.reservations),a=Math.min(Math.round(t/s*100),100);return{tableId:e.tableId,tableName:e.tableName,reservations:t,percentage:a}}),y={tenantId:t.tenantId,date:{gte:o}};A&&(y.storeId=A);let[T,b,S,g]=await Promise.all([d._.attendance.count({where:{...y,status:"present"}}),d._.attendance.count({where:{...y,status:"late"}}),d._.attendance.count({where:{...y,status:"absent"}}),d._.attendance.count({where:{...y,status:"excused"}})]),_=A?"AND e.storeId = ?":"",U=A?[p,o,A]:[p,o],C=await d._.$queryRawUnsafe(`SELECT
        DATE_FORMAT(e.date, '%Y-%m') as month,
        SUM(e.amount) as expense
      FROM expenses e
      WHERE e.tenantId = ?
        AND e.date >= ?
        AND e.status = 'approved'
        ${_}
      GROUP BY DATE_FORMAT(e.date, '%Y-%m')
      ORDER BY month ASC`,...U),F=await d._.$queryRawUnsafe(`SELECT
        DATE_FORMAT(o.createdAt, '%Y-%m') as month,
        SUM(o.total) as revenue
      FROM orders o
      WHERE o.tenantId = ?
        AND o.status = 'completed'
        AND o.paymentStatus = 'paid'
        AND o.createdAt >= ?
        ${f}
      GROUP BY DATE_FORMAT(o.createdAt, '%Y-%m')
      ORDER BY month ASC`,...x),q=new Set,P=new Map,j=new Map;for(let e of C)q.add(e.month),P.set(e.month,Number(e.expense));for(let e of F)q.add(e.month),j.set(e.month,Number(e.revenue));let k=Array.from(q).sort().map(e=>({month:e,expense:P.get(e)||0,revenue:j.get(e)||0}));return i.NextResponse.json({avgCompletionTime:{minutes:E,trend:h>0?E-h:0},peakHours:v,tableUtilization:O,attendanceSummary:{present:T,late:b,absent:S,excused:g},expenseVsRevenue:k})}catch(e){return console.error("Operations analytics error:",e),i.NextResponse.json({error:"Internal server error"},{status:500})}}let m=new n.AppRouteRouteModule({definition:{kind:s.x.APP_ROUTE,page:"/api/analytics/operations/route",pathname:"/api/analytics/operations",filename:"route",bundlePath:"app/api/analytics/operations/route"},resolvedPagePath:"D:\\PROJECT\\resto-saas\\src\\app\\api\\analytics\\operations\\route.ts",nextConfigOutput:"",userland:r}),{requestAsyncStorage:p,staticGenerationAsyncStorage:A,serverHooks:f}=m,x="/api/analytics/operations/route";function w(){return(0,o.patchFetch)({serverHooks:f,staticGenerationAsyncStorage:A})}},95456:(e,t,a)=>{a.d(t,{Gv:()=>l,MH:()=>f,PT:()=>x,RA:()=>m,WX:()=>p,c_:()=>c,ts:()=>A});var r=a(41482),n=a.n(r),s=a(42023),o=a.n(s),i=a(71615),u=a(8194);let d=process.env.JWT_SECRET||"fallback-secret-change-me";async function c(e){return o().hash(e,12)}async function l(e,t){return o().compare(e,t)}function m(e){return n().sign(e,d,{expiresIn:"7d"})}function p(e){try{return n().verify(e,d)}catch{return null}}async function A(){let e=await (0,i.cookies)(),t=e.get("token")?.value;if(!t)return null;let a=p(t);return a?await u._.user.findUnique({where:{id:a.userId},include:{tenant:!0,store:!0}}):null}function f(e,t){return t.includes(e)}function x(e){return!["owner","admin"].includes(e.role)&&!!e.storeId&&!!e.store&&!e.store.isActive}},8194:(e,t,a)=>{a.d(t,{_:()=>n});let r=require("@prisma/client"),n=globalThis.prisma??new r.PrismaClient},45239:(e,t,a)=>{a.d(t,{F:()=>s});var r=a(87070),n=a(15230);async function s(e,t){let a=await (0,n.p6)(e);return(0,n.U6)(a.features,t)?null:r.NextResponse.json({error:"Fitur ini tidak tersedia pada paket Anda. Silakan upgrade."},{status:403})}},15230:(e,t,a)=>{a.d(t,{MN:()=>s,U6:()=>o,p6:()=>n});var r=a(8194);async function n(e){let t=await r._.subscription.findFirst({where:{tenantId:e,status:{in:["active","trial"]}},include:{plan:!0},orderBy:{createdAt:"desc"}});return t?{maxStores:t.plan.maxStores,maxStaff:t.plan.maxStaff,maxMenuItems:t.plan.maxMenuItems,maxOrders:t.plan.maxOrders,features:JSON.parse(t.plan.features)}:{maxStores:1,maxStaff:3,maxMenuItems:30,maxOrders:100,features:["pos","qr_menu"]}}async function s(e,t){let a=await n(e),s=0,o=0;switch(t){case"stores":s=await r._.store.count({where:{tenantId:e,isActive:!0}}),o=a.maxStores;break;case"staff":s=await r._.user.count({where:{tenantId:e,isActive:!0}}),o=a.maxStaff;break;case"menuItems":s=await r._.menuItem.count({where:{tenantId:e,isActive:!0}}),o=a.maxMenuItems;break;case"orders":let i=new Date;i.setDate(1),i.setHours(0,0,0,0),s=await r._.order.count({where:{tenantId:e,createdAt:{gte:i}}}),o=a.maxOrders}return 0===o?{allowed:!0,current:s,max:o}:{allowed:s<o,current:s,max:o}}function o(e,t){return e.includes(t)}}};var t=require("../../../../webpack-runtime.js");t.C(e);var a=e=>t(t.s=e),r=t.X(0,[8948,5972,4261,2023],()=>a(13208));module.exports=r})();