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

1.财务增加账期锁定判断
2.OW-用箱费,超期费相关接口

纪新园 9 месяцев назад
Родитель
Сommit
a80be0f229
25 измененных файлов с 1458 добавлено и 331 удалено
  1. 6 0
      blade-service-api/blade-los-api/src/main/java/org/springblade/los/box/entity/TradingBox.java
  2. 6 0
      blade-service-api/blade-los-api/src/main/java/org/springblade/los/box/entity/TradingBoxItem.java
  3. 6 0
      blade-service-api/blade-los-api/src/main/java/org/springblade/los/box/excel/EmptyContainerAppearance.java
  4. 10 0
      blade-service-api/blade-los-api/src/main/java/org/springblade/los/business/sea/entity/Bills.java
  5. 34 0
      blade-service-api/blade-los-api/src/main/java/org/springblade/los/finance/fee/dto/FeeCenterItemsDTO.java
  6. 338 0
      blade-service-api/blade-los-api/src/main/java/org/springblade/los/finance/fee/entity/FeeCenterItems.java
  7. 36 0
      blade-service-api/blade-los-api/src/main/java/org/springblade/los/finance/fee/vo/FeeCenterItemsVO.java
  8. 5 0
      blade-service-api/blade-los-api/src/main/java/org/springblade/los/finance/stl/entity/FinStlBills.java
  9. 3 0
      blade-service/blade-los/src/main/java/org/springblade/los/Util/MagicValues.java
  10. 2 1
      blade-service/blade-los/src/main/java/org/springblade/los/basic/reports/controller/ReportsController.java
  11. 1 1
      blade-service/blade-los/src/main/java/org/springblade/los/basic/reports/service/IReportsBoxService.java
  12. 36 1
      blade-service/blade-los/src/main/java/org/springblade/los/basic/reports/service/impl/ReportsBoxServiceImpl.java
  13. 24 9
      blade-service/blade-los/src/main/java/org/springblade/los/box/controller/TradingBoxController.java
  14. 1 0
      blade-service/blade-los/src/main/java/org/springblade/los/box/dynamics/service/impl/BoxDynamicsRecordServiceImpl.java
  15. 9 4
      blade-service/blade-los/src/main/java/org/springblade/los/box/service/ITradingBoxService.java
  16. 464 305
      blade-service/blade-los/src/main/java/org/springblade/los/box/service/impl/TradingBoxServiceImpl.java
  17. 15 3
      blade-service/blade-los/src/main/java/org/springblade/los/business/sea/controller/BillsController.java
  18. 136 0
      blade-service/blade-los/src/main/java/org/springblade/los/finance/fee/controller/FeeCenterItemsController.java
  19. 42 0
      blade-service/blade-los/src/main/java/org/springblade/los/finance/fee/mapper/FeeCenterItemsMapper.java
  20. 68 0
      blade-service/blade-los/src/main/java/org/springblade/los/finance/fee/mapper/FeeCenterItemsMapper.xml
  21. 41 0
      blade-service/blade-los/src/main/java/org/springblade/los/finance/fee/service/IFeeCenterItemsService.java
  22. 41 0
      blade-service/blade-los/src/main/java/org/springblade/los/finance/fee/service/impl/FeeCenterItemsServiceImpl.java
  23. 50 6
      blade-service/blade-los/src/main/java/org/springblade/los/finance/genleg/service/impl/FinPeriodServiceImpl.java
  24. 45 0
      blade-service/blade-los/src/main/java/org/springblade/los/finance/invoices/service/impl/FinInvoicesServiceImpl.java
  25. 39 1
      blade-service/blade-los/src/main/java/org/springblade/los/finance/stl/service/impl/FinStlBillsServiceImpl.java

+ 6 - 0
blade-service-api/blade-los-api/src/main/java/org/springblade/los/box/entity/TradingBox.java

@@ -23,6 +23,7 @@ import io.swagger.annotations.ApiModel;
 import io.swagger.annotations.ApiModelProperty;
 import lombok.Data;
 import org.springblade.los.finance.fee.entity.FeeCenter;
+import org.springblade.los.finance.fee.entity.FeeCenterItems;
 import org.springblade.system.entity.Dept;
 
 import java.io.Serializable;
@@ -637,6 +638,11 @@ public class TradingBox implements Serializable {
 	 */
 	@TableField(exist = false)
 	private List<BoxAdjustmentCost> boxAdjustmentCostList;
+	/**
+	 * 费用字明细
+	 */
+	@TableField(exist = false)
+	private List<FeeCenterItems> feeCenterItemsList;
 
 	//请核标识  1买箱 2卖箱
 	@TableField(exist = false)

+ 6 - 0
blade-service-api/blade-los-api/src/main/java/org/springblade/los/box/entity/TradingBoxItem.java

@@ -625,4 +625,10 @@ public class TradingBoxItem implements Serializable {
 	 */
 	@ApiModelProperty(value = "是否计算租金")
 	private String whetherCountRent;
+
+	/**
+	 * 是否生成PickUp费用
+	 */
+	@ApiModelProperty(value = "是否生成PickUp费用")
+	private String whetherGeneratePickUpCost;
 }

+ 6 - 0
blade-service-api/blade-los-api/src/main/java/org/springblade/los/box/excel/EmptyContainerAppearance.java

@@ -66,6 +66,12 @@ public class EmptyContainerAppearance {
 	 */
 	@ExcelProperty(value = "动态日期*")
 	private Date boxStatusDate;
+
+	/**
+	 * 目的
+	 */
+	@ExcelProperty(value = "目的*")
+	private String objective;
 	/**
 	 * 箱好坏
 	 */

+ 10 - 0
blade-service-api/blade-los-api/src/main/java/org/springblade/los/business/sea/entity/Bills.java

@@ -1652,6 +1652,16 @@ public class Bills implements Serializable {
 	 */
 	@TableField(exist = false)
 	private List<String> etdList;
+	/**
+	 * 实际开船日期
+	 */
+	@TableField(exist = false)
+	private List<String> actualEtdList;
+	/**
+	 * 实际到港日期
+	 */
+	@TableField(exist = false)
+	private List<String> actualEtaList;
 	@TableField(exist = false)
 	private List<String> bookingDateList;
 	/**

+ 34 - 0
blade-service-api/blade-los-api/src/main/java/org/springblade/los/finance/fee/dto/FeeCenterItemsDTO.java

@@ -0,0 +1,34 @@
+/*
+ *      Copyright (c) 2018-2028, Chill Zhuang All rights reserved.
+ *
+ *  Redistribution and use in source and binary forms, with or without
+ *  modification, are permitted provided that the following conditions are met:
+ *
+ *  Redistributions of source code must retain the above copyright notice,
+ *  this list of conditions and the following disclaimer.
+ *  Redistributions in binary form must reproduce the above copyright
+ *  notice, this list of conditions and the following disclaimer in the
+ *  documentation and/or other materials provided with the distribution.
+ *  Neither the name of the dreamlu.net developer nor the names of its
+ *  contributors may be used to endorse or promote products derived from
+ *  this software without specific prior written permission.
+ *  Author: Chill 庄骞 (smallchill@163.com)
+ */
+package org.springblade.los.finance.fee.dto;
+
+import org.springblade.los.finance.fee.entity.FeeCenterItems;
+import lombok.Data;
+import lombok.EqualsAndHashCode;
+
+/**
+ * OW 费用明细子表数据传输对象实体类
+ *
+ * @author BladeX
+ * @since 2025-08-15
+ */
+@Data
+@EqualsAndHashCode(callSuper = true)
+public class FeeCenterItemsDTO extends FeeCenterItems {
+	private static final long serialVersionUID = 1L;
+
+}

+ 338 - 0
blade-service-api/blade-los-api/src/main/java/org/springblade/los/finance/fee/entity/FeeCenterItems.java

@@ -0,0 +1,338 @@
+/*
+ *      Copyright (c) 2018-2028, Chill Zhuang All rights reserved.
+ *
+ *  Redistribution and use in source and binary forms, with or without
+ *  modification, are permitted provided that the following conditions are met:
+ *
+ *  Redistributions of source code must retain the above copyright notice,
+ *  this list of conditions and the following disclaimer.
+ *  Redistributions in binary form must reproduce the above copyright
+ *  notice, this list of conditions and the following disclaimer in the
+ *  documentation and/or other materials provided with the distribution.
+ *  Neither the name of the dreamlu.net developer nor the names of its
+ *  contributors may be used to endorse or promote products derived from
+ *  this software without specific prior written permission.
+ *  Author: Chill 庄骞 (smallchill@163.com)
+ */
+package org.springblade.los.finance.fee.entity;
+
+import com.baomidou.mybatisplus.annotation.TableField;
+import com.baomidou.mybatisplus.annotation.TableName;
+import io.swagger.annotations.ApiModel;
+import io.swagger.annotations.ApiModelProperty;
+import lombok.Data;
+
+import java.io.Serializable;
+import java.math.BigDecimal;
+import java.time.LocalDateTime;
+import java.util.Date;
+
+/**
+ * OW 费用明细子表实体类
+ *
+ * @author BladeX
+ * @since 2025-08-15
+ */
+@Data
+@TableName("los_fee_center_items")
+@ApiModel(value = "FeeCenterItems对象", description = "OW 费用明细子表")
+public class FeeCenterItems implements Serializable {
+
+	private static final long serialVersionUID = 1L;
+
+	/**
+	 * 主键
+	 */
+	@ApiModelProperty(value = "主键")
+	private Long id;
+	/**
+	 * 分公司 Id
+	 */
+	@ApiModelProperty(value = "分公司 Id")
+	private String branchId;
+	/**
+	 * 创建人 Id
+	 */
+	@ApiModelProperty(value = "创建人 Id")
+	private Long createUser;
+	/**
+	 * 创建人
+	 */
+	@ApiModelProperty(value = "创建人")
+	private String createUserName;
+	/**
+	 * 创建时间
+	 */
+	@ApiModelProperty(value = "创建时间")
+	private Date createTime;
+	/**
+	 * 修改人 Id
+	 */
+	@ApiModelProperty(value = "修改人 Id")
+	private Long updateUser;
+	/**
+	 * 修改人
+	 */
+	@ApiModelProperty(value = "修改人")
+	private String updateUserName;
+	/**
+	 * 修改时间
+	 */
+	@ApiModelProperty(value = "修改时间")
+	private Date updateTime;
+	/**
+	 * 主表 id
+	 */
+	@ApiModelProperty(value = "主表 id")
+	private Long pid;
+	/**
+	 * 财务日期
+	 */
+	@ApiModelProperty(value = "财务日期")
+	private Date accountDate;
+	/**
+	 * 财务年
+	 */
+	@ApiModelProperty(value = "财务年")
+	private Integer accountYear;
+	/**
+	 * 财务月
+	 */
+	@ApiModelProperty(value = "财务月")
+	private Integer accountMonth;
+	/**
+	 * 财务日
+	 */
+	@ApiModelProperty(value = "财务日")
+	private Integer accountDay;
+	/**
+	 * 箱东 id
+	 */
+	@ApiModelProperty(value = "箱东 id")
+	private Long corpId;
+	/**
+	 * 箱东中文名称
+	 */
+	@ApiModelProperty(value = "箱东中文名称")
+	private String corpCnName;
+	/**
+	 * 箱东英文名称
+	 */
+	@ApiModelProperty(value = "箱东英文名称")
+	private String corpEnName;
+	/**
+	 * MB/L NO
+	 */
+	@ApiModelProperty(value = "MB/L NO")
+	private String mblno;
+	/**
+	 * HB/L NO
+	 */
+	@ApiModelProperty(value = "HB/L NO")
+	private String hblno;
+	/**
+	 * 开船日期
+	 */
+	@ApiModelProperty(value = "开船日期")
+	private Date etd;
+	/**
+	 * 到港日期
+	 */
+	@ApiModelProperty(value = "到港日期")
+	private Date eta;
+	/**
+	 * 箱号
+	 */
+	@ApiModelProperty(value = "箱号")
+	private String cntrNo;
+	/**
+	 * 装货港 id
+	 */
+	@ApiModelProperty(value = "装货港 id")
+	private Long polId;
+	/**
+	 * 装货港代码
+	 */
+	@ApiModelProperty(value = "装货港代码")
+	private String polCode;
+	/**
+	 * 装货港英文名称
+	 */
+	@ApiModelProperty(value = "装货港英文名称")
+	private String polCnName;
+	/**
+	 * 装货港英文名称
+	 */
+	@ApiModelProperty(value = "装货港英文名称")
+	private String polEnName;
+	/**
+	 * 卸货港 id
+	 */
+	@ApiModelProperty(value = "卸货港 id")
+	private String podId;
+	/**
+	 * 卸货港代码
+	 */
+	@ApiModelProperty(value = "卸货港代码")
+	private String podCode;
+	/**
+	 * 卸货港中文名称
+	 */
+	@ApiModelProperty(value = "卸货港中文名称")
+	private String podCnName;
+	/**
+	 * 卸货港英文名称
+	 */
+	@ApiModelProperty(value = "卸货港英文名称")
+	private String podEnName;
+	/**
+	 * 费用 Id
+	 */
+	@ApiModelProperty(value = "费用 Id")
+	private Long feeId;
+	/**
+	 * 费用中文名称
+	 */
+	@ApiModelProperty(value = "费用中文名称")
+	private String feeCode;
+	/**
+	 * 费用中文名称
+	 */
+	@ApiModelProperty(value = "费用中文名称")
+	private String feeCnName;
+	/**
+	 * 费用英文名称
+	 */
+	@ApiModelProperty(value = "费用英文名称")
+	private String feeEnName;
+	/**
+	 * 箱型
+	 */
+	@ApiModelProperty(value = "箱型")
+	private String unitNo;
+	/**
+	 * 天数
+	 */
+	@ApiModelProperty(value = "天数")
+	private Integer days;
+	/**
+	 * 单价
+	 */
+	@ApiModelProperty(value = "单价")
+	private BigDecimal price;
+	/**
+	 * 币种
+	 */
+	@ApiModelProperty(value = "币种")
+	private String curCode;
+	/**
+	 * 汇率
+	 */
+	@ApiModelProperty(value = "汇率")
+	private BigDecimal exrate;
+	/**
+	 * 金额
+	 */
+	@ApiModelProperty(value = "金额")
+	private BigDecimal amount;
+	/**
+	 * 排序
+	 */
+	@ApiModelProperty(value = "排序")
+	private Integer sort;
+	/**
+	 * 是否已删除(0 否 1是)
+	 */
+	@ApiModelProperty(value = "是否已删除(0 否 1是)")
+	private Integer isDeleted;
+	/**
+	 * 版本
+	 */
+	@ApiModelProperty(value = "版本")
+	private String version;
+	/**
+	 * 状态(0 正常 1停用)
+	 */
+	@ApiModelProperty(value = "状态(0 正常 1停用)")
+	private Integer status;
+	/**
+	 * 备注
+	 */
+	@ApiModelProperty(value = "备注")
+	private String remarks;
+	/**
+	 * 计费起始日期
+	 */
+	@ApiModelProperty(value = "计费起始日期")
+	private Date storageDate;
+	/**
+	 * 计费截止日期
+	 */
+	@ApiModelProperty(value = "计费截止日期")
+	private Date outboundDate;
+	/**
+	 * 费用类型  1= Pickup  2= Perdiem
+	 */
+	@ApiModelProperty(value = "费用类型  1= Pickup  2= Perdiem")
+	private String feeType;
+	/**
+	 * 来源明细id
+	 */
+	@ApiModelProperty(value = "来源明细id")
+	private Long srcItemId;
+	/**
+	 * 放箱号
+	 */
+	@ApiModelProperty(value = "放箱号")
+	private String containerNumber;
+	/**
+	 * 分公司
+	 */
+	@ApiModelProperty(value = "分公司")
+	private String branchName;
+	/**
+	 * pol预出场日期
+	 */
+	@ApiModelProperty(value = "pol预出场日期")
+	private Date polPreAppearanceDate;
+	/**
+	 * pol场站空箱出场日期
+	 */
+	@ApiModelProperty(value = "pol场站空箱出场日期")
+	private Date polStationEmptyContainerExitDate;
+	/**
+	 * pol还箱日期
+	 */
+	@ApiModelProperty(value = "pol还箱日期")
+	private Date polReturnDate;
+	/**
+	 * pod空箱还箱日期
+	 */
+	@ApiModelProperty(value = "pod空箱还箱日期")
+	private Date podEmptyContainerReturnDate;
+	/**
+	 * 租户号
+	 */
+	@ApiModelProperty(value = "租户号")
+	private String tenantId;
+
+	/**
+	 * 费用明细Id
+	 */
+	@ApiModelProperty(value = "费用明细Id")
+	private Long feeCenterId;
+
+	/**
+	 * 是否生成费用明细
+	 */
+	@ApiModelProperty(value = "是否生成费用明细")
+	private String whetherGenerateCost;
+
+	/**
+	 * 财务日期
+	 */
+	@TableField(exist = false)
+	private String date;
+
+
+}

+ 36 - 0
blade-service-api/blade-los-api/src/main/java/org/springblade/los/finance/fee/vo/FeeCenterItemsVO.java

@@ -0,0 +1,36 @@
+/*
+ *      Copyright (c) 2018-2028, Chill Zhuang All rights reserved.
+ *
+ *  Redistribution and use in source and binary forms, with or without
+ *  modification, are permitted provided that the following conditions are met:
+ *
+ *  Redistributions of source code must retain the above copyright notice,
+ *  this list of conditions and the following disclaimer.
+ *  Redistributions in binary form must reproduce the above copyright
+ *  notice, this list of conditions and the following disclaimer in the
+ *  documentation and/or other materials provided with the distribution.
+ *  Neither the name of the dreamlu.net developer nor the names of its
+ *  contributors may be used to endorse or promote products derived from
+ *  this software without specific prior written permission.
+ *  Author: Chill 庄骞 (smallchill@163.com)
+ */
+package org.springblade.los.finance.fee.vo;
+
+import org.springblade.los.finance.fee.entity.FeeCenterItems;
+import lombok.Data;
+import lombok.EqualsAndHashCode;
+import io.swagger.annotations.ApiModel;
+
+/**
+ * OW 费用明细子表视图实体类
+ *
+ * @author BladeX
+ * @since 2025-08-15
+ */
+@Data
+@EqualsAndHashCode(callSuper = true)
+@ApiModel(value = "FeeCenterItemsVO对象", description = "OW 费用明细子表")
+public class FeeCenterItemsVO extends FeeCenterItems {
+	private static final long serialVersionUID = 1L;
+
+}

+ 5 - 0
blade-service-api/blade-los-api/src/main/java/org/springblade/los/finance/stl/entity/FinStlBills.java

@@ -552,6 +552,11 @@ public class FinStlBills implements Serializable {
 	 */
 	@ApiModelProperty(value = "订舱代理英文名称")
 	private String bookingAgentEnName;
+	/**
+	 * 原汇率,外币转为本币的汇率
+	 */
+	@ApiModelProperty(value = "原汇率,外币转为本币的汇率")
+	private BigDecimal exrate;
 
 	/**
 	 * 预收时间

+ 3 - 0
blade-service/blade-los/src/main/java/org/springblade/los/Util/MagicValues.java

@@ -9,6 +9,9 @@ public class MagicValues {
 	public static final String BUSINESS = "业务";
 	public static final String OW = "OW";
 	public static final String OW_N = "OW-N";
+
+	public static final String PER_DIEM = "PerDiem";
+	public static final String PICK_UP = "PickUp";
 	public static final String OW_F = "OW-F";
 	public static final String BUY = "BUY";
 	public static final String ZR = "ZR";

+ 2 - 1
blade-service/blade-los/src/main/java/org/springblade/los/basic/reports/controller/ReportsController.java

@@ -198,9 +198,10 @@ public class ReportsController extends BladeController {
 						   @RequestParam(value = "corpIds", required = false) String corpIds,
 						   @RequestParam(value = "itemIds", required = false) String itemIds,
 						   @RequestParam(value = "curCode", required = false) String curCode,
+						   @RequestParam(value = "date", required = false) String date,
 						   @RequestParam(value = "type", required = false) String type
 	) {
-		return reportsBoxService.getReportData(billId, reportCode, groupCode, corpIds, itemIds, type, curCode);
+		return reportsBoxService.getReportData(billId, reportCode, groupCode, corpIds, itemIds, type, curCode,date);
 	}
 
 	@PostMapping("/generateMailFileAndSend")

+ 1 - 1
blade-service/blade-los/src/main/java/org/springblade/los/basic/reports/service/IReportsBoxService.java

@@ -30,6 +30,6 @@ public interface IReportsBoxService {
 	 * 获取模本数据加信息
 	 */
 	R getReportData(String billId, String reportCode, String groupCode, String corpIds,
-					String itemIds, String type, String curCode);
+					String itemIds, String type, String curCode,String date);
 
 }

+ 36 - 1
blade-service/blade-los/src/main/java/org/springblade/los/basic/reports/service/impl/ReportsBoxServiceImpl.java

@@ -43,6 +43,8 @@ import org.springblade.los.business.sea.service.IBillsService;
 import org.springblade.los.business.sea.service.ISeaBillsDetailService;
 import org.springblade.los.finance.fee.dto.ExpenseApplicationFeeReports;
 import org.springblade.los.finance.fee.entity.FeeCenter;
+import org.springblade.los.finance.fee.entity.FeeCenterItems;
+import org.springblade.los.finance.fee.service.IFeeCenterItemsService;
 import org.springblade.los.finance.fee.service.IFeeCenterService;
 import org.springblade.system.entity.Dept;
 import org.springblade.system.entity.DictBiz;
@@ -92,9 +94,12 @@ public class ReportsBoxServiceImpl implements IReportsBoxService {
 
 	private final IMktSlotQuotationService mktSlotQuotationService;
 
+	private final IFeeCenterItemsService feeCenterItemsService;
+
 
 	@Override
-	public R getReportData(String billId, String reportCode, String groupCode, String corpIds, String itemIds, String type, String curCode) {
+	public R getReportData(String billId, String reportCode, String groupCode, String corpIds, String itemIds,
+						   String type, String curCode, String accDate) {
 		Map<String, Object> map = new HashMap<>();
 		if (ObjectUtils.isNull(billId)) {
 			throw new RuntimeException("缺少比要参数");
@@ -133,6 +138,36 @@ public class ReportsBoxServiceImpl implements IReportsBoxService {
 			} else {
 				map.put(MagicValues.DATA, null);
 			}
+		} else if (MagicValues.OW.equals(reportCode) && (MagicValues.OW_N.equals(type) || MagicValues.OW_F.equals(type))
+			&& (MagicValues.PER_DIEM.equals(groupCode) || MagicValues.PICK_UP.equals(groupCode))) {
+			TradingBox tradingBox = tradingBoxService.getById(billId);
+			if (tradingBox != null) {
+				tradingBox.setBoxTypeQuantityOne(tradingBox.getBoxNumber() + "*" + tradingBox.getBoxTypeQuantityOne());
+				if (ObjectUtils.isNotNull(tradingBox.getPolStationId())) {
+					BCorps corps = bCorpsService.getById(tradingBox.getPolStationId());
+					if (corps != null) {
+						tradingBox.setPolStationAddress(corps.getCnAddr());
+						tradingBox.setPolStationTel(corps.getTel());
+					}
+				}
+				tradingBox.setDate(new Date());
+				tradingBox.setDept(dept);
+				LambdaQueryWrapper<FeeCenterItems> lambdaQueryWrapper = new LambdaQueryWrapper<>();
+				lambdaQueryWrapper.eq(FeeCenterItems::getTenantId, AuthUtil.getTenantId())
+					.eq(FeeCenterItems::getIsDeleted, 0)
+					.eq(FeeCenterItems::getPid, tradingBox.getId())
+					.eq(FeeCenterItems::getAccountDate, accDate);
+				if (MagicValues.PER_DIEM.equals(type)) {
+					lambdaQueryWrapper.eq(FeeCenterItems::getFeeType, "2");
+				} else {
+					lambdaQueryWrapper.eq(FeeCenterItems::getFeeType, "1");
+				}
+				List<FeeCenterItems> feeCenterItemsList = feeCenterItemsService.list(lambdaQueryWrapper);
+				tradingBox.setFeeCenterItemsList(feeCenterItemsList.isEmpty() ? new ArrayList<>() : feeCenterItemsList);
+				map.put(MagicValues.DATA, tradingBox);
+			} else {
+				map.put(MagicValues.DATA, null);
+			}
 		} else if ((MagicValues.OW_N.equals(reportCode) || MagicValues.OW_F.equals(reportCode)
 			|| MagicValues.BUY.equals(reportCode) || MagicValues.ZR.equals(reportCode)
 			|| MagicValues.DL.equals(reportCode) || MagicValues.XGFY.equals(reportCode)

+ 24 - 9
blade-service/blade-los/src/main/java/org/springblade/los/box/controller/TradingBoxController.java

@@ -35,7 +35,6 @@ import org.springblade.core.tool.utils.BeanUtil;
 import org.springblade.core.tool.utils.Func;
 import org.springblade.los.box.dto.ExportTradingBoxItemOut;
 import org.springblade.los.box.dto.ExportTradingBoxOut;
-import org.springblade.los.box.entity.PutBox;
 import org.springblade.los.box.entity.TradingBox;
 import org.springblade.los.box.entity.TradingBoxItem;
 import org.springblade.los.box.service.ITradingBoxItemService;
@@ -352,19 +351,35 @@ public class TradingBoxController extends BladeController {
 	}
 
 	/**
-	 * OW计算超期箱使费
+	 * OW计算超期箱使费-PerDiem
 	 */
-	@GetMapping("/countOverdueFee")
-	public R countOverdueFee(TradingBox tradingBox) {
-		return tradingBoxService.countOverdueFee(tradingBox);
+	@GetMapping("/countPerDiem")
+	public R countPerDiem(TradingBox tradingBox) {
+		return tradingBoxService.countPerDiem(tradingBox);
 	}
 
 	/**
-	 * OW撤销计算超期箱使费
+	 * OW撤销计算超期箱使费-PerDiem
 	 */
-	@GetMapping("/revokeCountOverdueFee")
-	public R revokeCountOverdueFee(TradingBox tradingBox) {
-		return tradingBoxService.revokeCountOverdueFee(tradingBox);
+	@GetMapping("/revokeCountPerDiem")
+	public R revokeCountPerDiem(TradingBox tradingBox) {
+		return tradingBoxService.revokeCountPerDiem(tradingBox);
+	}
+
+	/**
+	 * OW批量导入费用 - PickUp
+	 */
+	@GetMapping("/batchImportPickUpCost")
+	public R batchImportPickUpCost(@RequestParam("id") Long id, @RequestParam("accountDate") Date accountDate) {
+		return tradingBoxService.batchImportPickUpCost(id, accountDate);
+	}
+
+	/**
+	 * 合并生成费用明细
+	 */
+	@PostMapping("/mergeGenerateCost")
+	public R mergeGenerateCost(@Valid @RequestBody TradingBox tradingBox) {
+		return tradingBoxService.mergeGenerateCost(tradingBox);
 	}
 
 	/**

+ 1 - 0
blade-service/blade-los/src/main/java/org/springblade/los/box/dynamics/service/impl/BoxDynamicsRecordServiceImpl.java

@@ -221,6 +221,7 @@ public class BoxDynamicsRecordServiceImpl extends ServiceImpl<BoxDynamicsRecordM
 			recordItems.setBranchId(AuthUtil.getDeptId());
 			recordItems.setContainerNumber(item.getContainerNumber());
 			recordItems.setBoxCode(item.getBoxCode());
+			recordItems.setObjective(item.getObjective());
 			BCntrTypes cntrTypes = boxTypeList.stream().filter(e -> e.getCode95().equals(item.getBoxType())).findFirst().orElse(null);
 			if (cntrTypes == null) {
 				throw new RuntimeException("请先维护箱型:" + item.getBoxType() + "基础资料");

+ 9 - 4
blade-service/blade-los/src/main/java/org/springblade/los/box/service/ITradingBoxService.java

@@ -25,6 +25,7 @@ import com.baomidou.mybatisplus.core.metadata.IPage;
 import org.springblade.core.tool.api.R;
 import org.springframework.web.bind.annotation.RequestParam;
 
+import java.util.Date;
 import java.util.List;
 import java.util.Map;
 
@@ -66,11 +67,15 @@ public interface ITradingBoxService extends IService<TradingBox> {
 
 	List<Map<String, Object>> trend(String tenantId, String type, String date);
 
-	R countOverdueFee(TradingBox tradingBox);
-
-	R revokeCountOverdueFee(TradingBox tradingBox);
-
 	R batchUpdatePodStation(TradingBox tradingBox);
 
 	R synchronousPutBoxData(TradingBox tradingBox);
+
+	R batchImportPickUpCost(Long id, Date accountDate);
+
+	R countPerDiem(TradingBox tradingBox);
+
+	R revokeCountPerDiem(TradingBox tradingBox);
+
+	R mergeGenerateCost(TradingBox tradingBox);
 }

+ 464 - 305
blade-service/blade-los/src/main/java/org/springblade/los/box/service/impl/TradingBoxServiceImpl.java

@@ -26,6 +26,7 @@ import org.springblade.core.tool.utils.BeanUtil;
 import org.springblade.core.tool.utils.StringUtil;
 import org.springblade.los.Util.BoxNumUtils;
 import org.springblade.los.Util.CurrencyUtils;
+import org.springblade.los.Util.MagicValues;
 import org.springblade.los.basic.business.entity.BusinessType;
 import org.springblade.los.basic.business.service.IBusinessTypeService;
 import org.springblade.los.basic.cur.entity.BCurExrate;
@@ -39,11 +40,12 @@ import org.springblade.los.box.mapper.TradingBoxMapper;
 import org.springblade.los.box.service.*;
 import org.springblade.los.business.sea.entity.Bills;
 import org.springblade.los.business.sea.entity.Containers;
-import org.springblade.los.business.sea.entity.SeaContainerNumberItem;
 import org.springblade.los.business.sea.service.IBillsService;
 import org.springblade.los.business.sea.service.IContainersService;
 import org.springblade.los.business.sea.service.ISeaContainerNumberItemService;
 import org.springblade.los.finance.fee.entity.FeeCenter;
+import org.springblade.los.finance.fee.entity.FeeCenterItems;
+import org.springblade.los.finance.fee.service.IFeeCenterItemsService;
 import org.springblade.los.finance.fee.service.IFeeCenterService;
 import org.springblade.system.feign.ISysClient;
 import org.springframework.stereotype.Service;
@@ -104,6 +106,8 @@ public class TradingBoxServiceImpl extends ServiceImpl<TradingBoxMapper, Trading
 
 	private final ISysClient sysClient;
 
+	private final IFeeCenterItemsService feeCenterItemsService;
+
 	@Override
 	public TradingBox getDetail(TradingBox tradingBox) {
 		if (tradingBox.getId() == null) {
@@ -148,6 +152,12 @@ public class TradingBoxServiceImpl extends ServiceImpl<TradingBoxMapper, Trading
 				.eq(BoxAdjustmentCost::getPid, details.getId());
 			List<BoxAdjustmentCost> boxAdjustmentCostList = boxAdjustmentCostService.list(costLambdaQueryWrapper);
 			details.setBoxAdjustmentCostList(boxAdjustmentCostList.isEmpty() ? new ArrayList<>() : boxAdjustmentCostList);
+			LambdaQueryWrapper<FeeCenterItems> lambdaQueryWrapper = new LambdaQueryWrapper<>();
+			lambdaQueryWrapper.eq(FeeCenterItems::getTenantId, AuthUtil.getTenantId())
+				.eq(FeeCenterItems::getIsDeleted, 0)
+				.eq(FeeCenterItems::getPid, tradingBox.getId());
+			List<FeeCenterItems> feeCenterItemsList = feeCenterItemsService.list(lambdaQueryWrapper);
+			details.setFeeCenterItemsList(feeCenterItemsList.isEmpty() ? new ArrayList<>() : feeCenterItemsList);
 		}
 		return details;
 	}
@@ -2289,7 +2299,7 @@ public class TradingBoxServiceImpl extends ServiceImpl<TradingBoxMapper, Trading
 			feeCenter.setPolCnName(detail.getPolCname());
 			feeCenter.setPolEnName(detail.getPolEname());
 			feeCenter.setAutomaticGenerated("1");
-			if (new BigDecimal("0.00").compareTo(feeCenter.getAmount()) != 0){
+			if (new BigDecimal("0.00").compareTo(feeCenter.getAmount()) != 0) {
 				feeCenterList.add(feeCenter);
 			}
 			item.setUpdateTime(new Date());
@@ -2370,10 +2380,10 @@ public class TradingBoxServiceImpl extends ServiceImpl<TradingBoxMapper, Trading
 		List<TradingBoxItem> itemList = new ArrayList<>();
 		List<Long> feeId = new ArrayList<>();
 		for (TradingBoxItem item : tradingBoxItemList) {
-			if (ObjectUtils.isNull(item.getRentStartDate())){
+			if (ObjectUtils.isNull(item.getRentStartDate())) {
 				throw new RuntimeException("未计算过租金,撤销失败");
-			}else{
-				if (!feeCenters.isEmpty()){
+			} else {
+				if (!feeCenters.isEmpty()) {
 					List<FeeCenter> feeCenterList = feeCenters.stream().filter(e -> e.getCntrNo().equals(item.getCode())).collect(Collectors.toList());
 					if (!feeCenterList.isEmpty()) {
 						FeeCenter feeCenter = feeCenterList.get(0);
@@ -2450,306 +2460,6 @@ public class TradingBoxServiceImpl extends ServiceImpl<TradingBoxMapper, Trading
 
 	@Override
 	@Transactional(rollbackFor = Exception.class)
-	public R countOverdueFee(TradingBox tradingBox) {
-		if (tradingBox.getId() == null) {
-			throw new RuntimeException("缺少必要参数");
-		}
-		TradingBox detail = baseMapper.selectById(tradingBox.getId());
-		if (detail == null) {
-			throw new RuntimeException("未查到单据信息");
-		}
-		PutBox putBox = putBoxService.getOne(new LambdaQueryWrapper<PutBox>()
-			.eq(PutBox::getTenantId, AuthUtil.getTenantId())
-			.eq(PutBox::getIsDeleted, 0)
-			.eq(PutBox::getContainerNumber, detail.getContainerNumber())
-			.eq(PutBox::getPolId, detail.getPolId())
-			.eq(PutBox::getPolStationId, detail.getPolStationId())
-			.apply("find_in_set(bus_type,'OW(拿),OW(放)')")
-		);
-		if (putBox == null) {
-			throw new RuntimeException("未查到放箱号信息");
-		}
-		List<SeaContainerNumberItem> seaContainerNumberItemList = seaContainerNumberItemService.list(new LambdaQueryWrapper<SeaContainerNumberItem>()
-			.eq(SeaContainerNumberItem::getIsDeleted, 0)
-			.eq(SeaContainerNumberItem::getTenantId, AuthUtil.getTenantId())
-			.eq(SeaContainerNumberItem::getSrcId, putBox.getId()));
-		if (seaContainerNumberItemList.isEmpty()) {
-			throw new RuntimeException("放箱号" + detail.getContainerNumber() + "未使用");
-		}
-		List<Bills> billsList = billsService.list(new LambdaQueryWrapper<Bills>()
-			.eq(Bills::getTenantId, AuthUtil.getTenantId())
-			.eq(Bills::getIsDeleted, 0)
-			.in(Bills::getId, seaContainerNumberItemList.stream().map(SeaContainerNumberItem::getPid).collect(Collectors.toList())));
-		if (billsList.isEmpty()) {
-			throw new RuntimeException("放箱号" + detail.getContainerNumber() + "未查到单据信息");
-		}
-		List<Containers> containersList = containersService.list(new LambdaQueryWrapper<Containers>()
-			.eq(Containers::getIsDeleted, 0)
-			.eq(Containers::getTenantId, AuthUtil.getTenantId())
-			.in(Containers::getPid, billsList.stream().map(Bills::getId).collect(Collectors.toList())));
-		if (containersList.isEmpty()) {
-			throw new RuntimeException("放箱号" + detail.getContainerNumber() + "未查到单据配箱信息");
-		}
-		List<TradingBoxItem> tradingBoxItemList = tradingBoxItemService.list(new LambdaQueryWrapper<TradingBoxItem>()
-			.eq(TradingBoxItem::getTenantId, AuthUtil.getTenantId())
-			.eq(TradingBoxItem::getIsDeleted, 0)
-			.eq(TradingBoxItem::getPid, detail.getId()));
-		if (tradingBoxItemList.isEmpty()) {
-			throw new RuntimeException("未查到单据箱信息");
-		}
-		BFees fees = bFeesService.getOne(new LambdaQueryWrapper<BFees>()
-			.eq(BFees::getTenantId, AuthUtil.getTenantId())
-			.eq(BFees::getIsDeleted, 0)
-			.eq(BFees::getCode, "CQXSF"));
-		if (fees == null) {
-			throw new RuntimeException("请先维护费用基础信息");
-		}
-		List<FeeCenter> feeCenterList = new ArrayList<>();
-		for (TradingBoxItem item : tradingBoxItemList) {
-			Containers containers = containersList.stream().filter(e -> e.getCntrNo().equals(item.getCode())
-				&& e.getCntrTypeCode().equals(item.getBoxType())).findFirst().orElse(null);
-			if (containers == null) {
-				continue;
-			}
-			Bills bills = billsList.stream().filter(e -> e.getId().equals(containers.getPid())).findFirst().orElse(null);
-			if (bills == null) {
-				continue;
-			}
-			int pol = 0;
-			int pod = 0;
-			if (ObjectUtils.isNotNull(item.getPolPickUpDate()) && ObjectUtils.isNotNull(item.getEtd())) {
-				int polFreeBoxUseDays = ObjectUtils.isNull(bills.getPolFreeBoxUseDays()) ? 0 : bills.getPolFreeBoxUseDays();
-				Instant instant1 = item.getEtd().toInstant();
-				Instant instant2 = item.getPolPickUpDate().toInstant();
-				LocalDate date1 = instant1.atZone(ZoneId.systemDefault()).toLocalDate();
-				LocalDate date2 = instant2.atZone(ZoneId.systemDefault()).toLocalDate();
-				Duration duration = Duration.between(date1.atStartOfDay(), date2.atStartOfDay());
-				pol = Integer.parseInt(duration.toDays() + "") - polFreeBoxUseDays;
-			}
-			if (ObjectUtils.isNotNull(item.getPodReturnDate()) && ObjectUtils.isNotNull(item.getEta())) {
-				int podFreeBoxUseDays = ObjectUtils.isNull(bills.getPodFreeBoxUseDays()) ? 0 : bills.getPodFreeBoxUseDays();
-				Instant instant1 = item.getPodReturnDate().toInstant();
-				Instant instant2 = item.getEta().toInstant();
-				LocalDate date1 = instant1.atZone(ZoneId.systemDefault()).toLocalDate();
-				LocalDate date2 = instant2.atZone(ZoneId.systemDefault()).toLocalDate();
-				Duration duration = Duration.between(date1.atStartOfDay(), date2.atStartOfDay());
-				pod = Integer.parseInt(duration.toDays() + "") - podFreeBoxUseDays;
-			}
-			if (pol > 0) {
-
-			}
-			if (pod > 0) {
-
-			}
-			FeeCenter feeCenter = new FeeCenter();
-			feeCenter.setBillType("箱东");
-			feeCenter.setCorpId(detail.getPurchaseCompanyId());
-			feeCenter.setCorpCnName(detail.getPurchaseCompanyName());
-			feeCenter.setCorpEnName(detail.getPurchaseCompanyName());
-			feeCenter.setCreateTime(new Date());
-			feeCenter.setCreateUser(AuthUtil.getUserId());
-			feeCenter.setCreateUserName(AuthUtil.getUserName());
-			feeCenter.setPid(item.getPid());
-			if ("OW(拿)".equals(detail.getType())) {
-				feeCenter.setDc("C");
-			} else {
-				feeCenter.setDc("D");
-			}
-			feeCenter.setFeeId(fees.getId());
-			feeCenter.setFeeCode(fees.getCode());
-			feeCenter.setFeeCnName(fees.getCnName());
-			feeCenter.setFeeEnName(fees.getEnName());
-			feeCenter.setCurCode(fees.getCurNo());
-			feeCenter.setCntrNo(item.getCode());
-			feeCenter.setUnitNo(item.getBoxType());
-			if (ObjectUtils.isNotNull(item.getPodEmptyContainerReturnDate())
-				&& tradingBox.getRentDate().compareTo(item.getPodEmptyContainerReturnDate()) > 0) {
-				throw new RuntimeException("箱号:" + item.getCode() + "租金计算截止时间大于pod还箱日期");
-			}
-			Instant instant1 = item.getRentEndDate().toInstant();
-			Instant instant2 = tradingBox.getRentDate().toInstant();
-			LocalDate date1 = instant1.atZone(ZoneId.systemDefault()).toLocalDate();
-			LocalDate date2 = instant2.atZone(ZoneId.systemDefault()).toLocalDate();
-			Duration duration = Duration.between(date1.atStartOfDay(), date2.atStartOfDay());
-			Calendar calendar = Calendar.getInstance();
-			calendar.setTime(item.getRentEndDate());
-			calendar.add(Calendar.DAY_OF_MONTH, 1);
-			feeCenter.setDays(Integer.parseInt(duration.toDays() + ""));
-
-			Integer days = feeCenter.getDays();
-			int earlySumDays = 0;
-			if (item.getRentEndDate().compareTo(item.getPolPickUpDate()) != 0) {
-				Instant instant3 = item.getRentEndDate().toInstant();
-				Instant instant4 = item.getPolPickUpDate().toInstant();
-				LocalDate date3 = instant3.atZone(ZoneId.systemDefault()).toLocalDate();
-				LocalDate date4 = instant4.atZone(ZoneId.systemDefault()).toLocalDate();
-				Duration duratio1 = Duration.between(date4.atStartOfDay(), date3.atStartOfDay());
-				earlySumDays = Integer.parseInt(duratio1.toDays() + "") + 1;
-			}
-			String text = "";
-			int dayLength;
-			BigDecimal amount = new BigDecimal("0.00");
-			/*for (RentTerm term : rentTermList) {
-				dayLength = term.getStopDays() - term.getRiseDays() + 1;
-				if (earlySumDays >= dayLength) {
-					earlySumDays -= dayLength;
-					continue;
-				}
-				if (earlySumDays + days > dayLength) {
-					Integer tempDays = dayLength - earlySumDays;
-					earlySumDays = 0;
-					days -= tempDays;
-					BigDecimal calculate = term.getRate().multiply(new BigDecimal(tempDays + ""));
-					amount = amount.add(calculate);
-					text = text + tempDays + "天*" + term.getRate() + "元=" + calculate + "元,";
-				} else {
-					BigDecimal calculate = term.getRate().multiply(new BigDecimal(days + ""));
-					amount = amount.add(calculate);
-					text = text + days + "天*" + term.getRate() + "元=" + calculate + "元";
-					days = 0;
-					break;
-				}
-			}
-			if (days != 0) {
-				BigDecimal calculate = rentTermList.get(rentTermList.size() - 1).getRate().multiply(new BigDecimal(days + ""));
-				amount = amount.add(calculate);
-				text = text + "超出费用:" + days + "天*" + rentTermList.get(rentTermList.size() - 1).getRate() + "元=" + calculate + "元,";
-			}
-			if (exrateType.equals(feeCenter.getCurCode())) {
-				feeCenter.setExrate(new BigDecimal("1.00"));
-			} else {
-				feeCenter.setExrate(currencyUtils.obtainExrate("C", curExrateList, feeCenter.getCurCode(), "1"));
-			}*/
-			feeCenter.setAmount(amount);
-			feeCenter.setPrice(amount);
-			feeCenter.setRemarks(text);
-			feeCenter.setQuantity(new BigDecimal("1"));
-			feeCenter.setOutboundDate(tradingBox.getRentDate());
-			feeCenter.setBillNo(detail.getSysNo());
-			feeCenter.setBusinessType(detail.getType());
-			feeCenter.setBillDate(detail.getPurchaseDate());
-			feeCenter.setBillCorpId(detail.getPurchaseCompanyId());
-			feeCenter.setBillCorpCnName(detail.getPurchaseCompanyName());
-			feeCenter.setBillCorpEnName(detail.getPurchaseCompanyName());
-			feeCenter.setBillShortName(detail.getPurchaseCompanyName());
-			feeCenter.setMblno(detail.getContainerNumber());
-			feeCenter.setPolId(detail.getPolId());
-			feeCenter.setPolCode(detail.getPolCode());
-			feeCenter.setPolCnName(detail.getPolCname());
-			feeCenter.setPolEnName(detail.getPolEname());
-			feeCenter.setAutomaticGenerated("1");
-			feeCenterList.add(feeCenter);
-		}
-		return null;
-	}
-
-	@Override
-	@Transactional(rollbackFor = Exception.class)
-	public R revokeCountOverdueFee(TradingBox tradingBox) {
-		if (tradingBox.getId() == null) {
-			throw new RuntimeException("缺少必要参数");
-		}
-		TradingBox detail = baseMapper.selectById(tradingBox.getId());
-		List<TradingBoxItem> tradingBoxItemList = tradingBoxItemService.list(new LambdaQueryWrapper<TradingBoxItem>()
-			.eq(TradingBoxItem::getTenantId, AuthUtil.getTenantId())
-			.eq(TradingBoxItem::getIsDeleted, 0)
-			.eq(TradingBoxItem::getPid, detail.getId())
-		);
-		if (tradingBoxItemList.isEmpty()) {
-			throw new RuntimeException("未查到明细");
-		}
-		//获取订单费用信息
-		LambdaQueryWrapper<FeeCenter> tradingBoxFeesLambdaQueryWrapper = new LambdaQueryWrapper<>();
-		tradingBoxFeesLambdaQueryWrapper.eq(FeeCenter::getIsDeleted, 0)
-			.eq(FeeCenter::getPid, tradingBox.getId())
-			.eq(FeeCenter::getTenantId, AuthUtil.getTenantId())
-			.eq(FeeCenter::getFeeCode, "CQXSF")
-			.eq(FeeCenter::getAutomaticGenerated, "1")
-			.orderByDesc(FeeCenter::getCreateTime);
-		List<FeeCenter> feeCentersList = feeCenterService.list(tradingBoxFeesLambdaQueryWrapper);
-		if (feeCentersList.isEmpty()) {
-			throw new RuntimeException("未查到费用明细");
-		}
-		List<FeeCenter> feeCenters = feeCentersList.stream().filter(e -> e.getFeeCode().equals("BOX-ZJ")).collect(Collectors.toList());
-		if (feeCenters.isEmpty()) {
-			throw new RuntimeException("未计算过租金,撤销失败");
-		}
-		List<TradingBoxItem> itemList = new ArrayList<>();
-		List<Long> feeId = new ArrayList<>();
-		for (TradingBoxItem item : tradingBoxItemList) {
-			List<FeeCenter> feeCenterList = feeCenters.stream().filter(e -> e.getCntrNo().equals(item.getCode())).collect(Collectors.toList());
-			if (!feeCenterList.isEmpty()) {
-				FeeCenter feeCenter = feeCenterList.get(0);
-				if (1 == feeCenter.getAccStatus()) {
-					throw new RuntimeException("箱型:" + item.getBoxType() + "费用已生成账单,撤销失败");
-				}
-				feeCenterService.removeById(feeCenter.getId());
-				feeId.add(feeCenter.getId());
-				item.setUpdateTime(new Date());
-				item.setUpdateUser(AuthUtil.getUserId());
-				item.setUpdateUserName(AuthUtil.getUserName());
-				item.setCount(item.getCount() - 1);
-				if (feeCenterList.size() == 1) {
-					item.setRentEndDate(item.getPolPickUpDate());
-				} else {
-					Calendar calendar = Calendar.getInstance();
-					calendar.setTime(feeCenter.getStorageDate());
-					calendar.add(Calendar.DAY_OF_MONTH, -1);
-					item.setRentEndDate(calendar.getTime());
-				}
-				itemList.add(item);
-			}
-		}
-		if (!itemList.isEmpty()) {
-			tradingBoxItemService.updateBatchById(itemList);
-		}
-		if (!feeId.isEmpty()) {
-			String exrateType = currencyUtils.standardCurrency(AuthUtil.getDeptId());
-			List<FeeCenter> feeCenterList = feeCentersList.stream().filter(e -> !feeId.contains(e.getId())).collect(Collectors.toList());
-			//费用数据
-			BigDecimal amountD = new BigDecimal("0.00");
-			BigDecimal amountC = new BigDecimal("0.00");
-			BigDecimal amountDUsd = new BigDecimal("0.00");
-			BigDecimal amountCUsd = new BigDecimal("0.00");
-			BigDecimal amountDrLoc = new BigDecimal("0.00");
-			BigDecimal amountCrLoc = new BigDecimal("0.00");
-			for (FeeCenter item : feeCenterList) {
-				item.setAmountLoc(item.getAmount().multiply(item.getExrate()));
-				if (exrateType.equals(item.getCurCode())) {
-					if ("D".equals(item.getDc())) {
-						amountD = amountD.add(item.getAmount());
-						amountDrLoc = amountDrLoc.add(item.getAmount());
-					} else {
-						amountC = amountC.add(item.getAmount());
-						amountCrLoc = amountCrLoc.add(item.getAmount());
-					}
-				} else {
-					if ("D".equals(item.getDc())) {
-						amountDUsd = amountDUsd.add(item.getAmount());
-						amountDrLoc = amountDrLoc.add(item.getAmountLoc());
-					} else {
-						amountCUsd = amountCUsd.add(item.getAmount());
-						amountCrLoc = amountCrLoc.add(item.getAmountLoc());
-					}
-				}
-			}
-			tradingBox.setAmountD(amountD);
-			tradingBox.setAmountDUsd(amountDUsd);
-			tradingBox.setTotalAmountD(amountDrLoc);
-			tradingBox.setAmountC(amountC);
-			tradingBox.setAmountCUsd(amountCUsd);
-			tradingBox.setTotalAmountC(amountCrLoc);
-			tradingBox.setProfit(tradingBox.getAmountD().subtract(tradingBox.getAmountC()));
-			tradingBox.setProfitUsd(tradingBox.getAmountDUsd().subtract(tradingBox.getAmountCUsd()));
-			tradingBox.setTotalProfit(tradingBox.getTotalAmountD().subtract(tradingBox.getTotalAmountC()));
-			baseMapper.updateById(tradingBox);
-		}
-		tradingBox.setTradingBoxItemsList(tradingBoxItemList);
-		return R.data(tradingBox);
-	}
-
-	@Override
-	@Transactional(rollbackFor = Exception.class)
 	public R batchUpdatePodStation(TradingBox tradingBox) {
 		if (ObjectUtils.isNull(tradingBox.getTradingBoxItemsList()) || tradingBox.getTradingBoxItemsList().isEmpty()) {
 			throw new RuntimeException("请选择明细");
@@ -2890,4 +2600,453 @@ public class TradingBoxServiceImpl extends ServiceImpl<TradingBoxMapper, Trading
 		return R.data(tradingBox);
 	}
 
+	@Override
+	public R batchImportPickUpCost(Long id, Date accountDate) {
+		if (id == null || ObjectUtils.isNull(accountDate)) {
+			throw new RuntimeException("缺少必要参数");
+		}
+		TradingBox tradingBox = baseMapper.selectById(id);
+		if (tradingBox == null) {
+			throw new RuntimeException("未查到单据信息");
+		}
+		List<TradingBoxItem> tradingBoxItemList = tradingBoxItemService.list(new LambdaQueryWrapper<TradingBoxItem>()
+			.eq(TradingBoxItem::getIsDeleted, 0)
+			.eq(TradingBoxItem::getTenantId, AuthUtil.getTenantId())
+			.eq(TradingBoxItem::getPid, id)
+			.eq(TradingBoxItem::getWhetherGeneratePickUpCost, "0"));
+		if (tradingBoxItemList.isEmpty()) {
+			throw new RuntimeException("箱明细已全部生成PickUp费");
+		}
+		BFees fees = bFeesService.getOne(new LambdaQueryWrapper<BFees>()
+			.eq(BFees::getTenantId, AuthUtil.getTenantId())
+			.eq(BFees::getIsDeleted, 0)
+			.eq(BFees::getCode, "Pickup"));
+		if (fees == null) {
+			throw new RuntimeException("请先维护'Pickup'费用基础信息");
+		}
+		List<FeeCenterItems> feeCenterItemsList = new ArrayList<>();
+		Calendar calendar = Calendar.getInstance();
+		calendar.setTime(accountDate);
+		int year = calendar.get(Calendar.YEAR); // 获取年份
+		int month = calendar.get(Calendar.MONTH) + 1; // 获取月份(注意需加上1,因为月份从0开始计数)
+		int day = calendar.get(Calendar.DATE);
+		List<BCurExrate> bCurExrateList = currencyUtils.obtainRate(accountDate, "1", AuthUtil.getDeptId());
+		BigDecimal exrate = new BigDecimal("0.00");
+		if ("OW-F".equals(tradingBox.getType())) {
+			exrate = currencyUtils.obtainExrate("D", bCurExrateList, "USD", "1");
+		} else {
+			exrate = currencyUtils.obtainExrate("C", bCurExrateList, "USD", "1");
+		}
+		for (TradingBoxItem item : tradingBoxItemList) {
+			item.setWhetherGeneratePickUpCost("1");
+			item.setUpdateTime(new Date());
+			item.setUpdateUserName(AuthUtil.getUserName());
+			item.setUpdateUser(AuthUtil.getUserId());
+			FeeCenterItems feeCenterItems = new FeeCenterItems();
+			feeCenterItems.setBranchId(AuthUtil.getDeptId());
+			feeCenterItems.setCreateUser(AuthUtil.getUserId());
+			feeCenterItems.setCreateUserName(tradingBox.getCreateUserName());
+			feeCenterItems.setCreateTime(new Date());
+			feeCenterItems.setPid(tradingBox.getId());
+			feeCenterItems.setAccountDate(accountDate);
+			feeCenterItems.setAccountYear(year);
+			feeCenterItems.setAccountMonth(month);
+			feeCenterItems.setAccountDay(day);
+			feeCenterItems.setCorpId(tradingBox.getPurchaseCompanyId());
+			feeCenterItems.setCorpCnName(tradingBox.getPurchaseCompanyName());
+			feeCenterItems.setCorpEnName(tradingBox.getPurchaseCompanyName());
+			feeCenterItems.setPolId(tradingBox.getPolId());
+			feeCenterItems.setPolCode(tradingBox.getPolCode());
+			feeCenterItems.setPolCnName(tradingBox.getPolCname());
+			feeCenterItems.setPolEnName(tradingBox.getPolEname());
+			feeCenterItems.setPodId(tradingBox.getPodId());
+			feeCenterItems.setPodCode(tradingBox.getPodCode());
+			feeCenterItems.setPodCnName(tradingBox.getPodCname());
+			feeCenterItems.setPodEnName(tradingBox.getPodEname());
+			feeCenterItems.setMblno(item.getMblno());
+			feeCenterItems.setHblno(item.getHblno());
+			feeCenterItems.setEtd(item.getEtd());
+			feeCenterItems.setEta(item.getEta());
+			feeCenterItems.setCntrNo(item.getCode());
+			feeCenterItems.setUnitNo(item.getBoxType());
+			feeCenterItems.setSrcItemId(item.getId());
+			feeCenterItems.setContainerNumber(item.getContainerNumber());
+			feeCenterItems.setPolPreAppearanceDate(item.getPolPreAppearanceDate());
+			feeCenterItems.setPolStationEmptyContainerExitDate(item.getPolStationEmptyContainerExitDate());
+			feeCenterItems.setPolReturnDate(item.getPolReturnDate());
+			feeCenterItems.setPodEmptyContainerReturnDate(item.getPodEmptyContainerReturnDate());
+			feeCenterItems.setFeeId(fees.getId());
+			feeCenterItems.setFeeCode(fees.getCode());
+			feeCenterItems.setFeeCnName(fees.getCnName());
+			feeCenterItems.setFeeEnName(fees.getEnName());
+			feeCenterItems.setDays(1);
+			feeCenterItems.setPrice(tradingBox.getPickupFee());
+			feeCenterItems.setCurCode("USD");
+			feeCenterItems.setExrate(exrate);
+			feeCenterItems.setAmount(tradingBox.getPickupFee());
+			feeCenterItems.setStorageDate(tradingBox.getEffectiveDate());
+			feeCenterItems.setOutboundDate(tradingBox.getExpiryDate());
+			feeCenterItems.setFeeType("1");
+			feeCenterItemsList.add(feeCenterItems);
+		}
+		if (!feeCenterItemsList.isEmpty()) {
+			feeCenterItemsService.saveBatch(feeCenterItemsList);
+		}
+		if (!tradingBoxItemList.isEmpty()) {
+			tradingBoxItemService.updateBatchById(tradingBoxItemList);
+		}
+		return R.data(tradingBox);
+	}
+
+	@Override
+	@Transactional(rollbackFor = Exception.class)
+	public R countPerDiem(TradingBox tradingBox) {
+		if (tradingBox.getId() == null) {
+			throw new RuntimeException("缺少必要参数");
+		}
+		TradingBox detail = baseMapper.selectById(tradingBox.getId());
+		List<TradingBoxItem> putBoxItemsList = tradingBoxItemService.list(new LambdaQueryWrapper<TradingBoxItem>()
+			.eq(TradingBoxItem::getTenantId, AuthUtil.getTenantId())
+			.eq(TradingBoxItem::getIsDeleted, 0)
+			.eq(TradingBoxItem::getPid, detail.getId())
+			.lt(TradingBoxItem::getRentEndDate, tradingBox.getRentDate())
+		);
+		if (putBoxItemsList.isEmpty()) {
+			throw new RuntimeException("未查到需计算租金明细");
+		}
+		List<RentTerm> rentTermList = rentTermService.list(new LambdaQueryWrapper<RentTerm>()
+			.eq(RentTerm::getIsDeleted, 0)
+			.eq(RentTerm::getTenantId, AuthUtil.getTenantId())
+			.eq(RentTerm::getPid, detail.getId())
+			.isNotNull(RentTerm::getRiseDays)
+			.isNotNull(RentTerm::getStopDays)
+			.orderByAsc(RentTerm::getRiseDays)
+		);
+		if (rentTermList.isEmpty()) {
+			throw new RuntimeException("请先维护租金条款");
+		}
+		BFees fees = bFeesService.getOne(new LambdaQueryWrapper<BFees>()
+			.eq(BFees::getTenantId, AuthUtil.getTenantId())
+			.eq(BFees::getIsDeleted, 0)
+			.eq(BFees::getCode, "PerDiem"));
+		if (fees == null) {
+			throw new RuntimeException("请先维护'PerDiem'费用基础信息");
+		}
+		Calendar calendar = Calendar.getInstance();
+		calendar.setTime(new Date());
+		int year = calendar.get(Calendar.YEAR); // 获取年份
+		int month = calendar.get(Calendar.MONTH) + 1; // 获取月份(注意需加上1,因为月份从0开始计数)
+		int day = calendar.get(Calendar.DATE);
+		List<FeeCenterItems> feeCenterItemsList = new ArrayList<>();
+		SimpleDateFormat dateFormat = new SimpleDateFormat("yyyy-MM-dd");
+		String exrateType = currencyUtils.standardCurrency(AuthUtil.getDeptId());
+		List<BCurExrate> curExrateList = currencyUtils.obtainRate(new Date(), "1", AuthUtil.getDeptId());
+		for (TradingBoxItem item : putBoxItemsList) {
+			if (ObjectUtils.isNotNull(item.getPodEmptyContainerReturnDate())
+				&& tradingBox.getRentDate().compareTo(item.getPodEmptyContainerReturnDate()) > 0) {
+				throw new RuntimeException("箱号:" + item.getCode() + "租金计算截止时间大于pod还箱日期");
+			}
+			FeeCenterItems feeCenterItems = new FeeCenterItems();
+			feeCenterItems.setBranchId(AuthUtil.getDeptId());
+			feeCenterItems.setCreateUser(AuthUtil.getUserId());
+			feeCenterItems.setCreateUserName(tradingBox.getCreateUserName());
+			feeCenterItems.setCreateTime(new Date());
+			feeCenterItems.setPid(tradingBox.getId());
+			feeCenterItems.setAccountDate(new Date());
+			feeCenterItems.setAccountYear(year);
+			feeCenterItems.setAccountMonth(month);
+			feeCenterItems.setAccountDay(day);
+			feeCenterItems.setCorpId(tradingBox.getPurchaseCompanyId());
+			feeCenterItems.setCorpCnName(tradingBox.getPurchaseCompanyName());
+			feeCenterItems.setCorpEnName(tradingBox.getPurchaseCompanyName());
+			feeCenterItems.setPolId(tradingBox.getPolId());
+			feeCenterItems.setPolCode(tradingBox.getPolCode());
+			feeCenterItems.setPolCnName(tradingBox.getPolCname());
+			feeCenterItems.setPolEnName(tradingBox.getPolEname());
+			feeCenterItems.setPodId(tradingBox.getPodId());
+			feeCenterItems.setPodCode(tradingBox.getPodCode());
+			feeCenterItems.setPodCnName(tradingBox.getPodCname());
+			feeCenterItems.setPodEnName(tradingBox.getPodEname());
+			feeCenterItems.setMblno(item.getMblno());
+			feeCenterItems.setHblno(item.getHblno());
+			feeCenterItems.setEtd(item.getEtd());
+			feeCenterItems.setEta(item.getEta());
+			feeCenterItems.setCntrNo(item.getCode());
+			feeCenterItems.setUnitNo(item.getBoxType());
+			feeCenterItems.setSrcItemId(item.getId());
+			feeCenterItems.setContainerNumber(item.getContainerNumber());
+			feeCenterItems.setPolPreAppearanceDate(item.getPolPreAppearanceDate());
+			feeCenterItems.setPolStationEmptyContainerExitDate(item.getPolStationEmptyContainerExitDate());
+			feeCenterItems.setPolReturnDate(item.getPolReturnDate());
+			feeCenterItems.setPodEmptyContainerReturnDate(item.getPodEmptyContainerReturnDate());
+			feeCenterItems.setFeeId(fees.getId());
+			feeCenterItems.setFeeCode(fees.getCode());
+			feeCenterItems.setFeeCnName(fees.getCnName());
+			feeCenterItems.setFeeEnName(fees.getEnName());
+			feeCenterItems.setCurCode(rentTermList.get(0).getCurCode());
+			feeCenterItems.setFeeType("2");
+			Instant instant1 = item.getRentEndDate().toInstant();
+			Instant instant2 = tradingBox.getRentDate().toInstant();
+			LocalDate date1 = instant1.atZone(ZoneId.systemDefault()).toLocalDate();
+			LocalDate date2 = instant2.atZone(ZoneId.systemDefault()).toLocalDate();
+			Duration duration = Duration.between(date1.atStartOfDay(), date2.atStartOfDay());
+			if (!dateFormat.format(item.getRentEndDate()).equals(dateFormat.format(item.getPolPickUpDate()))) {
+				Calendar calendar1 = Calendar.getInstance();
+				calendar1.setTime(item.getRentEndDate());
+				calendar1.add(Calendar.DAY_OF_MONTH, 1);
+				feeCenterItems.setStorageDate(calendar1.getTime());
+				item.setRentStartDate(calendar1.getTime());
+				feeCenterItems.setDays(Integer.parseInt(duration.toDays() + ""));
+			} else {
+				feeCenterItems.setStorageDate(item.getRentEndDate());
+				item.setRentStartDate(item.getRentEndDate());
+				feeCenterItems.setDays(Integer.parseInt(duration.toDays() + "") + 1);
+			}
+			Integer days = feeCenterItems.getDays();
+			int earlySumDays = 0;
+			if (item.getRentEndDate().compareTo(item.getPolPickUpDate()) != 0) {
+				Instant instant3 = item.getRentEndDate().toInstant();
+				Instant instant4 = item.getPolPickUpDate().toInstant();
+				LocalDate date3 = instant3.atZone(ZoneId.systemDefault()).toLocalDate();
+				LocalDate date4 = instant4.atZone(ZoneId.systemDefault()).toLocalDate();
+				Duration duratio1 = Duration.between(date4.atStartOfDay(), date3.atStartOfDay());
+				earlySumDays = Integer.parseInt(duratio1.toDays() + "") + 1;
+			}
+			String text = "";
+			int dayLength;
+			BigDecimal amount = new BigDecimal("0.00");
+			for (RentTerm term : rentTermList) {
+				dayLength = term.getStopDays() - term.getRiseDays() + 1;
+				if (earlySumDays >= dayLength) {
+					earlySumDays -= dayLength;
+					continue;
+				}
+				if (earlySumDays + days > dayLength) {
+					Integer tempDays = dayLength - earlySumDays;
+					earlySumDays = 0;
+					days -= tempDays;
+					BigDecimal calculate = term.getRate().multiply(new BigDecimal(tempDays + ""));
+					amount = amount.add(calculate);
+					text = text + tempDays + "天*" + term.getRate() + "元=" + calculate + "元,";
+				} else {
+					BigDecimal calculate = term.getRate().multiply(new BigDecimal(days + ""));
+					amount = amount.add(calculate);
+					text = text + days + "天*" + term.getRate() + "元=" + calculate + "元";
+					days = 0;
+					break;
+				}
+			}
+			if (days != 0) {
+				BigDecimal calculate = rentTermList.get(rentTermList.size() - 1).getRate().multiply(new BigDecimal(days + ""));
+				amount = amount.add(calculate);
+				text = text + "超出费用:" + days + "天*" + rentTermList.get(rentTermList.size() - 1).getRate() + "元=" + calculate + "元,";
+			}
+			if (exrateType.equals(feeCenterItems.getCurCode())) {
+				feeCenterItems.setExrate(new BigDecimal("1.00"));
+			} else {
+				feeCenterItems.setExrate(currencyUtils.obtainExrate("C", curExrateList, feeCenterItems.getCurCode(), "1"));
+			}
+			feeCenterItems.setAmount(amount);
+			feeCenterItems.setPrice(amount);
+			feeCenterItems.setRemarks(text);
+			feeCenterItems.setOutboundDate(tradingBox.getRentDate());
+			if (new BigDecimal("0.00").compareTo(feeCenterItems.getAmount()) != 0) {
+				feeCenterItemsList.add(feeCenterItems);
+			}
+			item.setUpdateTime(new Date());
+			item.setUpdateUserName(AuthUtil.getUserName());
+			item.setUpdateUser(AuthUtil.getUserId());
+			item.setRentEndDate(tradingBox.getRentDate());
+		}
+		tradingBoxItemService.updateBatchById(putBoxItemsList);
+		if (!feeCenterItemsList.isEmpty()) {
+			feeCenterItemsService.saveBatch(feeCenterItemsList);
+		}
+		return R.data(tradingBox);
+	}
+
+	@Override
+	@Transactional(rollbackFor = Exception.class)
+	public R revokeCountPerDiem(TradingBox tradingBox) {
+		TradingBox detail = baseMapper.selectById(tradingBox.getId());
+		List<TradingBoxItem> tradingBoxItemList = tradingBoxItemService.list(new LambdaQueryWrapper<TradingBoxItem>()
+			.eq(TradingBoxItem::getTenantId, AuthUtil.getTenantId())
+			.eq(TradingBoxItem::getIsDeleted, 0)
+			.eq(TradingBoxItem::getPid, detail.getId())
+		);
+		if (tradingBoxItemList.isEmpty()) {
+			throw new RuntimeException("未查到明细");
+		}
+		//获取订单费用信息
+		LambdaQueryWrapper<FeeCenterItems> tradingBoxFeesLambdaQueryWrapper = new LambdaQueryWrapper<>();
+		tradingBoxFeesLambdaQueryWrapper.eq(FeeCenterItems::getIsDeleted, 0)
+			.eq(FeeCenterItems::getPid, tradingBox.getId())
+			.eq(FeeCenterItems::getTenantId, AuthUtil.getTenantId())
+			.eq(FeeCenterItems::getFeeCode, "BOX-ZJ")
+			.orderByDesc(FeeCenterItems::getCreateTime);
+		List<FeeCenterItems> feeCenterItemsList = feeCenterItemsService.list(tradingBoxFeesLambdaQueryWrapper);
+		List<FeeCenterItems> feeCenterItems = feeCenterItemsList.stream().filter(e -> e.getFeeCode().equals("BOX-ZJ")).collect(Collectors.toList());
+		List<TradingBoxItem> itemList = new ArrayList<>();
+		for (TradingBoxItem item : tradingBoxItemList) {
+			if (ObjectUtils.isNull(item.getRentStartDate())) {
+				throw new RuntimeException("未计算过租金,撤销失败");
+			} else {
+				if (!feeCenterItems.isEmpty()) {
+					List<FeeCenterItems> feeCenterItemsList1 = feeCenterItems.stream().filter(e -> e.getCntrNo().equals(item.getCode())).collect(Collectors.toList());
+					if (!feeCenterItemsList1.isEmpty()) {
+						FeeCenterItems feeCenter = feeCenterItemsList1.get(0);
+						if ("1".equals(feeCenter.getWhetherGenerateCost())) {
+							throw new RuntimeException("箱号:" + item.getCode() + "已生费用明细,撤销失败");
+						}
+						feeCenterItemsService.removeById(feeCenter.getId());
+					}
+				}
+				item.setUpdateTime(new Date());
+				item.setUpdateUser(AuthUtil.getUserId());
+				item.setUpdateUserName(AuthUtil.getUserName());
+				item.setCount(item.getCount() - 1);
+				Calendar calendar = Calendar.getInstance();
+				calendar.setTime(item.getRentStartDate());
+				calendar.add(Calendar.DAY_OF_MONTH, -1);
+				item.setRentEndDate(calendar.getTime());
+				itemList.add(item);
+			}
+		}
+		if (!itemList.isEmpty()) {
+			tradingBoxItemService.updateBatchById(itemList);
+		}
+		tradingBox.setTradingBoxItemsList(tradingBoxItemList);
+		return R.data(tradingBox);
+	}
+
+	@Override
+	@Transactional(rollbackFor = Exception.class)
+	public R mergeGenerateCost(TradingBox tradingBox) {
+		if (tradingBox.getId() == null || ObjectUtils.isNull(tradingBox.getFeeCenterItemsList()) || tradingBox.getFeeCenterItemsList().isEmpty()) {
+			throw new RuntimeException("缺少必要参数");
+		}
+		TradingBox detail = baseMapper.selectById(tradingBox.getId());
+		List<FeeCenter> feeCenters = feeCenterService.list(new LambdaQueryWrapper<FeeCenter>()
+			.eq(FeeCenter::getTenantId, AuthUtil.getTenantId())
+			.eq(FeeCenter::getIsDeleted, 0)
+			.eq(FeeCenter::getPid, detail.getId()));
+		List<FeeCenter> feeCenterList = new ArrayList<>();
+		List<String> boxCodeList = tradingBox.getFeeCenterItemsList().stream().map(FeeCenterItems::getCntrNo).filter(Objects::nonNull)
+			.distinct().collect(Collectors.toList());
+		for (String item : boxCodeList) {
+			FeeCenterItems centerItems = tradingBox.getFeeCenterItemsList().stream().filter(e -> e.getCntrNo().equals(item))
+				.collect(Collectors.toList()).get(0);
+			FeeCenter feeCenter = new FeeCenter();
+			feeCenter.setBillType("箱东");
+			feeCenter.setCorpId(centerItems.getCorpId());
+			feeCenter.setCorpCnName(centerItems.getCorpCnName());
+			feeCenter.setCorpEnName(centerItems.getCorpEnName());
+			feeCenter.setCreateTime(new Date());
+			feeCenter.setCreateUser(AuthUtil.getUserId());
+			feeCenter.setCreateUserName(AuthUtil.getUserName());
+			feeCenter.setPid(detail.getId());
+			if ("OW-N".equals(detail.getType())) {
+				feeCenter.setDc("C");
+			} else {
+				feeCenter.setDc("D");
+			}
+			feeCenter.setFeeId(centerItems.getFeeId());
+			feeCenter.setFeeCode(centerItems.getFeeCode());
+			feeCenter.setFeeCnName(centerItems.getFeeCnName());
+			feeCenter.setFeeEnName(centerItems.getFeeEnName());
+			feeCenter.setCurCode(centerItems.getCurCode());
+			feeCenter.setCntrNo(centerItems.getCntrNo());
+			feeCenter.setUnitNo(centerItems.getUnitNo());
+			feeCenter.setStorageDate(centerItems.getStorageDate());
+			feeCenter.setDays(centerItems.getDays());
+			feeCenter.setExrate(centerItems.getExrate());
+			feeCenter.setAmount(centerItems.getAmount());
+			feeCenter.setAmountLoc(centerItems.getAmount().multiply(feeCenter.getExrate()));
+			feeCenter.setPrice(centerItems.getAmount());
+			feeCenter.setRemarks(centerItems.getRemarks());
+			feeCenter.setQuantity(new BigDecimal("1"));
+			feeCenter.setOutboundDate(tradingBox.getRentDate());
+			feeCenter.setBillNo(detail.getSysNo());
+			feeCenter.setBusinessType(detail.getType());
+			feeCenter.setBillDate(detail.getPurchaseDate());
+			feeCenter.setBillCorpId(detail.getPurchaseCompanyId());
+			feeCenter.setBillCorpCnName(detail.getPurchaseCompanyName());
+			feeCenter.setBillCorpEnName(detail.getPurchaseCompanyName());
+			feeCenter.setBillShortName(detail.getPurchaseCompanyName());
+			feeCenter.setMblno(detail.getContainerNumber());
+			feeCenter.setPolId(detail.getPolId());
+			feeCenter.setPolCode(detail.getPolCode());
+			feeCenter.setPolCnName(detail.getPolCname());
+			feeCenter.setPolEnName(detail.getPolEname());
+			feeCenter.setAutomaticGenerated("1");
+			if (new BigDecimal("0.00").compareTo(feeCenter.getAmount()) != 0) {
+				feeCenterList.add(feeCenter);
+			}
+		}
+		if (!feeCenterList.isEmpty()) {
+			feeCenterService.saveBatch(feeCenterList);
+			if (!feeCenters.isEmpty()) {
+				feeCenters.addAll(feeCenterList);
+			} else {
+				feeCenters = feeCenterList;
+			}
+			//费用数据
+			BigDecimal amountD = new BigDecimal("0.00");
+			BigDecimal amountC = new BigDecimal("0.00");
+			BigDecimal amountDUsd = new BigDecimal("0.00");
+			BigDecimal amountCUsd = new BigDecimal("0.00");
+			BigDecimal amountDrLoc = new BigDecimal("0.00");
+			BigDecimal amountCrLoc = new BigDecimal("0.00");
+			String exrateType = currencyUtils.standardCurrency(AuthUtil.getDeptId());
+			List<BCurExrate> curExrateList = currencyUtils.obtainRate(new Date(), "1", AuthUtil.getDeptId());
+			for (FeeCenter item : feeCenters) {
+				item.setAmountLoc(item.getAmount().multiply(item.getExrate()));
+				if (exrateType.equals(item.getCurCode())) {
+					if ("D".equals(item.getDc())) {
+						amountD = amountD.add(item.getAmount());
+						amountDrLoc = amountDrLoc.add(item.getAmount());
+					} else {
+						amountC = amountC.add(item.getAmount());
+						amountCrLoc = amountCrLoc.add(item.getAmount());
+					}
+				} else {
+					if ("D".equals(item.getDc())) {
+						amountDUsd = amountDUsd.add(item.getAmount());
+						amountDrLoc = amountDrLoc.add(item.getAmountLoc());
+					} else {
+						amountCUsd = amountCUsd.add(item.getAmount());
+						amountCrLoc = amountCrLoc.add(item.getAmountLoc());
+					}
+				}
+			}
+			detail.setAmountD(amountD);
+			detail.setAmountDUsd(amountDUsd);
+			detail.setTotalAmountD(amountDrLoc);
+			detail.setAmountC(amountC);
+			detail.setAmountCUsd(amountCUsd);
+			detail.setTotalAmountC(amountCrLoc);
+			detail.setProfit(detail.getAmountD().subtract(detail.getAmountC()));
+			detail.setProfitUsd(detail.getAmountDUsd().subtract(detail.getAmountCUsd()));
+			detail.setTotalProfit(detail.getTotalAmountD().subtract(detail.getTotalAmountC()));
+			baseMapper.updateById(detail);
+		}
+		List<FeeCenterItems> feeCenterItemsList = new ArrayList<>();
+		for (FeeCenter item : feeCenterList) {
+			List<FeeCenterItems> feeCenterItems = tradingBox.getFeeCenterItemsList().stream()
+				.filter(e -> e.getCntrNo().equals(item.getCntrNo())).collect(Collectors.toList());
+			for (FeeCenterItems centerItems : feeCenterItems) {
+				centerItems.setUpdateTime(new Date());
+				centerItems.setUpdateUserName(AuthUtil.getUserName());
+				centerItems.setUpdateUser(AuthUtil.getUserId());
+				centerItems.setWhetherGenerateCost("1");
+				centerItems.setFeeCenterId(item.getId());
+				feeCenterItemsList.add(centerItems);
+			}
+		}
+		if (!feeCenterItemsList.isEmpty()) {
+			feeCenterItemsService.updateBatchById(feeCenterItemsList);
+		}
+		return R.data(tradingBox);
+	}
+
 }

+ 15 - 3
blade-service/blade-los/src/main/java/org/springblade/los/business/sea/controller/BillsController.java

@@ -128,9 +128,13 @@ public class BillsController extends BladeController {
 			lambdaQueryWrapper.ge(Bills::getEtd, bills.getEtdList().get(0));
 			lambdaQueryWrapper.le(Bills::getEtd, bills.getEtdList().get(1));
 		}
-		if (ObjectUtils.isNotNull(bills.getEtaList()) && !bills.getEtaList().isEmpty()) {
-			lambdaQueryWrapper.ge(Bills::getEta, bills.getEtaList().get(0));
-			lambdaQueryWrapper.le(Bills::getEta, bills.getEtaList().get(1));
+		if (ObjectUtils.isNotNull(bills.getActualEtdList()) && !bills.getActualEtdList().isEmpty()) {
+			lambdaQueryWrapper.ge(Bills::getActualEtd, bills.getActualEtdList().get(0));
+			lambdaQueryWrapper.le(Bills::getActualEtd, bills.getActualEtdList().get(1));
+		}
+		if (ObjectUtils.isNotNull(bills.getActualEtaList()) && !bills.getActualEtaList().isEmpty()) {
+			lambdaQueryWrapper.ge(Bills::getActualEta, bills.getActualEtaList().get(0));
+			lambdaQueryWrapper.le(Bills::getActualEta, bills.getActualEtaList().get(1));
 		}
 		if (!AuthUtil.getUserRole().contains("总部") && !AuthUtil.getUserRole().contains("admin")  ) {
 			lambdaQueryWrapper.eq(Bills::getBranchId, AuthUtil.getDeptId());
@@ -657,6 +661,14 @@ public class BillsController extends BladeController {
 			lambdaQueryWrapper.ge(Bills::getEta, bills.getEtaList().get(0));
 			lambdaQueryWrapper.le(Bills::getEta, bills.getEtaList().get(1));
 		}
+		if (ObjectUtils.isNotNull(bills.getActualEtdList()) && !bills.getActualEtdList().isEmpty()) {
+			lambdaQueryWrapper.ge(Bills::getActualEtd, bills.getActualEtdList().get(0));
+			lambdaQueryWrapper.le(Bills::getActualEtd, bills.getActualEtdList().get(1));
+		}
+		if (ObjectUtils.isNotNull(bills.getActualEtaList()) && !bills.getActualEtaList().isEmpty()) {
+			lambdaQueryWrapper.ge(Bills::getActualEta, bills.getActualEtaList().get(0));
+			lambdaQueryWrapper.le(Bills::getActualEta, bills.getActualEtaList().get(1));
+		}
 		if (!AuthUtil.getUserRole().contains("总部") && !AuthUtil.getUserRole().contains("admin")) {
 			lambdaQueryWrapper.eq(Bills::getBranchId, AuthUtil.getDeptId());
 			if (!AuthUtil.getUserRole().contains("secondaryAdmin") && !AuthUtil.getUserRole().contains("财务") && !AuthUtil.getUserRole().contains("操作经理")) {

+ 136 - 0
blade-service/blade-los/src/main/java/org/springblade/los/finance/fee/controller/FeeCenterItemsController.java

@@ -0,0 +1,136 @@
+/*
+ *      Copyright (c) 2018-2028, Chill Zhuang All rights reserved.
+ *
+ *  Redistribution and use in source and binary forms, with or without
+ *  modification, are permitted provided that the following conditions are met:
+ *
+ *  Redistributions of source code must retain the above copyright notice,
+ *  this list of conditions and the following disclaimer.
+ *  Redistributions in binary form must reproduce the above copyright
+ *  notice, this list of conditions and the following disclaimer in the
+ *  documentation and/or other materials provided with the distribution.
+ *  Neither the name of the dreamlu.net developer nor the names of its
+ *  contributors may be used to endorse or promote products derived from
+ *  this software without specific prior written permission.
+ *  Author: Chill 庄骞 (smallchill@163.com)
+ */
+package org.springblade.los.finance.fee.controller;
+
+import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
+import com.baomidou.mybatisplus.core.metadata.IPage;
+import com.github.xiaoymin.knife4j.annotations.ApiOperationSupport;
+import io.swagger.annotations.Api;
+import io.swagger.annotations.ApiOperation;
+import io.swagger.annotations.ApiParam;
+import lombok.AllArgsConstructor;
+import org.springblade.core.boot.ctrl.BladeController;
+import org.springblade.core.mp.support.Condition;
+import org.springblade.core.mp.support.Query;
+import org.springblade.core.secure.utils.AuthUtil;
+import org.springblade.core.tool.api.R;
+import org.springblade.core.tool.utils.Func;
+import org.springblade.los.finance.fee.entity.FeeCenterItems;
+import org.springblade.los.finance.fee.service.IFeeCenterItemsService;
+import org.springblade.los.finance.fee.vo.FeeCenterItemsVO;
+import org.springframework.web.bind.annotation.*;
+
+import javax.validation.Valid;
+import java.util.List;
+
+/**
+ * OW 费用明细子表 控制器
+ *
+ * @author BladeX
+ * @since 2025-08-15
+ */
+@RestController
+@AllArgsConstructor
+@RequestMapping("/feecenteritems")
+@Api(value = "OW 费用明细子表", tags = "OW 费用明细子表接口")
+public class FeeCenterItemsController extends BladeController {
+
+	private final IFeeCenterItemsService feeCenterItemsService;
+
+	/**
+	 * 详情
+	 */
+	@GetMapping("/detail")
+	@ApiOperationSupport(order = 1)
+	@ApiOperation(value = "详情", notes = "传入feeCenterItems")
+	public R<FeeCenterItems> detail(FeeCenterItems feeCenterItems) {
+		FeeCenterItems detail = feeCenterItemsService.getOne(Condition.getQueryWrapper(feeCenterItems));
+		return R.data(detail);
+	}
+
+	/**
+	 * 分页 OW 费用明细子表
+	 */
+	@GetMapping("/list")
+	@ApiOperationSupport(order = 2)
+	@ApiOperation(value = "分页", notes = "传入feeCenterItems")
+	public R<List<FeeCenterItems>> list(FeeCenterItems feeCenterItems) {
+		LambdaQueryWrapper<FeeCenterItems> lambdaQueryWrapper = new LambdaQueryWrapper<>();
+		lambdaQueryWrapper.eq(FeeCenterItems::getTenantId, AuthUtil.getTenantId())
+			.eq(FeeCenterItems::getIsDeleted, 0)
+			.eq(FeeCenterItems::getPid, feeCenterItems.getPid())
+			.eq(FeeCenterItems::getFeeType, feeCenterItems.getFeeType())
+			.eq(FeeCenterItems::getCntrNo, feeCenterItems.getCntrNo())
+			.apply("DATE_FORMAT(account_date,'%Y-%m') = '" + feeCenterItems.getDate() + "'");
+		List<FeeCenterItems> pages = feeCenterItemsService.list(Condition.getQueryWrapper(feeCenterItems));
+		return R.data(pages);
+	}
+
+	/**
+	 * 自定义分页 OW 费用明细子表
+	 */
+	@GetMapping("/page")
+	@ApiOperationSupport(order = 3)
+	@ApiOperation(value = "分页", notes = "传入feeCenterItems")
+	public R<IPage<FeeCenterItemsVO>> page(FeeCenterItemsVO feeCenterItems, Query query) {
+		IPage<FeeCenterItemsVO> pages = feeCenterItemsService.selectFeeCenterItemsPage(Condition.getPage(query), feeCenterItems);
+		return R.data(pages);
+	}
+
+	/**
+	 * 新增 OW 费用明细子表
+	 */
+	@PostMapping("/save")
+	@ApiOperationSupport(order = 4)
+	@ApiOperation(value = "新增", notes = "传入feeCenterItems")
+	public R save(@Valid @RequestBody FeeCenterItems feeCenterItems) {
+		return R.status(feeCenterItemsService.save(feeCenterItems));
+	}
+
+	/**
+	 * 修改 OW 费用明细子表
+	 */
+	@PostMapping("/update")
+	@ApiOperationSupport(order = 5)
+	@ApiOperation(value = "修改", notes = "传入feeCenterItems")
+	public R update(@Valid @RequestBody FeeCenterItems feeCenterItems) {
+		return R.status(feeCenterItemsService.updateById(feeCenterItems));
+	}
+
+	/**
+	 * 新增或修改 OW 费用明细子表
+	 */
+	@PostMapping("/submit")
+	@ApiOperationSupport(order = 6)
+	@ApiOperation(value = "新增或修改", notes = "传入feeCenterItems")
+	public R submit(@Valid @RequestBody FeeCenterItems feeCenterItems) {
+		return R.status(feeCenterItemsService.saveOrUpdate(feeCenterItems));
+	}
+
+
+	/**
+	 * 删除 OW 费用明细子表
+	 */
+	@PostMapping("/remove")
+	@ApiOperationSupport(order = 8)
+	@ApiOperation(value = "删除", notes = "传入ids")
+	public R remove(@ApiParam(value = "主键集合", required = true) @RequestParam String ids) {
+		return R.status(feeCenterItemsService.removeByIds(Func.toLongList(ids)));
+	}
+
+
+}

+ 42 - 0
blade-service/blade-los/src/main/java/org/springblade/los/finance/fee/mapper/FeeCenterItemsMapper.java

@@ -0,0 +1,42 @@
+/*
+ *      Copyright (c) 2018-2028, Chill Zhuang All rights reserved.
+ *
+ *  Redistribution and use in source and binary forms, with or without
+ *  modification, are permitted provided that the following conditions are met:
+ *
+ *  Redistributions of source code must retain the above copyright notice,
+ *  this list of conditions and the following disclaimer.
+ *  Redistributions in binary form must reproduce the above copyright
+ *  notice, this list of conditions and the following disclaimer in the
+ *  documentation and/or other materials provided with the distribution.
+ *  Neither the name of the dreamlu.net developer nor the names of its
+ *  contributors may be used to endorse or promote products derived from
+ *  this software without specific prior written permission.
+ *  Author: Chill 庄骞 (smallchill@163.com)
+ */
+package org.springblade.los.finance.fee.mapper;
+
+import org.springblade.los.finance.fee.entity.FeeCenterItems;
+import org.springblade.los.finance.fee.vo.FeeCenterItemsVO;
+import com.baomidou.mybatisplus.core.mapper.BaseMapper;
+import com.baomidou.mybatisplus.core.metadata.IPage;
+import java.util.List;
+
+/**
+ * OW 费用明细子表 Mapper 接口
+ *
+ * @author BladeX
+ * @since 2025-08-15
+ */
+public interface FeeCenterItemsMapper extends BaseMapper<FeeCenterItems> {
+
+	/**
+	 * 自定义分页
+	 *
+	 * @param page
+	 * @param feeCenterItems
+	 * @return
+	 */
+	List<FeeCenterItemsVO> selectFeeCenterItemsPage(IPage page, FeeCenterItemsVO feeCenterItems);
+
+}

+ 68 - 0
blade-service/blade-los/src/main/java/org/springblade/los/finance/fee/mapper/FeeCenterItemsMapper.xml

@@ -0,0 +1,68 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!DOCTYPE mapper PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN" "http://mybatis.org/dtd/mybatis-3-mapper.dtd">
+<mapper namespace="org.springblade.los.finance.fee.mapper.FeeCenterItemsMapper">
+
+    <!-- 通用查询映射结果 -->
+    <resultMap id="feeCenterItemsResultMap" type="org.springblade.los.finance.fee.entity.FeeCenterItems">
+        <id column="id" property="id"/>
+        <result column="branch_id" property="branchId"/>
+        <result column="create_user" property="createUser"/>
+        <result column="create_user_name" property="createUserName"/>
+        <result column="create_time" property="createTime"/>
+        <result column="update_user" property="updateUser"/>
+        <result column="update_user_name" property="updateUserName"/>
+        <result column="update_time" property="updateTime"/>
+        <result column="pid" property="pid"/>
+        <result column="account_date" property="accountDate"/>
+        <result column="account_year" property="accountYear"/>
+        <result column="account_month" property="accountMonth"/>
+        <result column="account_day" property="accountDay"/>
+        <result column="corp_id" property="corpId"/>
+        <result column="corp_cn_name" property="corpCnName"/>
+        <result column="corp_en_name" property="corpEnName"/>
+        <result column="mblno" property="mblno"/>
+        <result column="hblno" property="hblno"/>
+        <result column="etd" property="etd"/>
+        <result column="eta" property="eta"/>
+        <result column="cntr_no" property="cntrNo"/>
+        <result column="pol_id" property="polId"/>
+        <result column="pol_code" property="polCode"/>
+        <result column="pol_cn_name" property="polCnName"/>
+        <result column="pol_en_name" property="polEnName"/>
+        <result column="pod_id" property="podId"/>
+        <result column="pod_code" property="podCode"/>
+        <result column="pod_cn_name" property="podCnName"/>
+        <result column="pod_en_name" property="podEnName"/>
+        <result column="fee_id" property="feeId"/>
+        <result column="fee_code" property="feeCode"/>
+        <result column="fee_cn_name" property="feeCnName"/>
+        <result column="fee_en_name" property="feeEnName"/>
+        <result column="unit_no" property="unitNo"/>
+        <result column="days" property="days"/>
+        <result column="price" property="price"/>
+        <result column="cur_code" property="curCode"/>
+        <result column="exrate" property="exrate"/>
+        <result column="amount" property="amount"/>
+        <result column="sort" property="sort"/>
+        <result column="is_deleted" property="isDeleted"/>
+        <result column="version" property="version"/>
+        <result column="status" property="status"/>
+        <result column="remarks" property="remarks"/>
+        <result column="storage_date" property="storageDate"/>
+        <result column="outbound_date" property="outboundDate"/>
+        <result column="fee_type" property="feeType"/>
+        <result column="src_item_id" property="srcItemId"/>
+        <result column="container_number" property="containerNumber"/>
+        <result column="branch_name" property="branchName"/>
+        <result column="pol_pre_appearance_date" property="polPreAppearanceDate"/>
+        <result column="pol_station_empty_container_exit_date" property="polStationEmptyContainerExitDate"/>
+        <result column="pol_return_date" property="polReturnDate"/>
+        <result column="pod_empty_container_return_date" property="podEmptyContainerReturnDate"/>
+    </resultMap>
+
+
+    <select id="selectFeeCenterItemsPage" resultMap="feeCenterItemsResultMap">
+        select * from los_fee_center_items where is_deleted = 0
+    </select>
+
+</mapper>

+ 41 - 0
blade-service/blade-los/src/main/java/org/springblade/los/finance/fee/service/IFeeCenterItemsService.java

@@ -0,0 +1,41 @@
+/*
+ *      Copyright (c) 2018-2028, Chill Zhuang All rights reserved.
+ *
+ *  Redistribution and use in source and binary forms, with or without
+ *  modification, are permitted provided that the following conditions are met:
+ *
+ *  Redistributions of source code must retain the above copyright notice,
+ *  this list of conditions and the following disclaimer.
+ *  Redistributions in binary form must reproduce the above copyright
+ *  notice, this list of conditions and the following disclaimer in the
+ *  documentation and/or other materials provided with the distribution.
+ *  Neither the name of the dreamlu.net developer nor the names of its
+ *  contributors may be used to endorse or promote products derived from
+ *  this software without specific prior written permission.
+ *  Author: Chill 庄骞 (smallchill@163.com)
+ */
+package org.springblade.los.finance.fee.service;
+
+import org.springblade.los.finance.fee.entity.FeeCenterItems;
+import org.springblade.los.finance.fee.vo.FeeCenterItemsVO;
+import com.baomidou.mybatisplus.extension.service.IService;
+import com.baomidou.mybatisplus.core.metadata.IPage;
+
+/**
+ * OW 费用明细子表 服务类
+ *
+ * @author BladeX
+ * @since 2025-08-15
+ */
+public interface IFeeCenterItemsService extends IService<FeeCenterItems> {
+
+	/**
+	 * 自定义分页
+	 *
+	 * @param page
+	 * @param feeCenterItems
+	 * @return
+	 */
+	IPage<FeeCenterItemsVO> selectFeeCenterItemsPage(IPage<FeeCenterItemsVO> page, FeeCenterItemsVO feeCenterItems);
+
+}

+ 41 - 0
blade-service/blade-los/src/main/java/org/springblade/los/finance/fee/service/impl/FeeCenterItemsServiceImpl.java

@@ -0,0 +1,41 @@
+/*
+ *      Copyright (c) 2018-2028, Chill Zhuang All rights reserved.
+ *
+ *  Redistribution and use in source and binary forms, with or without
+ *  modification, are permitted provided that the following conditions are met:
+ *
+ *  Redistributions of source code must retain the above copyright notice,
+ *  this list of conditions and the following disclaimer.
+ *  Redistributions in binary form must reproduce the above copyright
+ *  notice, this list of conditions and the following disclaimer in the
+ *  documentation and/or other materials provided with the distribution.
+ *  Neither the name of the dreamlu.net developer nor the names of its
+ *  contributors may be used to endorse or promote products derived from
+ *  this software without specific prior written permission.
+ *  Author: Chill 庄骞 (smallchill@163.com)
+ */
+package org.springblade.los.finance.fee.service.impl;
+
+import org.springblade.los.finance.fee.entity.FeeCenterItems;
+import org.springblade.los.finance.fee.vo.FeeCenterItemsVO;
+import org.springblade.los.finance.fee.mapper.FeeCenterItemsMapper;
+import org.springblade.los.finance.fee.service.IFeeCenterItemsService;
+import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
+import org.springframework.stereotype.Service;
+import com.baomidou.mybatisplus.core.metadata.IPage;
+
+/**
+ * OW 费用明细子表 服务实现类
+ *
+ * @author BladeX
+ * @since 2025-08-15
+ */
+@Service
+public class FeeCenterItemsServiceImpl extends ServiceImpl<FeeCenterItemsMapper, FeeCenterItems> implements IFeeCenterItemsService {
+
+	@Override
+	public IPage<FeeCenterItemsVO> selectFeeCenterItemsPage(IPage<FeeCenterItemsVO> page, FeeCenterItemsVO feeCenterItems) {
+		return page.setRecords(baseMapper.selectFeeCenterItemsPage(page, feeCenterItems));
+	}
+
+}

+ 50 - 6
blade-service/blade-los/src/main/java/org/springblade/los/finance/genleg/service/impl/FinPeriodServiceImpl.java

@@ -42,6 +42,9 @@ import org.springblade.los.finance.genleg.service.IFinGenlegCalcService;
 import org.springblade.los.finance.genleg.service.IFinGenlegService;
 import org.springblade.los.finance.genleg.service.IFinPeriodService;
 import org.springblade.los.finance.genleg.vo.FinPeriodVO;
+import org.springblade.los.finance.invoices.entity.FinInvoices;
+import org.springblade.los.finance.invoices.service.IFinInvoicesService;
+import org.springblade.los.finance.stl.entity.FinStlBills;
 import org.springblade.los.finance.stl.service.IFinStlBillsService;
 import org.springblade.system.feign.ISysClient;
 import org.springframework.stereotype.Service;
@@ -77,6 +80,8 @@ public class FinPeriodServiceImpl extends ServiceImpl<FinPeriodMapper, FinPeriod
 
 	private final IFinStlBillsService finStlBillsService;
 
+	private final IFinInvoicesService finInvoicesService;
+
 	private final IFinGenlegCalcService finGenlegCalcService;
 
 	private final IFinGenlegService finGenlegService;
@@ -278,6 +283,45 @@ public class FinPeriodServiceImpl extends ServiceImpl<FinPeriodMapper, FinPeriod
 			reviewFailedExcel.setOperator(item.getOperatorName());
 			reviewFailedExcelList.add(reviewFailedExcel);
 		}
+		List<FinStlBills> finStlBillsLis = finStlBillsService.list(new LambdaQueryWrapper<FinStlBills>()
+			.eq(FinStlBills::getTenantId, AuthUtil.getTenantId())
+			.eq(FinStlBills::getIsDeleted, 0)
+			.eq(FinStlBills::getBranchId, detail.getBranchId())
+			.ne(FinStlBills::getBillStatus, "3"));
+		if (!finStlBillsLis.isEmpty()) {
+			for (FinStlBills item : finStlBillsLis) {
+				ReviewFailedExcel reviewFailedExcel = new ReviewFailedExcel();
+				if ("FFSQ".equals(item.getBusinessType())) {
+					reviewFailedExcel.setBusinessType("付费申请");
+				} else {
+					reviewFailedExcel.setBusinessType("结算中心");
+				}
+				reviewFailedExcel.setBillNo(item.getBillNo());
+				reviewFailedExcel.setBusinessDate(item.getBillDate());
+				reviewFailedExcel.setMblno(item.getMblno());
+				reviewFailedExcel.setOperator(item.getOperatorName());
+				reviewFailedExcelList.add(reviewFailedExcel);
+			}
+		}
+		List<FinInvoices> finInvoicesList = finInvoicesService.list(new LambdaQueryWrapper<FinInvoices>()
+			.eq(FinInvoices::getTenantId, AuthUtil.getTenantId())
+			.eq(FinInvoices::getIsDeleted, 0)
+			.eq(FinInvoices::getBranchId, detail.getBranchId())
+			.ne(FinInvoices::getBillStatus, "3"));
+		if (!finInvoicesList.isEmpty()) {
+			for (FinInvoices item : finInvoicesList) {
+				ReviewFailedExcel reviewFailedExcel = new ReviewFailedExcel();
+				if ("FPSQ".equals(item.getType())) {
+					reviewFailedExcel.setBusinessType("发票申请");
+				} else {
+					reviewFailedExcel.setBusinessType("销项发票");
+				}
+				reviewFailedExcel.setBillNo(item.getBillNo());
+				reviewFailedExcel.setBusinessDate(item.getBillDate());
+				reviewFailedExcel.setMblno(item.getMblno());
+				reviewFailedExcelList.add(reviewFailedExcel);
+			}
+		}
 		if (!reviewFailedExcelList.isEmpty()) {
 			return R.data(reviewFailedExcelList, "审核未通过");
 		}
@@ -531,12 +575,12 @@ public class FinPeriodServiceImpl extends ServiceImpl<FinPeriodMapper, FinPeriod
 		String deptId;
 		String deptName = "";
 		String branchId;
-		if (ObjectUtils.isNotNull(finPeriod.getBranchId())){
-			 deptId = finPeriod.getBranchId();
-			 branchId = finPeriod.getBranchId();
-		}else{
-			 deptId = AuthUtil.getDeptId();
-			 branchId = AuthUtil.getDeptId();
+		if (ObjectUtils.isNotNull(finPeriod.getBranchId())) {
+			deptId = finPeriod.getBranchId();
+			branchId = finPeriod.getBranchId();
+		} else {
+			deptId = AuthUtil.getDeptId();
+			branchId = AuthUtil.getDeptId();
 		}
 		//获取部门ids对应中文名
 		R<List<String>> res = sysClient.getDeptNames(branchId);

+ 45 - 0
blade-service/blade-los/src/main/java/org/springblade/los/finance/invoices/service/impl/FinInvoicesServiceImpl.java

@@ -38,6 +38,8 @@ import org.springblade.los.finance.fee.entity.FeeCenter;
 import org.springblade.los.finance.fee.entity.FinAccBills;
 import org.springblade.los.finance.fee.service.IFeeCenterService;
 import org.springblade.los.finance.fee.service.IFinAccBillsService;
+import org.springblade.los.finance.genleg.entity.FinPeriod;
+import org.springblade.los.finance.genleg.mapper.FinPeriodMapper;
 import org.springblade.los.finance.invoices.entity.FinInvoiceItemDetail;
 import org.springblade.los.finance.invoices.entity.FinInvoices;
 import org.springblade.los.finance.invoices.entity.FinInvoicesItems;
@@ -53,6 +55,8 @@ import org.springframework.transaction.interceptor.TransactionAspectSupport;
 
 import java.math.BigDecimal;
 import java.math.MathContext;
+import java.time.LocalDate;
+import java.time.ZoneId;
 import java.util.ArrayList;
 import java.util.Date;
 import java.util.List;
@@ -88,6 +92,8 @@ public class FinInvoicesServiceImpl extends ServiceImpl<FinInvoicesMapper, FinIn
 
 	private final IFilesCenterService filesCenterService;
 
+	private final FinPeriodMapper finPeriodMapper;
+
 	@Override
 	public IPage<FinInvoicesVO> selectFinInvoicesPage(IPage<FinInvoicesVO> page, FinInvoicesVO finInvoices) {
 		return page.setRecords(baseMapper.selectFinInvoicesPage(page, finInvoices));
@@ -161,6 +167,7 @@ public class FinInvoicesServiceImpl extends ServiceImpl<FinInvoicesMapper, FinIn
 				//计算字段null值处理
 				item.setCurrentAmount(ObjectUtils.isNotNull(item.getCurrentAmount()) ? item.getCurrentAmount() : new BigDecimal("0.00"));
 				item.setAmount(ObjectUtils.isNotNull(item.getAmount()) ? item.getAmount() : new BigDecimal("0.00"));
+				item.setCurrentExrate(finInvoices.getExrate());
 				//判断是否是本位币
 				if (exrateType.equals(item.getCurrentCurCode())) {
 					item.setCurrentAmountLoc(item.getCurrentAmount());
@@ -659,6 +666,25 @@ public class FinInvoicesServiceImpl extends ServiceImpl<FinInvoicesMapper, FinIn
 			throw new RuntimeException("缺少必要参数");
 		}
 		FinInvoices detail = baseMapper.selectById(finInvoices.getId());
+		if (ObjectUtils.isNotNull(detail.getInvoiceDate())) {
+			LocalDate date = detail.getInvoiceDate().toInstant().atZone(ZoneId.systemDefault()).toLocalDate();
+			int year = date.getYear();
+			int month = date.getMonthValue();
+			FinPeriod finPeriod = finPeriodMapper.selectOne(new LambdaQueryWrapper<FinPeriod>()
+				.eq(FinPeriod::getTenantId, AuthUtil.getTenantId())
+				.eq(FinPeriod::getBranchId, detail.getInvoiceDate())
+				.eq(FinPeriod::getIsDeleted, 0)
+				.eq(FinPeriod::getPeriodYear, year)
+				.eq(FinPeriod::getPeriodMonth, month));
+			if (finPeriod != null) {
+				if (1 == finPeriod.getIsClosed()) {
+					throw new RuntimeException(year + "年" + month + "月账期已结转,撤销失败");
+				}
+				if (1 == finPeriod.getLockingStatus()) {
+					throw new RuntimeException(year + "年" + month + "月账期已锁定,撤销失败");
+				}
+			}
+		}
 		if ("1".equals(detail.getBillStatus())) {
 			throw new RuntimeException("单据已结算,撤销失败");
 		}
@@ -905,6 +931,25 @@ public class FinInvoicesServiceImpl extends ServiceImpl<FinInvoicesMapper, FinIn
 			throw new RuntimeException("缺少必要参数");
 		}
 		FinInvoices detail = baseMapper.selectById(finInvoices.getId());
+		if (ObjectUtils.isNotNull(detail.getInvoiceDate())) {
+			LocalDate date = detail.getInvoiceDate().toInstant().atZone(ZoneId.systemDefault()).toLocalDate();
+			int year = date.getYear();
+			int month = date.getMonthValue();
+			FinPeriod finPeriod = finPeriodMapper.selectOne(new LambdaQueryWrapper<FinPeriod>()
+				.eq(FinPeriod::getTenantId, AuthUtil.getTenantId())
+				.eq(FinPeriod::getBranchId, detail.getInvoiceDate())
+				.eq(FinPeriod::getIsDeleted, 0)
+				.eq(FinPeriod::getPeriodYear, year)
+				.eq(FinPeriod::getPeriodMonth, month));
+			if (finPeriod != null) {
+				if (1 == finPeriod.getIsClosed()) {
+					throw new RuntimeException(year + "年" + month + "月账期已结转,撤销失败");
+				}
+				if (1 == finPeriod.getLockingStatus()) {
+					throw new RuntimeException(year + "年" + month + "月账期已锁定,撤销失败");
+				}
+			}
+		}
 		String exrateType = currencyUtils.standardCurrency(detail.getBranchId());
 		List<FeeCenter> feeCenterList = new ArrayList<>();
 		List<FinAccBills> finAccBillsList = new ArrayList<>();

+ 39 - 1
blade-service/blade-los/src/main/java/org/springblade/los/finance/stl/service/impl/FinStlBillsServiceImpl.java

@@ -165,7 +165,7 @@ public class FinStlBillsServiceImpl extends ServiceImpl<FinStlBillsMapper, FinSt
 		if (res.isSuccess() && ObjectUtils.isNotNull(res.getData())) {
 			deptName = res.getData();
 		}
-		if (ObjectUtils.isNotNull(finStlBills.getBillDate()) && "STL".equals(finStlBills.getBusinessType())) {
+		if (ObjectUtils.isNotNull(finStlBills.getBillDate()) && "STL,FFSQ".contains(finStlBills.getBusinessType())) {
 			LocalDate date = finStlBills.getBillDate().toInstant().atZone(ZoneId.systemDefault()).toLocalDate();
 			int year = date.getYear();
 			int month = date.getMonthValue();
@@ -1207,6 +1207,25 @@ public class FinStlBillsServiceImpl extends ServiceImpl<FinStlBillsMapper, FinSt
 			throw new RuntimeException("缺少必要参数");
 		}
 		FinStlBills detail = baseMapper.selectById(finStlBills.getId());
+		if (ObjectUtils.isNotNull(detail.getBillDate())) {
+			LocalDate date = detail.getBillDate().toInstant().atZone(ZoneId.systemDefault()).toLocalDate();
+			int year = date.getYear();
+			int month = date.getMonthValue();
+			FinPeriod finPeriod = finPeriodMapper.selectOne(new LambdaQueryWrapper<FinPeriod>()
+				.eq(FinPeriod::getTenantId, AuthUtil.getTenantId())
+				.eq(FinPeriod::getBranchId, detail.getBillDate())
+				.eq(FinPeriod::getIsDeleted, 0)
+				.eq(FinPeriod::getPeriodYear, year)
+				.eq(FinPeriod::getPeriodMonth, month));
+			if (finPeriod != null) {
+				if (1 == finPeriod.getIsClosed()) {
+					throw new RuntimeException(year + "年" + month + "月账期已结转,撤销失败");
+				}
+				if (1 == finPeriod.getLockingStatus()) {
+					throw new RuntimeException(year + "年" + month + "月账期已锁定,撤销失败");
+				}
+			}
+		}
 		if (ObjectUtils.isNotNull(finStlBills.getFinStlBillsItemsList())) {
 			List<Long> ids = finStlBills.getFinStlBillsItemsList().stream().map(FinStlBillsItems::getSrcIdInvoices).filter(Objects::nonNull).collect(Collectors.toList());
 			if (!ids.isEmpty()) {
@@ -1850,6 +1869,25 @@ public class FinStlBillsServiceImpl extends ServiceImpl<FinStlBillsMapper, FinSt
 		}
 		FinStlBills detail = baseMapper.selectById(finStlBills.getId());
 		String exrateType = currencyUtils.standardCurrency(detail.getBranchId());
+		if (ObjectUtils.isNotNull(detail.getBillDate())) {
+			LocalDate date = detail.getBillDate().toInstant().atZone(ZoneId.systemDefault()).toLocalDate();
+			int year = date.getYear();
+			int month = date.getMonthValue();
+			FinPeriod finPeriod = finPeriodMapper.selectOne(new LambdaQueryWrapper<FinPeriod>()
+				.eq(FinPeriod::getTenantId, AuthUtil.getTenantId())
+				.eq(FinPeriod::getBranchId, detail.getBillDate())
+				.eq(FinPeriod::getIsDeleted, 0)
+				.eq(FinPeriod::getPeriodYear, year)
+				.eq(FinPeriod::getPeriodMonth, month));
+			if (finPeriod != null) {
+				if (1 == finPeriod.getIsClosed()) {
+					throw new RuntimeException(year + "年" + month + "月账期已结转,撤销失败");
+				}
+				if (1 == finPeriod.getLockingStatus()) {
+					throw new RuntimeException(year + "年" + month + "月账期已锁定,撤销失败");
+				}
+			}
+		}
 		if (ObjectUtils.isNotNull(finStlBills.getFinStlBillsItemsList())) {
 			/*if (detail.getStatus() > 1) {
 				throw new RuntimeException("正在审核中,撤销失败");