fix the contract view and edit
This commit is contained in:
@@ -99,6 +99,13 @@ const chargeSchema = z.object({
|
||||
failureUrl: z.string().url(),
|
||||
})
|
||||
|
||||
const manualPaymentSchema = z.object({
|
||||
amount: z.number().int().positive(),
|
||||
currency: z.enum(['MAD', 'USD', 'EUR']).default('MAD'),
|
||||
type: z.enum(['CHARGE', 'DEPOSIT']).default('CHARGE'),
|
||||
paymentMethod: z.enum(['CASH', 'CHECK', 'BANK_TRANSFER', 'CARD', 'PAYPAL']),
|
||||
})
|
||||
|
||||
router.get('/company', async (req, res, next) => {
|
||||
try {
|
||||
const payments = await prisma.rentalPayment.findMany({
|
||||
@@ -226,6 +233,51 @@ router.post('/reservations/:id/capture-paypal', async (req, res, next) => {
|
||||
} catch (err) { next(err) }
|
||||
})
|
||||
|
||||
router.post('/reservations/:id/manual', async (req, res, next) => {
|
||||
try {
|
||||
const { amount, currency, type, paymentMethod } = manualPaymentSchema.parse(req.body)
|
||||
|
||||
const reservation = await prisma.reservation.findFirstOrThrow({
|
||||
where: { id: req.params.id, companyId: req.companyId },
|
||||
})
|
||||
|
||||
const remainingBalance = Math.max(reservation.totalAmount - reservation.paidAmount, 0)
|
||||
if (remainingBalance <= 0) {
|
||||
return res.status(409).json({ error: 'already_paid', message: 'Reservation is already fully paid', statusCode: 409 })
|
||||
}
|
||||
if (amount > remainingBalance) {
|
||||
return res.status(400).json({ error: 'amount_exceeds_balance', message: 'Payment amount exceeds remaining balance', statusCode: 400 })
|
||||
}
|
||||
|
||||
const payment = await prisma.rentalPayment.create({
|
||||
data: {
|
||||
companyId: req.companyId,
|
||||
reservationId: reservation.id,
|
||||
amount,
|
||||
currency,
|
||||
status: 'SUCCEEDED',
|
||||
type,
|
||||
paymentProvider: paymentMethod === 'PAYPAL' ? 'PAYPAL' : 'AMANPAY',
|
||||
paymentMethod,
|
||||
paidAt: new Date(),
|
||||
},
|
||||
})
|
||||
|
||||
const newPaidAmount = reservation.paidAmount + amount
|
||||
const paymentStatus = newPaidAmount >= reservation.totalAmount ? 'PAID' : 'PARTIAL'
|
||||
|
||||
await prisma.reservation.update({
|
||||
where: { id: reservation.id },
|
||||
data: {
|
||||
paidAmount: newPaidAmount,
|
||||
paymentStatus,
|
||||
},
|
||||
})
|
||||
|
||||
res.json({ data: payment })
|
||||
} catch (err) { next(err) }
|
||||
})
|
||||
|
||||
router.post('/reservations/:reservationId/payments/:paymentId/refund', async (req, res, next) => {
|
||||
try {
|
||||
const { amount, reason } = z.object({
|
||||
@@ -240,6 +292,9 @@ router.post('/reservations/:reservationId/payments/:paymentId/refund', async (re
|
||||
if (payment.status !== 'SUCCEEDED') {
|
||||
return res.status(400).json({ error: 'not_capturable', message: 'Only succeeded payments can be refunded', statusCode: 400 })
|
||||
}
|
||||
if (!payment.amanpayTransactionId && !payment.paypalCaptureId) {
|
||||
return res.status(400).json({ error: 'manual_refund_unsupported', message: 'Manual payments must be refunded outside the online gateway flow', statusCode: 400 })
|
||||
}
|
||||
|
||||
const refundAmount = amount ?? payment.amount
|
||||
|
||||
|
||||
Reference in New Issue
Block a user