BMS计费单据审核计费流水周期开始时间和结束时间的生成
This commit is contained in:
+50
-6
@@ -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);
|
||||
//处理数据
|
||||
|
||||
+123
-33
@@ -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<ContractManageDetailPO> 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);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
Reference in New Issue
Block a user