package com.kym.service.admin.impl;
import com.github.pagehelper.PageHelper;
import com.github.yulichang.base.MPJBaseServiceImpl;
import com.github.yulichang.toolkit.JoinWrappers;
import com.github.yulichang.wrapper.MPJLambdaWrapper;
import com.kym.common.exception.BusinessException;
import com.kym.common.utils.CommUtil;
import com.kym.entity.admin.*;
import com.kym.entity.admin.queryParams.StatementsQueryParam;
import com.kym.entity.admin.vo.StatementsVo;
import com.kym.entity.common.PageBean;
import com.kym.mapper.admin.StatementsMapper;
import com.kym.service.admin.AdminUserRoleService;
import com.kym.service.admin.InvestorInfoService;
import com.kym.service.admin.StatementsService;
import com.kym.service.admin.StationStatMonthService;
import com.kym.service.cache.KymCache;
import org.springframework.beans.BeanUtils;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
/**
*
* 客户对账单 服务实现类
*
*
* @author skyline
* @since 2023-12-27
*/
@Service
public class StatementsServiceImpl extends MPJBaseServiceImpl implements StatementsService {
private final InvestorInfoService investorInfoService;
private final StationStatMonthService stationStatMonthService;
private final AdminUserRoleService adminUserRoleService;
public StatementsServiceImpl(InvestorInfoService investorInfoService, StationStatMonthService stationStatMonthService, AdminUserRoleService adminUserRoleService) {
this.investorInfoService = investorInfoService;
this.stationStatMonthService = stationStatMonthService;
this.adminUserRoleService = adminUserRoleService;
}
@Override
@Transactional
public void createStatements(String statMonthId) {
// 站点统计信息
var statMonthInfo = stationStatMonthService.lambdaQuery()
.eq(StationStatMonth::getId, statMonthId)
.one();
// 校验站点月统计信息已填写实际抄表电量和实际抄表电费金额
if (statMonthInfo.getActualPower() == null || statMonthInfo.getActualElecMoney() == null) {
throw new BusinessException("请先完善月统计实际抄表电量和实际抄表电费金额");
}
// 站点关联客户和物业信息
var investorInfoList = investorInfoService.lambdaQuery()
.eq(InvestorInfo::getStationId, statMonthInfo.getStationId())
.eq(InvestorInfo::getStatus, InvestorInfo.STATUS_有效)
.list();
if (CommUtil.isEmptyOrNull(investorInfoList)) {
throw new BusinessException("请先完善站点相关投资者/物业信息");
}
// 创建客户对账单
var res = investorInfoList.stream().map(investorInfo -> {
// 实际参与分成的服务费=总服务费-优惠金额-电损电费
var actualServiceMoney = statMonthInfo.getServiceMoney() - statMonthInfo.getDiscountAmount();
// 总电损电费
var elecLossMoney = statMonthInfo.getActualElecMoney() - statMonthInfo.getElecMoney();
var elecLossAmount = (int) (elecLossMoney * investorInfo.getElecLossProportion());
// 分成金额 = 实际参与分成的服务费 * 分成比例 - 电损金额 * 电损承担比例
var splittingAmount = (int) (actualServiceMoney * investorInfo.getSplittingProportion()) - elecLossAmount;
return new Statements()
.setAdminUserId(investorInfo.getAdminUserId())
.setAdminUserName(investorInfo.getAdminUserName())
.setStationId(investorInfo.getStationId())
.setStationName(KymCache.INSTANCE.getStationNameById(investorInfo.getStationId()))
.setStatMonth(statMonthInfo.getStatMonth())
.setTotalPower(statMonthInfo.getTotalPower())
.setActualPower(statMonthInfo.getActualPower()) // 实际抄表电量
.setElecLossPower(statMonthInfo.getActualPower() - statMonthInfo.getTotalPower()) // 电损电量
.setTotalMoney(statMonthInfo.getTotalMoney())
.setElecMoney(statMonthInfo.getElecMoney())
.setActualElecMoney(statMonthInfo.getActualElecMoney())// 实际抄表电费
.setElecLossMoney(elecLossMoney) // 电损电费(分)
.setServiceMoney(statMonthInfo.getServiceMoney())
.setDiscountAmount(statMonthInfo.getDiscountAmount())
.setServiceMoneyDiscount(statMonthInfo.getServiceMoneyDiscount())
.setActualServiceMoney(actualServiceMoney) // 实际参与分成的服务费(分)
.setSplittingProportion(investorInfo.getSplittingProportion()) // 分成比例 0.45表示45%
.setSplittingAmount(splittingAmount) // 分成金额(分)
.setElecLossProportion(investorInfo.getElecLossProportion()) // 电损承担比例
.setElecLossAmount((int) (elecLossMoney * investorInfo.getElecLossProportion())) // 电损承担金额
.setVatRate(investorInfo.getVatRate()) // 增值税率 0.06表示6%
.setVatAmount((int) (splittingAmount / (1 + investorInfo.getVatRate()) * investorInfo.getVatRate() * 1.12)) // 增值税额(分)
.setActualSplittingAmount(splittingAmount - (int) (splittingAmount / (1 + investorInfo.getVatRate()) * investorInfo.getVatRate() * 1.12)); // 实际分成金额(分)
}).toList();
// 删除之前生成的对账单(投资者/物业 - 站点 - 月份)
var oldData = lambdaQuery()
.eq(Statements::getStatMonth, statMonthInfo.getStatMonth())
.eq(Statements::getStationId, statMonthInfo.getStationId())
.in(Statements::getAdminUserId, investorInfoList.stream().map(InvestorInfo::getAdminUserId).toList())
.list().stream().map(Statements::getId).toList();
removeBatchByIds(oldData);
saveBatch(res);
}
@Override
public PageBean listStatements(StatementsQueryParam params) {
PageHelper.startPage(params.getPageNum(), params.getPageSize());
var res = lambdaQuery()
.eq(!CommUtil.isEmptyOrNull(params.getStationId()), Statements::getStationId, params.getStationId())
.eq(!CommUtil.isEmptyOrNull(params.getStatMonth()), Statements::getStatMonth, params.getStatMonth())
.like(!CommUtil.isEmptyOrNull(params.getAdminUserName()), Statements::getAdminUserName, params.getAdminUserName())
.orderByDesc(Statements::getCreateTime)
.list();
return new PageBean<>(res);
}
@Override
public StatementsVo preview(String statId) {
var statements = getById(statId);
var investorInfo = investorInfoService.lambdaQuery()
.eq(InvestorInfo::getAdminUserId, statements.getAdminUserId())
.eq(InvestorInfo::getStationId, statements.getStationId())
.one();
// 查询角色
MPJLambdaWrapper wrapper = JoinWrappers.lambda(AdminUserRole.class)
.select(Role::getRoleName, Role::getRoleDesc)
.leftJoin(Role.class, Role::getId, AdminUserRole::getRoleId)
.eq(AdminUserRole::getAdminUserId, statements.getAdminUserId());
var res = adminUserRoleService.selectJoinMap(wrapper);
if (CommUtil.isEmptyOrNull(res)) {
throw new BusinessException("请先完善站点相关投资者/物业客户账号信息关联之后重新生成账单");
}
var statementsVo = new StatementsVo();
statementsVo.setRoleName(res.get("role_name").toString());
statementsVo.setRoleDesc(res.get("role_desc").toString());
BeanUtils.copyProperties(statements, statementsVo);
BeanUtils.copyProperties(investorInfo, statementsVo);
return statementsVo;
}
}