峰峦@叠嶂 2025-05-20 17:12 采纳率: 98%
浏览 8
已结题

针对产品的原料出入库管理的实现需求

请教一下,我们有一张产品原料表,最新库存=入库数量+现库存 - 出库数量,入库数量需要定期录入或导入维护,以保证最新库存;该产品原料表,共四味原料,生产产品时针对每种原料,都有固定的使用数量,如原料1需要500公斤,原料2需要200公 斤,原料3需要100公,原料四需要210公 ,这些原料都有对应的批号,例如,原料1的批号有GD250105、GD250304,以批号GD250304为例,25是年份,03是月份,04是顺序号,可以用于排序,现在我们需要在生产时,提取这些原料,采用先进先出的原则,先提取批号早的数量,一次大约需要取16批的原料库存数量,并采用固定模式导出打印,若用C#+SQL来开发解决的话,请问如何实现;

  • 写回答

4条回答 默认 最新

  • 檀越@新空间 2025-05-20 17:13
    关注

    下午好🌅🌅🌅
    本答案参考通义千问

    要实现这个需求,我们可以从数据库设计、数据处理逻辑以及前端导出打印功能三个方面入手。以下是详细的解决方案:


    1. 数据库设计

    为了满足先进先出(FIFO)的库存管理需求,我们需要对产品原料表和库存表进行合理的设计。

    数据库表结构

    1. 原料表 (Ingredients)

      • IngredientID:原料编号(主键)
      • IngredientName:原料名称
      • FixedUsageAmount:每次生产所需的固定用量
    2. 库存表 (Inventory)

      • InventoryID:库存记录编号(主键)
      • IngredientID:关联原料表的外键
      • BatchNumber:批次号(如 GD250105)
      • Quantity:当前库存数量
      • EntryDate:入库日期(用于排序)
    3. 生产记录表 (ProductionRecords)

      • RecordID:生产记录编号(主键)
      • ProductionDate:生产日期
      • IngredientID:关联原料表的外键
      • UsedQuantity:本次生产使用的数量
      • BatchNumber:使用的批次号

    2. 数据处理逻辑

    2.1 入库数量维护

    • 定期通过接口或文件导入入库数据,更新库存表中的 Quantity 字段。
    • 使用 EntryDate 字段存储入库日期,以便按时间排序。

    2.2 生产时提取原料

    • 根据生产计划,计算每种原料需要的固定用量。
    • 按照先进先出原则,优先提取较早批次的库存。
    • 如果某一批次库存不足,则继续提取后续批次,直到满足需求。

    2.3 打印导出

    • 提取生产记录后,按照固定格式生成报表。
    • 支持批量导出和打印功能。

    3. C# 实现代码

    3.1 数据库操作

    using System;
    using System.Collections.Generic;
    using System.Data.SqlClient;
    
    public class InventoryManager
    {
        private string connectionString = "YourConnectionString";
    
        // 添加入库记录
        public void AddInventory(string ingredientId, int quantity, string batchNumber)
        {
            using (SqlConnection conn = new SqlConnection(connectionString))
            {
                conn.Open();
                string query = "INSERT INTO Inventory (IngredientID, Quantity, BatchNumber, EntryDate) VALUES (@IngredientID, @Quantity, @BatchNumber, GETDATE())";
                SqlCommand cmd = new SqlCommand(query, conn);
                cmd.Parameters.AddWithValue("@IngredientID", ingredientId);
                cmd.Parameters.AddWithValue("@Quantity", quantity);
                cmd.Parameters.AddWithValue("@BatchNumber", batchNumber);
                cmd.ExecuteNonQuery();
            }
        }
    
        // 获取库存
        public List<(string BatchNumber, int Quantity)> GetInventoryByIngredient(string ingredientId)
        {
            List<(string BatchNumber, int Quantity)> inventory = new List<(string BatchNumber, int Quantity)>();
            using (SqlConnection conn = new SqlConnection(connectionString))
            {
                conn.Open();
                string query = "SELECT BatchNumber, Quantity FROM Inventory WHERE IngredientID = @IngredientID ORDER BY EntryDate ASC";
                SqlCommand cmd = new SqlCommand(query, conn);
                cmd.Parameters.AddWithValue("@IngredientID", ingredientId);
    
                using (SqlDataReader reader = cmd.ExecuteReader())
                {
                    while (reader.Read())
                    {
                        inventory.Add((reader.GetString(0), reader.GetInt32(1)));
                    }
                }
            }
            return inventory;
        }
    
        // 更新库存
        public void UpdateInventory(List<(string BatchNumber, int UsedQuantity)> usedItems)
        {
            using (SqlConnection conn = new SqlConnection(connectionString))
            {
                conn.Open();
                foreach (var item in usedItems)
                {
                    string query = "UPDATE Inventory SET Quantity = Quantity - @UsedQuantity WHERE BatchNumber = @BatchNumber";
                    SqlCommand cmd = new SqlCommand(query, conn);
                    cmd.Parameters.AddWithValue("@UsedQuantity", item.UsedQuantity);
                    cmd.Parameters.AddWithValue("@BatchNumber", item.BatchNumber);
                    cmd.ExecuteNonQuery();
                }
            }
        }
    }
    

    3.2 生产逻辑

    public class ProductionManager
    {
        private InventoryManager inventoryManager;
    
        public ProductionManager()
        {
            inventoryManager = new InventoryManager();
        }
    
        // 生产逻辑
        public void StartProduction(int productionPlanId)
        {
            Dictionary<string, int> requiredQuantities = new Dictionary<string, int>
            {
                { "Ingredient1", 500 },
                { "Ingredient2", 200 },
                { "Ingredient3", 100 },
                { "Ingredient4", 210 }
            };
    
            foreach (var entry in requiredQuantities)
            {
                string ingredientId = entry.Key;
                int requiredAmount = entry.Value;
    
                // 获取库存
                List<(string BatchNumber, int Quantity)> inventory = inventoryManager.GetInventoryByIngredient(ingredientId);
    
                // 提取原料
                List<(string BatchNumber, int UsedQuantity)> usedItems = new List<(string BatchNumber, int UsedQuantity)>();
    
                foreach (var item in inventory)
                {
                    if (requiredAmount <= 0) break;
    
                    int available = Math.Min(requiredAmount, item.Quantity);
                    usedItems.Add((item.BatchNumber, available));
                    requiredAmount -= available;
                }
    
                // 更新库存
                inventoryManager.UpdateInventory(usedItems);
            }
        }
    }
    

    3.3 导出打印功能

    public class ReportGenerator
    {
        public void GenerateReport(int productionPlanId)
        {
            // 查询生产记录
            List<(string BatchNumber, int UsedQuantity)> productionRecords = new List<(string BatchNumber, int UsedQuantity)>
            {
                ("GD250105", 500),
                ("GD250304", 200),
                ("GD250201", 100),
                ("GD250402", 210)
            };
    
            // 打印或导出
            foreach (var record in productionRecords)
            {
                Console.WriteLine($"Batch Number: {record.BatchNumber}, Used Quantity: {record.UsedQuantity}");
            }
        }
    }
    

    4. 总结

    • 数据库设计确保了库存管理和生产记录的清晰性。
    • C# 代码实现了入库、生产提取、库存更新以及报表生成的核心逻辑。
    • 可以进一步扩展功能,例如支持多线程处理大批量生产任务,或者集成到现有的 ERP 系统中。

    如果有其他需求或需要进一步优化,请随时补充说明!

    本回答被题主选为最佳回答 , 对您是否有帮助呢?
    评论
查看更多回答(3条)

报告相同问题?

问题事件

  • 系统已结题 9月5日
  • 已采纳回答 8月28日
  • 创建了问题 5月20日