进销存系统销售出库功能实现:从界面到库存联动
进销存系统销售出库功能实现:从界面到库存联动
如果说采购是“钱花出去了”,
那销售就是 系统开始真正创造价值的地方。
一、销售在进销存系统中的位置
从业务链条看:
采购 → 入库 → 库存 → 销售 → 出库
到这一篇为止,你的系统已经具备:
- 商品
- 库存
- 采购入库
销售出库,是整个系统的最后一块拼图。
二、销售和采购有什么本质区别?
| 对比项 | 采购 | 销售 |
|---|---|---|
| 库存变化 | 增加 | 减少 |
| 关键校验 | 无 | 必须校验库存 |
| 风险 | 较低 | 极高 |
销售是第一个“可能失败”的业务操作
三、为什么销售一定要“先校验库存”?
如果不校验,会发生:
- 库存为负
- 数据失真
- 财务统计错误
真实系统中:
库存不足 → 销售不能成立
四、销售出库的数据结构设计
销售单主表(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;
}

浙公网安备 33010602011771号