From 6b4cfc6f9d660b92be99ba4e3411a3267bc57155 Mon Sep 17 00:00:00 2001
From: gongchunyi <deslre0381@gmail.com>
Date: 星期六, 18 四月 2026 15:24:33 +0800
Subject: [PATCH] feat: 销售/采购订单的扫码合格/不合格出入库功能
---
src/main/java/com/ruoyi/purchase/dto/PurchaseScanStockDto.java | 22 +
src/main/java/com/ruoyi/sales/dto/SalesScanInboundDto.java | 23 +
src/main/java/com/ruoyi/purchase/service/IPurchaseLedgerService.java | 10
src/main/java/com/ruoyi/purchase/service/impl/PurchaseLedgerServiceImpl.java | 370 ++++++++++++++++++---
src/main/resources/mapper/stock/StockInventoryMapper.xml | 3
src/main/java/com/ruoyi/sales/pojo/SalesLedgerProduct.java | 26 +
src/main/java/com/ruoyi/stock/dto/StockUninventoryDto.java | 12
src/main/java/com/ruoyi/common/enums/StockInUnQualifiedRecordTypeEnum.java | 4
src/main/java/com/ruoyi/sales/service/ISalesLedgerService.java | 7
src/main/java/com/ruoyi/procurementrecord/utils/StockUtils.java | 77 ++++
doc/河南鹤壁天沐钢化玻璃厂.sql | 8
src/main/java/com/ruoyi/sales/service/impl/SalesLedgerProductServiceImpl.java | 10
src/main/java/com/ruoyi/sales/controller/SalesLedgerController.java | 28 +
src/main/java/com/ruoyi/stock/service/impl/StockUninventoryServiceImpl.java | 9
src/main/java/com/ruoyi/sales/service/impl/SalesLedgerServiceImpl.java | 303 +++++++++++++++++
src/main/java/com/ruoyi/purchase/controller/PurchaseLedgerController.java | 29 +
src/main/resources/mapper/stock/StockUninventoryMapper.xml | 3
src/main/java/com/ruoyi/common/enums/StockOutQualifiedRecordTypeEnum.java | 4
src/main/java/com/ruoyi/stock/service/impl/StockInventoryServiceImpl.java | 5
src/main/java/com/ruoyi/common/enums/StockInQualifiedRecordTypeEnum.java | 4
src/main/java/com/ruoyi/common/enums/StockOutUnQualifiedRecordTypeEnum.java | 4
21 files changed, 887 insertions(+), 74 deletions(-)
diff --git "a/doc/\346\262\263\345\215\227\351\271\244\345\243\201\345\244\251\346\262\220\351\222\242\345\214\226\347\216\273\347\222\203\345\216\202.sql" "b/doc/\346\262\263\345\215\227\351\271\244\345\243\201\345\244\251\346\262\220\351\222\242\345\214\226\347\216\273\347\222\203\345\216\202.sql"
index 0585f98..b305a1e 100644
--- "a/doc/\346\262\263\345\215\227\351\271\244\345\243\201\345\244\251\346\262\220\351\222\242\345\214\226\347\216\273\347\222\203\345\216\202.sql"
+++ "b/doc/\346\262\263\345\215\227\351\271\244\345\243\201\345\244\251\346\262\220\351\222\242\345\214\226\347\216\273\347\222\203\345\216\202.sql"
@@ -122,4 +122,10 @@
MODIFY COLUMN `stock_out_num` decimal(16, 4) NULL DEFAULT NULL COMMENT '鍑哄簱鏁伴噺' AFTER `outbound_batches`,
MODIFY COLUMN `record_id` int NULL DEFAULT NULL COMMENT '鍑哄簱鏉ユ簮id' AFTER `stock_out_num`,
ADD COLUMN `sales_ledger_id` bigint NULL COMMENT '閿�鍞鍗旾D' AFTER `type`,
- ADD COLUMN `sales_ledger_product_id` bigint NULL COMMENT '閿�鍞鍗曚骇鍝両D' AFTER `sales_ledger_id`;
\ No newline at end of file
+ ADD COLUMN `sales_ledger_product_id` bigint NULL COMMENT '閿�鍞鍗曚骇鍝両D' AFTER `sales_ledger_id`;
+
+ALTER TABLE `sales_ledger_product`
+ ADD COLUMN `stocked_quantity` decimal(18, 2) DEFAULT 0.00 COMMENT '宸插叆搴撴暟閲�' AFTER `product_stock_status`;
+
+ALTER TABLE `sales_ledger_product`
+ ADD COLUMN `remaining_quantity` decimal(18, 2) DEFAULT '0.00' COMMENT '鍓╀綑寰呭叆搴撴暟閲�' AFTER `stocked_quantity`
\ No newline at end of file
diff --git a/src/main/java/com/ruoyi/common/enums/StockInQualifiedRecordTypeEnum.java b/src/main/java/com/ruoyi/common/enums/StockInQualifiedRecordTypeEnum.java
index 05a6ffb..5349ab7 100644
--- a/src/main/java/com/ruoyi/common/enums/StockInQualifiedRecordTypeEnum.java
+++ b/src/main/java/com/ruoyi/common/enums/StockInQualifiedRecordTypeEnum.java
@@ -12,7 +12,9 @@
QUALITYINSPECT_STOCK_IN("6", "璐ㄦ-鍚堟牸鍏ュ簱"),
DEFECTIVE_PASS("11", "涓嶅悎鏍�-璁╂鏀捐"),
RETURN_HE_IN("14", "閿�鍞��璐�-鍚堟牸鍏ュ簱"),
- SALE_STOCK_IN("15", "閿�鍞鍗�-鍚堟牸鍏ュ簱");
+ SALE_STOCK_IN("15", "閿�鍞鍗�-鍚堟牸鍏ュ簱"),
+ SALE_SCAN_STOCK_IN("17", "閿�鍞鍗曟壂鐮�-鍚堟牸鍏ュ簱"),
+ PURCHASE_SCAN_STOCK_IN("18", "閲囪喘璁㈠崟鎵爜-鍚堟牸鍏ュ簱");
private final String code;
diff --git a/src/main/java/com/ruoyi/common/enums/StockInUnQualifiedRecordTypeEnum.java b/src/main/java/com/ruoyi/common/enums/StockInUnQualifiedRecordTypeEnum.java
index a03e6bd..1c6db55 100644
--- a/src/main/java/com/ruoyi/common/enums/StockInUnQualifiedRecordTypeEnum.java
+++ b/src/main/java/com/ruoyi/common/enums/StockInUnQualifiedRecordTypeEnum.java
@@ -11,7 +11,9 @@
PRODUCTION_SCRAP("5", "鐢熶骇鎶ュ伐-鎶ュ簾"),
CUSTOMIZATION_UNSTOCK_IN("9", "涓嶅悎鏍艰嚜瀹氫箟鍏ュ簱"),
QUALITYINSPECT_UNSTOCK_IN("12", "璐ㄦ-涓嶅悎鏍煎叆搴�"),
- RETURN_UNSTOCK_IN("15", "閿�鍞��璐�-涓嶅悎鏍煎叆搴�");
+ RETURN_UNSTOCK_IN("15", "閿�鍞��璐�-涓嶅悎鏍煎叆搴�"),
+ SALES_SCAN_UNSTOCK_IN("16", "閿�鍞鍗曟壂鐮�-涓嶅悎鏍煎叆搴�"),
+ PURCHASE_SCAN_UNSTOCK_IN("19", "閲囪喘璁㈠崟鎵爜-涓嶅悎鏍煎叆搴�");
private final String code;
diff --git a/src/main/java/com/ruoyi/common/enums/StockOutQualifiedRecordTypeEnum.java b/src/main/java/com/ruoyi/common/enums/StockOutQualifiedRecordTypeEnum.java
index 5e8fe53..3ec4a0d 100644
--- a/src/main/java/com/ruoyi/common/enums/StockOutQualifiedRecordTypeEnum.java
+++ b/src/main/java/com/ruoyi/common/enums/StockOutQualifiedRecordTypeEnum.java
@@ -9,7 +9,9 @@
PRODUCTION_REPORT_STOCK_OUT("3", "鐢熶骇鎶ュ伐-鍑哄簱"),
SALE_STOCK_OUT("8", "閿�鍞�-鍑哄簱"),
PURCHASE_RETURN_STOCK_OUT("9", "閲囪喘閫�璐�"),
- SALE_SHIP_STOCK_OUT("13", "閿�鍞�-鍙戣揣鍑哄簱");
+ SALE_SHIP_STOCK_OUT("13", "閿�鍞�-鍙戣揣鍑哄簱"),
+ SALE_SCAN_STOCK_OUT("17", "閿�鍞鍗曟壂鐮�-鍚堟牸鍑哄簱"),
+ PURCHASE_SCAN_STOCK_OUT("16", "閲囪喘璁㈠崟鎵爜-鍚堟牸鍑哄簱");
private final String code;
private final String value;
diff --git a/src/main/java/com/ruoyi/common/enums/StockOutUnQualifiedRecordTypeEnum.java b/src/main/java/com/ruoyi/common/enums/StockOutUnQualifiedRecordTypeEnum.java
index 2ee40bd..93e1908 100644
--- a/src/main/java/com/ruoyi/common/enums/StockOutUnQualifiedRecordTypeEnum.java
+++ b/src/main/java/com/ruoyi/common/enums/StockOutUnQualifiedRecordTypeEnum.java
@@ -7,7 +7,9 @@
public enum StockOutUnQualifiedRecordTypeEnum implements BaseEnum<String> {
- CUSTOMIZATION_UNSTOCK_OUT("10", "涓嶅悎鏍艰嚜瀹氫箟鍑哄簱");
+ CUSTOMIZATION_UNSTOCK_OUT("10", "涓嶅悎鏍艰嚜瀹氫箟鍑哄簱"),
+ SALE_SCAN_UNSTOCK_OUT("11", "閿�鍞鍗曟壂鐮�-涓嶅悎鏍煎嚭搴�"),
+ PURCHASE_SCAN_UNSTOCK_OUT("12", "閲囪喘璁㈠崟鎵爜-涓嶅悎鏍煎嚭搴�");
private final String code;
diff --git a/src/main/java/com/ruoyi/procurementrecord/utils/StockUtils.java b/src/main/java/com/ruoyi/procurementrecord/utils/StockUtils.java
index b1bb2cf..4b9dd7b 100644
--- a/src/main/java/com/ruoyi/procurementrecord/utils/StockUtils.java
+++ b/src/main/java/com/ruoyi/procurementrecord/utils/StockUtils.java
@@ -2,13 +2,17 @@
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.core.toolkit.ObjectUtils;
+import com.baomidou.mybatisplus.core.toolkit.Wrappers;
+import com.ruoyi.common.exception.ServiceException;
import com.ruoyi.procurementrecord.mapper.ProcurementRecordMapper;
import com.ruoyi.procurementrecord.mapper.ProcurementRecordOutMapper;
import com.ruoyi.stock.dto.StockInRecordDto;
import com.ruoyi.stock.dto.StockInventoryDto;
import com.ruoyi.stock.dto.StockUninventoryDto;
import com.ruoyi.stock.pojo.StockInRecord;
+import com.ruoyi.stock.pojo.StockInventory;
import com.ruoyi.stock.pojo.StockOutRecord;
+import com.ruoyi.stock.pojo.StockUninventory;
import com.ruoyi.stock.service.StockInRecordService;
import com.ruoyi.stock.service.StockInventoryService;
import com.ruoyi.stock.service.StockOutRecordService;
@@ -34,6 +38,52 @@
private final StockOutRecordService stockOutRecordService;
/**
+ * 鍚堟牸搴撳瓨鍑哄簱鍓嶆牎楠岋細鎸� stock_inventory 鍙敤鏁伴噺锛堟暟閲� 鈭� 鍐荤粨锛�
+ */
+ public void assertQualifiedAvailable(Long productModelId, BigDecimal outboundQty) {
+ if (productModelId == null) {
+ throw new ServiceException("鍑哄簱澶辫触,浜у搧瑙勬牸鏈淮鎶�");
+ }
+ if (outboundQty == null || outboundQty.compareTo(BigDecimal.ZERO) <= 0) {
+ return;
+ }
+ StockInventory inv = stockInventoryService.getOne(
+ Wrappers.<StockInventory>lambdaQuery().eq(StockInventory::getProductModelId, productModelId));
+ if (inv == null) {
+ throw new ServiceException("鍑哄簱澶辫触,鍚堟牸搴撲腑鏃犺浜у搧搴撳瓨");
+ }
+ BigDecimal locked = inv.getLockedQuantity() == null ? BigDecimal.ZERO : inv.getLockedQuantity();
+ BigDecimal qty = inv.getQualitity() == null ? BigDecimal.ZERO : inv.getQualitity();
+ BigDecimal available = qty.subtract(locked);
+ if (outboundQty.compareTo(available) > 0) {
+ throw new ServiceException("鍑哄簱澶辫触,鍑哄簱鏁伴噺涓嶈兘澶т簬褰撳墠鍚堟牸搴撳瓨鍙敤鏁伴噺");
+ }
+ }
+
+ /**
+ * 涓嶅悎鏍煎簱瀛樺嚭搴撳墠鏍¢獙锛氭寜 stock_uninventory 鍙敤鏁伴噺锛堟暟閲� 鈭� 鍐荤粨锛�
+ */
+ public void assertUnqualifiedAvailable(Long productModelId, BigDecimal outboundQty) {
+ if (productModelId == null) {
+ throw new ServiceException("鍑哄簱澶辫触,浜у搧瑙勬牸鏈淮鎶�");
+ }
+ if (outboundQty == null || outboundQty.compareTo(BigDecimal.ZERO) <= 0) {
+ return;
+ }
+ StockUninventory inv = stockUninventoryService.getOne(
+ Wrappers.<StockUninventory>lambdaQuery().eq(StockUninventory::getProductModelId, productModelId));
+ if (inv == null) {
+ throw new ServiceException("鍑哄簱澶辫触,涓嶅悎鏍煎簱涓棤璇ヤ骇鍝佸簱瀛�");
+ }
+ BigDecimal locked = inv.getLockedQuantity() == null ? BigDecimal.ZERO : inv.getLockedQuantity();
+ BigDecimal qty = inv.getQualitity() == null ? BigDecimal.ZERO : inv.getQualitity();
+ BigDecimal available = qty.subtract(locked);
+ if (outboundQty.compareTo(available) > 0) {
+ throw new ServiceException("鍑哄簱澶辫触,鍑哄簱鏁伴噺涓嶈兘澶т簬褰撳墠涓嶅悎鏍煎簱瀛樺彲鐢ㄦ暟閲�");
+ }
+ }
+
+ /**
* 涓嶅悎鏍煎叆搴�
*
* @param productModelId
@@ -42,28 +92,41 @@
* @param recordId
*/
public void addUnStock(Long productModelId, BigDecimal quantity, String recordType, Long recordId) {
+ addUnStock(null, null, productModelId, quantity, recordType, recordId);
+ }
+
+ /**
+ * 涓嶅悎鏍煎叆搴擄紙甯﹂攢鍞鍗曞叧鑱旓紝鍐欏叆鍏ュ簱璁板綍锛�
+ */
+ public void addUnStock(Long salesLedgerId, Long salesLedgerProductId, Long productModelId, BigDecimal quantity, String recordType, Long recordId) {
StockUninventoryDto stockUninventoryDto = new StockUninventoryDto();
stockUninventoryDto.setRecordId(recordId);
stockUninventoryDto.setRecordType(String.valueOf(recordType));
stockUninventoryDto.setQualitity(quantity);
stockUninventoryDto.setProductModelId(productModelId);
+ stockUninventoryDto.setSalesLedgerId(salesLedgerId);
+ stockUninventoryDto.setSalesLedgerProductId(salesLedgerProductId);
stockUninventoryService.addStockUninventory(stockUninventoryDto);
}
/**
* 涓嶅悎鏍煎嚭搴�
- *
- * @param productModelId
- * @param quantity
- * @param recordType
- * @param recordId
*/
- public void subtractUnStock(Long productModelId, BigDecimal quantity, Integer recordType, Long recordId) {
+ public void subtractUnStock(Long productModelId, BigDecimal quantity, String recordType, Long recordId) {
+ subtractUnStock(null, null, productModelId, quantity, recordType, recordId);
+ }
+
+ /**
+ * 涓嶅悎鏍煎嚭搴擄紙鍙甫閿�鍞鍗曞叧鑱斿啓鍏ュ嚭搴撹褰曪級
+ */
+ public void subtractUnStock(Long salesLedgerId, Long salesLedgerProductId, Long productModelId, BigDecimal quantity, String recordType, Long recordId) {
StockUninventoryDto stockUninventoryDto = new StockUninventoryDto();
stockUninventoryDto.setRecordId(recordId);
- stockUninventoryDto.setRecordType(String.valueOf(recordType));
+ stockUninventoryDto.setRecordType(recordType);
stockUninventoryDto.setQualitity(quantity);
stockUninventoryDto.setProductModelId(productModelId);
+ stockUninventoryDto.setSalesLedgerId(salesLedgerId);
+ stockUninventoryDto.setSalesLedgerProductId(salesLedgerProductId);
stockUninventoryService.subtractStockUninventory(stockUninventoryDto);
}
diff --git a/src/main/java/com/ruoyi/purchase/controller/PurchaseLedgerController.java b/src/main/java/com/ruoyi/purchase/controller/PurchaseLedgerController.java
index 2358caf..614d44e 100644
--- a/src/main/java/com/ruoyi/purchase/controller/PurchaseLedgerController.java
+++ b/src/main/java/com/ruoyi/purchase/controller/PurchaseLedgerController.java
@@ -11,6 +11,7 @@
import com.ruoyi.framework.web.domain.AjaxResult;
import com.ruoyi.framework.web.page.TableDataInfo;
import com.ruoyi.purchase.dto.PurchaseLedgerDto;
+import com.ruoyi.purchase.dto.PurchaseScanStockDto;
import com.ruoyi.purchase.mapper.PurchaseLedgerTemplateMapper;
import com.ruoyi.purchase.mapper.SalesLedgerProductTemplateMapper;
import com.ruoyi.purchase.pojo.PurchaseLedger;
@@ -268,4 +269,32 @@
public AjaxResult createPurchaseNo() {
return AjaxResult.success("鐢熸垚鎴愬姛",purchaseLedgerService.getPurchaseNo());
}
+
+ @PostMapping("/scanInbound")
+ @ApiOperation("閲囪喘璁㈠崟鎵爜-鍚堟牸鍏ュ簱")
+ public AjaxResult scanInbound(@RequestBody PurchaseScanStockDto dto) {
+ purchaseLedgerService.scanInbound(dto);
+ return AjaxResult.success();
+ }
+
+ @PostMapping("/scanInboundUnqualified")
+ @ApiOperation("閲囪喘璁㈠崟鎵爜-涓嶅悎鏍煎叆搴�")
+ public AjaxResult scanInboundUnqualified(@RequestBody PurchaseScanStockDto dto) {
+ purchaseLedgerService.scanInboundUnqualified(dto);
+ return AjaxResult.success();
+ }
+
+ @PostMapping("/scanOutbound")
+ @ApiOperation("閲囪喘璁㈠崟鎵爜-鍚堟牸鍑哄簱")
+ public AjaxResult scanOutbound(@RequestBody PurchaseScanStockDto dto) {
+ purchaseLedgerService.scanOutbound(dto);
+ return AjaxResult.success();
+ }
+
+ @PostMapping("/scanOutboundUnqualified")
+ @ApiOperation("閲囪喘璁㈠崟鎵爜-涓嶅悎鏍煎嚭搴�")
+ public AjaxResult scanOutboundUnqualified(@RequestBody PurchaseScanStockDto dto) {
+ purchaseLedgerService.scanOutboundUnqualified(dto);
+ return AjaxResult.success();
+ }
}
diff --git a/src/main/java/com/ruoyi/purchase/dto/PurchaseScanStockDto.java b/src/main/java/com/ruoyi/purchase/dto/PurchaseScanStockDto.java
new file mode 100644
index 0000000..00df58b
--- /dev/null
+++ b/src/main/java/com/ruoyi/purchase/dto/PurchaseScanStockDto.java
@@ -0,0 +1,22 @@
+package com.ruoyi.purchase.dto;
+
+import com.ruoyi.sales.pojo.SalesLedgerProduct;
+import io.swagger.annotations.ApiModel;
+import io.swagger.annotations.ApiModelProperty;
+import lombok.Data;
+
+import java.util.List;
+
+/**
+ * 閲囪喘璁㈠崟鎵爜鍏ュ嚭搴�(鍚堟牸/涓嶅悎鏍�)Dto
+ */
+@Data
+@ApiModel(value = "PurchaseScanStockDto", description = "閲囪喘璁㈠崟鎵爜鍏ュ嚭搴�(鍚堟牸/涓嶅悎鏍�)")
+public class PurchaseScanStockDto {
+
+ @ApiModelProperty("閲囪喘璁㈠崟Id")
+ private Long purchaseLedgerId;
+
+ @ApiModelProperty("閲囪喘浜у搧琛屾暟鎹�")
+ private List<SalesLedgerProduct> salesLedgerProductList;
+}
diff --git a/src/main/java/com/ruoyi/purchase/service/IPurchaseLedgerService.java b/src/main/java/com/ruoyi/purchase/service/IPurchaseLedgerService.java
index 34d19b3..f57288b 100644
--- a/src/main/java/com/ruoyi/purchase/service/IPurchaseLedgerService.java
+++ b/src/main/java/com/ruoyi/purchase/service/IPurchaseLedgerService.java
@@ -5,11 +5,11 @@
import com.baomidou.mybatisplus.extension.service.IService;
import com.ruoyi.framework.web.domain.AjaxResult;
import com.ruoyi.purchase.dto.PurchaseLedgerDto;
+import com.ruoyi.purchase.dto.PurchaseScanStockDto;
import com.ruoyi.purchase.pojo.PurchaseLedger;
import com.ruoyi.sales.pojo.InvoiceRegistrationProduct;
import org.springframework.web.multipart.MultipartFile;
-import java.io.IOException;
import java.util.List;
/**
@@ -45,4 +45,12 @@
AjaxResult importData(MultipartFile file);
PurchaseLedgerDto getPurchaseByCode(PurchaseLedgerDto purchaseLedgerDto);
+
+ void scanInbound(PurchaseScanStockDto dto);
+
+ void scanInboundUnqualified(PurchaseScanStockDto dto);
+
+ void scanOutbound(PurchaseScanStockDto dto);
+
+ void scanOutboundUnqualified(PurchaseScanStockDto dto);
}
diff --git a/src/main/java/com/ruoyi/purchase/service/impl/PurchaseLedgerServiceImpl.java b/src/main/java/com/ruoyi/purchase/service/impl/PurchaseLedgerServiceImpl.java
index b23148a..2d0ceae 100644
--- a/src/main/java/com/ruoyi/purchase/service/impl/PurchaseLedgerServiceImpl.java
+++ b/src/main/java/com/ruoyi/purchase/service/impl/PurchaseLedgerServiceImpl.java
@@ -1,29 +1,28 @@
package com.ruoyi.purchase.service.impl;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
-import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.core.metadata.IPage;
import com.baomidou.mybatisplus.core.toolkit.CollectionUtils;
import com.baomidou.mybatisplus.core.toolkit.ObjectUtils;
import com.baomidou.mybatisplus.core.toolkit.Wrappers;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
-import com.ruoyi.account.pojo.AccountExpense;
-import com.ruoyi.account.pojo.AccountIncome;
import com.ruoyi.account.service.AccountExpenseService;
-import com.ruoyi.account.service.AccountIncomeService;
import com.ruoyi.approve.pojo.ApproveProcess;
import com.ruoyi.approve.service.impl.ApproveProcessServiceImpl;
import com.ruoyi.approve.vo.ApproveProcessVO;
import com.ruoyi.basic.mapper.ProductMapper;
import com.ruoyi.basic.mapper.ProductModelMapper;
import com.ruoyi.basic.mapper.SupplierManageMapper;
-import com.ruoyi.basic.pojo.Customer;
import com.ruoyi.basic.pojo.Product;
import com.ruoyi.basic.pojo.ProductModel;
import com.ruoyi.basic.pojo.SupplierManage;
import com.ruoyi.common.enums.FileNameType;
+import com.ruoyi.common.enums.StockInQualifiedRecordTypeEnum;
+import com.ruoyi.common.enums.StockInUnQualifiedRecordTypeEnum;
+import com.ruoyi.common.enums.StockOutQualifiedRecordTypeEnum;
+import com.ruoyi.common.enums.StockOutUnQualifiedRecordTypeEnum;
+import com.ruoyi.common.exception.ServiceException;
import com.ruoyi.common.exception.base.BaseException;
-import com.ruoyi.common.utils.DateUtils;
import com.ruoyi.common.utils.SecurityUtils;
import com.ruoyi.common.utils.StringUtils;
import com.ruoyi.common.utils.poi.ExcelUtil;
@@ -32,26 +31,27 @@
import com.ruoyi.other.mapper.TempFileMapper;
import com.ruoyi.other.pojo.TempFile;
import com.ruoyi.procurementrecord.mapper.ProcurementRecordMapper;
+import com.ruoyi.procurementrecord.utils.StockUtils;
import com.ruoyi.procurementrecord.pojo.ProcurementRecordStorage;
import com.ruoyi.project.system.domain.SysUser;
import com.ruoyi.project.system.mapper.SysUserMapper;
import com.ruoyi.purchase.dto.PurchaseLedgerDto;
import com.ruoyi.purchase.dto.PurchaseLedgerImportDto;
import com.ruoyi.purchase.dto.PurchaseLedgerProductImportDto;
+import com.ruoyi.purchase.dto.PurchaseScanStockDto;
import com.ruoyi.purchase.mapper.*;
import com.ruoyi.purchase.pojo.*;
import com.ruoyi.purchase.service.IPurchaseLedgerService;
import com.ruoyi.quality.mapper.*;
import com.ruoyi.quality.pojo.*;
-import com.ruoyi.sales.dto.SalesLedgerImportDto;
-import com.ruoyi.sales.dto.SalesLedgerProductImportDto;
import com.ruoyi.sales.mapper.*;
import com.ruoyi.sales.pojo.CommonFile;
import com.ruoyi.sales.pojo.InvoiceRegistrationProduct;
import com.ruoyi.sales.pojo.SalesLedger;
import com.ruoyi.sales.pojo.SalesLedgerProduct;
import com.ruoyi.sales.service.impl.CommonFileServiceImpl;
-import lombok.RequiredArgsConstructor;
+import com.ruoyi.stock.dto.StockInventoryDto;
+import com.ruoyi.stock.service.StockInventoryService;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.io.FilenameUtils;
import org.springframework.beans.BeanUtils;
@@ -78,6 +78,8 @@
import java.util.concurrent.TimeUnit;
import java.util.stream.Collectors;
+import static com.ruoyi.common.enums.SaleEnum.PURCHASE;
+
/**
* 閲囪喘鍙拌处Service涓氬姟灞傚鐞�
*
@@ -88,68 +90,72 @@
@Slf4j
public class PurchaseLedgerServiceImpl extends ServiceImpl<PurchaseLedgerMapper, PurchaseLedger> implements IPurchaseLedgerService {
@Autowired
- private AccountExpenseService accountExpenseService;
+ private AccountExpenseService accountExpenseService;
@Autowired
- private PurchaseLedgerMapper purchaseLedgerMapper;
+ private PurchaseLedgerMapper purchaseLedgerMapper;
@Autowired
- private SalesLedgerMapper salesLedgerMapper;
+ private SalesLedgerMapper salesLedgerMapper;
@Autowired
- private SalesLedgerProductMapper salesLedgerProductMapper;
+ private SalesLedgerProductMapper salesLedgerProductMapper;
@Autowired
- private SysUserMapper userMapper;
+ private SysUserMapper userMapper;
@Autowired
- private TempFileMapper tempFileMapper;
+ private TempFileMapper tempFileMapper;
@Autowired
- private CommonFileMapper commonFileMapper;
+ private CommonFileMapper commonFileMapper;
@Autowired
- private SupplierManageMapper supplierManageMapper;
+ private SupplierManageMapper supplierManageMapper;
@Autowired
- private ProductMapper productMapper;
+ private ProductMapper productMapper;
@Autowired
- private ProductModelMapper productModelMapper;
+ private ProductModelMapper productModelMapper;
@Autowired
- private SysUserMapper sysUserMapper;
+ private SysUserMapper sysUserMapper;
@Autowired
- private TicketRegistrationMapper ticketRegistrationMapper;
+ private TicketRegistrationMapper ticketRegistrationMapper;
@Autowired
- private ProductRecordMapper productRecordMapper;
+ private ProductRecordMapper productRecordMapper;
@Autowired
- private PaymentRegistrationMapper paymentRegistrationMapper;
+ private PaymentRegistrationMapper paymentRegistrationMapper;
@Autowired
- private InvoiceRegistrationProductMapper invoiceRegistrationProductMapper;
+ private InvoiceRegistrationProductMapper invoiceRegistrationProductMapper;
@Autowired
- private StringRedisTemplate redisTemplate;
+ private StringRedisTemplate redisTemplate;
@Autowired
- private QualityInspectMapper qualityInspectMapper;
+ private QualityInspectMapper qualityInspectMapper;
@Autowired
- private CommonFileServiceImpl commonFileService;
+ private CommonFileServiceImpl commonFileService;
@Autowired
- private QualityTestStandardBindingMapper qualityTestStandardBindingMapper;
+ private QualityTestStandardBindingMapper qualityTestStandardBindingMapper;
@Autowired
- private QualityTestStandardParamMapper qualityTestStandardParamMapper;
+ private QualityTestStandardParamMapper qualityTestStandardParamMapper;
@Autowired
- private QualityTestStandardMapper qualityTestStandardMapper;
+ private QualityTestStandardMapper qualityTestStandardMapper;
@Autowired
- private QualityInspectParamMapper qualityInspectParamMapper;
+ private QualityInspectParamMapper qualityInspectParamMapper;
@Autowired
- private ApproveProcessServiceImpl approveProcessService;
+ private ApproveProcessServiceImpl approveProcessService;
@Autowired
- private ProcurementRecordMapper procurementRecordStorageMapper;
+ private ProcurementRecordMapper procurementRecordStorageMapper;
@Autowired
- private PurchaseLedgerTemplateMapper purchaseLedgerTemplateMapper;
+ private PurchaseLedgerTemplateMapper purchaseLedgerTemplateMapper;
@Autowired
- private SalesLedgerProductTemplateMapper salesLedgerProductTemplateMapper;
+ private SalesLedgerProductTemplateMapper salesLedgerProductTemplateMapper;
+ @Autowired
+ private StockInventoryService stockInventoryService;
+ @Autowired
+ private StockUtils stockUtils;
@Value("${file.upload-dir}")
private String uploadDir;
@@ -159,7 +165,7 @@
if (StringUtils.isNotBlank(purchaseLedger.getPurchaseContractNumber())) {
queryWrapper.like(PurchaseLedger::getPurchaseContractNumber, purchaseLedger.getPurchaseContractNumber());
}
- if(purchaseLedger.getSupplierId()!=null){
+ if (purchaseLedger.getSupplierId() != null) {
queryWrapper.eq(PurchaseLedger::getSupplierId, purchaseLedger.getSupplierId());
}
if (purchaseLedger.getApprovalStatus() != null) {
@@ -244,12 +250,12 @@
qualityInspect.setUnit(saleProduct.getUnit());
qualityInspect.setQuantity(saleProduct.getQuantity());
qualityInspectMapper.insert(qualityInspect);
- List<QualityTestStandard> qualityTestStandard = qualityTestStandardMapper.getQualityTestStandardByProductId(saleProduct.getProductId(), 0,null);
- if (qualityTestStandard.size()>0){
+ List<QualityTestStandard> qualityTestStandard = qualityTestStandardMapper.getQualityTestStandardByProductId(saleProduct.getProductId(), 0, null);
+ if (qualityTestStandard.size() > 0) {
qualityInspect.setTestStandardId(qualityTestStandard.get(0).getId());
qualityInspectMapper.updateById(qualityInspect);
qualityTestStandardParamMapper.selectList(Wrappers.<QualityTestStandardParam>lambdaQuery()
- .eq(QualityTestStandardParam::getTestStandardId,qualityTestStandard.get(0).getId()))
+ .eq(QualityTestStandardParam::getTestStandardId, qualityTestStandard.get(0).getId()))
.forEach(qualityTestStandardParam -> {
QualityInspectParam param = new QualityInspectParam();
com.ruoyi.common.utils.bean.BeanUtils.copyProperties(qualityTestStandardParam, param);
@@ -316,6 +322,7 @@
if (!updateList.isEmpty()) {
for (SalesLedgerProduct product : updateList) {
product.setType(type);
+ product.fillRemainingQuantity();
salesLedgerProductMapper.updateById(product);
}
}
@@ -330,6 +337,7 @@
salesLedgerProduct.setFutureTickets(salesLedgerProduct.getQuantity());
salesLedgerProduct.setFutureTicketsAmount(salesLedgerProduct.getTaxInclusiveTotalPrice());
salesLedgerProduct.setPendingTicketsTotal(salesLedgerProduct.getTaxInclusiveTotalPrice());
+ salesLedgerProduct.fillRemainingQuantity();
salesLedgerProductMapper.insert(salesLedgerProduct);
}
}
@@ -425,12 +433,12 @@
@Transactional(rollbackFor = Exception.class)
public int deletePurchaseLedgerByIds(Long[] ids) {
if (ids == null || ids.length == 0) {
- throw new BaseException("璇烽�変腑鑷冲皯涓�鏉℃暟鎹�");
+ throw new BaseException("璇烽�変腑鑷冲皯涓�鏉℃暟鎹�");
}
for (Long id : ids) {
PurchaseLedger purchaseLedger = purchaseLedgerMapper.selectById(id);
if (purchaseLedger.getApprovalStatus().equals(3)) {
- throw new BaseException(purchaseLedger.getPurchaseContractNumber()+"宸茬粡瀹℃壒閫氳繃锛屼笉鍏佽鍒犻櫎");
+ throw new BaseException(purchaseLedger.getPurchaseContractNumber() + "宸茬粡瀹℃壒閫氳繃锛屼笉鍏佽鍒犻櫎");
}
}
// 鎵归噺鍒犻櫎鍏宠仈鐨勯噰璐叆搴撹褰�
@@ -453,11 +461,11 @@
salesLedgerProductMapper.delete(queryWrapper);
// 鎵归噺鍒犻櫎鍏宠仈鐨勯噰璐彴璐︾殑鏉ョエ鐧昏
LambdaQueryWrapper<TicketRegistration> ticketRegistrationLambdaQueryWrapper = new LambdaQueryWrapper<>();
- ticketRegistrationLambdaQueryWrapper.in(TicketRegistration::getPurchaseLedgerId,ids);
+ ticketRegistrationLambdaQueryWrapper.in(TicketRegistration::getPurchaseLedgerId, ids);
ticketRegistrationMapper.delete(ticketRegistrationLambdaQueryWrapper);
// 鎵归噺鍒犻櫎鍏宠仈鐨勯噰璐彴璐︾殑鏉ョエ鐧昏璁板綍
LambdaQueryWrapper<ProductRecord> productRecordLambdaQueryWrapper = new LambdaQueryWrapper<>();
- productRecordLambdaQueryWrapper.in(ProductRecord::getPurchaseLedgerId,ids);
+ productRecordLambdaQueryWrapper.in(ProductRecord::getPurchaseLedgerId, ids);
productRecordMapper.delete(productRecordLambdaQueryWrapper);
// 鎵归噺鍒犻櫎浠樻鐧昏
LambdaQueryWrapper<PaymentRegistration> paymentRegistrationLambdaQueryWrapper = new LambdaQueryWrapper<>();
@@ -469,7 +477,7 @@
List<QualityInspect> qualityInspects = qualityInspectMapper.selectList(materialInspectLambdaQueryWrapper);
qualityInspects.stream().forEach(qualityInspect -> {
- if (ObjectUtils.isNotEmpty(qualityInspect.getInspectState())&&qualityInspect.getInspectState().equals(1)) {
+ if (ObjectUtils.isNotEmpty(qualityInspect.getInspectState()) && qualityInspect.getInspectState().equals(1)) {
throw new BaseException("宸叉彁浜ょ殑妫�楠屽崟涓嶈兘鍒犻櫎");
}
});
@@ -485,7 +493,7 @@
// 鍒犻櫎閲囪喘瀹℃壒璁板綍
for (Long id : ids) {
PurchaseLedger purchaseLedger = purchaseLedgerMapper.selectById(id);
- if(purchaseLedger != null){
+ if (purchaseLedger != null) {
ApproveProcess one = approveProcessService.getOne(new LambdaQueryWrapper<ApproveProcess>()
.eq(ApproveProcess::getApproveType, 5)
.eq(ApproveProcess::getApproveDelete, 0)
@@ -517,11 +525,12 @@
productWrapper.eq(SalesLedgerProduct::getSalesLedgerId, purchaseLedger.getId())
.eq(SalesLedgerProduct::getType, purchaseLedgerDto.getType());
List<SalesLedgerProduct> products = salesLedgerProductMapper.selectList(productWrapper);
+ products.forEach(SalesLedgerProduct::fillRemainingQuantity);
// 3.鏌ヨ涓婁紶鏂囦欢
LambdaQueryWrapper<CommonFile> salesLedgerFileWrapper = new LambdaQueryWrapper<>();
salesLedgerFileWrapper.eq(CommonFile::getCommonId, purchaseLedger.getId())
- .eq(CommonFile::getType,FileNameType.PURCHASE.getValue());
+ .eq(CommonFile::getType, FileNameType.PURCHASE.getValue());
List<CommonFile> salesLedgerFiles = commonFileMapper.selectList(salesLedgerFileWrapper);
// 4. 杞崲 DTO
@@ -577,6 +586,7 @@
product.setTicketsAmount(null);
product.setTempFutureTickets(product.getFutureTickets());
product.setTempFutureTicketsAmount(product.getFutureTicketsAmount());
+ product.fillRemainingQuantity();
});
resultDto.setProductData(productList);
return resultDto;
@@ -672,7 +682,7 @@
// 渚涘簲鍟嗘暟鎹�
List<SupplierManage> customers = supplierManageMapper.selectList(new LambdaQueryWrapper<SupplierManage>().in(SupplierManage::getSupplierName,
salesLedgerImportDtoList.stream().map(PurchaseLedgerImportDto::getSupplierName).collect(Collectors.toList())));
- List<Map<String,Object>> list = productModelMapper.getProductAndModelList();
+ List<Map<String, Object>> list = productModelMapper.getProductAndModelList();
// 褰曞叆浜烘暟鎹�
List<SysUser> sysUsers = sysUserMapper.selectList(new LambdaQueryWrapper<SysUser>().in(SysUser::getNickName,
salesLedgerImportDtoList.stream().map(PurchaseLedgerImportDto::getRecorderName).collect(Collectors.toList())));
@@ -680,7 +690,7 @@
PurchaseLedger purchaseLedger = purchaseLedgerMapper.selectOne(new LambdaQueryWrapper<PurchaseLedger>()
.eq(PurchaseLedger::getPurchaseContractNumber, salesLedgerImportDto.getPurchaseContractNumber())
.last("limit 1"));
- if(purchaseLedger != null){
+ if (purchaseLedger != null) {
continue;
}
PurchaseLedger salesLedger = new PurchaseLedger();
@@ -707,12 +717,12 @@
throw new RuntimeException("閲囪喘鍗曞彿:" + salesLedgerImportDto.getPurchaseContractNumber() + ",鏃犲搴斾骇鍝佹暟鎹紒");
salesLedger.setContractAmount(salesLedgerProductImportDtos.stream()
.map(PurchaseLedgerProductImportDto::getTaxInclusiveTotalPrice)
- .reduce(BigDecimal.ZERO,BigDecimal::add));
+ .reduce(BigDecimal.ZERO, BigDecimal::add));
// 閫氳繃閿�鍞崟鍙风粦瀹氶攢鍞�
SalesLedger salesLedger1 = salesLedgerMapper.selectOne(new LambdaQueryWrapper<SalesLedger>()
.eq(SalesLedger::getSalesContractNo, salesLedger.getSalesContractNo())
.last("LIMIT 1"));
- if(salesLedger1 != null){
+ if (salesLedger1 != null) {
salesLedger.setSalesLedgerId(salesLedger1.getId());
}
// 閲囪喘瀹℃牳
@@ -753,13 +763,14 @@
salesLedgerProduct.setPendingTicketsTotal(salesLedgerProductImportDto.getTaxInclusiveTotalPrice());
// 鏄惁璐ㄦ鍒ゆ柇
salesLedgerProduct.setIsChecked(salesLedgerProductImportDto.getIsChecked() == 1);
- if(salesLedgerProductImportDto.getIsChecked() == 1){
+ if (salesLedgerProductImportDto.getIsChecked() == 1) {
addQualityInspect(salesLedger, salesLedgerProduct);
}
+ salesLedgerProduct.fillRemainingQuantity();
salesLedgerProductMapper.insert(salesLedgerProduct);
}
// 閲囪喘瀹℃牳
- addApproveByPurchase(loginUser,salesLedger);
+ addApproveByPurchase(loginUser, salesLedger);
}
return AjaxResult.success("瀵煎叆鎴愬姛");
@@ -784,6 +795,7 @@
productWrapper.eq(SalesLedgerProduct::getSalesLedgerId, purchaseLedger.getId())
.eq(SalesLedgerProduct::getType, 2);
List<SalesLedgerProduct> products = salesLedgerProductMapper.selectList(productWrapper);
+ products.forEach(SalesLedgerProduct::fillRemainingQuantity);
// 4. 杞崲 DTO
PurchaseLedgerDto resultDto = new PurchaseLedgerDto();
@@ -795,7 +807,7 @@
return resultDto;
}
- public void addApproveByPurchase(LoginUser loginUser,PurchaseLedger purchaseLedger) throws Exception {
+ public void addApproveByPurchase(LoginUser loginUser, PurchaseLedger purchaseLedger) throws Exception {
ApproveProcessVO approveProcessVO = new ApproveProcessVO();
approveProcessVO.setApproveType(5);
approveProcessVO.setApproveDeptId(loginUser.getCurrentDeptId());
@@ -806,6 +818,258 @@
approveProcessService.addApprove(approveProcessVO);
}
+ @Override
+ @Transactional(rollbackFor = Exception.class)
+ public void scanInbound(PurchaseScanStockDto dto) {
+ if (dto == null || dto.getPurchaseLedgerId() == null) {
+ throw new ServiceException("閲囪喘鍏ュ簱澶辫触,鍏ュ簱鏁版嵁涓嶈兘涓虹┖");
+ }
+ PurchaseLedger purchaseLedger = purchaseLedgerMapper.selectById(dto.getPurchaseLedgerId());
+ if (purchaseLedger == null) {
+ throw new ServiceException("鍏ュ簱澶辫触,閲囪喘鍙拌处涓嶅瓨鍦�");
+ }
+ if (CollectionUtils.isEmpty(dto.getSalesLedgerProductList())) {
+ throw new ServiceException("閲囪喘鍏ュ簱澶辫触,鍏ュ簱浜у搧涓嶈兘涓虹┖");
+ }
+ int purchaseType = PURCHASE.getCode();
+ Map<Long, BigDecimal> inboundQtyByLineId = new LinkedHashMap<>();
+ for (SalesLedgerProduct inbound : dto.getSalesLedgerProductList()) {
+ if (inbound == null || inbound.getId() == null) {
+ throw new ServiceException("鍏ュ簱澶辫触,閲囪喘浜у搧淇℃伅涓嶅畬鏁�");
+ }
+ BigDecimal inboundQty = inbound.getStockedQuantity();
+ if (inboundQty == null) {
+ throw new ServiceException("鍏ュ簱澶辫触,鍏ュ簱鏁伴噺涓嶈兘涓虹┖");
+ }
+ if (inboundQty.compareTo(BigDecimal.ZERO) < 0) {
+ throw new ServiceException("鍏ュ簱澶辫触,鍏ュ簱鏁伴噺涓嶈兘涓鸿礋鏁�");
+ }
+ inboundQtyByLineId.merge(inbound.getId(), inboundQty, BigDecimal::add);
+ }
+ Long purchaseId = purchaseLedger.getId();
+ for (Map.Entry<Long, BigDecimal> entry : inboundQtyByLineId.entrySet()) {
+ Long productLineId = entry.getKey();
+ BigDecimal inboundThisLine = entry.getValue();
+ if (inboundThisLine.compareTo(BigDecimal.ZERO) == 0) {
+ continue;
+ }
+ SalesLedgerProduct dbProduct = salesLedgerProductMapper.selectById(productLineId);
+ if (dbProduct == null) {
+ throw new ServiceException("鍏ュ簱澶辫触,閲囪喘浜у搧涓嶅瓨鍦�");
+ }
+ if (!Objects.equals(dbProduct.getSalesLedgerId(), purchaseId) || !Objects.equals(dbProduct.getType(), purchaseType)) {
+ throw new ServiceException("鍏ュ簱澶辫触,浜у搧涓庨噰璐彴璐︿笉鍖归厤");
+ }
+ if (dbProduct.getProductModelId() == null) {
+ throw new ServiceException("鍏ュ簱澶辫触,浜у搧瑙勬牸鏈淮鎶�,鏃犳硶鍏ュ簱");
+ }
+ BigDecimal oldStocked = dbProduct.getStockedQuantity() == null ? BigDecimal.ZERO : dbProduct.getStockedQuantity();
+ BigDecimal newStocked = oldStocked.add(inboundThisLine);
+
+ StockInventoryDto stockInventoryDto = new StockInventoryDto();
+ stockInventoryDto.setRecordId(dbProduct.getId());
+ stockInventoryDto.setRecordType(StockInQualifiedRecordTypeEnum.PURCHASE_SCAN_STOCK_IN.getCode());
+ stockInventoryDto.setQualitity(inboundThisLine);
+ stockInventoryDto.setProductModelId(dbProduct.getProductModelId());
+ stockInventoryDto.setSalesLedgerId(null);
+ stockInventoryDto.setSalesLedgerProductId(dbProduct.getId());
+ stockInventoryService.addstockInventory(stockInventoryDto);
+
+ BigDecimal orderQty = dbProduct.getQuantity() == null ? BigDecimal.ZERO : dbProduct.getQuantity();
+ int lineStockStatus;
+ if (newStocked.compareTo(BigDecimal.ZERO) <= 0) {
+ lineStockStatus = 0;
+ } else if (orderQty.compareTo(BigDecimal.ZERO) > 0 && newStocked.compareTo(orderQty) < 0) {
+ lineStockStatus = 1;
+ } else {
+ lineStockStatus = 2;
+ }
+ dbProduct.setStockedQuantity(newStocked);
+ dbProduct.setProductStockStatus(lineStockStatus);
+ dbProduct.fillRemainingQuantity();
+ salesLedgerProductMapper.updateById(dbProduct);
+ }
+ }
+
+ @Override
+ @Transactional(rollbackFor = Exception.class)
+ public void scanOutbound(PurchaseScanStockDto dto) {
+ if (dto == null || dto.getPurchaseLedgerId() == null) {
+ throw new ServiceException("閲囪喘鍑哄簱澶辫触,鍑哄簱鏁版嵁涓嶈兘涓虹┖");
+ }
+ PurchaseLedger purchaseLedger = purchaseLedgerMapper.selectById(dto.getPurchaseLedgerId());
+ if (purchaseLedger == null) {
+ throw new ServiceException("鍑哄簱澶辫触,閲囪喘鍙拌处涓嶅瓨鍦�");
+ }
+ if (CollectionUtils.isEmpty(dto.getSalesLedgerProductList())) {
+ throw new ServiceException("閲囪喘鍑哄簱澶辫触,鍑哄簱浜у搧涓嶈兘涓虹┖");
+ }
+ int purchaseType = PURCHASE.getCode();
+ Map<Long, BigDecimal> outboundQtyByLineId = new LinkedHashMap<>();
+ for (SalesLedgerProduct line : dto.getSalesLedgerProductList()) {
+ if (line == null || line.getId() == null) {
+ throw new ServiceException("鍑哄簱澶辫触,閲囪喘浜у搧淇℃伅涓嶅畬鏁�");
+ }
+ BigDecimal outboundQty = line.getStockedQuantity();
+ if (outboundQty == null) {
+ throw new ServiceException("鍑哄簱澶辫触,鍑哄簱鏁伴噺涓嶈兘涓虹┖");
+ }
+ if (outboundQty.compareTo(BigDecimal.ZERO) < 0) {
+ throw new ServiceException("鍑哄簱澶辫触,鍑哄簱鏁伴噺涓嶈兘涓鸿礋鏁�");
+ }
+ outboundQtyByLineId.merge(line.getId(), outboundQty, BigDecimal::add);
+ }
+ Long purchaseId = purchaseLedger.getId();
+ for (Map.Entry<Long, BigDecimal> entry : outboundQtyByLineId.entrySet()) {
+ Long productLineId = entry.getKey();
+ BigDecimal outboundThisLine = entry.getValue();
+ if (outboundThisLine.compareTo(BigDecimal.ZERO) == 0) {
+ continue;
+ }
+ SalesLedgerProduct dbProduct = salesLedgerProductMapper.selectById(productLineId);
+ if (dbProduct == null) {
+ throw new ServiceException("鍑哄簱澶辫触,閲囪喘浜у搧涓嶅瓨鍦�");
+ }
+ if (!Objects.equals(dbProduct.getSalesLedgerId(), purchaseId) || !Objects.equals(dbProduct.getType(), purchaseType)) {
+ throw new ServiceException("鍑哄簱澶辫触,浜у搧涓庨噰璐彴璐︿笉鍖归厤");
+ }
+ if (dbProduct.getProductModelId() == null) {
+ throw new ServiceException("鍑哄簱澶辫触,浜у搧瑙勬牸鏈淮鎶�,鏃犳硶鍑哄簱");
+ }
+ stockUtils.assertQualifiedAvailable(dbProduct.getProductModelId(), outboundThisLine);
+
+ BigDecimal oldStocked = dbProduct.getStockedQuantity() == null ? BigDecimal.ZERO : dbProduct.getStockedQuantity();
+ BigDecimal newStocked = oldStocked.subtract(outboundThisLine);
+ if (newStocked.compareTo(BigDecimal.ZERO) < 0) {
+ newStocked = BigDecimal.ZERO;
+ }
+
+ StockInventoryDto stockInventoryDto = new StockInventoryDto();
+ stockInventoryDto.setRecordId(dbProduct.getId());
+ stockInventoryDto.setRecordType(StockOutQualifiedRecordTypeEnum.PURCHASE_SCAN_STOCK_OUT.getCode());
+ stockInventoryDto.setQualitity(outboundThisLine);
+ stockInventoryDto.setProductModelId(dbProduct.getProductModelId());
+ stockInventoryDto.setSalesLedgerId(null);
+ stockInventoryDto.setSalesLedgerProductId(dbProduct.getId());
+ stockInventoryService.subtractStockInventory(stockInventoryDto);
+
+ BigDecimal orderQty = dbProduct.getQuantity() == null ? BigDecimal.ZERO : dbProduct.getQuantity();
+ int lineStockStatus;
+ if (newStocked.compareTo(BigDecimal.ZERO) <= 0) {
+ lineStockStatus = 0;
+ } else if (orderQty.compareTo(BigDecimal.ZERO) > 0 && newStocked.compareTo(orderQty) < 0) {
+ lineStockStatus = 1;
+ } else {
+ lineStockStatus = 2;
+ }
+ dbProduct.setStockedQuantity(newStocked);
+ dbProduct.setProductStockStatus(lineStockStatus);
+ dbProduct.fillRemainingQuantity();
+ salesLedgerProductMapper.updateById(dbProduct);
+ }
+ }
+
+ @Override
+ @Transactional(rollbackFor = Exception.class)
+ public void scanInboundUnqualified(PurchaseScanStockDto dto) {
+ if (dto == null || dto.getPurchaseLedgerId() == null) {
+ throw new ServiceException("閲囪喘涓嶅悎鏍煎叆搴撳け璐�,鍏ュ簱鏁版嵁涓嶈兘涓虹┖");
+ }
+ PurchaseLedger purchaseLedger = purchaseLedgerMapper.selectById(dto.getPurchaseLedgerId());
+ if (purchaseLedger == null) {
+ throw new ServiceException("涓嶅悎鏍煎叆搴撳け璐�,閲囪喘鍙拌处涓嶅瓨鍦�");
+ }
+ if (CollectionUtils.isEmpty(dto.getSalesLedgerProductList())) {
+ throw new ServiceException("閲囪喘涓嶅悎鏍煎叆搴撳け璐�,鍏ュ簱浜у搧涓嶈兘涓虹┖");
+ }
+ int purchaseType = PURCHASE.getCode();
+ Map<Long, BigDecimal> inboundQtyByLineId = new LinkedHashMap<>();
+ for (SalesLedgerProduct inbound : dto.getSalesLedgerProductList()) {
+ if (inbound == null || inbound.getId() == null) {
+ throw new ServiceException("涓嶅悎鏍煎叆搴撳け璐�,閲囪喘浜у搧淇℃伅涓嶅畬鏁�");
+ }
+ BigDecimal inboundQty = inbound.getStockedQuantity();
+ if (inboundQty == null) {
+ throw new ServiceException("涓嶅悎鏍煎叆搴撳け璐�,鍏ュ簱鏁伴噺涓嶈兘涓虹┖");
+ }
+ if (inboundQty.compareTo(BigDecimal.ZERO) < 0) {
+ throw new ServiceException("涓嶅悎鏍煎叆搴撳け璐�,鍏ュ簱鏁伴噺涓嶈兘涓鸿礋鏁�");
+ }
+ inboundQtyByLineId.merge(inbound.getId(), inboundQty, BigDecimal::add);
+ }
+ Long purchaseId = purchaseLedger.getId();
+ for (Map.Entry<Long, BigDecimal> entry : inboundQtyByLineId.entrySet()) {
+ Long productLineId = entry.getKey();
+ BigDecimal inboundThisLine = entry.getValue();
+ if (inboundThisLine.compareTo(BigDecimal.ZERO) == 0) {
+ continue;
+ }
+ SalesLedgerProduct dbProduct = salesLedgerProductMapper.selectById(productLineId);
+ if (dbProduct == null) {
+ throw new ServiceException("涓嶅悎鏍煎叆搴撳け璐�,閲囪喘浜у搧涓嶅瓨鍦�");
+ }
+ if (!Objects.equals(dbProduct.getSalesLedgerId(), purchaseId) || !Objects.equals(dbProduct.getType(), purchaseType)) {
+ throw new ServiceException("涓嶅悎鏍煎叆搴撳け璐�,浜у搧涓庨噰璐彴璐︿笉鍖归厤");
+ }
+ if (dbProduct.getProductModelId() == null) {
+ throw new ServiceException("涓嶅悎鏍煎叆搴撳け璐�,浜у搧瑙勬牸鏈淮鎶�,鏃犳硶鍏ュ簱");
+ }
+ stockUtils.addUnStock(null, null, dbProduct.getProductModelId(), inboundThisLine,
+ StockInUnQualifiedRecordTypeEnum.PURCHASE_SCAN_UNSTOCK_IN.getCode(), dbProduct.getId());
+ }
+ }
+
+ @Override
+ @Transactional(rollbackFor = Exception.class)
+ public void scanOutboundUnqualified(PurchaseScanStockDto dto) {
+ if (dto == null || dto.getPurchaseLedgerId() == null) {
+ throw new ServiceException("閲囪喘涓嶅悎鏍煎嚭搴撳け璐�,鍑哄簱鏁版嵁涓嶈兘涓虹┖");
+ }
+ PurchaseLedger purchaseLedger = purchaseLedgerMapper.selectById(dto.getPurchaseLedgerId());
+ if (purchaseLedger == null) {
+ throw new ServiceException("涓嶅悎鏍煎嚭搴撳け璐�,閲囪喘鍙拌处涓嶅瓨鍦�");
+ }
+ if (CollectionUtils.isEmpty(dto.getSalesLedgerProductList())) {
+ throw new ServiceException("閲囪喘涓嶅悎鏍煎嚭搴撳け璐�,鍑哄簱浜у搧涓嶈兘涓虹┖");
+ }
+ int purchaseType = PURCHASE.getCode();
+ Map<Long, BigDecimal> outboundQtyByLineId = new LinkedHashMap<>();
+ for (SalesLedgerProduct line : dto.getSalesLedgerProductList()) {
+ if (line == null || line.getId() == null) {
+ throw new ServiceException("涓嶅悎鏍煎嚭搴撳け璐�,閲囪喘浜у搧淇℃伅涓嶅畬鏁�");
+ }
+ BigDecimal outboundQty = line.getStockedQuantity();
+ if (outboundQty == null) {
+ throw new ServiceException("涓嶅悎鏍煎嚭搴撳け璐�,鍑哄簱鏁伴噺涓嶈兘涓虹┖");
+ }
+ if (outboundQty.compareTo(BigDecimal.ZERO) < 0) {
+ throw new ServiceException("涓嶅悎鏍煎嚭搴撳け璐�,鍑哄簱鏁伴噺涓嶈兘涓鸿礋鏁�");
+ }
+ outboundQtyByLineId.merge(line.getId(), outboundQty, BigDecimal::add);
+ }
+ Long purchaseId = purchaseLedger.getId();
+ for (Map.Entry<Long, BigDecimal> entry : outboundQtyByLineId.entrySet()) {
+ Long productLineId = entry.getKey();
+ BigDecimal outboundThisLine = entry.getValue();
+ if (outboundThisLine.compareTo(BigDecimal.ZERO) == 0) {
+ continue;
+ }
+ SalesLedgerProduct dbProduct = salesLedgerProductMapper.selectById(productLineId);
+ if (dbProduct == null) {
+ throw new ServiceException("涓嶅悎鏍煎嚭搴撳け璐�,閲囪喘浜у搧涓嶅瓨鍦�");
+ }
+ if (!Objects.equals(dbProduct.getSalesLedgerId(), purchaseId) || !Objects.equals(dbProduct.getType(), purchaseType)) {
+ throw new ServiceException("涓嶅悎鏍煎嚭搴撳け璐�,浜у搧涓庨噰璐彴璐︿笉鍖归厤");
+ }
+ if (dbProduct.getProductModelId() == null) {
+ throw new ServiceException("涓嶅悎鏍煎嚭搴撳け璐�,浜у搧瑙勬牸鏈淮鎶�,鏃犳硶鍑哄簱");
+ }
+ stockUtils.assertUnqualifiedAvailable(dbProduct.getProductModelId(), outboundThisLine);
+ stockUtils.subtractUnStock(null, null, dbProduct.getProductModelId(), outboundThisLine,
+ StockOutUnQualifiedRecordTypeEnum.PURCHASE_SCAN_UNSTOCK_OUT.getCode(), dbProduct.getId());
+ }
+ }
+
/**
* 涓嬪垝绾垮懡鍚嶈浆椹煎嘲鍛藉悕
*/
diff --git a/src/main/java/com/ruoyi/sales/controller/SalesLedgerController.java b/src/main/java/com/ruoyi/sales/controller/SalesLedgerController.java
index 8a11486..b8863c1 100644
--- a/src/main/java/com/ruoyi/sales/controller/SalesLedgerController.java
+++ b/src/main/java/com/ruoyi/sales/controller/SalesLedgerController.java
@@ -411,4 +411,32 @@
return AjaxResult.success(list);
}
+ @PostMapping("/scanInbound")
+ @ApiOperation("閿�鍞鍗曟壂鐮�-鍚堟牸鍏ュ簱")
+ public AjaxResult scanInbound(@RequestBody SalesScanInboundDto dto) {
+ salesLedgerService.scanInbound(dto);
+ return AjaxResult.success();
+ }
+
+ @PostMapping("/scanInboundUnqualified")
+ @ApiOperation("閿�鍞鍗曟壂鐮�-涓嶅悎鏍煎叆搴�")
+ public AjaxResult scanInboundUnqualified(@RequestBody SalesScanInboundDto dto) {
+ salesLedgerService.scanInboundUnqualified(dto);
+ return AjaxResult.success();
+ }
+
+ @PostMapping("/scanOutbound")
+ @ApiOperation("閿�鍞鍗曟壂鐮�-鍚堟牸鍑哄簱")
+ public AjaxResult scanOutbound(@RequestBody SalesScanInboundDto dto) {
+ salesLedgerService.scanOutbound(dto);
+ return AjaxResult.success();
+ }
+
+ @PostMapping("/scanOutboundUnqualified")
+ @ApiOperation("閿�鍞鍗曟壂鐮�-涓嶅悎鏍煎嚭搴�")
+ public AjaxResult scanOutboundUnqualified(@RequestBody SalesScanInboundDto dto) {
+ salesLedgerService.scanOutboundUnqualified(dto);
+ return AjaxResult.success();
+ }
+
}
diff --git a/src/main/java/com/ruoyi/sales/dto/SalesScanInboundDto.java b/src/main/java/com/ruoyi/sales/dto/SalesScanInboundDto.java
new file mode 100644
index 0000000..dd33b4c
--- /dev/null
+++ b/src/main/java/com/ruoyi/sales/dto/SalesScanInboundDto.java
@@ -0,0 +1,23 @@
+package com.ruoyi.sales.dto;
+
+import com.ruoyi.sales.pojo.SalesLedgerProduct;
+import io.swagger.annotations.ApiModel;
+import io.swagger.annotations.ApiModelProperty;
+import lombok.Data;
+
+import java.util.List;
+
+/**
+ * 閿�鍞鍗曟壂鐮佸叆鍑哄簱(鍚堟牸/涓嶅悎鏍�)Dto
+ */
+@Data
+@ApiModel(value = "SalesScanInboundDto", description = "閿�鍞鍗曟壂鐮佸叆鍑哄簱(鍚堟牸/涓嶅悎鏍�)")
+public class SalesScanInboundDto {
+
+ @ApiModelProperty("閿�鍞鍗旾d")
+ private Long SalesLedgerId;
+
+ @ApiModelProperty("閿�鍞骇鍝佽鏁版嵁")
+ private List<SalesLedgerProduct> salesLedgerProductList;
+
+}
diff --git a/src/main/java/com/ruoyi/sales/pojo/SalesLedgerProduct.java b/src/main/java/com/ruoyi/sales/pojo/SalesLedgerProduct.java
index 02d5080..6bb145e 100644
--- a/src/main/java/com/ruoyi/sales/pojo/SalesLedgerProduct.java
+++ b/src/main/java/com/ruoyi/sales/pojo/SalesLedgerProduct.java
@@ -72,8 +72,22 @@
*/
@Excel(name = "鏁伴噺")
private BigDecimal quantity;
+
+ /**
+ * 宸插叆搴撴暟閲�
+ */
+ private BigDecimal stockedQuantity;
+
@Excel(name = "鏈�浣庡簱瀛樻暟閲�")
private BigDecimal minStock;
+
+ /**
+ * 鍓╀綑寰呭叆搴撴暟閲忥紙璁㈠崟鏁伴噺 鈭� 鍚堟牸宸插叆搴撴暟閲忥紝澶氬叆鏃惰涓� 0锛�
+ */
+ @Excel(name = "鍓╀綑鏁伴噺")
+ @ApiModelProperty("鍓╀綑寰呭叆搴撴暟閲�(璁㈠崟鏁伴噺-鍚堟牸宸插叆搴�)")
+ private BigDecimal remainingQuantity;
+
/**
* 绋庣巼
*/
@@ -293,9 +307,9 @@
private String floorCode;
/**
- * 浜у搧鍏ュ簱鐘舵�� 0-鏈叆搴擄紝1-宸插叆搴�
+ * 浜у搧鍏ュ簱鐘舵�侊細0-鏈叆搴擄紝1-閮ㄥ垎鍏ュ簱锛�2-宸插叆搴�
*/
- @ApiModelProperty("浜у搧鍏ュ簱鐘舵��")
+ @ApiModelProperty("浜у搧鍏ュ簱鐘舵�侊細0-鏈叆搴擄紝1-閮ㄥ垎鍏ュ簱锛�2-宸插叆搴�")
private Integer productStockStatus;
@TableField(exist = false)
@@ -312,4 +326,12 @@
// 鍙敤鏁伴噺 quantity - returnQuality
@TableField(exist = false)
private BigDecimal availableQuality;
+
+
+ public void fillRemainingQuantity() {
+ BigDecimal q = this.quantity == null ? BigDecimal.ZERO : this.quantity;
+ BigDecimal stocked = this.stockedQuantity == null ? BigDecimal.ZERO : this.stockedQuantity;
+ BigDecimal rem = q.subtract(stocked);
+ this.remainingQuantity = rem.compareTo(BigDecimal.ZERO) < 0 ? BigDecimal.ZERO : rem;
+ }
}
diff --git a/src/main/java/com/ruoyi/sales/service/ISalesLedgerService.java b/src/main/java/com/ruoyi/sales/service/ISalesLedgerService.java
index 807a830..dc93395 100644
--- a/src/main/java/com/ruoyi/sales/service/ISalesLedgerService.java
+++ b/src/main/java/com/ruoyi/sales/service/ISalesLedgerService.java
@@ -70,4 +70,11 @@
List<Customer> shippedCustomers();
+ void scanInbound(SalesScanInboundDto dto);
+
+ void scanInboundUnqualified(SalesScanInboundDto dto);
+
+ void scanOutbound(SalesScanInboundDto dto);
+
+ void scanOutboundUnqualified(SalesScanInboundDto dto);
}
diff --git a/src/main/java/com/ruoyi/sales/service/impl/SalesLedgerProductServiceImpl.java b/src/main/java/com/ruoyi/sales/service/impl/SalesLedgerProductServiceImpl.java
index ac469e8..ab45874 100644
--- a/src/main/java/com/ruoyi/sales/service/impl/SalesLedgerProductServiceImpl.java
+++ b/src/main/java/com/ruoyi/sales/service/impl/SalesLedgerProductServiceImpl.java
@@ -100,7 +100,11 @@
@Override
public SalesLedgerProduct selectSalesLedgerProductById(Long id) {
- return salesLedgerProductMapper.selectById(id);
+ SalesLedgerProduct row = salesLedgerProductMapper.selectById(id);
+ if (row != null) {
+ row.fillRemainingQuantity();
+ }
+ return row;
}
@Override
@@ -201,6 +205,7 @@
item.setReturnQuality(returnQuality);
BigDecimal quantity = item.getQuantity() == null ? BigDecimal.ZERO : item.getQuantity();
item.setAvailableQuality(quantity.subtract(returnQuality));
+ item.fillRemainingQuantity();
ProductModel productModel = finalProductModelMap.get(item.getProductModelId());
if (productModel != null) {
item.setThickness(productModel.getThickness());
@@ -275,6 +280,7 @@
int result;
Long salesLedgerId = salesLedgerProduct.getSalesLedgerId();
+ salesLedgerProduct.fillRemainingQuantity();
if (salesLedgerProduct.getId() == null) {
salesLedgerProduct.setRegisterDate(LocalDateTime.now());
result = salesLedgerProductMapper.insert(salesLedgerProduct);
@@ -497,6 +503,7 @@
} else {
item.setStatusName("鏈畬鎴愪粯娆�");
}
+ item.fillRemainingQuantity();
});
return salesLedgerProductDtoIPage;
}
@@ -511,6 +518,7 @@
} else {
item.setStatusName("鏈畬鎴愪粯娆�");
}
+ item.fillRemainingQuantity();
});
return salesLedgerProductDtoIPage;
}
diff --git a/src/main/java/com/ruoyi/sales/service/impl/SalesLedgerServiceImpl.java b/src/main/java/com/ruoyi/sales/service/impl/SalesLedgerServiceImpl.java
index 8cbef1d..0a277b1 100644
--- a/src/main/java/com/ruoyi/sales/service/impl/SalesLedgerServiceImpl.java
+++ b/src/main/java/com/ruoyi/sales/service/impl/SalesLedgerServiceImpl.java
@@ -19,6 +19,9 @@
import com.ruoyi.common.enums.FileNameType;
import com.ruoyi.common.enums.SaleEnum;
import com.ruoyi.common.enums.StockInQualifiedRecordTypeEnum;
+import com.ruoyi.common.enums.StockInUnQualifiedRecordTypeEnum;
+import com.ruoyi.common.enums.StockOutQualifiedRecordTypeEnum;
+import com.ruoyi.common.enums.StockOutUnQualifiedRecordTypeEnum;
import com.ruoyi.common.exception.ServiceException;
import com.ruoyi.common.exception.base.BaseException;
import com.ruoyi.common.utils.DateUtils;
@@ -37,6 +40,7 @@
import com.ruoyi.project.system.domain.SysUser;
import com.ruoyi.project.system.mapper.SysDeptMapper;
import com.ruoyi.project.system.mapper.SysUserMapper;
+import com.ruoyi.procurementrecord.utils.StockUtils;
import com.ruoyi.purchase.dto.SimpleReturnOrderGroupDto;
import com.ruoyi.purchase.mapper.PurchaseReturnOrderProductsMapper;
import com.ruoyi.quality.mapper.QualityInspectMapper;
@@ -139,6 +143,7 @@
private final StockOutRecordMapper stockOutRecordMapper;
private final StockInRecordService stockInRecordService;
private final StockOutRecordService stockOutRecordService;
+ private final StockUtils stockUtils;
@Autowired
private SysDeptMapper sysDeptMapper;
@@ -272,6 +277,7 @@
product.setActualTotalArea(pieceArea.multiply(quantity).setScale(2, RoundingMode.HALF_UP));
}
}
+ product.fillRemainingQuantity();
}
// 3.鏌ヨ涓婁紶鏂囦欢
@@ -620,6 +626,7 @@
salesLedgerProduct.setNoInvoiceNum(quantity);
salesLedgerProduct.setNoInvoiceAmount(salesLedgerProduct.getTaxExclusiveTotalPrice());
salesLedgerProduct.setPendingInvoiceTotal(taxInclusiveTotalPrice);
+ salesLedgerProduct.fillRemainingQuantity();
salesLedgerProductMapper.insert(salesLedgerProduct);
if (!processList.isEmpty()) {
salesLedgerProductProcessBindService.updateProductProcessBind(processList, salesLedgerProduct.getId());
@@ -1000,6 +1007,7 @@
for (SalesLedgerProduct product : updateList) {
product.setType(type.getCode());
product.setProductStockStatus(0);
+ product.fillRemainingQuantity();
salesLedgerProductMapper.updateById(product);
// 娓呯┖閿�鍞骇鍝佺粦瀹氱殑鍔犲伐
salesLedgerProductProcessBindService.updateProductProcessBind(product.getSalesProductProcessList(), product.getId());
@@ -1013,6 +1021,7 @@
salesLedgerProduct.setNoInvoiceAmount(salesLedgerProduct.getTaxInclusiveTotalPrice());
salesLedgerProduct.setPendingInvoiceTotal(salesLedgerProduct.getTaxInclusiveTotalPrice());
salesLedgerProduct.setProductStockStatus(0);
+ salesLedgerProduct.fillRemainingQuantity();
salesLedgerProductMapper.insert(salesLedgerProduct);
// 缁戝畾浜у搧棰濆鍔犲伐
// 娓呯┖閿�鍞骇鍝佺粦瀹氱殑鍔犲伐
@@ -1717,4 +1726,298 @@
.in(Customer::getId, customerIds)
.orderByAsc(Customer::getCustomerName));
}
+
+ @Override
+ @Transactional(rollbackFor = Exception.class)
+ public void scanInbound(SalesScanInboundDto dto) {
+ if (dto == null || dto.getSalesLedgerId() == null) {
+ throw new ServiceException("閿�鍞鍗曞叆搴撳け璐�,鍏ュ簱鏁版嵁涓嶈兘涓虹┖");
+ }
+
+ SalesLedger salesLedger = baseMapper.selectById(dto.getSalesLedgerId());
+ if (salesLedger == null) {
+ throw new ServiceException("鍏ュ簱澶辫触,閿�鍞鍗曚笉瀛樺湪");
+ }
+ if (salesLedger.getStockStatus() == null) {
+ throw new ServiceException("鍏ュ簱澶辫触,閿�鍞鍗曠姸鎬佸紓甯�");
+ }
+ if (salesLedger.getStockStatus() == 2) {
+ throw new ServiceException("鍏ュ簱澶辫触,璇ラ攢鍞鍗曞凡鍏ㄩ儴鍏ュ簱");
+ }
+ if (salesLedger.getDeliveryStatus() == 5) {
+ throw new ServiceException("鍏ュ簱澶辫触,璇ラ攢鍞鍗曞凡鍙戣揣");
+ }
+ if (CollectionUtils.isEmpty(dto.getSalesLedgerProductList())) {
+ throw new ServiceException("閿�鍞鍗曞叆搴撳け璐�,鍏ュ簱浜у搧涓嶈兘涓虹┖");
+ }
+ // 鏈鍏ュ簱鏁伴噺鍙互澶т簬璁㈠崟鏁伴噺,浣嗕笉鑳戒负璐�
+ Map<Long, BigDecimal> inboundQtyByLineId = new LinkedHashMap<>();
+ for (SalesLedgerProduct inbound : dto.getSalesLedgerProductList()) {
+ if (inbound == null || inbound.getId() == null) {
+ throw new ServiceException("鍏ュ簱澶辫触,閿�鍞骇鍝佷俊鎭笉瀹屾暣");
+ }
+ BigDecimal inboundQty = inbound.getStockedQuantity();
+ if (inboundQty == null) {
+ throw new ServiceException("鍏ュ簱澶辫触,鍏ュ簱鏁伴噺涓嶈兘涓虹┖");
+ }
+ if (inboundQty.compareTo(BigDecimal.ZERO) < 0) {
+ throw new ServiceException("鍏ュ簱澶辫触,鍏ュ簱鏁伴噺涓嶈兘涓鸿礋鏁�");
+ }
+ inboundQtyByLineId.merge(inbound.getId(), inboundQty, BigDecimal::add);
+ }
+ Long ledgerId = salesLedger.getId();
+ for (Map.Entry<Long, BigDecimal> entry : inboundQtyByLineId.entrySet()) {
+ Long salesLedgerProductId = entry.getKey();
+ BigDecimal inboundThisLine = entry.getValue();
+ if (inboundThisLine.compareTo(BigDecimal.ZERO) == 0) {
+ continue;
+ }
+ SalesLedgerProduct dbProduct = salesLedgerProductMapper.selectById(salesLedgerProductId);
+ if (dbProduct == null) {
+ throw new ServiceException("鍏ュ簱澶辫触,閿�鍞骇鍝佷笉瀛樺湪");
+ }
+ if (!Objects.equals(dbProduct.getSalesLedgerId(), ledgerId)) {
+ throw new ServiceException("鍏ュ簱澶辫触,閿�鍞骇鍝佷笌璁㈠崟涓嶅尮閰�");
+ }
+ if (!Objects.equals(dbProduct.getType(), SaleEnum.SALE.getCode())) {
+ throw new ServiceException("鍏ュ簱澶辫触,浠呮敮鎸侀攢鍞鍗曚骇鍝佽");
+ }
+ if (dbProduct.getProductModelId() == null) {
+ throw new ServiceException("鍏ュ簱澶辫触,浜у搧瑙勬牸鏈淮鎶�,鏃犳硶鍏ュ簱");
+ }
+ BigDecimal oldStocked = dbProduct.getStockedQuantity() == null ? BigDecimal.ZERO : dbProduct.getStockedQuantity();
+ BigDecimal newStocked = oldStocked.add(inboundThisLine);
+
+ StockInventoryDto stockInventoryDto = new StockInventoryDto();
+ stockInventoryDto.setRecordId(dbProduct.getId());
+ stockInventoryDto.setRecordType(StockInQualifiedRecordTypeEnum.SALE_SCAN_STOCK_IN.getCode());
+ stockInventoryDto.setQualitity(inboundThisLine);
+ stockInventoryDto.setProductModelId(dbProduct.getProductModelId());
+ stockInventoryDto.setSalesLedgerId(ledgerId);
+ stockInventoryDto.setSalesLedgerProductId(dbProduct.getId());
+ stockInventoryService.addstockInventory(stockInventoryDto);
+
+ BigDecimal orderQty = dbProduct.getQuantity() == null ? BigDecimal.ZERO : dbProduct.getQuantity();
+ int lineStockStatus;
+ if (newStocked.compareTo(BigDecimal.ZERO) <= 0) {
+ lineStockStatus = 0;
+ } else if (orderQty.compareTo(BigDecimal.ZERO) > 0 && newStocked.compareTo(orderQty) < 0) {
+ lineStockStatus = 1;
+ } else {
+ lineStockStatus = 2;
+ }
+ dbProduct.setStockedQuantity(newStocked);
+ dbProduct.setProductStockStatus(lineStockStatus);
+ dbProduct.fillRemainingQuantity();
+ salesLedgerProductMapper.updateById(dbProduct);
+ }
+ List<SalesLedgerProduct> ledgerAllProducts = salesLedgerProductMapper.selectList(
+ Wrappers.<SalesLedgerProduct>lambdaQuery().eq(SalesLedgerProduct::getSalesLedgerId, ledgerId));
+ boolean anyInbound = ledgerAllProducts.stream().anyMatch(p -> {
+ BigDecimal sq = p.getStockedQuantity();
+ return sq != null && sq.compareTo(BigDecimal.ZERO) > 0;
+ });
+ boolean allLinesFull = ledgerAllProducts.stream().allMatch(p -> Objects.equals(p.getProductStockStatus(), 2));
+ salesLedger.setStockStatus(allLinesFull ? 2 : (anyInbound ? 1 : 0));
+ baseMapper.updateById(salesLedger);
+ }
+
+ @Override
+ @Transactional(rollbackFor = Exception.class)
+ public void scanInboundUnqualified(SalesScanInboundDto dto) {
+ if (dto == null || dto.getSalesLedgerId() == null) {
+ throw new ServiceException("閿�鍞鍗曚笉鍚堟牸鍏ュ簱澶辫触,鍏ュ簱鏁版嵁涓嶈兘涓虹┖");
+ }
+ SalesLedger salesLedger = baseMapper.selectById(dto.getSalesLedgerId());
+ if (salesLedger == null) {
+ throw new ServiceException("涓嶅悎鏍煎叆搴撳け璐�,閿�鍞鍗曚笉瀛樺湪");
+ }
+ if (salesLedger.getDeliveryStatus() != null && salesLedger.getDeliveryStatus() == 5) {
+ throw new ServiceException("涓嶅悎鏍煎叆搴撳け璐�,璇ラ攢鍞鍗曞凡鍙戣揣");
+ }
+ if (CollectionUtils.isEmpty(dto.getSalesLedgerProductList())) {
+ throw new ServiceException("閿�鍞鍗曚笉鍚堟牸鍏ュ簱澶辫触,鍏ュ簱浜у搧涓嶈兘涓虹┖");
+ }
+ Map<Long, BigDecimal> inboundQtyByLineId = new LinkedHashMap<>();
+ for (SalesLedgerProduct inbound : dto.getSalesLedgerProductList()) {
+ if (inbound == null || inbound.getId() == null) {
+ throw new ServiceException("涓嶅悎鏍煎叆搴撳け璐�,閿�鍞骇鍝佷俊鎭笉瀹屾暣");
+ }
+ BigDecimal inboundQty = inbound.getStockedQuantity();
+ if (inboundQty == null) {
+ throw new ServiceException("涓嶅悎鏍煎叆搴撳け璐�,鍏ュ簱鏁伴噺涓嶈兘涓虹┖");
+ }
+ if (inboundQty.compareTo(BigDecimal.ZERO) < 0) {
+ throw new ServiceException("涓嶅悎鏍煎叆搴撳け璐�,鍏ュ簱鏁伴噺涓嶈兘涓鸿礋鏁�");
+ }
+ inboundQtyByLineId.merge(inbound.getId(), inboundQty, BigDecimal::add);
+ }
+ Long ledgerId = salesLedger.getId();
+ for (Map.Entry<Long, BigDecimal> entry : inboundQtyByLineId.entrySet()) {
+ Long salesLedgerProductId = entry.getKey();
+ BigDecimal inboundThisLine = entry.getValue();
+ if (inboundThisLine.compareTo(BigDecimal.ZERO) == 0) {
+ continue;
+ }
+ SalesLedgerProduct dbProduct = salesLedgerProductMapper.selectById(salesLedgerProductId);
+ if (dbProduct == null) {
+ throw new ServiceException("涓嶅悎鏍煎叆搴撳け璐�,閿�鍞骇鍝佷笉瀛樺湪");
+ }
+ if (!Objects.equals(dbProduct.getSalesLedgerId(), ledgerId)) {
+ throw new ServiceException("涓嶅悎鏍煎叆搴撳け璐�,閿�鍞骇鍝佷笌璁㈠崟涓嶅尮閰�");
+ }
+ if (!Objects.equals(dbProduct.getType(), SaleEnum.SALE.getCode())) {
+ throw new ServiceException("涓嶅悎鏍煎叆搴撳け璐�,浠呮敮鎸侀攢鍞鍗曚骇鍝佽");
+ }
+ if (dbProduct.getProductModelId() == null) {
+ throw new ServiceException("涓嶅悎鏍煎叆搴撳け璐�,浜у搧瑙勬牸鏈淮鎶�,鏃犳硶鍏ュ簱");
+ }
+ stockUtils.addUnStock(ledgerId, dbProduct.getId(), dbProduct.getProductModelId(), inboundThisLine,
+ StockInUnQualifiedRecordTypeEnum.SALES_SCAN_UNSTOCK_IN.getCode(), dbProduct.getId());
+ }
+ }
+
+ @Override
+ @Transactional(rollbackFor = Exception.class)
+ public void scanOutbound(SalesScanInboundDto dto) {
+ if (dto == null || dto.getSalesLedgerId() == null) {
+ throw new ServiceException("閿�鍞鍗曞嚭搴撳け璐�,鍑哄簱鏁版嵁涓嶈兘涓虹┖");
+ }
+ SalesLedger salesLedger = baseMapper.selectById(dto.getSalesLedgerId());
+ if (salesLedger == null) {
+ throw new ServiceException("鍑哄簱澶辫触,閿�鍞鍗曚笉瀛樺湪");
+ }
+ if (salesLedger.getDeliveryStatus() != null && salesLedger.getDeliveryStatus() == 5) {
+ throw new ServiceException("鍑哄簱澶辫触,璇ラ攢鍞鍗曞凡鍙戣揣");
+ }
+ if (CollectionUtils.isEmpty(dto.getSalesLedgerProductList())) {
+ throw new ServiceException("閿�鍞鍗曞嚭搴撳け璐�,鍑哄簱浜у搧涓嶈兘涓虹┖");
+ }
+ int saleType = SaleEnum.SALE.getCode();
+ Map<Long, BigDecimal> outboundQtyByLineId = new LinkedHashMap<>();
+ for (SalesLedgerProduct line : dto.getSalesLedgerProductList()) {
+ if (line == null || line.getId() == null) {
+ throw new ServiceException("鍑哄簱澶辫触,閿�鍞骇鍝佷俊鎭笉瀹屾暣");
+ }
+ BigDecimal outboundQty = line.getStockedQuantity();
+ if (outboundQty == null) {
+ throw new ServiceException("鍑哄簱澶辫触,鍑哄簱鏁伴噺涓嶈兘涓虹┖");
+ }
+ if (outboundQty.compareTo(BigDecimal.ZERO) < 0) {
+ throw new ServiceException("鍑哄簱澶辫触,鍑哄簱鏁伴噺涓嶈兘涓鸿礋鏁�");
+ }
+ outboundQtyByLineId.merge(line.getId(), outboundQty, BigDecimal::add);
+ }
+ Long ledgerId = salesLedger.getId();
+ for (Map.Entry<Long, BigDecimal> entry : outboundQtyByLineId.entrySet()) {
+ Long salesLedgerProductId = entry.getKey();
+ BigDecimal outboundThisLine = entry.getValue();
+ if (outboundThisLine.compareTo(BigDecimal.ZERO) == 0) {
+ continue;
+ }
+ SalesLedgerProduct dbProduct = salesLedgerProductMapper.selectById(salesLedgerProductId);
+ if (dbProduct == null) {
+ throw new ServiceException("鍑哄簱澶辫触,閿�鍞骇鍝佷笉瀛樺湪");
+ }
+ if (!Objects.equals(dbProduct.getSalesLedgerId(), ledgerId) || !Objects.equals(dbProduct.getType(), saleType)) {
+ throw new ServiceException("鍑哄簱澶辫触,閿�鍞骇鍝佷笌璁㈠崟涓嶅尮閰�");
+ }
+ if (dbProduct.getProductModelId() == null) {
+ throw new ServiceException("鍑哄簱澶辫触,浜у搧瑙勬牸鏈淮鎶�,鏃犳硶鍑哄簱");
+ }
+ stockUtils.assertQualifiedAvailable(dbProduct.getProductModelId(), outboundThisLine);
+
+ BigDecimal oldStocked = dbProduct.getStockedQuantity() == null ? BigDecimal.ZERO : dbProduct.getStockedQuantity();
+ BigDecimal newStocked = oldStocked.subtract(outboundThisLine);
+ if (newStocked.compareTo(BigDecimal.ZERO) < 0) {
+ newStocked = BigDecimal.ZERO;
+ }
+
+ StockInventoryDto stockInventoryDto = new StockInventoryDto();
+ stockInventoryDto.setRecordId(dbProduct.getId());
+ stockInventoryDto.setRecordType(StockOutQualifiedRecordTypeEnum.SALE_SCAN_STOCK_OUT.getCode());
+ stockInventoryDto.setQualitity(outboundThisLine);
+ stockInventoryDto.setProductModelId(dbProduct.getProductModelId());
+ stockInventoryDto.setSalesLedgerId(ledgerId);
+ stockInventoryDto.setSalesLedgerProductId(dbProduct.getId());
+ stockInventoryService.subtractStockInventory(stockInventoryDto);
+
+ BigDecimal orderQty = dbProduct.getQuantity() == null ? BigDecimal.ZERO : dbProduct.getQuantity();
+ int lineStockStatus;
+ if (newStocked.compareTo(BigDecimal.ZERO) <= 0) {
+ lineStockStatus = 0;
+ } else if (orderQty.compareTo(BigDecimal.ZERO) > 0 && newStocked.compareTo(orderQty) < 0) {
+ lineStockStatus = 1;
+ } else {
+ lineStockStatus = 2;
+ }
+ dbProduct.setStockedQuantity(newStocked);
+ dbProduct.setProductStockStatus(lineStockStatus);
+ dbProduct.fillRemainingQuantity();
+ salesLedgerProductMapper.updateById(dbProduct);
+ }
+ List<SalesLedgerProduct> ledgerAllProducts = salesLedgerProductMapper.selectList(
+ Wrappers.<SalesLedgerProduct>lambdaQuery().eq(SalesLedgerProduct::getSalesLedgerId, ledgerId));
+ boolean anyInbound = ledgerAllProducts.stream().anyMatch(p -> {
+ BigDecimal sq = p.getStockedQuantity();
+ return sq != null && sq.compareTo(BigDecimal.ZERO) > 0;
+ });
+ boolean allLinesFull = ledgerAllProducts.stream().allMatch(p -> Objects.equals(p.getProductStockStatus(), 2));
+ salesLedger.setStockStatus(allLinesFull ? 2 : (anyInbound ? 1 : 0));
+ baseMapper.updateById(salesLedger);
+ }
+
+ @Override
+ @Transactional(rollbackFor = Exception.class)
+ public void scanOutboundUnqualified(SalesScanInboundDto dto) {
+ if (dto == null || dto.getSalesLedgerId() == null) {
+ throw new ServiceException("閿�鍞鍗曚笉鍚堟牸鍑哄簱澶辫触,鍑哄簱鏁版嵁涓嶈兘涓虹┖");
+ }
+ SalesLedger salesLedger = baseMapper.selectById(dto.getSalesLedgerId());
+ if (salesLedger == null) {
+ throw new ServiceException("涓嶅悎鏍煎嚭搴撳け璐�,閿�鍞鍗曚笉瀛樺湪");
+ }
+ if (salesLedger.getDeliveryStatus() != null && salesLedger.getDeliveryStatus() == 5) {
+ throw new ServiceException("涓嶅悎鏍煎嚭搴撳け璐�,璇ラ攢鍞鍗曞凡鍙戣揣");
+ }
+ if (CollectionUtils.isEmpty(dto.getSalesLedgerProductList())) {
+ throw new ServiceException("閿�鍞鍗曚笉鍚堟牸鍑哄簱澶辫触,鍑哄簱浜у搧涓嶈兘涓虹┖");
+ }
+ int saleType = SaleEnum.SALE.getCode();
+ Map<Long, BigDecimal> outboundQtyByLineId = new LinkedHashMap<>();
+ for (SalesLedgerProduct line : dto.getSalesLedgerProductList()) {
+ if (line == null || line.getId() == null) {
+ throw new ServiceException("涓嶅悎鏍煎嚭搴撳け璐�,閿�鍞骇鍝佷俊鎭笉瀹屾暣");
+ }
+ BigDecimal outboundQty = line.getStockedQuantity();
+ if (outboundQty == null) {
+ throw new ServiceException("涓嶅悎鏍煎嚭搴撳け璐�,鍑哄簱鏁伴噺涓嶈兘涓虹┖");
+ }
+ if (outboundQty.compareTo(BigDecimal.ZERO) < 0) {
+ throw new ServiceException("涓嶅悎鏍煎嚭搴撳け璐�,鍑哄簱鏁伴噺涓嶈兘涓鸿礋鏁�");
+ }
+ outboundQtyByLineId.merge(line.getId(), outboundQty, BigDecimal::add);
+ }
+ Long ledgerId = salesLedger.getId();
+ for (Map.Entry<Long, BigDecimal> entry : outboundQtyByLineId.entrySet()) {
+ Long salesLedgerProductId = entry.getKey();
+ BigDecimal outboundThisLine = entry.getValue();
+ if (outboundThisLine.compareTo(BigDecimal.ZERO) == 0) {
+ continue;
+ }
+ SalesLedgerProduct dbProduct = salesLedgerProductMapper.selectById(salesLedgerProductId);
+ if (dbProduct == null) {
+ throw new ServiceException("涓嶅悎鏍煎嚭搴撳け璐�,閿�鍞骇鍝佷笉瀛樺湪");
+ }
+ if (!Objects.equals(dbProduct.getSalesLedgerId(), ledgerId) || !Objects.equals(dbProduct.getType(), saleType)) {
+ throw new ServiceException("涓嶅悎鏍煎嚭搴撳け璐�,閿�鍞骇鍝佷笌璁㈠崟涓嶅尮閰�");
+ }
+ if (dbProduct.getProductModelId() == null) {
+ throw new ServiceException("涓嶅悎鏍煎嚭搴撳け璐�,浜у搧瑙勬牸鏈淮鎶�,鏃犳硶鍑哄簱");
+ }
+ stockUtils.assertUnqualifiedAvailable(dbProduct.getProductModelId(), outboundThisLine);
+ stockUtils.subtractUnStock(ledgerId, dbProduct.getId(), dbProduct.getProductModelId(), outboundThisLine,
+ StockOutUnQualifiedRecordTypeEnum.SALE_SCAN_UNSTOCK_OUT.getCode(), dbProduct.getId());
+ }
+ }
}
diff --git a/src/main/java/com/ruoyi/stock/dto/StockUninventoryDto.java b/src/main/java/com/ruoyi/stock/dto/StockUninventoryDto.java
index 404c58a..c9263c9 100644
--- a/src/main/java/com/ruoyi/stock/dto/StockUninventoryDto.java
+++ b/src/main/java/com/ruoyi/stock/dto/StockUninventoryDto.java
@@ -6,7 +6,7 @@
import java.math.BigDecimal;
@Data
-public class StockUninventoryDto extends StockUninventory {
+public class StockUninventoryDto extends StockUninventory {
private String productName;
private String model;
private String unit;
@@ -19,4 +19,14 @@
private Long recordId;
private BigDecimal unLockedQuantity;
+
+ /**
+ * 閿�鍞鍗旾D
+ */
+ private Long salesLedgerId;
+
+ /**
+ * 閿�鍞鍗曚骇鍝佽ID
+ */
+ private Long salesLedgerProductId;
}
diff --git a/src/main/java/com/ruoyi/stock/service/impl/StockInventoryServiceImpl.java b/src/main/java/com/ruoyi/stock/service/impl/StockInventoryServiceImpl.java
index d98bc5a..5208f92 100644
--- a/src/main/java/com/ruoyi/stock/service/impl/StockInventoryServiceImpl.java
+++ b/src/main/java/com/ruoyi/stock/service/impl/StockInventoryServiceImpl.java
@@ -119,7 +119,10 @@
throw new RuntimeException("搴撳瓨涓嶈冻鏃犳硶鍑哄簱");
}
- stockInventoryMapper.updateSubtractStockInventory(stockInventoryDto);
+ int affectRows = stockInventoryMapper.updateSubtractStockInventory(stockInventoryDto);
+ if (affectRows <= 0) {
+ throw new RuntimeException("搴撳瓨涓嶈冻鏃犳硶鍑哄簱");
+ }
return true;
}
diff --git a/src/main/java/com/ruoyi/stock/service/impl/StockUninventoryServiceImpl.java b/src/main/java/com/ruoyi/stock/service/impl/StockUninventoryServiceImpl.java
index 2d5b8f5..6fb76e6 100644
--- a/src/main/java/com/ruoyi/stock/service/impl/StockUninventoryServiceImpl.java
+++ b/src/main/java/com/ruoyi/stock/service/impl/StockUninventoryServiceImpl.java
@@ -54,6 +54,8 @@
stockInRecordDto.setStockInNum(stockUninventoryDto.getQualitity());
stockInRecordDto.setProductModelId(stockUninventoryDto.getProductModelId());
stockInRecordDto.setType("1");
+ stockInRecordDto.setSalesLedgerId(stockUninventoryDto.getSalesLedgerId());
+ stockInRecordDto.setSalesLedgerProductId(stockUninventoryDto.getSalesLedgerProductId());
stockInRecordService.add(stockInRecordDto);
//鍐嶈繘琛屾柊澧炲簱瀛樻暟閲忓簱瀛�
//鍏堟煡璇㈠簱瀛樿〃涓殑浜у搧鏄惁瀛樺湪锛屼笉瀛樺湪鏂板锛屽瓨鍦ㄦ洿鏂�
@@ -82,12 +84,17 @@
stockOutRecordDto.setStockOutNum(stockUninventoryDto.getQualitity());
stockOutRecordDto.setProductModelId(stockUninventoryDto.getProductModelId());
stockOutRecordDto.setType("1");
+ stockOutRecordDto.setSalesLedgerId(stockUninventoryDto.getSalesLedgerId());
+ stockOutRecordDto.setSalesLedgerProductId(stockUninventoryDto.getSalesLedgerProductId());
stockOutRecordService.add(stockOutRecordDto);
StockUninventory oldStockInventory = stockUninventoryMapper.selectOne(new QueryWrapper<StockUninventory>().lambda().eq(StockUninventory::getProductModelId, stockUninventoryDto.getProductModelId()));
if (ObjectUtils.isEmpty(oldStockInventory)) {
throw new RuntimeException("浜у搧搴撳瓨涓嶅瓨鍦�");
}else {
- stockUninventoryMapper.updateSubtractStockUnInventory(stockUninventoryDto);
+ int affectRows = stockUninventoryMapper.updateSubtractStockUnInventory(stockUninventoryDto);
+ if (affectRows <= 0) {
+ throw new RuntimeException("搴撳瓨涓嶈冻鏃犳硶鍑哄簱");
+ }
}
return 1;
}
diff --git a/src/main/resources/mapper/stock/StockInventoryMapper.xml b/src/main/resources/mapper/stock/StockInventoryMapper.xml
index 3931022..fb46594 100644
--- a/src/main/resources/mapper/stock/StockInventoryMapper.xml
+++ b/src/main/resources/mapper/stock/StockInventoryMapper.xml
@@ -49,7 +49,8 @@
</if>
update_time = now()
</set>
- where product_model_id = #{ew.productModelId} and qualitity >= #{ew.qualitity}
+ where product_model_id = #{ew.productModelId}
+ and (qualitity - COALESCE(locked_quantity, 0)) >= #{ew.qualitity}
</update>
<select id="pagestockInventory" resultType="com.ruoyi.stock.dto.StockInventoryDto">
diff --git a/src/main/resources/mapper/stock/StockUninventoryMapper.xml b/src/main/resources/mapper/stock/StockUninventoryMapper.xml
index e043bd7..d48acfa 100644
--- a/src/main/resources/mapper/stock/StockUninventoryMapper.xml
+++ b/src/main/resources/mapper/stock/StockUninventoryMapper.xml
@@ -25,7 +25,8 @@
</if>
update_time = now()
</set>
- where product_model_id = #{ew.productModelId} and qualitity >= #{ew.qualitity}
+ where product_model_id = #{ew.productModelId}
+ and (qualitity - COALESCE(locked_quantity, 0)) >= #{ew.qualitity}
</update>
<update id="updateAddStockUnInventory">
update stock_uninventory
--
Gitblit v1.9.3