Spaces:
Sleeping
Sleeping
anoderb
feat: implement chatbot service, active shift logic corrections, audit logs, and void transaction tool
48013ee | import { Request, Response, NextFunction } from 'express'; | |
| import { BonService } from '../services/bon.service'; | |
| import { sukses } from '../utils/response'; | |
| import { AuthenticatedRequest } from '../middlewares/auth.middleware'; | |
| import prisma from '../utils/db'; | |
| export class BonController { | |
| 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) || 10; | |
| const statusFilter = (req.query.status_filter as any) || undefined; | |
| const memberId = req.query.member_id ? parseInt(req.query.member_id as string) : undefined; | |
| const bonList = await BonService.getBon(skip, limit, statusFilter, memberId); | |
| return sukses(res, bonList, 'Daftar kasbon berhasil dimuat'); | |
| } catch (error) { | |
| next(error); | |
| } | |
| } | |
| static async get(req: Request, res: Response, next: NextFunction) { | |
| try { | |
| const bonId = parseInt(req.params.id); | |
| const bon = await BonService.getBonById(bonId); | |
| return sukses(res, bon, 'Detail kasbon berhasil dimuat'); | |
| } catch (error) { | |
| next(error); | |
| } | |
| } | |
| static async payInstallment(req: AuthenticatedRequest, res: Response, next: NextFunction) { | |
| try { | |
| const bonId = 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 { nominal, metode } = req.body; | |
| const bon = await BonService.bayarCicilan({ | |
| bonId, | |
| nominal, | |
| metode, | |
| actorId, | |
| ip, | |
| userAgent, | |
| }); | |
| return sukses(res, bon, 'Cicilan kasbon berhasil dibayarkan'); | |
| } catch (error) { | |
| next(error); | |
| } | |
| } | |
| static async sendDebtReminder(req: AuthenticatedRequest, res: Response, next: NextFunction) { | |
| try { | |
| const bonId = parseInt(req.params.id); | |
| const waLink = await BonService.kirimReminderWA(bonId); | |
| return sukses(res, { wa_link: waLink }, 'WhatsApp reminder link generated successfully'); | |
| } catch (error) { | |
| next(error); | |
| } | |
| } | |
| static async listInstallments(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 installments = await prisma.bon_cicilan.findMany({ | |
| orderBy: { created_at: 'desc' }, | |
| skip, | |
| take: limit, | |
| include: { | |
| bon: { | |
| include: { | |
| member: true, | |
| }, | |
| }, | |
| }, | |
| }); | |
| const formatted = installments.map((ins) => ({ | |
| tanggal: ins.created_at.toISOString().replace('T', ' ').slice(0, 16), | |
| nama: ins.bon.member.nama, | |
| nominal: Number(ins.nominal), | |
| metode: ins.metode, | |
| })); | |
| return sukses(res, formatted, 'Daftar cicilan berhasil dimuat'); | |
| } catch (error) { | |
| next(error); | |
| } | |
| } | |
| static async payByMemberId(req: AuthenticatedRequest, res: Response, next: NextFunction) { | |
| try { | |
| const memberId = parseInt(req.params.memberId); | |
| 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 { nominal, metode } = req.body; | |
| const bon = await BonService.bayarCicilanByMemberId({ | |
| memberId, | |
| nominal, | |
| metode, | |
| actorId, | |
| ip, | |
| userAgent, | |
| }); | |
| return sukses(res, bon, 'Cicilan kasbon berhasil dibayarkan'); | |
| } catch (error) { | |
| next(error); | |
| } | |
| } | |
| } | |