diff --git a/mhd_bms/src/main/java/com/mhd/bms/application/server/businessDocument/BusinessDocumentApplicationService.java b/mhd_bms/src/main/java/com/mhd/bms/application/server/businessDocument/BusinessDocumentApplicationService.java index 383f0ccb6..3c9e7590d 100644 --- a/mhd_bms/src/main/java/com/mhd/bms/application/server/businessDocument/BusinessDocumentApplicationService.java +++ b/mhd_bms/src/main/java/com/mhd/bms/application/server/businessDocument/BusinessDocumentApplicationService.java @@ -147,15 +147,16 @@ public class BusinessDocumentApplicationService { if (ObjectUtil.isNull(loginUser)) { throw new DigitalLogisticsException(UserError.TIMEOUT); } + //先设置组织信息,因为handleDate方法中需要使用topOrganizationId + businessDocumentDO.setTopOrganizationId(loginUser.getUserPo().getTopOrganizationId()); + businessDocumentDO.setOrganizationId(loginUser.getUserPo().getOrganizationId()); + businessDocumentDO.setOrganizationName(loginUser.getUserPo().getOrganizationName()); //校验使用的表单是否必填校验 checkDoucumentType(businessDocumentDO); //处理数据 handleDate(businessDocumentDO); businessDocumentDO.setDataSources(2); businessDocumentDO.setBusinessFlow(OrderSequence.getOrderCode("LS")); - businessDocumentDO.setTopOrganizationId(loginUser.getUserPo().getTopOrganizationId()); - businessDocumentDO.setOrganizationId(loginUser.getUserPo().getOrganizationId()); - businessDocumentDO.setOrganizationName(loginUser.getUserPo().getOrganizationName()); //调用费用计算,计算费用金额进行保存 CostCalculationDTO costCalculationDTO = new CostCalculationDTO(); costCalculationDTO.setOriginalBusinessNum(businessDocumentDO.getOriginalBusinessNum()); @@ -211,6 +212,13 @@ public class BusinessDocumentApplicationService { * 处理数据 */ private void handleDate(BusinessDocumentDO businessDocumentDO) { + //确保topOrganizationId已设置,如果为null则从登录用户获取 + if (businessDocumentDO.getTopOrganizationId() == null) { + LoginUser loginUser = SecurityUtils.getLoginUser(); + if (ObjectUtil.isNotNull(loginUser) && loginUser.getUserPo() != null) { + businessDocumentDO.setTopOrganizationId(loginUser.getUserPo().getTopOrganizationId()); + } + } if(businessDocumentDO.getOrganizationId() != null){ //获取组织信息 AjaxResult ajaxResult = productServiceFeign.getOrganizationInfo(businessDocumentDO.getOrganizationId()); @@ -222,11 +230,23 @@ public class BusinessDocumentApplicationService { throw new ServiceException("组织信息未找到"); } businessDocumentDO.setOrganizationName(organizationPo.getOrganizationName()); - businessDocumentDO.setTopOrganizationId(organizationPo.getParentOrganizationId()); - if(organizationPo.getParentOrganizationId()==0){ + Long parentOrganizationId = organizationPo.getParentOrganizationId(); + if(parentOrganizationId != null && parentOrganizationId != 0){ + businessDocumentDO.setTopOrganizationId(parentOrganizationId); + } else { + //如果parentOrganizationId为null或0,使用organizationId作为topOrganizationId businessDocumentDO.setTopOrganizationId(businessDocumentDO.getOrganizationId()); } } + //再次确保topOrganizationId不为null(在设置组织信息后) + if (businessDocumentDO.getTopOrganizationId() == null) { + LoginUser loginUser = SecurityUtils.getLoginUser(); + if (ObjectUtil.isNotNull(loginUser) && loginUser.getUserPo() != null) { + businessDocumentDO.setTopOrganizationId(loginUser.getUserPo().getTopOrganizationId()); + } else { + throw new ServiceException("topOrganizationId不能为空,请确保已登录或传入有效的组织信息"); + } + } if(StringUtils.isNotEmpty(businessDocumentDO.getProjectCode())){ AjaxResult ajaxResult = systemServiceFeign.getProjectByCode(businessDocumentDO.getProjectCode()); if(!"200".equals(String.valueOf(ajaxResult.get("code")))) { @@ -304,7 +324,18 @@ public class BusinessDocumentApplicationService { } //根据费用科目code查询费用信息,并赋值 if(StringUtils.isNotEmpty(businessDocumentDO.getSecondSubjectCode())){ - AjaxResult ajaxResult = systemServiceFeign.getSubInfoByCode2(businessDocumentDO.getSecondSubjectCode(),businessDocumentDO.getTopOrganizationId()); + //确保topOrganizationId不为null,如果为null则从登录用户获取 + Long topOrganizationId = businessDocumentDO.getTopOrganizationId(); + if (topOrganizationId == null) { + LoginUser loginUser = SecurityUtils.getLoginUser(); + if (ObjectUtil.isNotNull(loginUser) && loginUser.getUserPo() != null) { + topOrganizationId = loginUser.getUserPo().getTopOrganizationId(); + businessDocumentDO.setTopOrganizationId(topOrganizationId); + } else { + throw new ServiceException("topOrganizationId不能为空"); + } + } + AjaxResult ajaxResult = systemServiceFeign.getSubInfoByCode2(businessDocumentDO.getSecondSubjectCode(), topOrganizationId); if("200".equals(String.valueOf(ajaxResult.get("code")))){ ExpenseAccountPO expenseAccountPO = JSON.parseObject(com.alibaba.fastjson2.JSONObject.toJSONString(ajaxResult.get("data")), ExpenseAccountPO.class); if(null == expenseAccountPO || expenseAccountPO.getExpenseAccountId()==null){ @@ -361,6 +392,19 @@ public class BusinessDocumentApplicationService { if(businessDocumentPO.getDataSources()==1){ throw new ServiceException("非手工录入数据,无法修改"); } + //确保组织信息已设置,因为handleDate方法中需要使用topOrganizationId + LoginUser loginUser = SecurityUtils.getLoginUser(); + if (ObjectUtil.isNotNull(loginUser) && loginUser.getUserPo() != null) { + if (businessDocumentDO.getTopOrganizationId() == null) { + businessDocumentDO.setTopOrganizationId(loginUser.getUserPo().getTopOrganizationId()); + } + if (businessDocumentDO.getOrganizationId() == null) { + businessDocumentDO.setOrganizationId(loginUser.getUserPo().getOrganizationId()); + } + if (StringUtils.isEmpty(businessDocumentDO.getOrganizationName())) { + businessDocumentDO.setOrganizationName(loginUser.getUserPo().getOrganizationName()); + } + } //校验使用的表单是否必填校验 checkDoucumentType(businessDocumentDO); //处理数据 diff --git a/mhd_bms/src/main/java/com/mhd/bms/domain/billingStatement/service/BillingStatementDomainService.java b/mhd_bms/src/main/java/com/mhd/bms/domain/billingStatement/service/BillingStatementDomainService.java index 7027efcd1..b18d7bc8a 100644 --- a/mhd_bms/src/main/java/com/mhd/bms/domain/billingStatement/service/BillingStatementDomainService.java +++ b/mhd_bms/src/main/java/com/mhd/bms/domain/billingStatement/service/BillingStatementDomainService.java @@ -371,7 +371,15 @@ public class BillingStatementDomainService { String[] ignroreFields = new String[]{"billingStatementId","dataSources","createBy","createByName","createTime","updateBy","updateByName","updateTime"}; BeanUtils.copyProperties(businessDocumentPO,billingStatementDO,ignroreFields); billingStatementDO.setBusinessDocumentId(businessDocumentPO.getBusinessDocumentId()); - billingStatementDO.setBusinessDate(businessDocumentPO.getCreateTime()); + //设置业务日期:优先使用计费时间,如果没有则使用创建时间,如果还没有则使用当前日期 + Date businessDate = businessDocumentPO.getBillingTime(); + if (businessDate == null) { + businessDate = businessDocumentPO.getCreateTime(); + } + if (businessDate == null) { + businessDate = new Date(); + } + billingStatementDO.setBusinessDate(businessDate); billingStatementDO.setBillingAmount(businessDocumentPO.getBillAmount()); billingStatementDO.setBillingState(1); billingStatementDO.setDataSources(1); @@ -394,6 +402,7 @@ public class BillingStatementDomainService { private void handleData(BillingStatementDO billingStatementDO) { //查询合同信息,赋值合同周期信息 //优先通过合同编号获取合同信息 + boolean cycleTimeSet = false; if(StringUtils.isNotEmpty(billingStatementDO.getContractNumber())){ AjaxResult ajaxResult = systemServiceFeign.getInfoByCode(billingStatementDO.getContractNumber()); if("200".equals(String.valueOf(ajaxResult.get("code")))){ @@ -402,7 +411,44 @@ public class BillingStatementDomainService { //根据合同判断计费流水的周期开始日期和周期结束日期 setCycleTimeByContract(billingStatementDO, contractManagePO); billingStatementDO.setContractType(contractManagePO.getContractType()); + //检查周期时间是否已设置 + if(billingStatementDO.getCycleBeginTime() != null && billingStatementDO.getCycleEndTime() != null){ + cycleTimeSet = true; + log.info("根据合同设置周期时间成功,合同编号:{},出账日:{},周期开始:{},周期结束:{}", + billingStatementDO.getContractNumber(), + contractManagePO.getPaymentDate(), + billingStatementDO.getCycleBeginTime(), + billingStatementDO.getCycleEndTime()); + } else { + log.warn("根据合同设置周期时间失败,合同编号:{},出账日:{}", + billingStatementDO.getContractNumber(), + contractManagePO.getPaymentDate()); + } + } else { + log.warn("合同信息为空,合同编号:{}", billingStatementDO.getContractNumber()); } + } else { + log.warn("查询合同信息失败,合同编号:{},返回码:{}", + billingStatementDO.getContractNumber(), + ajaxResult.get("code")); + } + } else { + log.warn("合同编号为空,无法查询合同信息"); + } + //如果周期时间未设置,使用业务日期作为默认值 + if(!cycleTimeSet){ + Date businessDate = billingStatementDO.getBusinessDate(); + if(businessDate != null){ + billingStatementDO.setCycleBeginTime(businessDate); + billingStatementDO.setCycleEndTime(businessDate); + log.warn("周期时间未设置,使用业务日期作为默认值:{}", businessDate); + } else { + //如果业务日期也为null,使用当前日期 + Date now = new Date(); + billingStatementDO.setBusinessDate(now); + billingStatementDO.setCycleBeginTime(now); + billingStatementDO.setCycleEndTime(now); + log.warn("业务日期为空,使用当前日期作为默认值:{}", now); } } //根据结算对象获取收支类型 @@ -420,47 +466,91 @@ public class BillingStatementDomainService { /** * 根据合同判断计费流水的周期开始日期和周期结束日期 - * (1)周期开始日期:根据合同明细的计费属性判断 - * - 实时计费、按天计费:周期开始日期 = 业务日期 - * - 按账期计费:周期开始日期 = 业务日期 - * - 按周计费:周期开始日期 = 业务日期 - * (2)周期结束日期:根据合同明细的计费属性判断 - * - 实时计费、按天计费:周期结束日期 = 业务日期 - * - 按账期计费:周期结束日期 = 合同的出账日期(paymentDate) - * - 按周计费:周期结束日期 = 业务日期往后推一周 + * 统一使用出账日来计算周期时间: + * (1)周期开始日期:上个月的出账日 + * (2)周期结束日期:本月出账日的前一天 + * 例如:出账日是10号,业务日期是3月15号,则周期为2月10号到3月9号 * @param billingStatementDO 计费流水对象 * @param contractManagePO 合同管理对象 */ private void setCycleTimeByContract(BillingStatementDO billingStatementDO, ContractManagePO contractManagePO) { - //取值合同详情,对比费用科目,取值计费周期 - if(contractManagePO.getContractManageDetailPOList()!=null && contractManagePO.getContractManageDetailPOList().size()>0){ - List contractManageDetailPOList = contractManagePO.getContractManageDetailPOList(); - String subjectCode = !StringUtils.isNotEmpty(billingStatementDO.getSecondSubjectCode()) ? billingStatementDO.getFirstSubjectCode() : billingStatementDO.getSecondSubjectCode(); - Date cycleBeginTime = null; - Date cycleEndTime = null; - for (ContractManageDetailPO contractManageDetailPO : contractManageDetailPOList) { - String subjectCodeContract = !StringUtils.isNotEmpty(contractManageDetailPO.getSecondSubjectCode()) ? contractManageDetailPO.getFirstSubjectCode() : contractManageDetailPO.getSecondSubjectCode(); - if(subjectCodeContract.equals(subjectCode)){ - Date businessDate = billingStatementDO.getBusinessDate(); - //根据不同类型获取计费周期 - if(ObjectUtil.equal(contractManageDetailPO.getBillingAttributesCode(),"1") || ObjectUtil.equal(contractManageDetailPO.getBillingAttributesCode(),"4")){ - //实时计费、按天计费,赋值为当天 - cycleBeginTime = businessDate; - cycleEndTime = businessDate; - }else if(ObjectUtil.equal(contractManageDetailPO.getBillingAttributesCode(),"2")){ - //按账期计费 - cycleBeginTime = businessDate; - cycleEndTime = contractManagePO.getPaymentDate(); - }else if(ObjectUtil.equal(contractManageDetailPO.getBillingAttributesCode(),"3")){ - //按周计费,用businessDate往后推一周的日期 - cycleBeginTime = businessDate; - cycleEndTime = DateUtil.offsetWeek(businessDate,1); + Date businessDate = billingStatementDO.getBusinessDate(); + //确保业务日期不为null + if (businessDate == null) { + businessDate = new Date(); + billingStatementDO.setBusinessDate(businessDate); + log.warn("业务日期为空,使用当前日期:{}", businessDate); + } + + //统一根据出账日计算周期时间:开始时间为上个月的出账日,结束时间为本月出账日的前一天 + Date paymentDate = contractManagePO.getPaymentDate(); + if (paymentDate != null) { + // 获取出账日的"日"部分(1-31) + // 注意:由于ContractManagePO中paymentDate的@JsonFormat设置为"d"(只显示日), + // 在反序列化时可能被解析为1970年1月1日,需要特殊处理 + int paymentDay; + // 检查是否是1970年1月1日(说明存储的实际上是"日"而不是完整日期) + if (DateUtil.year(paymentDate) == 1970 && DateUtil.month(paymentDate) == 0) { + // 这种情况下,需要从时间戳中提取天数 + // 如果数据库中存储的是"10"(表示10号),时间戳可能是10毫秒 + long timeInMillis = paymentDate.getTime(); + + // 如果时间戳很小(小于一天的毫秒数),说明存储的就是天数 + if (timeInMillis > 0 && timeInMillis < 24 * 60 * 60 * 1000) { + // 时间戳就是天数(比如10表示10号) + paymentDay = (int)timeInMillis; + } else { + // 否则尝试从日期中提取天数(如果是1970-01-11,则提取11) + paymentDay = DateUtil.dayOfMonth(paymentDate); + // 如果提取的是1(1970-01-01),尝试从时间戳计算天数 + if (paymentDay == 1) { + // 计算从1970-01-01 00:00:00 UTC开始的天数 + long daysFrom1970 = timeInMillis / (24 * 60 * 60 * 1000); + if (daysFrom1970 >= 1 && daysFrom1970 <= 31) { + paymentDay = (int)daysFrom1970; + } else { + // 尝试计算从1970-01-01 00:00:00 CST开始的天数 + // 1970-01-01 00:00:00 CST = 1970-01-01 08:00:00 UTC = -28800000毫秒 + long cstBaseTime = -8 * 60 * 60 * 1000L; // CST基准时间 + long daysFromCST = (timeInMillis - cstBaseTime) / (24 * 60 * 60 * 1000); + if (daysFromCST >= 1 && daysFromCST <= 31) { + paymentDay = (int)daysFromCST; + } + } } - break; } + log.info("检测到1970年日期,从时间戳提取出账日:时间戳={},从日期提取={},最终出账日={}", + timeInMillis, DateUtil.dayOfMonth(paymentDate), paymentDay); + } else { + // 正常情况,从日期中提取"日"部分 + paymentDay = DateUtil.dayOfMonth(paymentDate); } + + // 确保paymentDay在有效范围内(1-31) + if (paymentDay < 1 || paymentDay > 31) { + log.warn("出账日无效:{},使用业务日期的日作为默认值", paymentDay); + paymentDay = DateUtil.dayOfMonth(businessDate); + } + + // 使用业务日期来计算周期时间,而不是当前日期 + // 计算业务日期所在月的出账日 + Date currentMonthPaymentDate = DateUtil.beginOfMonth(businessDate); + currentMonthPaymentDate = DateUtil.offsetDay(currentMonthPaymentDate, paymentDay - 1); + // 结束时间:本月出账日的前一天 + Date cycleEndTime = DateUtil.offsetDay(currentMonthPaymentDate, -1); + // 开始时间:上个月的出账日 + Date cycleBeginTime = DateUtil.offsetMonth(currentMonthPaymentDate, -1); + billingStatementDO.setCycleBeginTime(cycleBeginTime); billingStatementDO.setCycleEndTime(cycleEndTime); + + log.info("计算周期时间 - 业务日期:{},出账日原始值:{},出账日(日):{},本月出账日:{},周期开始:{},周期结束:{}", + businessDate, paymentDate, paymentDay, currentMonthPaymentDate, cycleBeginTime, cycleEndTime); + } else { + // 如果没有出账日,使用业务日期作为默认值 + billingStatementDO.setCycleBeginTime(businessDate); + billingStatementDO.setCycleEndTime(businessDate); + log.warn("合同出账日为空,使用业务日期作为默认值:{}", businessDate); } }