feat(inventory): 新增出库单功能

- 添加出库单新增、编辑、查看页面
- 实现出库单列表展示和搜索功能
- 增加出库单撤销和确认出库操作
- 优化出库单生成逻辑,支持自定义发货时间和数量
dev_1.0.0
chenhao 2025-08-13 15:20:04 +08:00
parent b55f406e12
commit 0aa2f518fc
55 changed files with 3736 additions and 126 deletions

View File

@ -140,7 +140,9 @@ var table = {
fixedNumber: options.fixedNumber, // 列冻结的个数(左侧)
fixedRightNumber: options.fixedRightNumber, // 列冻结的个数(右侧)
onReorderRow: options.onReorderRow, // 当拖拽结束后处理函数
queryParams: options.queryParams, // 传递参数(*
queryParams:(params)=>{
return options.queryParams(params,options.id)
}, // 传递参数(*
rowStyle: options.rowStyle, // 通过自定义函数设置行样式
footerStyle: options.footerStyle, // 通过自定义函数设置页脚样式
headerStyle: options.headerStyle, // 通过自定义函数设置标题样式
@ -166,8 +168,8 @@ var table = {
return optionsIds.substring(0, optionsIds.length - 1);
},
// 查询条件
queryParams: function (params) {
table.set();
queryParams: function (params,id) {
table.set(id);
var curParams = {
// 传递参数查询参数
pageSize: params.limit,

View File

@ -0,0 +1,76 @@
<!DOCTYPE html>
<html lang="zh" xmlns:th="http://www.thymeleaf.org" >
<head>
<th:block th:include="include :: header('新增产品库存')" />
<th:block th:include="include :: datetimepicker-css" />
</head>
<body class="white-bg">
<div class="wrapper wrapper-content animated fadeInRight ibox-content">
<form class="form-horizontal m" id="form-delivery-add">
<div class="col-xs-6">
<div class="form-group">
<label class="col-sm-4 control-label">出库单号:</label>
<div class="col-sm-8">
<input name="outerCode" class="form-control" type="text">
</div>
</div>
</div>
<div class="col-xs-6">
<div class="form-group">
<label class="col-sm-4 control-label">所属仓库:</label>
<div class="col-sm-8">
<input name="warehouseId" class="form-control" type="text">
</div>
</div>
</div>
<div class="col-xs-6">
<div class="form-group">
<label class="col-sm-4 control-label">物流公司:</label>
<div class="col-sm-8">
<input name="logisticsCompany" class="form-control" type="text">
</div>
</div>
</div>
<div class="col-xs-6">
<div class="form-group">
<label class="col-sm-4 control-label">物流单号:</label>
<div class="col-sm-8">
<input name="logisticsCode" class="form-control" type="text">
</div>
</div>
</div>
<div class="col-xs-6">
<div class="form-group">
<label class="col-sm-4 control-label">发货时间:</label>
<div class="col-sm-8">
<div class="input-group date">
<input name="deliveryTime" class="form-control" placeholder="yyyy-MM-dd" type="text">
<span class="input-group-addon"><i class="fa fa-calendar"></i></span>
</div>
</div>
</div>
</div>
</form>
</div>
<th:block th:include="include :: footer" />
<th:block th:include="include :: datetimepicker-js" />
<script th:inline="javascript">
var prefix = ctx + "inventory/delivery"
$("#form-delivery-add").validate({
focusCleanup: true
});
function submitHandler() {
if ($.validate.form()) {
$.operate.save(prefix + "/add", $('#form-delivery-add').serialize());
}
}
$("input[name='deliveryTime']").datetimepicker({
format: "yyyy-mm-dd",
minView: "month",
autoclose: true
});
</script>
</body>
</html>

View File

@ -0,0 +1,150 @@
<!DOCTYPE html>
<html lang="zh" xmlns:th="http://www.thymeleaf.org" xmlns:shiro="http://www.pollix.at/thymeleaf/shiro">
<head>
<th:block th:include="include :: header('产品库存列表')"/>
</head>
<body class="gray-bg">
<div class="container-div">
<div class="row">
<div class="col-sm-12 search-collapse">
<form id="formId">
<div class="select-list">
<ul>
<li>
<label>出库单号:</label>
<input type="text" name="outerCode"/>
</li>
<li>
<label>物流单号:</label>
<input type="text" name="logisticsCode"/>
</li>
<li>
<label>项目编号:</label>
<input type="text" name="projectCode"/>
</li>
<li>
<label>合同编号:</label>
<input type="text" name="orderCode"/>
</li>
<li>
<label>项目名称:</label>
<input type="text" name="projectName"/>
</li>
<li>
<label>发货方式:</label>
<select name="deliveryType" id="deliveryType" class="form-control"
th:with="type=${@dict.getType('delivery_type')}"
required>
<option value="">所有</option>
<option th:each="dict : ${type}" th:text="${dict.dictLabel}"
th:value="${dict.dictValue}" ></option>
</select>
</li>
<li>
<a class="btn btn-primary btn-rounded btn-sm" onclick="$.table.search()"><i
class="fa fa-search"></i>&nbsp;搜索</a>
<a class="btn btn-warning btn-rounded btn-sm" onclick="$.form.reset()"><i
class="fa fa-refresh"></i>&nbsp;重置</a>
</li>
</ul>
</div>
</form>
</div>
<div class="btn-group-sm" id="toolbar" role="group">
<a class="btn btn-warning" onclick="$.table.exportExcel()" shiro:hasPermission="inventory:delivery:export">
<i class="fa fa-download"></i> 导出
</a>
</div>
<div class="col-sm-12 select-table table-striped">
<table id="bootstrap-table"></table>
</div>
</div>
</div>
<th:block th:include="include :: footer"/>
<script th:inline="javascript">
var editFlag = [[${@permission.hasPermi('inventory:delivery:edit')}]];
var removeFlag = [[${@permission.hasPermi('inventory:delivery:remove')}]];
var prefix = ctx + "inventory/delivery";
$(function () {
var options = {
url: prefix + "/list",
createUrl: prefix + "/add",
updateUrl: prefix + "/edit/{id}",
viewUrl: prefix + "/view/{id}",
removeUrl: prefix + "/remove",
exportUrl: prefix + "/export",
modalName: "发货记录",
columns: [{
title: '序号',
formatter: function (value, row, index) {
return $.table.serialNumber(index);
}
},
{
field: 'id',
title: '',
visible: false
},
{
field: 'outerCode',
title: '出库单号'
},
{
field: 'logisticsCode',
title: '物流单号'
},
{
field: 'projectCode',
title: '项目编号'
},
{
field: 'orderCode',
title: '合同编号'
},
{
field: 'projectName',
title: '项目名称'
},
{
field: 'productCode',
title: '产品编码'
},
{
field: 'model',
title: '产品型号'
},
{
field: 'quantity',
title: '发货数量'
},
{
field: 'deliveryType',
title: '发货方式',
formatter: function (value, row, index) {
return $.table.selectDictLabel([[${@dict.getType('delivery_type')}]], value);
}
},
{
field: 'deliveryTime',
title: '发货时间'
},
{
title: '操作',
align: 'center',
formatter: function (value, row, index) {
var actions = [];
actions.push('<a class="btn btn-default btn-xs " href="javascript:void(0)" onclick="$.operate.view(\'' + row.id + '\')">发货记录</a> ');
return actions.join('');
}
}]
};
$.table.init(options);
});
</script>
</body>
</html>

View File

@ -0,0 +1,77 @@
<!DOCTYPE html>
<html lang="zh" xmlns:th="http://www.thymeleaf.org" >
<head>
<th:block th:include="include :: header('修改产品库存')" />
<th:block th:include="include :: datetimepicker-css" />
</head>
<body class="white-bg">
<div class="wrapper wrapper-content animated fadeInRight ibox-content">
<form class="form-horizontal m" id="form-delivery-edit" th:object="${inventoryDelivery}">
<input name="id" th:field="*{id}" type="hidden">
<div class="col-xs-6">
<div class="form-group">
<label class="col-sm-4 control-label">出库单号:</label>
<div class="col-sm-8">
<input name="outerCode" th:field="*{outerCode}" class="form-control" type="text">
</div>
</div>
</div>
<div class="col-xs-6">
<div class="form-group">
<label class="col-sm-4 control-label">所属仓库:</label>
<div class="col-sm-8">
<input name="warehouseId" th:field="*{warehouseId}" class="form-control" type="text">
</div>
</div>
</div>
<div class="col-xs-6">
<div class="form-group">
<label class="col-sm-4 control-label">物流公司:</label>
<div class="col-sm-8">
<input name="logisticsCompany" th:field="*{logisticsCompany}" class="form-control" type="text">
</div>
</div>
</div>
<div class="col-xs-6">
<div class="form-group">
<label class="col-sm-4 control-label">物流单号:</label>
<div class="col-sm-8">
<input name="logisticsCode" th:field="*{logisticsCode}" class="form-control" type="text">
</div>
</div>
</div>
<div class="col-xs-6">
<div class="form-group">
<label class="col-sm-4 control-label">发货时间:</label>
<div class="col-sm-8">
<div class="input-group date">
<input name="deliveryTime" th:value="${#dates.format(inventoryDelivery.deliveryTime, 'yyyy-MM-dd')}" class="form-control" placeholder="yyyy-MM-dd" type="text">
<span class="input-group-addon"><i class="fa fa-calendar"></i></span>
</div>
</div>
</div>
</div>
</form>
</div>
<th:block th:include="include :: footer" />
<th:block th:include="include :: datetimepicker-js" />
<script th:inline="javascript">
var prefix = ctx + "inventory/delivery";
$("#form-delivery-edit").validate({
focusCleanup: true
});
function submitHandler() {
if ($.validate.form()) {
$.operate.save(prefix + "/edit", $('#form-delivery-edit').serialize());
}
}
$("input[name='deliveryTime']").datetimepicker({
format: "yyyy-mm-dd",
minView: "month",
autoclose: true
});
</script>
</body>
</html>

View File

@ -0,0 +1,176 @@
<!DOCTYPE html>
<html lang="zh" xmlns:th="http://www.thymeleaf.org" >
<head>
<th:block th:include="include :: header('修改产品库存')" />
<th:block th:include="include :: datetimepicker-css" />
</head>
<style>
.section-title {
font-weight: bold;
font-size: 30px;
padding: 10px 0;
color: black;
display: flex;
align-items: baseline; /* 垂直居中 */
font-family: "微软雅黑", Arial, sans-serif; /* 统一字体 */
}
.required-delivery-time {
font-size: 20px;
}
</style>
<body class="white-bg">
<div class="wrapper wrapper-content animated fadeInRight ibox-content">
<div class="col-xs-12 section-title" id="delivery-title" style="display: flex;justify-content: space-between">
<div></div>
<div class="delivery-title">发货单</div>
<div class="required-delivery-time"><span>要求发货时间:</span> <span
th:text="${#dates.format(inventoryDelivery.deliveryTime, 'yyyy-MM-dd')}"></span></div>
</div>
<form class="form-horizontal m" id="form-delivery-edit" th:object="${inventoryDelivery}">
<input name="id" th:field="*{id}" type="hidden">
<div class="col-xs-4">
<div class="form-group">
<label class="col-sm-4 control-label">物流单号:</label>
<div class="col-sm-8">
<input name="logisticsCode" th:field="*{logisticsCode}" class="form-control" type="text" readonly>
</div>
</div>
</div>
<div class="col-xs-4">
<div class="form-group">
<label class="col-sm-4 control-label">发货方式:</label>
<div class="col-sm-8">
<select name="deliveryType" id="deliveryType" class="form-control" disabled
th:with="type=${@dict.getType('delivery_type')}"
required>
<option th:each="dict : ${type}" th:text="${dict.dictLabel}"
th:value="${dict.dictValue}" th:field="*{deliveryType}"></option>
</select>
</div>
</div>
</div>
<div class="col-xs-4">
<div class="form-group">
<label class="col-sm-4 control-label">物流公司:</label>
<div class="col-sm-8">
<select name="logisticsCompany" id="logisticsCompany" class="form-control" disabled
th:with="type=${@dict.getType('logistics_company')}">
<option th:each="dict : ${type}" th:text="${dict.dictLabel}" th:field="*{logisticsCompany}"
th:value="${dict.dictValue}"></option>
</select>
</div>
</div>
</div>
<div class="col-xs-4">
<div class="form-group">
<label class="col-sm-4 control-label ">发货人:</label>
<div class="col-sm-8">
<input name="createByName" th:field="*{createByName}" class="form-control" type="text" readonly>
</div>
</div>
</div>
<div class="col-xs-8">
<div class="form-group">
<label class="col-sm-4 control-label">发货时间:</label>
<div class="col-sm-8">
<div class="input-group">
<input name="deliveryTime" disabled th:value="${#dates.format(inventoryDelivery.deliveryTime, 'yyyy-MM-dd')}" class="form-control" placeholder="yyyy-MM-dd" type="text">
</div>
</div>
</div>
</div>
</form>
<form id="query-product-sn">
<input type="hidden" name="inventoryStatus" value="1">
<input type="hidden" id="outCode" name="outerCode" th:value="${inventoryDelivery.outerCode}">
<input type="hidden" name="warehouseId" th:value="${inventoryDelivery.warehouseId}">
</form>
<div class="col-sm-12 select-table table-striped">
<table id="bootstrap-table"></table>
</div>
</div>
<th:block th:include="include :: footer" />
<th:block th:include="include :: datetimepicker-js" />
<script th:inline="javascript">
var prefix = ctx + "inventory/delivery";
var productPrefix = ctx + "inventory/info";
$("#form-delivery-edit").validate({
focusCleanup: true
});
function submitHandler() {
if ($.validate.form()) {
$.operate.save(prefix + "/edit", $('#form-delivery-edit').serialize());
}
}
$("input[name='deliveryTime']").datetimepicker({
format: "yyyy-mm-dd",
minView: "month",
autoclose: true
});
function initProductSnTable() {
var options = {
id: 'bootstrap-table',
url: productPrefix + "/list",
modalName: "出库单",
onCheck: (row, $ele) => {
updateTotal()
},
onUncheck: (row, $ele) => {
updateTotal()
},
onCheckAll: (rowsAfter, rowsBefore) => {
updateTotal()
},
onUncheckAll: (rowsAfter, rowsBefore) => {
updateTotal()
},
showSearch: false,
showRefresh: false,
showToggle: false,
showColumns: false,
rememberSelected: true,
formId: "query-product-sn",
columns: [
{
field: 'id',
title: '',
visible: false
},
{
field: 'productSn',
title: 'SN码'
},
{
field: 'productCode',
title: '产品编码'
},
{
field: 'model',
title: '产品型号'
},
{
field: 'productDesc',
title: '描述'
},
{
field: 'warehouseName',
title: '仓库'
}]
};
$.table.init(options);
// $('#bootstrap-table').before('<div ><span>已选:</span><span id="table-select-count">0</span><span>(台)</span></div>');
}
$(function(){
parent.$('.layui-layer-btn0').css('display', 'none')
initProductSnTable();
})
</script>
</body>
</html>

View File

@ -3,6 +3,7 @@
<head>
<th:block th:include="include :: header('新增项目管理')"/>
<th:block th:include="include :: datetimepicker-css"/>
<th:block th:include="include :: bootstrap-editable-css"/>
</head>
<style>
body {
@ -97,6 +98,11 @@
#generateOuter label{
padding-right: 0px;
}
.editable-clear-x {
display: none !important;
}
</style>
<body class="white-bg">
<div class="wrapper wrapper-content animated fadeInRight ibox-content">
@ -353,10 +359,11 @@
</div>
<form class="form-horizontal m" id="generateOuterForm">
<div class="col-xs-4">
<input type="hidden" name="orderCode" th:value="${projectOrderInfo.orderCode}">
<div class="form-group">
<label class="col-sm-4 control-label ">出库单号:</label>
<div class="col-sm-8">
<input placeholder="自动生成" class="form-control" type="text" readonly>
<input placeholder="自动生成" id="outerCode" class="form-control" type="text" readonly>
</div>
</div>
</div>
@ -364,7 +371,7 @@
<div class="form-group">
<label class="col-sm-4 control-label ">出库时间:</label>
<div class="col-sm-8">
<input placeholder="自动生成" class="form-control" type="text" readonly>
<input placeholder="自动生成" id="outerTime" class="form-control" type="text" readonly>
</div>
</div>
</div>
@ -394,33 +401,53 @@
<div class="col-xs-12">
<table id="warehouse-table"></table>
</div>
<div class="col-xs-12">
<div class="col-xs-12" id="out-quantity-column">
<label class="col-sm-3 control-label text-left">应出库(台)</label>
<label class="col-sm-9 control-label text-left " id="out-quantity">80</label>
</div>
<div class="col-xs-12">
<div class="col-xs-12" id="generated-quantity-column">
<label class="col-sm-3 control-label text-left" >已提交出库(台)</label>
<label class="col-sm-9 control-label text-left" id="out-generatedQuantity">80</label>
</div>
<div class="col-xs-12">
<label class="col-sm-3 control-label text-left" style="font-weight: bold;">本次提交出库(台)</label>
<label class="col-sm-9 control-label text-left" style="font-weight: bold;" id="out-current-quantity">80</label>
<input type="hidden" name="quantity" id="out-current-quantity-commit">
<label class="col-sm-9 control-label text-left" style="font-weight: bold;"
id="out-current-quantity">80</label>
</div>
<div class="col-xs-12">
<label class="col-sm-3 control-label text-left">收货地址:</label>
<input class="col-sm-9 control-label text-left" th:value="${projectOrderInfo.notifierAddress}" ></input>
<div class="col-sm-9">
<input class="form-control" type="text" name="contactAddress"
th:value="${projectOrderInfo.notifierAddress}"/>
</div>
</div>
<div class="col-xs-12">
<label class="col-sm-3 control-label text-left">联系人:</label>
<input class="col-sm-9 control-label text-left" th:value="${projectOrderInfo.notifier}"></input>
<div class="col-sm-9">
<input class="form-control" type="text" name="contactPerson"
th:value="${projectOrderInfo.notifier}"/>
</div>
</div>
<div class="col-xs-12">
<label class="col-sm-3 control-label text-left">联系电话(台)</label>
<input class="col-sm-9 control-label text-left" th:value="${projectOrderInfo.notifierPhone}"></input>
<label class="col-sm-3 control-label text-left">联系电话:</label>
<div class="col-sm-9">
<input class="form-control" type="text" name="contactPhone"
th:value="${projectOrderInfo.notifierPhone}"/>
</div>
</div>
<div class="col-xs-12">
<label class="col-sm-3 control-label text-left">要求发货时间:</label>
<label class="col-sm-9 control-label text-left">80</label>
<div class="col-sm-3">
<select class="form-control" name="deliveryTimeType" onchange="changeDeliveryTimeType()">
<option value="0">立即发货</option>
<option value="1">自定义</option>
</select>
</div>
<div class="col-sm-6">
<input name="deliveryTime" class="time-input form-control" id="deliveryTime" autocomplete="off"
placeholder="要求发货时间"/>
</div>
</div>
</form>
</div>
@ -428,17 +455,35 @@
<th:block th:include="include :: datetimepicker-js"/>
<th:block th:include="include :: layui"/>
<th:block th:include="include :: jquery-cxselect-js"/>
<th:block th:include="include :: bootstrap-table-editable-js"/>
<script th:inline="javascript">
var prefix = ctx + "project/order"
const executionPrefix = ctx + "inventory/execution"
const outerPrefix = ctx + "inventory/outer"
const canUpdate = [[${canUpdate}]]
const viewFlag = [[${view}]]
$("#form-order-edit").validate({
focusCleanup: true
});
function getNowDate() {
let now = new Date();
let formattedDate = now.getFullYear() + '-' +
String(now.getMonth() + 1).padStart(2, '0') + '-' +
String(now.getDate()).padStart(2, '0');
return formattedDate;
}
function changeDeliveryTimeType() {
let deliveryTimeType = $("select[name='deliveryTimeType']").val()
if (deliveryTimeType === '0') {
$('#deliveryTime').val(getNowDate());
$('#deliveryTime').attr('disabled', true)
} else {
$('#deliveryTime').attr('disabled', false)
}
}
function initProductDetailTable(data) {
var options = {
data: data ?? [[${productDetailList}]],
@ -469,15 +514,16 @@
},
{
field: 'quantity',
title: '应出库(台)'
title: '应出库'
},
{
field: 'confirmQuantity',
title: '已确认出库'
},
{
field: 'generatedQuantity',
title: '已生成出库(台)'
},
{
field: 'confirmQuantity',
title: '已确认出库(台)'
title: '已生成出库'
},
{
field: 'availableCount',
@ -489,8 +535,9 @@
align: 'center',
formatter: function (value, row, index) {
var actions = [];
actions.push('<a class="btn btn-default btn-xs " href="javascript:void(0)" onclick="checkOut(\'' + row.productCode + '\'' +
',\'' + row.model + '\',\'' + row.vendorName + '\',\'' + row.quantity + '\',\'' + row.generatedQuantity + '\')">出库</a>');
let disabled = Number(row.quantity) <= Number(row.generatedQuantity) + Number(row.confirmQuantity)
actions.push(`<a class="btn btn-default btn-xs " href="javascript:void(0)" ${disabled?'disabled':''}
onclick="checkOut(\'${row.productCode}\',\'${row.model}\',\'${row.vendorName}\',\'${row.quantity}\',\'${row.generatedQuantity}\',\'${row.confirmQuantity}\',\'[[${projectOrderInfo.id}]]\')">出库</a>`);
return actions.join('');
}
}]
@ -506,11 +553,17 @@ function initWarehouseTable(data) {
showRefresh: false,
showToggle: false,
showColumns: false,
onEditableSave: onEditableSave,
columns: [
{
field: 'warehouseName',
title: '仓库'
title: '仓库',
formatter: function (value, row, index) {
var html = $.common.sprintf("<input class='form-control' type='hidden' name='detailList[%s].warehouseId' value='%s'>" +
"<input class='form-control' type='hidden' name='detailList[%s].quantity' value='%s'>", index, row.warehouseId, index, row.confirmQuantity);
return value + html;
}
},
{
field: 'warehouseId',
@ -518,57 +571,154 @@ function initWarehouseTable(data) {
visible: false
},
{
field: 'model',
title: '实时用库存(台)'
field: 'availableCount',
title: '实时用库存'
},
{
field: 'quantity',
title: '本次提交出库(台)'
field: 'confirmQuantity',
title: '本次提交出库',
editable: {
type: 'number',
min: 0,
title: '本次提交出库',
emptytext: "【本次提交出库】为空",
validate: function (value) {
if (!value) {
return '数量不能空';
}
if (value > Number.MAX_VALUE) {
return '数量不能超过' + Number.MAX_VALUE;
}
if (value < 0) {
return '数量不能为负数';
}
},
toggleDisabled: function (isEnable) {
if (isEnable) {
console.log("enable")
this.enable();// 可编辑
} else {
console.log("disable")
this.disabled();// 不可编辑
}
}
}
}]
};
$.table.init(options);
}
function onEditableSave(field, row, rowIndex, oldValue, $el) {
function checkOut(productCode,model,vendorName,quantity,generatedQuantity) {
if (!row['defaultWarehouse'] && row[field] > row['availableCount']) {
$.modal.msgError("库存不足")
row[field] = oldValue
return
}
let bootstrapTable = $("#warehouse-table").bootstrapTable('getData');
let totalConfirmQuantity = 0;
bootstrapTable.forEach(item => {
totalConfirmQuantity += Number(item.confirmQuantity || 0)
});
let generateNumber = $('#out-generatedQuantity').text();
totalConfirmQuantity += Number(generateNumber)
if (totalConfirmQuantity > Number($('#out-quantity').text())) {
$.modal.msgError("本次提交出库数量不能大于应出库数量")
row[field] = oldValue
return;
}
$('#out-current-quantity').text(totalConfirmQuantity)
$('#out-current-quantity-commit').val(totalConfirmQuantity)
}
function checkOut(productCode, model, vendorName, quantity, generatedQuantity, confirmQuantity, projectOrderId) {
let disabled = Number(quantity) <= Number(generatedQuantity) + Number(confirmQuantity)
if (disabled) {
return
}
initModal()
$('#outer-productCode').val(productCode)
$('#outer-model').val(model)
$('#outer-vendorName').val(vendorName)
$('#out-quantity').text(quantity)
$('#out-generatedQuantity').text(generatedQuantity)
$('#deliveryTime').val(getNowDate());
$('#deliveryTime').attr('disabled', true);
parent.$('.layui-layer-btn').css('display', 'none')
let width = 1000, height = 700
if ($.common.isMobile()) {
width = 'auto';
height = 'auto';
}
let index=layer.open({
id: 'generate_outer',
type: 1,
title: '生成出库单',
shade: 0.5, // 不显示遮罩
area: [width + 'px', height + 'px'],
content: $('#generateOuter'), // 捕获的元素
btn: ['确定', '关闭'],
yes: function (index, layero, that) {
},
end: function () {
parent.$('.layui-layer-setwin').css('display', 'none')
$.operate.post(executionPrefix + '/checkOut/preview', {
productCode: productCode,
quantity: Number(quantity) - Number(generatedQuantity) - Number(confirmQuantity)
}, res => {
if (res.code != 0) {
$.modal.msgError(res.msg)
parent.$('.layui-layer-btn').css('display', '')
// layer.msg('关闭后的回调', {icon:6});
parent.$('.layui-layer-setwin').css('display', '')
return
}
});
layer.full(index);
$("#warehouse-table").bootstrapTable('load', res.data);
// 计算本次提交出库总数所有仓库confirmQuantity之和
let totalConfirmQuantity = 0;
if (res.data && Array.isArray(res.data)) {
totalConfirmQuantity = res.data.reduce((sum, item) => {
return sum + (item.confirmQuantity || 0);
}, 0);
}
$('#out-current-quantity').text(totalConfirmQuantity);
$('#out-current-quantity-commit').val(totalConfirmQuantity);
let width = 1000, height = 700
if ($.common.isMobile()) {
width = 'auto';
height = 'auto';
}
let index = layer.open({
id: 'generate_outer',
type: 1,
title: '生成出库单',
shade: 0.5, // 不显示遮罩
area: [width + 'px', height + 'px'],
content: $('#generateOuter'), // 捕获的元素
btn: ['确定', '关闭'],
yes: function (index, layero, that) {
$('#deliveryTime').attr('disabled', false);
$.operate.post(outerPrefix + "/add", $('#generateOuterForm').serializeArray(), res => {
refreshTable();
});
layer.close(index);
},
end: function () {
parent.$('.layui-layer-btn').css('display', '')
parent.$('.layui-layer-setwin').css('display', '')
// layer.msg('关闭后的回调', {icon:6});
}
});
layer.full(index);
})
}
function refreshTable() {
let id = [[${projectOrderInfo.id}]];
$.operate.get(executionPrefix + '/query/' + id, res => {
if (res.code != 0) {
$.modal.msgError("刷新表格失败");
return
}
$("#outer-table").bootstrapTable('load', res.data.inventoryOuterList);
$("#bootstrap-table").bootstrapTable('load', res.data.productDetailList);
})
}
function initOuterTable(data) {
var options = {
id: "outer-table",
data: data ?? [[${inventoryOuterList}]],
showSearch: false,
showRefresh: false,
showToggle: false,
@ -603,7 +753,11 @@ function initWarehouseTable(data) {
},
{
field: 'outerStatus',
title: '出库状态'
title: '出库状态',
formatter: function (value, row, index) {
return $.table.selectDictLabel([[${@dict.getType('outer_outer_status')}]], value);
}
},
{
field: 'contactPerson',
@ -623,7 +777,14 @@ function initWarehouseTable(data) {
align: 'center',
formatter: function (value, row, index) {
var actions = [];
actions.push('<a class="btn btn-default btn-xs " href="javascript:void(0)" onclick="">出库</a>');
if (row.outerStatus === '1' || row.outerStatus === '4') {
actions.push(`<a class="btn btn-danger btn-xs " style="margin:0px 5px" href="javascript:void(0)" onclick="deleteOuter('${row.id}','${row.orderCode}')">撤销</a>`);
actions.push(`<a class="btn btn-default btn-xs " href="javascript:void(0)" onclick="updateStatus('${row.id}','${row.orderCode}')">确认出库</a>`);
} else {
actions.push('<a class="btn btn-default btn-xs " href="javascript:void(0)" onclick="viewOuter(' + row.id + ')">查看详情</a>');
}
return actions.join('');
}
}]
@ -672,6 +833,87 @@ function initWarehouseTable(data) {
}
})
function initModal() {
$('#outerCode').val('')
$('#outerTime').val('')
$('#outer-productCode').val('')
$('#outer-model').val('')
$('#outer-vendorName').val('')
$('#out-current-quantity').text('')
$('[name="contactAddress"]').val([[${projectOrderInfo.notifierAddress}]])
$('[name="contactPerson"]').val([[${projectOrderInfo.notifier}]])
$('[name="contactPhone"]').val([[${projectOrderInfo.notifierPhone}]])
$('[name="deliveryTimeType"]').val('0')
$('#deliveryTime').val('')
$('#out-quantity-column').css('display', '')
$('#generated-quantity-column').css('display', '')
$.table.showColumn('availableCount', 'warehouse-table')
// generateOuterForm
$('#generateOuterForm').find('input,select').each(function () {
$(this).prop("disabled", false);
})
}
function viewOuter(id) {
$.operate.get(outerPrefix + '/query/' + id, res => {
if (res.code != 0) {
$.modal.msgError(res.msg)
return
}
//设置对应值
$('#outerCode').val(res.data.outerCode)
$('#outerTime').val(res.data.createTime)
$('#outer-productCode').val(res.data.productCode)
$('#outer-model').val(res.data.model)
$('#outer-vendorName').val(res.data.vendorName)
$('#out-current-quantity').text(res.data.quantity)
$('[name="contactAddress"]').val(res.data.contactAddress)
$('[name="contactPerson"]').val(res.data.contactPerson)
$('[name="contactPhone"]').val(res.data.contactPhone)
$('[name="deliveryTimeType"]').val(res.data.deliveryTimeType)
$('#deliveryTime').val(res.data.deliveryTime)
$('#out-quantity-column').css('display', 'none')
$('#generated-quantity-column').css('display', 'none')
$.table.hideColumn('availableCount', 'warehouse-table')
// generateOuterForm
$('#generateOuterForm').find('input,select').each(function () {
$(this).prop("disabled", true);
})
$("#warehouse-table").bootstrapTable('load', res.data.warehouseInfoList);
let width = 1000, height = 700
let index = layer.open({
id: 'generate_outer',
type: 1,
title: '生成出库单',
shade: 0.5, // 不显示遮罩
area: [width + 'px', height + 'px'],
content: $('#generateOuter'), // 捕获的元素
btn: ['关闭'],
end: function () {
parent.$('.layui-layer-btn').css('display', '')
// layer.msg('关闭后的回调', {icon:6});
}
});
layer.full(index);
})
}
function deleteOuter(id) {
$.operate.post(outerPrefix + '/remove', {id: id}, res => {
refreshTable();
})
}
function updateStatus(id,orderCode) {
$.operate.post(outerPrefix + '/status', {id: id, outerStatus: '2',orderCode:orderCode}, res => {
refreshTable();
})
}
function updateShipmentAmountValue(key) {
// 获取显示用的输入框

View File

@ -0,0 +1,100 @@
<!DOCTYPE html>
<html lang="zh" xmlns:th="http://www.thymeleaf.org" >
<head>
<th:block th:include="include :: header('新增出库单')" />
<th:block th:include="include :: datetimepicker-css" />
</head>
<body class="white-bg">
<div class="wrapper wrapper-content animated fadeInRight ibox-content">
<form class="form-horizontal m" id="form-outer-add">
<div class="col-xs-12">
<div class="form-group">
<label class="col-sm-3 control-label">出库单号:</label>
<div class="col-sm-8">
<input name="outerCode" class="form-control" type="text">
</div>
</div>
</div>
<div class="col-xs-12">
<div class="form-group">
<label class="col-sm-3 control-label">产品BOM编码</label>
<div class="col-sm-8">
<input name="productCode" class="form-control" type="text">
</div>
</div>
</div>
<div class="col-xs-12">
<div class="form-group">
<label class="col-sm-3 control-label">数量:</label>
<div class="col-sm-8">
<input name="quantity" class="form-control" type="text">
</div>
</div>
</div>
<div class="col-xs-12">
<div class="form-group">
<label class="col-sm-3 control-label">订单编码:</label>
<div class="col-sm-8">
<input name="orderCode" class="form-control" type="text">
</div>
</div>
</div>
<div class="col-xs-12">
<div class="form-group">
<label class="col-sm-3 control-label">联系人:</label>
<div class="col-sm-8">
<input name="contactPerson" class="form-control" type="text">
</div>
</div>
</div>
<div class="col-xs-12">
<div class="form-group">
<label class="col-sm-3 control-label">联系电话:</label>
<div class="col-sm-8">
<input name="contactPhone" class="form-control" type="text">
</div>
</div>
</div>
<div class="col-xs-12">
<div class="form-group">
<label class="col-sm-3 control-label">联系地址:</label>
<div class="col-sm-8">
<input name="contactAddress" class="form-control" type="text">
</div>
</div>
</div>
<div class="col-xs-12">
<div class="form-group">
<label class="col-sm-3 control-label">发货时间:</label>
<div class="col-sm-8">
<div class="input-group date">
<input name="deliveryTime" class="form-control" placeholder="yyyy-MM-dd" type="text">
<span class="input-group-addon"><i class="fa fa-calendar"></i></span>
</div>
</div>
</div>
</div>
</form>
</div>
<th:block th:include="include :: footer" />
<th:block th:include="include :: datetimepicker-js" />
<script th:inline="javascript">
var prefix = ctx + "inventory/outer"
$("#form-outer-add").validate({
focusCleanup: true
});
function submitHandler() {
if ($.validate.form()) {
$.operate.save(prefix + "/add", $('#form-outer-add').serialize());
}
}
$("input[name='deliveryTime']").datetimepicker({
format: "yyyy-mm-dd",
minView: "month",
autoclose: true
});
</script>
</body>
</html>

View File

@ -0,0 +1,652 @@
<!DOCTYPE html>
<html lang="zh" xmlns:th="http://www.thymeleaf.org">
<head>
<th:block th:include="include :: header('修改出库单')"/>
<th:block th:include="include :: datetimepicker-css"/>
</head>
<style>
.section-title {
font-weight: bold;
font-size: 30px;
padding: 10px 0;
color: black;
display: flex;
align-items: baseline; /* 垂直居中 */
font-family: "微软雅黑", Arial, sans-serif; /* 统一字体 */
}
.delivery-time-title {
font-weight: bold;
font-size: 23px;
padding: 10px 0;
color: black;
display: flex;
align-items: baseline; /* 垂直居中 */
font-family: "微软雅黑", Arial, sans-serif; /* 统一字体 */
justify-content: flex-end;
}
.required-delivery-time {
font-size: 20px;
}
</style>
<body class="white-bg">
<div class="wrapper wrapper-content animated fadeInRight ibox-content">
<div class="section-title" style="justify-content: center">
<span>基础信息</span>
</div>
<div class="delivery-time-title">
<div><span>要求发货时间:</span> <span
th:text="${#dates.format(inventoryOuter.deliveryTime, 'yyyy-MM-dd')}"></span></div>
</div>
<form class="form-horizontal m" id="form-outer-edit" th:object="${inventoryOuter}">
<input name="id" th:field="*{id}" type="hidden">
<div class="col-xs-6">
<div class="form-group">
<label class="col-sm-3 control-label">出库单号:</label>
<div class="col-sm-8">
<input name="outerCode" th:field="*{outerCode}" class="form-control" type="text" readonly>
</div>
</div>
</div>
<div class="col-xs-6">
<div class="form-group">
<label class="col-sm-3 control-label">项目编号:</label>
<div class="col-sm-8">
<input name="productCode" th:field="*{projectCode}" class="form-control" type="text" readonly>
</div>
</div>
</div>
<div class="col-xs-6">
<div class="form-group">
<label class="col-sm-3 control-label">合同编号:</label>
<div class="col-sm-8">
<input name="quantity" th:field="*{orderCode}" class="form-control" type="text" readonly>
</div>
</div>
</div>
<div class="col-xs-6">
<div class="form-group">
<label class="col-sm-3 control-label">项目名称:</label>
<div class="col-sm-8">
<input name="orderCode" th:field="*{projectName}" class="form-control" type="text" readonly>
</div>
</div>
</div>
<div class="section-title col-xs-12">
<span>产品清单</span>
</div>
<div class="col-sm-12 select-table table-striped">
<table id="product-table"></table>
</div>
<div class="section-title col-xs-12">
<span>已生成发货记录</span>
</div>
<div class="col-sm-12 select-table table-striped">
<table id="delivery-table"></table>
</div>
</form>
</div>
<div id="generateDelivery" style="display: none">
<div class="col-xs-12 section-title" id="delivery-title" style="display: flex;justify-content: space-between">
<div></div>
<div class="delivery-title">发货单</div>
<div class="required-delivery-time"><span>要求发货时间:</span> <span
th:text="${#dates.format(inventoryOuter.deliveryTime, 'yyyy-MM-dd')}"></span></div>
</div>
<form class="form-horizontal m" id="generateDeliveryForm">
<div class="col-xs-4">
<div class="form-group">
<label class="col-sm-4 control-label">物流单号:</label>
<div class="col-sm-8">
<input id="logisticsCode" name="logisticsCode" class="form-control" type="text">
</div>
</div>
</div>
<div class="col-xs-4">
<div class="form-group">
<label class="col-sm-4 control-label">发货方式:</label>
<div class="col-sm-8">
<select name="deliveryType" id="deliveryType" class="form-control"
th:with="type=${@dict.getType('delivery_type')}"
required>
<option th:each="dict : ${type}" th:text="${dict.dictLabel}"
th:value="${dict.dictValue}"></option>
</select>
</div>
</div>
</div>
<div class="col-xs-4">
<div class="form-group">
<label class="col-sm-4 control-label">物流公司:</label>
<div class="col-sm-8">
<select name="logisticsCompany" id="logisticsCompany" class="form-control"
th:with="type=${@dict.getType('logistics_company')}">
<option th:each="dict : ${type}" th:text="${dict.dictLabel}"
th:value="${dict.dictValue}"></option>
</select>
</div>
</div>
</div>
<div class="col-xs-4">
<div class="form-group">
<label class="col-sm-4 control-label ">发货人:</label>
<div class="col-sm-8">
<input placeholder="自动生成" id="createByName" class="form-control" type="text" readonly>
</div>
</div>
</div>
<div class="col-xs-8">
<div class="form-group">
<label class="col-sm-3 control-label ">实际发货时间:</label>
<div class="col-sm-3">
<select class="form-control" id="deliveryTimeType" name="deliveryTimeType"
onchange="changeDeliveryTimeType()">
<option value="0">立即发货</option>
<option value="1">自定义</option>
</select>
</div>
<div class="col-sm-6">
<input name="deliveryTime" class="time-input form-control" id="deliveryTime" autocomplete="off"
placeholder="要求发货时间"/>
</div>
</div>
</div>
</form>
<form id="query-product-sn">
<input type="hidden" name="inventoryStatus" value="0">
<input type="hidden" id="outCode" name="outerCode">
<input type="hidden" name="warehouseId">
</form>
<div class="btn-group-sm" id="toolbar" role="group">
<a class="btn btn-warning" onclick="importTemplate()">
<i class="fa fa-download"></i> 下载模板
</a>
<a class="btn btn-info" onclick="importList()">
<i class="fa fa-upload"></i> 导入
</a>
</div>
<div class="col-sm-12 select-table table-striped">
<table id="bootstrap-table"></table>
</div>
<input id="uploadInput" type="file" accept=".xls,.xlsx" style="display: none">
</div>
<th:block th:include="include :: footer"/>
<th:block th:include="include :: datetimepicker-js"/>
<script th:inline="javascript">
var prefix = ctx + "inventory/outer";
var productPrefix = ctx + "inventory/info";
var deliveryPrefix = ctx + "inventory/delivery";
const showReturnFlag = [[${deliveryList}]] && [[${deliveryList.size()}]]>0;
$("#form-outer-edit").validate({
focusCleanup: true
});
function importTemplate() {
$.get(prefix + "/importTemplate", function (result) {
if (result.code == web_status.SUCCESS) {
window.location.href = ctx + "common/download?fileName=" + encodeURI(result.msg) + "&delete=" + true;
} else if (result.code == web_status.WARNING) {
$.modal.alertWarning(result.msg)
} else {
$.modal.alertError(result.msg);
}
});
}
function importList() {
$('#uploadInput').click()
}
document.getElementById('uploadInput').addEventListener('change', function (event) {
const file = event.target.files[0];
let data = new FormData()
data.append('file', file)
var xhr = new XMLHttpRequest(); // 创建XMLHttpRequest对象
xhr.open('POST', prefix + '/importData', true); // 设置请求类型和URL
// 当请求完成时执行的回调函数
xhr.onload = function (res) {
let data = JSON.parse(res.currentTarget.response)
if (data.code === 0) {
$.modal.msgSuccess('上传成功');
$.table.refreshOptions({data: data})
} else {
top.layer.alert(data.msg || '导入失败', {
icon: 2,
title: "系统提示",
btn: ['确认'],
skin: 'content-br',
btnclass: ['btn btn-primary'],
});
}
$('#uploadInput').val('')
};
// 当请求发生错误时执行的回调函数
xhr.onerror = function () {
console.log('上传过程中发生错误');
};
//
// // 发送数据到服务器
xhr.send(data);
});
function submitHandler() {
$.modal.confirm("确认要确认退回吗?", function () {
$.operate.save(prefix + "/status", {"id": [[${inventoryOuter.id}]], "outerStatus": '4'});
})
}
$("input[name='deliveryTime']").datetimepicker({
format: "yyyy-mm-dd",
minView: "month",
autoclose: true
});
$(function () {
if (showReturnFlag) {
parent.$('.layui-layer-btn0').css('display', 'none')
} else {
parent.$('.layui-layer-btn0').text('退回')
}
initProductTable()
initDeliveryTable()
initProductSnTable()
});
function getNowDate() {
let now = new Date();
let formattedDate = now.getFullYear() + '-' +
String(now.getMonth() + 1).padStart(2, '0') + '-' +
String(now.getDate()).padStart(2, '0');
return formattedDate;
}
function changeDeliveryTimeType() {
let deliveryTimeType = $("select[name='deliveryTimeType']").val()
if (deliveryTimeType === '0') {
$('#deliveryTime').val(getNowDate());
$('#deliveryTime').attr('disabled', true)
} else {
$('#deliveryTime').attr('disabled', false)
}
}
function initProductSnTable() {
var options = {
id: 'bootstrap-table',
url: productPrefix + "/list",
modalName: "出库单",
onCheck: (row, $ele) => {
updateTotal()
},
onUncheck: (row, $ele) => {
updateTotal()
},
onCheckAll: (rowsAfter, rowsBefore) => {
updateTotal()
},
onUncheckAll: (rowsAfter, rowsBefore) => {
updateTotal()
},
showSearch: false,
showRefresh: false,
showToggle: false,
showColumns: false,
rememberSelected: true,
formId: "query-product-sn",
columns: [{
field: 'state',
checkbox: true
},
{
field: 'id',
title: '',
visible: false
},
{
field: 'productSn',
title: 'SN码'
},
{
field: 'productCode',
title: '产品编码'
},
{
field: 'model',
title: '产品型号'
},
{
field: 'productDesc',
title: '描述'
},
{
field: 'warehouseName',
title: '仓库'
}]
};
$.table.init(options);
$('#bootstrap-table').before('<div ><span>已选:</span><span id="table-select-count">0</span><span>(台)</span></div>');
}
function updateTotal() {
let $tableCount = $('#table-select-count');
if ($tableCount.length > 0) {
// 延迟100毫秒等待表格渲染完成
setTimeout(function () {
$tableCount.text($.table.selectColumns("productSn").length);
}, 100)
}
}
function initProductTable(data) {
var options = {
id: "product-table",
data: data || [[${productList}]],
pagination: false,
showSearch: false,
showRefresh: false,
showToggle: false,
showColumns: false,
columns: [
{
title: '序号',
formatter: function (value, row, index) {
return $.table.serialNumber(index);
}
},
{
field: 'id',
title: '',
visible: false
},
{
field: 'productCode',
title: '产品编码'
},
{
field: 'model',
title: '产品型号'
},
{
field: 'quantity',
title: '应发货'
},
{
field: 'deliveryConfirmQuantity',
title: '已确认发货'
},
{
field: 'deliveryGenerateQuantity',
title: '已生成发货'
},
{
field: 'availableCount',
title: '实时库存',
},
{
field: 'warehouseName',
title: '仓库',
},
{
title: '操作',
align: 'center',
formatter: function (value, row, index) {
var actions = [];
let disabled = Number(row.quantity) <= Number(row.deliveryGenerateQuantity) + Number(row.deliveryConfirmQuantity)
actions.push(`<span class="btn btn-default btn-xs " href="javascript:void(0)" ${disabled ? 'style="pointer-events: none;" disabled' : ''} onclick="checkDelivery(\'${row.quantity}\',\'${row.warehouseId}\')">发货</span>`);
return actions.join('');
}
}]
};
$.table.init(options);
}
function checkDelivery(quantity, warehouseId) {
initModal()
// $.table.set('bootstrap-table')
let width = 1000, height = 700
parent.$('.layui-layer-btn').css('display', 'none')
parent.$('.layui-layer-setwin').css('display', 'none')
$('[name="warehouseId"]').val(warehouseId)
$('[name="inventoryStatus"]').val(0)
$('#query-product-sn [name="outerCode"]').val('')
$.table.search('query-product-sn', 'bootstrap-table')
$('#table-select-count').text(0);
let index = layer.open({
id: 'generate_delivery',
type: 1,
title: '生成发货单',
shade: 0.5, // 不显示遮罩
area: [width + 'px', height + 'px'],
content: $('#generateDelivery'), // 捕获的元素
btn: ['确定', '关闭'],
yes: function (index, layero, that) {
var arrays = $.table.selectColumns("productSn");
if (arrays.length != quantity) {
$.modal.msgError(`产品选中数量应与发货数量一致,应发货数量为[${quantity}]`)
return
}
//保存数据
let data = {
productSnList: arrays,
logisticsCode: $('#logisticsCode').val(),
quantity: quantity,
warehouseId: warehouseId,
logisticsCompany: $('#logisticsCompany').val(),
deliveryType: $('#deliveryType').val(),
deliveryTime: $('#deliveryTime').val(),
deliveryTimeType: $('#deliveryTimeType').val(),
outerCode: $('[name="outerCode"]').val(),
}
var config = {
url: deliveryPrefix + "/add",
type: "post",
dataType: "json",
contentType: "application/json",
data: JSON.stringify(data),
beforeSend: function () {
$.modal.loading("正在处理中,请稍候...");
$.modal.disable();
},
success: function (result) {
if (typeof callback == "function") {
callback(result);
}
refreshTable()
$.modal.closeLoading();
$.modal.enable();
}
};
$.ajax(config)
layer.close(index);
},
end: function () {
parent.$('.layui-layer-btn').css('display', '')
parent.$('.layui-layer-setwin').css('display', '')
// layer.msg('关闭后的回调', {icon:6});
}
});
layer.full(index);
}
function initDeliveryTable(data) {
var options = {
id: "delivery-table",
data: data || [[${deliveryList}]],
showSearch: false,
showRefresh: false,
showToggle: false,
showColumns: false,
pagination: false,
columns: [
{
field: 'id',
title: '',
visible: false
},
{
field: 'outerCode',
title: '出库单号'
},
{
field: 'logisticsCode',
title: '物流单号'
},
{
field: 'warehouseName',
title: '仓库'
},
{
field: 'projectCode',
title: '项目编号'
},
{
field: 'orderCode',
title: '合同编号'
},
{
field: 'projectName',
title: '项目名称'
},
{
field: 'deliveryTime',
title: '发货时间',
},
{
field: 'quantity',
title: '发货数量',
},
{
field: 'deliveryType',
title: '发货方式',
formatter: function (value, row, index) {
return $.table.selectDictLabel([[${@dict.getType('delivery_type')}]], value);
}
},
{
field: 'createByName',
title: '发货人',
},
{
title: '操作',
align: 'center',
formatter: function (value, row, index) {
var actions = [];
if (row.deliveryStatus === '0') {
actions.push('<span class="btn btn-danger btn-xs " style="margin:0px 5px" href="javascript:void(0)" onclick="deleteDelivery(' + row.id + ')">撤销</span>');
actions.push(`<span class="btn btn-default btn-xs " href="javascript:void(0)" onclick="updateStatus(' ${row.id} ','${row.outerCode}','${row.orderCode}')">确认发货</span>`);
} else {
actions.push(`<!--<a class="btn btn-default btn-xs " href="javascript:void(0)" data-delivery='${JSON.stringify(row)}' onclick='viewDelivery(this)'>查看详情</a>-->`);
actions.push(`<span class="btn btn-default btn-xs " href="javascript:void(0)" data-delivery='${JSON.stringify(row)}' onclick=' $.modal.popupRight( "发货信息详情", deliveryPrefix+"/view/${row.id}");'>查看详情</span>`);
}
return actions.join('');
}
}]
};
$.table.init(options);
}
function initModal() {
$.form.reset('generateDeliveryForm');
$('#deliveryTime').val(getNowDate());
$('#toolbar').css('display', '')
$('#generateDeliveryForm').find('input,select').each(function () {
$(this).attr('disabled', false)
})
}
function viewDelivery(that) {
let attr = $(that).attr("data-delivery");
let row = JSON.parse(attr)
let width = 1000, height = 700
parent.$('.layui-layer-btn').css('display', 'none')
parent.$('.layui-layer-setwin').css('display', 'none')
$('[name="warehouseId"]').val(row.warehouseId)
$('[name="inventoryStatus"]').val(1)
$('#query-product-sn [name="outerCode"]').val(row.outerCode)
$.table.search('query-product-sn', 'bootstrap-table')
$('#logisticsCode').val(row.logisticsCode)
$('#deliveryType').val(row.deliveryType)
$('#logisticsCompany').val(row.logisticsCompany)
$('#createByName').val(row.createByName)
$('#deliveryTimeType').val(row.deliveryTimeType)
$('#deliveryTime').val(row.deliveryTime)
$('#toolbar').css('display', 'none')
$('#generateDeliveryForm').find('input,select').each(function () {
$(this).attr('disabled', true)
})
$('#table-select-count').text(row.quantity);
let index = layer.open({
id: 'generate_delivery',
type: 1,
title: '生成发货单',
shade: 0.5, // 不显示遮罩
area: [width + 'px', height + 'px'],
content: $('#generateDelivery'), // 捕获的元素
btn: ['关闭'],
end: function () {
parent.$('.layui-layer-btn').css('display', '')
parent.$('.layui-layer-setwin').css('display', '')
// layer.msg('关闭后的回调', {icon:6});
}
});
layer.full(index);
}
function deleteDelivery(id) {
$.modal.confirm("确定撤销吗?", function () {
$.operate.post(deliveryPrefix + '/remove', {id: id}, res => {
refreshTable();
})
})
}
function updateStatus(id, outerCode, orderCode) {
$.operate.post(deliveryPrefix + '/status', {id: id, outerCode: outerCode, orderCode: orderCode}, res => {
refreshTable();
})
}
function refreshTable() {
let id = [[${inventoryOuter.id}]];
$.operate.get(prefix + '/queryInfo/' + id, res => {
if (res.code != 0) {
$.modal.msgError("刷新表格失败");
return
}
$("#product-table").bootstrapTable('load', res.data.productList);
$("#delivery-table").bootstrapTable('load', res.data.deliveryList);
if (res.data.deliveryList.length > 0){
parent.$('.layui-layer-btn0').css('display', 'none')
}else{
parent.$('.layui-layer-btn0').css('display', '')
}
})
}
</script>
</body>
</html>

View File

@ -0,0 +1,157 @@
<!DOCTYPE html>
<html lang="zh" xmlns:th="http://www.thymeleaf.org" xmlns:shiro="http://www.pollix.at/thymeleaf/shiro">
<head>
<th:block th:include="include :: header('出库单列表')"/>
</head>
<body class="gray-bg">
<div class="container-div">
<div class="row">
<div class="col-sm-12 search-collapse">
<form id="formId">
<div class="select-list">
<ul>
<li>
<label>出库单号:</label>
<input type="text" name="outerCode"/>
</li>
<li>
<label>发货状态:</label>
<select name="deliveryStatus" class="form-control" th:with="type=${@dict.getType('outer_delivery_status')}">
<option value="">请选择</option>
<option th:each="dict : ${type}" th:text="${dict.dictLabel}"
th:value="${dict.dictValue}"></option>
</select>
</li>
<li>
<a class="btn btn-primary btn-rounded btn-sm" onclick="$.table.search()"><i
class="fa fa-search"></i>&nbsp;搜索</a>
<a class="btn btn-warning btn-rounded btn-sm" onclick="$.form.reset()"><i
class="fa fa-refresh"></i>&nbsp;重置</a>
</li>
</ul>
</div>
</form>
</div>
<div class="btn-group-sm" id="toolbar" role="group">
<a class="btn btn-warning" onclick="$.table.exportExcel()" shiro:hasPermission="inventory:outer:export">
<i class="fa fa-download"></i> 导出
</a>
</div>
<div class="col-sm-12 select-table table-striped">
<table id="bootstrap-table"></table>
</div>
</div>
</div>
<th:block th:include="include :: footer"/>
<script th:inline="javascript">
var editFlag = [[${@permission.hasPermi('inventory:outer:edit')}]];
var removeFlag = [[${@permission.hasPermi('inventory:outer:remove')}]];
var prefix = ctx + "inventory/outer";
$(function () {
var options = {
url: prefix + "/list",
createUrl: prefix + "/add",
updateUrl: prefix + "/edit/{id}",
removeUrl: prefix + "/remove",
exportUrl: prefix + "/export",
modalName: "出库单",
columns: [{
title: '序号',
formatter: function (value, row, index) {
return $.table.serialNumber(index);
}
},
{
field: 'id',
title: '',
visible: false
},
{
field: 'outerCode',
title: '出库单号'
},
{
field: 'deliveryTime',
title: '要求发货时间',
formatter: function (value, row, index) {
let html = "(" + (row.deliveryTimeType == 0 ? '立即发货' : '自定义') + ")";
html += row.deliveryTime
return html;
}
},
{
field: 'projectCode',
title: '项目编号'
},
{
field: 'orderCode',
title: '合同编号'
},
{
field: 'projectName',
title: '项目名称'
},
{
field: 'productCode',
title: '产品编码'
},
{
field: 'model',
title: '产品型号'
},
{
field: 'quantity',
title: '应发货'
},
{
field: 'deliveryStatus',
title: '发货状态',
formatter: function (value, row, index) {
return $.table.selectDictLabel([[${@dict.getType('outer_delivery_status')}]], value);
}
},
{
field: 'createTime',
title: '生成时间'
},
{
title: '操作',
align: 'center',
formatter: function (value, row, index) {
var actions = [];
if (row.outerStatus === '3') {
//已接收
actions.push('<a class="btn btn-success btn-xs ' + editFlag + '" href="javascript:void(0)" onclick="$.operate.editFull(\'' + row.id + '\')"><i class="fa fa-edit"></i>编辑</a> ');
} else {
actions.push('<a class="btn btn-default btn-xs " href="javascript:void(0)" onclick="refundable(\'' + row.id + '\')">退回</a> ');
actions.push('<a class="btn btn-default btn-xs " href="javascript:void(0)" onclick="received(\'' + row.id + '\')">确认接收</a>');
}
return actions.join('');
}
}]
};
$.table.init(options);
});
function received(id) {
$.modal.confirm("确认要确认接收吗?", function () {
$.operate.post(prefix + "/status", {"id": id, "outerStatus": '3'},()=>{
$.table.search()
});
})
}
function refundable(id) {
$.modal.confirm("确认要确认退回吗?", function () {
$.operate.post(prefix + "/status", {"id": id, "outerStatus": '4'},()=>{
$.table.search()
});
})
}
</script>
</body>
</html>

View File

@ -3,6 +3,8 @@
<head>
<th:block th:include="include :: header('新增制造商信息')" />
</head>
<th:block th:include="include :: select2-css" />
<th:block th:include="include :: bootstrap-select-css" />
<body class="white-bg">
<div class="wrapper wrapper-content animated fadeInRight ibox-content">
<form class="form-horizontal m" id="form-vendor-add">
@ -58,6 +60,18 @@
</div>
</div>
</div>
<div class="col-xs-12">
<div class="form-group">
<label class="col-sm-2 control-label">拥有仓库:</label>
<div class="col-sm-10">
<select name="warehouseIdList" class="form-control noselect2 selectpicker" data-none-selected-text="请选择拥有仓库" multiple th:with="type=${warehouseList}">
<option th:each="dict : ${type}" th:text="${dict.warehouseName}"
th:value="${dict.id}" ></option>
</select>
</div>
</div>
</div>
<div class="col-xs-12">
<div class="form-group">
<label class="col-sm-2 control-label">生产地址:</label>
@ -69,6 +83,8 @@
</form>
</div>
<th:block th:include="include :: footer" />
<th:block th:include="include :: select2-js" />
<th:block th:include="include :: bootstrap-select-js" />
<script th:inline="javascript">
var prefix = ctx + "system/vendor"
$("#form-vendor-add").validate({

View File

@ -3,6 +3,8 @@
<head>
<th:block th:include="include :: header('修改制造商信息')" />
</head>
<th:block th:include="include :: select2-css" />
<th:block th:include="include :: bootstrap-select-css" />
<body class="white-bg">
<div class="wrapper wrapper-content animated fadeInRight ibox-content">
<form class="form-horizontal m" id="form-vendor-edit" th:object="${vendorInfo}">
@ -51,7 +53,7 @@
<div class="form-group">
<label class="col-sm-4 control-label is-required">合作状态:</label>
<div class="col-sm-8">
<select name="vendorStatus" class="form-control" th:with="type=${@dict.getType('vendor_status')}">
<select name="vendorStatus" class="form-control" th:with="type=${@dict.getType('vendor_status')}">
<option value="">请选择</option>
<option th:each="dict : ${type}" th:text="${dict.dictLabel}"
th:value="${dict.dictValue}" th:selected="${vendorInfo.vendorStatus == dict.dictValue}"></option>
@ -71,6 +73,18 @@
</div>
</div>
</div>
<div class="col-xs-12">
<div class="form-group">
<label class="col-sm-2 control-label">拥有仓库:</label>
<div class="col-sm-10">
<select name="warehouseIdList" class="form-control noselect2 selectpicker" data-none-selected-text="请选择拥有仓库" multiple th:with="type=${warehouseList}">
<option th:each="dict : ${type}" th:text="${dict.warehouseName}"
th:value="${dict.id}" th:field="*{warehouseIdList}"></option>
</select>
</div>
</div>
</div>
<div class="col-xs-12">
<div class="form-group">
<label class="col-sm-2 control-label">生产地址:</label>
@ -82,6 +96,8 @@
</form>
</div>
<th:block th:include="include :: footer" />
<th:block th:include="include :: select2-js" />
<th:block th:include="include :: bootstrap-select-js" />
<script th:inline="javascript">
var prefix = ctx + "system/vendor";
const updateFlag= [[${update}]];

View File

@ -13,6 +13,7 @@
<div class="row">
<div class="col-sm-12 search-collapse">
<form id="formId">
<input type="hidden" name="orderByColumn" value="vendorName">
<div class="select-list">
<ul>
<li>

View File

@ -0,0 +1,146 @@
package com.ruoyi.sip.controller;
import java.util.List;
import org.apache.shiro.authz.annotation.RequiresPermissions;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Controller;
import org.springframework.ui.ModelMap;
import org.springframework.web.bind.annotation.*;
import com.ruoyi.common.annotation.Log;
import com.ruoyi.common.enums.BusinessType;
import com.ruoyi.sip.domain.InventoryDelivery;
import com.ruoyi.sip.service.IInventoryDeliveryService;
import com.ruoyi.common.core.controller.BaseController;
import com.ruoyi.common.core.domain.AjaxResult;
import com.ruoyi.common.utils.poi.ExcelUtil;
import com.ruoyi.common.core.page.TableDataInfo;
/**
* Controller
*
* @author ruoyi
* @date 2025-08-12
*/
@Controller
@RequestMapping("/inventory/delivery")
public class InventoryDeliveryController extends BaseController
{
private String prefix = "inventory/delivery";
@Autowired
private IInventoryDeliveryService inventoryDeliveryService;
@RequiresPermissions("inventory:delivery:view")
@GetMapping()
public String delivery()
{
return prefix + "/delivery";
}
/**
*
*/
@RequiresPermissions("inventory:delivery:list")
@PostMapping("/list")
@ResponseBody
public TableDataInfo list(InventoryDelivery inventoryDelivery)
{
startPage();
inventoryDelivery.setDeliveryStatus(InventoryDelivery.DeliveryStatusEnum.CONFIRM_DELIVERY.getCode());
List<InventoryDelivery> list = inventoryDeliveryService.selectInventoryDeliveryList(inventoryDelivery);
return getDataTable(list);
}
/**
*
*/
@RequiresPermissions("inventory:delivery:export")
@Log(title = "发货记录", businessType = BusinessType.EXPORT)
@PostMapping("/export")
@ResponseBody
public AjaxResult export(InventoryDelivery inventoryDelivery)
{
List<InventoryDelivery> list = inventoryDeliveryService.selectInventoryDeliveryList(inventoryDelivery);
ExcelUtil<InventoryDelivery> util = new ExcelUtil<InventoryDelivery>(InventoryDelivery.class);
return util.exportExcel(list, "发货记录数据");
}
/**
*
*/
@RequiresPermissions("inventory:delivery:add")
@GetMapping("/add")
public String add()
{
return prefix + "/add";
}
/**
*
*/
@RequiresPermissions("inventory:delivery:add")
@Log(title = "发货记录", businessType = BusinessType.INSERT)
@PostMapping("/add")
@ResponseBody
public AjaxResult addSave(@RequestBody InventoryDelivery inventoryDelivery)
{
return toAjax(inventoryDeliveryService.insertInventoryDelivery(inventoryDelivery));
}
@PostMapping("/status")
@ResponseBody
public AjaxResult status(InventoryDelivery inventoryDelivery)
{
inventoryDeliveryService.statusUpdate(inventoryDelivery);
return AjaxResult.success();
}
/**
*
*/
@RequiresPermissions("inventory:delivery:edit")
@GetMapping("/edit/{id}")
public String edit(@PathVariable("id") Long id, ModelMap mmap)
{
InventoryDelivery inventoryDelivery = inventoryDeliveryService.selectInventoryDeliveryById(id);
mmap.put("inventoryDelivery", inventoryDelivery);
return prefix + "/edit";
}
@GetMapping("/view/{id}")
public String view(@PathVariable("id") Long id, ModelMap mmap)
{
InventoryDelivery inventoryDelivery = inventoryDeliveryService.selectInventoryDeliveryById(id);
mmap.put("inventoryDelivery", inventoryDelivery);
return prefix + "/view";
}
/**
*
*/
@RequiresPermissions("inventory:delivery:edit")
@Log(title = "发货记录", businessType = BusinessType.UPDATE)
@PostMapping("/edit")
@ResponseBody
public AjaxResult editSave(InventoryDelivery inventoryDelivery)
{
return toAjax(inventoryDeliveryService.updateInventoryDelivery(inventoryDelivery));
}
/**
*
*/
@RequiresPermissions("inventory:delivery:remove")
@Log(title = "发货记录", businessType = BusinessType.DELETE)
@PostMapping( "/removeAll")
@ResponseBody
public AjaxResult remove(String ids)
{
return toAjax(inventoryDeliveryService.deleteInventoryDeliveryByIds(ids));
}
@Log(title = "发货记录", businessType = BusinessType.DELETE)
@PostMapping( "/remove")
@ResponseBody
public AjaxResult remove(Long id)
{
return toAjax(inventoryDeliveryService.deleteInventoryOuterById(id));
}
}

View File

@ -22,7 +22,9 @@ import org.springframework.web.multipart.MultipartFile;
import java.io.IOException;
import java.util.Collections;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
/**
* Controller
@ -66,6 +68,32 @@ public class InventoryExecutionController extends BaseController {
return prefix + "/edit";
}
@GetMapping("/query/{id}")
@ResponseBody
public AjaxResult query(@PathVariable("id") Long id)
{
ExecutionOrderVo vo = service.selectInfo(id);
Map<String,Object> resultMap=new HashMap<>();
resultMap.put("projectOrderInfo", vo.getProjectOrderInfo());
resultMap.put("productDetailList", vo.getProductDetailList());
resultMap.put("inventoryOuterList", vo.getInventoryOuterList());
return AjaxResult.success(resultMap);
}
/**
*
* @param productCode
* @return com.ruoyi.common.core.domain.AjaxResult
* @author ch
* @date 2025/08/11 09:31
*/
@PostMapping("/checkOut/preview")
@ResponseBody
public AjaxResult checkOutPreview(@RequestParam("productCode") String productCode,@RequestParam("quantity") Integer quantity ){
return AjaxResult.success(service.checkOutPreview(productCode,quantity));
}

View File

@ -1,6 +1,14 @@
package com.ruoyi.sip.controller;
import java.util.Arrays;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import com.ruoyi.common.core.domain.entity.SysUser;
import com.ruoyi.sip.dto.inventory.InventoryInfoExcelDto;
import com.ruoyi.sip.vo.OuterDeliveryVo;
import liquibase.pro.packaged.A;
import org.apache.shiro.authz.annotation.RequiresPermissions;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Controller;
@ -50,6 +58,7 @@ public class InventoryOuterController extends BaseController
public TableDataInfo list(InventoryOuter inventoryOuter)
{
startPage();
inventoryOuter.setOuterStatusList(Arrays.asList(InventoryOuter.OuterStatusEnum.WAIT_RECEIVE.getCode(), InventoryOuter.OuterStatusEnum.RECEIVED.getCode()));
List<InventoryOuter> list = inventoryOuterService.selectInventoryOuterList(inventoryOuter);
return getDataTable(list);
}
@ -97,11 +106,38 @@ public class InventoryOuterController extends BaseController
@GetMapping("/edit/{id}")
public String edit(@PathVariable("id") Long id, ModelMap mmap)
{
InventoryOuter inventoryOuter = inventoryOuterService.selectInventoryOuterById(id);
mmap.put("inventoryOuter", inventoryOuter);
OuterDeliveryVo vo = inventoryOuterService.selectBaseInfoById(id);
mmap.put("inventoryOuter", vo.getInventoryOuter());
mmap.put("productList", vo.getProductVoList());
mmap.put("deliveryList", vo.getDeliveryList());
return prefix + "/edit";
}
@GetMapping("/queryInfo/{id}")
@ResponseBody
public AjaxResult queryInfo(@PathVariable("id") Long id)
{
Map<String,Object> result=new HashMap<>();
OuterDeliveryVo vo = inventoryOuterService.selectBaseInfoById(id);
result.put("inventoryOuter", vo.getInventoryOuter());
result.put("productList", vo.getProductVoList());
result.put("deliveryList", vo.getDeliveryList());
return AjaxResult.success(result);
}
@GetMapping("/query/{id}")
@ResponseBody
public AjaxResult query(@PathVariable("id") Long id)
{
return AjaxResult.success(inventoryOuterService.selectInventoryOuterById(id));
}
@GetMapping("/importTemplate")
@ResponseBody
public AjaxResult importTemplate()
{
ExcelUtil<InventoryInfoExcelDto> util = new ExcelUtil<InventoryInfoExcelDto>(InventoryInfoExcelDto.class);
return util.importTemplateExcel("发货数据");
}
/**
*
*/
@ -113,7 +149,26 @@ public class InventoryOuterController extends BaseController
{
return toAjax(inventoryOuterService.updateInventoryOuter(inventoryOuter));
}
@RequiresPermissions("inventory:outer:edit")
@Log(title = "出库单", businessType = BusinessType.UPDATE)
@PostMapping("/status")
@ResponseBody
public AjaxResult statusUpdate(InventoryOuter inventoryOuter)
{
return toAjax(inventoryOuterService.statusUpdate(inventoryOuter));
}
/**
*
*/
@RequiresPermissions("inventory:outer:remove")
@Log(title = "出库单", businessType = BusinessType.DELETE)
@PostMapping( "/removeAll")
@ResponseBody
public AjaxResult removeAll(String ids)
{
return toAjax(inventoryOuterService.deleteInventoryOuterByIds(ids));
}
/**
*
*/
@ -121,8 +176,8 @@ public class InventoryOuterController extends BaseController
@Log(title = "出库单", businessType = BusinessType.DELETE)
@PostMapping( "/remove")
@ResponseBody
public AjaxResult remove(String ids)
public AjaxResult remove(Long id)
{
return toAjax(inventoryOuterService.deleteInventoryOuterByIds(ids));
return toAjax(inventoryOuterService.deleteInventoryOuterById(id));
}
}

View File

@ -0,0 +1,128 @@
package com.ruoyi.sip.controller;
import java.util.List;
import org.apache.shiro.authz.annotation.RequiresPermissions;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Controller;
import org.springframework.ui.ModelMap;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.PathVariable;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.ResponseBody;
import com.ruoyi.common.annotation.Log;
import com.ruoyi.common.enums.BusinessType;
import com.ruoyi.sip.domain.InventoryOuterDetail;
import com.ruoyi.sip.service.IInventoryOuterDetailService;
import com.ruoyi.common.core.controller.BaseController;
import com.ruoyi.common.core.domain.AjaxResult;
import com.ruoyi.common.utils.poi.ExcelUtil;
import com.ruoyi.common.core.page.TableDataInfo;
/**
* Controller
*
* @author ruoyi
* @date 2025-08-11
*/
@Controller
@RequestMapping("/inventory/detail")
public class InventoryOuterDetailController extends BaseController
{
private String prefix = "inventory/detail";
@Autowired
private IInventoryOuterDetailService inventoryOuterDetailService;
@RequiresPermissions("inventory:detail:view")
@GetMapping()
public String detail()
{
return prefix + "/detail";
}
/**
*
*/
@RequiresPermissions("inventory:detail:list")
@PostMapping("/list")
@ResponseBody
public TableDataInfo list(InventoryOuterDetail inventoryOuterDetail)
{
startPage();
List<InventoryOuterDetail> list = inventoryOuterDetailService.selectInventoryOuterDetailList(inventoryOuterDetail);
return getDataTable(list);
}
/**
*
*/
@RequiresPermissions("inventory:detail:export")
@Log(title = "出库单详情", businessType = BusinessType.EXPORT)
@PostMapping("/export")
@ResponseBody
public AjaxResult export(InventoryOuterDetail inventoryOuterDetail)
{
List<InventoryOuterDetail> list = inventoryOuterDetailService.selectInventoryOuterDetailList(inventoryOuterDetail);
ExcelUtil<InventoryOuterDetail> util = new ExcelUtil<InventoryOuterDetail>(InventoryOuterDetail.class);
return util.exportExcel(list, "出库单详情数据");
}
/**
*
*/
@RequiresPermissions("inventory:detail:add")
@GetMapping("/add")
public String add()
{
return prefix + "/add";
}
/**
*
*/
@RequiresPermissions("inventory:detail:add")
@Log(title = "出库单详情", businessType = BusinessType.INSERT)
@PostMapping("/add")
@ResponseBody
public AjaxResult addSave(InventoryOuterDetail inventoryOuterDetail)
{
return toAjax(inventoryOuterDetailService.insertInventoryOuterDetail(inventoryOuterDetail));
}
/**
*
*/
@RequiresPermissions("inventory:detail:edit")
@GetMapping("/edit/{id}")
public String edit(@PathVariable("id") Long id, ModelMap mmap)
{
InventoryOuterDetail inventoryOuterDetail = inventoryOuterDetailService.selectInventoryOuterDetailById(id);
mmap.put("inventoryOuterDetail", inventoryOuterDetail);
return prefix + "/edit";
}
/**
*
*/
@RequiresPermissions("inventory:detail:edit")
@Log(title = "出库单详情", businessType = BusinessType.UPDATE)
@PostMapping("/edit")
@ResponseBody
public AjaxResult editSave(InventoryOuterDetail inventoryOuterDetail)
{
return toAjax(inventoryOuterDetailService.updateInventoryOuterDetail(inventoryOuterDetail));
}
/**
*
*/
@RequiresPermissions("inventory:detail:remove")
@Log(title = "出库单详情", businessType = BusinessType.DELETE)
@PostMapping( "/remove")
@ResponseBody
public AjaxResult remove(String ids)
{
return toAjax(inventoryOuterDetailService.deleteInventoryOuterDetailByIds(ids));
}
}

View File

@ -0,0 +1,99 @@
package com.ruoyi.sip.domain;
import java.util.Date;
import java.util.List;
import com.fasterxml.jackson.annotation.JsonFormat;
import lombok.Data;
import lombok.Getter;
import lombok.ToString;
import org.apache.commons.lang3.builder.ToStringBuilder;
import org.apache.commons.lang3.builder.ToStringStyle;
import com.ruoyi.common.annotation.Excel;
import com.ruoyi.common.core.domain.BaseEntity;
/**
* oms_inventory_delivery
*
* @author ruoyi
* @date 2025-08-12
*/
@Data
@ToString
public class InventoryDelivery extends BaseEntity
{
private static final long serialVersionUID = 1L;
/** */
private Long id;
/** 出库单号 */
@Excel(name = "出库单号")
private String outerCode;
/** 所属仓库 */
private Long warehouseId;
private String warehouseName;
/** 物流公司 */
private String logisticsCompany;
/** 物流单号 */
@Excel(name = "物流单号")
private String logisticsCode;
@Excel(name = "项目编号")
private String projectCode;
@Excel(name = "合同编号")
private String orderCode;
@Excel(name = "项目名称")
private String projectName;
@Excel(name = "产品编码")
private String productCode;
@Excel(name = "产品型号")
private String model;
@Excel(name = "发货数量")
private Long quantity;
/** 发货方式1-快递2-物流3-自提 */
@Excel(name = "发货方式",dictType = "delivery_type")
private String deliveryType;
/** 发货时间类型 0 立即发货 1自定义 */
// @Excel(name = "发货时间类型")
private String deliveryTimeType;
/** 发货时间 */
@JsonFormat(pattern = "yyyy-MM-dd", timezone = "GMT+8")
@Excel(name = "发货时间", width = 30, dateFormat = "yyyy-MM-dd")
private Date deliveryTime;
private String deliveryStatus;
private List<String> productSnList;
private String createByName;
@Getter
public enum DeliveryStatusEnum {
WAIT_DELIVERY("0","待发货"),
CONFIRM_DELIVERY("1","已发货"),
;
private final String code;
private final String desc;
DeliveryStatusEnum(String code,String desc) {
this.code = code;
this.desc = desc;
}
}
}

View File

@ -4,7 +4,9 @@ import java.util.Date;
import java.util.List;
import com.fasterxml.jackson.annotation.JsonFormat;
import com.ruoyi.sip.dto.inventory.ProductWarehouseInfo;
import lombok.Data;
import lombok.Getter;
import lombok.ToString;
import org.apache.commons.lang3.builder.ToStringBuilder;
import org.apache.commons.lang3.builder.ToStringStyle;
@ -29,43 +31,94 @@ public class InventoryOuter extends BaseEntity
/** 出库单号 */
@Excel(name = "出库单号")
private String outerCode;
/** 产品BOM编码 */
@Excel(name = "产品BOM编码")
private String productCode;
private List<String> productCodeList;
/** 数量 */
@Excel(name = "数量")
private Long quantity;
/** 出库状态 */
@Excel(name = "出库状态")
private String outerStatus;
/** 订单编码 */
@Excel(name = "订单编码")
private String orderCode;
/** 联系人 */
@Excel(name = "联系人")
private String contactPerson;
/** 联系电话 */
@Excel(name = "联系电话")
private String contactPhone;
/** 联系地址 */
@Excel(name = "联系地址")
private String contactAddress;
/** 发货时间 */
@JsonFormat(pattern = "yyyy-MM-dd", timezone = "GMT+8")
@Excel(name = "发货时间", width = 30, dateFormat = "yyyy-MM-dd")
private Date deliveryTime;
@Excel(name = "项目编号")
private String projectCode;
/** 订单编码 */
@Excel(name = "合同编号")
private String orderCode;
@Excel(name = "项目名称")
private String projectName;
/** 产品BOM编码 */
@Excel(name = "产品编码")
private String productCode;
@Excel(name = "产品型号")
private String model;
private String vendorName;
private List<String> productCodeList;
/** 数量 */
@Excel(name = "应发货")
private Long quantity;
/** 出库状态 */
// @Excel(name = "出库状态")
private String outerStatus;
private List<String> outerStatusList;
@Excel(name = "发货状态",dictType = "outer_delivery_status")
private String deliveryStatus;
/** 联系人 */
// @Excel(name = "联系人")
private String contactPerson;
/** 联系电话 */
// @Excel(name = "联系电话")
private String contactPhone;
/** 联系地址 */
// @Excel(name = "联系地址")
private String contactAddress;
@JsonFormat(pattern = "yyyy-MM-dd", timezone = "GMT+8")
@Excel(name = "生成时间", width = 30, dateFormat = "yyyy-MM-dd")
private Date createTime;
/** 发货时间选择(0:立即发货 1:自定义) */
@Excel(name = "发货时间选择(0:立即发货 1:自定义)")
// @Excel(name = "发货时间选择(0:立即发货 1:自定义)")
private String deliveryTimeType;
private List<InventoryOuterDetail> detailList;
private List<ProductWarehouseInfo> warehouseInfoList;
@Getter
public enum OuterStatusEnum {
/** 待确认 */
WAIT_CONFIRM("1", "待确认"),
/** 已确认 */
WAIT_RECEIVE("2", "已确认"),
RECEIVED("3", "已接收"),
RETURN("4", "已退回"),
;
private final String code;
private final String desc;
OuterStatusEnum(String code, String desc) {
this.code = code;
this.desc = desc;
}
}
@Getter
public enum DeliveryStatusEnum {
/** 待确认 */
WAIT_DELIVERY("0", "未发货"),
/** 已确认 */
PART_DELIVERY("1", "部分发货"),
ALL_DELIVERY("2", "全部发货"),
;
private final String code;
private final String desc;
DeliveryStatusEnum(String code, String desc) {
this.code = code;
this.desc = desc;
}
}
}

View File

@ -0,0 +1,45 @@
package com.ruoyi.sip.domain;
import lombok.Data;
import lombok.ToString;
import org.apache.commons.lang3.builder.ToStringBuilder;
import org.apache.commons.lang3.builder.ToStringStyle;
import com.ruoyi.common.annotation.Excel;
import com.ruoyi.common.core.domain.BaseEntity;
/**
* oms_inventory_outer_detail
*
* @author ruoyi
* @date 2025-08-11
*/
@Data
@ToString
public class InventoryOuterDetail extends BaseEntity
{
private static final long serialVersionUID = 1L;
/** */
private Long id;
/** 出库单号 */
@Excel(name = "出库单号")
private String outerCode;
/** 仓库id */
@Excel(name = "仓库id")
private Long warehouseId;
private String warehouseName;
/** 数量 */
@Excel(name = "数量")
private Long quantity;
/** 出库状态 */
@Excel(name = "出库状态")
private String outerStatus;
private Long availableCount;
private String productCode;
private String model;
}

View File

@ -1,11 +1,19 @@
package com.ruoyi.sip.domain;
import cn.hutool.core.collection.CollUtil;
import com.ruoyi.common.utils.StringUtils;
import liquibase.util.CollectionUtil;
import lombok.AccessLevel;
import lombok.Data;
import lombok.Getter;
import com.ruoyi.common.annotation.Excel;
import com.ruoyi.common.core.domain.BaseEntity;
import lombok.Setter;
import java.util.Arrays;
import java.util.Collections;
import java.util.List;
import java.util.stream.Collectors;
/**
* varchar_info
@ -52,6 +60,26 @@ public class VendorInfo extends BaseEntity
private String vendorStatusName;
private String warehouseName;
private String warehouseId;
private String ownWarehouseId;
@Getter(AccessLevel.NONE)
@Setter(AccessLevel.NONE)
private List<String> warehouseIdList;
public void setWarehouseIdList(List<String> warehouseIdList) {
if (CollUtil.isEmpty(warehouseIdList)) {
return;
}
this.ownWarehouseId = String.join(",", warehouseIdList);
}
public List<String> getWarehouseIdList() {
if (StringUtils.isEmpty(ownWarehouseId)) {
return Collections.emptyList();
}
return Arrays.stream(ownWarehouseId.split(",")).collect(Collectors.toList());
}
@Getter
public enum VendorStatusEnum {

View File

@ -0,0 +1,36 @@
package com.ruoyi.sip.dto.inventory;
import com.ruoyi.common.annotation.Excel;
import lombok.Data;
import java.math.BigDecimal;
/**
* @author : ch
* @version : 1.0
* @ClassName : InventoryInfoExcelDto
* @Description :
* @DATE : Created in 15:19 2025/8/12
* <pre> Copyright: Copyright(c) 2025 </pre>
* <pre> Company : </pre>
* Modification History:
* Date Author Version Discription
* --------------------------------------------------------------------------
* 2025/08/12 ch 1.0 Why & What is modified: <> *
*/
@Data
public class InventoryInfoExcelDto {
@Excel(name = "SN码")
private String productSn;
@Excel(name = "产品编码")
private String productCode;
@Excel(name = "产品型号")
private String model;
@Excel(name = "描述")
private String productDesc;
@Excel(name = "仓库")
private String warehouseName;
@Excel(name = "入库价")
private BigDecimal innerPrice;
}

View File

@ -0,0 +1,26 @@
package com.ruoyi.sip.dto.inventory;
import lombok.Data;
/**
* @author : ch
* @version : 1.0
* @ClassName : ProductWarehouseInfo
* @Description :
* @DATE : Created in 9:33 2025/8/11
* <pre> Copyright: Copyright(c) 2025 </pre>
* <pre> Company : </pre>
* Modification History:
* Date Author Version Discription
* --------------------------------------------------------------------------
* 2025/08/11 ch 1.0 Why & What is modified: <> *
*/
@Data
public class ProductWarehouseInfo {
private String warehouseName;
private String warehouseId;
private Boolean defaultWarehouse;
private Long availableCount;
private Long confirmQuantity;
}

View File

@ -0,0 +1,66 @@
package com.ruoyi.sip.mapper;
import java.util.List;
import com.ruoyi.sip.domain.InventoryDelivery;
import org.apache.ibatis.annotations.Param;
import org.apache.ibatis.annotations.Select;
/**
* Mapper
*
* @author ruoyi
* @date 2025-08-12
*/
public interface InventoryDeliveryMapper
{
/**
*
*
* @param id
* @return
*/
public InventoryDelivery selectInventoryDeliveryById(Long id);
/**
*
*
* @param inventoryDelivery
* @return
*/
public List<InventoryDelivery> selectInventoryDeliveryList(InventoryDelivery inventoryDelivery);
/**
*
*
* @param inventoryDelivery
* @return
*/
public int insertInventoryDelivery(InventoryDelivery inventoryDelivery);
/**
*
*
* @param inventoryDelivery
* @return
*/
public int updateInventoryDelivery(InventoryDelivery inventoryDelivery);
/**
*
*
* @param id
* @return
*/
public int deleteInventoryDeliveryById(Long id);
/**
*
*
* @param ids
* @return
*/
public int deleteInventoryDeliveryByIds(String[] ids);
List<InventoryDelivery> selectQuantityByOrderCodeStatus(@Param("orderCode") String orderCode, @Param("status") String code);
}

View File

@ -2,6 +2,7 @@ package com.ruoyi.sip.mapper;
import java.util.List;
import com.ruoyi.sip.domain.InventoryInfo;
import com.ruoyi.sip.dto.inventory.ProductWarehouseInfo;
import org.apache.ibatis.annotations.Param;
/**
@ -61,4 +62,8 @@ public interface InventoryInfoMapper
public int deleteInventoryInfoByIds(String[] ids);
void saveBatch(List<InventoryInfo> inventoryInfoList);
List<ProductWarehouseInfo> checkOurPreview(List<String> productCodeList);
void clearOutInfo(List<Long> idList);
}

View File

@ -0,0 +1,67 @@
package com.ruoyi.sip.mapper;
import java.util.List;
import com.ruoyi.sip.domain.InventoryOuterDetail;
/**
* Mapper
*
* @author ruoyi
* @date 2025-08-11
*/
public interface InventoryOuterDetailMapper
{
/**
*
*
* @param id
* @return
*/
public InventoryOuterDetail selectInventoryOuterDetailById(Long id);
/**
*
*
* @param inventoryOuterDetail
* @return
*/
public List<InventoryOuterDetail> selectInventoryOuterDetailList(InventoryOuterDetail inventoryOuterDetail);
/**
*
*
* @param inventoryOuterDetail
* @return
*/
public int insertInventoryOuterDetail(InventoryOuterDetail inventoryOuterDetail);
/**
*
*
* @param inventoryOuterDetail
* @return
*/
public int updateInventoryOuterDetail(InventoryOuterDetail inventoryOuterDetail);
/**
*
*
* @param id
* @return
*/
public int deleteInventoryOuterDetailById(Long id);
/**
*
*
* @param ids
* @return
*/
public int deleteInventoryOuterDetailByIds(String[] ids);
void save(List<InventoryOuterDetail> detailList);
void deleteByOuterCode(List<String> outerCode);
}

View File

@ -18,6 +18,7 @@ public interface InventoryOuterMapper
* @return
*/
public InventoryOuter selectInventoryOuterById(Long id);
public InventoryOuter selectInventoryOuterByCode(String code);
/**
*
@ -58,4 +59,8 @@ public interface InventoryOuterMapper
* @return
*/
public int deleteInventoryOuterByIds(String[] ids);
int selectMaxOrderCode(String string);
int countByOrderCode(String orderCode);
}

View File

@ -1,7 +1,9 @@
package com.ruoyi.sip.mapper;
import java.util.Collection;
import java.util.List;
import com.ruoyi.sip.domain.OmsWarehouseInfo;
import org.apache.ibatis.annotations.Param;
/**
* Mapper
@ -60,4 +62,6 @@ public interface OmsWarehouseInfoMapper
public int deleteOmsWarehouseInfoByIds(String[] ids);
List<OmsWarehouseInfo> listByNameList(List<String> warehouseNameList);
List<OmsWarehouseInfo> listByIds(@Param("list") Collection<String> warehouseSet);
}

View File

@ -60,6 +60,7 @@ public interface ProjectProductInfoMapper
public int deleteProjectProductInfoByIds(String[] ids);
List<ProjectProductInfo> selectProjectProductInfoListByProjectId(List<Long> projectId);
List<ProjectProductInfo> selectProjectProductInfoListByOrderCode(List<String> orderCode);
void saveBatch(List<ProjectProductInfo> addList);

View File

@ -1,16 +1,10 @@
package com.ruoyi.sip.service;
import com.ruoyi.sip.domain.ProjectOrderInfo;
import com.ruoyi.sip.domain.ProjectProductInfo;
import com.ruoyi.sip.mapper.ProjectOrderInfoMapper;
import com.ruoyi.sip.dto.inventory.ProductWarehouseInfo;
import com.ruoyi.sip.vo.ExecutionOrderVo;
import org.springframework.beans.factory.annotation.Autowired;
import javax.annotation.Resource;
import java.util.Collections;
import java.util.List;
import java.util.stream.Collectors;
/**
* @author : ch
@ -28,4 +22,6 @@ import java.util.stream.Collectors;
public interface IExecutionTrackService {
ExecutionOrderVo selectInfo(Long id);
List<ProductWarehouseInfo> checkOutPreview(String productCode, Integer quantity);
}

View File

@ -0,0 +1,65 @@
package com.ruoyi.sip.service;
import java.util.List;
import com.ruoyi.sip.domain.InventoryDelivery;
/**
* Service
*
* @author ruoyi
* @date 2025-08-12
*/
public interface IInventoryDeliveryService
{
/**
*
*
* @param id
* @return
*/
public InventoryDelivery selectInventoryDeliveryById(Long id);
/**
*
*
* @param inventoryDelivery
* @return
*/
public List<InventoryDelivery> selectInventoryDeliveryList(InventoryDelivery inventoryDelivery);
/**
*
*
* @param inventoryDelivery
* @return
*/
public int insertInventoryDelivery(InventoryDelivery inventoryDelivery);
/**
*
*
* @param inventoryDelivery
* @return
*/
public int updateInventoryDelivery(InventoryDelivery inventoryDelivery);
/**
*
*
* @param ids
* @return
*/
public int deleteInventoryDeliveryByIds(String ids);
/**
*
*
* @param id
* @return
*/
public int deleteInventoryDeliveryById(Long id);
void statusUpdate(InventoryDelivery inventoryDelivery);
int deleteInventoryOuterById(Long id);
}

View File

@ -2,6 +2,7 @@ package com.ruoyi.sip.service;
import java.util.List;
import com.ruoyi.sip.domain.InventoryInfo;
import com.ruoyi.sip.dto.inventory.ProductWarehouseInfo;
import com.ruoyi.sip.dto.warehouse.WarehouseInnerExcelDto;
/**
@ -72,4 +73,7 @@ public interface IInventoryInfoService
void saveBatch(List<InventoryInfo> inventoryInfoList);
List<ProductWarehouseInfo> checkOurPreview(List<String> productCode);
void clearOutInfo(List<Long> collect);
}

View File

@ -0,0 +1,67 @@
package com.ruoyi.sip.service;
import java.util.List;
import com.ruoyi.sip.domain.InventoryOuterDetail;
/**
* Service
*
* @author ruoyi
* @date 2025-08-11
*/
public interface IInventoryOuterDetailService
{
/**
*
*
* @param id
* @return
*/
public InventoryOuterDetail selectInventoryOuterDetailById(Long id);
/**
*
*
* @param inventoryOuterDetail
* @return
*/
public List<InventoryOuterDetail> selectInventoryOuterDetailList(InventoryOuterDetail inventoryOuterDetail);
/**
*
*
* @param inventoryOuterDetail
* @return
*/
public int insertInventoryOuterDetail(InventoryOuterDetail inventoryOuterDetail);
/**
*
*
* @param inventoryOuterDetail
* @return
*/
public int updateInventoryOuterDetail(InventoryOuterDetail inventoryOuterDetail);
/**
*
*
* @param ids
* @return
*/
public int deleteInventoryOuterDetailByIds(String ids);
/**
*
*
* @param id
* @return
*/
public int deleteInventoryOuterDetailById(Long id);
void save(List<InventoryOuterDetail> detailList);
void deleteByOuterCode(List<String> outerCode);
}

View File

@ -2,6 +2,7 @@ package com.ruoyi.sip.service;
import java.util.List;
import com.ruoyi.sip.domain.InventoryOuter;
import com.ruoyi.sip.vo.OuterDeliveryVo;
/**
* Service
@ -58,4 +59,8 @@ public interface IInventoryOuterService
* @return
*/
public int deleteInventoryOuterById(Long id);
int statusUpdate(InventoryOuter inventoryOuter);
OuterDeliveryVo selectBaseInfoById(Long id);
}

View File

@ -1,6 +1,10 @@
package com.ruoyi.sip.service;
import java.util.Collection;
import java.util.Collections;
import java.util.List;
import java.util.Set;
import com.ruoyi.sip.domain.OmsWarehouseInfo;
/**
@ -65,4 +69,6 @@ public interface IOmsWarehouseInfoService
* @return
*/
List<OmsWarehouseInfo> listByNameList(List<String> warehouseNameList);
List<OmsWarehouseInfo> listByIds(Collection<String> warehouseSet);
}

View File

@ -47,6 +47,7 @@ public interface IProjectOrderInfoService
* @return
*/
public int updateProjectOrderInfo(ProjectOrderInfo projectOrderInfo);
public int updateProjectOrderInfoByCode(ProjectOrderInfo projectOrderInfo);
/**
*

View File

@ -63,8 +63,11 @@ public interface IProjectProductInfoService
public int deleteProjectProductInfoById(Long id);
List<ProjectProductInfo> selectProjectProductInfoListByProjectId(List<Long> projectId);
List<ProjectProductInfo> selectProjectProductInfoListByOrderCode(List<String> orderCode);
List<ProjectProductInfo> listDeliveryProductByOrderCode(List<String> orderCode);
void saveBatch(List<ProjectProductInfo> addList);
void calcByDiscountFold(BigDecimal discountFold, Long projectId);
// int count(BigDecimal discountFold, Long projectId);
}

View File

@ -1,11 +1,10 @@
package com.ruoyi.sip.service.impl;
import com.ruoyi.sip.domain.InventoryOuter;
import com.ruoyi.sip.domain.ProductInfo;
import com.ruoyi.sip.domain.ProjectOrderInfo;
import com.ruoyi.sip.domain.ProjectProductInfo;
import cn.hutool.core.collection.CollUtil;
import com.ruoyi.sip.domain.*;
import com.ruoyi.sip.dto.inventory.ProductDetail;
import com.ruoyi.sip.dto.inventory.ProductWarehouseInfo;
import com.ruoyi.sip.mapper.ProjectOrderInfoMapper;
import com.ruoyi.sip.service.*;
import com.ruoyi.sip.vo.ExecutionOrderVo;
@ -14,6 +13,7 @@ import org.springframework.stereotype.Service;
import javax.annotation.Resource;
import java.util.Collections;
import java.util.Comparator;
import java.util.List;
import java.util.Map;
import java.util.function.Function;
@ -44,6 +44,8 @@ public class ExecutionTrackServiceImpl implements IExecutionTrackService {
private IProductInfoService productInfoService;
@Autowired
private IInventoryOuterService outerService;
@Autowired
private IVendorInfoService vendorInfoService;
@Override
public ExecutionOrderVo selectInfo(Long id) {
@ -107,7 +109,7 @@ public class ExecutionTrackServiceImpl implements IExecutionTrackService {
// 查询出库单信息
InventoryOuter inventoryOuter = new InventoryOuter();
inventoryOuter.setOuterCode(projectOrderInfo.getOrderCode());
inventoryOuter.setOrderCode(projectOrderInfo.getOrderCode());
List<InventoryOuter> inventoryOuters = outerService.selectInventoryOuterList(inventoryOuter);
vo.setInventoryOuterList(inventoryOuters);
// 根据出库单状态设置generatedQuantity和confirmQuantity
@ -120,13 +122,15 @@ public class ExecutionTrackServiceImpl implements IExecutionTrackService {
if (outers != null) {
// generatedQuantity: 状态为"已生成"(假设为"1")的出库单数量总和
Long generated = outers.stream()
.filter(outer -> "1".equals(outer.getOuterStatus()))
.filter(outer -> !InventoryOuter.OuterStatusEnum.WAIT_RECEIVE.getCode().equals(outer.getOuterStatus())
&& !InventoryOuter.OuterStatusEnum.RECEIVED.getCode().equals(outer.getOuterStatus()))
.mapToLong(InventoryOuter::getQuantity)
.sum();
// confirmQuantity: 状态为"已确认"(假设为"2")的出库单数量总和
Long confirmed = outers.stream()
.filter(outer -> "2".equals(outer.getOuterStatus()))
.filter(outer -> InventoryOuter.OuterStatusEnum.WAIT_RECEIVE.getCode().equals(outer.getOuterStatus())
||InventoryOuter.OuterStatusEnum.RECEIVED.getCode().equals(outer.getOuterStatus()))
.mapToLong(InventoryOuter::getQuantity)
.sum();
@ -146,4 +150,68 @@ public class ExecutionTrackServiceImpl implements IExecutionTrackService {
vo.setProductDetailList(productDetails);
return vo;
}
@Override
public List<ProductWarehouseInfo> checkOutPreview(String productCode, Integer quantity) {
List<ProductWarehouseInfo> productWarehouseInfoList = inventoryInfoService.checkOurPreview(Collections.singletonList(productCode));
productWarehouseInfoList.sort(Comparator.comparing(ProductWarehouseInfo::getAvailableCount));
int remainingQuantity = quantity;
// 遍历仓库分配库存
for (ProductWarehouseInfo productWarehouseInfo : productWarehouseInfoList) {
if (remainingQuantity <= 0) {
productWarehouseInfo.setConfirmQuantity(0L);
continue;
}
Long availableCount = productWarehouseInfo.getAvailableCount();
if (availableCount >= remainingQuantity) {
// 当前仓库可以满足剩余需求
productWarehouseInfo.setConfirmQuantity(Long.valueOf(remainingQuantity));
remainingQuantity = 0;
} else {
// 当前仓库部分满足需求
productWarehouseInfo.setConfirmQuantity(availableCount);
remainingQuantity -= availableCount.intValue();
}
productWarehouseInfo.setDefaultWarehouse(false);
}
// 如果仍有未满足的需求,尝试使用默认仓库
if (remainingQuantity > 0) {
List<VendorInfo> currentVendors = vendorInfoService.current();
if (CollUtil.isNotEmpty(currentVendors)) {
VendorInfo defaultVendor = currentVendors.get(0);
// 检查默认仓库是否已经在列表中
boolean defaultVendorInList = productWarehouseInfoList.stream()
.anyMatch(info -> defaultVendor.getWarehouseId().equals(info.getWarehouseId()));
if (!defaultVendorInList) {
// 如果默认仓库不在现有列表中,创建一个新的条目
ProductWarehouseInfo defaultWarehouseInfo = new ProductWarehouseInfo();
defaultWarehouseInfo.setWarehouseId(defaultVendor.getWarehouseId());
defaultWarehouseInfo.setWarehouseName(defaultVendor.getVendorName());
// 这里假设默认仓库有足够库存,实际应用中可能需要查询具体库存
List<ProductInfo> productInfos = productInfoService.selectProductInfoByCodeList(Collections.singletonList(productCode));
defaultWarehouseInfo.setAvailableCount(productInfos.get(0).getAvailableCount() == null ? 0L : productInfos.get(0).getAvailableCount());
defaultWarehouseInfo.setConfirmQuantity((long) remainingQuantity);
defaultWarehouseInfo.setDefaultWarehouse(true);
productWarehouseInfoList.add(defaultWarehouseInfo);
} else {
// 如果默认仓库已在列表中,增加其分配数量
int finalRemainingQuantity = remainingQuantity;
productWarehouseInfoList.stream()
.filter(info -> defaultVendor.getWarehouseId().equals(info.getWarehouseId()))
.findFirst()
.ifPresent(info -> {
Long currentConfirmQuantity = info.getConfirmQuantity() != null ? info.getConfirmQuantity() : 0L;
info.setConfirmQuantity(currentConfirmQuantity + finalRemainingQuantity);
info.setDefaultWarehouse(true);
});
}
}
}
return productWarehouseInfoList;
}
}

View File

@ -0,0 +1,180 @@
package com.ruoyi.sip.service.impl;
import java.util.Collection;
import java.util.Collections;
import java.util.Date;
import java.util.List;
import java.util.stream.Collectors;
import cn.hutool.core.collection.CollUtil;
import com.ruoyi.common.exception.ServiceException;
import com.ruoyi.common.utils.DateUtils;
import com.ruoyi.common.utils.ShiroUtils;
import com.ruoyi.sip.domain.*;
import com.ruoyi.sip.mapper.InventoryOuterMapper;
import com.ruoyi.sip.service.*;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import com.ruoyi.sip.mapper.InventoryDeliveryMapper;
import com.ruoyi.common.core.text.Convert;
import org.springframework.transaction.annotation.Transactional;
import javax.annotation.Resource;
/**
* Service
*
* @author ruoyi
* @date 2025-08-12
*/
@Service
@Transactional(rollbackFor = Exception.class)
public class InventoryDeliveryServiceImpl implements IInventoryDeliveryService {
@Autowired
private InventoryDeliveryMapper inventoryDeliveryMapper;
@Autowired
private IInventoryInfoService inventoryInfoService;
@Resource
private InventoryOuterMapper inventoryOuterMapper;
@Autowired
private IProjectProductInfoService projectProductInfoService;
@Autowired
private IProjectOrderInfoService projectOrderInfoService;
/**
*
*
* @param id
* @return
*/
@Override
public InventoryDelivery selectInventoryDeliveryById(Long id) {
return inventoryDeliveryMapper.selectInventoryDeliveryById(id);
}
/**
*
*
* @param inventoryDelivery
* @return
*/
@Override
public List<InventoryDelivery> selectInventoryDeliveryList(InventoryDelivery inventoryDelivery) {
return inventoryDeliveryMapper.selectInventoryDeliveryList(inventoryDelivery);
}
/**
*
*
* @param inventoryDelivery
* @return
*/
@Override
public int insertInventoryDelivery(InventoryDelivery inventoryDelivery) {
inventoryDelivery.setCreateTime(DateUtils.getNowDate());
String currentUserId = ShiroUtils.getUserId().toString();
inventoryDelivery.setCreateBy(currentUserId);
inventoryDelivery.setDeliveryStatus(InventoryDelivery.DeliveryStatusEnum.WAIT_DELIVERY.getCode());
//处理库存
List<String> productSnList = inventoryDelivery.getProductSnList();
if (CollUtil.isEmpty(productSnList)) {
throw new ServiceException("发货清单为空,保存失败");
}
List<InventoryInfo> inventoryInfoList = productSnList.stream().map(item -> {
InventoryInfo info = new InventoryInfo();
info.setProductSn(item);
info.setOuterCode(inventoryDelivery.getOuterCode());
info.setInventoryStatus(InventoryInfo.InventoryStatusEnum.OUTER.getCode());
info.setUpdateBy(currentUserId);
return info;
}).collect(Collectors.toList());
inventoryInfoService.saveBatch(inventoryInfoList);
return inventoryDeliveryMapper.insertInventoryDelivery(inventoryDelivery);
}
/**
*
*
* @param inventoryDelivery
* @return
*/
@Override
public int updateInventoryDelivery(InventoryDelivery inventoryDelivery) {
inventoryDelivery.setUpdateTime(DateUtils.getNowDate());
inventoryDelivery.setUpdateBy(ShiroUtils.getUserId().toString());
return inventoryDeliveryMapper.updateInventoryDelivery(inventoryDelivery);
}
/**
*
*
* @param ids
* @return
*/
@Override
public int deleteInventoryDeliveryByIds(String ids) {
return inventoryDeliveryMapper.deleteInventoryDeliveryByIds(Convert.toStrArray(ids));
}
/**
*
*
* @param id
* @return
*/
@Override
public int deleteInventoryDeliveryById(Long id) {
return inventoryDeliveryMapper.deleteInventoryDeliveryById(id);
}
@Override
public void statusUpdate(InventoryDelivery inventoryDelivery) {
//修改发货状态
inventoryDelivery.setDeliveryStatus(InventoryDelivery.DeliveryStatusEnum.CONFIRM_DELIVERY.getCode());
inventoryDeliveryMapper.updateInventoryDelivery(inventoryDelivery);
List<ProjectProductInfo> projectProductInfos = projectProductInfoService.listDeliveryProductByOrderCode(Collections.singletonList(inventoryDelivery.getOrderCode()));
//软硬件之和
long sum = projectProductInfos.stream().mapToLong(ProjectProductInfo::getQuantity).sum();
//已确认发货数量
List<InventoryDelivery> deliveryList = inventoryDeliveryMapper.selectQuantityByOrderCodeStatus(inventoryDelivery.getOrderCode(), InventoryDelivery.DeliveryStatusEnum.CONFIRM_DELIVERY.getCode());
long outerSum = deliveryList.stream().filter(item -> item.getOuterCode().equals(inventoryDelivery.getOuterCode())).mapToLong(InventoryDelivery::getQuantity).sum();
//修改出库单的发货状态
InventoryOuter updateDto = new InventoryOuter();
updateDto.setOuterCode(inventoryDelivery.getOuterCode());
InventoryOuter inventoryOuter = inventoryOuterMapper.selectInventoryOuterByCode(inventoryDelivery.getOuterCode());
if (outerSum == 0) {
updateDto.setDeliveryStatus(InventoryOuter.DeliveryStatusEnum.WAIT_DELIVERY.getCode());
} else {
updateDto.setDeliveryStatus(inventoryOuter.getQuantity().compareTo(outerSum) == 0 ? InventoryOuter.DeliveryStatusEnum.ALL_DELIVERY.getCode() : InventoryOuter.DeliveryStatusEnum.PART_DELIVERY.getCode());
}
updateDto.setId(inventoryOuter.getId());
//状态变化才更新
if (!updateDto.getDeliveryStatus().equals(inventoryOuter.getDeliveryStatus())) {
inventoryOuterMapper.updateInventoryOuter(updateDto);
}
long allSum = deliveryList.stream().mapToLong(InventoryDelivery::getQuantity).sum();
//修改订单的发货状态
ProjectOrderInfo updateOrder = new ProjectOrderInfo();
updateOrder.setOrderCode(inventoryDelivery.getOrderCode());
updateOrder.setUpdateTime(new Date());
updateOrder.setUpdateBy(ShiroUtils.getUserId().toString());
updateOrder.setDeliveryStatus(sum == allSum ? ProjectOrderInfo.DeliveryStatusEnum.ALL_DELIVERY.getCode() : ProjectOrderInfo.DeliveryStatusEnum.PART_DELIVERY.getCode());
projectOrderInfoService.updateProjectOrderInfoByCode(updateOrder);
}
@Override
public int deleteInventoryOuterById(Long id) {
InventoryDelivery inventoryDelivery = inventoryDeliveryMapper.selectInventoryDeliveryById(id);
//还原库存信息
InventoryInfo inventoryInfo = new InventoryInfo();
inventoryInfo.setOuterCode(inventoryDelivery.getOuterCode());
inventoryInfo.setWarehouseId(inventoryDelivery.getWarehouseId());
List<InventoryInfo> inventoryInfos = inventoryInfoService.selectInventoryInfoList(inventoryInfo);
if (CollUtil.isNotEmpty(inventoryInfos)) {
inventoryInfoService.clearOutInfo(inventoryInfos.stream().map(InventoryInfo::getId).collect(Collectors.toList()));
}
return inventoryDeliveryMapper.deleteInventoryDeliveryById(id);
}
}

View File

@ -7,6 +7,7 @@ import com.ruoyi.common.utils.StringUtils;
import com.ruoyi.sip.domain.InventoryInfo;
import com.ruoyi.sip.domain.OmsWarehouseInfo;
import com.ruoyi.sip.domain.ProductInfo;
import com.ruoyi.sip.dto.inventory.ProductWarehouseInfo;
import com.ruoyi.sip.dto.warehouse.WarehouseInnerExcelDto;
import com.ruoyi.sip.mapper.InventoryInfoMapper;
import com.ruoyi.sip.service.IInventoryInfoService;
@ -149,5 +150,18 @@ public class InventoryInfoServiceImpl implements IInventoryInfoService {
inventoryInfoMapper.saveBatch(inventoryInfoList);
}
@Override
public List<ProductWarehouseInfo> checkOurPreview(List<String> productCodeList) {
if (CollUtil.isEmpty(productCodeList)){
return Collections.emptyList();
}
return inventoryInfoMapper.checkOurPreview(productCodeList);
}
@Override
public void clearOutInfo(List<Long> idList) {
inventoryInfoMapper.clearOutInfo(idList);
}
}

View File

@ -0,0 +1,118 @@
package com.ruoyi.sip.service.impl;
import java.util.Collections;
import java.util.List;
import java.util.stream.Collectors;
import cn.hutool.core.collection.CollUtil;
import com.ruoyi.common.exception.ServiceException;
import com.ruoyi.common.utils.DateUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import com.ruoyi.sip.mapper.InventoryOuterDetailMapper;
import com.ruoyi.sip.domain.InventoryOuterDetail;
import com.ruoyi.sip.service.IInventoryOuterDetailService;
import com.ruoyi.common.core.text.Convert;
/**
* Service
*
* @author ruoyi
* @date 2025-08-11
*/
@Service
public class InventoryOuterDetailServiceImpl implements IInventoryOuterDetailService
{
@Autowired
private InventoryOuterDetailMapper inventoryOuterDetailMapper;
/**
*
*
* @param id
* @return
*/
@Override
public InventoryOuterDetail selectInventoryOuterDetailById(Long id)
{
return inventoryOuterDetailMapper.selectInventoryOuterDetailById(id);
}
/**
*
*
* @param inventoryOuterDetail
* @return
*/
@Override
public List<InventoryOuterDetail> selectInventoryOuterDetailList(InventoryOuterDetail inventoryOuterDetail)
{
return inventoryOuterDetailMapper.selectInventoryOuterDetailList(inventoryOuterDetail);
}
/**
*
*
* @param inventoryOuterDetail
* @return
*/
@Override
public int insertInventoryOuterDetail(InventoryOuterDetail inventoryOuterDetail)
{
inventoryOuterDetail.setCreateTime(DateUtils.getNowDate());
return inventoryOuterDetailMapper.insertInventoryOuterDetail(inventoryOuterDetail);
}
/**
*
*
* @param inventoryOuterDetail
* @return
*/
@Override
public int updateInventoryOuterDetail(InventoryOuterDetail inventoryOuterDetail)
{
inventoryOuterDetail.setUpdateTime(DateUtils.getNowDate());
return inventoryOuterDetailMapper.updateInventoryOuterDetail(inventoryOuterDetail);
}
/**
*
*
* @param ids
* @return
*/
@Override
public int deleteInventoryOuterDetailByIds(String ids)
{
return inventoryOuterDetailMapper.deleteInventoryOuterDetailByIds(Convert.toStrArray(ids));
}
/**
*
*
* @param id
* @return
*/
@Override
public int deleteInventoryOuterDetailById(Long id)
{
return inventoryOuterDetailMapper.deleteInventoryOuterDetailById(id);
}
@Override
public void save(List<InventoryOuterDetail> detailList) {
if (CollUtil.isEmpty(detailList)){
return;
}
List<InventoryOuterDetail> addList = detailList.stream().filter(item -> item.getQuantity() != null && item.getQuantity() != 0).collect(Collectors.toList());
inventoryOuterDetailMapper.save(addList);
}
@Override
public void deleteByOuterCode(List<String> outerCode) {
inventoryOuterDetailMapper.deleteByOuterCode(outerCode);
}
}

View File

@ -1,13 +1,27 @@
package com.ruoyi.sip.service.impl;
import java.util.Collections;
import java.util.List;
import java.util.Map;
import java.util.function.Function;
import java.util.stream.Collectors;
import cn.hutool.core.collection.CollUtil;
import com.ruoyi.common.exception.ServiceException;
import com.ruoyi.common.utils.DateUtils;
import com.ruoyi.common.utils.ShiroUtils;
import com.ruoyi.sip.domain.*;
import com.ruoyi.sip.dto.inventory.ProductWarehouseInfo;
import com.ruoyi.sip.service.*;
import com.ruoyi.sip.vo.OuterDeliveryProductVo;
import com.ruoyi.sip.vo.OuterDeliveryVo;
import liquibase.pro.packaged.A;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import com.ruoyi.sip.mapper.InventoryOuterMapper;
import com.ruoyi.sip.domain.InventoryOuter;
import com.ruoyi.sip.service.IInventoryOuterService;
import com.ruoyi.common.core.text.Convert;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.web.context.annotation.ApplicationScope;
/**
* Service
@ -16,11 +30,22 @@ import com.ruoyi.common.core.text.Convert;
* @date 2025-08-08
*/
@Service
@Transactional(rollbackFor = Exception.class)
public class InventoryOuterServiceImpl implements IInventoryOuterService
{
@Autowired
private InventoryOuterMapper inventoryOuterMapper;
@Autowired
private IProjectOrderInfoService orderInfoService;
@Autowired
private IInventoryOuterDetailService detailService;
@Autowired
private IProductInfoService productInfoService;
@Autowired
private IInventoryDeliveryService deliveryService;
@Autowired
private IProjectProductInfoService projectProductInfoService;
/**
*
*
@ -30,7 +55,19 @@ public class InventoryOuterServiceImpl implements IInventoryOuterService
@Override
public InventoryOuter selectInventoryOuterById(Long id)
{
return inventoryOuterMapper.selectInventoryOuterById(id);
InventoryOuter inventoryOuter = inventoryOuterMapper.selectInventoryOuterById(id);
InventoryOuterDetail inventoryOuterDetail = new InventoryOuterDetail();
inventoryOuterDetail.setOuterCode(inventoryOuter.getOuterCode());
List<InventoryOuterDetail> detailList = detailService.selectInventoryOuterDetailList(inventoryOuterDetail);
inventoryOuter.setDetailList(detailList);
List<ProductWarehouseInfo> collect = detailList.stream().map(item -> {
ProductWarehouseInfo productWarehouseInfo = new ProductWarehouseInfo();
productWarehouseInfo.setConfirmQuantity(item.getQuantity());
productWarehouseInfo.setWarehouseName(item.getWarehouseName());
return productWarehouseInfo;
}).collect(Collectors.toList());
inventoryOuter.setWarehouseInfoList(collect);
return inventoryOuter;
}
/**
@ -54,10 +91,32 @@ public class InventoryOuterServiceImpl implements IInventoryOuterService
@Override
public int insertInventoryOuter(InventoryOuter inventoryOuter)
{
inventoryOuter.setOuterCode(generateOutCode());
inventoryOuter.setDeliveryStatus(InventoryOuter.DeliveryStatusEnum.WAIT_DELIVERY.getCode());
inventoryOuter.setOuterStatus(InventoryOuter.OuterStatusEnum.WAIT_CONFIRM.getCode());
inventoryOuter.setCreateBy(ShiroUtils.getUserId().toString());
inventoryOuter.setCreateTime(DateUtils.getNowDate());
List<InventoryOuterDetail> detailList = inventoryOuter.getDetailList();
if (CollUtil.isEmpty(detailList)) {
throw new ServiceException("出库单详情为空,保存失败");
}
for (InventoryOuterDetail inventoryOuterDetail : detailList) {
inventoryOuterDetail.setOuterCode(inventoryOuter.getOuterCode());
}
detailService.save(detailList);
//减去对应产品库存
productInfoService.updateAvailableCount(-inventoryOuter.getQuantity(), inventoryOuter.getProductCode());
return inventoryOuterMapper.insertInventoryOuter(inventoryOuter);
}
private String generateOutCode() {
StringBuilder code = new StringBuilder();
code.append("C-");
code.append(DateUtils.dateTime());
int count = inventoryOuterMapper.selectMaxOrderCode(code.toString());
code.append(String.format("%03d", count + 1));
return code.toString();
}
/**
*
*
@ -68,16 +127,18 @@ public class InventoryOuterServiceImpl implements IInventoryOuterService
public int updateInventoryOuter(InventoryOuter inventoryOuter)
{
inventoryOuter.setUpdateTime(DateUtils.getNowDate());
inventoryOuter.setUpdateBy(ShiroUtils.getUserId().toString());
return inventoryOuterMapper.updateInventoryOuter(inventoryOuter);
}
/**
*
*
* 使 deleteInventoryOuterById
* @param ids
* @return
*/
@Override
@Deprecated
public int deleteInventoryOuterByIds(String ids)
{
return inventoryOuterMapper.deleteInventoryOuterByIds(Convert.toStrArray(ids));
@ -92,6 +153,98 @@ public class InventoryOuterServiceImpl implements IInventoryOuterService
@Override
public int deleteInventoryOuterById(Long id)
{
InventoryOuter inventoryOuter = inventoryOuterMapper.selectInventoryOuterById(id);
detailService.deleteByOuterCode(Collections.singletonList(inventoryOuter.getOuterCode()));
productInfoService.updateAvailableCount(inventoryOuter.getQuantity(), inventoryOuter.getProductCode());
int count = inventoryOuterMapper.countByOrderCode(inventoryOuter.getOrderCode());
//如果全部撤销
if (count <= 0) {
ProjectOrderInfo projectOrderInfo = new ProjectOrderInfo();
projectOrderInfo.setOrderCode(inventoryOuter.getOrderCode());
projectOrderInfo.setOuterStatus(ProjectOrderInfo.OuterStatusEnum.NOT_OUTER.getCode());
orderInfoService.updateProjectOrderInfoByCode(projectOrderInfo);
}
return inventoryOuterMapper.deleteInventoryOuterById(id);
}
@Override
public int statusUpdate(InventoryOuter inventoryOuter) {
InventoryOuter queryDto = new InventoryOuter();
queryDto.setOrderCode(inventoryOuter.getOrderCode());
ProjectOrderInfo projectOrderInfo = new ProjectOrderInfo();
projectOrderInfo.setOrderCode(inventoryOuter.getOrderCode());
projectOrderInfo.setUpdateBy(ShiroUtils.getUserId().toString());
projectOrderInfo.setUpdateTime(DateUtils.getNowDate());
if (inventoryOuter.getOuterStatus().equals(InventoryOuter.OuterStatusEnum.RETURN.getCode())) {
//已退回
projectOrderInfo.setOuterStatus(ProjectOrderInfo.OuterStatusEnum.RETURN.getCode());
} else {
List<ProjectProductInfo> projectProductInfos = projectProductInfoService.listDeliveryProductByOrderCode(Collections.singletonList(inventoryOuter.getOrderCode()));
//软硬件之和
long sum = projectProductInfos.stream().mapToLong(ProjectProductInfo::getQuantity).sum();
List<InventoryOuter> list = inventoryOuterMapper.selectInventoryOuterList(queryDto);
long count = list.stream().filter(item ->
//已确认和已接收数量
InventoryOuter.OuterStatusEnum.WAIT_RECEIVE.getCode().equals(item.getOuterStatus()) || !InventoryOuter.OuterStatusEnum.RECEIVED.getCode().equals(item.getOuterStatus()))
.mapToLong(InventoryOuter::getQuantity).sum();
//部分接收
if (count == 0L) {
projectOrderInfo.setOuterStatus(ProjectOrderInfo.OuterStatusEnum.NOT_OUTER.getCode());
} else {
projectOrderInfo.setOuterStatus(count == sum ? ProjectOrderInfo.OuterStatusEnum.ALL_OUTER.getCode() : ProjectOrderInfo.OuterStatusEnum.PART_OUTER.getCode());
}
}
orderInfoService.updateProjectOrderInfoByCode(projectOrderInfo);
inventoryOuter.setOrderCode(null);
return this.updateInventoryOuter(inventoryOuter);
}
@Override
public OuterDeliveryVo selectBaseInfoById(Long id) {
OuterDeliveryVo outerDeliveryVo = new OuterDeliveryVo();
InventoryOuter inventoryOuter = this.selectInventoryOuterById(id);
outerDeliveryVo.setInventoryOuter(inventoryOuter);
//查询发货记录
InventoryDelivery queryDeliveryDto = new InventoryDelivery();
queryDeliveryDto.setOuterCode(inventoryOuter.getOuterCode());
List<InventoryDelivery> inventoryDeliveries = deliveryService.selectInventoryDeliveryList(queryDeliveryDto);
outerDeliveryVo.setDeliveryList(inventoryDeliveries);
//查询产品清单
Map<Long, InventoryDelivery> inventoryDeliveryMap = inventoryDeliveries.stream().collect(Collectors.toMap(InventoryDelivery::getWarehouseId, Function.identity(), (v1, v2) -> v1));
InventoryOuterDetail inventoryOuterDetail = new InventoryOuterDetail();
inventoryOuterDetail.setOuterCode(inventoryOuter.getOuterCode());
List<InventoryOuterDetail> detailList = detailService.selectInventoryOuterDetailList(inventoryOuterDetail);
List<OuterDeliveryProductVo> productVoList = detailList.stream().map(item -> {
OuterDeliveryProductVo vo = new OuterDeliveryProductVo();
vo.setProductCode(item.getProductCode());
vo.setModel(item.getModel());
vo.setQuantity(item.getQuantity());
vo.setWarehouseId(item.getWarehouseId());
vo.setWarehouseName(item.getWarehouseName());
vo.setAvailableCount(item.getAvailableCount());
vo.setQuantity(item.getQuantity());
vo.setDeliveryGenerateQuantity(0L);
vo.setDeliveryConfirmQuantity(0L);
InventoryDelivery inventoryDelivery = inventoryDeliveryMap.get(vo.getWarehouseId());
if (inventoryDelivery != null) {
if (inventoryDelivery.getDeliveryStatus().equals(InventoryDelivery.DeliveryStatusEnum.WAIT_DELIVERY.getCode())) {
vo.setDeliveryGenerateQuantity(vo.getDeliveryGenerateQuantity() + item.getQuantity());
} else {
vo.setDeliveryGenerateQuantity(vo.getDeliveryGenerateQuantity() + item.getQuantity());
vo.setDeliveryConfirmQuantity(vo.getDeliveryConfirmQuantity() + item.getQuantity());
}
}
return vo;
}).collect(Collectors.toList());
outerDeliveryVo.setProductVoList(productVoList);
return outerDeliveryVo;
}
}

View File

@ -1,5 +1,6 @@
package com.ruoyi.sip.service.impl;
import java.util.Collection;
import java.util.Collections;
import java.util.List;
import java.util.stream.Collectors;
@ -7,6 +8,7 @@ import java.util.stream.Collectors;
import cn.hutool.core.collection.CollUtil;
import com.ruoyi.common.utils.DateUtils;
import com.ruoyi.common.utils.ShiroUtils;
import liquibase.pro.packaged.O;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import com.ruoyi.sip.mapper.OmsWarehouseInfoMapper;
@ -123,4 +125,9 @@ public class OmsWarehouseInfoServiceImpl implements IOmsWarehouseInfoService {
}
return omsWarehouseInfoMapper.listByNameList(warehouseNameList);
}
@Override
public List<OmsWarehouseInfo> listByIds(Collection<String> warehouseSet) {
return omsWarehouseInfoMapper.listByIds(warehouseSet);
}
}

View File

@ -386,6 +386,11 @@ public class ProjectOrderInfoServiceImpl implements IProjectOrderInfoService, To
return projectOrderInfoMapper.updateProjectOrderInfo(projectOrderInfo);
}
@Override
public int updateProjectOrderInfoByCode(ProjectOrderInfo projectOrderInfo) {
return projectOrderInfoMapper.updateProjectOrderInfoByCode(projectOrderInfo);
}
private String getFlowBusinessKey(String code, String processType) {
if (StringUtils.isEmpty(code)) {
throw new ServiceException("流程BusinessKey为空");

View File

@ -109,6 +109,18 @@ public class ProjectProductInfoServiceImpl implements IProjectProductInfoService
return projectProductInfoMapper.selectProjectProductInfoListByProjectId(projectId);
}
@Override
public List<ProjectProductInfo> selectProjectProductInfoListByOrderCode(List<String> orderCode) {
return projectProductInfoMapper.selectProjectProductInfoListByOrderCode(orderCode);
}
@Override
public List<ProjectProductInfo> listDeliveryProductByOrderCode(List<String> orderCode) {
List<ProjectProductInfo> projectProductInfos = this.selectProjectProductInfoListByOrderCode(orderCode);
return projectProductInfos.stream().filter(item -> item.getType().equals(ProductInfo.ProductTypeEnum.HARDWARE.getType()) ||
item.getType().equals(ProductInfo.ProductTypeEnum.SOFTWARE.getType())).collect(Collectors.toList());
}
@Override
public void saveBatch(List<ProjectProductInfo> list) {
//校验数据是否在产品库中

View File

@ -1,7 +1,6 @@
package com.ruoyi.sip.service.impl;
import java.util.Collections;
import java.util.List;
import java.util.*;
import java.util.stream.Collectors;
import cn.hutool.core.collection.CollUtil;
@ -10,8 +9,11 @@ import com.ruoyi.common.core.domain.entity.SysUser;
import com.ruoyi.common.exception.ServiceException;
import com.ruoyi.common.utils.DateUtils;
import com.ruoyi.common.utils.ShiroUtils;
import com.ruoyi.common.utils.StringUtils;
import com.ruoyi.sip.domain.OmsWarehouseInfo;
import com.ruoyi.sip.domain.VendorInfo;
import com.ruoyi.sip.mapper.VendorInfoMapper;
import com.ruoyi.sip.service.IOmsWarehouseInfoService;
import com.ruoyi.sip.service.IVendorInfoService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
@ -28,6 +30,8 @@ import com.ruoyi.common.core.text.Convert;
public class VendorInfoServiceImpl implements IVendorInfoService {
@Autowired
private VendorInfoMapper vendorInfoMapper;
@Autowired
private IOmsWarehouseInfoService warehouseInfoService;
/**
*

View File

@ -0,0 +1,30 @@
package com.ruoyi.sip.vo;
import lombok.Data;
/**
* @author : ch
* @version : 1.0
* @ClassName : OuterDeliveryProductVo
* @Description :
* @DATE : Created in 10:32 2025/8/12
* <pre> Copyright: Copyright(c) 2025 </pre>
* <pre> Company : </pre>
* Modification History:
* Date Author Version Discription
* --------------------------------------------------------------------------
* 2025/08/12 ch 1.0 Why & What is modified: <> *
*/
@Data
public class OuterDeliveryProductVo {
private String productCode;
private String model;
private Long quantity;
private Long deliveryGenerateQuantity;
private Long deliveryConfirmQuantity;
private Long availableCount;
private String warehouseName;
private Long warehouseId;
}

View File

@ -0,0 +1,31 @@
package com.ruoyi.sip.vo;
import com.ruoyi.sip.domain.InventoryDelivery;
import com.ruoyi.sip.domain.InventoryOuter;
import lombok.Data;
import java.util.List;
/**
* @author : ch
* @version : 1.0
* @ClassName : OuterDeliveryVo
* @Description :
* @DATE : Created in 10:30 2025/8/12
* <pre> Copyright: Copyright(c) 2025 </pre>
* <pre> Company : </pre>
* Modification History:
* Date Author Version Discription
* --------------------------------------------------------------------------
* 2025/08/12 ch 1.0 Why & What is modified: <> *
*/
@Data
public class OuterDeliveryVo {
private InventoryOuter inventoryOuter;
private List<OuterDeliveryProductVo> productVoList;
private List<InventoryDelivery> deliveryList;
}

View File

@ -0,0 +1,132 @@
<?xml version="1.0" encoding="UTF-8" ?>
<!DOCTYPE mapper
PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN"
"http://mybatis.org/dtd/mybatis-3-mapper.dtd">
<mapper namespace="com.ruoyi.sip.mapper.InventoryDeliveryMapper">
<resultMap type="InventoryDelivery" id="InventoryDeliveryResult">
<result property="id" column="id" />
<result property="outerCode" column="outer_code" />
<result property="warehouseId" column="warehouse_id" />
<result property="logisticsCompany" column="logistics_company" />
<result property="logisticsCode" column="logistics_code" />
<result property="deliveryTimeType" column="delivery_time_type" />
<result property="deliveryTime" column="delivery_time" />
<result property="deliveryStatus" column="delivery_status" />
<result property="deliveryType" column="delivery_type" />
<result property="createBy" column="create_by" />
<result property="createTime" column="create_time" />
<result property="updateBy" column="update_by" />
<result property="updateTime" column="update_time" />
</resultMap>
<sql id="selectInventoryDeliveryVo">
select t1.id, t1.outer_code, t1.warehouse_id,t1.quantity, t1.logistics_company,t1.delivery_status, t1.logistics_code
, t1.delivery_time_type, t1.delivery_time, t1.delivery_type, t1.create_by, t1.create_time, t1.update_by, t1.update_time
,t2.warehouse_name,
t5.project_code, t5.project_name,
t4.order_code,
t6.user_name as create_by_name,
t7.product_code,t7.model
from oms_inventory_delivery t1
left join oms_warehouse_info t2 on t1.warehouse_id = t2.id
left join oms_inventory_outer t3 on t1.outer_code = t3.outer_code
left join project_order_info t4 on t3.order_code=t4.order_code
left join project_info t5 on t4.project_id=t5.id
left join sys_user t6 on t1.create_by = t6.user_id
left join product_info t7 on t3.product_code = t7.product_code
</sql>
<select id="selectInventoryDeliveryList" parameterType="InventoryDelivery" resultMap="InventoryDeliveryResult">
<include refid="selectInventoryDeliveryVo"/>
<where>
<if test="outerCode != null and outerCode != ''"> and t1.outer_code = #{outerCode}</if>
<if test="warehouseId != null "> and t1.warehouse_id = #{warehouseId}</if>
<if test="logisticsCompany != null and logisticsCompany != ''"> and t1.logistics_company = #{logisticsCompany}</if>
<if test="deliveryStatus != null and deliveryStatus != ''"> and t1.delivery_status = #{deliveryStatus}</if>
<if test="logisticsCode != null and logisticsCode != ''"> and t1.logistics_code = #{logisticsCode}</if>
<if test="deliveryTimeType != null and deliveryTimeType != ''"> and t1.delivery_time_type = #{deliveryTimeType}</if>
<if test="deliveryTime != null "> and t1.delivery_time = #{deliveryTime}</if>
<if test="deliveryType != null and deliveryType != ''"> and t1.delivery_type = #{deliveryType}</if>
<if test="projectCode != null and projectCode != ''"> and t5.project_code = #{projectCode}</if>
<if test="orderCode != null and orderCode != ''"> and t3.order_code = #{orderCode}</if>
<if test="projectName != null and projectName != ''"> and t5.project_name like concat('%',#{projectName},'%')</if>
</where>
</select>
<select id="selectInventoryDeliveryById" parameterType="Long" resultMap="InventoryDeliveryResult">
<include refid="selectInventoryDeliveryVo"/>
where t1.id = #{id}
</select>
<select id="selectQuantityByOrderCodeStatus" resultType="com.ruoyi.sip.domain.InventoryDelivery">
<include refid="selectInventoryDeliveryVo"/>
where t3.order_code= #{orderCode} and t1.delivery_status = #{status}
</select>
<insert id="insertInventoryDelivery" parameterType="InventoryDelivery" useGeneratedKeys="true" keyProperty="id">
insert into oms_inventory_delivery
<trim prefix="(" suffix=")" suffixOverrides=",">
<if test="outerCode != null">outer_code,</if>
<if test="warehouseId != null">warehouse_id,</if>
<if test="quantity != null">quantity,</if>
<if test="logisticsCompany != null">logistics_company,</if>
<if test="logisticsCode != null">logistics_code,</if>
<if test="deliveryStatus != null and deliveryStatus != ''">delivery_status, </if>
<if test="deliveryTimeType != null">delivery_time_type,</if>
<if test="deliveryTime != null">delivery_time,</if>
<if test="deliveryType != null">delivery_type,</if>
<if test="createBy != null">create_by,</if>
<if test="createTime != null">create_time,</if>
<if test="updateBy != null">update_by,</if>
<if test="updateTime != null">update_time,</if>
</trim>
<trim prefix="values (" suffix=")" suffixOverrides=",">
<if test="outerCode != null">#{outerCode},</if>
<if test="warehouseId != null">#{warehouseId},</if>
<if test="quantity != null">#{quantity},</if>
<if test="logisticsCompany != null">#{logisticsCompany},</if>
<if test="logisticsCode != null">#{logisticsCode},</if>
<if test="deliveryStatus != null and deliveryStatus != ''"> #{deliveryStatus},</if>
<if test="deliveryTimeType != null">#{deliveryTimeType},</if>
<if test="deliveryTime != null">#{deliveryTime},</if>
<if test="deliveryType != null">#{deliveryType},</if>
<if test="createBy != null">#{createBy},</if>
<if test="createTime != null">#{createTime},</if>
<if test="updateBy != null">#{updateBy},</if>
<if test="updateTime != null">#{updateTime},</if>
</trim>
</insert>
<update id="updateInventoryDelivery" parameterType="InventoryDelivery">
update oms_inventory_delivery
<trim prefix="SET" suffixOverrides=",">
<if test="outerCode != null">outer_code = #{outerCode},</if>
<if test="warehouseId != null">warehouse_id = #{warehouseId},</if>
<if test="quantity != null">quantity=#{quantity},</if>
<if test="logisticsCompany != null">logistics_company = #{logisticsCompany},</if>
<if test="deliveryStatus != null and deliveryStatus != ''">delivery_status = #{deliveryStatus},</if>
<if test="logisticsCode != null">logistics_code = #{logisticsCode},</if>
<if test="deliveryTimeType != null">delivery_time_type = #{deliveryTimeType},</if>
<if test="deliveryTime != null">delivery_time = #{deliveryTime},</if>
<if test="deliveryType != null">delivery_type = #{deliveryType},</if>
<if test="createBy != null">create_by = #{createBy},</if>
<if test="createTime != null">create_time = #{createTime},</if>
<if test="updateBy != null">update_by = #{updateBy},</if>
<if test="updateTime != null">update_time = #{updateTime},</if>
</trim>
where id = #{id}
</update>
<delete id="deleteInventoryDeliveryById" parameterType="Long">
delete from oms_inventory_delivery where id = #{id}
</delete>
<delete id="deleteInventoryDeliveryByIds" parameterType="String">
delete from oms_inventory_delivery where id in
<foreach item="id" collection="array" open="(" separator="," close=")">
#{id}
</foreach>
</delete>
</mapper>

View File

@ -47,6 +47,20 @@ PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN"
<include refid="selectInventoryInfoVo"/>
where t1.id = #{id}
</select>
<select id="checkOurPreview" resultType="com.ruoyi.sip.dto.inventory.ProductWarehouseInfo">
SELECT t1.available_count,t1.warehouse_id,
t2.warehouse_name
FROM (SELECT warehouse_id, count(CASE inventory_status WHEN 0 THEN 1 ELSE 0 END) available_count
FROM oms_inventory_info
WHERE product_code in
<foreach item="item" index="index" collection="list" separator="," open="(" close=")">
#{item}
</foreach>
GROUP BY warehouse_id) t1
LEFT JOIN oms_warehouse_info t2 ON t1.warehouse_id = t2.id
order by t1.available_count
</select>
<insert id="insertInventoryInfo" parameterType="InventoryInfo" useGeneratedKeys="true" keyProperty="id">
@ -89,7 +103,7 @@ PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN"
inventory_status = VALUES(inventory_status),
outer_code = VALUES(outer_code),
outer_price = VALUES(outer_price),
update_by = VALUES(create_by),
update_by = VALUES(update_by),
update_time = now()
</insert>
@ -111,6 +125,14 @@ PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN"
</trim>
where id = #{id}
</update>
<update id="clearOutInfo">
update oms_inventory_info
set inventory_status = 0,outer_code=null
where id in
<foreach item="id" collection="list" separator="," open="(" close=")">
#{id}
</foreach>
</update>
<delete id="deleteInventoryInfoById" parameterType="Long">
delete from oms_inventory_info where id = #{id}

View File

@ -0,0 +1,112 @@
<?xml version="1.0" encoding="UTF-8" ?>
<!DOCTYPE mapper
PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN"
"http://mybatis.org/dtd/mybatis-3-mapper.dtd">
<mapper namespace="com.ruoyi.sip.mapper.InventoryOuterDetailMapper">
<resultMap type="InventoryOuterDetail" id="InventoryOuterDetailResult">
<result property="id" column="id" />
<result property="outerCode" column="outer_code" />
<result property="warehouseId" column="warehouse_id" />
<result property="quantity" column="quantity" />
<result property="outerStatus" column="outer_status" />
<result property="createBy" column="create_by" />
<result property="updateBy" column="update_by" />
<result property="createTime" column="create_time" />
<result property="updateTime" column="update_time" />
</resultMap>
<sql id="selectInventoryOuterDetailVo">
select t1.id, t1.outer_code, t1.warehouse_id, t1.quantity, t1.outer_status,t1. create_by, t1.update_by, t1.create_time, t1.update_time ,
t2.warehouse_name,
t4.product_code,
t4.model,
t4.available_count
from oms_inventory_outer_detail t1
left join oms_warehouse_info t2 on t1.warehouse_id=t2.id
left join oms_inventory_outer t3 on t1.outer_code=t3.outer_code
left join product_info t4 on t4.product_code=t3.product_code
</sql>
<select id="selectInventoryOuterDetailList" parameterType="InventoryOuterDetail" resultMap="InventoryOuterDetailResult">
<include refid="selectInventoryOuterDetailVo"/>
<where>
<if test="outerCode != null and outerCode != ''"> and t1.outer_code = #{outerCode}</if>
<if test="warehouseId != null "> and t1.warehouse_id = #{warehouseId}</if>
<if test="quantity != null "> and t1.quantity = #{quantity}</if>
<if test="outerStatus != null and outerStatus != ''"> and t1.outer_status = #{outerStatus}</if>
</where>
</select>
<select id="selectInventoryOuterDetailById" parameterType="Long" resultMap="InventoryOuterDetailResult">
<include refid="selectInventoryOuterDetailVo"/>
where id = #{id}
</select>
<insert id="insertInventoryOuterDetail" parameterType="InventoryOuterDetail" useGeneratedKeys="true" keyProperty="id">
insert into oms_inventory_outer_detail
<trim prefix="(" suffix=")" suffixOverrides=",">
<if test="outerCode != null">outer_code,</if>
<if test="warehouseId != null">warehouse_id,</if>
<if test="quantity != null">quantity,</if>
<if test="outerStatus != null">outer_status,</if>
<if test="createBy != null">create_by,</if>
<if test="updateBy != null">update_by,</if>
<if test="createTime != null">create_time,</if>
<if test="updateTime != null">update_time,</if>
</trim>
<trim prefix="values (" suffix=")" suffixOverrides=",">
<if test="outerCode != null">#{outerCode},</if>
<if test="warehouseId != null">#{warehouseId},</if>
<if test="quantity != null">#{quantity},</if>
<if test="outerStatus != null">#{outerStatus},</if>
<if test="createBy != null">#{createBy},</if>
<if test="updateBy != null">#{updateBy},</if>
<if test="createTime != null">#{createTime},</if>
<if test="updateTime != null">#{updateTime},</if>
</trim>
</insert>
<insert id="save">
insert into oms_inventory_outer_detail (outer_code, warehouse_id, quantity, outer_status, create_by, update_by, create_time, update_time)
values
<foreach item="item" index="index" collection="list" separator=",">
(#{item.outerCode}, #{item.warehouseId}, #{item.quantity}, #{item.outerStatus}, #{item.createBy}, #{item.updateBy}, #{item.createTime}, #{item.updateTime})
</foreach>
on duplicate key update
outer_status = values(outer_status),
update_by = values(update_by), update_time = values(update_time)
</insert>
<update id="updateInventoryOuterDetail" parameterType="InventoryOuterDetail">
update oms_inventory_outer_detail
<trim prefix="SET" suffixOverrides=",">
<if test="outerCode != null">outer_code = #{outerCode},</if>
<if test="warehouseId != null">warehouse_id = #{warehouseId},</if>
<if test="quantity != null">quantity = #{quantity},</if>
<if test="outerStatus != null">outer_status = #{outerStatus},</if>
<if test="createBy != null">create_by = #{createBy},</if>
<if test="updateBy != null">update_by = #{updateBy},</if>
<if test="createTime != null">create_time = #{createTime},</if>
<if test="updateTime != null">update_time = #{updateTime},</if>
</trim>
where id = #{id}
</update>
<delete id="deleteInventoryOuterDetailById" parameterType="Long">
delete from oms_inventory_outer_detail where id = #{id}
</delete>
<delete id="deleteInventoryOuterDetailByIds" parameterType="String">
delete from oms_inventory_outer_detail where id in
<foreach item="id" collection="array" open="(" separator="," close=")">
#{id}
</foreach>
</delete>
<delete id="deleteByOuterCode">
delete from oms_inventory_outer_detail where outer_code in
<foreach item="outerCode" collection="list" open="(" separator="," close=")">
#{outerCode}
</foreach>
</delete>
</mapper>

View File

@ -23,35 +23,123 @@ PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN"
</resultMap>
<sql id="selectInventoryOuterVo">
select id, outer_code, product_code, quantity, outer_status, order_code, contact_person, contact_phone, contact_address, delivery_time, delivery_time_type, create_by, update_by, create_time, update_time from oms_inventory_outer
select id,
outer_code,
product_code,
quantity,
outer_status,
order_code,
contact_person,
contact_phone,
contact_address,
delivery_time,
delivery_time_type,
create_by,
update_by,
create_time,
update_time
from oms_inventory_outer t1
</sql>
<sql id="selectInventoryOuterRelationVo">
select t1.id,
t1.outer_code,
t1.product_code,
t1.quantity,
t1.outer_status,
t1.order_code,
t1.contact_person,
t1.contact_phone,
t1.contact_address,
t1.delivery_time,
t1.delivery_time_type,
t1.create_by,
t1.update_by,
t1.create_time,
t1.update_time,
t1.delivery_status,
t2.model,
t4.project_code,
t4.project_name
from oms_inventory_outer t1
left join product_info t2 on t1.product_code = t2.product_code
left join project_order_info t3 on t1.order_code = t3.order_code
left join project_info t4 on t4.id = t3.project_id
</sql>
<select id="selectInventoryOuterList" parameterType="InventoryOuter" resultMap="InventoryOuterResult">
<include refid="selectInventoryOuterVo"/>
<include refid="selectInventoryOuterRelationVo"/>
<where>
<if test="outerCode != null and outerCode != ''">and outer_code = #{outerCode}</if>
<if test="productCode != null and productCode != ''">and product_code = #{productCode}</if>
<if test="productCodeList != null and productCodeList.size>0">and product_code in
<if test="outerCode != null and outerCode != ''">and t1.outer_code = #{outerCode}</if>
<if test="productCode != null and productCode != ''">and t1.product_code = #{productCode}</if>
<if test="productCodeList != null and productCodeList.size>0">and t1.product_code in
<foreach item="item" index="index" collection="productCodeList" separator="," open="(" close=")">
#{item}
</foreach>
</if>
<if test="quantity != null ">and quantity = #{quantity}</if>
<if test="outerStatus != null and outerStatus != ''">and outer_status = #{outerStatus}</if>
<if test="orderCode != null and orderCode != ''">and order_code = #{orderCode}</if>
<if test="contactPerson != null and contactPerson != ''">and contact_person = #{contactPerson}</if>
<if test="contactPhone != null and contactPhone != ''">and contact_phone = #{contactPhone}</if>
<if test="contactAddress != null and contactAddress != ''">and contact_address = #{contactAddress}</if>
<if test="deliveryTime != null ">and delivery_time = #{deliveryTime}</if>
<if test="deliveryTimeType != null and deliveryTimeType != ''">and delivery_time_type =
<if test="quantity != null ">and t1.quantity = #{quantity}</if>
<if test="outerStatus != null and outerStatus != ''">and t1.outer_status = #{outerStatus}</if>
<if test="outerStatusList != null and outerStatusList.size>0">and t1.outer_status in
<foreach collection="outerStatusList" open="(" close=")" item="item" separator=",">
#{item}
</foreach>
</if>
<if test="orderCode != null and orderCode != ''">and t1.order_code = #{orderCode}</if>
<if test="contactPerson != null and contactPerson != ''">and t1.contact_person = #{contactPerson}</if>
<if test="contactPhone != null and contactPhone != ''">and t1.contact_phone = #{contactPhone}</if>
<if test="deliveryStatus != null and deliveryStatus != ''">and t1.delivery_status = #{deliveryStatus}</if>
<if test="contactAddress != null and contactAddress != ''">and t1.contact_address = #{contactAddress}</if>
<if test="deliveryTime != null ">and t1.delivery_time = #{deliveryTime}</if>
<if test="deliveryTimeType != null and deliveryTimeType != ''">and t1.delivery_time_type =
#{deliveryTimeType}
</if>
</where>
</select>
<select id="selectInventoryOuterById" parameterType="Long" resultMap="InventoryOuterResult">
<include refid="selectInventoryOuterVo"/>
where id = #{id}
select t1.id,
t1.outer_code,
t1.product_code,
t1.quantity,
t1.outer_status,
t1.order_code,
t1.contact_person,
t1.contact_phone,
t1.contact_address,
t1.delivery_time,
t1.delivery_time_type,
t1.create_by,
t1.update_by,
t1.create_time,
t1.update_time,
t2.model,
t3.vendor_name,
t5.project_name,
t5.project_code
from oms_inventory_outer t1
left join product_info t2 on t1.product_code = t2.product_code
left join oms_vendor_info t3 on t2.vendor_code = t3.vendor_code
left join project_order_info t4 on t1.order_code = t4.order_code
left join project_info t5 on t5.id = t4.project_id
where t1.id = #{id}
</select>
<select id="selectMaxOrderCode" resultType="java.lang.Integer">
select ifnull(max(SUBSTR(outer_code FROM LENGTH(#{code}) + 1 FOR 3)), 0)
from oms_inventory_outer
where outer_code like concat(#{code}, '%')
</select>
<select id="countByOrderCode" resultType="java.lang.Integer">
select count(1)
from oms_inventory_outer
where order_code = #{orderCode}
</select>
<select id="selectInventoryOuterByCode" resultType="com.ruoyi.sip.domain.InventoryOuter">
<include refid="selectInventoryOuterRelationVo"/>
where t1.outer_code=#{code}
</select>
<insert id="insertInventoryOuter" parameterType="InventoryOuter" useGeneratedKeys="true" keyProperty="id">
@ -61,6 +149,7 @@ PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN"
<if test="productCode != null">product_code,</if>
<if test="quantity != null">quantity,</if>
<if test="outerStatus != null">outer_status,</if>
<if test="deliveryStatus != null and deliveryStatus!=''">delivery_status,</if>
<if test="orderCode != null">order_code,</if>
<if test="contactPerson != null">contact_person,</if>
<if test="contactPhone != null">contact_phone,</if>
@ -77,6 +166,7 @@ PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN"
<if test="productCode != null">#{productCode},</if>
<if test="quantity != null">#{quantity},</if>
<if test="outerStatus != null">#{outerStatus},</if>
<if test="deliveryStatus != null and deliveryStatus!=''">#{deliveryStatus},</if>
<if test="orderCode != null">#{orderCode},</if>
<if test="contactPerson != null">#{contactPerson},</if>
<if test="contactPhone != null">#{contactPhone},</if>
@ -97,6 +187,7 @@ PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN"
<if test="productCode != null">product_code = #{productCode},</if>
<if test="quantity != null">quantity = #{quantity},</if>
<if test="outerStatus != null">outer_status = #{outerStatus},</if>
<if test="deliveryStatus != null and deliveryStatus!=''">delivery_status=#{deliveryStatus},</if>
<if test="orderCode != null">order_code = #{orderCode},</if>
<if test="contactPerson != null">contact_person = #{contactPerson},</if>
<if test="contactPhone != null">contact_phone = #{contactPhone},</if>

View File

@ -99,6 +99,9 @@ PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN"
<if test="supplier != null and supplier != ''"> and t1.supplier = #{supplier}</if>
<if test="supplier != null and supplier != ''"> and t1.supplier = #{supplier}</if>
<if test="orderStatus != null and orderStatus != ''"> and t1.order_status = #{orderStatus}</if>
<if test="deliveryStatus != null and deliveryStatus != ''"> and t1.delivery_status = #{deliveryStatus}</if>
<if test="outerStatus != null and outerStatus != ''"> and t1.outer_status = #{outerStatus}</if>
<if test="signStatus != null and signStatus != ''"> and t1.sign_status = #{signStatus}</if>
<if test="deliveryTimeStart != null or deliveryTimeEnd != null">
<choose>
<when test="deliveryTimeStart != null and deliveryTimeEnd != null">
@ -361,6 +364,9 @@ PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN"
<if test="supplier != null">supplier = #{supplier},</if>
<if test="remark != null">remark = #{remark},</if>
<if test="orderStatus != null">order_status = #{orderStatus},</if>
<if test="outerStatus != null">outer_status = #{outerStatus},</if>
<if test="deliveryStatus != null">delivery_status = #{deliveryStatus},</if>
<if test="signStatus != null">sign_status = #{signStatus},</if>
<if test="createBy != null">create_by = #{createBy},</if>
<if test="createTime != null">create_time = #{createTime},</if>
<if test="updateBy != null">update_by = #{updateBy},</if>

View File

@ -62,6 +62,16 @@ PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN"
<foreach collection="list" item="item" close=")" open="(" separator=",">
#{item}
</foreach>
</select>
<select id="selectProjectProductInfoListByOrderCode" resultType="com.ruoyi.sip.domain.ProjectProductInfo">
<include refid="selectProjectProductRelationInfoVo"/>
where project_id in (select project_id from project_order_info where order_code in <foreach collection="list"
item="item"
close=")" open="("
separator=",">
#{item}
</foreach>)
</select>
<insert id="insertProjectProductInfo" parameterType="ProjectProductInfo" useGeneratedKeys="true" keyProperty="id">

View File

@ -21,7 +21,7 @@ PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN"
<sql id="selectVendorInfoVo">
select t1.vendor_id, t1.vendor_code, t1.vendor_name, t1.vendor_address, t1.vendor_user, t1.vendor_email, t1.vendor_phone, t1.vendor_status
, t1.create_by, t1.update_by, t1.create_time, t1.update_time,t1.warehouse_id
, t1.create_by, t1.update_by, t1.create_time, t1.update_time,t1.warehouse_id,t1.own_warehouse_id
,t2.warehouse_name
from oms_vendor_info t1
left join oms_warehouse_info t2 on t1.warehouse_id = t2.id
@ -59,6 +59,7 @@ PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN"
<if test="vendorEmail != null">vendor_email,</if>
<if test="vendorPhone != null and vendorPhone != ''">vendor_phone,</if>
<if test="warehouseId != null and warehouseId!=''">warehouse_id,</if>
<if test="ownWarehouseId != null and ownWarehouseId!=''">own_warehouse_id,</if>
<if test="vendorStatus != null">vendor_status,</if>
<if test="createBy != null">create_by,</if>
<if test="updateBy != null">update_by,</if>
@ -74,6 +75,7 @@ PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN"
<if test="vendorEmail != null">#{vendorEmail},</if>
<if test="vendorPhone != null and vendorPhone != ''">#{vendorPhone},</if>
<if test="warehouseId != null and warehouseId!=''"> #{warehouseId},</if>
<if test="ownWarehouseId != null and ownWarehouseId!=''">#{ownWarehouseId},</if>
<if test="vendorStatus != null">#{vendorStatus},</if>
<if test="createBy != null">#{createBy},</if>
<if test="updateBy != null">#{updateBy},</if>
@ -93,6 +95,7 @@ PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN"
<if test="vendorPhone != null and vendorPhone != ''">vendor_phone = #{vendorPhone},</if>
<if test="vendorStatus != null">vendor_status = #{vendorStatus},</if>
<if test="warehouseId != null and warehouseId!=''">warehouse_id = #{warehouseId},</if>
<if test="ownWarehouseId != null and ownWarehouseId!=''">own_warehouse_id=#{ownWarehouseId},</if>
<if test="createBy != null">create_by = #{createBy},</if>
<if test="updateBy != null">update_by = #{updateBy},</if>
<if test="createTime != null">create_time = #{createTime},</if>

View File

@ -51,6 +51,14 @@ PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN"
</foreach>
</select>
<select id="listByIds" resultType="com.ruoyi.sip.domain.OmsWarehouseInfo">
<include refid="selectOmsWarehouseInfoVo"/>
where id in
<foreach item="item" collection="list" separator="," open="(" close=")">
#{item}
</foreach>
</select>
<insert id="insertOmsWarehouseInfo" parameterType="OmsWarehouseInfo">
insert into oms_warehouse_info