openerp/jshERP-boot/src/main/java/com/jsh/erp/service/DepotItemService.java

1413 lines
74 KiB
Java
Raw Normal View History

2025-02-24 23:08:06 +08:00
package com.jsh.erp.service;
2021-04-07 23:53:57 +08:00
import com.alibaba.fastjson.JSONArray;
import com.alibaba.fastjson.JSONObject;
import com.jsh.erp.constants.BusinessConstants;
import com.jsh.erp.constants.ExceptionConstants;
import com.jsh.erp.datasource.entities.*;
import com.jsh.erp.datasource.mappers.*;
import com.jsh.erp.datasource.vo.DepotItemStockWarningCount;
import com.jsh.erp.datasource.vo.DepotItemVo4Stock;
2021-09-29 01:17:20 +08:00
import com.jsh.erp.datasource.vo.DepotItemVoBatchNumberList;
import com.jsh.erp.datasource.vo.InOutPriceVo;
2021-04-07 23:53:57 +08:00
import com.jsh.erp.exception.BusinessRunTimeException;
import com.jsh.erp.exception.JshException;
import com.jsh.erp.utils.StringUtil;
import com.jsh.erp.utils.Tools;
2021-04-07 23:53:57 +08:00
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import javax.annotation.Resource;
import javax.servlet.http.HttpServletRequest;
import java.math.BigDecimal;
import java.util.*;
2021-04-07 23:53:57 +08:00
@Service
public class DepotItemService {
private Logger logger = LoggerFactory.getLogger(DepotItemService.class);
private final static String TYPE = "入库";
private final static String SUM_TYPE = "number";
private final static String IN = "in";
private final static String OUT = "out";
@Resource
private DepotItemMapper depotItemMapper;
@Resource
private DepotItemMapperEx depotItemMapperEx;
@Resource
private MaterialService materialService;
@Resource
private MaterialExtendService materialExtendService;
@Resource
private SerialNumberMapperEx serialNumberMapperEx;
@Resource
private DepotHeadService depotHeadService;
2021-04-07 23:53:57 +08:00
@Resource
private DepotHeadMapper depotHeadMapper;
@Resource
private SerialNumberService serialNumberService;
2021-04-07 23:53:57 +08:00
@Resource
private UserService userService;
@Resource
private SystemConfigService systemConfigService;
@Resource
private DepotService depotService;
@Resource
private UnitService unitService;
2022-10-23 17:09:48 +08:00
@Resource
2021-04-07 23:53:57 +08:00
private MaterialCurrentStockMapper materialCurrentStockMapper;
@Resource
private MaterialCurrentStockMapperEx materialCurrentStockMapperEx;
@Resource
2021-04-07 23:53:57 +08:00
private LogService logService;
public DepotItem getDepotItem(long id)throws Exception {
DepotItem result=null;
try{
result=depotItemMapper.selectByPrimaryKey(id);
}catch(Exception e){
JshException.readFail(logger, e);
}
return result;
}
public List<DepotItem> getDepotItem()throws Exception {
DepotItemExample example = new DepotItemExample();
example.createCriteria().andDeleteFlagNotEqualTo(BusinessConstants.DELETE_FLAG_DELETED);
List<DepotItem> list=null;
try{
list=depotItemMapper.selectByExample(example);
}catch(Exception e){
JshException.readFail(logger, e);
}
return list;
}
public List<DepotItem> select(String name, Integer type, String remark, int offset, int rows)throws Exception {
List<DepotItem> list=null;
try{
list=depotItemMapperEx.selectByConditionDepotItem(name, type, remark, offset, rows);
}catch(Exception e){
JshException.readFail(logger, e);
}
return list;
}
public Long countDepotItem(String name, Integer type, String remark) throws Exception{
Long result =null;
try{
result=depotItemMapperEx.countsByDepotItem(name, type, remark);
}catch(Exception e){
JshException.readFail(logger, e);
}
return result;
}
@Transactional(value = "transactionManager", rollbackFor = Exception.class)
public int insertDepotItem(JSONObject obj, HttpServletRequest request)throws Exception {
DepotItem depotItem = JSONObject.parseObject(obj.toJSONString(), DepotItem.class);
int result =0;
try{
result=depotItemMapper.insertSelective(depotItem);
}catch(Exception e){
JshException.readFail(logger, e);
}
return result;
}
@Transactional(value = "transactionManager", rollbackFor = Exception.class)
public int updateDepotItem(JSONObject obj, HttpServletRequest request)throws Exception {
DepotItem depotItem = JSONObject.parseObject(obj.toJSONString(), DepotItem.class);
int result =0;
try{
result=depotItemMapper.updateByPrimaryKeySelective(depotItem);
}catch(Exception e){
JshException.readFail(logger, e);
}
return result;
}
@Transactional(value = "transactionManager", rollbackFor = Exception.class)
public int deleteDepotItem(Long id, HttpServletRequest request)throws Exception {
int result =0;
try{
result=depotItemMapper.deleteByPrimaryKey(id);
}catch(Exception e){
JshException.writeFail(logger, e);
}
return result;
}
@Transactional(value = "transactionManager", rollbackFor = Exception.class)
public int batchDeleteDepotItem(String ids, HttpServletRequest request)throws Exception {
List<Long> idList = StringUtil.strToLongList(ids);
DepotItemExample example = new DepotItemExample();
example.createCriteria().andIdIn(idList);
int result =0;
try{
result=depotItemMapper.deleteByExample(example);
}catch(Exception e){
JshException.writeFail(logger, e);
}
return result;
}
public int checkIsNameExist(Long id, String name)throws Exception {
DepotItemExample example = new DepotItemExample();
example.createCriteria().andIdNotEqualTo(id).andDeleteFlagNotEqualTo(BusinessConstants.DELETE_FLAG_DELETED);
List<DepotItem> list =null;
try{
list=depotItemMapper.selectByExample(example);
}catch(Exception e){
JshException.readFail(logger, e);
}
return list==null?0:list.size();
}
public List<DepotItemVo4DetailByTypeAndMId> findDetailByDepotIdsAndMaterialIdList(String depotIds, Boolean forceFlag, Boolean inOutManageFlag, String sku, String batchNumber,
String number, String beginTime, String endTime, Long mId, Integer offset, Integer rows)throws Exception {
Long depotId = null;
if(StringUtil.isNotEmpty(depotIds)) {
depotId = Long.parseLong(depotIds);
2021-04-07 23:53:57 +08:00
}
List<Long> depotList = depotService.parseDepotList(depotId);
Long[] depotIdArray = StringUtil.listToLongArray(depotList);
2021-04-07 23:53:57 +08:00
List<DepotItemVo4DetailByTypeAndMId> list =null;
try{
list = depotItemMapperEx.findDetailByDepotIdsAndMaterialIdList(depotIdArray, forceFlag, inOutManageFlag, sku, batchNumber, number, beginTime, endTime, mId, offset, rows);
2021-04-07 23:53:57 +08:00
}catch(Exception e){
JshException.readFail(logger, e);
}
return list;
}
public Long findDetailByDepotIdsAndMaterialIdCount(String depotIds, Boolean forceFlag, Boolean inOutManageFlag, String sku, String batchNumber,
String number, String beginTime, String endTime, Long mId)throws Exception {
Long depotId = null;
if(StringUtil.isNotEmpty(depotIds)) {
depotId = Long.parseLong(depotIds);
2021-04-07 23:53:57 +08:00
}
List<Long> depotList = depotService.parseDepotList(depotId);
Long[] depotIdArray = StringUtil.listToLongArray(depotList);
2021-04-07 23:53:57 +08:00
Long result =null;
try{
result = depotItemMapperEx.findDetailByDepotIdsAndMaterialIdCount(depotIdArray, forceFlag, inOutManageFlag, sku, batchNumber, number, beginTime, endTime, mId);
2021-04-07 23:53:57 +08:00
}catch(Exception e){
JshException.readFail(logger, e);
}
return result;
}
@Transactional(value = "transactionManager", rollbackFor = Exception.class)
public int insertDepotItemWithObj(DepotItem depotItem)throws Exception {
int result =0;
try{
result = depotItemMapper.insertSelective(depotItem);
}catch(Exception e){
JshException.writeFail(logger, e);
}
return result;
}
@Transactional(value = "transactionManager", rollbackFor = Exception.class)
public int updateDepotItemWithObj(DepotItem depotItem)throws Exception {
int result =0;
try{
result = depotItemMapper.updateByPrimaryKeySelective(depotItem);
}catch(Exception e){
JshException.writeFail(logger, e);
}
return result;
}
public List<DepotItem> getListByHeaderId(Long headerId)throws Exception {
List<DepotItem> list =null;
try{
DepotItemExample example = new DepotItemExample();
example.createCriteria().andHeaderIdEqualTo(headerId).andDeleteFlagNotEqualTo(BusinessConstants.DELETE_FLAG_DELETED);
2021-04-07 23:53:57 +08:00
list = depotItemMapper.selectByExample(example);
}catch(Exception e){
JshException.readFail(logger, e);
}
return list;
}
/**
* 查询当前单据中指定商品的明细信息
* @param headerId
* @param meId
* @return
* @throws Exception
*/
public DepotItem getItemByHeaderIdAndMaterial(Long headerId, Long meId)throws Exception {
DepotItem depotItem = new DepotItem();
try{
DepotItemExample example = new DepotItemExample();
example.createCriteria().andHeaderIdEqualTo(headerId).andMaterialExtendIdEqualTo(meId).andDeleteFlagNotEqualTo(BusinessConstants.DELETE_FLAG_DELETED);
List<DepotItem> list = depotItemMapper.selectByExample(example);
if(list!=null && list.size()>0) {
depotItem = list.get(0);
}
}catch(Exception e){
JshException.readFail(logger, e);
}
return depotItem;
}
/**
* 查询被关联订单中指定商品的明细信息
* @param linkStr
* @param meId
* @return
* @throws Exception
*/
public DepotItem getPreItemByHeaderIdAndMaterial(String linkStr, Long meId, Long linkId)throws Exception {
DepotItem depotItem = new DepotItem();
try{
DepotHead depotHead = depotHeadService.getDepotHead(linkStr);
if(null!=depotHead && null!=depotHead.getId()) {
DepotItemExample example = new DepotItemExample();
example.createCriteria().andHeaderIdEqualTo(depotHead.getId()).andMaterialExtendIdEqualTo(meId).andIdEqualTo(linkId).andDeleteFlagNotEqualTo(BusinessConstants.DELETE_FLAG_DELETED);
List<DepotItem> list = depotItemMapper.selectByExample(example);
if(list!=null && list.size()>0) {
depotItem = list.get(0);
}
}
}catch(Exception e){
JshException.readFail(logger, e);
}
return depotItem;
}
2021-04-07 23:53:57 +08:00
public List<DepotItemVo4WithInfoEx> getDetailList(Long headerId)throws Exception {
List<DepotItemVo4WithInfoEx> list =null;
try{
list = depotItemMapperEx.getDetailList(headerId);
}catch(Exception e){
JshException.readFail(logger, e);
}
return list;
}
public List<DepotItemVo4WithInfoEx> getInOutStock(String materialParam, List<Long> categoryIdList, String endTime, Integer offset, Integer rows)throws Exception {
2021-04-07 23:53:57 +08:00
List<DepotItemVo4WithInfoEx> list =null;
try{
list = depotItemMapperEx.getInOutStock(materialParam, categoryIdList, endTime, offset, rows);
2021-04-07 23:53:57 +08:00
}catch(Exception e){
JshException.readFail(logger, e);
}
return list;
}
public int getInOutStockCount(String materialParam, List<Long> categoryIdList, String endTime)throws Exception {
2021-04-07 23:53:57 +08:00
int result=0;
try{
result = depotItemMapperEx.getInOutStockCount(materialParam, categoryIdList, endTime);
2021-04-07 23:53:57 +08:00
}catch(Exception e){
JshException.readFail(logger, e);
}
return result;
}
public List<DepotItemVo4WithInfoEx> getListWithBuyOrSale(String materialParam, String billType,
String beginTime, String endTime, String[] creatorArray, Long organId, String[] organArray, List<Long> categoryList, List<Long> depotList, Boolean forceFlag, Integer offset, Integer rows)throws Exception {
List<DepotItemVo4WithInfoEx> list =null;
try{
list = depotItemMapperEx.getListWithBuyOrSale(materialParam, billType, beginTime, endTime, creatorArray, organId, organArray, categoryList, depotList, forceFlag, offset, rows);
}catch(Exception e){
JshException.readFail(logger, e);
}
return list;
}
public int getListWithBuyOrSaleCount(String materialParam, String billType,
String beginTime, String endTime, String[] creatorArray, Long organId, String[] organArray, List<Long> categoryList, List<Long> depotList, Boolean forceFlag)throws Exception {
int result=0;
try{
result = depotItemMapperEx.getListWithBuyOrSaleCount(materialParam, billType, beginTime, endTime, creatorArray, organId, organArray, categoryList, depotList, forceFlag);
}catch(Exception e){
JshException.readFail(logger, e);
}
return result;
}
2025-04-01 15:54:01 +08:00
public BigDecimal buyOrSale(String type, String subType, Long meId, String beginTime, String endTime,
String[] creatorArray, Long organId, String [] organArray, List<Long> depotList, Boolean forceFlag, String sumType) throws Exception{
2021-04-07 23:53:57 +08:00
BigDecimal result= BigDecimal.ZERO;
try{
if (SUM_TYPE.equals(sumType)) {
2025-04-01 15:54:01 +08:00
result= depotItemMapperEx.buyOrSaleNumber(type, subType, meId, beginTime, endTime, creatorArray, organId, organArray, depotList, forceFlag, sumType);
2021-04-07 23:53:57 +08:00
} else {
2025-04-01 15:54:01 +08:00
result= depotItemMapperEx.buyOrSalePrice(type, subType, meId, beginTime, endTime, creatorArray, organId, organArray, depotList, forceFlag, sumType);
2021-04-07 23:53:57 +08:00
}
}catch(Exception e){
JshException.readFail(logger, e);
}
return result;
}
public BigDecimal buyOrSalePriceTotal(String type, String subType, String materialParam, String beginTime, String endTime,
String[] creatorArray, Long organId, String [] organArray, List<Long> categoryList, List<Long> depotList, Boolean forceFlag) throws Exception{
BigDecimal result= BigDecimal.ZERO;
try{
result= depotItemMapperEx.buyOrSalePriceTotal(type, subType, materialParam, beginTime, endTime, creatorArray, organId, organArray, categoryList, depotList, forceFlag);
}catch(Exception e){
JshException.readFail(logger, e);
}
return result;
2021-04-07 23:53:57 +08:00
}
/**
* 统计采购销售零售的总金额列表
* @param beginTime
* @param endTime
2021-04-07 23:53:57 +08:00
* @return
* @throws Exception
*/
public List<InOutPriceVo> inOrOutPriceList(String beginTime, String endTime) throws Exception{
List<InOutPriceVo> result = new ArrayList<>();
2021-11-09 00:35:48 +08:00
try{
String [] creatorArray = depotHeadService.getCreatorArray();
Boolean forceFlag = systemConfigService.getForceApprovalFlag();
result = depotItemMapperEx.inOrOutPriceList(beginTime, endTime, creatorArray, forceFlag);
2021-11-09 00:35:48 +08:00
}catch(Exception e){
JshException.readFail(logger, e);
}
return result;
}
2021-04-07 23:53:57 +08:00
@Transactional(value = "transactionManager", rollbackFor = Exception.class)
public void saveDetials(String rows, Long headerId, String actionType, HttpServletRequest request) throws Exception{
2021-04-07 23:53:57 +08:00
//查询单据主表信息
DepotHead depotHead =depotHeadMapper.selectByPrimaryKey(headerId);
//删除序列号和回收序列号
deleteOrCancelSerialNumber(actionType, depotHead, headerId);
2021-04-07 23:53:57 +08:00
//删除单据的明细
deleteDepotItemHeadId(headerId);
JSONArray rowArr = JSONArray.parseArray(rows);
2021-05-31 01:09:14 +08:00
if (null != rowArr && rowArr.size()>0) {
//针对组装单、拆卸单校验是否存在组合件和普通子件
checkAssembleWithMaterialType(rowArr, depotHead.getSubType());
2021-04-07 23:53:57 +08:00
for (int i = 0; i < rowArr.size(); i++) {
DepotItem depotItem = new DepotItem();
JSONObject rowObj = JSONObject.parseObject(rowArr.getString(i));
depotItem.setHeaderId(headerId);
String barCode = rowObj.getString("barCode");
MaterialExtend materialExtend = materialExtendService.getInfoByBarCode(barCode);
if(materialExtend == null) {
throw new BusinessRunTimeException(ExceptionConstants.MATERIAL_BARCODE_IS_NOT_EXIST_CODE,
String.format(ExceptionConstants.MATERIAL_BARCODE_IS_NOT_EXIST_MSG, barCode));
}
2021-04-07 23:53:57 +08:00
depotItem.setMaterialId(materialExtend.getMaterialId());
depotItem.setMaterialExtendId(materialExtend.getId());
depotItem.setMaterialUnit(rowObj.getString("unit"));
Material material= materialService.getMaterial(depotItem.getMaterialId());
if (BusinessConstants.ENABLE_SERIAL_NUMBER_ENABLED.equals(material.getEnableSerialNumber()) ||
BusinessConstants.ENABLE_BATCH_NUMBER_ENABLED.equals(material.getEnableBatchNumber())) {
//组装拆卸单不能选择批号或序列号商品
if(BusinessConstants.SUB_TYPE_ASSEMBLE.equals(depotHead.getSubType()) ||
BusinessConstants.SUB_TYPE_DISASSEMBLE.equals(depotHead.getSubType())) {
throw new BusinessRunTimeException(ExceptionConstants.MATERIAL_ASSEMBLE_SELECT_ERROR_CODE,
String.format(ExceptionConstants.MATERIAL_ASSEMBLE_SELECT_ERROR_MSG, barCode));
}
//调拨单不能选择批号或序列号商品(该场景走出库和入库单)
if(BusinessConstants.SUB_TYPE_TRANSFER.equals(depotHead.getSubType())) {
throw new BusinessRunTimeException(ExceptionConstants.MATERIAL_TRANSFER_SELECT_ERROR_CODE,
String.format(ExceptionConstants.MATERIAL_TRANSFER_SELECT_ERROR_MSG, barCode));
}
2022-09-23 00:00:39 +08:00
//盘点业务不能选择批号或序列号商品(该场景走出库和入库单)
if(BusinessConstants.SUB_TYPE_CHECK_ENTER.equals(depotHead.getSubType())
||BusinessConstants.SUB_TYPE_REPLAY.equals(depotHead.getSubType())) {
throw new BusinessRunTimeException(ExceptionConstants.MATERIAL_STOCK_CHECK_ERROR_CODE,
String.format(ExceptionConstants.MATERIAL_STOCK_CHECK_ERROR_MSG, barCode));
}
}
if (StringUtil.isExist(rowObj.get("snList"))) {
depotItem.setSnList(rowObj.getString("snList"));
if(StringUtil.isExist(rowObj.get("depotId"))) {
String [] snArray = depotItem.getSnList().split(",");
int operNum = rowObj.getInteger("operNumber");
if(snArray.length == operNum) {
Long depotId = rowObj.getLong("depotId");
2024-04-08 00:49:29 +08:00
BigDecimal inPrice = BigDecimal.ZERO;
if (StringUtil.isExist(rowObj.get("unitPrice"))) {
inPrice = rowObj.getBigDecimal("unitPrice");
}
serialNumberService.addSerialNumberByBill(depotHead.getType(), depotHead.getSubType(),
2024-04-08 00:49:29 +08:00
depotHead.getNumber(), materialExtend.getMaterialId(), depotId, inPrice, depotItem.getSnList());
} else {
throw new BusinessRunTimeException(ExceptionConstants.DEPOT_HEAD_SN_NUMBERE_FAILED_CODE,
String.format(ExceptionConstants.DEPOT_HEAD_SN_NUMBERE_FAILED_MSG, barCode));
}
}
} else {
//入库或出库
if (BusinessConstants.DEPOTHEAD_TYPE_IN.equals(depotHead.getType()) ||
BusinessConstants.DEPOTHEAD_TYPE_OUT.equals(depotHead.getType())) {
//序列号不能为空
if (BusinessConstants.ENABLE_SERIAL_NUMBER_ENABLED.equals(material.getEnableSerialNumber())) {
//如果开启出入库管理,并且类型等于采购、采购退货、销售、销售退货,则跳过
if(systemConfigService.getInOutManageFlag() &&
(BusinessConstants.SUB_TYPE_PURCHASE.equals(depotHead.getSubType())
||BusinessConstants.SUB_TYPE_PURCHASE_RETURN.equals(depotHead.getSubType())
||BusinessConstants.SUB_TYPE_SALES.equals(depotHead.getSubType())
||BusinessConstants.SUB_TYPE_SALES_RETURN.equals(depotHead.getSubType()))) {
//跳过
} else {
throw new BusinessRunTimeException(ExceptionConstants.MATERIAL_SERIAL_NUMBERE_EMPTY_CODE,
String.format(ExceptionConstants.MATERIAL_SERIAL_NUMBERE_EMPTY_MSG, barCode));
}
}
}
}
if (StringUtil.isExist(rowObj.get("batchNumber"))) {
depotItem.setBatchNumber(rowObj.getString("batchNumber"));
} else {
//入库或出库
if(BusinessConstants.DEPOTHEAD_TYPE_IN.equals(depotHead.getType()) ||
BusinessConstants.DEPOTHEAD_TYPE_OUT.equals(depotHead.getType())) {
//批号不能为空
if (BusinessConstants.ENABLE_BATCH_NUMBER_ENABLED.equals(material.getEnableBatchNumber())) {
//如果开启出入库管理,并且类型等于采购、采购退货、销售、销售退货,则跳过
if(systemConfigService.getInOutManageFlag() &&
(BusinessConstants.SUB_TYPE_PURCHASE.equals(depotHead.getSubType())
||BusinessConstants.SUB_TYPE_PURCHASE_RETURN.equals(depotHead.getSubType())
||BusinessConstants.SUB_TYPE_SALES.equals(depotHead.getSubType())
||BusinessConstants.SUB_TYPE_SALES_RETURN.equals(depotHead.getSubType()))) {
//跳过
} else {
throw new BusinessRunTimeException(ExceptionConstants.DEPOT_HEAD_BATCH_NUMBERE_EMPTY_CODE,
String.format(ExceptionConstants.DEPOT_HEAD_BATCH_NUMBERE_EMPTY_MSG, barCode));
}
}
}
}
if (StringUtil.isExist(rowObj.get("expirationDate"))) {
depotItem.setExpirationDate(rowObj.getDate("expirationDate"));
}
if (StringUtil.isExist(rowObj.get("sku"))) {
depotItem.setSku(rowObj.getString("sku"));
}
if (StringUtil.isExist(rowObj.get("linkId"))) {
depotItem.setLinkId(rowObj.getLong("linkId"));
}
//以下进行单位换算
2024-12-18 00:02:06 +08:00
Unit unitInfo = materialService.findUnit(materialExtend.getMaterialId()); //查询多单位信息
2021-04-07 23:53:57 +08:00
if (StringUtil.isExist(rowObj.get("operNumber"))) {
depotItem.setOperNumber(rowObj.getBigDecimal("operNumber"));
String unit = rowObj.get("unit").toString();
BigDecimal oNumber = rowObj.getBigDecimal("operNumber");
if (StringUtil.isNotEmpty(unitInfo.getName())) {
String basicUnit = unitInfo.getBasicUnit(); //基本单位
2021-12-03 21:52:53 +08:00
if (unit.equals(basicUnit)) { //如果等于基本单位
2021-04-07 23:53:57 +08:00
depotItem.setBasicNumber(oNumber); //数量一致
2021-12-01 00:58:54 +08:00
} else if (unit.equals(unitInfo.getOtherUnit())) { //如果等于副单位
depotItem.setBasicNumber(oNumber.multiply(unitInfo.getRatio())); //数量乘以比例
2021-12-01 00:58:54 +08:00
} else if (unit.equals(unitInfo.getOtherUnitTwo())) { //如果等于副单位2
depotItem.setBasicNumber(oNumber.multiply(unitInfo.getRatioTwo())); //数量乘以比例
2021-12-01 00:58:54 +08:00
} else if (unit.equals(unitInfo.getOtherUnitThree())) { //如果等于副单位3
depotItem.setBasicNumber(oNumber.multiply(unitInfo.getRatioThree())); //数量乘以比例
} else {
depotItem.setBasicNumber(oNumber); //数量一致
2021-04-07 23:53:57 +08:00
}
} else {
depotItem.setBasicNumber(oNumber); //其他情况
}
}
//如果数量+已完成数量>原订单数量,给出预警(判断前提是存在关联订单|关联请购单)
String linkStr = StringUtil.isNotEmpty(depotHead.getLinkNumber())? depotHead.getLinkNumber(): depotHead.getLinkApply();
if (StringUtil.isNotEmpty(linkStr) && StringUtil.isExist(rowObj.get("preNumber")) && StringUtil.isExist(rowObj.get("finishNumber"))) {
if("add".equals(actionType)) {
//在新增模式进行状态赋值
BigDecimal preNumber = rowObj.getBigDecimal("preNumber");
BigDecimal finishNumber = rowObj.getBigDecimal("finishNumber");
if(depotItem.getOperNumber().add(finishNumber).compareTo(preNumber)>0) {
if(!systemConfigService.getOverLinkBillFlag()) {
throw new BusinessRunTimeException(ExceptionConstants.DEPOT_HEAD_NUMBER_NEED_EDIT_FAILED_CODE,
String.format(ExceptionConstants.DEPOT_HEAD_NUMBER_NEED_EDIT_FAILED_MSG, barCode));
}
}
} else if("update".equals(actionType)) {
//当前单据的类型
String currentSubType = depotHead.getSubType();
//在更新模式进行状态赋值
String unit = rowObj.get("unit").toString();
Long preHeaderId = depotHeadService.getDepotHead(linkStr).getId();
if(null!=preHeaderId) {
//前一个单据的数量
BigDecimal preNumber = getPreItemByHeaderIdAndMaterial(linkStr, depotItem.getMaterialExtendId(), depotItem.getLinkId()).getOperNumber();
//除去此单据之外的已入库|已出库
BigDecimal realFinishNumber = getRealFinishNumber(currentSubType, depotItem.getMaterialExtendId(), depotItem.getLinkId(), preHeaderId, headerId, unitInfo, unit);
if(preNumber!=null) {
if (depotItem.getOperNumber().add(realFinishNumber).compareTo(preNumber) > 0) {
if (!systemConfigService.getOverLinkBillFlag()) {
throw new BusinessRunTimeException(ExceptionConstants.DEPOT_HEAD_NUMBER_NEED_EDIT_FAILED_CODE,
String.format(ExceptionConstants.DEPOT_HEAD_NUMBER_NEED_EDIT_FAILED_MSG, barCode));
}
}
} else {
throw new BusinessRunTimeException(ExceptionConstants.DEPOT_ITEM_PRE_BILL_IS_CHANGE_CODE,
ExceptionConstants.DEPOT_ITEM_PRE_BILL_IS_CHANGE_MSG);
}
}
}
}
2021-04-07 23:53:57 +08:00
if (StringUtil.isExist(rowObj.get("unitPrice"))) {
BigDecimal unitPrice = rowObj.getBigDecimal("unitPrice");
depotItem.setUnitPrice(unitPrice);
if(materialExtend.getLowDecimal()!=null) {
//零售或销售单价低于最低售价,进行提示
if("零售".equals(depotHead.getSubType()) || "销售".equals(depotHead.getSubType())) {
if (unitPrice.compareTo(materialExtend.getLowDecimal()) < 0) {
throw new BusinessRunTimeException(ExceptionConstants.DEPOT_HEAD_UNIT_PRICE_LOW_CODE,
String.format(ExceptionConstants.DEPOT_HEAD_UNIT_PRICE_LOW_MSG, barCode));
}
}
}
2021-04-07 23:53:57 +08:00
}
//如果是销售出库、销售退货、零售出库、零售退货则给采购单价字段赋值(如果是批次商品,则要根据批号去找之前的入库价)
if(BusinessConstants.SUB_TYPE_SALES.equals(depotHead.getSubType()) ||
BusinessConstants.SUB_TYPE_SALES_RETURN.equals(depotHead.getSubType()) ||
BusinessConstants.SUB_TYPE_RETAIL.equals(depotHead.getSubType()) ||
BusinessConstants.SUB_TYPE_RETAIL_RETURN.equals(depotHead.getSubType())) {
boolean moveAvgPriceFlag = systemConfigService.getMoveAvgPriceFlag();
BigDecimal currentUnitPrice = materialCurrentStockMapperEx.getCurrentUnitPriceByMId(materialExtend.getMaterialId());
currentUnitPrice = unitService.parseUnitPriceByUnit(currentUnitPrice, unitInfo, depotItem.getMaterialUnit());
BigDecimal unitPrice = moveAvgPriceFlag? currentUnitPrice: materialExtend.getPurchaseDecimal();
depotItem.setPurchaseUnitPrice(unitPrice);
if(StringUtil.isNotEmpty(depotItem.getBatchNumber())) {
depotItem.setPurchaseUnitPrice(getDepotItemByBatchNumber(depotItem.getMaterialExtendId(),depotItem.getBatchNumber()).getUnitPrice());
}
}
2021-04-07 23:53:57 +08:00
if (StringUtil.isExist(rowObj.get("taxUnitPrice"))) {
depotItem.setTaxUnitPrice(rowObj.getBigDecimal("taxUnitPrice"));
}
if (StringUtil.isExist(rowObj.get("allPrice"))) {
depotItem.setAllPrice(rowObj.getBigDecimal("allPrice"));
}
if (StringUtil.isExist(rowObj.get("depotId"))) {
depotItem.setDepotId(rowObj.getLong("depotId"));
} else {
2024-04-19 22:56:31 +08:00
if(!BusinessConstants.SUB_TYPE_PURCHASE_APPLY.equals(depotHead.getSubType())
&& !BusinessConstants.SUB_TYPE_PURCHASE_ORDER.equals(depotHead.getSubType())
2021-09-23 22:44:13 +08:00
&& !BusinessConstants.SUB_TYPE_SALES_ORDER.equals(depotHead.getSubType())) {
throw new BusinessRunTimeException(ExceptionConstants.DEPOT_HEAD_DEPOT_FAILED_CODE,
String.format(ExceptionConstants.DEPOT_HEAD_DEPOT_FAILED_MSG));
}
2021-04-07 23:53:57 +08:00
}
if(BusinessConstants.SUB_TYPE_TRANSFER.equals(depotHead.getSubType())) {
if (StringUtil.isExist(rowObj.get("anotherDepotId"))) {
if(rowObj.getLong("anotherDepotId").equals(rowObj.getLong("depotId"))) {
throw new BusinessRunTimeException(ExceptionConstants.DEPOT_HEAD_ANOTHER_DEPOT_EQUAL_FAILED_CODE,
String.format(ExceptionConstants.DEPOT_HEAD_ANOTHER_DEPOT_EQUAL_FAILED_MSG));
} else {
depotItem.setAnotherDepotId(rowObj.getLong("anotherDepotId"));
}
2021-04-07 23:53:57 +08:00
} else {
throw new BusinessRunTimeException(ExceptionConstants.DEPOT_HEAD_ANOTHER_DEPOT_FAILED_CODE,
String.format(ExceptionConstants.DEPOT_HEAD_ANOTHER_DEPOT_FAILED_MSG));
}
}
if (StringUtil.isExist(rowObj.get("taxRate"))) {
depotItem.setTaxRate(rowObj.getBigDecimal("taxRate"));
}
if (StringUtil.isExist(rowObj.get("taxMoney"))) {
depotItem.setTaxMoney(rowObj.getBigDecimal("taxMoney"));
}
if (StringUtil.isExist(rowObj.get("taxLastMoney"))) {
depotItem.setTaxLastMoney(rowObj.getBigDecimal("taxLastMoney"));
}
if (StringUtil.isExist(rowObj.get("mType"))) {
depotItem.setMaterialType(rowObj.getString("mType"));
}
if (StringUtil.isExist(rowObj.get("remark"))) {
depotItem.setRemark(rowObj.getString("remark"));
}
//出库时判断库存是否充足
if(BusinessConstants.DEPOTHEAD_TYPE_OUT.equals(depotHead.getType())){
String stockMsg = material.getName() + "-" + barCode;
BigDecimal stock = getCurrentStockByParam(depotItem.getDepotId(),depotItem.getMaterialId());
if(StringUtil.isNotEmpty(depotItem.getSku())) {
//对于sku商品要换个方式计算库存
stock = getSkuStockByParam(depotItem.getDepotId(),depotItem.getMaterialExtendId(),null,null);
}
if(StringUtil.isNotEmpty(depotItem.getBatchNumber())) {
//对于批次商品要换个方式计算库存
stock = getOneBatchNumberStock(depotItem.getDepotId(), barCode, depotItem.getBatchNumber());
stockMsg += "-批号" + depotItem.getBatchNumber();
}
BigDecimal thisRealNumber = depotItem.getBasicNumber()==null?BigDecimal.ZERO:depotItem.getBasicNumber();
if(StringUtil.isNotEmpty(depotItem.getBatchNumber())) {
//对于批次商品,直接使用当前填写的数量
thisRealNumber = depotItem.getOperNumber()==null?BigDecimal.ZERO:depotItem.getOperNumber();
}
if(!systemConfigService.getMinusStockFlag() && stock.compareTo(thisRealNumber)<0){
2021-04-07 23:53:57 +08:00
throw new BusinessRunTimeException(ExceptionConstants.MATERIAL_STOCK_NOT_ENOUGH_CODE,
String.format(ExceptionConstants.MATERIAL_STOCK_NOT_ENOUGH_MSG, stockMsg));
2021-04-07 23:53:57 +08:00
}
//出库时处理序列号
if(!BusinessConstants.SUB_TYPE_TRANSFER.equals(depotHead.getSubType())) {
//判断商品是否开启序列号,开启的售出序列号,未开启的跳过
2021-04-07 23:53:57 +08:00
if(BusinessConstants.ENABLE_SERIAL_NUMBER_ENABLED.equals(material.getEnableSerialNumber())) {
//如果开启出入库管理,并且类型等于采购、采购退货、销售、销售退货,则跳过
if(systemConfigService.getInOutManageFlag() &&
(BusinessConstants.SUB_TYPE_PURCHASE.equals(depotHead.getSubType())
||BusinessConstants.SUB_TYPE_PURCHASE_RETURN.equals(depotHead.getSubType())
||BusinessConstants.SUB_TYPE_SALES.equals(depotHead.getSubType())
||BusinessConstants.SUB_TYPE_SALES_RETURN.equals(depotHead.getSubType()))) {
//跳过
} else {
//售出序列号,获得当前操作人
User userInfo = userService.getCurrentUser();
serialNumberService.checkAndUpdateSerialNumber(depotItem, depotHead.getNumber(), userInfo, StringUtil.toNull(depotItem.getSnList()));
}
2021-04-07 23:53:57 +08:00
}
}
}
this.insertDepotItemWithObj(depotItem);
//更新当前库存
2021-07-28 23:13:37 +08:00
updateCurrentStock(depotItem);
//更新当前成本价
updateCurrentUnitPrice(depotItem);
//更新商品的价格
updateMaterialExtendPrice(materialExtend.getId(), depotHead.getSubType(), depotHead.getBillType(), rowObj);
2021-04-07 23:53:57 +08:00
}
//如果关联单据号非空则更新订单的状态,单据类型:采购入库单、销售出库单、盘点复盘单、其它入库单、其它出库单
2021-11-05 23:40:04 +08:00
if(BusinessConstants.SUB_TYPE_PURCHASE.equals(depotHead.getSubType())
|| BusinessConstants.SUB_TYPE_SALES.equals(depotHead.getSubType())
|| BusinessConstants.SUB_TYPE_REPLAY.equals(depotHead.getSubType())
|| BusinessConstants.SUB_TYPE_OTHER.equals(depotHead.getSubType())) {
2021-11-05 23:40:04 +08:00
if(StringUtil.isNotEmpty(depotHead.getLinkNumber())) {
//单据状态:是否全部完成 2-全部完成 3-部分完成(针对订单的分批出入库)
String billStatus = getBillStatusByParam(depotHead, depotHead.getLinkNumber(), "normal");
changeBillStatus(depotHead.getLinkNumber(), billStatus);
2021-11-05 23:40:04 +08:00
}
}
//当前单据类型为采购订单的逻辑
if(BusinessConstants.SUB_TYPE_PURCHASE_ORDER.equals(depotHead.getSubType())) {
//如果关联单据号非空则更新订单的状态,此处针对销售订单转采购订单的场景
if(StringUtil.isNotEmpty(depotHead.getLinkNumber())) {
String billStatus = getBillStatusByParam(depotHead, depotHead.getLinkNumber(), "normal");
changeBillPurchaseStatus(depotHead.getLinkNumber(), billStatus);
}
//如果关联单据号非空则更新订单的状态,此处针对请购单转采购订单的场景
if(StringUtil.isNotEmpty(depotHead.getLinkApply())) {
String billStatus = getBillStatusByParam(depotHead, depotHead.getLinkApply(), "apply");
changeBillStatus(depotHead.getLinkApply(), billStatus);
}
}
2021-05-31 01:09:14 +08:00
} else {
throw new BusinessRunTimeException(ExceptionConstants.DEPOT_HEAD_ROW_FAILED_CODE,
String.format(ExceptionConstants.DEPOT_HEAD_ROW_FAILED_MSG));
2021-04-07 23:53:57 +08:00
}
}
/**
* 判断单据的状态
* 通过数组对比原单据的商品和商品数量汇总 分批操作后单据的商品和商品数量汇总
* @param depotHead
* @param linkStr
* @return
*/
@Transactional(value = "transactionManager", rollbackFor = Exception.class)
public String getBillStatusByParam(DepotHead depotHead, String linkStr, String linkType) {
String res = BusinessConstants.BILLS_STATUS_SKIPED;
//获取原单据的商品和商品数量(汇总)
List<DepotItemVo4MaterialAndSum> linkList = depotItemMapperEx.getLinkBillDetailMaterialSum(linkStr);
//获取分批操作后单据的商品和商品数量(汇总)
List<DepotItemVo4MaterialAndSum> batchList = depotItemMapperEx.getBatchBillDetailMaterialSum(linkStr, linkType, depotHead.getType());
//将分批操作后的单据的商品和商品数据构造成Map
Map<Long, BigDecimal> materialSumMap = new HashMap<>();
for(DepotItemVo4MaterialAndSum materialAndSum : batchList) {
materialSumMap.put(materialAndSum.getMaterialExtendId(), materialAndSum.getOperNumber());
}
for(DepotItemVo4MaterialAndSum materialAndSum : linkList) {
//过滤掉原单里面有数量为0的商品
if(materialAndSum.getOperNumber().compareTo(BigDecimal.ZERO) != 0) {
BigDecimal materialSum = materialSumMap.get(materialAndSum.getMaterialExtendId());
if (materialSum != null) {
if (materialSum.compareTo(materialAndSum.getOperNumber()) < 0) {
res = BusinessConstants.BILLS_STATUS_SKIPING;
}
} else {
res = BusinessConstants.BILLS_STATUS_SKIPING;
}
}
}
return res;
}
/**
* 更新单据状态
* @param linkStr
* @param billStatus
*/
@Transactional(value = "transactionManager", rollbackFor = Exception.class)
public void changeBillStatus(String linkStr, String billStatus) {
DepotHead depotHeadOrders = new DepotHead();
depotHeadOrders.setStatus(billStatus);
DepotHeadExample example = new DepotHeadExample();
List<String> linkNoList = StringUtil.strToStringList(linkStr);
example.createCriteria().andNumberIn(linkNoList);
try{
depotHeadMapper.updateByExampleSelective(depotHeadOrders, example);
}catch(Exception e){
logger.error("异常码[{}],异常提示[{}],异常[{}]",
ExceptionConstants.DATA_WRITE_FAIL_CODE,ExceptionConstants.DATA_WRITE_FAIL_MSG,e);
throw new BusinessRunTimeException(ExceptionConstants.DATA_WRITE_FAIL_CODE,
ExceptionConstants.DATA_WRITE_FAIL_MSG);
}
}
/**
* 更新单据状态,此处针对销售订单转采购订单的场景
* @param linkStr
* @param billStatus
*/
@Transactional(value = "transactionManager", rollbackFor = Exception.class)
public void changeBillPurchaseStatus(String linkStr, String billStatus) {
DepotHead depotHeadOrders = new DepotHead();
depotHeadOrders.setPurchaseStatus(billStatus);
DepotHeadExample example = new DepotHeadExample();
List<String> linkNoList = StringUtil.strToStringList(linkStr);
example.createCriteria().andNumberIn(linkNoList);
try{
depotHeadMapper.updateByExampleSelective(depotHeadOrders, example);
}catch(Exception e){
logger.error("异常码[{}],异常提示[{}],异常[{}]",
ExceptionConstants.DATA_WRITE_FAIL_CODE,ExceptionConstants.DATA_WRITE_FAIL_MSG,e);
throw new BusinessRunTimeException(ExceptionConstants.DATA_WRITE_FAIL_CODE,
ExceptionConstants.DATA_WRITE_FAIL_MSG);
}
}
/**
* 根据批号查询单据明细信息
* @param materialExtendId
* @param batchNumber
* @return
*/
public DepotItem getDepotItemByBatchNumber(Long materialExtendId, String batchNumber) {
List<DepotItem> depotItemList = depotItemMapperEx.getDepotItemByBatchNumber(materialExtendId, batchNumber);
if(null != depotItemList && depotItemList.size() > 0){
return depotItemList.get(0);
} else {
return new DepotItem();
}
}
2021-04-07 23:53:57 +08:00
@Transactional(value = "transactionManager", rollbackFor = Exception.class)
public void deleteDepotItemHeadId(Long headerId)throws Exception {
try{
2021-10-23 21:30:55 +08:00
//1、查询删除前的单据明细
List<DepotItem> depotItemList = getListByHeaderId(headerId);
//2、删除单据明细
DepotItemExample example = new DepotItemExample();
example.createCriteria().andHeaderIdEqualTo(headerId);
2021-04-07 23:53:57 +08:00
depotItemMapper.deleteByExample(example);
2021-10-23 21:30:55 +08:00
//3、计算删除之后单据明细中商品的库存
for(DepotItem depotItem : depotItemList){
updateCurrentStock(depotItem);
}
2021-04-07 23:53:57 +08:00
}catch(Exception e){
JshException.writeFail(logger, e);
}
}
/**
* 删除序列号和回收序列号
* @param actionType
* @throws Exception
*/
@Transactional(value = "transactionManager", rollbackFor = Exception.class)
public void deleteOrCancelSerialNumber(String actionType, DepotHead depotHead, Long headerId) throws Exception {
if(actionType.equals("update")) {
User userInfo = userService.getCurrentUser();
if(BusinessConstants.DEPOTHEAD_TYPE_IN.equals(depotHead.getType())){
//入库逻辑
String number = depotHead.getNumber();
SerialNumberExample example = new SerialNumberExample();
example.createCriteria().andInBillNoEqualTo(number);
serialNumberService.deleteByExample(example);
} else if(BusinessConstants.DEPOTHEAD_TYPE_OUT.equals(depotHead.getType())){
//出库逻辑
DepotItemExample example = new DepotItemExample();
example.createCriteria().andHeaderIdEqualTo(headerId).andDeleteFlagNotEqualTo(BusinessConstants.DELETE_FLAG_DELETED);
List<DepotItem> depotItemList = depotItemMapper.selectByExample(example);
if(null != depotItemList && depotItemList.size() > 0){
for (DepotItem depotItem : depotItemList){
if(StringUtil.isNotEmpty(depotItem.getSnList())){
serialNumberService.cancelSerialNumber(depotItem.getMaterialId(), depotHead.getNumber(), (depotItem.getBasicNumber() == null ? 0 : depotItem.getBasicNumber()).intValue(), userInfo);
}
}
}
}
}
}
/**
* 针对组装单拆卸单校验是否存在组合件和普通子件
* @param rowArr
* @param subType
*/
public void checkAssembleWithMaterialType(JSONArray rowArr, String subType) {
if(BusinessConstants.SUB_TYPE_ASSEMBLE.equals(subType) ||
BusinessConstants.SUB_TYPE_DISASSEMBLE.equals(subType)) {
if(rowArr.size() > 1) {
JSONObject firstRowObj = JSONObject.parseObject(rowArr.getString(0));
JSONObject secondRowObj = JSONObject.parseObject(rowArr.getString(1));
String firstMaterialType = firstRowObj.getString("mType");
String secondMaterialType = secondRowObj.getString("mType");
if(!"组合件".equals(firstMaterialType) || !"普通子件".equals(secondMaterialType)) {
throw new BusinessRunTimeException(ExceptionConstants.DEPOT_HEAD_CHECK_ASSEMBLE_EMPTY_CODE,
String.format(ExceptionConstants.DEPOT_HEAD_CHECK_ASSEMBLE_EMPTY_MSG));
}
} else {
throw new BusinessRunTimeException(ExceptionConstants.DEPOT_HEAD_CHECK_ASSEMBLE_EMPTY_CODE,
String.format(ExceptionConstants.DEPOT_HEAD_CHECK_ASSEMBLE_EMPTY_MSG));
}
}
}
/**
* 更新商品的价格
* @param meId
* @param subType
* @param rowObj
*/
@Transactional(value = "transactionManager", rollbackFor = Exception.class)
public void updateMaterialExtendPrice(Long meId, String subType, String billType, JSONObject rowObj) throws Exception {
if(systemConfigService.getUpdateUnitPriceFlag()) {
if (StringUtil.isExist(rowObj.get("unitPrice"))) {
BigDecimal unitPrice = rowObj.getBigDecimal("unitPrice");
MaterialExtend materialExtend = new MaterialExtend();
materialExtend.setId(meId);
if(BusinessConstants.SUB_TYPE_PURCHASE.equals(subType)) {
materialExtend.setPurchaseDecimal(unitPrice);
}
if(BusinessConstants.SUB_TYPE_SALES.equals(subType)) {
materialExtend.setWholesaleDecimal(unitPrice);
}
if(BusinessConstants.SUB_TYPE_RETAIL.equals(subType)) {
materialExtend.setCommodityDecimal(unitPrice);
}
//其它入库-生产入库的情况更新采购单价
if(BusinessConstants.SUB_TYPE_OTHER.equals(subType)) {
if(BusinessConstants.BILL_TYPE_PRODUCE_IN.equals(billType)) {
materialExtend.setPurchaseDecimal(unitPrice);
}
}
materialExtendService.updateMaterialExtend(materialExtend);
}
}
}
2021-04-07 23:53:57 +08:00
@Transactional(value = "transactionManager", rollbackFor = Exception.class)
public List<DepotItemStockWarningCount> findStockWarningCount(Integer offset, Integer rows, String materialParam, List<Long> depotList, List<Long> categoryList) {
2021-04-07 23:53:57 +08:00
List<DepotItemStockWarningCount> list = null;
try{
list =depotItemMapperEx.findStockWarningCount(offset, rows, materialParam, depotList, categoryList);
2021-04-07 23:53:57 +08:00
}catch(Exception e){
JshException.readFail(logger, e);
}
return list;
}
2021-04-07 23:53:57 +08:00
@Transactional(value = "transactionManager", rollbackFor = Exception.class)
public int findStockWarningCountTotal(String materialParam, List<Long> depotList, List<Long> categoryList) {
2021-04-07 23:53:57 +08:00
int result = 0;
try{
result =depotItemMapperEx.findStockWarningCountTotal(materialParam, depotList, categoryList);
2021-04-07 23:53:57 +08:00
}catch(Exception e){
JshException.readFail(logger, e);
}
return result;
}
2021-07-28 23:13:37 +08:00
/**
* 库存统计-sku
* @param depotId
* @param meId
* @param beginTime
* @param endTime
* @return
*/
public BigDecimal getSkuStockByParam(Long depotId, Long meId, String beginTime, String endTime) throws Exception {
Boolean forceFlag = systemConfigService.getForceApprovalFlag();
Boolean inOutManageFlag = systemConfigService.getInOutManageFlag();
List<Long> depotList = depotService.parseDepotList(depotId);
//盘点复盘后数量的变动
BigDecimal stockCheckSum = depotItemMapperEx.getSkuStockCheckSumByDepotList(depotList, meId, forceFlag, beginTime, endTime);
DepotItemVo4Stock stockObj = depotItemMapperEx.getSkuStockByParamWithDepotList(depotList, meId, forceFlag, inOutManageFlag, beginTime, endTime);
2021-07-28 23:13:37 +08:00
BigDecimal stockSum = BigDecimal.ZERO;
if(stockObj!=null) {
BigDecimal inTotal = stockObj.getInTotal();
BigDecimal transfInTotal = stockObj.getTransfInTotal();
BigDecimal assemInTotal = stockObj.getAssemInTotal();
BigDecimal disAssemInTotal = stockObj.getDisAssemInTotal();
BigDecimal outTotal = stockObj.getOutTotal();
BigDecimal transfOutTotal = stockObj.getTransfOutTotal();
BigDecimal assemOutTotal = stockObj.getAssemOutTotal();
BigDecimal disAssemOutTotal = stockObj.getDisAssemOutTotal();
stockSum = inTotal.add(transfInTotal).add(assemInTotal).add(disAssemInTotal)
.subtract(outTotal).subtract(transfOutTotal).subtract(assemOutTotal).subtract(disAssemOutTotal);
}
return stockCheckSum.add(stockSum);
2021-07-28 23:13:37 +08:00
}
2021-04-07 23:53:57 +08:00
/**
2021-12-07 00:26:08 +08:00
* 库存统计-单仓库
2021-04-07 23:53:57 +08:00
* @param depotId
* @param mId
* @param beginTime
* @param endTime
* @return
*/
public BigDecimal getStockByParam(Long depotId, Long mId, String beginTime, String endTime) throws Exception {
List<Long> depotList = depotService.parseDepotList(depotId);
2021-12-07 00:26:08 +08:00
return getStockByParamWithDepotList(depotList, mId, beginTime, endTime);
}
/**
* 库存统计-多仓库
* @param depotList
* @param mId
* @param beginTime
* @param endTime
* @return
*/
public BigDecimal getStockByParamWithDepotList(List<Long> depotList, Long mId, String beginTime, String endTime) throws Exception {
Boolean forceFlag = systemConfigService.getForceApprovalFlag();
Boolean inOutManageFlag = systemConfigService.getInOutManageFlag();
2021-04-07 23:53:57 +08:00
//初始库存
2021-12-07 00:26:08 +08:00
BigDecimal initStock = materialService.getInitStockByMidAndDepotList(depotList, mId);
2021-04-07 23:53:57 +08:00
//盘点复盘后数量的变动
BigDecimal stockCheckSum = depotItemMapperEx.getStockCheckSumByDepotList(depotList, mId, forceFlag, beginTime, endTime);
DepotItemVo4Stock stockObj = depotItemMapperEx.getStockByParamWithDepotList(depotList, mId, forceFlag, inOutManageFlag, beginTime, endTime);
2021-07-28 23:13:37 +08:00
BigDecimal stockSum = BigDecimal.ZERO;
if(stockObj!=null) {
BigDecimal inTotal = stockObj.getInTotal();
BigDecimal transfInTotal = stockObj.getTransfInTotal();
BigDecimal assemInTotal = stockObj.getAssemInTotal();
BigDecimal disAssemInTotal = stockObj.getDisAssemInTotal();
BigDecimal outTotal = stockObj.getOutTotal();
BigDecimal transfOutTotal = stockObj.getTransfOutTotal();
BigDecimal assemOutTotal = stockObj.getAssemOutTotal();
BigDecimal disAssemOutTotal = stockObj.getDisAssemOutTotal();
stockSum = inTotal.add(transfInTotal).add(assemInTotal).add(disAssemInTotal)
.subtract(outTotal).subtract(transfOutTotal).subtract(assemOutTotal).subtract(disAssemOutTotal);
}
return initStock.add(stockCheckSum).add(stockSum);
2021-04-07 23:53:57 +08:00
}
/**
* 统计时间段内的入库和出库数量-多仓库
2021-12-07 00:26:08 +08:00
* @param depotList
2021-04-07 23:53:57 +08:00
* @param mId
* @param beginTime
* @param endTime
* @return
*/
public Map<String, BigDecimal> getIntervalMapByParamWithDepotList(List<Long> depotList, Long mId, String beginTime, String endTime) throws Exception {
Boolean forceFlag = systemConfigService.getForceApprovalFlag();
Boolean inOutManageFlag = systemConfigService.getInOutManageFlag();
Map<String,BigDecimal> intervalMap = new HashMap<>();
BigDecimal inSum = BigDecimal.ZERO;
BigDecimal outSum = BigDecimal.ZERO;
//盘点复盘后数量的变动
BigDecimal stockCheckSum = depotItemMapperEx.getStockCheckSumByDepotList(depotList, mId, forceFlag, beginTime, endTime);
DepotItemVo4Stock stockObj = depotItemMapperEx.getStockByParamWithDepotList(depotList, mId, forceFlag, inOutManageFlag, beginTime, endTime);
2021-07-28 23:13:37 +08:00
if(stockObj!=null) {
BigDecimal inTotal = stockObj.getInTotal();
BigDecimal transfInTotal = stockObj.getTransfInTotal();
BigDecimal assemInTotal = stockObj.getAssemInTotal();
BigDecimal disAssemInTotal = stockObj.getDisAssemInTotal();
inSum = inTotal.add(transfInTotal).add(assemInTotal).add(disAssemInTotal);
2021-07-28 23:13:37 +08:00
BigDecimal outTotal = stockObj.getOutTotal();
BigDecimal transfOutTotal = stockObj.getTransfOutTotal();
BigDecimal assemOutTotal = stockObj.getAssemOutTotal();
BigDecimal disAssemOutTotal = stockObj.getDisAssemOutTotal();
2021-12-08 01:35:57 +08:00
outSum = outTotal.add(transfOutTotal).add(assemOutTotal).add(disAssemOutTotal);
2021-07-28 23:13:37 +08:00
}
if(stockCheckSum.compareTo(BigDecimal.ZERO)>0) {
inSum = inSum.add(stockCheckSum);
} else {
//盘点复盘数量为负数代表出库
outSum = outSum.subtract(stockCheckSum);
}
intervalMap.put("inSum", inSum);
intervalMap.put("outSum", outSum);
return intervalMap;
2021-04-07 23:53:57 +08:00
}
/**
* 根据单据明细来批量更新当前库存
* @param depotItem
*/
@Transactional(value = "transactionManager", rollbackFor = Exception.class)
public void updateCurrentStock(DepotItem depotItem) throws Exception {
2021-07-28 23:13:37 +08:00
updateCurrentStockFun(depotItem.getMaterialId(), depotItem.getDepotId());
2021-04-07 23:53:57 +08:00
if(depotItem.getAnotherDepotId()!=null){
2021-07-28 23:13:37 +08:00
updateCurrentStockFun(depotItem.getMaterialId(), depotItem.getAnotherDepotId());
2021-04-07 23:53:57 +08:00
}
}
/**
* 根据单据明细来批量更新当前成本价
* @param depotItem
*/
@Transactional(value = "transactionManager", rollbackFor = Exception.class)
public void updateCurrentUnitPrice(DepotItem depotItem) throws Exception {
Boolean forceFlag = systemConfigService.getForceApprovalFlag();
Boolean inOutManageFlag = systemConfigService.getInOutManageFlag();
2024-12-18 00:02:06 +08:00
//查询多单位信息
Unit unitInfo = materialService.findUnit(depotItem.getMaterialId());
List<DepotItemVo4DetailByTypeAndMId> itemList = findDetailByDepotIdsAndMaterialIdList(null, forceFlag, inOutManageFlag, depotItem.getSku(),
depotItem.getBatchNumber(), null, null, null, depotItem.getMaterialId(), null, null);
Collections.reverse(itemList); //倒序之后变成按时间从前往后排序
BigDecimal currentNumber = BigDecimal.ZERO;
BigDecimal currentUnitPrice = BigDecimal.ZERO;
BigDecimal currentAllPrice = BigDecimal.ZERO;
for(DepotItemVo4DetailByTypeAndMId item: itemList) {
BigDecimal basicNumber = item.getBnum()!=null?item.getBnum():BigDecimal.ZERO;
//数量*单价 另外计算新的成本价
BigDecimal allPrice = unitService.parseAllPriceByUnit(item.getAllPrice()!=null?item.getAllPrice():BigDecimal.ZERO, unitInfo, item.getMaterialUnit());
if(basicNumber.compareTo(BigDecimal.ZERO)!=0 && allPrice.compareTo(BigDecimal.ZERO)!=0) {
//入库
if (BusinessConstants.DEPOTHEAD_TYPE_IN.equals(item.getType())) {
//零售退货、销售退货
if (BusinessConstants.SUB_TYPE_RETAIL_RETURN.equals(item.getSubType()) || BusinessConstants.SUB_TYPE_SALES_RETURN.equals(item.getSubType())) {
//数量*当前的成本单价
currentNumber = currentNumber.add(basicNumber);
currentAllPrice = currentAllPrice.add(basicNumber.multiply(currentUnitPrice));
} else {
currentAllPrice = currentAllPrice.add(allPrice);
currentNumber = currentNumber.add(basicNumber);
//只有当前库存总金额和当前库存数量都大于0才计算移动平均价
if (currentAllPrice.compareTo(BigDecimal.ZERO) > 0 && currentNumber.compareTo(BigDecimal.ZERO) > 0) {
currentUnitPrice = currentAllPrice.divide(currentNumber, 2, BigDecimal.ROUND_HALF_UP);
} else {
currentUnitPrice = item.getUnitPrice();
}
2024-05-24 23:55:29 +08:00
}
}
//出库
if (BusinessConstants.DEPOTHEAD_TYPE_OUT.equals(item.getType())) {
//采购退货
if (BusinessConstants.SUB_TYPE_PURCHASE_RETURN.equals(item.getSubType())) {
currentAllPrice = currentAllPrice.add(allPrice);
currentNumber = currentNumber.add(basicNumber);
//只有当前库存总金额和当前库存数量都大于0才计算移动平均价
if (currentAllPrice.compareTo(BigDecimal.ZERO) > 0 && currentNumber.compareTo(BigDecimal.ZERO) > 0) {
currentUnitPrice = currentAllPrice.divide(currentNumber, 2, BigDecimal.ROUND_HALF_UP);
} else {
currentUnitPrice = item.getUnitPrice();
}
} else {
currentNumber = currentNumber.add(basicNumber);
//数量*当前的成本单价
currentAllPrice = currentAllPrice.add(basicNumber.multiply(currentUnitPrice));
2024-05-24 23:55:29 +08:00
}
}
//防止单价金额溢出
if(currentUnitPrice.compareTo(BigDecimal.valueOf(100000000))>0 || currentUnitPrice.compareTo(BigDecimal.valueOf(-100000000))<0) {
currentUnitPrice = BigDecimal.ZERO;
}
}
}
//更新实时库存中的当前单价
materialCurrentStockMapperEx.updateUnitPriceByMId(currentUnitPrice, depotItem.getMaterialId());
}
2021-04-07 23:53:57 +08:00
/**
* 根据商品和仓库来更新当前库存
* @param mId
* @param dId
*/
public void updateCurrentStockFun(Long mId, Long dId) throws Exception {
2021-09-23 22:44:13 +08:00
if(mId!=null && dId!=null) {
MaterialCurrentStockExample example = new MaterialCurrentStockExample();
example.createCriteria().andMaterialIdEqualTo(mId).andDepotIdEqualTo(dId)
.andDeleteFlagNotEqualTo(BusinessConstants.DELETE_FLAG_DELETED);
List<MaterialCurrentStock> list = materialCurrentStockMapper.selectByExample(example);
MaterialCurrentStock materialCurrentStock = new MaterialCurrentStock();
materialCurrentStock.setMaterialId(mId);
materialCurrentStock.setDepotId(dId);
materialCurrentStock.setCurrentNumber(getStockByParam(dId,mId,null,null));
if(list!=null && list.size()>0) {
Long mcsId = list.get(0).getId();
materialCurrentStock.setId(mcsId);
materialCurrentStockMapper.updateByPrimaryKeySelective(materialCurrentStock);
} else {
materialCurrentStockMapper.insertSelective(materialCurrentStock);
}
2021-04-07 23:53:57 +08:00
}
}
@Transactional(value = "transactionManager", rollbackFor = Exception.class)
public BigDecimal getFinishNumber(Long meId, Long id, Long headerId, Unit unitInfo, String materialUnit, String linkType) {
Long linkId = id;
String goToType = "";
DepotHead depotHead =depotHeadMapper.selectByPrimaryKey(headerId);
String linkStr = depotHead.getNumber(); //订单号
if("purchase".equals(linkType)) {
//针对以销定购的情况
if(BusinessConstants.SUB_TYPE_SALES_ORDER.equals(depotHead.getSubType())) {
goToType = BusinessConstants.SUB_TYPE_PURCHASE_ORDER;
}
} else if("other".equals(linkType)) {
//采购入库、采购退货、销售出库、销售退货都转其它入库
if(BusinessConstants.SUB_TYPE_PURCHASE.equals(depotHead.getSubType())
|| BusinessConstants.SUB_TYPE_PURCHASE_RETURN.equals(depotHead.getSubType())
|| BusinessConstants.SUB_TYPE_SALES.equals(depotHead.getSubType())
|| BusinessConstants.SUB_TYPE_SALES_RETURN.equals(depotHead.getSubType())) {
goToType = BusinessConstants.SUB_TYPE_OTHER;
}
2023-12-05 22:10:13 +08:00
} else if("basic".equals(linkType)) {
//采购订单转采购入库
2022-05-19 00:12:37 +08:00
if(BusinessConstants.SUB_TYPE_PURCHASE_ORDER.equals(depotHead.getSubType())) {
goToType = BusinessConstants.SUB_TYPE_PURCHASE;
}
//销售订单转销售出库
2022-05-19 00:12:37 +08:00
if(BusinessConstants.SUB_TYPE_SALES_ORDER.equals(depotHead.getSubType())) {
goToType = BusinessConstants.SUB_TYPE_SALES;
}
//采购入库转采购退货
if(BusinessConstants.SUB_TYPE_PURCHASE.equals(depotHead.getSubType())) {
goToType = BusinessConstants.SUB_TYPE_PURCHASE_RETURN;
}
//销售出库转销售退货
if(BusinessConstants.SUB_TYPE_SALES.equals(depotHead.getSubType())) {
goToType = BusinessConstants.SUB_TYPE_SALES_RETURN;
}
}
String noType = "normal";
if(BusinessConstants.SUB_TYPE_PURCHASE_APPLY.equals(depotHead.getSubType())) {
noType = "apply";
}
BigDecimal count = depotItemMapperEx.getFinishNumber(meId, linkId, linkStr, noType, goToType);
//根据多单位情况进行数量的转换
if(materialUnit.equals(unitInfo.getOtherUnit()) && unitInfo.getRatio()!=null && unitInfo.getRatio().compareTo(BigDecimal.ZERO)!=0) {
count = count.divide(unitInfo.getRatio(),2,BigDecimal.ROUND_HALF_UP);
}
if(materialUnit.equals(unitInfo.getOtherUnitTwo()) && unitInfo.getRatioTwo()!=null && unitInfo.getRatioTwo().compareTo(BigDecimal.ZERO)!=0) {
count = count.divide(unitInfo.getRatioTwo(),2,BigDecimal.ROUND_HALF_UP);
}
if(materialUnit.equals(unitInfo.getOtherUnitThree()) && unitInfo.getRatioThree()!=null && unitInfo.getRatioThree().compareTo(BigDecimal.ZERO)!=0) {
count = count.divide(unitInfo.getRatioThree(),2,BigDecimal.ROUND_HALF_UP);
}
return count;
}
/**
* 除去此单据之外的已入库|已出库|已转采购
* @param currentSubType
* @param meId
* @param linkId
* @param preHeaderId
* @param currentHeaderId
* @param unitInfo
* @param materialUnit
* @return
*/
@Transactional(value = "transactionManager", rollbackFor = Exception.class)
public BigDecimal getRealFinishNumber(String currentSubType, Long meId, Long linkId, Long preHeaderId, Long currentHeaderId, Unit unitInfo, String materialUnit) {
String goToType = currentSubType;
DepotHead depotHead =depotHeadMapper.selectByPrimaryKey(preHeaderId);
String linkStr = depotHead.getNumber(); //订单号
String linkType = "normal";
if(BusinessConstants.SUB_TYPE_PURCHASE_APPLY.equals(depotHead.getSubType())) {
linkType = "apply";
}
BigDecimal count = depotItemMapperEx.getRealFinishNumber(meId, linkId, linkStr, linkType, currentHeaderId, goToType);
//根据多单位情况进行数量的转换
if(materialUnit.equals(unitInfo.getOtherUnit()) && unitInfo.getRatio()!=null && unitInfo.getRatio().compareTo(BigDecimal.ZERO)!=0) {
count = count.divide(unitInfo.getRatio(),2,BigDecimal.ROUND_HALF_UP);
}
if(materialUnit.equals(unitInfo.getOtherUnitTwo()) && unitInfo.getRatioTwo()!=null && unitInfo.getRatioTwo().compareTo(BigDecimal.ZERO)!=0) {
count = count.divide(unitInfo.getRatioTwo(),2,BigDecimal.ROUND_HALF_UP);
}
if(materialUnit.equals(unitInfo.getOtherUnitThree()) && unitInfo.getRatioThree()!=null && unitInfo.getRatioThree().compareTo(BigDecimal.ZERO)!=0) {
count = count.divide(unitInfo.getRatioThree(),2,BigDecimal.ROUND_HALF_UP);
}
return count;
}
2021-09-29 01:17:20 +08:00
public List<DepotItemVoBatchNumberList> getBatchNumberList(String number, String name, Long depotId, String barCode,
String batchNumber, Boolean forceFlag, Boolean inOutManageFlag) throws Exception {
List<DepotItemVoBatchNumberList> reslist = new ArrayList<>();
List<DepotItemVoBatchNumberList> list = depotItemMapperEx.getBatchNumberList(StringUtil.toNull(number), name,
depotId, barCode, batchNumber, forceFlag, inOutManageFlag);
for(DepotItemVoBatchNumberList bn: list) {
if(bn.getTotalNum()!=null && bn.getTotalNum().compareTo(BigDecimal.ZERO)>0) {
bn.setExpirationDateStr(Tools.parseDateToStr(bn.getExpirationDate()));
if(bn.getUnitId()!=null) {
Unit unit = unitService.getUnit(bn.getUnitId());
String commodityUnit = bn.getCommodityUnit();
bn.setTotalNum(unitService.parseStockByUnit(bn.getTotalNum(), unit, commodityUnit));
}
reslist.add(bn);
}
}
return reslist;
2021-09-29 01:17:20 +08:00
}
2022-05-13 18:25:57 +08:00
/**
* 查询某个批号的商品库存
* @param depotId
* @param barCode
* @param batchNumber
* @return
* @throws Exception
*/
public BigDecimal getOneBatchNumberStock(Long depotId, String barCode, String batchNumber) throws Exception {
BigDecimal totalNum = BigDecimal.ZERO;
Boolean forceFlag = systemConfigService.getForceApprovalFlag();
Boolean inOutManageFlag = systemConfigService.getInOutManageFlag();
List<DepotItemVoBatchNumberList> list = depotItemMapperEx.getBatchNumberList(null, null,
depotId, barCode, batchNumber, forceFlag, inOutManageFlag);
if(list!=null && list.size()>0) {
DepotItemVoBatchNumberList bn = list.get(0);
totalNum = bn.getTotalNum();
if(bn.getTotalNum()!=null && bn.getTotalNum().compareTo(BigDecimal.ZERO)>0) {
if(bn.getUnitId()!=null) {
Unit unit = unitService.getUnit(bn.getUnitId());
String commodityUnit = bn.getCommodityUnit();
totalNum = unitService.parseStockByUnit(bn.getTotalNum(), unit, commodityUnit);
}
}
}
return totalNum;
}
2022-05-13 18:25:57 +08:00
public Long getCountByMaterialAndDepot(Long mId, Long depotId) {
return depotItemMapperEx.getCountByMaterialAndDepot(mId, depotId);
}
public JSONObject parseMapByExcelData(String barCodes, List<Map<String, String>> detailList, String prefixNo) throws Exception {
JSONObject map = new JSONObject();
JSONArray arr = new JSONArray();
List<MaterialVo4Unit> list = depotItemMapperEx.getBillItemByParam(barCodes);
Map<String, MaterialVo4Unit> materialMap = new HashMap<>();
Map<String, Long> depotMap = new HashMap<>();
for (MaterialVo4Unit material: list) {
materialMap.put(material.getmBarCode(), material);
}
JSONArray depotArr = depotService.findDepotByCurrentUser();
for (Object depotObj: depotArr) {
if(depotObj!=null) {
JSONObject depotObject = JSONObject.parseObject(depotObj.toString());
depotMap.put(depotObject.getString("depotName"), depotObject.getLong("id"));
}
}
for (Map<String, String> detailMap: detailList) {
JSONObject item = new JSONObject();
String barCode = detailMap.get("barCode");
2023-05-23 22:03:01 +08:00
if(StringUtil.isNotEmpty(barCode)) {
MaterialVo4Unit m = materialMap.get(barCode);
if(m!=null) {
//判断仓库是否存在
String depotName = detailMap.get("depotName");
if(StringUtil.isNotEmpty(depotName)) {
if(depotMap.get(depotName)!=null) {
item.put("depotName", depotName);
item.put("depotId", depotMap.get(depotName));
} else {
throw new BusinessRunTimeException(ExceptionConstants.DEPOT_ITEM_DEPOTNAME_IS_NOT_EXIST_CODE,
String.format(ExceptionConstants.DEPOT_ITEM_DEPOTNAME_IS_NOT_EXIST_MSG, depotName));
}
}
2023-05-23 22:03:01 +08:00
item.put("barCode", barCode);
item.put("name", m.getName());
item.put("standard", m.getStandard());
if(StringUtil.isNotEmpty(m.getModel())) {
item.put("model", m.getModel());
}
2023-05-23 22:03:01 +08:00
if(StringUtil.isNotEmpty(m.getColor())) {
item.put("color", m.getColor());
}
if(StringUtil.isNotEmpty(m.getSku())) {
item.put("sku", m.getSku());
}
BigDecimal stock = BigDecimal.ZERO;
if(StringUtil.isNotEmpty(m.getSku())){
stock = getSkuStockByParam(null, m.getMeId(),null,null);
} else {
stock = getCurrentStockByParam(null, m.getId());
}
2023-05-23 22:03:01 +08:00
item.put("stock", stock);
item.put("unit", m.getCommodityUnit());
BigDecimal operNumber = BigDecimal.ZERO;
BigDecimal unitPrice = BigDecimal.ZERO;
BigDecimal taxRate = BigDecimal.ZERO;
if(StringUtil.isNotEmpty(detailMap.get("num"))) {
operNumber = new BigDecimal(detailMap.get("num"));
}
if(StringUtil.isNotEmpty(detailMap.get("unitPrice"))) {
unitPrice = new BigDecimal(detailMap.get("unitPrice"));
} else {
if("CGDD".equals(prefixNo)) {
unitPrice = m.getPurchaseDecimal();
} else if("XSDD".equals(prefixNo)) {
unitPrice = m.getWholesaleDecimal();
}
}
if(StringUtil.isNotEmpty(detailMap.get("taxRate"))) {
taxRate = new BigDecimal(detailMap.get("taxRate"));
}
String remark = detailMap.get("remark");
item.put("operNumber", operNumber);
item.put("unitPrice", unitPrice);
BigDecimal allPrice = BigDecimal.ZERO;
if(unitPrice!=null && unitPrice.compareTo(BigDecimal.ZERO)!=0) {
allPrice = unitPrice.multiply(operNumber);
}
BigDecimal taxMoney = BigDecimal.ZERO;
if(taxRate.compareTo(BigDecimal.ZERO) != 0) {
taxMoney = taxRate.multiply(allPrice).divide(BigDecimal.valueOf(100), 2, BigDecimal.ROUND_HALF_UP);
}
BigDecimal taxLastMoney = allPrice.add(taxMoney);
item.put("allPrice", allPrice);
item.put("taxRate", taxRate);
item.put("taxMoney", taxMoney);
item.put("taxLastMoney", taxLastMoney);
item.put("remark", remark);
arr.add(item);
} else {
throw new BusinessRunTimeException(ExceptionConstants.DEPOT_ITEM_BARCODE_IS_NOT_EXIST_CODE,
String.format(ExceptionConstants.DEPOT_ITEM_BARCODE_IS_NOT_EXIST_MSG, barCode));
}
}
}
map.put("rows", arr);
return map;
}
public BigDecimal getLastUnitPriceByParam(Long organId, Long meId, String prefixNo) {
String type = "";
String subType = "";
if("XSDD".equals(prefixNo)) {
type = "其它";
subType = "销售订单";
} else if("XSCK".equals(prefixNo)) {
type = "出库";
subType = "销售";
} else if("XSTH".equals(prefixNo)) {
type = "入库";
subType = "销售退货";
} else if("QTCK".equals(prefixNo)) {
type = "出库";
subType = "其它";
}
return depotItemMapperEx.getLastUnitPriceByParam(organId, meId, type, subType);
}
public BigDecimal getCurrentStockByParam(Long depotId, Long mId) {
2023-08-11 18:49:05 +08:00
BigDecimal stock = depotItemMapperEx.getCurrentStockByParam(depotId, mId);
return stock!=null? stock: BigDecimal.ZERO;
}
2021-04-07 23:53:57 +08:00
}