doc/20260522_StockInRecordÁбíÔ´µ¥ºÅǰ¶ËÁªµ÷Îĵµ.md
¶Ô±ÈÐÂÎļþ @@ -0,0 +1,75 @@ # StockInRecord å表æºåå·å端èè°ææ¡£ æ´æ°æ¶é´ï¼2026-05-22 éç¨æ¥å£ï¼`GET /stockInRecord/listPage` ## 1. åæ´è¯´æ æ¬æ¬¡å¯¹å ¥åºç®¡çå表æ¥å£å¢å è¿ååæ®µ `sourceOrderNo`ï¼æºåå·ï¼ï¼ç¨äºåææåºæ¯å±ç¤ºéè´æ¥æºåå·ã çææ¡ä»¶ï¼ - å½è¯·æ±åæ° `topParentProductId = 278` æ¶ï¼å端è¿å `sourceOrderNo`ã - å ¶ä» `topParentProductId` åºæ¯ä¸ï¼è¯¥å段è¿å `null`ï¼æä¸å±ç¤ºï¼ã ## 2. åæ®µå®ä¹ æ°å¢åæ®µï¼ - `sourceOrderNo`ï¼`string`ï¼æºåå·ï¼éè´ååå·ï¼ã ## 3. åå¼è§å ä» å¨ `topParentProductId = 278` æ¶æâæ¥æºâ计ç®ï¼ 1. æ¥æº = `éè´-å ¥åº`ï¼`recordType = 7`ï¼ - å æ `recordId` æ¥éè´äº§å表 `sales_ledger_product`ï¼`type=2`ï¼ï¼ - åéè¿ `sales_ledger_product.sales_ledger_id` æ¥éè´å°è´¦è¡¨ `purchase_ledger`ï¼ - è¿å `purchase_ledger.purchase_contract_number` ä½ä¸º `sourceOrderNo`ã - å ¼å®¹å åºï¼è¥æªå½ä¸éè´äº§åé¾è·¯ï¼åæ `recordId` ç´æ¥æ¥ `purchase_ledger.id` ååå·ã 2. æ¥æº = `éè´-è´¨æ£-åæ ¼å ¥åº`ï¼`recordType = 10`ï¼ - å æ `recordId` æ¥è´¨æ£è¡¨ `quality_inspect`ï¼ - åéè¿ `quality_inspect.purchase_ledger_id` æ¥éè´å°è´¦è¡¨ `purchase_ledger`ï¼ - è¿å `purchase_ledger.purchase_contract_number` ä½ä¸º `sourceOrderNo`ã ## 4. è¿åç¤ºä¾ ```json { "code": 200, "msg": "æä½æå", "data": { "records": [ { "id": 1024, "recordType": "7", "productName": "éæ", "model": "T2-30x3", "sourceOrderNo": "CG-2026-00128" }, { "id": 1025, "recordType": "10", "productName": "éæ", "model": "T2-30x3", "sourceOrderNo": "CG-2026-00131" } ], "total": 2 } } ``` ## 5. å端èè°å»ºè®® 1. åè¡¨åæ°å¢âæºåå·âï¼è¯»ååæ®µ `sourceOrderNo`ã 2. å»ºè®®ä» å¨ `topParentProductId = 278` ç页é¢/ç鿡件ä¸å±ç¤ºè¯¥åã 3. å½ `sourceOrderNo` 为空æ¶å±ç¤º `--`ï¼é¿å 空ç½ã ## 6. å彿¸ å 1. `topParentProductId=278` + `recordType=7`ï¼åºè¿åéè´ååå·ã 2. `topParentProductId=278` + `recordType=10`ï¼åºè¿åéè´ååå·ï¼ç»è´¨æ£é¾è·¯ï¼ã 3. `topParentProductId!=278`ï¼`sourceOrderNo` åºä¸º `null` æå端ä¸å±ç¤ºã 4. åæå段ï¼`productName/model/unit/createBy` çï¼ä¸åå½±åã doc/20260522_StockInRecordÁбíÔ´µ¥ºÅǰ¶ËÁªµ÷Îĵµ_276²¹³ä.md
¶Ô±ÈÐÂÎļþ @@ -0,0 +1,65 @@ # StockInRecord å表æºåå·å端èè°ææ¡£ï¼`topParentProductId=276`è¡¥å ï¼ æ´æ°æ¶é´ï¼2026-05-22 éç¨æ¥å£ï¼`GET /stockInRecord/listPage` ## 1. åæ´è¯´æ å¨å·²æ `sourceOrderNo` åºç¡ä¸ï¼æ°å¢ `topParentProductId = 276` çæºåå·æº¯æºé»è¾ï¼ - æ ¹æ®âæ¥æºï¼recordTypeï¼+ recordIdâæº¯æºï¼ - ä¼å è¿åéå®åå·ï¼éå®ååå·ï¼ï¼ - è¥éå®åå·ä¸ºç©ºï¼ååéè¿åç产订åå·ï¼ - ä¸èèèªå®ä¹å ¥åºï¼`recordType=0/9`ï¼ã ## 2. è¿ååæ®µ åæ®µæ æ°å¢ï¼ç»§ç»ä½¿ç¨ï¼ - `sourceOrderNo`ï¼`string`ï¼æºåå·ã ## 3. 276 åºæ¯åå¼è§å 请æ±åæ°æ»¡è¶³ `topParentProductId = 276` æ¶ï¼ 1. `recordType = 14/15`ï¼éå®éè´§-åæ ¼/ä¸åæ ¼å ¥åºï¼ - `stock_in_record.record_id -> return_sale_product.id -> return_management.shipping_id -> shipping_info.sales_ledger_id -> sales_ledger.sales_contract_no` - è¿åéå®ååå·ã 2. `recordType = 2/5`ï¼ç产æ¥å·¥-å ¥åº/æ¥åºï¼ - `stock_in_record.record_id -> production_product_main.id -> production_operation_task.production_order_id -> production_order` - å å该ç产订åå ³èéå®ååå·ï¼ç±ç产计åå ³èéå®å°è´¦èåï¼ï¼ - éå®ååå·ä¸ºç©ºæ¶ï¼è¿å `production_order.nps_no`ã 3. `recordType = 6`ï¼è´¨æ£-åæ ¼å ¥åºï¼ - `stock_in_record.record_id -> quality_inspect.id -> quality_inspect.product_main_id -> production_product_main -> production_operation_task -> production_order` - å åéå®ååå·ï¼ç©ºååé `production_order.nps_no`ã 4. `recordType = 4/11`ï¼ä¸åæ ¼å¤ç-æ¥åº/è®©æ¥æ¾è¡ï¼ - `stock_in_record.record_id -> quality_unqualified.id -> quality_unqualified.inspect_id -> quality_inspect -> production_product_main -> production_operation_task -> production_order` - å åéå®ååå·ï¼ç©ºååé `production_order.nps_no`ã 5. `recordType = 20/22`ï¼é¢æéæ/ç产éæ-åæ ¼å ¥åºï¼ - `stock_in_record.record_id -> production_order_pick.id -> production_order` - å åéå®ååå·ï¼ç©ºååé `production_order.nps_no`ã 6. `recordType = 0/9`ï¼èªå®ä¹å ¥åºï¼ - ä¸å䏿º¯æºï¼`sourceOrderNo = null`ã ## 4. å ¶ä»åºæ¯è¯´æ - `topParentProductId = 278` çéè´é¾è·¯æºåå·é»è¾ä¿æä¸åã - å ¶ä» `topParentProductId` ä¸è§¦åæ¬æ¬¡ 276 è§åï¼`sourceOrderNo` 为空ã ## 5. å端èè°å»ºè®® 1. å¨ `topParentProductId=276` çåè¡¨åºæ¯å±ç¤ºâæºåå·âåï¼è¯»å `sourceOrderNo`ã 2. 建议空å¼ç»ä¸å±ç¤º `--`ã 3. ä¸éè¦æ°å¢è¯·æ±åæ°ï¼æ²¿ç¨ç°æ `/stockInRecord/listPage`ã ## 6. å彿¸ å 1. `topParentProductId=276` + `recordType=14/15`ï¼åºè¿åéå®ååå·ã 2. `topParentProductId=276` + `recordType=2/5/6/4/11/20/22`ï¼ä¼å éå®ååå·ï¼ç¼ºå¤±æ¶è¿åç产订åå·ã 3. `topParentProductId=276` + `recordType=0/9`ï¼`sourceOrderNo` 为空ã 4. `topParentProductId=278`ï¼ä»æéè´é¾è·¯è¿åéè´ååå·ã doc/20260522_²É¹ºÌ¨ÕËÈë¿â״̬_ÏúÊÛ²úÆ·Èë¿âÉóºË״̬ǰ¶ËÁªµ÷Îĵµ.md
¶Ô±ÈÐÂÎļþ @@ -0,0 +1,127 @@ # éè´å ¥åºç¶æå端èè°ææ¡£ æ´æ°æ¶é´ï¼2026-05-22 éç¨çæ¬ï¼æ¬æ¬¡åç«¯åæ´å ## 1. åæ´èå´ 1. `GET /purchaseLedger/listPage` - æ°å¢æ¥è¯¢æ¡ä»¶ï¼`stockInStatus`ï¼å ¥åºç¶æï¼ - æ°å¢è¿ååæ®µï¼`stockInStatus`ï¼å ¥åºç¶æï¼ 2. `GET /salesLedgerProduct/list` - æ°å¢è¿ååæ®µï¼`stockInApprovalStatus`ï¼æ¯ä¸ªäº§åçå ¥åºå®¡æ ¸ç¶æï¼ --- ## 2. å ¥åºç¶ææä¸¾ï¼ä¸¤æ¥å£ä¸è´ï¼ - `å¾ å ¥åº` - `å ¥åºä¸` - `å®å ¨å ¥åº` 说æï¼å端çéå¼è¯·ç´æ¥ä½¿ç¨ä»¥ä¸ä¸ææä¸¾å¼ã --- ## 3. æ¥å£ä¸ï¼`GET /purchaseLedger/listPage` ### 3.1 æ°å¢è¯·æ±åæ° - `stockInStatus`ï¼`string`ï¼å¯é å¯ä¼ å¼ï¼`å¾ å ¥åº` / `å ¥åºä¸` / `å®å ¨å ¥åº` ### 3.2 æ°å¢è¿ååæ®µ - `stockInStatus`ï¼`string`ï¼éè´å°è´¦ç»´åº¦å ¥åºç¶æ ### 3.3 ç¶æè®¡ç®è§åï¼éè´å°è´¦ç»´åº¦ï¼ 以该éè´å°è´¦ä¸ `sales_ledger_product.type = 2` çéè´äº§å为计ç®èå´ï¼ 1. å ¨é¨äº§åé½è¾¾å°âå®å ¨å ¥åºâ => å°è´¦ç¶æ `å®å ¨å ¥åº` 2. è³å°æä¸ä¸ªäº§ååå¨âå®¡æ ¸éè¿å ¥åºâï¼ä½æªå ¨é¨å®å ¨å ¥åº => å°è´¦ç¶æ `å ¥åºä¸` 3. 没æä»»ä½äº§ååå¨âå®¡æ ¸éè¿å ¥åºâ => å°è´¦ç¶æ `å¾ å ¥åº` âå®¡æ ¸éè¿å ¥åºâç»è®¡å£å¾ï¼`stock_in_record.approval_status = 1`ï¼å¹¶æä»¥ä¸æ¥æºæº¯æºï¼ - `record_type = 7`ï¼éè´-å ¥åºï¼ï¼æéè´å°è´¦+产åå ³èç»è®¡ - `record_type = 10`ï¼éè´-è´¨æ£-åæ ¼å ¥åºï¼ï¼éè¿ `quality_inspect` åæº¯å°éè´å°è´¦+产åç»è®¡ ### 3.4 è¿å示ä¾ï¼èéï¼ ```json { "code": 200, "msg": "æä½æå", "data": { "records": [ { "id": 1201, "purchaseContractNumber": "CG20260522001", "supplierName": "XXä¾åºå", "stockInStatus": "å ¥åºä¸" } ], "total": 1 } } ``` --- ## 4. æ¥å£äºï¼`GET /salesLedgerProduct/list` ### 4.1 æ°å¢è¿ååæ®µ - `stockInApprovalStatus`ï¼`string`ï¼å½å产åè¡çå ¥åºå®¡æ ¸ç¶æ ### 4.2 ç¶æè®¡ç®è§åï¼äº§åç»´åº¦ï¼ ä» å½äº§å `type = 2`ï¼éè´äº§åï¼æ¶è®¡ç®å¹¶è¿åï¼ 1. å®¡æ ¸éè¿å ¥åºæ°é `<= 0` => `å¾ å ¥åº` 2. å®¡æ ¸éè¿å ¥åºæ°é `>= 产åéè´æ°é` => `å®å ¨å ¥åº` 3. å ¶ä»æ åµ => `å ¥åºä¸` å ¶ä¸âå®¡æ ¸éè¿å ¥åºæ°éâç»è®¡åæ ·åºäºï¼ - `stock_in_record.approval_status = 1` - æ¥æº `record_type = 7 / 10` çæº¯æºå ³èé»è¾ `type != 2` ç产åï¼è¯¥å段è¿å `null`ã ### 4.3 è¿å示ä¾ï¼èéï¼ ```json { "code": 200, "msg": "æä½æå", "data": [ { "id": 5566, "type": 2, "productCategory": "éæ", "specificationModel": "T2-30x3", "quantity": 100, "stockInApprovalStatus": "å¾ å ¥åº" } ] } ``` --- ## 5. å端æ¹é 建议 1. éè´å°è´¦å表æ°å¢âå ¥åºç¶æâçé项ï¼å¼åºå®ï¼`å¾ å ¥åº/å ¥åºä¸/å®å ¨å ¥åº`ã 2. éè´å°è´¦å表æ°å¢âå ¥åºç¶æâåï¼å±ç¤º `stockInStatus`ã 3. éè´äº§åå表æ°å¢âå ¥åºå®¡æ ¸ç¶æâåï¼å±ç¤º `stockInApprovalStatus`ã 4. 空å¼ï¼å¦ `type != 2`ï¼å»ºè®®å±ç¤ºä¸º `--`ã --- ## 6. èè°æ£æ¥æ¸ å 1. `/purchaseLedger/listPage` ä¸ä¼ `stockInStatus`ï¼åºæ£å¸¸è¿åå ¨é¨æ°æ®ï¼å¹¶å¸¦ `stockInStatus`ã 2. `/purchaseLedger/listPage?stockInStatus=å¾ å ¥åº`ï¼ä» è¿åå¾ å ¥åºå°è´¦ã 3. `/purchaseLedger/listPage?stockInStatus=å ¥åºä¸`ï¼ä» è¿åå ¥åºä¸å°è´¦ã 4. `/purchaseLedger/listPage?stockInStatus=å®å ¨å ¥åº`ï¼ä» è¿åå®å ¨å ¥åºå°è´¦ã 5. `/salesLedgerProduct/list` å¨éè´äº§åï¼`type=2`ï¼ä¸è¿å `stockInApprovalStatus`ã 6. `/salesLedgerProduct/list` å¨ééè´äº§åï¼`type!=2`ï¼ä¸ `stockInApprovalStatus` 为 `null`ã src/main/java/com/ruoyi/home/dto/StatisticsReceivablePayableDto.java
@@ -19,10 +19,10 @@ @Schema(description = "åºä»éé¢") private BigDecimal payableMoney; @Schema(description = "颿¶éé¢") @Schema(description = "æ¶æ¬¾éé¢") private BigDecimal advanceMoney; @Schema(description = "é¢ä»éé¢") @Schema(description = "仿¬¾éé¢") private BigDecimal prepayMoney; } src/main/java/com/ruoyi/home/service/impl/HomeServiceImpl.java
@@ -3,10 +3,18 @@ import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper; import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper; import com.baomidou.mybatisplus.core.toolkit.ObjectUtils; import com.baomidou.mybatisplus.extension.plugins.pagination.Page; import com.ruoyi.account.bean.dto.purchase.PurchaseInboundDto; import com.ruoyi.account.bean.dto.purchase.PurchaseReturnDto; import com.ruoyi.account.bean.dto.sales.SalesOutboundDto; import com.ruoyi.account.bean.dto.sales.SalesReturnDto; import com.ruoyi.account.bean.vo.purchase.PurchaseInboundVo; import com.ruoyi.account.bean.vo.purchase.PurchaseReturnVo; import com.ruoyi.account.bean.vo.sales.SalesOutboundVo; import com.ruoyi.account.bean.vo.sales.SalesReturnVo; import com.ruoyi.account.mapper.AccountStatementMapper; import com.ruoyi.account.mapper.purchase.AccountPurchasePaymentMapper; import com.ruoyi.account.mapper.sales.AccountSalesCollectionMapper; import com.ruoyi.account.pojo.AccountStatement; import com.ruoyi.account.pojo.purchase.AccountPurchasePayment; import com.ruoyi.account.pojo.sales.AccountSalesCollection; import com.ruoyi.approve.mapper.ApproveProcessMapper; @@ -29,11 +37,13 @@ import com.ruoyi.home.dto.*; import com.ruoyi.home.mapper.HomeMapper; import com.ruoyi.home.service.HomeService; import com.ruoyi.procurementrecord.mapper.ReturnManagementMapper; import com.ruoyi.production.bean.dto.ProductionProductOutputDto; import com.ruoyi.production.mapper.*; import com.ruoyi.project.system.domain.SysDept; import com.ruoyi.project.system.mapper.SysDeptMapper; import com.ruoyi.purchase.mapper.PurchaseLedgerMapper; import com.ruoyi.purchase.mapper.PurchaseReturnOrdersMapper; import com.ruoyi.purchase.pojo.PurchaseLedger; import com.ruoyi.quality.mapper.QualityInspectMapper; import com.ruoyi.quality.mapper.QualityUnqualifiedMapper; @@ -45,7 +55,9 @@ import com.ruoyi.sales.pojo.SalesLedgerProduct; import com.ruoyi.staff.mapper.StaffOnJobMapper; import com.ruoyi.staff.pojo.StaffOnJob; import com.ruoyi.stock.mapper.StockInRecordMapper; import com.ruoyi.stock.mapper.StockInventoryMapper; import com.ruoyi.stock.mapper.StockOutRecordMapper; import lombok.RequiredArgsConstructor; import lombok.extern.slf4j.Slf4j; import org.springframework.stereotype.Service; @@ -71,6 +83,10 @@ public class HomeServiceImpl implements HomeService { private final SalesLedgerMapper salesLedgerMapper; private final StockOutRecordMapper stockOutRecordMapper; private final ReturnManagementMapper returnManagementMapper; private final StockInRecordMapper stockInRecordMapper; private final PurchaseReturnOrdersMapper purchaseReturnOrdersMapper; private final PurchaseLedgerMapper purchaseLedgerMapper; @@ -417,14 +433,26 @@ LocalDate startDate = range[0]; LocalDate endDate = range[1]; //éå®åºåº BigDecimal receivableBase = sumSalesContractAmount(startDate, endDate); //éå®éè´§ BigDecimal salesReturnAmount = sumSalesReturnAmount(startDate, endDate); //éè´å ¥åº BigDecimal payableBase = sumPurchaseContractAmount(startDate, endDate); //éè´éè´§ BigDecimal purchaseReturnAmount = sumPurchaseReturnAmount(startDate, endDate); //æ¶æ¬¾ BigDecimal advanceMoney = sumCollectionAmount(startDate, endDate); //仿¬¾ BigDecimal prepayMoney = sumPaymentAmount(startDate, endDate); dto.setReceivableMoney(scaleMoney(maxZero(receivableBase.subtract(advanceMoney)))); dto.setPayableMoney(scaleMoney(maxZero(payableBase.subtract(prepayMoney)))); //åºæ¶éé¢=éå®åºåº-éå®éè´§ dto.setReceivableMoney(scaleMoney(maxZero(receivableBase.subtract(salesReturnAmount)))); //åºä»éé¢=éè´å ¥åº-éè´éè´§ dto.setPayableMoney(scaleMoney(maxZero(payableBase.subtract(purchaseReturnAmount)))); //æ¶æ¬¾éé¢=æ¶æ¬¾å dto.setAdvanceMoney(scaleMoney(advanceMoney)); //仿¬¾éé¢=仿¬¾å dto.setPrepayMoney(scaleMoney(prepayMoney)); return dto; } @@ -1239,33 +1267,21 @@ YearMonth currentMonth = YearMonth.from(today); LocalDate startDate = currentMonth.atDay(1); LocalDate endDate = currentMonth.atEndOfMonth(); //æ¶æ¬¾ BigDecimal monthlyIncome = sumCollectionAmount(startDate, endDate); //éå®åºåº BigDecimal receivableBase = sumSalesContractAmount(startDate, endDate); String collectionRate = toRateString(monthlyIncome, receivableBase); String currentMonthText = currentMonth.toString(); List<AccountStatement> receivableStatements = defaultList(accountStatementMapper.selectList( new LambdaQueryWrapper<AccountStatement>() .eq(AccountStatement::getAccountType, 1) .le(AccountStatement::getStatementMonth, currentMonthText))); long overdueNum = receivableStatements.stream() .filter(item -> item.getStatementMonth() != null && item.getStatementMonth().compareTo(currentMonthText) < 0) .filter(item -> defaultDecimal(item.getClosingBalance()).compareTo(BigDecimal.ZERO) > 0) .count(); long totalReceivableCount = receivableStatements.size(); String overdueRate = totalReceivableCount == 0 ? "0.00" : BigDecimal.valueOf(overdueNum) .multiply(BigDecimal.valueOf(100)) .divide(BigDecimal.valueOf(totalReceivableCount), 2, RoundingMode.HALF_UP) .toString(); //éå®éè´§ BigDecimal salesReturnAmount = sumSalesReturnAmount(startDate, endDate); //忬¾ç=æ¶æ¬¾/(éå®åºåº-éå®éè´§)åºæ¶ String collectionRate = toRateString(monthlyIncome, receivableBase.subtract(salesReturnAmount)); //龿æ°=(éå®åºåºéé¢-éå®éè´§éé¢)åºæ¶éé¢-æ¶æ¬¾éé¢ BigDecimal overdueAmount = receivableBase.subtract(salesReturnAmount).subtract(monthlyIncome); //龿ç=龿æ°/åºæ¶éé¢ String overdueRate = toRateString(overdueAmount, receivableBase); dto.setMonthlyIncome(scaleMoney(monthlyIncome)); dto.setCollectionRate(collectionRate); dto.setOverdueNum(BigDecimal.valueOf(overdueNum)); dto.setOverdueNum(overdueAmount); dto.setOverdueRate(overdueRate); return dto; } @@ -1277,16 +1293,25 @@ YearMonth currentMonth = YearMonth.from(today); LocalDate startDate = currentMonth.atDay(1); LocalDate endDate = currentMonth.atEndOfMonth(); //æ¯åº BigDecimal monthlyExpenditure = sumPaymentAmount(startDate, endDate); //éè´å ¥åº BigDecimal payableBase = sumPurchaseContractAmount(startDate, endDate); //éè´éè´§ BigDecimal purchaseReturnAmount = sumPurchaseReturnAmount(startDate, endDate); //仿¬¾ç=仿¬¾/(éè´å ¥åº-éè´éè´§)åºä» String paymentRate = toRateString(monthlyExpenditure, payableBase.subtract(purchaseReturnAmount)); //æ¶æ¬¾ BigDecimal monthlyIncome = sumCollectionAmount(startDate, endDate); //æ¯å©æ¶¦= æ¶æ¬¾-æ¯åº BigDecimal grossProfit = monthlyIncome.subtract(monthlyExpenditure); //婿¶¦ç=æ¯å©æ¶¦/æ¶æ¬¾ String profitMarginRate = toRateString(grossProfit, monthlyIncome); dto.setMonthlyExpenditure(scaleMoney(monthlyExpenditure)); dto.setPaymentRate(toRateString(monthlyExpenditure, payableBase)); dto.setPaymentRate(paymentRate); dto.setGrossProfit(scaleMoney(grossProfit)); dto.setProfitMarginRate(toRateString(grossProfit, monthlyIncome)); dto.setProfitMarginRate(profitMarginRate); return dto; } @@ -2317,20 +2342,43 @@ return new LocalDate[]{startDate, endDate}; } //è®¡ç®æ¥æå çéå®åºåºéé¢ private BigDecimal sumSalesContractAmount(LocalDate startDate, LocalDate endDate) { List<SalesLedger> salesLedgers = defaultList(salesLedgerMapper.selectList(new LambdaQueryWrapper<SalesLedger>() .ge(SalesLedger::getEntryDate, toDate(startDate)) .lt(SalesLedger::getEntryDate, toExclusiveEndDate(endDate)))); return sumAmount(salesLedgers, SalesLedger::getContractAmount); SalesOutboundDto salesOutboundDto = new SalesOutboundDto(); salesOutboundDto.setStartDate(startDate); salesOutboundDto.setEndDate(endDate); List<SalesOutboundVo> salesOutboundVos = stockOutRecordMapper.listPageAccountSales(new Page(1, -1), salesOutboundDto).getRecords(); return sumAmount(salesOutboundVos, SalesOutboundVo::getOutboundAmount); } //è®¡ç®æ¥æå çéå®éè´§éé¢ private BigDecimal sumSalesReturnAmount(LocalDate startDate, LocalDate endDate) { SalesReturnDto salesReturnDto = new SalesReturnDto(); salesReturnDto.setStartDate(startDate); salesReturnDto.setEndDate(endDate); List<SalesReturnVo> salesReturnVos = returnManagementMapper.listPageAccountSalesReturn(new Page(1, -1), salesReturnDto).getRecords(); return sumAmount(salesReturnVos, SalesReturnVo::getRefundAmount); } //è®¡ç®æ¥æå çéè´å ¥åºéé¢ private BigDecimal sumPurchaseContractAmount(LocalDate startDate, LocalDate endDate) { List<PurchaseLedger> purchaseLedgers = defaultList(purchaseLedgerMapper.selectList(new LambdaQueryWrapper<PurchaseLedger>() .ge(PurchaseLedger::getEntryDate, toDate(startDate)) .lt(PurchaseLedger::getEntryDate, toExclusiveEndDate(endDate)))); return sumAmount(purchaseLedgers, PurchaseLedger::getContractAmount); PurchaseInboundDto purchaseInboundDto = new PurchaseInboundDto(); purchaseInboundDto.setStartDate(startDate); purchaseInboundDto.setEndDate(endDate); List<PurchaseInboundVo> purchaseInboundVos = stockInRecordMapper.listPageAccountPurchase(new Page(1, -1), purchaseInboundDto).getRecords(); return sumAmount(purchaseInboundVos, PurchaseInboundVo::getInboundAmount); } //è®¡ç®æ¥æå çéè´éè´§éé¢ private BigDecimal sumPurchaseReturnAmount(LocalDate startDate, LocalDate endDate) { PurchaseReturnDto purchaseReturnDto = new PurchaseReturnDto(); purchaseReturnDto.setStartDate(startDate); purchaseReturnDto.setEndDate(endDate); List<PurchaseReturnVo> purchaseReturnVos = purchaseReturnOrdersMapper.listPageAccountPurchaseReturn(new Page(1, -1), purchaseReturnDto).getRecords(); return sumAmount(purchaseReturnVos, PurchaseReturnVo::getTotalAmount); } //è®¡ç®æ¥æå çæ»æ¶æ¬¾éé¢ private BigDecimal sumCollectionAmount(LocalDate startDate, LocalDate endDate) { List<AccountSalesCollection> collections = defaultList(accountSalesCollectionMapper.selectList( new LambdaQueryWrapper<AccountSalesCollection>() @@ -2339,6 +2387,7 @@ return sumAmount(collections, AccountSalesCollection::getCollectionAmount); } //è®¡ç®æ¥æå çæ»ä»æ¬¾éé¢ private BigDecimal sumPaymentAmount(LocalDate startDate, LocalDate endDate) { List<AccountPurchasePayment> payments = defaultList(accountPurchasePaymentMapper.selectList( new LambdaQueryWrapper<AccountPurchasePayment>() src/main/java/com/ruoyi/purchase/dto/PurchaseLedgerDto.java
@@ -27,6 +27,8 @@ private String entryDateStart; private String entryDateEnd; @Schema(description = "å ¥åºç¶æ") private String stockInStatus; private Long id; src/main/java/com/ruoyi/purchase/service/impl/PurchaseLedgerServiceImpl.java
@@ -451,12 +451,7 @@ @Override public IPage<PurchaseLedgerDto> selectPurchaseLedgerListPage(IPage ipage, PurchaseLedgerDto purchaseLedger) { IPage<PurchaseLedgerDto> purchaseLedgerDtoIPage = purchaseLedgerMapper.selectPurchaseLedgerListPage(ipage, purchaseLedger); purchaseLedgerDtoIPage.getRecords().forEach(purchaseLedgerDto -> { List<CommonFile> commonFiles = commonFileMapper.selectList(new LambdaQueryWrapper<CommonFile>().eq(CommonFile::getCommonId, purchaseLedgerDto.getId()).eq(CommonFile::getType, FileNameType.PURCHASE.getValue())); purchaseLedgerDto.setSalesLedgerFiles(commonFiles); }); return purchaseLedgerDtoIPage; return purchaseLedgerMapper.selectPurchaseLedgerListPage(ipage, purchaseLedger); } @Override src/main/java/com/ruoyi/sales/pojo/SalesLedgerProduct.java
@@ -149,6 +149,10 @@ /** * 产åç¶æ */ @TableField(exist = false) @Schema(description = "å ¥åºå®¡æ ¸ç¶æ") private String stockInApprovalStatus; // @TableField(exist = false) @Schema(description = "产åç¶æï¼1-å è¶³") private Integer approveStatus; src/main/java/com/ruoyi/sales/service/impl/SalesLedgerServiceImpl.java
@@ -8,6 +8,10 @@ import com.baomidou.mybatisplus.core.toolkit.Wrappers; import com.baomidou.mybatisplus.extension.plugins.pagination.Page; import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl; import com.ruoyi.account.mapper.sales.AccountInvoiceApplicationMapper; import com.ruoyi.account.mapper.sales.AccountSalesCollectionMapper; import com.ruoyi.account.pojo.sales.AccountInvoiceApplication; import com.ruoyi.account.pojo.sales.AccountSalesCollection; import com.ruoyi.basic.enums.ApplicationTypeEnum; import com.ruoyi.basic.enums.RecordTypeEnum; import com.ruoyi.basic.mapper.CustomerMapper; @@ -26,7 +30,9 @@ import com.ruoyi.framework.security.LoginUser; import com.ruoyi.framework.web.domain.AjaxResult; import com.ruoyi.other.mapper.TempFileMapper; import com.ruoyi.production.mapper.*; import com.ruoyi.production.mapper.ProductionProductInputMapper; import com.ruoyi.production.mapper.ProductionProductMainMapper; import com.ruoyi.production.mapper.ProductionProductOutputMapper; import com.ruoyi.production.service.ProductionProductMainService; import com.ruoyi.project.system.domain.SysDept; import com.ruoyi.project.system.domain.SysUser; @@ -36,8 +42,14 @@ import com.ruoyi.purchase.mapper.PurchaseReturnOrderProductsMapper; import com.ruoyi.quality.mapper.QualityInspectMapper; import com.ruoyi.sales.dto.*; import com.ruoyi.sales.mapper.*; import com.ruoyi.sales.pojo.*; import com.ruoyi.sales.mapper.CommonFileMapper; import com.ruoyi.sales.mapper.SalesLedgerMapper; import com.ruoyi.sales.mapper.SalesLedgerProductMapper; import com.ruoyi.sales.mapper.ShippingInfoMapper; import com.ruoyi.sales.pojo.CommonFile; import com.ruoyi.sales.pojo.SalesLedger; import com.ruoyi.sales.pojo.SalesLedgerProduct; import com.ruoyi.sales.pojo.ShippingInfo; import com.ruoyi.sales.service.ISalesLedgerService; import com.ruoyi.sales.vo.SalesLedgerVo; import lombok.RequiredArgsConstructor; @@ -93,6 +105,8 @@ private final QualityInspectMapper qualityInspectMapper; private final RedisTemplate<String, String> redisTemplate; private final FileUtil fileUtil; private final AccountInvoiceApplicationMapper accountInvoiceApplicationMapper; private final AccountSalesCollectionMapper accountSalesCollectionMapper; @Autowired private SysDeptMapper sysDeptMapper; @@ -263,23 +277,37 @@ @Override public List<MonthlyAmountDto> getAmountHalfYear(Integer type) { LocalDate now = LocalDate.now(); List<MonthlyAmountDto> result = new ArrayList<>(); for (int i = 5; i >= 0; i--) { YearMonth yearMonth = YearMonth.from(now.minusMonths(i)); LocalDateTime startTime = yearMonth.atDay(1).atStartOfDay(); LocalDateTime endTime = yearMonth.atEndOfMonth().atTime(23, 59, 59); LocalDate startTime = yearMonth.atDay(1); LocalDate endTime = yearMonth.atEndOfMonth(); MonthlyAmountDto dto = new MonthlyAmountDto(); dto.setMonth(yearMonth.format(DateTimeFormatter.ofPattern("yyyy-MM"))); dto.setReceiptAmount(BigDecimal.ZERO); dto.setInvoiceAmount(BigDecimal.ZERO); //忬¾éé¢ List<AccountSalesCollection> accountSalesCollections = accountSalesCollectionMapper.selectList(new LambdaQueryWrapper<AccountSalesCollection>() .between(AccountSalesCollection::getCollectionDate, startTime, endTime)); BigDecimal totalIncome = Optional.of( accountSalesCollections.stream() .map(AccountSalesCollection::getCollectionAmount) .filter(Objects::nonNull) .reduce(BigDecimal.ZERO, BigDecimal::add) ).orElse(BigDecimal.ZERO); dto.setReceiptAmount(totalIncome); //å¼ç¥¨éé¢ List<AccountInvoiceApplication> accountInvoiceApplications = accountInvoiceApplicationMapper.selectList(new LambdaQueryWrapper<AccountInvoiceApplication>() .eq(AccountInvoiceApplication::getStatus,1) .between(AccountInvoiceApplication::getApplyDate, startTime, endTime)); BigDecimal totalInvoiceAmount = Optional.of( accountInvoiceApplications.stream() .map(AccountInvoiceApplication::getInvoiceAmount) .filter(Objects::nonNull) .reduce(BigDecimal.ZERO, BigDecimal::add) ).orElse(BigDecimal.ZERO); dto.setInvoiceAmount(totalInvoiceAmount); result.add(dto); } return result; } src/main/java/com/ruoyi/stock/controller/StockInRecordController.java
@@ -70,4 +70,15 @@ return AjaxResult.success(); } @PostMapping("/reAudit") @Log(title = "å ¥åºç®¡ç-åå®¡å ¥åº", businessType = BusinessType.UPDATE) @Operation(summary = "æ¹éåå®¡å ¥åºè®°å½") public AjaxResult reAudit(@RequestBody StockInRecordDto approveDto) { if(CollectionUtils.isEmpty(approveDto.getIds())){ return AjaxResult.error("è¯·éæ©è³å°ä¸æ¡æ°æ®"); } stockInRecordService.batchReAudit(approveDto.getIds()); return AjaxResult.success(); } } src/main/java/com/ruoyi/stock/dto/StockInRecordDto.java
@@ -40,4 +40,7 @@ @Schema(description = "è®°å½IDå表") private List<Long> ids; @Schema(description = "æºåå·") private String sourceOrderNo; } src/main/java/com/ruoyi/stock/service/StockInRecordService.java
@@ -23,4 +23,6 @@ void exportStockInRecord(HttpServletResponse response, StockInRecordDto stockInRecordDto); int batchApprove(List<Long> ids, Integer approvalStatus); int batchReAudit(List<Long> ids); } src/main/java/com/ruoyi/stock/service/impl/StockInRecordServiceImpl.java
@@ -156,6 +156,32 @@ return stockUninventoryMapper.selectOne(eq); } /** * åæ»ç产éæå ¥åºçé¢æè®°å½éææ°é * @param stockInRecord å ¥åºè®°å½ */ private void rollbackFeedReturnQty(StockInRecord stockInRecord) { ProductionOrderPick productionOrderPick = productionOrderPickMapper.selectById(stockInRecord.getRecordId()); if (productionOrderPick != null) { BigDecimal returnQty = productionOrderPick.getReturnQty(); if (returnQty == null) { returnQty = BigDecimal.ZERO; } BigDecimal newReturnQty = returnQty.subtract(stockInRecord.getStockInNum()); if (newReturnQty.compareTo(BigDecimal.ZERO) < 0) { newReturnQty = BigDecimal.ZERO; } productionOrderPick.setReturnQty(newReturnQty); // éæ°è®¡ç®å®é ç¨é BigDecimal actualQty = productionOrderPick.getQuantity().add( productionOrderPick.getFeedingQty() != null ? productionOrderPick.getFeedingQty() : BigDecimal.ZERO) .subtract(newReturnQty); productionOrderPick.setActualQty(actualQty); productionOrderPick.setReturned(newReturnQty.compareTo(BigDecimal.ZERO) > 0); productionOrderPickMapper.updateById(productionOrderPick); } } @Override @Transactional(rollbackFor = Exception.class) public int batchDeletePending(List<Long> ids) { @@ -166,6 +192,11 @@ } if (stockInRecord.getApprovalStatus() != null && !ReviewStatusEnum.PENDING_REVIEW.getCode().equals(stockInRecord.getApprovalStatus())) { throw new BaseException("åªæå¾ å®¡æ¹ç¶æçè®°å½æè½å é¤,å ¥åºæ¹æ¬¡:" + stockInRecord.getInboundBatches()); } // 妿æ¯ç产éæå ¥åºï¼å 餿¶éè¦åæ»é¢æè®°å½çéææ°é if (StockInQualifiedRecordTypeEnum.FEED_RETURN_IN.getCode().equals(stockInRecord.getRecordType())) { rollbackFeedReturnQty(stockInRecord); } } return stockInRecordMapper.deleteBatchIds(ids); @@ -194,27 +225,7 @@ // 审æ¹é©³åæ¶ï¼å¦ææ¯ç产éæå ¥åºï¼éè¦åæ»é¢æè®°å½çéææ°é if (ReviewStatusEnum.REJECTED.getCode().equals(approvalStatus) && StockInQualifiedRecordTypeEnum.FEED_RETURN_IN.getCode().equals(stockInRecord.getRecordType())) { // æ¾å°å¯¹åºçé¢æè®°å½ ProductionOrderPick productionOrderPick = productionOrderPickMapper.selectById(stockInRecord.getRecordId()); if (productionOrderPick != null) { // 忻鿿°é BigDecimal returnQty = productionOrderPick.getReturnQty(); if (returnQty == null) { returnQty = BigDecimal.ZERO; } BigDecimal newReturnQty = returnQty.subtract(stockInRecord.getStockInNum()); if (newReturnQty.compareTo(BigDecimal.ZERO) < 0) { newReturnQty = BigDecimal.ZERO; } productionOrderPick.setReturnQty(newReturnQty); // éæ°è®¡ç®å®é ç¨é BigDecimal actualQty = productionOrderPick.getQuantity().add( productionOrderPick.getFeedingQty() != null ? productionOrderPick.getFeedingQty() : BigDecimal.ZERO) .subtract(newReturnQty); productionOrderPick.setActualQty(actualQty); productionOrderPick.setReturned(newReturnQty.compareTo(BigDecimal.ZERO) > 0); productionOrderPickMapper.updateById(productionOrderPick); } rollbackFeedReturnQty(stockInRecord); } // 审æ¹éè¿æ¶ï¼åºåå¢å @@ -262,4 +273,50 @@ } return ids.size(); } @Override @Transactional(rollbackFor = Exception.class) public int batchReAudit(List<Long> ids) { if (CollectionUtils.isEmpty(ids)) { throw new BaseException("è¯·éæ©è³å°ä¸æ¡æ°æ®"); } for (Long id : ids) { StockInRecord stockInRecord = stockInRecordMapper.selectById(id); if (stockInRecord == null) { throw new BaseException("å ¥åºè®°å½ä¸åå¨,æ æ³éæ°å®¡æ ¸!!!"); } // åªæé©³åç¶ææè½éæ°å®¡æ ¸ if (!ReviewStatusEnum.REJECTED.getCode().equals(stockInRecord.getApprovalStatus())) { throw new BaseException("åªæé©³åç¶æçè®°å½æè½éæ°å®¡æ ¸,å ¥åºæ¹æ¬¡:" + stockInRecord.getInboundBatches()); } // 妿æ¯ç产éæå ¥åºï¼æ¢å¤éææ°éï¼å ä¸ºé©³åæ¶å·²æ£åï¼ if (StockInQualifiedRecordTypeEnum.FEED_RETURN_IN.getCode().equals(stockInRecord.getRecordType())) { ProductionOrderPick productionOrderPick = productionOrderPickMapper.selectById(stockInRecord.getRecordId()); if (productionOrderPick != null) { BigDecimal returnQty = productionOrderPick.getReturnQty(); if (returnQty == null) { returnQty = BigDecimal.ZERO; } // éæ°å®¡æ ¸æ¶æ¢å¤éææ°é BigDecimal newReturnQty = returnQty.add(stockInRecord.getStockInNum()); productionOrderPick.setReturnQty(newReturnQty); // éæ°è®¡ç®å®é ç¨é BigDecimal actualQty = productionOrderPick.getQuantity().add( productionOrderPick.getFeedingQty() != null ? productionOrderPick.getFeedingQty() : BigDecimal.ZERO) .subtract(newReturnQty); productionOrderPick.setActualQty(actualQty); productionOrderPick.setReturned(newReturnQty.compareTo(BigDecimal.ZERO) > 0); productionOrderPickMapper.updateById(productionOrderPick); } } // å°ç¶ææ¹ä¸ºå¾ å®¡æ ¸ stockInRecord.setApprovalStatus(ReviewStatusEnum.PENDING_REVIEW.getCode()); stockInRecordMapper.updateById(stockInRecord); } return ids.size(); } } src/main/resources/application.yml
@@ -3,7 +3,7 @@ main: allow-circular-references: true profiles: active: dev-pro active: dev langchain4j: mcp: # MCP æå¡ç«¯å°åï¼æ ¹æ®å®é é¨ç½²ç MCP æå¡è°æ´ï¼ src/main/resources/mapper/purchase/PurchaseLedgerMapper.xml
@@ -17,6 +17,8 @@ </select> <select id="selectPurchaseLedgerListPage" resultType="com.ruoyi.purchase.dto.PurchaseLedgerDto"> SELECT result.* FROM ( SELECT pl.id, pl.purchase_contract_number, @@ -34,9 +36,65 @@ sm.is_white, pl.approval_status, pl.payment_method, pl.remarks pl.remarks, CASE WHEN IFNULL(ls.total_product_count, 0) = 0 THEN 'å¾ å ¥åº' WHEN IFNULL(ls.full_product_count, 0) >= IFNULL(ls.total_product_count, 0) THEN 'å®å ¨å ¥åº' WHEN IFNULL(ls.approved_product_count, 0) > 0 THEN 'å ¥åºä¸' ELSE 'å¾ å ¥åº' END AS stock_in_status FROM purchase_ledger pl LEFT JOIN supplier_manage sm ON pl.supplier_id = sm.id LEFT JOIN ( SELECT product_status.sales_ledger_id, COUNT(1) AS total_product_count, SUM(CASE WHEN product_status.approved_stock_in_num > 0 THEN 1 ELSE 0 END) AS approved_product_count, SUM(CASE WHEN product_status.approved_stock_in_num >= product_status.product_quantity THEN 1 ELSE 0 END) AS full_product_count FROM ( SELECT slp.id AS sales_ledger_product_id, slp.sales_ledger_id, IFNULL(slp.quantity, 0) AS product_quantity, IFNULL(approved_qty.approved_stock_in_num, 0) AS approved_stock_in_num FROM sales_ledger_product slp LEFT JOIN ( SELECT rel.sales_ledger_product_id, IFNULL(SUM(rel.stock_in_num), 0) AS approved_stock_in_num FROM ( SELECT slp.id AS sales_ledger_product_id, sir.stock_in_num FROM stock_in_record sir INNER JOIN sales_ledger_product slp ON slp.type = 2 AND TRIM(sir.record_type) = '7' AND sir.record_id = slp.sales_ledger_id AND ( (sir.batch_no IS NOT NULL AND sir.batch_no LIKE CONCAT('%-', slp.id)) OR (sir.batch_no IS NULL AND sir.product_model_id = slp.product_model_id) ) WHERE sir.approval_status = 1 UNION ALL SELECT slp.id AS sales_ledger_product_id, sir.stock_in_num FROM stock_in_record sir INNER JOIN quality_inspect qi ON TRIM(sir.record_type) = '10' AND sir.record_id = qi.id INNER JOIN sales_ledger_product slp ON slp.type = 2 AND slp.sales_ledger_id = qi.purchase_ledger_id AND slp.product_model_id = qi.product_model_id WHERE sir.approval_status = 1 ) rel GROUP BY rel.sales_ledger_product_id ) approved_qty ON approved_qty.sales_ledger_product_id = slp.id WHERE slp.type = 2 ) product_status GROUP BY product_status.sales_ledger_id ) ls ON ls.sales_ledger_id = pl.id <where> <if test="c.purchaseContractNumber != null and c.purchaseContractNumber != ''"> AND pl.purchase_contract_number LIKE CONCAT('%', #{c.purchaseContractNumber}, '%') @@ -66,7 +124,11 @@ AND pl.approval_status = #{c.approvalStatus} </if> </where> ORDER BY pl.entry_date DESC ) result <if test="c.stockInStatus != null and c.stockInStatus != ''"> WHERE result.stock_in_status = #{c.stockInStatus} </if> ORDER BY result.entry_date DESC </select> <select id="selectTotalPurchaseAmount" resultType="java.math.BigDecimal"> src/main/resources/mapper/sales/SalesLedgerProductMapper.xml
@@ -38,7 +38,13 @@ WHEN IFNULL(t3.shipped_quantity, 0) = 0 THEN 'å¾ åè´§' WHEN (IFNULL(T1.quantity, 0) - IFNULL(t3.shipped_quantity, 0)) > 0 THEN 'é¨ååè´§' ELSE 'å·²åè´§' END as shippingStatus END as shippingStatus, CASE WHEN T1.type != 2 THEN NULL WHEN IFNULL(t4.approved_stock_in_num, 0) <= 0 THEN 'å¾ å ¥åº' WHEN IFNULL(t4.approved_stock_in_num, 0) >= IFNULL(T1.quantity, 0) THEN 'å®å ¨å ¥åº' ELSE 'å ¥åºä¸' END AS stock_in_approval_status FROM sales_ledger_product T1 LEFT JOIN ( @@ -53,6 +59,39 @@ where si.status != 'å®¡æ ¸æç»' GROUP BY sales_ledger_product_id ) t3 ON t3.sales_ledger_product_id = T1.id LEFT JOIN ( SELECT rel.sales_ledger_product_id, IFNULL(SUM(rel.stock_in_num), 0) AS approved_stock_in_num FROM ( SELECT slp.id AS sales_ledger_product_id, sir.stock_in_num FROM stock_in_record sir INNER JOIN sales_ledger_product slp ON slp.type = 2 AND TRIM(sir.record_type) = '7' AND sir.record_id = slp.sales_ledger_id AND ( (sir.batch_no IS NOT NULL AND sir.batch_no LIKE CONCAT('%-', slp.id)) OR (sir.batch_no IS NULL AND sir.product_model_id = slp.product_model_id) ) WHERE sir.approval_status = 1 UNION ALL SELECT slp.id AS sales_ledger_product_id, sir.stock_in_num FROM stock_in_record sir INNER JOIN quality_inspect qi ON TRIM(sir.record_type) = '10' AND sir.record_id = qi.id INNER JOIN sales_ledger_product slp ON slp.type = 2 AND slp.sales_ledger_id = qi.purchase_ledger_id AND slp.product_model_id = qi.product_model_id WHERE sir.approval_status = 1 ) rel GROUP BY rel.sales_ledger_product_id ) t4 ON t4.sales_ledger_product_id = T1.id left join product_model pm ON T1.product_model_id = pm.id left join product p ON pm.product_id = p.id <where> src/main/resources/mapper/stock/StockInRecordMapper.xml
@@ -19,11 +19,96 @@ p.product_name as product_name, pm.model, pm.unit, u.nick_name as createBy u.nick_name as createBy, CASE WHEN #{params.topParentProductId} = 278 AND TRIM(sir.record_type) = '7' THEN COALESCE(pl_by_product.purchase_contract_number, pl_direct.purchase_contract_number) WHEN #{params.topParentProductId} = 278 AND TRIM(sir.record_type) = '10' THEN pl_by_quality.purchase_contract_number WHEN #{params.topParentProductId} = 276 THEN CASE WHEN TRIM(sir.record_type) IN ('14', '15') THEN sl_return.sales_contract_no WHEN TRIM(sir.record_type) IN ('2', '5') THEN COALESCE(po_sales_main.sales_contract_no, po_main.nps_no) WHEN TRIM(sir.record_type) = '6' THEN COALESCE(po_sales_qi.sales_contract_no, po_qi.nps_no) WHEN TRIM(sir.record_type) IN ('4', '11') THEN COALESCE(po_sales_uq.sales_contract_no, po_uq.nps_no) WHEN TRIM(sir.record_type) IN ('20', '22') THEN COALESCE(po_sales_pick.sales_contract_no, po_pick.nps_no) ELSE NULL END ELSE NULL END AS sourceOrderNo FROM stock_in_record as sir LEFT JOIN product_model as pm on sir.product_model_id = pm.id LEFT JOIN product as p on pm.product_id = p.id LEFT JOIN sys_user as u on sir.create_user = u.user_id LEFT JOIN quality_inspect as qi_purchase on TRIM(sir.record_type) = '10' and sir.record_id = qi_purchase.id LEFT JOIN sales_ledger_product as slp on TRIM(sir.record_type) = '7' and slp.id = sir.record_id and slp.type = 2 LEFT JOIN purchase_ledger as pl_by_product on TRIM(sir.record_type) = '7' and pl_by_product.id = slp.sales_ledger_id LEFT JOIN purchase_ledger as pl_direct on TRIM(sir.record_type) = '7' and pl_direct.id = sir.record_id LEFT JOIN purchase_ledger as pl_by_quality on TRIM(sir.record_type) = '10' and pl_by_quality.id = qi_purchase.purchase_ledger_id LEFT JOIN production_product_main as ppm_main on TRIM(sir.record_type) IN ('2', '5') and sir.record_id = ppm_main.id LEFT JOIN production_operation_task as pot_main on ppm_main.production_operation_task_id = pot_main.id LEFT JOIN production_order as po_main on pot_main.production_order_id = po_main.id LEFT JOIN ( select po2.id as production_order_id, group_concat(distinct sl2.sales_contract_no order by sl2.sales_contract_no separator ',') as sales_contract_no from production_order po2 left join production_plan pp2 on find_in_set(pp2.id, replace(replace(replace(po2.production_plan_ids, '[', ''), ']', ''), ' ', '')) > 0 left join sales_ledger sl2 on sl2.id = pp2.sales_ledger_id group by po2.id ) as po_sales_main on po_sales_main.production_order_id = po_main.id LEFT JOIN quality_inspect as qi_prod on TRIM(sir.record_type) = '6' and sir.record_id = qi_prod.id LEFT JOIN production_product_main as ppm_qi on qi_prod.product_main_id = ppm_qi.id LEFT JOIN production_operation_task as pot_qi on ppm_qi.production_operation_task_id = pot_qi.id LEFT JOIN production_order as po_qi on pot_qi.production_order_id = po_qi.id LEFT JOIN ( select po2.id as production_order_id, group_concat(distinct sl2.sales_contract_no order by sl2.sales_contract_no separator ',') as sales_contract_no from production_order po2 left join production_plan pp2 on find_in_set(pp2.id, replace(replace(replace(po2.production_plan_ids, '[', ''), ']', ''), ' ', '')) > 0 left join sales_ledger sl2 on sl2.id = pp2.sales_ledger_id group by po2.id ) as po_sales_qi on po_sales_qi.production_order_id = po_qi.id LEFT JOIN quality_unqualified as qu on TRIM(sir.record_type) IN ('4', '11') and sir.record_id = qu.id LEFT JOIN quality_inspect as qi_uq on qu.inspect_id = qi_uq.id LEFT JOIN production_product_main as ppm_uq on qi_uq.product_main_id = ppm_uq.id LEFT JOIN production_operation_task as pot_uq on ppm_uq.production_operation_task_id = pot_uq.id LEFT JOIN production_order as po_uq on pot_uq.production_order_id = po_uq.id LEFT JOIN ( select po2.id as production_order_id, group_concat(distinct sl2.sales_contract_no order by sl2.sales_contract_no separator ',') as sales_contract_no from production_order po2 left join production_plan pp2 on find_in_set(pp2.id, replace(replace(replace(po2.production_plan_ids, '[', ''), ']', ''), ' ', '')) > 0 left join sales_ledger sl2 on sl2.id = pp2.sales_ledger_id group by po2.id ) as po_sales_uq on po_sales_uq.production_order_id = po_uq.id LEFT JOIN production_order_pick as pop on TRIM(sir.record_type) IN ('20', '22') and sir.record_id = pop.id LEFT JOIN production_order as po_pick on pop.production_order_id = po_pick.id LEFT JOIN ( select po2.id as production_order_id, group_concat(distinct sl2.sales_contract_no order by sl2.sales_contract_no separator ',') as sales_contract_no from production_order po2 left join production_plan pp2 on find_in_set(pp2.id, replace(replace(replace(po2.production_plan_ids, '[', ''), ']', ''), ' ', '')) > 0 left join sales_ledger sl2 on sl2.id = pp2.sales_ledger_id group by po2.id ) as po_sales_pick on po_sales_pick.production_order_id = po_pick.id LEFT JOIN return_sale_product as rsp on TRIM(sir.record_type) IN ('14', '15') and sir.record_id = rsp.id LEFT JOIN return_management as rm on rsp.return_management_id = rm.id LEFT JOIN shipping_info as si_return on rm.shipping_id = si_return.id LEFT JOIN sales_ledger as sl_return on si_return.sales_ledger_id = sl_return.id <where> <if test="params.timeStr != null and params.timeStr != ''"> and sir.create_time like concat('%',#{params.timeStr},'%')