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; import java.math.BigDecimal; import java.time.LocalDate; import java.time.LocalDateTime; import java.util.List; @Service @RequiredArgsConstructor public class ProductionAccountServiceImpl extends ServiceImpl 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 listPage(Page page, ProductionAccountDto dto) { // 分页查询生产核算数据 ProductionAccountDto queryDto = normalizeDateQuery(dto); return baseMapper.listPage(page, queryDto); } @Override public IPage listProductionDetails(ProductionAccountDto dto, Page page) { // 查询生产核算明细 ProductionAccountDto queryDto = normalizeDateQuery(dto); if (queryDto.getAuditStatus() == null) { queryDto.setAuditStatus(1); } if (queryDto.getReportType() == null) { queryDto.setReportType(0); } return productionProductMainMapper.listProductionDetails(queryDto, page); } @Override @Transactional(rollbackFor = Exception.class) public Boolean batchAccounting(ProductionAccountDto dto) { ProductionAccountDto queryDto = normalizeDateQuery(dto); LambdaQueryWrapper queryWrapper = Wrappers.lambdaQuery() .eq(ProductionProductMain::getAuditStatus, 1) .eq(ProductionProductMain::getReportType, 0); 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 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.getSchedulingUserId() == null) { throw new ServiceException("请选择需要修正的人员"); } BigDecimal adjustAmount = dto.getAdjustAmount(); if (adjustAmount == null || adjustAmount.compareTo(BigDecimal.ZERO) == 0) { throw new ServiceException("修正金额不能为空"); } 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; } private void rebuildAccount(ProductionProductMain productionProductMain) { if (productionProductMain == null || productionProductMain.getId() == null) { return; } productionAccountDelete(productionProductMain.getId()); ProductionProductOutput output = productionProductOutputMapper.selectOne( Wrappers.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()); baseMapper.insert(account); } private void productionAccountDelete(Long productionProductMainId) { if (productionProductMainId == null) { return; } baseMapper.delete(new LambdaQueryWrapper() .eq(ProductionAccount::getProductionProductMainId, productionProductMainId)); } private ProductionAccountDto normalizeDateQuery(ProductionAccountDto dto) { // 规范日期查询范围,补齐缺失的开始或结束时间 if (dto == null) { return new ProductionAccountDto(); } LocalDate[] dateRange = dto.getDateRange(); if ((dto.getEntryDateStart() == null || dto.getEntryDateEnd() == null) && dateRange != null && dateRange.length > 0) { if (dto.getEntryDateStart() == null) { dto.setEntryDateStart(dateRange[0]); } if (dto.getEntryDateEnd() == null) { dto.setEntryDateEnd(dateRange.length > 1 ? dateRange[1] : dateRange[0]); } } String dateType = dto.getDateType(); if ("day".equalsIgnoreCase(dateType)) { if (dto.getEntryDate() == null && dateRange != null && dateRange.length > 0) { dto.setEntryDate(dateRange[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; } }