Commit 73a53585 张少辉

1.增加电子仓损耗报表

1 个父辈 1449ec19
......@@ -213,6 +213,7 @@ public class MenuInit {
addDefaultFunctionMenu(74,pMenuReport, "安全库存", "safetyInventory", "system/safetyInventory/index", "safeInventory");
addDefaultFunctionMenu(75, pMenuReport,"过期物料", "expireMaterials", "system/expireMaterials/index", "sMaterial");
addDefaultFunctionMenu(81,pMenuReport, "物料追踪", "materialChart", "neolight/materialChart/index", "maChart");
addDefaultFunctionMenu(82,pMenuReport, "物料损耗", "lossReport", "report/lossReport/index", "lossReport");
//可观测性:物料追踪
//Menu guanceMenu = Menu.CreatePMenu("可观测性", 10, "observability", "scanKey",null);
//addDefaultFunctionMenu(81,guanceMenu, "物料追踪", "materialChart", "neolight/materialChart/index", "maChart");
......
......@@ -17,4 +17,6 @@ public interface IDataLogManager extends IBaseManager<DataLog> {
List<SpDailyLog> getSpDailyLogs(Date start, Date end, String inoutType);
List<SpDailyLog> getSpPnSummaryLists(String inoutType);
DataLog findOne(Query with);
}
......@@ -74,13 +74,16 @@ public class DataLogManagerImpl implements IDataLogManager {
@Override
public List<SpDailyLog> getSpDailyLogs(Date start, Date end, String inoutType){
return dataLogDao.getSpDailyLogs(start,end,inoutType);
}
@Override
public List<SpDailyLog> getSpPnSummaryLists(String inoutType) {
return dataLogDao.getSpPnSummaryLists( inoutType );
}
@Override
public DataLog findOne(Query q) {
return dataLogDao.findOne(q);
}
}
......@@ -29,6 +29,7 @@ import com.neotel.smfcore.core.storage.service.po.StoragePos;
import com.neotel.smfcore.core.system.bean.MSDAppendInfo;
import com.neotel.smfcore.core.system.service.dao.IDataLogDao;
import com.neotel.smfcore.core.system.service.po.DataLog;
import com.neotel.smfcore.custom.aiqingzhiyin1643.electronicWarehouse.service.manager.IMaterialLossManager;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
......@@ -63,6 +64,9 @@ public class TaskService {
@Autowired
private SmfApi smfApi;
@Autowired
private IMaterialLossManager materialLossManager;
/**
* 任务队列,Key 为dataLog的ID,value 为本区域待执行的任务
*/
......@@ -170,6 +174,7 @@ public class TaskService {
smfApi.onTaskStatusChange(task);
selfAuditUtil.onTaskStatusChange(task);
materialTraceUtil.onTaskStatusChange(task);
materialLossManager.savaOrUpdate(task);
}
/**
......
package com.neotel.smfcore.custom.aiqingzhiyin1643.electronicWarehouse.rest;
import com.neotel.smfcore.common.base.IExcelDownLoad;
import com.neotel.smfcore.common.bean.PageData;
import com.neotel.smfcore.common.utils.FileUtil;
import com.neotel.smfcore.common.utils.QueryHelp;
import com.neotel.smfcore.custom.aiqingzhiyin1643.electronicWarehouse.rest.dto.MaterialLossDto;
import com.neotel.smfcore.custom.aiqingzhiyin1643.electronicWarehouse.rest.mapstruct.MaterialLossMapper;
import com.neotel.smfcore.custom.aiqingzhiyin1643.electronicWarehouse.rest.query.MaterialLossCriteria;
import com.neotel.smfcore.custom.aiqingzhiyin1643.electronicWarehouse.service.manager.IMaterialLossManager;
import com.neotel.smfcore.custom.aiqingzhiyin1643.electronicWarehouse.service.po.MaterialLoss;
import io.swagger.annotations.ApiOperation;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.domain.Pageable;
import org.springframework.data.mongodb.core.query.Query;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.IOException;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.Collections;
import java.util.List;
@RestController
@RequestMapping("/materialLoss")
public class MaterialLossController {
@Autowired
private IMaterialLossManager materialLossManager;
@Autowired
private MaterialLossMapper materialLossMapper;
@ApiOperation("查询所有电子仓损耗报表")
@RequestMapping("/list")
public PageData list(MaterialLossCriteria criteria, Pageable pageable) {
Query query = QueryHelp.getQuery(criteria);
PageData<MaterialLoss> pageData = materialLossManager.findByPage(query, pageable);
int totalElements = pageData.getTotalElements();
if (totalElements == 0){
return new PageData<>();
}
List<MaterialLoss> content = pageData.getContent();
List<MaterialLossDto> dtoList = materialLossMapper.toDto(content);
for (MaterialLossDto dto : dtoList) {
int issueNumDiff = dto.getTotalOutNum() - dto.getNeedNum();
dto.setIssueNumDiff(issueNumDiff);
int issueNum = dto.getTotalOutNum() - dto.getReturnNum();
dto.setIssueNum(issueNum);
int issueReturnDiff = issueNumDiff - dto.getReturnNum();
dto.setIssueReturnDiff(issueReturnDiff);
}
return new PageData<>(dtoList,totalElements);
}
@ApiOperation("电子仓损耗报表导出")
@RequestMapping("/list/download")
public void listDownload(MaterialLossCriteria criteria,Pageable pageable ,HttpServletResponse response) throws IOException {
Query query = QueryHelp.getQuery(criteria);
FileUtil.downloadExcel(query, pageable, response, new IExcelDownLoad() {
@Override
public List<List<String>> getHeader() {
List<List<String>> headerList = new ArrayList<>();
headerList.add(Arrays.asList("工单号"));
headerList.add(Arrays.asList("物料编码"));
headerList.add(Arrays.asList("物料名称"));
headerList.add(Arrays.asList("需求"));
headerList.add(Arrays.asList("发料"));
headerList.add(Arrays.asList("差异"));
headerList.add(Arrays.asList("领料"));
headerList.add(Arrays.asList("退料"));
headerList.add(Arrays.asList("损耗"));
return headerList;
}
@Override
public List<List<Object>> getPageData(Query query, Pageable pageable) {
List<List<Object>> dataList = new ArrayList<>();
List<MaterialLoss> materialLossList = materialLossManager.findByQuery(query, pageable);
if (materialLossList != null && !materialLossList.isEmpty()){
List<MaterialLossDto> dtoList = materialLossMapper.toDto(materialLossList);
for (MaterialLossDto dto : dtoList) {
int issueNumDiff = dto.getTotalOutNum() - dto.getNeedNum();
dto.setIssueNumDiff(issueNumDiff);
int issueNum = dto.getTotalOutNum() - dto.getReturnNum();
dto.setIssueNum(issueNum);
int issueReturnDiff = issueNumDiff - dto.getReturnNum();
dto.setIssueReturnDiff(issueReturnDiff);
List<Object> data = new ArrayList<>();
data.add(dto.getOrderNo());
data.add(dto.getPartNumber());
data.add(dto.getDescribe());
data.add(dto.getNeedNum());
data.add(dto.getTotalOutNum());
data.add(dto.getIssueNumDiff());
data.add(dto.getIssueNum());
data.add(dto.getReturnNum());
data.add(dto.getIssueReturnDiff());
dataList.add(data);
}
}
return dataList;
}
});
}
}
package com.neotel.smfcore.custom.aiqingzhiyin1643.electronicWarehouse.rest.dto;
import io.swagger.annotations.ApiModel;
import io.swagger.annotations.ApiModelProperty;
import lombok.Data;
@ApiModel("电子仓损耗报表")
@Data
public class MaterialLossDto {
@ApiModelProperty(value = "物料编号")
private String partNumber;
@ApiModelProperty(value = "物料描述")
private String describe; // 注:规范命名建议改为 description
@ApiModelProperty(value = "需求数量(生产/领料计划要求的物料数量)")
private int needNum;
@ApiModelProperty(value = "实际出库总数(累计已发出的物料总数量)")
private int totalOutNum;
@ApiModelProperty(value = "发料数量差异(需求数量-实际出库总数,正数=短缺,负数=超发)")
private int issueNumDiff;
@ApiModelProperty(value = "单次发料数量(单批/单次实际发出的物料数量)")
private int issueNum;
@ApiModelProperty(value = "退回数量(发料后退回仓库的物料数量)")
private int returnNum;
@ApiModelProperty(value = "发料退回差异(净发料数量,发料数量-退回数量)")
private int issueReturnDiff;
@ApiModelProperty(value = "订单编号(生产单/领料单/出库单的唯一编号)")
private String orderNo;
@ApiModelProperty(value = "详情id")
private String orderItemId;
}
package com.neotel.smfcore.custom.aiqingzhiyin1643.electronicWarehouse.rest.mapstruct;
import com.neotel.smfcore.common.base.BaseMapper;
import com.neotel.smfcore.custom.aiqingzhiyin1643.electronicWarehouse.rest.dto.MaterialLossDto;
import com.neotel.smfcore.custom.aiqingzhiyin1643.electronicWarehouse.service.po.MaterialLoss;
import org.mapstruct.Mapper;
import org.mapstruct.ReportingPolicy;
@Mapper(componentModel = "spring" ,unmappedTargetPolicy = ReportingPolicy.IGNORE)
public interface MaterialLossMapper extends BaseMapper<MaterialLossDto, MaterialLoss> {
}
package com.neotel.smfcore.custom.aiqingzhiyin1643.electronicWarehouse.rest.query;
import com.neotel.smfcore.common.annotation.QueryCondition;
import lombok.Data;
@Data
public class MaterialLossCriteria {
@QueryCondition(blurry = "orderNo")
private String orderNo;
@QueryCondition(blurry = "partNumber")
private String partNumber;
}
package com.neotel.smfcore.custom.aiqingzhiyin1643.electronicWarehouse.service.dao;
import com.neotel.smfcore.common.base.IBaseDao;
public interface IMaterialLossDao extends IBaseDao {
}
package com.neotel.smfcore.custom.aiqingzhiyin1643.electronicWarehouse.service.dao.impl;
import com.neotel.smfcore.common.base.AbstractBaseDao;
import com.neotel.smfcore.custom.aiqingzhiyin1643.electronicWarehouse.service.dao.IMaterialLossDao;
import com.neotel.smfcore.custom.aiqingzhiyin1643.electronicWarehouse.service.po.MaterialLoss;
import org.springframework.stereotype.Service;
@Service
public class MaterialLossDaoImpl extends AbstractBaseDao implements IMaterialLossDao {
@Override
public Class getEntityClass() {
return MaterialLoss.class;
}
}
package com.neotel.smfcore.custom.aiqingzhiyin1643.electronicWarehouse.service.manager;
import com.neotel.smfcore.common.base.IBaseManager;
import com.neotel.smfcore.core.system.service.po.DataLog;
import com.neotel.smfcore.custom.aiqingzhiyin1643.electronicWarehouse.service.po.MaterialLoss;
import org.springframework.data.domain.Pageable;
import org.springframework.data.mongodb.core.query.Query;
import java.util.List;
public interface IMaterialLossManager extends IBaseManager<MaterialLoss> {
void savaOrUpdate(DataLog task);
List<MaterialLoss> findByQuery(Query query, Pageable pageable);
}
package com.neotel.smfcore.custom.aiqingzhiyin1643.electronicWarehouse.service.manager.impl;
import com.neotel.smfcore.common.bean.PageData;
import com.neotel.smfcore.common.exception.ValidateException;
import com.neotel.smfcore.common.utils.StringUtils;
import com.neotel.smfcore.core.barcode.service.manager.IComponentManager;
import com.neotel.smfcore.core.barcode.service.po.Component;
import com.neotel.smfcore.core.device.enums.OP;
import com.neotel.smfcore.core.device.util.DataCache;
import com.neotel.smfcore.core.order.service.manager.ILiteOrderItemManager;
import com.neotel.smfcore.core.order.service.po.LiteOrderItem;
import com.neotel.smfcore.core.storage.enums.CORRESPONDING_WAREHOUSE;
import com.neotel.smfcore.core.storage.service.po.Storage;
import com.neotel.smfcore.core.system.service.manager.IDataLogManager;
import com.neotel.smfcore.core.system.service.po.DataLog;
import com.neotel.smfcore.custom.aiqingzhiyin1643.electronicWarehouse.service.dao.IMaterialLossDao;
import com.neotel.smfcore.custom.aiqingzhiyin1643.electronicWarehouse.service.manager.IMaterialLossManager;
import com.neotel.smfcore.custom.aiqingzhiyin1643.electronicWarehouse.service.po.MaterialLoss;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.domain.Pageable;
import org.springframework.data.domain.Sort;
import org.springframework.data.mongodb.core.query.Criteria;
import org.springframework.data.mongodb.core.query.Query;
import org.springframework.stereotype.Service;
import java.util.ArrayList;
import java.util.Collections;
import java.util.List;
@Service
@Slf4j
public class MaterialLossManagerImpl implements IMaterialLossManager {
@Autowired
private DataCache dataCache;
@Autowired
private IMaterialLossDao materialLossDao;
@Autowired
private ILiteOrderItemManager liteOrderItemManager;
@Autowired
private IDataLogManager dataLogManager;
@Autowired
private IComponentManager componentManager;
@Override
public MaterialLoss get(String id) {
return null;
}
@Override
public MaterialLoss save(MaterialLoss object) throws ValidateException {
return null;
}
@Override
public void delete(MaterialLoss object) throws ValidateException {
}
@Override
public PageData<MaterialLoss> findByPage(Query query, Pageable pageable) {
int count = materialLossDao.countByQuery(query);
if (count == 0){
return new PageData<>(new ArrayList<>(),0);
}
List list = materialLossDao.findByQuery(query, pageable);
return new PageData<>(list,count);
}
@Override
public List<MaterialLoss> findByQuery(Query query) {
return Collections.emptyList();
}
@Override
public void savaOrUpdate(DataLog task) {
String cid = task.getCid();
Storage storage = dataCache.getStorage(cid);
if (storage.getCorrespondingWarehouse() != CORRESPONDING_WAREHOUSE.ELECTRONIC_WAREHOUSE){
return;
}
if (task.isCheckOutTask() && task.isFinished()){
String subSourceId = task.getSubSourceId();
if (StringUtils.isEmpty(subSourceId)){
return;
}
String orderNo = task.getSourceName();
MaterialLoss materialLoss = findOneByOrderNoAndSubSourceId(orderNo,subSourceId);
if (materialLoss != null){
materialLoss.setTotalOutNum(materialLoss.getTotalOutNum() + task.getNum());
} else {
//找到最后一个出库任务
LiteOrderItem liteOrderItem = liteOrderItemManager.get(subSourceId);
materialLoss = new MaterialLoss();
materialLoss.setPartNumber(liteOrderItem.getPn());
materialLoss.setDescribe("");
Component component = componentManager.findByPartNumberAndProvider(liteOrderItem.getPn(),"");
if (component != null){
materialLoss.setDescribe(component.getDescription());
}
materialLoss.setNeedNum(liteOrderItem.getNeedNum());
materialLoss.setTotalOutNum(task.getNum());
materialLoss.setOrderNo(orderNo);
materialLoss.setOrderItemId(liteOrderItem.getId());
}
materialLossDao.save(materialLoss);
} else if (task.isFinished() && task.isPutInTask()){
DataLog dataLog = dataLogManager.findOne(new Query(
Criteria.where("barcode").is(task.getBarcode())
.and("type").is(OP.CHECKOUT)
//.and("posName").exists(true).ne("")
).with(Sort.by(Sort.Direction.DESC, "updateDate")));
if (dataLog != null){
if (dataLog.isCheckOutTask() && dataLog.isFinished()){
String subSourceId = dataLog.getSourceId();
if (StringUtils.isNotEmpty(subSourceId)){
String orderNo = dataLog.getSourceName();
MaterialLoss materialLoss = findOneByOrderNoAndSubSourceId(orderNo, subSourceId);
if (materialLoss != null){
materialLoss.setReturnNum(materialLoss.getReturnNum() + task.getNum());
materialLossDao.save(materialLoss);
}
}
}
}
}
}
@Override
public List<MaterialLoss> findByQuery(Query query, Pageable pageable) {
return materialLossDao.findByQuery(query,pageable);
}
public MaterialLoss findOneByOrderNoAndSubSourceId(String orderNo,String subSourceId){
return materialLossDao.findOne(new Query(Criteria.where("orderNo").is(orderNo).and("orderItemId").is(subSourceId)));
}
}
package com.neotel.smfcore.custom.aiqingzhiyin1643.electronicWarehouse.service.po;
import com.neotel.smfcore.common.base.BasePo;
import io.swagger.annotations.ApiModel;
import io.swagger.annotations.ApiModelProperty;
import lombok.Data;
@ApiModel("电子仓损耗报表")
@Data
public class MaterialLoss extends BasePo {
private String partNumber;
private String describe; // 注:规范命名建议改为 description
private int needNum;
private int totalOutNum;
private int returnNum;
private String orderNo;
private String orderItemId;
}
......@@ -66,7 +66,7 @@ app:
type: ""
menu:
show:
show: lossReport
hide:
smd:
......
支持 Markdown 格式
你添加了 0 到此讨论。请谨慎行事。
Finish editing this message first!