From 69e0f44e279f7763fa9c9a4d105f154db39ee1d8 Mon Sep 17 00:00:00 2001
From: 云 <2163098428@qq.com>
Date: 星期六, 23 五月 2026 11:38:02 +0800
Subject: [PATCH] feat(sales): 添加每件数量字段支持及多业务流程优化
---
src/main/java/com/ruoyi/approve/service/impl/ApproveProcessServiceImpl.java | 47 +++++++
doc/20260522_sales_每件数量前端联调文档.md | 106 +++++++++++++++++
src/main/java/com/ruoyi/sales/pojo/SalesLedgerProduct.java | 3
src/main/java/com/ruoyi/sales/dto/ShippingInfoDto.java | 5
src/main/resources/mapper/sales/SalesQuotationMapper.xml | 27 ++--
src/main/java/com/ruoyi/sales/service/impl/SalesLedgerProductServiceImpl.java | 8 +
src/main/java/com/ruoyi/sales/controller/SalesLedgerController.java | 31 -----
src/main/java/com/ruoyi/sales/service/impl/ShippingInfoServiceImpl.java | 33 +++++
src/main/resources/mapper/sales/SalesLedgerProductMapper.xml | 5
src/main/java/com/ruoyi/sales/service/impl/SalesLedgerServiceImpl.java | 13 ++
src/main/java/com/ruoyi/sales/service/impl/SalesQuotationServiceImpl.java | 14 +
src/main/java/com/ruoyi/sales/dto/SalesLedgerProductImportDto.java | 6 +
src/main/java/com/ruoyi/sales/controller/ShippingInfoController.java | 9
src/main/java/com/ruoyi/sales/dto/SalesQuotationDto.java | 6 -
src/main/resources/static/销售台账导入模板.xlsx | 0
src/main/java/com/ruoyi/sales/pojo/SalesQuotationProduct.java | 4
16 files changed, 247 insertions(+), 70 deletions(-)
diff --git "a/doc/20260522_sales_\346\257\217\344\273\266\346\225\260\351\207\217\345\211\215\347\253\257\350\201\224\350\260\203\346\226\207\346\241\243.md" "b/doc/20260522_sales_\346\257\217\344\273\266\346\225\260\351\207\217\345\211\215\347\253\257\350\201\224\350\260\203\346\226\207\346\241\243.md"
new file mode 100644
index 0000000..16055f8
--- /dev/null
+++ "b/doc/20260522_sales_\346\257\217\344\273\266\346\225\260\351\207\217\345\211\215\347\253\257\350\201\224\350\260\203\346\226\207\346\241\243.md"
@@ -0,0 +1,106 @@
+# Sales 妯″潡銆屾瘡浠舵暟閲忋�嶅墠绔仈璋冩枃妗�
+
+## 1. 鍙樻洿鑼冨洿
+
+- 閿�鍞彴璐︼細閿�鍞骇鍝佹柊澧炲瓧娈� `singleQuantity`锛堟瘡浠舵暟閲忥級
+- 閿�鍞姤浠凤細鎶ヤ环浜у搧鏂板瀛楁 `singleQuantity`锛堟瘡浠舵暟閲忥級
+- 鍙戣揣/鍑哄簱鏁伴噺璁$畻锛氭寜 `鏁伴噺 * 姣忎欢鏁伴噺` 璁$畻骞惰惤搴�
+
+## 1.1 鑱旇皟鍓嶇疆锛堟暟鎹簱锛�
+
+闇�淇濊瘉浠ヤ笅涓ゅ紶琛ㄥ凡鏂板鍒� `single_quantity`锛堝缓璁粯璁ゅ�� `1`锛夛細
+
+- `sales_ledger_product.single_quantity`
+- `sales_quotation_product.single_quantity`
+
+## 2. 瀛楁瀹氫箟
+
+- 瀛楁鍚嶏細`singleQuantity`
+- 鍚箟锛氭瘡浠舵暟閲�
+- 绫诲瀷锛歚number`锛堝悗绔� `BigDecimal`锛�
+- 榛樿瑙勫垯锛氭湭浼犮�佷负 `null`銆佹垨 `<= 0` 鏃讹紝鍚庣鎸� `1` 澶勭悊
+
+## 3. 鎺ュ彛鍙樻洿娓呭崟
+
+### 3.1 閿�鍞彴璐�
+
+1. `POST /sales/ledger/addOrUpdateSalesLedger`
+ - 鍏ュ弬 `productData[]` 鏂板瀛楁 `singleQuantity`
+2. `POST /sales/product/addOrUpdateSalesLedgerProduct`
+ - 鍏ュ弬鏂板瀛楁 `singleQuantity`
+3. `GET /sales/product/list`
+ - 杩斿洖瀛楁鏂板 `singleQuantity`
+ - `noQuantity`锛堝緟鍙戣揣鏁伴噺锛夎绠楁敼涓猴細
+ - `noQuantity = quantity * singleQuantity - shippedQuantity`
+ - 鍙戣揣鐘舵�佽绠楀悓姝ュ熀浜庝笂闈㈠叕寮�
+
+### 3.2 閿�鍞姤浠�
+
+1. `POST /sales/quotation/add`
+ - 鍏ュ弬 `products[]` 鏂板瀛楁 `singleQuantity`
+2. `POST /sales/quotation/update`
+ - 鍏ュ弬 `products[]` 鏂板瀛楁 `singleQuantity`
+3. `GET /sales/quotation/list`
+ - 杩斿洖 `products[]` 鏂板瀛楁 `singleQuantity`
+
+### 3.3 鍙戣揣涓庡嚭搴�
+
+1. `POST /shippingInfo/add`
+ - 鍚庣浼氭寜閿�鍞骇鍝� `singleQuantity` 鑷姩鎹㈢畻鍙戣揣鏄庣粏鏁伴噺锛�
+ - `shipping_product_detail.quantity = 鍓嶇浼犲叆quantity * singleQuantity`
+ - 鍑哄簱璁板綍鏁伴噺涓庡彂璐ф槑缁嗕竴鑷达紙鍚屾牱涓轰箻绉悗鐨勬暟閲忥級
+
+## 4. 鍓嶇鑱旇皟瑕佹眰
+
+1. 閿�鍞彴璐︿骇鍝佽銆侀攢鍞姤浠蜂骇鍝佽鏂板銆屾瘡浠舵暟閲忋�嶈緭鍏ラ」锛屽瓧娈靛悕 `singleQuantity`
+2. `singleQuantity` 寤鸿闄愬埗涓哄ぇ浜� `0` 鐨勬暟瀛�
+3. 鍙戣揣鎻愪氦娴佺▼涓紝`batchNoDetailList[].quantity` 浼犫�滀欢鏁扳�濓紝涓嶈鍦ㄥ墠绔啀涔� `singleQuantity`
+ - 鍘熷洜锛氬悗绔凡缁熶竴鎹㈢畻锛屽墠绔啀涔樹細瀵艰嚧閲嶅鏀惧ぇ
+4. 鍒楄〃灞曠ず寰呭彂璐ф暟閲忔椂锛岀洿鎺ヤ娇鐢ㄦ帴鍙h繑鍥炵殑 `noQuantity`
+
+## 5. 鑱旇皟绀轰緥
+
+### 5.1 閿�鍞彴璐︽柊澧�/缂栬緫锛堜骇鍝佺墖娈碉級
+
+```json
+{
+ "productData": [
+ {
+ "productModelId": 101,
+ "quantity": 10,
+ "singleQuantity": 12
+ }
+ ]
+}
+```
+
+### 5.2 閿�鍞姤浠锋柊澧�/缂栬緫锛堜骇鍝佺墖娈碉級
+
+```json
+{
+ "products": [
+ {
+ "productModelId": 101,
+ "quantity": 10,
+ "singleQuantity": 12
+ }
+ ]
+}
+```
+
+### 5.3 鍙戣揣鎻愪氦锛堟槑缁嗙墖娈碉級
+
+```json
+{
+ "salesLedgerProductId": 2001,
+ "batchNoDetailList": [
+ {
+ "productModelId": 101,
+ "batchNo": "B20260522001",
+ "quantity": 3
+ }
+ ]
+}
+```
+
+璇存槑锛氳嫢璇� `salesLedgerProductId` 瀵瑰簲 `singleQuantity=12`锛屽垯瀹為檯鍙戣揣/鍑哄簱鏁伴噺涓� `36`銆�
diff --git a/src/main/java/com/ruoyi/approve/service/impl/ApproveProcessServiceImpl.java b/src/main/java/com/ruoyi/approve/service/impl/ApproveProcessServiceImpl.java
index c9d7aae..66853d9 100644
--- a/src/main/java/com/ruoyi/approve/service/impl/ApproveProcessServiceImpl.java
+++ b/src/main/java/com/ruoyi/approve/service/impl/ApproveProcessServiceImpl.java
@@ -26,6 +26,7 @@
import com.ruoyi.basic.utils.FileUtil;
import com.ruoyi.common.enums.FileNameType;
import com.ruoyi.common.enums.StockInQualifiedRecordTypeEnum;
+import com.ruoyi.common.enums.StockOutQualifiedRecordTypeEnum;
import com.ruoyi.common.utils.OrderUtils;
import com.ruoyi.common.utils.SecurityUtils;
import com.ruoyi.procurementrecord.utils.StockUtils;
@@ -39,9 +40,11 @@
import com.ruoyi.purchase.pojo.PurchaseLedger;
import com.ruoyi.sales.mapper.CommonFileMapper;
import com.ruoyi.sales.mapper.SalesLedgerProductMapper;
+import com.ruoyi.sales.mapper.SalesQuotationMapper;
import com.ruoyi.sales.mapper.ShippingInfoMapper;
import com.ruoyi.sales.pojo.CommonFile;
import com.ruoyi.sales.pojo.SalesLedgerProduct;
+import com.ruoyi.sales.pojo.SalesQuotation;
import com.ruoyi.sales.pojo.ShippingInfo;
import com.ruoyi.sales.service.impl.CommonFileServiceImpl;
import lombok.RequiredArgsConstructor;
@@ -71,6 +74,7 @@
private final ISysNoticeService sysNoticeService;
private final PurchaseLedgerMapper purchaseLedgerMapper;
private final SalesLedgerProductMapper salesLedgerProductMapper;
+ private final SalesQuotationMapper salesQuotationMapper;
private final StockUtils stockUtils;
private final ShippingInfoMapper shippingInfoMapper;
private final ApproveNodeMapper approveNodeMapper;
@@ -89,7 +93,17 @@
.collect(Collectors.toList());
// 鏃犲鏍镐汉閫昏緫娣诲姞
if (CollectionUtils.isEmpty(nodeIds)) {
- autoPassPurchaseApproveIfNoApprover(approveProcessVO); // 閲囪喘鍗曟棤瀹℃牳浜洪�昏緫
+ switch (approveProcessVO.getApproveType()){
+ case 5:
+ autoPassPurchaseApproveIfNoApprover(approveProcessVO); // 閲囪喘鍗曟棤瀹℃牳浜洪�昏緫
+ break;
+ case 6:
+ autoPassSalesApproveIfNoApprover(approveProcessVO); // 閿�鍞姤浠锋棤瀹℃牳浜洪�昏緫
+ break;
+ case 7:
+ autoShippingApproveIfNoApprover(approveProcessVO); // 閿�鍞彂璐ф棤瀹℃牳浜洪�昏緫
+ break;
+ }
return;
}
List<SysUser> sysUsers = sysUserMapper.selectUserByIds(nodeIds);
@@ -154,10 +168,35 @@
}
}
+ private void autoPassSalesApproveIfNoApprover(ApproveProcessVO approveProcessVO) {
+ if (!StringUtils.hasText(approveProcessVO.getApproveReason())) {
+ return;
+ }
+ salesQuotationMapper.update(null, new LambdaUpdateWrapper<SalesQuotation>()
+ .eq(SalesQuotation::getQuotationNo, approveProcessVO.getApproveReason())
+ .set(SalesQuotation::getStatus, "閫氳繃"));
+ }
+
+ private void autoShippingApproveIfNoApprover(ApproveProcessVO approveProcessVO) {
+ if (!StringUtils.hasText(approveProcessVO.getApproveReason())) {
+ return;
+ }
+ ShippingInfo shippingInfo = shippingInfoMapper.selectOne(new LambdaQueryWrapper<ShippingInfo>()
+ .eq(ShippingInfo::getShippingNo, approveProcessVO.getApproveReason())
+ .last("limit 1"));
+ if(shippingInfo == null){
+ return;
+ }
+ shippingInfoMapper.update(null, new LambdaUpdateWrapper<ShippingInfo>()
+ .eq(ShippingInfo::getShippingNo, approveProcessVO.getApproveReason())
+ .set(ShippingInfo::getStatus, "瀹℃牳閫氳繃"));
+ //鏇存敼鍑哄簱瀹℃牳鐘舵�侊紙寰呯‘璁ゆ敼鎴愬緟瀹℃牳锛�
+ stockUtils.shipmentStatus(StockOutQualifiedRecordTypeEnum.SALE_SHIP_STOCK_OUT.getCode(), shippingInfo.getId());
+ }
+
private void autoPassPurchaseApproveIfNoApprover(ApproveProcessVO approveProcessVO) {
- if (!Objects.equals(approveProcessVO.getApproveType(), 5)
- || !StringUtils.hasText(approveProcessVO.getApproveReason())) {
- throw new RuntimeException("瀹℃牳鐢ㄦ埛涓嶅瓨鍦�");
+ if (!StringUtils.hasText(approveProcessVO.getApproveReason())) {
+ return;
}
purchaseLedgerMapper.update(null, new LambdaUpdateWrapper<PurchaseLedger>()
diff --git a/src/main/java/com/ruoyi/sales/controller/SalesLedgerController.java b/src/main/java/com/ruoyi/sales/controller/SalesLedgerController.java
index 44b8563..12737f8 100644
--- a/src/main/java/com/ruoyi/sales/controller/SalesLedgerController.java
+++ b/src/main/java/com/ruoyi/sales/controller/SalesLedgerController.java
@@ -237,42 +237,13 @@
@GetMapping("/listPage")
public IPage<SalesLedgerVo> listPage(Page page, SalesLedgerDto salesLedgerDto) {
IPage<SalesLedgerVo> iPage = salesLedgerService.selectSalesLedgerListPage(page, salesLedgerDto);
-
// 鏌ヨ缁撴灉涓虹┖,鐩存帴杩斿洖
if (CollectionUtils.isEmpty(iPage.getRecords())) {
return iPage;
}
-
- // 鑾峰彇褰撳墠椤垫墍鏈夊彴璐﹁褰曠殑 ID 闆嗗悎
- List<Long> salesLedgerIds = iPage.getRecords().stream().map(SalesLedger::getId).collect(Collectors.toList());
-
-
-
-
- // 杞崲鍥炴鏁版嵁, key 涓哄彴璐D, value 涓鸿鍙拌处鐨勬�诲洖娆鹃噾棰�
- Map<Long, BigDecimal> receiptTotals = new HashMap<>();
-
-
for (SalesLedgerVo salesLedgerVo : iPage.getRecords()) {
- Long ledgerId = salesLedgerVo.getId();
- // 鍚堝悓鎬婚噾棰�
- BigDecimal contractAmount = salesLedgerVo.getContractAmount() == null ? BigDecimal.ZERO : salesLedgerVo.getContractAmount();
- // 寮�绁ㄦ�婚鍜屽洖娆炬�婚
- BigDecimal receiptPaymentAmountTotal = receiptTotals.getOrDefault(ledgerId, BigDecimal.ZERO);
-
- // 濡傛灉宸茬粡鏈夎繃寮�绁ㄦ垨鍥炴鎿嶄綔,鍒欎笉鍏佽缂栬緫
- boolean hasReceiptOperation = receiptPaymentAmountTotal.compareTo(BigDecimal.ZERO) > 0;
- salesLedgerVo.setIsEdit(hasReceiptOperation);
-
- salesLedgerVo.setStorageBlobVOs(fileUtil.getStorageBlobVOsByApplicationAndRecordTypeAndRecordId(ApplicationTypeEnum.FILE, RecordTypeEnum.SALES_LEDGER, ledgerId));
+ salesLedgerVo.setStorageBlobVOs(fileUtil.getStorageBlobVOsByApplicationAndRecordTypeAndRecordId(ApplicationTypeEnum.FILE, RecordTypeEnum.SALES_LEDGER, salesLedgerVo.getId()));
}
-
- if (ObjectUtils.isNotEmpty(salesLedgerDto.getStatus())) {
- if (salesLedgerDto.getStatus()) {
- iPage.setTotal(iPage.getRecords().size());
- }
- }
-
return iPage;
}
diff --git a/src/main/java/com/ruoyi/sales/controller/ShippingInfoController.java b/src/main/java/com/ruoyi/sales/controller/ShippingInfoController.java
index f707b5b..ddcc700 100644
--- a/src/main/java/com/ruoyi/sales/controller/ShippingInfoController.java
+++ b/src/main/java/com/ruoyi/sales/controller/ShippingInfoController.java
@@ -57,19 +57,18 @@
public AjaxResult add(@RequestBody ShippingInfoDto req) throws Exception {
LoginUser loginUser = SecurityUtils.getLoginUser();
String sh = OrderUtils.countTodayByCreateTime(shippingInfoMapper, "SH","shipping_no");
+ // 娣诲姞鍙戣揣娑堟伅
+ req.setShippingNo(sh);
+ req.setStatus("寰呭鏍�");
+ boolean save = shippingInfoService.add(req);
// 鍙戣揣瀹℃壒
ApproveProcessVO approveProcessVO = new ApproveProcessVO();
approveProcessVO.setApproveType(7);
approveProcessVO.setApproveDeptId(loginUser.getCurrentDeptId());
approveProcessVO.setApproveReason(sh);//鍙戣揣缂栧彿
- approveProcessVO.setApproveUserIds(req.getApproveUserIds());
approveProcessVO.setApproveUser(loginUser.getUserId());
approveProcessVO.setApproveTime(LocalDate.now().toString());
approveProcessService.addApprove(approveProcessVO);
- // 娣诲姞鍙戣揣娑堟伅
- req.setShippingNo(sh);
- req.setStatus("寰呭鏍�");
- boolean save = shippingInfoService.add(req);
return save ? AjaxResult.success() : AjaxResult.error();
}
diff --git a/src/main/java/com/ruoyi/sales/dto/SalesLedgerProductImportDto.java b/src/main/java/com/ruoyi/sales/dto/SalesLedgerProductImportDto.java
index 9f05b60..3bf962f 100644
--- a/src/main/java/com/ruoyi/sales/dto/SalesLedgerProductImportDto.java
+++ b/src/main/java/com/ruoyi/sales/dto/SalesLedgerProductImportDto.java
@@ -44,6 +44,12 @@
private BigDecimal quantity;
/**
+ * 姣忎欢鏁伴噺
+ */
+ @Excel(name = "姣忎欢鏁伴噺")
+ private BigDecimal singleQuantity;
+
+ /**
* 绋庣巼
*/
@Excel(name = "绋庣巼")
diff --git a/src/main/java/com/ruoyi/sales/dto/SalesQuotationDto.java b/src/main/java/com/ruoyi/sales/dto/SalesQuotationDto.java
index 4841ffd..0ff2ab6 100644
--- a/src/main/java/com/ruoyi/sales/dto/SalesQuotationDto.java
+++ b/src/main/java/com/ruoyi/sales/dto/SalesQuotationDto.java
@@ -11,10 +11,4 @@
public class SalesQuotationDto extends SalesQuotation {
@Schema(description = "鎶ヤ环鍟嗗搧")
private List<SalesQuotationProduct> products;
-
- /**
- * 瀹℃壒浜篿d鍒楄〃
- */
- // 瀹℃壒浜�
- private String approveUserIds;
}
diff --git a/src/main/java/com/ruoyi/sales/dto/ShippingInfoDto.java b/src/main/java/com/ruoyi/sales/dto/ShippingInfoDto.java
index 43409bc..7f0ac08 100644
--- a/src/main/java/com/ruoyi/sales/dto/ShippingInfoDto.java
+++ b/src/main/java/com/ruoyi/sales/dto/ShippingInfoDto.java
@@ -18,11 +18,6 @@
@Data
public class ShippingInfoDto extends ShippingInfo {
- /**
- * 瀹℃壒浜篿d鍒楄〃
- */
- // 瀹℃壒浜�
- private String approveUserIds;
private String type; // 鍙戣揣绫诲瀷
diff --git a/src/main/java/com/ruoyi/sales/pojo/SalesLedgerProduct.java b/src/main/java/com/ruoyi/sales/pojo/SalesLedgerProduct.java
index f4a42d6..63f5c50 100644
--- a/src/main/java/com/ruoyi/sales/pojo/SalesLedgerProduct.java
+++ b/src/main/java/com/ruoyi/sales/pojo/SalesLedgerProduct.java
@@ -66,6 +66,9 @@
*/
@Excel(name = "鏁伴噺")
private BigDecimal quantity;
+ @TableField(value = "single_quantity")
+ @Excel(name = "姣忎欢鏁伴噺")
+ private BigDecimal singleQuantity;
@Excel(name = "鏈�浣庡簱瀛樻暟閲�")
private BigDecimal minStock;
/**
diff --git a/src/main/java/com/ruoyi/sales/pojo/SalesQuotationProduct.java b/src/main/java/com/ruoyi/sales/pojo/SalesQuotationProduct.java
index 2e55e79..5ca58f3 100644
--- a/src/main/java/com/ruoyi/sales/pojo/SalesQuotationProduct.java
+++ b/src/main/java/com/ruoyi/sales/pojo/SalesQuotationProduct.java
@@ -4,6 +4,7 @@
import io.swagger.v3.oas.annotations.media.Schema;
import lombok.Data;
+import java.math.BigDecimal;
import java.time.LocalDateTime;
@Data
@@ -30,6 +31,9 @@
private Double unitPrice;
@Schema(description = "鏁伴噺")
private Integer quantity;
+ @TableField(value = "single_quantity")
+ @Schema(description = "姣忎欢鏁伴噺")
+ private BigDecimal singleQuantity;
@Schema(description = "閲戦")
private Double amount;
@Schema(description = "鍒涘缓鏃堕棿")
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 19aa02f..6a86537 100644
--- a/src/main/java/com/ruoyi/sales/service/impl/SalesLedgerProductServiceImpl.java
+++ b/src/main/java/com/ruoyi/sales/service/impl/SalesLedgerProductServiceImpl.java
@@ -167,6 +167,7 @@
int result;
Long salesLedgerId = salesLedgerProduct.getSalesLedgerId();
+ salesLedgerProduct.setSingleQuantity(normalizeSingleQuantity(salesLedgerProduct.getSingleQuantity()));
if (salesLedgerProduct.getId() == null) {
salesLedgerProduct.setRegisterDate(LocalDateTime.now());
result = salesLedgerProductMapper.insert(salesLedgerProduct);
@@ -336,6 +337,13 @@
return R.ok();
}
+ private BigDecimal normalizeSingleQuantity(BigDecimal singleQuantity) {
+ if (singleQuantity == null || singleQuantity.compareTo(BigDecimal.ZERO) <= 0) {
+ return BigDecimal.ONE;
+ }
+ return singleQuantity;
+ }
+
private String generateNextPlanNo(String datePrefix) {
QueryWrapper<ProductionPlan> queryWrapper = new QueryWrapper<>();
queryWrapper.likeRight("mps_no", "JH" + datePrefix);
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 fe385f1..4775de5 100644
--- a/src/main/java/com/ruoyi/sales/service/impl/SalesLedgerServiceImpl.java
+++ b/src/main/java/com/ruoyi/sales/service/impl/SalesLedgerServiceImpl.java
@@ -388,6 +388,7 @@
for (SalesLedgerProductImportDto salesLedgerProductImportDto : salesLedgerProductImportDtos) {
SalesLedgerProduct salesLedgerProduct = new SalesLedgerProduct();
BeanUtils.copyProperties(salesLedgerProductImportDto, salesLedgerProduct);
+ salesLedgerProduct.setSingleQuantity(normalizeSingleQuantity(salesLedgerProduct.getSingleQuantity()));
salesLedgerProduct.setSalesLedgerId(salesLedger.getId());
salesLedgerProduct.setType(1);
// 璁$畻涓嶅惈绋庢�讳环
@@ -590,7 +591,10 @@
public void handleSalesLedgerProducts(Long salesLedgerId, List<SalesLedgerProduct> products, SaleEnum type) {
// 鎸塈D鍒嗙粍锛屽尯鍒嗘柊澧炲拰鏇存柊鐨勮褰�
Map<Boolean, List<SalesLedgerProduct>> partitionedProducts = products.stream()
- .peek(p -> p.setSalesLedgerId(salesLedgerId))
+ .peek(p -> {
+ p.setSalesLedgerId(salesLedgerId);
+ p.setSingleQuantity(normalizeSingleQuantity(p.getSingleQuantity()));
+ })
.collect(Collectors.partitioningBy(p -> p.getId() != null));
List<SalesLedgerProduct> updateList = partitionedProducts.get(true);
@@ -620,6 +624,13 @@
return entity;
}
+ private BigDecimal normalizeSingleQuantity(BigDecimal singleQuantity) {
+ if (singleQuantity == null || singleQuantity.compareTo(BigDecimal.ZERO) <= 0) {
+ return BigDecimal.ONE;
+ }
+ return singleQuantity;
+ }
+
@Transactional(readOnly = true)
public String generateSalesContractNo() {
LocalDate currentDate = LocalDate.now();
diff --git a/src/main/java/com/ruoyi/sales/service/impl/SalesQuotationServiceImpl.java b/src/main/java/com/ruoyi/sales/service/impl/SalesQuotationServiceImpl.java
index de86ad0..32359ec 100644
--- a/src/main/java/com/ruoyi/sales/service/impl/SalesQuotationServiceImpl.java
+++ b/src/main/java/com/ruoyi/sales/service/impl/SalesQuotationServiceImpl.java
@@ -29,6 +29,7 @@
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
+import java.math.BigDecimal;
import java.time.LocalDate;
import java.util.Collections;
import java.util.List;
@@ -78,6 +79,7 @@
List<SalesQuotationProduct> products = salesQuotationDto.getProducts().stream().map(product -> {
SalesQuotationProduct salesQuotationProduct = new SalesQuotationProduct();
BeanUtils.copyProperties(product, salesQuotationProduct);
+ salesQuotationProduct.setSingleQuantity(normalizeSingleQuantity(salesQuotationProduct.getSingleQuantity()));
salesQuotationProduct.setSalesQuotationId(salesQuotation.getId());
return salesQuotationProduct;
}).collect(Collectors.toList());
@@ -87,7 +89,6 @@
approveProcessVO.setApproveType(6);
approveProcessVO.setApproveDeptId(loginUser.getCurrentDeptId());
approveProcessVO.setApproveReason(quotationNo);
- approveProcessVO.setApproveUserIds(salesQuotationDto.getApproveUserIds());
approveProcessVO.setApproveUser(loginUser.getUserId());
approveProcessVO.setApproveTime(LocalDate.now().toString());
approveProcessVO.setPrice(salesQuotationDto.getTotalAmount());
@@ -95,7 +96,7 @@
approveProcessService.addApprove(approveProcessVO);
}catch (Exception e){
log.error("SalesQuotationServiceImpl error:{}", e);
- throw new RuntimeException("瀹℃壒澶辫触");
+ throw new RuntimeException("瀹℃壒澶辫触");
}
return true;
}
@@ -118,13 +119,13 @@
List<SalesQuotationProduct> products = salesQuotationDto.getProducts().stream().map(product -> {
SalesQuotationProduct salesQuotationProduct = new SalesQuotationProduct();
BeanUtils.copyProperties(product, salesQuotationProduct);
+ salesQuotationProduct.setSingleQuantity(normalizeSingleQuantity(salesQuotationProduct.getSingleQuantity()));
salesQuotationProduct.setSalesQuotationId(salesQuotation.getId());
return salesQuotationProduct;
}).collect(Collectors.toList());
salesQuotationProductService.saveBatch(products);
// 淇敼鎶ヤ环瀹℃壒
- vo.setApproveUserIds(salesQuotationDto.getApproveUserIds());
vo.setApproveType(6);
vo.setApproveReason(salesQuotationDto.getQuotationNo());
approveProcessService.updateApproveUser(vo);
@@ -147,5 +148,12 @@
return true;
}
+ private BigDecimal normalizeSingleQuantity(BigDecimal singleQuantity) {
+ if (singleQuantity == null || singleQuantity.compareTo(BigDecimal.ZERO) <= 0) {
+ return BigDecimal.ONE;
+ }
+ return singleQuantity;
+ }
+
}
diff --git a/src/main/java/com/ruoyi/sales/service/impl/ShippingInfoServiceImpl.java b/src/main/java/com/ruoyi/sales/service/impl/ShippingInfoServiceImpl.java
index 8d16029..69a0820 100644
--- a/src/main/java/com/ruoyi/sales/service/impl/ShippingInfoServiceImpl.java
+++ b/src/main/java/com/ruoyi/sales/service/impl/ShippingInfoServiceImpl.java
@@ -19,6 +19,7 @@
import com.ruoyi.sales.mapper.SalesLedgerProductMapper;
import com.ruoyi.sales.mapper.ShippingInfoMapper;
import com.ruoyi.sales.mapper.ShippingProductDetailMapper;
+import com.ruoyi.sales.pojo.SalesLedgerProduct;
import com.ruoyi.sales.pojo.ShippingInfo;
import com.ruoyi.sales.pojo.ShippingProductDetail;
import com.ruoyi.sales.service.ShippingInfoService;
@@ -27,6 +28,7 @@
import org.apache.commons.collections4.CollectionUtils;
import org.springframework.stereotype.Service;
+import java.math.BigDecimal;
import java.util.List;
/**
@@ -127,6 +129,10 @@
@Override
public boolean add(ShippingInfoDto req) {
+ if (CollectionUtils.isEmpty(req.getBatchNoDetailList())) {
+ throw new RuntimeException("鍙戣揣鏄庣粏涓嶈兘涓虹┖");
+ }
+// normalizeShippingQuantity(req.getBatchNoDetailList(), req.getSalesLedgerProductId());
this.save(req);
req.getBatchNoDetailList().forEach(item -> item.setShippingInfoId(req.getId()));
shippingProductDetailMapper.insert(req.getBatchNoDetailList());
@@ -153,4 +159,31 @@
shippingApproveDto.setShippingProductDetailDtoList(dateilByShippingNo);
return shippingApproveDto;
}
+
+ /**
+ * 姝e父鍖栧彂璐ф暟閲�
+ * @param shippingProductDetails
+ * @param salesLedgerProductId
+ */
+ private void normalizeShippingQuantity(List<ShippingProductDetail> shippingProductDetails, Long salesLedgerProductId) {
+ if (CollectionUtils.isEmpty(shippingProductDetails)) {
+ return;
+ }
+ BigDecimal singleQuantity = BigDecimal.ONE;
+ if (salesLedgerProductId != null) {
+ SalesLedgerProduct salesLedgerProduct = salesLedgerProductMapper.selectById(salesLedgerProductId);
+ if (salesLedgerProduct != null && salesLedgerProduct.getSingleQuantity() != null
+ && salesLedgerProduct.getSingleQuantity().compareTo(BigDecimal.ZERO) > 0) {
+ singleQuantity = salesLedgerProduct.getSingleQuantity();
+ }
+ }
+ if (singleQuantity.compareTo(BigDecimal.ONE) == 0) {
+ return;
+ }
+ for (ShippingProductDetail shippingProductDetail : shippingProductDetails) {
+ if (shippingProductDetail.getQuantity() != null) {
+ shippingProductDetail.setQuantity(shippingProductDetail.getQuantity().multiply(singleQuantity));
+ }
+ }
+ }
}
diff --git a/src/main/resources/mapper/sales/SalesLedgerProductMapper.xml b/src/main/resources/mapper/sales/SalesLedgerProductMapper.xml
index 49569de..d824291 100644
--- a/src/main/resources/mapper/sales/SalesLedgerProductMapper.xml
+++ b/src/main/resources/mapper/sales/SalesLedgerProductMapper.xml
@@ -10,6 +10,7 @@
T1.sales_ledger_id,
T1.warn_num,
T1.quantity,
+ T1.single_quantity,
T1.min_stock,
T1.tax_rate,
T1.tax_inclusive_unit_price,
@@ -33,10 +34,10 @@
WHEN (IFNULL(t2.qualitity, 0) - IFNULL(t2.locked_quantity, 0)) >0 THEN 1
ELSE 0
END as has_sufficient_stock,
- (IFNULL(T1.quantity, 0) - IFNULL(t3.shipped_quantity, 0)) as no_quantity,
+ (IFNULL(T1.quantity, 0) * IFNULL(NULLIF(T1.single_quantity, 0), 1) - IFNULL(t3.shipped_quantity, 0)) as no_quantity,
CASE
WHEN IFNULL(t3.shipped_quantity, 0) = 0 THEN '寰呭彂璐�'
- WHEN (IFNULL(T1.quantity, 0) - IFNULL(t3.shipped_quantity, 0)) > 0 THEN '閮ㄥ垎鍙戣揣'
+ WHEN (IFNULL(T1.quantity, 0) * IFNULL(NULLIF(T1.single_quantity, 0), 1) - IFNULL(t3.shipped_quantity, 0)) > 0 THEN '閮ㄥ垎鍙戣揣'
ELSE '宸插彂璐�'
END as shippingStatus,
CASE
diff --git a/src/main/resources/mapper/sales/SalesQuotationMapper.xml b/src/main/resources/mapper/sales/SalesQuotationMapper.xml
index 3c93850..5434341 100644
--- a/src/main/resources/mapper/sales/SalesQuotationMapper.xml
+++ b/src/main/resources/mapper/sales/SalesQuotationMapper.xml
@@ -4,20 +4,19 @@
"http://mybatis.org/dtd/mybatis-3-mapper.dtd">
<mapper namespace="com.ruoyi.sales.mapper.SalesQuotationMapper">
<select id="listPage" resultType="com.ruoyi.sales.dto.SalesQuotationDto">
- SELECT t1.*,
- t2.approve_user_ids
+ SELECT t1.*
FROM sales_quotation t1
- LEFT JOIN approve_process t2 ON t1.quotation_no = t2.approve_reason and t2.approve_type = 6
- WHERE 1=1
- and t2.approve_deleted = 0
- <if test="salesQuotationDto.quotationNo != null and salesQuotationDto.quotationNo != '' ">
- AND t1.quotation_no LIKE CONCAT('%',#{salesQuotationDto.quotationNo},'%')
- </if>
- <if test="salesQuotationDto.customer != null and salesQuotationDto.customer != '' ">
- AND t1.customer = #{salesQuotationDto.customer}
- </if>
- <if test="salesQuotationDto.status != null and salesQuotationDto.status != '' ">
- AND t1.status = #{salesQuotationDto.status}
- </if>
+ <where>
+ <if test="salesQuotationDto.quotationNo != null and salesQuotationDto.quotationNo != '' ">
+ AND t1.quotation_no LIKE CONCAT('%',#{salesQuotationDto.quotationNo},'%')
+ </if>
+ <if test="salesQuotationDto.customer != null and salesQuotationDto.customer != '' ">
+ AND t1.customer = #{salesQuotationDto.customer}
+ </if>
+ <if test="salesQuotationDto.status != null and salesQuotationDto.status != '' ">
+ AND t1.status = #{salesQuotationDto.status}
+ </if>
+ </where>
+
</select>
</mapper>
diff --git "a/src/main/resources/static/\351\224\200\345\224\256\345\217\260\350\264\246\345\257\274\345\205\245\346\250\241\346\235\277.xlsx" "b/src/main/resources/static/\351\224\200\345\224\256\345\217\260\350\264\246\345\257\274\345\205\245\346\250\241\346\235\277.xlsx"
index 0dad163..8edc4ea 100644
--- "a/src/main/resources/static/\351\224\200\345\224\256\345\217\260\350\264\246\345\257\274\345\205\245\346\250\241\346\235\277.xlsx"
+++ "b/src/main/resources/static/\351\224\200\345\224\256\345\217\260\350\264\246\345\257\274\345\205\245\346\250\241\346\235\277.xlsx"
Binary files differ
--
Gitblit v1.9.3