const { BillPayment, Bill } = require('../models'); const { Op, fn, col } = require('sequelize'); const response = require('../utils/response'); const rentalBillingService = require('../services/rentalBillingService'); // 获取账单的所有支付流水 const getPaymentsByBillId = async (req, res) => { try { const { billId } = req.params; const tenantId = req.user.tenantId; const payments = await BillPayment.findAll({ where: { billId, tenantId, isDeleted: 0 }, order: [['paymentTime', 'DESC']] }); response.success(res, '获取成功', payments); } catch (error) { console.error('获取支付流水失败:', error); response.serverError(res, '获取支付流水失败', error); } }; // 创建支付流水(收款) const createPayment = async (req, res) => { const transaction = await require('../config/db').transaction(); try { const { billId } = req.params; const { amount, paymentMethod, paymentTime, transactionNo, remark } = req.body; const tenantId = req.user.tenantId; const createBy = req.user.id; const bill = await Bill.findOne({ where: { id: billId, tenantId, isDeleted: 0 }, transaction }); if (!bill) { await transaction.rollback(); return response.notFound(res, '账单不存在'); } if (transactionNo) { const existingPayment = await BillPayment.findOne({ where: { transactionNo, billId, tenantId, isDeleted: 0 }, transaction }); if (existingPayment) { await transaction.rollback(); return response.badRequest(res, '该交易流水号已存在,请勿重复提交'); } } let paymentInfo; try { paymentInfo = rentalBillingService.validatePaymentAmount(bill, amount); } catch (validationError) { await transaction.rollback(); return response.badRequest(res, validationError.message); } const payment = await BillPayment.create({ billId, amount: paymentInfo.paymentAmount, paymentMethod, paymentTime: paymentTime || new Date(), transactionNo: transactionNo || null, remark: remark || null, tenantId, createBy, isDeleted: 0 }, { transaction }); await bill.update({ receivedAmount: paymentInfo.newReceivedAmount, status: paymentInfo.newStatus, updateBy: createBy }, { transaction }); await transaction.commit(); response.created(res, '收款成功', { payment, bill: { id: bill.id, receivedAmount: paymentInfo.newReceivedAmount, status: paymentInfo.newStatus } }); } catch (error) { await transaction.rollback(); console.error('创建支付流水失败:', error); response.serverError(res, '创建支付流水失败', error); } }; // 删除支付流水(退款/撤销) const deletePayment = async (req, res) => { const transaction = await require('../config/db').transaction(); try { const { id } = req.params; const tenantId = req.user.tenantId; const updateBy = req.user.id; const payment = await BillPayment.findOne({ where: { id, tenantId, isDeleted: 0 }, transaction }); if (!payment) { await transaction.rollback(); return response.notFound(res, '支付流水不存在'); } const bill = await Bill.findOne({ where: { id: payment.billId, tenantId, isDeleted: 0 }, transaction }); if (!bill) { await transaction.rollback(); return response.notFound(res, '关联账单不存在'); } await payment.update({ isDeleted: 1 }, { transaction }); const remainingPayments = await BillPayment.findAll({ where: { billId: bill.id, tenantId, isDeleted: 0 }, transaction }); const newReceivedAmount = remainingPayments.reduce((sum, p) => sum + parseFloat(p.amount), 0); let newStatus = 'unpaid'; if (newReceivedAmount >= parseFloat(bill.receivableAmount)) { newStatus = 'paid'; } else if (newReceivedAmount > 0) { newStatus = 'partial'; } await bill.update({ receivedAmount: newReceivedAmount, status: newStatus, updateBy }, { transaction }); await transaction.commit(); response.success(res, '支付流水已撤销,账单状态已更新', { bill: { id: bill.id, receivedAmount: newReceivedAmount, status: newStatus } }); } catch (error) { await transaction.rollback(); console.error('撤销支付流水失败:', error); response.serverError(res, '撤销支付流水失败', error); } }; // 获取支付流水统计 const getPaymentStatistics = async (req, res) => { try { const tenantId = req.user.tenantId; const { startDate, endDate } = req.query; const where = { tenantId, isDeleted: 0 }; if (startDate && endDate) { where.paymentTime = { [Op.between]: [new Date(startDate), new Date(endDate)] }; } const payments = await BillPayment.findAll({ where, attributes: ['paymentMethod', [fn('SUM', col('amount')), 'totalAmount'], [fn('COUNT', col('id')), 'count']], group: ['paymentMethod'] }); response.success(res, '获取成功', payments); } catch (error) { console.error('获取支付统计失败:', error); response.serverError(res, '获取支付统计失败', error); } }; module.exports = { getPaymentsByBillId, createPayment, deletePayment, getPaymentStatistics };