package com.gkhy.hazmat.system.service.impl;
import cn.hutool.core.date.DatePattern;
import cn.hutool.core.date.DateUtil;
import com.baomidou.mybatisplus.core.conditions.update.LambdaUpdateWrapper;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.gkhy.hazmat.common.api.CommonPage;
import com.gkhy.hazmat.common.config.IdTableNameHandler;
import com.gkhy.hazmat.common.constant.Constant;
import com.gkhy.hazmat.common.domain.entity.SysUser;
import com.gkhy.hazmat.common.enums.CodePrexEnum;
import com.gkhy.hazmat.common.enums.EntryStateEnum;
import com.gkhy.hazmat.common.enums.HazmatStatusEnum;
import com.gkhy.hazmat.common.enums.UserTypeEnum;
import com.gkhy.hazmat.common.exception.ApiException;
import com.gkhy.hazmat.common.listener.CustomEventPublisher;
import com.gkhy.hazmat.common.service.RedisService;
import com.gkhy.hazmat.common.utils.PageUtils;
import com.gkhy.hazmat.common.utils.SecurityUtils;
import com.gkhy.hazmat.common.utils.StringUtils;
import com.gkhy.hazmat.system.domain.*;
import com.gkhy.hazmat.system.domain.vo.TabooDisVo;
import com.gkhy.hazmat.system.mapper.*;
import com.gkhy.hazmat.system.service.HzEntryRecordService;
import com.gkhy.hazmat.system.service.HzHazmatService;
import com.gkhy.hazmat.system.service.TabooWarningService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.transaction.support.TransactionSynchronization;
import org.springframework.transaction.support.TransactionSynchronizationManager;
import java.time.LocalDateTime;
import java.util.*;
/**
*
* 入库记录表 服务实现类
*
*
* @author kzy
* @since 2024-08-06 10:33:05
*/
@Service
public class HzEntryRecordServiceImpl extends ServiceImpl implements HzEntryRecordService {
@Autowired
private HzHazmatBasicMapper hazmatBasicMapper;
@Autowired
private HzHazmatMapper hazmatMapper;
@Autowired
private HzHazmatService hazmatService;
@Autowired
private HzWarehouseRecordMapper warehouseRecordMapper;
@Autowired
private CustomEventPublisher customEventPublisher;
@Autowired
private SysCompanyMapper companyMapper;
@Autowired
private RedisService redisService;
// @Autowired
// private TabooWarningService tabooWarningService;
@Autowired
private HzTabooWarningMapper tabooWarningMapper;
@Override
public CommonPage selectEntryRecordList(HzEntryRecord entryRecord) {
SysUser currentUser = SecurityUtils.getLoginUser().getUser();
if (!currentUser.getUserType().equals(UserTypeEnum.SYSTEM_USER.getCode())) {
entryRecord.setCompanyId(currentUser.getCompanyId());
}
PageUtils.startPage();
List entryRecordList = baseMapper.selectEntryRecordList(entryRecord);
return CommonPage.restPage(entryRecordList);
}
@Override
public HzEntryRecord selectEntryRecordById(Long entryRecordId) {
HzEntryRecord entryRecord = baseMapper.selectById(entryRecordId);
SysUser currentUser = SecurityUtils.getLoginUser().getUser();
if (currentUser.getUserType().equals(UserTypeEnum.SYSTEM_USER.getCode())) {
return entryRecord;
} else if (!entryRecord.getCompanyId().equals(currentUser.getCompanyId())) {
throw new ApiException("无权限查看其它企业数据");
}
return entryRecord;
}
@Override
public int insertEntryRecord(HzEntryRecord entryRecord) {
SysUser currentUser=SecurityUtils.getLoginUser().getUser();
HzHazmatBasic hazmatBasic=hazmatBasicMapper.selectById(entryRecord.getBasicId());
if(hazmatBasic==null){
throw new ApiException("危化品基础数据不存在");
}
if(entryRecord.getNum()>hazmatBasic.getMaxEntry()){
throw new ApiException("数量超过单次入库最大数量<"+hazmatBasic.getMaxEntry()+">");
}
entryRecord.setCompanyId(currentUser.getCompanyId());
entryRecord.setCreateBy(currentUser.getUsername());
checkUserAllowed(null,currentUser);
int row=0;
synchronized (this) {
//生成条码范围
generateCode(entryRecord);
row = baseMapper.insert(entryRecord);
if (row < 1) {
throw new ApiException("新增入库记录失败");
}
}
return row;
}
public void generateCode(HzEntryRecord entryRecord){
SysCompany company=companyMapper.selectById(entryRecord.getCompanyId());
String code=company.getCode();
if(StringUtils.isBlank(code)){
throw new ApiException("公司两位编码为空");
}
String currentDate= DateUtil.format(new Date(), DatePattern.PURE_DATE_FORMAT);
StringBuilder prefixBuilder=new StringBuilder().append(CodePrexEnum.MATERIAL.getCode())
.append(code)
.append(currentDate);
HzEntryRecord er=baseMapper.selectLastEntryRecord(prefixBuilder.toString(),entryRecord.getCompanyId());
int startCode=1;
int endCode=startCode+entryRecord.getNum()-1;
if(er!=null){
startCode=er.getEndCode()+1;
endCode=startCode+entryRecord.getNum()-1;
}
entryRecord.setCodePrex(prefixBuilder.toString());
entryRecord.setStartCode(startCode);
entryRecord.setEndCode(endCode);
entryRecord.setState(EntryStateEnum.UNENTER.getCode());
}
@Override
public int deleteEntryRecordById(Long entryRecordId) {
HzEntryRecord entryRecord=baseMapper.selectById(entryRecordId);
if(entryRecord==null){
throw new ApiException("入库记录不存在");
}
if(entryRecord.getState().equals(EntryStateEnum.ENTER.getCode())){
throw new ApiException("已入库状态的记录不能删除");
}
SysUser currentUser = SecurityUtils.getLoginUser().getUser();
checkUserAllowed(entryRecord,currentUser);
baseMapper.deleteById(entryRecordId);
return 0;
}
@Override
@Transactional(rollbackFor = RuntimeException.class)
public void doEntry(Long entryRecordId) {
HzEntryRecord entryRecord=getById(entryRecordId);
if(entryRecord.getState().equals(EntryStateEnum.ENTER.getCode())){
throw new ApiException("已完成入库,不能再操作");
}
SysUser currentUser=SecurityUtils.getLoginUser().getUser();
checkUserAllowed(entryRecord,currentUser);
HzHazmatBasic hazmatBasic=hazmatBasicMapper.selectById(entryRecord.getBasicId());
if(hazmatBasic==null){
throw new ApiException("危化品基础数据不存在");
}
// synchronized (this) {
//获取当前仓库库存
//设置分表id
IdTableNameHandler.setCurrentId(currentUser.getCompanyId());
int count = hazmatMapper.selectHazmatCountOfWarehouse(entryRecord.getWarehouseId(), hazmatBasic.getId(), currentUser.getCompanyId(), entryRecord.getCupboardId());
//新增危化品变动记录
HzWarehouseRecord warehouseRecord = new HzWarehouseRecord()
.setWarehouseId(entryRecord.getWarehouseId())
.setCupboardId(entryRecord.getCupboardId())
.setBasicId(hazmatBasic.getId())
.setNum(entryRecord.getNum())
.setCompanyId(currentUser.getCompanyId())
.setCreateId(currentUser.getId())
.setRemaining(entryRecord.getNum() + count);
warehouseRecordMapper.insert(warehouseRecord);
// 校验生成相忌数据
Map redata = (Map)redisService.get(Constant.TABOO_UNIQUE_KEY);
if (!redata.isEmpty()){
// 查询对应仓库和柜子的物品信息获取品类 获取相冲相弱相吸相异
List collectData =
hazmatMapper.selectHazmatWarehouseCheck(entryRecord.getWarehouseId(), currentUser.getCompanyId(), entryRecord.getCupboardId());
if (!collectData.isEmpty() && collectData.size() > 0) {
for (TabooDisVo collectDatum : collectData) {
String key1 = collectDatum.getSpNum() + "_" + hazmatBasic.getPeculiarityNumber();
String key2 = hazmatBasic.getPeculiarityNumber() + "_" + collectDatum.getSpNum();
if (redata.containsKey(key1) || redata.containsKey(key2)) {
// 记录数据
Long l = redata.get(key1);
Long l1 = l == null ? redata.get(key2) : l;
HzTabooWarning tabooWarning = new HzTabooWarning()
.setWarningType(l1)
.setWarehouseId(entryRecord.getWarehouseId())
.setCupboardId(entryRecord.getCupboardId())
.setEntryId(entryRecord.getId())
.setCompanyId(currentUser.getCompanyId())
.setTabooBasicId(collectDatum.getId()).setCreateBy(currentUser.getUsername());
tabooWarningMapper.insert(tabooWarning);
break;
}
}
}
// if (null != collectData) {
// Iterator> iterator = collectData.entrySet().iterator();
// while (iterator.hasNext()) {
// Map.Entry entry = iterator.next();
// String key = entry.getKey();
// Integer value = entry.getValue();
// Integer i = collectData.get(value);
// String key1 = value + "_" + hazmatBasic.getPeculiarityNumber();
// String key2 = hazmatBasic.getPeculiarityNumber() + "_" + value;
//
// if (redata.containsKey(key1) || redata.containsKey(key2)) {
// // 记录数据
// Long l = redata.get(key1);
// Long l1 = l == null ? redata.get(key2) : l;
// HzTabooWarning tabooWarning = new HzTabooWarning()
// .setWarningType(l1)
// .setEntryId(entryRecord.getId())
// .setCompanyId(currentUser.getCompanyId())
// .setTabooBasicId(i.longValue()).setCreateBy(currentUser.getUsername());
// tabooWarningMapper.insert(tabooWarning);
// break;
// }
// }
// }
}else {
throw new ApiException("危化品相忌信息不存在");
}
int startCode=entryRecord.getStartCode();
int endCode=entryRecord.getEndCode();
List hazmatList = new ArrayList<>();
for (int i = startCode; i <=endCode; i++) {
String lastCode= StringUtils.addZeroForNum(String.valueOf(i),4);
String code=String.format("%s%s",entryRecord.getCodePrex(),lastCode);
hazmatList.add(new HzHazmat().setWarehouseId(entryRecord.getWarehouseId())
.setCupboardId(entryRecord.getCupboardId())
.setBasicId(entryRecord.getBasicId())
.setCupboardId(entryRecord.getCupboardId())
.setEntryId(entryRecord.getId())
.setRemaining(hazmatBasic.getMetering())
.setCompanyId(currentUser.getCompanyId())
.setState(HazmatStatusEnum.WAREHOUSEIN.getCode())
.setCode(code));
}
//批量创建危化品
if (hazmatList.size() > 100) {
while (!hazmatList.isEmpty()) {
int endIndex = Math.min(hazmatList.size(), 100);
List subList = hazmatList.subList(0, endIndex);
hazmatService.saveBatch(subList);
hazmatList = hazmatList.subList(endIndex, hazmatList.size());
}
} else {
hazmatService.saveBatch(hazmatList);
}
// }
//更新入库记录状态
entryRecord.setState(EntryStateEnum.ENTER.getCode());
updateById(entryRecord);
IdTableNameHandler.removeCurrentId();
//异步执行
// 注册一个事务完成后执行的回调
TransactionSynchronizationManager.registerSynchronization(new TransactionSynchronization() {
@Override
public void afterCommit() {
customEventPublisher.publishEntry(entryRecord.getId(), CodePrexEnum.MATERIAL.getCode(), currentUser.getCompanyId(), currentUser.getId());
}
});
}
@Override
public int updateEntryRecord(HzEntryRecord entryRecord) {
SysUser currentUser = SecurityUtils.getLoginUser().getUser();
checkUserAllowed(entryRecord,currentUser);
HzHazmatBasic hazmatBasic=hazmatBasicMapper.selectById(entryRecord.getBasicId());
if(hazmatBasic==null){
throw new ApiException("危化品基础数据不存在");
}
HzEntryRecord existEr=baseMapper.selectById(entryRecord.getId());
if(existEr.getState().equals(EntryStateEnum.ENTER.getCode())){
throw new ApiException("已经入库,不能再修改");
}
if(entryRecord.getNum()>hazmatBasic.getMaxEntry()){
throw new ApiException("数量超过单次入库最大数量<"+hazmatBasic.getMaxEntry()+">");
}
entryRecord.setUpdateBy(currentUser.getUsername());
int row=baseMapper.updateById(entryRecord);
if(row<1){
throw new ApiException("更新入库信息失败");
}
return row;
}
@Override
public CommonPage selectHazmatListByEntryId(Long entryId) {
SysUser currentUser = SecurityUtils.getLoginUser().getUser();
HzEntryRecord entryRecord=getById(entryId);
if(entryRecord==null){
throw new ApiException("入库信息不存在");
}
checkUserAllowed(entryRecord,currentUser);
//设置分表id
IdTableNameHandler.setCurrentId(currentUser.getCompanyId());
PageUtils.startPage();
List hazmatList = hazmatMapper.selectHazmatList(new HzHazmat().setEntryId(entryId));
IdTableNameHandler.removeCurrentId();
return CommonPage.restPage(hazmatList);
}
public void checkUserAllowed(HzEntryRecord entryRecord,SysUser user) {
if (user.getUserType().equals(UserTypeEnum.SYSTEM_USER.getCode())) {
throw new ApiException("管理员不能操作");
}
if(entryRecord!=null){
if(!Objects.equals(user.getCompanyId(), entryRecord.getCompanyId())){
throw new ApiException("无权限操作其他企业数据");
}
}
}
}