forked from wangziqi/gongxue-base
feat: link deposits to bill payment
This commit is contained in:
@@ -170,7 +170,7 @@ export class DepositsController {
|
||||
action: '退还押金',
|
||||
targetId: +id,
|
||||
targetType: 'deposit',
|
||||
detail: `退还¥${result.refundAmount}, 扣除¥${result.deductionAmount}`,
|
||||
detail: `退还全部可用押金 ¥${result.refundAmount}`,
|
||||
ipAddress,
|
||||
userAgent,
|
||||
});
|
||||
@@ -182,7 +182,7 @@ export class DepositsController {
|
||||
recipientIds: [student.userId],
|
||||
type: 'deposit_refunded',
|
||||
title: '押金已退还',
|
||||
content: `您的押金已退还,退还¥${result.refundAmount},扣除¥${result.deductionAmount}`,
|
||||
content: `您的剩余押金已全部退还,金额: ¥${result.refundAmount}`,
|
||||
});
|
||||
}
|
||||
} catch (_) { /* don't block response */ }
|
||||
|
||||
@@ -46,16 +46,28 @@ export class DepositsService {
|
||||
async create(dto: CreateDepositDto, userId?: number) {
|
||||
const student = await this.studentRepo.findOne({ where: { id: dto.studentId } });
|
||||
if (!student) throw new NotFoundException('学生不存在');
|
||||
const deposit = this.repo.create({
|
||||
studentId: dto.studentId,
|
||||
amount: dto.amount,
|
||||
paidDate: dto.paidDate,
|
||||
notes: dto.notes,
|
||||
status: 'paid',
|
||||
recordedBy: userId,
|
||||
});
|
||||
if (Number(dto.amount) <= 0) throw new BadRequestException('收取金额必须大于0');
|
||||
|
||||
return this.repo.save(deposit);
|
||||
const existing = await this.repo.findOne({ where: { studentId: dto.studentId } });
|
||||
if (existing) {
|
||||
existing.amount = Number((Number(existing.amount || 0) + Number(dto.amount)).toFixed(2));
|
||||
existing.paidDate = dto.paidDate;
|
||||
existing.status = 'paid';
|
||||
existing.recordedBy = userId ?? null;
|
||||
if (dto.notes) existing.notes = dto.notes;
|
||||
return this.repo.save(existing);
|
||||
}
|
||||
|
||||
return this.repo.save(
|
||||
this.repo.create({
|
||||
studentId: dto.studentId,
|
||||
amount: dto.amount,
|
||||
paidDate: dto.paidDate,
|
||||
notes: dto.notes,
|
||||
status: 'paid',
|
||||
recordedBy: userId,
|
||||
}),
|
||||
);
|
||||
}
|
||||
|
||||
async addInstallment(depositId: number, amount: number, dueDate: string) {
|
||||
@@ -90,18 +102,16 @@ export class DepositsService {
|
||||
async refund(id: number, dto: RefundDepositDto, userId?: number) {
|
||||
const deposit = await this.repo.findOne({ where: { id } });
|
||||
if (!deposit) throw new NotFoundException('押金记录不存在');
|
||||
if (deposit.status !== 'paid') throw new BadRequestException('该押金已处理');
|
||||
if (deposit.status !== 'paid' || Number(deposit.amount) <= 0) {
|
||||
throw new BadRequestException('该学生当前没有可退押金');
|
||||
}
|
||||
|
||||
const deduction = dto.deductionAmount || 0;
|
||||
const refundAmount = Number(deposit.amount) - deduction;
|
||||
if (refundAmount < 0) throw new BadRequestException('扣除金额不能大于押金金额');
|
||||
const refundAmount = Number(deposit.amount);
|
||||
|
||||
deposit.refundDate = dto.refundDate;
|
||||
deposit.deductionAmount = deduction;
|
||||
deposit.deductionReason = dto.deductionReason || '';
|
||||
deposit.refundAmount = refundAmount;
|
||||
deposit.status =
|
||||
deduction > 0 ? (refundAmount > 0 ? 'partial_refund' : 'deducted') : 'refunded';
|
||||
deposit.amount = 0;
|
||||
deposit.status = 'refunded';
|
||||
if (dto.notes) deposit.notes = dto.notes;
|
||||
deposit.refundedBy = userId ?? null;
|
||||
deposit.refundedAt = new Date();
|
||||
|
||||
@@ -19,14 +19,6 @@ export class RefundDepositDto {
|
||||
@IsString()
|
||||
refundDate: string;
|
||||
|
||||
@IsOptional()
|
||||
@IsNumber()
|
||||
deductionAmount?: number;
|
||||
|
||||
@IsOptional()
|
||||
@IsString()
|
||||
deductionReason?: string;
|
||||
|
||||
@IsOptional()
|
||||
@IsString()
|
||||
notes?: string;
|
||||
|
||||
Reference in New Issue
Block a user