| | |
| | | import cn.iocoder.yudao.module.erp.controller.admin.purchase.vo.order.ErpPurchaseOrderPageReqVO; |
| | | import cn.iocoder.yudao.module.erp.controller.admin.purchase.vo.order.ErpPurchaseOrderRespVO; |
| | | import cn.iocoder.yudao.module.erp.controller.admin.purchase.vo.order.ErpPurchaseOrderSaveReqVO; |
| | | import cn.iocoder.yudao.module.erp.controller.admin.purchase.vo.order.ErpPurchaseOrderImportExcelVO; |
| | | import cn.iocoder.yudao.module.erp.controller.admin.purchase.vo.order.ErpPurchaseOrderImportRespVO; |
| | | import cn.iocoder.yudao.module.erp.dal.dataobject.purchase.ErpPurchaseOrderDO; |
| | | import cn.iocoder.yudao.module.erp.dal.dataobject.purchase.ErpPurchaseOrderItemDO; |
| | | import cn.iocoder.yudao.module.erp.enums.ErpAuditStatus; |
| | | import cn.iocoder.yudao.module.erp.enums.ErpPurchaseOrderSourceTypeEnum; |
| | | import cn.iocoder.yudao.module.srm.api.supplier.SrmSupplierApi; |
| | | import cn.iocoder.yudao.module.srm.api.supplier.dto.SrmSupplierRespDTO; |
| | | import cn.iocoder.yudao.module.erp.service.purchase.ErpPurchaseInvoiceService; |
| | | import cn.iocoder.yudao.module.erp.service.purchase.ErpPurchaseOrderService; |
| | | import cn.iocoder.yudao.module.mdm.api.item.MdmItemApi; |
| | | import cn.iocoder.yudao.module.mdm.api.item.dto.MdmItemRespDTO; |
| | |
| | | import org.springframework.security.access.prepost.PreAuthorize; |
| | | import org.springframework.validation.annotation.Validated; |
| | | import org.springframework.web.bind.annotation.*; |
| | | import org.springframework.web.multipart.MultipartFile; |
| | | |
| | | import java.io.IOException; |
| | | import java.math.BigDecimal; |
| | | import java.util.List; |
| | | import java.util.Arrays; |
| | | import java.util.Map; |
| | | |
| | | import static cn.iocoder.yudao.framework.apilog.core.enums.OperateTypeEnum.EXPORT; |
| | | import static cn.iocoder.yudao.framework.common.exception.util.ServiceExceptionUtil.exception; |
| | | import static cn.iocoder.yudao.framework.common.pojo.CommonResult.success; |
| | | import static cn.iocoder.yudao.module.erp.enums.ErrorCodeConstants.*; |
| | | import static cn.iocoder.yudao.framework.common.util.collection.CollectionUtils.convertMultiMap; |
| | | import static cn.iocoder.yudao.framework.common.util.collection.CollectionUtils.convertSet; |
| | | import static cn.iocoder.yudao.framework.security.core.util.SecurityFrameworkUtils.getLoginUserId; |
| | |
| | | |
| | | @Resource |
| | | private ErpPurchaseOrderService purchaseOrderService; |
| | | @Resource |
| | | private ErpPurchaseInvoiceService purchaseInvoiceService; |
| | | @Resource |
| | | private SrmSupplierApi srmSupplierApi; |
| | | |
| | |
| | | ExcelUtils.write(response, "采购订单.xls", "数据", ErpPurchaseOrderRespVO.class, list); |
| | | } |
| | | |
| | | @GetMapping("/get-import-template") |
| | | @Operation(summary = "获得导入采购订单模板") |
| | | @PreAuthorize("@ss.hasPermission('erp:purchase-order:import')") |
| | | public void importTemplate(HttpServletResponse response) throws IOException { |
| | | List<ErpPurchaseOrderImportExcelVO> list = Arrays.asList( |
| | | ErpPurchaseOrderImportExcelVO.builder() |
| | | .no("CGDD20260101000001").supplierName("示例供应商") |
| | | .orderTime("2026-01-01 10:00:00").productCode("ITEM001").productName("示例产品A") |
| | | .count(new BigDecimal("100")).productPrice(new BigDecimal("10.00")) |
| | | .taxPercent(new BigDecimal("13")).qcCheckFlag("否").remark("示例").build()); |
| | | ExcelUtils.write(response, "采购订单导入模板.xls", "采购订单", ErpPurchaseOrderImportExcelVO.class, list); |
| | | } |
| | | |
| | | @PostMapping("/import") |
| | | @Operation(summary = "导入采购订单") |
| | | @PreAuthorize("@ss.hasPermission('erp:purchase-order:import')") |
| | | public CommonResult<ErpPurchaseOrderImportRespVO> importPurchaseOrderExcel( |
| | | @RequestParam("file") MultipartFile file, |
| | | @RequestParam(value = "directApprove", required = false, defaultValue = "false") Boolean directApprove) throws Exception { |
| | | List<ErpPurchaseOrderImportExcelVO> list = ExcelUtils.read(file, ErpPurchaseOrderImportExcelVO.class); |
| | | return success(purchaseOrderService.importPurchaseOrderList(list, directApprove)); |
| | | } |
| | | |
| | | @PostMapping("/confirm-receipt") |
| | | @Operation(summary = "确认收货") |
| | | @Parameter(name = "id", description = "采购订单编号", required = true) |
| | | @PreAuthorize("@ss.hasPermission('erp:purchase-order:confirm-receipt')") |
| | | public CommonResult<Long> confirmReceipt(@RequestParam("id") Long id) { |
| | | return success(purchaseOrderService.confirmReceipt(id)); |
| | | } |
| | | |
| | | @PostMapping("/reverse-approve") |
| | | @Operation(summary = "反审批(协同办公已办任务中撤回已审核订单,直接重新进入待办审批)") |
| | | @Parameter(name = "processInstanceId", description = "流程实例编号", required = true) |
| | | @PreAuthorize("@ss.hasPermission('erp:purchase-order:update-status')") |
| | | public CommonResult<Boolean> reverseApprove(@RequestParam("processInstanceId") String processInstanceId) { |
| | | // 1. 根据流程实例编号找到采购订单 |
| | | ErpPurchaseOrderDO purchaseOrder = purchaseOrderService.getPurchaseOrderByProcessInstanceId(processInstanceId); |
| | | if (purchaseOrder == null) { |
| | | throw exception(PURCHASE_ORDER_NOT_EXISTS); |
| | | } |
| | | // 2. 反审核:已审核 -> 未审核(含入库/退货校验) |
| | | purchaseOrderService.updatePurchaseOrderStatus(purchaseOrder.getId(), ErpAuditStatus.PROCESS.getStatus()); |
| | | // 3. 自动重新提交审批 -> 订单直接回到协同办公待办任务 |
| | | purchaseOrderService.submitPurchaseOrder(purchaseOrder.getId(), "purchase_order_approve", getLoginUserId()); |
| | | return success(true); |
| | | } |
| | | |
| | | private PageResult<ErpPurchaseOrderRespVO> buildPurchaseOrderVOPageResult(PageResult<ErpPurchaseOrderDO> pageResult) { |
| | |
| | | // 1.5 单位信息 |
| | | Map<Long, MdmUnitMeasureRespDTO> unitMeasureMap = mdmUnitMeasureApi.getUnitMeasureMap( |
| | | convertSet(purchaseOrderItemList, ErpPurchaseOrderItemDO::getProductUnitId)); |
| | | // 1.6 已来票金额:按采购订单统计,用于计算剩余可开票金额 |
| | | Map<Long, BigDecimal> invoicePriceSumMap = purchaseInvoiceService |
| | | .getPurchaseInvoicePriceSumMapByOrderIds(convertSet(pageResult.getList(), ErpPurchaseOrderDO::getId)); |
| | | // 2. 开始拼接 |
| | | return BeanUtils.toBean(pageResult, ErpPurchaseOrderRespVO.class, purchaseOrder -> { |
| | | purchaseOrder.setItems(BeanUtils.toBean(purchaseOrderItemMap.get(purchaseOrder.getId()), ErpPurchaseOrderRespVO.Item.class, |
| | | purchaseOrder.setItems(BeanUtils.toBean( |
| | | purchaseOrderItemMap.getOrDefault(purchaseOrder.getId(), java.util.Collections.<ErpPurchaseOrderItemDO>emptyList()), |
| | | ErpPurchaseOrderRespVO.Item.class, |
| | | item -> { |
| | | MapUtils.findAndThen(itemMap, item.getProductId(), mdmItem -> item.setProductName(mdmItem.getName()) |
| | | .setProductBarCode(mdmItem.getBarCode())); |
| | |
| | | MapUtils.findAndThen(userMap, Long.parseLong(purchaseOrder.getCreator()), user -> purchaseOrder.setCreatorName(user.getNickname())); |
| | | purchaseOrder.setSourceTypeName(ErpPurchaseOrderSourceTypeEnum.WORK_ORDER.getType() |
| | | .equals(purchaseOrder.getSourceType()) ? "生产工单" : null); |
| | | // 剩余可开票金额 = 订单总金额 - 已来票金额 |
| | | purchaseOrder.setRemainInvoicePrice(purchaseOrder.getTotalPrice().subtract( |
| | | invoicePriceSumMap.getOrDefault(purchaseOrder.getId(), BigDecimal.ZERO))); |
| | | }); |
| | | } |
| | | |