进销存系统供应商管理与智能比价
供应商管理概述
供应商是进销存系统的重要参与方,优质的供应商资源可以降低采购成本、提高供应链效率。本文介绍供应商管理系统的设计方案,包括供应商评估、智能比价、合同管理等功能模块的实现。
供应商评估体系
多维度供应商评分模型:
// 供应商评估模型
class SupplierEvaluator {
constructor(weights = {}) {
this.weights = {
price: weights.price || 0.30, // 价格权重 30%
quality: weights.quality || 0.25, // 质量权重 25%
delivery: weights.delivery || 0.20, // 交付权重 20%
service: weights.service || 0.15, // 服务权重 15%
cooperation: weights.cooperation || 0.10, // 合作稳定性 10%
...weights
};
}
// 评估供应商
evaluate(supplierId, metrics) {
const scores = {
// 价格得分:低价得高分
price: this.calculatePriceScore(metrics.avgPrice, metrics.marketPrice),
// 质量得分
quality: this.calculateQualityScore(metrics.defectRate),
// 交付得分
delivery: this.calculateDeliveryScore(metrics.onTimeRate, metrics.delayDays),
// 服务得分
service: this.calculateServiceScore(metrics.responseTime, metrics.complaintCount),
// 合作稳定性
cooperation: this.calculateCooperationScore(metrics.cooperationYears, metrics.orderCompletionRate)
};
// 加权计算总分
const totalScore = Object.entries(scores).reduce((sum, [key, score]) => {
return sum + score * this.weights[key];
}, 0);
return {
supplierId,
scores,
totalScore: Math.round(totalScore * 100) / 100,
grade: this.getGrade(totalScore)
};
}
// 价格得分计算
calculatePriceScore(avgPrice, marketPrice) {
if (!marketPrice || marketPrice === 0) return 70;
const ratio = (marketPrice - avgPrice) / marketPrice;
// 低于市场价 20% 得满分,高于市场价 20% 得 0 分
return Math.max(0, Math.min(100, 50 + ratio * 250));
}
// 质量得分计算
calculateQualityScore(defectRate) {
// 缺陷率 0% 得 100 分,每增加 1% 扣 10 分
return Math.max(0, 100 - defectRate * 100);
}
// 交付得分计算
calculateDeliveryScore(onTimeRate, avgDelayDays) {
const onTimeScore = onTimeRate * 100;
const delayScore = Math.max(0, 100 - avgDelayDays * 10);
return onTimeScore * 0.7 + delayScore * 0.3;
}
// 服务得分计算
calculateServiceScore(avgResponseTime, complaintCount) {
// 响应时间评分
let responseScore = 100;
if (avgResponseTime > 24) responseScore = 20;
else if (avgResponseTime > 12) responseScore = 40;
else if (avgResponseTime > 4) responseScore = 60;
else if (avgResponseTime > 2) responseScore = 80;
// 投诉扣分
const complaintScore = Math.max(0, 100 - complaintCount * 10);
return responseScore * 0.5 + complaintScore * 0.5;
}
// 合作稳定性
calculateCooperationScore(years, completionRate) {
const yearsScore = Math.min(100, years * 20);
const completionScore = completionRate * 100;
return yearsScore * 0.3 + completionScore * 0.7;
}
// 评级
getGrade(score) {
if (score >= 90) return 'A+';
if (score >= 80) return 'A';
if (score >= 70) return 'B';
if (score >= 60) return 'C';
return 'D';
}
}
// 供应商等级划分
const supplierGrades = {
'A+': {
label: '战略合作伙伴',
color: '#52c41a',
discount: 0.15,
paymentTerms: '月结60天',
priority: 1
},
'A': {
label: '优秀供应商',
color: '#1890ff',
discount: 0.10,
paymentTerms: '月结45天',
priority: 2
},
'B': {
label: '合格供应商',
color: '#faad14',
discount: 0.05,
paymentTerms: '月结30天',
priority: 3
},
'C': {
label: '观察供应商',
color: '#fa541c',
discount: 0,
paymentTerms: '现结',
priority: 4
},
'D': {
label: '不合格供应商',
color: '#f5222d',
discount: 0,
paymentTerms: '现结',
priority: 99,
action: '建议淘汰'
}
};
// 供应商分类
const supplierCategories = [
{ id: 'raw', name: '原材料', criticality: 'high' },
{ id: 'parts', name: '零部件', criticality: 'high' },
{ id: 'pack', name: '包装材料', criticality: 'medium' },
{ id: 'consumable', name: '辅料耗材', criticality: 'low' }
];
智能比价系统
自动获取多供应商报价并比较:
// 智能比价系统
class PriceComparisonSystem {
constructor() {
this.priceHistory = new Map(); // supplierId:productId -> [prices]
}
// 发起询价
async createInquiry(inquiryData) {
const inquiry = {
id: this.generateId(),
products: inquiryData.products, // [{ productId, quantity, spec }]
suppliers: inquiryData.suppliers,
deadline: inquiryData.deadline,
status: 'pending',
createdAt: new Date()
};
// 向所有供应商发送询价请求
for (const supplierId of inquiry.suppliers) {
await this.sendInquiryRequest(supplierId, inquiry);
}
return inquiry;
}
// 收集报价
async collectQuotations(inquiryId) {
const quotations = [];
for (const supplierId of this.getInquirySuppliers(inquiryId)) {
const quote = await this.getSupplierQuote(supplierId, inquiryId);
if (quote) {
quotations.push(quote);
}
}
return quotations;
}
// 比价分析
async comparePrices(inquiryId, quotations) {
const productAnalysis = {};
// 按产品分组分析
for (const quote of quotations) {
for (const item of quote.items) {
const productId = item.productId;
if (!productAnalysis[productId]) {
productAnalysis[productId] = {
productId,
quotations: [],
lowestPrice: null,
avgPrice: null,
recommendation: null
};
}
productAnalysis[productId].quotations.push({
supplierId: quote.supplierId,
supplierName: quote.supplierName,
price: item.unitPrice,
totalPrice: item.unitPrice * item.quantity,
deliveryDate: item.deliveryDate,
validUntil: item.validUntil,
remarks: item.remarks
});
}
}
// 计算各项指标并推荐
for (const productId in productAnalysis) {
const analysis = productAnalysis[productId];
const prices = analysis.quotations.map(q => q.price);
analysis.lowestPrice = Math.min(...prices);
analysis.avgPrice = prices.reduce((s, p) => s + p, 0) / prices.length;
analysis.priceDifference = ((analysis.avgPrice - analysis.lowestPrice) / analysis.avgPrice * 100).toFixed(2);
// 综合推荐(考虑价格、质量、交期)
analysis.recommendation = this.getBestRecommendation(analysis.quotations);
}
return productAnalysis;
}
// 综合推荐
getBestRecommendation(quotations) {
// 过滤有效报价
const valid = quotations.filter(q =>
new Date(q.validUntil) > new Date()
);
if (valid.length === 0) return null;
// 评分计算
const scored = valid.map(q => {
const priceScore = 100 - (q.price / Math.max(...valid.map(v => v.price)) * 50);
// 假设交期越早越好
const deliveryScore = Math.max(0, 100 - (new Date(q.deliveryDate) - new Date()) / (1000 * 60 * 60 * 24));
return {
...q,
score: priceScore * 0.6 + deliveryScore * 0.4
};
});
// 排序返回最佳
scored.sort((a, b) => b.score - a.score);
return {
supplierId: scored[0].supplierId,
supplierName: scored[0].supplierName,
price: scored[0].price,
reason: `价格优势 ${(100 - scored[0].price / scored[scored.length - 1].price * 100).toFixed(1)}%`
};
}
// 历史价格分析
analyzePriceHistory(productId, supplierId) {
const history = this.priceHistory.get(`${supplierId}:${productId}`) || [];
if (history.length < 2) return null;
const prices = history.map(p => p.price);
const trend = prices[prices.length - 1] > prices[0] ? 'up' : 'down';
const volatility = this.calculateVolatility(prices);
return {
supplierId,
productId,
minPrice: Math.min(...prices),
maxPrice: Math.max(...prices),
avgPrice: prices.reduce((s, p) => s + p, 0) / prices.length,
trend,
volatility,
latestPrice: prices[prices.length - 1],
priceCount: prices.length
};
}
calculateVolatility(prices) {
const avg = prices.reduce((s, p) => s + p, 0) / prices.length;
const variance = prices.reduce((s, p) => s + Math.pow(p - avg, 2), 0) / prices.length;
return Math.sqrt(variance) / avg;
}
}
合同管理
采购合同的生命周期管理:
// 采购合同管理
class PurchaseContractManager {
constructor() {
this.contracts = new Map();
}
// 创建合同
async createContract(contractData) {
const contract = {
id: this.generateId(),
contractNo: this.generateContractNo(contractData.supplierId),
supplierId: contractData.supplierId,
supplierName: contractData.supplierName,
items: contractData.items,
totalAmount: contractData.items.reduce((sum, item) =>
sum + item.price * item.quantity, 0),
paymentTerms: contractData.paymentTerms,
deliveryTerms: contractData.deliveryTerms,
startDate: contractData.startDate,
endDate: contractData.endDate,
status: 'draft',
attachments: [],
createdBy: contractData.userId,
createdAt: new Date()
};
// 合同条款校验
await this.validateContract(contract);
this.contracts.set(contract.id, contract);
return contract;
}
// 合同审批流程
async submitForApproval(contractId, approvers) {
const contract = this.contracts.get(contractId);
contract.status = 'pending_approval';
contract.approvers = approvers.map((userId, index) => ({
userId,
step: index + 1,
status: 'pending',
comment: ''
}));
contract.currentApprover = approvers[0];
// 发送审批通知
await this.sendApprovalNotification(approvers[0], contract);
return contract;
}
// 审批通过
async approve(contractId, userId, comment = '') {
const contract = this.contracts.get(contractId);
const approver = contract.approvers.find(a => a.userId === userId);
if (!approver) throw new Error('无审批权限');
approver.status = 'approved';
approver.comment = comment;
approver.approvedAt = new Date();
// 检查是否所有审批人都已通过
const allApproved = contract.approvers.every(a => a.status === 'approved');
if (allApproved) {
contract.status = 'active';
contract.approvedAt = new Date();
// 通知创建人
await this.notifyContractCreated(contract);
} else {
// 进入下一步审批
const nextApprover = contract.approvers.find(a => a.status === 'pending');
if (nextApprover) {
contract.currentApprover = nextApprover.userId;
await this.sendApprovalNotification(nextApprover.userId, contract);
}
}
return contract;
}
// 合同履约跟踪
async trackPerformance(contractId) {
const contract = this.contracts.get(contractId);
const deliveries = await this.getDeliveryRecords(contractId);
const performance = {
contractId,
totalItems: contract.items.length,
deliveredItems: deliveries.filter(d => d.status === 'delivered').length,
pendingItems: deliveries.filter(d => d.status === 'pending').length,
overdueDeliveries: deliveries.filter(d =>
d.status === 'pending' && new Date(d.plannedDate) < new Date()
).length,
totalOrderValue: contract.totalAmount,
deliveredValue: deliveries.reduce((sum, d) => sum + d.value, 0),
completionRate: 0
};
performance.completionRate = performance.deliveredItems / performance.totalItems * 100;
return performance;
}
}
// 合同到期提醒
class ContractExpirationMonitor {
constructor(contractManager) {
this.contractManager = contractManager;
}
// 检查即将到期的合同
checkExpiringContracts(daysThreshold = 30) {
const threshold = new Date();
threshold.setDate(threshold.getDate() + daysThreshold);
const expiring = [];
for (const [id, contract] of this.contractManager.contracts) {
if (contract.status === 'active' && contract.endDate <= threshold) {
expiring.push({
contractId: id,
contractNo: contract.contractNo,
supplierName: contract.supplierName,
endDate: contract.endDate,
daysRemaining: Math.ceil((contract.endDate - new Date()) / (1000 * 60 * 60 * 24))
});
}
}
return expiring.sort((a, b) => a.daysRemaining - b.daysRemaining);
}
// 发送提醒
async sendExpirationReminder(contract) {
console.log(`合同即将到期提醒:${contract.contractNo}`);
// 发送邮件/消息通知
}
}
总结
供应商管理与智能比价系统是采购管理的核心:
- 供应商评估:多维度评分,选择优质供应商
- 智能比价:自动收集报价,推荐最优方案
- 合同管理:合同生命周期管理,合规可控
- 风险预警:合同到期、交付延迟自动提醒
通过系统化管理,可以显著降低采购成本,提高供应链稳定性。