Commit cbf748b0 by yao.xiao

增加-销售业绩预测

parent fb188029
......@@ -18,8 +18,6 @@ import org.springframework.web.bind.annotation.RequestBody;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;
import javax.annotation.Resource;
@Controller
@RestController
@RequestMapping("/practitioner")
......@@ -291,7 +289,7 @@ public class PractitionerController {
}
/**
* 队员销售活动量
* 队员销售活动量列表
* @param requestVO 请求数据
* @return 响应数据
*/
......@@ -303,4 +301,18 @@ public class PractitionerController {
result.setData(responseVO);
return result;
}
/**
* 销售业绩预测 保费/佣金/件数 月季年
* @param requestVO 请求数据
* @return 响应数据
*/
@RequestMapping("/salesPerformanceForecastListQuery")
public Object salesPerformanceForecastListQuery(@RequestBody SalesPerformanceForecastListQueryRequestVO requestVO){
JsonResult result = new JsonResult();
SalesPerformanceForecastListQueryResponseVO responseVO = practitionerService.salesPerformanceForecastListQuery(requestVO);
result.addResult(responseVO);
result.setData(responseVO);
return result;
}
}
......@@ -152,4 +152,11 @@ public interface PractitionerService {
* @return
*/
PlayerSalesActivityQueryResponseVO playerSalesActivityQuery(PlayerSalesActivityQueryRequestVO requestVO);
/**
* 销售业绩预测 保费/佣金/件数 月季年
* @param requestVO
* @return
*/
SalesPerformanceForecastListQueryResponseVO salesPerformanceForecastListQuery(SalesPerformanceForecastListQueryRequestVO requestVO);
}
......@@ -1364,12 +1364,12 @@ public class PractitionerServiceImpl implements com.yd.api.practitioner.service.
targetScoreMonth += singleScore * info.getActionStandards();
}
Double achievementRateMonth = BigDecimal.valueOf(scoreMonth)
.divide(BigDecimal.valueOf(targetScoreMonth),1,BigDecimal.ROUND_HALF_UP)
.divide(BigDecimal.valueOf(targetScoreMonth),4,BigDecimal.ROUND_HALF_UP)
.doubleValue();
Double achievementRateWeek = BigDecimal.valueOf(scoreWeek)
.divide(BigDecimal.valueOf(targetScoreMonth),1,BigDecimal.ROUND_HALF_UP)
.divide(BigDecimal.valueOf(targetScoreMonth),4,BigDecimal.ROUND_HALF_UP)
.multiply(BigDecimal.valueOf(12))
.divide(BigDecimal.valueOf(52),1,BigDecimal.ROUND_HALF_UP)
.divide(BigDecimal.valueOf(52),4,BigDecimal.ROUND_HALF_UP)
.doubleValue();
resp.setAchievementRateMonth(achievementRateMonth);
resp.setAchievementRateWeek(achievementRateWeek);
......@@ -1452,12 +1452,22 @@ public class PractitionerServiceImpl implements com.yd.api.practitioner.service.
mktLeadsGoals.setPractitionerId(practitionerId);
mktLeadsGoals.setCurrentYear(year);
mktLeadsGoals.setGoalsType(goalsType);
AclPractitionerSubordinateSystem subordinateSystem ;
if (goalsType == 2){
List<AclPractitionerSubordinateSystem> subordinateSystems = aclPractitionerSubordinateSystemDALService.findByOwnerPractitionerId(practitionerId);
if (subordinateSystems.isEmpty()){
responseVO.setCommonResult(new CommonResult(true, ZHBErrorConfig.getErrorInfo("830017")));
return responseVO;
}
mktLeadsGoals.setSubordinateSystemId(subordinateSystems.get(0).getId());
subordinateSystem = subordinateSystems.get(0);
}else {
subordinateSystem = aclPractitionerSubordinateSystemDALService.findByPractitionerId(practitionerId);
if (subordinateSystem == null){
responseVO.setCommonResult(new CommonResult(true, ZHBErrorConfig.getErrorInfo("830017")));
return responseVO;
}
}
mktLeadsGoals.setSubordinateSystemId(subordinateSystem.getId());
List<MktLeadsGoals> mktLeadsGoalsList = mktLeadsGoalsDALService.findByMktLeadsGoals(mktLeadsGoals);
List<SalesTargetMonth> salesTargetMonthList = new ArrayList<>();
for (MktLeadsGoals info :mktLeadsGoalsList){
......@@ -1613,7 +1623,7 @@ public class PractitionerServiceImpl implements com.yd.api.practitioner.service.
}
for (PlayerSalesActivityInfo info : playerSalesActivityInfos){
//总分数
Integer predictionScore = 0;
int predictionScore = 0;
for (MktLeadsGoalsActions actions : mktLeadsGoalsActions){
if (info.getPractitionerId().equals(actions.getPractitionerId())){
predictionScore += actions.getActionStandards() * optionsIdToScore.get(actions.getLeadsActionId());
......@@ -1629,6 +1639,217 @@ public class PractitionerServiceImpl implements com.yd.api.practitioner.service.
return responseVO;
}
@Override
public SalesPerformanceForecastListQueryResponseVO salesPerformanceForecastListQuery(SalesPerformanceForecastListQueryRequestVO requestVO) {
SalesPerformanceForecastListQueryResponseVO responseVO = new SalesPerformanceForecastListQueryResponseVO();
List<SalesPerformanceForecastInfo> infos = new ArrayList<>();
//通过团队长经纪人id,查询此团队所有经纪人id
Long practitionerId = requestVO.getPractitionerId();
List<AclPractitioner> practitioners = aclPractitionerDALService.findForSubordinateIdByPractitionerId(practitionerId);
if (practitioners.isEmpty()){
responseVO.setCommonResult(new CommonResult(true, ZHBErrorConfig.getErrorInfo("800000")));
return responseVO;
}
List<Long> practitionerIds = new ArrayList<>();
ConcurrentHashMap<Long,String> practitionerIdToName = new ConcurrentHashMap<>();
for (AclPractitioner aclPractitioner : practitioners){
practitionerIds.add(aclPractitioner.getId());
practitionerIdToName.put(aclPractitioner.getId(),aclPractitioner.getName());
}
//通过团队所有经纪人id,去查询自己的预测值
Calendar cal = Calendar.getInstance();
int year = cal.get(Calendar.YEAR);
List<MktLeadsGoals> mktLeadsGoals = mktLeadsGoalsDALService.selectByPractitionerIds(practitionerIds,year);
//查询词团队所有经纪人的商机预测值
MdDropOptions mdDropOptions = mdDropOptionsDALService.selectByMasterCodeAndOptionsCode("bizchance_promotion_action","refused");
List<MktLeadsAssigneds> mktLeadsAssigneds = mktLeadsAssignedsDALService.selectByPractitionerIdRemoveRefused(practitionerIds,mdDropOptions.getId());
String time = requestVO.getTime();
if ("M".equalsIgnoreCase(time)){
//月度
int month = cal.get(Calendar.MONTH) + 1;
infos = getMouthPerformanceForecast(practitionerIds,mktLeadsGoals,mktLeadsAssigneds,practitionerIdToName,month);
}else if ("Q".equalsIgnoreCase(time)){
//季度
int month = cal.get(Calendar.MONTH) + 1;
infos = getQuarterPerformanceForecast(practitionerIds,mktLeadsGoals,mktLeadsAssigneds,practitionerIdToName,month);
}else if ("Y".equalsIgnoreCase(time)){
//年
infos = getYearPerformanceForecast(practitionerIds,mktLeadsGoals,mktLeadsAssigneds,practitionerIdToName);
}
responseVO.setSalesPerformanceForecastInfos(infos);
responseVO.setCommonResult(new CommonResult(true, ZHBErrorConfig.getErrorInfo("800000")));
return responseVO;
}
@SuppressWarnings("unchecked")
private List<SalesPerformanceForecastInfo> getYearPerformanceForecast(List<Long> practitionerIds, List<MktLeadsGoals> mktLeadsGoals, List<MktLeadsAssigneds> mktLeadsAssigneds, ConcurrentHashMap<Long, String> practitionerIdToName) {
List<SalesPerformanceForecastInfo> infos = new ArrayList<>();
for (Long praId : practitionerIds) {
SalesPerformanceForecastInfo info = new SalesPerformanceForecastInfo();
BeanPropertyValueEqualsPredicate predicate = new BeanPropertyValueEqualsPredicate("practitionerId", praId);
List<MktLeadsGoals> mktLeadsGoalsList = (List<MktLeadsGoals>) CollectionUtils.select(mktLeadsGoals, predicate);
if (mktLeadsGoalsList.isEmpty()){
info.setPractitionerId(praId);
info.setName(practitionerIdToName.get(praId));
infos.add(info);
continue;
}
//总预测值
BigDecimal quarterGoal = BigDecimal.ZERO;
for (MktLeadsGoals leadsGoals : mktLeadsGoalsList) {
if (leadsGoals.getStatisticTimeUnit() == 1) {
quarterGoal = quarterGoal.add(BigDecimal.valueOf(leadsGoals.getCommission()));
}
}
//商机累加值
predicate = new BeanPropertyValueEqualsPredicate("assignedPractitionerId", praId);
List<MktLeadsAssigneds> mktLeadsAssignedsList = (List<MktLeadsAssigneds>)CollectionUtils.select(mktLeadsAssigneds,predicate);
BigDecimal defaultCommission = BigDecimal.ZERO;
BigDecimal defaultPremium = BigDecimal.ZERO;
Integer defaultPieces = 0;
for (MktLeadsAssigneds leadsAssigneds: mktLeadsAssignedsList) {
String timeToClose = CommonUtil.dateParseString(leadsAssigneds.getTimeToClose(), "yyyy-MM-dd");
if (CommonUtil.isNullOrBlank(timeToClose)){
continue;
}
if (CommonUtil.isThisYear(timeToClose)){
defaultPieces += leadsAssigneds.getPieces();
defaultCommission = defaultCommission.add(leadsAssigneds.getFyc());
defaultPremium = defaultPremium.add(leadsAssigneds.getFyp());
}
}
Double achievementRate = defaultCommission.divide(quarterGoal,4,BigDecimal.ROUND_HALF_UP).doubleValue();
info.setPractitionerId(praId);
info.setName(practitionerIdToName.get(praId));
info.setPieces(defaultPieces);
info.setPremium(defaultPremium.doubleValue());
info.setCommission(defaultCommission.doubleValue());
info.setAchievementRate(achievementRate);
infos.add(info);
}
return infos;
}
@SuppressWarnings("unchecked")
private List<SalesPerformanceForecastInfo> getQuarterPerformanceForecast(List<Long> practitionerIds, List<MktLeadsGoals> mktLeadsGoals, List<MktLeadsAssigneds> mktLeadsAssigneds, ConcurrentHashMap<Long, String> practitionerIdToName, int month) {
List<SalesPerformanceForecastInfo> infos = new ArrayList<>();
for (Long praId : practitionerIds) {
SalesPerformanceForecastInfo info = new SalesPerformanceForecastInfo();
BeanPropertyValueEqualsPredicate predicate = new BeanPropertyValueEqualsPredicate("practitionerId", praId);
List<MktLeadsGoals> mktLeadsGoalsList = (List<MktLeadsGoals>) CollectionUtils.select(mktLeadsGoals, predicate);
if (mktLeadsGoalsList.isEmpty()){
info.setPractitionerId(praId);
info.setName(practitionerIdToName.get(praId));
infos.add(info);
continue;
}
Integer[] quarter = new Integer[]{};
if (month == 1 || month == 2 || month == 3) {
quarter = new Integer[]{1, 2, 3};
} else if (month == 4 || month == 5 || month == 6) {
quarter = new Integer[]{4, 5, 6};
} else if (month == 7 || month == 8 || month == 9) {
quarter = new Integer[]{7, 8, 9};
} else if (month == 10 || month == 11 || month == 12) {
quarter = new Integer[]{10, 11, 12};
}
//总预测值
BigDecimal quarterGoal = BigDecimal.ZERO;
for (MktLeadsGoals leadsGoals : mktLeadsGoalsList) {
if (leadsGoals.getStatisticTimeUnit() == 3) {
//月目标
//判断是否为本季度
Integer monthNum = leadsGoals.getSeqTime();
if (Arrays.asList(quarter).contains(monthNum)) {
quarterGoal = quarterGoal.add(BigDecimal.valueOf(leadsGoals.getCommission()));
}
}
}
//商机累加值
predicate = new BeanPropertyValueEqualsPredicate("assignedPractitionerId", praId);
List<MktLeadsAssigneds> mktLeadsAssignedsList = (List<MktLeadsAssigneds>)CollectionUtils.select(mktLeadsAssigneds,predicate);
BigDecimal defaultCommission = BigDecimal.ZERO;
BigDecimal defaultPremium = BigDecimal.ZERO;
Integer defaultPieces = 0;
for (MktLeadsAssigneds leadsAssigneds: mktLeadsAssignedsList) {
String timeToClose = CommonUtil.dateParseString(leadsAssigneds.getTimeToClose(), "yyyy-MM-dd");
if (CommonUtil.isNullOrBlank(timeToClose)){
continue;
}
Calendar c = Calendar.getInstance();
c.setTime(leadsAssigneds.getTimeToClose());
int timeToCloseMonth = c.get(Calendar.MONTH);
if (Arrays.asList(quarter).contains(timeToCloseMonth)){
defaultPieces += leadsAssigneds.getPieces();
defaultCommission = defaultCommission.add(leadsAssigneds.getFyc());
defaultPremium = defaultPremium.add(leadsAssigneds.getFyp());
}
}
Double achievementRate = defaultCommission.divide(quarterGoal,4,BigDecimal.ROUND_HALF_UP).doubleValue();
info.setPractitionerId(praId);
info.setName(practitionerIdToName.get(praId));
info.setPieces(defaultPieces);
info.setPremium(defaultPremium.doubleValue());
info.setCommission(defaultCommission.doubleValue());
info.setAchievementRate(achievementRate);
infos.add(info);
}
return infos;
}
@SuppressWarnings("unchecked")
private List<SalesPerformanceForecastInfo> getMouthPerformanceForecast(List<Long> practitionerIds, List<MktLeadsGoals> mktLeadsGoals, List<MktLeadsAssigneds> mktLeadsAssigneds, ConcurrentHashMap<Long, String> practitionerIdToName, int month) {
List<SalesPerformanceForecastInfo> infos = new ArrayList<>();
for (Long praId : practitionerIds){
SalesPerformanceForecastInfo info = new SalesPerformanceForecastInfo();
BeanPropertyValueEqualsPredicate predicate = new BeanPropertyValueEqualsPredicate("practitionerId", praId);
List<MktLeadsGoals> mktLeadsGoalsList = (List<MktLeadsGoals>)CollectionUtils.select(mktLeadsGoals,predicate);
predicate = new BeanPropertyValueEqualsPredicate("seqTime", month);
mktLeadsGoalsList = (List<MktLeadsGoals>)CollectionUtils.select(mktLeadsGoalsList,predicate);
if (mktLeadsGoalsList.isEmpty()){
info.setPractitionerId(praId);
info.setName(practitionerIdToName.get(praId));
infos.add(info);
continue;
}
MktLeadsGoals leadsGoals = mktLeadsGoalsList.get(0);
//筛选此经纪人的所有指派信息
predicate = new BeanPropertyValueEqualsPredicate("assignedPractitionerId", praId);
List<MktLeadsAssigneds> mktLeadsAssignedsList = (List<MktLeadsAssigneds>)CollectionUtils.select(mktLeadsAssigneds,predicate);
BigDecimal defaultCommission = BigDecimal.ZERO;
BigDecimal defaultPremium = BigDecimal.ZERO;
Integer defaultPieces = 0;
for (MktLeadsAssigneds leadsAssigneds : mktLeadsAssignedsList){
String timeToClose = CommonUtil.dateParseString(leadsAssigneds.getTimeToClose(), "yyyy-MM-dd");
if (CommonUtil.isNullOrBlank(timeToClose)){
continue;
}
if (CommonUtil.isThisMonth(timeToClose)){
defaultPieces += leadsAssigneds.getPieces();
defaultCommission = defaultCommission.add(leadsAssigneds.getFyc());
defaultPremium = defaultPremium.add(leadsAssigneds.getFyp());
}
}
Double achievementRate = defaultCommission.divide(BigDecimal.valueOf(leadsGoals.getCommission()),4,BigDecimal.ROUND_HALF_UP).doubleValue();
info.setPractitionerId(praId);
info.setName(practitionerIdToName.get(praId));
info.setPieces(defaultPieces);
info.setPremium(defaultPremium.doubleValue());
info.setCommission(defaultCommission.doubleValue());
info.setAchievementRate(achievementRate);
infos.add(info);
}
return infos;
}
private ConcurrentHashMap<String, Double> getAchievementRate(List<MktLeadsGoals> leadsGoals,HashMap<String,BigDecimal> performanceForecast) {
ConcurrentHashMap<String, Double> achievementRateMap = new ConcurrentHashMap<>();
//获取当前月份
......
package com.yd.api.practitioner.vo.opportunity;
import lombok.Data;
@Data
public class SalesPerformanceForecastInfo {
private Long practitionerId;
private String name;
/**
* 件数
*/
private Integer pieces;
/**
* 保费
*/
private Double premium;
/**
* 佣金
*/
private Double commission;
/**
* 完成率
*/
private Double achievementRate;
}
package com.yd.api.practitioner.vo.opportunity;
import lombok.Data;
@Data
public class SalesPerformanceForecastListQueryRequestVO {
private Long practitionerId;
private String time; //M月 Q季 Y年
}
package com.yd.api.practitioner.vo.opportunity;
import com.yd.api.result.CommonResult;
import lombok.Data;
import java.util.List;
@Data
public class SalesPerformanceForecastListQueryResponseVO {
private List<SalesPerformanceForecastInfo> salesPerformanceForecastInfos;
private CommonResult commonResult;
}
......@@ -27,4 +27,6 @@ public interface MktLeadsAssignedsMapper {
Integer countPractitionerIdsAndThisWeek(List<Long> practitionerIds);
HashMap<String, BigDecimal> performanceForecastForTeam(@Param("practitionerIds") List<Long> practitionerIds,@Param("refusedId") Long refusedId);
List<MktLeadsAssigneds> selectByPractitionerIdRemoveRefused(@Param("practitionerIds")List<Long> practitionerIds,@Param("dropOptionsId") Long dropOptionsId);
}
\ No newline at end of file
......@@ -18,4 +18,6 @@ public interface MktLeadsGoalsMapper {
void updateIsActiveIsNull(@Param("practitionerId") Long practitionerId, @Param("year") Integer year, @Param("goalsType") Integer goalsType);
List<MktLeadsGoals> selectByMktLeadsGoals(MktLeadsGoals mktLeadsGoals);
List<MktLeadsGoals> selectByPractitionerIds(@Param("practitionerIds") List<Long> practitionerIds,@Param("year") Integer year);
}
\ No newline at end of file
......@@ -49,4 +49,9 @@ public class MktLeadsAssignedsDALServiceImpl implements MktLeadsAssignedsDALServ
public HashMap<String, BigDecimal> performanceForecastForTeam(List<Long> practitionerIds,Long refusedId) {
return mktLeadsAssignedsMapper.performanceForecastForTeam(practitionerIds,refusedId);
}
@Override
public List<MktLeadsAssigneds> selectByPractitionerIdRemoveRefused(List<Long> practitionerIds, Long dropOptionsId) {
return mktLeadsAssignedsMapper.selectByPractitionerIdRemoveRefused( practitionerIds, dropOptionsId);
}
}
......@@ -31,4 +31,9 @@ public class MktLeadsGoalsDALServiceImpl implements MktLeadsGoalsDALService {
return mktLeadsGoalsMapper.selectByMktLeadsGoals(mktLeadsGoals);
}
@Override
public List<MktLeadsGoals> selectByPractitionerIds(List<Long> practitionerIds, int year) {
return mktLeadsGoalsMapper.selectByPractitionerIds( practitionerIds, year);
}
}
......@@ -27,4 +27,12 @@ public interface MktLeadsAssignedsDALService {
* ag_mkt_leads_assigned_track跟进记录不可有"拒绝" md_drop_option_id = 102 (传入)
*/
HashMap<String, BigDecimal> performanceForecastForTeam(List<Long> practitionerIds,Long refusedId);
/**
* 查询该团队所有商机指派,排除以失败的
* @param practitionerIds
* @param dropOptionsId
* @return
*/
List<MktLeadsAssigneds> selectByPractitionerIdRemoveRefused(List<Long> practitionerIds, Long dropOptionsId);
}
......@@ -13,4 +13,5 @@ public interface MktLeadsGoalsDALService {
List<MktLeadsGoals> findByMktLeadsGoals(MktLeadsGoals mktLeadsGoals);
List<MktLeadsGoals> selectByPractitionerIds(List<Long> practitionerIds, int year);
}
......@@ -30,4 +30,5 @@
830015=每天同一个跟进状态只能对一个商机经行一次增加!
830016=您不是团队长,无法进行编辑保存
830017=您不是团队长,无法进行查看
830018=您暂无团队,无法设置
900003=保险公司响应报文为空!
\ No newline at end of file
......@@ -279,4 +279,17 @@
</foreach>
and a.id = t.leads_assigned_id)
</select>
<select id="selectByPractitionerIdRemoveRefused" resultMap="BaseResultMap">
select *
from ag_mkt_leads_assigneds a
where a.assigned_practitioner_id in
<foreach collection="practitionerIds" item="practitionerId" index="index" open="(" close=")" separator=",">
#{practitionerId,jdbcType=BIGINT}
</foreach>
and not EXISTS (select t.leads_assigned_id
from ag_mkt_leads_assigned_track t
where t.md_drop_option_id = #{dropOptionsId,jdbcType=BIGINT}
and t.practitioner_id = a.id
and a.id = t.leads_assigned_id);
</select>
</mapper>
\ No newline at end of file
......@@ -315,4 +315,16 @@
</if>
</where>
</select>
<select id="selectByPractitionerIds" resultMap="BaseResultMap">
select
<include refid="Base_Column_List" />
from ag_mkt_leads_goals
where practitioner_id in
<foreach collection="practitionerIds" item="practitionerId" index="index" open="(" close=")" separator=",">
#{practitionerId,jdbcType=BIGINT}
</foreach>
and is_active = 1
and current_year = #{year,jdbcType=INTEGER}
and goals_type = 1
</select>
</mapper>
\ No newline at end of file
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