|
@@ -49,6 +49,7 @@ import org.springframework.data.redis.core.RedisTemplate;
|
|
|
|
|
|
|
|
import java.math.BigDecimal;
|
|
import java.math.BigDecimal;
|
|
|
import java.time.LocalDateTime;
|
|
import java.time.LocalDateTime;
|
|
|
|
|
+import java.time.ZoneId;
|
|
|
import java.util.*;
|
|
import java.util.*;
|
|
|
import java.util.concurrent.TimeUnit;
|
|
import java.util.concurrent.TimeUnit;
|
|
|
import java.util.stream.Collectors;
|
|
import java.util.stream.Collectors;
|
|
@@ -307,6 +308,117 @@ public class RemoteContractServiceImpl implements RemoteContractService {
|
|
|
return kwcContractTradeMapper.queryNewSignPrice(entId, goodsId, time);
|
|
return kwcContractTradeMapper.queryNewSignPrice(entId, goodsId, time);
|
|
|
}
|
|
}
|
|
|
|
|
|
|
|
|
|
+ /**
|
|
|
|
|
+ * 根据企业ID、商品ID和指定时间,查询该企业在当时有效的最新贸易合同中的商品价格。
|
|
|
|
|
+ * <p>
|
|
|
|
|
+ * 业务逻辑:
|
|
|
|
|
+ * 1. 参数校验:确保 entId, goodsId, time 不为空。
|
|
|
|
|
+ * 2. 查找关联合同:查询该企业(作为供应商或采购商)参与的所有未删除的贸易合同单元,获取合同ID列表。
|
|
|
|
|
+ * 3. 筛选商品关联:在上述合同ID列表中,查找包含指定商品ID且未删除的合同商品记录。
|
|
|
|
|
+ * 4. 构建映射:将合同商品记录以 contractId 为 key 建立映射,方便后续快速查找。
|
|
|
|
|
+ * 5. 确定有效合同:在筛选出的合同中,查找满足以下条件的唯一最新合同:
|
|
|
|
|
+ * - 状态为已签约 (SIGNED)
|
|
|
|
|
+ * - 未删除
|
|
|
|
|
+ * - 指定时间在合同有效期内 (startTime <= time < endTime 或 endTime 为空)
|
|
|
|
|
+ * - 按创建时间倒序排列,取第一条(即最近创建的符合条件的合同)
|
|
|
|
|
+ * 6. 返回结果:如果找到有效合同,返回对应的合同ID、商品ID和价格;否则返回 null。
|
|
|
|
|
+ *
|
|
|
|
|
+ * @param entId 企业ID
|
|
|
|
|
+ * @param goodsId 商品ID
|
|
|
|
|
+ * @param time 查询时间点
|
|
|
|
|
+ * @return 贸易合同商品信息DTO,包含合同ID、商品ID和价格;若无匹配数据则返回 null
|
|
|
|
|
+ */
|
|
|
|
|
+ @Override
|
|
|
|
|
+ public TradeContractGoodsDto queryTradeContractNewByEnt(Long entId, Long goodsId, LocalDateTime time) {
|
|
|
|
|
+ // 1. 参数校验
|
|
|
|
|
+ if (Objects.isNull(entId) || Objects.isNull(goodsId) || Objects.isNull(time)) {
|
|
|
|
|
+ log.warn("查询企业商品最新签约价参数异常,entId:{},goodsId:{},time:{}", entId, goodsId, time);
|
|
|
|
|
+ return null;
|
|
|
|
|
+ }
|
|
|
|
|
+
|
|
|
|
|
+ log.debug("开始查询企业[{}]商品[{}]在时间[{}]的最新签约价", entId, goodsId, time);
|
|
|
|
|
+
|
|
|
|
|
+ // 将 LocalDateTime 转换为 Date 用于数据库查询
|
|
|
|
|
+ Date queryTime = Date.from(time.atZone(ZoneId.systemDefault()).toInstant());
|
|
|
|
|
+
|
|
|
|
|
+ // 2. 查找该企业参与的所有有效贸易合同ID
|
|
|
|
|
+ // 条件:未删除、企业ID匹配、单位类型为供应商或采购商
|
|
|
|
|
+ List<Long> contractIdsByEnt = kwcContractTradeUnitMapper.selectList(new LambdaQueryWrapper<KwcContractTradeUnit>()
|
|
|
|
|
+ .eq(KwcContractTradeUnit::getDelFlag, Global.NO)
|
|
|
|
|
+ .eq(KwcContractTradeUnit::getEntId, entId)
|
|
|
|
|
+ .in(KwcContractTradeUnit::getUnitType, List.of(CooperateTypeEnum.SUPPLIER.getCode(), CooperateTypeEnum.PURCHASER.getCode())))
|
|
|
|
|
+ .stream()
|
|
|
|
|
+ .map(KwcContractTradeUnit::getContractId)
|
|
|
|
|
+ .filter(Objects::nonNull)
|
|
|
|
|
+ .distinct()
|
|
|
|
|
+ .toList();
|
|
|
|
|
+
|
|
|
|
|
+ if (CollectionUtils.isEmpty(contractIdsByEnt)) {
|
|
|
|
|
+ log.debug("企业[{}]未找到任何关联的贸易合同单元", entId);
|
|
|
|
|
+ return null;
|
|
|
|
|
+ }
|
|
|
|
|
+ log.debug("企业[{}]关联的合同ID数量: {}", entId, contractIdsByEnt.size());
|
|
|
|
|
+
|
|
|
|
|
+ // 3. 在这些合同中查找包含指定商品的记录
|
|
|
|
|
+ List<KwcContractTradeGoods> contractGoods = kwcContractTradeGoodsMapper.selectList(new LambdaQueryWrapper<KwcContractTradeGoods>()
|
|
|
|
|
+ .eq(KwcContractTradeGoods::getDelFlag, Global.NO)
|
|
|
|
|
+ .eq(KwcContractTradeGoods::getGoodsId, goodsId)
|
|
|
|
|
+ .in(KwcContractTradeGoods::getContractId, contractIdsByEnt));
|
|
|
|
|
+
|
|
|
|
|
+ if (CollectionUtils.isEmpty(contractGoods)) {
|
|
|
|
|
+ log.debug("在企业[{}]的合同中找到商品[{}]的记录为空", entId, goodsId);
|
|
|
|
|
+ return null;
|
|
|
|
|
+ }
|
|
|
|
|
+
|
|
|
|
|
+ // 4. 构建合同ID到合同商品对象的映射,以便后续通过合同ID快速获取商品信息
|
|
|
|
|
+ Map<Long, KwcContractTradeGoods> contractGoodsMap = contractGoods.stream()
|
|
|
|
|
+ .filter(item -> Objects.nonNull(item.getContractId()))
|
|
|
|
|
+ .collect(Collectors.toMap(KwcContractTradeGoods::getContractId, item -> item, (oldValue, newValue) -> oldValue));
|
|
|
|
|
+
|
|
|
|
|
+ if (CollectionUtils.isEmpty(contractGoodsMap)) {
|
|
|
|
|
+ log.warn("构建合同商品映射失败,contractGoodsMap为空");
|
|
|
|
|
+ return null;
|
|
|
|
|
+ }
|
|
|
|
|
+
|
|
|
|
|
+ // 5. 查询在指定时间点有效的最新已签约合同
|
|
|
|
|
+ // 条件:
|
|
|
|
|
+ // - 未删除
|
|
|
|
|
+ // - 状态为已签约
|
|
|
|
|
+ // - 合同ID在之前筛选出的包含该商品的合同ID集合中
|
|
|
|
|
+ // - 合同开始时间 <= 查询时间
|
|
|
|
|
+ // - 合同结束时间 > 查询时间 或 结束时间为空(表示长期有效)
|
|
|
|
|
+ // - 按创建时间倒序,取最新的一条
|
|
|
|
|
+ KwcContractTrade contractTrade = kwcContractTradeMapper.selectOne(new LambdaQueryWrapper<KwcContractTrade>()
|
|
|
|
|
+ .eq(KwcContractTrade::getDelFlag, Global.NO)
|
|
|
|
|
+ .eq(KwcContractTrade::getStatus, ContractStatusEnum.SIGNED.getCode())
|
|
|
|
|
+ .in(KwcContractTrade::getId, contractGoodsMap.keySet())
|
|
|
|
|
+ .lt(KwcContractTrade::getStartTime, queryTime)
|
|
|
|
|
+ .and(wrapper -> wrapper.gt(KwcContractTrade::getEndTime, queryTime).or().isNull(KwcContractTrade::getEndTime))
|
|
|
|
|
+ .orderByDesc(KwcContractTrade::getCreateTime)
|
|
|
|
|
+ .last("limit 1"));
|
|
|
|
|
+
|
|
|
|
|
+ if (Objects.isNull(contractTrade)) {
|
|
|
|
|
+ log.debug("未找到企业[{}]商品[{}]在时间[{}]的有效已签约合同", entId, goodsId, time);
|
|
|
|
|
+ return null;
|
|
|
|
|
+ }
|
|
|
|
|
+ log.info("找到企业[{}]商品[{}]的有效合同ID: {}", entId, goodsId, contractTrade.getId());
|
|
|
|
|
+
|
|
|
|
|
+ // 6. 从映射中获取对应的商品信息并组装返回对象
|
|
|
|
|
+ KwcContractTradeGoods newestContractGoods = contractGoodsMap.get(contractTrade.getId());
|
|
|
|
|
+ if (Objects.isNull(newestContractGoods)) {
|
|
|
|
|
+ log.error("数据不一致:合同ID[{}]在contractGoodsMap中不存在", contractTrade.getId());
|
|
|
|
|
+ return null;
|
|
|
|
|
+ }
|
|
|
|
|
+
|
|
|
|
|
+ TradeContractGoodsDto tradeContractGoodsDto = new TradeContractGoodsDto();
|
|
|
|
|
+ tradeContractGoodsDto.setContractId(contractTrade.getId());
|
|
|
|
|
+ tradeContractGoodsDto.setGoodsId(goodsId);
|
|
|
|
|
+ tradeContractGoodsDto.setPrice(newestContractGoods.getPrice());
|
|
|
|
|
+
|
|
|
|
|
+ log.debug("查询成功,返回合同ID: {}, 价格: {}", tradeContractGoodsDto.getContractId(), tradeContractGoodsDto.getPrice());
|
|
|
|
|
+ return tradeContractGoodsDto;
|
|
|
|
|
+ }
|
|
|
|
|
+
|
|
|
@Override
|
|
@Override
|
|
|
public List<Long> queryNewSignGoods(Long entId, LocalDateTime time) {
|
|
public List<Long> queryNewSignGoods(Long entId, LocalDateTime time) {
|
|
|
return kwcContractTradeMapper.queryNewSignGoods(entId, time);
|
|
return kwcContractTradeMapper.queryNewSignGoods(entId, time);
|