恢复 ERP 采购入库/退货后端,补齐采购统计接口
- 恢复 8c14b507 删除的采购入库、采购退货 Controller/Service/DO/Mapper,
物料与单位改走 MDM API,库存同步改走 MES WMS API,供应商名称改走 SRM
- WmsStockApi 及请求/响应 DTO 移入 yudao-module-mes-api,供 ERP 依赖
- 采购统计新增 /supplier、/price、/uncompleted 三个分页接口,
/summary 在原有首页金额字段上补充订单/入库/退货的总数与总金额
- 修复采购订单回写入库/退货数量时,历史数据 in_count/return_count 为 NULL 导致的 NPE
- 新增 CFWJ 建表脚本 erp_purchase_in / erp_purchase_return 及默认结算账户
Co-Authored-By: Claude Code <noreply@anthropic.com>
已添加25个文件
已重命名5个文件
已修改8个文件
| ¶Ô±ÈÐÂÎļþ |
| | |
| | | -- CFWJï¼è¯åäºéï¼ERP éè´å
¥åº / éè´éè´§è¡¨ç»æ 2026-11-03 |
| | | -- èæ¯ï¼ERP éè´å
¥åºãéè´é货代ç å¨ 8c14b507 被å é¤åéæ°æ¢å¤ï¼ |
| | | -- ç»è®¡é¡µï¼erp/purchase-statisticsï¼ä¾èµ erp_purchase_in / erp_purchase_return ä¸¤å¼ è¡¨ã |
| | | -- 说æï¼è¡¨ç»æå¯¹é½ç°æ erp_purchase_orderï¼æ tenant_id åï¼deleted ä½¿ç¨ bit(1)ï¼ã |
| | | -- å¹çï¼CREATE TABLE IF NOT EXISTSï¼å¯é夿§è¡ã |
| | | |
| | | SET NAMES utf8mb4; |
| | | |
| | | CREATE TABLE IF NOT EXISTS `erp_purchase_in` ( |
| | | `id` bigint NOT NULL AUTO_INCREMENT COMMENT 'ç¼å·', |
| | | `no` varchar(255) NOT NULL COMMENT 'éè´å
¥åºåå·', |
| | | `status` int NOT NULL COMMENT 'å
¥åºç¶æ', |
| | | `supplier_id` bigint DEFAULT NULL COMMENT 'ä¾åºåç¼å·', |
| | | `account_id` bigint DEFAULT NULL COMMENT 'ç»ç®è´¦æ·ç¼å·', |
| | | `in_time` datetime NOT NULL COMMENT 'å
¥åºæ¶é´', |
| | | `order_id` bigint DEFAULT NULL COMMENT 'éè´è®¢åç¼å·', |
| | | `order_no` varchar(255) DEFAULT NULL COMMENT 'éè´è®¢åå·', |
| | | `total_count` decimal(24,6) NOT NULL DEFAULT '0.000000' COMMENT 'å计æ°é', |
| | | `total_price` decimal(24,6) NOT NULL DEFAULT '0.000000' COMMENT 'æç»åè®¡ä»·æ ¼ï¼åä½ï¼å
', |
| | | `payment_price` decimal(24,6) NOT NULL DEFAULT '0.000000' COMMENT 'å·²æ¯ä»éé¢ï¼åä½ï¼å
', |
| | | `total_product_price` decimal(24,6) NOT NULL DEFAULT '0.000000' COMMENT 'å计产åä»·æ ¼ï¼åä½ï¼å
', |
| | | `total_tax_price` decimal(24,6) NOT NULL DEFAULT '0.000000' COMMENT 'å计ç¨é¢ï¼åä½ï¼å
', |
| | | `discount_percent` decimal(24,6) NOT NULL DEFAULT '0.000000' COMMENT '伿 çï¼ç¾åæ¯', |
| | | `discount_price` decimal(24,6) NOT NULL DEFAULT '0.000000' COMMENT '伿 éé¢ï¼åä½ï¼å
', |
| | | `other_price` decimal(24,6) NOT NULL DEFAULT '0.000000' COMMENT 'å
¶å®éé¢ï¼åä½ï¼å
', |
| | | `remark` varchar(255) DEFAULT NULL COMMENT '夿³¨', |
| | | `creator` varchar(64) DEFAULT '' COMMENT 'å建è
', |
| | | `create_time` datetime NOT NULL DEFAULT CURRENT_TIMESTAMP COMMENT 'å建æ¶é´', |
| | | `updater` varchar(64) DEFAULT '' COMMENT 'æ´æ°è
', |
| | | `update_time` datetime NOT NULL DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP COMMENT 'æ´æ°æ¶é´', |
| | | `deleted` bit(1) NOT NULL DEFAULT b'0' COMMENT 'æ¯å¦å é¤', |
| | | PRIMARY KEY (`id`) USING BTREE, |
| | | KEY `idx_no` (`no`) USING BTREE, |
| | | KEY `idx_order_id` (`order_id`) USING BTREE, |
| | | KEY `idx_in_time` (`in_time`) USING BTREE |
| | | ) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_unicode_ci ROW_FORMAT=DYNAMIC COMMENT='ERP éè´å
¥åº'; |
| | | |
| | | CREATE TABLE IF NOT EXISTS `erp_purchase_in_items` ( |
| | | `id` bigint NOT NULL AUTO_INCREMENT COMMENT 'ç¼å·', |
| | | `in_id` bigint NOT NULL COMMENT 'éè´å
¥åºç¼å·', |
| | | `order_item_id` bigint DEFAULT NULL COMMENT 'éè´è®¢å项ç¼å·', |
| | | `warehouse_id` bigint DEFAULT NULL COMMENT 'ä»åºç¼å·ï¼MES ä»åºï¼', |
| | | `product_id` bigint DEFAULT NULL COMMENT 'ç©æç¼å·ï¼MDM ç©æï¼', |
| | | `product_unit_id` bigint DEFAULT NULL COMMENT '产ååä½ç¼å·', |
| | | `product_price` decimal(24,6) NOT NULL DEFAULT '0.000000' COMMENT '产ååä»·ï¼åä½ï¼å
', |
| | | `count` decimal(24,6) NOT NULL DEFAULT '0.000000' COMMENT 'æ°é', |
| | | `total_price` decimal(24,6) NOT NULL DEFAULT '0.000000' COMMENT 'æ»ä»·ï¼åä½ï¼å
', |
| | | `tax_percent` decimal(24,6) DEFAULT NULL COMMENT 'ç¨çï¼ç¾åæ¯', |
| | | `tax_price` decimal(24,6) DEFAULT NULL COMMENT 'ç¨é¢ï¼åä½ï¼å
', |
| | | `remark` varchar(255) DEFAULT NULL COMMENT '夿³¨', |
| | | `creator` varchar(64) DEFAULT '' COMMENT 'å建è
', |
| | | `create_time` datetime NOT NULL DEFAULT CURRENT_TIMESTAMP COMMENT 'å建æ¶é´', |
| | | `updater` varchar(64) DEFAULT '' COMMENT 'æ´æ°è
', |
| | | `update_time` datetime NOT NULL DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP COMMENT 'æ´æ°æ¶é´', |
| | | `deleted` bit(1) NOT NULL DEFAULT b'0' COMMENT 'æ¯å¦å é¤', |
| | | PRIMARY KEY (`id`) USING BTREE, |
| | | KEY `idx_in_id` (`in_id`) USING BTREE, |
| | | KEY `idx_order_item_id` (`order_item_id`) USING BTREE |
| | | ) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_unicode_ci ROW_FORMAT=DYNAMIC COMMENT='ERP éè´å
¥åºé¡¹'; |
| | | |
| | | CREATE TABLE IF NOT EXISTS `erp_purchase_return` ( |
| | | `id` bigint NOT NULL AUTO_INCREMENT COMMENT 'ç¼å·', |
| | | `no` varchar(255) NOT NULL COMMENT 'éè´éè´§å·', |
| | | `status` int NOT NULL COMMENT 'éè´§ç¶æ', |
| | | `supplier_id` bigint DEFAULT NULL COMMENT 'ä¾åºåç¼å·', |
| | | `account_id` bigint DEFAULT NULL COMMENT 'ç»ç®è´¦æ·ç¼å·', |
| | | `return_time` datetime NOT NULL COMMENT 'éè´§æ¶é´', |
| | | `order_id` bigint DEFAULT NULL COMMENT 'éè´è®¢åç¼å·', |
| | | `order_no` varchar(255) DEFAULT NULL COMMENT 'éè´è®¢åå·', |
| | | `total_count` decimal(24,6) NOT NULL DEFAULT '0.000000' COMMENT 'å计æ°é', |
| | | `total_price` decimal(24,6) NOT NULL DEFAULT '0.000000' COMMENT 'æç»åè®¡ä»·æ ¼ï¼åä½ï¼å
', |
| | | `refund_price` decimal(24,6) NOT NULL DEFAULT '0.000000' COMMENT '已鿬¾éé¢ï¼åä½ï¼å
', |
| | | `total_product_price` decimal(24,6) NOT NULL DEFAULT '0.000000' COMMENT 'å计产åä»·æ ¼ï¼åä½ï¼å
', |
| | | `total_tax_price` decimal(24,6) NOT NULL DEFAULT '0.000000' COMMENT 'å计ç¨é¢ï¼åä½ï¼å
', |
| | | `discount_percent` decimal(24,6) NOT NULL DEFAULT '0.000000' COMMENT '伿 çï¼ç¾åæ¯', |
| | | `discount_price` decimal(24,6) NOT NULL DEFAULT '0.000000' COMMENT '伿 éé¢ï¼åä½ï¼å
', |
| | | `other_price` decimal(24,6) NOT NULL DEFAULT '0.000000' COMMENT 'å
¶å®éé¢ï¼åä½ï¼å
', |
| | | `remark` varchar(255) DEFAULT NULL COMMENT '夿³¨', |
| | | `creator` varchar(64) DEFAULT '' COMMENT 'å建è
', |
| | | `create_time` datetime NOT NULL DEFAULT CURRENT_TIMESTAMP COMMENT 'å建æ¶é´', |
| | | `updater` varchar(64) DEFAULT '' COMMENT 'æ´æ°è
', |
| | | `update_time` datetime NOT NULL DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP COMMENT 'æ´æ°æ¶é´', |
| | | `deleted` bit(1) NOT NULL DEFAULT b'0' COMMENT 'æ¯å¦å é¤', |
| | | PRIMARY KEY (`id`) USING BTREE, |
| | | KEY `idx_no` (`no`) USING BTREE, |
| | | KEY `idx_order_id` (`order_id`) USING BTREE, |
| | | KEY `idx_return_time` (`return_time`) USING BTREE |
| | | ) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_unicode_ci ROW_FORMAT=DYNAMIC COMMENT='ERP éè´éè´§'; |
| | | |
| | | CREATE TABLE IF NOT EXISTS `erp_purchase_return_items` ( |
| | | `id` bigint NOT NULL AUTO_INCREMENT COMMENT 'ç¼å·', |
| | | `return_id` bigint NOT NULL COMMENT 'éè´éè´§ç¼å·', |
| | | `order_item_id` bigint DEFAULT NULL COMMENT 'éè´è®¢å项ç¼å·', |
| | | `warehouse_id` bigint DEFAULT NULL COMMENT 'ä»åºç¼å·ï¼MES ä»åºï¼', |
| | | `product_id` bigint DEFAULT NULL COMMENT 'ç©æç¼å·ï¼MDM ç©æï¼', |
| | | `product_unit_id` bigint DEFAULT NULL COMMENT '产ååä½ç¼å·', |
| | | `product_price` decimal(24,6) NOT NULL DEFAULT '0.000000' COMMENT '产ååä»·ï¼åä½ï¼å
', |
| | | `count` decimal(24,6) NOT NULL DEFAULT '0.000000' COMMENT 'æ°é', |
| | | `total_price` decimal(24,6) NOT NULL DEFAULT '0.000000' COMMENT 'æ»ä»·ï¼åä½ï¼å
', |
| | | `tax_percent` decimal(24,6) DEFAULT NULL COMMENT 'ç¨çï¼ç¾åæ¯', |
| | | `tax_price` decimal(24,6) DEFAULT NULL COMMENT 'ç¨é¢ï¼åä½ï¼å
', |
| | | `remark` varchar(255) DEFAULT NULL COMMENT '夿³¨', |
| | | `creator` varchar(64) DEFAULT '' COMMENT 'å建è
', |
| | | `create_time` datetime NOT NULL DEFAULT CURRENT_TIMESTAMP COMMENT 'å建æ¶é´', |
| | | `updater` varchar(64) DEFAULT '' COMMENT 'æ´æ°è
', |
| | | `update_time` datetime NOT NULL DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP COMMENT 'æ´æ°æ¶é´', |
| | | `deleted` bit(1) NOT NULL DEFAULT b'0' COMMENT 'æ¯å¦å é¤', |
| | | PRIMARY KEY (`id`) USING BTREE, |
| | | KEY `idx_return_id` (`return_id`) USING BTREE, |
| | | KEY `idx_order_item_id` (`order_item_id`) USING BTREE |
| | | ) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_unicode_ci ROW_FORMAT=DYNAMIC COMMENT='ERP éè´é货项'; |
| | | |
| | | -- --------------------------------------------------------------------------- |
| | | -- ç»ç®è´¦æ·å
åºï¼éè´å
¥åº / éè´éè´§çåå»ºé½æ ¡éªç»ç®è´¦æ·ï¼erp_accountï¼ï¼ |
| | | -- è CFWJ åºæ¤å没æè´¦æ·æ°æ®ã乿²¡æè´¦æ·ç»´æ¤èåï¼ä¼å¯¼è´âç»ç®è´¦æ·âä¸æä¸ºç©ºãåæ®å»ºä¸åºæ¥ã |
| | | -- è¿éè¡¥ä¸æ¡é»è®¤è´¦æ·ï¼å¹çï¼æ no 夿ï¼ã |
| | | -- --------------------------------------------------------------------------- |
| | | INSERT INTO `erp_account` (`name`, `no`, `remark`, `status`, `sort`, `default_status`, `creator`, `create_time`, `updater`, `update_time`) |
| | | SELECT 'ç°éè´¦æ·', 'CASH', 'ç³»ç»é»è®¤ç»ç®è´¦æ·ï¼éè´å
¥åº/éè´§ãè´¢å¡æ¶ä»æ¬¾ä½¿ç¨', 0, 0, 1, '1', NOW(), '1', NOW() |
| | | WHERE NOT EXISTS (SELECT 1 FROM `erp_account` WHERE `no` = 'CASH' AND `deleted` = 0); |
| ¶Ô±ÈÐÂÎļþ |
| | |
| | | package cn.iocoder.yudao.module.erp.controller.admin.purchase; |
| | | |
| | | import cn.hutool.core.collection.CollUtil; |
| | | 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.pojo.PageResult; |
| | | import cn.iocoder.yudao.framework.common.util.collection.MapUtils; |
| | | 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.in.ErpPurchaseInPageReqVO; |
| | | import cn.iocoder.yudao.module.erp.controller.admin.purchase.vo.in.ErpPurchaseInRespVO; |
| | | import cn.iocoder.yudao.module.erp.controller.admin.purchase.vo.in.ErpPurchaseInSaveReqVO; |
| | | import cn.iocoder.yudao.module.erp.dal.dataobject.purchase.ErpPurchaseInDO; |
| | | import cn.iocoder.yudao.module.erp.dal.dataobject.purchase.ErpPurchaseInItemDO; |
| | | import cn.iocoder.yudao.module.erp.service.purchase.ErpPurchaseInService; |
| | | import cn.iocoder.yudao.module.mdm.api.item.MdmItemApi; |
| | | import cn.iocoder.yudao.module.mdm.api.item.dto.MdmItemRespDTO; |
| | | import cn.iocoder.yudao.module.mdm.api.unit.MdmUnitMeasureApi; |
| | | import cn.iocoder.yudao.module.mdm.api.unit.dto.MdmUnitMeasureRespDTO; |
| | | import cn.iocoder.yudao.module.mes.api.wms.stock.WmsStockApi; |
| | | import cn.iocoder.yudao.module.srm.api.supplier.SrmSupplierApi; |
| | | import cn.iocoder.yudao.module.srm.api.supplier.dto.SrmSupplierRespDTO; |
| | | import cn.iocoder.yudao.module.system.api.user.AdminUserApi; |
| | | import cn.iocoder.yudao.module.system.api.user.dto.AdminUserRespDTO; |
| | | import io.swagger.v3.oas.annotations.Operation; |
| | | import io.swagger.v3.oas.annotations.Parameter; |
| | | import io.swagger.v3.oas.annotations.tags.Tag; |
| | | import jakarta.annotation.Resource; |
| | | import jakarta.servlet.http.HttpServletResponse; |
| | | import jakarta.validation.Valid; |
| | | import org.springframework.security.access.prepost.PreAuthorize; |
| | | import org.springframework.validation.annotation.Validated; |
| | | import org.springframework.web.bind.annotation.*; |
| | | |
| | | import java.io.IOException; |
| | | import java.math.BigDecimal; |
| | | import java.util.List; |
| | | import java.util.Map; |
| | | |
| | | 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.util.collection.CollectionUtils.convertMultiMap; |
| | | import static cn.iocoder.yudao.framework.common.util.collection.CollectionUtils.convertSet; |
| | | |
| | | @Tag(name = "管çåå° - ERP éè´å
¥åº") |
| | | @RestController |
| | | @RequestMapping("/erp/purchase-in") |
| | | @Validated |
| | | public class ErpPurchaseInController { |
| | | |
| | | @Resource |
| | | private ErpPurchaseInService purchaseInService; |
| | | @Resource |
| | | private SrmSupplierApi srmSupplierApi; |
| | | |
| | | @Resource |
| | | private MdmItemApi mdmItemApi; |
| | | @Resource |
| | | private MdmUnitMeasureApi mdmUnitMeasureApi; |
| | | @Resource |
| | | private WmsStockApi wmsStockApi; |
| | | |
| | | @Resource |
| | | private AdminUserApi adminUserApi; |
| | | |
| | | @PostMapping("/create") |
| | | @Operation(summary = "å建éè´å
¥åº") |
| | | @PreAuthorize("@ss.hasPermission('erp:purchase-in:create')") |
| | | public CommonResult<Long> createPurchaseIn(@Valid @RequestBody ErpPurchaseInSaveReqVO createReqVO) { |
| | | return success(purchaseInService.createPurchaseIn(createReqVO)); |
| | | } |
| | | |
| | | @PutMapping("/update") |
| | | @Operation(summary = "æ´æ°éè´å
¥åº") |
| | | @PreAuthorize("@ss.hasPermission('erp:purchase-in:update')") |
| | | public CommonResult<Boolean> updatePurchaseIn(@Valid @RequestBody ErpPurchaseInSaveReqVO updateReqVO) { |
| | | purchaseInService.updatePurchaseIn(updateReqVO); |
| | | return success(true); |
| | | } |
| | | |
| | | @PutMapping("/update-status") |
| | | @Operation(summary = "æ´æ°éè´å
¥åºçç¶æ") |
| | | @PreAuthorize("@ss.hasPermission('erp:purchase-in:update-status')") |
| | | public CommonResult<Boolean> updatePurchaseInStatus(@RequestParam("id") Long id, |
| | | @RequestParam("status") Integer status) { |
| | | purchaseInService.updatePurchaseInStatus(id, status); |
| | | return success(true); |
| | | } |
| | | |
| | | @DeleteMapping("/delete") |
| | | @Operation(summary = "å é¤éè´å
¥åº") |
| | | @Parameter(name = "ids", description = "ç¼å·æ°ç»", required = true) |
| | | @PreAuthorize("@ss.hasPermission('erp:purchase-in:delete')") |
| | | public CommonResult<Boolean> deletePurchaseIn(@RequestParam("ids") List<Long> ids) { |
| | | purchaseInService.deletePurchaseIn(ids); |
| | | return success(true); |
| | | } |
| | | |
| | | @GetMapping("/get") |
| | | @Operation(summary = "è·å¾éè´å
¥åº") |
| | | @Parameter(name = "id", description = "ç¼å·", required = true, example = "1024") |
| | | @PreAuthorize("@ss.hasPermission('erp:purchase-in:query')") |
| | | public CommonResult<ErpPurchaseInRespVO> getPurchaseIn(@RequestParam("id") Long id) { |
| | | ErpPurchaseInDO purchaseIn = purchaseInService.getPurchaseIn(id); |
| | | if (purchaseIn == null) { |
| | | return success(null); |
| | | } |
| | | List<ErpPurchaseInItemDO> purchaseInItemList = purchaseInService.getPurchaseInItemListByInId(id); |
| | | Map<Long, MdmItemRespDTO> itemMap = mdmItemApi.getItemMap( |
| | | convertSet(purchaseInItemList, ErpPurchaseInItemDO::getProductId)); |
| | | Map<Long, MdmUnitMeasureRespDTO> unitMap = mdmUnitMeasureApi.getUnitMeasureMap( |
| | | convertSet(purchaseInItemList, ErpPurchaseInItemDO::getProductUnitId)); |
| | | return success(BeanUtils.toBean(purchaseIn, ErpPurchaseInRespVO.class, purchaseInVO -> |
| | | purchaseInVO.setItems(BeanUtils.toBean(purchaseInItemList, ErpPurchaseInRespVO.Item.class, item -> { |
| | | BigDecimal stockCount = wmsStockApi.getStockQuantity(item.getProductId(), item.getWarehouseId()); |
| | | item.setStockCount(stockCount != null ? stockCount : BigDecimal.ZERO); |
| | | MapUtils.findAndThen(itemMap, item.getProductId(), mdmItem -> item.setProductName(mdmItem.getName()) |
| | | .setProductBarCode(mdmItem.getBarCode())); |
| | | MapUtils.findAndThen(unitMap, item.getProductUnitId(), unit -> item.setProductUnitName(unit.getName())); |
| | | })))); |
| | | } |
| | | |
| | | @GetMapping("/page") |
| | | @Operation(summary = "è·å¾éè´å
¥åºå页") |
| | | @PreAuthorize("@ss.hasPermission('erp:purchase-in:query')") |
| | | public CommonResult<PageResult<ErpPurchaseInRespVO>> getPurchaseInPage(@Valid ErpPurchaseInPageReqVO pageReqVO) { |
| | | PageResult<ErpPurchaseInDO> pageResult = purchaseInService.getPurchaseInPage(pageReqVO); |
| | | return success(buildPurchaseInVOPageResult(pageResult)); |
| | | } |
| | | |
| | | @GetMapping("/export-excel") |
| | | @Operation(summary = "导åºéè´å
¥åº Excel") |
| | | @PreAuthorize("@ss.hasPermission('erp:purchase-in:export')") |
| | | @ApiAccessLog(operateType = EXPORT) |
| | | public void exportPurchaseInExcel(@Valid ErpPurchaseInPageReqVO pageReqVO, |
| | | HttpServletResponse response) throws IOException { |
| | | pageReqVO.setPageSize(PageParam.PAGE_SIZE_NONE); |
| | | List<ErpPurchaseInRespVO> list = buildPurchaseInVOPageResult(purchaseInService.getPurchaseInPage(pageReqVO)).getList(); |
| | | // å¯¼åº Excel |
| | | ExcelUtils.write(response, "éè´å
¥åº.xls", "æ°æ®", ErpPurchaseInRespVO.class, list); |
| | | } |
| | | |
| | | private PageResult<ErpPurchaseInRespVO> buildPurchaseInVOPageResult(PageResult<ErpPurchaseInDO> pageResult) { |
| | | if (CollUtil.isEmpty(pageResult.getList())) { |
| | | return PageResult.empty(pageResult.getTotal()); |
| | | } |
| | | // 1.1 å
¥åºé¡¹ |
| | | List<ErpPurchaseInItemDO> purchaseInItemList = purchaseInService.getPurchaseInItemListByInIds( |
| | | convertSet(pageResult.getList(), ErpPurchaseInDO::getId)); |
| | | Map<Long, List<ErpPurchaseInItemDO>> purchaseInItemMap = convertMultiMap(purchaseInItemList, ErpPurchaseInItemDO::getInId); |
| | | // 1.2 ç©æä¿¡æ¯ |
| | | Map<Long, MdmItemRespDTO> itemMap = mdmItemApi.getItemMap( |
| | | convertSet(purchaseInItemList, ErpPurchaseInItemDO::getProductId)); |
| | | Map<Long, MdmUnitMeasureRespDTO> unitMap = mdmUnitMeasureApi.getUnitMeasureMap( |
| | | convertSet(purchaseInItemList, ErpPurchaseInItemDO::getProductUnitId)); |
| | | // 1.3 ä¾åºåä¿¡æ¯ï¼ä¾åºåä¸»æ°æ®å·²è¿ç§»å° SRMï¼ |
| | | Map<Long, SrmSupplierRespDTO> supplierMap = srmSupplierApi.getSupplierList( |
| | | convertSet(pageResult.getList(), ErpPurchaseInDO::getSupplierId)).getCheckedData().stream() |
| | | .collect(java.util.stream.Collectors.toMap(SrmSupplierRespDTO::getId, v -> v, (a, b) -> a)); |
| | | // 1.4 管çåä¿¡æ¯ |
| | | Map<Long, AdminUserRespDTO> userMap = adminUserApi.getUserMap( |
| | | convertSet(pageResult.getList(), purchaseIn -> Long.parseLong(purchaseIn.getCreator()))); |
| | | // 2. å¼å§æ¼æ¥ |
| | | return BeanUtils.toBean(pageResult, ErpPurchaseInRespVO.class, purchaseIn -> { |
| | | purchaseIn.setItems(BeanUtils.toBean(purchaseInItemMap.get(purchaseIn.getId()), ErpPurchaseInRespVO.Item.class, |
| | | item -> { |
| | | MapUtils.findAndThen(itemMap, item.getProductId(), mdmItem -> item.setProductName(mdmItem.getName()) |
| | | .setProductBarCode(mdmItem.getBarCode())); |
| | | MapUtils.findAndThen(unitMap, item.getProductUnitId(), unit -> item.setProductUnitName(unit.getName())); |
| | | })); |
| | | purchaseIn.setProductNames(CollUtil.join(purchaseIn.getItems(), "ï¼", ErpPurchaseInRespVO.Item::getProductName)); |
| | | MapUtils.findAndThen(supplierMap, purchaseIn.getSupplierId(), supplier -> purchaseIn.setSupplierName(supplier.getName())); |
| | | MapUtils.findAndThen(userMap, Long.parseLong(purchaseIn.getCreator()), user -> purchaseIn.setCreatorName(user.getNickname())); |
| | | }); |
| | | } |
| | | |
| | | } |
| ¶Ô±ÈÐÂÎļþ |
| | |
| | | package cn.iocoder.yudao.module.erp.controller.admin.purchase; |
| | | |
| | | import cn.hutool.core.collection.CollUtil; |
| | | 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.pojo.PageResult; |
| | | import cn.iocoder.yudao.framework.common.util.collection.MapUtils; |
| | | 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.returns.ErpPurchaseReturnPageReqVO; |
| | | import cn.iocoder.yudao.module.erp.controller.admin.purchase.vo.returns.ErpPurchaseReturnRespVO; |
| | | import cn.iocoder.yudao.module.erp.controller.admin.purchase.vo.returns.ErpPurchaseReturnSaveReqVO; |
| | | import cn.iocoder.yudao.module.erp.dal.dataobject.purchase.ErpPurchaseReturnDO; |
| | | import cn.iocoder.yudao.module.erp.dal.dataobject.purchase.ErpPurchaseReturnItemDO; |
| | | import cn.iocoder.yudao.module.erp.service.purchase.ErpPurchaseReturnService; |
| | | import cn.iocoder.yudao.module.mdm.api.item.MdmItemApi; |
| | | import cn.iocoder.yudao.module.mdm.api.item.dto.MdmItemRespDTO; |
| | | import cn.iocoder.yudao.module.mdm.api.unit.MdmUnitMeasureApi; |
| | | import cn.iocoder.yudao.module.mdm.api.unit.dto.MdmUnitMeasureRespDTO; |
| | | import cn.iocoder.yudao.module.mes.api.wms.stock.WmsStockApi; |
| | | import cn.iocoder.yudao.module.srm.api.supplier.SrmSupplierApi; |
| | | import cn.iocoder.yudao.module.srm.api.supplier.dto.SrmSupplierRespDTO; |
| | | import cn.iocoder.yudao.module.system.api.user.AdminUserApi; |
| | | import cn.iocoder.yudao.module.system.api.user.dto.AdminUserRespDTO; |
| | | import io.swagger.v3.oas.annotations.Operation; |
| | | import io.swagger.v3.oas.annotations.Parameter; |
| | | import io.swagger.v3.oas.annotations.tags.Tag; |
| | | import jakarta.annotation.Resource; |
| | | import jakarta.servlet.http.HttpServletResponse; |
| | | import jakarta.validation.Valid; |
| | | import org.springframework.security.access.prepost.PreAuthorize; |
| | | import org.springframework.validation.annotation.Validated; |
| | | import org.springframework.web.bind.annotation.*; |
| | | |
| | | import java.io.IOException; |
| | | import java.math.BigDecimal; |
| | | import java.util.List; |
| | | import java.util.Map; |
| | | |
| | | 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.util.collection.CollectionUtils.convertMultiMap; |
| | | import static cn.iocoder.yudao.framework.common.util.collection.CollectionUtils.convertSet; |
| | | |
| | | @Tag(name = "管çåå° - ERP éè´éè´§") |
| | | @RestController |
| | | @RequestMapping("/erp/purchase-return") |
| | | @Validated |
| | | public class ErpPurchaseReturnController { |
| | | |
| | | @Resource |
| | | private ErpPurchaseReturnService purchaseReturnService; |
| | | @Resource |
| | | private SrmSupplierApi srmSupplierApi; |
| | | |
| | | @Resource |
| | | private MdmItemApi mdmItemApi; |
| | | @Resource |
| | | private MdmUnitMeasureApi mdmUnitMeasureApi; |
| | | @Resource |
| | | private WmsStockApi wmsStockApi; |
| | | |
| | | @Resource |
| | | private AdminUserApi adminUserApi; |
| | | |
| | | @PostMapping("/create") |
| | | @Operation(summary = "å建éè´éè´§") |
| | | @PreAuthorize("@ss.hasPermission('erp:purchase-return:create')") |
| | | public CommonResult<Long> createPurchaseReturn(@Valid @RequestBody ErpPurchaseReturnSaveReqVO createReqVO) { |
| | | return success(purchaseReturnService.createPurchaseReturn(createReqVO)); |
| | | } |
| | | |
| | | @PutMapping("/update") |
| | | @Operation(summary = "æ´æ°éè´éè´§") |
| | | @PreAuthorize("@ss.hasPermission('erp:purchase-return:update')") |
| | | public CommonResult<Boolean> updatePurchaseReturn(@Valid @RequestBody ErpPurchaseReturnSaveReqVO updateReqVO) { |
| | | purchaseReturnService.updatePurchaseReturn(updateReqVO); |
| | | return success(true); |
| | | } |
| | | |
| | | @PutMapping("/update-status") |
| | | @Operation(summary = "æ´æ°éè´éè´§çç¶æ") |
| | | @PreAuthorize("@ss.hasPermission('erp:purchase-return:update-status')") |
| | | public CommonResult<Boolean> updatePurchaseReturnStatus(@RequestParam("id") Long id, |
| | | @RequestParam("status") Integer status) { |
| | | purchaseReturnService.updatePurchaseReturnStatus(id, status); |
| | | return success(true); |
| | | } |
| | | |
| | | @DeleteMapping("/delete") |
| | | @Operation(summary = "å é¤éè´éè´§") |
| | | @Parameter(name = "ids", description = "ç¼å·æ°ç»", required = true) |
| | | @PreAuthorize("@ss.hasPermission('erp:purchase-return:delete')") |
| | | public CommonResult<Boolean> deletePurchaseReturn(@RequestParam("ids") List<Long> ids) { |
| | | purchaseReturnService.deletePurchaseReturn(ids); |
| | | return success(true); |
| | | } |
| | | |
| | | @GetMapping("/get") |
| | | @Operation(summary = "è·å¾éè´éè´§") |
| | | @Parameter(name = "id", description = "ç¼å·", required = true, example = "1024") |
| | | @PreAuthorize("@ss.hasPermission('erp:purchase-return:query')") |
| | | public CommonResult<ErpPurchaseReturnRespVO> getPurchaseReturn(@RequestParam("id") Long id) { |
| | | ErpPurchaseReturnDO purchaseReturn = purchaseReturnService.getPurchaseReturn(id); |
| | | if (purchaseReturn == null) { |
| | | return success(null); |
| | | } |
| | | List<ErpPurchaseReturnItemDO> purchaseReturnItemList = purchaseReturnService.getPurchaseReturnItemListByReturnId(id); |
| | | Map<Long, MdmItemRespDTO> itemMap = mdmItemApi.getItemMap( |
| | | convertSet(purchaseReturnItemList, ErpPurchaseReturnItemDO::getProductId)); |
| | | Map<Long, MdmUnitMeasureRespDTO> unitMap = mdmUnitMeasureApi.getUnitMeasureMap( |
| | | convertSet(purchaseReturnItemList, ErpPurchaseReturnItemDO::getProductUnitId)); |
| | | return success(BeanUtils.toBean(purchaseReturn, ErpPurchaseReturnRespVO.class, purchaseReturnVO -> |
| | | purchaseReturnVO.setItems(BeanUtils.toBean(purchaseReturnItemList, ErpPurchaseReturnRespVO.Item.class, item -> { |
| | | BigDecimal stockCount = wmsStockApi.getStockQuantity(item.getProductId(), item.getWarehouseId()); |
| | | item.setStockCount(stockCount != null ? stockCount : BigDecimal.ZERO); |
| | | MapUtils.findAndThen(itemMap, item.getProductId(), mdmItem -> item.setProductName(mdmItem.getName()) |
| | | .setProductBarCode(mdmItem.getBarCode())); |
| | | MapUtils.findAndThen(unitMap, item.getProductUnitId(), unit -> item.setProductUnitName(unit.getName())); |
| | | })))); |
| | | } |
| | | |
| | | @GetMapping("/page") |
| | | @Operation(summary = "è·å¾éè´éè´§å页") |
| | | @PreAuthorize("@ss.hasPermission('erp:purchase-return:query')") |
| | | public CommonResult<PageResult<ErpPurchaseReturnRespVO>> getPurchaseReturnPage(@Valid ErpPurchaseReturnPageReqVO pageReqVO) { |
| | | PageResult<ErpPurchaseReturnDO> pageResult = purchaseReturnService.getPurchaseReturnPage(pageReqVO); |
| | | return success(buildPurchaseReturnVOPageResult(pageResult)); |
| | | } |
| | | |
| | | @GetMapping("/export-excel") |
| | | @Operation(summary = "导åºéè´éè´§ Excel") |
| | | @PreAuthorize("@ss.hasPermission('erp:purchase-return:export')") |
| | | @ApiAccessLog(operateType = EXPORT) |
| | | public void exportPurchaseReturnExcel(@Valid ErpPurchaseReturnPageReqVO pageReqVO, |
| | | HttpServletResponse response) throws IOException { |
| | | pageReqVO.setPageSize(PageParam.PAGE_SIZE_NONE); |
| | | List<ErpPurchaseReturnRespVO> list = buildPurchaseReturnVOPageResult(purchaseReturnService.getPurchaseReturnPage(pageReqVO)).getList(); |
| | | // å¯¼åº Excel |
| | | ExcelUtils.write(response, "éè´éè´§.xls", "æ°æ®", ErpPurchaseReturnRespVO.class, list); |
| | | } |
| | | |
| | | private PageResult<ErpPurchaseReturnRespVO> buildPurchaseReturnVOPageResult(PageResult<ErpPurchaseReturnDO> pageResult) { |
| | | if (CollUtil.isEmpty(pageResult.getList())) { |
| | | return PageResult.empty(pageResult.getTotal()); |
| | | } |
| | | // 1.1 é货项 |
| | | List<ErpPurchaseReturnItemDO> purchaseReturnItemList = purchaseReturnService.getPurchaseReturnItemListByReturnIds( |
| | | convertSet(pageResult.getList(), ErpPurchaseReturnDO::getId)); |
| | | Map<Long, List<ErpPurchaseReturnItemDO>> purchaseReturnItemMap = convertMultiMap(purchaseReturnItemList, ErpPurchaseReturnItemDO::getReturnId); |
| | | // 1.2 ç©æä¿¡æ¯ |
| | | Map<Long, MdmItemRespDTO> itemMap = mdmItemApi.getItemMap( |
| | | convertSet(purchaseReturnItemList, ErpPurchaseReturnItemDO::getProductId)); |
| | | Map<Long, MdmUnitMeasureRespDTO> unitMap = mdmUnitMeasureApi.getUnitMeasureMap( |
| | | convertSet(purchaseReturnItemList, ErpPurchaseReturnItemDO::getProductUnitId)); |
| | | // 1.3 ä¾åºåä¿¡æ¯ï¼ä¾åºåä¸»æ°æ®å·²è¿ç§»å° SRMï¼ |
| | | Map<Long, SrmSupplierRespDTO> supplierMap = srmSupplierApi.getSupplierList( |
| | | convertSet(pageResult.getList(), ErpPurchaseReturnDO::getSupplierId)).getCheckedData().stream() |
| | | .collect(java.util.stream.Collectors.toMap(SrmSupplierRespDTO::getId, v -> v, (a, b) -> a)); |
| | | // 1.4 管çåä¿¡æ¯ |
| | | Map<Long, AdminUserRespDTO> userMap = adminUserApi.getUserMap( |
| | | convertSet(pageResult.getList(), purchaseReturn -> Long.parseLong(purchaseReturn.getCreator()))); |
| | | // 2. å¼å§æ¼æ¥ |
| | | return BeanUtils.toBean(pageResult, ErpPurchaseReturnRespVO.class, purchaseReturn -> { |
| | | purchaseReturn.setItems(BeanUtils.toBean(purchaseReturnItemMap.get(purchaseReturn.getId()), ErpPurchaseReturnRespVO.Item.class, |
| | | item -> { |
| | | MapUtils.findAndThen(itemMap, item.getProductId(), mdmItem -> item.setProductName(mdmItem.getName()) |
| | | .setProductBarCode(mdmItem.getBarCode())); |
| | | MapUtils.findAndThen(unitMap, item.getProductUnitId(), unit -> item.setProductUnitName(unit.getName())); |
| | | })); |
| | | purchaseReturn.setProductNames(CollUtil.join(purchaseReturn.getItems(), "ï¼", ErpPurchaseReturnRespVO.Item::getProductName)); |
| | | MapUtils.findAndThen(supplierMap, purchaseReturn.getSupplierId(), supplier -> purchaseReturn.setSupplierName(supplier.getName())); |
| | | MapUtils.findAndThen(userMap, Long.parseLong(purchaseReturn.getCreator()), user -> purchaseReturn.setCreatorName(user.getNickname())); |
| | | }); |
| | | } |
| | | |
| | | } |
| ¶Ô±ÈÐÂÎļþ |
| | |
| | | package cn.iocoder.yudao.module.erp.controller.admin.purchase.vo.in; |
| | | |
| | | import cn.iocoder.yudao.framework.common.pojo.PageParam; |
| | | import io.swagger.v3.oas.annotations.media.Schema; |
| | | import lombok.Data; |
| | | import lombok.EqualsAndHashCode; |
| | | import lombok.ToString; |
| | | import org.springframework.format.annotation.DateTimeFormat; |
| | | |
| | | import java.time.LocalDateTime; |
| | | |
| | | import static cn.iocoder.yudao.framework.common.util.date.DateUtils.FORMAT_YEAR_MONTH_DAY_HOUR_MINUTE_SECOND; |
| | | |
| | | @Schema(description = "管çåå° - ERP éè´å
¥åºå页 Request VO") |
| | | @Data |
| | | @EqualsAndHashCode(callSuper = true) |
| | | @ToString(callSuper = true) |
| | | public class ErpPurchaseInPageReqVO extends PageParam { |
| | | |
| | | public static final Integer PAYMENT_STATUS_NONE = 0; |
| | | public static final Integer PAYMENT_STATUS_PART = 1; |
| | | public static final Integer PAYMENT_STATUS_ALL = 2; |
| | | |
| | | @Schema(description = "éè´åç¼å·", example = "XS001") |
| | | private String no; |
| | | |
| | | @Schema(description = "ä¾åºåç¼å·", example = "1724") |
| | | private Long supplierId; |
| | | |
| | | @Schema(description = "å
¥åºæ¶é´") |
| | | @DateTimeFormat(pattern = FORMAT_YEAR_MONTH_DAY_HOUR_MINUTE_SECOND) |
| | | private LocalDateTime[] inTime; |
| | | |
| | | @Schema(description = "夿³¨", example = "ä½ ç") |
| | | private String remark; |
| | | |
| | | @Schema(description = "å
¥åºç¶æ", example = "2") |
| | | private Integer status; |
| | | |
| | | @Schema(description = "å建è
") |
| | | private String creator; |
| | | |
| | | @Schema(description = "产åç¼å·", example = "1") |
| | | private Long productId; |
| | | |
| | | @Schema(description = "ä»åºç¼å·", example = "1") |
| | | private Long warehouseId; |
| | | |
| | | @Schema(description = "ç»ç®è´¦å·ç¼å·", example = "1") |
| | | private Long accountId; |
| | | |
| | | @Schema(description = "仿¬¾ç¶æ", example = "1") |
| | | private Integer paymentStatus; |
| | | |
| | | @Schema(description = "æ¯å¦å¯ä»æ¬¾", example = "true") |
| | | private Boolean paymentEnable; // å¯¹åº paymentStatus = [0, 1] |
| | | |
| | | @Schema(description = "éè´åå·", example = "1") |
| | | private String orderNo; |
| | | |
| | | } |
| ¶Ô±ÈÐÂÎļþ |
| | |
| | | package cn.iocoder.yudao.module.erp.controller.admin.purchase.vo.in; |
| | | |
| | | import cn.idev.excel.annotation.ExcelIgnoreUnannotated; |
| | | import cn.idev.excel.annotation.ExcelProperty; |
| | | import io.swagger.v3.oas.annotations.media.Schema; |
| | | import jakarta.validation.constraints.NotNull; |
| | | import lombok.Data; |
| | | |
| | | import java.math.BigDecimal; |
| | | import java.time.LocalDateTime; |
| | | import java.util.List; |
| | | |
| | | @Schema(description = "管çåå° - ERP éè´å
¥åº Response VO") |
| | | @Data |
| | | @ExcelIgnoreUnannotated |
| | | public class ErpPurchaseInRespVO { |
| | | |
| | | @Schema(description = "ç¼å·", requiredMode = Schema.RequiredMode.REQUIRED, example = "17386") |
| | | @ExcelProperty("ç¼å·") |
| | | private Long id; |
| | | |
| | | @Schema(description = "å
¥åºåç¼å·", requiredMode = Schema.RequiredMode.REQUIRED, example = "XS001") |
| | | @ExcelProperty("å
¥åºåç¼å·") |
| | | private String no; |
| | | |
| | | @Schema(description = "å
¥åºç¶æ", requiredMode = Schema.RequiredMode.REQUIRED, example = "2") |
| | | @ExcelProperty("å
¥åºç¶æ") |
| | | private Integer status; |
| | | |
| | | @Schema(description = "ä¾åºåç¼å·", requiredMode = Schema.RequiredMode.REQUIRED, example = "1724") |
| | | private Long supplierId; |
| | | @Schema(description = "ä¾åºååç§°", example = "èé") |
| | | @ExcelProperty("ä¾åºååç§°") |
| | | private String supplierName; |
| | | |
| | | @Schema(description = "ç»ç®è´¦æ·ç¼å·", requiredMode = Schema.RequiredMode.REQUIRED, example = "311.89") |
| | | @ExcelProperty("ç»ç®è´¦æ·ç¼å·") |
| | | private Long accountId; |
| | | |
| | | @Schema(description = "å
¥åºæ¶é´", requiredMode = Schema.RequiredMode.REQUIRED) |
| | | @ExcelProperty("å
¥åºæ¶é´") |
| | | private LocalDateTime inTime; |
| | | |
| | | @Schema(description = "éè´è®¢åç¼å·", requiredMode = Schema.RequiredMode.REQUIRED, example = "17386") |
| | | private Long orderId; |
| | | @Schema(description = "éè´è®¢åå·", requiredMode = Schema.RequiredMode.REQUIRED, example = "XS001") |
| | | private String orderNo; |
| | | |
| | | @Schema(description = "å计æ°é", requiredMode = Schema.RequiredMode.REQUIRED, example = "15663") |
| | | @ExcelProperty("å计æ°é") |
| | | private BigDecimal totalCount; |
| | | @Schema(description = "æç»åè®¡ä»·æ ¼", requiredMode = Schema.RequiredMode.REQUIRED, example = "24906") |
| | | @ExcelProperty("æç»åè®¡ä»·æ ¼") |
| | | private BigDecimal totalPrice; |
| | | @Schema(description = "已仿¬¾éé¢ï¼åä½ï¼å
", requiredMode = Schema.RequiredMode.REQUIRED, example = "7127") |
| | | private BigDecimal paymentPrice; |
| | | |
| | | @Schema(description = "å计产åä»·æ ¼ï¼åä½ï¼å
", requiredMode = Schema.RequiredMode.REQUIRED, example = "7127") |
| | | private BigDecimal totalProductPrice; |
| | | |
| | | @Schema(description = "å计ç¨é¢ï¼åä½ï¼å
", requiredMode = Schema.RequiredMode.REQUIRED, example = "7127") |
| | | private BigDecimal totalTaxPrice; |
| | | |
| | | @Schema(description = "伿 çï¼ç¾åæ¯", requiredMode = Schema.RequiredMode.REQUIRED, example = "99.88") |
| | | private BigDecimal discountPercent; |
| | | |
| | | @Schema(description = "伿 éé¢ï¼åä½ï¼å
", requiredMode = Schema.RequiredMode.REQUIRED, example = "7127") |
| | | private BigDecimal discountPrice; |
| | | |
| | | @Schema(description = "å®ééé¢ï¼åä½ï¼å
", requiredMode = Schema.RequiredMode.REQUIRED, example = "7127") |
| | | private BigDecimal otherPrice; |
| | | |
| | | |
| | | @Schema(description = "夿³¨", example = "ä½ ç") |
| | | @ExcelProperty("夿³¨") |
| | | private String remark; |
| | | |
| | | @Schema(description = "å建人", example = "èé") |
| | | private String creator; |
| | | @Schema(description = "å建人åç§°", example = "èé") |
| | | private String creatorName; |
| | | |
| | | @Schema(description = "å建æ¶é´", requiredMode = Schema.RequiredMode.REQUIRED) |
| | | @ExcelProperty("å建æ¶é´") |
| | | private LocalDateTime createTime; |
| | | |
| | | @Schema(description = "å
¥åºé¡¹å表", requiredMode = Schema.RequiredMode.REQUIRED) |
| | | private List<Item> items; |
| | | |
| | | @Schema(description = "产åä¿¡æ¯", requiredMode = Schema.RequiredMode.REQUIRED) |
| | | @ExcelProperty("产åä¿¡æ¯") |
| | | private String productNames; |
| | | |
| | | @Data |
| | | public static class Item { |
| | | |
| | | @Schema(description = "å
¥åºé¡¹ç¼å·", example = "11756") |
| | | private Long id; |
| | | |
| | | @Schema(description = "éè´è®¢å项ç¼å·", requiredMode = Schema.RequiredMode.REQUIRED, example = "11756") |
| | | private Long orderItemId; |
| | | |
| | | @Schema(description = "ä»åºç¼å·", requiredMode = Schema.RequiredMode.REQUIRED, example = "3113") |
| | | private Long warehouseId; |
| | | |
| | | @Schema(description = "产åç¼å·", requiredMode = Schema.RequiredMode.REQUIRED, example = "3113") |
| | | private Long productId; |
| | | |
| | | @Schema(description = "产ååä½åä½", requiredMode = Schema.RequiredMode.REQUIRED, example = "3113") |
| | | private Long productUnitId; |
| | | |
| | | @Schema(description = "产ååä»·", example = "100.00") |
| | | private BigDecimal productPrice; |
| | | |
| | | @Schema(description = "äº§åæ°é", requiredMode = Schema.RequiredMode.REQUIRED, example = "100.00") |
| | | @NotNull(message = "äº§åæ°éä¸è½ä¸ºç©º") |
| | | private BigDecimal count; |
| | | |
| | | @Schema(description = "ç¨çï¼ç¾åæ¯", example = "99.88") |
| | | private BigDecimal taxPercent; |
| | | |
| | | @Schema(description = "ç¨é¢ï¼åä½ï¼å
", example = "100.00") |
| | | private BigDecimal taxPrice; |
| | | |
| | | @Schema(description = "夿³¨", example = "é便") |
| | | private String remark; |
| | | |
| | | // ========== å
³èåæ®µ ========== |
| | | |
| | | @Schema(description = "产ååç§°", requiredMode = Schema.RequiredMode.REQUIRED, example = "å·§å
å") |
| | | private String productName; |
| | | @Schema(description = "äº§åæ¡ç ", requiredMode = Schema.RequiredMode.REQUIRED, example = "A9985") |
| | | private String productBarCode; |
| | | @Schema(description = "产ååä½åç§°", requiredMode = Schema.RequiredMode.REQUIRED, example = "ç") |
| | | private String productUnitName; |
| | | |
| | | @Schema(description = "åºåæ°é", requiredMode = Schema.RequiredMode.REQUIRED, example = "100.00") |
| | | private BigDecimal stockCount; // è¯¥åæ®µä»
ä»
å¨â详æ
âåâç¼è¾âæ¶ä½¿ç¨ |
| | | |
| | | } |
| | | |
| | | } |
| ¶Ô±ÈÐÂÎļþ |
| | |
| | | package cn.iocoder.yudao.module.erp.controller.admin.purchase.vo.in; |
| | | |
| | | import io.swagger.v3.oas.annotations.media.Schema; |
| | | import jakarta.validation.constraints.NotNull; |
| | | import lombok.Data; |
| | | |
| | | import java.math.BigDecimal; |
| | | import java.time.LocalDateTime; |
| | | import java.util.List; |
| | | |
| | | @Schema(description = "管çåå° - ERP éè´å
¥åºæ°å¢/ä¿®æ¹ Request VO") |
| | | @Data |
| | | public class ErpPurchaseInSaveReqVO { |
| | | |
| | | @Schema(description = "ç¼å·", requiredMode = Schema.RequiredMode.REQUIRED, example = "17386") |
| | | private Long id; |
| | | |
| | | @Schema(description = "ç»ç®è´¦æ·ç¼å·", example = "31189") |
| | | private Long accountId; |
| | | |
| | | @Schema(description = "å
¥åºæ¶é´", requiredMode = Schema.RequiredMode.REQUIRED) |
| | | @NotNull(message = "å
¥åºæ¶é´ä¸è½ä¸ºç©º") |
| | | private LocalDateTime inTime; |
| | | |
| | | @Schema(description = "éè´è®¢åç¼å·", requiredMode = Schema.RequiredMode.REQUIRED, example = "17386") |
| | | @NotNull(message = "éè´è®¢åç¼å·ä¸è½ä¸ºç©º") |
| | | private Long orderId; |
| | | |
| | | @Schema(description = "伿 çï¼ç¾åæ¯", requiredMode = Schema.RequiredMode.REQUIRED, example = "99.88") |
| | | private BigDecimal discountPercent; |
| | | |
| | | @Schema(description = "å
¶å®éé¢ï¼åä½ï¼å
", example = "7127") |
| | | private BigDecimal otherPrice; |
| | | |
| | | |
| | | @Schema(description = "夿³¨", example = "ä½ ç") |
| | | private String remark; |
| | | |
| | | @Schema(description = "å
¥åºæ¸
åå表") |
| | | private List<Item> items; |
| | | |
| | | @Data |
| | | public static class Item { |
| | | |
| | | @Schema(description = "å
¥åºé¡¹ç¼å·", example = "11756") |
| | | private Long id; |
| | | |
| | | @Schema(description = "éè´è®¢å项ç¼å·", requiredMode = Schema.RequiredMode.REQUIRED, example = "11756") |
| | | @NotNull(message = "éè´è®¢å项ç¼å·ä¸è½ä¸ºç©º") |
| | | private Long orderItemId; |
| | | |
| | | @Schema(description = "ä»åºç¼å·", requiredMode = Schema.RequiredMode.REQUIRED, example = "3113") |
| | | @NotNull(message = "ä»åºç¼å·ä¸è½ä¸ºç©º") |
| | | private Long warehouseId; |
| | | |
| | | @Schema(description = "产åç¼å·", requiredMode = Schema.RequiredMode.REQUIRED, example = "3113") |
| | | @NotNull(message = "产åç¼å·ä¸è½ä¸ºç©º") |
| | | private Long productId; |
| | | |
| | | @Schema(description = "产ååä½åä½", requiredMode = Schema.RequiredMode.REQUIRED, example = "3113") |
| | | @NotNull(message = "产ååä½åä½ä¸è½ä¸ºç©º") |
| | | private Long productUnitId; |
| | | |
| | | @Schema(description = "产ååä»·", example = "100.00") |
| | | private BigDecimal productPrice; |
| | | |
| | | @Schema(description = "äº§åæ°é", requiredMode = Schema.RequiredMode.REQUIRED, example = "100.00") |
| | | @NotNull(message = "äº§åæ°éä¸è½ä¸ºç©º") |
| | | private BigDecimal count; |
| | | |
| | | @Schema(description = "ç¨çï¼ç¾åæ¯", example = "99.88") |
| | | private BigDecimal taxPercent; |
| | | |
| | | @Schema(description = "夿³¨", example = "é便") |
| | | private String remark; |
| | | |
| | | } |
| | | |
| | | } |
| ¶Ô±ÈÐÂÎļþ |
| | |
| | | package cn.iocoder.yudao.module.erp.controller.admin.purchase.vo.returns; |
| | | |
| | | import cn.iocoder.yudao.framework.common.pojo.PageParam; |
| | | import io.swagger.v3.oas.annotations.media.Schema; |
| | | import lombok.Data; |
| | | import lombok.EqualsAndHashCode; |
| | | import lombok.ToString; |
| | | import org.springframework.format.annotation.DateTimeFormat; |
| | | |
| | | import java.time.LocalDateTime; |
| | | |
| | | import static cn.iocoder.yudao.framework.common.util.date.DateUtils.FORMAT_YEAR_MONTH_DAY_HOUR_MINUTE_SECOND; |
| | | |
| | | @Schema(description = "管çåå° - ERP éè´éè´§å页 Request VO") |
| | | @Data |
| | | @EqualsAndHashCode(callSuper = true) |
| | | @ToString(callSuper = true) |
| | | public class ErpPurchaseReturnPageReqVO extends PageParam { |
| | | |
| | | public static final Integer REFUND_STATUS_NONE = 0; |
| | | public static final Integer REFUND_STATUS_PART = 1; |
| | | public static final Integer REFUND_STATUS_ALL = 2; |
| | | |
| | | @Schema(description = "éè´åç¼å·", example = "XS001") |
| | | private String no; |
| | | |
| | | @Schema(description = "ä¾åºåç¼å·", example = "1724") |
| | | private Long supplierId; |
| | | |
| | | @Schema(description = "éè´§æ¶é´") |
| | | @DateTimeFormat(pattern = FORMAT_YEAR_MONTH_DAY_HOUR_MINUTE_SECOND) |
| | | private LocalDateTime[] returnTime; |
| | | |
| | | @Schema(description = "夿³¨", example = "ä½ ç") |
| | | private String remark; |
| | | |
| | | @Schema(description = "éè´§ç¶æ", example = "2") |
| | | private Integer status; |
| | | |
| | | @Schema(description = "å建è
") |
| | | private String creator; |
| | | |
| | | @Schema(description = "产åç¼å·", example = "1") |
| | | private Long productId; |
| | | |
| | | @Schema(description = "ä»åºç¼å·", example = "1") |
| | | private Long warehouseId; |
| | | |
| | | @Schema(description = "ç»ç®è´¦å·ç¼å·", example = "1") |
| | | private Long accountId; |
| | | |
| | | @Schema(description = "éè´åå·", example = "1") |
| | | private String orderNo; |
| | | |
| | | @Schema(description = "鿬¾ç¶æ", example = "1") |
| | | private Integer refundStatus; |
| | | |
| | | @Schema(description = "æ¯å¦å¯é款", example = "true") |
| | | private Boolean refundEnable; // å¯¹åº refundStatus = [0, 1] |
| | | |
| | | } |
| ¶Ô±ÈÐÂÎļþ |
| | |
| | | package cn.iocoder.yudao.module.erp.controller.admin.purchase.vo.returns; |
| | | |
| | | import cn.idev.excel.annotation.ExcelIgnoreUnannotated; |
| | | import cn.idev.excel.annotation.ExcelProperty; |
| | | import io.swagger.v3.oas.annotations.media.Schema; |
| | | import jakarta.validation.constraints.NotNull; |
| | | import lombok.Data; |
| | | |
| | | import java.math.BigDecimal; |
| | | import java.time.LocalDateTime; |
| | | import java.util.List; |
| | | |
| | | @Schema(description = "管çåå° - ERP éè´éè´§ Response VO") |
| | | @Data |
| | | @ExcelIgnoreUnannotated |
| | | public class ErpPurchaseReturnRespVO { |
| | | |
| | | @Schema(description = "ç¼å·", requiredMode = Schema.RequiredMode.REQUIRED, example = "17386") |
| | | @ExcelProperty("ç¼å·") |
| | | private Long id; |
| | | |
| | | @Schema(description = "éè´§åç¼å·", requiredMode = Schema.RequiredMode.REQUIRED, example = "XS001") |
| | | @ExcelProperty("éè´§åç¼å·") |
| | | private String no; |
| | | |
| | | @Schema(description = "éè´§ç¶æ", requiredMode = Schema.RequiredMode.REQUIRED, example = "2") |
| | | @ExcelProperty("éè´§ç¶æ") |
| | | private Integer status; |
| | | |
| | | @Schema(description = "ä¾åºåç¼å·", requiredMode = Schema.RequiredMode.REQUIRED, example = "1724") |
| | | private Long supplierId; |
| | | @Schema(description = "ä¾åºååç§°", example = "èé") |
| | | @ExcelProperty("ä¾åºååç§°") |
| | | private String supplierName; |
| | | |
| | | @Schema(description = "ç»ç®è´¦æ·ç¼å·", requiredMode = Schema.RequiredMode.REQUIRED, example = "311.89") |
| | | @ExcelProperty("ç»ç®è´¦æ·ç¼å·") |
| | | private Long accountId; |
| | | |
| | | @Schema(description = "éè´§æ¶é´", requiredMode = Schema.RequiredMode.REQUIRED) |
| | | @ExcelProperty("éè´§æ¶é´") |
| | | private LocalDateTime returnTime; |
| | | |
| | | @Schema(description = "éè´è®¢åç¼å·", requiredMode = Schema.RequiredMode.REQUIRED, example = "17386") |
| | | private Long orderId; |
| | | @Schema(description = "éè´è®¢åå·", requiredMode = Schema.RequiredMode.REQUIRED, example = "XS001") |
| | | private String orderNo; |
| | | |
| | | @Schema(description = "å计æ°é", requiredMode = Schema.RequiredMode.REQUIRED, example = "15663") |
| | | @ExcelProperty("å计æ°é") |
| | | private BigDecimal totalCount; |
| | | @Schema(description = "æç»åè®¡ä»·æ ¼", requiredMode = Schema.RequiredMode.REQUIRED, example = "24906") |
| | | @ExcelProperty("æç»åè®¡ä»·æ ¼") |
| | | private BigDecimal totalPrice; |
| | | @Schema(description = "已鿬¾éé¢ï¼åä½ï¼å
", requiredMode = Schema.RequiredMode.REQUIRED, example = "7127") |
| | | private BigDecimal refundPrice; |
| | | |
| | | @Schema(description = "å计产åä»·æ ¼ï¼åä½ï¼å
", requiredMode = Schema.RequiredMode.REQUIRED, example = "7127") |
| | | private BigDecimal totalProductPrice; |
| | | |
| | | @Schema(description = "å计ç¨é¢ï¼åä½ï¼å
", requiredMode = Schema.RequiredMode.REQUIRED, example = "7127") |
| | | private BigDecimal totalTaxPrice; |
| | | |
| | | @Schema(description = "伿 çï¼ç¾åæ¯", requiredMode = Schema.RequiredMode.REQUIRED, example = "99.88") |
| | | private BigDecimal discountPercent; |
| | | |
| | | @Schema(description = "伿 éé¢ï¼åä½ï¼å
", requiredMode = Schema.RequiredMode.REQUIRED, example = "7127") |
| | | private BigDecimal discountPrice; |
| | | |
| | | @Schema(description = "å®ééé¢ï¼åä½ï¼å
", requiredMode = Schema.RequiredMode.REQUIRED, example = "7127") |
| | | private BigDecimal otherPrice; |
| | | |
| | | |
| | | @Schema(description = "夿³¨", example = "ä½ ç") |
| | | @ExcelProperty("夿³¨") |
| | | private String remark; |
| | | |
| | | @Schema(description = "å建人", example = "èé") |
| | | private String creator; |
| | | @Schema(description = "å建人åç§°", example = "èé") |
| | | private String creatorName; |
| | | |
| | | @Schema(description = "å建æ¶é´", requiredMode = Schema.RequiredMode.REQUIRED) |
| | | @ExcelProperty("å建æ¶é´") |
| | | private LocalDateTime createTime; |
| | | |
| | | @Schema(description = "é货项å表", requiredMode = Schema.RequiredMode.REQUIRED) |
| | | private List<Item> items; |
| | | |
| | | @Schema(description = "产åä¿¡æ¯", requiredMode = Schema.RequiredMode.REQUIRED) |
| | | @ExcelProperty("产åä¿¡æ¯") |
| | | private String productNames; |
| | | |
| | | @Data |
| | | public static class Item { |
| | | |
| | | @Schema(description = "é货项ç¼å·", example = "11756") |
| | | private Long id; |
| | | |
| | | @Schema(description = "éè´è®¢å项ç¼å·", requiredMode = Schema.RequiredMode.REQUIRED, example = "11756") |
| | | private Long orderItemId; |
| | | |
| | | @Schema(description = "ä»åºç¼å·", requiredMode = Schema.RequiredMode.REQUIRED, example = "3113") |
| | | private Long warehouseId; |
| | | |
| | | @Schema(description = "产åç¼å·", requiredMode = Schema.RequiredMode.REQUIRED, example = "3113") |
| | | private Long productId; |
| | | |
| | | @Schema(description = "产ååä½åä½", requiredMode = Schema.RequiredMode.REQUIRED, example = "3113") |
| | | private Long productUnitId; |
| | | |
| | | @Schema(description = "产ååä»·", example = "100.00") |
| | | private BigDecimal productPrice; |
| | | |
| | | @Schema(description = "äº§åæ°é", requiredMode = Schema.RequiredMode.REQUIRED, example = "100.00") |
| | | @NotNull(message = "äº§åæ°éä¸è½ä¸ºç©º") |
| | | private BigDecimal count; |
| | | |
| | | @Schema(description = "ç¨çï¼ç¾åæ¯", example = "99.88") |
| | | private BigDecimal taxPercent; |
| | | |
| | | @Schema(description = "ç¨é¢ï¼åä½ï¼å
", example = "100.00") |
| | | private BigDecimal taxPrice; |
| | | |
| | | @Schema(description = "夿³¨", example = "é便") |
| | | private String remark; |
| | | |
| | | // ========== å
³èåæ®µ ========== |
| | | |
| | | @Schema(description = "产ååç§°", requiredMode = Schema.RequiredMode.REQUIRED, example = "å·§å
å") |
| | | private String productName; |
| | | @Schema(description = "äº§åæ¡ç ", requiredMode = Schema.RequiredMode.REQUIRED, example = "A9985") |
| | | private String productBarCode; |
| | | @Schema(description = "产ååä½åç§°", requiredMode = Schema.RequiredMode.REQUIRED, example = "ç") |
| | | private String productUnitName; |
| | | |
| | | @Schema(description = "åºåæ°é", requiredMode = Schema.RequiredMode.REQUIRED, example = "100.00") |
| | | private BigDecimal stockCount; // è¯¥åæ®µä»
ä»
å¨â详æ
âåâç¼è¾âæ¶ä½¿ç¨ |
| | | |
| | | } |
| | | |
| | | } |
| ¶Ô±ÈÐÂÎļþ |
| | |
| | | package cn.iocoder.yudao.module.erp.controller.admin.purchase.vo.returns; |
| | | |
| | | import io.swagger.v3.oas.annotations.media.Schema; |
| | | import jakarta.validation.constraints.NotNull; |
| | | import lombok.Data; |
| | | |
| | | import java.math.BigDecimal; |
| | | import java.time.LocalDateTime; |
| | | import java.util.List; |
| | | |
| | | @Schema(description = "管çåå° - ERP éè´éè´§æ°å¢/ä¿®æ¹ Request VO") |
| | | @Data |
| | | public class ErpPurchaseReturnSaveReqVO { |
| | | |
| | | @Schema(description = "ç¼å·", requiredMode = Schema.RequiredMode.REQUIRED, example = "17386") |
| | | private Long id; |
| | | |
| | | @Schema(description = "ç»ç®è´¦æ·ç¼å·", example = "31189") |
| | | private Long accountId; |
| | | |
| | | @Schema(description = "éè´§æ¶é´", requiredMode = Schema.RequiredMode.REQUIRED) |
| | | @NotNull(message = "éè´§æ¶é´ä¸è½ä¸ºç©º") |
| | | private LocalDateTime returnTime; |
| | | |
| | | @Schema(description = "éè´è®¢åç¼å·", requiredMode = Schema.RequiredMode.REQUIRED, example = "17386") |
| | | @NotNull(message = "éè´è®¢åç¼å·ä¸è½ä¸ºç©º") |
| | | private Long orderId; |
| | | |
| | | @Schema(description = "伿 çï¼ç¾åæ¯", requiredMode = Schema.RequiredMode.REQUIRED, example = "99.88") |
| | | private BigDecimal discountPercent; |
| | | |
| | | @Schema(description = "å
¶å®éé¢ï¼åä½ï¼å
", example = "7127") |
| | | private BigDecimal otherPrice; |
| | | |
| | | |
| | | @Schema(description = "夿³¨", example = "ä½ ç") |
| | | private String remark; |
| | | |
| | | @Schema(description = "éè´§æ¸
åå表") |
| | | private List<Item> items; |
| | | |
| | | @Data |
| | | public static class Item { |
| | | |
| | | @Schema(description = "é货项ç¼å·", example = "11756") |
| | | private Long id; |
| | | |
| | | @Schema(description = "éè´è®¢å项ç¼å·", requiredMode = Schema.RequiredMode.REQUIRED, example = "11756") |
| | | @NotNull(message = "éè´è®¢å项ç¼å·ä¸è½ä¸ºç©º") |
| | | private Long orderItemId; |
| | | |
| | | @Schema(description = "ä»åºç¼å·", requiredMode = Schema.RequiredMode.REQUIRED, example = "3113") |
| | | @NotNull(message = "ä»åºç¼å·ä¸è½ä¸ºç©º") |
| | | private Long warehouseId; |
| | | |
| | | @Schema(description = "产åç¼å·", requiredMode = Schema.RequiredMode.REQUIRED, example = "3113") |
| | | @NotNull(message = "产åç¼å·ä¸è½ä¸ºç©º") |
| | | private Long productId; |
| | | |
| | | @Schema(description = "产ååä½åä½", requiredMode = Schema.RequiredMode.REQUIRED, example = "3113") |
| | | @NotNull(message = "产ååä½åä½ä¸è½ä¸ºç©º") |
| | | private Long productUnitId; |
| | | |
| | | @Schema(description = "产ååä»·", example = "100.00") |
| | | private BigDecimal productPrice; |
| | | |
| | | @Schema(description = "äº§åæ°é", requiredMode = Schema.RequiredMode.REQUIRED, example = "100.00") |
| | | @NotNull(message = "äº§åæ°éä¸è½ä¸ºç©º") |
| | | private BigDecimal count; |
| | | |
| | | @Schema(description = "ç¨çï¼ç¾åæ¯", example = "99.88") |
| | | private BigDecimal taxPercent; |
| | | |
| | | @Schema(description = "夿³¨", example = "é便") |
| | | private String remark; |
| | | |
| | | } |
| | | |
| | | } |
| | |
| | | |
| | | import cn.hutool.core.date.LocalDateTimeUtil; |
| | | import cn.iocoder.yudao.framework.common.pojo.CommonResult; |
| | | import cn.iocoder.yudao.framework.common.pojo.PageResult; |
| | | import cn.iocoder.yudao.framework.common.util.date.LocalDateTimeUtils; |
| | | import cn.iocoder.yudao.module.erp.controller.admin.statistics.vo.purchase.ErpPurchasePriceAnalysisRespVO; |
| | | import cn.iocoder.yudao.module.erp.controller.admin.statistics.vo.purchase.ErpPurchaseStatisticsReqVO; |
| | | import cn.iocoder.yudao.module.erp.controller.admin.statistics.vo.purchase.ErpPurchaseSummaryRespVO; |
| | | import cn.iocoder.yudao.module.erp.controller.admin.statistics.vo.purchase.ErpPurchaseSupplierStatisticsRespVO; |
| | | import cn.iocoder.yudao.module.erp.controller.admin.statistics.vo.purchase.ErpPurchaseTimeSummaryRespVO; |
| | | import cn.iocoder.yudao.module.erp.controller.admin.statistics.vo.purchase.ErpPurchaseUncompletedOrderRespVO; |
| | | import cn.iocoder.yudao.module.erp.service.statistics.ErpPurchaseStatisticsService; |
| | | import io.swagger.v3.oas.annotations.Operation; |
| | | import io.swagger.v3.oas.annotations.Parameter; |
| | | import io.swagger.v3.oas.annotations.tags.Tag; |
| | | import jakarta.annotation.Resource; |
| | | import jakarta.validation.Valid; |
| | | import org.springframework.security.access.prepost.PreAuthorize; |
| | | import org.springframework.validation.annotation.Validated; |
| | | import org.springframework.web.bind.annotation.GetMapping; |
| | |
| | | LocalDateTime yesterday = LocalDateTimeUtils.getYesterday(); |
| | | LocalDateTime month = LocalDateTimeUtils.getMonth(); |
| | | LocalDateTime year = LocalDateTimeUtils.getYear(); |
| | | ErpPurchaseSummaryRespVO summary = new ErpPurchaseSummaryRespVO() |
| | | // 1.1 æ¦è§ï¼è®¢å / å
¥åº / éè´§çæ»æ°ä¸æ»éé¢ |
| | | ErpPurchaseSummaryRespVO summary = purchaseStatisticsService.getPurchaseSummary(); |
| | | // 1.2 é¦é¡µçæ¿ï¼ä»æ¥ / æ¨æ¥ / æ¬æ / ä»å¹´éè´éé¢ï¼å¤ç¨åä¸ååºï¼é¿å
䏤奿¥å£ï¼ |
| | | return success(summary |
| | | .setTodayPrice(purchaseStatisticsService.getPurchasePrice(today, null)) |
| | | .setYesterdayPrice(purchaseStatisticsService.getPurchasePrice(yesterday, today)) |
| | | .setMonthPrice(purchaseStatisticsService.getPurchasePrice(month, null)) |
| | | .setYearPrice(purchaseStatisticsService.getPurchasePrice(year, null)); |
| | | return success(summary); |
| | | .setYearPrice(purchaseStatisticsService.getPurchasePrice(year, null))); |
| | | } |
| | | |
| | | @GetMapping("/time-summary") |
| | |
| | | return success(summaryList); |
| | | } |
| | | |
| | | @GetMapping("/supplier") |
| | | @Operation(summary = "è·å¾ä¾åºåä¾è´§ç»è®¡") |
| | | @PreAuthorize("@ss.hasPermission('erp:purchase-statistics:query')") |
| | | public CommonResult<PageResult<ErpPurchaseSupplierStatisticsRespVO>> getSupplierStatistics( |
| | | @Valid ErpPurchaseStatisticsReqVO reqVO) { |
| | | return success(purchaseStatisticsService.getSupplierStatistics(reqVO)); |
| | | } |
| | | |
| | | @GetMapping("/price") |
| | | @Operation(summary = "è·å¾éè´ä»·æ ¼åæ") |
| | | @PreAuthorize("@ss.hasPermission('erp:purchase-statistics:query')") |
| | | public CommonResult<PageResult<ErpPurchasePriceAnalysisRespVO>> getPriceAnalysis( |
| | | @Valid ErpPurchaseStatisticsReqVO reqVO) { |
| | | return success(purchaseStatisticsService.getPriceAnalysis(reqVO)); |
| | | } |
| | | |
| | | @GetMapping("/uncompleted") |
| | | @Operation(summary = "è·å¾æªå®æéè´è®¢åè·è¸ª") |
| | | @PreAuthorize("@ss.hasPermission('erp:purchase-statistics:query')") |
| | | public CommonResult<PageResult<ErpPurchaseUncompletedOrderRespVO>> getUncompletedOrders( |
| | | @Valid ErpPurchaseStatisticsReqVO reqVO) { |
| | | return success(purchaseStatisticsService.getUncompletedOrders(reqVO)); |
| | | } |
| | | |
| | | } |
| ¶Ô±ÈÐÂÎļþ |
| | |
| | | package cn.iocoder.yudao.module.erp.controller.admin.statistics.vo.purchase; |
| | | |
| | | import io.swagger.v3.oas.annotations.media.Schema; |
| | | import lombok.Data; |
| | | |
| | | import java.math.BigDecimal; |
| | | |
| | | @Schema(description = "管çåå° - ERP éè´ä»·æ ¼åæ Response VO") |
| | | @Data |
| | | public class ErpPurchasePriceAnalysisRespVO { |
| | | |
| | | @Schema(description = "产åç¼å·ï¼MDM ç©æç¼å·ï¼", example = "1024") |
| | | private Long productId; |
| | | |
| | | @Schema(description = "产ååç§°", example = "å
è§èºæ ") |
| | | private String productName; |
| | | |
| | | @Schema(description = "äº§åæ¡ç ", example = "6901234567890") |
| | | private String productBarCode; |
| | | |
| | | @Schema(description = "å¹³åä»·æ ¼", example = "12.50") |
| | | private BigDecimal avgPrice; |
| | | |
| | | @Schema(description = "æä½ä»·æ ¼", example = "10.00") |
| | | private BigDecimal minPrice; |
| | | |
| | | @Schema(description = "æé«ä»·æ ¼", example = "15.00") |
| | | private BigDecimal maxPrice; |
| | | |
| | | @Schema(description = "æè¿ä¸æ¬¡éè´ä»·æ ¼", example = "13.00") |
| | | private BigDecimal latestPrice; |
| | | |
| | | @Schema(description = "ä»·æ ¼ååçï¼æè¿ä»·æ ¼ç¸å¯¹å¹³åä»·æ ¼ï¼ç¾åæ¯ï¼", example = "4.00") |
| | | private BigDecimal priceChangeRate; |
| | | |
| | | } |
| ¶Ô±ÈÐÂÎļþ |
| | |
| | | package cn.iocoder.yudao.module.erp.controller.admin.statistics.vo.purchase; |
| | | |
| | | import cn.iocoder.yudao.framework.common.pojo.PageParam; |
| | | import lombok.Data; |
| | | import lombok.EqualsAndHashCode; |
| | | import org.springframework.format.annotation.DateTimeFormat; |
| | | |
| | | import java.time.LocalDateTime; |
| | | |
| | | import static cn.iocoder.yudao.framework.common.util.date.DateUtils.FORMAT_YEAR_MONTH_DAY_HOUR_MINUTE_SECOND; |
| | | |
| | | /** |
| | | * ERP éè´ç»è®¡æ¥è¯¢ Request VO |
| | | * |
| | | * ä¾åºåä¾è´§ç»è®¡ãä»·æ ¼åæãæªå®æè®¢åè·è¸ªä¸ä¸ªé¡µé¢å
±ç¨ |
| | | * |
| | | * @author è¶
级管çå |
| | | */ |
| | | @Data |
| | | @EqualsAndHashCode(callSuper = true) |
| | | public class ErpPurchaseStatisticsReqVO extends PageParam { |
| | | |
| | | /** |
| | | * ä¾åºåç¼å· |
| | | */ |
| | | private Long supplierId; |
| | | |
| | | /** |
| | | * 产åç¼å·ï¼MDM ç©æç¼å·ï¼ |
| | | */ |
| | | private Long productId; |
| | | |
| | | /** |
| | | * 订åå·ï¼æ¨¡ç³å¹é
ï¼ |
| | | */ |
| | | private String orderNo; |
| | | |
| | | /** |
| | | * è®¢åæ¶é´èå´ |
| | | */ |
| | | @DateTimeFormat(pattern = FORMAT_YEAR_MONTH_DAY_HOUR_MINUTE_SECOND) |
| | | private LocalDateTime[] orderTime; |
| | | |
| | | } |
| | |
| | | @Schema(description = "ä»å¹´éè´éé¢", requiredMode = Schema.RequiredMode.REQUIRED, example = "88888") |
| | | private BigDecimal yearPrice; |
| | | |
| | | // ==================== éè´ç»è®¡é¡µï¼æ±æ»å¡çï¼ ==================== |
| | | |
| | | @Schema(description = "æ»è®¢åæ°", example = "10") |
| | | private Long totalOrderCount; |
| | | |
| | | @Schema(description = "æ»è®¢åéé¢", example = "1024.00") |
| | | private BigDecimal totalOrderAmount; |
| | | |
| | | @Schema(description = "æ»å
¥åºæ°", example = "8") |
| | | private Long totalInCount; |
| | | |
| | | @Schema(description = "æ»å
¥åºéé¢", example = "888.00") |
| | | private BigDecimal totalInAmount; |
| | | |
| | | @Schema(description = "æ»éè´§æ°", example = "1") |
| | | private Long totalReturnCount; |
| | | |
| | | @Schema(description = "æ»éè´§éé¢", example = "100.00") |
| | | private BigDecimal totalReturnAmount; |
| | | |
| | | } |
| ¶Ô±ÈÐÂÎļþ |
| | |
| | | package cn.iocoder.yudao.module.erp.controller.admin.statistics.vo.purchase; |
| | | |
| | | import io.swagger.v3.oas.annotations.media.Schema; |
| | | import lombok.Data; |
| | | |
| | | import java.math.BigDecimal; |
| | | |
| | | @Schema(description = "管çåå° - ERP ä¾åºåä¾è´§ç»è®¡ Response VO") |
| | | @Data |
| | | public class ErpPurchaseSupplierStatisticsRespVO { |
| | | |
| | | @Schema(description = "ä¾åºåç¼å·", example = "1024") |
| | | private Long supplierId; |
| | | |
| | | @Schema(description = "ä¾åºååç§°", example = "è¯åäºé") |
| | | private String supplierName; |
| | | |
| | | @Schema(description = "è®¢åæ°", example = "10") |
| | | private Long orderCount; |
| | | |
| | | @Schema(description = "订åéé¢", example = "1024.00") |
| | | private BigDecimal orderAmount; |
| | | |
| | | @Schema(description = "å
¥åºåæ°", example = "8") |
| | | private Long inCount; |
| | | |
| | | @Schema(description = "å
¥åºéé¢", example = "888.00") |
| | | private BigDecimal inAmount; |
| | | |
| | | @Schema(description = "éè´§åæ°", example = "1") |
| | | private Long returnCount; |
| | | |
| | | @Schema(description = "éè´§éé¢", example = "100.00") |
| | | private BigDecimal returnAmount; |
| | | |
| | | } |
| ¶Ô±ÈÐÂÎļþ |
| | |
| | | package cn.iocoder.yudao.module.erp.controller.admin.statistics.vo.purchase; |
| | | |
| | | import io.swagger.v3.oas.annotations.media.Schema; |
| | | import lombok.Data; |
| | | |
| | | import java.math.BigDecimal; |
| | | import java.time.LocalDateTime; |
| | | |
| | | @Schema(description = "管çåå° - ERP æªå®æéè´è®¢åè·è¸ª Response VO") |
| | | @Data |
| | | public class ErpPurchaseUncompletedOrderRespVO { |
| | | |
| | | @Schema(description = "订åç¼å·", example = "1024") |
| | | private Long orderId; |
| | | |
| | | @Schema(description = "订åå·", example = "CGDD20261103000001") |
| | | private String orderNo; |
| | | |
| | | @Schema(description = "ä¾åºååç§°", example = "è¯åäºé") |
| | | private String supplierName; |
| | | |
| | | @Schema(description = "è®¢åæ¶é´") |
| | | private LocalDateTime orderTime; |
| | | |
| | | @Schema(description = "产ååç§°ï¼å¤ä¸ªç¨éå·æ¼æ¥ï¼", example = "å
è§èºæ ï¼å«ç") |
| | | private String productNames; |
| | | |
| | | @Schema(description = "订åéé¢", example = "1024.00") |
| | | private BigDecimal orderAmount; |
| | | |
| | | @Schema(description = "å·²å
¥åºéé¢", example = "512.00") |
| | | private BigDecimal inAmount; |
| | | |
| | | @Schema(description = "æªå®æéé¢", example = "512.00") |
| | | private BigDecimal uncompletedAmount; |
| | | |
| | | @Schema(description = "è¶
æå¤©æ°ï¼æä¸åå 30 天交æä¼°ç®ï¼æªè¶
æä¸º 0ï¼", example = "3") |
| | | private Integer daysOverdue; |
| | | |
| | | } |
| ¶Ô±ÈÐÂÎļþ |
| | |
| | | package cn.iocoder.yudao.module.erp.dal.dataobject.purchase; |
| | | |
| | | import cn.iocoder.yudao.framework.mybatis.core.dataobject.BaseDO; |
| | | import cn.iocoder.yudao.module.erp.dal.dataobject.finance.ErpAccountDO; |
| | | import com.baomidou.mybatisplus.annotation.KeySequence; |
| | | import com.baomidou.mybatisplus.annotation.TableId; |
| | | import com.baomidou.mybatisplus.annotation.TableName; |
| | | import lombok.*; |
| | | |
| | | import java.math.BigDecimal; |
| | | import java.time.LocalDateTime; |
| | | |
| | | /** |
| | | * ERP éè´å
¥åº DO |
| | | * |
| | | * @author èéæºç |
| | | */ |
| | | @TableName(value = "erp_purchase_in") |
| | | @KeySequence("erp_purchase_in_seq") // ç¨äº OracleãPostgreSQLãKingbaseãDB2ãH2 æ°æ®åºç主é®èªå¢ãå¦ææ¯ MySQL çæ°æ®åºï¼å¯ä¸åã |
| | | @Data |
| | | @EqualsAndHashCode(callSuper = true) |
| | | @ToString(callSuper = true) |
| | | @Builder |
| | | @NoArgsConstructor |
| | | @AllArgsConstructor |
| | | public class ErpPurchaseInDO extends BaseDO { |
| | | |
| | | /** |
| | | * ç¼å· |
| | | */ |
| | | @TableId |
| | | private Long id; |
| | | /** |
| | | * éè´å
¥åºåå· |
| | | */ |
| | | private String no; |
| | | /** |
| | | * å
¥åºç¶æ |
| | | * |
| | | * æä¸¾ {@link cn.iocoder.yudao.module.erp.enums.ErpAuditStatus} |
| | | */ |
| | | private Integer status; |
| | | /** |
| | | * ä¾åºåç¼å· |
| | | * |
| | | * å
³è {@link ErpSupplierDO#getId()} |
| | | */ |
| | | private Long supplierId; |
| | | /** |
| | | * ç»ç®è´¦æ·ç¼å· |
| | | * |
| | | * å
³è {@link ErpAccountDO#getId()} |
| | | */ |
| | | private Long accountId; |
| | | /** |
| | | * å
¥åºæ¶é´ |
| | | */ |
| | | private LocalDateTime inTime; |
| | | |
| | | /** |
| | | * éè´è®¢åç¼å· |
| | | * |
| | | * å
³è {@link ErpPurchaseOrderDO#getId()} |
| | | */ |
| | | private Long orderId; |
| | | /** |
| | | * éè´è®¢åå· |
| | | * |
| | | * åä½ {@link ErpPurchaseOrderDO#getNo()} |
| | | */ |
| | | private String orderNo; |
| | | |
| | | /** |
| | | * å计æ°é |
| | | */ |
| | | private BigDecimal totalCount; |
| | | /** |
| | | * æç»åè®¡ä»·æ ¼ï¼åä½ï¼å
|
| | | * |
| | | * totalPrice = totalProductPrice + totalTaxPrice - discountPrice + otherPrice |
| | | */ |
| | | private BigDecimal totalPrice; |
| | | /** |
| | | * å·²æ¯ä»éé¢ï¼åä½ï¼å
|
| | | * |
| | | * ç®çï¼å {@link cn.iocoder.yudao.module.erp.dal.dataobject.finance.ErpFinancePaymentDO} ç»åï¼è®°å½å·²æ¯ä»éé¢ |
| | | */ |
| | | private BigDecimal paymentPrice; |
| | | |
| | | /** |
| | | * å计产åä»·æ ¼ï¼åä½ï¼å
|
| | | */ |
| | | private BigDecimal totalProductPrice; |
| | | /** |
| | | * å计ç¨é¢ï¼åä½ï¼å
|
| | | */ |
| | | private BigDecimal totalTaxPrice; |
| | | /** |
| | | * 伿 çï¼ç¾åæ¯ |
| | | */ |
| | | private BigDecimal discountPercent; |
| | | /** |
| | | * 伿 éé¢ï¼åä½ï¼å
|
| | | * |
| | | * discountPrice = (totalProductPrice + totalTaxPrice) * discountPercent |
| | | */ |
| | | private BigDecimal discountPrice; |
| | | /** |
| | | * å
¶å®éé¢ï¼åä½ï¼å
|
| | | */ |
| | | private BigDecimal otherPrice; |
| | | |
| | | /** |
| | | * 夿³¨ |
| | | */ |
| | | private String remark; |
| | | |
| | | } |
| ¶Ô±ÈÐÂÎļþ |
| | |
| | | package cn.iocoder.yudao.module.erp.dal.dataobject.purchase; |
| | | |
| | | import cn.iocoder.yudao.framework.mybatis.core.dataobject.BaseDO; |
| | | import com.baomidou.mybatisplus.annotation.KeySequence; |
| | | import com.baomidou.mybatisplus.annotation.TableId; |
| | | import com.baomidou.mybatisplus.annotation.TableName; |
| | | import lombok.*; |
| | | |
| | | import java.math.BigDecimal; |
| | | |
| | | /** |
| | | * ERP éè´å
¥åºé¡¹ DO |
| | | * |
| | | * @author èéæºç |
| | | */ |
| | | @TableName("erp_purchase_in_items") |
| | | @KeySequence("erp_purchase_in_items_seq") // ç¨äº OracleãPostgreSQLãKingbaseãDB2ãH2 æ°æ®åºç主é®èªå¢ãå¦ææ¯ MySQL çæ°æ®åºï¼å¯ä¸åã |
| | | @Data |
| | | @EqualsAndHashCode(callSuper = true) |
| | | @ToString(callSuper = true) |
| | | @Builder |
| | | @NoArgsConstructor |
| | | @AllArgsConstructor |
| | | public class ErpPurchaseInItemDO extends BaseDO { |
| | | |
| | | /** |
| | | * ç¼å· |
| | | */ |
| | | @TableId |
| | | private Long id; |
| | | /** |
| | | * éè´å
¥åºç¼å· |
| | | * |
| | | * å
³è {@link ErpPurchaseInDO##getId()} |
| | | */ |
| | | private Long inId; |
| | | /** |
| | | * éè´è®¢å项ç¼å· |
| | | * |
| | | * å
³è {@link ErpPurchaseOrderItemDO#getId()} |
| | | * ç®çï¼æ¹ä¾¿æ´æ°å
³èçéè´è®¢å项çå
¥åºæ°é |
| | | */ |
| | | private Long orderItemId; |
| | | /** |
| | | * ä»åºç¼å· |
| | | * |
| | | * å
³è MES ä»åºç¼å· |
| | | */ |
| | | private Long warehouseId; |
| | | /** |
| | | * 产åç¼å· |
| | | * |
| | | * å
³è MDM ç©æç¼å· |
| | | */ |
| | | private Long productId; |
| | | /** |
| | | * 产ååä½åä½ |
| | | * |
| | | * åä½ MDM ç©æè®¡éåä½ç¼å· |
| | | */ |
| | | private Long productUnitId; |
| | | |
| | | /** |
| | | * 产ååä½åä»·ï¼åä½ï¼å
|
| | | */ |
| | | private BigDecimal productPrice; |
| | | /** |
| | | * æ°é |
| | | */ |
| | | private BigDecimal count; |
| | | /** |
| | | * æ»ä»·ï¼åä½ï¼å
|
| | | * |
| | | * totalPrice = productPrice * count |
| | | */ |
| | | private BigDecimal totalPrice; |
| | | /** |
| | | * ç¨çï¼ç¾åæ¯ |
| | | */ |
| | | private BigDecimal taxPercent; |
| | | /** |
| | | * ç¨é¢ï¼åä½ï¼å
|
| | | * |
| | | * taxPrice = totalPrice * taxPercent |
| | | */ |
| | | private BigDecimal taxPrice; |
| | | |
| | | /** |
| | | * 夿³¨ |
| | | */ |
| | | private String remark; |
| | | |
| | | } |
| ¶Ô±ÈÐÂÎļþ |
| | |
| | | package cn.iocoder.yudao.module.erp.dal.dataobject.purchase; |
| | | |
| | | import cn.iocoder.yudao.framework.mybatis.core.dataobject.BaseDO; |
| | | import cn.iocoder.yudao.module.erp.dal.dataobject.finance.ErpAccountDO; |
| | | import com.baomidou.mybatisplus.annotation.KeySequence; |
| | | import com.baomidou.mybatisplus.annotation.TableId; |
| | | import com.baomidou.mybatisplus.annotation.TableName; |
| | | import lombok.*; |
| | | |
| | | import java.math.BigDecimal; |
| | | import java.time.LocalDateTime; |
| | | |
| | | /** |
| | | * ERP éè´éè´§ DO |
| | | * |
| | | * @author èéæºç |
| | | */ |
| | | @TableName(value = "erp_purchase_return") |
| | | @KeySequence("erp_purchase_return_seq") // ç¨äº OracleãPostgreSQLãKingbaseãDB2ãH2 æ°æ®åºç主é®èªå¢ãå¦ææ¯ MySQL çæ°æ®åºï¼å¯ä¸åã |
| | | @Data |
| | | @EqualsAndHashCode(callSuper = true) |
| | | @ToString(callSuper = true) |
| | | @Builder |
| | | @NoArgsConstructor |
| | | @AllArgsConstructor |
| | | public class ErpPurchaseReturnDO extends BaseDO { |
| | | |
| | | /** |
| | | * ç¼å· |
| | | */ |
| | | @TableId |
| | | private Long id; |
| | | /** |
| | | * éè´éè´§åå· |
| | | */ |
| | | private String no; |
| | | /** |
| | | * éè´§ç¶æ |
| | | * |
| | | * æä¸¾ {@link cn.iocoder.yudao.module.erp.enums.ErpAuditStatus} |
| | | */ |
| | | private Integer status; |
| | | /** |
| | | * ä¾åºåç¼å· |
| | | * |
| | | * å
³è {@link ErpSupplierDO#getId()} |
| | | */ |
| | | private Long supplierId; |
| | | /** |
| | | * ç»ç®è´¦æ·ç¼å· |
| | | * |
| | | * å
³è {@link ErpAccountDO#getId()} |
| | | */ |
| | | private Long accountId; |
| | | /** |
| | | * éè´§æ¶é´ |
| | | */ |
| | | private LocalDateTime returnTime; |
| | | |
| | | /** |
| | | * éè´è®¢åç¼å· |
| | | * |
| | | * å
³è {@link ErpPurchaseOrderDO#getId()} |
| | | */ |
| | | private Long orderId; |
| | | /** |
| | | * éè´è®¢åå· |
| | | * |
| | | * åä½ {@link ErpPurchaseOrderDO#getNo()} |
| | | */ |
| | | private String orderNo; |
| | | |
| | | /** |
| | | * å计æ°é |
| | | */ |
| | | private BigDecimal totalCount; |
| | | /** |
| | | * æç»åè®¡ä»·æ ¼ï¼åä½ï¼å
|
| | | * |
| | | * totalPrice = totalProductPrice + totalTaxPrice - discountPrice + otherPrice |
| | | */ |
| | | private BigDecimal totalPrice; |
| | | /** |
| | | * 已鿬¾éé¢ï¼åä½ï¼å
|
| | | * |
| | | * ç®çï¼å {@link cn.iocoder.yudao.module.erp.dal.dataobject.finance.ErpFinancePaymentDO} ç»åï¼è®°å½å·²æ¯ä»éé¢ |
| | | */ |
| | | private BigDecimal refundPrice; |
| | | |
| | | /** |
| | | * å计产åä»·æ ¼ï¼åä½ï¼å
|
| | | */ |
| | | private BigDecimal totalProductPrice; |
| | | /** |
| | | * å计ç¨é¢ï¼åä½ï¼å
|
| | | */ |
| | | private BigDecimal totalTaxPrice; |
| | | /** |
| | | * 伿 çï¼ç¾åæ¯ |
| | | */ |
| | | private BigDecimal discountPercent; |
| | | /** |
| | | * 伿 éé¢ï¼åä½ï¼å
|
| | | * |
| | | * discountPrice = (totalProductPrice + totalTaxPrice) * discountPercent |
| | | */ |
| | | private BigDecimal discountPrice; |
| | | /** |
| | | * å
¶å®éé¢ï¼åä½ï¼å
|
| | | */ |
| | | private BigDecimal otherPrice; |
| | | |
| | | /** |
| | | * 夿³¨ |
| | | */ |
| | | private String remark; |
| | | |
| | | } |
| ¶Ô±ÈÐÂÎļþ |
| | |
| | | package cn.iocoder.yudao.module.erp.dal.dataobject.purchase; |
| | | |
| | | import cn.iocoder.yudao.framework.mybatis.core.dataobject.BaseDO; |
| | | import com.baomidou.mybatisplus.annotation.KeySequence; |
| | | import com.baomidou.mybatisplus.annotation.TableId; |
| | | import com.baomidou.mybatisplus.annotation.TableName; |
| | | import lombok.*; |
| | | |
| | | import java.math.BigDecimal; |
| | | |
| | | /** |
| | | * ERP éè´é货项 DO |
| | | * |
| | | * @author èéæºç |
| | | */ |
| | | @TableName("erp_purchase_return_items") |
| | | @KeySequence("erp_purchase_return_items_seq") // ç¨äº OracleãPostgreSQLãKingbaseãDB2ãH2 æ°æ®åºç主é®èªå¢ãå¦ææ¯ MySQL çæ°æ®åºï¼å¯ä¸åã |
| | | @Data |
| | | @EqualsAndHashCode(callSuper = true) |
| | | @ToString(callSuper = true) |
| | | @Builder |
| | | @NoArgsConstructor |
| | | @AllArgsConstructor |
| | | public class ErpPurchaseReturnItemDO extends BaseDO { |
| | | |
| | | /** |
| | | * ç¼å· |
| | | */ |
| | | @TableId |
| | | private Long id; |
| | | /** |
| | | * éè´éè´§ç¼å· |
| | | * |
| | | * å
³è {@link ErpPurchaseReturnDO##getId()} |
| | | */ |
| | | private Long returnId; |
| | | /** |
| | | * éè´è®¢å项ç¼å· |
| | | * |
| | | * å
³è {@link ErpPurchaseOrderItemDO#getId()} |
| | | * ç®çï¼æ¹ä¾¿æ´æ°å
³èçéè´è®¢å项çéè´§æ°é |
| | | */ |
| | | private Long orderItemId; |
| | | /** |
| | | * ä»åºç¼å· |
| | | * |
| | | * å
³è MES ä»åºç¼å· |
| | | */ |
| | | private Long warehouseId; |
| | | /** |
| | | * 产åç¼å· |
| | | * |
| | | * å
³è MDM ç©æç¼å· |
| | | */ |
| | | private Long productId; |
| | | /** |
| | | * 产ååä½åä½ |
| | | * |
| | | * åä½ MDM ç©æè®¡éåä½ç¼å· |
| | | */ |
| | | private Long productUnitId; |
| | | |
| | | /** |
| | | * 产ååä½åä»·ï¼åä½ï¼å
|
| | | */ |
| | | private BigDecimal productPrice; |
| | | /** |
| | | * æ°é |
| | | */ |
| | | private BigDecimal count; |
| | | /** |
| | | * æ»ä»·ï¼åä½ï¼å
|
| | | * |
| | | * totalPrice = productPrice * count |
| | | */ |
| | | private BigDecimal totalPrice; |
| | | /** |
| | | * ç¨çï¼ç¾åæ¯ |
| | | */ |
| | | private BigDecimal taxPercent; |
| | | /** |
| | | * ç¨é¢ï¼åä½ï¼å
|
| | | * |
| | | * taxPrice = totalPrice * taxPercent |
| | | */ |
| | | private BigDecimal taxPrice; |
| | | |
| | | /** |
| | | * 夿³¨ |
| | | */ |
| | | private String remark; |
| | | |
| | | } |
| ¶Ô±ÈÐÂÎļþ |
| | |
| | | package cn.iocoder.yudao.module.erp.dal.mysql.purchase; |
| | | |
| | | import cn.hutool.core.collection.CollUtil; |
| | | import cn.iocoder.yudao.framework.mybatis.core.mapper.BaseMapperX; |
| | | import cn.iocoder.yudao.module.erp.dal.dataobject.purchase.ErpPurchaseInItemDO; |
| | | import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper; |
| | | import org.apache.ibatis.annotations.Mapper; |
| | | |
| | | import java.math.BigDecimal; |
| | | import java.util.Collection; |
| | | import java.util.Collections; |
| | | import java.util.List; |
| | | import java.util.Map; |
| | | |
| | | import static cn.iocoder.yudao.framework.common.util.collection.CollectionUtils.convertMap; |
| | | |
| | | /** |
| | | * ERP éè´å
¥åºé¡¹ Mapper |
| | | * |
| | | * @author èéæºç |
| | | */ |
| | | @Mapper |
| | | public interface ErpPurchaseInItemMapper extends BaseMapperX<ErpPurchaseInItemDO> { |
| | | |
| | | default List<ErpPurchaseInItemDO> selectListByInId(Long inId) { |
| | | return selectList(ErpPurchaseInItemDO::getInId, inId); |
| | | } |
| | | |
| | | default List<ErpPurchaseInItemDO> selectListByInIds(Collection<Long> inIds) { |
| | | return selectList(ErpPurchaseInItemDO::getInId, inIds); |
| | | } |
| | | |
| | | default int deleteByInId(Long inId) { |
| | | return delete(ErpPurchaseInItemDO::getInId, inId); |
| | | } |
| | | |
| | | /** |
| | | * åºäºéè´è®¢åç¼å·ï¼æ¥è¯¢æ¯ä¸ªéè´è®¢å项çå
¥åºæ°éä¹å |
| | | * |
| | | * @param inIds å
¥åºè®¢å项ç¼å·æ°ç» |
| | | * @return keyï¼éè´è®¢å项ç¼å·ï¼valueï¼å
¥åºæ°éä¹å |
| | | */ |
| | | default Map<Long, BigDecimal> selectOrderItemCountSumMapByInIds(Collection<Long> inIds) { |
| | | if (CollUtil.isEmpty(inIds)) { |
| | | return Collections.emptyMap(); |
| | | } |
| | | // SQL sum æ¥è¯¢ |
| | | List<Map<String, Object>> result = selectMaps(new QueryWrapper<ErpPurchaseInItemDO>() |
| | | .select("order_item_id, SUM(count) AS sum_count") |
| | | .groupBy("order_item_id") |
| | | .in("in_id", inIds)); |
| | | // è·å¾æ°é |
| | | return convertMap(result, obj -> (Long) obj.get("order_item_id"), obj -> (BigDecimal) obj.get("sum_count")); |
| | | } |
| | | |
| | | } |
| ¶Ô±ÈÐÂÎļþ |
| | |
| | | package cn.iocoder.yudao.module.erp.dal.mysql.purchase; |
| | | |
| | | |
| | | import cn.iocoder.yudao.framework.common.pojo.PageResult; |
| | | import cn.iocoder.yudao.framework.mybatis.core.mapper.BaseMapperX; |
| | | import cn.iocoder.yudao.framework.mybatis.core.query.MPJLambdaWrapperX; |
| | | import cn.iocoder.yudao.module.erp.controller.admin.purchase.vo.in.ErpPurchaseInPageReqVO; |
| | | import cn.iocoder.yudao.module.erp.dal.dataobject.purchase.ErpPurchaseInDO; |
| | | import cn.iocoder.yudao.module.erp.dal.dataobject.purchase.ErpPurchaseInItemDO; |
| | | import cn.iocoder.yudao.module.erp.enums.ErpAuditStatus; |
| | | import com.baomidou.mybatisplus.core.conditions.update.LambdaUpdateWrapper; |
| | | import org.apache.ibatis.annotations.Mapper; |
| | | |
| | | import java.util.List; |
| | | import java.util.Objects; |
| | | |
| | | /** |
| | | * ERP éè´å
¥åº Mapper |
| | | * |
| | | * @author èéæºç |
| | | */ |
| | | @Mapper |
| | | public interface ErpPurchaseInMapper extends BaseMapperX<ErpPurchaseInDO> { |
| | | |
| | | default PageResult<ErpPurchaseInDO> selectPage(ErpPurchaseInPageReqVO reqVO) { |
| | | MPJLambdaWrapperX<ErpPurchaseInDO> query = new MPJLambdaWrapperX<ErpPurchaseInDO>() |
| | | .likeIfPresent(ErpPurchaseInDO::getNo, reqVO.getNo()) |
| | | .eqIfPresent(ErpPurchaseInDO::getSupplierId, reqVO.getSupplierId()) |
| | | .betweenIfPresent(ErpPurchaseInDO::getInTime, reqVO.getInTime()) |
| | | .eqIfPresent(ErpPurchaseInDO::getStatus, reqVO.getStatus()) |
| | | .likeIfPresent(ErpPurchaseInDO::getRemark, reqVO.getRemark()) |
| | | .eqIfPresent(ErpPurchaseInDO::getCreator, reqVO.getCreator()) |
| | | .eqIfPresent(ErpPurchaseInDO::getAccountId, reqVO.getAccountId()) |
| | | .likeIfPresent(ErpPurchaseInDO::getOrderNo, reqVO.getOrderNo()) |
| | | .orderByDesc(ErpPurchaseInDO::getId); |
| | | // 仿¬¾ç¶æã为ä»ä¹éè¦ t. çåå ï¼æ¯å 为è表æ¥è¯¢æ¶ï¼éè¦æå®è¡¨åï¼ä¸ç¶ä¼æ¥å段ä¸åå¨çé误 |
| | | if (Objects.equals(reqVO.getPaymentStatus(), ErpPurchaseInPageReqVO.PAYMENT_STATUS_NONE)) { |
| | | query.eq(ErpPurchaseInDO::getPaymentPrice, 0); |
| | | } else if (Objects.equals(reqVO.getPaymentStatus(), ErpPurchaseInPageReqVO.PAYMENT_STATUS_PART)) { |
| | | query.gt(ErpPurchaseInDO::getPaymentPrice, 0).apply("t.payment_price < t.total_price"); |
| | | } else if (Objects.equals(reqVO.getPaymentStatus(), ErpPurchaseInPageReqVO.PAYMENT_STATUS_ALL)) { |
| | | query.apply("t.payment_price = t.total_price"); |
| | | } |
| | | if (Boolean.TRUE.equals(reqVO.getPaymentEnable())) { |
| | | query.eq(ErpPurchaseInDO::getStatus, ErpAuditStatus.APPROVE.getStatus()) |
| | | .apply("t.payment_price < t.total_price"); |
| | | } |
| | | if (reqVO.getWarehouseId() != null || reqVO.getProductId() != null) { |
| | | query.leftJoin(ErpPurchaseInItemDO.class, ErpPurchaseInItemDO::getInId, ErpPurchaseInDO::getId) |
| | | .eq(reqVO.getWarehouseId() != null, ErpPurchaseInItemDO::getWarehouseId, reqVO.getWarehouseId()) |
| | | .eq(reqVO.getProductId() != null, ErpPurchaseInItemDO::getProductId, reqVO.getProductId()) |
| | | .groupBy(ErpPurchaseInDO::getId); // é¿å
1 坹夿¥è¯¢ï¼äº§çç¸åç 1 |
| | | } |
| | | return selectJoinPage(reqVO, ErpPurchaseInDO.class, query); |
| | | } |
| | | |
| | | default int updateByIdAndStatus(Long id, Integer status, ErpPurchaseInDO updateObj) { |
| | | return update(updateObj, new LambdaUpdateWrapper<ErpPurchaseInDO>() |
| | | .eq(ErpPurchaseInDO::getId, id).eq(ErpPurchaseInDO::getStatus, status)); |
| | | } |
| | | |
| | | default ErpPurchaseInDO selectByNo(String no) { |
| | | return selectOne(ErpPurchaseInDO::getNo, no); |
| | | } |
| | | |
| | | default List<ErpPurchaseInDO> selectListByOrderId(Long orderId) { |
| | | return selectList(ErpPurchaseInDO::getOrderId, orderId); |
| | | } |
| | | |
| | | } |
| ¶Ô±ÈÐÂÎļþ |
| | |
| | | package cn.iocoder.yudao.module.erp.dal.mysql.purchase; |
| | | |
| | | import cn.hutool.core.collection.CollUtil; |
| | | import cn.iocoder.yudao.framework.mybatis.core.mapper.BaseMapperX; |
| | | import cn.iocoder.yudao.module.erp.dal.dataobject.purchase.ErpPurchaseReturnItemDO; |
| | | import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper; |
| | | import org.apache.ibatis.annotations.Mapper; |
| | | |
| | | import java.math.BigDecimal; |
| | | import java.util.Collection; |
| | | import java.util.Collections; |
| | | import java.util.List; |
| | | import java.util.Map; |
| | | |
| | | import static cn.iocoder.yudao.framework.common.util.collection.CollectionUtils.convertMap; |
| | | |
| | | /** |
| | | * ERP éè´é货项 Mapper |
| | | * |
| | | * @author èéæºç |
| | | */ |
| | | @Mapper |
| | | public interface ErpPurchaseReturnItemMapper extends BaseMapperX<ErpPurchaseReturnItemDO> { |
| | | |
| | | default List<ErpPurchaseReturnItemDO> selectListByReturnId(Long returnId) { |
| | | return selectList(ErpPurchaseReturnItemDO::getReturnId, returnId); |
| | | } |
| | | |
| | | default List<ErpPurchaseReturnItemDO> selectListByReturnIds(Collection<Long> returnIds) { |
| | | return selectList(ErpPurchaseReturnItemDO::getReturnId, returnIds); |
| | | } |
| | | |
| | | default int deleteByReturnId(Long returnId) { |
| | | return delete(ErpPurchaseReturnItemDO::getReturnId, returnId); |
| | | } |
| | | |
| | | /** |
| | | * åºäºéè´è®¢åç¼å·ï¼æ¥è¯¢æ¯ä¸ªéè´è®¢å项çéè´§æ°éä¹å |
| | | * |
| | | * @param returnIds å
¥åºè®¢å项ç¼å·æ°ç» |
| | | * @return keyï¼éè´è®¢å项ç¼å·ï¼valueï¼éè´§æ°éä¹å |
| | | */ |
| | | default Map<Long, BigDecimal> selectOrderItemCountSumMapByReturnIds(Collection<Long> returnIds) { |
| | | if (CollUtil.isEmpty(returnIds)) { |
| | | return Collections.emptyMap(); |
| | | } |
| | | // SQL sum æ¥è¯¢ |
| | | List<Map<String, Object>> result = selectMaps(new QueryWrapper<ErpPurchaseReturnItemDO>() |
| | | .select("order_item_id, SUM(count) AS sum_count") |
| | | .groupBy("order_item_id") |
| | | .in("return_id", returnIds)); |
| | | // è·å¾æ°é |
| | | return convertMap(result, obj -> (Long) obj.get("order_item_id"), obj -> (BigDecimal) obj.get("sum_count")); |
| | | } |
| | | |
| | | } |
| ¶Ô±ÈÐÂÎļþ |
| | |
| | | package cn.iocoder.yudao.module.erp.dal.mysql.purchase; |
| | | |
| | | import cn.iocoder.yudao.framework.common.pojo.PageResult; |
| | | import cn.iocoder.yudao.framework.mybatis.core.mapper.BaseMapperX; |
| | | import cn.iocoder.yudao.framework.mybatis.core.query.MPJLambdaWrapperX; |
| | | import cn.iocoder.yudao.module.erp.controller.admin.purchase.vo.returns.ErpPurchaseReturnPageReqVO; |
| | | import cn.iocoder.yudao.module.erp.dal.dataobject.purchase.ErpPurchaseInDO; |
| | | import cn.iocoder.yudao.module.erp.dal.dataobject.purchase.ErpPurchaseReturnDO; |
| | | import cn.iocoder.yudao.module.erp.dal.dataobject.purchase.ErpPurchaseReturnItemDO; |
| | | import cn.iocoder.yudao.module.erp.enums.ErpAuditStatus; |
| | | import com.baomidou.mybatisplus.core.conditions.update.LambdaUpdateWrapper; |
| | | import org.apache.ibatis.annotations.Mapper; |
| | | |
| | | import java.util.List; |
| | | import java.util.Objects; |
| | | |
| | | /** |
| | | * ERP éè´éè´§ Mapper |
| | | * |
| | | * @author èéæºç |
| | | */ |
| | | @Mapper |
| | | public interface ErpPurchaseReturnMapper extends BaseMapperX<ErpPurchaseReturnDO> { |
| | | |
| | | default PageResult<ErpPurchaseReturnDO> selectPage(ErpPurchaseReturnPageReqVO reqVO) { |
| | | MPJLambdaWrapperX<ErpPurchaseReturnDO> query = new MPJLambdaWrapperX<ErpPurchaseReturnDO>() |
| | | .likeIfPresent(ErpPurchaseReturnDO::getNo, reqVO.getNo()) |
| | | .eqIfPresent(ErpPurchaseReturnDO::getSupplierId, reqVO.getSupplierId()) |
| | | .betweenIfPresent(ErpPurchaseReturnDO::getReturnTime, reqVO.getReturnTime()) |
| | | .eqIfPresent(ErpPurchaseReturnDO::getStatus, reqVO.getStatus()) |
| | | .likeIfPresent(ErpPurchaseReturnDO::getRemark, reqVO.getRemark()) |
| | | .eqIfPresent(ErpPurchaseReturnDO::getCreator, reqVO.getCreator()) |
| | | .eqIfPresent(ErpPurchaseReturnDO::getAccountId, reqVO.getAccountId()) |
| | | .likeIfPresent(ErpPurchaseReturnDO::getOrderNo, reqVO.getOrderNo()) |
| | | .orderByDesc(ErpPurchaseReturnDO::getId); |
| | | // 鿬¾ç¶æã为ä»ä¹éè¦ t. çåå ï¼æ¯å 为è表æ¥è¯¢æ¶ï¼éè¦æå®è¡¨åï¼ä¸ç¶ä¼æ¥å段ä¸åå¨çé误 |
| | | if (Objects.equals(reqVO.getRefundStatus(), ErpPurchaseReturnPageReqVO.REFUND_STATUS_NONE)) { |
| | | query.eq(ErpPurchaseReturnDO::getRefundPrice, 0); |
| | | } else if (Objects.equals(reqVO.getRefundStatus(), ErpPurchaseReturnPageReqVO.REFUND_STATUS_PART)) { |
| | | query.gt(ErpPurchaseReturnDO::getRefundPrice, 0).apply("t.refund_price < t.total_price"); |
| | | } else if (Objects.equals(reqVO.getRefundStatus(), ErpPurchaseReturnPageReqVO.REFUND_STATUS_ALL)) { |
| | | query.apply("t.refund_price = t.total_price"); |
| | | } |
| | | if (Boolean.TRUE.equals(reqVO.getRefundEnable())) { |
| | | query.eq(ErpPurchaseInDO::getStatus, ErpAuditStatus.APPROVE.getStatus()) |
| | | .apply("t.refund_price < t.total_price"); |
| | | } |
| | | if (reqVO.getWarehouseId() != null || reqVO.getProductId() != null) { |
| | | query.leftJoin(ErpPurchaseReturnItemDO.class, ErpPurchaseReturnItemDO::getReturnId, ErpPurchaseReturnDO::getId) |
| | | .eq(reqVO.getWarehouseId() != null, ErpPurchaseReturnItemDO::getWarehouseId, reqVO.getWarehouseId()) |
| | | .eq(reqVO.getProductId() != null, ErpPurchaseReturnItemDO::getProductId, reqVO.getProductId()) |
| | | .groupBy(ErpPurchaseReturnDO::getId); // é¿å
1 坹夿¥è¯¢ï¼äº§çç¸åç 1 |
| | | } |
| | | return selectJoinPage(reqVO, ErpPurchaseReturnDO.class, query); |
| | | } |
| | | |
| | | default int updateByIdAndStatus(Long id, Integer status, ErpPurchaseReturnDO updateObj) { |
| | | return update(updateObj, new LambdaUpdateWrapper<ErpPurchaseReturnDO>() |
| | | .eq(ErpPurchaseReturnDO::getId, id).eq(ErpPurchaseReturnDO::getStatus, status)); |
| | | } |
| | | |
| | | default ErpPurchaseReturnDO selectByNo(String no) { |
| | | return selectOne(ErpPurchaseReturnDO::getNo, no); |
| | | } |
| | | |
| | | default List<ErpPurchaseReturnDO> selectListByOrderId(Long orderId) { |
| | | return selectList(ErpPurchaseReturnDO::getOrderId, orderId); |
| | | } |
| | | |
| | | } |
| | |
| | | package cn.iocoder.yudao.module.erp.dal.mysql.statistics; |
| | | |
| | | import cn.iocoder.yudao.module.erp.controller.admin.statistics.vo.purchase.ErpPurchasePriceAnalysisRespVO; |
| | | import cn.iocoder.yudao.module.erp.controller.admin.statistics.vo.purchase.ErpPurchaseStatisticsReqVO; |
| | | import cn.iocoder.yudao.module.erp.controller.admin.statistics.vo.purchase.ErpPurchaseSummaryRespVO; |
| | | import cn.iocoder.yudao.module.erp.controller.admin.statistics.vo.purchase.ErpPurchaseSupplierStatisticsRespVO; |
| | | import cn.iocoder.yudao.module.erp.controller.admin.statistics.vo.purchase.ErpPurchaseUncompletedOrderRespVO; |
| | | import com.baomidou.mybatisplus.extension.plugins.pagination.Page; |
| | | import org.apache.ibatis.annotations.Mapper; |
| | | import org.apache.ibatis.annotations.Param; |
| | | |
| | |
| | | BigDecimal getPurchasePrice(@Param("beginTime") LocalDateTime beginTime, |
| | | @Param("endTime") LocalDateTime endTime); |
| | | |
| | | /** |
| | | * éè´æ±æ»ç»è®¡ï¼è®¢å / å
¥åº / éè´§çæ»æ°ä¸æ»éé¢ï¼ |
| | | * |
| | | * @return æ±æ»ç»è®¡ |
| | | */ |
| | | ErpPurchaseSummaryRespVO selectPurchaseSummary(); |
| | | |
| | | /** |
| | | * ä¾åºåä¾è´§ç»è®¡ |
| | | * |
| | | * @param page å页 |
| | | * @param reqVO æ¥è¯¢æ¡ä»¶ |
| | | * @return åé¡µç»æ |
| | | */ |
| | | Page<ErpPurchaseSupplierStatisticsRespVO> selectSupplierStatistics( |
| | | Page<ErpPurchaseSupplierStatisticsRespVO> page, |
| | | @Param("reqVO") ErpPurchaseStatisticsReqVO reqVO); |
| | | |
| | | /** |
| | | * éè´ä»·æ ¼åæï¼æäº§åèåï¼ |
| | | * |
| | | * @param page å页 |
| | | * @param reqVO æ¥è¯¢æ¡ä»¶ |
| | | * @return åé¡µç»æ |
| | | */ |
| | | Page<ErpPurchasePriceAnalysisRespVO> selectPriceAnalysis( |
| | | Page<ErpPurchasePriceAnalysisRespVO> page, |
| | | @Param("reqVO") ErpPurchaseStatisticsReqVO reqVO); |
| | | |
| | | /** |
| | | * æªå®æéè´è®¢åè·è¸ª |
| | | * |
| | | * @param page å页 |
| | | * @param reqVO æ¥è¯¢æ¡ä»¶ |
| | | * @return åé¡µç»æ |
| | | */ |
| | | Page<ErpPurchaseUncompletedOrderRespVO> selectUncompletedOrders( |
| | | Page<ErpPurchaseUncompletedOrderRespVO> page, |
| | | @Param("reqVO") ErpPurchaseStatisticsReqVO reqVO); |
| | | |
| | | } |
| | |
| | | public static final String PURCHASE_INVOICE_NO_PREFIX = "FPD"; |
| | | |
| | | /** |
| | | * éè´å
¥åº {@link cn.iocoder.yudao.module.erp.dal.dataobject.purchase.ErpPurchaseInDO} |
| | | */ |
| | | public static final String PURCHASE_IN_NO_PREFIX = "CGRK"; |
| | | |
| | | /** |
| | | * éè´éè´§ {@link cn.iocoder.yudao.module.erp.dal.dataobject.purchase.ErpPurchaseReturnDO} |
| | | */ |
| | | public static final String PURCHASE_RETURN_NO_PREFIX = "CGTH"; |
| | | |
| | | /** |
| | | * 仿¬¾å {@link cn.iocoder.yudao.module.erp.dal.dataobject.finance.ErpFinancePaymentDO} |
| | | */ |
| | | public static final String FINANCE_PAYMENT_NO_PREFIX = "FKD"; |
| ¶Ô±ÈÐÂÎļþ |
| | |
| | | package cn.iocoder.yudao.module.erp.service.purchase; |
| | | |
| | | import cn.iocoder.yudao.framework.common.pojo.PageResult; |
| | | import cn.iocoder.yudao.module.erp.controller.admin.purchase.vo.in.ErpPurchaseInPageReqVO; |
| | | import cn.iocoder.yudao.module.erp.controller.admin.purchase.vo.in.ErpPurchaseInSaveReqVO; |
| | | import cn.iocoder.yudao.module.erp.dal.dataobject.purchase.ErpPurchaseInDO; |
| | | import cn.iocoder.yudao.module.erp.dal.dataobject.purchase.ErpPurchaseInItemDO; |
| | | import jakarta.validation.Valid; |
| | | |
| | | import java.math.BigDecimal; |
| | | import java.util.Collection; |
| | | import java.util.List; |
| | | |
| | | /** |
| | | * ERP éè´å
¥åº Service æ¥å£ |
| | | * |
| | | * @author èéæºç |
| | | */ |
| | | public interface ErpPurchaseInService { |
| | | |
| | | /** |
| | | * å建éè´å
¥åº |
| | | * |
| | | * @param createReqVO åå»ºä¿¡æ¯ |
| | | * @return ç¼å· |
| | | */ |
| | | Long createPurchaseIn(@Valid ErpPurchaseInSaveReqVO createReqVO); |
| | | |
| | | /** |
| | | * æ´æ°éè´å
¥åº |
| | | * |
| | | * @param updateReqVO æ´æ°ä¿¡æ¯ |
| | | */ |
| | | void updatePurchaseIn(@Valid ErpPurchaseInSaveReqVO updateReqVO); |
| | | |
| | | /** |
| | | * æ´æ°éè´å
¥åºçç¶æ |
| | | * |
| | | * @param id ç¼å· |
| | | * @param status ç¶æ |
| | | */ |
| | | void updatePurchaseInStatus(Long id, Integer status); |
| | | |
| | | /** |
| | | * æ´æ°éè´å
¥åºç仿¬¾éé¢ |
| | | * |
| | | * @param id ç¼å· |
| | | * @param paymentPrice 仿¬¾éé¢ |
| | | */ |
| | | void updatePurchaseInPaymentPrice(Long id, BigDecimal paymentPrice); |
| | | |
| | | /** |
| | | * å é¤éè´å
¥åº |
| | | * |
| | | * @param ids ç¼å·æ°ç» |
| | | */ |
| | | void deletePurchaseIn(List<Long> ids); |
| | | |
| | | /** |
| | | * è·å¾éè´å
¥åº |
| | | * |
| | | * @param id ç¼å· |
| | | * @return éè´å
¥åº |
| | | */ |
| | | ErpPurchaseInDO getPurchaseIn(Long id); |
| | | |
| | | /** |
| | | * æ ¡éªéè´å
¥åºï¼å·²ç»å®¡æ ¸éè¿ |
| | | * |
| | | * @param id ç¼å· |
| | | * @return éè´å
¥åº |
| | | */ |
| | | ErpPurchaseInDO validatePurchaseIn(Long id); |
| | | |
| | | /** |
| | | * è·å¾éè´å
¥åºå页 |
| | | * |
| | | * @param pageReqVO å页æ¥è¯¢ |
| | | * @return éè´å
¥åºå页 |
| | | */ |
| | | PageResult<ErpPurchaseInDO> getPurchaseInPage(ErpPurchaseInPageReqVO pageReqVO); |
| | | |
| | | // ==================== éè´å
¥åºé¡¹ ==================== |
| | | |
| | | /** |
| | | * è·å¾éè´å
¥åºé¡¹å表 |
| | | * |
| | | * @param inId éè´å
¥åºç¼å· |
| | | * @return éè´å
¥åºé¡¹å表 |
| | | */ |
| | | List<ErpPurchaseInItemDO> getPurchaseInItemListByInId(Long inId); |
| | | |
| | | /** |
| | | * è·å¾éè´å
¥åºé¡¹ List |
| | | * |
| | | * @param inIds éè´å
¥åºç¼å·æ°ç» |
| | | * @return éè´å
¥åºé¡¹ List |
| | | */ |
| | | List<ErpPurchaseInItemDO> getPurchaseInItemListByInIds(Collection<Long> inIds); |
| | | |
| | | } |
| ¶Ô±ÈÐÂÎļþ |
| | |
| | | package cn.iocoder.yudao.module.erp.service.purchase; |
| | | |
| | | import cn.hutool.core.collection.CollUtil; |
| | | import cn.hutool.core.util.ObjectUtil; |
| | | import cn.hutool.core.util.StrUtil; |
| | | import cn.iocoder.yudao.framework.common.pojo.PageResult; |
| | | import cn.iocoder.yudao.framework.common.util.number.MoneyUtils; |
| | | import cn.iocoder.yudao.framework.common.util.object.BeanUtils; |
| | | import cn.iocoder.yudao.module.erp.controller.admin.purchase.vo.in.ErpPurchaseInPageReqVO; |
| | | import cn.iocoder.yudao.module.erp.controller.admin.purchase.vo.in.ErpPurchaseInSaveReqVO; |
| | | import cn.iocoder.yudao.module.erp.dal.dataobject.purchase.ErpPurchaseInDO; |
| | | import cn.iocoder.yudao.module.erp.dal.dataobject.purchase.ErpPurchaseInItemDO; |
| | | import cn.iocoder.yudao.module.erp.dal.dataobject.purchase.ErpPurchaseOrderDO; |
| | | import cn.iocoder.yudao.module.erp.dal.mysql.purchase.ErpPurchaseInItemMapper; |
| | | import cn.iocoder.yudao.module.erp.dal.mysql.purchase.ErpPurchaseInMapper; |
| | | import cn.iocoder.yudao.module.erp.dal.redis.no.ErpNoRedisDAO; |
| | | import cn.iocoder.yudao.module.erp.enums.ErpAuditStatus; |
| | | import cn.iocoder.yudao.module.erp.service.finance.ErpAccountService; |
| | | import cn.iocoder.yudao.module.mdm.api.item.MdmItemApi; |
| | | import cn.iocoder.yudao.module.mdm.api.item.dto.MdmItemRespDTO; |
| | | import cn.iocoder.yudao.module.mes.api.wms.dto.WmsPurchaseInboundReqDTO; |
| | | import cn.iocoder.yudao.module.mes.api.wms.stock.WmsStockApi; |
| | | import cn.iocoder.yudao.module.system.api.user.AdminUserApi; |
| | | import jakarta.annotation.Resource; |
| | | import lombok.extern.slf4j.Slf4j; |
| | | import org.springframework.context.annotation.Lazy; |
| | | import org.springframework.stereotype.Service; |
| | | import org.springframework.transaction.annotation.Transactional; |
| | | import org.springframework.validation.annotation.Validated; |
| | | |
| | | import java.math.BigDecimal; |
| | | import java.time.LocalDateTime; |
| | | import java.util.Collection; |
| | | import java.util.Collections; |
| | | import java.util.List; |
| | | import java.util.Map; |
| | | import java.util.Set; |
| | | |
| | | import static cn.iocoder.yudao.framework.common.exception.util.ServiceExceptionUtil.exception; |
| | | import static cn.iocoder.yudao.framework.common.util.collection.CollectionUtils.*; |
| | | import static cn.iocoder.yudao.module.erp.enums.ErrorCodeConstants.*; |
| | | |
| | | // TODO èè¿ï¼è®°å½æä½æ¥å¿ |
| | | |
| | | /** |
| | | * ERP éè´å
¥åº Service å®ç°ç±» |
| | | * |
| | | * @author èéæºç |
| | | */ |
| | | @Service |
| | | @Validated |
| | | @Slf4j |
| | | public class ErpPurchaseInServiceImpl implements ErpPurchaseInService { |
| | | |
| | | @Resource |
| | | private ErpPurchaseInMapper purchaseInMapper; |
| | | @Resource |
| | | private ErpPurchaseInItemMapper purchaseInItemMapper; |
| | | |
| | | @Resource |
| | | private ErpNoRedisDAO noRedisDAO; |
| | | |
| | | @Resource |
| | | private MdmItemApi mdmItemApi; |
| | | @Resource |
| | | @Lazy // å»¶è¿å è½½ï¼é¿å
循ç¯ä¾èµ |
| | | private ErpPurchaseOrderService purchaseOrderService; |
| | | @Resource |
| | | private ErpAccountService accountService; |
| | | |
| | | @Resource |
| | | private WmsStockApi wmsStockApi; |
| | | |
| | | @Resource |
| | | private AdminUserApi adminUserApi; |
| | | |
| | | @Override |
| | | @Transactional(rollbackFor = Exception.class) |
| | | public Long createPurchaseIn(ErpPurchaseInSaveReqVO createReqVO) { |
| | | // 1.1 æ ¡éªéè´è®¢åå·²å®¡æ ¸ |
| | | ErpPurchaseOrderDO purchaseOrder = purchaseOrderService.validatePurchaseOrder(createReqVO.getOrderId()); |
| | | // 1.2 æ ¡éªå
¥åºé¡¹çæææ§ |
| | | List<ErpPurchaseInItemDO> purchaseInItems = validatePurchaseInItems(createReqVO.getItems()); |
| | | // 1.3 æ ¡éªç»ç®è´¦æ· |
| | | accountService.validateAccount(createReqVO.getAccountId()); |
| | | // 1.4 çæå
¥åºåå·ï¼å¹¶æ ¡éªå¯ä¸æ§ |
| | | String no = noRedisDAO.generate(ErpNoRedisDAO.PURCHASE_IN_NO_PREFIX); |
| | | if (purchaseInMapper.selectByNo(no) != null) { |
| | | throw exception(PURCHASE_IN_NO_EXISTS); |
| | | } |
| | | |
| | | // 2.1 æå
¥å
¥åº |
| | | ErpPurchaseInDO purchaseIn = BeanUtils.toBean(createReqVO, ErpPurchaseInDO.class, in -> in |
| | | .setNo(no).setStatus(ErpAuditStatus.PROCESS.getStatus())) |
| | | .setOrderNo(purchaseOrder.getNo()).setSupplierId(purchaseOrder.getSupplierId()); |
| | | calculateTotalPrice(purchaseIn, purchaseInItems); |
| | | purchaseInMapper.insert(purchaseIn); |
| | | // 2.2 æå
¥å
¥åºé¡¹ |
| | | purchaseInItems.forEach(o -> o.setInId(purchaseIn.getId())); |
| | | purchaseInItemMapper.insertBatch(purchaseInItems); |
| | | |
| | | // 3. æ´æ°éè´è®¢åçå
¥åºæ°é |
| | | updatePurchaseOrderInCount(createReqVO.getOrderId()); |
| | | return purchaseIn.getId(); |
| | | } |
| | | |
| | | @Override |
| | | @Transactional(rollbackFor = Exception.class) |
| | | public void updatePurchaseIn(ErpPurchaseInSaveReqVO updateReqVO) { |
| | | // 1.1 æ ¡éªåå¨ |
| | | ErpPurchaseInDO purchaseIn = validatePurchaseInExists(updateReqVO.getId()); |
| | | if (ErpAuditStatus.APPROVE.getStatus().equals(purchaseIn.getStatus())) { |
| | | throw exception(PURCHASE_IN_UPDATE_FAIL_APPROVE, purchaseIn.getNo()); |
| | | } |
| | | // 1.2 æ ¡éªéè´è®¢åå·²å®¡æ ¸ |
| | | ErpPurchaseOrderDO purchaseOrder = purchaseOrderService.validatePurchaseOrder(updateReqVO.getOrderId()); |
| | | // 1.3 æ ¡éªç»ç®è´¦æ· |
| | | accountService.validateAccount(updateReqVO.getAccountId()); |
| | | // 1.4 æ ¡éªè®¢åé¡¹çæææ§ |
| | | List<ErpPurchaseInItemDO> purchaseInItems = validatePurchaseInItems(updateReqVO.getItems()); |
| | | |
| | | // 2.1 æ´æ°å
¥åº |
| | | ErpPurchaseInDO updateObj = BeanUtils.toBean(updateReqVO, ErpPurchaseInDO.class) |
| | | .setOrderNo(purchaseOrder.getNo()).setSupplierId(purchaseOrder.getSupplierId()); |
| | | calculateTotalPrice(updateObj, purchaseInItems); |
| | | purchaseInMapper.updateById(updateObj); |
| | | // 2.2 æ´æ°å
¥åºé¡¹ |
| | | updatePurchaseInItemList(updateReqVO.getId(), purchaseInItems); |
| | | |
| | | // 3.1 æ´æ°éè´è®¢åçå
¥åºæ°é |
| | | updatePurchaseOrderInCount(updateObj.getOrderId()); |
| | | // 3.2 注æï¼å¦æéè´è®¢åç¼å·åæ´äºï¼éè¦æ´æ°âèâéè´è®¢åçå
¥åºæ°é |
| | | if (ObjectUtil.notEqual(purchaseIn.getOrderId(), updateObj.getOrderId())) { |
| | | updatePurchaseOrderInCount(purchaseIn.getOrderId()); |
| | | } |
| | | } |
| | | |
| | | private void calculateTotalPrice(ErpPurchaseInDO purchaseIn, List<ErpPurchaseInItemDO> purchaseInItems) { |
| | | purchaseIn.setTotalCount(getSumValue(purchaseInItems, ErpPurchaseInItemDO::getCount, BigDecimal::add)); |
| | | purchaseIn.setTotalProductPrice(getSumValue(purchaseInItems, ErpPurchaseInItemDO::getTotalPrice, BigDecimal::add, BigDecimal.ZERO)); |
| | | purchaseIn.setTotalTaxPrice(getSumValue(purchaseInItems, ErpPurchaseInItemDO::getTaxPrice, BigDecimal::add, BigDecimal.ZERO)); |
| | | purchaseIn.setTotalPrice(purchaseIn.getTotalProductPrice().add(purchaseIn.getTotalTaxPrice())); |
| | | // 计ç®ä¼æ ä»·æ ¼ |
| | | if (purchaseIn.getDiscountPercent() == null) { |
| | | purchaseIn.setDiscountPercent(BigDecimal.ZERO); |
| | | } |
| | | purchaseIn.setDiscountPrice(MoneyUtils.priceMultiplyPercent(purchaseIn.getTotalPrice(), purchaseIn.getDiscountPercent())); |
| | | purchaseIn.setTotalPrice(purchaseIn.getTotalPrice().subtract(purchaseIn.getDiscountPrice()).add(purchaseIn.getOtherPrice())); |
| | | } |
| | | |
| | | private void updatePurchaseOrderInCount(Long orderId) { |
| | | // 1.1 æ¥è¯¢éè´è®¢å对åºçéè´å
¥åºåå表 |
| | | List<ErpPurchaseInDO> purchaseIns = purchaseInMapper.selectListByOrderId(orderId); |
| | | // 1.2 æ¥è¯¢å¯¹åºçéè´è®¢å项çå
¥åºæ°é |
| | | Map<Long, BigDecimal> returnCountMap = purchaseInItemMapper.selectOrderItemCountSumMapByInIds( |
| | | convertList(purchaseIns, ErpPurchaseInDO::getId)); |
| | | // 2. æ´æ°éè´è®¢åçå
¥åºæ°é |
| | | purchaseOrderService.updatePurchaseOrderInCount(orderId, returnCountMap); |
| | | } |
| | | |
| | | @Override |
| | | @Transactional(rollbackFor = Exception.class) |
| | | public void updatePurchaseInStatus(Long id, Integer status) { |
| | | boolean approve = ErpAuditStatus.APPROVE.getStatus().equals(status); |
| | | // 1.1 æ ¡éªåå¨ |
| | | ErpPurchaseInDO purchaseIn = validatePurchaseInExists(id); |
| | | // 1.2 æ ¡éªç¶æ |
| | | if (purchaseIn.getStatus().equals(status)) { |
| | | throw exception(approve ? PURCHASE_IN_APPROVE_FAIL : PURCHASE_IN_PROCESS_FAIL); |
| | | } |
| | | // 1.3 æ ¡éªå·²ä»æ¬¾ |
| | | if (!approve && purchaseIn.getPaymentPrice().compareTo(BigDecimal.ZERO) > 0) { |
| | | throw exception(PURCHASE_IN_PROCESS_FAIL_EXISTS_PAYMENT); |
| | | } |
| | | |
| | | // 2. æ´æ°ç¶æ |
| | | int updateCount = purchaseInMapper.updateByIdAndStatus(id, purchaseIn.getStatus(), |
| | | new ErpPurchaseInDO().setStatus(status)); |
| | | if (updateCount == 0) { |
| | | throw exception(approve ? PURCHASE_IN_APPROVE_FAIL : PURCHASE_IN_PROCESS_FAIL); |
| | | } |
| | | |
| | | // 3. 忥 WMS åºåï¼MES åºåï¼ |
| | | if (approve) { |
| | | List<ErpPurchaseInItemDO> purchaseInItems = purchaseInItemMapper.selectListByInId(id); |
| | | syncToWmsPurchaseInbound(purchaseIn, purchaseInItems); |
| | | } |
| | | } |
| | | |
| | | /** |
| | | * 忥éè´å
¥åºå° WMS åºå |
| | | */ |
| | | private void syncToWmsPurchaseInbound(ErpPurchaseInDO purchaseIn, List<ErpPurchaseInItemDO> purchaseInItems) { |
| | | if (CollUtil.isEmpty(purchaseInItems)) { |
| | | return; |
| | | } |
| | | |
| | | log.info("[syncToWmsPurchaseInbound] å¼å§åæ¥éè´å
¥åºå°WMSï¼purchaseInId={}", purchaseIn.getId()); |
| | | |
| | | // æå»ºå
¥åºè¯·æ± |
| | | WmsPurchaseInboundReqDTO reqDTO = new WmsPurchaseInboundReqDTO() |
| | | .setBizId(purchaseIn.getId()) |
| | | .setBizCode(purchaseIn.getNo()) |
| | | .setReceiptTime(LocalDateTime.now()); |
| | | |
| | | // è½¬æ¢æç»é¡¹ï¼ERP 产åç¼å·å³ MDM ç©æç¼å·ï¼ä»åºç¼å·å³ MES ä»åºç¼å· |
| | | List<WmsPurchaseInboundReqDTO.Item> items = convertList(purchaseInItems, item -> new WmsPurchaseInboundReqDTO.Item() |
| | | .setItemId(item.getProductId()) |
| | | .setWarehouseId(item.getWarehouseId()) |
| | | .setQuantity(item.getCount()) |
| | | .setBizLineId(item.getId())); |
| | | |
| | | // è¿æ»¤ææ å°å¤±è´¥ç项 |
| | | items = items.stream().filter(java.util.Objects::nonNull).toList(); |
| | | if (CollUtil.isEmpty(items)) { |
| | | log.warn("[syncToWmsPurchaseInbound] æ ææçå
¥åºæç»ï¼è·³è¿WMS忥"); |
| | | return; |
| | | } |
| | | |
| | | reqDTO.setItems(items); |
| | | |
| | | try { |
| | | Long transactionId = wmsStockApi.purchaseInbound(reqDTO); |
| | | log.info("[syncToWmsPurchaseInbound] 忥æåï¼transactionId={}", transactionId); |
| | | } catch (Exception e) { |
| | | log.error("[syncToWmsPurchaseInbound] åæ¥å¤±è´¥", e); |
| | | // 注æï¼è¿éå¯ä»¥éæ©æåºå¼å¸¸åæ»ï¼æä»
è®°å½æ¥å¿ |
| | | // throw exception(PURCHASE_IN_SYNC_WMS_FAIL); |
| | | } |
| | | } |
| | | |
| | | @Override |
| | | public void updatePurchaseInPaymentPrice(Long id, BigDecimal paymentPrice) { |
| | | ErpPurchaseInDO purchaseIn = purchaseInMapper.selectById(id); |
| | | if (purchaseIn.getPaymentPrice().equals(paymentPrice)) { |
| | | return; |
| | | } |
| | | if (paymentPrice.compareTo(purchaseIn.getTotalPrice()) > 0) { |
| | | throw exception(PURCHASE_IN_FAIL_PAYMENT_PRICE_EXCEED, paymentPrice, purchaseIn.getTotalPrice()); |
| | | } |
| | | purchaseInMapper.updateById(new ErpPurchaseInDO().setId(id).setPaymentPrice(paymentPrice)); |
| | | } |
| | | |
| | | private List<ErpPurchaseInItemDO> validatePurchaseInItems(List<ErpPurchaseInSaveReqVO.Item> list) { |
| | | // 1. æ ¡éªç©æåå¨ï¼ç©æä¸»æ°æ®å·²è¿ç§»å° MDMï¼ |
| | | Set<Long> productIds = convertSet(list, ErpPurchaseInSaveReqVO.Item::getProductId); |
| | | Map<Long, MdmItemRespDTO> itemMap = productIds.isEmpty() ? Collections.emptyMap() : mdmItemApi.getItemMap(productIds); |
| | | if (itemMap.size() != productIds.size()) { |
| | | throw exception(PRODUCT_NOT_EXISTS); |
| | | } |
| | | // 2. 转å为 ErpPurchaseInItemDO å表 |
| | | return convertList(list, o -> BeanUtils.toBean(o, ErpPurchaseInItemDO.class, item -> { |
| | | item.setProductUnitId(itemMap.get(item.getProductId()).getUnitMeasureId()); |
| | | item.setTotalPrice(MoneyUtils.priceMultiply(item.getProductPrice(), item.getCount())); |
| | | if (item.getTotalPrice() == null) { |
| | | return; |
| | | } |
| | | if (item.getTaxPercent() != null) { |
| | | item.setTaxPrice(MoneyUtils.priceMultiplyPercent(item.getTotalPrice(), item.getTaxPercent())); |
| | | } |
| | | })); |
| | | } |
| | | |
| | | private void updatePurchaseInItemList(Long id, List<ErpPurchaseInItemDO> newList) { |
| | | // ç¬¬ä¸æ¥ï¼å¯¹æ¯æ°èæ°æ®ï¼è·å¾æ·»å ãä¿®æ¹ãå é¤çå表 |
| | | List<ErpPurchaseInItemDO> oldList = purchaseInItemMapper.selectListByInId(id); |
| | | List<List<ErpPurchaseInItemDO>> diffList = diffList(oldList, newList, // id ä¸åï¼å°±è®¤ä¸ºæ¯ä¸åçè®°å½ |
| | | (oldVal, newVal) -> oldVal.getId().equals(newVal.getId())); |
| | | |
| | | // ç¬¬äºæ¥ï¼æ¹éæ·»å ãä¿®æ¹ãå é¤ |
| | | if (CollUtil.isNotEmpty(diffList.get(0))) { |
| | | diffList.get(0).forEach(o -> o.setInId(id)); |
| | | purchaseInItemMapper.insertBatch(diffList.get(0)); |
| | | } |
| | | if (CollUtil.isNotEmpty(diffList.get(1))) { |
| | | purchaseInItemMapper.updateBatch(diffList.get(1)); |
| | | } |
| | | if (CollUtil.isNotEmpty(diffList.get(2))) { |
| | | purchaseInItemMapper.deleteByIds(convertList(diffList.get(2), ErpPurchaseInItemDO::getId)); |
| | | } |
| | | } |
| | | |
| | | @Override |
| | | @Transactional(rollbackFor = Exception.class) |
| | | public void deletePurchaseIn(List<Long> ids) { |
| | | // 1. æ ¡éªä¸å¤äºå·²å®¡æ¹ |
| | | List<ErpPurchaseInDO> purchaseIns = purchaseInMapper.selectByIds(ids); |
| | | if (CollUtil.isEmpty(purchaseIns)) { |
| | | return; |
| | | } |
| | | purchaseIns.forEach(purchaseIn -> { |
| | | if (ErpAuditStatus.APPROVE.getStatus().equals(purchaseIn.getStatus())) { |
| | | throw exception(PURCHASE_IN_DELETE_FAIL_APPROVE, purchaseIn.getNo()); |
| | | } |
| | | }); |
| | | |
| | | // 2. éåå é¤ï¼å¹¶è®°å½æä½æ¥å¿ |
| | | purchaseIns.forEach(purchaseIn -> { |
| | | // 2.1 å é¤è®¢å |
| | | purchaseInMapper.deleteById(purchaseIn.getId()); |
| | | // 2.2 å é¤è®¢å项 |
| | | purchaseInItemMapper.deleteByInId(purchaseIn.getId()); |
| | | |
| | | // 2.3 æ´æ°éè´è®¢åçå
¥åºæ°é |
| | | updatePurchaseOrderInCount(purchaseIn.getOrderId()); |
| | | }); |
| | | |
| | | } |
| | | |
| | | private ErpPurchaseInDO validatePurchaseInExists(Long id) { |
| | | ErpPurchaseInDO purchaseIn = purchaseInMapper.selectById(id); |
| | | if (purchaseIn == null) { |
| | | throw exception(PURCHASE_IN_NOT_EXISTS); |
| | | } |
| | | return purchaseIn; |
| | | } |
| | | |
| | | @Override |
| | | public ErpPurchaseInDO getPurchaseIn(Long id) { |
| | | return purchaseInMapper.selectById(id); |
| | | } |
| | | |
| | | @Override |
| | | public ErpPurchaseInDO validatePurchaseIn(Long id) { |
| | | ErpPurchaseInDO purchaseIn = validatePurchaseInExists(id); |
| | | if (ObjectUtil.notEqual(purchaseIn.getStatus(), ErpAuditStatus.APPROVE.getStatus())) { |
| | | throw exception(PURCHASE_IN_NOT_APPROVE); |
| | | } |
| | | return purchaseIn; |
| | | } |
| | | |
| | | @Override |
| | | public PageResult<ErpPurchaseInDO> getPurchaseInPage(ErpPurchaseInPageReqVO pageReqVO) { |
| | | return purchaseInMapper.selectPage(pageReqVO); |
| | | } |
| | | |
| | | // ==================== éè´å
¥åºé¡¹ ==================== |
| | | |
| | | @Override |
| | | public List<ErpPurchaseInItemDO> getPurchaseInItemListByInId(Long inId) { |
| | | return purchaseInItemMapper.selectListByInId(inId); |
| | | } |
| | | |
| | | @Override |
| | | public List<ErpPurchaseInItemDO> getPurchaseInItemListByInIds(Collection<Long> inIds) { |
| | | if (CollUtil.isEmpty(inIds)) { |
| | | return Collections.emptyList(); |
| | | } |
| | | return purchaseInItemMapper.selectListByInIds(inIds); |
| | | } |
| | | |
| | | } |
| | |
| | | // 1. æ´æ°æ¯ä¸ªéè´è®¢å项 |
| | | orderItems.forEach(item -> { |
| | | BigDecimal inCount = inCountMap.getOrDefault(item.getId(), BigDecimal.ZERO); |
| | | if (item.getInCount().equals(inCount)) { |
| | | // åå²/导å
¥æ°æ®çå
¥åºæ°éå¯è½ä¸ºç©ºï¼æ 0 å¤çï¼é¿å
NPE |
| | | if (ObjectUtil.defaultIfNull(item.getInCount(), BigDecimal.ZERO).compareTo(inCount) == 0) { |
| | | return; |
| | | } |
| | | if (inCount.compareTo(item.getCount()) > 0) { |
| | |
| | | // 1. æ´æ°æ¯ä¸ªéè´è®¢å项 |
| | | orderItems.forEach(item -> { |
| | | BigDecimal returnCount = returnCountMap.getOrDefault(item.getId(), BigDecimal.ZERO); |
| | | if (item.getReturnCount().equals(returnCount)) { |
| | | // åå²/导å
¥æ°æ®çéè´§æ°éãå
¥åºæ°éå¯è½ä¸ºç©ºï¼æ 0 å¤çï¼é¿å
NPE |
| | | if (ObjectUtil.defaultIfNull(item.getReturnCount(), BigDecimal.ZERO).compareTo(returnCount) == 0) { |
| | | return; |
| | | } |
| | | if (returnCount.compareTo(item.getInCount()) > 0) { |
| | | BigDecimal inCount = ObjectUtil.defaultIfNull(item.getInCount(), BigDecimal.ZERO); |
| | | if (returnCount.compareTo(inCount) > 0) { |
| | | throw exception(PURCHASE_ORDER_ITEM_RETURN_FAIL_IN_EXCEED, |
| | | "产åID:" + item.getProductId(), item.getInCount()); |
| | | "产åID:" + item.getProductId(), inCount); |
| | | } |
| | | purchaseOrderItemMapper.updateById(new ErpPurchaseOrderItemDO().setId(item.getId()).setReturnCount(returnCount)); |
| | | }); |
| ¶Ô±ÈÐÂÎļþ |
| | |
| | | package cn.iocoder.yudao.module.erp.service.purchase; |
| | | |
| | | import cn.iocoder.yudao.framework.common.pojo.PageResult; |
| | | import cn.iocoder.yudao.module.erp.controller.admin.purchase.vo.returns.ErpPurchaseReturnPageReqVO; |
| | | import cn.iocoder.yudao.module.erp.controller.admin.purchase.vo.returns.ErpPurchaseReturnSaveReqVO; |
| | | import cn.iocoder.yudao.module.erp.dal.dataobject.purchase.ErpPurchaseReturnDO; |
| | | import cn.iocoder.yudao.module.erp.dal.dataobject.purchase.ErpPurchaseReturnItemDO; |
| | | import jakarta.validation.Valid; |
| | | |
| | | import java.math.BigDecimal; |
| | | import java.util.Collection; |
| | | import java.util.List; |
| | | |
| | | /** |
| | | * ERP éè´éè´§ Service æ¥å£ |
| | | * |
| | | * @author èéæºç |
| | | */ |
| | | public interface ErpPurchaseReturnService { |
| | | |
| | | /** |
| | | * å建éè´éè´§ |
| | | * |
| | | * @param createReqVO åå»ºä¿¡æ¯ |
| | | * @return ç¼å· |
| | | */ |
| | | Long createPurchaseReturn(@Valid ErpPurchaseReturnSaveReqVO createReqVO); |
| | | |
| | | /** |
| | | * æ´æ°éè´éè´§ |
| | | * |
| | | * @param updateReqVO æ´æ°ä¿¡æ¯ |
| | | */ |
| | | void updatePurchaseReturn(@Valid ErpPurchaseReturnSaveReqVO updateReqVO); |
| | | |
| | | /** |
| | | * æ´æ°éè´éè´§çç¶æ |
| | | * |
| | | * @param id ç¼å· |
| | | * @param status ç¶æ |
| | | */ |
| | | void updatePurchaseReturnStatus(Long id, Integer status); |
| | | |
| | | /** |
| | | * æ´æ°éè´éè´§ç鿬¾éé¢ |
| | | * |
| | | * @param id ç¼å· |
| | | * @param refundPrice 鿬¾éé¢ |
| | | */ |
| | | void updatePurchaseReturnRefundPrice(Long id, BigDecimal refundPrice); |
| | | |
| | | /** |
| | | * å é¤éè´éè´§ |
| | | * |
| | | * @param ids ç¼å·æ°ç» |
| | | */ |
| | | void deletePurchaseReturn(List<Long> ids); |
| | | |
| | | /** |
| | | * è·å¾éè´éè´§ |
| | | * |
| | | * @param id ç¼å· |
| | | * @return éè´éè´§ |
| | | */ |
| | | ErpPurchaseReturnDO getPurchaseReturn(Long id); |
| | | |
| | | /** |
| | | * æ ¡éªéè´éè´§ï¼å·²ç»å®¡æ ¸éè¿ |
| | | * |
| | | * @param id ç¼å· |
| | | * @return éè´éè´§ |
| | | */ |
| | | ErpPurchaseReturnDO validatePurchaseReturn(Long id); |
| | | |
| | | /** |
| | | * è·å¾éè´éè´§å页 |
| | | * |
| | | * @param pageReqVO å页æ¥è¯¢ |
| | | * @return éè´éè´§å页 |
| | | */ |
| | | PageResult<ErpPurchaseReturnDO> getPurchaseReturnPage(ErpPurchaseReturnPageReqVO pageReqVO); |
| | | |
| | | // ==================== éè´é货项 ==================== |
| | | |
| | | /** |
| | | * è·å¾éè´é货项å表 |
| | | * |
| | | * @param returnId éè´éè´§ç¼å· |
| | | * @return éè´é货项å表 |
| | | */ |
| | | List<ErpPurchaseReturnItemDO> getPurchaseReturnItemListByReturnId(Long returnId); |
| | | |
| | | /** |
| | | * è·å¾éè´é货项 List |
| | | * |
| | | * @param returnIds éè´éè´§ç¼å·æ°ç» |
| | | * @return éè´é货项 List |
| | | */ |
| | | List<ErpPurchaseReturnItemDO> getPurchaseReturnItemListByReturnIds(Collection<Long> returnIds); |
| | | |
| | | } |
| ¶Ô±ÈÐÂÎļþ |
| | |
| | | package cn.iocoder.yudao.module.erp.service.purchase; |
| | | |
| | | import cn.hutool.core.collection.CollUtil; |
| | | import cn.hutool.core.util.ObjectUtil; |
| | | import cn.iocoder.yudao.framework.common.pojo.PageResult; |
| | | import cn.iocoder.yudao.framework.common.util.number.MoneyUtils; |
| | | import cn.iocoder.yudao.framework.common.util.object.BeanUtils; |
| | | import cn.iocoder.yudao.module.erp.controller.admin.purchase.vo.returns.ErpPurchaseReturnPageReqVO; |
| | | import cn.iocoder.yudao.module.erp.controller.admin.purchase.vo.returns.ErpPurchaseReturnSaveReqVO; |
| | | import cn.iocoder.yudao.module.erp.dal.dataobject.purchase.ErpPurchaseOrderDO; |
| | | import cn.iocoder.yudao.module.erp.dal.dataobject.purchase.ErpPurchaseReturnDO; |
| | | import cn.iocoder.yudao.module.erp.dal.dataobject.purchase.ErpPurchaseReturnItemDO; |
| | | import cn.iocoder.yudao.module.erp.dal.mysql.purchase.ErpPurchaseReturnItemMapper; |
| | | import cn.iocoder.yudao.module.erp.dal.mysql.purchase.ErpPurchaseReturnMapper; |
| | | import cn.iocoder.yudao.module.erp.dal.redis.no.ErpNoRedisDAO; |
| | | import cn.iocoder.yudao.module.erp.enums.ErpAuditStatus; |
| | | import cn.iocoder.yudao.module.erp.service.finance.ErpAccountService; |
| | | import cn.iocoder.yudao.module.mdm.api.item.MdmItemApi; |
| | | import cn.iocoder.yudao.module.mdm.api.item.dto.MdmItemRespDTO; |
| | | import cn.iocoder.yudao.module.mes.api.wms.dto.WmsPurchaseInboundReqDTO; |
| | | import cn.iocoder.yudao.module.mes.api.wms.stock.WmsStockApi; |
| | | import jakarta.annotation.Resource; |
| | | import org.springframework.context.annotation.Lazy; |
| | | import org.springframework.stereotype.Service; |
| | | import org.springframework.transaction.annotation.Transactional; |
| | | import lombok.extern.slf4j.Slf4j; |
| | | import org.springframework.validation.annotation.Validated; |
| | | |
| | | import java.math.BigDecimal; |
| | | import java.util.Collection; |
| | | import java.util.Collections; |
| | | import java.util.List; |
| | | import java.util.Map; |
| | | import java.util.Set; |
| | | |
| | | import static cn.iocoder.yudao.framework.common.exception.util.ServiceExceptionUtil.exception; |
| | | import static cn.iocoder.yudao.framework.common.util.collection.CollectionUtils.*; |
| | | import static cn.iocoder.yudao.module.erp.enums.ErrorCodeConstants.*; |
| | | |
| | | // TODO èè¿ï¼è®°å½æä½æ¥å¿ |
| | | |
| | | /** |
| | | * ERP éè´éè´§ Service å®ç°ç±» |
| | | * |
| | | * @author èéæºç |
| | | */ |
| | | @Service |
| | | @Validated |
| | | @Slf4j |
| | | public class ErpPurchaseReturnServiceImpl implements ErpPurchaseReturnService { |
| | | |
| | | @Resource |
| | | private ErpPurchaseReturnMapper purchaseReturnMapper; |
| | | @Resource |
| | | private ErpPurchaseReturnItemMapper purchaseReturnItemMapper; |
| | | |
| | | @Resource |
| | | private ErpNoRedisDAO noRedisDAO; |
| | | |
| | | @Resource |
| | | private MdmItemApi mdmItemApi; |
| | | @Resource |
| | | @Lazy // å»¶è¿å è½½ï¼é¿å
循ç¯ä¾èµ |
| | | private ErpPurchaseOrderService purchaseOrderService; |
| | | @Resource |
| | | private ErpAccountService accountService; |
| | | @Resource |
| | | private WmsStockApi wmsStockApi; |
| | | |
| | | @Override |
| | | @Transactional(rollbackFor = Exception.class) |
| | | public Long createPurchaseReturn(ErpPurchaseReturnSaveReqVO createReqVO) { |
| | | // 1.1 æ ¡éªéè´è®¢åå·²å®¡æ ¸ |
| | | ErpPurchaseOrderDO purchaseOrder = purchaseOrderService.validatePurchaseOrder(createReqVO.getOrderId()); |
| | | // 1.2 æ ¡éªéè´§é¡¹çæææ§ |
| | | List<ErpPurchaseReturnItemDO> purchaseReturnItems = validatePurchaseReturnItems(createReqVO.getItems()); |
| | | // 1.3 æ ¡éªç»ç®è´¦æ· |
| | | accountService.validateAccount(createReqVO.getAccountId()); |
| | | // 1.4 çæéè´§åå·ï¼å¹¶æ ¡éªå¯ä¸æ§ |
| | | String no = noRedisDAO.generate(ErpNoRedisDAO.PURCHASE_RETURN_NO_PREFIX); |
| | | if (purchaseReturnMapper.selectByNo(no) != null) { |
| | | throw exception(PURCHASE_RETURN_NO_EXISTS); |
| | | } |
| | | |
| | | // 2.1 æå
¥éè´§ |
| | | ErpPurchaseReturnDO purchaseReturn = BeanUtils.toBean(createReqVO, ErpPurchaseReturnDO.class, in -> in |
| | | .setNo(no).setStatus(ErpAuditStatus.PROCESS.getStatus())) |
| | | .setOrderNo(purchaseOrder.getNo()).setSupplierId(purchaseOrder.getSupplierId()); |
| | | calculateTotalPrice(purchaseReturn, purchaseReturnItems); |
| | | purchaseReturnMapper.insert(purchaseReturn); |
| | | // 2.2 æå
¥é货项 |
| | | purchaseReturnItems.forEach(o -> o.setReturnId(purchaseReturn.getId())); |
| | | purchaseReturnItemMapper.insertBatch(purchaseReturnItems); |
| | | |
| | | // 3. æ´æ°éè´è®¢åçéè´§æ°é |
| | | updatePurchaseOrderReturnCount(createReqVO.getOrderId()); |
| | | return purchaseReturn.getId(); |
| | | } |
| | | |
| | | @Override |
| | | @Transactional(rollbackFor = Exception.class) |
| | | public void updatePurchaseReturn(ErpPurchaseReturnSaveReqVO updateReqVO) { |
| | | // 1.1 æ ¡éªåå¨ |
| | | ErpPurchaseReturnDO purchaseReturn = validatePurchaseReturnExists(updateReqVO.getId()); |
| | | if (ErpAuditStatus.APPROVE.getStatus().equals(purchaseReturn.getStatus())) { |
| | | throw exception(PURCHASE_RETURN_UPDATE_FAIL_APPROVE, purchaseReturn.getNo()); |
| | | } |
| | | // 1.2 æ ¡éªéè´è®¢åå·²å®¡æ ¸ |
| | | ErpPurchaseOrderDO purchaseOrder = purchaseOrderService.validatePurchaseOrder(updateReqVO.getOrderId()); |
| | | // 1.3 æ ¡éªç»ç®è´¦æ· |
| | | accountService.validateAccount(updateReqVO.getAccountId()); |
| | | // 1.4 æ ¡éªè®¢åé¡¹çæææ§ |
| | | List<ErpPurchaseReturnItemDO> purchaseReturnItems = validatePurchaseReturnItems(updateReqVO.getItems()); |
| | | |
| | | // 2.1 æ´æ°éè´§ |
| | | ErpPurchaseReturnDO updateObj = BeanUtils.toBean(updateReqVO, ErpPurchaseReturnDO.class) |
| | | .setOrderNo(purchaseOrder.getNo()).setSupplierId(purchaseOrder.getSupplierId()); |
| | | calculateTotalPrice(updateObj, purchaseReturnItems); |
| | | purchaseReturnMapper.updateById(updateObj); |
| | | // 2.2 æ´æ°é货项 |
| | | updatePurchaseReturnItemList(updateReqVO.getId(), purchaseReturnItems); |
| | | |
| | | // 3.1 æ´æ°éè´è®¢åçåºåºæ°é |
| | | updatePurchaseOrderReturnCount(updateObj.getOrderId()); |
| | | // 3.2 注æï¼å¦æéè´è®¢åç¼å·åæ´äºï¼éè¦æ´æ°âèâéè´è®¢åçåºåºæ°é |
| | | if (ObjectUtil.notEqual(purchaseReturn.getOrderId(), updateObj.getOrderId())) { |
| | | updatePurchaseOrderReturnCount(purchaseReturn.getOrderId()); |
| | | } |
| | | } |
| | | |
| | | private void calculateTotalPrice(ErpPurchaseReturnDO purchaseReturn, List<ErpPurchaseReturnItemDO> purchaseReturnItems) { |
| | | purchaseReturn.setTotalCount(getSumValue(purchaseReturnItems, ErpPurchaseReturnItemDO::getCount, BigDecimal::add)); |
| | | purchaseReturn.setTotalProductPrice(getSumValue(purchaseReturnItems, ErpPurchaseReturnItemDO::getTotalPrice, BigDecimal::add, BigDecimal.ZERO)); |
| | | purchaseReturn.setTotalTaxPrice(getSumValue(purchaseReturnItems, ErpPurchaseReturnItemDO::getTaxPrice, BigDecimal::add, BigDecimal.ZERO)); |
| | | purchaseReturn.setTotalPrice(purchaseReturn.getTotalProductPrice().add(purchaseReturn.getTotalTaxPrice())); |
| | | // 计ç®ä¼æ ä»·æ ¼ |
| | | if (purchaseReturn.getDiscountPercent() == null) { |
| | | purchaseReturn.setDiscountPercent(BigDecimal.ZERO); |
| | | } |
| | | purchaseReturn.setDiscountPrice(MoneyUtils.priceMultiplyPercent(purchaseReturn.getTotalPrice(), purchaseReturn.getDiscountPercent())); |
| | | purchaseReturn.setTotalPrice(purchaseReturn.getTotalPrice().subtract(purchaseReturn.getDiscountPrice()).add(purchaseReturn.getOtherPrice())); |
| | | } |
| | | |
| | | private void updatePurchaseOrderReturnCount(Long orderId) { |
| | | // 1.1 æ¥è¯¢éè´è®¢å对åºçéè´åºåºåå表 |
| | | List<ErpPurchaseReturnDO> purchaseReturns = purchaseReturnMapper.selectListByOrderId(orderId); |
| | | // 1.2 æ¥è¯¢å¯¹åºçéè´è®¢å项çéè´§æ°é |
| | | Map<Long, BigDecimal> returnCountMap = purchaseReturnItemMapper.selectOrderItemCountSumMapByReturnIds( |
| | | convertList(purchaseReturns, ErpPurchaseReturnDO::getId)); |
| | | // 2. æ´æ°éè´è®¢åçåºåºæ°é |
| | | purchaseOrderService.updatePurchaseOrderReturnCount(orderId, returnCountMap); |
| | | } |
| | | |
| | | @Override |
| | | @Transactional(rollbackFor = Exception.class) |
| | | public void updatePurchaseReturnStatus(Long id, Integer status) { |
| | | boolean approve = ErpAuditStatus.APPROVE.getStatus().equals(status); |
| | | // 1.1 æ ¡éªåå¨ |
| | | ErpPurchaseReturnDO purchaseReturn = validatePurchaseReturnExists(id); |
| | | // 1.2 æ ¡éªç¶æ |
| | | if (purchaseReturn.getStatus().equals(status)) { |
| | | throw exception(approve ? PURCHASE_RETURN_APPROVE_FAIL : PURCHASE_RETURN_PROCESS_FAIL); |
| | | } |
| | | // 1.3 æ ¡éªå·²é款 |
| | | if (!approve && purchaseReturn.getRefundPrice().compareTo(BigDecimal.ZERO) > 0) { |
| | | throw exception(PURCHASE_RETURN_PROCESS_FAIL_EXISTS_REFUND); |
| | | } |
| | | |
| | | // 2. æ´æ°ç¶æ |
| | | int updateCount = purchaseReturnMapper.updateByIdAndStatus(id, purchaseReturn.getStatus(), |
| | | new ErpPurchaseReturnDO().setStatus(status)); |
| | | if (updateCount == 0) { |
| | | throw exception(approve ? PURCHASE_RETURN_APPROVE_FAIL : PURCHASE_RETURN_PROCESS_FAIL); |
| | | } |
| | | |
| | | // 3. å®¡æ ¸éè¿æ¶ï¼åæ¥ MES ä»å¨åè´§ï¼éè´éè´§åºåºï¼ |
| | | if (approve) { |
| | | syncToWmsPurchaseReturnOutbound(purchaseReturn); |
| | | } |
| | | } |
| | | |
| | | /** |
| | | * 忥éè´éè´§å° WMSï¼MES ä»å¨ï¼åºå |
| | | */ |
| | | private void syncToWmsPurchaseReturnOutbound(ErpPurchaseReturnDO purchaseReturn) { |
| | | List<ErpPurchaseReturnItemDO> purchaseReturnItems = purchaseReturnItemMapper.selectListByReturnId(purchaseReturn.getId()); |
| | | if (CollUtil.isEmpty(purchaseReturnItems)) { |
| | | return; |
| | | } |
| | | WmsPurchaseInboundReqDTO reqDTO = new WmsPurchaseInboundReqDTO() |
| | | .setBizId(purchaseReturn.getId()) |
| | | .setBizCode(purchaseReturn.getNo()) |
| | | .setVendorId(purchaseReturn.getSupplierId()) |
| | | .setReceiptTime(purchaseReturn.getReturnTime()) |
| | | .setItems(convertList(purchaseReturnItems, item -> new WmsPurchaseInboundReqDTO.Item() |
| | | .setItemId(item.getProductId()) |
| | | .setWarehouseId(item.getWarehouseId()) |
| | | .setQuantity(item.getCount()) |
| | | .setBizLineId(item.getId()))); |
| | | try { |
| | | wmsStockApi.purchaseReturnOutbound(reqDTO); |
| | | } catch (Exception e) { |
| | | log.error("[syncToWmsPurchaseReturnOutbound] åæ¥å¤±è´¥ï¼purchaseReturnId={}", purchaseReturn.getId(), e); |
| | | } |
| | | } |
| | | |
| | | @Override |
| | | public void updatePurchaseReturnRefundPrice(Long id, BigDecimal refundPrice) { |
| | | ErpPurchaseReturnDO purchaseReturn = purchaseReturnMapper.selectById(id); |
| | | if (purchaseReturn.getRefundPrice().equals(refundPrice)) { |
| | | return; |
| | | } |
| | | if (refundPrice.compareTo(purchaseReturn.getTotalPrice()) > 0) { |
| | | throw exception(PURCHASE_RETURN_FAIL_REFUND_PRICE_EXCEED, refundPrice, purchaseReturn.getTotalPrice()); |
| | | } |
| | | purchaseReturnMapper.updateById(new ErpPurchaseReturnDO().setId(id).setRefundPrice(refundPrice)); |
| | | } |
| | | |
| | | private List<ErpPurchaseReturnItemDO> validatePurchaseReturnItems(List<ErpPurchaseReturnSaveReqVO.Item> list) { |
| | | // 1. æ ¡éªç©æåå¨ï¼ç©æä¸»æ°æ®å·²è¿ç§»å° MDMï¼ |
| | | Set<Long> productIds = convertSet(list, ErpPurchaseReturnSaveReqVO.Item::getProductId); |
| | | Map<Long, MdmItemRespDTO> itemMap = productIds.isEmpty() ? Collections.emptyMap() : mdmItemApi.getItemMap(productIds); |
| | | if (itemMap.size() != productIds.size()) { |
| | | throw exception(PRODUCT_NOT_EXISTS); |
| | | } |
| | | // 2. 转å为 ErpPurchaseReturnItemDO å表 |
| | | return convertList(list, o -> BeanUtils.toBean(o, ErpPurchaseReturnItemDO.class, item -> { |
| | | item.setProductUnitId(itemMap.get(item.getProductId()).getUnitMeasureId()); |
| | | item.setTotalPrice(MoneyUtils.priceMultiply(item.getProductPrice(), item.getCount())); |
| | | if (item.getTotalPrice() == null) { |
| | | return; |
| | | } |
| | | if (item.getTaxPercent() != null) { |
| | | item.setTaxPrice(MoneyUtils.priceMultiplyPercent(item.getTotalPrice(), item.getTaxPercent())); |
| | | } |
| | | })); |
| | | } |
| | | |
| | | private void updatePurchaseReturnItemList(Long id, List<ErpPurchaseReturnItemDO> newList) { |
| | | // ç¬¬ä¸æ¥ï¼å¯¹æ¯æ°èæ°æ®ï¼è·å¾æ·»å ãä¿®æ¹ãå é¤çå表 |
| | | List<ErpPurchaseReturnItemDO> oldList = purchaseReturnItemMapper.selectListByReturnId(id); |
| | | List<List<ErpPurchaseReturnItemDO>> diffList = diffList(oldList, newList, // id ä¸åï¼å°±è®¤ä¸ºæ¯ä¸åçè®°å½ |
| | | (oldVal, newVal) -> oldVal.getId().equals(newVal.getId())); |
| | | |
| | | // ç¬¬äºæ¥ï¼æ¹éæ·»å ãä¿®æ¹ãå é¤ |
| | | if (CollUtil.isNotEmpty(diffList.get(0))) { |
| | | diffList.get(0).forEach(o -> o.setReturnId(id)); |
| | | purchaseReturnItemMapper.insertBatch(diffList.get(0)); |
| | | } |
| | | if (CollUtil.isNotEmpty(diffList.get(1))) { |
| | | purchaseReturnItemMapper.updateBatch(diffList.get(1)); |
| | | } |
| | | if (CollUtil.isNotEmpty(diffList.get(2))) { |
| | | purchaseReturnItemMapper.deleteByIds(convertList(diffList.get(2), ErpPurchaseReturnItemDO::getId)); |
| | | } |
| | | } |
| | | |
| | | @Override |
| | | @Transactional(rollbackFor = Exception.class) |
| | | public void deletePurchaseReturn(List<Long> ids) { |
| | | // 1. æ ¡éªä¸å¤äºå·²å®¡æ¹ |
| | | List<ErpPurchaseReturnDO> purchaseReturns = purchaseReturnMapper.selectByIds(ids); |
| | | if (CollUtil.isEmpty(purchaseReturns)) { |
| | | return; |
| | | } |
| | | purchaseReturns.forEach(purchaseReturn -> { |
| | | if (ErpAuditStatus.APPROVE.getStatus().equals(purchaseReturn.getStatus())) { |
| | | throw exception(PURCHASE_RETURN_DELETE_FAIL_APPROVE, purchaseReturn.getNo()); |
| | | } |
| | | }); |
| | | |
| | | // 2. éåå é¤ï¼å¹¶è®°å½æä½æ¥å¿ |
| | | purchaseReturns.forEach(purchaseReturn -> { |
| | | // 2.1 å é¤è®¢å |
| | | purchaseReturnMapper.deleteById(purchaseReturn.getId()); |
| | | // 2.2 å é¤è®¢å项 |
| | | purchaseReturnItemMapper.deleteByReturnId(purchaseReturn.getId()); |
| | | |
| | | // 2.3 æ´æ°éè´è®¢åçåºåºæ°é |
| | | updatePurchaseOrderReturnCount(purchaseReturn.getOrderId()); |
| | | }); |
| | | |
| | | } |
| | | |
| | | private ErpPurchaseReturnDO validatePurchaseReturnExists(Long id) { |
| | | ErpPurchaseReturnDO purchaseReturn = purchaseReturnMapper.selectById(id); |
| | | if (purchaseReturn == null) { |
| | | throw exception(PURCHASE_RETURN_NOT_EXISTS); |
| | | } |
| | | return purchaseReturn; |
| | | } |
| | | |
| | | @Override |
| | | public ErpPurchaseReturnDO getPurchaseReturn(Long id) { |
| | | return purchaseReturnMapper.selectById(id); |
| | | } |
| | | |
| | | @Override |
| | | public ErpPurchaseReturnDO validatePurchaseReturn(Long id) { |
| | | ErpPurchaseReturnDO purchaseReturn = getPurchaseReturn(id); |
| | | if (ObjectUtil.notEqual(purchaseReturn.getStatus(), ErpAuditStatus.APPROVE.getStatus())) { |
| | | throw exception(PURCHASE_RETURN_NOT_APPROVE); |
| | | } |
| | | return purchaseReturn; |
| | | } |
| | | |
| | | @Override |
| | | public PageResult<ErpPurchaseReturnDO> getPurchaseReturnPage(ErpPurchaseReturnPageReqVO pageReqVO) { |
| | | return purchaseReturnMapper.selectPage(pageReqVO); |
| | | } |
| | | |
| | | // ==================== éè´é货项 ==================== |
| | | |
| | | @Override |
| | | public List<ErpPurchaseReturnItemDO> getPurchaseReturnItemListByReturnId(Long returnId) { |
| | | return purchaseReturnItemMapper.selectListByReturnId(returnId); |
| | | } |
| | | |
| | | @Override |
| | | public List<ErpPurchaseReturnItemDO> getPurchaseReturnItemListByReturnIds(Collection<Long> returnIds) { |
| | | if (CollUtil.isEmpty(returnIds)) { |
| | | return Collections.emptyList(); |
| | | } |
| | | return purchaseReturnItemMapper.selectListByReturnIds(returnIds); |
| | | } |
| | | |
| | | } |
| | |
| | | package cn.iocoder.yudao.module.erp.service.statistics; |
| | | |
| | | import cn.iocoder.yudao.framework.common.pojo.PageResult; |
| | | import cn.iocoder.yudao.module.erp.controller.admin.statistics.vo.purchase.ErpPurchasePriceAnalysisRespVO; |
| | | import cn.iocoder.yudao.module.erp.controller.admin.statistics.vo.purchase.ErpPurchaseStatisticsReqVO; |
| | | import cn.iocoder.yudao.module.erp.controller.admin.statistics.vo.purchase.ErpPurchaseSummaryRespVO; |
| | | import cn.iocoder.yudao.module.erp.controller.admin.statistics.vo.purchase.ErpPurchaseSupplierStatisticsRespVO; |
| | | import cn.iocoder.yudao.module.erp.controller.admin.statistics.vo.purchase.ErpPurchaseUncompletedOrderRespVO; |
| | | |
| | | import java.math.BigDecimal; |
| | | import java.time.LocalDateTime; |
| | | |
| | |
| | | */ |
| | | BigDecimal getPurchasePrice(LocalDateTime beginTime, LocalDateTime endTime); |
| | | |
| | | /** |
| | | * è·å¾éè´æ±æ»ç»è®¡ï¼è®¢å / å
¥åº / éè´§çæ»æ°ä¸æ»éé¢ï¼ |
| | | * |
| | | * @return æ±æ»ç»è®¡ |
| | | */ |
| | | ErpPurchaseSummaryRespVO getPurchaseSummary(); |
| | | |
| | | /** |
| | | * è·å¾ä¾åºåä¾è´§ç»è®¡ |
| | | * |
| | | * @param reqVO æ¥è¯¢æ¡ä»¶ |
| | | * @return åé¡µç»æ |
| | | */ |
| | | PageResult<ErpPurchaseSupplierStatisticsRespVO> getSupplierStatistics(ErpPurchaseStatisticsReqVO reqVO); |
| | | |
| | | /** |
| | | * è·å¾éè´ä»·æ ¼åæ |
| | | * |
| | | * @param reqVO æ¥è¯¢æ¡ä»¶ |
| | | * @return åé¡µç»æ |
| | | */ |
| | | PageResult<ErpPurchasePriceAnalysisRespVO> getPriceAnalysis(ErpPurchaseStatisticsReqVO reqVO); |
| | | |
| | | /** |
| | | * è·å¾æªå®æéè´è®¢åè·è¸ª |
| | | * |
| | | * @param reqVO æ¥è¯¢æ¡ä»¶ |
| | | * @return åé¡µç»æ |
| | | */ |
| | | PageResult<ErpPurchaseUncompletedOrderRespVO> getUncompletedOrders(ErpPurchaseStatisticsReqVO reqVO); |
| | | |
| | | } |
| | |
| | | package cn.iocoder.yudao.module.erp.service.statistics; |
| | | |
| | | import cn.hutool.core.collection.CollUtil; |
| | | import cn.iocoder.yudao.framework.common.pojo.PageResult; |
| | | import cn.iocoder.yudao.framework.common.util.collection.MapUtils; |
| | | import cn.iocoder.yudao.module.erp.controller.admin.statistics.vo.purchase.ErpPurchasePriceAnalysisRespVO; |
| | | import cn.iocoder.yudao.module.erp.controller.admin.statistics.vo.purchase.ErpPurchaseStatisticsReqVO; |
| | | import cn.iocoder.yudao.module.erp.controller.admin.statistics.vo.purchase.ErpPurchaseSummaryRespVO; |
| | | import cn.iocoder.yudao.module.erp.controller.admin.statistics.vo.purchase.ErpPurchaseSupplierStatisticsRespVO; |
| | | import cn.iocoder.yudao.module.erp.controller.admin.statistics.vo.purchase.ErpPurchaseUncompletedOrderRespVO; |
| | | import cn.iocoder.yudao.module.erp.dal.dataobject.purchase.ErpPurchaseOrderItemDO; |
| | | import cn.iocoder.yudao.module.erp.dal.mysql.purchase.ErpPurchaseOrderItemMapper; |
| | | import cn.iocoder.yudao.module.erp.dal.mysql.statistics.ErpPurchaseStatisticsMapper; |
| | | import cn.iocoder.yudao.module.mdm.api.item.MdmItemApi; |
| | | import cn.iocoder.yudao.module.mdm.api.item.dto.MdmItemRespDTO; |
| | | import com.baomidou.mybatisplus.extension.plugins.pagination.Page; |
| | | import jakarta.annotation.Resource; |
| | | import org.springframework.stereotype.Service; |
| | | |
| | | import java.math.BigDecimal; |
| | | import java.math.RoundingMode; |
| | | import java.time.LocalDateTime; |
| | | import java.util.Collections; |
| | | import java.util.List; |
| | | import java.util.Map; |
| | | import java.util.stream.Collectors; |
| | | |
| | | import static cn.iocoder.yudao.framework.common.util.collection.CollectionUtils.convertMultiMap; |
| | | import static cn.iocoder.yudao.framework.common.util.collection.CollectionUtils.convertSet; |
| | | |
| | | /** |
| | | * ERP éè´ç»è®¡ Service å®ç°ç±» |
| | |
| | | |
| | | @Resource |
| | | private ErpPurchaseStatisticsMapper purchaseStatisticsMapper; |
| | | @Resource |
| | | private ErpPurchaseOrderItemMapper purchaseOrderItemMapper; |
| | | @Resource |
| | | private MdmItemApi mdmItemApi; |
| | | |
| | | @Override |
| | | public BigDecimal getPurchasePrice(LocalDateTime beginTime, LocalDateTime endTime) { |
| | | return purchaseStatisticsMapper.getPurchasePrice(beginTime, endTime); |
| | | } |
| | | |
| | | @Override |
| | | public ErpPurchaseSummaryRespVO getPurchaseSummary() { |
| | | ErpPurchaseSummaryRespVO summary = purchaseStatisticsMapper.selectPurchaseSummary(); |
| | | return summary != null ? summary : new ErpPurchaseSummaryRespVO() |
| | | .setTotalOrderCount(0L).setTotalOrderAmount(BigDecimal.ZERO) |
| | | .setTotalInCount(0L).setTotalInAmount(BigDecimal.ZERO) |
| | | .setTotalReturnCount(0L).setTotalReturnAmount(BigDecimal.ZERO); |
| | | } |
| | | |
| | | @Override |
| | | public PageResult<ErpPurchaseSupplierStatisticsRespVO> getSupplierStatistics(ErpPurchaseStatisticsReqVO reqVO) { |
| | | Page<ErpPurchaseSupplierStatisticsRespVO> page = new Page<>(reqVO.getPageNo(), reqVO.getPageSize()); |
| | | purchaseStatisticsMapper.selectSupplierStatistics(page, reqVO); |
| | | return new PageResult<>(page.getRecords(), page.getTotal()); |
| | | } |
| | | |
| | | @Override |
| | | public PageResult<ErpPurchasePriceAnalysisRespVO> getPriceAnalysis(ErpPurchaseStatisticsReqVO reqVO) { |
| | | Page<ErpPurchasePriceAnalysisRespVO> page = new Page<>(reqVO.getPageNo(), reqVO.getPageSize()); |
| | | purchaseStatisticsMapper.selectPriceAnalysis(page, reqVO); |
| | | fillProductInfo(page.getRecords()); |
| | | return new PageResult<>(page.getRecords(), page.getTotal()); |
| | | } |
| | | |
| | | @Override |
| | | public PageResult<ErpPurchaseUncompletedOrderRespVO> getUncompletedOrders(ErpPurchaseStatisticsReqVO reqVO) { |
| | | Page<ErpPurchaseUncompletedOrderRespVO> page = new Page<>(reqVO.getPageNo(), reqVO.getPageSize()); |
| | | purchaseStatisticsMapper.selectUncompletedOrders(page, reqVO); |
| | | fillUncompletedOrderInfo(page.getRecords()); |
| | | return new PageResult<>(page.getRecords(), page.getTotal()); |
| | | } |
| | | |
| | | /** |
| | | * è¡¥å
¨äº§ååç§°ãæ¡ç ï¼å¹¶è®¡ç®ä»·æ ¼ååç |
| | | */ |
| | | private void fillProductInfo(List<ErpPurchasePriceAnalysisRespVO> list) { |
| | | if (CollUtil.isEmpty(list)) { |
| | | return; |
| | | } |
| | | Map<Long, MdmItemRespDTO> itemMap = mdmItemApi.getItemMap( |
| | | convertSet(list, ErpPurchasePriceAnalysisRespVO::getProductId)); |
| | | list.forEach(vo -> { |
| | | MapUtils.findAndThen(itemMap, vo.getProductId(), item -> vo |
| | | .setProductName(item.getName()).setProductBarCode(item.getBarCode())); |
| | | // ä»·æ ¼ååç = (æè¿ä»·æ ¼ - å¹³åä»·æ ¼) / å¹³åä»·æ ¼ à 100 |
| | | if (vo.getLatestPrice() == null || vo.getAvgPrice() == null |
| | | || vo.getAvgPrice().compareTo(BigDecimal.ZERO) == 0) { |
| | | vo.setPriceChangeRate(BigDecimal.ZERO); |
| | | return; |
| | | } |
| | | vo.setPriceChangeRate(vo.getLatestPrice().subtract(vo.getAvgPrice()) |
| | | .multiply(BigDecimal.valueOf(100)) |
| | | .divide(vo.getAvgPrice(), 2, RoundingMode.HALF_UP)); |
| | | }); |
| | | } |
| | | |
| | | /** |
| | | * è¡¥å
¨äº§ååç§°ï¼å¹¶è®¡ç®æªå®æéé¢ |
| | | */ |
| | | private void fillUncompletedOrderInfo(List<ErpPurchaseUncompletedOrderRespVO> list) { |
| | | if (CollUtil.isEmpty(list)) { |
| | | return; |
| | | } |
| | | List<ErpPurchaseOrderItemDO> orderItems = purchaseOrderItemMapper.selectListByOrderIds( |
| | | convertSet(list, ErpPurchaseUncompletedOrderRespVO::getOrderId)); |
| | | Map<Long, List<ErpPurchaseOrderItemDO>> orderItemMap = convertMultiMap(orderItems, ErpPurchaseOrderItemDO::getOrderId); |
| | | Map<Long, MdmItemRespDTO> itemMap = mdmItemApi.getItemMap( |
| | | convertSet(orderItems, ErpPurchaseOrderItemDO::getProductId)); |
| | | list.forEach(vo -> { |
| | | List<ErpPurchaseOrderItemDO> items = orderItemMap.getOrDefault(vo.getOrderId(), Collections.emptyList()); |
| | | vo.setProductNames(items.stream() |
| | | .map(item -> { |
| | | MdmItemRespDTO mdmItem = itemMap.get(item.getProductId()); |
| | | return mdmItem != null ? mdmItem.getName() : "ID=" + item.getProductId(); |
| | | }) |
| | | .distinct() |
| | | .collect(Collectors.joining("ï¼"))); |
| | | BigDecimal orderAmount = vo.getOrderAmount() != null ? vo.getOrderAmount() : BigDecimal.ZERO; |
| | | BigDecimal inAmount = vo.getInAmount() != null ? vo.getInAmount() : BigDecimal.ZERO; |
| | | vo.setUncompletedAmount(orderAmount.subtract(inAmount)); |
| | | }); |
| | | } |
| | | |
| | | } |
| | |
| | | <if test="endTime != null"> |
| | | AND in_time < #{endTime} |
| | | </if> |
| | | <if test="@cn.iocoder.yudao.framework.tenant.core.context.TenantContextHolder@getTenantId() != null"> |
| | | AND tenant_id = ${@cn.iocoder.yudao.framework.tenant.core.context.TenantContextHolder@getTenantId()} |
| | | </if> |
| | | AND deleted = 0) - |
| | | (SELECT IFNULL(SUM(total_price), 0) |
| | | FROM erp_purchase_return |
| | |
| | | <if test="endTime != null"> |
| | | AND return_time < #{endTime} |
| | | </if> |
| | | <if test="@cn.iocoder.yudao.framework.tenant.core.context.TenantContextHolder@getTenantId() != null"> |
| | | AND tenant_id = ${@cn.iocoder.yudao.framework.tenant.core.context.TenantContextHolder@getTenantId()} |
| | | </if> |
| | | AND deleted = 0) |
| | | </select> |
| | | |
| | | </mapper> |
| | | <select id="selectPurchaseSummary" |
| | | resultType="cn.iocoder.yudao.module.erp.controller.admin.statistics.vo.purchase.ErpPurchaseSummaryRespVO"> |
| | | SELECT |
| | | (SELECT COUNT(1) FROM erp_purchase_order WHERE deleted = 0) AS totalOrderCount, |
| | | (SELECT IFNULL(SUM(total_price), 0) FROM erp_purchase_order WHERE deleted = 0) AS totalOrderAmount, |
| | | (SELECT COUNT(1) FROM erp_purchase_in WHERE deleted = 0) AS totalInCount, |
| | | (SELECT IFNULL(SUM(total_price), 0) FROM erp_purchase_in WHERE deleted = 0) AS totalInAmount, |
| | | (SELECT COUNT(1) FROM erp_purchase_return WHERE deleted = 0) AS totalReturnCount, |
| | | (SELECT IFNULL(SUM(total_price), 0) FROM erp_purchase_return WHERE deleted = 0) AS totalReturnAmount |
| | | </select> |
| | | |
| | | <select id="selectSupplierStatistics" |
| | | resultType="cn.iocoder.yudao.module.erp.controller.admin.statistics.vo.purchase.ErpPurchaseSupplierStatisticsRespVO"> |
| | | SELECT s.id AS supplierId, |
| | | s.name AS supplierName, |
| | | IFNULL(o.order_count, 0) AS orderCount, |
| | | IFNULL(o.order_amount, 0) AS orderAmount, |
| | | IFNULL(i.in_count, 0) AS inCount, |
| | | IFNULL(i.in_amount, 0) AS inAmount, |
| | | IFNULL(r.return_count, 0) AS returnCount, |
| | | IFNULL(r.return_amount, 0) AS returnAmount |
| | | FROM srm_supplier s |
| | | INNER JOIN ( |
| | | SELECT supplier_id, |
| | | COUNT(1) AS order_count, |
| | | IFNULL(SUM(total_price), 0) AS order_amount |
| | | FROM erp_purchase_order |
| | | WHERE deleted = 0 |
| | | AND supplier_id IS NOT NULL |
| | | <if test="reqVO.supplierId != null"> |
| | | AND supplier_id = #{reqVO.supplierId} |
| | | </if> |
| | | <if test="reqVO.orderTime != null and reqVO.orderTime.length == 2"> |
| | | AND order_time BETWEEN #{reqVO.orderTime[0]} AND #{reqVO.orderTime[1]} |
| | | </if> |
| | | GROUP BY supplier_id |
| | | ) o ON o.supplier_id = s.id |
| | | LEFT JOIN ( |
| | | SELECT po.supplier_id, |
| | | COUNT(1) AS in_count, |
| | | IFNULL(SUM(pi.total_price), 0) AS in_amount |
| | | FROM erp_purchase_in pi |
| | | INNER JOIN erp_purchase_order po ON po.id = pi.order_id AND po.deleted = 0 |
| | | WHERE pi.deleted = 0 |
| | | <if test="reqVO.supplierId != null"> |
| | | AND po.supplier_id = #{reqVO.supplierId} |
| | | </if> |
| | | <if test="reqVO.orderTime != null and reqVO.orderTime.length == 2"> |
| | | AND po.order_time BETWEEN #{reqVO.orderTime[0]} AND #{reqVO.orderTime[1]} |
| | | </if> |
| | | GROUP BY po.supplier_id |
| | | ) i ON i.supplier_id = s.id |
| | | LEFT JOIN ( |
| | | SELECT po.supplier_id, |
| | | COUNT(1) AS return_count, |
| | | IFNULL(SUM(pr.total_price), 0) AS return_amount |
| | | FROM erp_purchase_return pr |
| | | INNER JOIN erp_purchase_order po ON po.id = pr.order_id AND po.deleted = 0 |
| | | WHERE pr.deleted = 0 |
| | | <if test="reqVO.supplierId != null"> |
| | | AND po.supplier_id = #{reqVO.supplierId} |
| | | </if> |
| | | <if test="reqVO.orderTime != null and reqVO.orderTime.length == 2"> |
| | | AND po.order_time BETWEEN #{reqVO.orderTime[0]} AND #{reqVO.orderTime[1]} |
| | | </if> |
| | | GROUP BY po.supplier_id |
| | | ) r ON r.supplier_id = s.id |
| | | WHERE s.deleted = 0 |
| | | <if test="reqVO.supplierId != null"> |
| | | AND s.id = #{reqVO.supplierId} |
| | | </if> |
| | | ORDER BY orderAmount DESC, supplierId ASC |
| | | </select> |
| | | |
| | | <select id="selectPriceAnalysis" |
| | | resultType="cn.iocoder.yudao.module.erp.controller.admin.statistics.vo.purchase.ErpPurchasePriceAnalysisRespVO"> |
| | | SELECT item.product_id AS productId, |
| | | AVG(item.product_price) AS avgPrice, |
| | | MIN(item.product_price) AS minPrice, |
| | | MAX(item.product_price) AS maxPrice, |
| | | (SELECT i2.product_price |
| | | FROM erp_purchase_order_items i2 |
| | | INNER JOIN erp_purchase_order o2 ON o2.id = i2.order_id AND o2.deleted = 0 |
| | | WHERE i2.deleted = 0 |
| | | AND i2.product_id = item.product_id |
| | | ORDER BY o2.order_time DESC, i2.id DESC |
| | | LIMIT 1) AS latestPrice |
| | | FROM erp_purchase_order_items item |
| | | INNER JOIN erp_purchase_order o ON o.id = item.order_id AND o.deleted = 0 |
| | | WHERE item.deleted = 0 |
| | | <if test="reqVO.productId != null"> |
| | | AND item.product_id = #{reqVO.productId} |
| | | </if> |
| | | <if test="reqVO.orderTime != null and reqVO.orderTime.length == 2"> |
| | | AND o.order_time BETWEEN #{reqVO.orderTime[0]} AND #{reqVO.orderTime[1]} |
| | | </if> |
| | | GROUP BY item.product_id |
| | | ORDER BY productId ASC |
| | | </select> |
| | | |
| | | <select id="selectUncompletedOrders" |
| | | resultType="cn.iocoder.yudao.module.erp.controller.admin.statistics.vo.purchase.ErpPurchaseUncompletedOrderRespVO"> |
| | | SELECT o.id AS orderId, |
| | | o.no AS orderNo, |
| | | s.name AS supplierName, |
| | | o.order_time AS orderTime, |
| | | o.total_price AS orderAmount, |
| | | IFNULL((SELECT IFNULL(SUM(i.total_price), 0) |
| | | FROM erp_purchase_in i |
| | | WHERE i.order_id = o.id AND i.deleted = 0 AND i.status = 20), 0) AS inAmount, |
| | | GREATEST(DATEDIFF(CURDATE(), DATE(o.order_time)) - 30, 0) AS daysOverdue |
| | | FROM erp_purchase_order o |
| | | LEFT JOIN srm_supplier s ON s.id = o.supplier_id AND s.deleted = 0 |
| | | WHERE o.deleted = 0 |
| | | AND o.status = 20 |
| | | AND (o.in_status IS NULL OR o.in_status != 2) |
| | | <if test="reqVO.supplierId != null"> |
| | | AND o.supplier_id = #{reqVO.supplierId} |
| | | </if> |
| | | <if test="reqVO.orderNo != null and reqVO.orderNo != ''"> |
| | | AND o.no LIKE CONCAT('%', #{reqVO.orderNo}, '%') |
| | | </if> |
| | | <if test="reqVO.orderTime != null and reqVO.orderTime.length == 2"> |
| | | AND o.order_time BETWEEN #{reqVO.orderTime[0]} AND #{reqVO.orderTime[1]} |
| | | </if> |
| | | ORDER BY o.order_time ASC, o.id ASC |
| | | </select> |
| | | |
| | | </mapper> |