From 1c7f790142f80a5ce66383177aee071ebe2ae04b Mon Sep 17 00:00:00 2001
From: hayu <1604366271@qq.com>
Date: Tue, 6 Jan 2026 15:05:02 +0800
Subject: [PATCH] =?UTF-8?q?=E5=AE=89=E5=85=A8=E5=B7=A5=E5=99=A8=E5=85=B7?=
=?UTF-8?q?=E5=8F=B0=E8=B4=A6=E5=8F=8A=E4=BF=AE=E6=94=B9?=
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit
---
js/aq_demand_plan/child/send_out_detail.js | 12 +-
js/aq_demand_plan/child/send_out_edit_form.js | 65 +-
js/aq_demand_plan/child/send_out_form.js | 70 +-
.../child/send_out_pro_detail.js | 3 +
.../child/send_out_supplement.js | 693 ++++++++++++++++++
js/aq_inventory/safety_tools_ledger.js | 228 ++++--
.../child/send_out_edit_form.html | 8 +-
page/aq_demand_plan/child/send_out_form.html | 4 +-
.../child/send_out_supplemen.html | 189 +++++
.../child/send_out_unplanned_form.html | 2 +-
page/aq_inventory/safety_tools_ledger.html | 10 +-
11 files changed, 1189 insertions(+), 95 deletions(-)
create mode 100644 js/aq_demand_plan/child/send_out_supplement.js
create mode 100644 page/aq_demand_plan/child/send_out_supplemen.html
diff --git a/js/aq_demand_plan/child/send_out_detail.js b/js/aq_demand_plan/child/send_out_detail.js
index 3029612..77ae94e 100644
--- a/js/aq_demand_plan/child/send_out_detail.js
+++ b/js/aq_demand_plan/child/send_out_detail.js
@@ -40,7 +40,7 @@ function getPurchaseDetails() {
function setTableData(obj) {
$('#planCode').html(obj.planCode);
$('#cgNum').html(obj.cgNum);
- $('#money').html('¥ ' + obj.money);
+ $('#money').html(formatMoney(obj.money));
$('#lkNum').html(obj.lkNum);
$('#fhDay').html(obj.fhDay);
$('#jbUser').html(obj.jbUser);
@@ -53,6 +53,16 @@ function getPurchaseDetails() {
}
}
+function formatMoney(value) {
+ // 第一步:处理空值/异常值,转为0
+ let num = 0;
+ if (value !== null && value !== undefined && value !== '' && !isNaN(Number(value))) {
+ num = Number(value);
+ }
+ // 第二步:保留2位小数,返回带¥的格式化字符串
+ return '¥ ' + num.toFixed(2);
+}
+
// 采购发货明细
function getPurchaseDetailsList() {
let params = {
diff --git a/js/aq_demand_plan/child/send_out_edit_form.js b/js/aq_demand_plan/child/send_out_edit_form.js
index f5e9e08..8e3fdba 100644
--- a/js/aq_demand_plan/child/send_out_edit_form.js
+++ b/js/aq_demand_plan/child/send_out_edit_form.js
@@ -205,43 +205,58 @@ function saveData2() {
// 提交前确认
function beforeSubmitApply() {
- // 校验附件证明是否上传
- let length = $('.file-iteme').length;
- if (length === 0) {
- return layer.msg('请上传附件证明', { icon: 7 });
- }
let dataList = getBaseTableData();
- // 校验 发货明细数据
+ let hasError = false;
+ let targetData = null; // 存储需要提交的目标数据
+ let confirmIndex = -1; // 存储需要确认的行索引
+
+ // 第一步:先完成所有校验,不执行异步操作
for (let i = 0; i < dataList.length; i++) {
+ if (hasError) break;
let o = dataList[i];
let list = o.supList;
- let cgNum = 0,lkNum = 0; // 采购量、利库量
+ let cgNum = 0,lkNum = 0;
for (let j = 0; j < list.length; j++) {
let l = list[j];
cgNum += (l.cgNum ? parseInt(l.cgNum) : 0);
lkNum += (l.lkNum ? parseInt(l.lkNum) : 0);
- if (!l.supId && cgNum > 0) {
- // 采购才需要填写供应商
- return layer.msg('序号为' + (i + 1) + '的数据,未选择供应商', { icon: 7 });
- }
- if (!l.ccDay) {
- return layer.msg('序号为' + (i + 1) + '的数据,未选择出厂日期', { icon: 7 });
- }
- if (!l.jyDay) {
- return layer.msg('序号为' + (i + 1) + '的数据,未选择检验日期', { icon: 7 });
+ let thisCgNum= (l.cgNum ? parseInt(l.cgNum) : 0);
+ if (!l.supId && thisCgNum > 0) {
+ layer.msg('序号为' + (i + 1) + '的数据,未选择供应商', { icon: 7 });
+ hasError = true;
+ break;
}
}
-
- if (parseInt(o.needNum) < (cgNum + lkNum)) { // 采购量 大于需求量
- layer.confirm('序号为' + (i + 1) + '的数据,采购量和利库量大于需要量是否确认?', {
- btn: ['确定', '关闭'] //按钮
- }, function(){
- openIframeByParamObj("quickAddForm", "采购发货确认", "./send_out_confirm.html", "92%", "92%", dataList);
- }, function(){
-
- });
+ if (hasError) break;
+ if (cgNum + lkNum<=0) {
+ layer.msg('请填写采购量或利库量', { icon: 7 });
+ hasError = true;
+ break;
}
+ o.cgTotal = cgNum; // 存储总采购量
+ o.lkTotal = lkNum; // 存储总利库量
+ if (parseInt(o.needNum) < (cgNum + lkNum)) {
+ confirmIndex = i;
+ targetData = dataList;
+ break; // 先记录需要确认的行,终止循环
+ } else {
+ targetData = dataList;
+ }
+ }
+ // 第二步:校验通过后,处理异步确认或直接打开弹窗
+ if (hasError) return;
+
+ if (confirmIndex > -1) {
+ // 有需要确认的行
+ layer.confirm('序号为' + (confirmIndex + 1) + '的数据,采购量和利库量大于需要量是否确认?', {
+ btn: ['确定', '关闭']
+ }, function(){
+ openIframeByParamObj("quickAddForm", "采购发货确认", "./send_out_confirm.html", "92%", "92%", targetData);
+ });
+ } else {
+ // 无需确认,直接打开
+ openIframeByParamObj("quickAddForm", "采购发货确认", "./send_out_confirm.html", "92%", "92%", targetData);
}
}
diff --git a/js/aq_demand_plan/child/send_out_form.js b/js/aq_demand_plan/child/send_out_form.js
index 8fbf9d7..bf6465e 100644
--- a/js/aq_demand_plan/child/send_out_form.js
+++ b/js/aq_demand_plan/child/send_out_form.js
@@ -139,32 +139,74 @@ function saveData2() {
// 提交前确认
function beforeSubmitApply() {
- // 校验发货附件是否上传
- /* if (fileList.length === 0) {
- return layer.msg('请上传发货附件', { icon: 7 });
- }*/
+ // 校验发货附件是否上传(注释保留,可按需启用)
+ /* if (fileList.length === 0) {
+ layer.msg('请上传发货附件', { icon: 7 });
+ return; // 这里直接return有效,因为不在嵌套循环内
+ }*/
let dataList = getBaseTableData();
+ // 1. 定义错误标记,用于终止多层循环和函数
+ let hasError = false;
+ // 2. 定义变量存储需要确认的行索引(用于弹窗提示)
+ let needConfirmIndex = -1;
+
// 校验 发货明细数据
for (let i = 0; i < dataList.length; i++) {
+ if (hasError) break; // 已发现错误,直接终止外层循环
let o = dataList[i];
let list = o.supList;
- let cgNum = 0,lkNum = 0; // 采购量、利库量
+ let cgNum = 0, lkNum = 0; // 采购量、利库量
for (let j = 0; j < list.length; j++) {
+ if (hasError) break; // 已发现错误,终止内层循环
let l = list[j];
+ // 累加采购量和利库量
cgNum += (l.cgNum ? parseInt(l.cgNum) : 0);
lkNum += (l.lkNum ? parseInt(l.lkNum) : 0);
- if (cgNum > 0 || lkNum > 0) {
- // 如果没有选择供应商且 cgNum 大于 0,显示警告
- if (!l.supId && cgNum > 0) {
- return layer.msg('序号为' + (i + 1) + '的数据,未选择供应商', { icon: 7 });
- }
- } else {
- // 如果 cgNum 和 lkNum 都不大于 0,弹出提示
- return layer.msg('序号为' + (i + 1) + '的数据,采购量 或 利库量 必须大于 0', { icon: 7 });
+ let thisCgNum = (l.cgNum ? parseInt(l.cgNum) : 0);
+
+ // 校验供应商是否选择(采购量大于0时必填)
+ if (!l.supId && thisCgNum > 0) {
+ layer.msg('序号为' + (i + 1) + '的数据,未选择供应商', { icon: 7 });
+ hasError = true; // 标记错误状态
+ break; // 终止内层循环
}
}
+ if (hasError) break; // 再次判断,确保外层循环终止
+
+ // 校验采购量或利库量是否填写
+ if (cgNum + lkNum <= 0) {
+ layer.msg('请填写采购量或利库量', { icon: 7 });
+ hasError = true;
+ break; // 终止外层循环
+ }
+
+ // 校验:采购量+利库量 是否大于 需要量,记录需要确认的行索引
+ if (parseInt(o.needNum) < (cgNum + lkNum)) {
+ needConfirmIndex = i; // 存储当前需要确认的行号
+ break; // 发现需要确认的行,先终止循环(避免多笔数据重复弹窗)
+ }
+ }
+
+ // 若存在错误,直接退出函数,不执行后续操作
+ if (hasError) {
+ return;
+ }
+
+ // 3. 处理 layer.confirm 确认提示逻辑
+ if (needConfirmIndex > -1) {
+ // 有数据需要确认,弹出确认弹窗
+ layer.confirm('序号为' + (needConfirmIndex + 1) + '的数据,采购量和利库量大于需要量是否确认?', {
+ btn: ['确定', '关闭'] // 弹窗按钮
+ }, function(){
+ // 用户点击“确定”,执行打开iframe操作
+ openIframeByParamObj("quickAddForm", "采购发货确认", "./send_out_confirm.html", "92%", "92%", dataList);
+ }, function(){
+ // 用户点击“关闭”,不执行任何操作(弹窗关闭)
+ });
+ } else {
+ // 无需确认(采购量+利库量 ≤ 需要量),直接打开iframe
+ openIframeByParamObj("quickAddForm", "采购发货确认", "./send_out_confirm.html", "92%", "92%", dataList);
}
- openIframeByParamObj("quickAddForm", "采购发货确认", "./send_out_confirm.html", "92%", "92%", dataList);
}
// 提交
diff --git a/js/aq_demand_plan/child/send_out_pro_detail.js b/js/aq_demand_plan/child/send_out_pro_detail.js
index 0491196..29d7740 100644
--- a/js/aq_demand_plan/child/send_out_pro_detail.js
+++ b/js/aq_demand_plan/child/send_out_pro_detail.js
@@ -265,6 +265,7 @@ function initTable() {
html += "详情";
html += "
|
修改发货";
html += "|
二维码下载";
+ html += "|
补发货";
html += "|
撤销";
}
@@ -321,6 +322,8 @@ function sendOutForm(obj, type) {
let content = '../aq_demand_plan/child/send_out_form.html';
if (type === 2) {
content = '../aq_demand_plan/child/send_out_edit_form.html';
+ } else if (type === 3) {
+ content = '../aq_demand_plan/child/send_out_supplemen.html';
}
openIframeByParamObj2("sendOutForm", "采购发货", content, "92%", "95%", obj);
}
diff --git a/js/aq_demand_plan/child/send_out_supplement.js b/js/aq_demand_plan/child/send_out_supplement.js
new file mode 100644
index 0000000..5867d55
--- /dev/null
+++ b/js/aq_demand_plan/child/send_out_supplement.js
@@ -0,0 +1,693 @@
+// 全局变量定义
+let objParam, dataObj, fileList = new Array(), imgListUp = new Array(), delImgIdList = [];
+let form, laydate, layer, upload, table, util;
+let pageNum = 1, tableIns;
+let supplierList = [];
+let delSupIdArr = [];
+// 存储原始采购量/利库量(用于灵活校验,独立于DOM元素)
+let originalCgLkMap = new Map(); // key: modelId_index, value: {originalCgNum: 0, originalLkNum: 0}
+
+// 设置参数初始化
+function setParams(obj) {
+ objParam = JSON.parse(obj);
+ console.error(objParam);
+ $('#proName').html(objParam.proName);
+ $('#companyName').val((objParam.companyName !== null && objParam.companyName !== '') ? objParam.companyName : '/');
+ layui.use(['form', 'layer', 'laydate', 'upload', 'table'], function () {
+ form = layui.form;
+ layer = layui.layer;
+ laydate = layui.laydate;
+ upload = layui.upload;
+ table = layui.table;
+ util = layui.util;
+
+ // 渲染日期选择器(只读状态,不可修改)
+ laydate.render({
+ elem: '#fhDay',
+ trigger: 'none' // 禁止触发日期选择
+ });
+ laydate.render({
+ elem: '.cjDate',
+ trigger: 'none'
+ });
+ laydate.render({
+ elem: '.jyDate',
+ trigger: 'none'
+ });
+
+ form.verify();
+ // 表单提交监听
+ form.on('submit(formData)', function (data) {
+ beforeSubmitApply(data);
+ });
+
+ // 文件上传配置(仅可新增,不可删除原有附件)
+ let uploadObj = upload.render({
+ elem: '#test2',
+ multiple: true,
+ dataType: "json",
+ exts: 'jpg|png|jpeg|doc|docx|pdf|xlsx|xls',
+ acceptMime: 'image/jpg,image/png,image/jpeg,application/pdf,application/msword,application/vnd.openxmlformats-officedocument.wordprocessingml.document,application/vnd.ms-excel,application/vnd.openxmlformats-officedocument.spreadsheetml.sheet',
+ number: 5, //最大上传数量
+ size: 1024 * 10, //最大文件大小,单位k
+ auto: false, //是否自动上传
+ bindAction: '#hideUpload', //绑定的按钮
+ choose: function (obj) {
+ let length = $('.file-iteme').length;
+ if (length >= 5) {
+ return layer.msg('最多上传5个发货附件', { icon: 7 });
+ }
+ uploadObj.config.elem.next()[0].value = '';
+ let num = 0;
+ obj.preview(function (index, file, result) {
+ num++;
+ if (num <= (5 - length)) {
+ $('#uploader-list').append(
+ '' +
+ '
' + // 隐藏删除按钮
+ handleFileType(index, file, result) +
+ '
'
+ );
+ let map = new Map();
+ map.index = index;
+ map.file = file;
+ fileList.push(map);
+ }
+ });
+ }
+ });
+ });
+ // 先获取供应商,再加载其他数据,解决异步加载问题
+ getSupplierList(function() {
+ getPurchaseDetails();
+ getPurchaseDetailsList();
+ });
+}
+
+// 获取采购详情(回填只读数据)
+function getPurchaseDetails() {
+ let params = {
+ encryptedData: JSON.stringify({
+ 'id': objParam.id
+ })
+ };
+ let url = dataUrl + 'backstage/purchase/getPurchaseDetails';
+ ajaxRequest(url, "POST", params, true, function () {
+ }, function (result) {
+ console.error(result);
+ if (result.code === 200) {
+ dataObj = result.data;
+ setFormData(result.data);
+ } else {
+ }
+ }, function (xhr, status, error) {
+ errorFn(xhr, status, error)
+ }, null);
+
+ function setFormData(obj) {
+ $('#code').html(obj.planCode);
+ // 表单赋值(全部只读)
+ form.val('formInfo', obj);
+ let fileList = obj.fileList, html = '';
+ for (let i = 0; i < fileList.length; i++) {
+ let path = fileUrl + fileList[i].fileUrl + '?token=' + sessionStorage.getItem("gz-token");
+ let file = { name: fileList[i].fileName, id: fileList[i].id };
+ html += '' +
+ '
' + // 隐藏删除按钮,不可删除原有附件
+ handleFileType(i, file, path) +
+ '
'
+ }
+ $('#uploader-list').append(html);
+ }
+}
+
+// 获取发货明细列表
+function getPurchaseDetailsList() {
+ let params = {
+ encryptedData: JSON.stringify({
+ 'id': objParam.id
+ })
+ };
+ let url = dataUrl + 'backstage/purchase/getPurchaseDetailsList';
+ ajaxRequest(url, "POST", params, true, function () {
+ }, function (result) {
+ console.error(result);
+ if (result.code === 200) {
+ // 先存储原始采购量/利库量到全局Map(强制确保键值正确)
+ saveOriginalCgLkNum(result.data);
+ // 渲染表格
+ setBaseTable(result.data);
+ }
+ }, function (xhr, status, error) {
+ errorFn(xhr, status, error)
+ }, null);
+}
+
+// 存储原始采购量/利库量(核心:修复键值生成逻辑,确保唯一性和一致性)
+function saveOriginalCgLkNum(data) {
+ if (!data || data.length === 0) return;
+ originalCgLkMap.clear();
+ for (let i = 0; i < data.length; i++) {
+ let item = data[i];
+ let modelId = item.modelId || 'default_' + i; // 兜底:防止modelId为空
+ if (item.supList && item.supList.length > 0) {
+ for (let j = 0; j < item.supList.length; j++) {
+ let supItem = item.supList[j];
+ let key = modelId + '_' + j; // 明确:modelId + 索引j,与提交校验时一致
+ originalCgLkMap.set(key, {
+ originalCgNum: parseInt(supItem.cgNum || 0),
+ originalLkNum: parseInt(supItem.lkNum || 0)
+ });
+ // 控制台打印:方便调试查看原始值存储情况
+ console.log('原始值存储 - 键:', key, ' 采购量:', parseInt(supItem.cgNum || 0), ' 利库量:', parseInt(supItem.lkNum || 0));
+ }
+ }
+ }
+}
+
+// 设置文件类型渲染
+function handleFileType(index, file, result) {
+ let html = '', img = '';
+ if (file.ext) {
+ file.ext = file.ext.toLowerCase();
+ }
+ if (file.name) {
+ file.name = file.name.toLowerCase();
+ }
+ if (file.ext === 'doc' || file.ext === 'docx' || file.name.indexOf('doc') > -1 || file.name.indexOf('docx') > -1) {
+ img = '../../../images/docx.png';
+ } else if (file.ext === 'xls' || file.ext === 'xlsx' || file.name.indexOf('xls') > -1 || file.name.indexOf('xlsx') > -1) {
+ img = '../../../images/xlsx.png';
+ } else if (file.ext === 'pdf' || file.name.indexOf('pdf') > -1) {
+ img = '../../../images/pdf.png';
+ } else {
+ return '
';
+ }
+ html += '' +
+ '

' +
+ '
' + file.name + '
' +
+ '
';
+ return html;
+}
+
+// 隐藏删除按钮,禁止删除文件(补充模式下仅可新增附件)
+$(document).on("click", ".file-iteme .handle", function (event) {
+ layer.msg('补充模式下不可删除附件,仅可新增', { icon: 7 });
+ return false;
+});
+
+// 触发表单提交
+function saveData2() {
+ $('#formSubmit').trigger('click')
+}
+
+// 提交前确认与灵活校验(核心修复:供应商回显+采购量>0时必填供应商)
+function beforeSubmitApply() {
+ let dataList = getBaseTableData();
+ let hasError = false;
+ let targetData = null;
+ let confirmIndex = -1;
+
+ // 第一步:优先校验采购量/利库量是否小于原始值(最高优先级,发现错误立即阻断)
+ for (let i = 0; i < dataList.length; i++) {
+ if (hasError) break;
+ let o = dataList[i];
+ let modelId = o.modelId || 'default_' + i; // 与存储时兜底逻辑一致
+ let list = o.supList;
+ let cgNum = 0, lkNum = 0;
+
+ for (let j = 0; j < list.length; j++) {
+ let l = list[j];
+ let currentCgNum = parseInt(l.cgNum || 0);
+ let currentLkNum = parseInt(l.lkNum || 0);
+ cgNum += currentCgNum;
+ lkNum += currentLkNum;
+
+ // 关键修复:使用与存储时完全一致的键值,获取原始值
+ let key = modelId + '_' + j;
+ let originalData = originalCgLkMap.get(key);
+
+ // 兜底:防止原始值未获取到
+ if (!originalData) {
+ layer.msg('序号为' + (i + 1) + '的数据,未获取到原始数据,请刷新页面重试', { icon: 7 });
+ hasError = true;
+ break;
+ }
+
+ // 强制校验:采购量不可小于原始值
+ if (currentCgNum < originalData.originalCgNum) {
+ layer.msg('序号为' + (i + 1) + '的数据,采购量不可小于原始值:' + originalData.originalCgNum + '(当前值:' + currentCgNum + ')', { icon: 7 });
+ hasError = true;
+ break;
+ }
+ // 强制校验:利库量不可小于原始值(修复第二条数据不提示问题)
+ if (currentLkNum < originalData.originalLkNum) {
+ layer.msg('序号为' + (i + 1) + '的数据,利库量不可小于原始值:' + originalData.originalLkNum + '(当前值:' + currentLkNum + ')', { icon: 7 });
+ hasError = true;
+ break;
+ }
+
+ // 新增校验:采购量>0时,供应商为必填项
+ if (currentCgNum > 0 && (!l.supId || l.supId === '')) {
+ layer.msg('序号为' + (i + 1) + '的数据,采购量大于0时必须选择供应商', { icon: 7 });
+ hasError = true;
+ break;
+ }
+
+ }
+
+ if (hasError) break;
+
+ // 第二步:校验采购量+利库量不可全部为0
+ if (cgNum + lkNum <= 0) {
+ layer.msg('序号为' + (i + 1) + '的数据,请填写采购量或利库量(不可全部为0)', { icon: 7 });
+ hasError = true;
+ break;
+ }
+
+ o.cgTotal = cgNum;
+ o.lkTotal = lkNum;
+
+ // 第三步:校验采购量+利库量是否大于需用量(仅当前面无错误时执行)
+ let needNumInt = parseInt(o.needNum || 0);
+ if (cgNum + lkNum > needNumInt) {
+ confirmIndex = i;
+ targetData = dataList;
+ // 不break,继续校验其他数据是否有原始值违规
+ } else {
+ if (!targetData) {
+ targetData = dataList;
+ }
+ }
+ }
+
+ // 若存在错误,直接返回,不执行后续逻辑
+ if (hasError) return;
+
+ // 第四步:仅当无任何错误时,才判断是否需要弹出总量超需用量的确认框
+ if (confirmIndex > -1) {
+ layer.confirm('序号为' + (confirmIndex + 1) + '的数据,采购量+利库量总和大于需要量,是否确认提交?', {
+ btn: ['确定', '关闭']
+ }, function () {
+ openIframeByParamObj("quickAddForm", "采购发货补充确认", "./send_out_confirm.html", "92%", "92%", targetData);
+ });
+ } else {
+ openIframeByParamObj("quickAddForm", "采购发货补充确认", "./send_out_confirm.html", "92%", "92%", targetData);
+ }
+}
+
+// 提交数据到后台
+function submitApply() {
+ // 补充模式下,清空供应商删除ID,禁止删除供应商
+ delSupIdArr = [];
+
+ let data = form.val('formInfo');
+ let dataList = getBaseTableData();
+ data.id = dataObj.id;
+ data.detailsList = dataList;
+ data.planId = objParam.id;
+ data.proId = objParam.proId;
+
+ // 补充模式下,禁止删除原有文件,清空删除文件ID
+ delImgIdList = [];
+ let delFileId = '', delSupId = '';
+ if (delImgIdList && delImgIdList.length > 0) {
+ for (let i = 0; i < delImgIdList.length; i++) {
+ if (i === delImgIdList.length - 1) {
+ delFileId += delImgIdList[i];
+ } else {
+ delFileId += delImgIdList[i] + '@';
+ }
+ }
+ }
+ if (delSupIdArr && delSupIdArr.length > 0) {
+ for (let i = 0; i < delSupIdArr.length; i++) {
+ if (i === delSupIdArr.length - 1) {
+ delSupId += delSupIdArr[i];
+ } else {
+ delSupId += delSupIdArr[i] + '@';
+ }
+ }
+ }
+ data.delFileId = delFileId;
+ data.delSupId = delSupId;
+ let formData = new FormData();
+ for (let i = 0; i < fileList.length; i++) {
+ formData.append("file[]", fileList[i].file)
+ }
+ console.log(data);
+ formData.append('params', JSON.stringify(data));
+ let loadingMsg = layer.msg('正在提交补充,请稍等...', { icon: 16, shade: 0.01, time: '0' });
+ let url = dataUrl + 'backstage/purchase/updatePurchaseData';
+ ajaxRequestByUploadFile(url, formData, function () {
+ $('.save').addClass("layui-btn-disabled").attr("disabled", true);
+ $('.cancel').addClass("layui-btn-disabled").attr("disabled", true);
+ }, function (result) {
+ layer.close(loadingMsg);
+ $('.save').removeClass("layui-btn-disabled").attr("disabled", false);
+ $('.cancel').removeClass("layui-btn-disabled").attr("disabled", false);
+ if (result.code === 200) {
+ parent.layer.msg(result.msg, { icon: 1 });
+ closePage(result.data);
+ } else {
+ layer.msg(result.msg, { icon: 2 });
+ }
+ }, function (xhr, status, error) {
+ layer.close(loadingMsg);
+ layer.msg('服务异常,请稍后重试', { icon: 16, scrollbar: false, time: 2000 });
+ $('.save').removeClass("layui-btn-disabled").attr("disabled", false);
+ $('.cancel').removeClass("layui-btn-disabled").attr("disabled", false);
+ errorFn(xhr, status, error)
+ }, null);
+}
+
+// 获取供应商下拉选列表(新增回调,确保先加载供应商再渲染表格)
+function getSupplierList(callback) {
+ supplierList.splice(0, supplierList.length);
+ let encryptedData = {};
+ let url = dataUrl + 'backstage/sup/getSelected?encryptedData=' + encodeURIComponent(JSON.stringify(encryptedData));
+ ajaxRequest(url, "GET", null, false, function () {
+ }, function (result) {
+ if (result.code === 200) {
+ supplierList = result.data;
+ // 执行回调函数
+ if (typeof callback === 'function') {
+ callback();
+ }
+ }
+ }, function (xhr, status, error) {
+ errorFn(xhr, status, error);
+ // 即使获取失败,也执行回调,避免页面阻塞
+ if (typeof callback === 'function') {
+ callback();
+ }
+ }, null);
+}
+
+// 厂家校验(禁用,仅保留兼容,不限制供应商)
+function supCheck(modelId, contractId, value) {
+ return true; // 直接返回通过,不做校验
+}
+
+// 库存数量校验(保留,不影响核心逻辑)
+function maTypeCheck(modelId) {
+ let num = 0;
+ let params = {
+ encryptedData: JSON.stringify({
+ 'modelId': modelId
+ })
+ };
+ let url = dataUrl + 'backstage/maType/maTypeCheck';
+ ajaxRequest(url, "POST", params, false, function () {
+ }, function (result) {
+ if (result.code === 200) {
+ num = result.data;
+ }
+ }, function (xhr, status, error) {
+ errorFn(xhr, status, error)
+ }, null);
+ return num;
+}
+
+// 获取发货明细表格数据(确保modelId和索引j正确传递)
+function getBaseTableData() {
+ let dataList = [];
+ $('#baseTable tbody tr.mainTr').each(function (trIndex) {
+ let obj = {};
+ let modelId = $(this).attr('id') || 'default_' + trIndex; // 与存储时兜底逻辑一致
+ let detailId = $(this).attr('detailId');
+ let type = $(this).find('td').eq(2).html();
+ let name = $(this).find('td').eq(3).html();
+ let model = $(this).find('td').eq(4).html();
+ let unit = $(this).find('td').eq(5).html();
+ let needNum = $(this).find('td').eq(6).html();
+ let formList = [];
+ let idx = $('.model' + modelId).length;
+
+ for (let i = 0; i < idx; i++) {
+ let formObj = {};
+ let dataId = $('.model' + modelId).eq(i).attr('dataId');
+ let num = $('.num' + modelId).eq(i).val();
+ let lkNum = $('.lkNum' + modelId).eq(i).val();
+ let supplier = $('.supplier' + modelId).eq(i).val();
+ let supplierName = $('.supplier' + modelId).eq(i).find('option:checked').text();
+ let contractId = '';
+ if (supplier) {
+ let item = JSON.parse($('.supplier' + modelId).eq(i).find('option:checked').attr('item'));
+ contractId = item.contractId;
+ }
+ let cjDate = $('.cjDate' + modelId).eq(i).val();
+ let jyDate = $('.jyDate' + modelId).eq(i).val();
+ let remark = $('.remark' + modelId).eq(i).val();
+ formObj.cgNum = num;
+ formObj.lkNum = lkNum;
+ formObj.supId = supplier;
+ formObj.supName = supplierName;
+ formObj.ccDay = cjDate;
+ formObj.jyDay = jyDate;
+ formObj.remark = remark;
+ formObj.modelId = modelId; // 确保modelId正确赋值
+ formObj.contractId = contractId;
+ formObj.id = dataId;
+ formList.push(formObj);
+ }
+
+ obj.modelId = modelId;
+ obj.id = detailId;
+ obj.type = type;
+ obj.name = name;
+ obj.model = model;
+ obj.unit = unit;
+ obj.needNum = needNum;
+ obj.supList = formList;
+ dataList.push(obj);
+ })
+ return dataList;
+}
+
+// 关闭当前页面(iframe)
+function closePage(data) {
+ let index = parent.layer.getFrameIndex(window.name);
+ if (data) {
+ let obj = {
+ resultData: data.resultData,
+ resultData2: data.resultData2,
+ id: data.planId
+ };
+ let frameId = parent.document.getElementById('sendOutProDetail').getElementsByTagName("iframe")[0];
+ frameId.contentWindow.sendOutSuccess(JSON.stringify(obj));
+ }
+ parent.layer.close(index);
+}
+
+// 监听采购量输入框(增强提示:实时+失焦双重提示,确保用户感知)
+// 修复:选择器匹配修改后的输入框类名,确保监听生效
+$(document).on('input blur', '.num, .num' + objParam.modelId, function () {
+ let $this = $(this);
+ let modelId = $this.attr('modelId') || $this.closest('tr').attr('id') || $this.closest('tr').attr('class').match(/model(\S+)/)[1] || 'default_0';
+ let index = $this.attr('index') || $this.closest('td').index() - 7 || 0;
+ let currentVal = parseInt($this.val() || 0);
+ let key = modelId + '_' + index;
+ let originalData = originalCgLkMap.get(key);
+
+ if (!originalData) return;
+
+ // 实时提示:采购量不可小于原始值
+ if (currentVal < originalData.originalCgNum) {
+ layer.tips('采购量不可小于原始值:' + originalData.originalCgNum + '(当前值:' + currentVal + ')', $this, {
+ tips: [1, '#f56c6c'],
+ time: 3000
+ });
+ }
+
+ // 实时提示:采购量>0时需要选择供应商
+ if (currentVal > 0) {
+ let $supplier = $('.supplier' + modelId).eq(index);
+ if (!$supplier.val() || $supplier.val() === '') {
+ layer.tips('采购量大于0时必须选择供应商', $supplier, {
+ tips: [1, '#f56c6c'],
+ time: 3000
+ });
+ }
+ }
+});
+
+// 监听利库量输入框(增强提示:实时+失焦双重提示,确保用户感知)
+// 修复:选择器匹配修改后的输入框类名,确保监听生效
+$(document).on('input blur', '.lkNum, .lkNum' + objParam.modelId, function () {
+ let $this = $(this);
+ let modelId = $this.attr('modelId') || $this.closest('tr').attr('id') || $this.closest('tr').attr('class').match(/model(\S+)/)[1] || 'default_0';
+ let index = $this.attr('index') || $this.closest('td').index() - 7 || 0;
+ let currentVal = parseInt($this.val() || 0);
+ let key = modelId + '_' + index;
+ let originalData = originalCgLkMap.get(key);
+
+ if (!originalData) return;
+
+ // 实时提示:输入时就给出反馈,修复第二条数据不提示问题
+ if (currentVal < originalData.originalLkNum) {
+ layer.tips('利库量不可小于原始值:' + originalData.originalLkNum + '(当前值:' + currentVal + ')', $this, {
+ tips: [1, '#f56c6c'],
+ time: 3000
+ });
+ }
+});
+
+// 空值处理函数(对齐参考文件)
+function setNullValue(val) {
+ return val === undefined || val === null || val === '' ? '' : val;
+}
+
+// 构建下拉选数据(对齐参考文件逻辑,核心修复供应商回显)
+function setSelectData(modelId, value) {
+ let html = "";
+ if (!supplierList || supplierList.length === 0) {
+ return html;
+ }
+ $.each(supplierList, function (index, item) {
+ // 统一转为字符串,解决类型不匹配问题
+ let targetValue = (value || '').toString().trim();
+ let supIdStr = (item.supId || item.id).toString().trim();
+ let selected = '';
+ if (targetValue === supIdStr) {
+ selected = 'selected';
+ }
+ // 转义JSON中的双引号,避免HTML渲染异常
+ let itemJson = JSON.stringify(item).replace(/"/g, '"');
+ html += "";
+ });
+ return html;
+}
+
+// 构建表单输入项(核心修复:出厂日期/检验日期/备注添加readonly属性,禁用编辑)
+function setFormInput(value, type, id) {
+ let html = '';
+ return html;
+}
+
+// 完整setBaseTable函数(完全对齐参考文件结构,保留索引属性确保提示生效)
+function setBaseTable(data) {
+ let html = "";
+ if (data && data.length > 0) {
+ for (var i = 0; i < data.length; i++) {
+ var l = data[i];
+ let list = l.supList || [];
+ // 对齐参考文件,遍历supList渲染主行和子行
+ $.each(list, function (index, item) {
+ // 给每个输入框绑定index属性,确保提示功能能获取到正确索引
+ let itemIndex = index;
+ if (index === 0) {
+ // 主行:带rowspan合并单元格
+ html += "";
+ html += ' | ';
+ html += "" + (i + 1) + " | ";
+ html += "" + (l.type || '') + " | ";
+ html += "" + (l.name || '') + " | ";
+ html += "" + (l.model || '') + " | ";
+ html += "" + (l.unit || '') + " | ";
+ html += "" + (l.needNum || 0) + " | ";
+ // 采购量:添加index属性
+ html += "" + setFormInput(item.cgNum, 1, l.modelId).replace('";
+ // 利库量:添加index属性
+ html += " | " + setFormInput(item.lkNum, 2, l.modelId).replace('";
+ html += " | " + setFormInput(item.supId, 3, l.modelId) + " | ";
+ // 出厂日期:已通过setFormInput添加readonly
+ html += "" + setFormInput(item.ccDay, 4, l.modelId) + " | ";
+ // 检验日期:已通过setFormInput添加readonly
+ html += "" + setFormInput(item.jyDay, 5, l.modelId) + " | ";
+ // 备注:已通过setFormInput添加readonly
+ html += "" + setFormInput(item.remark, 6, l.modelId) + " | ";
+ html += "
";
+ } else {
+ // 子行:不合并单元格
+ html += "";
+ // 采购量:添加index属性
+ html += "| " + setFormInput(item.cgNum, 1, l.modelId).replace('";
+ // 利库量:添加index属性
+ html += " | " + setFormInput(item.lkNum, 2, l.modelId).replace('";
+ html += " | " + setFormInput(item.supId, 3, l.modelId) + " | ";
+ // 出厂日期:已通过setFormInput添加readonly
+ html += "" + setFormInput(item.ccDay, 4, l.modelId) + " | ";
+ // 检验日期:已通过setFormInput添加readonly
+ html += "" + setFormInput(item.jyDay, 5, l.modelId) + " | ";
+ // 备注:已通过setFormInput添加readonly
+ html += "" + setFormInput(item.remark, 6, l.modelId) + " | ";
+ html += "
";
+ }
+ });
+ }
+ } else {
+ html += "| 没有相关数据 |
";
+ }
+ $("#baseTable tbody").empty().append(html);
+ // 重新渲染日期选择器
+ laydate.render({
+ elem: '.cjDate',
+ trigger: 'none' // 再次确认日期选择器不可触发
+ });
+ laydate.render({
+ elem: '.jyDate',
+ trigger: 'none' // 再次确认日期选择器不可触发
+ });
+ // 强制渲染layui表单,确保供应商下拉选生效
+ layui.form.render();
+}
+
+// 校验数据(保留原有逻辑,确保失焦时校验提示生效)
+function checkValue(that, type) {
+ let value = $(that).val().trim();
+ // 统一处理前置0(保留纯0的情况)
+ let processedValue = value.replace(/^0+(?=\d)/, '');
+ if (processedValue === '') {
+ processedValue = '0'; // 输入全是0的情况(如0000)转为0
+ }
+ // 先更新输入框值为处理后的值
+ $(that).val(processedValue);
+ value = processedValue; // 后续校验使用处理后的值
+
+ if (type === 1) { // 采购量
+ const regex = /^(0|[1-9]\d{0,6})$/;
+ if (!regex.test(value) && value) {
+ $(that).val(0);
+ return layer.msg('采购量输入有误,请重新输入!', { icon: 5 })
+ }
+ } else if (type === 2) { // 利库量
+ const regex = /^(0|[1-9]\d{0,6})$/;
+ if (!regex.test(value) && value) {
+ $(that).val(0);
+ return layer.msg('利库量输入有误,请重新输入!', { icon: 5 })
+ }
+ if (value) {
+ // 新的利库量与库存量校验
+ let modelId = $(that).attr('modelId');
+ let oldValue = $(that).attr('oldValue');
+ let num = maTypeCheck(modelId);
+ let newValue = parseInt(value) - parseInt(oldValue);
+ if (newValue > 0) {
+ if (newValue > num) {
+ $(that).val(oldValue);
+ return layer.msg('利库量不能大于库存量,请重新输入!', { icon: 5 })
+ }
+ }
+ }
+ }
+}
\ No newline at end of file
diff --git a/js/aq_inventory/safety_tools_ledger.js b/js/aq_inventory/safety_tools_ledger.js
index 72d0c45..2b63350 100644
--- a/js/aq_inventory/safety_tools_ledger.js
+++ b/js/aq_inventory/safety_tools_ledger.js
@@ -1,13 +1,60 @@
let form, table;
let tableIns;
let pageNum = 1; // 定义分页
+let proListData = []; // 存储工程列表数据(新增)
+
layui.use(["form", "table"], function () {
form = layui.form;
table = layui.table;
+ getProList(); // 新增:加载工程下拉数据
initTable();
getStatistics();
});
+// 新增:获取工程列表数据
+function getProList() {
+ let url = dataUrl + 'backstage/planApply/getProSelectAndCompanyName';
+ ajaxRequest(url, "POST", null, false, function () {
+ console.log("开始获取工程列表...");
+ }, function (result) {
+ console.log("获取工程列表结果:", result);
+ if (result.code === 200) {
+ if (result.data && result.data.length > 0) {
+ console.log("工程数据:", result.data);
+ proListData = result.data;
+ setSelectProData(result.data); // 渲染工程下拉选
+ } else {
+ console.warn("工程列表为空");
+ setSelectProData([]);
+ }
+ } else {
+ console.error("获取工程列表失败:", result.msg);
+ }
+ }, function (xhr, status, error) {
+ console.error("获取工程列表异常:", error);
+ errorFn(xhr, status, error)
+ }, null);
+}
+
+// 新增:渲染工程下拉选
+function setSelectProData(proList) {
+ let html = '';
+ $.each(proList || [], function (index, item) {
+ // 拼接工程名称和公司名称(如果有)
+ let proText = item.name || item.proName || '';
+ if (item.companyName) {
+ proText += ' - ' + item.companyName;
+ }
+ html += '';
+ });
+
+ $('#projectId').empty().append(html);
+
+ // 重新渲染Layui表单
+ if (layui && layui.form) {
+ layui.form.render('select');
+ }
+}
// 数据概览
function getStatistics() {
@@ -51,6 +98,7 @@ function queryTable(type) {
$('#keyWord').val('');
$('#useUnit').val('');
$('#isShortage').val('');
+ $('#projectId').val(''); // 新增:重置工程下拉选
layui.form.render();
reloadTable(1);
}
@@ -62,20 +110,23 @@ function reloadData() {
getStatistics();
}
-// 重载表格
+// 重载表格 - 修改:添加工程筛选条件
function reloadTable(pageNum) {
table.reload("currentTableId", {
- where: {
- encryptedData: JSON.stringify({
- 'keyWord': $('#keyWord').val(),
- 'isShortage': $('#isShortage').val()
- }),
+ page: {
+ curr: pageNum ? pageNum : 1,
+ },
+ where: {
+ encryptedData: JSON.stringify({
+ 'keyWord': $('#keyWord').val(),
+ 'proId': $('#projectId').val() // 新增:工程ID筛选条件
+ }),
+ },
},
- },
);
}
-// 初始化表格
+// 初始化表格 - 修改:添加工程筛选条件
function initTable() {
tableIns = table.render({
elem: "#currentTableId",
@@ -87,7 +138,8 @@ function initTable() {
url: dataUrl + "backstage/inventoryCount/getSafetyToolsLedger",
where: {
encryptedData: JSON.stringify({
- 'keyWord': $('#keyWord').val()
+ 'keyWord': $('#keyWord').val(),
+ 'proId': $('#projectId').val()
}),
},
request: {
@@ -116,61 +168,150 @@ function initTable() {
},
},
{
- field: "type",
+ field: "proName",
width: '15%',
- title: "物资类型",
+ title: "工程名称",
unresize: true,
align: "center",
},
{
field: "name",
- width: '15%',
+ width: '8%',
title: "物资名称",
unresize: true,
align: "center",
},
{
field: "model",
- width: '18%',
+ width: '8%',
title: "规格型号",
unresize: true,
align: "center",
},
{
- field: "storageNum",
- width: '16%',
- title: "库存量",
+ field: "unit",
+ width: '5%',
+ title: "单位",
unresize: true,
align: "center",
- sort: true,
},
{
- field: "totalCk",
- width: '16%',
- title: "出库总量",
+ field: "planApplyCode",
+ width: '10%',
+ title: "计划编号",
+ unresize: true,
+ align: "center",
+ },
+ {
+ field: "needNum",
+ width: '7%',
+ title: "总需用量",
unresize: true,
align: "center",
- sort: true,
templet: function (d) {
- return d.totalCk || 0;
+ return d.needNum || 0;
},
},
{
- field: "totalBack",
+ field: "price",
+ width: '8%',
+ title: "单价",
+ unresize: true,
+ align: "center",
+ },
+ {
+ field: "totalPrice",
+ width: '8%',
+ title: "总价",
+ unresize: true,
+ align: "center",
+ templet: function (d) {
+ // 转换为数字,空值默认0,避免NaN
+ const price = Number(d.price || 0);
+ const needNum = Number(d.needNum || 0);
+ // 计算总价并保留2位小数(金额常用格式)
+ const totalPrice = (price * needNum).toFixed(2);
+ return totalPrice;
+ },
+ },
+ {
+ field: "outInfo",
+ width: '14.5%',
+ title: "发货时间",
+ unresize: true,
+ align: "center",
+ },
+ {
+ field: "outAddress",
width: '15%',
- title: "退还数量",
+ title: "发货地址",
unresize: true,
align: "center",
- sort: true,
- templet: function (d) {
- return d.totalBack || 0;
- },
},
+ {
+ field: "supName",
+ width: '10%',
+ title: "供应商",
+ unresize: true,
+ align: "center",
+ },
+ {
+ field: "backNum",
+ width: '8%',
+ title: "退还数量",
+ align: "center",
+ templet: function (d) {
+ return Number(d.backNum ?? 0);
+ }
+ },
+ {
+ field: "backTime",
+ width: '15.5%',
+ title: "退还时间",
+ align: "center",
+ },
+ {
+ title: "差缺",
+ width: '8%',
+ align: "center",
+ templet: function (d) {
+ let needNum = Number(d.needNum ?? 0);
+ let backNum = Number(d.backNum ?? 0);
+
+ let diff = needNum - backNum; // 允许为负数
+ return diff;
+ }
+ },
+ {
+ title: "差缺总价",
+ width: '8%',
+ align: "center",
+ templet: function (d) {
+ // 转换为数字,空值默认0,避免NaN
+ let needNum = Number(d.needNum ?? 0);
+ let backNum = Number(d.backNum ?? 0);
+ let price = Number(d.price || 0);
+
+ // 计算差缺数量
+ let diff = needNum - backNum;
+ // 计算差缺总价 = 差缺数量 × 单价,保留2位小数
+ let diffTotalPrice = (diff * price).toFixed(2);
+
+ return diffTotalPrice;
+ }
+ },
+ {
+ field: "remark",
+ width: '6%',
+ title: "备注",
+ align: "center",
+ },
+
],
],
limits: [10, 20, 30, 50, 100],
- limit: 50,
- page: false,
+ limit: 10,
+ page: true,
done: function (res, curr, count) {
pageNum = tableIns.config.page.curr;
table.resize("currentTableId");
@@ -178,32 +319,25 @@ function initTable() {
});
}
-// 查看详情
-function viewDetail(id) {
- layer.msg('查看工程物料详情功能待开发', { icon: 1 });
- // 这里可以添加查看详情的逻辑,比如打开新窗口或弹窗显示详细信息
- // openIframe('工程物料详情', 'page/aq_inventory/project_material_detail.html?id=' + id);
-}
-
-// 导出Excel
+// 导出Excel - 修改:添加工程筛选条件
function exportExcel() {
let keyWord = $('#keyWord').val();
- let isShortage = $('#isShortage').val();
-
+ let projectId = $('#projectId').val();
+
let params = {
'keyWord': keyWord,
- 'isShortage': isShortage
+ 'proId': projectId // 新增:工程ID筛选条件
};
-
+
let encryptedData = JSON.stringify(params);
- let url = dataUrl + 'backstage/inventoryCount/exportLedgerListByProjectAndModel?encryptedData=' + encodeURIComponent(encryptedData);
-
+ let url = dataUrl + 'backstage/inventoryCount/exportLedgerList?encryptedData=' + encodeURIComponent(encryptedData);
+
// 创建隐藏的下载链接
let link = document.createElement('a');
link.href = url;
- link.download = '工程物料统计_' + new Date().getTime() + '.xlsx';
+ link.download = '安全用品发放台账_' + new Date().getTime() + '.xlsx';
link.style.display = 'none';
-
+
// 添加授权头并下载
fetch(url, {
method: 'GET',
@@ -226,4 +360,4 @@ function exportExcel() {
}).catch(error => {
layer.msg('导出失败:' + error.message, { icon: 2 });
});
-}
\ No newline at end of file
+}
\ No newline at end of file
diff --git a/page/aq_demand_plan/child/send_out_edit_form.html b/page/aq_demand_plan/child/send_out_edit_form.html
index 29633c6..5488aba 100644
--- a/page/aq_demand_plan/child/send_out_edit_form.html
+++ b/page/aq_demand_plan/child/send_out_edit_form.html
@@ -78,7 +78,7 @@
- 发货附件*
+ 发货附件

@@ -155,9 +155,9 @@
需要量 |
*采购量 |
*利库量 |
-
*供应商 |
-
*出厂日期 |
-
*检验日期 |
+
供应商 |
+
出厂日期 |
+
检验日期 |
备注 |
diff --git a/page/aq_demand_plan/child/send_out_form.html b/page/aq_demand_plan/child/send_out_form.html
index 1f05f9c..77ea07d 100644
--- a/page/aq_demand_plan/child/send_out_form.html
+++ b/page/aq_demand_plan/child/send_out_form.html
@@ -84,7 +84,7 @@
-
必传项:请上传出门条
+
请上传出门条
可选项: 领料单、装卸货照片、车牌号
@@ -155,7 +155,7 @@
需要量 |
*采购量 |
*利库量 |
-
*供应商 |
+
供应商 |
出厂日期 |
检验日期 |
备注 |
diff --git a/page/aq_demand_plan/child/send_out_supplemen.html b/page/aq_demand_plan/child/send_out_supplemen.html
new file mode 100644
index 0000000..a19c776
--- /dev/null
+++ b/page/aq_demand_plan/child/send_out_supplemen.html
@@ -0,0 +1,189 @@
+
+
+
+
+
+
+
采购发货-补充
+
+
+
+
+
+
+
+
+
+
+
+

+
+
+
+
+
+
+ 发货附件
+
+
+

+
+
+
提示:最多上传5个附件
+
支持格式:jpg、png、jpeg
+
doc、docx、pdf、xlsx、xls
+
+
+
+
+
▋
+
发货明细(仅可增加采购量/利库量)
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/page/aq_demand_plan/child/send_out_unplanned_form.html b/page/aq_demand_plan/child/send_out_unplanned_form.html
index db0bec4..657fa44 100644
--- a/page/aq_demand_plan/child/send_out_unplanned_form.html
+++ b/page/aq_demand_plan/child/send_out_unplanned_form.html
@@ -84,7 +84,7 @@
-
必传项:请上传出门条
+
请上传出门条
可选项: 领料单、装卸货照片、车牌号
diff --git a/page/aq_inventory/safety_tools_ledger.html b/page/aq_inventory/safety_tools_ledger.html
index ea564f1..32b8d26 100644
--- a/page/aq_inventory/safety_tools_ledger.html
+++ b/page/aq_inventory/safety_tools_ledger.html
@@ -37,10 +37,18 @@