From 2d27b8ca9041c80ccfc8d0f3007424d5e283f693 Mon Sep 17 00:00:00 2001 From: amel Date: Mon, 26 May 2025 10:57:14 +0800 Subject: [PATCH 1/2] upd: api mobile Deskripsi: - update sortir data riwayat kalender NoIssues --- src/app/api/mobile/calendar/history/route.ts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/app/api/mobile/calendar/history/route.ts b/src/app/api/mobile/calendar/history/route.ts index 7136d2f..5203e1f 100644 --- a/src/app/api/mobile/calendar/history/route.ts +++ b/src/app/api/mobile/calendar/history/route.ts @@ -63,7 +63,7 @@ export async function GET(request: Request) { }, orderBy: [ { - dateStart: 'asc' + dateStart: 'desc' }, { timeStart: 'asc' From a36bd31a26107ccbc54065af8fb080483d936934 Mon Sep 17 00:00:00 2001 From: amel Date: Mon, 26 May 2025 17:35:25 +0800 Subject: [PATCH 2/2] upd: api mobile Deskripsi: - update api mobile fitur task divisi No Issues --- src/app/api/mobile/task/[id]/lainnya/route.ts | 49 +++ src/app/api/mobile/task/[id]/member/route.ts | 101 ++++++ src/app/api/mobile/task/[id]/route.ts | 339 ++++++++++++++++++ src/app/api/mobile/task/detail/[id]/route.ts | 243 +++++++++++++ src/app/api/mobile/task/file/[id]/route.ts | 227 ++++++++++++ src/app/api/mobile/task/route.ts | 331 +++++++++++++++++ 6 files changed, 1290 insertions(+) create mode 100644 src/app/api/mobile/task/[id]/lainnya/route.ts create mode 100644 src/app/api/mobile/task/[id]/member/route.ts create mode 100644 src/app/api/mobile/task/[id]/route.ts create mode 100644 src/app/api/mobile/task/detail/[id]/route.ts create mode 100644 src/app/api/mobile/task/file/[id]/route.ts create mode 100644 src/app/api/mobile/task/route.ts diff --git a/src/app/api/mobile/task/[id]/lainnya/route.ts b/src/app/api/mobile/task/[id]/lainnya/route.ts new file mode 100644 index 0000000..4dc98e5 --- /dev/null +++ b/src/app/api/mobile/task/[id]/lainnya/route.ts @@ -0,0 +1,49 @@ +import { prisma } from "@/module/_global"; +import { funGetUserById } from "@/module/auth"; +import { createLogUserMobile } from "@/module/user"; +import { NextResponse } from "next/server"; + +// PENGHAPUSAN TUGAS DIVISI +export async function DELETE(request: Request, context: { params: { id: string } }) { + try { + const { id } = context.params; + const { user } = (await request.json()); + + const userMobile = await funGetUserById({ id: String(user) }) + if (userMobile.id == "null" || userMobile.id == undefined || userMobile.id == "") { + return NextResponse.json({ success: false, message: "Anda harus login untuk mengakses ini" }, { status: 200 }); + } + const data = await prisma.divisionProject.count({ + where: { + id: id, + }, + }); + + if (data == 0) { + return NextResponse.json( + { + success: false, + message: "Penghapusan tugas gagal, data tugas tidak ditemukan", + }, + { status: 200 } + ); + } + + const update = await prisma.divisionProject.update({ + where: { + id + }, + data: { + isActive: false, + } + }); + + // create log user + const log = await createLogUserMobile({ act: 'DELETE', desc: 'User menghapus tugas divisi', table: 'divisionProject', data: id, user: userMobile.id }) + + return NextResponse.json({ success: true, message: "Tugas berhasil dihapuskan", user: userMobile.id }, { status: 200 }); + } catch (error) { + console.error(error); + return NextResponse.json({ success: false, message: "Gagal menghapus tugas, coba lagi nanti (error: 500)", reason: (error as Error).message, }, { status: 500 }); + } +} \ No newline at end of file diff --git a/src/app/api/mobile/task/[id]/member/route.ts b/src/app/api/mobile/task/[id]/member/route.ts new file mode 100644 index 0000000..0330080 --- /dev/null +++ b/src/app/api/mobile/task/[id]/member/route.ts @@ -0,0 +1,101 @@ +import { prisma } from "@/module/_global"; +import { funGetUserByCookies, funGetUserById } from "@/module/auth"; +import { createLogUser, createLogUserMobile } from "@/module/user"; +import _ from "lodash"; +import { NextResponse } from "next/server"; + +// ADD MEMBER TASK DIVISI +export async function POST(request: Request, context: { params: { id: string } }) { + try { + const { id } = context.params; + const { member, idDivision, user } = (await request.json()); + + const userMobile = await funGetUserById({ id: String(user) }) + if (userMobile.id == "null" || userMobile.id == undefined || userMobile.id == "") { + return NextResponse.json({ success: false, message: "Anda harus login untuk mengakses ini" }, { status: 200 }); + } + + const data = await prisma.divisionProject.count({ + where: { + id: id, + }, + }); + + if (data == 0) { + return NextResponse.json( + { + success: false, + message: "Tambah anggota tugas gagal, data tugas tidak ditemukan", + }, + { status: 200 } + ); + } + + if (member.length > 0) { + const dataMember = member.map((v: any) => ({ + ..._.omit(v, ["idUser", "name", "img"]), + idDivision: idDivision, + idProject: id, + idUser: v.idUser, + })) + + const insertMember = await prisma.divisionProjectMember.createMany({ + data: dataMember + }) + } + + // create log user + const log = await createLogUserMobile({ act: 'CREATE', desc: 'User menambahkan anggota tugas divisi', table: 'divisionProject', data: id, user: userMobile.id }) + + + return NextResponse.json({ success: true, message: "Berhasil menambahkan anggota tugas", }, { status: 200 }); + } catch (error) { + console.error(error); + return NextResponse.json({ success: false, message: "Gagal menambah anggota tugas, coba lagi nanti (error: 500)", reason: (error as Error).message, }, { status: 500 }); + } +} + +// MENGELUARKAN ANGGOTA +export async function DELETE(request: Request, context: { params: { id: string } }) { + try { + const { id } = context.params; + const { idUser, user } = (await request.json()); + + const userMobile = await funGetUserById({ id: String(user) }) + if (userMobile.id == "null" || userMobile.id == undefined || userMobile.id == "") { + return NextResponse.json({ success: false, message: "Anda harus login untuk mengakses ini" }, { status: 200 }); + } + + const data = await prisma.divisionProject.count({ + where: { + id: id, + }, + }); + + + if (data == 0) { + return NextResponse.json( + { + success: false, + message: "Gagal, data tugas tidak ditemukan", + }, + { status: 200 } + ); + } + + const del = await prisma.divisionProjectMember.deleteMany({ + where: { + idUser: idUser, + idProject: id + } + }) + + // create log user + const log = await createLogUserMobile({ act: 'DELETE', desc: 'User mengeluarkan anggota dari tugas divisi', table: 'divisionProject', data: id, user: userMobile.id }) + + return NextResponse.json({ success: true, message: "Berhasil mengeluarkan anggota", }, { status: 200 }); + } catch (error) { + console.error(error); + return NextResponse.json({ success: false, message: "Gagal mengeluarkan anggota, coba lagi nanti (error: 500)", reason: (error as Error).message, }, { status: 500 }); + } +} diff --git a/src/app/api/mobile/task/[id]/route.ts b/src/app/api/mobile/task/[id]/route.ts new file mode 100644 index 0000000..8328320 --- /dev/null +++ b/src/app/api/mobile/task/[id]/route.ts @@ -0,0 +1,339 @@ +import { prisma } from "@/module/_global"; +import { funGetUserById } from "@/module/auth"; +import { createLogUserMobile } from "@/module/user"; +import _ from "lodash"; +import moment from "moment"; +import "moment/locale/id"; +import { NextResponse } from "next/server"; + + +// GET DETAIL TASK DIVISI / GET ONE +export async function GET(request: Request, context: { params: { id: string } }) { + try { + let allData + const { id } = context.params; + const { searchParams } = new URL(request.url); + const kategori = searchParams.get("cat"); + const user = searchParams.get("user"); + + const userMobile = await funGetUserById({ id: String(user) }) + if (userMobile.id == "null" || userMobile.id == undefined || userMobile.id == "") { + return NextResponse.json({ success: false, message: "Anda harus login untuk mengakses ini" }, { status: 200 }); + } + + const data = await prisma.divisionProject.findUnique({ + where: { + id: String(id), + isActive: true + } + }); + + if (!data) { + return NextResponse.json({ success: false, message: "Gagal mendapatkan tugas, data tidak ditemukan", }, { status: 200 }); + } + + if (kategori == "data") { + allData = data + } else if (kategori == "progress") { + const dataProgress = await prisma.divisionProjectTask.findMany({ + where: { + isActive: true, + idProject: String(id) + }, + orderBy: { + updatedAt: 'desc' + } + }) + + if (dataProgress.length > 0) { + const semua = dataProgress.length + const selesai = _.filter(dataProgress, { status: 1 }).length + const progress = Math.ceil((selesai / semua) * 100) + + allData = { + progress: progress, + lastUpdate: moment(dataProgress[0]?.updatedAt).format("DD MMMM YYYY"), + } + } else { + allData = { + progress: 0, + lastUpdate: '1 Januari 1999', + } + } + + + } else if (kategori == "task") { + const dataProgress = await prisma.divisionProjectTask.findMany({ + where: { + isActive: true, + idProject: String(id) + }, + select: { + id: true, + title: true, + status: true, + dateStart: true, + dateEnd: true, + }, + orderBy: { + createdAt: 'asc' + } + }) + + const fix = dataProgress.map((v: any) => ({ + ..._.omit(v, ["dateStart", "dateEnd"]), + dateStart: moment(v.dateStart).format("DD-MM-YYYY"), + dateEnd: moment(v.dateEnd).format("DD-MM-YYYY"), + })) + + allData = fix + + } else if (kategori == "file") { + const dataFile = await prisma.divisionProjectFile.findMany({ + where: { + isActive: true, + idProject: String(id) + }, + select: { + id: true, + ContainerFileDivision: { + select: { + id: true, + name: true, + extension: true, + idStorage: true + } + } + } + }) + + const fix = dataFile.map((v: any) => ({ + ..._.omit(v, ["ContainerFileDivision"]), + nameInStorage: v.ContainerFileDivision.id, + name: v.ContainerFileDivision.name, + extension: v.ContainerFileDivision.extension, + idStorage: v.ContainerFileDivision.idStorage, + })) + + allData = fix + + } else if (kategori == "member") { + const dataMember = await prisma.divisionProjectMember.findMany({ + where: { + isActive: true, + idProject: String(id) + }, + select: { + id: true, + idUser: true, + User: { + select: { + name: true, + email: true, + img: true, + Position: { + select: { + name: true + } + } + } + } + } + }) + + + const fix = dataMember.map((v: any) => ({ + ..._.omit(v, ["User"]), + name: v.User.name, + email: v.User.email, + img: v.User.img, + position: v.User.Position.name + })) + + allData = fix + } + + return NextResponse.json({ success: true, message: "Berhasil mendapatkan tugas divisi", data: allData }, { status: 200 }); + + } + catch (error) { + console.error(error); + return NextResponse.json({ success: false, message: "Gagal mendapatkan tugas divisi, coba lagi nanti (error: 500)", reason: (error as Error).message, }, { status: 500 }); + } +} + + +// CREATE NEW DETAIL TASK DIVISI +export async function POST(request: Request, context: { params: { id: string } }) { + try { + const { id } = context.params; + const { title, dateStart, dateEnd, idDivision, user } = (await request.json()); + const userMobile = await funGetUserById({ id: String(user) }) + + if (userMobile.id == "null" || userMobile.id == undefined || userMobile.id == "") { + return NextResponse.json({ success: false, message: "Anda harus login untuk mengakses ini" }, { status: 200 }); + } + + const data = await prisma.divisionProject.count({ + where: { + id: id, + }, + }); + + if (data == 0) { + return NextResponse.json( + { + success: false, + message: "Tambah detail tugas gagal, data tugas tidak ditemukan", + }, + { status: 200 } + ); + } + + const create = await prisma.divisionProjectTask.create({ + data: { + idProject: id, + idDivision, + title, + dateStart: new Date(dateStart), + dateEnd: new Date(dateEnd), + }, + select: { + id: true + } + }); + + // const cek progress + const dataTask = await prisma.divisionProjectTask.findMany({ + where: { + isActive: true, + idProject: id + } + }) + + const semua = dataTask.length + const selesai = _.filter(dataTask, { status: 1 }).length + const progress = Math.ceil((selesai / semua) * 100) + let statusProject = 1 + + if (progress == 100) { + statusProject = 2 + } else if (progress == 0) { + statusProject = 0 + } + + const updProject = await prisma.divisionProject.update({ + where: { + id: id + }, + data: { + status: statusProject + } + }) + + // create log user + const log = await createLogUserMobile({ act: 'CREATE', desc: 'User menambahkan detail tugas divisi', table: 'divisionProjectTask', data: create.id, user: userMobile.id }) + + return NextResponse.json({ success: true, message: "Detail tugas berhasil ditambahkan", data, }, { status: 200 }); + } catch (error) { + console.error(error); + return NextResponse.json({ success: false, message: "Gagal mengedit detail tugas, coba lagi nanti (error: 500)", reason: (error as Error).message, }, { status: 500 }); + } +} + + + +// PEMBATALAN TASK DIVISI +export async function DELETE(request: Request, context: { params: { id: string } }) { + try { + const { id } = context.params; + const { reason, user } = (await request.json()); + + const userMobile = await funGetUserById({ id: String(user) }) + if (userMobile.id == "null" || userMobile.id == undefined || userMobile.id == "") { + return NextResponse.json({ success: false, message: "Anda harus login untuk mengakses ini" }, { status: 200 }); + } + + const data = await prisma.divisionProject.count({ + where: { + id: id, + }, + }); + + if (data == 0) { + return NextResponse.json( + { + success: false, + message: "Pembatalan tugas gagal, data tugas tidak ditemukan", + }, + { status: 200 } + ); + } + + const update = await prisma.divisionProject.update({ + where: { + id + }, + data: { + reason: reason, + status: 3 + } + }); + + // create log user + const log = await createLogUserMobile({ act: 'UPDATE', desc: 'User membatalkan tugas divisi', table: 'divisionProject', data: id, user: userMobile.id }) + + return NextResponse.json({ success: true, message: "Tugas berhasil dibatalkan", }, { status: 200 }); + } catch (error) { + console.error(error); + return NextResponse.json({ success: false, message: "Gagal membatalkan tugas, coba lagi nanti (error: 500)", reason: (error as Error).message, }, { status: 500 }); + } +} + + +// EDIT TASK DIVISI +export async function PUT(request: Request, context: { params: { id: string } }) { + try { + const { id } = context.params; + const { title, user } = (await request.json()); + + const userMobile = await funGetUserById({ id: String(user) }) + if (userMobile.id == "null" || userMobile.id == undefined || userMobile.id == "") { + return NextResponse.json({ success: false, message: "Anda harus login untuk mengakses ini" }, { status: 200 }); + } + + const data = await prisma.divisionProject.count({ + where: { + id: id, + }, + }); + + if (data == 0) { + return NextResponse.json( + { + success: false, + message: "Tugas gagal diedit, data tugas tidak ditemukan", + }, + { status: 200 } + ); + } + + const update = await prisma.divisionProject.update({ + where: { + id + }, + data: { + title + } + }); + + // create log user + const log = await createLogUserMobile({ act: 'UPDATE', desc: 'User mengupdate data tugas divisi', table: 'divisionProject', data: id, user: userMobile.id }) + + return NextResponse.json({ success: true, message: "Tugas berhasil diedit", }, { status: 200 }); + } catch (error) { + console.error(error); + return NextResponse.json({ success: false, message: "Gagal mengedit tugas, coba lagi nanti (error: 500)", reason: (error as Error).message, }, { status: 500 }); + } +} + diff --git a/src/app/api/mobile/task/detail/[id]/route.ts b/src/app/api/mobile/task/detail/[id]/route.ts new file mode 100644 index 0000000..cc53e39 --- /dev/null +++ b/src/app/api/mobile/task/detail/[id]/route.ts @@ -0,0 +1,243 @@ +import { prisma } from "@/module/_global"; +import { funGetUserById } from "@/module/auth"; +import { createLogUserMobile } from "@/module/user"; +import _ from "lodash"; +import { NextResponse } from "next/server"; + + +// HAPUS DETAIL TASK +export async function DELETE(request: Request, context: { params: { id: string } }) { + try { + const { id } = context.params; + const { idProject, user } = (await request.json()); + + const userMobile = await funGetUserById({ id: String(user) }) + if (userMobile.id == "null" || userMobile.id == undefined || userMobile.id == "") { + return NextResponse.json({ success: false, message: "Anda harus login untuk mengakses ini" }, { status: 200 }); + } + + const data = await prisma.divisionProjectTask.count({ + where: { + id: id, + }, + }); + + if (data == 0) { + return NextResponse.json( + { + success: false, + message: "Hapus tugas gagal, data tidak ditemukan", + }, + { status: 200 } + ); + } + + const update = await prisma.divisionProjectTask.update({ + where: { + id: id, + }, + data: { + isActive: false, + }, + }); + + // const cek progress + const dataTask = await prisma.divisionProjectTask.findMany({ + where: { + isActive: true, + idProject: idProject + } + }) + + const semua = dataTask.length + const selesai = _.filter(dataTask, { status: 1 }).length + const progress = Math.ceil((selesai / semua) * 100) + let statusProject = 1 + + if (progress == 100) { + statusProject = 2 + } else if (progress == 0) { + statusProject = 0 + } + + const updProject = await prisma.divisionProject.update({ + where: { + id: idProject + }, + data: { + status: statusProject + } + }) + + // create log user + const log = await createLogUserMobile({ act: 'DELETE', desc: 'User menghapus detail task divisi', table: 'divisionProjectTask', data: id, user: userMobile.id }) + + return NextResponse.json({ success: true, message: "Tugas berhasil dihapus", }, { status: 200 }); + } catch (error) { + console.error(error); + return NextResponse.json({ success: false, message: "Gagal menghapus tugas divisi, coba lagi nanti (error: 500)", reason: (error as Error).message, }, { status: 500 }); + } +} + +// EDIT STATUS DETAIL TASK +export async function PUT(request: Request, context: { params: { id: string } }) { + try { + const { id } = context.params; + const { status, idProject, user } = (await request.json()); + + const userMobile = await funGetUserById({ id: String(user) }) + if (userMobile.id == "null" || userMobile.id == undefined || userMobile.id == "") { + return NextResponse.json({ success: false, message: "Anda harus login untuk mengakses ini" }, { status: 200 }); + } + + + const data = await prisma.divisionProjectTask.count({ + where: { + id: id, + }, + }); + + + if (data == 0) { + return NextResponse.json( + { + success: false, + message: "Update status detail tugas gagal, data tidak ditemukan", + }, + { status: 200 } + ); + } + + + const update = await prisma.divisionProjectTask.update({ + where: { + id: id, + }, + data: { + status: status, + }, + }); + + + // const cek progress + const dataTask = await prisma.divisionProjectTask.findMany({ + where: { + isActive: true, + idProject: idProject + } + }) + + const semua = dataTask.length + const selesai = _.filter(dataTask, { status: 1 }).length + const progress = Math.ceil((selesai / semua) * 100) + let statusProject = 1 + + if (progress == 100) { + statusProject = 2 + } else if (progress == 0) { + statusProject = 0 + } + + + const updProject = await prisma.divisionProject.update({ + where: { + id: idProject + }, + data: { + status: statusProject + } + }) + + + // create log user + const log = await createLogUserMobile({ act: 'UPDATE', desc: 'User mengupdate status detail task divisi', table: 'divisionProjectTask', data: id, user: userMobile.id }) + + return NextResponse.json({ success: true, message: "Status detail tugas berhasil diupdate", data, }, { status: 200 }); + } catch (error) { + console.error(error); + return NextResponse.json({ success: false, message: "Gagal mengupdate status detail tugas, coba lagi nanti (error: 500)", reason: (error as Error).message, }, { status: 500 }); + } +} + + +// GET ONE DETAIL TASK +export async function GET(request: Request, context: { params: { id: string } }) { + try { + const { id } = context.params; + const { searchParams } = new URL(request.url); + const user = searchParams.get("user"); + + const userMobile = await funGetUserById({ id: String(user) }) + if (userMobile.id == "null" || userMobile.id == undefined || userMobile.id == "") { + return NextResponse.json({ success: false, message: "Anda harus login untuk mengakses ini" }, { status: 200 }); + } + + const data = await prisma.divisionProjectTask.findUnique({ + where: { + id: String(id), + isActive: true + } + }); + + if (!data) { + return NextResponse.json({ success: false, message: "Gagal mendapatkan detail tugas, data tidak ditemukan" }, { status: 200 }); + } + + return NextResponse.json({ success: true, message: "Berhasil mendapatkan detail tugas divisi", data }, { status: 200 }); + + } + catch (error) { + console.error(error); + return NextResponse.json({ success: false, message: "Gagal mendapatkan detail tugas divisi, coba lagi nanti (error: 500)", reason: (error as Error).message, }, { status: 500 }); + } +} + + + +// EDIT DETAIL TASK +export async function POST(request: Request, context: { params: { id: string } }) { + try { + const { id } = context.params; + const { title, dateStart, dateEnd, user } = (await request.json()); + + const userMobile = await funGetUserById({ id: String(user) }) + if (userMobile.id == "null" || userMobile.id == undefined || userMobile.id == "") { + return NextResponse.json({ success: false, message: "Anda harus login untuk mengakses ini" }, { status: 200 }); + } + + const data = await prisma.divisionProjectTask.count({ + where: { + id: id, + }, + }); + + if (data == 0) { + return NextResponse.json( + { + success: false, + message: "Edit detail tugas gagal, data tidak ditemukan", + }, + { status: 200 } + ); + } + + const update = await prisma.divisionProjectTask.update({ + where: { + id: id, + }, + data: { + title, + dateStart: new Date(dateStart), + dateEnd: new Date(dateEnd), + }, + }); + + // create log user + const log = await createLogUserMobile({ act: 'UPDATE', desc: 'User mengupdate data detail task divisi', table: 'divisionProjectTask', data: id, user: userMobile.id }) + + return NextResponse.json({ success: true, message: "Detail tugas berhasil diedit", data, }, { status: 200 }); + } catch (error) { + console.error(error); + return NextResponse.json({ success: false, message: "Gagal mengedit detail tugas, coba lagi nanti (error: 500)", reason: (error as Error).message, }, { status: 500 }); + } +} \ No newline at end of file diff --git a/src/app/api/mobile/task/file/[id]/route.ts b/src/app/api/mobile/task/file/[id]/route.ts new file mode 100644 index 0000000..e1eed89 --- /dev/null +++ b/src/app/api/mobile/task/file/[id]/route.ts @@ -0,0 +1,227 @@ +import { DIR, funDeleteFile, funUploadFile, prisma } from "@/module/_global"; +import { funGetUserById } from "@/module/auth"; +import { createLogUserMobile } from "@/module/user"; +import _ from "lodash"; +import { NextResponse } from "next/server"; + +// HAPUS DETAIL FILE, HAPUS FILE DI ASSETS DAN DATABASE (BUKAN PAKE ISACTIVE) +export async function DELETE(request: Request, context: { params: { id: string } }) { + try { + const { id } = context.params; + const { user } = (await request.json()) + + const userMobile = await funGetUserById({ id: String(user) }) + if (userMobile.id == "null" || userMobile.id == undefined || userMobile.id == "") { + return NextResponse.json({ success: false, message: "Anda harus login untuk mengakses ini" }, { status: 200 }); + } + + const data = await prisma.divisionProjectFile.count({ + where: { + id: id, + }, + }); + + if (data == 0) { + return NextResponse.json( + { + success: false, + message: "Hapus file gagal, data tidak ditemukan", + }, + { status: 200 } + ); + } + + const dataRelasi = await prisma.divisionProjectFile.findUnique({ + where: { + id: id, + } + }) + + const dataFile = await prisma.containerFileDivision.findUnique({ + where: { + id: dataRelasi?.idFile + } + }) + + await funDeleteFile({ fileId: String(dataFile?.idStorage) }) + + const deleteRelasi = await prisma.divisionProjectFile.delete({ + where: { + id: id, + }, + }); + + const deleteFile = await prisma.containerFileDivision.delete({ + where: { + id: dataRelasi?.idFile, + }, + }); + + // create log user + const log = await createLogUserMobile({ act: 'DELETE', desc: 'User menghapus file tugas divisi', table: 'divisionProject', data: String(dataRelasi?.idProject), user: userMobile.id }) + + return NextResponse.json({ success: true, message: "File berhasil dihapus", data, }, { status: 200 }); + + } catch (error) { + console.error(error); + return NextResponse.json({ success: false, message: "Gagal menghapus file, coba lagi nanti (error: 500)", reason: (error as Error).message, }, { status: 500 }); + } +} + + +// TAMBAH FILE TASK DIVISI +export async function POST(request: Request, context: { params: { id: string } }) { + try { + + const { id } = context.params; + const body = await request.formData() + const data = JSON.parse(body.get("data") as string) + const user = await funGetUserById({ id: data.user }) + const cekFile = body.has("file0") + + if (user.id == "null" || user.id == undefined || user.id == "") { + return NextResponse.json({ success: false, message: "Anda harus login untuk mengakses ini" }, { status: 200 }); + } + + const dataCek = await prisma.divisionProject.count({ + where: { + id: id, + }, + }); + + if (dataCek == 0) { + return NextResponse.json( + { + success: false, + message: "Tambah file tugas gagal, data tugas tidak ditemukan", + }, + { status: 200 } + ); + } + + const dataProject = await prisma.divisionProject.findUnique({ + where: { + id: id, + }, + }); + + + let fileFix: any[] = [] + + if (cekFile) { + body.delete("data") + for (var pair of body.entries()) { + if (String(pair[0]).substring(0, 4) == "file") { + const file = body.get(pair[0]) as File + const fExt = file.name.split(".").pop() + const fName = file.name.replace("." + fExt, "") + + + const upload = await funUploadFile({ file: file, dirId: DIR.task }) + if (upload.success) { + const insertToContainer = await prisma.containerFileDivision.create({ + data: { + idDivision: String(dataProject?.idDivision), + name: fName, + extension: String(fExt), + idStorage: upload.data.id + }, + select: { + id: true + } + }) + + const dataFile = { + idProject: id, + idDivision: dataProject?.idDivision, + idFile: insertToContainer.id, + createdBy: user.id, + } + + fileFix.push(dataFile) + } + } + } + + const insertFile = await prisma.divisionProjectFile.createMany({ + data: fileFix + }) + } + + // create log user + const log = await createLogUserMobile({ act: 'CREATE', desc: 'User menambahkan file tugas divisi baru', table: 'divisionProject', data: id, user: user.id }) + return NextResponse.json({ success: true, message: "Berhasil menambahkan file" }, { status: 200 }); + + } catch (error) { + console.error(error); + return NextResponse.json({ success: false, message: "Gagal menambahkan filae, coba lagi nanti (error: 500)", reason: (error as Error).message, }, { status: 500 }); + } +} + + + +// CEK FILE TASK DIVISI APAKAH PERNAH DIUPLOAD PADA TASK YG SAMA +export async function PUT(request: Request, context: { params: { id: string } }) { + try { + const { id } = context.params; + const body = await request.formData() + const data = JSON.parse(body.get("data") as string) + const user = await funGetUserById({ id: data.user }) + + if (user.id == "null" || user.id == undefined || user.id == "") { + return NextResponse.json({ success: false, message: "Anda harus login untuk mengakses ini" }, { status: 200 }); + } + + const file = body.get("file") as File + const fileName = file.name + + const dataCek = await prisma.divisionProject.count({ + where: { + id: id, + }, + }); + + if (dataCek == 0) { + return NextResponse.json( + { + success: false, + message: "Upload file gagal, data tugas tidak ditemukan", + }, + { status: 200 } + ); + } + + const dataTaskFile = await prisma.divisionProjectFile.findMany({ + where: { + idProject: id, + isActive: true + }, + select: { + ContainerFileDivision: { + select: { + name: true, + extension: true + } + } + } + }) + + const dataOmit = dataTaskFile.map((v: any) => ({ + ..._.omit(v, ["ContainerFileDivision"]), + file: v.ContainerFileDivision.name + '.' + v.ContainerFileDivision.extension, + })) + + const cek = dataOmit.some((i: any) => i.file == fileName) + + + if (cek) { + return NextResponse.json({ success: false, message: "File sudah pernah diupload" }, { status: 200 }); + } else { + return NextResponse.json({ success: true, message: "Cek berhasil" }, { status: 200 }); + } + + } catch (error) { + console.error(error); + return NextResponse.json({ success: false, message: "Upload file gagal, coba lagi nanti (error: 500)", reason: (error as Error).message, }, { status: 500 }); + } +} \ No newline at end of file diff --git a/src/app/api/mobile/task/route.ts b/src/app/api/mobile/task/route.ts new file mode 100644 index 0000000..0e3109f --- /dev/null +++ b/src/app/api/mobile/task/route.ts @@ -0,0 +1,331 @@ +import { DIR, funUploadFile, prisma } from "@/module/_global"; +import { funGetUserById } from "@/module/auth"; +import { createLogUserMobile } from "@/module/user"; +import _, { ceil } from "lodash"; +import { NextResponse } from "next/server"; + + +// GET ALL DATA TUGAS DIVISI +export async function GET(request: Request) { + try { + const { searchParams } = new URL(request.url); + const name = searchParams.get('search'); + const divisi = searchParams.get('division'); + const status = searchParams.get('status'); + const page = searchParams.get('page'); + const user = searchParams.get('user'); + const dataSkip = Number(page) * 10 - 10; + + const userMobile = await funGetUserById({ id: String(user) }) + if (userMobile.id == "null" || userMobile.id == undefined || userMobile.id == "") { + return NextResponse.json({ success: false, message: "Anda harus login untuk mengakses ini" }, { status: 200 }); + } + + const cek = await prisma.division.count({ + where: { + // isActive: true, + id: String(divisi) + } + }) + + if (cek == 0) { + return NextResponse.json({ success: false, message: "Gagal mendapatkan divisi, data tidak ditemukan", }, { status: 200 }); + } + + const data = await prisma.divisionProject.findMany({ + // skip: dataSkip, + // take: 10, + where: { + isActive: true, + idDivision: String(divisi), + status: (status == "0" || status == "1" || status == "2" || status == "3") ? Number(status) : 0, + title: { + contains: (name == undefined || name == "null") ? "" : name, + mode: "insensitive" + } + }, + select: { + id: true, + title: true, + desc: true, + status: true, + DivisionProjectTask: { + where: { + isActive: true + }, + select: { + title: true, + status: true + } + }, + DivisionProjectMember: { + where: { + isActive: true + }, + select: { + idUser: true + } + } + }, + orderBy: { + createdAt: "desc" + } + }); + + const formatData = data.map((v: any) => ({ + ..._.omit(v, ["DivisionProjectTask", "DivisionProjectMember"]), + progress: ceil((v.DivisionProjectTask.filter((i: any) => i.status == 1).length * 100) / v.DivisionProjectTask.length), + member: v.DivisionProjectMember.length + })) + + const totalData = await prisma.divisionProject.count({ + where: { + isActive: true, + idDivision: String(divisi), + status: (status == "0" || status == "1" || status == "2" || status == "3") ? Number(status) : 0, + title: { + contains: (name == undefined || name == "null") ? "" : name, + mode: "insensitive" + } + } + }) + + return NextResponse.json({ success: true, message: "Berhasil mendapatkan divisi", data: formatData, total: totalData }, { status: 200 }); + + } catch (error) { + console.error(error); + return NextResponse.json({ success: false, message: "Gagal mendapatkan divisi, coba lagi nanti (error: 500)", reason: (error as Error).message, }, { status: 500 }); + } +} + + +// CREATE PROJECT TASK DIVISION +export async function POST(request: Request) { + try { + const body = await request.formData() + const dataBody = body.get("data") + const cekFile = body.has("file0") + const { title, task, member, idDivision, user } = JSON.parse(dataBody as string) + + const userMobile = await funGetUserById({ id: String(user) }) + if (userMobile.id == "null" || userMobile.id == undefined || userMobile.id == "") { + return NextResponse.json({ success: false, message: "Anda harus login untuk mengakses ini" }, { status: 200 }); + } + + const userId = userMobile.id + const userRoleLogin = userMobile.idUserRole + + + const cek = await prisma.division.count({ + where: { + isActive: true, + id: idDivision + } + }) + + if (cek == 0) { + return NextResponse.json({ success: false, message: "Gagal, data divisi tidak ditemukan", }, { status: 200 }); + } + + const data = await prisma.divisionProject.create({ + data: { + idDivision: idDivision, + title: title, + desc: '' + }, + select: { + id: true + } + }) + + + if (task.length > 0) { + const dataTask = task.map((v: any) => ({ + ..._.omit(v, ["dateStart", "dateEnd", "title"]), + idDivision: idDivision, + idProject: data.id, + title: v.title, + dateStart: new Date(v.dateStart), + dateEnd: new Date(v.dateEnd), + })) + + const insertTask = await prisma.divisionProjectTask.createMany({ + data: dataTask + }) + } + + if (member.length > 0) { + const dataMember = member.map((v: any) => ({ + ..._.omit(v, ["idUser", "name", "img"]), + idDivision: idDivision, + idProject: data.id, + idUser: v.idUser, + })) + + const insertMember = await prisma.divisionProjectMember.createMany({ + data: dataMember + }) + } + + + + let fileFix: any[] = [] + + if (cekFile) { + for (var pair of body.entries()) { + if (String(pair[0]).substring(0, 4) == "file") { + const file = body.get(pair[0]) as File + const fExt = file.name.split(".").pop() + const fName = file.name.replace("." + fExt, "") + + const upload = await funUploadFile({ file: file, dirId: DIR.task }) + if (upload.success) { + const insertToContainer = await prisma.containerFileDivision.create({ + data: { + idDivision: idDivision, + name: fName, + extension: String(fExt), + idStorage: upload.data.id + }, + select: { + id: true + } + }) + + const dataFile = { + idProject: data.id, + idDivision: idDivision, + idFile: insertToContainer.id, + createdBy: userMobile.id, + } + + fileFix.push(dataFile) + } + } + } + + const insertFile = await prisma.divisionProjectFile.createMany({ + data: fileFix + }) + } + + const memberDivision = await prisma.divisionMember.findMany({ + where: { + idDivision: idDivision + }, + select: { + User: { + select: { + id: true, + Subscribe: { + select: { + subscription: true + } + } + } + } + } + }) + + // mengirim notifikasi + // datanotif untuk realtime notifikasi + // datapush untuk web push notifikasi ketika aplikasi tidak aktif + const dataNotif = memberDivision.map((v: any) => ({ + ..._.omit(v, ["User", "Subscribe"]), + idUserTo: v.User.id, + idUserFrom: String(userMobile.id), + category: 'division/' + idDivision + '/task', + idContent: data.id, + title: 'Tugas Baru', + desc: 'Terdapat tugas baru. Silahkan periksa detailnya.' + })) + + const dataPush = memberDivision.map((v: any) => ({ + ..._.omit(v, ["User", "Subscribe"]), + idUser: v.User.id, + subscription: v.User.Subscribe?.subscription, + })) + + if (userRoleLogin != "supadmin") { + const perbekel = await prisma.user.findFirst({ + where: { + isActive: true, + idUserRole: "supadmin", + idVillage: user.idVillage + }, + select: { + id: true, + Subscribe: { + select: { + subscription: true + } + } + } + }) + + dataNotif.push({ + idUserTo: perbekel?.id, + idUserFrom: userId, + category: 'division/' + idDivision + '/task', + idContent: data.id, + title: 'Tugas Baru', + desc: 'Terdapat tugas baru. Silahkan periksa detailnya.' + }) + + dataPush.push({ + idUser: perbekel?.id, + subscription: perbekel?.Subscribe?.subscription + }) + } + + if (userRoleLogin != "cosupadmin") { + const ketuaGrup = await prisma.user.findFirst({ + where: { + isActive: true, + idUserRole: "cosupadmin", + idGroup: user.idGroup + }, + select: { + id: true, + Subscribe: { + select: { + subscription: true + } + } + } + }) + + dataNotif.push({ + idUserTo: ketuaGrup?.id, + idUserFrom: userId, + category: 'division/' + idDivision + '/task', + idContent: data.id, + title: 'Tugas Baru', + desc: 'Terdapat tugas baru. Silahkan periksa detailnya.' + }) + + dataPush.push({ + idUser: ketuaGrup?.id, + subscription: ketuaGrup?.Subscribe?.subscription + }) + } + + const pushNotif = dataPush.filter((item) => item.subscription != undefined) + + // const sendWebPush = await funSendWebPush({ sub: pushNotif, message: { body: 'Terdapat tugas baru. Silahkan periksa detailnya.', title: 'Tugas Baru' } }) + const insertNotif = await prisma.notifications.createMany({ + data: dataNotif + }) + + + // create log user + const log = await createLogUserMobile({ act: 'CREATE', desc: 'User membuat tugas divisi baru', table: 'divisionProject', data: data.id, user: userMobile.id }) + + + return NextResponse.json({ success: true, message: "Berhasil membuat tugas divisi", notif: dataNotif }, { status: 200 }); + + } catch (error) { + console.error(error); + return NextResponse.json({ success: false, message: "Gagal membuat tugas divisi, coba lagi nanti (error: 500)", reason: (error as Error).message, }, { status: 500 }); + } +} \ No newline at end of file