Merge remote-tracking branch 'origin/dev' into dev

dev
xs 2 weeks ago
commit 880c808569

@ -113,4 +113,15 @@ public class ErpAfterSalesController extends BaseController {
return R.ok(list); return R.ok(list);
} }
/**
*
*/
@SaCheckPermission("oa/erp:afterSales:add")
@Log(title = "项目售后信息", businessType = BusinessType.INSERT)
@RepeatSubmit()
@PostMapping("/submitAndFlowStart")
public R<ErpAfterSalesVo> submitAndFlowStart(@Validated(AddGroup.class) @RequestBody ErpAfterSalesBo bo) {
return R.ok(erpAfterSalesService.submitAndFlowStart(bo));
}
} }

@ -44,6 +44,7 @@ public class ErpProjectReportController extends BaseController {
@SaCheckPermission("oa/erp:projectReport:list") @SaCheckPermission("oa/erp:projectReport:list")
@GetMapping("/list") @GetMapping("/list")
public TableDataInfo<ErpProjectReportVo> list(ErpProjectReportBo bo, PageQuery pageQuery) { public TableDataInfo<ErpProjectReportVo> list(ErpProjectReportBo bo, PageQuery pageQuery) {
return erpProjectReportService.queryPageList(bo, pageQuery); return erpProjectReportService.queryPageList(bo, pageQuery);
} }

@ -15,7 +15,11 @@ import org.dromara.common.log.enums.BusinessType;
import org.dromara.common.mybatis.core.page.PageQuery; import org.dromara.common.mybatis.core.page.PageQuery;
import org.dromara.common.mybatis.core.page.TableDataInfo; import org.dromara.common.mybatis.core.page.TableDataInfo;
import org.dromara.common.web.core.BaseController; import org.dromara.common.web.core.BaseController;
import org.dromara.oa.erp.domain.bo.ErpContractInfoBo;
import org.dromara.oa.erp.domain.bo.ErpProjectReportBo;
import org.dromara.oa.erp.domain.bo.ErpProjectReportDetailBo; import org.dromara.oa.erp.domain.bo.ErpProjectReportDetailBo;
import org.dromara.oa.erp.domain.bo.ProjectReportAndDetailWrapperBo;
import org.dromara.oa.erp.domain.vo.ErpContractInfoVo;
import org.dromara.oa.erp.domain.vo.ErpProjectReportDetailVo; import org.dromara.oa.erp.domain.vo.ErpProjectReportDetailVo;
import org.dromara.oa.erp.service.IErpProjectReportDetailService; import org.dromara.oa.erp.service.IErpProjectReportDetailService;
import org.springframework.validation.annotation.Validated; import org.springframework.validation.annotation.Validated;
@ -114,4 +118,18 @@ public class ErpProjectReportDetailController extends BaseController {
return R.ok(list); return R.ok(list);
} }
/**
*
* @param wrapper
* @return
*/
@SaCheckPermission("oa/erp:projectReportDetail:add")
@Log(title = "项目周报明细", businessType = BusinessType.INSERT)
@RepeatSubmit()
@PostMapping("/projectReportSubmitAndFlowStart")
public R<ErpProjectReportDetailVo> projectReportSubmitAndFlowStart(@Validated(AddGroup.class) @RequestBody ProjectReportAndDetailWrapperBo wrapper) {
ErpProjectReportBo projectReport = wrapper.getProjectReport();
ErpProjectReportDetailBo projectDetailReport = wrapper.getProjectDetailReport();
return R.ok(erpProjectReportDetailService.projectReportSubmitAndFlowStart(projectReport, projectDetailReport));
}
} }

@ -1,9 +1,6 @@
package org.dromara.oa.erp.domain; package org.dromara.oa.erp.domain;
import com.baomidou.mybatisplus.annotation.IdType; import com.baomidou.mybatisplus.annotation.*;
import com.baomidou.mybatisplus.annotation.TableId;
import com.baomidou.mybatisplus.annotation.TableLogic;
import com.baomidou.mybatisplus.annotation.TableName;
import lombok.Data; import lombok.Data;
import lombok.EqualsAndHashCode; import lombok.EqualsAndHashCode;
import org.dromara.common.tenant.core.TenantEntity; import org.dromara.common.tenant.core.TenantEntity;
@ -27,7 +24,7 @@ public class ErpProjectReport extends TenantEntity {
/** /**
* ID * ID
*/ */
@TableId(value = "report_id", type = IdType.AUTO) @TableId(value = "report_id", type = IdType.ASSIGN_ID)
private Long reportId; private Long reportId;
/** /**
@ -101,5 +98,27 @@ public class ErpProjectReport extends TenantEntity {
*/ */
private String projectCode; private String projectCode;
/**
*
*/
@TableField(exist = false)
private String deptName;
/**
*
*/
@TableField(exist = false)
private String managerName;
/**
*
*/
@TableField(exist = false)
private String chargeName;
/**
*
*/
@TableField(exist = false)
private String deputyName;
} }

@ -28,7 +28,7 @@ public class ErpProjectReportDetail extends TenantEntity {
/** /**
* ID * ID
*/ */
@TableId(value = "report_detail_id", type = IdType.AUTO) @TableId(value = "report_detail_id", type = IdType.ASSIGN_ID)
private Long reportDetailId; private Long reportDetailId;
/** /**

@ -13,10 +13,12 @@ import java.math.BigDecimal;
import java.util.Date; import java.util.Date;
import com.fasterxml.jackson.annotation.JsonFormat; import com.fasterxml.jackson.annotation.JsonFormat;
import java.util.List; // 1. 别忘了导包 List import java.util.List; // 1. 别忘了导包 List
import java.util.Map;
// 2. 导入两个子表的 BO 对象,因为前端传的是子表的业务数据 // 2. 导入两个子表的 BO 对象,因为前端传的是子表的业务数据
import org.dromara.oa.erp.domain.bo.ErpAfterSalesLaborCostsBo; import org.dromara.oa.erp.domain.bo.ErpAfterSalesLaborCostsBo;
import org.dromara.oa.erp.domain.bo.ErpAfterSalesMaterialCostsBo; import org.dromara.oa.erp.domain.bo.ErpAfterSalesMaterialCostsBo;
import org.dromara.workflow.api.domain.RemoteFlowInstanceBizExt;
/** /**
* erp_after_sales * erp_after_sales
@ -180,5 +182,20 @@ public class ErpAfterSalesBo extends BaseEntity {
*/ */
private List<ErpAfterSalesMaterialCostsBo> materialCostsList; private List<ErpAfterSalesMaterialCostsBo> materialCostsList;
/**
*
*/
private String flowCode;
/**
* {'entity': {}}
*/
private Map<String, Object> variables;
/**
*
*/
private RemoteFlowInstanceBizExt bizExt;
} }

@ -1,5 +1,6 @@
package org.dromara.oa.erp.domain.bo; package org.dromara.oa.erp.domain.bo;
import cn.idev.excel.annotation.ExcelProperty;
import io.github.linpeilie.annotations.AutoMapper; import io.github.linpeilie.annotations.AutoMapper;
import jakarta.validation.constraints.NotNull; import jakarta.validation.constraints.NotNull;
import lombok.Data; import lombok.Data;
@ -90,5 +91,23 @@ public class ErpProjectReportBo extends BaseEntity {
*/ */
private String projectCode; private String projectCode;
/**
*
*/
private String deptName;
/**
*
*/
private String managerName;
/**
*
*/
private String chargeName;
/**
*
*/
private String deputyName;
} }

@ -1,5 +1,6 @@
package org.dromara.oa.erp.domain.bo; package org.dromara.oa.erp.domain.bo;
import cn.hutool.core.util.ObjectUtil;
import io.github.linpeilie.annotations.AutoMapper; import io.github.linpeilie.annotations.AutoMapper;
import jakarta.validation.constraints.NotNull; import jakarta.validation.constraints.NotNull;
import lombok.Data; import lombok.Data;
@ -7,8 +8,12 @@ import lombok.EqualsAndHashCode;
import org.dromara.common.core.validate.EditGroup; import org.dromara.common.core.validate.EditGroup;
import org.dromara.common.mybatis.core.domain.BaseEntity; import org.dromara.common.mybatis.core.domain.BaseEntity;
import org.dromara.oa.erp.domain.ErpProjectReportDetail; import org.dromara.oa.erp.domain.ErpProjectReportDetail;
import org.dromara.workflow.api.domain.RemoteFlowInstanceBizExt;
import java.util.Date; import java.util.Date;
import java.util.HashMap;
import java.util.Map;
import java.util.Objects;
/** /**
* erp_project_report_detail * erp_project_report_detail
@ -96,6 +101,10 @@ public class ErpProjectReportDetailBo extends BaseEntity {
* *
*/ */
private String flowStatus; private String flowStatus;
/**
*
*/
private String flowCode;
/** /**
* *
@ -127,5 +136,49 @@ public class ErpProjectReportDetailBo extends BaseEntity {
*/ */
private String activeFlag; private String activeFlag;
/**
* {'entity': {}}
*/
private Map<String, Object> variables;
/**
*
*/
private RemoteFlowInstanceBizExt bizExt;
/**
*
*/
private String deptName;
/**
*
*/
private String managerName;
/**
*
*/
private String chargeName;
/**
*
*/
private String deputyName;
public Map<String, Object> getVariables() {
if (variables == null) {
return new HashMap<>(16);
}
variables.entrySet().removeIf(entry -> Objects.isNull(entry.getValue()));
return variables;
}
public RemoteFlowInstanceBizExt getBizExt() {
if (ObjectUtil.isNull(bizExt)) {
bizExt = new RemoteFlowInstanceBizExt();
}
return bizExt;
}
} }

@ -0,0 +1,12 @@
package org.dromara.oa.erp.domain.bo;
import jakarta.validation.Valid;
import lombok.Data;
@Data
public class ProjectReportAndDetailWrapperBo {
@Valid
private ErpProjectReportBo projectReport;
@Valid
private ErpProjectReportDetailBo projectDetailReport;
}

@ -155,5 +155,28 @@ public class ErpProjectReportDetailVo implements Serializable {
@ExcelDictFormat(readConverterExp = "1=是,0=否") @ExcelDictFormat(readConverterExp = "1=是,0=否")
private String activeFlag; private String activeFlag;
/**
*
*/
@ExcelProperty(value = "部门名称")
private String deptName;
/**
*
*/
@ExcelProperty(value = "项目经理名称")
private String managerName;
/**
*
*/
@ExcelProperty(value = "部门负责人名称")
private String chargeName;
/**
*
*/
@ExcelProperty(value = "分管副总名称")
private String deputyName;
} }

@ -66,4 +66,12 @@ public interface IErpAfterSalesService {
* @return * @return
*/ */
Boolean deleteWithValidByIds(Collection<Long> ids, Boolean isValid); Boolean deleteWithValidByIds(Collection<Long> ids, Boolean isValid);
/**
*
* @param bo
* @return
*/
ErpAfterSalesVo submitAndFlowStart(ErpAfterSalesBo bo);
} }

@ -2,7 +2,11 @@ package org.dromara.oa.erp.service;
import org.dromara.common.mybatis.core.page.PageQuery; import org.dromara.common.mybatis.core.page.PageQuery;
import org.dromara.common.mybatis.core.page.TableDataInfo; import org.dromara.common.mybatis.core.page.TableDataInfo;
import org.dromara.oa.erp.domain.bo.ErpContractInfoBo;
import org.dromara.oa.erp.domain.bo.ErpProjectReportBo;
import org.dromara.oa.erp.domain.bo.ErpProjectReportDetailBo; import org.dromara.oa.erp.domain.bo.ErpProjectReportDetailBo;
import org.dromara.oa.erp.domain.bo.ProjectReportAndDetailWrapperBo;
import org.dromara.oa.erp.domain.vo.ErpContractInfoVo;
import org.dromara.oa.erp.domain.vo.ErpProjectReportDetailVo; import org.dromara.oa.erp.domain.vo.ErpProjectReportDetailVo;
import java.util.Collection; import java.util.Collection;
@ -65,4 +69,11 @@ public interface IErpProjectReportDetailService {
* @return * @return
*/ */
Boolean deleteWithValidByIds(Collection<Long> ids, Boolean isValid); Boolean deleteWithValidByIds(Collection<Long> ids, Boolean isValid);
/**
*
* @param
* @return
*/
ErpProjectReportDetailVo projectReportSubmitAndFlowStart(ErpProjectReportBo projectReport, ErpProjectReportDetailBo projectDetailReport);
} }

@ -1,6 +1,12 @@
package org.dromara.oa.erp.service.impl; package org.dromara.oa.erp.service.impl;
import cn.hutool.core.collection.CollUtil; import cn.hutool.core.collection.CollUtil;
import cn.hutool.core.convert.Convert;
import lombok.extern.slf4j.Slf4j;
import org.apache.dubbo.config.annotation.DubboReference;
import org.apache.seata.spring.annotation.GlobalTransactional;
import org.dromara.common.core.enums.BusinessStatusEnum;
import org.dromara.common.core.exception.ServiceException;
import org.dromara.common.core.utils.MapstructUtils; import org.dromara.common.core.utils.MapstructUtils;
import org.dromara.common.core.utils.StringUtils; import org.dromara.common.core.utils.StringUtils;
import org.dromara.common.mybatis.core.page.TableDataInfo; import org.dromara.common.mybatis.core.page.TableDataInfo;
@ -10,6 +16,7 @@ import com.github.yulichang.toolkit.JoinWrappers;
import com.github.yulichang.wrapper.MPJLambdaWrapper; import com.github.yulichang.wrapper.MPJLambdaWrapper;
import com.baomidou.mybatisplus.core.toolkit.Wrappers; import com.baomidou.mybatisplus.core.toolkit.Wrappers;
import lombok.RequiredArgsConstructor; import lombok.RequiredArgsConstructor;
import org.dromara.common.tenant.helper.TenantHelper;
import org.dromara.oa.erp.domain.ErpAfterSalesLaborCosts; import org.dromara.oa.erp.domain.ErpAfterSalesLaborCosts;
import org.dromara.oa.erp.domain.ErpAfterSalesMaterialCosts; import org.dromara.oa.erp.domain.ErpAfterSalesMaterialCosts;
import org.dromara.oa.erp.domain.bo.ErpAfterSalesLaborCostsBo; import org.dromara.oa.erp.domain.bo.ErpAfterSalesLaborCostsBo;
@ -18,6 +25,8 @@ import org.dromara.oa.erp.domain.vo.ErpAfterSalesLaborCostsVo;
import org.dromara.oa.erp.domain.vo.ErpAfterSalesMaterialCostsVo; import org.dromara.oa.erp.domain.vo.ErpAfterSalesMaterialCostsVo;
import org.dromara.oa.erp.service.IErpAfterSalesLaborCostsService; import org.dromara.oa.erp.service.IErpAfterSalesLaborCostsService;
import org.dromara.oa.erp.service.IErpAfterSalesMaterialCostsService; import org.dromara.oa.erp.service.IErpAfterSalesMaterialCostsService;
import org.dromara.workflow.api.RemoteWorkflowService;
import org.dromara.workflow.api.domain.RemoteStartProcess;
import org.springframework.stereotype.Service; import org.springframework.stereotype.Service;
import org.dromara.oa.erp.domain.bo.ErpAfterSalesBo; import org.dromara.oa.erp.domain.bo.ErpAfterSalesBo;
import org.dromara.oa.erp.domain.vo.ErpAfterSalesVo; import org.dromara.oa.erp.domain.vo.ErpAfterSalesVo;
@ -26,7 +35,12 @@ import org.dromara.oa.erp.mapper.ErpAfterSalesMapper;
import org.dromara.oa.erp.service.IErpAfterSalesService; import org.dromara.oa.erp.service.IErpAfterSalesService;
import org.springframework.transaction.annotation.Transactional; import org.springframework.transaction.annotation.Transactional;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper; import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import org.springframework.context.event.EventListener;
import org.dromara.workflow.api.event.ProcessEvent;
import java.util.HashMap;
import java.util.List; import java.util.List;
import java.util.Map; import java.util.Map;
import java.util.Collection; import java.util.Collection;
@ -39,12 +53,14 @@ import java.util.Collection;
*/ */
@RequiredArgsConstructor @RequiredArgsConstructor
@Service @Service
@Slf4j
public class ErpAfterSalesServiceImpl implements IErpAfterSalesService { public class ErpAfterSalesServiceImpl implements IErpAfterSalesService {
private final ErpAfterSalesMapper baseMapper; private final ErpAfterSalesMapper baseMapper;
// 【修改点 1】注入两个子表的 Service @DubboReference(timeout = 30000)
// 注意:这里必须加 final配合 @RequiredArgsConstructor 使用 private RemoteWorkflowService remoteWorkflowService;
private final IErpAfterSalesLaborCostsService laborCostsService; private final IErpAfterSalesLaborCostsService laborCostsService;
private final IErpAfterSalesMaterialCostsService materialCostsService; private final IErpAfterSalesMaterialCostsService materialCostsService;
@ -56,31 +72,21 @@ public class ErpAfterSalesServiceImpl implements IErpAfterSalesService {
*/ */
@Override @Override
public ErpAfterSalesVo queryById(Long afterSalesId){ public ErpAfterSalesVo queryById(Long afterSalesId){
// 1. 查询主表 VO
ErpAfterSalesVo vo = baseMapper.selectVoById(afterSalesId); ErpAfterSalesVo vo = baseMapper.selectVoById(afterSalesId);
// 2. 如果主表存在,继续查询子表
if (vo != null) { if (vo != null) {
// ============ 处理人工费 ============
// 2.1 使用 list 方法查询出 Entity 列表
List<ErpAfterSalesLaborCosts> laborEntities = laborCostsService.list( List<ErpAfterSalesLaborCosts> laborEntities = laborCostsService.list(
new LambdaQueryWrapper<ErpAfterSalesLaborCosts>() new LambdaQueryWrapper<ErpAfterSalesLaborCosts>()
.eq(ErpAfterSalesLaborCosts::getAfterSalesId, afterSalesId) .eq(ErpAfterSalesLaborCosts::getAfterSalesId, afterSalesId)
); );
// 2.2 将 Entity 列表转换为 VO 列表 (核心修复点)
List<ErpAfterSalesLaborCostsVo> laborVos = MapstructUtils.convert(laborEntities, ErpAfterSalesLaborCostsVo.class); List<ErpAfterSalesLaborCostsVo> laborVos = MapstructUtils.convert(laborEntities, ErpAfterSalesLaborCostsVo.class);
// 2.3 塞入主表对象
vo.setLaborCostsList(laborVos); vo.setLaborCostsList(laborVos);
// ============ 处理材料费 ============
// 3.1 使用 list 方法查询出 Entity 列表
List<ErpAfterSalesMaterialCosts> materialEntities = materialCostsService.list( List<ErpAfterSalesMaterialCosts> materialEntities = materialCostsService.list(
new LambdaQueryWrapper<ErpAfterSalesMaterialCosts>() new LambdaQueryWrapper<ErpAfterSalesMaterialCosts>()
.eq(ErpAfterSalesMaterialCosts::getAfterSalesId, afterSalesId) .eq(ErpAfterSalesMaterialCosts::getAfterSalesId, afterSalesId)
); );
// 3.2 将 Entity 列表转换为 VO 列表
List<ErpAfterSalesMaterialCostsVo> materialVos = MapstructUtils.convert(materialEntities, ErpAfterSalesMaterialCostsVo.class); List<ErpAfterSalesMaterialCostsVo> materialVos = MapstructUtils.convert(materialEntities, ErpAfterSalesMaterialCostsVo.class);
// 3.3 塞入主表对象
vo.setMaterialCostsList(materialVos); vo.setMaterialCostsList(materialVos);
} }
return vo; return vo;
@ -155,35 +161,23 @@ public class ErpAfterSalesServiceImpl implements IErpAfterSalesService {
@Override @Override
@Transactional(rollbackFor = Exception.class) // 【重要】开启事务!如果子表保存失败,主表也要回滚,防止数据不一致 @Transactional(rollbackFor = Exception.class) // 【重要】开启事务!如果子表保存失败,主表也要回滚,防止数据不一致
public Boolean insertByBo(ErpAfterSalesBo bo) { public Boolean insertByBo(ErpAfterSalesBo bo) {
// 1. 将 BO (业务对象) 转换为 Entity (数据库实体)
// MapstructUtils 是 Plus 封装的高性能 Bean 拷贝工具
ErpAfterSales add = MapstructUtils.convert(bo, ErpAfterSales.class); ErpAfterSales add = MapstructUtils.convert(bo, ErpAfterSales.class);
// 2. 校验数据(这是生成的代码自带的)
validEntityBeforeSave(add); validEntityBeforeSave(add);
// 3. 保存主表
// baseMapper.insert(add) 返回受影响行数大于0表示成功
// 成功后MyBatis 会自动把生成的 ID 回填到 add 对象中
boolean flag = baseMapper.insert(add) > 0; boolean flag = baseMapper.insert(add) > 0;
bo.setAfterSalesId(add.getAfterSalesId()); // 将生成的 ID 回填给 BO
// 4. 如果主表保存成功,开始处理子表
if (flag) { if (flag) {
Long afterSalesId = add.getAfterSalesId(); // 拿到主表刚才生成的 ID Long afterSalesId = add.getAfterSalesId();
// --- 处理子表 A人员费用 ---
List<ErpAfterSalesLaborCostsBo> laborBoList = bo.getLaborCostsList(); List<ErpAfterSalesLaborCostsBo> laborBoList = bo.getLaborCostsList();
// 使用 CollUtil.isNotEmpty 判断列表不为空
if (CollUtil.isNotEmpty(laborBoList)) { if (CollUtil.isNotEmpty(laborBoList)) {
// 将 BO 列表转为 Entity 列表
List<ErpAfterSalesLaborCosts> laborList = MapstructUtils.convert(laborBoList, ErpAfterSalesLaborCosts.class); List<ErpAfterSalesLaborCosts> laborList = MapstructUtils.convert(laborBoList, ErpAfterSalesLaborCosts.class);
// 遍历每个子对象,把主表 ID 填进去,建立外键关联
laborList.forEach(item -> item.setAfterSalesId(afterSalesId)); laborList.forEach(item -> item.setAfterSalesId(afterSalesId));
// 批量保存
laborCostsService.saveBatch(laborList); laborCostsService.saveBatch(laborList);
} }
// --- 处理子表 B材料费用 ---
List<ErpAfterSalesMaterialCostsBo> materialBoList = bo.getMaterialCostsList(); List<ErpAfterSalesMaterialCostsBo> materialBoList = bo.getMaterialCostsList();
if (CollUtil.isNotEmpty(materialBoList)) { if (CollUtil.isNotEmpty(materialBoList)) {
List<ErpAfterSalesMaterialCosts> materialList = MapstructUtils.convert(materialBoList, ErpAfterSalesMaterialCosts.class); List<ErpAfterSalesMaterialCosts> materialList = MapstructUtils.convert(materialBoList, ErpAfterSalesMaterialCosts.class);
@ -203,17 +197,14 @@ public class ErpAfterSalesServiceImpl implements IErpAfterSalesService {
@Override @Override
@Transactional(rollbackFor = Exception.class) // 【重要】开启事务 @Transactional(rollbackFor = Exception.class) // 【重要】开启事务
public Boolean updateByBo(ErpAfterSalesBo bo) { public Boolean updateByBo(ErpAfterSalesBo bo) {
// 1. 更新主表数据
ErpAfterSales update = MapstructUtils.convert(bo, ErpAfterSales.class); ErpAfterSales update = MapstructUtils.convert(bo, ErpAfterSales.class);
validEntityBeforeSave(update); validEntityBeforeSave(update);
// updateById 会根据主键 ID 更新其他字段
int row = baseMapper.updateById(update); int row = baseMapper.updateById(update);
// 2. 如果主表更新成功,开始处理子表
if (row > 0) { if (row > 0) {
Long afterSalesId = bo.getAfterSalesId(); Long afterSalesId = bo.getAfterSalesId();
// ================== 1. 处理人员费用 ================== // ================== 处理人员费用 ==================
// 先删除旧的 // 先删除旧的
laborCostsService.remove(new LambdaQueryWrapper<ErpAfterSalesLaborCosts>() laborCostsService.remove(new LambdaQueryWrapper<ErpAfterSalesLaborCosts>()
.eq(ErpAfterSalesLaborCosts::getAfterSalesId, afterSalesId)); .eq(ErpAfterSalesLaborCosts::getAfterSalesId, afterSalesId));
@ -223,7 +214,7 @@ public class ErpAfterSalesServiceImpl implements IErpAfterSalesService {
if (CollUtil.isNotEmpty(laborBoList)) { if (CollUtil.isNotEmpty(laborBoList)) {
List<ErpAfterSalesLaborCosts> laborList = MapstructUtils.convert(laborBoList, ErpAfterSalesLaborCosts.class); List<ErpAfterSalesLaborCosts> laborList = MapstructUtils.convert(laborBoList, ErpAfterSalesLaborCosts.class);
// 【核心修改点 👇】遍历列表,清空 ID // 遍历列表,清空 ID
laborList.forEach(item -> { laborList.forEach(item -> {
item.setLaborCostsId(null); // 关键清空ID让MP重新生成雪花ID避免和逻辑删除的数据冲突 item.setLaborCostsId(null); // 关键清空ID让MP重新生成雪花ID避免和逻辑删除的数据冲突
item.setAfterSalesId(afterSalesId); item.setAfterSalesId(afterSalesId);
@ -232,17 +223,14 @@ public class ErpAfterSalesServiceImpl implements IErpAfterSalesService {
laborCostsService.saveBatch(laborList); laborCostsService.saveBatch(laborList);
} }
// ================== 2. 处理材料费用 ================== // ================== 处理材料费用 ==================
// 先删除旧的
materialCostsService.remove(new LambdaQueryWrapper<ErpAfterSalesMaterialCosts>() materialCostsService.remove(new LambdaQueryWrapper<ErpAfterSalesMaterialCosts>()
.eq(ErpAfterSalesMaterialCosts::getAfterSalesId, afterSalesId)); .eq(ErpAfterSalesMaterialCosts::getAfterSalesId, afterSalesId));
// 后新增新的
List<ErpAfterSalesMaterialCostsBo> materialBoList = bo.getMaterialCostsList(); List<ErpAfterSalesMaterialCostsBo> materialBoList = bo.getMaterialCostsList();
if (CollUtil.isNotEmpty(materialBoList)) { if (CollUtil.isNotEmpty(materialBoList)) {
List<ErpAfterSalesMaterialCosts> materialList = MapstructUtils.convert(materialBoList, ErpAfterSalesMaterialCosts.class); List<ErpAfterSalesMaterialCosts> materialList = MapstructUtils.convert(materialBoList, ErpAfterSalesMaterialCosts.class);
// 【核心修改点 👇】遍历列表,清空 ID
materialList.forEach(item -> { materialList.forEach(item -> {
item.setMaterialCostsId(null); // 关键清空ID item.setMaterialCostsId(null); // 关键清空ID
item.setAfterSalesId(afterSalesId); item.setAfterSalesId(afterSalesId);
@ -275,4 +263,104 @@ public class ErpAfterSalesServiceImpl implements IErpAfterSalesService {
} }
return baseMapper.deleteByIds(ids) > 0; return baseMapper.deleteByIds(ids) > 0;
} }
/**
*
*
* @param bo
* @return
*/
@Override
@GlobalTransactional(rollbackFor = Exception.class) // 开启全局事务
public ErpAfterSalesVo submitAndFlowStart(ErpAfterSalesBo bo) {
ErpAfterSales add = MapstructUtils.convert(bo, ErpAfterSales.class);
validEntityBeforeSave(add);
if (bo.getAfterSalesId() == null) {
this.insertByBo(bo);
} else {
this.updateByBo(bo);
}
// 准备启动流程参数
// 后端发起需要忽略权限
if (bo.getVariables() == null) {
bo.setVariables(new HashMap<>());
}
bo.getVariables().put("ignore", true);
RemoteStartProcess startProcess = new RemoteStartProcess();
startProcess.setBusinessId(bo.getAfterSalesId().toString());
startProcess.setFlowCode(bo.getFlowCode());
startProcess.setVariables(bo.getVariables());
startProcess.setBizExt(bo.getBizExt());
// 确保 BizExt 里也有 BusinessId
if (bo.getBizExt() != null) {
bo.getBizExt().setBusinessId(startProcess.getBusinessId());
}
// 调用远程服务启动流程
// startCompleteTask 表示“启动并自动完成第一个发起节点”,直接流转到下一个审批人
boolean flagOne = remoteWorkflowService.startCompleteTask(startProcess);
if (!flagOne) {
throw new ServiceException("流程发起异常");
}
return MapstructUtils.convert(add, ErpAfterSalesVo.class);
}
/**
* (: 稿退)
*
* @param processEvent
*/
@EventListener(condition = "#processEvent.flowCode == 'OAAS'")
public void processHandler(ProcessEvent processEvent) {
// 多租户上下文切换(防止异步线程找不到租户)
TenantHelper.dynamic(processEvent.getTenantId(), () -> {
log.info("【售后流程监听】开始处理: key={}, status={}", processEvent.getFlowCode(), processEvent.getStatus());
// 根据 BusinessId 查询出当前的售后单
Long afterSalesId = Convert.toLong(processEvent.getBusinessId());
ErpAfterSales afterSales = baseMapper.selectById(afterSalesId);
if (afterSales == null) {
log.error("未找到对应的售后单据id={}", afterSalesId);
return;
}
// 同步流程状态 (flow_status)
afterSales.setFlowStatus(processEvent.getStatus());
// 根据流程状态,更新业务状态 (after_sales_status)
String status = processEvent.getStatus();
// A. 审批中
if (BusinessStatusEnum.WAITING.getStatus().equals(status)) {
afterSales.setAfterSalesStatus("1");
}
// B. 流程结束/审批通过 (Finish)
else if (BusinessStatusEnum.FINISH.getStatus().equals(status)) {
afterSales.setAfterSalesStatus("2");
}
// C. 驳回 (Back) 或 撤销 (Cancel)
else if (BusinessStatusEnum.BACK.getStatus().equals(status)
|| BusinessStatusEnum.CANCEL.getStatus().equals(status)) {
afterSales.setAfterSalesStatus("0");
}
// D. 作废 (Invalid) 或 终止 (Termination)
else if (BusinessStatusEnum.INVALID.getStatus().equals(status)
|| BusinessStatusEnum.TERMINATION.getStatus().equals(status)) {
afterSales.setAfterSalesStatus("0");
}
// 4. 更新数据库
baseMapper.updateById(afterSales);
});
}
} }

@ -1,23 +1,46 @@
package org.dromara.oa.erp.service.impl; package org.dromara.oa.erp.service.impl;
import cn.hutool.core.convert.Convert;
import cn.hutool.core.map.MapUtil;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page; import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.github.yulichang.toolkit.JoinWrappers; import com.github.yulichang.toolkit.JoinWrappers;
import lombok.extern.slf4j.Slf4j;
import com.github.yulichang.wrapper.MPJLambdaWrapper; import com.github.yulichang.wrapper.MPJLambdaWrapper;
import lombok.RequiredArgsConstructor; import lombok.RequiredArgsConstructor;
import org.apache.dubbo.config.annotation.DubboReference;
import org.apache.seata.spring.annotation.GlobalTransactional;
import org.dromara.common.core.enums.BusinessStatusEnum;
import org.dromara.common.core.enums.OAStatusEnum;
import org.dromara.common.core.exception.ServiceException;
import org.dromara.common.core.utils.MapstructUtils; import org.dromara.common.core.utils.MapstructUtils;
import org.dromara.common.core.utils.StringUtils; import org.dromara.common.core.utils.StringUtils;
import org.dromara.common.mybatis.core.page.PageQuery; import org.dromara.common.mybatis.core.page.PageQuery;
import org.dromara.common.mybatis.core.page.TableDataInfo; import org.dromara.common.mybatis.core.page.TableDataInfo;
import org.dromara.common.tenant.helper.TenantHelper;
import org.dromara.oa.erp.domain.ErpContractInfo;
import org.dromara.oa.erp.domain.ErpProjectReport;
import org.dromara.oa.erp.domain.ErpProjectReportDetail; import org.dromara.oa.erp.domain.ErpProjectReportDetail;
import org.dromara.oa.erp.domain.bo.ErpContractInfoBo;
import org.dromara.oa.erp.domain.bo.ErpProjectReportBo;
import org.dromara.oa.erp.domain.bo.ErpProjectReportDetailBo; import org.dromara.oa.erp.domain.bo.ErpProjectReportDetailBo;
import org.dromara.oa.erp.domain.bo.ProjectReportAndDetailWrapperBo;
import org.dromara.oa.erp.domain.vo.ErpContractInfoVo;
import org.dromara.oa.erp.domain.vo.ErpProjectReportDetailVo; import org.dromara.oa.erp.domain.vo.ErpProjectReportDetailVo;
import org.dromara.oa.erp.domain.vo.ErpProjectReportVo;
import org.dromara.oa.erp.mapper.ErpProjectReportDetailMapper; import org.dromara.oa.erp.mapper.ErpProjectReportDetailMapper;
import org.dromara.oa.erp.mapper.ErpProjectReportMapper;
import org.dromara.oa.erp.service.IErpProjectReportDetailService; import org.dromara.oa.erp.service.IErpProjectReportDetailService;
import org.dromara.oa.erp.service.IErpProjectReportService;
import org.dromara.workflow.api.RemoteWorkflowService;
import org.dromara.workflow.api.domain.RemoteStartProcess;
import org.dromara.workflow.api.event.ProcessEvent;
import org.springframework.context.event.EventListener;
import org.springframework.stereotype.Service; import org.springframework.stereotype.Service;
import java.util.Collection; import java.util.Collection;
import java.util.List; import java.util.List;
import java.util.Map; import java.util.Map;
import java.util.Objects;
/** /**
* Service * Service
@ -27,10 +50,17 @@ import java.util.Map;
*/ */
@RequiredArgsConstructor @RequiredArgsConstructor
@Service @Service
@Slf4j
public class ErpProjectReportDetailServiceImpl implements IErpProjectReportDetailService { public class ErpProjectReportDetailServiceImpl implements IErpProjectReportDetailService {
private final IErpProjectReportService erpProjectReportService;
private final ErpProjectReportDetailMapper baseMapper; private final ErpProjectReportDetailMapper baseMapper;
@DubboReference(timeout = 30000)
private RemoteWorkflowService remoteWorkflowService;
/** /**
* *
* *
@ -146,4 +176,77 @@ public class ErpProjectReportDetailServiceImpl implements IErpProjectReportDetai
} }
return baseMapper.deleteByIds(ids) > 0; return baseMapper.deleteByIds(ids) > 0;
} }
/**
*
* @param projectReport
* @param projectDetailReport
* @return
*/
@Override
@GlobalTransactional(rollbackFor = Exception.class)
public ErpProjectReportDetailVo projectReportSubmitAndFlowStart(ErpProjectReportBo projectReport, ErpProjectReportDetailBo projectDetailReport) {
if (projectReport.getReportId() != null) {
ErpProjectReportVo existingReport = erpProjectReportService.queryById(projectReport.getReportId());
if (existingReport != null) {
erpProjectReportService.updateByBo(projectReport);
} else {
erpProjectReportService.insertByBo(projectReport);
}
} else {
erpProjectReportService.insertByBo(projectReport);
}
ErpProjectReportDetail erpProjectReportDetail = MapstructUtils.convert(projectDetailReport, ErpProjectReportDetail.class);
validEntityBeforeSave(erpProjectReportDetail);
if (StringUtils.isNull(projectDetailReport.getReportDetailId())) {
this.insertByBo(projectDetailReport);
} else {
this.updateByBo(projectDetailReport);
}
// 后端发起需要忽略权限
projectDetailReport.getVariables().put("ignore", true);
RemoteStartProcess startProcess = new RemoteStartProcess();
startProcess.setBusinessId(projectDetailReport.getReportDetailId().toString());
startProcess.setFlowCode(projectDetailReport.getFlowCode());
startProcess.setVariables(projectDetailReport.getVariables());
startProcess.setBizExt(projectDetailReport.getBizExt());
projectDetailReport.getBizExt().setBusinessId(startProcess.getBusinessId());
boolean flagOne = remoteWorkflowService.startCompleteTask(startProcess);
if (!flagOne) {
throw new ServiceException("流程发起异常");
}
return MapstructUtils.convert(erpProjectReportDetail, ErpProjectReportDetailVo.class);
}
/**
* (: 稿退)
*
* @param processEvent
*/
@EventListener(condition = "#processEvent.flowCode =='XMZB'")
public void processHandler(ProcessEvent processEvent) {
TenantHelper.dynamic(processEvent.getTenantId(), () -> {
log.info("当前任务执行了{}", processEvent.toString());
ErpProjectReportDetail projectReportDetail = baseMapper.selectById(Convert.toLong(processEvent.getBusinessId()));
projectReportDetail.setFlowStatus(processEvent.getStatus());
Map<String, Object> params = processEvent.getParams();
if (MapUtil.isNotEmpty(params)) {
// 办理人
String handler = Convert.toStr(params.get("handler"));
}
if (Objects.equals(processEvent.getStatus(), BusinessStatusEnum.WAITING.getStatus())) {
projectReportDetail.setProjectReportStatus(OAStatusEnum.APPROVING.getStatus());
} else if (Objects.equals(processEvent.getStatus(), BusinessStatusEnum.FINISH.getStatus())) {
projectReportDetail.setProjectReportStatus(OAStatusEnum.COMPLETED.getStatus());
} else if (Objects.equals(processEvent.getStatus(), BusinessStatusEnum.INVALID.getStatus())
|| Objects.equals(processEvent.getStatus(), BusinessStatusEnum.TERMINATION.getStatus())) {
projectReportDetail.setProjectReportStatus(OAStatusEnum.INVALID.getStatus());
} else if (Objects.equals(processEvent.getStatus(), BusinessStatusEnum.BACK.getStatus())
|| Objects.equals(processEvent.getStatus(), BusinessStatusEnum.CANCEL.getStatus())) {
projectReportDetail.setProjectReportStatus(OAStatusEnum.DRAFT.getStatus());
}
baseMapper.updateById(projectReportDetail);
});
}
} }

@ -38,23 +38,23 @@ public class ErpProjectReportServiceImpl implements IErpProjectReportService {
* @return * @return
*/ */
@Override @Override
public ErpProjectReportVo queryById(Long reportId){ public ErpProjectReportVo queryById(Long reportId) {
return baseMapper.selectVoById(reportId); return baseMapper.selectVoById(reportId);
} }
/** /**
* *
* *
* @param bo * @param bo
* @param pageQuery * @param pageQuery
* @return * @return
*/ */
@Override @Override
public TableDataInfo<ErpProjectReportVo> queryPageList(ErpProjectReportBo bo, PageQuery pageQuery) { public TableDataInfo<ErpProjectReportVo> queryPageList(ErpProjectReportBo bo, PageQuery pageQuery) {
MPJLambdaWrapper<ErpProjectReport> lqw = buildQueryWrapper(bo); MPJLambdaWrapper<ErpProjectReport> lqw = buildQueryWrapper(bo);
Page<ErpProjectReportVo> result = baseMapper.selectCustomErpProjectReportVoList(pageQuery.build(), lqw); Page<ErpProjectReportVo> result = baseMapper.selectCustomErpProjectReportVoList(pageQuery.build(), lqw);
return TableDataInfo.build(result); return TableDataInfo.build(result);
} }
/** /**
* *
@ -71,21 +71,27 @@ public class ErpProjectReportServiceImpl implements IErpProjectReportService {
private MPJLambdaWrapper<ErpProjectReport> buildQueryWrapper(ErpProjectReportBo bo) { private MPJLambdaWrapper<ErpProjectReport> buildQueryWrapper(ErpProjectReportBo bo) {
Map<String, Object> params = bo.getParams(); Map<String, Object> params = bo.getParams();
MPJLambdaWrapper<ErpProjectReport> lqw = JoinWrappers.lambda(ErpProjectReport.class) MPJLambdaWrapper<ErpProjectReport> lqw = JoinWrappers.lambda(ErpProjectReport.class)
.selectAll(ErpProjectReport.class) .selectAll(ErpProjectReport.class)
.eq(bo.getProjectId() != null, ErpProjectReport::getProjectId, bo.getProjectId()) .eq(bo.getProjectId() != null, ErpProjectReport::getProjectId, bo.getProjectId())
.like(StringUtils.isNotBlank(bo.getProjectName()), ErpProjectReport::getProjectName, bo.getProjectName()) .eq(StringUtils.isNotBlank(bo.getMilestonePlan()), ErpProjectReport::getMilestonePlan, bo.getMilestonePlan())
.eq(StringUtils.isNotBlank(bo.getMilestonePlan()), ErpProjectReport::getMilestonePlan, bo.getMilestonePlan()) .eq(bo.getManagerId() != null, ErpProjectReport::getManagerId, bo.getManagerId())
.eq(bo.getManagerId() != null, ErpProjectReport::getManagerId, bo.getManagerId()) .eq(bo.getDeptId() != null, ErpProjectReport::getDeptId, bo.getDeptId())
.eq(bo.getDeptId() != null, ErpProjectReport::getDeptId, bo.getDeptId()) .eq(bo.getChargeId() != null, ErpProjectReport::getChargeId, bo.getChargeId())
.eq(bo.getChargeId() != null, ErpProjectReport::getChargeId, bo.getChargeId()) .eq(bo.getDeputyId() != null, ErpProjectReport::getDeputyId, bo.getDeputyId())
.eq(bo.getDeputyId() != null, ErpProjectReport::getDeputyId, bo.getDeputyId()) .eq(StringUtils.isNotBlank(bo.getInformationNote()), ErpProjectReport::getInformationNote, bo.getInformationNote())
.eq(StringUtils.isNotBlank(bo.getInformationNote()), ErpProjectReport::getInformationNote, bo.getInformationNote()) .eq(bo.getSortOrder() != null, ErpProjectReport::getSortOrder, bo.getSortOrder())
.eq(bo.getSortOrder() != null, ErpProjectReport::getSortOrder, bo.getSortOrder()) .eq(StringUtils.isNotBlank(bo.getOssId()), ErpProjectReport::getOssId, bo.getOssId())
.eq(StringUtils.isNotBlank(bo.getOssId()), ErpProjectReport::getOssId, bo.getOssId()) .eq(StringUtils.isNotBlank(bo.getActiveFlag()), ErpProjectReport::getActiveFlag, bo.getActiveFlag())
.eq(StringUtils.isNotBlank(bo.getActiveFlag()), ErpProjectReport::getActiveFlag, bo.getActiveFlag()) .like(StringUtils.isNotBlank(bo.getProjectName()), ErpProjectReport::getProjectName, bo.getProjectName())
.eq(StringUtils.isNotBlank(bo.getProjectCode()), ErpProjectReport::getProjectCode, bo.getProjectCode()) .like(StringUtils.isNotBlank(bo.getProjectCode()), ErpProjectReport::getProjectCode, bo.getProjectCode())
; // 关联表条件 - 使用 apply 方法添加
.apply(StringUtils.isNotBlank(bo.getDeptName()), "d.dept_name LIKE CONCAT('%', {0}, '%')", bo.getDeptName())
.apply(StringUtils.isNotBlank(bo.getManagerName()), "u1.nick_name LIKE CONCAT('%', {0}, '%')", bo.getManagerName())
.apply(StringUtils.isNotBlank(bo.getChargeName()), "u2.nick_name LIKE CONCAT('%', {0}, '%')", bo.getChargeName())
.apply(StringUtils.isNotBlank(bo.getDeputyName()), "u3.nick_name LIKE CONCAT('%', {0}, '%')", bo.getDeputyName());
return lqw; return lqw;
} }
/** /**
@ -121,7 +127,7 @@ public class ErpProjectReportServiceImpl implements IErpProjectReportService {
/** /**
* *
*/ */
private void validEntityBeforeSave(ErpProjectReport entity){ private void validEntityBeforeSave(ErpProjectReport entity) {
//TODO 做一些数据校验,如唯一约束 //TODO 做一些数据校验,如唯一约束
} }
@ -134,7 +140,7 @@ public class ErpProjectReportServiceImpl implements IErpProjectReportService {
*/ */
@Override @Override
public Boolean deleteWithValidByIds(Collection<Long> ids, Boolean isValid) { public Boolean deleteWithValidByIds(Collection<Long> ids, Boolean isValid) {
if(isValid){ if (isValid) {
//TODO 做一些业务上的校验,判断是否需要校验 //TODO 做一些业务上的校验,判断是否需要校验
} }
return baseMapper.deleteByIds(ids) > 0; return baseMapper.deleteByIds(ids) > 0;

@ -37,7 +37,8 @@
left join sys_user u1 on u1.user_id = t.manager_id left join sys_user u1 on u1.user_id = t.manager_id
left join sys_user u2 on u2.user_id = t.charge_id left join sys_user u2 on u2.user_id = t.charge_id
left join sys_user u3 on u3.user_id = t.deputy_id left join sys_user u3 on u3.user_id = t.deputy_id
${ew.getCustomSqlSegment} ${ew.getCustomSqlSegment}
</select> </select>
</mapper> </mapper>

@ -51,6 +51,7 @@ public class WmsInventoryDetails extends TenantEntity {
* *
*/ */
private Double inventoryAmount; private Double inventoryAmount;
private Double startInventoryAmount; private Double startInventoryAmount;
/** /**
* *

@ -50,7 +50,7 @@ public class WmsInventoryDetailsBo extends BaseEntity {
* *
*/ */
private Double inventoryAmount; private Double inventoryAmount;
private Double startInventoryAmount;
/** /**
* *
*/ */

@ -8,6 +8,7 @@ import org.apache.ibatis.annotations.Param;
import org.dromara.wms.domain.WmsInventoryLedger; import org.dromara.wms.domain.WmsInventoryLedger;
import org.dromara.wms.domain.vo.WmsInventoryLedgerVo; import org.dromara.wms.domain.vo.WmsInventoryLedgerVo;
import org.dromara.common.mybatis.core.mapper.BaseMapperPlus; import org.dromara.common.mybatis.core.mapper.BaseMapperPlus;
import org.springframework.stereotype.Repository;
/** /**
* Mapper * Mapper
@ -15,6 +16,7 @@ import org.dromara.common.mybatis.core.mapper.BaseMapperPlus;
* @author Yinq * @author Yinq
* @date 2025-12-02 * @date 2025-12-02
*/ */
@Repository
public interface WmsInventoryLedgerMapper extends BaseMapperPlus<WmsInventoryLedger, WmsInventoryLedgerVo> { public interface WmsInventoryLedgerMapper extends BaseMapperPlus<WmsInventoryLedger, WmsInventoryLedgerVo> {
/** /**

@ -67,7 +67,8 @@ public interface IWmsInventoryDetailsService {
*/ */
Boolean deleteWithValidByIds(Collection<Long> ids, Boolean isValid); Boolean deleteWithValidByIds(Collection<Long> ids, Boolean isValid);
void insertList(List<WmsInventoryDetails> inventoryDetailsList);
TableDataInfo<WmsInventoryDetailsVo> listCount(WmsInventoryDetailsBo bo, PageQuery pageQuery); TableDataInfo<WmsInventoryDetailsVo> listCount(WmsInventoryDetailsBo bo, PageQuery pageQuery);
WmsInventoryDetails queryInventory(WmsInventoryDetailsBo inventory);
} }

@ -14,13 +14,15 @@ import org.dromara.system.api.RemoteCodeRuleService;
import org.dromara.wms.domain.WmsInStockBill; import org.dromara.wms.domain.WmsInStockBill;
import org.dromara.wms.domain.WmsInStockDetails; import org.dromara.wms.domain.WmsInStockDetails;
import org.dromara.wms.domain.WmsInventoryDetails; import org.dromara.wms.domain.WmsInventoryDetails;
import org.dromara.wms.domain.WmsInventoryLedger;
import org.dromara.wms.domain.bo.WmsInStockBillBo; import org.dromara.wms.domain.bo.WmsInStockBillBo;
import org.dromara.wms.domain.bo.WmsInventoryDetailsBo;
import org.dromara.wms.domain.vo.WmsInStockBillVo; import org.dromara.wms.domain.vo.WmsInStockBillVo;
import org.dromara.wms.mapper.WmsInStockBillMapper; import org.dromara.wms.mapper.WmsInStockBillMapper;
import org.dromara.wms.mapper.WmsInStockDetailsMapper; import org.dromara.wms.mapper.WmsInStockDetailsMapper;
import org.dromara.wms.mapper.WmsInventoryLedgerMapper;
import org.dromara.wms.service.IWmsInStockBillService; import org.dromara.wms.service.IWmsInStockBillService;
import org.dromara.wms.service.IWmsInventoryDetailsService; import org.dromara.wms.service.IWmsInventoryDetailsService;
import org.dromara.wms.service.IWmsWarehouseInfoService;
import org.dromara.workflow.api.RemoteWorkflowService; import org.dromara.workflow.api.RemoteWorkflowService;
import org.dromara.workflow.api.domain.RemoteStartProcess; import org.dromara.workflow.api.domain.RemoteStartProcess;
import org.dromara.workflow.api.event.ProcessEvent; import org.dromara.workflow.api.event.ProcessEvent;
@ -42,7 +44,8 @@ public class WmsInStockBillServiceImpl implements IWmsInStockBillService {
private final WmsInStockBillMapper baseMapper; private final WmsInStockBillMapper baseMapper;
private final WmsInStockDetailsMapper wmsInStockDetailsMapper; private final WmsInStockDetailsMapper wmsInStockDetailsMapper;
private final IWmsInventoryDetailsService inventoryService; private final IWmsInventoryDetailsService inventoryService;
private final IWmsWarehouseInfoService warehouseService; // private final IWmsWarehouseInfoService warehouseService;
private final WmsInventoryLedgerMapper wmsInventoryLedgerMapper;
@DubboReference @DubboReference
private RemoteCodeRuleService remoteCodeRuleService; private RemoteCodeRuleService remoteCodeRuleService;
@DubboReference(timeout = 30000)//超时时间 @DubboReference(timeout = 30000)//超时时间
@ -110,31 +113,57 @@ public class WmsInStockBillServiceImpl implements IWmsInStockBillService {
@Override @Override
public Boolean insertByBo(WmsInStockBillBo bo) { public Boolean insertByBo(WmsInStockBillBo bo) {
WmsInStockBill add = MapstructUtils.convert(bo, WmsInStockBill.class); WmsInStockBill add = MapstructUtils.convert(bo, WmsInStockBill.class);
add.setInStockCode(remoteCodeRuleService.selectCodeRuleCode("1005")); String inStockType = add.getInStockType();
add.setInStockCode(remoteCodeRuleService.selectCodeRuleCode("1005"));// 物料入库编码
add.setInStockBillStatus("3"); add.setInStockBillStatus("3");
boolean flag = baseMapper.insert(add) > 0; boolean flag = baseMapper.insert(add) > 0;//插入主表
if (flag) { if (flag) {
Long inStockBillId = add.getInStockBillId(); Long inStockBillId = add.getInStockBillId();
List<WmsInStockDetails> inStockDetailsList = bo.getInStockDetailsList(); List<WmsInStockDetails> inStockDetailsList = bo.getInStockDetailsList();
List<WmsInventoryDetails> inventoryDetailsList = new ArrayList<>(inStockDetailsList.size());//库存集合 List<WmsInventoryLedger> wmsInventoryLedgers = new ArrayList<>(inStockDetailsList.size());//库存集合
Long projectId = bo.getProjectId();// 项目ID Long projectId = bo.getProjectId();// 项目ID
inStockDetailsList.forEach(item -> { inStockDetailsList.forEach(item -> {
item.setInStockBillId(inStockBillId); // 设置入库单明细的入库单ID item.setInStockBillId(inStockBillId); // 设置入库单明细的入库单ID
item.setProjectId(projectId); // 关联项目 item.setProjectId(projectId); // 关联项目
WmsInventoryDetails inventory = new WmsInventoryDetails();
inventory.setWarehouseId(item.getWarehouseId()); // 关联仓库
inventory.setProjectId(projectId); // 关联项目
inventory.setBatchNumber(item.getBatchNumber()); // 关联批次号
inventory.setMaterielId(item.getMaterialId()); // 关联物料
inventory.setUnitPrice(item.getUnitPrice());
Double inStockAmount = item.getInStockAmount(); Double inStockAmount = item.getInStockAmount();
inventory.setInventoryAmount(inStockAmount); Double inventoryTableAmount = 0.0;// 库存表数量
inventory.setStartInventoryAmount(inStockAmount); // 初始库存数量 // 构建库存明细
inventoryDetailsList.add(inventory); WmsInventoryDetailsBo inventory = new WmsInventoryDetailsBo();
inventory.setWarehouseId(item.getWarehouseId());
inventory.setProjectId(projectId);
inventory.setBatchNumber(item.getBatchNumber());
inventory.setMaterielId(item.getMaterialId());
inventory.setUnitPrice(item.getUnitPrice());
// 查询相同项目 相同仓库 相同批次 相同单价的物料
WmsInventoryDetails queryInventory = inventoryService.queryInventory(inventory);
if (queryInventory != null) {
WmsInventoryDetailsBo inventoryUpdate = new WmsInventoryDetailsBo();
inventoryUpdate.setInventoryDetailsId(queryInventory.getInventoryDetailsId());
inventoryTableAmount = queryInventory.getInventoryAmount() ;
inventoryUpdate.setInventoryAmount(inventoryTableAmount+ inStockAmount);
inventoryService.updateByBo(inventoryUpdate); // 更新库存数量
} else {
inventory.setUnitName(item.getUnitName());
inventory.setInventoryAmount(inStockAmount);
inventory.setStartInventoryAmount(inStockAmount); // 初始库存数量
inventoryService.insertByBo(inventory);
}
//库存变动
WmsInventoryLedger wmsInventoryLedger = new WmsInventoryLedger();
wmsInventoryLedger.setWarehouseId(item.getWarehouseId());
wmsInventoryLedger.setBatchNumber(item.getBatchNumber());
wmsInventoryLedger.setMaterielId(item.getMaterialId());
wmsInventoryLedger.setChangeType(inStockType);//变动类型
wmsInventoryLedger.setLedgerState("1");
wmsInventoryLedger.setChangeAmount(inStockAmount);
wmsInventoryLedger.setInventoryAmount(inventoryTableAmount);
wmsInventoryLedgers.add(wmsInventoryLedger);
}); });
wmsInStockDetailsMapper.insert(inStockDetailsList); //插入子表 wmsInStockDetailsMapper.insert(inStockDetailsList); //插入子表
inventoryService.insertList(inventoryDetailsList); //插入库存 wmsInventoryLedgerMapper.insert(wmsInventoryLedgers);
} }
return flag; return flag;
} }

@ -127,7 +127,6 @@ public class WmsInventoryDetailsServiceImpl implements IWmsInventoryDetailsServi
@Override @Override
public Boolean insertByBo(WmsInventoryDetailsBo bo) { public Boolean insertByBo(WmsInventoryDetailsBo bo) {
WmsInventoryDetails add = MapstructUtils.convert(bo, WmsInventoryDetails.class); WmsInventoryDetails add = MapstructUtils.convert(bo, WmsInventoryDetails.class);
validEntityBeforeSave(add);
boolean flag = baseMapper.insert(add) > 0; boolean flag = baseMapper.insert(add) > 0;
if (flag) { if (flag) {
bo.setInventoryDetailsId(add.getInventoryDetailsId()); bo.setInventoryDetailsId(add.getInventoryDetailsId());
@ -144,16 +143,9 @@ public class WmsInventoryDetailsServiceImpl implements IWmsInventoryDetailsServi
@Override @Override
public Boolean updateByBo(WmsInventoryDetailsBo bo) { public Boolean updateByBo(WmsInventoryDetailsBo bo) {
WmsInventoryDetails update = MapstructUtils.convert(bo, WmsInventoryDetails.class); WmsInventoryDetails update = MapstructUtils.convert(bo, WmsInventoryDetails.class);
validEntityBeforeSave(update);
return baseMapper.updateById(update) > 0; return baseMapper.updateById(update) > 0;
} }
/**
*
*/
private void validEntityBeforeSave(WmsInventoryDetails entity) {
//TODO 做一些数据校验,如唯一约束
}
/** /**
* *
@ -164,14 +156,22 @@ public class WmsInventoryDetailsServiceImpl implements IWmsInventoryDetailsServi
*/ */
@Override @Override
public Boolean deleteWithValidByIds(Collection<Long> ids, Boolean isValid) { public Boolean deleteWithValidByIds(Collection<Long> ids, Boolean isValid) {
if (isValid) {
//TODO 做一些业务上的校验,判断是否需要校验
}
return baseMapper.deleteByIds(ids) > 0; return baseMapper.deleteByIds(ids) > 0;
} }
@Override @Override
public void insertList(List<WmsInventoryDetails> inventoryDetailsList) { public WmsInventoryDetails queryInventory(WmsInventoryDetailsBo bo) {
baseMapper.insert(inventoryDetailsList); MPJLambdaWrapper<WmsInventoryDetails> lqw = JoinWrappers.lambda(WmsInventoryDetails.class)
.selectAll(WmsInventoryDetails.class)
.eq(StringUtils.isNotBlank(bo.getLocationCode()), WmsInventoryDetails::getLocationCode, bo.getLocationCode())
.eq(bo.getWarehouseId() != null, WmsInventoryDetails::getWarehouseId, bo.getWarehouseId())
.eq(bo.getMaterielId() != null, WmsInventoryDetails::getMaterielId, bo.getMaterielId())
.eq(bo.getProjectId() != null, WmsInventoryDetails::getProjectId, bo.getProjectId())
.eq(StringUtils.isNotBlank(bo.getBatchNumber()), WmsInventoryDetails::getBatchNumber, bo.getBatchNumber())
.eq(bo.getUnitPrice() != null, WmsInventoryDetails::getUnitPrice, bo.getUnitPrice());
return baseMapper.selectOne(lqw);
} }
} }

@ -10,14 +10,18 @@ import org.dromara.common.core.utils.StringUtils;
import org.dromara.common.mybatis.core.page.PageQuery; import org.dromara.common.mybatis.core.page.PageQuery;
import org.dromara.common.mybatis.core.page.TableDataInfo; import org.dromara.common.mybatis.core.page.TableDataInfo;
import org.dromara.system.api.RemoteCodeRuleService; import org.dromara.system.api.RemoteCodeRuleService;
import org.dromara.wms.domain.WmsInventoryDetails;
import org.dromara.wms.domain.WmsOutStockBill; import org.dromara.wms.domain.WmsOutStockBill;
import org.dromara.wms.domain.WmsOutStockDetails; import org.dromara.wms.domain.WmsOutStockDetails;
import org.dromara.wms.domain.bo.WmsOutStockBillBo; import org.dromara.wms.domain.bo.WmsOutStockBillBo;
import org.dromara.wms.domain.vo.WmsInventoryDetailsVo;
import org.dromara.wms.domain.vo.WmsOutStockBillVo; import org.dromara.wms.domain.vo.WmsOutStockBillVo;
import org.dromara.wms.mapper.WmsInventoryDetailsMapper;
import org.dromara.wms.mapper.WmsOutStockBillMapper; import org.dromara.wms.mapper.WmsOutStockBillMapper;
import org.dromara.wms.mapper.WmsOutStockDetailsMapper; import org.dromara.wms.mapper.WmsOutStockDetailsMapper;
import org.dromara.wms.service.IWmsOutStockBillService; import org.dromara.wms.service.IWmsOutStockBillService;
import org.springframework.stereotype.Service; import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import java.util.Collection; import java.util.Collection;
import java.util.List; import java.util.List;
@ -37,6 +41,7 @@ public class WmsOutStockBillServiceImpl implements IWmsOutStockBillService {
private final WmsOutStockDetailsMapper wmsOutStockDetailsMapper; private final WmsOutStockDetailsMapper wmsOutStockDetailsMapper;
@DubboReference @DubboReference
private RemoteCodeRuleService remoteCodeRuleService; private RemoteCodeRuleService remoteCodeRuleService;
private final WmsInventoryDetailsMapper wmsInventoryDetailsMapper;
/** /**
* *
@ -98,6 +103,7 @@ public class WmsOutStockBillServiceImpl implements IWmsOutStockBillService {
* @return * @return
*/ */
@Override @Override
@Transactional(rollbackFor = Exception.class)
public Boolean insertByBo(WmsOutStockBillBo bo) { public Boolean insertByBo(WmsOutStockBillBo bo) {
WmsOutStockBill add = MapstructUtils.convert(bo, WmsOutStockBill.class); WmsOutStockBill add = MapstructUtils.convert(bo, WmsOutStockBill.class);
add.setOutStockCode(remoteCodeRuleService.selectCodeRuleCode("1006")); add.setOutStockCode(remoteCodeRuleService.selectCodeRuleCode("1006"));
@ -107,7 +113,15 @@ public class WmsOutStockBillServiceImpl implements IWmsOutStockBillService {
Long outStockBillId = add.getOutStockBillId(); Long outStockBillId = add.getOutStockBillId();
List<WmsOutStockDetails> outStockDetailsList = bo.getOutStockDetailsList(); List<WmsOutStockDetails> outStockDetailsList = bo.getOutStockDetailsList();
outStockDetailsList.forEach(item -> { outStockDetailsList.forEach(item -> {
item.setOutStockBillId(outStockBillId); item.setOutStockBillId(outStockBillId);
// 从出库明细中获取库存ID
Long inventoryId = item.getInventoryDetailsId();
WmsInventoryDetails inventory = wmsInventoryDetailsMapper.selectById(inventoryId);
if (inventory.getInventoryAmount()<item.getOutStockAmount()) {
throw new IllegalArgumentException("库存数量不足");
}
}); });
//插入出库明细 //插入出库明细
wmsOutStockDetailsMapper.insert(outStockDetailsList); wmsOutStockDetailsMapper.insert(outStockDetailsList);

Loading…
Cancel
Save