进销存系统客户信用管理与账期控制
信用管理概述
客户信用管理是进销存系统的核心模块之一,涉及客户信用评级、账期设置、应收账款管理和催收策略等功能。良好的信用管理可以有效控制坏账风险,加速资金周转。本文详细介绍客户信用管理系统的设计与实现。
信用评级体系
| 信用等级 | 信用额度 | 账期天数 | 折扣系数 |
|---|---|---|---|
| AAA(优质) | 50万以上 | 90天 | 0.95 |
| AA(良好) | 20-50万 | 60天 | 0.97 |
| A(一般) | 10-20万 | 30天 | 1.00 |
| B(警惕) | 5-10万 | 15天 | 1.02 |
| C(限制) | 0-5万 | 0天(现结) | 1.05 |
信用评分算法
基于多维度指标计算客户信用评分:
// 信用评分服务
class CreditScoreService {
constructor(customerModel, orderModel, paymentModel) {
this.Customer = customerModel;
this.Order = orderModel;
this.Payment = paymentModel;
}
// 计算客户信用评分
async calculateCreditScore(customerId) {
const customer = await this.Customer.findById(customerId);
// 获取各项评分指标
const paymentScore = await this.getPaymentHistoryScore(customerId);
const transactionScore = await this.getTransactionScore(customerId);
const cooperationScore = await this.getCooperationScore(customer);
const financialScore = await this.getFinancialScore(customer);
// 加权计算总分
const weights = {
payment: 0.35, # 付款记录权重
transaction: 0.25, # 交易活跃度权重
cooperation: 0.20, # 合作年限权重
financial: 0.20 # 财务状况权重
};
const totalScore =
paymentScore * weights.payment +
transactionScore * weights.transaction +
cooperationScore * weights.cooperation +
financialScore * weights.financial;
// 确定信用等级
const creditLevel = this.getCreditLevel(totalScore);
return {
customerId,
totalScore: Math.round(totalScore),
creditLevel,
details: {
paymentScore,
transactionScore,
cooperationScore,
financialScore
},
calculatedAt: new Date()
};
}
// 获取付款记录评分
async getPaymentHistoryScore(customerId, period = 365) {
const startDate = new Date();
startDate.setDate(startDate.getDate() - period);
// 获取历史付款记录
const payments = await this.Payment.find({
customerId,
paymentDate: { $gte: startDate }
});
if (payments.length === 0) return 60; # 默认分数
// 计算付款及时率
const orders = await this.Order.find({
customerId,
createdAt: { $gte: startDate }
});
let onTimeCount = 0;
let totalCount = orders.length;
for (const order of orders) {
const paymentsForOrder = payments.filter(p =>
p.orderId.toString() === order._id.toString()
);
if (paymentsForOrder.length > 0) {
const payment = paymentsForOrder[0];
const dueDate = new Date(order.createdAt);
dueDate.setDate(dueDate.getDate() + order.paymentDays);
if (new Date(payment.paymentDate) <= dueDate) {
onTimeCount++;
}
}
}
const onTimeRate = totalCount > 0 ? onTimeCount / totalCount : 0;
// 计算逾期次数扣分
const overduePayments = payments.filter(p => p.isOverdue);
const overdueRate = payments.length > 0 ? overduePayments.length / payments.length : 0;
// 评分计算
let score = onTimeRate * 70 + (1 - overdueRate) * 30;
return Math.round(score);
}
// 获取交易活跃度评分
async getTransactionScore(customerId, period = 180) {
const startDate = new Date();
startDate.setDate(startDate.getDate() - period);
const orders = await this.Order.find({
customerId,
createdAt: { $gte: startDate }
});
// 计算订单频率
const days = period;
const orderFrequency = orders.length / (days / 30); # 月均订单数
// 计算平均订单金额
const totalAmount = orders.reduce((sum, o) => sum + o.totalAmount, 0);
const avgOrderAmount = orders.length > 0 ? totalAmount / orders.length : 0;
// 频率和金额综合评分
const frequencyScore = Math.min(orderFrequency / 10 * 50, 50);
const amountScore = Math.min(avgOrderAmount / 10000 * 50, 50);
return Math.round(frequencyScore + amountScore);
}
// 获取合作年限评分
getCooperationScore(customer) {
if (!customer.cooperationStartDate) return 50;
const years = (new Date() - new Date(customer.cooperationStartDate)) / (365 * 24 * 60 * 60 * 1000);
// 合作年限越长分数越高,最高30分
return Math.round(Math.min(years * 5, 30));
}
// 获取财务状况评分
async getFinancialScore(customer) {
// 根据客户规模给定基础分
let baseScore = 50;
if (customer.enterpriseType === 'large') baseScore = 80;
else if (customer.enterpriseType === 'medium') baseScore = 65;
else if (customer.enterpriseType === 'small') baseScore = 50;
else baseScore = 40;
// 根据注册资本调整
if (customer.registeredCapital) {
if (customer.registeredCapital > 10000000) baseScore += 10;
else if (customer.registeredCapital > 1000000) baseScore += 5;
}
return Math.min(baseScore, 100);
}
// 确定信用等级
getCreditLevel(score) {
if (score >= 90) return { level: 'AAA', label: '优质客户' };
if (score >= 80) return { level: 'AA', label: '良好客户' };
if (score >= 70) return { level: 'A', label: '一般客户' };
if (score >= 60) return { level: 'B', label: '警惕客户' };
return { level: 'C', label: '限制客户' };
}
}
账期控制机制
智能账期控制和超期预警:
// 账期管理服务
class PaymentTermService {
constructor(customerModel, orderModel, receivableModel) {
this.Customer = customerModel;
this.Order = orderModel;
this.Receivable = receivableModel;
}
// 检查客户是否可以下单
async checkCreditLimit(customerId, orderAmount) {
const customer = await this.Customer.findById(customerId);
const creditInfo = await this.getCustomerCreditInfo(customerId);
// 计算当前可用信用额度
const usedCredit = await this.getUsedCredit(customerId);
const availableCredit = creditInfo.creditLimit - usedCredit;
// 检查是否超额度
if (orderAmount > availableCredit) {
return {
allowed: false,
reason: '超出信用额度',
availableCredit,
requiredCredit: orderAmount,
deficit: orderAmount - availableCredit
};
}
// 检查是否有超期应收账款
const overdueReceivables = await this.getOverdueReceivables(customerId);
if (overdueReceivables.length > 0) {
const overdueAmount = overdueReceivables.reduce((sum, r) => sum + r.amount, 0);
// 超期金额超过信用额度的20%,限制下单
if (overdueAmount > creditInfo.creditLimit * 0.2) {
return {
allowed: false,
reason: '存在超期应收账款',
overdueAmount,
overdueDays: overdueReceivables[0].overdueDays
};
}
}
return {
allowed: true,
availableCredit,
creditLevel: creditInfo.creditLevel
};
}
// 获取客户信用信息
async getCustomerCreditInfo(customerId) {
const customer = await this.Customer.findById(customerId);
// 如果没有信用记录,创建默认信用信息
if (!customer.creditInfo) {
return {
creditLimit: 50000,
creditLevel: 'C',
paymentDays: 0
};
}
return customer.creditInfo;
}
// 获取已使用信用额度(未结清订单+应收账款)
async getUsedCredit(customerId) {
// 未结清订单金额
const pendingOrders = await this.Order.find({
customerId,
status: { $in: ['pending', 'processing', 'shipped'] }
});
const pendingAmount = pendingOrders.reduce((sum, o) => sum + o.totalAmount, 0);
// 未收款金额
const receivables = await this.Receivable.find({
customerId,
status: { $in: ['pending', 'partial'] }
});
const receivableAmount = receivables.reduce((sum, r) => sum + r.balance, 0);
return pendingAmount + receivableAmount;
}
// 获取超期应收账款
async getOverdueReceivables(customerId) {
const today = new Date();
return this.Receivable.aggregate([
{
$match: {
customerId,
status: { $in: ['pending', 'partial'] },
dueDate: { $lt: today }
}
},
{
$project: {
orderNo: 1,
amount: 1,
balance: 1,
dueDate: 1,
overdueDays: {
$divide: [
{ $subtract: [today, '$dueDate'] },
1000 * 60 * 60 * 24 # 转换为天数
]
}
}
},
{ $sort: { overdueDays: -1 } }
]);
}
// 自动计算并调整信用等级
async autoAdjustCreditLevel(customerId) {
const creditScore = await this.calculateCreditScore(customerId);
const customer = await this.Customer.findById(customerId);
// 计算新的信用额度
const newCreditLimit = this.calculateCreditLimit(creditScore.totalScore, customer);
// 计算新的账期
const newPaymentDays = this.calculatePaymentDays(creditScore.creditLevel.level);
// 更新客户信用信息
await this.Customer.updateOne(
{ _id: customerId },
{
'creditInfo.creditLevel': creditScore.creditLevel.level,
'creditInfo.creditScore': creditScore.totalScore,
'creditInfo.creditLimit': newCreditLimit,
'creditInfo.paymentDays': newPaymentDays,
'creditInfo.lastAdjustDate': new Date()
}
);
return {
oldLevel: customer.creditInfo?.creditLevel,
newLevel: creditScore.creditLevel.level,
oldLimit: customer.creditInfo?.creditLimit,
newLimit: newCreditLimit,
oldDays: customer.creditInfo?.paymentDays,
newDays: newPaymentDays
};
}
// 计算信用额度
calculateCreditLimit(score, customer) {
const baseLimit = 50000;
const maxLimit = 500000;
// 根据评分调整额度
let limit = baseLimit + (score - 60) * 5000;
// 根据客户类型调整
if (customer.enterpriseType === 'large') limit *= 3;
else if (customer.enterpriseType === 'medium') limit *= 1.5;
return Math.min(Math.max(limit, baseLimit), maxLimit);
}
// 计算账期天数
calculatePaymentDays(level) {
const paymentDaysMap = {
'AAA': 90,
'AA': 60,
'A': 30,
'B': 15,
'C': 0
};
return paymentDaysMap[level] || 0;
}
}
应收账款管理
全面的应收账款跟踪和预警:
// 应收账款管理服务
class ReceivableService {
constructor(orderModel, paymentModel, receivableModel, notificationService) {
this.Order = orderModel;
this.Payment = paymentModel;
this.Receivable = receivableModel;
this.Notification = notificationService;
}
// 生成应收账款(订单完成后)
async createReceivable(orderId) {
const order = await this.Order.findById(orderId);
// 检查是否需要生成应收账款(如果有账期)
if (order.paymentDays === 0) {
return null; # 现结订单不需要应收账款
}
const receivable = await this.Receivable.create({
orderId: order._id,
customerId: order.customerId,
saleDate: order.createdAt,
dueDate: this.calculateDueDate(order.createdAt, order.paymentDays),
amount: order.totalAmount,
balance: order.totalAmount,
status: 'pending',
paymentDays: order.paymentDays
});
// 发送账期提醒
await this.Notification.sendReminder(order.customerId, receivable);
return receivable;
}
// 计算到期日
calculateDueDate(saleDate, paymentDays) {
const dueDate = new Date(saleDate);
dueDate.setDate(dueDate.getDate() + paymentDays);
return dueDate;
}
// 收款处理
async receivePayment(receivableId, paymentAmount, paymentMethod, paymentDate = new Date()) {
const receivable = await this.Receivable.findById(receivableId);
const receivableBefore = receivable.balance;
// 更新应收账款
receivable.balance -= paymentAmount;
if (receivable.balance <= 0) {
receivable.status = 'paid';
receivable.paidDate = paymentDate;
} else {
receivable.status = 'partial';
}
await receivable.save();
// 记录付款明细
await this.Payment.create({
receivableId,
orderId: receivable.orderId,
customerId: receivable.customerId,
paymentAmount,
paymentMethod,
paymentDate,
isOverdue: paymentDate > receivable.dueDate
});
return { receivable, receivedAmount: paymentAmount, remainingBalance: receivable.balance };
}
// 应收账款预警
async sendPaymentReminder() {
const today = new Date();
const threeDaysLater = new Date(today.getTime() + 3 * 24 * 60 * 60 * 1000);
// 查找即将到期的应收账款(3天内)
const soonDue = await this.Receivable.find({
status: 'pending',
dueDate: { $gte: today, $lte: threeDaysLater }
});
for (const receivable of soonDue) {
await this.Notification.send({
customerId: receivable.customerId,
type: 'payment_reminder',
title: '应收账款到期提醒',
content: `您有一笔金额为 ${receivable.balance} 元的账款将于 ${receivable.dueDate.toLocaleDateString()} 到期,请及时付款。`
});
}
// 查找已超期的应收账款
const overdue = await this.Receivable.find({
status: { $in: ['pending', 'partial'] },
dueDate: { $lt: today }
});
for (const receivable of overdue) {
const overdueDays = Math.floor((today - receivable.dueDate) / (24 * 60 * 60 * 1000));
// 根据超期天数发送不同级别的催收通知
if (overdueDays === 1) {
await this.Notification.sendFirstReminder(receivable);
} else if (overdueDays === 7) {
await this.Notification.sendSecondReminder(receivable);
} else if (overdueDays === 30) {
await this.Notification.sendUrgentReminder(receivable);
}
}
return { soonDueCount: soonDue.length, overdueCount: overdue.length };
}
}
总结
客户信用管理系统是进销存系统控制经营风险的重要模块,核心价值包括:
- 风险控制:科学的信用评估减少坏账风险
- 额度管理:动态信用额度优化资金使用
- 自动预警:智能账期提醒减少人工跟进
- 持续优化:自动调整信用等级适应市场变化
通过信用管理系统的实施,企业可以实现销售与风险的最佳平衡。