fix(apbdes-edit): preserve realisasi data when editing APBDes
- Fix backend updt.ts to preserve realisasiItems from old items - Load existing items with realisasiItems before delete - Re-create realisasiItems for new items based on kode match - Recalculate totalRealisasi, selisih, persentase after restore - Update frontend state to handle realisasi fields - Add realisasi, selisih, persentase to ApbdesItemSchema - Fix edit.load() to map totalRealisasi → realisasi - Fix edit.update() to omit calculated fields when sending to backend - Update edit page.tsx to display realisasi data - Fix load data to use item.totalRealisasi (not item.realisasi) - Add Realisasi, Selisih, % columns to items table - Update handleAddItem and handleReset to preserve realisasi fields Root cause: Backend was resetting totalRealisasi=0 for all items on update, and frontend was accessing wrong field name (realisasi vs totalRealisasi) Co-authored-by: Qwen-Coder <qwen-coder@alibabacloud.com>
This commit is contained in:
@@ -28,6 +28,16 @@ export default async function apbdesUpdate(context: Context) {
|
||||
// 1. Pastikan APBDes ada
|
||||
const existing = await prisma.aPBDes.findUnique({
|
||||
where: { id },
|
||||
include: {
|
||||
items: {
|
||||
where: { isActive: true },
|
||||
include: {
|
||||
realisasiItems: {
|
||||
where: { isActive: true },
|
||||
},
|
||||
},
|
||||
},
|
||||
},
|
||||
});
|
||||
|
||||
if (!existing) {
|
||||
@@ -38,17 +48,35 @@ export default async function apbdesUpdate(context: Context) {
|
||||
};
|
||||
}
|
||||
|
||||
// 2. Hapus semua item lama (cascade akan menghapus realisasiItems juga)
|
||||
// 2. Build map untuk preserve realisasiItems berdasarkan kode
|
||||
const existingItemsMap = new Map<string, {
|
||||
id: string;
|
||||
realisasiItems: any[];
|
||||
}>();
|
||||
|
||||
existing.items.forEach(item => {
|
||||
existingItemsMap.set(item.kode, {
|
||||
id: item.id,
|
||||
realisasiItems: item.realisasiItems,
|
||||
});
|
||||
});
|
||||
|
||||
// 3. Hapus semua item lama (cascade akan menghapus realisasiItems juga)
|
||||
// TAPI kita sudah save realisasiItems di map atas
|
||||
await prisma.aPBDesItem.deleteMany({
|
||||
where: { apbdesId: id },
|
||||
});
|
||||
|
||||
// 3. Buat item baru dengan auto-calculate fields
|
||||
// 4. Buat item baru dengan preserve realisasiItems
|
||||
await prisma.aPBDesItem.createMany({
|
||||
data: body.items.map((item) => {
|
||||
data: await Promise.all(body.items.map(async (item) => {
|
||||
const anggaran = item.anggaran;
|
||||
const totalRealisasi = 0; // Reset karena items baru
|
||||
const selisih = anggaran - totalRealisasi; // Sisa anggaran (positif = belum digunakan)
|
||||
|
||||
// Check apakah item ini punya realisasiItems lama
|
||||
const existingItem = existingItemsMap.get(item.kode);
|
||||
const realisasiItemsData = existingItem?.realisasiItems || [];
|
||||
const totalRealisasi = realisasiItemsData.reduce((sum, r) => sum + r.jumlah, 0);
|
||||
const selisih = anggaran - totalRealisasi;
|
||||
const persentase = anggaran > 0 ? (totalRealisasi / anggaran) * 100 : 0;
|
||||
|
||||
return {
|
||||
@@ -63,16 +91,68 @@ export default async function apbdesUpdate(context: Context) {
|
||||
persentase,
|
||||
isActive: true,
|
||||
};
|
||||
}),
|
||||
})),
|
||||
});
|
||||
|
||||
// 4. Dapatkan semua item yang baru dibuat untuk mendapatkan ID-nya
|
||||
// 5. Dapatkan semua item yang baru dibuat untuk mendapatkan ID-nya
|
||||
const allItems = await prisma.aPBDesItem.findMany({
|
||||
where: { apbdesId: id },
|
||||
select: { id: true, kode: true },
|
||||
});
|
||||
|
||||
// 5. Update parentId untuk setiap item
|
||||
// 6. Build map baru untuk item IDs
|
||||
const newItemIdsMap = new Map<string, string>();
|
||||
allItems.forEach(item => {
|
||||
newItemIdsMap.set(item.kode, item.id);
|
||||
});
|
||||
|
||||
// 7. Re-create realisasiItems dengan link ke item IDs yang baru
|
||||
for (const [oldKode, oldItemData] of existingItemsMap.entries()) {
|
||||
if (oldItemData.realisasiItems.length > 0) {
|
||||
const newItemId = newItemIdsMap.get(oldKode);
|
||||
if (newItemId) {
|
||||
// Re-create realisasiItems untuk item ini
|
||||
await prisma.realisasiItem.createMany({
|
||||
data: oldItemData.realisasiItems.map(r => ({
|
||||
apbdesItemId: newItemId,
|
||||
kode: r.kode,
|
||||
jumlah: r.jumlah,
|
||||
tanggal: r.tanggal,
|
||||
keterangan: r.keterangan,
|
||||
buktiFileId: r.buktiFileId,
|
||||
isActive: true,
|
||||
})),
|
||||
});
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// 8. Recalculate totalRealisasi setelah re-create realisasiItems
|
||||
for (const [kode, _] of existingItemsMap.entries()) {
|
||||
const newItemId = newItemIdsMap.get(kode);
|
||||
if (newItemId) {
|
||||
const realisasiItems = await prisma.realisasiItem.findMany({
|
||||
where: { apbdesItemId: newItemId, isActive: true },
|
||||
});
|
||||
const totalRealisasi = realisasiItems.reduce((sum, r) => sum + r.jumlah, 0);
|
||||
|
||||
const item = await prisma.aPBDesItem.findUnique({
|
||||
where: { id: newItemId },
|
||||
});
|
||||
|
||||
if (item) {
|
||||
const selisih = item.anggaran - totalRealisasi;
|
||||
const persentase = item.anggaran > 0 ? (totalRealisasi / item.anggaran) * 100 : 0;
|
||||
|
||||
await prisma.aPBDesItem.update({
|
||||
where: { id: newItemId },
|
||||
data: { totalRealisasi, selisih, persentase },
|
||||
});
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// 9. Update parentId untuk setiap item
|
||||
const itemsForParentUpdate = allItems.map(item => ({
|
||||
id: item.id,
|
||||
kode: item.kode,
|
||||
@@ -80,7 +160,7 @@ export default async function apbdesUpdate(context: Context) {
|
||||
|
||||
await assignParentIdsToApbdesItems(itemsForParentUpdate);
|
||||
|
||||
// 6. Update data APBDes
|
||||
// 10. Update data APBDes
|
||||
await prisma.aPBDes.update({
|
||||
where: { id },
|
||||
data: {
|
||||
@@ -93,7 +173,7 @@ export default async function apbdesUpdate(context: Context) {
|
||||
},
|
||||
});
|
||||
|
||||
// 7. Ambil data lengkap untuk response (include realisasiItems)
|
||||
// 11. Ambil data lengkap untuk response (include realisasiItems)
|
||||
const result = await prisma.aPBDes.findUnique({
|
||||
where: { id },
|
||||
include: {
|
||||
|
||||
Reference in New Issue
Block a user