Spaces:
Sleeping
Sleeping
anoderb
feat: implement chatbot service, active shift logic corrections, audit logs, and void transaction tool
48013ee | /** | |
| * 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); | |
| } | |
| } | |
| } | |