feat: add balance withdrawal management with history and deletion support
This commit is contained in:
+123
-18
@@ -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({
|
||||
|
||||
Reference in New Issue
Block a user