package com.zy.asrs.controller;
|
|
import com.baomidou.mybatisplus.annotations.TableField;
|
import com.baomidou.mybatisplus.mapper.EntityWrapper;
|
import com.baomidou.mybatisplus.plugins.Page;
|
import com.core.common.Cools;
|
import com.core.common.R;
|
import com.core.annotations.ManagerAuth;
|
import com.zy.asrs.entity.MaterialReceive;
|
import com.zy.asrs.service.MaterialReceiveService;
|
import com.zy.common.web.BaseController;
|
import org.springframework.beans.factory.annotation.Autowired;
|
import org.springframework.web.bind.annotation.*;
|
import com.core.common.DateUtils;
|
import java.lang.reflect.Field;
|
import java.math.BigDecimal;
|
import java.util.ArrayList;
|
import java.util.Date;
|
import java.util.HashMap;
|
import java.util.List;
|
import java.util.Map;
|
|
@RestController
|
public class MaterialReceiveController extends BaseController {
|
|
@Autowired
|
private MaterialReceiveService materialReceiveService;
|
|
@RequestMapping(value = "/materialReceive/{id}/auth")
|
@ManagerAuth
|
public R get(@PathVariable("id") String id) {
|
return R.ok(materialReceiveService.selectById(String.valueOf(id)));
|
}
|
|
@RequestMapping(value = "/materialReceive/list/auth")
|
@ManagerAuth
|
public R list(@RequestParam(defaultValue = "1") Integer curr,
|
@RequestParam(defaultValue = "1000") Integer limit,
|
@RequestParam(required = false) String orderByField,
|
@RequestParam(required = false) String orderByType,
|
@RequestParam(required = false) String condition,
|
@RequestParam(required = false) Boolean pdaQuery,
|
@RequestParam Map<String, Object> param) {
|
EntityWrapper<MaterialReceive> wrapper = new EntityWrapper<>();
|
excludeTrash(param);
|
// 移除pdaQuery参数,因为它不是数据库字段,只是控制参数
|
param.remove("pdaQuery");
|
convert(param, wrapper);
|
allLike(MaterialReceive.class, param.keySet(), wrapper, condition);
|
|
// 参考其他出库模块,PDA出库查询时过滤掉已全部出库的物料(只显示还有剩余数量的)
|
// 通过 pdaQuery 参数判断是否是PDA出库查询
|
if (pdaQuery != null && pdaQuery) {
|
// PDA出库查询:只显示剩余数量大于0的记录
|
wrapper.gt("remain_qty", 0);
|
}
|
|
if (!Cools.isEmpty(orderByField)) {
|
wrapper.orderBy(humpToLine(orderByField), "asc".equals(orderByType));
|
}
|
return R.ok(materialReceiveService.selectPage(new Page<>(curr, limit), wrapper));
|
}
|
|
@RequestMapping(value = "/materialReceive/batchSave/auth", method = RequestMethod.POST)
|
@ManagerAuth
|
public R batchSave(@RequestBody List<Map<String, Object>> dataList) {
|
if (Cools.isEmpty(dataList)) {
|
return R.error("数据不能为空");
|
}
|
int successCount = 0;
|
int updateCount = 0;
|
for (Map<String, Object> data : dataList) {
|
try {
|
// 检查是否已存在(根据soCode和invCode和finterid唯一标识)
|
String soCode = data.get("soCode") != null ? String.valueOf(data.get("soCode")) : null;
|
String invCode = data.get("invCode") != null ? String.valueOf(data.get("invCode")) : null;
|
Integer finterid = null;
|
if (data.get("finterid") != null) {
|
try {
|
finterid = Integer.valueOf(String.valueOf(data.get("finterid")));
|
} catch (Exception e) {
|
// 忽略转换错误
|
}
|
}
|
|
MaterialReceive existRecord = null;
|
if (soCode != null && invCode != null && finterid != null) {
|
existRecord = materialReceiveService.selectOne(new EntityWrapper<MaterialReceive>()
|
.eq("so_code", soCode)
|
.eq("inv_code", invCode)
|
.eq("finterid", finterid));
|
}
|
|
MaterialReceive materialReceive;
|
if (existRecord != null) {
|
// 已存在,更新数据(不覆盖出库相关字段)
|
materialReceive = existRecord;
|
updateCount++;
|
} else {
|
// 不存在,创建新记录
|
materialReceive = new MaterialReceive();
|
materialReceive.setCreateTime(new Date());
|
// 初始化出库相关字段
|
materialReceive.setOutQty(BigDecimal.ZERO);
|
materialReceive.setRemainQty(data.get("qty") != null ?
|
new BigDecimal(String.valueOf(data.get("qty"))) : BigDecimal.ZERO);
|
materialReceive.setIsAllOut(0);
|
successCount++;
|
}
|
|
// 更新/设置字段
|
materialReceive.setSoCode(soCode);
|
materialReceive.setFbillno(data.get("fbillno") != null ? String.valueOf(data.get("fbillno")) : null);
|
materialReceive.setInvCode(invCode);
|
materialReceive.setInvName(data.get("invName") != null ? String.valueOf(data.get("invName")) : null);
|
materialReceive.setInvStd(data.get("invStd") != null ? String.valueOf(data.get("invStd")) : null);
|
|
// 数量字段处理(优先使用fqty,如果没有则使用qty)
|
BigDecimal qty = null;
|
if (data.get("fqty") != null) {
|
qty = new BigDecimal(String.valueOf(data.get("fqty")));
|
materialReceive.setFqty(qty);
|
} else if (data.get("qty") != null) {
|
qty = new BigDecimal(String.valueOf(data.get("qty")));
|
materialReceive.setQty(qty);
|
}
|
|
if (data.get("fauxqty") != null) {
|
materialReceive.setFauxqty(new BigDecimal(String.valueOf(data.get("fauxqty"))));
|
}
|
|
// 如果已存在,更新剩余数量(基于原始数量)
|
if (existRecord == null && qty != null) {
|
materialReceive.setRemainQty(qty);
|
} else if (existRecord != null && qty != null) {
|
// 已存在时,如果数量有变化,重新计算剩余数量
|
BigDecimal originalQty = existRecord.getFqty() != null ? existRecord.getFqty() :
|
(existRecord.getQty() != null ? existRecord.getQty() : BigDecimal.ZERO);
|
BigDecimal outQty = existRecord.getOutQty() != null ? existRecord.getOutQty() : BigDecimal.ZERO;
|
// 如果新数量与原始数量不同,说明数量更新了,需要重新计算剩余数量
|
if (qty.compareTo(originalQty) != 0) {
|
// 数量变化,剩余数量 = 新数量 - 已出库数量
|
materialReceive.setRemainQty(qty.subtract(outQty));
|
} else {
|
// 数量没变化,保持原有剩余数量
|
materialReceive.setRemainQty(existRecord.getRemainQty());
|
}
|
}
|
|
materialReceive.setUnit(data.get("unit") != null ? String.valueOf(data.get("unit")) : null);
|
materialReceive.setDepName(data.get("depName") != null ? String.valueOf(data.get("depName")) : null);
|
materialReceive.setDepCode(data.get("depCode") != null ? String.valueOf(data.get("depCode")) : null);
|
if (data.get("depId") != null) {
|
try {
|
materialReceive.setDepId(Integer.valueOf(String.valueOf(data.get("depId"))));
|
} catch (Exception e) {
|
// 忽略转换错误
|
}
|
}
|
if (data.get("fworkshop") != null) {
|
try {
|
materialReceive.setFworkshop(Integer.valueOf(String.valueOf(data.get("fworkshop"))));
|
} catch (Exception e) {
|
// 忽略转换错误
|
}
|
}
|
if (data.get("whId") != null) {
|
try {
|
materialReceive.setWhId(Integer.valueOf(String.valueOf(data.get("whId"))));
|
} catch (Exception e) {
|
// 忽略转换错误
|
}
|
}
|
materialReceive.setWhName(data.get("whName") != null ? String.valueOf(data.get("whName")) : null);
|
if (data.get("fplancommitdate") != null && !Cools.isEmpty(String.valueOf(data.get("fplancommitdate")))) {
|
try {
|
String dateStr = String.valueOf(data.get("fplancommitdate"));
|
java.text.SimpleDateFormat sdf = new java.text.SimpleDateFormat("yyyy-MM-dd");
|
materialReceive.setFplancommitdate(sdf.parse(dateStr));
|
} catch (Exception ex) {
|
// 忽略日期解析错误
|
}
|
}
|
if (data.get("fplanfinishdate") != null && !Cools.isEmpty(String.valueOf(data.get("fplanfinishdate")))) {
|
try {
|
String dateStr = String.valueOf(data.get("fplanfinishdate"));
|
java.text.SimpleDateFormat sdf = new java.text.SimpleDateFormat("yyyy-MM-dd");
|
materialReceive.setFplanfinishdate(sdf.parse(dateStr));
|
} catch (Exception ex) {
|
// 忽略日期解析错误
|
}
|
}
|
if (finterid != null) {
|
materialReceive.setFinterid(finterid);
|
}
|
if (data.get("fitemid") != null) {
|
try {
|
materialReceive.setFitemid(Integer.valueOf(String.valueOf(data.get("fitemid"))));
|
} catch (Exception e) {
|
// 忽略转换错误
|
}
|
}
|
if (data.get("funitid") != null) {
|
try {
|
materialReceive.setFunitid(Integer.valueOf(String.valueOf(data.get("funitid"))));
|
} catch (Exception e) {
|
// 忽略转换错误
|
}
|
}
|
|
// 将其他字段存储到ext_data(JSON格式),用于校验生产领料出库数量
|
Map<String, Object> extDataMap = new HashMap<>();
|
// 已映射到数据库表字段的字段列表(这些字段不需要存储在ext_data中)
|
java.util.Set<String> mappedFields = new java.util.HashSet<>();
|
mappedFields.add("soCode");
|
mappedFields.add("fbillno");
|
mappedFields.add("invCode");
|
mappedFields.add("invName");
|
mappedFields.add("invStd");
|
mappedFields.add("qty");
|
mappedFields.add("fqty");
|
mappedFields.add("fauxqty");
|
mappedFields.add("unit");
|
mappedFields.add("depName");
|
mappedFields.add("depCode");
|
mappedFields.add("depId");
|
mappedFields.add("fworkshop");
|
mappedFields.add("whId");
|
mappedFields.add("whName");
|
mappedFields.add("fplancommitdate");
|
mappedFields.add("fplanfinishdate");
|
mappedFields.add("finterid");
|
mappedFields.add("fitemid");
|
mappedFields.add("funitid");
|
|
// 将所有未映射的字段存储到ext_data中(包含所有打印预览和打印相关的字段)
|
for (Map.Entry<String, Object> entry : data.entrySet()) {
|
String key = entry.getKey();
|
if (!mappedFields.contains(key) && entry.getValue() != null) {
|
extDataMap.put(key, entry.getValue());
|
}
|
}
|
|
// 始终更新ext_data,即使为空也要存储(用于后续扩展)
|
materialReceive.setExtData(com.alibaba.fastjson.JSON.toJSONString(extDataMap));
|
|
materialReceive.setSyncTime(new Date());
|
materialReceive.setUpdateTime(new Date());
|
|
// 保存或更新
|
if (existRecord != null) {
|
materialReceiveService.updateById(materialReceive);
|
} else {
|
materialReceiveService.insert(materialReceive);
|
}
|
} catch (Exception e) {
|
// 记录失败的记录,继续处理下一条
|
e.printStackTrace();
|
}
|
}
|
return R.ok("成功保存 " + successCount + " 条新数据,更新 " + updateCount + " 条已存在数据");
|
}
|
|
@RequestMapping(value = "/materialReceive/update/auth")
|
@ManagerAuth
|
public R update(MaterialReceive materialReceive) {
|
if (Cools.isEmpty(materialReceive) || null == materialReceive.getId()) {
|
return R.error();
|
}
|
materialReceive.setUpdateTime(new Date());
|
materialReceiveService.updateById(materialReceive);
|
return R.ok();
|
}
|
|
@RequestMapping(value = "/materialReceive/updateOutQty/auth", method = RequestMethod.POST)
|
@ManagerAuth
|
public R updateOutQty(@RequestBody Map<String, Object> param) {
|
Long id = Long.valueOf(String.valueOf(param.get("id")));
|
BigDecimal addOutQty = new BigDecimal(String.valueOf(param.get("outQty"))); // 本次出库数量
|
|
MaterialReceive materialReceive = materialReceiveService.selectById(id);
|
if (materialReceive == null) {
|
return R.error("记录不存在");
|
}
|
|
// 累加出库数量
|
BigDecimal currentOutQty = materialReceive.getOutQty() != null ? materialReceive.getOutQty() : BigDecimal.ZERO;
|
BigDecimal newOutQty = currentOutQty.add(addOutQty);
|
materialReceive.setOutQty(newOutQty);
|
|
// 计算剩余数量(优先使用fqty,如果没有则使用qty)
|
BigDecimal qty = materialReceive.getFqty() != null ? materialReceive.getFqty() :
|
(materialReceive.getQty() != null ? materialReceive.getQty() : BigDecimal.ZERO);
|
BigDecimal remainQty = qty.subtract(newOutQty);
|
materialReceive.setRemainQty(remainQty.compareTo(BigDecimal.ZERO) > 0 ? remainQty : BigDecimal.ZERO);
|
|
// 判断是否全部出库完成
|
materialReceive.setIsAllOut(remainQty.compareTo(BigDecimal.ZERO) <= 0 ? 1 : 0);
|
materialReceive.setUpdateTime(new Date());
|
|
materialReceiveService.updateById(materialReceive);
|
return R.ok();
|
}
|
|
@RequestMapping(value = "/materialReceive/checkSyncStatus/auth")
|
@ManagerAuth
|
public R checkSyncStatus(@RequestParam String soCode, @RequestParam(required = false) String invCode, @RequestParam(required = false) String fbillno) {
|
EntityWrapper<MaterialReceive> wrapper = new EntityWrapper<>();
|
wrapper.eq("so_code", soCode);
|
wrapper.eq("fbillno", fbillno);
|
if (!Cools.isEmpty(invCode)) {
|
wrapper.eq("inv_code", invCode);
|
}
|
List<MaterialReceive> list = materialReceiveService.selectList(wrapper);
|
|
Map<String, Object> result = new HashMap<>();
|
if (Cools.isEmpty(list)) {
|
result.put("synced", false);
|
result.put("allOut", false);
|
result.put("message", "该生产单号未同步到WMS");
|
return R.ok(result);
|
}
|
|
// 检查是否全部出库完成
|
boolean allOut = true;
|
List<Map<String, Object>> notOutList = new ArrayList<>();
|
for (MaterialReceive mr : list) {
|
if (mr.getIsAllOut() == null || mr.getIsAllOut() != 1) {
|
allOut = false;
|
Map<String, Object> notOutItem = new HashMap<>();
|
notOutItem.put("invCode", mr.getInvCode());
|
notOutItem.put("invName", mr.getInvName());
|
notOutItem.put("remainQty", mr.getRemainQty());
|
notOutList.add(notOutItem);
|
}
|
}
|
|
result.put("synced", true);
|
result.put("allOut", allOut);
|
result.put("records", list);
|
if (!allOut && !notOutList.isEmpty()) {
|
result.put("notOutList", notOutList);
|
result.put("message", "部分物料未全部出库完成");
|
} else if (allOut) {
|
result.put("message", "全部物料已出库完成");
|
}
|
return R.ok(result);
|
}
|
|
private void convert(Map<String, Object> map, EntityWrapper<MaterialReceive> wrapper) {
|
for (Map.Entry<String, Object> entry : map.entrySet()) {
|
String fieldName = entry.getKey();
|
String columnName = getColumnName(MaterialReceive.class, fieldName);
|
String val = String.valueOf(entry.getValue());
|
if (val.contains(RANGE_TIME_LINK)) {
|
String[] dates = val.split(RANGE_TIME_LINK);
|
wrapper.ge(columnName, DateUtils.convert(dates[0]));
|
wrapper.le(columnName, DateUtils.convert(dates[1]));
|
} else {
|
wrapper.like(columnName, val);
|
}
|
}
|
}
|
|
/**
|
* 根据实体类字段名获取数据库列名
|
* @param cls 实体类
|
* @param fieldName Java字段名(驼峰命名)
|
* @return 数据库列名(下划线命名)
|
*/
|
private String getColumnName(Class<?> cls, String fieldName) {
|
for (Field field : Cools.getAllFields(cls)) {
|
if (field.getName().equals(fieldName)) {
|
if (field.isAnnotationPresent(TableField.class)) {
|
TableField annotation = field.getAnnotation(TableField.class);
|
if (!annotation.exist()) {
|
continue;
|
}
|
String column = annotation.value();
|
if (!Cools.isEmpty(column)) {
|
return column;
|
}
|
}
|
// 如果没有@TableField注解,使用humpToLine转换
|
return humpToLine(fieldName);
|
}
|
}
|
// 如果找不到字段,使用humpToLine转换
|
return humpToLine(fieldName);
|
}
|
|
@RequestMapping(value = "/materialReceive/delete/auth")
|
@ManagerAuth
|
public R delete(@RequestParam String param) {
|
com.alibaba.fastjson.JSONArray jsonArray = com.alibaba.fastjson.JSONArray.parseArray(param);
|
List<MaterialReceive> list = jsonArray.toJavaList(MaterialReceive.class);
|
if (Cools.isEmpty(list)) {
|
return R.error("请选择要删除的数据");
|
}
|
for (MaterialReceive entity : list) {
|
materialReceiveService.deleteById(entity.getId());
|
}
|
return R.ok();
|
}
|
}
|