feat(ekonomi): implement UMKM module with CRUD API and Dashboard analytics

This commit is contained in:
2026-04-20 16:51:59 +08:00
parent 97902f6277
commit 58ab306428
34 changed files with 2944 additions and 2 deletions

View File

@@ -11,6 +11,10 @@ import DemografiPekerjaan from "./demografi-pekerjaan";
import JumlahPengangguran from "./jumlah-pengangguran";
import PendapatanAsliDesa from "./pendapatan-asli-desa";
import StrukturOrganisasi from "./struktur-bumdes";
import Umkm from "./umkm";
import ProdukUmkm from "./umkm/produk";
import PenjualanProduk from "./umkm/penjualan";
import UmkmDashboard from "./umkm/dashboard";
const Ekonomi = new Elysia({
prefix: "/ekonomi",
@@ -21,6 +25,10 @@ const Ekonomi = new Elysia({
.use(LowonganKerja)
.use(ProgramKemiskinan)
.use(StrukturOrganisasi)
.use(Umkm)
.use(ProdukUmkm)
.use(PenjualanProduk)
.use(UmkmDashboard)
.use(GrafikUsiaKerjaYangMenganggur)
.use(GrafikMenganggurBerdasarkanPendidikan)
.use(JumlahPendudukMiskin)

View File

@@ -0,0 +1,35 @@
import prisma from "@/lib/prisma";
import { Context } from "elysia";
async function umkmCreate(context: Context) {
const body = context.body as any;
try {
const data = await prisma.umkm.create({
data: {
nama: body.nama,
pemilik: body.pemilik,
deskripsi: body.deskripsi,
alamat: body.alamat,
kontak: body.kontak,
imageId: body.imageId,
kategoriId: body.kategoriId,
isActive: body.isActive ?? true,
},
});
return {
success: true,
message: "Berhasil membuat UMKM baru",
data,
};
} catch (e) {
console.error("Error di umkmCreate:", e);
return {
success: false,
message: "Gagal membuat UMKM baru",
};
}
}
export default umkmCreate;

View File

@@ -0,0 +1,72 @@
import prisma from "@/lib/prisma";
import { Context } from "elysia";
async function umkmDashboardDetailPenjualan(context: Context) {
const periode = (context.query.periode as string) ||
`${new Date().getFullYear()}-${String(new Date().getMonth() + 1).padStart(2, '0')}`;
const date = new Date(periode + "-01");
date.setMonth(date.getMonth() - 1);
const periodeLalu = `${date.getFullYear()}-${String(date.getMonth() + 1).padStart(2, '0')}`;
try {
// Ambil semua produk yang punya penjualan bulan ini atau bulan lalu
const [produkSkrg, produkLalu, allProduks] = await Promise.all([
prisma.penjualanProduk.groupBy({
by: ['produkId'],
where: { periode, deletedAt: null },
_sum: { totalNilai: true, jumlah: true }
}),
prisma.penjualanProduk.groupBy({
by: ['produkId'],
where: { periode: periodeLalu, deletedAt: null },
_sum: { totalNilai: true }
}),
prisma.produkUmkm.findMany({
where: { deletedAt: null },
select: { id: true, nama: true, stok: true }
})
]);
const data = allProduks.map(p => {
const skrgRaw = produkSkrg.find(s => s.produkId === p.id)?._sum || { totalNilai: 0, jumlah: 0 };
const laluRaw = produkLalu.find(l => l.produkId === p.id)?._sum || { totalNilai: 0 };
const skrg = {
totalNilai: skrgRaw.totalNilai || 0,
jumlah: skrgRaw.jumlah || 0
};
const lalu = {
totalNilai: laluRaw.totalNilai || 0
};
let trend = "stable";
if (skrg.totalNilai > lalu.totalNilai) trend = "up";
if (skrg.totalNilai < lalu.totalNilai) trend = "down";
let statusStok = "Aman";
if (p.stok < 5) statusStok = "Rendah";
else if (p.stok < 20) statusStok = "Menipis";
return {
namaProduk: p.nama,
penjualanBulanIni: skrg.totalNilai,
penjualanBulanLalu: lalu.totalNilai,
trend,
volume: skrg.jumlah,
stok: p.stok,
statusStok
};
});
return {
success: true,
data
};
} catch (e) {
console.error("Error di umkmDashboardDetailPenjualan:", e);
return { success: false, message: "Gagal mengambil detail penjualan dashboard" };
}
}
export default umkmDashboardDetailPenjualan;

View File

@@ -0,0 +1,16 @@
import Elysia from "elysia";
import umkmDashboardKpi from "./kpi";
import umkmDashboardRingSummary from "./ringSummary";
import umkmDashboardTopProduk from "./topProduk";
import umkmDashboardDetailPenjualan from "./detailPenjualan";
const UmkmDashboard = new Elysia({
prefix: "/umkm/dashboard",
tags: ["Ekonomi/UMKM Dashboard"],
})
.get("/kpi", umkmDashboardKpi)
.get("/ringkasan-penjualan", umkmDashboardRingSummary)
.get("/top-produk", umkmDashboardTopProduk)
.get("/detail-penjualan", umkmDashboardDetailPenjualan);
export default UmkmDashboard;

View File

@@ -0,0 +1,49 @@
import prisma from "@/lib/prisma";
import { Context } from "elysia";
async function umkmDashboardKpi(context: Context) {
const periode = (context.query.periode as string) ||
`${new Date().getFullYear()}-${String(new Date().getMonth() + 1).padStart(2, '0')}`;
try {
const [umkmAktif, totalUmkm, omzetBulanan, kategoriTerbanyak] = await Promise.all([
prisma.umkm.count({ where: { isActive: true, deletedAt: null } }),
prisma.umkm.count({ where: { deletedAt: null } }),
prisma.penjualanProduk.aggregate({
where: { periode, deletedAt: null },
_sum: { totalNilai: true }
}),
prisma.umkm.groupBy({
by: ['kategoriId'],
_count: { _all: true },
orderBy: { _count: { kategoriId: 'desc' } },
take: 1
})
]);
// Ambil nama kategori jika ada
let kategoriNama = "-";
if (kategoriTerbanyak.length > 0) {
const kat = await prisma.kategoriProduk.findUnique({
where: { id: kategoriTerbanyak[0].kategoriId },
select: { nama: true }
});
kategoriNama = kat?.nama || "-";
}
return {
success: true,
data: {
umkmAktif,
totalUmkm,
omzetBulanan: omzetBulanan._sum.totalNilai || 0,
kategoriTerbanyak: kategoriNama
}
};
} catch (e) {
console.error("Error di umkmDashboardKpi:", e);
return { success: false, message: "Gagal mengambil data KPI dashboard" };
}
}
export default umkmDashboardKpi;

View File

@@ -0,0 +1,52 @@
import prisma from "@/lib/prisma";
import { Context } from "elysia";
async function umkmDashboardRingSummary(context: Context) {
const periode = (context.query.periode as string) ||
`${new Date().getFullYear()}-${String(new Date().getMonth() + 1).padStart(2, '0')}`;
// Hitung periode bulan lalu
const date = new Date(periode + "-01");
date.setMonth(date.getMonth() - 1);
const periodeLalu = `${date.getFullYear()}-${String(date.getMonth() + 1).padStart(2, '0')}`;
try {
const [penjualanSkrg, penjualanLalu, produkAktif, totalTransaksi] = await Promise.all([
prisma.penjualanProduk.aggregate({
where: { periode, deletedAt: null },
_sum: { totalNilai: true }
}),
prisma.penjualanProduk.aggregate({
where: { periode: periodeLalu, deletedAt: null },
_sum: { totalNilai: true }
}),
prisma.produkUmkm.count({ where: { isActive: true, deletedAt: null } }),
prisma.penjualanProduk.count({ where: { periode, deletedAt: null } })
]);
const skrg = penjualanSkrg._sum.totalNilai || 0;
const lalu = penjualanLalu._sum.totalNilai || 0;
let persentasePerubahan = 0;
if (lalu > 0) {
persentasePerubahan = ((skrg - lalu) / lalu) * 100;
} else if (skrg > 0) {
persentasePerubahan = 100;
}
return {
success: true,
data: {
totalPenjualan: skrg,
persentasePerubahan: Math.round(persentasePerubahan * 100) / 100,
produkAktif,
totalTransaksi
}
};
} catch (e) {
console.error("Error di umkmDashboardRingSummary:", e);
return { success: false, message: "Gagal mengambil ringkasan dashboard" };
}
}
export default umkmDashboardRingSummary;

View File

@@ -0,0 +1,42 @@
import prisma from "@/lib/prisma";
import { Context } from "elysia";
async function umkmDashboardTopProduk(context: Context) {
const periode = (context.query.periode as string) ||
`${new Date().getFullYear()}-${String(new Date().getMonth() + 1).padStart(2, '0')}`;
try {
const topPenjualan = await prisma.penjualanProduk.groupBy({
by: ['produkId'],
where: { periode, deletedAt: null },
_sum: { totalNilai: true, jumlah: true },
orderBy: { _sum: { totalNilai: 'desc' } },
take: 3
});
const data = await Promise.all(topPenjualan.map(async (item) => {
const produk = await prisma.produkUmkm.findUnique({
where: { id: item.produkId },
include: { umkm: true }
});
return {
namaProduk: produk?.nama || "Unknown",
namaUmkm: produk?.umkm.nama || "Unknown",
totalPenjualan: item._sum.totalNilai || 0,
jumlahTerjual: item._sum.jumlah || 0,
growth: 0 // logic growth bisa ditambah jika diperlukan
};
}));
return {
success: true,
data
};
} catch (e) {
console.error("Error di umkmDashboardTopProduk:", e);
return { success: false, message: "Gagal mengambil top produk" };
}
}
export default umkmDashboardTopProduk;

View File

@@ -0,0 +1,31 @@
import prisma from "@/lib/prisma";
import { Context } from "elysia";
async function umkmDelete(context: Context) {
const id = context.params.id;
try {
// Soft delete
const data = await prisma.umkm.update({
where: { id },
data: {
deletedAt: new Date(),
isActive: false,
},
});
return {
success: true,
message: "Berhasil menghapus UMKM",
data,
};
} catch (e) {
console.error("Error di umkmDelete:", e);
return {
success: false,
message: "Gagal menghapus UMKM",
};
}
}
export default umkmDelete;

View File

@@ -0,0 +1,59 @@
/* eslint-disable @typescript-eslint/no-explicit-any */
import prisma from "@/lib/prisma";
import { Context } from "elysia";
async function umkmFindMany(context: Context) {
const page = Number(context.query.page) || 1;
const limit = Number(context.query.limit) || 10;
const search = (context.query.search as string) || '';
const kategoriId = context.query.kategoriId as string | undefined;
const skip = (page - 1) * limit;
const where: any = { deletedAt: null };
if (kategoriId) {
where.kategoriId = kategoriId;
}
if (search) {
where.OR = [
{ nama: { contains: search, mode: 'insensitive' } },
{ pemilik: { contains: search, mode: 'insensitive' } },
{ alamat: { contains: search, mode: 'insensitive' } },
];
}
try {
const [data, total] = await Promise.all([
prisma.umkm.findMany({
where,
include: {
image: true,
kategori: true,
},
skip,
take: limit,
orderBy: { createdAt: 'desc' },
}),
prisma.umkm.count({ where }),
]);
return {
success: true,
message: "Berhasil mengambil data UMKM",
data,
page,
limit,
total,
totalPages: Math.ceil(total / limit),
};
} catch (e) {
console.error("Error di umkmFindMany:", e);
return {
success: false,
message: "Gagal mengambil data UMKM",
};
}
}
export default umkmFindMany;

View File

@@ -0,0 +1,31 @@
import prisma from "@/lib/prisma";
async function umkmFindManyAll() {
try {
const data = await prisma.umkm.findMany({
where: {
isActive: true,
deletedAt: null,
},
select: {
id: true,
nama: true,
},
orderBy: { nama: 'asc' },
});
return {
success: true,
message: "Berhasil mengambil semua UMKM aktif",
data,
};
} catch (e) {
console.error("Error di umkmFindManyAll:", e);
return {
success: false,
message: "Gagal mengambil data UMKM",
};
}
}
export default umkmFindManyAll;

View File

@@ -0,0 +1,41 @@
import prisma from "@/lib/prisma";
import { Context } from "elysia";
async function umkmFindUnique(context: Context) {
const id = context.params.id;
try {
const data = await prisma.umkm.findUnique({
where: { id },
include: {
image: true,
kategori: true,
produk: {
where: { deletedAt: null },
include: { image: true }
}
},
});
if (!data) {
return {
success: false,
message: "UMKM tidak ditemukan",
};
}
return {
success: true,
message: "Berhasil mengambil detail UMKM",
data,
};
} catch (e) {
console.error("Error di umkmFindUnique:", e);
return {
success: false,
message: "Gagal mengambil detail UMKM",
};
}
}
export default umkmFindUnique;

View File

@@ -0,0 +1,53 @@
import Elysia, { t } from "elysia";
import umkmCreate from "./create";
import umkmDelete from "./del";
import umkmFindMany from "./findMany";
import umkmFindManyAll from "./findManyAll";
import umkmFindUnique from "./findUnique";
import umkmUpdate from "./updt";
const Umkm = new Elysia({
prefix: "/umkm",
tags: ["Ekonomi/UMKM"],
})
.get("/find-many", umkmFindMany)
.get("/find-many-all", umkmFindManyAll)
.get("/:id", umkmFindUnique, {
params: t.Object({
id: t.String(),
}),
})
.post("/create", umkmCreate, {
body: t.Object({
nama: t.String(),
pemilik: t.String(),
kategoriId: t.String(),
deskripsi: t.Optional(t.String()),
alamat: t.Optional(t.String()),
kontak: t.Optional(t.String()),
imageId: t.Optional(t.String()),
isActive: t.Optional(t.Boolean()),
}),
})
.put("/:id", umkmUpdate, {
params: t.Object({
id: t.String(),
}),
body: t.Object({
nama: t.String(),
pemilik: t.String(),
kategoriId: t.String(),
deskripsi: t.Optional(t.String()),
alamat: t.Optional(t.String()),
kontak: t.Optional(t.String()),
imageId: t.Optional(t.String()),
isActive: t.Boolean(),
}),
})
.delete("/del/:id", umkmDelete, {
params: t.Object({
id: t.String(),
}),
});
export default Umkm;

View File

@@ -0,0 +1,56 @@
import prisma from "@/lib/prisma";
import { Context } from "elysia";
async function penjualanProdukCreate(context: Context) {
const body = context.body as any;
const tanggal = body.tanggal ? new Date(body.tanggal) : new Date();
// Format periode YYYY-MM
const periode = `${tanggal.getFullYear()}-${String(tanggal.getMonth() + 1).padStart(2, '0')}`;
const totalNilai = body.jumlah * body.hargaSatuan;
try {
// Gunakan transaction untuk update stok produk
const result = await prisma.$transaction(async (tx) => {
// 1. Catat penjualan
const penjualan = await tx.penjualanProduk.create({
data: {
produkId: body.produkId,
jumlah: body.jumlah,
hargaSatuan: body.hargaSatuan,
totalNilai: totalNilai,
tanggal: tanggal,
periode: periode,
isActive: body.isActive ?? true,
},
});
// 2. Update stok produk
await tx.produkUmkm.update({
where: { id: body.produkId },
data: {
stok: {
decrement: body.jumlah
}
}
});
return penjualan;
});
return {
success: true,
message: "Berhasil mencatat penjualan produk",
data: result,
};
} catch (e) {
console.error("Error di penjualanProdukCreate:", e);
return {
success: false,
message: "Gagal mencatat penjualan produk",
};
}
}
export default penjualanProdukCreate;

View File

@@ -0,0 +1,53 @@
import prisma from "@/lib/prisma";
import { Context } from "elysia";
async function penjualanProdukDelete(context: Context) {
const id = context.params.id;
try {
const result = await prisma.$transaction(async (tx) => {
// 1. Ambil data penjualan
const data = await tx.penjualanProduk.findUnique({
where: { id },
select: { jumlah: true, produkId: true }
});
if (!data) throw new Error("Data penjualan tidak ditemukan");
// 2. Soft delete
const deleted = await tx.penjualanProduk.update({
where: { id },
data: {
deletedAt: new Date(),
isActive: false,
},
});
// 3. Kembalikan stok produk
await tx.produkUmkm.update({
where: { id: data.produkId },
data: {
stok: {
increment: data.jumlah
}
}
});
return deleted;
});
return {
success: true,
message: "Berhasil menghapus data penjualan dan mengembalikan stok",
data: result,
};
} catch (e) {
console.error("Error di penjualanProdukDelete:", e);
return {
success: false,
message: "Gagal menghapus data penjualan",
};
}
}
export default penjualanProdukDelete;

View File

@@ -0,0 +1,58 @@
/* eslint-disable @typescript-eslint/no-explicit-any */
import prisma from "@/lib/prisma";
import { Context } from "elysia";
async function penjualanProdukFindMany(context: Context) {
const page = Number(context.query.page) || 1;
const limit = Number(context.query.limit) || 10;
const produkId = context.query.produkId as string | undefined;
const periode = context.query.periode as string | undefined; // YYYY-MM
const skip = (page - 1) * limit;
const where: any = { deletedAt: null };
if (produkId) {
where.produkId = produkId;
}
if (periode) {
where.periode = periode;
}
try {
const [data, total] = await Promise.all([
prisma.penjualanProduk.findMany({
where,
include: {
produk: {
include: {
umkm: true
}
}
},
skip,
take: limit,
orderBy: { tanggal: 'desc' },
}),
prisma.penjualanProduk.count({ where }),
]);
return {
success: true,
message: "Berhasil mengambil data penjualan produk",
data,
page,
limit,
total,
totalPages: Math.ceil(total / limit),
};
} catch (e) {
console.error("Error di penjualanProdukFindMany:", e);
return {
success: false,
message: "Gagal mengambil data penjualan produk",
};
}
}
export default penjualanProdukFindMany;

View File

@@ -0,0 +1,40 @@
import prisma from "@/lib/prisma";
import { Context } from "elysia";
async function penjualanProdukFindUnique(context: Context) {
const id = context.params.id;
try {
const data = await prisma.penjualanProduk.findUnique({
where: { id },
include: {
produk: {
include: {
umkm: true
}
}
},
});
if (!data) {
return {
success: false,
message: "Data penjualan tidak ditemukan",
};
}
return {
success: true,
message: "Berhasil mengambil detail penjualan produk",
data,
};
} catch (e) {
console.error("Error di penjualanProdukFindUnique:", e);
return {
success: false,
message: "Gagal mengambil detail penjualan produk",
};
}
}
export default penjualanProdukFindUnique;

View File

@@ -0,0 +1,45 @@
import Elysia, { t } from "elysia";
import penjualanProdukCreate from "./create";
import penjualanProdukDelete from "./del";
import penjualanProdukFindMany from "./findMany";
import penjualanProdukFindUnique from "./findUnique";
import penjualanProdukUpdate from "./updt";
const PenjualanProduk = new Elysia({
prefix: "/umkm/penjualan",
tags: ["Ekonomi/UMKM Penjualan"],
})
.get("/find-many", penjualanProdukFindMany)
.get("/:id", penjualanProdukFindUnique, {
params: t.Object({
id: t.String(),
}),
})
.post("/create", penjualanProdukCreate, {
body: t.Object({
produkId: t.String(),
jumlah: t.Number(),
hargaSatuan: t.Number(),
tanggal: t.Optional(t.String()),
isActive: t.Optional(t.Boolean()),
}),
})
.put("/:id", penjualanProdukUpdate, {
params: t.Object({
id: t.String(),
}),
body: t.Object({
produkId: t.String(),
jumlah: t.Number(),
hargaSatuan: t.Number(),
tanggal: t.Optional(t.String()),
isActive: t.Boolean(),
}),
})
.delete("/del/:id", penjualanProdukDelete, {
params: t.Object({
id: t.String(),
}),
});
export default PenjualanProduk;

View File

@@ -0,0 +1,83 @@
import prisma from "@/lib/prisma";
import { Context } from "elysia";
async function penjualanProdukUpdate(context: Context) {
const body = context.body as any;
const id = context.params.id;
const tanggal = body.tanggal ? new Date(body.tanggal) : new Date();
const periode = `${tanggal.getFullYear()}-${String(tanggal.getMonth() + 1).padStart(2, '0')}`;
const totalNilai = body.jumlah * body.hargaSatuan;
try {
const result = await prisma.$transaction(async (tx) => {
// 1. Ambil data lama untuk hitung selisih stok
const oldData = await tx.penjualanProduk.findUnique({
where: { id },
select: { jumlah: true, produkId: true }
});
if (!oldData) throw new Error("Data penjualan tidak ditemukan");
// 2. Update penjualan
const updated = await tx.penjualanProduk.update({
where: { id },
data: {
produkId: body.produkId,
jumlah: body.jumlah,
hargaSatuan: body.hargaSatuan,
totalNilai: totalNilai,
tanggal: tanggal,
periode: periode,
isActive: body.isActive,
},
});
// 3. Update stok jika produk sama, sesuaikan selisih
if (oldData.produkId === body.produkId) {
const diff = body.jumlah - oldData.jumlah;
await tx.produkUmkm.update({
where: { id: body.produkId },
data: {
stok: {
decrement: diff
}
}
});
} else {
// Jika produk berubah, kembalikan stok lama dan kurangi stok baru
await tx.produkUmkm.update({
where: { id: oldData.produkId },
data: {
stok: {
increment: oldData.jumlah
}
}
});
await tx.produkUmkm.update({
where: { id: body.produkId },
data: {
stok: {
decrement: body.jumlah
}
}
});
}
return updated;
});
return {
success: true,
message: "Berhasil memperbarui data penjualan",
data: result,
};
} catch (e) {
console.error("Error di penjualanProdukUpdate:", e);
return {
success: false,
message: "Gagal memperbarui data penjualan",
};
}
}
export default penjualanProdukUpdate;

View File

@@ -0,0 +1,34 @@
import prisma from "@/lib/prisma";
import { Context } from "elysia";
async function produkUmkmCreate(context: Context) {
const body = context.body as any;
try {
const data = await prisma.produkUmkm.create({
data: {
nama: body.nama,
harga: body.harga,
stok: body.stok ?? 0,
deskripsi: body.deskripsi,
umkmId: body.umkmId,
imageId: body.imageId,
isActive: body.isActive ?? true,
},
});
return {
success: true,
message: "Berhasil membuat produk UMKM baru",
data,
};
} catch (e) {
console.error("Error di produkUmkmCreate:", e);
return {
success: false,
message: "Gagal membuat produk UMKM baru",
};
}
}
export default produkUmkmCreate;

View File

@@ -0,0 +1,31 @@
import prisma from "@/lib/prisma";
import { Context } from "elysia";
async function produkUmkmDelete(context: Context) {
const id = context.params.id;
try {
// Soft delete
const data = await prisma.produkUmkm.update({
where: { id },
data: {
deletedAt: new Date(),
isActive: false,
},
});
return {
success: true,
message: "Berhasil menghapus produk UMKM",
data,
};
} catch (e) {
console.error("Error di produkUmkmDelete:", e);
return {
success: false,
message: "Gagal menghapus produk UMKM",
};
}
}
export default produkUmkmDelete;

View File

@@ -0,0 +1,64 @@
/* eslint-disable @typescript-eslint/no-explicit-any */
import prisma from "@/lib/prisma";
import { Context } from "elysia";
async function produkUmkmFindMany(context: Context) {
const page = Number(context.query.page) || 1;
const limit = Number(context.query.limit) || 10;
const search = (context.query.search as string) || '';
const umkmId = context.query.umkmId as string | undefined;
const kategoriId = context.query.kategoriId as string | undefined;
const skip = (page - 1) * limit;
const where: any = { deletedAt: null };
if (umkmId) {
where.umkmId = umkmId;
}
if (kategoriId) {
where.umkm = {
kategoriId: kategoriId
};
}
if (search) {
where.nama = { contains: search, mode: 'insensitive' };
}
try {
const [data, total] = await Promise.all([
prisma.produkUmkm.findMany({
where,
include: {
image: true,
umkm: {
include: { kategori: true }
}
},
skip,
take: limit,
orderBy: { createdAt: 'desc' },
}),
prisma.produkUmkm.count({ where }),
]);
return {
success: true,
message: "Berhasil mengambil data produk UMKM",
data,
page,
limit,
total,
totalPages: Math.ceil(total / limit),
};
} catch (e) {
console.error("Error di produkUmkmFindMany:", e);
return {
success: false,
message: "Gagal mengambil data produk UMKM",
};
}
}
export default produkUmkmFindMany;

View File

@@ -0,0 +1,42 @@
import prisma from "@/lib/prisma";
import { Context } from "elysia";
async function produkUmkmFindUnique(context: Context) {
const id = context.params.id;
try {
const data = await prisma.produkUmkm.findUnique({
where: { id },
include: {
image: true,
umkm: true,
penjualan: {
where: { deletedAt: null },
orderBy: { tanggal: 'desc' },
take: 10
}
},
});
if (!data) {
return {
success: false,
message: "Produk UMKM tidak ditemukan",
};
}
return {
success: true,
message: "Berhasil mengambil detail produk UMKM",
data,
};
} catch (e) {
console.error("Error di produkUmkmFindUnique:", e);
return {
success: false,
message: "Gagal mengambil detail produk UMKM",
};
}
}
export default produkUmkmFindUnique;

View File

@@ -0,0 +1,49 @@
import Elysia, { t } from "elysia";
import produkUmkmCreate from "./create";
import produkUmkmDelete from "./del";
import produkUmkmFindMany from "./findMany";
import produkUmkmFindUnique from "./findUnique";
import produkUmkmUpdate from "./updt";
const ProdukUmkm = new Elysia({
prefix: "/umkm/produk",
tags: ["Ekonomi/UMKM Produk"],
})
.get("/find-many", produkUmkmFindMany)
.get("/:id", produkUmkmFindUnique, {
params: t.Object({
id: t.String(),
}),
})
.post("/create", produkUmkmCreate, {
body: t.Object({
nama: t.String(),
harga: t.Number(),
umkmId: t.String(),
stok: t.Optional(t.Number()),
deskripsi: t.Optional(t.String()),
imageId: t.Optional(t.String()),
isActive: t.Optional(t.Boolean()),
}),
})
.put("/:id", produkUmkmUpdate, {
params: t.Object({
id: t.String(),
}),
body: t.Object({
nama: t.String(),
harga: t.Number(),
umkmId: t.String(),
stok: t.Number(),
deskripsi: t.Optional(t.String()),
imageId: t.Optional(t.String()),
isActive: t.Boolean(),
}),
})
.delete("/del/:id", produkUmkmDelete, {
params: t.Object({
id: t.String(),
}),
});
export default ProdukUmkm;

View File

@@ -0,0 +1,36 @@
import prisma from "@/lib/prisma";
import { Context } from "elysia";
async function produkUmkmUpdate(context: Context) {
const body = context.body as any;
const id = context.params.id;
try {
const data = await prisma.produkUmkm.update({
where: { id },
data: {
nama: body.nama,
harga: body.harga,
stok: body.stok,
deskripsi: body.deskripsi,
umkmId: body.umkmId,
imageId: body.imageId,
isActive: body.isActive,
},
});
return {
success: true,
message: "Berhasil memperbarui produk UMKM",
data,
};
} catch (e) {
console.error("Error di produkUmkmUpdate:", e);
return {
success: false,
message: "Gagal memperbarui produk UMKM",
};
}
}
export default produkUmkmUpdate;

View File

@@ -0,0 +1,37 @@
import prisma from "@/lib/prisma";
import { Context } from "elysia";
async function umkmUpdate(context: Context) {
const body = context.body as any;
const id = context.params.id;
try {
const data = await prisma.umkm.update({
where: { id },
data: {
nama: body.nama,
pemilik: body.pemilik,
deskripsi: body.deskripsi,
alamat: body.alamat,
kontak: body.kontak,
imageId: body.imageId,
kategoriId: body.kategoriId,
isActive: body.isActive,
},
});
return {
success: true,
message: "Berhasil memperbarui data UMKM",
data,
};
} catch (e) {
console.error("Error di umkmUpdate:", e);
return {
success: false,
message: "Gagal memperbarui data UMKM",
};
}
}
export default umkmUpdate;