# 导入datetime和timedelta类,用于处理日期和时间
from datetime import datetime, timedelta
# 导入类型提示模块,用于声明函数参数和返回值类型
from typing import List, Dict
# 导入日志模块,用于记录系统运行日志
import logging
# 导入双端队列类,用于实现FIFO(先进先出)功能
from collections import deque
class FIFOInventory:
"""先进先出库存管理类,用于管理库存的入库和出库操作"""
def __init__(self):
# 创建一个字典,用于存储每个产品的FIFO队列
self.inventory_queue = {}
# 创建一个字典,用于存储每个产品的总库存数量
self.total_inventory = {}
def add_inventory(self, product_id: str, quantity: int, batch_id: str = None):
"""添加库存的方法,处理入库操作"""
# 如果产品ID不在库存队列中,初始化该产品的队列和总库存
if product_id not in self.inventory_queue:
# 为新产品创建一个空的双端队列
self.inventory_queue[product_id] = deque()
# 初始化该产品的总库存为0
self.total_inventory[product_id] = 0
# 创建一个入库记录字典
entry = {
# 如果没有提供批次号,则生成一个基于当前时间的批次号
'batch_id': batch_id or f"BATCH_{datetime.now().strftime('%Y%m%d%H%M%S')}",
# 记录入库数量
'quantity': quantity,
# 记录入库时间
'date': datetime.now()
}
# 将入库记录添加到产品的FIFO队列中
self.inventory_queue[product_id].append(entry)
# 更新产品的总库存数量
self.total_inventory[product_id] += quantity
# 打印入库成功的信息
print(f"入库成功 - 产品: {product_id}, 批次: {entry['batch_id']}, 数量: {quantity}")
# 返回生成的批次号
return entry['batch_id']
def remove_inventory(self, product_id: str, quantity: int):
"""移除库存的方法,处理出库操作"""
# 检查产品是否存在
if product_id not in self.inventory_queue:
raise ValueError(f"产品 {product_id} 不存在")
# 检查库存是否充足
if self.total_inventory[product_id] < quantity:
raise ValueError(f"库存不足 - 需要: {quantity}, 现有: {self.total_inventory[product_id]}")
# 初始化待出库数量
remaining_quantity = quantity
# 创建一个列表存储出库记录
removed_entries = []
# 循环处理出库,直到数量满足要求
while remaining_quantity > 0:
# 检查是否还有库存可用
if not self.inventory_queue[product_id]:
break
# 获取最早入库的批次(FIFO原则)
current_entry = self.inventory_queue[product_id][0]
# 如果当前批次的数量小于或等于待出库数量
if current_entry['quantity'] <= remaining_quantity:
# 移除整个批次
removed_entry = self.inventory_queue[product_id].popleft()
# 记录实际出库数量
removed_quantity = removed_entry['quantity']
# 添加出库记录
removed_entries.append({
'batch_id': removed_entry['batch_id'],
'quantity': removed_quantity,
'date': removed_entry['date']
})
# 更新待出库数量
remaining_quantity -= removed_quantity
else:
# 如果当前批次数量大于待出库数量,则部分出库
removed_quantity = remaining_quantity
# 更新批次中剩余的数量
current_entry['quantity'] -= remaining_quantity
# 添加出库记录
removed_entries.append({
'batch_id': current_entry['batch_id'],
'quantity': removed_quantity,
'date': current_entry['date']
})
# 设置待出库数量为0
remaining_quantity = 0
# 更新产品的总库存
self.total_inventory[product_id] -= quantity
# 打印出库成功信息
print(f"出库成功 - 产品: {product_id}, 总数量: {quantity}")
# 返回出库记录列表
return removed_entries
def get_inventory_level(self, product_id: str):
"""获取指定产品的当前库存水平"""
# 返回产品的总库存数量,如果产品不存在则返回0
return self.total_inventory.get(product_id, 0)
def get_inventory_details(self, product_id: str):
"""获取指定产品的库存详细信息"""
# 如果产品不在库存中,返回空列表
if product_id not in self.inventory_queue:
return []
# 返回产品的所有批次信息列表
return list(self.inventory_queue[product_id])
class SafetyStock:
"""安全库存类,用于设置和管理产品的安全库存水平"""
def __init__(self, min_qty: int, max_qty: int):
# 设置最小安全库存量
self.min_qty = min_qty
# 设置最大安全库存量
self.max_qty = max_qty
class ERPEngine:
"""ERP系统核心引擎类,管理整个系统的业务逻辑"""
def __init__(self):
# 初始化销售订单列表
self.sales_orders = []
# 初始化生产订单列表
self.production_orders = []
# 初始化采购订单列表
self.purchase_orders = []
# 初始化安全库存设置字典
self.safety_stock = {}
# 初始化供应商信息字典
self.suppliers = {}
# 初始化物料清单字典
self.bom = {}
# 创建日志记录器
self.logger = logging.getLogger(__name__)
# 创建FIFO库存管理实例
self.fifo_inventory = FIFOInventory()
class SalesOrder:
"""销售订单内部类,管理销售订单信息"""
def __init__(self, order_id: str, product_id: str, quantity: int, customer_id: str):
# 设置订单编号
self.order_id = order_id
# 设置产品编号
self.product_id = product_id
# 设置订单数量
self.quantity = quantity
# 设置客户编号
self.customer_id = customer_id
# 设置订单状态为草稿
self.status = 'draft'
# 记录订单创建时间
self.create_date = datetime.now()
class ProductionOrder:
"""生产订单内部类,管理生产订单信息"""
def __init__(self, order_id: str, product_id: str, quantity: int):
# 设置生产订单编号
self.order_id = order_id
# 设置产品编号
self.product_id = product_id
# 设置生产数量
self.quantity = quantity
# 设置订单状态为已计划
self.status = 'planned'
# 初始化开始时间为空
self.start_date = None
# 初始化结束时间为空
self.end_date = None
class PurchaseOrder:
"""采购订单内部类,管理采购订单信息"""
def __init__(self, order_id: str, material_id: str, quantity: int, supplier_id: str):
# 设置采购订单编号
self.order_id = order_id
# 设置物料编号
self.material_id = material_id
# 设置采购数量
self.quantity = quantity
# 设置供应商编号
self.supplier_id = supplier_id
# 设置订单状态为草稿
self.status = 'draft'
# 记录订单创建时间
self.create_date = datetime.now()
def create_sales_order(self, product_id: str, quantity: int, customer_id: str) -> str:
"""创建新的销售订单"""
# 生成新的销售订单编号
order_id = f"SO{len(self.sales_orders) + 1:06d}"
# 创建新的销售订单对象
order = self.SalesOrder(order_id, product_id, quantity, customer_id)
# 将订单添加到销售订单列表
self.sales_orders.append(order)
# 记录创建订单的日志
self.logger.info(f"Created sales order: {order_id}")
# 检查库存并规划生产
self.check_and_plan_production(product_id, quantity)
# 返回订单编号
return order_id
def check_and_plan_production(self, product_id: str, quantity: int):
"""检查库存并规划生产需求"""
# 获取当前可用库存
available_qty = self.fifo_inventory.get_inventory_level(product_id)
# 如果库存不足,创建生产订单
if available_qty < quantity:
# 计算需要生产的数量
needed_qty = quantity - available_qty
# 创建生产订单
self.create_production_order(product_id, needed_qty)
def create_production_order(self, product_id: str, quantity: int) -> str:
"""创建新的生产订单"""
# 生成新的生产订单编号
order_id = f"PO{len(self.production_orders) + 1:06d}"
# 创建新的生产订单对象
order = self.ProductionOrder(order_id, product_id, quantity)
# 将订单添加到生产订单列表
self.production_orders.append(order)
# 检查物料需求
self.check_materials_requirement(product_id, quantity)
# 返回订单编号
return order_id
def check_materials_requirement(self, product_id: str, quantity: int):
"""检查生产所需的原材料需求"""
# 检查产品是否存在物料清单(BOM)
if product_id in self.bom:
# 遍历产品所需的每种物料
for material_id, required_qty in self.bom[product_id].items():
# 计算总需求量
total_required = required_qty * quantity
# 获取当前物料库存量
available_qty = self.fifo_inventory.get_inventory_level(material_id)
# 如果库存不足,创建采购订单
if available_qty < total_required:
self.check_and_create_purchase_order(material_id, total_required - available_qty)
def set_safety_stock(self, product_id: str, min_qty: int, max_qty: int):
"""设置产品的安全库存水平"""
# 验证最小库存不能大于最大库存
if min_qty > max_qty:
raise ValueError("Minimum quantity cannot be greater than maximum quantity")
# 创建安全库存设置
self.safety_stock[product_id] = SafetyStock(min_qty, max_qty)
def check_stock_level(self, product_id: str) -> Dict:
"""检查产品的库存水平状态"""
# 获取当前库存量
current_stock = self.fifo_inventory.get_inventory_level(product_id)
# 获取安全库存设置
safety_stock = self.safety_stock.get(product_id)
# 如果没有设置安全库存,返回基本信息
if safety_stock is None:
return {
'product_id': product_id,
'current_stock': current_stock,
'status': 'no_safety_stock_defined'
}
# 判断库存状态
if current_stock < safety_stock.min_qty:
status = 'below_minimum'
elif current_stock > safety_stock.max_qty:
status = 'above_maximum'
else:
status = 'normal'
# 返回完整的库存状态信息
return {
'product_id': product_id,
'current_stock': current_stock,
'min_safety_stock': safety_stock.min_qty,
'max_safety_stock': safety_stock.max_qty,
'status': status
}
def check_and_create_purchase_order(self, material_id: str, quantity: int):
"""检查并创建采购订单"""
# 获取物料的安全库存设置
safety_stock = self.safety_stock.get(material_id)
# 如果没有设置安全库存,记录警告并返回
if not safety_stock:
self.logger.warning(f"No safety stock defined for material: {material_id}")
return
# 获取当前库存量
current_stock = self.fifo_inventory.get_inventory_level(material_id)
# 如果当前库存低于最小安全库存
if current_stock < safety_stock.min_qty:
# 计算目标库存量(取最大库存和当前需求量的较大值)
target_stock = max(safety_stock.max_qty, current_stock + quantity)
# 计算需要采购的数量
purchase_qty = target_stock - current_stock
# 创建采购订单
self.create_purchase_order(material_id, purchase_qty)
def create_purchase_order(self, material_id: str, quantity: int) -> str:
"""创建采购订单"""
# 获取最佳供应商
supplier_id = self.get_best_supplier(material_id)
# 如果没有找到供应商,记录错误并返回
if supplier_id is None:
self.logger.error(f"No supplier found for material: {material_id}")
return None
# 生成采购订单编号
order_id = f"PUR{len(self.purchase_orders) + 1:06d}"
# 创建采购订单对象
order = self.PurchaseOrder(order_id, material_id, quantity, supplier_id)
# 将订单添加到采购订单列表
self.purchase_orders.append(order)
# 记录创建订单的日志
self.logger.info(f"Created purchase order: {order_id}")
# 返回订单编号
return order_id
def get_best_supplier(self, material_id: str) -> str:
"""获取物料的最佳供应商"""
# 如果物料有对应的供应商,返回第一个供应商
if material_id in self.suppliers:
return self.suppliers[material_id][0]
# 如果没有供应商,返回None
return None
def process_production_completion(self, production_order_id: str):
"""处理生产完成的订单"""
# 遍历所有生产订单
for order in self.production_orders:
if order.order_id == production_order_id:
# 更新订单状态为完成
order.status = 'completed'
# 将生产的产品加入库存
batch_id = self.fifo_inventory.add_inventory(order.product_id, order.quantity)
# 记录日志
self.logger.info(f"Production completed, created batch: {batch_id}")
break
def process_purchase_receipt(self, purchase_order_id: str):
"""处理采购收货"""
# 遍历所有采购订单
for order in self.purchase_orders:
if order.order_id == purchase_order_id:
# 更新订单状态为已收货
order.status = 'received'
# 将收到的物料加入库存
batch_id = self.fifo_inventory.add_inventory(order.material_id, order.quantity)
# 记录日志
self.logger.info(f"Purchase received, created batch: {batch_id}")
break
def process_sales_delivery(self, sales_order_id: str):
"""处理销售订单发货"""
# 遍历所有销售订单
for order in self.sales_orders:
if order.order_id == sales_order_id:
try:
# 从库存中移除产品
removed_entries = self.fifo_inventory.remove_inventory(
order.product_id,
order.quantity
)
# 更新订单状态为已发货
order.status = 'delivered'
# 记录日志
self.logger.info(f"Sales delivered using batches: {removed_entries}")
except ValueError as e:
# 如果出现错误(如库存不足),记录错误日志
self.logger.error(f"Failed to process sales order: {e}")
def get_inventory_report(self, product_id: str) -> Dict:
"""获取产品的库存报告"""
# 获取当前库存量
current_stock = self.fifo_inventory.get_inventory_level(product_id)
# 获取批次详细信息
batch_details = self.fifo_inventory.get_inventory_details(product_id)
# 获取安全库存设置
safety_stock = self.safety_stock.get(product_id)
# 创建基本报告信息
report = {
'product_id': product_id,
'current_stock': current_stock,
'batches': batch_details
}
# 如果设置了安全库存,添加安全库存信息
if safety_stock:
report.update({
'min_safety_stock': safety_stock.min_qty,
'max_safety_stock': safety_stock.max_qty
})
# 返回完整的库存报告
return report
def main():
"""主函数:演示ERP系统的基本功能"""
# 初始化 ERP 系统实例
erp = ERPEngine()
# 设置产品PROD001的物料清单:需要2个MAT001和1个MAT002
erp.bom = {
'PROD001': {'MAT001': 2, 'MAT002': 1}
}
# 为产品和原材料设置安全库存水平
erp.set_safety_stock('PROD001', min_qty=100, max_qty=500) # 产品的安全库存
erp.set_safety_stock('MAT001', min_qty=200, max_qty=1000) # 原材料1的安全库存
erp.set_safety_stock('MAT002', min_qty=150, max_qty=800) # 原材料2的安全库存
# 配置供应商信息:MAT001有两个供应商,MAT002有一个供应商
erp.suppliers = {
'MAT001': ['SUP001', 'SUP002'], # 原材料1的供应商列表
'MAT002': ['SUP003'] # 原材料2的供应商
}
# 打印测试标题
print("\n=== FIFO库存管理测试 ===")
# 步骤1:添加初始库存
print("\n1. 添加初始库存:")
erp.fifo_inventory.add_inventory('PROD001', 80) # 添加80个产品
erp.fifo_inventory.add_inventory('MAT001', 400) # 添加400个原材料1
erp.fifo_inventory.add_inventory('MAT002', 300) # 添加300个原材料2
# 步骤2:创建销售订单
print("\n2. 创建销售订单:")
sales_order_id = erp.create_sales_order('PROD001', 20, 'CUST001') # 创建20个产品的订单
print(f"Created sales order: {sales_order_id}")
# 步骤3:显示库存状态报告
print("\n3. 库存状态报告:")
report = erp.get_inventory_report('PROD001') # 获取产品库存报告
print(f"产品: {report['product_id']}") # 打印产品ID
print(f"当前库存: {report['current_stock']}") # 打印当前库存量
# 打印每个批次的详细信息
print("\n批次详情:")
for batch in report['batches']:
print(f"批次号: {batch['batch_id']}") # 打印批次编号
print(f"数量: {batch['quantity']}") # 打印批次数量
print(f"入库时间: {batch['date']}") # 打印入库时间
print("---") # 分隔线
# 步骤4:处理销售发货
print("\n4. 处理销售发货:")
erp.process_sales_delivery(sales_order_id) # 处理销售订单的发货
# 步骤5:显示发货后的库存状态
print("\n5. 发货后库存状态:")
report = erp.get_inventory_report('PROD001') # 再次获取库存报告
print(f"剩余库存: {report['current_stock']}") # 打印剩余库存量
# 打印剩余批次的详细信息
print("\n剩余批次详情:")
for batch in report['batches']:
print(f"批次号: {batch['batch_id']}") # 打印批次编号
print(f"数量: {batch['quantity']}") # 打印批次数量
print(f"入库时间: {batch['date']}") # 打印入库时间
print("---") # 分隔线
# 程序入口点
if __name__ == "__main__":
# 配置日志级别为INFO(当前被注释)
# logging.basicConfig(level=logging.INFO)
# 运行主函数
print("##################1.销售出库 库存足#################")
main()
print("#################################################")
def main():
"""主函数:演示贸易公司的销售订单触发采购流程"""
# 初始化 ERP 引擎
erp = ERPEngine()
# 设置安全库存水平 (只设置产品的安全库存,因为是贸易公司)
erp.set_safety_stock('PROD001', min_qty=100, max_qty=500) # 产品的安全库存
# 设置供应商信息 (直接采购产品)
erp.suppliers = {
'PROD001': ['SUP001', 'SUP002'] # 产品的供应商
}
print("\n=== 贸易公司销售订单触发采购流程测试 ===")
# 1. 检查初始库存状态
print("\n1. 初始库存状态:")
print(f"PROD001初始库存: {erp.fifo_inventory.get_inventory_level('PROD001')}")
# 2. 添加少量初始库存
print("\n2. 添加初始库存:")
initial_stock = 50 # 初始库存50个
erp.fifo_inventory.add_inventory('PROD001', initial_stock)
print(f"添加后库存: {erp.fifo_inventory.get_inventory_level('PROD001')}")
# 3. 创建销售订单
print("\n3. 创建销售订单:")
sales_qty = 200 # 客户订购200个
sales_order_id = erp.create_sales_order('PROD001', sales_qty, 'CUST001')
print(f"创建销售订单: {sales_order_id}")
print(f"订购数量: {sales_qty}")
# 4. 检查库存缺口并触发采购
print("\n4. 库存缺口分析:")
current_stock = erp.fifo_inventory.get_inventory_level('PROD001')
shortage = sales_qty - current_stock
print(f"当前库存: {current_stock}")
print(f"订单需求: {sales_qty}")
print(f"库存缺口: {shortage}")
# 5. 创建采购订单
print("\n5. 创建采购订单:")
if shortage > 0:
# 计算采购数量(考虑安全库存)
safety_stock = erp.safety_stock['PROD001']
purchase_qty = max(shortage, safety_stock.max_qty - current_stock)
purchase_order_id = erp.create_purchase_order('PROD001', purchase_qty)
print(f"创建采购订单: {purchase_order_id}")
print(f"采购数量: {purchase_qty}")
# 6. 显示采购订单详情
print("\n6. 采购订单详情:")
for order in erp.purchase_orders:
print(f"\n采购订单号: {order.order_id}")
print(f"产品: {order.material_id}")
print(f"数量: {order.quantity}")
print(f"供应商: {order.supplier_id}")
print(f"状态: {order.status}")
# 7. 处理采购收货
print("\n7. 处理采购收货:")
for order in erp.purchase_orders:
erp.process_purchase_receipt(order.order_id)
print(f"已处理采购订单收货: {order.order_id}")
# 8. 查看收货后库存状态
print("\n8. 收货后库存状态:")
current_stock = erp.fifo_inventory.get_inventory_level('PROD001')
print(f"当前库存: {current_stock}")
# 显示详细的库存批次信息
print("\n库存批次详情:")
inventory_report = erp.get_inventory_report('PROD001')
for batch in inventory_report['batches']:
print(f"批次号: {batch['batch_id']}")
print(f"数量: {batch['quantity']}")
print(f"入库时间: {batch['date']}")
print("---")
# 9. 处理销售订单发货
print("\n9. 处理销售发货:")
try:
erp.process_sales_delivery(sales_order_id)
print(f"已完成销售订单发货: {sales_order_id}")
except ValueError as e:
print(f"发货失败: {e}")
# 10. 显示最终库存状态
print("\n10. 最终库存状态:")
final_stock = erp.fifo_inventory.get_inventory_level('PROD001')
print(f"最终库存: {final_stock}")
# 11. 检查是否需要补充安全库存
print("\n11. 安全库存检查:")
safety_stock = erp.safety_stock['PROD001']
if final_stock < safety_stock.min_qty:
replenishment_qty = safety_stock.max_qty - final_stock
print(f"库存低于安全水平,需要补充采购:")
print(f"当前库存: {final_stock}")
print(f"最小安全库存: {safety_stock.min_qty}")
print(f"建议补充数量: {replenishment_qty}")
else:
print("库存处于安全水平,无需补充")
# 12. 显示交易统计
print("\n12. 交易统计:")
print(f"初始库存: {initial_stock}")
print(f"采购入库: {sum(order.quantity for order in erp.purchase_orders)}")
print(f"销售出库: {sales_qty}")
print(f"当前库存: {final_stock}")
if __name__ == "__main__":
print("############2.销售出库 库存不足 发起采购##############")
main()
print("#################################################")
def main():
"""主函数:演示销售订单触发库存不足采购流程"""
# 初始化 ERP 引擎
erp = ERPEngine()
# 设置物料清单(BOM)
erp.bom = {
'PROD001': {'MAT001': 2, 'MAT002': 1} # 生产一个PROD001需要2个MAT001和1个MAT002
}
# 设置安全库存水平
erp.set_safety_stock('PROD001', min_qty=100, max_qty=500) # 产品的安全库存
erp.set_safety_stock('MAT001', min_qty=200, max_qty=1000) # 原材料1的安全库存
erp.set_safety_stock('MAT002', min_qty=150, max_qty=800) # 原材料2的安全库存
# 设置供应商信息
erp.suppliers = {
'MAT001': ['SUP001', 'SUP002'],
'MAT002': ['SUP003']
}
print("\n=== 销售订单触发库存不足采购流程测试 ===")
# 1. 初始库存状态
print("\n1. 初始库存状态:")
print("\n产品库存:")
print(f"PROD001: {erp.fifo_inventory.get_inventory_level('PROD001')}")
print("\n原材料库存:")
print(f"MAT001: {erp.fifo_inventory.get_inventory_level('MAT001')}")
print(f"MAT002: {erp.fifo_inventory.get_inventory_level('MAT002')}")
# 2. 添加少量初始库存
print("\n2. 添加初始库存:")
erp.fifo_inventory.add_inventory('PROD001', 50) # 产品库存
erp.fifo_inventory.add_inventory('MAT001', 150) # 原材料1库存
erp.fifo_inventory.add_inventory('MAT002', 100) # 原材料2库存
print("\n添加后的库存水平:")
print(f"PROD001: {erp.fifo_inventory.get_inventory_level('PROD001')}")
print(f"MAT001: {erp.fifo_inventory.get_inventory_level('MAT001')}")
print(f"MAT002: {erp.fifo_inventory.get_inventory_level('MAT002')}")
# 3. 创建销售订单
print("\n3. 创建销售订单:")
sales_qty = 200 # 订购200个产品
sales_order_id = erp.create_sales_order('PROD001', sales_qty, 'CUST001')
print(f"创建销售订单: {sales_order_id}, 数量: {sales_qty}")
# 4. 检查产品库存和生产需求
print("\n4. 产品库存检查:")
current_stock = erp.fifo_inventory.get_inventory_level('PROD001')
needed_qty = sales_qty - current_stock
print(f"当前产品库存: {current_stock}")
print(f"销售需求: {sales_qty}")
print(f"需要生产数量: {needed_qty}")
# 5. 显示生产订单
print("\n5. 生产订单信息:")
for order in erp.production_orders:
print(f"\n生产订单号: {order.order_id}")
print(f"产品: {order.product_id}")
print(f"数量: {order.quantity}")
print(f"状态: {order.status}")
# 6. 显示原材料需求和采购订单
print("\n6. 原材料需求分析:")
for material, qty_per_unit in erp.bom['PROD001'].items():
total_required = qty_per_unit * needed_qty
current_stock = erp.fifo_inventory.get_inventory_level(material)
print(f"\n物料 {material}:")
print(f"- 需求数量: {total_required}")
print(f"- 当前库存: {current_stock}")
print(f"- 缺口数量: {max(0, total_required - current_stock)}")
# 7. 显示自动生成的采购订单
print("\n7. 采购订单信息:")
for order in erp.purchase_orders:
print(f"\n采购订单号: {order.order_id}")
print(f"物料: {order.material_id}")
print(f"数量: {order.quantity}")
print(f"供应商: {order.supplier_id}")
print(f"状态: {order.status}")
# 8. 处理采购收货
print("\n8. 处理采购收货:")
for order in erp.purchase_orders:
erp.process_purchase_receipt(order.order_id)
print(f"处理采购订单收货: {order.order_id}")
# 9. 开始生产
print("\n9. 开始生产:")
for order in erp.production_orders:
erp.process_production_completion(order.order_id)
print(f"完成生产订单: {order.order_id}")
# 10. 显示最终库存状态
print("\n10. 最终库存状态:")
print("\n产品库存:")
prod_report = erp.get_inventory_report('PROD001')
print(f"PROD001 当前库存: {prod_report['current_stock']}")
print(f"最小安全库存: {prod_report['min_safety_stock']}")
print(f"最大安全库存: {prod_report['max_safety_stock']}")
print("\n原材料库存:")
for material in ['MAT001', 'MAT002']:
report = erp.get_inventory_report(material)
print(f"\n{material}:")
print(f"当前库存: {report['current_stock']}")
print(f"最小安全库存: {report['min_safety_stock']}")
print(f"最大安全库存: {report['max_safety_stock']}")
# 11. 处理销售发货
print("\n11. 处理销售发货:")
erp.process_sales_delivery(sales_order_id)
print(f"已处理销售订单发货: {sales_order_id}")
# 12. 显示发货后的最终库存
print("\n12. 发货后的最终库存:")
print(f"PROD001: {erp.fifo_inventory.get_inventory_level('PROD001')}")
print(f"MAT001: {erp.fifo_inventory.get_inventory_level('MAT001')}")
print(f"MAT002: {erp.fifo_inventory.get_inventory_level('MAT002')}")
if __name__ == "__main__":
#logging.basicConfig(level=logging.INFO)
print("##########3.销售订单-原料不足-采购-采购收货###########")
main()
print("#################################################")
def main():
"""主函数:演示ERP系统的生产订单管理功能"""
# 初始化 ERP 引擎
erp = ERPEngine()
# 设置物料清单(BOM)
erp.bom = {
'PROD001': {'MAT001': 2, 'MAT002': 1}, # 产品PROD001的BOM
'PROD002': {'MAT001': 1, 'MAT002': 3} # 产品PROD002的BOM
}
# 设置安全库存水平
erp.set_safety_stock('PROD001', min_qty=100, max_qty=500)
erp.set_safety_stock('PROD002', min_qty=80, max_qty=400)
erp.set_safety_stock('MAT001', min_qty=200, max_qty=1000)
erp.set_safety_stock('MAT002', min_qty=150, max_qty=800)
# 设置供应商
erp.suppliers = {
'MAT001': ['SUP001', 'SUP002'],
'MAT002': ['SUP003']
}
print("\n=== 生产订单管理测试 ===")
# 1. 添加初始原材料库存
print("\n1. 添加初始原材料库存:")
erp.fifo_inventory.add_inventory('MAT001', 500) # 添加500个MAT001
erp.fifo_inventory.add_inventory('MAT002', 400) # 添加400个MAT002
print("初始库存水平:")
print(f"MAT001: {erp.fifo_inventory.get_inventory_level('MAT001')}")
print(f"MAT002: {erp.fifo_inventory.get_inventory_level('MAT002')}")
# 2. 创建生产订单
print("\n2. 创建生产订单:")
# 为PROD001创建生产订单
prod_order_1 = erp.create_production_order('PROD001', 100)
print(f"创建PROD001生产订单: {prod_order_1}")
# 为PROD002创建生产订单
prod_order_2 = erp.create_production_order('PROD002', 50)
print(f"创建PROD002生产订单: {prod_order_2}")
# 3. 查看生产订单状态
print("\n3. 生产订单状态:")
for order in erp.production_orders:
print(f"订单号: {order.order_id}")
print(f"产品: {order.product_id}")
print(f"数量: {order.quantity}")
print(f"状态: {order.status}")
print("---")
# 4. 检查原材料消耗情况
print("\n4. 原材料需求:")
for prod_order in erp.production_orders:
print(f"\n生产订单 {prod_order.order_id} 的原材料需求:")
for material, qty in erp.bom[prod_order.product_id].items():
required_qty = qty * prod_order.quantity
available_qty = erp.fifo_inventory.get_inventory_level(material)
print(f"物料 {material}:")
print(f"- 需求数量: {required_qty}")
print(f"- 当前库存: {available_qty}")
print(f"- 库存状态: {'充足' if available_qty >= required_qty else '不足'}")
# 5. 模拟生产完成
print("\n5. 处理生产完成:")
erp.process_production_completion(prod_order_1)
# 6. 查看生产后的库存状态
print("\n6. 生产完成后状态:")
# 查看产品库存
print("\n产品库存:")
print(f"PROD001: {erp.fifo_inventory.get_inventory_level('PROD001')}")
print(f"PROD002: {erp.fifo_inventory.get_inventory_level('PROD002')}")
# 查看原材料库存
print("\n原材料库存:")
print(f"MAT001: {erp.fifo_inventory.get_inventory_level('MAT001')}")
print(f"MAT002: {erp.fifo_inventory.get_inventory_level('MAT002')}")
# 7. 查看详细的库存报告
print("\n7. 详细库存报告:")
for product_id in ['PROD001', 'PROD002', 'MAT001', 'MAT002']:
report = erp.get_inventory_report(product_id)
print(f"\n{product_id}库存报告:")
print(f"当前库存: {report['current_stock']}")
if 'min_safety_stock' in report:
print(f"最小安全库存: {report['min_safety_stock']}")
print(f"最大安全库存: {report['max_safety_stock']}")
print("\n批次详情:")
for batch in report['batches']:
print(f"批次号: {batch['batch_id']}")
print(f"数量: {batch['quantity']}")
print(f"入库时间: {batch['date']}")
print("---")
# 8. 创建新的销售订单,触发新的生产需求
print("\n8. 创建销售订单,触发生产需求:")
sales_order = erp.create_sales_order('PROD001', 200, 'CUST001')
print(f"创建销售订单: {sales_order}")
# 9. 查看新生成的生产订单
print("\n9. 新生成的生产订单:")
for order in erp.production_orders:
if order.status == 'planned': # 只显示新计划的订单
print(f"订单号: {order.order_id}")
print(f"产品: {order.product_id}")
print(f"数量: {order.quantity}")
print(f"状态: {order.status}")
print("---")
if __name__ == "__main__":
#logging.basicConfig(level=logging.INFO)
print("#######################################3. 生产订单:创建销售订单,触发生产需求###########################################")
main()
print("######################################-------------------------------############################################")
def main():
"""主函数:演示ERP系统的基本功能,包括采购订单管理"""
# 初始化 ERP 引擎
erp = ERPEngine()
# 设置物料清单
erp.bom = {
'PROD001': {'MAT001': 2, 'MAT002': 1} # 生产一个PROD001需要2个MAT001和1个MAT002
}
# 设置安全库存水平
erp.set_safety_stock('PROD001', min_qty=100, max_qty=500)
erp.set_safety_stock('MAT001', min_qty=200, max_qty=1000)
erp.set_safety_stock('MAT002', min_qty=150, max_qty=800)
# 设置供应商信息
erp.suppliers = {
'MAT001': ['SUP001', 'SUP002'],
'MAT002': ['SUP003']
}
print("\n=== ERP系统测试 ===")
# 1. 查看初始库存状态
print("\n1. 初始库存状态:")
print(f"MAT001库存: {erp.fifo_inventory.get_inventory_level('MAT001')}")
print(f"MAT002库存: {erp.fifo_inventory.get_inventory_level('MAT002')}")
# 2. 创建采购订单
print("\n2. 创建采购订单:")
# 为MAT001创建采购订单(数量低于安全库存)
purchase_order_1 = erp.create_purchase_order('MAT001', 300)
print(f"创建MAT001采购订单: {purchase_order_1}")
# 为MAT002创建采购订单
purchase_order_2 = erp.create_purchase_order('MAT002', 200)
print(f"创建MAT002采购订单: {purchase_order_2}")
# 3. 处理采购收货
print("\n3. 处理采购收货:")
erp.process_purchase_receipt(purchase_order_1)
erp.process_purchase_receipt(purchase_order_2)
# 4. 查看收货后的库存状态
print("\n4. 收货后库存状态:")
print(f"MAT001库存: {erp.fifo_inventory.get_inventory_level('MAT001')}")
print(f"MAT002库存: {erp.fifo_inventory.get_inventory_level('MAT002')}")
# 5. 创建大量产品订单,触发自动采购
print("\n5. 创建生产订单,触发自动采购:")
production_order = erp.create_production_order('PROD001', 200)
print(f"创建生产订单: {production_order}")
# 6. 查看库存详细报告
print("\n6. 库存详细报告:")
for material_id in ['MAT001', 'MAT002']:
report = erp.get_inventory_report(material_id)
print(f"\n{material_id}库存报告:")
print(f"当前库存: {report['current_stock']}")
if 'min_safety_stock' in report:
print(f"最小安全库存: {report['min_safety_stock']}")
print(f"最大安全库存: {report['max_safety_stock']}")
print("\n批次详情:")
for batch in report['batches']:
print(f"批次号: {batch['batch_id']}")
print(f"数量: {batch['quantity']}")
print(f"入库时间: {batch['date']}")
print("---")
# 7. 查看所有采购订单状态
print("\n7. 采购订单状态:")
for order in erp.purchase_orders:
print(f"订单号: {order.order_id}")
print(f"物料: {order.material_id}")
print(f"数量: {order.quantity}")
print(f"供应商: {order.supplier_id}")
print(f"状态: {order.status}")
print("---")
if __name__ == "__main__":
#logging.basicConfig(level=logging.INFO)
print("##################################4.采购单例子:创建生产订单,触发自动采购(拉式)###################################################")
main()
print("##################################-------------------------------###################################################")