package com.ruoyi.sales.controller; import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper; import com.baomidou.mybatisplus.core.metadata.IPage; import com.baomidou.mybatisplus.extension.plugins.pagination.Page; import com.ruoyi.approve.mapper.ApproveProcessMapper; import com.ruoyi.approve.pojo.ApproveProcess; import com.ruoyi.approve.service.impl.ApproveProcessServiceImpl; import com.ruoyi.approve.vo.ApproveProcessVO; import com.ruoyi.common.enums.FileNameType; import com.ruoyi.common.utils.OrderUtils; import com.ruoyi.common.utils.SecurityUtils; import com.ruoyi.common.utils.poi.ExcelUtil; import com.ruoyi.framework.aspectj.lang.annotation.Log; import com.ruoyi.framework.aspectj.lang.enums.BusinessType; import com.ruoyi.framework.security.LoginUser; import com.ruoyi.framework.web.controller.BaseController; import com.ruoyi.framework.web.domain.AjaxResult; import com.ruoyi.other.service.impl.TempFileServiceImpl; import com.ruoyi.procurementrecord.utils.StockUtils; import com.ruoyi.sales.dto.ShippingInfoDto; import com.ruoyi.sales.mapper.ShipmentApprovalMapper; import com.ruoyi.sales.mapper.ShippingInfoMapper; import com.ruoyi.sales.pojo.SalesLedger; import com.ruoyi.sales.pojo.SalesLedgerProduct; import com.ruoyi.sales.pojo.ShipmentApproval; import com.ruoyi.sales.pojo.ShippingInfo; import com.ruoyi.sales.service.ISalesLedgerProductService; import com.ruoyi.sales.service.ISalesLedgerService; import com.ruoyi.sales.service.ShippingInfoService; import com.ruoyi.sales.service.impl.CommonFileServiceImpl; import io.swagger.annotations.Api; import io.swagger.annotations.ApiOperation; import org.apache.commons.collections4.CollectionUtils; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.transaction.annotation.Transactional; import org.springframework.web.bind.annotation.*; import javax.servlet.http.HttpServletResponse; import java.io.IOException; import java.time.LocalDate; import java.util.List; /** * @author :yys * @date : 2025/10/22 9:34 */ @RestController @RequestMapping("/shippingInfo") @Api(tags = "发货信息管理") public class ShippingInfoController extends BaseController { @Autowired private ShippingInfoService shippingInfoService; @Autowired private CommonFileServiceImpl commonFileService; @Autowired private ApproveProcessServiceImpl approveProcessService; @Autowired private StockUtils stockUtils; @Autowired private ISalesLedgerService salesLedgerService; @GetMapping("/listPage") @ApiOperation("发货信息列表") public AjaxResult listPage(Page page, ShippingInfo req) { IPage listPage = shippingInfoService.listPage(page,req); return AjaxResult.success(listPage); } @PostMapping("/add") @ApiOperation("添加发货信息") @Transactional(rollbackFor = Exception.class) @Log(title = "发货信息管理", businessType = BusinessType.INSERT) public AjaxResult add(@RequestBody ShippingInfoDto req) throws Exception { LoginUser loginUser = SecurityUtils.getLoginUser(); // 查询销售单号 String salesContractNo = ""; if (req.getSalesLedgerId() != null) { SalesLedger salesLedger = salesLedgerService.getById(req.getSalesLedgerId()); if (salesLedger != null) { salesContractNo = salesLedger.getSalesContractNo(); } } String sh = OrderUtils.countTodayByCreateTime(shippingInfoMapper, "SH", "shipping_no"); // 查询该销售合同下是否有"待审核"的发货记录,用于合并审批(需审批人相同) boolean shouldMergeApproval = false; ApproveProcess existingApprove = null; List pendingShippings = shippingInfoMapper.selectList( new LambdaQueryWrapper() .eq(ShippingInfo::getSalesLedgerId, req.getSalesLedgerId()) .eq(ShippingInfo::getStatus, "待审核") ); if (!CollectionUtils.isEmpty(pendingShippings) && salesContractNo != null && !salesContractNo.isEmpty()) { // 找到对应的审批流程(通过销售单号匹配,且审批人相同) existingApprove = approveProcessService.getOne( new LambdaQueryWrapper() .like(ApproveProcess::getApproveReason, "销售单号:" + salesContractNo) .eq(ApproveProcess::getApproveType, 7) // 发货审批类型 .eq(ApproveProcess::getApproveStatus, 0) // 待审核状态 .eq(ApproveProcess::getApproveUser, loginUser.getUserId()) // 审批人相同 .orderByDesc(ApproveProcess::getCreateTime) .last("limit 1") ); if (existingApprove != null) { shouldMergeApproval = true; } } // 生成当前发货信息的描述 StringBuilder currentShippingDesc = new StringBuilder(); currentShippingDesc.append("发货单号:").append(sh); if (salesContractNo != null && !salesContractNo.isEmpty()) { currentShippingDesc.append("\n销售单号:").append(salesContractNo); } currentShippingDesc.append("\n").append(req.getType()); if ("货车".equals(req.getType()) && req.getShippingCarNumber() != null && !req.getShippingCarNumber().isEmpty()) { currentShippingDesc.append(":").append(req.getShippingCarNumber()); } else if ("快递".equals(req.getType()) && req.getExpressCompany() != null && !req.getExpressCompany().isEmpty()) { currentShippingDesc.append(":").append(req.getExpressCompany()); } if (shouldMergeApproval && existingApprove != null) { // 合并审批:将被合并的发货单号添加到审批原因中 String updatedReason = existingApprove.getApproveReason() + "\n\n" + currentShippingDesc.toString(); existingApprove.setApproveReason(updatedReason); approveProcessService.updateById(existingApprove); } else { // 创建新的审批流程 ApproveProcessVO approveProcessVO = new ApproveProcessVO(); approveProcessVO.setApproveType(7); approveProcessVO.setApproveDeptId(loginUser.getCurrentDeptId()); approveProcessVO.setApproveReason(currentShippingDesc.toString()); approveProcessVO.setApproveUserIds(req.getApproveUserIds()); approveProcessVO.setApproveUser(loginUser.getUserId()); approveProcessVO.setApproveTime(LocalDate.now().toString()); approveProcessService.addApprove(approveProcessVO); } // 添加发货记录 req.setShippingNo(sh); req.setStatus("待审核"); boolean save = shippingInfoService.save(req); return save ? AjaxResult.success() : AjaxResult.error(); } @ApiOperation("发货扣库存") @PostMapping("/deductStock") @Transactional(rollbackFor = Exception.class) @Log(title = "发货信息管理", businessType = BusinessType.UPDATE) public AjaxResult deductStock(@RequestBody ShippingInfoDto req) throws IOException { return shippingInfoService.deductStock( req) ? AjaxResult.success() : AjaxResult.error(); } @PostMapping("/update") @ApiOperation("修改发货信息") @Transactional(rollbackFor = Exception.class) @Log(title = "发货信息管理", businessType = BusinessType.UPDATE) public AjaxResult update(@RequestBody ShippingInfo req) { ShippingInfo byId = shippingInfoService.getById(req.getId()); if (byId == null) { return AjaxResult.error("发货信息不存在"); } boolean update = shippingInfoService.updateById(req); return update ? AjaxResult.success() : AjaxResult.error(); } @DeleteMapping("/delete") @ApiOperation("删除发货信息") @Transactional(rollbackFor = Exception.class) @Log(title = "发货信息管理", businessType = BusinessType.DELETE) public AjaxResult delete(@RequestBody List ids) { return shippingInfoService.delete(ids) ? AjaxResult.success("删除成功") : AjaxResult.error("删除失败"); } @Autowired private ShippingInfoMapper shippingInfoMapper; /** * 导出发货信息管理 */ @PostMapping("/export") @ApiOperation("导出发货信息") public void export(HttpServletResponse response) { List list = shippingInfoMapper.listAll(); ExcelUtil util = new ExcelUtil(ShippingInfo.class); util.exportExcel(response, list, "发货信息"); } @GetMapping("/getByCustomerName") @ApiOperation("通过客户名称查询") public AjaxResult getByCustomerName(String customerName) { return AjaxResult.success(shippingInfoService.getShippingInfoByCustomerName(customerName)); } /** * 一键发货 - 自动审批通过并出库 */ @PostMapping("/oneClickShipping") @ApiOperation("一键发货") @Transactional(rollbackFor = Exception.class) @Log(title = "发货信息管理", businessType = BusinessType.INSERT) public AjaxResult oneClickShipping(@RequestBody ShippingInfoDto req) throws IOException { return shippingInfoService.oneClickShipping(req) ? AjaxResult.success("发货成功") : AjaxResult.error("发货失败"); } /** * 批量一键发货 - 将销售台账下所有未发货的产品全部发货 */ @PostMapping("/batchOneClickShipping") @ApiOperation("批量一键发货") @Transactional(rollbackFor = Exception.class) @Log(title = "发货信息管理", businessType = BusinessType.INSERT) public AjaxResult batchOneClickShipping(@RequestBody ShippingInfoDto req) throws IOException { if (req.getSalesLedgerId() == null) { return AjaxResult.error("销售台账ID不能为空"); } return shippingInfoService.batchOneClickShipping(req.getSalesLedgerId(), req) ? AjaxResult.success("批量发货成功") : AjaxResult.error("批量发货失败"); } }