import { Request, Response, NextFunction } from 'express'; import { OpsService } from '../services/ops.service'; import { sukses } from '../utils/response'; import { AuthenticatedRequest } from '../middlewares/auth.middleware'; export class OpsController { // Shift Kasir static async getActiveShift(req: AuthenticatedRequest, res: Response, next: NextFunction) { try { const userId = req.user.id; const shift = await OpsService.getActiveShift(userId); if (!shift) { return sukses(res, null, 'Tidak ada shift aktif untuk kasir saat ini'); } return sukses(res, shift, 'Shift aktif berhasil dimuat'); } catch (error) { next(error); } } static async openShift(req: AuthenticatedRequest, res: Response, next: NextFunction) { try { const actorId = req.user.id; const ip = (req.ip || req.socket.remoteAddress || 'unknown').replace('::ffff:', ''); const userAgent = (req.headers['user-agent'] || 'unknown') as string; const { modal_awal, catatan } = req.body; const shift = await OpsService.bukaShift(modal_awal, catatan, actorId, ip, userAgent); return sukses(res, shift, 'Shift berhasil dibuka'); } catch (error) { next(error); } } static async closeShift(req: AuthenticatedRequest, res: Response, next: NextFunction) { try { const actorId = req.user.id; const ip = (req.ip || req.socket.remoteAddress || 'unknown').replace('::ffff:', ''); const userAgent = (req.headers['user-agent'] || 'unknown') as string; const { modal_akhir_fisik, catatan } = req.body; const shift = await OpsService.tutupShift(modal_akhir_fisik, catatan, actorId, ip, userAgent); return sukses(res, shift, 'Shift kasir ditutup, selisih kas fisik berhasil dicatat'); } catch (error) { next(error); } } // Dashboard & Laporan static async getDashboardSummary(req: AuthenticatedRequest, res: Response, next: NextFunction) { try { const summary = await OpsService.getDashboardSummary(); return sukses(res, summary, 'Dashboard summary berhasil dimuat'); } catch (error) { next(error); } } static async getSalesReport(req: AuthenticatedRequest, res: Response, next: NextFunction) { try { const tglMulai = new Date(req.query.tgl_mulai as string); const tglSelesai = new Date(req.query.tgl_selesai as string); const report = await OpsService.buatLaporanPenjualan(tglMulai, tglSelesai); return sukses(res, report, 'Laporan penjualan berhasil dibuat'); } catch (error) { next(error); } } static async getProfitLossReport(req: AuthenticatedRequest, res: Response, next: NextFunction) { try { const tglMulai = new Date(req.query.tgl_mulai as string); const tglSelesai = new Date(req.query.tgl_selesai as string); const report = await OpsService.buatLaporanLabaRugi(tglMulai, tglSelesai); return sukses(res, report, 'Laporan laba rugi berhasil dibuat'); } catch (error) { next(error); } } static async eksporLaporan(req: AuthenticatedRequest, res: Response, next: NextFunction) { try { const jenis = req.query.jenis as any; const format = req.query.format as any; const tglMulai = new Date(req.query.tgl_mulai as string); const tglSelesai = new Date(req.query.tgl_selesai as string); if (!['penjualan', 'laba-rugi', 'mutasi-stok'].includes(jenis)) { throw new Error('Jenis laporan tidak valid'); } if (!['csv', 'excel', 'pdf'].includes(format)) { throw new Error('Format laporan tidak valid. Harus csv, excel, atau pdf'); } const fileInfo = await OpsService.eksporLaporan({ jenis, format, tglMulai, tglSelesai, }); return sukses(res, fileInfo, 'Laporan berhasil diekspor'); } catch (error: any) { res.status(400).json({ sukses: false, pesan: error.message || 'Gagal mengekspor laporan' }); } } // Settings/Pengaturan static async getSettings(req: Request, res: Response, next: NextFunction) { try { const settings = await OpsService.getSettings(); return sukses(res, settings, 'Pengaturan toko berhasil dimuat'); } catch (error) { next(error); } } static async getSettingByKey(req: Request, res: Response, next: NextFunction) { try { const { kunci } = req.params; const value = await OpsService.getSettingByKey(kunci); return sukses(res, { kunci, nilai: value }, `Pengaturan '${kunci}' berhasil dimuat`); } catch (error) { next(error); } } static async updateSetting(req: AuthenticatedRequest, res: Response, next: NextFunction) { try { const { kunci } = req.params; const actorId = req.user.id; const ip = (req.ip || req.socket.remoteAddress || 'unknown').replace('::ffff:', ''); const userAgent = (req.headers['user-agent'] || 'unknown') as string; await OpsService.updateSetting(kunci, req.body, actorId, ip, userAgent); const value = await OpsService.getSettingByKey(kunci); return sukses(res, { kunci, nilai: value }, 'Pengaturan berhasil diperbarui'); } catch (error) { next(error); } } // Notifikasi static async listNotifications(req: Request, res: Response, next: NextFunction) { try { const skip = parseInt(req.query.skip as string) || 0; const limit = parseInt(req.query.limit as string) || 20; const dibaca = req.query.dibaca !== undefined ? parseInt(req.query.dibaca as string) : undefined; const notifs = await OpsService.getNotifications(skip, limit, dibaca); return sukses(res, notifs, 'Notifikasi berhasil dimuat'); } catch (error) { next(error); } } static async readAllNotifications(req: Request, res: Response, next: NextFunction) { try { const affected = await OpsService.markAllNotifAsRead(); return sukses(res, { jumlah_diubah: affected }, 'Semua notifikasi ditandai dibaca'); } catch (error) { next(error); } } static async readNotification(req: Request, res: Response, next: NextFunction) { try { const notifId = parseInt(req.params.notif_id); const notif = await OpsService.markNotifAsRead(notifId); return sukses(res, notif, 'Notifikasi ditandai dibaca'); } catch (error) { next(error); } } static async getUnreadNotificationCount(req: Request, res: Response, next: NextFunction) { try { const count = await OpsService.getUnreadNotifCount(); return sukses(res, { unread_count: count }, 'Jumlah notifikasi belum dibaca berhasil dihitung'); } catch (error) { next(error); } } }