feat: add balance withdrawal management with history and deletion support

This commit is contained in:
Firman Ramdhani
2026-09-16 15:02:11 +07:00
parent 1337af0102
commit 7c3c5e2249
4 changed files with 812 additions and 131 deletions
+123 -18
View File
@@ -661,14 +661,16 @@ export async function getCreatorReport(creator_id: string, startDate?: Date, end
// === BALANCE ACTIONS ===
export async function getBalancesAsCreator(creator_id: string) {
const submissions = await prisma.submission.findMany({
where: {
order: { creator_id },
},
include: {
user: { select: { id: true, name: true, photo: true } },
},
})
const [submissions, withdrawals] = await Promise.all([
prisma.submission.findMany({
where: { order: { creator_id } },
include: { user: { select: { id: true, name: true, photo: true } } },
}),
prisma.balanceWithdrawal.findMany({
where: { creator_id },
include: { user: { select: { id: true, name: true, photo: true } } },
}),
])
const balanceMap = new Map<string, { user: any; amount: number }>()
@@ -691,22 +693,35 @@ export async function getBalancesAsCreator(creator_id: string) {
}
})
// Kurangi saldo dengan total withdrawal yang sudah dilakukan
withdrawals.forEach((w) => {
if (!balanceMap.has(w.user_id)) {
balanceMap.set(w.user_id, { user: w.user, amount: -w.amount })
} else {
balanceMap.get(w.user_id)!.amount -= w.amount
}
})
return Array.from(balanceMap.values()).filter((b) => b.amount !== 0)
}
export async function getBalancesAsSubmittor(user_id: string) {
const submissions = await prisma.submission.findMany({
where: {
user_id,
},
include: {
order: {
include: {
creator: { select: { id: true, name: true, photo: true } },
const [submissions, withdrawals] = await Promise.all([
prisma.submission.findMany({
where: { user_id },
include: {
order: {
include: {
creator: { select: { id: true, name: true, photo: true } },
},
},
},
},
})
}),
prisma.balanceWithdrawal.findMany({
where: { user_id },
include: { creator: { select: { id: true, name: true, photo: true } } },
}),
])
const balanceMap = new Map<string, { creator: any; amount: number }>()
@@ -730,9 +745,99 @@ export async function getBalancesAsSubmittor(user_id: string) {
}
})
// Kurangi saldo dengan total withdrawal yang dilakukan kreator
withdrawals.forEach((w) => {
if (!balanceMap.has(w.creator_id)) {
balanceMap.set(w.creator_id, { creator: w.creator, amount: -w.amount })
} else {
balanceMap.get(w.creator_id)!.amount -= w.amount
}
})
return Array.from(balanceMap.values()).filter((b) => b.amount !== 0)
}
// === WITHDRAWAL ACTIONS ===
export async function createWithdrawal(data: {
creator_id: string
user_id: string
amount: number
note?: string
}) {
try {
const me = await getSessionUser()
if (!me || me.id !== data.creator_id) {
return { success: false, error: 'Unauthorized' }
}
if (!data.amount || data.amount <= 0) {
return { success: false, error: 'Nominal harus lebih dari 0' }
}
// Hitung saldo tersedia saat ini untuk user ini
const balances = await getBalancesAsCreator(data.creator_id)
const userBalance = balances.find((b) => b.user.id === data.user_id)
const available = userBalance ? userBalance.amount : 0
if (data.amount > available) {
return {
success: false,
error: `Nominal melebihi saldo tersedia (${new Intl.NumberFormat('id-ID', { style: 'currency', currency: 'IDR', maximumFractionDigits: 0 }).format(available)})`,
}
}
await prisma.balanceWithdrawal.create({
data: {
creator_id: data.creator_id,
user_id: data.user_id,
amount: data.amount,
note: data.note || null,
},
})
revalidatePath('/balances')
revalidatePath('/my-orders')
revalidatePath('/reports')
return { success: true }
} catch (e) {
console.error(e)
return { success: false, error: 'Gagal mencatat penarikan saldo.' }
}
}
export async function getWithdrawalHistory(creator_id: string, user_id?: string) {
return await prisma.balanceWithdrawal.findMany({
where: {
creator_id,
...(user_id ? { user_id } : {}),
},
include: {
user: { select: { id: true, name: true, photo: true } },
},
orderBy: { created_at: 'desc' },
})
}
export async function deleteWithdrawal(id: string) {
try {
const me = await getSessionUser()
const record = await prisma.balanceWithdrawal.findUnique({ where: { id } })
if (!record) return { success: false, error: 'Data tidak ditemukan' }
if (!me || me.id !== record.creator_id) {
return { success: false, error: 'Unauthorized' }
}
await prisma.balanceWithdrawal.delete({ where: { id } })
revalidatePath('/balances')
revalidatePath('/my-orders')
revalidatePath('/reports')
return { success: true }
} catch (e) {
console.error(e)
return { success: false, error: 'Gagal menghapus riwayat penarikan.' }
}
}
export async function deleteSubmission(submission_id: string, user_id: string) {
try {
const submission = await prisma.submission.findUnique({