Просмотр исходного кода

Merge remote-tracking branch 'origin/dev' into dev

liyuan 8 месяцев назад
Родитель
Сommit
5bc004dfba

+ 6 - 1
blade-service/blade-los/src/main/java/org/springblade/los/Util/Regular_VOLTA.java

@@ -212,7 +212,12 @@ public class Regular_VOLTA {
 		if("danger".equals(ediData.getCargoType())){
 			if(ObjectUtils.isNull(ediData.getHsCode())){
 				// HS CODE 不是必填
-				// msg += "HS CODE,";
+				msg += "HS CODE,";
+			}else{
+				String line = ediData.getHsCode();
+				if(line.length()!=4){
+					msg += "请录入 4 位长度 HS CODE,";
+				}
 			}
 			if(ObjectUtils.isNull(ediData.getDgImdgCode())){
 				msg += "IMDG CODE,";

+ 354 - 271
blade-service/blade-los/src/main/java/org/springblade/los/business/sea/service/impl/TemplateImportServiceImpl.java

@@ -9,6 +9,7 @@ import org.apache.poi.ss.usermodel.*;
 import org.apache.poi.xssf.usermodel.XSSFWorkbook;
 import org.springblade.core.secure.utils.AuthUtil;
 import org.springblade.core.tool.api.R;
+import org.springblade.los.Util.RegularUtils;
 import org.springblade.los.basic.packages.entity.BPackages;
 import org.springblade.los.basic.packages.service.IBPackagesService;
 import org.springblade.los.basic.ports.entity.BPorts;
@@ -22,6 +23,7 @@ import org.springblade.los.business.sea.service.IBillsService;
 import org.springblade.los.business.sea.service.ITemplateImportService;
 import org.springframework.stereotype.Service;
 import org.springframework.web.multipart.MultipartFile;
+import org.stringtemplate.v4.ST;
 
 import java.io.FileInputStream;
 import java.lang.reflect.Field;
@@ -31,9 +33,7 @@ import java.math.RoundingMode;
 import java.nio.file.Files;
 import java.nio.file.Path;
 import java.nio.file.StandardCopyOption;
-import java.util.ArrayList;
-import java.util.Arrays;
-import java.util.List;
+import java.util.*;
 
 /**
  * @author :jixinyuan
@@ -51,12 +51,16 @@ public class TemplateImportServiceImpl implements ITemplateImportService {
 	private final IBillsService billsService;
 
 	public static double splitNumericPrefixFromString(String str){
-		str=str.trim();
-		String str2="";
+		str=str.replace(" ","").trim();
+		String str2="", str3="";
+		Boolean bf = false;
 		if(str != null && !"".equals(str)){
 			for(int i=0; i<str.length(); i++){
-				if(str.charAt(i)==46||(str.charAt(i)>=48 && str.charAt(i)<=57)){
-					str2+=str.charAt(i);
+				if(!bf && (str.charAt(i)==46||(str.charAt(i)>=48 && str.charAt(i)<=57))){
+					str2 += str.charAt(i);
+				}else{
+					bf = true;
+					str3 += str.charAt(i);
 				}
 			}
 		}
@@ -72,6 +76,35 @@ public class TemplateImportServiceImpl implements ITemplateImportService {
 		}
 	}
 
+	public static Map<String, Object> splitNumericPrefixMapFromString(String str){
+		Map<String, Object> map = new HashMap<>();
+		str=str.replace(" ","").trim();
+		String str2="", str3="";
+		Boolean bf = false;
+		if(str != null && !"".equals(str)){
+			for(int i=0; i<str.length(); i++){
+				if(!bf && (str.charAt(i)==46||(str.charAt(i)>=48 && str.charAt(i)<=57))){
+					str2 += str.charAt(i);
+				}else{
+					bf = true;
+					str3 += str.charAt(i);
+				}
+			}
+		}
+
+		double d=0;
+
+		try{
+			d = Double.parseDouble(str2);
+		}catch (Exception e){
+			d = 0;
+		}finally{
+			map.put("value", d);
+			map.put("str", str3);
+			return map;
+		}
+	}
+
 	public static String getSheetCellValueAsString(Sheet sheet, int row, int col){
 		Row r = sheet.getRow(row);
 		Cell c = ObjectUtils.isNotNull(r) ? r.getCell(col) : null;
@@ -132,6 +165,12 @@ public class TemplateImportServiceImpl implements ITemplateImportService {
 		return splitNumericPrefixFromString(str);
 	}
 
+	public static Map<String, Object> getSheetCellValueAsNumericPrefixMap(Sheet sheet, int row, int col) {
+		String str = getSheetCellValueAsString(sheet, row, col);
+
+		return splitNumericPrefixMapFromString(str);
+	}
+
 	public static Boolean stringBuilderIsNotEmpty(StringBuilder sb){
 		return ObjectUtils.isNotNull(sb) && !sb.toString().trim().isEmpty();
 	}
@@ -225,284 +264,328 @@ public class TemplateImportServiceImpl implements ITemplateImportService {
 		Files.copy(file.getInputStream(), tempFile, StandardCopyOption.REPLACE_EXISTING);
 		// 创建FileInputStream来读取临时文件
 		FileInputStream fis = new FileInputStream(tempFile.toFile());
-		Workbook workbook = WorkbookFactory.create(fis);
-		Sheet sheet = workbook.getSheetAt(0); // 获取第一个工作表
-
-		String stringCellValue = "";
+		Workbook workbook = null;
+		Sheet sheet = null;
+		String errMsg = "";
 
-		//TO
-		if (ObjectUtils.isNotNull(sheet.getRow(1).getCell(1))) {
-			String to = getSheetCellValueAsString(sheet, 1, 1);
-			System.out.println("TO:" + to);
-		}
-		//ATTN
-		if (ObjectUtils.isNotNull(sheet.getRow(2).getCell(1))) {
-			String attn = getSheetCellValueAsString(sheet, 2, 1);
-			System.out.println("attn:" + attn);
-		}
-		//SHIPPER
-		StringBuilder shipper = new StringBuilder();
-		for (int i = 3; i <= 7; i++) {
-			if (ObjectUtils.isNotNull(sheet.getRow(i).getCell(1))) {
-				shipper.append(getSheetCellValueAsString(sheet, i, 1) + "\r\n");
-			}
-		}
-		if (stringBuilderIsNotEmpty(shipper)) {
-			seaBillsDetail.setHshipperDetails(shipper.toString().trim());
-//			bills.setHshipperDetails(shipper.toString());
-			System.out.println("shipper:" + shipper);
-		} else {
-			throw new RuntimeException("发货人提单描述不能为空");
-		}
-		//CONSIGNEE
-		StringBuilder consignee = new StringBuilder();
-		for (int i = 8; i <= 12; i++) {
-			if (ObjectUtils.isNotNull(sheet.getRow(i).getCell(1))) {
-				consignee.append(getSheetCellValueAsString(sheet, i, 1) + "\r\n");
-			}
-		}
-		if (stringBuilderIsNotEmpty(consignee)) {
-			seaBillsDetail.setHconsigneeDetails(consignee.toString().trim());
-//			bills.setHconsigneeDetails(consignee.toString());
-			System.out.println("consignee:" + consignee);
-		} else {
-			throw new RuntimeException("收货人提单描述不能为空");
-		}
-		//NOTIFY PARTY
-		StringBuilder notifyParty = new StringBuilder();
-		for (int i = 13; i <= 17; i++) {
-			if (ObjectUtils.isNotNull(sheet.getRow(i).getCell(1))) {
-				notifyParty.append(getSheetCellValueAsString(sheet, i, 1) + "\r\n");
-			}
+		try{
+			workbook = WorkbookFactory.create(fis);
+			sheet = workbook.getSheetAt(0); // 获取第一个工作表
+		}catch (Exception e){
+			workbook = null;
+			sheet = null;
+			errMsg = e.getMessage();
 		}
-		if (stringBuilderIsNotEmpty(notifyParty)) {
-			seaBillsDetail.setHnotifyDetails(notifyParty.toString().trim());
-//			bills.setHnotifyDetails(notifyParty.toString());
-			System.out.println("notifyParty:" + notifyParty);
-		} else {
-			throw new RuntimeException("通知人提单描述不能为空");
+
+		if(ObjectUtils.isNull(workbook) || ObjectUtils.isNull(sheet)) {
+			throw new RuntimeException("文件读取失败,该文件可能不是 Excel 文件!" + errMsg);
 		}
-		//B/L NO
-		if (ObjectUtils.isNotNull(sheet.getRow(18).getCell(1))) {
-			String blno = getSheetCellValueAsString(sheet, 18, 1);
-			System.out.println("blno:" + blno);
-			bills.setMblno(blno);
-		} else {
-			throw new RuntimeException("提单号不能为空");
+
+		String stringCellValue = "";
+
+		int firstRow = sheet.getFirstRowNum();
+		int lastRow = sheet.getLastRowNum();
+		if(firstRow<=0 && lastRow<0){
+			throw new RuntimeException("文件内容为空!");
 		}
-		//VSL/VOY
-		if (ObjectUtils.isNotNull(sheet.getRow(18).getCell(4))) {
-			String vslVoy = getSheetCellValueAsString(sheet, 18, 4);
-			if (vslVoy.contains("/")) {
-				String vsl = vslVoy.substring(0, vslVoy.indexOf("/"));
-				String voy = vslVoy.substring(vslVoy.indexOf("/") + 1);
-				if (ObjectUtils.isNotNull(vsl)) {
-					BVessels vessels = bVesselsService.getOne(new LambdaQueryWrapper<BVessels>()
-						.eq(BVessels::getTenantId, AuthUtil.getTenantId())
-						.eq(BVessels::getIsDeleted, 0)
-						.like(BVessels::getEnName, vsl)
+
+		StringBuilder sbLines = new StringBuilder();
+		for(int r=firstRow; r<=lastRow; r++) {
+			String val0 = getSheetCellValueAsString(sheet, r, 0).toUpperCase().replace(" ", "");
+			if(val0.isEmpty()){
+				sbLines.append(getSheetCellValueAsString(sheet, r, 1).concat("\r\n"));
+			} else if (val0.equals("TO:")) {
+				System.out.println("TO:" + getSheetCellValueAsString(sheet, r, 1).toUpperCase());
+			} else if (val0.equals("ATTN:")) {
+				System.out.println("ATTN:" + getSheetCellValueAsString(sheet, r, 1).toUpperCase());
+			} else if (val0.equals("SHIPPER")) {
+				sbLines.setLength(0);
+				sbLines.append(getSheetCellValueAsString(sheet, r, 1).concat("\r\n"));
+			} else if (val0.equals("CONSIGNEE")) {
+				if (stringBuilderIsNotEmpty(sbLines)) {
+					System.out.println("shipper:" + sbLines);
+					seaBillsDetail.setHshipperDetails(sbLines.toString().trim());
+				} else {
+					// throw new RuntimeException("提单发货人描述不能为空");
+				}
+				sbLines.setLength(0);
+				sbLines.append(getSheetCellValueAsString(sheet, r, 1).toUpperCase().concat("\r\n"));
+			} else if (val0.equals("NOTIFYPARTY")) {
+				if (stringBuilderIsNotEmpty(sbLines)) {
+					System.out.println("consignee:" + sbLines);
+					seaBillsDetail.setHconsigneeDetails(sbLines.toString().trim());
+				} else {
+					// throw new RuntimeException("提单收货人描述不能为空");
+				}
+				sbLines.setLength(0);
+				sbLines.append(getSheetCellValueAsString(sheet, r, 1).toUpperCase().concat("\r\n"));
+			} else if (val0.equals("B/LNO")) {
+				if (stringBuilderIsNotEmpty(sbLines)) {
+					System.out.println("notifyParty:" + sbLines);
+					seaBillsDetail.setHnotifyDetails(sbLines.toString().trim());
+				} else {
+					seaBillsDetail.setHnotifyDetails("SAME AS CNEE");
+					// throw new RuntimeException("提单通知人描述不能为空");
+				}
+				sbLines.setLength(0);
+
+				String blno = getSheetCellValueAsString(sheet, r, 1);
+				if(ObjectUtils.isNotNull(blno)){
+					System.out.println("blno:" + blno);
+					bills.setMblno(blno);
+				} else {
+					// throw new RuntimeException("提单号不能为空");
+				}
+
+				//VSL/VOY
+				String vslVoy = getSheetCellValueAsString(sheet, r, 4);
+				if (ObjectUtils.isNotNull(vslVoy)) {
+					if (vslVoy.contains("/")) {
+						String vsl = vslVoy.substring(0, vslVoy.indexOf("/"));
+						String voy = vslVoy.substring(vslVoy.indexOf("/") + 1);
+						if (ObjectUtils.isNotNull(vsl)) {
+							BVessels vessels = bVesselsService.getOne(new LambdaQueryWrapper<BVessels>()
+								.eq(BVessels::getTenantId, AuthUtil.getTenantId())
+								.eq(BVessels::getIsDeleted, 0)
+								.like(BVessels::getEnName, vsl)
+								.last("limit 1"));
+							if (vessels != null) {
+								bills.setVesselEnName(vessels.getEnName());
+								bills.setVesselCnName(vessels.getCnName());
+								bills.setVesselId(vessels.getId());
+							}
+						}
+						bills.setVoyageNo(voy);
+						System.out.println("vsl:" + vsl);
+						System.out.println("voy:" + voy);
+						System.out.println("vslVoy:" + vslVoy);
+					} else {
+						throw new RuntimeException("船名航次不能为空");
+					}
+				} else {
+					// throw new RuntimeException("船名航次不能为空");
+				}
+			} else if (val0.equals("POR")) {
+				String port = getSheetCellValueAsString(sheet, r, 1);
+				System.out.println("por:" + port);
+				if (ObjectUtils.isNotNull(port)) {
+					BPorts ports = bPortsService.getOne(new LambdaQueryWrapper<BPorts>()
+						.eq(BPorts::getTenantId, AuthUtil.getTenantId())
+						.eq(BPorts::getIsDeleted, 0)
+						.like(BPorts::getEnName, port)
 						.last("limit 1"));
-					if (vessels != null) {
-						bills.setVesselEnName(vessels.getEnName());
-						bills.setVesselCnName(vessels.getCnName());
-						bills.setVesselId(vessels.getId());
+					if (ports != null) {
+						bills.setPlaceReceiptId(ports.getId());
+						bills.setPlaceReceiptCode(ports.getCode());
+						bills.setPlaceReceiptName(ports.getEnName());
+						bills.setPlaceReceiptNamePrint(ports.getEnName());
+					}else {
+						throw new RuntimeException("收货地 " + port + " 无法识别!");
 					}
+				} else {
+					// throw new RuntimeException("收货地不能为空");
 				}
-				bills.setVoyageNo(voy);
-				System.out.println("vsl:" + vsl);
-				System.out.println("voy:" + voy);
-				System.out.println("vslVoy:" + vslVoy);
-			} else {
-				throw new RuntimeException("船名航次不能为空");
-			}
-		} else {
-			throw new RuntimeException("船名航次不能为空");
-		}
-		//POR
-		if (ObjectUtils.isNotNull(sheet.getRow(19).getCell(1))) {
-			String por = getSheetCellValueAsString(sheet, 19, 1);
-			if (ObjectUtils.isNotNull(por)) {
-				BPorts ports = bPortsService.getOne(new LambdaQueryWrapper<BPorts>()
-					.eq(BPorts::getTenantId, AuthUtil.getTenantId())
-					.eq(BPorts::getIsDeleted, 0)
-					.like(BPorts::getEnName, por)
-					.last("limit 1"));
-				if (ports != null) {
-					bills.setPlaceReceiptId(ports.getId());
-					bills.setPlaceReceiptCode(ports.getCode());
-					bills.setPlaceReceiptName(ports.getEnName());
-					bills.setPlaceReceiptNamePrint(ports.getEnName());
+
+				port = getSheetCellValueAsString(sheet, r, 4);
+				System.out.println("pol:" + port);
+				if (ObjectUtils.isNotNull(port)) {
+					BPorts ports = bPortsService.getOne(new LambdaQueryWrapper<BPorts>()
+						.eq(BPorts::getTenantId, AuthUtil.getTenantId())
+						.eq(BPorts::getIsDeleted, 0)
+						.like(BPorts::getEnName, port)
+						.last("limit 1"));
+					if (ports != null) {
+						bills.setPolId(ports.getId());
+						bills.setPolCode(ports.getCode());
+						bills.setPolCnName(ports.getCnName());
+						bills.setPolEnName(ports.getEnName());
+						bills.setPolNamePrint(ports.getEnName());
+					}else {
+						throw new RuntimeException("装货港 " + port + " 无法识别!");
+					}
+				} else {
+					// throw new RuntimeException("装货港不能为空");
+				}
+			} else if (val0.equals("POD")) {
+				String port = getSheetCellValueAsString(sheet, r, 1);
+				System.out.println("pod:" + port);
+				if (ObjectUtils.isNotNull(port)) {
+					BPorts ports = bPortsService.getOne(new LambdaQueryWrapper<BPorts>()
+						.eq(BPorts::getTenantId, AuthUtil.getTenantId())
+						.eq(BPorts::getIsDeleted, 0)
+						.like(BPorts::getEnName, port)
+						.last("limit 1"));
+					if (ports != null) {
+						bills.setPodId(ports.getId());
+						bills.setPodCode(ports.getCode());
+						bills.setPodCnName(ports.getCnName());
+						bills.setPodEnName(ports.getEnName());
+						bills.setPodNamePrint(ports.getEnName());
+					}else {
+						throw new RuntimeException("卸货港 " + port + " 无法识别!");
+					}
+				} else {
+					// throw new RuntimeException("卸货港不能为空");
 				}
-			}
-			System.out.println("por:" + por);
 
-		} else {
-			throw new RuntimeException("收货地不能为空");
-		}
-		//POL
-		if (ObjectUtils.isNotNull(sheet.getRow(19).getCell(4))) {
-			String pol = getSheetCellValueAsString(sheet, 19, 4);
-			if (ObjectUtils.isNotNull(pol)) {
-				BPorts ports = bPortsService.getOne(new LambdaQueryWrapper<BPorts>()
-					.eq(BPorts::getTenantId, AuthUtil.getTenantId())
-					.eq(BPorts::getIsDeleted, 0)
-					.like(BPorts::getEnName, pol)
-					.last("limit 1"));
-				if (ports != null) {
-					bills.setPolId(ports.getId());
-					bills.setPolCode(ports.getCode());
-					bills.setPolCnName(ports.getCnName());
-					bills.setPolEnName(ports.getEnName());
-					bills.setPolNamePrint(ports.getEnName());
+				port = getSheetCellValueAsString(sheet, r, 4);
+				System.out.println("place Of Delivery:" + port);
+				if (ObjectUtils.isNotNull(port)) {
+					BPorts ports = bPortsService.getOne(new LambdaQueryWrapper<BPorts>()
+						.eq(BPorts::getTenantId, AuthUtil.getTenantId())
+						.eq(BPorts::getIsDeleted, 0)
+						.like(BPorts::getEnName, port)
+						.last("limit 1"));
+					if (ports != null) {
+						bills.setPlaceDeliveryId(ports.getId());
+						bills.setPlaceDeliveryCode(ports.getCode());
+						bills.setPlaceDeliveryName(ports.getEnName());
+						bills.setPlaceDeliveryNamePrint(ports.getEnName());
+					}else {
+						throw new RuntimeException("交货地 " + port + " 无法识别!");
+					}
+				} else {
+					// throw new RuntimeException("交货地不能为空");
 				}
-			}
-			System.out.println("pol:" + pol);
-		} else {
-			throw new RuntimeException("装运港不能为空");
-		}
-		//POD
-		if (ObjectUtils.isNotNull(sheet.getRow(20).getCell(1))) {
-			String pod = getSheetCellValueAsString(sheet, 20, 1);
-			if (ObjectUtils.isNotNull(pod)) {
-				BPorts ports = bPortsService.getOne(new LambdaQueryWrapper<BPorts>()
-					.eq(BPorts::getTenantId, AuthUtil.getTenantId())
-					.eq(BPorts::getIsDeleted, 0)
-					.like(BPorts::getEnName, pod)
-					.last("limit 1"));
-				if (ports != null) {
-					bills.setPodId(ports.getId());
-					bills.setPodCode(ports.getCode());
-					bills.setPodCnName(ports.getCnName());
-					bills.setPodEnName(ports.getEnName());
-					bills.setPodNamePrint(ports.getEnName());
+			} else if (val0.equals("KINDOFB/L")) {
+				String s1 = getSheetCellValueAsString(sheet, r, 1);
+				System.out.println("kindOfBl:" + s1);
+				if (ObjectUtils.isNotNull(s1)) {
+					// 正本 ORI
+					// 电放 TER
+					// SWB EXP WAYBILL
+					bills.setIssueType("WAYBILL".equals(s1) ? "EXP" : ("电放".equals(s1) ? "TER" : "ORI"));
+				} else {
+					// throw new RuntimeException("签单方式不能为空");
 				}
-			}
-			System.out.println("pod:" + pod);
-		} else {
-			throw new RuntimeException("卸货港不能为空");
-		}
-		//PLACE OF DELIVERY
-		if (ObjectUtils.isNotNull(sheet.getRow(20).getCell(4))) {
-			String placeOfDelivery = getSheetCellValueAsString(sheet, 20, 4);
-			if (ObjectUtils.isNotNull(placeOfDelivery)) {
-				BPorts ports = bPortsService.getOne(new LambdaQueryWrapper<BPorts>()
-					.eq(BPorts::getTenantId, AuthUtil.getTenantId())
-					.eq(BPorts::getIsDeleted, 0)
-					.like(BPorts::getEnName, placeOfDelivery)
-					.last("limit 1"));
-				if (ports != null) {
-					bills.setPlaceDeliveryId(ports.getId());
-					bills.setPlaceDeliveryCode(ports.getCode());
-					bills.setPlaceDeliveryName(ports.getEnName());
-					bills.setPlaceDeliveryNamePrint(ports.getEnName());
+
+				s1 = getSheetCellValueAsString(sheet, r, 4);
+				System.out.println("PAYMODE:" + s1);
+				if(s1.indexOf("PREPAID")>=0){
+					bills.setHpaymode("PP");
 				}
-			}
-			System.out.println("placeOfDelivery:" + placeOfDelivery);
-		} else {
-			throw new RuntimeException("目的港不能为空");
-		}
-		//KIND OF B/L
-		if (ObjectUtils.isNotNull(sheet.getRow(21).getCell(1))) {
-			String kindOfBl = getSheetCellValueAsString(sheet, 21, 1);
-			System.out.println("kindOfBl:" + kindOfBl);
-			bills.setIssueType(kindOfBl);
-		} else {
-			throw new RuntimeException("签单方式不能为空");
-		}
-		//PLACE OF ISSUE
-		if (ObjectUtils.isNotNull(sheet.getRow(22).getCell(1))) {
-			String placeOfIssue = getSheetCellValueAsString(sheet, 22, 1);
-			System.out.println("placeOfIssue:" + placeOfIssue);
-			bills.setIssueAt(placeOfIssue);
-		} else {
-			throw new RuntimeException("签单地不能为空");
-		}
-		//FREIGHT PAYABLE AT
-		if (ObjectUtils.isNotNull(sheet.getRow(22).getCell(4))) {
-			String freightPayAbleAt = getSheetCellValueAsString(sheet, 22, 4);
-			System.out.println("freightPayAbleAt:" + freightPayAbleAt);
-			bills.setHpayplace(freightPayAbleAt);
-		} else {
-			throw new RuntimeException("付费地不能为空");
-		}
-		//MARKS
-		StringBuilder marks = new StringBuilder();
-		for (int i = 25; i <= 46; i++) {
-			if (ObjectUtils.isNotNull(sheet.getRow(i).getCell(0))) {
-				marks.append(getSheetCellValueAsString(sheet, i, 0) + "\r\n");
-			}
-		}
-		if (stringBuilderIsNotEmpty(marks)) {
-			System.out.println("marks:" + marks);
-			bills.setMarks(marks.toString().trim());
-		} else {
-			throw new RuntimeException("唛头不能为空");
-		}
-		//BAGS
-		if (ObjectUtils.isNotNull(sheet.getRow(25).getCell(1))) {
-			double bags = getSheetCellValueAsNumericPrefix(sheet, 25, 1);
-			System.out.println("bags:" + bags);
-			bills.setQuantity(new BigDecimal(bags).setScale(0, RoundingMode.HALF_UP));
-		} else {
-			throw new RuntimeException("件数不能为空");
-		}
-		//DESCRIPTION
-		StringBuilder description = new StringBuilder();
-		for (int i = 25; i <= 46; i++) {
-			if (ObjectUtils.isNotNull(sheet.getRow(i).getCell(2))) {
-				description.append(getSheetCellValueAsString(sheet, i, 2) + "\r\n");
-			}
-		}
-		if (stringBuilderIsNotEmpty(description)) {
-			System.out.println("description:" + description);
-			bills.setCommodityDescr(description.toString());
-		} else {
-			throw new RuntimeException("提单上货物描述不能为空");
-		}
-		//G.W.
-		if (ObjectUtils.isNotNull(sheet.getRow(25).getCell(4))) {
-			double gw = getSheetCellValueAsNumericPrefix(sheet, 25, 4);
-			System.out.println("gw:" + gw);
-			bills.setGrossWeight(new BigDecimal(gw).setScale(3, RoundingMode.HALF_UP));
-		} else {
-			throw new RuntimeException("毛重不能为空");
-		}
-		//MEAS
-		if (ObjectUtils.isNotNull(sheet.getRow(25).getCell(6))) {
-			double meas = getSheetCellValueAsNumericPrefix(sheet, 25, 6);
-			System.out.println("meas:" + meas);
-			bills.setMeasurement(new BigDecimal(meas).setScale(3, RoundingMode.HALF_UP));
-		} else {
-			throw new RuntimeException("体积不能为空");
-		}
-		//REMARK
-		StringBuilder remark = new StringBuilder();
-		for (int i = 47; i <= 50; i++) {
-			if (ObjectUtils.isNotNull(sheet.getRow(i).getCell(1))) {
-				remark.append(getSheetCellValueAsString(sheet, i, 1) + "\r\n");
-			}
-		}
-		if (stringBuilderIsNotEmpty(remark)) {
-			System.out.println("remark:" + remark);
-			bills.setRemarks(remark.toString().trim());
-		}
-		//FINAL DESTINATION FOR THE MERCHANT’S REFERENCE
-		if (ObjectUtils.isNotNull(sheet.getRow(51).getCell(4))) {
-			String finalDestination = getSheetCellValueAsString(sheet, 51,4);
-			if (ObjectUtils.isNotNull(finalDestination)) {
-				BPorts ports = bPortsService.getOne(new LambdaQueryWrapper<BPorts>()
-					.eq(BPorts::getTenantId, AuthUtil.getTenantId())
-					.eq(BPorts::getIsDeleted, 0)
-					.eq(BPorts::getEnName, finalDestination)
-					.last("limit 1"));
-				if (ports != null) {
-					bills.setFinalDestinationId(ports.getId());
-					bills.setFinalDestinationCode(ports.getCode());
-					bills.setFinalDestinationName(ports.getEnName());
-					bills.setFinalDestinationNamePrint(ports.getEnName());
+				if(s1.indexOf("COLLECT")>=0){
+					bills.setHpaymode("CC");
+				}
+			} else if (val0.equals("PLACEOFISSUE")) {
+				String port = getSheetCellValueAsString(sheet, r, 1);
+				System.out.println("Issue At:" + port);
+				if (ObjectUtils.isNotNull(port)) {
+					BPorts ports = bPortsService.getOne(new LambdaQueryWrapper<BPorts>()
+						.eq(BPorts::getTenantId, AuthUtil.getTenantId())
+						.eq(BPorts::getIsDeleted, 0)
+						.like(BPorts::getEnName, port)
+						.last("limit 1"));
+					if (ports != null) {
+						bills.setIssueAtId(ports.getId());
+						bills.setIssueAt(ports.getEnName());
+					}else {
+						throw new RuntimeException("签单地点 " + port + " 无法识别!");
+					}
 				}
+
+				port = getSheetCellValueAsString(sheet, r, 4);
+				System.out.println("FREIGHT PAYABLE AT:" + port);
+				if (ObjectUtils.isNotNull(port)) {
+					bills.setHpayplace(port);
+				}
+			} else if (val0.equals("CONTRACTNO")) {
+				String s1 = getSheetCellValueAsString(sheet, r, 1);
+				System.out.println("Contract No:" + s1);
+				bills.setCarrierArgreementNo(ObjectUtils.isNotNull(s1) ? s1 : "");
+
+				s1 = getSheetCellValueAsString(sheet, r, 4);
+				System.out.println("Volume:" + s1);
+			} else if (val0.equals("MARKS")) {
+				// MARKS
+				int remarkLn = 0;
+				sbLines.setLength(0);
+				for (int l = r + 1; l<=lastRow; l++) {
+					String s1 = getSheetCellValueAsString(sheet, l, 0);
+					if("REMARK".equals(s1.trim())){
+						if (stringBuilderIsNotEmpty(sbLines)) {
+							System.out.println("marks:" + sbLines);
+							bills.setMarks(sbLines.toString().trim());
+						}
+
+						remarkLn = l;
+						break;
+					}else{
+						sbLines.append(s1.concat("\r\n"));
+					}
+				}
+
+				// BAGS
+				// double bags = getSheetCellValueAsNumericPrefix(sheet, r + 1, 1);
+				// System.out.println("bags:" + bags);
+
+				Map<String, Object> pkgs = getSheetCellValueAsNumericPrefixMap(sheet, r + 1, 1);
+				String kindPkgs = pkgs.get("str").toString();
+				if(ObjectUtils.isNull(kindPkgs)) {
+					kindPkgs = getSheetCellValueAsString(sheet, r, 1);
+				}
+				if(ObjectUtils.isNotNull(kindPkgs)) {
+					BPackages bPackages = bPackagesService.getOne(new LambdaQueryWrapper<BPackages>()
+						.eq(BPackages::getEnName, kindPkgs));
+					if (bPackages != null) {
+						bills.setPackingUnitId(bPackages.getId());
+						bills.setPackingUnit(bPackages.getEnName());
+					}
+				}
+
+				bills.setQuantity(new BigDecimal(String.valueOf(pkgs.get("value"))).setScale(0, RoundingMode.HALF_UP));
+
+				//G.W.
+				double gw = getSheetCellValueAsNumericPrefix(sheet, r + 1, 4);
+				System.out.println("gw:" + gw);
+				bills.setGrossWeight(new BigDecimal(gw).setScale(3, RoundingMode.HALF_UP));
+
+				//MEAS
+				double meas = getSheetCellValueAsNumericPrefix(sheet, r + 1, 6);
+				System.out.println("meas:" + meas);
+				bills.setMeasurement(new BigDecimal(meas).setScale(3, RoundingMode.HALF_UP));
+
+				if(remarkLn>0) {
+					// DESCRIPTION
+					sbLines.setLength(0);
+					for (int l = r + 1; l<remarkLn; l++) {
+						String s1 = getSheetCellValueAsString(sheet, l, 2);
+						sbLines.append(s1.concat("\r\n"));
+					}
+					System.out.println("description:" + sbLines);
+					bills.setCommodityDescr(sbLines.toString().trim());
+
+					sbLines.setLength(0);
+					for (int l = remarkLn; l<=lastRow; l++) {
+						String s1 = getSheetCellValueAsString(sheet, l, 0);
+						if(s1.isEmpty() || "REMARK".equals(s1)){
+							sbLines.append(getSheetCellValueAsString(sheet, l, 1).concat("\r\n"));
+						}else if("FINAL DESTINATION FOR THE MERCHANT’S REFERENCE".equals(s1)){
+							String port = getSheetCellValueAsString(sheet, l, 4);
+							System.out.println("finalDestination:" + port);
+							if (ObjectUtils.isNotNull(port)) {
+								BPorts ports = bPortsService.getOne(new LambdaQueryWrapper<BPorts>()
+									.eq(BPorts::getTenantId, AuthUtil.getTenantId())
+									.eq(BPorts::getIsDeleted, 0)
+									.like(BPorts::getEnName, port)
+									.last("limit 1"));
+								if (ports != null) {
+									bills.setFinalDestinationId(ports.getId());
+									bills.setFinalDestinationCode(ports.getCode());
+									bills.setFinalDestinationName(ports.getEnName());
+									bills.setFinalDestinationNamePrint(ports.getEnName());
+								}else {
+									throw new RuntimeException("最终目的地 " + port + " 无法识别!");
+								}
+							}
+						}
+					}
+					System.out.println("REMARK:" + sbLines);
+					bills.setBookingRemarks(sbLines.toString().trim());
+				}
+
+				break;
 			}
-			System.out.println("finalDestination:" + finalDestination);
 		}
 
 		bills.setContainersList(new ArrayList<>());

+ 158 - 174
blade-service/blade-los/src/main/java/org/springblade/los/edi/service/impl/EDISenderServiceImpl.java

@@ -5894,7 +5894,7 @@ public class EDISenderServiceImpl implements IEDISenderService {
 			List<String> goodsDesc = RegularUtils.reformatEDIText(hmmSiDto.getGoodsDesc(), 70, true);
 			int descrLineCount = goodsDesc.size();
 			for (int l = 0; l < descrLineCount; l++) {
-				String line = goodsMarks.get(l);
+				String line = goodsDesc.get(l);
 				if(line.trim().isEmpty()){
 					line=".";
 				}
@@ -7053,7 +7053,7 @@ public class EDISenderServiceImpl implements IEDISenderService {
 			// 向文件写入数据
 			// 00 HEAD RECORD
 			// 2=增加  3=删除 4=变更  9=原始
-			writer.write("00:IFTMBF:BOOKING:9:" + voltaSoDto.getSenderCode() + ":HMM:" + voltaSoDto.getFileDate() + "'");
+			writer.write("00:IFTMBF:BOOKING:9:" + voltaSoDto.getSenderCode() + ":VOL:" + voltaSoDto.getFileDate() + "'");
 			writer.newLine();
 			count++;
 
@@ -7063,7 +7063,7 @@ public class EDISenderServiceImpl implements IEDISenderService {
 			// 运编号
 			writer.write(":" + voltaSoDto.getMblNo());
 			// 提单号
-			writer.write(":" + voltaSoDto.getMblNo());
+			writer.write(":" + voltaSoDto.getBookingNo());
 			// 交货条款 CY-CY(pier-pier/port):30
 			//CY-CFS(pier/port-door): 29
 			//CFS-CY(door-pier/port): 28
@@ -7072,29 +7072,33 @@ public class EDISenderServiceImpl implements IEDISenderService {
 			// 货代方企业名称
 			writer.write(":" + voltaSoDto.getSenderCode());
 			// 即接受订舱的人的代码 + 签单人说明 + 询价单位 + 国外订舱单位 + 转船标识 + 分批 + 装期 + 效期 + 运费协议号 + 费率本代码 + 服务合同号 + BOND NO + 舱位互用标识
-			writer.write(":HMM::::::::" + voltaSoDto.getCarrierArgreementNo() + "::"+voltaSoDto.getCorpArgreementNo()+"::'");
+			String s1 = ObjectUtils.isNotNull(voltaSoDto.getCarrierArgreementNo()) ? voltaSoDto.getCarrierArgreementNo() : voltaSoDto.getSenderCode();
+			writer.write(":VOL::::::::" + s1 + "::"+voltaSoDto.getCorpArgreementNo()+"::'");
 			writer.newLine();
 			count++;
 
 			// 03 提单信息,不填
 			// 提单类型(ORI: BILL OF LADING EXP: WAYBILL) + 提单签发地代码 + 提单签发地 + 签发日期 + 正本提单份数 + 预付地点 + 到付地点
 			writer.write("03:::" + voltaSoDto.getIssuanceLand() + ":" + voltaSoDto.getIssueDate() + ":3:"
-				+ ("PP".equals(voltaSoDto.getMPayMode()) ? voltaSoDto.getMPayPlaceName() : "")
+				+ ("PP".equals(voltaSoDto.getMPayMode()) ? voltaSoDto.getMPayPlaceName() : "") + ":"
 				+ ("CC".equals(voltaSoDto.getMPayMode()) ? voltaSoDto.getMPayPlaceName() : ""));
 			// AMS Ams Tag AmsCode
 			// V_AMSPROP	IF(AMSPROP='Y','Y',IF(AMSPROP='N','N',IF(AMSPROP='1',' ','')))
-			writer.write(":");
+			s1 = "Y".equals(voltaSoDto.getAMSProp()) ? "Y" : ("N".equals(voltaSoDto.getAMSProp()) ? "N" : ("1".equals(voltaSoDto.getAMSProp()) ? " " : ""));
+			writer.write(":" + s1);
 
 			// ACI Canada Aci
 			// V_ACIPROP	IF(ACIPROP='Y','Y',IF(ACIPROP='N','N',IF(ACIPROP='1',' ','')))
 			// ACI NO VarChar(35)
-			writer.write("::'");
+			s1 = "Y".equals(voltaSoDto.getACIProp()) ? "Y" : ("N".equals(voltaSoDto.getACIProp()) ? "N" : ("1".equals(voltaSoDto.getACIProp()) ? " " : ""));
+			writer.write(":" + s1 + "'");
 			writer.newLine();
 			count++;
 
 			// 11 VESSEL 船舶信息
 			// 记录类型标识 + 船舶呼号 +  船名 + 航次 + 船舶经营人
-			writer.write("11:::::::::::"+voltaSoDto.getVesselCode()+":"+voltaSoDto.getVesselName()+":"+voltaSoDto.getVoyageNo()+"'");
+			// writer.write("11:::::::::::"+voltaSoDto.getVesselCode()+":"+voltaSoDto.getVesselName()+":"+voltaSoDto.getVoyageNo()+"'");
+			writer.write("11::"+voltaSoDto.getVesselName()+":"+voltaSoDto.getVoyageNo()+":VOL::::" + voltaSoDto.getEtd()+":::::'");
 			writer.newLine();
 			count++;
 
@@ -7110,8 +7114,9 @@ public class EDISenderServiceImpl implements IEDISenderService {
 			writer.write(":" + voltaSoDto.getPotCode() + ":" + voltaSoDto.getPotName());
 			// 交货地代码  + 交货地
 			writer.write(":" + voltaSoDto.getPlaceDeliveryCode() + ":" + voltaSoDto.getPlaceDeliveryName());
-			// 目的地代码  + 目的地
-			writer.write(":" + voltaSoDto.getPlaceDestinationCode() + ":" + voltaSoDto.getPlaceDestinationName() + "'");
+			// 目的地代码  + 目的地 不填
+			// writer.write(":" + voltaSoDto.getPlaceDestinationCode() + ":" + voltaSoDto.getPlaceDestinationName() + "'");
+			// writer.write("::'");
 			writer.newLine();
 			count++;
 
@@ -7122,8 +7127,10 @@ public class EDISenderServiceImpl implements IEDISenderService {
 			writer.newLine();
 			count++;
 
+			// wfg 2025-04-16
+
 			// 15 运费及费用项目
-			writer.write("15::NONE:" + pmc + "'");
+			writer.write("15:::" + pmc + "'");
 			writer.newLine();
 			count++;
 
@@ -7134,34 +7141,63 @@ public class EDISenderServiceImpl implements IEDISenderService {
 			String IEIEC = ObjectUtils.isNotNull(voltaSoDto.getEdiIeiec()) ? voltaSoDto.getEdiIeiec().trim() : "";
 			List<String> bookingRemarks = RegularUtils.reformatEDIText(voltaSoDto.getBookingRemarks(), 35, true);
 			if (bookingRemarks.size()>0 || !IEIEC.isEmpty()) {
+				int lc = 0;
 				writer.write("17"); // 发货人代码为空
 				if(IEIEC.isEmpty()) {
-					int lc = 0;
 					for (int l = 0; l < bookingRemarks.size(); l++) {
 						String line = bookingRemarks.get(l);
 						if (line.trim().isEmpty()) {
 							line = ".";
 						}
-						lc++;
 						if (l <= 5) {
 							writer.write(":" + line);
+							lc++;
 						} else {
 							bookingRemarksAddtion.add(line);
 						}
 					}
 				}else{
-					writer.write(":" + IEIEC);
-					if(ObjectUtils.isNotNull(voltaSoDto.getEdiIegstin())){
-						writer.write(":" + voltaSoDto.getEdiIegstin());
-					}
-					if(ObjectUtils.isNotNull(voltaSoDto.getEdiIemail())){
-						writer.write(":" + RegularUtils.escapeEDILine(voltaSoDto.getEdiIemail()));
+					if(bookingRemarks.size()==0) {
+						writer.write(":" + IEIEC);
+						if (ObjectUtils.isNotNull(voltaSoDto.getEdiIegstin())) {
+							writer.write(":" + voltaSoDto.getEdiIegstin());
+							lc++;
+						}
+						if (ObjectUtils.isNotNull(voltaSoDto.getEdiIemail())) {
+							writer.write(":" + RegularUtils.escapeEDILine(voltaSoDto.getEdiIemail()));
+							lc++;
+						}
+					}else{
+						for (int l = 0; l < bookingRemarks.size(); l++) {
+							String line = bookingRemarks.get(l);
+							if (line.trim().isEmpty()) {
+								line = ".";
+							}
+							if (l <= 5) {
+								writer.write(":" + line);
+								lc++;
+							} else {
+								bookingRemarksAddtion.add(line);
+							}
+						}
+
+						writer.write(":" + IEIEC);
+						if (ObjectUtils.isNotNull(voltaSoDto.getEdiIegstin())) {
+							writer.write(":" + voltaSoDto.getEdiIegstin());
+							lc++;
+						}
+						if (ObjectUtils.isNotNull(voltaSoDto.getEdiIemail())) {
+							writer.write(":" + RegularUtils.escapeEDILine(voltaSoDto.getEdiIemail()));
+							lc++;
+						}
 					}
 				}
 
-				writer.write("'");
-				writer.newLine();
-				count++;
+				if(lc>0) {
+					writer.write("'");
+					writer.newLine();
+					count++;
+				}
 			}
 
 			// 20	SHIPPER 发货人
@@ -7169,10 +7205,10 @@ public class EDISenderServiceImpl implements IEDISenderService {
 			List<String> goodsDescAddtion = new ArrayList<>();
 			// 发货人
 			String shpr = ObjectUtils.isNull(voltaSoDto.getMShipper()) ? voltaSoDto.getHShipper() : voltaSoDto.getMShipper();
-			List<String> hShipper = RegularUtils.reformatEDIText(shpr, 35, true);
+			List<String> hShipper = RegularUtils.reformatEDIText(shpr, 65, true);
 			writer.write("20:"); // 发货人代码为空
 			for (int l = 0; l < hShipper.size(); l++) {
-				if (l < 5) {
+				if (l < 6) {
 					writer.write(":" + hShipper.get(l));
 				} else {
 					goodsDescAddtion.add("*" + hShipper.get(l));
@@ -7184,10 +7220,10 @@ public class EDISenderServiceImpl implements IEDISenderService {
 
 			// 21	CONSIGNEE 收货人
 			String cnee = ObjectUtils.isNull(voltaSoDto.getMConsignee()) ? voltaSoDto.getHConsignee() : voltaSoDto.getMConsignee();
-			List<String> hConsignee = RegularUtils.reformatEDIText(cnee, 35, true);
+			List<String> hConsignee = RegularUtils.reformatEDIText(cnee, 65, true);
 			writer.write("21:"); // 收货人代码为空
 			for (int l = 0; l < hConsignee.size(); l++) {
-				if (l < 5) {
+				if (l < 6) {
 					writer.write(":" + hConsignee.get(l));
 				} else {
 					goodsDescAddtion.add("**" + hConsignee.get(l));
@@ -7199,10 +7235,10 @@ public class EDISenderServiceImpl implements IEDISenderService {
 
 			// 22	NOTIFY PARTY 通知人
 			String notify = ObjectUtils.isNull(voltaSoDto.getMNotify()) ? voltaSoDto.getHNotify() : voltaSoDto.getMNotify();
-			List<String> hNotify = RegularUtils.reformatEDIText(notify, 35, true);
+			List<String> hNotify = RegularUtils.reformatEDIText(notify, 65, true);
 			writer.write("22:"); // 通知人代码为空
 			for (int l = 0; l < hNotify.size(); l++) {
-				if (l < 5) {
+				if (l < 6) {
 					writer.write(":" + hNotify.get(l));
 				} else {
 					goodsDescAddtion.add("***" + hNotify.get(l));
@@ -7217,11 +7253,11 @@ public class EDISenderServiceImpl implements IEDISenderService {
 			// 2) CARGO ID (货物标识)的填法: S=普通,  R=冷冻,   D=危险 ,  O=非标
 			// 41:1::S:8378:CT:CARTONS:20559:138.8::::::20559'
 			// 记录类型标识 + 货物序号 + 货类代码 + 货物标识
-			writer.write("41:1::" + ("danger".equals(cargoType) ? "D" : ("reefer".equals(cargoType) ? "R" : "S")));
+			writer.write("41:1:" + voltaSoDto.getHsCode() + ":" + ("danger".equals(cargoType) ? "D" : ("reefer".equals(cargoType) ? "R" : "S")));
 			// 第一层包装件数 + 第一层包装类型 + 第一层包装说明
 			writer.write(":" + voltaSoDto.getPackagesNumber() + ":" + voltaSoDto.getPackagesCode() + ":" + voltaSoDto.getPackagesDescribe());
 			// 第一层包装皮重 + 第一层包装尺码
-			writer.write(":" + voltaSoDto.getGrossWeight().setScale(0, BigDecimal.ROUND_HALF_UP));
+			writer.write(":" + voltaSoDto.getGrossWeight().setScale(1, BigDecimal.ROUND_HALF_UP));
 			writer.write(":" + voltaSoDto.getVolumeOfGoods().setScale(3, BigDecimal.ROUND_HALF_UP));
 			// 第二层包装件数 + 第二层包装类型 + 第二层包装说明 + 第二层包装皮重 + 第二层包装尺码 + 货毛重
 			writer.write("::::::" + voltaSoDto.getGrossWeight().setScale(2, BigDecimal.ROUND_HALF_UP) + "'");
@@ -7230,7 +7266,7 @@ public class EDISenderServiceImpl implements IEDISenderService {
 
 			// 43 DANGEROUS, REEFER & OOG 危险品,冷藏和超标信息
 			// 温度中,除正(+)负(-)号及小数点外,最多只能三位数字。
-			if (ObjectUtils.isNotNull(voltaSoDto.getPreCntrs())) {
+			if (("danger".equals(cargoType) || "reefer".equals(cargoType)) && ObjectUtils.isNotNull(voltaSoDto.getPreCntrs())) {
 				List<Map<String, Object>> mapList = voltaSoDto.getPreCntrs();
 				if (mapList.size() > 0) {
 					Map<String, Object> map = mapList.get(0);
@@ -7240,14 +7276,16 @@ public class EDISenderServiceImpl implements IEDISenderService {
 						throw new SecurityException("温度和通风度必须同时填写!");
 					}
 
-					writer.write("43:"+voltaSoDto.getDgImdgCode()+"::"+voltaSoDto.getDgUnCode()+":::::::" + map.get("ventilation") + ":"+(ObjectUtils.isNotNull(map.get("temperature"))?"C":"")+":" + map.get("temperature") + ":::::::'");
+					writer.write("43:"+voltaSoDto.getDgImdgCode()+"::"+voltaSoDto.getDgUnCode()+"::::::"+voltaSoDto.getDgContacts());
+					writer.write(":" + map.get("ventilation") + ":"+(ObjectUtils.isNotNull(map.get("temperature"))?"C":""));
+					writer.write(":" + map.get("temperature") + ":::::::'");
 					writer.newLine();
 					count += 1;
 				}
 			}
 
 			// 44	MARKS & NOS. 唛头 1-10 行
-			List<String> goodsMarks = RegularUtils.reformatEDIText(voltaSoDto.getMarks(), 47, true);
+			List<String> goodsMarks = RegularUtils.reformatEDIText(voltaSoDto.getMarks(), 32, true);
 			List<String> goodsMarksAddtion = new ArrayList<>();
 			writer.write("44");
 			for (int l = 0; l < goodsMarks.size(); l++) {
@@ -7294,9 +7332,11 @@ public class EDISenderServiceImpl implements IEDISenderService {
 			}
 
 			// 90 订舱人联系信息
+			/*
 			writer.write("90:QJM:QINGDAO JMS-LOGISTICS SERVICE CO.,LTD.::Miya Wang:0086-532-82668811-216:0086-532-82668660-216:hmm-seataocn@jms-logistics.com'");
 			writer.newLine();
 			count += 1;
+			*/
 
 			// 99 TRAILER RECORD              尾记录
 			// RECORD TOTAL OF FILE   记录总数	9(6)	包括:头、尾记录
@@ -7327,7 +7367,7 @@ public class EDISenderServiceImpl implements IEDISenderService {
 			// 向文件写入数据
 			// 00 HEAD RECORD
 			// 2=增加  3=删除 4=变更  9=原始
-			writer.write("00:IFTMIN:shipping request:9:" + voltaSiDto.getSenderCode() + ":HMM:" + voltaSiDto.getFileDate() + "'");
+			writer.write("00:IFTMIN:BOOKING:9:" + voltaSiDto.getSenderCode() + ":VOL:" + voltaSiDto.getFileDate() + "'");
 			writer.newLine();
 			count++;
 
@@ -7335,9 +7375,9 @@ public class EDISenderServiceImpl implements IEDISenderService {
 			// 记录类型标识
 			writer.write("02");
 			// 运编号
-			writer.write(":" + (ObjectUtils.isNotNull(voltaSiDto.getBookingNo()) ? voltaSiDto.getBookingNo() : voltaSiDto.getMblNo()));
-			// 提单号
 			writer.write(":" + voltaSiDto.getMblNo());
+			// 提单号
+			writer.write(":" + voltaSiDto.getBookingNo());
 			// 交货条款 CY-CY(pier-pier/port):30
 			//CY-CFS(pier/port-door): 29
 			//CFS-CY(door-pier/port): 28
@@ -7346,30 +7386,35 @@ public class EDISenderServiceImpl implements IEDISenderService {
 			// 货代方企业名称
 			writer.write(":" + voltaSiDto.getSenderCode());
 			// 即接受订舱的人的代码 + 签单人说明 + 询价单位 + 国外订舱单位 + 转船标识 + 分批 + 装期 + 效期 + 运费协议号 + 费率本代码 + 服务合同号 + BOND NO + 舱位互用标识
-			writer.write(":HMM::::::::::"+voltaSiDto.getCarrierArgreementNo()+"::'");
+			writer.write(":VOL::::::::"+voltaSiDto.getCarrierArgreementNo()+":::"+voltaSiDto.getMblNo()+":");
+			writer.write(":" + voltaSiDto.getSenderEmail());
+			writer.write(":" + voltaSiDto.getSenderContacts());
+			writer.write(":" + voltaSiDto.getSenderTel() + "'");
 			writer.newLine();
 			count++;
 
 			// 03 提单信息,不填
-			// 提单类型(ORI: BILL OF LADING EXP: WAYBILL) + 提单签发地代码 + 提单签发地 + 签发日期 + 正本提单份数 + 预付地点 + 到付地点
-			String issueType = "ORI".equals(voltaSiDto.getIssueType()) || "EXP".equals(voltaSiDto.getIssueType()) ? voltaSiDto.getIssueType() : "";
-			writer.write("03:"+issueType+"::" + voltaSiDto.getIssuanceLand() + ":" + voltaSiDto.getIssueDate() + ":3:"
+			// 提单类型(ORI: BILL OF LADING EXP: WAYBILL TER: 电放) + 提单签发地代码 + 提单签发地 + 签发日期 + 正本提单份数 + 预付地点 + 到付地点
+			String issueType = voltaSiDto.getIssueType();
+			writer.write("03:"+issueType+":"+voltaSiDto.getIssuanceLandCode()+":" + voltaSiDto.getIssuanceLand() + ":" + voltaSiDto.getIssueDate() + ":3:"
 				+ ("PP".equals(voltaSiDto.getMPayMode()) ? voltaSiDto.getMPayPlaceName() : "")
 				+ ("CC".equals(voltaSiDto.getMPayMode()) ? voltaSiDto.getMPayPlaceName() : ""));
 			// AMS Ams Tag AmsCode
 			// V_AMSPROP	IF(AMSPROP='Y','Y',IF(AMSPROP='N','N',IF(AMSPROP='1',' ','')))
-			writer.write(":");
+			String s1 = "Y".equals(voltaSiDto.getAMSProp()) ? "Y" : ("N".equals(voltaSiDto.getAMSProp()) ? "N" : ("1".equals(voltaSiDto.getAMSProp()) ? " " : ""));
+			writer.write(":" + s1);
 
 			// ACI Canada Aci
 			// V_ACIPROP	IF(ACIPROP='Y','Y',IF(ACIPROP='N','N',IF(ACIPROP='1',' ','')))
 			// ACI NO VarChar(35)
-			writer.write(":'");
+			s1 = "Y".equals(voltaSiDto.getACIProp()) ? "Y" : ("N".equals(voltaSiDto.getACIProp()) ? "N" : ("1".equals(voltaSiDto.getACIProp()) ? " " : ""));
+			writer.write(":"+s1+"'");
 			writer.newLine();
 			count++;
 
 			// 11 VESSEL 船舶信息
 			// 记录类型标识 + 船舶呼号 +  船名 + 航次 + 船舶经营人
-			writer.write("11:::::::::::"+voltaSiDto.getVesselCode()+":"+voltaSiDto.getVesselName()+":"+voltaSiDto.getVoyageNo()+"'");
+			writer.write("11::"+voltaSiDto.getVesselName()+":"+voltaSiDto.getVoyageNo()+":::VOL:::::::'");
 			writer.newLine();
 			count++;
 
@@ -7386,7 +7431,8 @@ public class EDISenderServiceImpl implements IEDISenderService {
 			// 交货地代码  + 交货地
 			writer.write(":" + voltaSiDto.getPlaceDeliveryCode() + ":" + voltaSiDto.getPlaceDeliveryName());
 			// 目的地代码  + 目的地
-			writer.write(":" + voltaSiDto.getPlaceDestinationCode() + ":" + voltaSiDto.getPlaceDestinationName() + "'");
+			// writer.write(":" + voltaSiDto.getPlaceDestinationCode() + ":" + voltaSiDto.getPlaceDestinationName() + "'");
+			writer.write("::'");
 			writer.newLine();
 			count++;
 
@@ -7398,59 +7444,29 @@ public class EDISenderServiceImpl implements IEDISenderService {
 			count++;
 
 			// 15 运费及费用项目
-			writer.write("15::NONE:" + pm + "'");
+			writer.write("15:::" + pm + "'");
 			writer.newLine();
 			count++;
 
 			// 17 REMARKS 订舱备注 其他信息
-			// 有订舱备注,填订舱备注,否则填 IEIEC
-			String IEIEC = ObjectUtils.isNotNull(voltaSiDto.getEdiIeiec()) ? voltaSiDto.getEdiIeiec().trim() : "";
-			String IEGSTIN = ObjectUtils.isNotNull(voltaSiDto.getEdiIegstin()) ? voltaSiDto.getEdiIegstin().trim() : "";
-			String IEMAIL = ObjectUtils.isNotNull(voltaSiDto.getEdiIemail()) ? voltaSiDto.getEdiIemail().trim() : "";
-			if(!IEIEC.isEmpty()){
-				writer.write("17:" + IEIEC + ":" + IEGSTIN +":" + IEMAIL + "'");
-				writer.newLine();
-				count++;
+			String[] buf = voltaSiDto.getSiRemarks().split("\n");
+			String remarksLn = "";
+			for (String item : buf) {
+				String ln = item.trim();
+				if(!ln.isEmpty()) {
+					remarksLn += ((remarksLn.isEmpty() ? "" : ":") + RegularUtils.escapeEDILine(ln));
+				}
 			}
-//			List<String> bookingRemarksAddtion = new ArrayList<>();
-//			List<String> bookingRemarks = RegularUtils.reformatEDIText(hmmSiDto.getBookingRemarks(), 35, true);
-//			if (bookingRemarks.size()>0 || !IEIEC.isEmpty()) {
-//				writer.write("17"); // 发货人代码为空
-//				if(IEIEC.isEmpty()) {
-//					int lc = 0;
-//					for (int l = 0; l < bookingRemarks.size(); l++) {
-//						String line = bookingRemarks.get(l);
-//						if (line.trim().isEmpty()) {
-//							line = ".";
-//						}
-//						lc++;
-//						if (l <= 5) {
-//							writer.write(":" + line);
-//						} else {
-//							bookingRemarksAddtion.add(line);
-//						}
-//					}
-//				}else{
-//					writer.write(":" + IEIEC);
-//					if(ObjectUtils.isNotNull(hmmSiDto.getEdiIegstin())){
-//						writer.write(":" + hmmSiDto.getEdiIegstin());
-//					}
-//					if(ObjectUtils.isNotNull(hmmSiDto.getEdiIemail())){
-//						writer.write(":" + RegularUtils.escapeEDILine(hmmSiDto.getEdiIemail()));
-//					}
-//				}
-//
-//				writer.write("'");
-//				writer.newLine();
-//				count++;
-//			}
+			writer.write("17:" + remarksLn + "'");
+			writer.newLine();
+			count++;
 
 			// 20	SHIPPER 发货人
 			// 处理收发通之前,先处理货描,因为收发通多余的部分要追加到货描
 			List<String> goodsDescAddtion = new ArrayList<>();
 			// 发货人
 			String shpr = ObjectUtils.isNull(voltaSiDto.getMShipper()) ? voltaSiDto.getHShipper() : voltaSiDto.getMShipper();
-			List<String> hShipper = RegularUtils.reformatEDIText(shpr, 35, true);
+			List<String> hShipper = RegularUtils.reformatEDIText(shpr, 50, true);
 			writer.write("20:"); // 发货人代码为空
 			for (int l = 0; l < hShipper.size(); l++) {
 				if (l < 5) {
@@ -7465,7 +7481,7 @@ public class EDISenderServiceImpl implements IEDISenderService {
 
 			// 21	CONSIGNEE 收货人
 			String cnee = ObjectUtils.isNull(voltaSiDto.getMConsignee()) ? voltaSiDto.getHConsignee() : voltaSiDto.getMConsignee();
-			List<String> hConsignee = RegularUtils.reformatEDIText(cnee, 35, true);
+			List<String> hConsignee = RegularUtils.reformatEDIText(cnee, 49, true);
 			writer.write("21:"); // 收货人代码为空
 			for (int l = 0; l < hConsignee.size(); l++) {
 				if (l < 5) {
@@ -7480,7 +7496,7 @@ public class EDISenderServiceImpl implements IEDISenderService {
 
 			// 22	NOTIFY PARTY 通知人
 			String notify = ObjectUtils.isNull(voltaSiDto.getMNotify()) ? voltaSiDto.getHNotify() : voltaSiDto.getMNotify();
-			List<String> hNotify = RegularUtils.reformatEDIText(notify, 35, true);
+			List<String> hNotify = RegularUtils.reformatEDIText(notify, 49, true);
 			writer.write("22:"); // 通知人代码为空
 			for (int l = 0; l < hNotify.size(); l++) {
 				if (l < 5) {
@@ -7494,30 +7510,30 @@ public class EDISenderServiceImpl implements IEDISenderService {
 			count += 1;
 
 			// 23	SEC NOTIFY PARTY 第二通知人
-			String notify2 = ObjectUtils.isNull(voltaSiDto.getMNotify2()) ? voltaSiDto.getHNotify2() : voltaSiDto.getMNotify2();
-			List<String> hNotify2 = RegularUtils.reformatEDIText(notify2, 35, true);
-			writer.write("23:"); // 通知人代码为空
-			for (int l = 0; l < hNotify2.size(); l++) {
-				if (l < 5) {
-					writer.write(":" + hNotify2.get(l));
-				} else {
-					goodsDescAddtion.add("****" + hNotify2.get(l));
-				}
-			}
-			writer.write("'");
-			writer.newLine();
-			count += 1;
+//			String notify2 = ObjectUtils.isNull(voltaSiDto.getMNotify2()) ? voltaSiDto.getHNotify2() : voltaSiDto.getMNotify2();
+//			List<String> hNotify2 = RegularUtils.reformatEDIText(notify2, 35, true);
+//			writer.write("23:"); // 通知人代码为空
+//			for (int l = 0; l < hNotify2.size(); l++) {
+//				if (l < 5) {
+//					writer.write(":" + hNotify2.get(l));
+//				} else {
+//					goodsDescAddtion.add("****" + hNotify2.get(l));
+//				}
+//			}
+//			writer.write("'");
+//			writer.newLine();
+//			count += 1;
 
 			// 41 CARGO OF BOOKING  订舱货物
 			// 注:1)货物有两种包装,如是大包装(如托盘),则必须同时填小包装件数和包装类型;
 			// 2) CARGO ID (货物标识)的填法: S=普通,  R=冷冻,   D=危险 ,  O=非标
 			// 41:1::S:8378:CT:CARTONS:20559:138.8::::::20559'
 			// 记录类型标识 + 货物序号 + 货类代码 + 货物标识
-			writer.write("41:1::" + ("danger".equals(cargoType) ? "D" : ("reefer".equals(cargoType) ? "R" : "S")));
+			writer.write("41:1:"+voltaSiDto.getHsCode()+":" + ("danger".equals(cargoType) ? "D" : ("reefer".equals(cargoType) ? "R" : "S")));
 			// 第一层包装件数 + 第一层包装类型 + 第一层包装说明
 			writer.write(":" + voltaSiDto.getPackagesNumber() + ":" + voltaSiDto.getPackagesCode() + ":" + voltaSiDto.getPackagesDescribe());
 			// 第一层包装皮重 + 第一层包装尺码
-			writer.write(":" + voltaSiDto.getGrossWeight().setScale(3, BigDecimal.ROUND_HALF_UP));
+			writer.write(":" + voltaSiDto.getGrossWeight().setScale(1, BigDecimal.ROUND_HALF_UP));
 			writer.write(":" + voltaSiDto.getVolumeOfGoods().setScale(3, BigDecimal.ROUND_HALF_UP));
 			// 第二层包装件数 + 第二层包装类型 + 第二层包装说明 + 第二层包装皮重 + 第二层包装尺码 + 货毛重
 			writer.write("::::::" + voltaSiDto.getGrossWeight().setScale(3, BigDecimal.ROUND_HALF_UP) + "'");
@@ -7526,6 +7542,7 @@ public class EDISenderServiceImpl implements IEDISenderService {
 
 			// 43 DANGEROUS, REEFER & OOG 危险品,冷藏和超标信息
 			// 温度中,除正(+)负(-)号及小数点外,最多只能三位数字。
+			String goodsDescText = voltaSiDto.getGoodsDesc();
 			if (ObjectUtils.isNotNull(voltaSiDto.getPreCntrs())) {
 				List<Map<String, Object>> mapList = voltaSiDto.getPreCntrs();
 				if (mapList.size() > 0) {
@@ -7536,25 +7553,35 @@ public class EDISenderServiceImpl implements IEDISenderService {
 						throw new SecurityException("温度和通风度必须同时填写!");
 					}
 
-					writer.write("43:"+voltaSiDto.getDgImdgCode()+"::"+voltaSiDto.getDgUnCode()+":::::::" + map.get("ventilation") + ":C:" + map.get("temperature") + "::::::::'");
-					writer.newLine();
-					count += 1;
+					if(!T.isEmpty()){
+						goodsDescText += "\nCARGO IS STOWED IN REEFER CONTAINER AT THE ";
+						goodsDescText += "\nSHIPPER'S REQUESTED CARRYING TEMP OF " + T + " 'C VENT: " + V + " CBM/H";
+					}
+
+//					writer.write("43:"+voltaSiDto.getDgImdgCode()+"::"+voltaSiDto.getDgUnCode()+":::::::" + map.get("ventilation") + ":C:" + map.get("temperature") + "::::::::'");
+//					writer.newLine();
+//					count += 1;
 				}
 			}
 
 			// 44	MARKS & NOS. 唛头 12 节
-			List<String> goodsMarks = RegularUtils.reformatEDIText(voltaSiDto.getMarks(), 35, true);
+			List<String> goodsMarks = RegularUtils.reformatEDIText(voltaSiDto.getMarks(), 25, true);
 			int marksLineCount = goodsMarks.size();
 			for (int l = 0; l < marksLineCount; l++) {
 				String line = goodsMarks.get(l);
 				if(line.trim().isEmpty()){
 					line=".";
 				}
-				if((l % 9)==0){
+				if((l % 10)==0){
+					if(l>0){
+						writer.write("'");
+						writer.newLine();
+						count += 1;
+					}
 					writer.write("44");
 				}
 				writer.write(":" + line);
-				if((l % 9)==8 || l==(marksLineCount - 1)){
+				if(l==(marksLineCount - 1)){
 					writer.write("'");
 					writer.newLine();
 					count += 1;
@@ -7562,18 +7589,23 @@ public class EDISenderServiceImpl implements IEDISenderService {
 			}
 
 			// 47 CARGO DESCRIPTION 货物描述 5行一组
-			List<String> goodsDesc = RegularUtils.reformatEDIText(voltaSiDto.getGoodsDesc(), 70, true);
+			List<String> goodsDesc = RegularUtils.reformatEDIText(goodsDescText, 44, true);
 			int descrLineCount = goodsDesc.size();
 			for (int l = 0; l < descrLineCount; l++) {
-				String line = goodsMarks.get(l);
+				String line = goodsDesc.get(l);
 				if(line.trim().isEmpty()){
 					line=".";
 				}
 				if((l % 5)==0){
+					if(l>0){
+						writer.write("'");
+						writer.newLine();
+						count += 1;
+					}
 					writer.write("47");
 				}
 				writer.write(":" + line);
-				if((l % 5)==7 || l==(descrLineCount - 1)){
+				if(l==(descrLineCount - 1)){
 					writer.write("'");
 					writer.newLine();
 					count += 1;
@@ -7594,25 +7626,25 @@ public class EDISenderServiceImpl implements IEDISenderService {
 					// 记录类型标识 + 集装箱尺寸类 + 集装箱箱数
 					writer.write("48:" + map1.get("sizeType") + ":" + map1.get("cntrQty"));
 					// 集装箱状态
-					writer.write(":" + (ObjectUtils.isNotNull(voltaSiDto.getBookingNo()) && !voltaSiDto.getBookingNo().equals(voltaSiDto.getMblNo()) ? "L" : "F"));
+					writer.write(":F");
 					// 主拼号 + 装箱方式 自选/内装/自派车队等
-					writer.write(":" + (ObjectUtils.isNotNull(voltaSiDto.getBookingNo()) && !voltaSiDto.getBookingNo().equals(voltaSiDto.getMblNo()) ? voltaSiDto.getBookingNo() : ""));
-					writer.write("::::N'");
+					writer.write(":::::N'");
 					writer.newLine();
 					count += 1;
 				}
 			}
 
 			// DD, MM + HH
+			// 应改为,发送分单时,提取主单配箱
 			List<InttraSoDto> billsList = new ArrayList<>();
 			billsList.add(voltaSiDto);
 			voltaSiDto.setIsMasterBill(true);
-			if (ObjectUtils.isNotNull(voltaSiDto.getHblBillsList())) {
-				for (InttraSoDto bill : voltaSiDto.getHblBillsList()) {
-					bill.setIsMasterBill(false);
-					billsList.add(bill);
-				}
-			}
+//			if (ObjectUtils.isNotNull(voltaSiDto.getHblBillsList())) {
+//				for (InttraSoDto bill : voltaSiDto.getHblBillsList()) {
+//					bill.setIsMasterBill(false);
+//					billsList.add(bill);
+//				}
+//			}
 
 			for(InttraSoDto bill : billsList) {
 				if (ObjectUtils.isNotNull(bill.getLoadedCntrs())) {
@@ -7621,14 +7653,12 @@ public class EDISenderServiceImpl implements IEDISenderService {
 						// 箱号
 						String cntrNo=map.get("cntrNo").toString();
 						String sealNo=map.get("sealNo").toString();
-						if(!(cntrNo.isEmpty() && sealNo.isEmpty())){
-							if(cntrNo.isEmpty() || sealNo.isEmpty()){
-								throw new SecurityException("箱号、铅封号必须同时填写!");
-							}
+						if(cntrNo.isEmpty() || sealNo.isEmpty()){
+							throw new SecurityException("箱号、铅封号必须同时填写!");
 						}
 						String sizeType=map.get("sizeType").toString();
 						if(sizeType.isEmpty()) {
-							throw new SecurityException("HMM EDI 箱型代码没有维护!");
+							throw new SecurityException("VOLTA EDI 箱型代码没有维护!");
 						}
 						BigDecimal pkgs = ((BigDecimal) map.get("quantity")).setScale(0, BigDecimal.ROUND_HALF_UP);
 						BigDecimal gwt = ((BigDecimal) map.get("grossWeight")).setScale(3, BigDecimal.ROUND_HALF_UP);
@@ -7641,61 +7671,15 @@ public class EDISenderServiceImpl implements IEDISenderService {
 						}
 
 						writer.write("51:"+cntrNo+":"+sizeType+":" + sealNo + ":" + pkgs.toString());
-						writer.write(":" + gwt.toString() + ":" + ((BigDecimal) map.get("tareWeight")).setScale(3, BigDecimal.ROUND_HALF_UP).toString());
+						writer.write(":" + gwt.toString() + ":");
 						writer.write(":" + vol.toString());
-						writer.write("::::::");
-						// VGM WT + VGM DATE + VGM METHOD + VGM LOCATION
-						// wfg
-						writer.write("::::'");
+						writer.write("'");
 						writer.newLine();
 						count += 1;
-
-						// 录入品名
-						if(ObjectUtils.isNotNull(map.get("commodityList"))){
-							List<ContainersCommodity> cargoList = (List<ContainersCommodity>) map.get("commodityList");
-							for (ContainersCommodity cargo : cargoList) {
-								if (ObjectUtils.isNull(cargo.getHscode())) {
-									throw new RuntimeException("箱内货物没有填写 HSCODE");
-								}
-								if (ObjectUtils.isNull(cargo.getPackingUnitCode())) {
-									throw new RuntimeException("箱内货物包装单位没有填写或缺少EDI代码");
-								}
-								if (cargo.getQuantity().equals(BigDecimal.ZERO)
-									|| cargo.getGrossWeight().equals(BigDecimal.ZERO)
-									|| cargo.getMeasurement().equals(BigDecimal.ZERO)
-								) {
-									throw new RuntimeException("箱内货物件重尺填写不全");
-								}
-								BigDecimal ccPkgs = cargo.getQuantity().setScale(0, RoundingMode.HALF_UP);
-								BigDecimal ccGw = cargo.getGrossWeight().setScale(3, RoundingMode.HALF_UP);
-								BigDecimal ccVol = cargo.getMeasurement().setScale(3, RoundingMode.HALF_UP);
-
-								String ncm = cargo.getHscode()  + ":" + cargo.getCommodityEnName();
-								ncm+=":" + cargo.getPackingUnitCode() + ":" + ccPkgs.toString();
-								ncm+=":" + ccGw.toString() + ":" + ccVol.toString();
-
-								writer.write("53:"+cntrNo+":"+ncm + "'");
-								writer.newLine();
-								count += 1;
-							}
-						}
-
-						// VGM Shipper
-						// wfg
-						writer.write("58::::::::'");
-
-						// VGM WEIGHT COMPANY
-						// wfg
-						writer.write("59::::::::'");
 					}
 				}
 			}
 
-			// 90 订舱人联系信息
-			writer.write("90:QJM:QINGDAO JMS-LOGISTICS SERVICE CO.,LTD.::Miya Wang:0532-82668811 Ext.171:0532-82668660 Ext.171:hmm-seataocn@jms-logistics.com'");
-			writer.newLine();
-			count += 1;
-
 			// 99 TRAILER RECORD              尾记录
 			// RECORD TOTAL OF FILE   记录总数	9(6)	包括:头、尾记录
 			writer.write("99:" + (++count) + "'");

+ 2 - 2
blade-service/blade-los/src/main/java/org/springblade/los/edi/service/impl/EdiTypesServiceImpl.java

@@ -224,8 +224,8 @@ public class EdiTypesServiceImpl extends ServiceImpl<EdiTypesMapper, EdiTypes> i
 		inttraSoDto.setTransportTermCode(details.getServiceTerms());
 		inttraSoDto.setLclType("2");
 		inttraSoDto.setLoadType(details.getLoadType());
-		inttraSoDto.setBookingRemarks(details.getBookingRemarks());
-		inttraSoDto.setSiRemarks(details.getSiRemarks());
+		inttraSoDto.setBookingRemarks(ObjectUtils.isNotNull(details.getBookingRemarks()) ? details.getBookingRemarks() : "");
+		inttraSoDto.setSiRemarks(ObjectUtils.isNotNull(details.getSiRemarks()) ? details.getSiRemarks() : inttraSoDto.getBookingRemarks());
 		inttraSoDto.setCarrySingleRemarks(details.getRemarks());
 		inttraSoDto.setWeightOfGoods(details.getGrossWeight().toString());
 		inttraSoDto.setPackagesNumber(details.getQuantity());