fix(lease): 修复仓库出租率导出总面积、日租率计算错误
导出时总面积被算成全系统所有仓库库区面积之和(6168),日租率因此也错误(0.16)。 根因:导出方法调用 warehouseOccupancyRate(),该方法在不传 warehouseId 时 totalArea 会累加所有仓库面积。 - 导出方法不再调用 warehouseOccupancyRate(),改为自行按(业务日期+仓库)维度计算 - 总面积按仓库单独累加库区面积(通宇关务测试仓库 100,不再 6168) - 整租/散租面积按(日期+仓库)聚合 - 日租率 = (整租+散租)/该仓库总面积×100,直接输出百分比(10.00) - 增加总面积为0的除零保护 - 查询接口 warehouseOccupancyRate() 不受影响
This commit is contained in:
+57
-21
@@ -508,24 +508,53 @@ public class LeaseApplicationService {
|
||||
* 参数与 /warehouseOccupancyRate、/list 一致
|
||||
*/
|
||||
public void exportOccupancyRate(HttpServletResponse response, ShipperLeaseDetailsDO shipperLeaseDetailsDO) throws IOException {
|
||||
// ===== 1. 查出租率(注意:该方法内部会修改传入的 DO,所以先查它)=====
|
||||
List<WarehouseOccupancyRate> rateList = warehouseOccupancyRate(shipperLeaseDetailsDO);
|
||||
// 注意:本方法不调用 warehouseOccupancyRate(),因为该方法在不传 warehouseId 时
|
||||
// totalArea 会算成全系统所有仓库库区面积之和(如 6168),导致导出面积/日租率错误。
|
||||
// 这里自行按 (业务日期 + 仓库) 维度计算,保证多仓库导出时每个仓库的面积/日租率正确。
|
||||
|
||||
// ===== 2. 用副本查明细,避免被上面改过的 DO 影响 =====
|
||||
// ===== 1. 查全部明细(用副本 DO,避免影响外部)=====
|
||||
ShipperLeaseDetailsDO detailDO = new ShipperLeaseDetailsDO();
|
||||
BeanUtils.copyProperties(shipperLeaseDetailsDO, detailDO);
|
||||
List<ShipperLeaseDetailsPO> detailList = shipperLeaseDetailsService.queryList(detailDO);
|
||||
|
||||
// ===== 3. 出租率按 (业务日期 + 仓库ID) 建映射,方便明细行查汇总 =====
|
||||
SimpleDateFormat keySdf = new SimpleDateFormat("yyyy-MM-dd");
|
||||
Map<String, WarehouseOccupancyRate> rateMap = new HashMap<>();
|
||||
for (WarehouseOccupancyRate r : rateList) {
|
||||
String key = (r.getBusinessDate() == null ? "" : keySdf.format(r.getBusinessDate()))
|
||||
+ "_" + r.getWarehouseId();
|
||||
rateMap.put(key, r);
|
||||
if (detailList == null) {
|
||||
detailList = new ArrayList<>();
|
||||
}
|
||||
|
||||
// ===== 4. 明细为主,每行拼上对应仓库当天的汇总 =====
|
||||
// ===== 2. 预算每个仓库的总面积(启用库区的 storageRegion 累加),建 warehouseId -> totalArea 映射 =====
|
||||
Set<Long> warehouseIds = detailList.stream()
|
||||
.map(ShipperLeaseDetailsPO::getWarehouseId)
|
||||
.filter(Objects::nonNull)
|
||||
.collect(Collectors.toSet());
|
||||
Map<Long, BigDecimal> warehouseTotalAreaMap = new HashMap<>();
|
||||
for (Long wid : warehouseIds) {
|
||||
StorageSectionDO storageSectionDO = new StorageSectionDO();
|
||||
storageSectionDO.setWarehouseId(wid);
|
||||
storageSectionDO.setOpeningUp(1);
|
||||
List<StorageSectionPO> sections = storageSectionApplicationService.queryList(storageSectionDO);
|
||||
BigDecimal area = BigDecimal.ZERO;
|
||||
for (StorageSectionPO s : sections) {
|
||||
area = area.add(s.getStorageRegion() == null ? BigDecimal.ZERO : s.getStorageRegion());
|
||||
}
|
||||
warehouseTotalAreaMap.put(wid, area);
|
||||
}
|
||||
|
||||
// ===== 3. 按 (业务日期 + 仓库ID) 聚合,算每个仓库当天的整租/散租面积 =====
|
||||
// summaryMap: key -> [整租面积, 散租面积]
|
||||
SimpleDateFormat keySdf = new SimpleDateFormat("yyyy-MM-dd");
|
||||
Map<String, BigDecimal[]> summaryMap = new HashMap<>();
|
||||
for (ShipperLeaseDetailsPO d : detailList) {
|
||||
String key = (d.getBusinessDate() == null ? "" : keySdf.format(d.getBusinessDate()))
|
||||
+ "_" + d.getWarehouseId();
|
||||
BigDecimal[] arr = summaryMap.computeIfAbsent(key, k -> new BigDecimal[]{BigDecimal.ZERO, BigDecimal.ZERO});
|
||||
BigDecimal leaseArea = d.getLeaseArea() == null ? BigDecimal.ZERO : d.getLeaseArea();
|
||||
if ("整租".equals(d.getLeaseType())) {
|
||||
arr[0] = arr[0].add(leaseArea);
|
||||
} else {
|
||||
arr[1] = arr[1].add(leaseArea);
|
||||
}
|
||||
}
|
||||
|
||||
// ===== 4. 明细为主,每行拼上对应仓库当天的汇总(总面积/日租率按仓库单独算)=====
|
||||
List<WarehouseLeaseExportVO> exportList = new ArrayList<>();
|
||||
for (ShipperLeaseDetailsPO d : detailList) {
|
||||
WarehouseLeaseExportVO vo = new WarehouseLeaseExportVO();
|
||||
@@ -536,20 +565,27 @@ public class LeaseApplicationService {
|
||||
vo.setCargoOwnerName(d.getCargoOwnerName());
|
||||
vo.setLeaseType(d.getLeaseType());
|
||||
vo.setLeaseArea(d.getLeaseArea());
|
||||
// 汇总列(从映射取,找不到就留空)
|
||||
// 汇总列
|
||||
String key = (d.getBusinessDate() == null ? "" : keySdf.format(d.getBusinessDate()))
|
||||
+ "_" + d.getWarehouseId();
|
||||
WarehouseOccupancyRate r = rateMap.get(key);
|
||||
if (r != null) {
|
||||
vo.setEntireLeaseArea(r.getEntireLeaseArea());
|
||||
vo.setFractionalLeaseArea(r.getFractionalLeaseArea());
|
||||
vo.setTotalArea(r.getTotalArea());
|
||||
vo.setDailyRentalRate(r.getDailyRentalRate());
|
||||
}
|
||||
BigDecimal[] arr = summaryMap.get(key);
|
||||
BigDecimal entireLeaseArea = (arr != null) ? arr[0] : BigDecimal.ZERO;
|
||||
BigDecimal fractionalLeaseArea = (arr != null) ? arr[1] : BigDecimal.ZERO;
|
||||
vo.setEntireLeaseArea(entireLeaseArea);
|
||||
vo.setFractionalLeaseArea(fractionalLeaseArea);
|
||||
// 该仓库的总面积(按仓库单独算,不再用全局总和)
|
||||
BigDecimal widTotalArea = warehouseTotalAreaMap.getOrDefault(d.getWarehouseId(), BigDecimal.ZERO);
|
||||
vo.setTotalArea(widTotalArea);
|
||||
// 日租率 = (整租+散租) / 总面积 × 100,保留2位小数(直接输出百分比值,如 10.00)
|
||||
BigDecimal leaseSum = entireLeaseArea.add(fractionalLeaseArea);
|
||||
BigDecimal dailyRate = widTotalArea.compareTo(BigDecimal.ZERO) == 0
|
||||
? BigDecimal.ZERO
|
||||
: leaseSum.multiply(new BigDecimal("100")).divide(widTotalArea, 2, BigDecimal.ROUND_HALF_UP);
|
||||
vo.setDailyRentalRate(dailyRate);
|
||||
exportList.add(vo);
|
||||
}
|
||||
|
||||
// ===== 5. 按业务日期降序排序(null 排最后)=====
|
||||
// ===== 5. 按业务日期降序、仓库名升序排序(null 排最后)=====
|
||||
exportList.sort(Comparator
|
||||
.comparing(WarehouseLeaseExportVO::getBusinessDate, Comparator.nullsLast(Comparator.reverseOrder()))
|
||||
.thenComparing(WarehouseLeaseExportVO::getWarehouseName, Comparator.nullsLast(Comparator.naturalOrder())));
|
||||
|
||||
Reference in New Issue
Block a user