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 一致
|
* 参数与 /warehouseOccupancyRate、/list 一致
|
||||||
*/
|
*/
|
||||||
public void exportOccupancyRate(HttpServletResponse response, ShipperLeaseDetailsDO shipperLeaseDetailsDO) throws IOException {
|
public void exportOccupancyRate(HttpServletResponse response, ShipperLeaseDetailsDO shipperLeaseDetailsDO) throws IOException {
|
||||||
// ===== 1. 查出租率(注意:该方法内部会修改传入的 DO,所以先查它)=====
|
// 注意:本方法不调用 warehouseOccupancyRate(),因为该方法在不传 warehouseId 时
|
||||||
List<WarehouseOccupancyRate> rateList = warehouseOccupancyRate(shipperLeaseDetailsDO);
|
// totalArea 会算成全系统所有仓库库区面积之和(如 6168),导致导出面积/日租率错误。
|
||||||
|
// 这里自行按 (业务日期 + 仓库) 维度计算,保证多仓库导出时每个仓库的面积/日租率正确。
|
||||||
|
|
||||||
// ===== 2. 用副本查明细,避免被上面改过的 DO 影响 =====
|
// ===== 1. 查全部明细(用副本 DO,避免影响外部)=====
|
||||||
ShipperLeaseDetailsDO detailDO = new ShipperLeaseDetailsDO();
|
ShipperLeaseDetailsDO detailDO = new ShipperLeaseDetailsDO();
|
||||||
BeanUtils.copyProperties(shipperLeaseDetailsDO, detailDO);
|
BeanUtils.copyProperties(shipperLeaseDetailsDO, detailDO);
|
||||||
List<ShipperLeaseDetailsPO> detailList = shipperLeaseDetailsService.queryList(detailDO);
|
List<ShipperLeaseDetailsPO> detailList = shipperLeaseDetailsService.queryList(detailDO);
|
||||||
|
if (detailList == null) {
|
||||||
// ===== 3. 出租率按 (业务日期 + 仓库ID) 建映射,方便明细行查汇总 =====
|
detailList = new ArrayList<>();
|
||||||
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);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// ===== 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<>();
|
List<WarehouseLeaseExportVO> exportList = new ArrayList<>();
|
||||||
for (ShipperLeaseDetailsPO d : detailList) {
|
for (ShipperLeaseDetailsPO d : detailList) {
|
||||||
WarehouseLeaseExportVO vo = new WarehouseLeaseExportVO();
|
WarehouseLeaseExportVO vo = new WarehouseLeaseExportVO();
|
||||||
@@ -536,20 +565,27 @@ public class LeaseApplicationService {
|
|||||||
vo.setCargoOwnerName(d.getCargoOwnerName());
|
vo.setCargoOwnerName(d.getCargoOwnerName());
|
||||||
vo.setLeaseType(d.getLeaseType());
|
vo.setLeaseType(d.getLeaseType());
|
||||||
vo.setLeaseArea(d.getLeaseArea());
|
vo.setLeaseArea(d.getLeaseArea());
|
||||||
// 汇总列(从映射取,找不到就留空)
|
// 汇总列
|
||||||
String key = (d.getBusinessDate() == null ? "" : keySdf.format(d.getBusinessDate()))
|
String key = (d.getBusinessDate() == null ? "" : keySdf.format(d.getBusinessDate()))
|
||||||
+ "_" + d.getWarehouseId();
|
+ "_" + d.getWarehouseId();
|
||||||
WarehouseOccupancyRate r = rateMap.get(key);
|
BigDecimal[] arr = summaryMap.get(key);
|
||||||
if (r != null) {
|
BigDecimal entireLeaseArea = (arr != null) ? arr[0] : BigDecimal.ZERO;
|
||||||
vo.setEntireLeaseArea(r.getEntireLeaseArea());
|
BigDecimal fractionalLeaseArea = (arr != null) ? arr[1] : BigDecimal.ZERO;
|
||||||
vo.setFractionalLeaseArea(r.getFractionalLeaseArea());
|
vo.setEntireLeaseArea(entireLeaseArea);
|
||||||
vo.setTotalArea(r.getTotalArea());
|
vo.setFractionalLeaseArea(fractionalLeaseArea);
|
||||||
vo.setDailyRentalRate(r.getDailyRentalRate());
|
// 该仓库的总面积(按仓库单独算,不再用全局总和)
|
||||||
}
|
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);
|
exportList.add(vo);
|
||||||
}
|
}
|
||||||
|
|
||||||
// ===== 5. 按业务日期降序排序(null 排最后)=====
|
// ===== 5. 按业务日期降序、仓库名升序排序(null 排最后)=====
|
||||||
exportList.sort(Comparator
|
exportList.sort(Comparator
|
||||||
.comparing(WarehouseLeaseExportVO::getBusinessDate, Comparator.nullsLast(Comparator.reverseOrder()))
|
.comparing(WarehouseLeaseExportVO::getBusinessDate, Comparator.nullsLast(Comparator.reverseOrder()))
|
||||||
.thenComparing(WarehouseLeaseExportVO::getWarehouseName, Comparator.nullsLast(Comparator.naturalOrder())));
|
.thenComparing(WarehouseLeaseExportVO::getWarehouseName, Comparator.nullsLast(Comparator.naturalOrder())));
|
||||||
|
|||||||
Reference in New Issue
Block a user