Bladeren bron

fix: 宜搭实例可推送包材核价,正式回写改走正式区

Co-authored-by: Cursor <cursoragent@cursor.com>
admin 4 dagen geleden
bovenliggende
commit
d41cffa42a

+ 56 - 5
src/main/java/com/malk/minglei/controller/MingleiPortController.java

@@ -1,7 +1,11 @@
 package com.malk.minglei.controller;
 
+import com.fasterxml.jackson.databind.JsonNode;
+import com.fasterxml.jackson.databind.ObjectMapper;
 import com.malk.minglei.dto.MingleiPortRequest;
+import com.malk.minglei.dto.SupplierPriceApprovalProcessRequest;
 import com.malk.minglei.service.port.MingleiPortService;
+import com.malk.minglei.service.port.SupplierPriceApprovalProcessService;
 import org.slf4j.Logger;
 import org.slf4j.LoggerFactory;
 import org.springframework.http.HttpStatus;
@@ -15,10 +19,13 @@ import org.springframework.web.bind.annotation.RequestMapping;
 import org.springframework.web.bind.annotation.RestController;
 import org.springframework.web.client.RestClientException;
 
-import javax.validation.Valid;
+import javax.validation.ConstraintViolation;
+import javax.validation.Validation;
+import javax.validation.Validator;
 import java.util.Collections;
 import java.util.LinkedHashMap;
 import java.util.Map;
+import java.util.Set;
 
 /**
  * 提供调用明磊外部单据接口的本地触发入口。
@@ -30,27 +37,60 @@ public class MingleiPortController {
     private static final Logger LOGGER = LoggerFactory.getLogger(MingleiPortController.class);
 
     private final MingleiPortService mingleiPortService;
+    private final SupplierPriceApprovalProcessService supplierPriceApprovalProcessService;
+    private final ObjectMapper objectMapper;
+    private final Validator validator = Validation.buildDefaultValidatorFactory().getValidator();
 
     /**
      * 创建明磊外部单据接口控制器。
      *
      * @param mingleiPortService 明磊外部单据接口服务
+     * @param supplierPriceApprovalProcessService 宜搭实例转 T100 单据服务
+     * @param objectMapper JSON 解析器
      */
-    public MingleiPortController(MingleiPortService mingleiPortService) {
+    public MingleiPortController(MingleiPortService mingleiPortService,
+                                 SupplierPriceApprovalProcessService supplierPriceApprovalProcessService,
+                                 ObjectMapper objectMapper) {
         this.mingleiPortService = mingleiPortService;
+        this.supplierPriceApprovalProcessService = supplierPriceApprovalProcessService;
+        this.objectMapper = objectMapper;
     }
 
     /**
-     * 接收本系统的供应商价格审批单请求,并调用外部 T100 接口。
+     * 接收两类请求。带 formId 时按宜搭实例读取表单并推送 T100;否则按已组装好的 head、detail 转发。
      *
-     * @param request 仅包含 head 和 detail 的供应商价格审批单请求体
+     * @param body 宜搭实例标识,或 T100 单据 head、detail
      * @return 外部 T100 接口响应内容
      */
     @PostMapping("/supplier-price-approvals")
-    public ResponseEntity<Map<String, Object>> submitSupplierPriceApproval(@Valid @RequestBody MingleiPortRequest request) {
+    public ResponseEntity<Map<String, Object>> submitSupplierPriceApproval(@RequestBody JsonNode body) {
+        if (body != null && body.has("formId")) {
+            return ResponseEntity.ok(submitYidaInstance(body));
+        }
+        MingleiPortRequest request = objectMapper.convertValue(body, MingleiPortRequest.class);
+        Set<ConstraintViolation<MingleiPortRequest>> violations = validator.validate(request);
+        if (!violations.isEmpty()) {
+            return ResponseEntity.badRequest().body(Collections.<String, Object>singletonMap("message", "Request validation failed"));
+        }
         return ResponseEntity.ok(mingleiPortService.submitSupplierPriceApproval(request));
     }
 
+    private Map<String, Object> submitYidaInstance(JsonNode body) {
+        SupplierPriceApprovalProcessRequest request = objectMapper.convertValue(body, SupplierPriceApprovalProcessRequest.class);
+        if (isBlank(request.getFormId()) || isBlank(request.getFormInstanceId())) {
+            throw new IllegalArgumentException("formId and formInstanceId must not be blank");
+        }
+        if (request.requiresProcessInstanceId() && isBlank(request.getProcessInstanceId())) {
+            throw new IllegalArgumentException("processInstanceId must not be blank");
+        }
+        return supplierPriceApprovalProcessService.submitByInstanceIds(
+                request.getFormId(), request.getFormInstanceId(), request.getProcessInstanceId());
+    }
+
+    private static boolean isBlank(String value) {
+        return value == null || value.trim().isEmpty();
+    }
+
     /**
      * 返回本地请求体校验或 JSON 解析失败的信息,不发起外部调用。
      *
@@ -62,6 +102,17 @@ public class MingleiPortController {
         return ResponseEntity.badRequest().body(Collections.singletonMap("message", "Request validation failed"));
     }
 
+    /**
+     * 返回宜搭实例参数不完整或表单不受支持的错误信息。
+     *
+     * @param exception 参数异常
+     * @return 参数错误响应
+     */
+    @ExceptionHandler(IllegalArgumentException.class)
+    public ResponseEntity<Map<String, String>> handleInvalidArgument(IllegalArgumentException exception) {
+        return ResponseEntity.badRequest().body(Collections.singletonMap("message", exception.getMessage()));
+    }
+
     /**
      * 将外部服务的连接、超时或响应异常转换为本地网关错误。
      *

+ 2 - 0
src/main/resources/application-prod.yml

@@ -1,6 +1,8 @@
 minglei:
   port:
     supplier-price-approval-url: ${MINGLEI_SUPPLIER_PRICE_APPROVAL_URL:http://10.0.2.60/wstopprd/ws/r/awsp920}
+  reply-erp:
+    url: ${MINGLEI_REPLY_ERP_URL:http://10.0.2.60/wstopprd/ws/r/awsp920}
   erp-t100:
     request:
       service-id: topprd

+ 2 - 0
src/main/resources/application-test.yml

@@ -1,6 +1,8 @@
 minglei:
   port:
     supplier-price-approval-url: ${MINGLEI_SUPPLIER_PRICE_APPROVAL_URL:http://10.0.2.60/wtoptst/ws/r/awsp920}
+  reply-erp:
+    url: ${MINGLEI_REPLY_ERP_URL:http://10.0.2.60/wtoptst/ws/r/awsp920}
   erp-t100:
     request:
       service-id: toptst

+ 28 - 2
src/test/java/com/malk/minglei/controller/MingleiPortControllerTest.java

@@ -1,7 +1,9 @@
 package com.malk.minglei.controller;
 
+import com.fasterxml.jackson.databind.ObjectMapper;
 import com.malk.minglei.dto.MingleiPortRequest;
 import com.malk.minglei.service.port.MingleiPortService;
+import com.malk.minglei.service.port.SupplierPriceApprovalProcessService;
 import org.junit.jupiter.api.Test;
 import org.springframework.http.MediaType;
 import org.springframework.test.web.servlet.MockMvc;
@@ -10,6 +12,8 @@ import org.springframework.test.web.servlet.setup.MockMvcBuilders;
 import java.util.Collections;
 
 import static org.mockito.ArgumentMatchers.any;
+import static org.mockito.ArgumentMatchers.eq;
+import static org.mockito.ArgumentMatchers.isNull;
 import static org.mockito.BDDMockito.given;
 import static org.mockito.Mockito.mock;
 import static org.mockito.Mockito.verify;
@@ -27,7 +31,7 @@ class MingleiPortControllerTest {
         MingleiPortService service = mock(MingleiPortService.class);
         given(service.submitSupplierPriceApproval(any(MingleiPortRequest.class)))
                 .willReturn(Collections.<String, Object>singletonMap("srvcode", "000"));
-        MockMvc mockMvc = MockMvcBuilders.standaloneSetup(new MingleiPortController(service)).build();
+        MockMvc mockMvc = MockMvcBuilders.standaloneSetup(controller(service, mock(SupplierPriceApprovalProcessService.class))).build();
 
         mockMvc.perform(post("/api/minglei/ports/supplier-price-approvals")
                         .contentType(MediaType.APPLICATION_JSON)
@@ -41,7 +45,7 @@ class MingleiPortControllerTest {
     @Test
     void rejectsRequestWithoutRequiredHeadField() throws Exception {
         MingleiPortService service = mock(MingleiPortService.class);
-        MockMvc mockMvc = MockMvcBuilders.standaloneSetup(new MingleiPortController(service)).build();
+        MockMvc mockMvc = MockMvcBuilders.standaloneSetup(controller(service, mock(SupplierPriceApprovalProcessService.class))).build();
 
         mockMvc.perform(post("/api/minglei/ports/supplier-price-approvals")
                         .contentType(MediaType.APPLICATION_JSON)
@@ -50,6 +54,28 @@ class MingleiPortControllerTest {
                 .andExpect(jsonPath("$.message").value("Request validation failed"));
     }
 
+    @Test
+    void submitsPackagingMaterialPriceApprovalFromYidaInstance() throws Exception {
+        MingleiPortService portService = mock(MingleiPortService.class);
+        SupplierPriceApprovalProcessService processService = mock(SupplierPriceApprovalProcessService.class);
+        given(processService.submitByInstanceIds(eq("FORM-69A12600F87349D3B653BF86E419224DLIX9"),
+                eq("form-instance-1"), isNull())).willReturn(Collections.<String, Object>singletonMap("srvcode", "000"));
+        MockMvc mockMvc = MockMvcBuilders.standaloneSetup(controller(portService, processService)).build();
+
+        mockMvc.perform(post("/api/minglei/ports/supplier-price-approvals")
+                        .contentType(MediaType.APPLICATION_JSON)
+                        .content("{\"formId\":\"FORM-69A12600F87349D3B653BF86E419224DLIX9\",\"formInstanceId\":\"form-instance-1\"}"))
+                .andExpect(status().isOk())
+                .andExpect(jsonPath("$.srvcode").value("000"));
+
+        verify(processService).submitByInstanceIds("FORM-69A12600F87349D3B653BF86E419224DLIX9", "form-instance-1", null);
+    }
+
+    private MingleiPortController controller(MingleiPortService portService,
+                                             SupplierPriceApprovalProcessService processService) {
+        return new MingleiPortController(portService, processService, new ObjectMapper());
+    }
+
     private String validRequestJson() {
         return "{\"head\":{\"pmdidocno\":\"CH3\",\"pmdi001\":\"N\",\"pmdi034\":\"605188\","
                 + "\"pmdidocdt\":\"2026-08-06\",\"pmdi004\":\"517022\",\"pmdi015\":\"2026-08-06\","