| | |
| | | package com.ruoyi.production.service.impl; |
| | | |
| | | import com.baomidou.mybatisplus.core.metadata.IPage; |
| | | import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper; |
| | | import com.baomidou.mybatisplus.extension.plugins.pagination.Page; |
| | | import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl; |
| | | import com.ruoyi.production.bean.dto.ProductionAccountDto; |
| | | import com.ruoyi.production.bean.dto.ProductionProductMainDto; |
| | | import com.ruoyi.production.bean.vo.ProductionAccountVo; |
| | | import com.ruoyi.production.mapper.ProductionAccountMapper; |
| | | import com.ruoyi.production.mapper.ProductionOperationTaskMapper; |
| | | import com.ruoyi.production.mapper.ProductionOrderRoutingOperationMapper; |
| | | import com.ruoyi.production.mapper.ProductionProductMainMapper; |
| | | import com.ruoyi.production.mapper.ProductionProductOutputMapper; |
| | | import com.ruoyi.production.pojo.ProductionAccount; |
| | | import com.ruoyi.production.pojo.ProductionOperationTask; |
| | | import com.ruoyi.production.pojo.ProductionOrderRoutingOperation; |
| | | import com.ruoyi.production.pojo.ProductionProductMain; |
| | | import com.ruoyi.production.pojo.ProductionProductOutput; |
| | | import com.ruoyi.technology.mapper.TechnologyOperationMapper; |
| | | import com.ruoyi.technology.mapper.TechnologyRoutingOperationMapper; |
| | | import com.ruoyi.technology.pojo.TechnologyOperation; |
| | | import com.ruoyi.technology.pojo.TechnologyRoutingOperation; |
| | | import com.ruoyi.project.system.mapper.SysUserMapper; |
| | | import com.ruoyi.project.system.domain.SysUser; |
| | | import com.ruoyi.production.service.ProductionAccountService; |
| | | import com.baomidou.mybatisplus.core.toolkit.Wrappers; |
| | | import com.ruoyi.common.exception.ServiceException; |
| | | import lombok.RequiredArgsConstructor; |
| | | import org.springframework.stereotype.Service; |
| | | import org.springframework.transaction.annotation.Transactional; |
| | | |
| | | /** |
| | | * <p> |
| | | * 生产核算表 服务实现类 |
| | | * </p> |
| | | * |
| | | * @author 芯导软件(江苏)有限公司 |
| | | * @since 2026-04-21 03:55:52 |
| | | */ |
| | | import java.math.BigDecimal; |
| | | import java.time.LocalDate; |
| | | import java.time.LocalDateTime; |
| | | import java.time.format.DateTimeParseException; |
| | | import java.util.Arrays; |
| | | import java.util.List; |
| | | |
| | | @Service |
| | | @RequiredArgsConstructor |
| | | public class ProductionAccountServiceImpl extends ServiceImpl<ProductionAccountMapper, ProductionAccount> implements ProductionAccountService { |
| | | |
| | | |
| | | private final ProductionProductMainMapper productionProductMainMapper; |
| | | private final ProductionProductOutputMapper productionProductOutputMapper; |
| | | private final ProductionOperationTaskMapper productionOperationTaskMapper; |
| | | private final ProductionOrderRoutingOperationMapper productionOrderRoutingOperationMapper; |
| | | private final TechnologyRoutingOperationMapper technologyRoutingOperationMapper; |
| | | private final TechnologyOperationMapper technologyOperationMapper; |
| | | private final SysUserMapper sysUserMapper; |
| | | |
| | | @Override |
| | | public IPage<ProductionAccountVo> listPage(Page<ProductionAccountDto> page, ProductionAccountDto dto) { |
| | | // 分页查询生产核算数据 |
| | | ProductionAccountDto queryDto = normalizeDateQuery(dto); |
| | | return baseMapper.listPage(page, queryDto); |
| | | } |
| | | |
| | | @Override |
| | | public IPage<ProductionProductMainDto> listProductionDetails(ProductionAccountDto dto, Page page) { |
| | | // 查询生产核算明细 |
| | | ProductionAccountDto queryDto = normalizeDateQuery(dto); |
| | | if (queryDto.getAuditStatus() == null) { |
| | | queryDto.setAuditStatus(1); |
| | | } |
| | | return productionProductMainMapper.listProductionDetails(queryDto, page); |
| | | } |
| | | |
| | | @Override |
| | | @Transactional(rollbackFor = Exception.class) |
| | | public Boolean batchAccounting(ProductionAccountDto dto) { |
| | | ProductionAccountDto queryDto = normalizeDateQuery(dto); |
| | | LambdaQueryWrapper<ProductionProductMain> queryWrapper = Wrappers.<ProductionProductMain>lambdaQuery() |
| | | .eq(ProductionProductMain::getAuditStatus, 1) |
| | | .in(ProductionProductMain::getReportType, Arrays.asList(0, 1)); |
| | | if (queryDto.getSchedulingUserId() != null) { |
| | | queryWrapper.eq(ProductionProductMain::getUserId, queryDto.getSchedulingUserId()); |
| | | } |
| | | if (queryDto.getSchedulingUserName() != null && !queryDto.getSchedulingUserName().isEmpty()) { |
| | | queryWrapper.like(ProductionProductMain::getUserName, queryDto.getSchedulingUserName()); |
| | | } |
| | | if (queryDto.getEntryDate() != null) { |
| | | queryWrapper.apply("date(create_time) = {0}", queryDto.getEntryDate()); |
| | | } |
| | | if (queryDto.getEntryDateStart() != null) { |
| | | queryWrapper.ge(ProductionProductMain::getCreateTime, queryDto.getEntryDateStart().atStartOfDay()); |
| | | } |
| | | if (queryDto.getEntryDateEnd() != null) { |
| | | queryWrapper.le(ProductionProductMain::getCreateTime, queryDto.getEntryDateEnd().atTime(23, 59, 59)); |
| | | } |
| | | List<ProductionProductMain> reportList = productionProductMainMapper.selectList(queryWrapper); |
| | | for (ProductionProductMain report : reportList) { |
| | | rebuildAccount(report); |
| | | } |
| | | return Boolean.TRUE; |
| | | } |
| | | |
| | | @Override |
| | | @Transactional(rollbackFor = Exception.class) |
| | | public Boolean singleAdjust(ProductionAccountDto dto) { |
| | | if (dto == null || (dto.getProductionProductMainId() == null && dto.getSchedulingUserId() == null)) { |
| | | throw new ServiceException("请选择需要修正的人员"); |
| | | } |
| | | BigDecimal adjustAmount = dto.getAdjustAmount(); |
| | | if (adjustAmount == null || adjustAmount.compareTo(BigDecimal.ZERO) == 0) { |
| | | throw new ServiceException("修正金额不能为空"); |
| | | } |
| | | if (dto.getProductionProductMainId() != null) { |
| | | ProductionAccount account = new ProductionAccount(); |
| | | account.setAdjustAmount(adjustAmount); |
| | | account.setAdjustRemark(dto.getAdjustRemark()); |
| | | account.setAdjustUser(dto.getAdjustUser()); |
| | | account.setAdjustTime(LocalDateTime.now()); |
| | | baseMapper.update(account, new LambdaQueryWrapper<ProductionAccount>() |
| | | .eq(ProductionAccount::getProductionProductMainId, dto.getProductionProductMainId())); |
| | | } else { |
| | | ProductionAccount account = new ProductionAccount(); |
| | | account.setSchedulingUserId(dto.getSchedulingUserId()); |
| | | account.setSchedulingUserName(dto.getSchedulingUserName()); |
| | | account.setTechnologyOperationName("工资修正"); |
| | | account.setAdjustAmount(adjustAmount); |
| | | account.setAdjustRemark(dto.getAdjustRemark()); |
| | | account.setAdjustUser(dto.getAdjustUser()); |
| | | account.setAdjustTime(LocalDateTime.now()); |
| | | account.setSchedulingDate(LocalDateTime.now()); |
| | | account.setWorkHours(BigDecimal.ZERO); |
| | | account.setFinishedNum(BigDecimal.ZERO); |
| | | account.setAccountingBatchNo("ADJ-" + LocalDate.now()); |
| | | baseMapper.insert(account); |
| | | } |
| | | return Boolean.TRUE; |
| | | } |
| | | |
| | | @Override |
| | | @Transactional(rollbackFor = Exception.class) |
| | | public Boolean rebuildByProductionProductMainId(Long productionProductMainId) { |
| | | if (productionProductMainId == null) { |
| | | return Boolean.FALSE; |
| | | } |
| | | ProductionProductMain productionProductMain = productionProductMainMapper.selectById(productionProductMainId); |
| | | if (productionProductMain == null) { |
| | | return Boolean.FALSE; |
| | | } |
| | | if (productionProductMain.getAuditStatus() == null || productionProductMain.getAuditStatus() != 1) { |
| | | productionAccountDelete(productionProductMainId); |
| | | return Boolean.FALSE; |
| | | } |
| | | if (productionProductMain.getReportType() == null |
| | | || (!Integer.valueOf(0).equals(productionProductMain.getReportType()) |
| | | && !Integer.valueOf(1).equals(productionProductMain.getReportType()))) { |
| | | productionAccountDelete(productionProductMainId); |
| | | return Boolean.FALSE; |
| | | } |
| | | rebuildAccount(productionProductMain); |
| | | return Boolean.TRUE; |
| | | } |
| | | |
| | | private void rebuildAccount(ProductionProductMain productionProductMain) { |
| | | if (productionProductMain == null || productionProductMain.getId() == null) { |
| | | return; |
| | | } |
| | | ProductionAccount existedAccount = baseMapper.selectOne(Wrappers.<ProductionAccount>lambdaQuery() |
| | | .eq(ProductionAccount::getProductionProductMainId, productionProductMain.getId()) |
| | | .last("limit 1")); |
| | | BigDecimal existedAdjustAmount = existedAccount == null ? null : existedAccount.getAdjustAmount(); |
| | | String existedAdjustRemark = existedAccount == null ? null : existedAccount.getAdjustRemark(); |
| | | Long existedAdjustUser = existedAccount == null ? null : existedAccount.getAdjustUser(); |
| | | LocalDateTime existedAdjustTime = existedAccount == null ? null : existedAccount.getAdjustTime(); |
| | | |
| | | productionAccountDelete(productionProductMain.getId()); |
| | | ProductionProductOutput output = productionProductOutputMapper.selectOne( |
| | | Wrappers.<ProductionProductOutput>lambdaQuery() |
| | | .eq(ProductionProductOutput::getProductionProductMainId, productionProductMain.getId()) |
| | | .last("limit 1")); |
| | | if (output == null || output.getQuantity() == null || output.getQuantity().compareTo(BigDecimal.ZERO) <= 0) { |
| | | return; |
| | | } |
| | | ProductionOperationTask task = productionOperationTaskMapper.selectById(productionProductMain.getProductionOperationTaskId()); |
| | | if (task == null) { |
| | | return; |
| | | } |
| | | ProductionOrderRoutingOperation routingOperation = productionOrderRoutingOperationMapper.selectById(task.getProductionOrderRoutingOperationId()); |
| | | if (routingOperation == null) { |
| | | return; |
| | | } |
| | | TechnologyRoutingOperation technologyRoutingOperation = technologyRoutingOperationMapper.selectById(routingOperation.getTechnologyRoutingOperationId()); |
| | | TechnologyOperation technologyOperation = technologyRoutingOperation == null ? null |
| | | : technologyOperationMapper.selectById(technologyRoutingOperation.getTechnologyOperationId()); |
| | | SysUser user = sysUserMapper.selectUserById(productionProductMain.getUserId()); |
| | | |
| | | ProductionAccount account = new ProductionAccount(); |
| | | account.setProductionProductMainId(productionProductMain.getId()); |
| | | account.setSchedulingUserId(user == null ? productionProductMain.getUserId() : user.getUserId()); |
| | | account.setSchedulingUserName(user == null ? productionProductMain.getUserName() : user.getNickName()); |
| | | account.setFinishedNum(output.getQuantity()); |
| | | account.setWorkHours(technologyOperation == null ? null : technologyOperation.getSalaryQuota()); |
| | | account.setTechnologyOperationName(technologyOperation == null ? null : technologyOperation.getName()); |
| | | account.setSchedulingDate(LocalDateTime.now()); |
| | | account.setAccountingBatchNo("BATCH-" + LocalDate.now()); |
| | | account.setAdjustAmount(existedAdjustAmount); |
| | | account.setAdjustRemark(existedAdjustRemark); |
| | | account.setAdjustUser(existedAdjustUser); |
| | | account.setAdjustTime(existedAdjustTime); |
| | | baseMapper.insert(account); |
| | | } |
| | | |
| | | private void productionAccountDelete(Long productionProductMainId) { |
| | | if (productionProductMainId == null) { |
| | | return; |
| | | } |
| | | baseMapper.delete(new LambdaQueryWrapper<ProductionAccount>() |
| | | .eq(ProductionAccount::getProductionProductMainId, productionProductMainId)); |
| | | } |
| | | |
| | | private ProductionAccountDto normalizeDateQuery(ProductionAccountDto dto) { |
| | | // 规范日期查询范围,补齐缺失的开始或结束时间 |
| | | if (dto == null) { |
| | | return new ProductionAccountDto(); |
| | | } |
| | | if ((dto.getEntryDateStart() == null || dto.getEntryDateEnd() == null) |
| | | && dto.getDateRange() != null |
| | | && dto.getDateRange().length > 0) { |
| | | LocalDate rangeStart = parseDate(dto.getDateRange()[0]); |
| | | LocalDate rangeEnd = dto.getDateRange().length > 1 ? parseDate(dto.getDateRange()[1]) : rangeStart; |
| | | if (dto.getEntryDateStart() == null) { |
| | | dto.setEntryDateStart(rangeStart); |
| | | } |
| | | if (dto.getEntryDateEnd() == null) { |
| | | dto.setEntryDateEnd(rangeEnd); |
| | | } |
| | | } |
| | | |
| | | String dateType = dto.getDateType(); |
| | | if ("day".equalsIgnoreCase(dateType)) { |
| | | if (dto.getEntryDate() == null && dto.getDateRange() != null && dto.getDateRange().length > 0) { |
| | | dto.setEntryDate(parseDate(dto.getDateRange()[0])); |
| | | } |
| | | if (dto.getEntryDate() == null) { |
| | | dto.setEntryDate(dto.getEntryDateStart()); |
| | | } |
| | | dto.setEntryDateStart(null); |
| | | dto.setEntryDateEnd(null); |
| | | } else if ("month".equalsIgnoreCase(dateType)) { |
| | | if ((dto.getEntryDateStart() == null || dto.getEntryDateEnd() == null) && dto.getEntryDate() != null) { |
| | | LocalDate monthDate = dto.getEntryDate(); |
| | | dto.setEntryDateStart(monthDate.withDayOfMonth(1)); |
| | | dto.setEntryDateEnd(monthDate.withDayOfMonth(monthDate.lengthOfMonth())); |
| | | } |
| | | dto.setEntryDate(null); |
| | | } |
| | | return dto; |
| | | } |
| | | |
| | | private LocalDate parseDate(String dateValue) { |
| | | if (dateValue == null || dateValue.isEmpty()) { |
| | | return null; |
| | | } |
| | | try { |
| | | return LocalDate.parse(dateValue); |
| | | } catch (DateTimeParseException e) { |
| | | throw new ServiceException("日期格式错误,请使用 yyyy-MM-dd"); |
| | | } |
| | | } |
| | | |
| | | } |