From a422cb5b73799050827251f835ebc53d5757a96b Mon Sep 17 00:00:00 2001
From: 1 <1@123>
Date: 星期六, 24 一月 2026 09:06:21 +0800
Subject: [PATCH] lsh#

---
 rsf-server/src/main/java/com/vincent/rsf/server/api/controller/erp/params/SyncOrdersItem.java |  315 +++++++++++++++++++++++++++++++++++++++++++++++-----
 1 files changed, 282 insertions(+), 33 deletions(-)

diff --git a/rsf-server/src/main/java/com/vincent/rsf/server/api/controller/erp/params/SyncOrdersItem.java b/rsf-server/src/main/java/com/vincent/rsf/server/api/controller/erp/params/SyncOrdersItem.java
index e902599..073db9c 100644
--- a/rsf-server/src/main/java/com/vincent/rsf/server/api/controller/erp/params/SyncOrdersItem.java
+++ b/rsf-server/src/main/java/com/vincent/rsf/server/api/controller/erp/params/SyncOrdersItem.java
@@ -1,78 +1,327 @@
 package com.vincent.rsf.server.api.controller.erp.params;
 
-
+import com.fasterxml.jackson.annotation.JsonIgnore;
+import com.vincent.rsf.framework.common.Cools;
 import io.swagger.annotations.ApiModel;
 import io.swagger.annotations.ApiModelProperty;
-import lombok.experimental.Accessors;
 import lombok.Data;
+import lombok.experimental.Accessors;
 
+import javax.validation.constraints.*;
 import java.io.Serializable;
+import java.math.BigDecimal;
 
 @Data
 @Accessors(chain = true)
-@ApiModel(value = "SyncOrdersParams", description = "鍚屾鐩樼偣鍙傛暟")
+@ApiModel(value = "SyncOrdersItem", description = "鍗曟嵁鏄庣粏鍙傛暟")
 public class SyncOrdersItem implements Serializable {
 
     private static final long serialVersionUID = 1L;
 
-    @ApiModelProperty("鐩樼偣鍗曟槑缁咺D")
+    /**
+     * 璐т富绫诲瀷鏋氫妇
+     */
+    public interface OwnerType {
+        String SUPPLIER = "supplier";   // 渚涘簲鍟�
+        String CUSTOMER = "customer";   // 瀹㈡埛
+        String COMPANY = "company";     // 鍏徃
+        String THIRD_PARTY = "third_party"; // 绗笁鏂�
+    }
+
+    @ApiModelProperty(value = "鐩樼偣鍗曟槑缁咺D", example = "1001")
     private Long id;
 
-    @ApiModelProperty("璁㈠崟ID")
-    private Long orderId;
-
-    @ApiModelProperty("璁㈠崟鐘舵�亄in: 鍏ュ簱鍗�, out: 鍑哄簱鍗�, check: 鐩樼偣鍗晑")
-    private String orderType;
-
-    @ApiModelProperty("涓氬姟绫诲瀷")
-    private String wkType;
-
-    @ApiModelProperty("ASN鍗曞彿")
-    private String orderCode;
-
-    @ApiModelProperty("鐗╂枡鏍囪瘑")
+    @ApiModelProperty(value = "鐗╂枡鏍囪瘑", example = "2001")
     private Long matnrId;
 
-    @ApiModelProperty("鐗╂枡缂栫爜")
-    private String matnrCode;
+    @NotBlank(message = "鐗╂枡缂栫爜涓嶈兘涓虹┖")
+    @Size(max = 50, message = "鐗╂枡缂栫爜闀垮害涓嶈兘瓒呰繃50涓瓧绗�")
+    @ApiModelProperty(value = "鐗╂枡缂栫爜", required = true, example = "MAT001")
+    private String matnr;
 
-    @ApiModelProperty("鐗╂枡鍚嶇О")
+    @ApiModelProperty(value = "鐗╂枡鍚嶇О", example = "鍘熸潗鏂橝")
     private String maktx;
 
-    @ApiModelProperty("瀹㈠崟鍙�")
+    @ApiModelProperty(value = "瀹㈠崟鍙�", example = "CUST20240101001")
     private String platOrderCode;
 
-    @ApiModelProperty("骞冲彴鏍囪瘑锛堣鍙凤級")
+    @NotBlank(message = "骞冲彴鏍囪瘑锛堣鍙凤級涓嶈兘涓虹┖")
+    @ApiModelProperty(value = "骞冲彴鏍囪瘑锛堣鍙凤級", required = true, example = "10")
     private String platItemId;
 
-    @ApiModelProperty("宸ュ崟鍙�")
+    @ApiModelProperty(value = "宸ュ崟鍙�", example = "WO20240101001")
     private String platWorkCode;
 
-    @ApiModelProperty("椤圭洰鍙�")
+    @ApiModelProperty(value = "椤圭洰鍙�", example = "PROJ001")
     private String projectCode;
 
-    @ApiModelProperty("瀛楁绱㈠紩")
+    @ApiModelProperty(value = "瀛楁绱㈠紩", example = "ext_001")
     private String fieldsIndex;
 
-    @ApiModelProperty("瑙勬牸")
+    @ApiModelProperty(value = "瑙勬牸", example = "10 * 20 * 30")
     private String spec;
 
-    @ApiModelProperty("鍨嬪彿")
+    @ApiModelProperty(value = "鍨嬪彿", example = "MODEL-A")
     private String model;
 
-    @ApiModelProperty("鏁伴噺")
+    @NotNull(message = "鏁伴噺涓嶈兘涓虹┖")
+    @DecimalMin(value = "0.0", inclusive = false, message = "鏁伴噺蹇呴』澶т簬0")
+    @Digits(integer = 10, fraction = 3, message = "鏁伴噺鏁存暟浣嶄笉瓒呰繃10浣嶏紝灏忔暟浣嶄笉瓒呰繃3浣�")
+    @ApiModelProperty(value = "鏁伴噺", required = true, example = "100.5")
     private Double anfme;
 
-    @ApiModelProperty("搴撳瓨鍗曚綅")
+    @ApiModelProperty(value = "搴撳瓨鍗曚綅", example = "涓�")
     private String unit;
 
-    @ApiModelProperty("搴撳瓨鎵规")
+    @NotBlank(message = "搴撳瓨鎵规涓嶈兘涓虹┖")
+    @Size(max = 50, message = "搴撳瓨鎵规闀垮害涓嶈兘瓒呰繃50涓瓧绗�")
+    @ApiModelProperty(value = "搴撳瓨鎵规", required = true, example = "BATCH20240101")
     private String batch;
 
-    @ApiModelProperty("宸叉敹鏁伴噺")
+    @DecimalMin(value = "0.0", message = "宸叉敹鏁伴噺涓嶈兘涓鸿礋鏁�")
+    @ApiModelProperty(value = "宸叉敹鏁伴噺", example = "50.0")
     private Double qty;
 
-    @ApiModelProperty("鏉″舰鐮�")
+    @ApiModelProperty(value = "鏉″舰鐮�", example = "6936983800013")
     private String barcode;
 
-}
+    @ApiModelProperty(value = "鐜伴噾绁ㄥ彿", example = "CASH001")
+    private String crushNo;
+
+    @NotBlank(message = "璁″垝璺熻釜鍙蜂笉鑳戒负绌�")
+    @Size(max = 50, message = "璁″垝璺熻釜鍙烽暱搴︿笉鑳借秴杩�50涓瓧绗�")
+    @ApiModelProperty(value = "璁″垝璺熻釜鍙�", required = true, example = "PLAN20240101")
+    private String planNo;
+
+    @NotBlank(message = "琛屽唴鐮佷笉鑳戒负绌�")
+    @Size(max = 50, message = "琛屽唴鐮侀暱搴︿笉鑳借秴杩�50涓瓧绗�")
+    @ApiModelProperty(value = "琛屽唴鐮侊紝鍞竴鏍囪瘑", required = true, example = "LINE001")
+    private String lineId;
+
+    @ApiModelProperty(value = "鐗╂枡缂栫爜", example = "MAT001")
+    private String matNr;
+
+    @ApiModelProperty(value = "鐗╂枡鍚嶇О", example = "鍘熸潗鏂橝")
+    private String makTx;
+
+    @ApiModelProperty(value = "瑙勬牸", example = "10 * 20 * 30")
+    private String specs;
+
+    @ApiModelProperty(value = "鍩烘湰鍗曚綅", example = "PCS")
+    private String baseUnitId;
+
+    @ApiModelProperty(value = "鎵樼洏鐮侊紝鍗婃垚鍝�/鎴愬搧鍏ュ簱ERP闇�瑕佷紶锛岄潪鍒橢RP涓嶉渶瑕佷紶", example = "PALLET001")
+    private String palletId;
+
+    @ApiModelProperty(value = "璁′环鍗曚綅", example = "BOX")
+    private String priceUnitId;
+
+    @ApiModelProperty(value = "寤鸿鐩爣浠撳簱", example = "WH001")
+    private String targetWareHouseId;
+
+    @ApiModelProperty(value = "璋冨嚭浠�", example = "WH002")
+    private String sourceWareHouseId;
+
+    @ApiModelProperty(value = "鍏ュ簱绫诲瀷", example = "purchase")
+    private String inStockType;
+
+    @NotBlank(message = "璐т富绫诲瀷涓嶈兘涓虹┖")
+    @Pattern(regexp = "^(supplier|customer|company|third_party)$",
+            message = "璐т富绫诲瀷蹇呴』鏄痵upplier銆乧ustomer銆乧ompany鎴杢hird_party")
+    @ApiModelProperty(value = "璐т富绫诲瀷", required = true, example = "company")
+    private String ownerTypeId;
+
+    @NotBlank(message = "璐т富涓嶈兘涓虹┖")
+    @Size(max = 50, message = "璐т富闀垮害涓嶈兘瓒呰繃50涓瓧绗�")
+    @ApiModelProperty(value = "璐т富", required = true, example = "OWNER001")
+    private String ownerId;
+
+    @NotBlank(message = "璐т富鍚嶇О涓嶈兘涓虹┖")
+    @Size(max = 100, message = "璐т富鍚嶇О闀垮害涓嶈兘瓒呰繃100涓瓧绗�")
+    @ApiModelProperty(value = "璐т富鍚嶇О", required = true, example = "XX鏈夐檺鍏徃")
+    private String ownerName;
+
+    @ApiModelProperty(value = "淇濈鑰呯被鍨�", example = "warehouse")
+    private String keeperTypeId;
+
+    @ApiModelProperty(value = "淇濈鑰�", example = "KEEPER001")
+    private String keeperId;
+
+    @ApiModelProperty(value = "淇濈鑰呭悕绉�", example = "浠撳簱绠$悊閮�")
+    private String keeperName;
+
+    /**
+     * 鑾峰彇瀹為檯鐨勭墿鏂欑紪鐮�
+     * 浼樺厛浣跨敤 matnr锛屽鏋滀负绌哄垯浣跨敤 matNr
+     */
+    @JsonIgnore
+    public String getActualMatnr() {
+        return !Cools.isEmpty(matnr) ? matnr : matNr;
+    }
+
+    /**
+     * 鑾峰彇瀹為檯鐨勭墿鏂欏悕绉�
+     * 浼樺厛浣跨敤 maktx锛屽鏋滀负绌哄垯浣跨敤 makTx
+     */
+    @JsonIgnore
+    public String getActualMaktx() {
+        return !Cools.isEmpty(maktx) ? maktx : makTx;
+    }
+
+    /**
+     * 鑾峰彇瀹為檯鐨勮鏍�
+     * 浼樺厛浣跨敤 spec锛屽鏋滀负绌哄垯浣跨敤 specs
+     */
+    @JsonIgnore
+    public String getActualSpec() {
+        return !Cools.isEmpty(spec) ? spec : specs;
+    }
+
+    /**
+     * 璁剧疆鐗╂枡缂栫爜锛堜繚鎸佷袱涓瓧娈靛悓姝ワ級
+     */
+    public void setMatnr(String matnr) {
+        this.matnr = matnr;
+        this.matNr = matnr;
+    }
+
+    public void setMatNr(String matNr) {
+        this.matNr = matNr;
+        this.matnr = matNr;
+    }
+
+    /**
+     * 璁剧疆鐗╂枡鍚嶇О锛堜繚鎸佷袱涓瓧娈靛悓姝ワ級
+     */
+    public void setMaktx(String maktx) {
+        this.maktx = maktx;
+        this.makTx = maktx;
+    }
+
+    public void setMakTx(String makTx) {
+        this.makTx = makTx;
+        this.maktx = makTx;
+    }
+
+    /**
+     * 璁剧疆瑙勬牸锛堜繚鎸佷袱涓瓧娈靛悓姝ワ級
+     */
+    public void setSpec(String spec) {
+        this.spec = spec;
+        this.specs = spec;
+    }
+
+    public void setSpecs(String specs) {
+        this.specs = specs;
+        this.spec = specs;
+    }
+
+    /**
+     * 杞崲涓築igDecimal锛堢簿搴﹁绠椾娇鐢級
+     */
+    @JsonIgnore
+    public BigDecimal getAnfmeAsBigDecimal() {
+        return anfme != null ? BigDecimal.valueOf(anfme) : BigDecimal.ZERO;
+    }
+
+    @JsonIgnore
+    public BigDecimal getQtyAsBigDecimal() {
+        return qty != null ? BigDecimal.valueOf(qty) : BigDecimal.ZERO;
+    }
+
+    /**
+     * 鑾峰彇鍓╀綑鏁伴噺
+     */
+    @JsonIgnore
+    public Double getRemainingQty() {
+        if (anfme == null) {
+            return 0.0;
+        }
+        double currentQty = qty != null ? qty : 0.0;
+        double remaining = anfme - currentQty;
+        return Math.max(0, remaining);
+    }
+
+    /**
+     * 鏄惁宸插畬鎴�
+     */
+    @JsonIgnore
+    public boolean isCompleted() {
+        if (anfme == null) {
+            return false;
+        }
+        double currentQty = qty != null ? qty : 0.0;
+        return currentQty >= anfme;
+    }
+
+    /**
+     * 鑾峰彇瀹屾垚鐧惧垎姣�
+     */
+    @JsonIgnore
+    public int getCompletionPercentage() {
+        if (anfme == null || anfme == 0) {
+            return 0;
+        }
+        double currentQty = qty != null ? qty : 0.0;
+        int percentage = (int) ((currentQty / anfme) * 100);
+        return Math.min(Math.max(percentage, 0), 100);
+    }
+
+    /**
+     * 涓氬姟楠岃瘉
+     */
+    public void validateBusiness(String orderType) {
+        if ("purchase".equals(inStockType) && Cools.isEmpty(palletId)) {
+            throw new IllegalArgumentException("閲囪喘鍏ュ簱鏄庣粏蹇呴』鎻愪緵鎵樼洏鐮�");
+        }
+
+        if ("production".equals(inStockType) && Cools.isEmpty(palletId)) {
+            throw new IllegalArgumentException("鐢熶骇鍏ュ簱鏄庣粏蹇呴』鎻愪緵鎵樼洏鐮�");
+        }
+
+        if (!Cools.isEmpty(targetWareHouseId) && !Cools.isEmpty(sourceWareHouseId)) {
+            if (targetWareHouseId.equals(sourceWareHouseId)) {
+                throw new IllegalArgumentException("鐩爣浠撳簱鍜岃皟鍑轰粨搴撲笉鑳界浉鍚�");
+            }
+        }
+
+        if (qty != null && qty > anfme) {
+            throw new IllegalArgumentException("宸叉敹鏁伴噺涓嶈兘澶т簬璁″垝鏁伴噺");
+        }
+    }
+
+    /**
+     * 鏄惁闇�瑕佹墭鐩樼爜
+     */
+    @JsonIgnore
+    public boolean requiresPallet() {
+        return "purchase".equals(inStockType) ||
+                "production".equals(inStockType) ||
+                "return".equals(inStockType);
+    }
+
+    /**
+     * 鏄惁璋冩嫧鏄庣粏
+     */
+    @JsonIgnore
+    public boolean isTransferItem() {
+        return !Cools.isEmpty(sourceWareHouseId) && !Cools.isEmpty(targetWareHouseId);
+    }
+
+    /**
+     * 鑾峰彇鐗╂枡鍞竴鏍囪瘑
+     */
+    @JsonIgnore
+    public String getMaterialKey() {
+        return String.format("%s_%s_%s", getActualMatnr(), batch, getActualSpec());
+    }
+
+    /**
+     * 鑾峰彇鏄庣粏鎽樿
+     */
+    @JsonIgnore
+    public String getSummary() {
+        return String.format("鐗╂枡[%s] 鎵规[%s] 鏁伴噺[%s/%s]",
+                getActualMatnr(), batch, qty, anfme);
+    }
+}
\ No newline at end of file

--
Gitblit v1.9.1