/** * diskon.controller.ts * Controller untuk mengelola data diskon & promosi (CRUD). */ import { Request, Response, NextFunction } from 'express'; import prisma from '../utils/db'; import { sukses, gagal } from '../utils/response'; import { AuthenticatedRequest } from '../middlewares/auth.middleware'; import { catatAudit } from '../utils/audit'; export class DiskonController { static async list(req: Request, res: Response, next: NextFunction) { try { const skip = parseInt(req.query.skip as string) || 0; const limit = parseInt(req.query.limit as string) || 100; const pencarian = req.query.pencarian as string || undefined; const where: any = {}; if (pencarian) { where.nama = { contains: pencarian, }; } const total = await prisma.diskon.count({ where }); const promos = await prisma.diskon.findMany({ where, skip, take: limit, orderBy: { created_at: 'desc' }, }); return sukses(res, promos, 'Daftar promosi berhasil dimuat', { total }); } catch (error) { next(error); } } static async get(req: Request, res: Response, next: NextFunction) { try { const id = parseInt(req.params.id); const promo = await prisma.diskon.findUnique({ where: { id }, }); if (!promo) { return gagal(res, 404, 'Promosi tidak ditemukan'); } return sukses(res, promo, 'Detail promosi berhasil dimuat'); } catch (error) { next(error); } } static async create(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 { nama, tipe, nilai, min_belanja, produk_ids, member_only, tgl_mulai, tgl_selesai, jam_mulai, jam_selesai, is_aktif, } = req.body; const promo = await prisma.diskon.create({ data: { nama, tipe, nilai: Number(nilai), min_belanja: min_belanja !== undefined ? Number(min_belanja) : 0, produk_ids: produk_ids || null, member_only: member_only !== undefined ? Number(member_only) : 0, tgl_mulai: new Date(tgl_mulai), tgl_selesai: new Date(tgl_selesai), jam_mulai: jam_mulai ? new Date(`1970-01-01T${jam_mulai}`) : null, jam_selesai: jam_selesai ? new Date(`1970-01-01T${jam_selesai}`) : null, is_aktif: is_aktif !== undefined ? Number(is_aktif) : 1, }, }); await catatAudit({ userId: actorId, aksi: 'create', entitas: 'diskon', entitasId: promo.id, dataBaru: { nama: promo.nama, tipe: promo.tipe, nilai: Number(promo.nilai) }, ipAddress: ip, userAgent, }); return sukses(res, promo, 'Promosi berhasil dibuat'); } catch (error) { next(error); } } static async update(req: AuthenticatedRequest, res: Response, next: NextFunction) { try { const id = parseInt(req.params.id); 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 existing = await prisma.diskon.findUnique({ where: { id } }); if (!existing) { return gagal(res, 404, 'Promosi tidak ditemukan'); } const { nama, tipe, nilai, min_belanja, produk_ids, member_only, tgl_mulai, tgl_selesai, jam_mulai, jam_selesai, is_aktif, } = req.body; const promo = await prisma.diskon.update({ where: { id }, data: { nama: nama !== undefined ? nama : undefined, tipe: tipe !== undefined ? tipe : undefined, nilai: nilai !== undefined ? Number(nilai) : undefined, min_belanja: min_belanja !== undefined ? Number(min_belanja) : undefined, produk_ids: produk_ids !== undefined ? produk_ids : undefined, member_only: member_only !== undefined ? Number(member_only) : undefined, tgl_mulai: tgl_mulai !== undefined ? new Date(tgl_mulai) : undefined, tgl_selesai: tgl_selesai !== undefined ? new Date(tgl_selesai) : undefined, jam_mulai: jam_mulai !== undefined ? (jam_mulai ? new Date(`1970-01-01T${jam_mulai}`) : null) : undefined, jam_selesai: jam_selesai !== undefined ? (jam_selesai ? new Date(`1970-01-01T${jam_selesai}`) : null) : undefined, is_aktif: is_aktif !== undefined ? Number(is_aktif) : undefined, }, }); await catatAudit({ userId: actorId, aksi: 'update', entitas: 'diskon', entitasId: promo.id, dataLama: { nama: existing.nama, tipe: existing.tipe, nilai: Number(existing.nilai) }, dataBaru: { nama: promo.nama, tipe: promo.tipe, nilai: Number(promo.nilai) }, ipAddress: ip, userAgent, }); return sukses(res, promo, 'Promosi berhasil diperbarui'); } catch (error) { next(error); } } static async delete(req: AuthenticatedRequest, res: Response, next: NextFunction) { try { const id = parseInt(req.params.id); 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 existing = await prisma.diskon.findUnique({ where: { id } }); if (!existing) { return gagal(res, 404, 'Promosi tidak ditemukan'); } await prisma.diskon.delete({ where: { id } }); await catatAudit({ userId: actorId, aksi: 'delete', entitas: 'diskon', entitasId: id, dataLama: { nama: existing.nama, tipe: existing.tipe, nilai: Number(existing.nilai) }, dataBaru: { deleted: true }, ipAddress: ip, userAgent, }); return sukses(res, null, 'Promosi berhasil dihapus'); } catch (error) { next(error); } } }