Commit 3ea990f6 by zhangxingmin

Merge remote-tracking branch 'origin/dev' into prod

parents 60a764a9 760e13be
......@@ -12,9 +12,7 @@ import org.springframework.scheduling.annotation.EnableScheduling;
@SpringBootApplication(scanBasePackages = "com.yd")
@MapperScan("com.yd.**.dao")
@EnableFeignClients(basePackages = "com.yd")
@ComponentScan(basePackages = {
"com.yd.auth.core" // 包含认证模块的包路径
})
@ComponentScan(basePackages = {"com.yd.auth.core", "com.yd.csf.service.config"})
public class CsfApiApplication {
public static void main(String[] args) {
......
......@@ -30,6 +30,8 @@ import org.redisson.api.RedissonClient;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.transaction.support.TransactionSynchronization;
import org.springframework.transaction.support.TransactionSynchronizationManager;
import org.springframework.transaction.support.TransactionTemplate;
import org.springframework.web.bind.annotation.*;
import org.springframework.web.multipart.MultipartFile;
......@@ -151,26 +153,28 @@ public class ApiCommissionController {
// 数据处理
List<Commission> entities = processData(dataList, loginUserId, reconciliationYearMonth);
transactionTemplate.execute(status -> {
// 保存来佣数据
commissionService.saveBatch(entities);
return null;
});
// 1. 先保存主数据
commissionService.saveBatch(entities);
// // 转换为 VO
// List<CommissionVO> commissionVOList = commissionService.getCommissionList(entities);
// 开启新事务,比对数据
transactionTemplate.execute(status -> {
try {
commissionAsyncService.commissionCompareBatch(entities);
} catch (Exception e) {
// 比对失败不影响主事务,记录日志即可
e.printStackTrace();
log.error("批量导入, 比对操作执行失败, error: {}", e.getMessage());
}
return null;
});
// 2. 事务提交后执行比对
TransactionSynchronizationManager.registerSynchronization(
new TransactionSynchronization() {
@Override
public void afterCommit() {
try {
// 这里会开启新事务执行更新
commissionAsyncService.commissionCompareBatch(entities);
} catch (Exception e) {
log.error("批量导入, 比对操作执行失败, error: {}", e.getMessage());
// 可以发送告警或记录失败任务
}
}
}
);
return Result.success(true);
}
......
......@@ -283,7 +283,7 @@ public class ApiCommissionExpectedController {
if (!CollectionUtils.isEmpty(allExpectedIdList)) {
receivableReportPage = commissionExpectedService.receivableReportPage(reportPage, allExpectedIdList);
}
enrichReceivableReportWithCompanyName(receivableReportPage);
// enrichReceivableReportWithCompanyName(receivableReportPage);
receivableReportPage = convertProductName(receivableReportPage);
// 组装返回结果
ReceivableReportResponse response = new ReceivableReportResponse();
......
......@@ -530,6 +530,7 @@ public class ApiFortuneController {
QueryWrapper<Fortune> queryWrapper = new QueryWrapper<>();
queryWrapper.eq("expected_fortune_biz_id", fortuneQueryRequest.getExpectedFortuneBizId());
queryWrapper.eq("status", FortuneStatusEnum.SENT.getItemValue());
queryWrapper.or().eq("status", FortuneStatusEnum.CHECKED.getItemValue());
Page<Fortune> fortunePage = fortuneService.page(new Page<>(current, size),
queryWrapper);
// 组装返回值
......
package com.yd.csf.api.controller;
import cn.hutool.core.date.DateField;
import cn.hutool.core.date.DatePattern;
import cn.hutool.core.date.DateUtil;
import com.alibaba.excel.EasyExcel;
import com.alibaba.excel.ExcelReader;
import com.alibaba.excel.context.AnalysisContext;
import com.alibaba.excel.event.AnalysisEventListener;
import com.alibaba.excel.read.metadata.ReadSheet;
import com.alibaba.fastjson.JSON;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.yd.auth.core.dto.AuthUserDto;
......@@ -28,15 +30,18 @@ import com.yd.csf.service.common.ErrorCode;
import com.yd.csf.service.component.PolicyReportPdfService;
import com.yd.csf.service.dto.*;
import com.yd.csf.service.enums.PolicyFollowStatusEnum;
import com.yd.csf.service.helper.FeignResultHelper;
import com.yd.csf.service.model.*;
import com.yd.csf.service.service.*;
import com.yd.csf.service.vo.PolicyFollowDetailVO;
import com.yd.csf.service.vo.PolicyFollowRecordVO;
import com.yd.csf.service.vo.PolicyFollowVO;
import com.yd.csf.service.vo.PolicyNumberResponseVO;
import com.yd.feign.config.FeignTokenInterceptor;
import com.yd.insurance.base.feign.client.insurancereconciliationcompany.ApiInsuranceReconciliationCompanyFeignClient;
import com.yd.insurance.base.feign.request.insurancereconciliationcompany.ApiInsuranceReconciliationCompanyPageRequest;
import com.yd.product.feign.client.announcementcommissionratio.ApiAnnouncementCommissionRatioFeignClient;
import com.yd.product.feign.request.announcementcommissionratio.ApiAnnouncementCommissionRatioListRequest;
import com.yd.product.feign.response.announcementcommissionratio.ApiAnnouncementCommissionRatioListResponse;
import com.yd.product.feign.response.expectedspecies.ApiExpectedSpeciesListResponse;
import io.swagger.v3.oas.annotations.Operation;
import io.swagger.v3.oas.annotations.tags.Tag;
......@@ -46,7 +51,6 @@ import org.apache.commons.lang3.StringUtils;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.BeanUtils;
import org.springframework.scheduling.annotation.Async;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.web.bind.annotation.*;
import org.springframework.web.multipart.MultipartFile;
......@@ -91,9 +95,12 @@ public class ApiPolicyFollowController {
private CommissionExpectedService commissionExpectedService;
@Resource
private ApiPolicyFollowService apiPolicyFollowService;
@Resource
private ApiExpectedFortuneService apiExpectedFortuneService;
@Resource
private ApiAnnouncementCommissionRatioFeignClient apiAnnouncementCommissionRatioFeignClient;
@Resource
private FeignResultHelper feignResultHelper;
@PostMapping("/upload/excel")
......@@ -538,6 +545,25 @@ public class ApiPolicyFollowController {
if (!hasCommissionInfo) {
return Result.fail(ResultCode.NULL_ERROR.getCode(), "产品未维护发佣信息");
}
//查询产品发佣配置,获取结算币种
ApiAnnouncementCommissionRatioListRequest announcementRatioListRequest = new ApiAnnouncementCommissionRatioListRequest();
announcementRatioListRequest.setProductLaunchBizId(productLaunchBizId);
announcementRatioListRequest.setEffectiveDate(changePolicyFollowStatusRequest.getEffectiveDate());
announcementRatioListRequest.setPaymentTerm(String.valueOf(policyFollow.getIssueNumber()));
try {
feignResultHelper.extractListData(
apiAnnouncementCommissionRatioFeignClient.list(announcementRatioListRequest),
ApiAnnouncementCommissionRatioListResponse.class
);
} catch (BusinessException e) {
log.info("===== 进入BusinessException catch块 =====");
log.info("查询结算币种->保单号:{},入参request:{}", policyFollow.getPolicyNo(), JSON.toJSONString(announcementRatioListRequest));
return Result.fail("未查询到产品发佣配置,查询条件:" + transferMsg(announcementRatioListRequest, policyFollow));
} catch (Exception e) {
log.info("===== 进入Exception catch块 =====");
log.info("查询结算币种->保单号:{},入参request:{}", policyFollow.getPolicyNo(), JSON.toJSONString(announcementRatioListRequest));
return Result.fail("未查询到产品发佣配置,查询条件:" + transferMsg(announcementRatioListRequest, policyFollow));
}
}
// 修改逻辑
......@@ -554,6 +580,13 @@ public class ApiPolicyFollowController {
return Result.success(true);
}
private String transferMsg(ApiAnnouncementCommissionRatioListRequest announcementRatioListRequest, PolicyFollow policyFollow) {
return String.format("保单生效日: %s, 供款年期: %s, 产品名称: %s, ",
DateUtil.format(announcementRatioListRequest.getEffectiveDate(), DatePattern.NORM_DATE_PATTERN),
policyFollow.getIssueNumber(),
policyFollow.getProductName());
}
/**
* 异步处理
*
......
......@@ -31,6 +31,16 @@ public class GenerateExpectedFortuneDto {
private String policyNo;
/**
* 产品业务id
*/
private String productLaunchBizId;
/**
* 保险公司业务id
*/
private String insuranceCompanyBizId;
/**
* 发佣期数(1=第一年; 2=第二年; 3=第三年; 4=第四年; 5=第五年)
*/
private Integer fortunePeriod;
......
......@@ -15,11 +15,11 @@ import com.yd.csf.service.dto.QueryPolicyAndBrokerDto;
import com.yd.csf.service.model.CommissionRuleBinding;
import com.yd.csf.service.model.ExpectedFortune;
import com.yd.csf.service.vo.ExpectedFortuneStatisticsVO;
import com.yd.product.feign.response.announcementcommissionratio.ApiAnnouncementCommissionRatioListResponse;
import org.springframework.scheduling.annotation.Async;
import javax.servlet.http.HttpServletResponse;
import java.util.List;
import java.util.Map;
public interface ApiExpectedFortuneService {
Result<ApiGenerateExpectedFortuneResponse> generate(ApiGenerateExpectedFortuneRequest request);
......@@ -37,7 +37,8 @@ public interface ApiExpectedFortuneService {
@Async("asyncQueryExecutor")
Result execute(List<QueryPolicyAndBrokerDto> queryPolicyAndBrokerDtoList,
List<CommissionRuleBinding> commissionRuleBindingList,
String policyNo);
String policyNo,
List<ApiAnnouncementCommissionRatioListResponse> announcementRatioList);
/**
* 同步执行预计发佣生成
......
......@@ -18,6 +18,7 @@ import com.yd.csf.feign.dto.appointment.*;
import com.yd.csf.feign.dto.appointmentfile.ApiAppointmentFileDto;
import com.yd.csf.feign.request.appointment.*;
import com.yd.csf.feign.response.appointment.*;
import com.yd.csf.service.dao.AppointmentMapper;
import com.yd.csf.service.dto.PolicySigner;
import com.yd.csf.service.enums.AppointmentStatusEnum;
import com.yd.csf.service.enums.FnaStatusEnum;
......@@ -141,6 +142,8 @@ public class ApiAppointmentServiceImpl implements ApiAppointmentService {
private PolicyBrokerService policyBrokerService;
@Resource
private PolicyAppointmentFileService policyAppointmentFileService;
@Resource
private AppointmentMapper appointmentMapper;
/**
* 预约分页查询
......
......@@ -2,9 +2,6 @@ package com.yd.csf.api.service.impl;
import cn.hutool.core.bean.BeanUtil;
import cn.hutool.core.collection.CollUtil;
import cn.hutool.json.JSONArray;
import cn.hutool.json.JSONObject;
import cn.hutool.json.JSONUtil;
import com.alibaba.excel.EasyExcel;
import com.alibaba.excel.ExcelWriter;
import com.alibaba.excel.write.metadata.WriteSheet;
......@@ -31,7 +28,9 @@ import com.yd.csf.feign.response.expectedfortune.ApiGenerateExpectedFortuneRespo
import com.yd.csf.service.dto.CommissionRuleBindingDto;
import com.yd.csf.service.dto.QueryPolicyAndBrokerDto;
import com.yd.csf.service.dto.QueryPolicyBrokerDto;
import com.yd.csf.service.enums.CurrencyEnum;
import com.yd.csf.service.enums.FortuneStatusEnum;
import com.yd.csf.service.helper.FeignResultHelper;
import com.yd.csf.service.model.*;
import com.yd.csf.service.service.*;
import com.yd.csf.service.vo.ExpectedFortuneExportDTO;
......@@ -106,6 +105,10 @@ public class ApiExpectedFortuneServiceImpl implements ApiExpectedFortuneService
private CommissionExpectedService commissionExpectedService;
@Resource
private ApiAnnouncementCommissionRatioFeignClient apiAnnouncementCommissionRatioFeignClient;
@Resource
private FeignResultHelper feignResultHelper;
@Resource
private ApiAnnouncementCommissionRatioFeignClient ratioFeignClient;
/**
* 生成预计发佣
......@@ -147,9 +150,28 @@ public class ApiExpectedFortuneServiceImpl implements ApiExpectedFortuneService
throw new BusinessException("绑定基本法数据不存在");
}
//查询产品发佣配置,获取结算币种
QueryPolicyAndBrokerDto queryPolicyAndBrokerDto = queryPolicyAndBrokerDtoList.get(0);
ApiAnnouncementCommissionRatioListRequest announcementRatioListRequest = new ApiAnnouncementCommissionRatioListRequest();
announcementRatioListRequest.setProductLaunchBizId(queryPolicyAndBrokerDto.getPlanBizId());
announcementRatioListRequest.setEffectiveDate(Date.from(queryPolicyAndBrokerDto.getEffectiveDate().atStartOfDay(ZoneId.systemDefault()).toInstant()));
announcementRatioListRequest.setPaymentTerm(String.valueOf(queryPolicyAndBrokerDto.getPaymentTerm()));
List<ApiAnnouncementCommissionRatioListResponse> announcementRatioList;
try {
announcementRatioList = feignResultHelper.extractListData(
apiAnnouncementCommissionRatioFeignClient.list(announcementRatioListRequest),
ApiAnnouncementCommissionRatioListResponse.class
);
} catch (Exception e) {
log.info("查询结算币种->保单号:{},入参request:{}", request.getPolicyNo(), JSON.toJSONString(announcementRatioListRequest));
throw new BusinessException("未查询到产品发佣配置,查询条件:" + JSON.toJSONString(announcementRatioListRequest));
}
//遍历保单转介人列表信息 -> 调用基本法算出预计发佣列表
// 通过代理对象调用
getSelf().execute(queryPolicyAndBrokerDtoList, commissionRuleBindingList, request.getPolicyNo());
getSelf().execute(queryPolicyAndBrokerDtoList, commissionRuleBindingList, request.getPolicyNo(), announcementRatioList);
return Result.success(null, "生成预计发佣正在处理....,稍后查看预计发佣列表");
}
......@@ -193,8 +215,52 @@ public class ApiExpectedFortuneServiceImpl implements ApiExpectedFortuneService
// throw new BusinessException("绑定基本法数据不存在");
// }
//查询产品发佣配置,获取结算币种
QueryPolicyAndBrokerDto queryPolicyAndBrokerDto = queryPolicyAndBrokerDtoList.get(0);
ApiAnnouncementCommissionRatioListRequest announcementRatioListRequest = new ApiAnnouncementCommissionRatioListRequest();
announcementRatioListRequest.setProductLaunchBizId(queryPolicyAndBrokerDto.getPlanBizId());
announcementRatioListRequest.setEffectiveDate(Date.from(queryPolicyAndBrokerDto.getEffectiveDate().atStartOfDay(ZoneId.systemDefault()).toInstant()));
announcementRatioListRequest.setPaymentTerm(String.valueOf(queryPolicyAndBrokerDto.getPaymentTerm()));
List<ApiAnnouncementCommissionRatioListResponse> announcementRatioList;
try {
announcementRatioList = feignResultHelper.extractListData(
apiAnnouncementCommissionRatioFeignClient.list(announcementRatioListRequest),
ApiAnnouncementCommissionRatioListResponse.class
);
} catch (Exception e) {
log.info("查询结算币种->保单号:{},入参request:{}", request.getPolicyNo(), JSON.toJSONString(announcementRatioListRequest));
throw new BusinessException("未查询到产品发佣配置,查询条件:" + JSON.toJSONString(announcementRatioListRequest));
}
Integer paymentTerm = 0;
PolicyFollow policyFollow = policyFollowService.queryOneByPolicyNo(request.getPolicyNo());
if (policyFollow != null) {
ApiAnnouncementCommissionRatioListRequest ratioListRequest = new ApiAnnouncementCommissionRatioListRequest();
ratioListRequest.setEffectiveDate(policyFollow.getEffectiveDate());
ratioListRequest.setPaymentTerm(policyFollow.getIssueNumber().toString()); // 保留原有过滤条件(可根据业务决定是否需要)
ratioListRequest.setProductLaunchBizId(policyFollow.getProductLaunchBizId());
Result<List<ApiAnnouncementCommissionRatioListResponse>> listResult = ratioFeignClient.list(ratioListRequest);
if (listResult != null && !CollectionUtils.isEmpty(listResult.getData())) {
// 取 endPeriod 的最大值作为总期数
paymentTerm = listResult.getData().stream()
.map(item -> {
try {
return Integer.parseInt(item.getEndPeriod()); // 将字符串转为整数
} catch (NumberFormatException e) {
// 若转换失败,记录日志并返回0,避免影响最大值计算
log.warn("endPeriod 格式错误: {}", item.getEndPeriod());
return 0;
}
})
.max(Integer::compareTo)
.orElse(0); // 若无有效值,默认0
}
}
//遍历保单转介人列表信息 -> 调用基本法算出预计发佣列表(同步执行)
executeSync(queryPolicyAndBrokerDtoList, request.getPolicyNo());
executeSync(queryPolicyAndBrokerDtoList, request.getPolicyNo(), announcementRatioList,paymentTerm);
return Result.success(null, "生成预计发佣成功");
}
......@@ -290,7 +356,8 @@ public class ApiExpectedFortuneServiceImpl implements ApiExpectedFortuneService
@Async("commonAsyncExecutor")
public Result execute(List<QueryPolicyAndBrokerDto> queryPolicyAndBrokerDtoList,
List<CommissionRuleBinding> commissionRuleBindingList,
String policyNo) {
String policyNo,
List<ApiAnnouncementCommissionRatioListResponse> announcementRatioList) {
// 使用编程式事务,确保异步方法内的事务一致性
return transactionTemplate.execute(status -> {
......@@ -322,13 +389,8 @@ public class ApiExpectedFortuneServiceImpl implements ApiExpectedFortuneService
List<ExpectedFortune> expectedFortuneList = updatePayableNoBatch(policyNo);
//默认结算汇率、港币金额
if (CollUtil.isNotEmpty(queryPolicyAndBrokerDtoList)) {
log.info("queryPolicyAndBrokerDtoList: {}", queryPolicyAndBrokerDtoList);
QueryPolicyAndBrokerDto queryPolicyAndBrokerDto = queryPolicyAndBrokerDtoList.get(0);
updateHkdAmountBatch(expectedFortuneList, queryPolicyAndBrokerDto);
}
String policyCurrency = queryPolicyAndBrokerDtoList.get(0).getCurrency();
updateHkdAmountBatch(expectedFortuneList, policyCurrency, announcementRatioList);
//执行成功完毕,也要销毁redis缓存
redisUtil.deleteObject(RedisConstants.EXPECTED_FORTUNE + policyNo);
......@@ -357,50 +419,35 @@ public class ApiExpectedFortuneServiceImpl implements ApiExpectedFortuneService
});
}
private void updateHkdAmountBatch(List<ExpectedFortune> expectedFortuneList, QueryPolicyAndBrokerDto queryPolicyAndBrokerDto) {
//查询结算币种
ApiAnnouncementCommissionRatioListRequest request = new ApiAnnouncementCommissionRatioListRequest();
request.setProductLaunchBizId(queryPolicyAndBrokerDto.getPlanBizId());
//localDate转换为Date
request.setEffectiveDate(Date.from(queryPolicyAndBrokerDto.getEffectiveDate().atStartOfDay(ZoneId.systemDefault()).toInstant()));
request.setPaymentTerm(String.valueOf(queryPolicyAndBrokerDto.getPaymentTerm()));
Result<List<ApiAnnouncementCommissionRatioListResponse>> result = apiAnnouncementCommissionRatioFeignClient.list(request);
private void updateHkdAmountBatch(List<ExpectedFortune> expectedFortuneList, String policyCurrency, List<ApiAnnouncementCommissionRatioListResponse> announcementRatioList) {
log.info("查询结算币种->入参request:{},出参result:{}", JSON.toJSONString(request), JSON.toJSONString(result));
log.info("------------------------开始计算默认结算汇率、港币金额----------------------");
if (result.getCode() == 200) {
if (!CollectionUtils.isEmpty(announcementRatioList)) {
ApiAnnouncementCommissionRatioListResponse announcementRatio = announcementRatioList.get(0);
String currency = announcementRatio.getCurrency();
// 使用 Map 来处理数据
Object data = result.getData();
// 将数据转换为JSONObject进行解析
JSONArray announcementRatioList = JSONUtil.parseArray(data);
log.info("结算币种:{}", currency);
//查询默认结算汇率
if (!announcementRatioList.isEmpty()) {
JSONObject announcementRatio = announcementRatioList.get(0, JSONObject.class);
String currency = announcementRatio.getStr("currency");
BigDecimal exchangeRate = queryExchangeRateByFeign(policyCurrency, currency);
log.info("结算币种:{}", currency);
log.info("结算汇率:{}", exchangeRate);
BigDecimal exchangeRate = queryExchangeRateByFeign(queryPolicyAndBrokerDto.getCurrency(), currency);
for (ExpectedFortune expectedFortune : expectedFortuneList) {
//设置结算货币
expectedFortune.setCurrency(currency);
//设置默认结算汇率
expectedFortune.setDefaultExchangeRate(exchangeRate);
//设置港币金额(标准发佣金额 * 默认结算汇率)
expectedFortune.setHkdAmount(expectedFortune.getAmount().multiply(exchangeRate));
//默认值
expectedFortune.setPaidAmount(BigDecimal.ZERO);
expectedFortune.setPaidRatio(BigDecimal.ZERO);
expectedFortune.setUnpaidAmount(expectedFortune.getHkdAmount());
expectedFortune.setUnpaidRatio(BigDecimal.valueOf(100));
log.info("结算汇率:{}", exchangeRate);
for (ExpectedFortune expectedFortune : expectedFortuneList) {
//设置结算货币
expectedFortune.setCurrency(currency);
//设置默认结算汇率
expectedFortune.setDefaultExchangeRate(exchangeRate);
//设置港币金额(标准发佣金额 * 默认结算汇率)
expectedFortune.setHkdAmount(expectedFortune.getAmount().multiply(exchangeRate));
iExpectedFortuneService.updateById(expectedFortune);
}
} else {
log.error("查询结算币种失败,未查询到默认结算汇率->入参request:{},出参result:{}", JSON.toJSONString(request), JSON.toJSONString(result));
iExpectedFortuneService.updateById(expectedFortune);
}
} else {
log.error("查询结算币种失败,入参request:{},出参result:{}", JSON.toJSONString(request), JSON.toJSONString(result));
}
}
......@@ -417,15 +464,16 @@ public class ApiExpectedFortuneServiceImpl implements ApiExpectedFortuneService
* @return
*/
public Result executeSync(List<QueryPolicyAndBrokerDto> queryPolicyAndBrokerDtoList,
String policyNo) {
String policyNo, List<ApiAnnouncementCommissionRatioListResponse> announcementRatioList,Integer paymentTerm) {
log.info("同步处理-> 遍历保单转介人列表信息 -> 调用基本法算出预计发佣列表->入参queryPolicyAndBrokerDtoList:{}",JSON.toJSONString(queryPolicyAndBrokerDtoList));
log.info("同步处理-> 遍历保单转介人列表信息 -> 调用基本法算出预计发佣列表->入参policyNo:{}",policyNo);
// 使用编程式事务,确保方法内的事务一致性
return transactionTemplate.execute(status -> {
try {
for (QueryPolicyAndBrokerDto brokerDto : queryPolicyAndBrokerDtoList) {
Integer paymentTerm = brokerDto.getPaymentTerm();
if (Objects.isNull(paymentTerm)) {
// Integer paymentTerm = brokerDto.getPaymentTerm();
if (paymentTerm == null || paymentTerm == 0) {
throw new BusinessException("保单的供款年期不存在");
}
......@@ -453,15 +501,9 @@ public class ApiExpectedFortuneServiceImpl implements ApiExpectedFortuneService
//批量设置应付款编号
List<ExpectedFortune> expectedFortuneList = updatePayableNoBatch(policyNo);
//默认结算汇率、港币金额
if (ObjectUtils.isNotEmpty(queryPolicyAndBrokerDtoList)) {
log.info("------------------------开始计算默认结算汇率、港币金额----------------------");
QueryPolicyAndBrokerDto queryPolicyAndBrokerDto = queryPolicyAndBrokerDtoList.get(0);
updateHkdAmountBatch(expectedFortuneList, queryPolicyAndBrokerDto);
}
String policyCurrency = queryPolicyAndBrokerDtoList.get(0).getCurrency();
updateHkdAmountBatch(expectedFortuneList, policyCurrency, announcementRatioList);;
//执行成功完毕,也要销毁redis缓存
redisUtil.deleteObject(RedisConstants.EXPECTED_FORTUNE + policyNo);
......@@ -593,10 +635,14 @@ public class ApiExpectedFortuneServiceImpl implements ApiExpectedFortuneService
.status(FortuneStatusEnum.WAIT.getItemValue())
//期交保费
.paymentPremium(brokerDto.getPaymentPremium())
//所属团队 TODO
// .team()
//所属团队业务ID TODO
// .teamBizId()
//所属团队
.team(brokerDto.getTeam())
//所属团队业务ID
.teamBizId(brokerDto.getTeamBizId())
//产品业务id
.productLaunchBizId(brokerDto.getPlanBizId())
//保险公司业务id
.insuranceCompanyBizId(brokerDto.getInsuranceCompanyBizId())
.build());
return Result.success();
......@@ -663,10 +709,14 @@ public class ApiExpectedFortuneServiceImpl implements ApiExpectedFortuneService
.status(FortuneStatusEnum.WAIT.getItemValue())
//期交保费
.paymentPremium(brokerDto.getPaymentPremium())
//所属团队 TODO
// .team()
//所属团队业务ID TODO
// .teamBizId()
//所属团队
.team(brokerDto.getTeam())
//所属团队业务ID
.teamBizId(brokerDto.getTeamBizId())
//产品业务id
.productLaunchBizId(brokerDto.getPlanBizId())
//保险公司业务id
.insuranceCompanyBizId(brokerDto.getInsuranceCompanyBizId())
.build());
return Result.success();
......@@ -706,6 +756,14 @@ public class ApiExpectedFortuneServiceImpl implements ApiExpectedFortuneService
fortune.setBroker(fortuneDto.getBroker());
//转介人业务ID (获得积分的业务员)
fortune.setBrokerBizId(fortuneDto.getBrokerBizId());
//所属团队
fortune.setTeam(fortuneDto.getTeam());
//所属团队业务ID
fortune.setTeamBizId(fortuneDto.getTeamBizId());
//产品业务id
fortune.setProductLaunchBizId(fortuneDto.getProductLaunchBizId());
//保险公司业务id
fortune.setInsuranceCompanyBizId(fortuneDto.getInsuranceCompanyBizId());
//出账项目名称 -> 基本法项目名称
fortune.setFortuneName(algorithmResDto.getItemName());
//保单预计发佣业务id
......@@ -967,8 +1025,10 @@ public class ApiExpectedFortuneServiceImpl implements ApiExpectedFortuneService
List<PayableReportVO> voList = payableReportPage.getRecords().stream().map(vo -> {
Policy policy = policyMap.get(vo.getPolicyNo());
PolicyFollow policyFollow= policyFollowMap.get(vo.getPolicyNo());
vo.setCurrency(CurrencyEnum.toLabel(vo.getCurrency()));
if (policy != null) {
vo.setPolicyCurrency(policy.getCurrency());
vo.setPolicyCurrency(CurrencyEnum.toLabel(policy.getCurrency()));
}
if (policyFollow != null) {
vo.setProductName(policyFollow.getProductName());
......@@ -1042,8 +1102,8 @@ public class ApiExpectedFortuneServiceImpl implements ApiExpectedFortuneService
// 按保单号模糊查询
queryWrapper.eq(ObjectUtils.isNotEmpty(payableNo), "payable_no", payableNo);
queryWrapper.like(StringUtils.isNotBlank(policyNo), "policy_no", policyNo);
queryWrapper.gt(ObjectUtils.isNotEmpty(payoutDateStart), "payout_date", payoutDateStart);
queryWrapper.lt(ObjectUtils.isNotEmpty(payoutDateEnd), "payout_date", payoutDateEnd);
queryWrapper.ge(ObjectUtils.isNotEmpty(payoutDateStart), "payout_date", payoutDateStart);
queryWrapper.le(ObjectUtils.isNotEmpty(payoutDateEnd), "payout_date", payoutDateEnd);
queryWrapper.in(ObjectUtils.isNotEmpty(statusList), "status", statusList);
queryWrapper.eq(ObjectUtils.isNotEmpty(fortunePeriod), "fortune_period", fortunePeriod);
queryWrapper.eq(StringUtils.isNotBlank(fortuneType), "fortune_type", fortuneType);
......
......@@ -12,6 +12,13 @@
<artifactId>yd-csf-service</artifactId>
<dependencies>
<!-- Java 8 时间类型支持 -->
<dependency>
<groupId>com.fasterxml.jackson.datatype</groupId>
<artifactId>jackson-datatype-jsr310</artifactId>
<version>2.13.2</version>
</dependency>
<!-- 公共工具类 -->
<dependency>
<groupId>commons-io</groupId>
......
......@@ -18,6 +18,7 @@ import org.apache.commons.collections4.CollectionUtils;
import org.apache.commons.lang3.ObjectUtils;
import org.apache.commons.lang3.StringUtils;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Propagation;
import org.springframework.transaction.annotation.Transactional;
import javax.annotation.Resource;
......@@ -40,7 +41,7 @@ public class CommissionAsyncService {
private CommissionCompareRecordService commissionCompareRecordService;
// @Async("commonAsyncExecutor")
@Transactional(rollbackFor = Exception.class)
@Transactional(propagation = Propagation.REQUIRES_NEW)
public void commissionCompareBatch(List<Commission> entities) {
// 根据是否关联保单号,来区分比对方式
List<Commission> hasPolicyNoList = new ArrayList<>();
......
package com.yd.csf.service.config;
import com.alibaba.fastjson.JSON;
import com.baomidou.mybatisplus.annotation.DbType;
import com.baomidou.mybatisplus.core.handlers.MetaObjectHandler;
import com.baomidou.mybatisplus.extension.plugins.MybatisPlusInterceptor;
import com.baomidou.mybatisplus.extension.plugins.inner.PaginationInnerInterceptor;
import com.yd.auth.core.dto.AuthUserDto;
import com.yd.auth.core.utils.SecurityUtil;
import lombok.extern.slf4j.Slf4j;
import org.apache.ibatis.reflection.MetaObject;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.context.annotation.Primary;
import java.time.LocalDateTime;
@Slf4j
@Configuration
public class CsfMybatisPlusConfig {
......@@ -25,21 +31,35 @@ public class CsfMybatisPlusConfig {
}
/**
* 自动填充字段配置(如创建时间、更新时间
* 自动填充字段配置(如创建人、更新人等
*/
@Bean
@Primary
public MetaObjectHandler metaObjectHandler() {
log.info("MetaObjectHandler Bean 正在创建...","MetaObjectHandler Bean 正在创建==========");
return new MetaObjectHandler() {
@Override
public void insertFill(MetaObject metaObject) {
this.strictInsertFill(metaObject, "createTime", LocalDateTime.class, LocalDateTime.now());
//获取Security上下文当前用户的登录信息
AuthUserDto authUserDto = SecurityUtil.getCurrentLoginUser();
log.info("metaObjectHandler=======insertFill自动填充获取用户信息:{}", JSON.toJSONString(authUserDto));
if (authUserDto != null) {
//自动注入创建人和创建用户名
this.strictInsertFill(metaObject, "creatorId", String.class, authUserDto.getUserBizId());
this.strictInsertFill(metaObject, "creatorName", String.class, authUserDto.getUsername());
}
}
@Override
public void updateFill(MetaObject metaObject) {
this.strictUpdateFill(metaObject, "updateTime", LocalDateTime.class, LocalDateTime.now());
//获取Security上下文当前用户的登录信息
AuthUserDto authUserDto = SecurityUtil.getCurrentLoginUser();
log.info("metaObjectHandler=======updateFill自动填充获取用户信息:{}", JSON.toJSONString(authUserDto));
if (authUserDto != null) {
//自动注入更新人和更新用户名
this.strictUpdateFill(metaObject, "updaterId", String.class, authUserDto.getUserBizId());
this.strictUpdateFill(metaObject, "updaterName", String.class, authUserDto.getUsername());
}
}
};
}
......
package com.yd.csf.service.dto;
import com.fasterxml.jackson.annotation.JsonFormat;
import com.yd.common.dto.PageDto;
import io.swagger.v3.oas.annotations.media.Schema;
import lombok.Data;
import java.time.LocalDate;
import java.util.Date;
import java.util.List;
......@@ -32,15 +32,13 @@ public class CommissionExpectedQueryRequest extends PageDto {
* 预计入账日期开始 格式:yyyy-MM-dd
*/
@Schema(description = "预计入账日期开始 格式:yyyy-MM-dd")
@JsonFormat(pattern = "yyyy-MM-dd", timezone = "GMT+8")
private Date commissionDateStart;
private LocalDate commissionDateStart;
/**
* 预计入账日期结束 格式:yyyy-MM-dd
*/
@Schema(description = "预计入账日期结束 格式:yyyy-MM-dd")
@JsonFormat(pattern = "yyyy-MM-dd", timezone = "GMT+8")
private Date commissionDateEnd;
private LocalDate commissionDateEnd;
/**
* 入账期数
......
......@@ -17,9 +17,13 @@ public class FortuneAccountExportDTO implements Serializable {
@ExcelProperty("转介人")
private String broker;
private String brokerBizId;
@ExcelProperty("所属团队")
private String team;
private String teamBizId;
@ExcelProperty("出账币种")
private String currency;
......
......@@ -53,8 +53,7 @@ public class PolicyFollowQueryRequest extends PageDto implements Serializable {
* 最晚缴费日期
*/
@Schema(description = "最晚缴费日期 格式: yyyy-MM-dd", example = "2023-01-01", format = "yyyy-MM-dd")
@JsonFormat(pattern = "yyyy-MM-dd", timezone = "GMT+8")
private Date latestPaymentDate;
private String latestPaymentDate;
/**
* 投保人业务id列表
......@@ -84,7 +83,7 @@ public class PolicyFollowQueryRequest extends PageDto implements Serializable {
* 缴费年期
*/
@Schema(description = "缴费年期")
private String issueNumber;
private Integer issueNumber;
private static final long serialVersionUID = 1L;
}
\ No newline at end of file
......@@ -35,6 +35,11 @@ public class QueryPolicyAndBrokerDto {
private String productCode;
/**
* 保险公司业务id
*/
private String insuranceCompanyBizId;
/**
* 供款年期(字典)
*/
private Integer paymentTerm;
......
......@@ -30,4 +30,13 @@ public enum CommissionStatusEnum {
public String getItemValue() {
return itemValue;
}
public static String toLabel(String itemValue) {
for (CommissionStatusEnum anEnum : CommissionStatusEnum.values()) {
if (anEnum.itemValue.equals(itemValue)) {
return anEnum.getItemLabel();
}
}
return "";
}
}
......@@ -17,8 +17,8 @@ import org.apache.commons.lang3.ObjectUtils;
public enum CurrencyEnum {
// 货币枚举
USD("美元", "USD"),
CNY("人民", "CNY"),
HKD("港", "HKD"),
CNY("人民", "CNY"),
HKD("港", "HKD"),
AUD("澳元", "AUD"),
JPY("日元", "JPY"),
CAD("加元", "CAD"),
......@@ -65,4 +65,13 @@ public enum CurrencyEnum {
public String getItemValue() {
return itemValue;
}
public static String toLabel(String itemValue) {
for (CurrencyEnum anEnum : CurrencyEnum.values()) {
if (anEnum.itemValue.equalsIgnoreCase(itemValue)) {
return anEnum.getItemLabel();
}
}
return "";
}
}
package com.yd.csf.service.helper;
import com.fasterxml.jackson.databind.ObjectMapper;
import com.yd.common.enums.ResultCode;
import com.yd.common.exception.BusinessException;
import com.yd.common.result.Result;
import org.springframework.stereotype.Component;
import javax.annotation.Resource;
import java.util.List;
@Component
public class FeignResultHelper {
@Resource
private ObjectMapper objectMapper;
public <T> T extractData(Result<T> result) {
if (result == null) {
throw new BusinessException(ResultCode.FAIL.getCode(), "远程调用返回null");
}
if (result.getCode() != ResultCode.SUCCESS.getCode()) {
throw new BusinessException(result.getCode(), result.getMsg());
}
return result.getData();
}
public <T> List<T> extractListData(Result<?> result, Class<T> elementType) {
if (result == null) {
throw new BusinessException(ResultCode.FAIL.getCode(), "远程调用返回null");
}
if (result.getCode() != ResultCode.SUCCESS.getCode()) {
throw new BusinessException(result.getCode(), result.getMsg());
}
Object data = result.getData();
if (data == null) {
throw new BusinessException(ResultCode.FAIL.getCode(), "远程调用 result.getData() 为 null");
}
if (data instanceof List) {
if (((List<?>) data).isEmpty()) {
throw new BusinessException(ResultCode.FAIL.getCode(), "远程调用 result.getData() 为 []");
}
return objectMapper.convertValue(
data,
objectMapper.getTypeFactory().constructCollectionType(
List.class, elementType
)
);
} else {
throw new BusinessException(ResultCode.FAIL.getCode(), "返回数据类型错误");
}
}
}
\ No newline at end of file
package com.yd.csf.service.model;
import com.baomidou.mybatisplus.annotation.IdType;
import com.baomidou.mybatisplus.annotation.TableField;
import com.baomidou.mybatisplus.annotation.TableId;
import com.baomidou.mybatisplus.annotation.TableName;
import com.baomidou.mybatisplus.annotation.*;
import lombok.Getter;
import lombok.Setter;
......@@ -342,19 +339,19 @@ public class Appointment implements Serializable {
/**
* 创建人ID
*/
@TableField("creator_id")
@TableField(value = "creator_id", fill = FieldFill.INSERT)
private String creatorId;
/**
* 创建人用户名
*/
@TableField("creator_name")
@TableField(value = "creator_name", fill = FieldFill.INSERT)
private String creatorName;
/**
* 更新人ID
*/
@TableField("updater_id")
@TableField(value = "updater_id", fill = FieldFill.UPDATE)
private String updaterId;
/**
......
......@@ -51,6 +51,11 @@ public class CommissionExpected implements Serializable {
private BigDecimal premium;
/**
* 保单币种
*/
private String policyCurrency;
/**
* 保险公司业务id
*/
private String insuranceCompanyBizId;
......
......@@ -34,11 +34,21 @@ public class FortuneAccount implements Serializable {
private String broker;
/**
* 转介人业务id
*/
private String brokerBizId;
/**
* 所属团队
*/
private String team;
/**
* 所属团队业务id
*/
private String teamBizId;
/**
* 出账币种
*/
private String currency;
......
......@@ -37,7 +37,7 @@ public class PolicyBroker implements Serializable {
private String brokerName;
/**
* 转介人业务ID(客户端用户表唯一业务ID)
* 转介人业务ID
*/
private String brokerBizId;
......
......@@ -2,6 +2,8 @@ package com.yd.csf.service.service.impl;
import cn.hutool.core.collection.CollUtil;
import cn.hutool.core.convert.Convert;
import cn.hutool.core.date.DateUtil;
import cn.hutool.json.JSONUtil;
import com.alibaba.fastjson.JSON;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.core.metadata.IPage;
......@@ -20,10 +22,7 @@ import com.yd.common.utils.RedisUtil;
import com.yd.csf.service.component.ReceivableService;
import com.yd.csf.service.dto.*;
import com.yd.csf.service.enums.CommissionExpectedStatusEnum;
import com.yd.csf.service.model.Commission;
import com.yd.csf.service.model.CommissionExpected;
import com.yd.csf.service.model.Policy;
import com.yd.csf.service.model.PolicyFollow;
import com.yd.csf.service.model.*;
import com.yd.csf.service.service.*;
import com.yd.csf.service.dao.CommissionExpectedMapper;
import com.yd.csf.service.vo.CommissionExpectedStatisticsVO;
......@@ -297,8 +296,8 @@ public class CommissionExpectedServiceImpl extends ServiceImpl<CommissionExpecte
List<String> insurerCompanyBizIdList = commissionExpectedQueryRequest.getInsurerCompanyBizIdList();
List<String> reconciliationCompanyBizIdList = commissionExpectedQueryRequest.getReconciliationCompanyBizIdList();
List<String> statusList = commissionExpectedQueryRequest.getStatusList();
Date commissionDateStart = commissionExpectedQueryRequest.getCommissionDateStart();
Date commissionDateEnd = commissionExpectedQueryRequest.getCommissionDateEnd();
LocalDate commissionDateStart = commissionExpectedQueryRequest.getCommissionDateStart();
LocalDate commissionDateEnd = commissionExpectedQueryRequest.getCommissionDateEnd();
Integer commissionPeriod = commissionExpectedQueryRequest.getCommissionPeriod();
String productLaunchBizId = commissionExpectedQueryRequest.getProductLaunchBizId();
String commissionBizType = commissionExpectedQueryRequest.getCommissionBizType();
......@@ -314,8 +313,8 @@ public class CommissionExpectedServiceImpl extends ServiceImpl<CommissionExpecte
queryWrapper.eq(ObjectUtils.isNotEmpty(commissionBizType), "commission_biz_type", commissionBizType);
queryWrapper.in(ObjectUtils.isNotEmpty(statusList), "status", statusList);
// 范围查询
queryWrapper.gt(ObjectUtils.isNotEmpty(commissionDateStart), "commission_date", commissionDateStart);
queryWrapper.lt(ObjectUtils.isNotEmpty(commissionDateEnd), "commission_date", commissionDateEnd);
queryWrapper.ge(ObjectUtils.isNotEmpty(commissionDateStart), "commission_date", commissionDateStart);
queryWrapper.le(ObjectUtils.isNotEmpty(commissionDateEnd), "commission_date", commissionDateEnd);
// 转介人所属团队业务ID 关联保单表查询
if (StringUtils.isNotBlank(teamBizId)) {
queryWrapper.apply("EXISTS (SELECT 1 FROM policy_broker pb WHERE pb.policy_no = commission_expected.policy_no AND pb.team_biz_id = {0})",
......@@ -545,11 +544,37 @@ public class CommissionExpectedServiceImpl extends ServiceImpl<CommissionExpecte
expectedStatisticsVO.setPendingPaidAmount(BigDecimal.ZERO);
expectedStatisticsVO.setPaidAmountRatio(BigDecimal.ZERO);
expectedStatisticsVO.setTotalPolicyCount(0);
expectedStatisticsVO.setTotalPremium(BigDecimal.ZERO);
return expectedStatisticsVO;
}
// 自定义统计数据
CommissionExpectedStatisticsVO commissionStatistics = baseMapper.getExpectedStatistics(expectedIds);
// 计算总保费
String policyNos = commissionStatistics.getPolicyNos();
if (ObjectUtils.isNotEmpty(policyNos)) {
List<CommissionExpected> commissionExpectedList = this.listByIds(expectedIds);
Map<String, BigDecimal> exchangeRateMap = new HashMap<>();
for (CommissionExpected commissionExpected : commissionExpectedList) {
exchangeRateMap.put(commissionExpected.getPolicyNo(), commissionExpected.getDefaultExchangeRate());
}
Set<String> policyNoSet = commissionExpectedList.stream().map(CommissionExpected::getPolicyNo).collect(Collectors.toSet());
// 查询总保费
List<Policy> policyList = policyService.lambdaQuery().in(Policy::getPolicyNo, policyNoSet).list();
BigDecimal totalPremium = BigDecimal.ZERO;
if (CollectionUtils.isNotEmpty(policyList)) {
for (Policy policy : policyList) {
BigDecimal exchangeRate = exchangeRateMap.getOrDefault(policy.getPolicyNo(), BigDecimal.ONE);
totalPremium = totalPremium.add(policy.getTotalPaymentPremium().multiply(exchangeRate));
}
commissionStatistics.setTotalPremium(totalPremium);
}
} else {
commissionStatistics.setTotalPremium(BigDecimal.ZERO);
}
BigDecimal totalAmount = commissionStatistics.getTotalAmount();
BigDecimal totalPaidAmount = commissionStatistics.getTotalPaidAmount();
// 计算待入账金额
......@@ -608,12 +633,15 @@ public class CommissionExpectedServiceImpl extends ServiceImpl<CommissionExpecte
// 匹配规格并获取不匹配的条件
MatchResult matchResult = matchExpectedSpecies(
expectedSpeciesList, paymentTerm, reconciliationCompanyBizId,
policyHolderAge, paymentPremium, effectiveDate);
policyHolderAge, paymentPremium, effectiveDate, policy);
if (matchResult.getMatchedList().isEmpty()) {
String errorMsg = matchResult.getUnmatchedConditions().isEmpty()
? "未查询到对应供款年期的佣金规格"
: "未查询到对应供款年期的佣金规格,不匹配条件:" + String.join("、", matchResult.getUnmatchedConditions());
log.info("未查询到对应供款年期的佣金规格,当前规格:{}", JSONUtil.toJsonStr(expectedSpeciesList));
throw new BusinessException(ResultCode.FAIL.getCode(), errorMsg);
}
......@@ -630,6 +658,7 @@ public class CommissionExpectedServiceImpl extends ServiceImpl<CommissionExpecte
commissionExpected.setCommissionBizType("R");
commissionExpected.setPolicyNo(policyNo);
commissionExpected.setPremium(paymentPremium);
commissionExpected.setPolicyCurrency(policy.getCurrency());
commissionExpected.setInsuranceCompanyBizId(insuranceCompanyBizId);
commissionExpected.setProductLaunchBizId(productLaunchBizId);
commissionExpected.setReconciliationCompany(reconciliationCompany);
......@@ -705,7 +734,7 @@ public class CommissionExpectedServiceImpl extends ServiceImpl<CommissionExpecte
*/
private MatchResult matchExpectedSpecies(List<ApiExpectedSpeciesListResponse> expectedSpeciesList,
String paymentTerm, String reconciliationCompanyId,
Integer policyHolderAge, BigDecimal paymentPremium, Date effectiveDate) {
Integer policyHolderAge, BigDecimal paymentPremium, Date effectiveDate, Policy policy) {
List<String> unmatchedConditions = new ArrayList<>();
List<ApiExpectedSpeciesListResponse> currentList = expectedSpeciesList;
......@@ -720,7 +749,7 @@ public class CommissionExpectedServiceImpl extends ServiceImpl<CommissionExpecte
// 检查对账公司
currentList = filterAndCheck(currentList,
i -> reconciliationCompanyId.equals(i.getReconciliationCompany()),
unmatchedConditions, "对账公司[" + reconciliationCompanyId + "]");
unmatchedConditions, "对账公司[" + policy.getReconciliationCompany() + "]");
if (unmatchedConditions.size() > 0) {
return new MatchResult(Collections.emptyList(), unmatchedConditions);
}
......@@ -741,7 +770,7 @@ public class CommissionExpectedServiceImpl extends ServiceImpl<CommissionExpecte
// 检查生效日期
currentList = filterAndCheck(currentList,
i -> isEffective(i.getEffectiveStart(), i.getEffectiveEnd(), effectiveDate),
unmatchedConditions, "生效日期[" + effectiveDate + "]");
unmatchedConditions, "生效日期[" + DateUtil.format(effectiveDate, "yyyy-MM-dd") + "]");
if (unmatchedConditions.size() > 0) {
return new MatchResult(Collections.emptyList(), unmatchedConditions);
}
......
......@@ -28,15 +28,12 @@ import com.yd.csf.service.vo.CommissionStatisticsVO;
import com.yd.csf.service.vo.CommissionVO;
import com.yd.insurance.base.feign.client.insurancereconciliationcompany.ApiInsuranceReconciliationCompanyFeignClient;
import com.yd.insurance.base.feign.request.insurancereconciliationcompany.ApiInsuranceReconciliationCompanyPageRequest;
import com.yd.user.feign.client.sysdict.ApiSysDictFeignClient;
import com.yd.user.feign.response.sysdict.GetDictItemListByDictTypeResponse;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.collections4.CollectionUtils;
import org.apache.commons.collections4.MapUtils;
import org.apache.commons.lang3.ObjectUtils;
import org.apache.commons.lang3.StringUtils;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.transaction.support.TransactionSynchronization;
......@@ -272,7 +269,6 @@ public class CommissionServiceImpl extends ServiceImpl<CommissionMapper, Commiss
if (policy != null) {
// 填充保费、产品名称、保险公司、对账公司
commission.setPremium(String.valueOf(policy.getPaymentPremium()));
commission.setCurrency(policy.getCurrency());
commission.setPolicyCurrency(policy.getCurrency());
commission.setProductLaunchBizId(policy.getProductLaunchBizId());
commission.setInsuranceCompanyBizId(policy.getInsuranceCompanyBizId());
......@@ -299,7 +295,7 @@ public class CommissionServiceImpl extends ServiceImpl<CommissionMapper, Commiss
}
// 计算来佣金额(港币)
commission.setHkdAmount(calculateHKDAmount(commission.getAmount(), commission.getExchangeRate(), commission.getCurrency()));
commission.setHkdAmount(calculateHKDAmount(commission.getAmount(), commission.getCurrency()));
}
}
......@@ -378,11 +374,13 @@ public class CommissionServiceImpl extends ServiceImpl<CommissionMapper, Commiss
if (commission == null) {
throw new BusinessException(ResultCode.NULL_ERROR.getCode(), "未找到该来佣记录");
}
Policy policy = null;
if (StringUtils.isNotBlank(commission.getPolicyNo())) {
Policy policy = policyService.lambdaQuery().eq(Policy::getPolicyNo, commission.getPolicyNo()).one();
policy = policyService.lambdaQuery().eq(Policy::getPolicyNo, commission.getPolicyNo()).one();
if (policy == null) {
throw new BusinessException(ResultCode.NULL_ERROR.getCode(), "保单不存在:" + commission.getPolicyNo());
}
commission.setPolicyCurrency(policy.getCurrency());
}
BigDecimal requestAmount = commissionUpdateRequest.getAmount();
......@@ -401,10 +399,7 @@ public class CommissionServiceImpl extends ServiceImpl<CommissionMapper, Commiss
}
}
// 计算来佣金额(港币)
commission.setHkdAmount(calculateHKDAmount(
requestAmount,
commissionUpdateRequest.getExchangeRate(),
commissionUpdateRequest.getCurrency()));
commission.setHkdAmount(calculateHKDAmount(requestAmount, commissionUpdateRequest.getCurrency()));
// 获取当前登录用户
AuthUserDto currentLoginUser = SecurityUtil.getCurrentLoginUser();
......@@ -442,10 +437,14 @@ public class CommissionServiceImpl extends ServiceImpl<CommissionMapper, Commiss
return true;
}
private BigDecimal calculateHKDAmount(BigDecimal requestAmount, BigDecimal exchangeRate, String currency) {
private BigDecimal calculateHKDAmount(BigDecimal requestAmount, String currency) {
if ("HKD".equalsIgnoreCase(currency)) {
return requestAmount;
}
// 查询入账币种到港币的汇率
BigDecimal exchangeRate = queryExchangeRateByFeign(currency, "HKD");
return requestAmount.multiply(exchangeRate);
}
......@@ -629,6 +628,15 @@ public class CommissionServiceImpl extends ServiceImpl<CommissionMapper, Commiss
}
filteredExpectedFortuneList2.add(expectedFortune);
}
// 2.3 校验预计发佣记录是否有出账币种、默认结算汇率
for (ExpectedFortune expectedFortune : filteredExpectedFortuneList2) {
if (StringUtils.isBlank(expectedFortune.getCurrency())) {
throw new BusinessException(ResultCode.NULL_ERROR.getCode(), "预计发佣记录" + expectedFortune.getExpectedFortuneBizId() + "未配置出账币种");
}
if (expectedFortune.getDefaultExchangeRate() == null) {
throw new BusinessException(ResultCode.NULL_ERROR.getCode(), "预计发佣记录" + expectedFortune.getExpectedFortuneBizId() + "未配置默认结算汇率");
}
}
// 3. 构建实际的初始发佣记录
List<Fortune> newFortuneList = buildNewFortunes(filteredExpectedFortuneList2, commissions);
......@@ -721,7 +729,7 @@ public class CommissionServiceImpl extends ServiceImpl<CommissionMapper, Commiss
if (result != null && result.getData() != null) {
return result.getData();
}
return null;
return BigDecimal.ONE;
}
/**
......@@ -748,7 +756,7 @@ public class CommissionServiceImpl extends ServiceImpl<CommissionMapper, Commiss
throw new BusinessException(ResultCode.NULL_ERROR.getCode(), "当前结算汇率不能为空");
}
// 获取保单币种
String currency = commissionExpected.getCurrency();
String currency = commissionExpected.getPolicyCurrency();
// 如果当前入账币种等于保单币种,直接计算来佣比例
if (StringUtils.equalsIgnoreCase(currentCurrency, currency)) {
......@@ -824,8 +832,9 @@ public class CommissionServiceImpl extends ServiceImpl<CommissionMapper, Commiss
for (CommissionAddRequest request : customerAddRequestList) {
Commission commission = new Commission();
BeanUtils.copyProperties(request, commission);
// 计算来佣金额(港币)
commission.setHkdAmount(calculateHKDAmount(request.getAmount(), request.getExchangeRate(), request.getCurrency()));
commission.setHkdAmount(calculateHKDAmount(request.getAmount(), request.getCurrency()));
// 入账业务id
commission.setCommissionBizId(RandomStringGenerator.generateBizId16(CommonEnum.UID_TYPE_COMMISSION.getCode()));
// 关联业务id
......@@ -838,7 +847,6 @@ public class CommissionServiceImpl extends ServiceImpl<CommissionMapper, Commiss
commission.setProductLaunchBizId(policy.getProductLaunchBizId());
commission.setInsuranceCompanyBizId(policy.getInsuranceCompanyBizId());
commission.setPremium(Convert.toStr(policy.getPaymentPremium()));
commission.setCurrency(policy.getCurrency());
commission.setPolicyCurrency(policy.getCurrency());
} else {
throw new BusinessException(ResultCode.PARAMS_ERROR.getCode(), "保单不存在, policyNo: " + request.getPolicyNo());
......@@ -857,23 +865,24 @@ public class CommissionServiceImpl extends ServiceImpl<CommissionMapper, Commiss
commissionList.add(commission);
}
// 提交事务,保存数据
transactionTemplate.execute(status -> {
saveOrUpdateBatch(commissionList);
return null;
});
// 1. 先保存主数据
saveOrUpdateBatch(commissionList);
// 开启新事务,比对数据
transactionTemplate.execute(status -> {
try {
commissionAsyncService.commissionCompareBatch(commissionList);
} catch (Exception e) {
// 比对失败不影响主事务,记录日志即可
e.printStackTrace();
log.error("批量新增, 比对操作执行失败, error: {}", e.getMessage());
}
return null;
});
// 2. 事务提交后执行比对
TransactionSynchronizationManager.registerSynchronization(
new TransactionSynchronization() {
@Override
public void afterCommit() {
try {
// 这里会开启新事务执行更新
commissionAsyncService.commissionCompareBatch(commissionList);
} catch (Exception e) {
log.error("比对更新失败", e);
// 可以发送告警或记录失败任务
}
}
}
);
return commissionList;
}
......@@ -941,6 +950,9 @@ public class CommissionServiceImpl extends ServiceImpl<CommissionMapper, Commiss
if (ObjectUtils.isEmpty(request.getAmount())) {
throw new BusinessException(ResultCode.PARAMS_ERROR.getCode(), "入账金额不能为空");
}
if (ObjectUtils.isEmpty(request.getExchangeRate())) {
throw new BusinessException(ResultCode.PARAMS_ERROR.getCode(), "结算汇率不能为空");
}
if ("R".equals(request.getCommissionBizType())) {
// 校验保单号是否存在
if (ObjectUtils.isEmpty(request.getExchangeRate())) {
......
......@@ -6,6 +6,7 @@ import com.baomidou.mybatisplus.core.metadata.IPage;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.yd.csf.feign.request.expectedfortune.ApiExpectedFortunePageRequest;
import com.yd.csf.feign.response.expectedfortune.ApiExpectedFortunePageResponse;
import com.yd.csf.service.enums.CurrencyEnum;
import com.yd.csf.service.model.ExpectedFortune;
import com.yd.csf.service.dao.ExpectedFortuneMapper;
import com.yd.csf.service.model.Policy;
......@@ -133,6 +134,8 @@ public class ExpectedFortuneServiceImpl extends ServiceImpl<ExpectedFortuneMappe
ApiExpectedFortunePageResponse vo = new ApiExpectedFortunePageResponse();
BeanUtils.copyProperties(ef, vo);
vo.setCurrency(CurrencyEnum.toLabel(ef.getCurrency()));
String ratio = finalBrokerRatioMap.get(ef.getBrokerBizId());
vo.setCommissionRatio(ratio);
......
......@@ -122,7 +122,9 @@ public class FortuneAccountServiceImpl extends ServiceImpl<FortuneAccountMapper,
FortuneAccount fortuneAccount = new FortuneAccount();
fortuneAccount.setFortuneAccountBizId(RandomStringGenerator.generateBizId16("fortune_account"));
fortuneAccount.setBroker(accountExportDTO.getBroker());
fortuneAccount.setBrokerBizId(accountExportDTO.getBrokerBizId());
fortuneAccount.setTeam(accountExportDTO.getTeam());
fortuneAccount.setTeamBizId(accountExportDTO.getTeamBizId());
fortuneAccount.setCurrency(accountExportDTO.getCurrency());
fortuneAccount.setHkdAmount(accountExportDTO.getAmount());
fortuneAccount.setFortuneAccountDate(currentDate);
......@@ -161,6 +163,10 @@ public class FortuneAccountServiceImpl extends ServiceImpl<FortuneAccountMapper,
updateFortune.setId(item.getId());
updateFortune.setFortuneAccountBizId(fortuneAccountBizId);
updateFortune.setStatus(FortuneStatusEnum.CHECKED.getItemValue());
// 处理金额字段
updateFortune.setCurrentPaymentHkdAmount(item.getHkdAmount());
updateFortune.setCurrentPaymentRatio(BigDecimal.valueOf(100));
updateFortune.setReconciliationOperator(currentLoginUser.getUsername());
updateFortuneList.add(updateFortune);
}
}
......@@ -283,6 +289,10 @@ public class FortuneAccountServiceImpl extends ServiceImpl<FortuneAccountMapper,
.list();
if (CollectionUtils.isNotEmpty(fortunes)) {
fortunes.forEach(f -> {
if (f.getCurrentPaymentHkdAmount() == null) {
f.setCurrentPaymentHkdAmount(f.getHkdAmount());
f.setCurrentPaymentRatio(BigDecimal.valueOf(100));
}
f.setStatus(FortuneStatusEnum.SENT.getItemValue());
f.setActualPayoutDate(new Date());
f.setUpdaterId(loginUserId.toString());
......@@ -306,20 +316,20 @@ public class FortuneAccountServiceImpl extends ServiceImpl<FortuneAccountMapper,
.last("FOR UPDATE")
.list();
// 4.3 全量汇总:把同一 expected_fortune 下所有 fortune 的 current_payment_amount 求和
// 4.3 全量汇总:把同一 expected_fortune 下所有 fortune 的 current_payment_hkd_amount 求和
Map<String, BigDecimal> paidMap = fortuneService.lambdaQuery()
.in(Fortune::getExpectedFortuneBizId, expectedIds)
.eq(Fortune::getStatus, FortuneStatusEnum.SENT.getItemValue())
.list()
.stream()
.collect(Collectors.groupingBy(Fortune::getExpectedFortuneBizId,
Collectors.mapping(Fortune::getCurrentPaymentAmount,
Collectors.mapping(Fortune::getCurrentPaymentHkdAmount,
Collectors.reducing(BigDecimal.ZERO, BigDecimal::add))));
// 4.4 反写 expected_fortune
expectedList.forEach(ef -> {
BigDecimal totalPaid = paidMap.getOrDefault(ef.getExpectedFortuneBizId(), BigDecimal.ZERO);
BigDecimal totalAmount = ef.getAmount();
BigDecimal totalAmount = ef.getHkdAmount();
BigDecimal unpaid = totalAmount.subtract(totalPaid);
String newStatus;
......@@ -339,6 +349,7 @@ public class FortuneAccountServiceImpl extends ServiceImpl<FortuneAccountMapper,
.set(ExpectedFortune::getUnpaidRatio,
unpaid.divide(totalAmount, 4, RoundingMode.HALF_UP).multiply(BigDecimal.valueOf(100)))
.set(ExpectedFortune::getStatus, newStatus)
.set(ExpectedFortune::getActualPayoutDate, new Date())
.set(ExpectedFortune::getUpdaterId, loginUserId.toString())
.set(ExpectedFortune::getUpdateTime, LocalDateTime.now())
.eq(ExpectedFortune::getId, ef.getId())
......
......@@ -183,15 +183,9 @@ public class FortuneServiceImpl extends ServiceImpl<FortuneMapper, Fortune>
}
BigDecimal currentPaymentHkdAmount = fortuneUpdateRequest.getCurrentPaymentHkdAmount();
if (currentPaymentHkdAmount != null) {
if (currentPaymentHkdAmount.compareTo(BigDecimal.ZERO) < 0) {
throw new BusinessException(ResultCode.PARAM_CHECK_ERROR.getCode(), "出账港币金额不能小于0");
}
if (currentPaymentHkdAmount.compareTo(expectedFortune.getHkdAmount()) > 0) {
throw new BusinessException(ResultCode.PARAM_CHECK_ERROR.getCode(), "出账港币金额不能大于应付款港币金额");
}
if (StringUtils.isBlank(fortuneUpdateRequest.getCurrency())) {
throw new BusinessException(ResultCode.PARAM_CHECK_ERROR.getCode(), "出账币种不能为空");
}
}
// 更新结算汇率
BigDecimal exchangeRate = ObjectUtils.isNotEmpty((fortuneUpdateRequest.getExchangeRate()))
......@@ -214,22 +208,40 @@ public class FortuneServiceImpl extends ServiceImpl<FortuneMapper, Fortune>
if (currentPaymentHkdAmount != null && currentPaymentHkdAmount.compareTo(BigDecimal.ZERO) != 0) {
splitFortune(fortune, currentPaymentHkdAmount, expectedFortune, loginUserId, fortuneUpdateRequest);
} else {
// 如果未传入金额,仅更新预计出账状态为已出帐
expectedFortuneService.lambdaUpdate()
.set(ExpectedFortune::getStatus, fortuneUpdateRequest.getStatus())
.eq(ExpectedFortune::getId, expectedFortune.getId())
.update();
// 如果未传入金额,全额发放,出账状态为已出帐
totalFortune(fortune, expectedFortune, loginUserId, fortuneUpdateRequest);
}
return true;
}
// 统一更新实际出账数据
BeanUtils.copyProperties(fortuneUpdateRequest, fortune, "id", "fortuneBizId", "expectedFortuneBizId", "commissionBizId");
private void totalFortune(Fortune fortune, ExpectedFortune expectedFortune, String loginUserId, FortuneUpdateRequest fortuneUpdateRequest) {
// 更新实际出账数据
fortune.setUpdaterId(loginUserId);
fortune.setUpdateTime(new Date());
AuthUserDto currentLoginUser = SecurityUtil.getCurrentLoginUser();
this.updateById(fortune);
}
return true;
// 1. 更新fortune记录为全额发放状态
fortune.setCurrentPaymentHkdAmount(fortune.getHkdAmount());
fortune.setCurrentPaymentRatio(BigDecimal.valueOf(100));
fortune.setStatus(FortuneStatusEnum.CHECKED.getItemValue());
fortune.setReconciliationOperator(currentLoginUser.getUsername());
fortune.setUpdaterId(loginUserId);
fortune.setUpdateTime(new Date());
// 更新实际出账日期
Date actualPayoutDate = new Date();
fortune.setActualPayoutDate(actualPayoutDate);
this.updateById(fortune);
// 2. 更新expected_fortune记录为已全额发放状态
// 统一使用港币金额
expectedFortune.setPaidAmount(expectedFortune.getHkdAmount());
expectedFortune.setUnpaidAmount(BigDecimal.ZERO);
expectedFortune.setPaidRatio(BigDecimal.valueOf(100));
expectedFortune.setUnpaidRatio(BigDecimal.ZERO);
expectedFortune.setStatus("6"); // 全额发放完成状态
expectedFortune.setActualPayoutDate(LocalDate.now());
expectedFortuneService.updateById(expectedFortune);
}
private BigDecimal queryDefaultExchangeRate(String currency) {
......@@ -254,25 +266,25 @@ public class FortuneServiceImpl extends ServiceImpl<FortuneMapper, Fortune>
* 拆分发放(按本次发放金额拆)
*/
@Transactional(rollbackFor = Exception.class)
public void splitFortune(Fortune main, BigDecimal currentPaymentAmount, ExpectedFortune expectedFortune, String loginUserId, FortuneUpdateRequest fortuneUpdateRequest) {
if (currentPaymentAmount == null || currentPaymentAmount.compareTo(BigDecimal.ZERO) <= 0)
throw new BusinessException("本次发放金额必须大于0");
public void splitFortune(Fortune main, BigDecimal currentPaymentHkdAmount, ExpectedFortune expectedFortune, String loginUserId, FortuneUpdateRequest fortuneUpdateRequest) {
if (!main.getStatus().equals(FortuneStatusEnum.CAN_SEND.getItemValue()))
throw new BusinessException("只有可出账记录才能修改金额");
BigDecimal fullAmount = main.getAmount();
if (currentPaymentAmount.compareTo(main.getCurrentPaymentAmount()) > 0)
BigDecimal fullAmount = main.getHkdAmount();
if (currentPaymentHkdAmount.compareTo(main.getCurrentPaymentHkdAmount()) > 0)
throw new BusinessException("本次发放金额不能大于可出账金额");
// 本次发放港币金额
BigDecimal currentHkdAmount = currentPaymentAmount.multiply(main.getExchangeRate());
// 获取当前登录用户的ID
AuthUserDto currentLoginUser = SecurityUtil.getCurrentLoginUser();
// 1. 更新主行 = 本次发放金额
main.setCurrentPaymentAmount(currentPaymentAmount);
main.setCurrentPaymentHkdAmount(currentHkdAmount);
main.setCurrentPaymentRatio(currentPaymentAmount
.divide(expectedFortune.getAmount(), 4, RoundingMode.HALF_UP).multiply(BigDecimal.valueOf(100)));
main.setCurrentPaymentAmount(null);
main.setCurrentPaymentHkdAmount(currentPaymentHkdAmount);
main.setCurrentPaymentRatio(currentPaymentHkdAmount
.divide(expectedFortune.getHkdAmount(), 4, RoundingMode.HALF_UP).multiply(BigDecimal.valueOf(100)));
main.setStatus(FortuneStatusEnum.CHECKED.getItemValue());
main.setReconciliationOperator(currentLoginUser.getUsername());
main.setUpdaterId(loginUserId);
main.setUpdateTime(new Date());
// 其他字段更新
......@@ -282,43 +294,39 @@ public class FortuneServiceImpl extends ServiceImpl<FortuneMapper, Fortune>
this.updateById(main);
// 2. 剩余金额生成新行
BigDecimal leftAmount = fullAmount.subtract(currentPaymentAmount);
BigDecimal leftAmount = fullAmount.subtract(currentPaymentHkdAmount);
if (leftAmount.compareTo(BigDecimal.ZERO) > 0) {
Fortune part = new Fortune();
BeanUtils.copyProperties(main, part, "id", "fortuneBizId", "currentPaymentAmount", "status", "isPart", "payoutDate");
part.setFortuneBizId(RandomStringGenerator.generateBizId16(CommonEnum.UID_TYPE_FORTUNE.getCode()));
part.setCurrentPaymentAmount(leftAmount);
part.setCurrentPaymentHkdAmount(leftAmount.multiply(main.getExchangeRate()));
part.setCurrentPaymentAmount(null);
part.setCurrentPaymentHkdAmount(leftAmount);
part.setCurrentPaymentRatio(leftAmount
.divide(expectedFortune.getAmount(), 4, RoundingMode.HALF_UP).multiply(BigDecimal.valueOf(100)));
.divide(expectedFortune.getHkdAmount(), 4, RoundingMode.HALF_UP).multiply(BigDecimal.valueOf(100)));
part.setStatus(FortuneStatusEnum.WAIT.getItemValue());
part.setIsPart(1);
part.setPayoutDate(LocalDate.now().plusMonths(1)); // 次月
part.setReconciliationOperator(currentLoginUser.getUsername());
part.setCreatorId(loginUserId);
part.setCreateTime(new Date());
this.save(part);
}
// 3. 同步 expected_fortune
ExpectedFortune ef = expectedFortuneService.lambdaQuery()
.eq(ExpectedFortune::getExpectedFortuneBizId, main.getExpectedFortuneBizId())
.one();
if (ef == null) return;
// 统一使用港币金额
BigDecimal newPaid = ef.getPaidAmount() == null ? BigDecimal.ZERO : ef.getPaidAmount().add(currentHkdAmount);
BigDecimal newUnpaid = ef.getHkdAmount().subtract(newPaid);
BigDecimal newPaid = expectedFortune.getPaidAmount() == null ? BigDecimal.ZERO : expectedFortune.getPaidAmount().add(currentPaymentHkdAmount);
BigDecimal newUnpaid = expectedFortune.getHkdAmount().subtract(newPaid);
String newStatus = newUnpaid.compareTo(BigDecimal.ZERO) == 0 ? "6" : "3";
expectedFortuneService.lambdaUpdate()
.set(ExpectedFortune::getPaidAmount, newPaid)
.set(ExpectedFortune::getUnpaidAmount, newUnpaid)
.set(ExpectedFortune::getPaidRatio,
newPaid.divide(ef.getHkdAmount(), 4, RoundingMode.HALF_UP).multiply(BigDecimal.valueOf(100)))
newPaid.divide(expectedFortune.getHkdAmount(), 4, RoundingMode.HALF_UP).multiply(BigDecimal.valueOf(100)))
.set(ExpectedFortune::getUnpaidRatio,
newUnpaid.divide(ef.getHkdAmount(), 4, RoundingMode.HALF_UP).multiply(BigDecimal.valueOf(100)))
newUnpaid.divide(expectedFortune.getHkdAmount(), 4, RoundingMode.HALF_UP).multiply(BigDecimal.valueOf(100)))
.set(ExpectedFortune::getStatus, newStatus)
.eq(ExpectedFortune::getId, ef.getId())
.eq(ExpectedFortune::getId, expectedFortune.getId())
.update();
}
......@@ -392,11 +400,13 @@ public class FortuneServiceImpl extends ServiceImpl<FortuneMapper, Fortune>
FortuneAccountExportDTO accountDTO = new FortuneAccountExportDTO();
accountDTO.setBroker(broker);
accountDTO.setBrokerBizId(brokerFortunes.get(0).getBrokerBizId());
accountDTO.setFortuneList(brokerFortunes);
// 设置团队、币种(取第一个记录)
if (CollUtil.isNotEmpty(brokerFortunes)) {
accountDTO.setTeam(brokerFortunes.get(0).getTeam());
accountDTO.setTeamBizId(brokerFortunes.get(0).getTeamBizId());
accountDTO.setCurrency(currency);
}
......
......@@ -113,17 +113,17 @@ public class PolicyFollowServiceImpl extends ServiceImpl<PolicyFollowMapper, Pol
String appointmentNo = policyFollowQueryRequest.getAppointmentNo();
Date signDateStart = policyFollowQueryRequest.getSignDateStart();
Date signDateEnd = policyFollowQueryRequest.getSignDateEnd();
Date latestPaymentDate = policyFollowQueryRequest.getLatestPaymentDate();
String latestPaymentDate = policyFollowQueryRequest.getLatestPaymentDate();
List<String> insuranceCompanyBizIdList = policyFollowQueryRequest.getInsuranceCompanyBizIdList();
List<String> productLaunchBizIdList = policyFollowQueryRequest.getProductLaunchBizIdList();
String issueNumber = policyFollowQueryRequest.getIssueNumber();
Integer issueNumber = policyFollowQueryRequest.getIssueNumber();
queryWrapper.like(ObjectUtils.isNotEmpty(policyNo), "policy_no", policyNo);
queryWrapper.eq(ObjectUtils.isNotEmpty(status), "status", status);
queryWrapper.eq(ObjectUtils.isNotEmpty(appointmentNo), "appointment_no", appointmentNo);
queryWrapper.ge(ObjectUtils.isNotEmpty(signDateStart), "sign_date", signDateStart);
queryWrapper.le(ObjectUtils.isNotEmpty(signDateEnd), "sign_date", signDateEnd);
queryWrapper.ge(ObjectUtils.isNotEmpty(latestPaymentDate), "latest_payment_date", latestPaymentDate);
queryWrapper.eq(ObjectUtils.isNotEmpty(latestPaymentDate), "latest_payment_date", latestPaymentDate);
if (CollectionUtils.isNotEmpty(insuranceCompanyBizIdList)) {
queryWrapper.in("insurance_company_biz_id", insuranceCompanyBizIdList);
......@@ -503,20 +503,21 @@ public class PolicyFollowServiceImpl extends ServiceImpl<PolicyFollowMapper, Pol
if (policy == null) {
throw new BusinessException(ErrorCode.NOT_FOUND_ERROR.getCode(), "policy不存在");
}
BigDecimal paymentPremium = policy.getPaymentPremium();
if (paymentPremium == null) {
throw new BusinessException("期交保费不能为空");
}
Object paymentTerm = policy.getPaymentTerm();
if (paymentTerm == null) {
throw new BusinessException("供款期数不能为空");
}
// 新单跟进,校验 policy 数据
policyFollowChangeStatusValidPolicy(policy);
// 新单跟进,校验 policyFollow 数据
policyFollowChangeStatusValidPolicyFollow(policyFollow);
policy.setPolicyNo(policyFollow.getPolicyNo());
policy.setPolicyHolderAge(calculatePolicyHolderAge(policyFollow.getCustomerBizId()));
policy.setCoolingOffEndDate(policyFollow.getCoolingOffEndDate());
policy.setReconciliationCompanyBizId(policyFollow.getReconciliationCompanyBizId());
policy.setReconciliationCompanyCode(policyFollow.getReconciliationCompanyCode());
policy.setReconciliationCompany(policyFollow.getReconciliationCompany());
policy.setInsuranceCompanyBizId(policyFollow.getInsuranceCompanyBizId());
policy.setInsuranceCompany(policyFollow.getInsuranceCompany());
policy.setProductName(policyFollow.getProductName());
// 更新保单状态为生效
policy.setStatus(PolicyStatusEnum.INFORCE.getItemValue());
// 手动映射不同名的字段
......@@ -529,20 +530,24 @@ public class PolicyFollowServiceImpl extends ServiceImpl<PolicyFollowMapper, Pol
//冷静期结束日期
policy.setCoolingOffEndDate(changePolicyFollowStatusRequest.getCoolingOffEndDate() != null ? changePolicyFollowStatusRequest.getCoolingOffEndDate() : policy.getCoolingOffEndDate());
if (ObjectUtils.isEmpty(policy.getInsuranceCompany()) || ObjectUtils.isEmpty(policy.getInsuranceCompany())) {
// 获取保单产品信息,填充对账公司相关字段
PolicyProductInfo productInfo = getPolicyProductInfo(policyFollow.getProductLaunchBizId());
if (productInfo != null) {
policy.setInsuranceCompany(productInfo.getInsuranceCompany());
policy.setInsuranceCompanyBizId(productInfo.getInsuranceCompanyBizId());
if (ObjectUtils.isEmpty(policy.getReconciliationCompany())) {
policy.setReconciliationCompany(productInfo.getReconciliationCompany());
}
if (ObjectUtils.isEmpty(policy.getReconciliationCompanyBizId())) {
policy.setReconciliationCompanyBizId(productInfo.getReconciliationCompanyBizId());
}
}
}
// if (ObjectUtils.isEmpty(policy.getInsuranceCompany()) || ObjectUtils.isEmpty(policy.getInsuranceCompanyBizId())) {
// // 获取保单产品信息,填充对账公司相关字段
// PolicyProductInfo productInfo = getPolicyProductInfo(policyFollow.getProductLaunchBizId());
// if (productInfo != null) {
// if (ObjectUtils.isNotEmpty(productInfo.getInsuranceCompany())) {
// policy.setInsuranceCompany(productInfo.getInsuranceCompany());
// }
// if (ObjectUtils.isNotEmpty(productInfo.getInsuranceCompanyBizId())) {
// policy.setInsuranceCompanyBizId(productInfo.getInsuranceCompanyBizId());
// }
// if (ObjectUtils.isNotEmpty(productInfo.getReconciliationCompanyBizId())) {
// policy.setReconciliationCompany(productInfo.getReconciliationCompany());
// }
// if (ObjectUtils.isNotEmpty(productInfo.getReconciliationCompanyBizId())) {
// policy.setReconciliationCompanyBizId(productInfo.getReconciliationCompanyBizId());
// }
// }
// }
// 保存保单
policyService.updateById(policy);
......@@ -573,6 +578,41 @@ public class PolicyFollowServiceImpl extends ServiceImpl<PolicyFollowMapper, Pol
return true;
}
private void policyFollowChangeStatusValidPolicyFollow(PolicyFollow policyFollow) {
if (ObjectUtils.isEmpty(policyFollow.getReconciliationCompanyBizId())) {
throw new BusinessException("新单跟进-基础数据,reconciliationCompanyBizId 不能为空");
}
if (ObjectUtils.isEmpty(policyFollow.getReconciliationCompanyCode())) {
throw new BusinessException("新单跟进-基础数据,reconciliationCompanyCode 不能为空");
}
if (ObjectUtils.isEmpty(policyFollow.getReconciliationCompany())) {
throw new BusinessException("新单跟进-基础数据,reconciliationCompany 不能为空");
}
if (ObjectUtils.isEmpty(policyFollow.getInsuranceCompanyBizId())) {
throw new BusinessException("新单跟进-基础数据,insuranceCompanyBizId 不能为空");
}
if (ObjectUtils.isEmpty(policyFollow.getInsuranceCompany())) {
throw new BusinessException("新单跟进-基础数据,insuranceCompany 不能为空");
}
if (ObjectUtils.isEmpty(policyFollow.getProductName())) {
throw new BusinessException("新单跟进-基础数据,productName 不能为空");
}
if (ObjectUtils.isEmpty(policyFollow.getProductLaunchBizId())) {
throw new BusinessException("新单跟进-基础数据,productLaunchBizId 不能为空");
}
}
private void policyFollowChangeStatusValidPolicy(Policy policy) {
BigDecimal paymentPremium = policy.getPaymentPremium();
if (paymentPremium == null) {
throw new BusinessException("期交保费不能为空");
}
Object paymentTerm = policy.getPaymentTerm();
if (paymentTerm == null) {
throw new BusinessException("供款期数不能为空");
}
}
private BigDecimal calculateTotalPaymentPremium(Policy policy) {
BigDecimal paymentPremium = policy.getPaymentPremium();
Object paymentTerm = policy.getPaymentTerm();
......@@ -667,9 +707,11 @@ public class PolicyFollowServiceImpl extends ServiceImpl<PolicyFollowMapper, Pol
currency = "USD";
break;
case "人民幣":
case "人民币":
currency = "CNY";
break;
case "港幣":
case "港币":
currency = "HKD";
break;
case "澳元":
......@@ -682,6 +724,7 @@ public class PolicyFollowServiceImpl extends ServiceImpl<PolicyFollowMapper, Pol
currency = "EUR";
break;
case "英鎊":
case "英镑":
currency = "GBP";
break;
case "新加坡元":
......
package com.yd.csf.service.vo;
import com.fasterxml.jackson.annotation.JsonIgnore;
import io.swagger.v3.oas.annotations.media.Schema;
import lombok.Data;
......@@ -39,4 +40,13 @@ public class CommissionExpectedStatisticsVO {
*/
@Schema(description = "总保单数")
private Integer totalPolicyCount;
/**
* 总保费(HKD)
*/
@Schema(description = "总保费(HKD)")
private BigDecimal totalPremium;
@JsonIgnore
private String policyNos;
}
package com.yd.csf.service.vo;
import com.fasterxml.jackson.annotation.JsonFormat;
import com.yd.csf.service.enums.CommissionStatusEnum;
import com.yd.csf.service.model.Commission;
import io.swagger.v3.oas.annotations.media.Schema;
import lombok.Data;
......@@ -165,6 +166,12 @@ public class CommissionVO implements Serializable {
private String commissionStatus;
/**
* 比对状态名称
*/
@Schema(description = "比对状态 0=未比对 1=比对成功 2=比对失败 3=未匹配到预计入账记录 字典值: csf_commission_status")
private String commissionStatusName;
/**
* 预计来佣业务id
*/
@Schema(description = "预计来佣业务id")
......@@ -246,7 +253,9 @@ public class CommissionVO implements Serializable {
}
CommissionVO commissionVO = new CommissionVO();
BeanUtils.copyProperties(commission, commissionVO);
commissionVO.setCommissionStatus(commission.getStatus());
commissionVO.setCommissionStatusName(CommissionStatusEnum.toLabel(commission.getStatus()));
return commissionVO;
}
}
package com.yd.csf.service.vo;
import cn.hutool.core.util.NumberUtil;
import cn.hutool.core.util.ObjectUtil;
import com.fasterxml.jackson.annotation.JsonFormat;
import com.yd.csf.service.model.ExpectedFortune;
import com.yd.csf.service.enums.CurrencyEnum;
import com.yd.csf.service.model.Fortune;
import io.swagger.v3.oas.annotations.media.Schema;
import lombok.Data;
......@@ -9,7 +11,6 @@ import org.springframework.beans.BeanUtils;
import java.io.Serializable;
import java.math.BigDecimal;
import java.math.RoundingMode;
import java.time.LocalDate;
import java.util.Date;
......@@ -232,7 +233,7 @@ public class FortuneVO implements Serializable {
*/
@Schema(description = "出账日(实)")
@JsonFormat(pattern = "yyyy-MM-dd", timezone = "GMT+8")
private LocalDate actualPayoutDate;
private Date actualPayoutDate;
/**
* 是否含税 0=No, 1=Yes
......@@ -328,12 +329,16 @@ public class FortuneVO implements Serializable {
}
FortuneVO fortuneVO = new FortuneVO();
BeanUtils.copyProperties(fortune, fortuneVO);
// 待出账比例
if (fortuneVO.getCurrentPaymentRatio() != null) {
fortuneVO.setFortuneUnpaidRatio(BigDecimal.valueOf(100).subtract(fortuneVO.getCurrentPaymentRatio()));
} else {
fortuneVO.setFortuneUnpaidRatio(BigDecimal.valueOf(100));
}
// 计算待出账比例
BigDecimal currentPaymentRatio = ObjectUtil.defaultIfNull(fortuneVO.getCurrentPaymentRatio(), BigDecimal.ZERO);
fortuneVO.setCurrentPaymentRatio(currentPaymentRatio);
fortuneVO.setFortuneUnpaidRatio(BigDecimal.valueOf(100).subtract(currentPaymentRatio));
fortuneVO.setFortunePaidAmount(fortune.getCurrentPaymentHkdAmount());
fortuneVO.setFortuneUnpaidAmount(NumberUtil.sub(fortune.getHkdAmount(), fortune.getCurrentPaymentHkdAmount()));
fortuneVO.setCurrency(CurrencyEnum.toLabel(fortune.getCurrency()));
fortuneVO.setPolicyCurrency((CurrencyEnum.toLabel(fortune.getPolicyCurrency())));
return fortuneVO;
}
......
......@@ -11,6 +11,7 @@
<result property="commissionBizType" column="commission_biz_type" />
<result property="policyNo" column="policy_no" />
<result property="premium" column="premium" />
<result property="policyCurrency" column="policy_currency" />
<result property="insuranceCompanyBizId" column="insurance_company_biz_id" />
<result property="productLaunchBizId" column="product_launch_biz_id" />
<result property="reconciliationCompany" column="reconciliation_company" />
......@@ -41,7 +42,7 @@
<sql id="Base_Column_List">
id,commission_expected_biz_id,receivable_no,commission_biz_type,
policy_no,premium,insurance_company_biz_id,product_launch_biz_id,
policy_no,premium,policy_currency,insurance_company_biz_id,product_launch_biz_id,
reconciliation_company,reconciliation_company_code,reconciliation_company_biz_id,commission_period,
total_period,commission_name,commission_type,commission_ratio,amount,currency,default_exchange_rate,expected_amount,
commission_date,status,status_desc,paid_amount,paid_ratio,remark,is_deleted,creator_id,
......@@ -52,9 +53,10 @@
SELECT
IFNULL(SUM(expected_amount),0) AS totalAmount,
IFNULL(SUM(paid_amount),0) AS totalPaidAmount,
COUNT(DISTINCT policy_no) AS totalPolicyCount
COUNT(DISTINCT policy_no) AS totalPolicyCount,
GROUP_CONCAT(DISTINCT policy_no) AS policyNos
FROM
commission_expected
commission_expected ce
<where>
<if test="expectedIds != null and expectedIds.size > 0">
id IN
......@@ -73,7 +75,7 @@
MAX(ce.reconciliation_company_biz_id) as reconciliationCompanyBizId,
ce.commission_period as commissionPeriod,
MAX(ce.total_period) as totalPeriod,
DATE_ADD(DATE_ADD(MAX(p.effective_date), INTERVAL 2 MONTH), INTERVAL (ce.commission_period - 1) YEAR) as commissionDate,
MAX(ce.commission_date) as commissionDate,
ifnull(avg(ce.commission_ratio), 0) as commissionRatio,
ifnull(sum(ce.amount), 0) as amount,
MAX(ce.currency) as currency,
......
......@@ -107,7 +107,7 @@
) as expectePaidAmount,
COUNT(DISTINCT c.policy_no) as totalPolicyCount,
COALESCE(p.total_payment_premium * e.default_exchange_rate, 0) AS totalPremium,
COUNT(DISTINCT c.reconciliation_company) as reconciliationCompanyCount,
COUNT(DISTINCT c.reconciliation_company_code) as reconciliationCompanyCount,
COUNT(DISTINCT c.id) as totalCompareCommissionCount,
SUM(CASE WHEN c.status = '1' THEN 1 ELSE 0 END) as successCompareCommissionCount,
SUM(CASE WHEN c.status = '2' THEN 1 ELSE 0 END) as failedCompareCommissionCount
......
......@@ -8,6 +8,9 @@
<id property="id" column="id" />
<result property="fortuneAccountBizId" column="fortune_account_biz_id" />
<result property="broker" column="broker" />
<result property="brokerBizId" column="broker_biz_id" />
<result property="team" column="team" />
<result property="teamBizId" column="team_biz_id" />
<result property="currency" column="currency" />
<result property="amount" column="amount" />
<result property="hkdAmount" column="hkd_amount" />
......@@ -23,7 +26,8 @@
</resultMap>
<sql id="Base_Column_List">
id,fortune_account_biz_id,broker,currency,amount,hkd_amount,status,fortune_account_date,content,remark,
id,fortune_account_biz_id,broker,broker_biz_id,team,team_biz_id,
currency,amount,hkd_amount,status,fortune_account_date,content,remark,
is_deleted,creator_id,updater_id,create_time,update_time
</sql>
</mapper>
......@@ -63,13 +63,13 @@
<select id="getFortuneStatistics" resultType="com.yd.csf.service.dto.FortuneStatisticsVO">
SELECT
f.policy_no,
SUM(CASE WHEN f.is_part = '0' THEN f.hkd_amount ELSE 0 END) AS amount,
IFNULL(SUM(CASE WHEN f.is_part = '0' THEN f.hkd_amount ELSE 0 END),0) AS amount,
SUM(CASE WHEN f.status = '2' THEN f.current_payment_hkd_amount ELSE 0 END) AS sentAmount,
IFNULL(
(select sum(unpaid_amount)
from expected_fortune where status = '0' and policy_no = f.policy_no
),0) AS pendingOutAmount,
SUM(CASE WHEN f.status in ('6','1') THEN f.current_payment_hkd_amount ELSE 0 END) AS availableOutAmount,
IFNULL(SUM(CASE WHEN f.status in ('6','1') THEN f.current_payment_hkd_amount ELSE 0 END),0) AS availableOutAmount,
COUNT(DISTINCT f.policy_no) AS totalPolicyCount
FROM fortune f
WHERE 1 = 1
......
......@@ -82,6 +82,7 @@
<result property="updaterId" column="updater_id" />
<result property="createTime" column="create_time" />
<result property="updateTime" column="update_time" />
<result property="policyType" column="policy_type" />
</resultMap>
<sql id="Base_Column_List">
......@@ -99,7 +100,7 @@
mailing_method,renewal_payment_method,dividend_distribution_method,delivery_no,
policy_levy,initial_premium_paid,initial_premium_due,latest_payment_date,broker_sign_date,
insurer_mailing_date,customer_sign_date,attachments,remark,is_deleted,
creator_id,updater_id,create_time,update_time
creator_id,updater_id,create_time,update_time,policy_type
</sql>
<select id="queryPolicyReportData" resultType="com.yd.csf.service.dto.PolicyReportData">
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment