| | |
| | | package cn.iocoder.yudao.module.erp.controller.admin.purchase; |
| | | |
| | | import cn.hutool.core.collection.CollUtil; |
| | | import cn.hutool.core.util.ObjectUtil; |
| | | import cn.iocoder.yudao.framework.apilog.core.annotation.ApiAccessLog; |
| | | import cn.iocoder.yudao.framework.common.pojo.CommonResult; |
| | | import cn.iocoder.yudao.framework.common.pojo.PageParam; |
| | |
| | | import cn.iocoder.yudao.framework.common.util.number.NumberUtils; |
| | | import cn.iocoder.yudao.framework.common.util.object.BeanUtils; |
| | | import cn.iocoder.yudao.framework.excel.core.util.ExcelUtils; |
| | | import cn.iocoder.yudao.module.erp.controller.admin.purchase.vo.invoice.ErpPurchaseInvoiceOrderRespVO; |
| | | import cn.iocoder.yudao.module.erp.controller.admin.purchase.vo.invoice.ErpPurchaseInvoicePageReqVO; |
| | | import cn.iocoder.yudao.module.erp.controller.admin.purchase.vo.invoice.ErpPurchaseInvoiceRespVO; |
| | | import cn.iocoder.yudao.module.erp.controller.admin.purchase.vo.invoice.ErpPurchaseInvoiceSaveReqVO; |
| | | import cn.iocoder.yudao.module.erp.controller.admin.purchase.vo.order.ErpPurchaseOrderRespVO; |
| | | import cn.iocoder.yudao.module.erp.dal.dataobject.purchase.ErpPurchaseInvoiceDO; |
| | | import cn.iocoder.yudao.module.erp.dal.dataobject.purchase.ErpPurchaseInvoiceOrderDO; |
| | | import cn.iocoder.yudao.module.erp.dal.dataobject.purchase.ErpPurchaseOrderDO; |
| | | import cn.iocoder.yudao.module.erp.enums.ErpPurchaseInvoiceAuditStatusEnum; |
| | | import cn.iocoder.yudao.module.erp.service.finance.ErpFinancePaymentService; |
| | | import cn.iocoder.yudao.module.erp.service.purchase.ErpPurchaseInvoiceService; |
| | | import cn.iocoder.yudao.module.erp.service.purchase.ErpPurchaseInvoiceServiceImpl; |
| | |
| | | import java.math.BigDecimal; |
| | | import java.util.ArrayList; |
| | | import java.util.Collections; |
| | | import java.util.HashSet; |
| | | import java.util.List; |
| | | import java.util.Map; |
| | | import java.util.Set; |
| | | |
| | | import static cn.iocoder.yudao.framework.apilog.core.enums.OperateTypeEnum.EXPORT; |
| | | import static cn.iocoder.yudao.framework.common.pojo.CommonResult.success; |
| | | import static cn.iocoder.yudao.framework.common.pojo.PageParam.PAGE_SIZE_NONE; |
| | | import static cn.iocoder.yudao.framework.common.util.collection.CollectionUtils.convertList; |
| | | import static cn.iocoder.yudao.framework.common.util.collection.CollectionUtils.convertMap; |
| | | 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.common.util.collection.MapUtils.findAndThen; |
| | | import static cn.iocoder.yudao.framework.security.core.util.SecurityFrameworkUtils.getLoginUserId; |
| | | |
| | | @Tag(name = "管理后台 - ERP 采购来票") |
| | | @RestController |
| | |
| | | Map<Long, SrmSupplierRespDTO> supplierMap = srmSupplierApi.getSupplierList( |
| | | convertSet(invoiceList, ErpPurchaseInvoiceDO::getSupplierId)).getCheckedData().stream() |
| | | .collect(java.util.stream.Collectors.toMap(SrmSupplierRespDTO::getId, v -> v, (a, b) -> a)); |
| | | // 1.2 获取采购订单列表 |
| | | // 1.2 获取采购订单分摊明细(一张来票可关联多张订单) |
| | | Map<Long, List<ErpPurchaseInvoiceOrderDO>> allocationMap = convertMultiMap( |
| | | invoiceService.getPurchaseInvoiceOrderListByInvoiceIds( |
| | | convertSet(invoiceList, ErpPurchaseInvoiceDO::getId)), |
| | | ErpPurchaseInvoiceOrderDO::getInvoiceId); |
| | | // 1.2.1 兼容历史数据:没有分摊明细的来票,按主订单 + 来票金额视为一条分摊 |
| | | for (ErpPurchaseInvoiceDO invoice : invoiceList) { |
| | | if (!allocationMap.containsKey(invoice.getId()) && invoice.getPurchaseOrderId() != null) { |
| | | allocationMap.put(invoice.getId(), Collections.singletonList( |
| | | ErpPurchaseInvoiceOrderDO.builder().invoiceId(invoice.getId()) |
| | | .purchaseOrderId(invoice.getPurchaseOrderId()).price(invoice.getPrice()).sort(0).build())); |
| | | } |
| | | } |
| | | // 1.2.2 这些订单的全部分摊明细,用于计算每张订单「其他来票已占用金额」 |
| | | Set<Long> orderIds = convertSet(allocationMap.values().stream().flatMap(List::stream).toList(), |
| | | ErpPurchaseInvoiceOrderDO::getPurchaseOrderId); |
| | | List<ErpPurchaseInvoiceOrderDO> orderAllocations = invoiceService.getPurchaseInvoiceOrderListByPurchaseOrderIds(orderIds); |
| | | // 1.2.3 获取采购订单列表(含主订单,兼容历史数据) |
| | | Set<Long> orderIdsAll = new HashSet<>(orderIds); |
| | | invoiceList.stream().map(ErpPurchaseInvoiceDO::getPurchaseOrderId) |
| | | .filter(java.util.Objects::nonNull).forEach(orderIdsAll::add); |
| | | Map<Long, ErpPurchaseOrderDO> orderMap = convertMap( |
| | | purchaseOrderService.getPurchaseOrderList(convertList(invoiceList, ErpPurchaseInvoiceDO::getPurchaseOrderId)), |
| | | ErpPurchaseOrderDO::getId); |
| | | purchaseOrderService.getPurchaseOrderList(new ArrayList<>(orderIdsAll)), ErpPurchaseOrderDO::getId); |
| | | // 1.2.4 获取分摊订单的供应商列表(一张来票可能涉及多个供应商) |
| | | Map<Long, SrmSupplierRespDTO> orderSupplierMap = srmSupplierApi.getSupplierList( |
| | | convertSet(orderMap.values(), ErpPurchaseOrderDO::getSupplierId)).getCheckedData().stream() |
| | | .collect(java.util.stream.Collectors.toMap(SrmSupplierRespDTO::getId, v -> v, (a, b) -> a)); |
| | | // 1.3 获取创建人列表 |
| | | Map<Long, AdminUserRespDTO> userMap = adminUserApi.getUserMap( |
| | | convertSet(invoiceList, invoice -> NumberUtils.parseLong(invoice.getCreator()))); |
| | |
| | | return BeanUtils.toBean(invoiceList, ErpPurchaseInvoiceRespVO.class, (invoiceVO) -> { |
| | | // 2.1 拼接供应商名称 |
| | | findAndThen(supplierMap, invoiceVO.getSupplierId(), supplier -> invoiceVO.setSupplierName(supplier.getName())); |
| | | // 2.2 拼接采购订单信息 |
| | | // 2.2 拼接采购订单信息(主订单) |
| | | findAndThen(orderMap, invoiceVO.getPurchaseOrderId(), order -> |
| | | invoiceVO.setOrder(BeanUtils.toBean(order, ErpPurchaseOrderRespVO.class))); |
| | | // 2.2.1 拼接采购订单分摊明细 |
| | | List<ErpPurchaseInvoiceOrderDO> rows = allocationMap.getOrDefault(invoiceVO.getId(), Collections.emptyList()); |
| | | List<ErpPurchaseInvoiceOrderRespVO> allocationVOs = new ArrayList<>(rows.size()); |
| | | for (ErpPurchaseInvoiceOrderDO row : rows) { |
| | | ErpPurchaseInvoiceOrderRespVO allocationVO = new ErpPurchaseInvoiceOrderRespVO() |
| | | .setPurchaseOrderId(row.getPurchaseOrderId()).setPrice(row.getPrice()); |
| | | ErpPurchaseOrderDO order = orderMap.get(row.getPurchaseOrderId()); |
| | | if (order != null) { |
| | | allocationVO.setOrderNo(order.getNo()).setSupplierId(order.getSupplierId()) |
| | | .setOrderTotalPrice(order.getTotalPrice()); |
| | | findAndThen(orderSupplierMap, order.getSupplierId(), |
| | | supplier -> allocationVO.setSupplierName(supplier.getName())); |
| | | } |
| | | // 该订单其他来票已占用金额 = 全部分摊 - 本张来票的分摊 |
| | | BigDecimal otherInvoicedPrice = orderAllocations.stream() |
| | | .filter(other -> ObjectUtil.equal(other.getPurchaseOrderId(), row.getPurchaseOrderId()) |
| | | && !ObjectUtil.equal(other.getInvoiceId(), invoiceVO.getId())) |
| | | .map(ErpPurchaseInvoiceOrderDO::getPrice) |
| | | .reduce(BigDecimal.ZERO, BigDecimal::add); |
| | | allocationVO.setInvoicedPrice(otherInvoicedPrice); |
| | | if (order != null) { |
| | | allocationVO.setRemainPrice(order.getTotalPrice().subtract(otherInvoicedPrice)); |
| | | } |
| | | allocationVOs.add(allocationVO); |
| | | } |
| | | invoiceVO.setOrderAllocations(allocationVOs); |
| | | invoiceVO.setOrderCount(allocationVOs.size()); |
| | | invoiceVO.setOrderNos(CollUtil.join(allocationVOs, "、", ErpPurchaseInvoiceOrderRespVO::getOrderNo)); |
| | | // 2.3 拼接创建人名称 |
| | | MapUtils.findAndThen(userMap, NumberUtils.parseLong(invoiceVO.getCreator()), |
| | | user -> invoiceVO.setCreatorName(user.getNickname())); |
| | |
| | | }); |
| | | } |
| | | |
| | | @PutMapping("/submit") |
| | | @Operation(summary = "提交来票审批") |
| | | @PreAuthorize("@ss.hasPermission('erp:purchase-invoice:update')") |
| | | public CommonResult<Boolean> submitPurchaseInvoice(@RequestParam("id") Long id) { |
| | | invoiceService.submitPurchaseInvoice(id, getLoginUserId()); |
| | | return success(true); |
| | | } |
| | | |
| | | @GetMapping("/audit-count") |
| | | @Operation(summary = "获得待审核来票数量") |
| | | @PreAuthorize("@ss.hasPermission('erp:purchase-invoice:query')") |
| | | public CommonResult<Long> getAuditInvoiceCount() { |
| | | return success(invoiceService.getAuditInvoiceCount()); |
| | | } |
| | | |
| | | @GetMapping("/simple-list") |
| | | @Operation(summary = "获得来票精简列表", description = "只包含审核通过且已上传发票附件的来票,主要用于付款创建时选择关联来票") |
| | | @Operation(summary = "获得来票精简列表", description = "只包含已上传发票附件的来票,主要用于付款创建时选择关联来票") |
| | | @Parameter(name = "supplierId", description = "供应商编号", required = true) |
| | | @Parameter(name = "purchaseOrderId", description = "采购订单编号(可选,用于按订单过滤)") |
| | | @PreAuthorize("@ss.hasPermission('erp:purchase-invoice:query')") |
| | |
| | | @RequestParam(value = "purchaseOrderId", required = false) Long purchaseOrderId) { |
| | | List<ErpPurchaseInvoiceDO> invoices; |
| | | if (purchaseOrderId != null) { |
| | | invoices = invoiceService.getPurchaseInvoiceListByOrderIdAndStatus(purchaseOrderId, |
| | | List.of(ErpPurchaseInvoiceAuditStatusEnum.APPROVE.getStatus())); |
| | | invoices = invoiceService.getPurchaseInvoiceListByOrderId(purchaseOrderId); |
| | | } else { |
| | | invoices = invoiceService.getPurchaseInvoiceListBySupplierIdAndStatus(supplierId, |
| | | List.of(ErpPurchaseInvoiceAuditStatusEnum.APPROVE.getStatus())); |
| | | invoices = invoiceService.getPurchaseInvoiceListBySupplierId(supplierId); |
| | | } |
| | | if (CollUtil.isEmpty(invoices)) { |
| | | return success(Collections.emptyList()); |
| | |
| | | .setId(invoice.getId()).setNo(invoice.getNo()).setInvoiceNo(invoice.getInvoiceNo()) |
| | | .setInvoiceTitle(invoice.getInvoiceTitle()).setPrice(invoice.getPrice()) |
| | | .setSupplierId(invoice.getSupplierId()).setPurchaseOrderId(invoice.getPurchaseOrderId()) |
| | | .setAuditStatus(invoice.getAuditStatus()).setHasAttachment(true) |
| | | .setHasAttachment(true) |
| | | .setRemainingInvoicePrice(remainingPrice)); |
| | | } |
| | | return success(result); |