diff --git a/src/app/api/mobile/project/task/[id]/approval/route.ts b/src/app/api/mobile/project/task/[id]/approval/route.ts index 45d41b7..de84136 100644 --- a/src/app/api/mobile/project/task/[id]/approval/route.ts +++ b/src/app/api/mobile/project/task/[id]/approval/route.ts @@ -96,13 +96,13 @@ async function sendNotification({ } } -async function getApproversInVillage(idVillage: string): Promise { +async function getApproversInVillage(idVillage: string, idGroup: string): Promise { const approvers = await prisma.user.findMany({ where: { isActive: true, idVillage, OR: [ - { isApprover: true }, + { isApprover: true, idGroup }, { UserRole: { id: 'supadmin' } } ] }, @@ -198,7 +198,10 @@ export async function POST(request: Request, context: { params: { id: string } } const task = await prisma.projectTask.findUnique({ where: { id, isActive: true }, - select: { id: true, status: true, idProject: true, title: true } + select: { + id: true, status: true, title: true, + Project: { select: { id: true, idGroup: true } } + } }); if (!task) { @@ -227,14 +230,14 @@ export async function POST(request: Request, context: { params: { id: string } } }) ]); - await recalculateProjectStatus(task.idProject); + await recalculateProjectStatus(task.Project.id); - // Notifikasi ke semua approver - const approverTargets = await getApproversInVillage(String(userMobile.idVillage)); + // Notifikasi ke semua approver di desa dan group yang sama + const approverTargets = await getApproversInVillage(String(userMobile.idVillage), task.Project.idGroup); await sendNotification({ targets: approverTargets, idUserFrom: userMobile.id, - idContent: task.idProject, + idContent: task.Project.id, title: 'Pengajuan Penyelesaian Tugas', desc: task.title, }); @@ -271,7 +274,7 @@ export async function PUT(request: Request, context: { params: { id: string } }) const task = await prisma.projectTask.findUnique({ where: { id, isActive: true }, - select: { id: true, status: true, idProject: true, title: true } + select: { id: true, status: true, title: true, Project: { select: { id: true } } } }); if (!task) { @@ -304,7 +307,7 @@ export async function PUT(request: Request, context: { params: { id: string } }) }) ]); - await recalculateProjectStatus(task.idProject); + await recalculateProjectStatus(task.Project.id); // Notifikasi ke submitter const submitterTarget = await getUserNotifTarget(pendingApproval.idUser); @@ -312,7 +315,7 @@ export async function PUT(request: Request, context: { params: { id: string } }) await sendNotification({ targets: [submitterTarget], idUserFrom: userMobile.id, - idContent: task.idProject, + idContent: task.Project.id, title: 'Tugas Disetujui', desc: task.title, }); @@ -339,7 +342,7 @@ export async function PUT(request: Request, context: { params: { id: string } }) }) ]); - await recalculateProjectStatus(task.idProject); + await recalculateProjectStatus(task.Project.id); // Notifikasi ke submitter const submitterTarget = await getUserNotifTarget(pendingApproval.idUser); @@ -347,7 +350,7 @@ export async function PUT(request: Request, context: { params: { id: string } }) await sendNotification({ targets: [submitterTarget], idUserFrom: userMobile.id, - idContent: task.idProject, + idContent: task.Project.id, title: 'Tugas Ditolak', desc: task.title, }); diff --git a/src/app/api/mobile/task/[id]/route.ts b/src/app/api/mobile/task/[id]/route.ts index 4714ef5..409f1aa 100644 --- a/src/app/api/mobile/task/[id]/route.ts +++ b/src/app/api/mobile/task/[id]/route.ts @@ -25,6 +25,9 @@ export async function GET(request: Request, context: { params: { id: string } }) where: { id: String(id), isActive: true + }, + include: { + Division: { select: { idGroup: true } } } }); @@ -33,7 +36,7 @@ export async function GET(request: Request, context: { params: { id: string } }) } if (kategori == "data") { - allData = data + allData = { ...data, idGroup: data.Division.idGroup } } else if (kategori == "progress") { const dataProgress = await prisma.divisionProjectTask.findMany({ where: { diff --git a/src/app/api/mobile/task/tugas/[id]/approval/route.ts b/src/app/api/mobile/task/tugas/[id]/approval/route.ts index 0b53c6d..cbbc236 100644 --- a/src/app/api/mobile/task/tugas/[id]/approval/route.ts +++ b/src/app/api/mobile/task/tugas/[id]/approval/route.ts @@ -96,13 +96,19 @@ async function sendNotification({ } async function getApproversForDivision(idVillage: string, idDivision: string): Promise { + const division = await prisma.division.findUnique({ + where: { id: idDivision }, + select: { idGroup: true } + }); + const idGroup = division?.idGroup; + const [globalApprovers, divisionAdmins] = await Promise.all([ prisma.user.findMany({ where: { isActive: true, idVillage, OR: [ - { isApprover: true }, + { isApprover: true, idGroup }, { UserRole: { id: 'supadmin' } } ] }, @@ -285,23 +291,35 @@ export async function PUT(request: Request, context: { params: { id: string } }) return NextResponse.json({ success: false, message: "Anda harus login untuk mengakses ini" }, { status: 200 }); } - const canApprove = await getApproverStatus(userMobile.id); - if (!canApprove) { - // Check if division admin - const task = await prisma.divisionProjectTask.findUnique({ - where: { id, isActive: true }, - select: { idDivision: true } - }); - if (task) { - const isDivAdmin = await prisma.divisionMember.count({ - where: { idDivision: task.idDivision, idUser: userMobile.id, isAdmin: true, isActive: true } - }); - if (isDivAdmin === 0) { - return NextResponse.json({ success: false, message: "Anda tidak memiliki izin untuk menyetujui atau menolak tugas" }, { status: 200 }); - } - } else { - return NextResponse.json({ success: false, message: "Tugas tidak ditemukan" }, { status: 200 }); - } + const taskForAuth = await prisma.divisionProjectTask.findUnique({ + where: { id, isActive: true }, + select: { idDivision: true } + }); + if (!taskForAuth) { + return NextResponse.json({ success: false, message: "Tugas tidak ditemukan" }, { status: 200 }); + } + + const [division, userFull, isDivAdmin] = await Promise.all([ + prisma.division.findUnique({ + where: { id: taskForAuth.idDivision }, + select: { idGroup: true, idVillage: true } + }), + prisma.user.findUnique({ + where: { id: userMobile.id }, + select: { isApprover: true, idGroup: true, idVillage: true, UserRole: { select: { id: true } } } + }), + prisma.divisionMember.count({ + where: { idDivision: taskForAuth.idDivision, idUser: userMobile.id, isAdmin: true, isActive: true } + }) + ]); + + const isSupadmin = APPROVER_ROLES.includes(userFull?.UserRole?.id ?? ''); + const isGroupApprover = !!(userFull?.isApprover && + userFull.idVillage === division?.idVillage && + userFull.idGroup === division?.idGroup); + + if (!isSupadmin && !isGroupApprover && isDivAdmin === 0) { + return NextResponse.json({ success: false, message: "Anda tidak memiliki izin untuk menyetujui atau menolak tugas" }, { status: 200 }); } const task = await prisma.divisionProjectTask.findUnique({