feat(customer): 客户编码自动生成并优化相关功能
-客户编码改为自动生成,无需手动输入 - 添加生成客户编码的逻辑和接口 - 修改客户信息保存逻辑,支持自动生成编码 - 优化客户信息编辑界面,使编码字段只读dev_1.0.0
parent
5bf1250714
commit
f85e557d1c
|
|
@ -519,7 +519,7 @@
|
|||
formatter: function (value, row, index) {
|
||||
var actions = [];
|
||||
let disabled = Number(row.quantity) <= Number(row.generatedQuantity) + Number(row.confirmQuantity)
|
||||
actions.push(`<a class="btn btn-default btn-sm " href="javascript:void(0)" ${disabled?'disabled':''}
|
||||
actions.push(`<a class="btn btn-success btn-sm " 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('');
|
||||
}
|
||||
|
|
@ -555,7 +555,7 @@ function initWarehouseTable(data) {
|
|||
},
|
||||
{
|
||||
field: 'availableCount',
|
||||
title: '实时用库存'
|
||||
title: '实时库存'
|
||||
},
|
||||
{
|
||||
field: 'confirmQuantity',
|
||||
|
|
@ -767,7 +767,7 @@ function initWarehouseTable(data) {
|
|||
} else {
|
||||
|
||||
// actions.push('<a class="btn btn-default btn-xs " href="javascript:void(0)" onclick="viewOuter(' + row.id + ')">查看详情</a>');
|
||||
actions.push(`<a class="btn btn-default btn-sm " href="javascript:void(0)" onclick="$.modal.popupRight( '订单执行跟踪详情', outerPrefix+'/view/${row.id}');">查看详情</a>`);
|
||||
actions.push(`<a class="btn btn-success btn-sm " href="javascript:void(0)" onclick="$.modal.popupRight( '订单执行跟踪详情', outerPrefix+'/view/${row.id}');">查看详情</a>`);
|
||||
}
|
||||
return actions.join('');
|
||||
}
|
||||
|
|
|
|||
|
|
@ -110,6 +110,7 @@
|
|||
</div>
|
||||
<form class="form-horizontal m" id="generateDeliveryForm">
|
||||
<div class="col-xs-12">
|
||||
<input type="hidden" id="deliveryQuantity">
|
||||
<table>
|
||||
<tr>
|
||||
<td><label class="control-label is-required">物流单号:</label></td>
|
||||
|
|
@ -172,6 +173,75 @@
|
|||
var productPrefix = ctx + "inventory/info";
|
||||
var deliveryPrefix = ctx + "inventory/delivery";
|
||||
const showReturnFlag = [[${deliveryList}]] && [[${deliveryList.size()}]]>0;
|
||||
|
||||
let productSnData = [];
|
||||
let productSnOptions = {
|
||||
id: 'bootstrap-table',
|
||||
url: productPrefix + "/list",
|
||||
modalName: "出库单",
|
||||
|
||||
onCheck: (row, $ele) => {
|
||||
updateTotal()
|
||||
},
|
||||
onUncheck: (row, $ele) => {
|
||||
if (productSnData.length > 0) {
|
||||
$('#bootstrap-table').bootstrapTable('checkAll');
|
||||
$.modal.msgError("导入数据不允许取消勾选")
|
||||
return
|
||||
}
|
||||
updateTotal()
|
||||
},
|
||||
onCheckAll: (rowsAfter, rowsBefore) => {
|
||||
updateTotal()
|
||||
},
|
||||
onUncheckAll: (rowsAfter, rowsBefore) => {
|
||||
if (productSnData.length > 0) {
|
||||
$('#bootstrap-table').bootstrapTable('checkAll');
|
||||
$.modal.msgError("导入数据不允许取消勾选")
|
||||
return
|
||||
}
|
||||
updateTotal()
|
||||
},
|
||||
onLoadSuccess: (data) => {
|
||||
$('#bootstrap-table').bootstrapTable('checkAll');
|
||||
},
|
||||
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: '仓库'
|
||||
}]
|
||||
};
|
||||
|
||||
$("#form-outer-edit").validate({
|
||||
focusCleanup: true
|
||||
});
|
||||
|
|
@ -197,6 +267,7 @@
|
|||
let data = new FormData()
|
||||
data.append('file', file)
|
||||
data.append('productCode', $('[name="productCode"]').val())
|
||||
data.append('quantity', Number($('#deliveryQuantity').val()))
|
||||
var xhr = new XMLHttpRequest(); // 创建XMLHttpRequest对象
|
||||
xhr.open('POST', prefix + '/importData', true); // 设置请求类型和URL
|
||||
// 当请求完成时执行的回调函数
|
||||
|
|
@ -204,7 +275,17 @@
|
|||
let data = JSON.parse(res.currentTarget.response)
|
||||
if (data.code === 0) {
|
||||
$.modal.msgSuccess('上传成功');
|
||||
$.table.search('query-product-sn', 'bootstrap-table')
|
||||
productSnData = data.data;
|
||||
$.table.refreshOptions($.extend(productSnOptions, {
|
||||
url: '',
|
||||
data: productSnData,
|
||||
pagination: false
|
||||
}), 'bootstrap-table')
|
||||
setTimeout(() => {
|
||||
$('#bootstrap-table').bootstrapTable('checkAll');
|
||||
}, 200);
|
||||
$('#bootstrap-table').before(`<div ><span>已选:</span><span id="table-select-count">${productSnData.length}</span><span>(台)</span></div>`);
|
||||
// $.table.search('query-product-sn', 'bootstrap-table')
|
||||
} else {
|
||||
top.layer.alert(data.msg || '导入失败', {
|
||||
icon: 2,
|
||||
|
|
@ -272,61 +353,10 @@
|
|||
}
|
||||
}
|
||||
|
||||
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);
|
||||
function initProductSnTable() {
|
||||
|
||||
$.table.init(productSnOptions);
|
||||
$('#bootstrap-table').before('<div ><span>已选:</span><span id="table-select-count">0</span><span>(台)</span></div>');
|
||||
}
|
||||
|
||||
|
|
@ -335,7 +365,7 @@
|
|||
if ($tableCount.length > 0) {
|
||||
// 延迟100毫秒,等待表格渲染完成
|
||||
setTimeout(function () {
|
||||
$tableCount.text($.table.selectColumns("productSn").length);
|
||||
$tableCount.text(productSnData.length > 0 ? productSnData.length : $.table.selectColumns("productSn").length);
|
||||
}, 100)
|
||||
}
|
||||
}
|
||||
|
|
@ -398,7 +428,7 @@
|
|||
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-sm " href="javascript:void(0)" ${disabled ? 'style="pointer-events: none;" disabled' : ''} onclick="checkDelivery(\'${row.quantity}\',\'${row.warehouseId}\','${row.productCode}')">发货</span>`);
|
||||
actions.push(`<span class="btn btn-success btn-sm " href="javascript:void(0)" ${disabled ? 'style="pointer-events: none;" disabled' : ''} onclick="checkDelivery(\'${row.quantity}\',\'${row.warehouseId}\','${row.productCode}')">发货</span>`);
|
||||
return actions.join('');
|
||||
}
|
||||
}]
|
||||
|
|
@ -412,12 +442,18 @@
|
|||
let width = 1000, height = 700
|
||||
parent.$('.layui-layer-btn').css('display', 'none')
|
||||
parent.$('.layui-layer-setwin').css('display', 'none')
|
||||
$('#deliveryQuantity').val(quantity)
|
||||
$('[name="warehouseId"]').val(warehouseId)
|
||||
$('[name="productCode"]').val(productCode)
|
||||
$('[name="inventoryStatus"]').val(0)
|
||||
$('#query-product-sn [name="outerCode"]').val('')
|
||||
$.table.search('query-product-sn', 'bootstrap-table')
|
||||
|
||||
productSnData = []
|
||||
$.table.refreshOptions($.extend(productSnOptions, {
|
||||
url: productPrefix + "/list",
|
||||
pagination: true,
|
||||
pageSize: quantity
|
||||
}), 'bootstrap-table')
|
||||
$('#bootstrap-table').before('<div ><span>已选:</span><span id="table-select-count">0</span><span>(台)</span></div>');
|
||||
$('#table-select-count').text(0);
|
||||
let index = layer.open({
|
||||
id: 'generate_delivery',
|
||||
|
|
@ -432,15 +468,25 @@
|
|||
$.modal.msgError('物流单号必填')
|
||||
return;
|
||||
}
|
||||
var arrays = $.table.selectColumns("productSn");
|
||||
let arrays = []
|
||||
if (productSnData.length <= 0) {
|
||||
arrays = $.table.selectColumns("productSn");
|
||||
if (arrays.length != quantity) {
|
||||
$.modal.msgError(`产品选中数量应与发货数量一致,应发货数量为[${quantity}]`)
|
||||
return
|
||||
}
|
||||
} else {
|
||||
if (productSnData.length != quantity) {
|
||||
$.modal.msgError(`产品选中数量应与发货数量一致,应发货数量为[${quantity}]`)
|
||||
return
|
||||
}
|
||||
}
|
||||
|
||||
//保存数据
|
||||
let data = {
|
||||
productSnList: arrays,
|
||||
logisticsCode: $('#logisticsCode').val(),
|
||||
productCode: productCode,
|
||||
quantity: quantity,
|
||||
warehouseId: warehouseId,
|
||||
logisticsCompany: $('#logisticsCompany').val(),
|
||||
|
|
@ -448,6 +494,7 @@
|
|||
deliveryTime: $('#deliveryTime').val(),
|
||||
deliveryTimeType: $('#deliveryTimeType').val(),
|
||||
outerCode: $('[name="outerCode"]').val(),
|
||||
productSnDataList: productSnData,
|
||||
}
|
||||
var config = {
|
||||
url: deliveryPrefix + "/add",
|
||||
|
|
@ -460,18 +507,22 @@
|
|||
$.modal.disable();
|
||||
},
|
||||
success: function (result) {
|
||||
if (result.code != 0) {
|
||||
$.modal.closeLoading();
|
||||
$.modal.enable();
|
||||
$.modal.msgError(result.msg)
|
||||
return
|
||||
}
|
||||
if (typeof callback == "function") {
|
||||
callback(result);
|
||||
}
|
||||
refreshTable()
|
||||
$.modal.closeLoading();
|
||||
$.modal.enable();
|
||||
layer.close(index);
|
||||
}
|
||||
};
|
||||
$.ajax(config)
|
||||
|
||||
layer.close(index);
|
||||
|
||||
},
|
||||
end: function () {
|
||||
parent.$('.layui-layer-btn').css('display', '')
|
||||
|
|
|
|||
|
|
@ -129,7 +129,7 @@
|
|||
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 ' + editFlag + '" href="javascript:void(0)" onclick="refundable(\'' + row.id + '\',\''+row.orderCode+'\')">退回</a> ');
|
||||
actions.push('<a class="btn btn-default btn-xs ' + editFlag + '" href="javascript:void(0)" onclick="received(\'' + row.id + '\')">确认接收</a>');
|
||||
actions.push('<a class="btn btn-success btn-xs ' + editFlag + '" href="javascript:void(0)" onclick="received(\'' + row.id + '\')">确认接收</a>');
|
||||
}
|
||||
return actions.join('');
|
||||
}
|
||||
|
|
@ -140,11 +140,11 @@
|
|||
|
||||
|
||||
function received(id) {
|
||||
$.modal.confirm("确认要确认接收吗?", function () {
|
||||
// $.modal.confirm("确认要确认接收吗?", function () {
|
||||
$.operate.post(prefix + "/status", {"id": id, "outerStatus": '3'},()=>{
|
||||
// $.table.refresh()
|
||||
});
|
||||
})
|
||||
// })
|
||||
}
|
||||
|
||||
function refundable(id,orderCode) {
|
||||
|
|
|
|||
|
|
@ -9,9 +9,9 @@
|
|||
<form class="form-horizontal m" id="form-info-add">
|
||||
<div class="col-xs-6">
|
||||
<div class="form-group">
|
||||
<label class="col-sm-5 control-label is-required">客户编码:</label>
|
||||
<label class="col-sm-5 control-label ">客户编码:</label>
|
||||
<div class="col-sm-7">
|
||||
<input name="customerCode" class="form-control" type="text" required>
|
||||
<input name="customerCode" class="form-control" type="text" readonly placeholder="自动生成">
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
|
|
|||
|
|
@ -12,7 +12,7 @@
|
|||
<div class="form-group">
|
||||
<label class="col-sm-5 control-label is-required">客户编码:</label>
|
||||
<div class="col-sm-7">
|
||||
<input name="customerCode" th:field="*{customerCode}" class="form-control" type="text" required>
|
||||
<input name="customerCode" th:field="*{customerCode}" class="form-control" type="text" readonly required>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
|
|
|||
|
|
@ -171,7 +171,7 @@ public class InventoryOuterController extends BaseController
|
|||
|
||||
@PostMapping("/importData")
|
||||
@ResponseBody
|
||||
public AjaxResult importTemplate(@RequestPart("file") MultipartFile file, @RequestParam(value = "productCode") String productCode) {
|
||||
public AjaxResult importTemplate(@RequestPart("file") MultipartFile file, @RequestParam(value = "productCode") String productCode,@RequestParam(value = "quantity") Long quantity) {
|
||||
ExcelUtil<InventoryInfoExcelDto> util = new ExcelUtil<InventoryInfoExcelDto>(InventoryInfoExcelDto.class);
|
||||
|
||||
try (InputStream inputStream = file.getInputStream()) {
|
||||
|
|
@ -179,7 +179,10 @@ public class InventoryOuterController extends BaseController
|
|||
if (CollUtil.isEmpty(inventoryInfoExcelDtoList)){
|
||||
return AjaxResult.error("导入数据为空");
|
||||
}
|
||||
innerService.importByOuter(inventoryInfoExcelDtoList, productCode);
|
||||
if (inventoryInfoExcelDtoList.size()!=quantity.intValue()){
|
||||
return AjaxResult.error("导入数据应等于发货数量");
|
||||
}
|
||||
return AjaxResult.success(innerService.getInventoryInfoList(inventoryInfoExcelDtoList, productCode));
|
||||
|
||||
} catch (IOException e) {
|
||||
throw new ServiceException("读取excel错误,请联系管理员");
|
||||
|
|
@ -187,8 +190,6 @@ public class InventoryOuterController extends BaseController
|
|||
return AjaxResult.error(e.getMessage());
|
||||
}
|
||||
|
||||
|
||||
return AjaxResult.success();
|
||||
}
|
||||
|
||||
|
||||
|
|
|
|||
|
|
@ -73,6 +73,7 @@ public class InventoryDelivery extends BaseEntity
|
|||
|
||||
private String deliveryStatus;
|
||||
private List<String> productSnList;
|
||||
private List<InventoryInfo> productSnDataList;
|
||||
|
||||
|
||||
|
||||
|
|
|
|||
|
|
@ -18,10 +18,15 @@ import com.ruoyi.sip.flowable.service.TodoService;
|
|||
import com.ruoyi.system.service.ISysUserService;
|
||||
import lombok.SneakyThrows;
|
||||
import org.apache.commons.lang3.ObjectUtils;
|
||||
import org.flowable.common.engine.api.delegate.Expression;
|
||||
import org.flowable.common.engine.api.delegate.event.FlowableEngineEntityEvent;
|
||||
import org.flowable.common.engine.impl.el.ExpressionManager;
|
||||
import org.flowable.common.engine.impl.el.JuelExpression;
|
||||
import org.flowable.engine.RepositoryService;
|
||||
import org.flowable.engine.RuntimeService;
|
||||
import org.flowable.engine.TaskService;
|
||||
import org.flowable.engine.delegate.event.AbstractFlowableEngineEventListener;
|
||||
import org.flowable.engine.delegate.event.FlowableMultiInstanceActivityCompletedEvent;
|
||||
import org.flowable.engine.delegate.event.FlowableMultiInstanceActivityEvent;
|
||||
import org.flowable.engine.delegate.event.FlowableProcessStartedEvent;
|
||||
import org.flowable.engine.delegate.event.impl.FlowableEntityWithVariablesEventImpl;
|
||||
|
|
@ -35,6 +40,7 @@ import org.slf4j.LoggerFactory;
|
|||
import org.springframework.beans.factory.annotation.Autowired;
|
||||
import org.springframework.stereotype.Component;
|
||||
|
||||
import javax.annotation.Resource;
|
||||
import java.lang.reflect.Method;
|
||||
import java.util.*;
|
||||
import java.util.stream.Collectors;
|
||||
|
|
@ -88,6 +94,53 @@ public class ProcessListener extends AbstractFlowableEngineEventListener {
|
|||
super.multiInstanceActivityStarted(event);
|
||||
}
|
||||
|
||||
@SneakyThrows
|
||||
@Override
|
||||
protected void multiInstanceActivityCompletedWithCondition(FlowableMultiInstanceActivityCompletedEvent event) {
|
||||
if ("userTask".equals(event.getActivityType())) {
|
||||
log.info("多实例任务完成 start--------");
|
||||
String processInstanceId = event.getProcessInstanceId();
|
||||
ProcessInstance processInstance = runtimeService.createProcessInstanceQuery().processInstanceId(processInstanceId).singleResult();
|
||||
|
||||
{
|
||||
List<Todo> todos = todoService.selectTodoListByProcessInstanceId(new Todo().setProcessInstanceId(processInstanceId));
|
||||
if (ObjectUtils.isNotEmpty(todos)) {
|
||||
String ids = todos.stream().map(Todo::getTodoId).map(String::valueOf).collect(Collectors.joining(","));
|
||||
todoService.deleteTodoByIds(ids);
|
||||
log.error("待办任务删除成功 {}", ids);
|
||||
}
|
||||
// 处理业务回调 - 添加默认回调逻辑
|
||||
Instance instance = processConfig.getInstance();
|
||||
String processDefinitionId = processInstance.getProcessDefinitionKey();
|
||||
|
||||
try {
|
||||
Method method1 = BeanUtils.findMethod(instance.getClass(),
|
||||
"get" + processDefinitionId.substring(0, 1).toUpperCase() + processDefinitionId.substring(1));
|
||||
if (method1 != null) {
|
||||
// 默认多实例回调
|
||||
TodoCommonTemplate todoExecuteInstance = todoService.getTodoExecuteInstance(
|
||||
new Todo().setProcessKey(processDefinitionId));
|
||||
if (todoExecuteInstance != null) {
|
||||
Method multiInstanceCallbackMethod = BeanUtils.findMethod(
|
||||
todoExecuteInstance.getClass(), "multiInstanceApproveCallback", String.class,ProcessInstance.class);
|
||||
if (multiInstanceCallbackMethod != null) {
|
||||
multiInstanceCallbackMethod.invoke(todoExecuteInstance, event.getActivityName(),processInstance);
|
||||
log.error("默认多实例回调执行成功");
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
} catch (Exception e) {
|
||||
log.error("多实例回调执行异常", e);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
super.multiInstanceActivityCompletedWithCondition(event);
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void taskCreated(FlowableEngineEntityEvent event) {
|
||||
|
||||
|
|
@ -127,11 +180,10 @@ public class ProcessListener extends AbstractFlowableEngineEventListener {
|
|||
if(!"noTodo".equals(taskEntity.getCategory())) {
|
||||
List<Todo> todos = todoService.selectTodoListByProcessInstanceId(new Todo().setProcessInstanceId(taskEntity.getProcessInstanceId()));
|
||||
if (ObjectUtils.isNotEmpty(todos)) {
|
||||
String ids = todos.stream().map(Todo::getTodoId).map(String::valueOf).collect(Collectors.joining(","));
|
||||
Integer btn = null;
|
||||
todoService.deleteTodoByIds(ids);
|
||||
log.error("待办任务删除成功 {}", ids);
|
||||
Todo todo = todos.stream().filter(d -> d.getTaskId().equals(taskEntity.getId())).findFirst().get();
|
||||
todoService.deleteTodoByIds(String.valueOf(todo.getTodoId()));
|
||||
log.error("待办任务删除成功 {}", todo.getId());
|
||||
if (event instanceof FlowableEntityWithVariablesEventImpl) {
|
||||
Map variables = ((FlowableEntityWithVariablesEventImpl) event).getVariables();
|
||||
log.error("variables {}", ObjectUtils.isNotEmpty(variables) ? JSON.toJSONString(variables) : "无数据");
|
||||
|
|
|
|||
|
|
@ -2,6 +2,7 @@ package com.ruoyi.sip.flowable.service;
|
|||
|
||||
|
||||
import com.ruoyi.sip.flowable.domain.Todo;
|
||||
import org.flowable.engine.runtime.ProcessInstance;
|
||||
|
||||
/**
|
||||
* 流程相关接口模板定义
|
||||
|
|
@ -39,6 +40,10 @@ public interface TodoCommonTemplate {
|
|||
//默认实现
|
||||
return true;
|
||||
}
|
||||
default boolean multiInstanceApproveCallback(String activityName,ProcessInstance processInstance) {
|
||||
//默认实现
|
||||
return true;
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
|
|
|
|||
|
|
@ -61,4 +61,6 @@ public interface CustomerInfoMapper
|
|||
*/
|
||||
public int deleteCustomerInfoByIds(String[] ids);
|
||||
public int selectCountByCode(CustomerInfo customerInfo);
|
||||
|
||||
int selectMaxByPrefix(String province);
|
||||
}
|
||||
|
|
|
|||
|
|
@ -70,4 +70,5 @@ public interface InventoryInfoMapper
|
|||
List<InventoryInfo> countBySn(List<String> productSnList);
|
||||
|
||||
void deleteInventoryInfoByInnerIds(String[] idArray);
|
||||
List<InventoryInfo> listInventoryInfoByInnerIds(String[] idArray);
|
||||
}
|
||||
|
|
|
|||
|
|
@ -2,6 +2,7 @@ package com.ruoyi.sip.service;
|
|||
|
||||
import java.util.List;
|
||||
|
||||
import com.ruoyi.sip.domain.InventoryInfo;
|
||||
import com.ruoyi.sip.domain.OmsInventoryInner;
|
||||
import com.ruoyi.sip.dto.inventory.InventoryInfoExcelDto;
|
||||
|
||||
|
|
@ -62,5 +63,6 @@ public interface IOmsInventoryInnerService
|
|||
public int deleteOmsInventoryInnerById(Long id);
|
||||
|
||||
|
||||
void importByOuter(List<InventoryInfoExcelDto> inventoryInfoExcelDtoList, String productCode);
|
||||
void importByOuter(List<InventoryInfo> inventoryInfoList,String productCode);
|
||||
List<InventoryInfo> getInventoryInfoList(List<InventoryInfoExcelDto> inventoryInfoExcelDtoList, String productCode);
|
||||
}
|
||||
|
|
|
|||
|
|
@ -2,10 +2,14 @@ package com.ruoyi.sip.service.impl;
|
|||
|
||||
import java.util.List;
|
||||
|
||||
import cn.hutool.core.collection.CollUtil;
|
||||
import com.ruoyi.common.exception.ServiceException;
|
||||
import com.ruoyi.common.utils.ShiroUtils;
|
||||
import com.ruoyi.common.utils.StringUtils;
|
||||
import com.ruoyi.sip.domain.Cnarea;
|
||||
import com.ruoyi.sip.domain.CustomerInfo;
|
||||
import com.ruoyi.sip.mapper.CustomerInfoMapper;
|
||||
import com.ruoyi.sip.service.ICnareaService;
|
||||
import com.ruoyi.sip.service.ICustomerInfoService;
|
||||
import org.springframework.beans.factory.annotation.Autowired;
|
||||
import org.springframework.stereotype.Service;
|
||||
|
|
@ -23,7 +27,8 @@ public class CustomerInfoServiceImpl implements ICustomerInfoService
|
|||
{
|
||||
@Autowired
|
||||
private CustomerInfoMapper customerInfoMapper;
|
||||
|
||||
@Autowired
|
||||
private ICnareaService cnareaService;
|
||||
/**
|
||||
* 查询客户信息
|
||||
*
|
||||
|
|
@ -58,6 +63,7 @@ public class CustomerInfoServiceImpl implements ICustomerInfoService
|
|||
public int insertCustomerInfo(CustomerInfo customerInfo)
|
||||
{
|
||||
customerInfo.setCreateBy(ShiroUtils.getUserId().toString());
|
||||
customerInfo.setCustomerCode(generateCode(customerInfo.getProvince()));
|
||||
int i = customerInfoMapper.selectCountByCode(customerInfo);
|
||||
if (i > 0){
|
||||
throw new ServiceException("客户编码已存在");
|
||||
|
|
@ -65,6 +71,28 @@ public class CustomerInfoServiceImpl implements ICustomerInfoService
|
|||
return customerInfoMapper.insertCustomerInfo(customerInfo);
|
||||
}
|
||||
|
||||
private String generateCode(String province) {
|
||||
if (StringUtils.isEmpty(province)) {
|
||||
throw new ServiceException("客户所属省为空,无法生成客户编码");
|
||||
}
|
||||
Cnarea cnarea = new Cnarea();
|
||||
cnarea.setName(province);
|
||||
cnarea.setLevel("1");
|
||||
List<Cnarea> cnareas = cnareaService.queryAll(cnarea);
|
||||
if (CollUtil.isEmpty(cnareas)) {
|
||||
throw new ServiceException("省市未配置,生成订单编号出错,请联系管理员");
|
||||
}
|
||||
String shortCode = cnareas.get(0).getShortCode();
|
||||
StringBuilder result = new StringBuilder();
|
||||
result.append("CU-");
|
||||
result.append(shortCode);
|
||||
result.append("-");
|
||||
int count = customerInfoMapper.selectMaxByPrefix(result.toString());
|
||||
// 生成顺序编码,不足四位补零
|
||||
String sequence = String.format("%04d", count + 1);
|
||||
result.append(sequence);
|
||||
return result.toString();
|
||||
}
|
||||
/**
|
||||
* 修改客户信息
|
||||
*
|
||||
|
|
@ -75,10 +103,35 @@ public class CustomerInfoServiceImpl implements ICustomerInfoService
|
|||
public int updateCustomerInfo(CustomerInfo customerInfo)
|
||||
{
|
||||
customerInfo.setUpdateBy(ShiroUtils.getUserId().toString());
|
||||
int i = customerInfoMapper.selectCountByCode(customerInfo);
|
||||
if (i > 0){
|
||||
|
||||
// 检查客户编码是否已存在(排除当前记录)
|
||||
// CustomerInfo queryParam = new CustomerInfo();
|
||||
// queryParam.setCustomerCode(customerInfo.getCustomerCode());
|
||||
// List<CustomerInfo> customerInfoList = customerInfoMapper.selectCustomerInfoList(queryParam);
|
||||
//
|
||||
// if (CollUtil.isNotEmpty(customerInfoList)) {
|
||||
// CustomerInfo existInfo = customerInfoList.get(0);
|
||||
// // 如果编码已存在且不是当前正在更新的记录,则抛出异常
|
||||
// if (!existInfo.getId().equals(customerInfo.getId())) {
|
||||
// throw new ServiceException("客户编码已存在");
|
||||
// }
|
||||
// }
|
||||
|
||||
// 如果省份发生变化,需要重新生成客户编码
|
||||
CustomerInfo oldCustomerInfo = customerInfoMapper.selectCustomerInfoById(customerInfo.getId());
|
||||
if (oldCustomerInfo != null && !oldCustomerInfo.getProvince().equals(customerInfo.getProvince())) {
|
||||
String newCustomerCode = generateCode(customerInfo.getProvince());
|
||||
customerInfo.setCustomerCode(newCustomerCode);
|
||||
|
||||
// 检查新生成的编码是否已存在
|
||||
CustomerInfo codeCheckParam = new CustomerInfo();
|
||||
codeCheckParam.setCustomerCode(newCustomerCode);
|
||||
int count = customerInfoMapper.selectCountByCode(codeCheckParam);
|
||||
if (count > 0) {
|
||||
throw new ServiceException("客户编码已存在");
|
||||
}
|
||||
}
|
||||
|
||||
return customerInfoMapper.updateCustomerInfo(customerInfo);
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -2,6 +2,7 @@ package com.ruoyi.sip.service.impl;
|
|||
|
||||
|
||||
import cn.hutool.core.collection.CollUtil;
|
||||
import com.ruoyi.common.exception.ServiceException;
|
||||
import com.ruoyi.sip.domain.*;
|
||||
import com.ruoyi.sip.dto.inventory.ProductDetail;
|
||||
import com.ruoyi.sip.dto.inventory.ProductWarehouseInfo;
|
||||
|
|
@ -182,9 +183,15 @@ public class ExecutionTrackServiceImpl implements IExecutionTrackService {
|
|||
}
|
||||
// 如果仍有未满足的需求,尝试使用默认仓库
|
||||
if (remainingQuantity > 0) {
|
||||
List<ProductInfo> productInfoList = productInfoService.selectProductInfoByCodeList(Collections.singletonList(productCode));
|
||||
if (CollUtil.isEmpty(productInfoList)) {
|
||||
throw new ServiceException("产品编码对应产品未找到");
|
||||
}
|
||||
ProductInfo productInfo = productInfoList.get(0);
|
||||
List<VendorInfo> currentVendors = inventoryAuthService.currentVendor();
|
||||
if (CollUtil.isNotEmpty(currentVendors)) {
|
||||
VendorInfo defaultVendor = currentVendors.get(0);
|
||||
boolean vendorAuthFlag = currentVendors.stream().anyMatch(item -> item.getVendorCode().equals(productInfo.getVendorCode()));
|
||||
if (CollUtil.isNotEmpty(currentVendors) && vendorAuthFlag) {
|
||||
VendorInfo defaultVendor = currentVendors.stream().filter(item -> item.getVendorCode().equals(productInfo.getVendorCode())).findFirst().orElseThrow(() -> new ServiceException("制造商未授权"));
|
||||
|
||||
// 检查默认仓库是否已经在列表中
|
||||
boolean defaultVendorInList = productWarehouseInfoList.stream()
|
||||
|
|
@ -196,8 +203,7 @@ public class ExecutionTrackServiceImpl implements IExecutionTrackService {
|
|||
defaultWarehouseInfo.setWarehouseId(defaultVendor.getWarehouseId());
|
||||
defaultWarehouseInfo.setWarehouseName(defaultVendor.getWarehouseName());
|
||||
// 这里假设默认仓库有足够库存,实际应用中可能需要查询具体库存
|
||||
List<ProductInfo> productInfos = productInfoService.selectProductInfoByCodeList(Collections.singletonList(productCode));
|
||||
defaultWarehouseInfo.setAvailableCount(productInfos.get(0).getAvailableCount() == null ? 0L : productInfos.get(0).getAvailableCount());
|
||||
defaultWarehouseInfo.setAvailableCount(productInfo.getAvailableCount() == null ? 0L : productInfo.getAvailableCount());
|
||||
defaultWarehouseInfo.setConfirmQuantity((long) remainingQuantity);
|
||||
defaultWarehouseInfo.setDefaultWarehouse(true);
|
||||
productWarehouseInfoList.add(defaultWarehouseInfo);
|
||||
|
|
|
|||
|
|
@ -35,6 +35,8 @@ public class InventoryDeliveryServiceImpl implements IInventoryDeliveryService {
|
|||
private InventoryDeliveryMapper inventoryDeliveryMapper;
|
||||
@Autowired
|
||||
private IInventoryInfoService inventoryInfoService;
|
||||
@Autowired
|
||||
private IOmsInventoryInnerService omsInventoryInnerService;
|
||||
@Resource
|
||||
private InventoryOuterMapper inventoryOuterMapper;
|
||||
@Autowired
|
||||
|
|
@ -74,27 +76,42 @@ public class InventoryDeliveryServiceImpl implements IInventoryDeliveryService {
|
|||
*/
|
||||
@Override
|
||||
public int insertInventoryDelivery(InventoryDelivery inventoryDelivery) {
|
||||
inventoryDelivery.setCreateTime(DateUtils.getNowDate());
|
||||
|
||||
Date nowDate = DateUtils.getNowDate();
|
||||
inventoryDelivery.setCreateTime(nowDate);
|
||||
String currentUserId = ShiroUtils.getUserId().toString();
|
||||
inventoryDelivery.setCreateBy(currentUserId);
|
||||
inventoryDelivery.setCreateTime(DateUtils.getNowDate());
|
||||
inventoryDelivery.setCreateTime(nowDate);
|
||||
inventoryDelivery.setUpdateBy(currentUserId);
|
||||
inventoryDelivery.setUpdateTime(DateUtils.getNowDate());
|
||||
inventoryDelivery.setUpdateTime(nowDate);
|
||||
inventoryDelivery.setDeliveryStatus(InventoryDelivery.DeliveryStatusEnum.WAIT_DELIVERY.getCode());
|
||||
//处理库存
|
||||
List<String> productSnList = inventoryDelivery.getProductSnList();
|
||||
if (CollUtil.isEmpty(productSnList)) {
|
||||
List<InventoryInfo> productSnDataList = inventoryDelivery.getProductSnDataList();
|
||||
if (CollUtil.isEmpty(productSnList) && CollUtil.isEmpty(productSnDataList)) {
|
||||
throw new ServiceException("发货清单为空,保存失败");
|
||||
}
|
||||
|
||||
if (CollUtil.isEmpty(productSnDataList)) {
|
||||
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);
|
||||
info.setUpdateTime(nowDate);
|
||||
return info;
|
||||
}).collect(Collectors.toList());
|
||||
inventoryInfoService.saveBatch(inventoryInfoList);
|
||||
}else{
|
||||
for (InventoryInfo inventoryInfo : productSnDataList) {
|
||||
inventoryInfo.setInventoryStatus(InventoryInfo.InventoryStatusEnum.OUTER.getCode());
|
||||
inventoryInfo.setOuterCode(inventoryDelivery.getOuterCode());
|
||||
inventoryInfo.setUpdateBy(currentUserId);
|
||||
inventoryInfo.setUpdateTime(nowDate);
|
||||
}
|
||||
omsInventoryInnerService.importByOuter(productSnDataList,inventoryDelivery.getProductCode());
|
||||
}
|
||||
return inventoryDeliveryMapper.insertInventoryDelivery(inventoryDelivery);
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -20,6 +20,7 @@ import com.ruoyi.sip.vo.DeliveryInfoVo;
|
|||
import liquibase.pro.packaged.O;
|
||||
import org.springframework.beans.factory.annotation.Autowired;
|
||||
import org.springframework.stereotype.Service;
|
||||
import org.springframework.transaction.annotation.Transactional;
|
||||
|
||||
import java.util.Collections;
|
||||
import java.util.List;
|
||||
|
|
@ -34,6 +35,7 @@ import java.util.stream.Collectors;
|
|||
* @date 2025-08-07
|
||||
*/
|
||||
@Service
|
||||
@Transactional(rollbackFor = Exception.class)
|
||||
public class InventoryInfoServiceImpl implements IInventoryInfoService {
|
||||
@Autowired
|
||||
private InventoryInfoMapper inventoryInfoMapper;
|
||||
|
|
@ -186,6 +188,12 @@ public class InventoryInfoServiceImpl implements IInventoryInfoService {
|
|||
|
||||
@Override
|
||||
public void deleteInventoryInfoByInnerIds(String[] idArray) {
|
||||
List<InventoryInfo> inventoryInfos = inventoryInfoMapper.listInventoryInfoByInnerIds(idArray);
|
||||
Map<String, List<InventoryInfo>> listMap = inventoryInfos.stream().collect(Collectors.groupingBy(InventoryInfo::getProductCode));
|
||||
for (Map.Entry<String, List<InventoryInfo>> entry : listMap.entrySet()) {
|
||||
//此处删除 应该只有一个productCode
|
||||
productInfoService.updateAvailableCount((long) -entry.getValue().size(),entry.getKey());
|
||||
}
|
||||
inventoryInfoMapper.deleteInventoryInfoByInnerIds(idArray);
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -175,7 +175,19 @@ public class OmsInventoryInnerServiceImpl implements IOmsInventoryInnerService {
|
|||
}
|
||||
|
||||
@Override
|
||||
public void importByOuter(List<InventoryInfoExcelDto> inventoryInfoExcelDtoList, String productCode) {
|
||||
public void importByOuter(List<InventoryInfo> inventoryInfoList,String productCode) {
|
||||
List<ProductInfo> productInfos = productInfoService.selectProductInfoByCodeList(Collections.singletonList(productCode));
|
||||
OmsInventoryInner omsInventoryInner = new OmsInventoryInner();
|
||||
omsInventoryInner.setVendorCode(productInfos.get(0).getVendorCode());
|
||||
omsInventoryInner.setProductCode(productCode);
|
||||
omsInventoryInner.setWarehouseId(inventoryInfoList.get(0).getWarehouseId());
|
||||
omsInventoryInner.setInventoryInfoList(inventoryInfoList);
|
||||
this.insertOmsInventoryInner(omsInventoryInner);
|
||||
|
||||
}
|
||||
|
||||
@Override
|
||||
public List<InventoryInfo> getInventoryInfoList(List<InventoryInfoExcelDto> inventoryInfoExcelDtoList, String productCode) {
|
||||
long count = inventoryInfoExcelDtoList.stream().filter(item -> !item.getProductCode().equals(productCode)).count();
|
||||
if (count > 0){
|
||||
throw new ServiceException("导入清单的产品与出库单不符");
|
||||
|
|
@ -184,6 +196,10 @@ public class OmsInventoryInnerServiceImpl implements IOmsInventoryInnerService {
|
|||
if (warehouseNameList.size() > 1){
|
||||
throw new ServiceException("导入清单只能有一个仓库");
|
||||
}
|
||||
List<ProductInfo> productInfos = productInfoService.selectProductInfoByCodeList(Collections.singletonList(productCode));
|
||||
if (CollUtil.isEmpty(productInfos)){
|
||||
throw new ServiceException("产品编码对应产品未找到");
|
||||
}
|
||||
List<OmsWarehouseInfo> warehouseInfoList = warehouseInfoService.listByNameList(warehouseNameList);
|
||||
Map<String, OmsWarehouseInfo> warehouseInfoMap = warehouseInfoList.stream().collect(Collectors.toMap(OmsWarehouseInfo::getWarehouseName, Function.identity(), (v1, v2) -> v1));
|
||||
List<InventoryInfo> inventoryInfoList = inventoryInfoExcelDtoList.stream().map(item -> {
|
||||
|
|
@ -191,23 +207,23 @@ public class OmsInventoryInnerServiceImpl implements IOmsInventoryInnerService {
|
|||
info.setInventoryStatus(InventoryInfo.InventoryStatusEnum.INNER.getCode());
|
||||
info.setProductSn(item.getProductSn());
|
||||
info.setProductCode(productCode);
|
||||
info.setModel(productInfos.get(0).getModel());
|
||||
info.setProductDesc(productInfos.get(0).getDescription());
|
||||
info.setInnerPrice(item.getInnerPrice());
|
||||
OmsWarehouseInfo omsWarehouseInfo = warehouseInfoMap.get(item.getWarehouseName());
|
||||
if (omsWarehouseInfo == null){
|
||||
throw new ServiceException("仓库未找到,导入失败");
|
||||
}
|
||||
info.setWarehouseId(omsWarehouseInfo.getId());
|
||||
info.setWarehouseName(omsWarehouseInfo.getWarehouseName());
|
||||
|
||||
return info;
|
||||
}).collect(Collectors.toList());
|
||||
List<ProductInfo> productInfos = productInfoService.selectProductInfoByCodeList(Collections.singletonList(productCode));
|
||||
OmsInventoryInner omsInventoryInner = new OmsInventoryInner();
|
||||
omsInventoryInner.setVendorCode(productInfos.get(0).getVendorCode());
|
||||
omsInventoryInner.setProductCode(productCode);
|
||||
omsInventoryInner.setWarehouseId(warehouseInfoList.get(0).getId());
|
||||
omsInventoryInner.setInventoryInfoList(inventoryInfoList);
|
||||
this.insertOmsInventoryInner(omsInventoryInner);
|
||||
|
||||
List<String> repeatSnList = inventoryInfoService.checkUnq(inventoryInfoList.stream().map(InventoryInfo::getProductSn).collect(Collectors.toList()));
|
||||
if (CollUtil.isNotEmpty(repeatSnList)) {
|
||||
throw new ServiceException(StrUtil.format("SN码[{}]已存在,导入失败", repeatSnList));
|
||||
}
|
||||
return inventoryInfoList;
|
||||
}
|
||||
|
||||
|
||||
|
|
|
|||
|
|
@ -1033,14 +1033,25 @@ public class ProjectOrderInfoServiceImpl implements IProjectOrderInfoService, To
|
|||
// 审批通过处理
|
||||
if ("产品经理".equals(taskName)) {
|
||||
handleProductManagerApproval(businessKey);
|
||||
} else if ("公司领导".equals(taskName)) {
|
||||
handleCompanyLeaderApproval(businessKey);
|
||||
}
|
||||
}
|
||||
|
||||
return TodoCommonTemplate.super.todoApproveCallback(todo);
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean multiInstanceApproveCallback(String activityName,ProcessInstance processInstance) {
|
||||
String flowBusinessKey = processInstance.getBusinessKey();
|
||||
String[] split = flowBusinessKey.split("#");
|
||||
String businessKey = split.length > 1 ? split[1] : split[0];
|
||||
Map<String, Object> processVariables = processInstance.getProcessVariables();
|
||||
Integer approveBtn = (Integer) processVariables.get("approveBtn");
|
||||
if ("公司领导".equals(activityName) && approveBtn == 1) {
|
||||
handleCompanyLeaderApproval(businessKey);
|
||||
}
|
||||
|
||||
return TodoCommonTemplate.super.multiInstanceApproveCallback(activityName,processInstance);
|
||||
}
|
||||
|
||||
/**
|
||||
* 处理订单驳回
|
||||
|
|
|
|||
|
|
@ -73,6 +73,14 @@ PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN"
|
|||
#{item}
|
||||
</foreach>
|
||||
</select>
|
||||
<select id="listInventoryInfoByInnerIds" resultType="com.ruoyi.sip.domain.InventoryInfo">
|
||||
select product_code from oms_inventory_info where inner_code in (
|
||||
select inner_code from oms_inventory_inner where id in
|
||||
<foreach item="id" collection="array" open="(" separator="," close=")">
|
||||
#{id}
|
||||
</foreach>
|
||||
)
|
||||
</select>
|
||||
|
||||
|
||||
<insert id="insertInventoryInfo" parameterType="InventoryInfo" useGeneratedKeys="true" keyProperty="id">
|
||||
|
|
|
|||
|
|
@ -67,6 +67,14 @@ PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN"
|
|||
select count(1) from customer_info where customer_code = #{customerCode} and status=0
|
||||
<if test="id != null">and id != #{id}</if>
|
||||
</select>
|
||||
<select id="selectMaxByPrefix" resultType="java.lang.Integer">
|
||||
|
||||
select ifnull(max(SUBSTR(customer_code FROM LENGTH(#{prefix}) + 1 FOR 4)), 0)
|
||||
from customer_info
|
||||
WHERE customer_code like concat(#{prefix}, '%');
|
||||
|
||||
|
||||
</select>
|
||||
|
||||
<insert id="insertCustomerInfo" parameterType="CustomerInfo">
|
||||
insert into customer_info
|
||||
|
|
|
|||
Loading…
Reference in New Issue