进销存系统销售出库功能实现:从界面到库存联动

进销存系统销售出库功能实现:从界面到库存联动

如果说采购是“钱花出去了”,
那销售就是 系统开始真正创造价值的地方


一、销售在进销存系统中的位置

从业务链条看:

采购 → 入库 → 库存 → 销售 → 出库

到这一篇为止,你的系统已经具备:

  • 商品
  • 库存
  • 采购入库

销售出库,是整个系统的最后一块拼图。


二、销售和采购有什么本质区别?

对比项 采购 销售
库存变化 增加 减少
关键校验 必须校验库存
风险 较低 极高

销售是第一个“可能失败”的业务操作


三、为什么销售一定要“先校验库存”?

如果不校验,会发生:

  • 库存为负
  • 数据失真
  • 财务统计错误

真实系统中:

库存不足 → 销售不能成立


四、销售出库的数据结构设计

销售单主表(sale)

CREATE TABLE sale (
    id INT PRIMARY KEY IDENTITY(1,1),
    sale_no VARCHAR(50) NOT NULL UNIQUE,
    create_time DATETIME DEFAULT GETDATE(),
    remark VARCHAR(200)
);

销售明细表(sale_item)

CREATE TABLE sale_item (
    id INT PRIMARY KEY IDENTITY(1,1),
    sale_id INT NOT NULL,
    product_id INT NOT NULL,
    quantity INT NOT NULL
);

和采购单结构几乎一致
这是所有进销存系统的通用设计。


五、销售出库的完整业务流程

用户录入销售单
   ↓
校验库存是否足够
   ↓
保存销售单
   ↓
保存销售明细
   ↓
扣减库存

任一步失败,整个销售必须失败


六、库存校验逻辑(核心)

private bool CheckStock(int productId, int saleQty)
{
    string sql = "SELECT quantity FROM stock WHERE product_id = @pid";

    using (SqlConnection conn = new SqlConnection(connectionString))
    {
        conn.Open();

        SqlCommand cmd = new SqlCommand(sql, conn);
        cmd.Parameters.AddWithValue("@pid", productId);

        int currentStock = Convert.ToInt32(cmd.ExecuteScalar());
        return currentStock >= saleQty;
    }
}

七、创建销售单

private int CreateSale(string remark)
{
    string sql = @"
        INSERT INTO sale(sale_no, remark)
        VALUES(@no, @remark);
        SELECT SCOPE_IDENTITY();";

    using (SqlConnection conn = new SqlConnection(connectionString))
    {
        conn.Open();

        SqlCommand cmd = new SqlCommand(sql, conn);
        cmd.Parameters.AddWithValue("@no", "XS" + DateTime.Now.Ticks);
        cmd.Parameters.AddWithValue("@remark", remark);

        return Convert.ToInt32(cmd.ExecuteScalar());
    }
}

八、保存销售明细并扣减库存

private bool AddSaleItem(int saleId, int productId, int quantity)
{
    if (!CheckStock(productId, quantity))
    {
        MessageBox.Show("库存不足,无法完成销售!");
        return false;
    }

    string sql = @"
        INSERT INTO sale_item(sale_id, product_id, quantity)
        VALUES(@sid, @pid, @qty)";

    using (SqlConnection conn = new SqlConnection(connectionString))
    {
        conn.Open();

        SqlCommand cmd = new SqlCommand(sql, conn);
        cmd.Parameters.AddWithValue("@sid", saleId);
        cmd.Parameters.AddWithValue("@pid", productId);
        cmd.Parameters.AddWithValue("@qty", quantity);

        cmd.ExecuteNonQuery();
    }

    // 扣减库存
    DecreaseStock(productId, quantity);
    return true;
}

posted @ 2025-10-29 11:31  元始天尊123  阅读(7)  评论(0)    收藏  举报