商品如何按照批次号进行出库?
场景/问题描述
使用轻流系统搭建商品多批次号的出入库,实现按照商品的采购单的多个入库批次号进行商品出库操作。并且实现按照批次号录入的先后顺序进行出库。保证批次号在前的优先出库。
注意点:
1、批次号是根据日期+序号生成,所以出库优先顺序是根据批次号的日期+序号来判断的
2、当入库或者出库超过采购的数量或者库存的数量,会提示相应报错
思路逻辑
由于一个采购单号会有多个生产批次号,而对于该采购单号进行商品出库时,需要进行批次号的优先级进行依次出库。所以这里使用代码块的来完成上述操作。
注意:由于代码块在表单中触发,所以进行出库时,避免多人同时发起数据,会导致出库数据出错。后续代码块节点上线可以解决该问题
配置过程
表单设计

商品信息

采购单

采购单号
使用公式生成单号:CONCAT("CG-", TEXT(CURDATE(),"YYYYMMDD"), "-", RIGHT(CONCAT("000",RECNO()),3))

采购明细
- 采购明细-商品名称

成本价

采购价
公式:采购明细.成本价*采购明细.采购数量

入库单

采购单号

入库批次号
公式:CONCAT("RK-", TEXT(CURDATE(),"YYYYMMDD"), "-", RIGHT(CONCAT("000",RECNO()),3))


入库日期
日期格式:年月日
公式:CURDATE()


商品入库明细
商品入库明细-商品名称

商品入库明细-采购数量

商品入库明细-入库总数量

商品入库明细-剩余采购数量
公式:商品入库明细.采购数量- NUM(商品入库明细.入库总数量)-商品入库明细.本批次入库数量


提交校验
公式:AND(SEARCH("-",商品入库明细.剩余采购数量)==0)
作用:防止入库数量超过采购数量

流程配置



库存明细

出库单
出库日期
公式:CURDATE()
格式:年月日


采购单号

商品出库
商品出库-商品名称

商品名称-库存总和

代码块
代码注释
qf_field.{采购单号$$17AA76919$$}:表单中采购单号字段
queId: 167888878——表示采购单号字段的字段ID
URL为获取应用数据接口,文档参考:https://help.qingflow.com/help-docs?type=qingCode&docId=fc8e64656428ea3a06fe9b406b9b7be9&parentId=
queid的获取方式:https://exiao.yuque.com/rlf3k1/oanb79/ub34vw3b7cdqvovg?singleDoc# 《调用添加数据接口,如何写body内容》
accessToken:轻商城——拓展设置——openAPI——超管token
这里图中的queid代表【库存明细】应用中的商品名称、本批次库存数量、入库批次号、采购单号字段

qf_field.{商品出库$$179C49908$$}:表单中表格商品出库字段
field_167904381:表格中的商品名称字段的ID
field_167904382:表格中的出库数量字段的ID
field_id获取方式https://exiao.yuque.com/rlf3k1/oanb79/ml0u7lgb3wa0vhiz?singleDoc# 《如何在代码块中分辨表格的不同列》

const axios = require('axios');
let data = JSON.stringify({
"pageSize": "50",
"pageNum": "1",
"queries": [
{
"queId": 167888878,
"searchKey":qf_field.{采购单号$$17AA76919$$}
}
]
});
let config = {
method: 'post',
url: 'https://api.qingflow.com/app/a82c5f67/apply/filter',
headers: {
'accessToken': '9d6be42a-a2d9-441e-958b-585dcbc2c9**',
'Content-Type': 'application/json'
},
data: data
};
axios(config)
.then(function (res) {
const msg = res.data;
const result = msg.result.result;
const reslist = [];
result.forEach(value => {
const res_msg = {};
value.answers.forEach(v => {
const queId = v.queId;
const queTitle = v.queTitle;
if (queId === 167888961 || queId === 167888962 || queId === 167888879|| queId === 167888878) {
const values = v.values;
const dataValue = values[0].dataValue;
res_msg[queTitle] = dataValue;
}
});
reslist.push(res_msg);
});
const table = qf_field.{商品出库$$179C49908$$};
let resCopy = deepClone(reslist);
// 对 reslist 进行排序
const sortedReslist = reslist.sort((a, b) => {
const batchNumberA = a['入库批次号'];
const batchNumberB = b['入库批次号'];
// 提取日期+序号部分进行比较
const sortKeyA = batchNumberA.substr(3);
const sortKeyB = batchNumberB.substr(3);
return sortKeyA.localeCompare(sortKeyB);
});
// 计算并添加商品出库剩余总量字段
for (const item of sortedReslist) {
const productName = item['商品名称'];
const totalStockQuantity = sortedReslist
.filter(entry => entry['商品名称'] === productName)
.reduce((sum, entry) => sum + parseInt(entry['本批次库存数量']), 0);
const outgoingQuantity = table
.filter(entry => entry['field_167904381'] === productName)
.reduce((sum, entry) => sum + entry['field_167904382'], 0);
item['该商品出库剩余总量'] = (totalStockQuantity - outgoingQuantity).toString();
}
// 出库操作函数
const performOutbound = (productName, quantity) => {
const selectedItems = sortedReslist.filter(item => item['商品名称'] === productName);
let remainingQuantity = quantity;
for (const item of selectedItems) {
const currentQuantity = parseInt(item['本批次库存数量']);
if (currentQuantity >= remainingQuantity) {
item['本批次库存数量'] = (currentQuantity - remainingQuantity).toString();
break;
} else {
item['本批次库存数量'] = '0';
remainingQuantity -= currentQuantity;
}
}
};
// Perform outbound operations based on table
for (const item of table) {
const productName = item['field_167904381'];
const outboundQuantity = item['field_167904382'];
performOutbound(productName, outboundQuantity);
}
// 计算并添加该批次已出库数量字段
for (const item of sortedReslist) {
const productName = item['商品名称'];
const picinum=item['入库批次号'];
const StockQuantity = sortedReslist
.find(entry => entry['商品名称'] === productName &&
entry['入库批次号'] === picinum)['本批次库存数量'];
const outgoing = resCopy
.find(entry => entry['商品名称'] === productName
&&entry['入库批次号'] === picinum)['本批次库存数量'];
item['该批次已出库数量'] = (outgoing - StockQuantity).toString();
}
const filteredReslist = sortedReslist.filter(item => {
const productName = item['商品名称'];
const batchNumber = item['入库批次号'];
const stockQuantity = parseInt(item['本批次库存数量']);
return resCopy.some(entry => {
return entry['商品名称'] === productName &&
entry['入库批次号'] === batchNumber &&
stockQuantity - parseInt(entry['本批次库存数量']) < 0;
});
});
qf_output={filteredReslist}
//console.log(filteredReslist);
});
// deep copy
function deepClone(obj) {
return JSON.parse(JSON.stringify(obj));
}
代码测试



解析规则配置

接收字段配置

提交校验

公式:AND(SEARCH("-",出库后明细.库存总剩余量)==0)
作用:防止出库数量大于现有库存!!!

流程设置



出库明细

库存明细

实现效果
