fix manual salary settlement net payable
This commit is contained in:
parent
a48fddb613
commit
3cef4fc322
@ -31,4 +31,14 @@ public class TeamManualSalaryPaymentQryCmd extends PageCommand {
|
||||
* 用户 id.
|
||||
*/
|
||||
private Long userId;
|
||||
|
||||
/**
|
||||
* 排序字段.
|
||||
*/
|
||||
private String sortField;
|
||||
|
||||
/**
|
||||
* 排序方向.
|
||||
*/
|
||||
private String sortOrder;
|
||||
}
|
||||
|
||||
@ -82,7 +82,12 @@ public class TeamManualSalaryPaymentDTO implements Serializable {
|
||||
private Boolean satisfyLevel;
|
||||
|
||||
/**
|
||||
* 应发工资.
|
||||
* 当前账期按积分档位计算出的工资.
|
||||
*/
|
||||
private BigDecimal expectedSalary;
|
||||
|
||||
/**
|
||||
* 待结算工资 = 当前账期应发工资 - 当前账期实收工资.
|
||||
*/
|
||||
private BigDecimal payableSalary;
|
||||
|
||||
@ -91,6 +96,11 @@ public class TeamManualSalaryPaymentDTO implements Serializable {
|
||||
*/
|
||||
private BigDecimal totalIssuedSalary;
|
||||
|
||||
/**
|
||||
* 当前账期多发工资.
|
||||
*/
|
||||
private BigDecimal overIssuedSalary;
|
||||
|
||||
/**
|
||||
* 当前工资余额.
|
||||
*/
|
||||
|
||||
@ -215,8 +215,10 @@ public class TeamSalaryBackServiceImpl implements TeamSalaryBackService {
|
||||
.setCurrentTarget(dto.getCurrentTarget())
|
||||
.setPolicyLevel(dto.getPolicyLevel())
|
||||
.setSatisfyLevel(dto.getSatisfyLevel())
|
||||
.setExpectedSalary(dto.getExpectedSalary())
|
||||
.setPayableSalary(dto.getPayableSalary())
|
||||
.setTotalIssuedSalary(dto.getTotalIssuedSalary())
|
||||
.setOverIssuedSalary(dto.getOverIssuedSalary())
|
||||
.setCurrentSalaryBalance(dto.getCurrentSalaryBalance())
|
||||
.setPaid(dto.getPaid());
|
||||
}
|
||||
|
||||
@ -39,8 +39,10 @@ public class TeamManualSalaryCO implements Serializable {
|
||||
private Long currentTarget;
|
||||
private Integer policyLevel;
|
||||
private Boolean satisfyLevel;
|
||||
private BigDecimal expectedSalary;
|
||||
private BigDecimal payableSalary;
|
||||
private BigDecimal totalIssuedSalary;
|
||||
private BigDecimal overIssuedSalary;
|
||||
private BigDecimal currentSalaryBalance;
|
||||
private Boolean paid;
|
||||
}
|
||||
|
||||
@ -3,9 +3,10 @@ package com.red.circle.other.infra.database.mongo.service.team.team;
|
||||
import com.red.circle.framework.dto.PageResult;
|
||||
import com.red.circle.other.infra.database.mongo.dto.team.TeamSalaryPaymentDetails;
|
||||
import com.red.circle.other.infra.database.mongo.entity.team.team.TeamPolicyManager;
|
||||
import com.red.circle.other.infra.database.mongo.entity.team.team.TeamSalaryPayment;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
import com.red.circle.other.infra.database.mongo.entity.team.team.TeamSalaryPayment;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
import java.util.Set;
|
||||
|
||||
/**
|
||||
* 团队工资实时支付记录.
|
||||
@ -80,10 +81,16 @@ public interface TeamSalaryPaymentService {
|
||||
/**
|
||||
* 获得数据.
|
||||
*/
|
||||
TeamSalaryPayment getOneById(String id);
|
||||
|
||||
/**
|
||||
* 基于父ID修改子记录状态为已退款.
|
||||
TeamSalaryPayment getOneById(String id);
|
||||
|
||||
/**
|
||||
* 按用户和账期批量获得数据.
|
||||
*/
|
||||
Map<String, TeamSalaryPayment> mapByUserIdsAndDateNumbers(String sysOrigin, Set<Long> userIds,
|
||||
Set<Integer> dateNumbers);
|
||||
|
||||
/**
|
||||
* 基于父ID修改子记录状态为已退款.
|
||||
*
|
||||
* @param id ID
|
||||
* @param salarySendDetails 发送工资记录集合.
|
||||
|
||||
@ -13,10 +13,12 @@ import com.red.circle.other.inner.model.dto.agency.agency.TeamSalaryPaymentRemar
|
||||
import com.red.circle.tool.core.collection.CollectionUtils;
|
||||
import com.red.circle.tool.core.date.TimestampUtils;
|
||||
import com.red.circle.tool.core.text.StringUtils;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
import java.util.Objects;
|
||||
import java.util.Optional;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
import java.util.Objects;
|
||||
import java.util.Optional;
|
||||
import java.util.Set;
|
||||
import java.util.stream.Collectors;
|
||||
import lombok.RequiredArgsConstructor;
|
||||
import org.springframework.data.domain.Sort;
|
||||
import org.springframework.data.mongodb.core.MongoTemplate;
|
||||
@ -178,13 +180,33 @@ public class TeamSalaryPaymentServiceImpl implements TeamSalaryPaymentService {
|
||||
}
|
||||
|
||||
@Override
|
||||
public TeamSalaryPayment getOneById(String id) {
|
||||
|
||||
return mongoTemplate.findOne(Query.query(Criteria.where("id").is(id)), TeamSalaryPayment.class);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void updateDetails(String id, List<TeamSalaryPaymentDetails> salarySendDetails) {
|
||||
public TeamSalaryPayment getOneById(String id) {
|
||||
|
||||
return mongoTemplate.findOne(Query.query(Criteria.where("id").is(id)), TeamSalaryPayment.class);
|
||||
}
|
||||
|
||||
@Override
|
||||
public Map<String, TeamSalaryPayment> mapByUserIdsAndDateNumbers(String sysOrigin,
|
||||
Set<Long> userIds, Set<Integer> dateNumbers) {
|
||||
|
||||
if (StringUtils.isBlank(sysOrigin) || CollectionUtils.isEmpty(userIds)
|
||||
|| CollectionUtils.isEmpty(dateNumbers)) {
|
||||
return Maps.newHashMap();
|
||||
}
|
||||
|
||||
Criteria criteria = Criteria.where("sysOrigin").is(sysOrigin)
|
||||
.and("userId").in(userIds)
|
||||
.and("dateNumber").in(dateNumbers);
|
||||
|
||||
return mongoTemplate.find(Query.query(criteria), TeamSalaryPayment.class)
|
||||
.stream()
|
||||
.filter(payment -> StringUtils.isNotBlank(payment.getId()))
|
||||
.collect(Collectors.toMap(TeamSalaryPayment::getId, payment -> payment,
|
||||
(first, second) -> first));
|
||||
}
|
||||
|
||||
@Override
|
||||
public void updateDetails(String id, List<TeamSalaryPaymentDetails> salarySendDetails) {
|
||||
|
||||
if (Objects.isNull(id) || CollectionUtils.isEmpty(salarySendDetails)) {
|
||||
return;
|
||||
|
||||
@ -44,6 +44,7 @@ import java.math.RoundingMode;
|
||||
import java.sql.Timestamp;
|
||||
import java.util.ArrayList;
|
||||
import java.util.Comparator;
|
||||
import java.util.HashSet;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
import java.util.Objects;
|
||||
@ -65,6 +66,11 @@ public class TeamManualSalaryPaymentClientServiceImpl implements
|
||||
|
||||
private static final String MANUAL_SALARY_LOCK_PREFIX = "TeamManualSalaryPayment:";
|
||||
private static final int LOCK_SECONDS = 300;
|
||||
private static final String SORT_FIELD_CURRENT_SALARY_BALANCE = "currentSalaryBalance";
|
||||
private static final String SORT_FIELD_PAYABLE_SALARY = "payableSalary";
|
||||
private static final String SORT_FIELD_TOTAL_ISSUED_SALARY = "totalIssuedSalary";
|
||||
private static final String SORT_ORDER_ASCEND = "ascend";
|
||||
private static final int LEGACY_HALF_MONTH_COMPAT_BILL_BELONG = 202605;
|
||||
|
||||
private final RedisService redisService;
|
||||
private final TeamMemberService teamMemberService;
|
||||
@ -81,6 +87,7 @@ public class TeamManualSalaryPaymentClientServiceImpl implements
|
||||
|
||||
List<ManualSalaryRow> rows = buildRows(cmd.getSysOrigin(), cmd.getCountryCode(),
|
||||
singletonUserId(cmd.getUserId()), TeamBillCycleUtils.getCalcBillBelong());
|
||||
rows = sortRows(rows, cmd.getSortField(), cmd.getSortOrder());
|
||||
|
||||
int cursor = 1;
|
||||
int limit = 20;
|
||||
@ -132,18 +139,28 @@ public class TeamManualSalaryPaymentClientServiceImpl implements
|
||||
continue;
|
||||
}
|
||||
|
||||
BigDecimal issueSalary = policyPayment.getSalary().compareTo(BigDecimal.ZERO) > 0
|
||||
? policyPayment.getSalary()
|
||||
: BigDecimal.ZERO.setScale(2, RoundingMode.DOWN);
|
||||
BigDecimal beforeBalance = getAccurateBalance(row.getUserId());
|
||||
String detailsId = IdWorkerUtils.getIdStr();
|
||||
|
||||
Boolean incrSuccess = ResponseAssert.requiredSuccess(userBankBalanceClient.incr(new UserBankBalanceIncrCmd()
|
||||
.setUserId(row.getUserId())
|
||||
.setSysOrigin(row.getSysOrigin())
|
||||
.setAmount(PennyAmount.ofDollar(policyPayment.getSalary()))));
|
||||
ResponseAssert.isTrue(CommonErrorCode.OPERATION_CONFLICT, Boolean.TRUE.equals(incrSuccess));
|
||||
if (issueSalary.compareTo(BigDecimal.ZERO) > 0) {
|
||||
Boolean incrSuccess = ResponseAssert.requiredSuccess(userBankBalanceClient.incr(new UserBankBalanceIncrCmd()
|
||||
.setUserId(row.getUserId())
|
||||
.setSysOrigin(row.getSysOrigin())
|
||||
.setAmount(PennyAmount.ofDollar(issueSalary))));
|
||||
ResponseAssert.isTrue(CommonErrorCode.OPERATION_CONFLICT, Boolean.TRUE.equals(incrSuccess));
|
||||
}
|
||||
|
||||
BigDecimal afterBalance = getAccurateBalance(row.getUserId());
|
||||
addRunningWater(detailsId, row.getUserId(), row.getSysOrigin(),
|
||||
policyPayment.getSalary(), afterBalance, cmd.getOperationUserId());
|
||||
if (issueSalary.compareTo(BigDecimal.ZERO) > 0) {
|
||||
addRunningWater(detailsId, row.getUserId(), row.getSysOrigin(),
|
||||
issueSalary, afterBalance, cmd.getOperationUserId());
|
||||
}
|
||||
String settlementRemark = issueSalary.compareTo(BigDecimal.ZERO) > 0
|
||||
? "后台手动发放主播工资"
|
||||
: "后台手动结算主播工资,实收已大于等于应发,本次发放0";
|
||||
|
||||
teamSalaryPaymentService.paymentSalary(payment.getId(), new TeamSalaryPaymentDetails()
|
||||
.setId(detailsId)
|
||||
@ -155,12 +172,12 @@ public class TeamManualSalaryPaymentClientServiceImpl implements
|
||||
.setTeamBillId(Long.valueOf(billBelong))
|
||||
.setTeamRegionId(row.getRegion())
|
||||
.setRemarks(List.of(new TeamSalaryPaymentRemark()
|
||||
.setRemark("后台手动发放主播工资")
|
||||
.setRemark(settlementRemark)
|
||||
.setCreateTime(TimestampUtils.now())))
|
||||
.setAnchor(Boolean.TRUE)
|
||||
.setHostSalaryToAgent(Boolean.FALSE)
|
||||
.setTarget(row.getCurrentTarget())
|
||||
.setSalary(policyPayment.getSalary())
|
||||
.setSalary(issueSalary)
|
||||
.setPolicyLevel(policyPayment.getLevel())
|
||||
.setPolicy(policyPayment.getPolicy()));
|
||||
|
||||
@ -177,7 +194,7 @@ public class TeamManualSalaryPaymentClientServiceImpl implements
|
||||
.setBillBelong(billBelong)
|
||||
.setBeforeSalaryBalance(beforeBalance)
|
||||
.setAfterSalaryBalance(afterBalance)
|
||||
.setIssuedSalary(policyPayment.getSalary())
|
||||
.setIssuedSalary(issueSalary)
|
||||
.setCurrentTarget(row.getCurrentTarget())
|
||||
.setPolicyLevel(policyPayment.getLevel()));
|
||||
}
|
||||
@ -215,17 +232,55 @@ public class TeamManualSalaryPaymentClientServiceImpl implements
|
||||
.collect(Collectors.toSet());
|
||||
Map<Long, TeamMember> memberMap = teamMemberService.mapByMemberIds(memberIds);
|
||||
Map<Long, TeamProfile> teamProfileMap = teamProfileService.mapProfileByIds(teamIds);
|
||||
Map<String, TeamSalaryPayment> salaryPaymentMap =
|
||||
teamSalaryPaymentService.mapByUserIdsAndDateNumbers(sysOrigin, memberIds,
|
||||
getMergedSalaryPaymentBillBelongs(billBelong));
|
||||
|
||||
Map<String, TeamPolicyManager> policyCache = CollectionUtils.newHashMap();
|
||||
return targets.stream()
|
||||
.map(target -> buildRow(target, memberMap, teamProfileMap, policyCache, billBelong,
|
||||
countryCode))
|
||||
countryCode, salaryPaymentMap))
|
||||
.filter(Objects::nonNull)
|
||||
.sorted(Comparator.comparing(ManualSalaryRow::getCurrentTarget).reversed()
|
||||
.thenComparing(ManualSalaryRow::getUserId))
|
||||
.collect(Collectors.toList());
|
||||
}
|
||||
|
||||
private List<ManualSalaryRow> sortRows(List<ManualSalaryRow> rows, String sortField,
|
||||
String sortOrder) {
|
||||
if (CollectionUtils.isEmpty(rows) || StringUtils.isBlank(sortField)
|
||||
|| StringUtils.isBlank(sortOrder)) {
|
||||
return rows;
|
||||
}
|
||||
Comparator<ManualSalaryRow> comparator = getSalarySortComparator(sortField);
|
||||
if (Objects.isNull(comparator)) {
|
||||
return rows;
|
||||
}
|
||||
if (!SORT_ORDER_ASCEND.equalsIgnoreCase(sortOrder)) {
|
||||
comparator = comparator.reversed();
|
||||
}
|
||||
return rows.stream()
|
||||
.sorted(comparator.thenComparing(ManualSalaryRow::getUserId))
|
||||
.collect(Collectors.toList());
|
||||
}
|
||||
|
||||
private Comparator<ManualSalaryRow> getSalarySortComparator(String sortField) {
|
||||
if (SORT_FIELD_PAYABLE_SALARY.equals(sortField)) {
|
||||
return Comparator.comparing(row -> decimalValue(row.getPayableSalary()));
|
||||
}
|
||||
if (SORT_FIELD_TOTAL_ISSUED_SALARY.equals(sortField)) {
|
||||
return Comparator.comparing(row -> decimalValue(row.getTotalIssuedSalary()));
|
||||
}
|
||||
if (SORT_FIELD_CURRENT_SALARY_BALANCE.equals(sortField)) {
|
||||
return Comparator.comparing(row -> decimalValue(row.getCurrentSalaryBalance()));
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
private BigDecimal decimalValue(BigDecimal value) {
|
||||
return Objects.isNull(value) ? BigDecimal.ZERO : value;
|
||||
}
|
||||
|
||||
private Set<Long> singletonUserId(Long userId) {
|
||||
if (Objects.isNull(userId)) {
|
||||
return Set.of();
|
||||
@ -242,9 +297,36 @@ public class TeamManualSalaryPaymentClientServiceImpl implements
|
||||
.collect(Collectors.toSet());
|
||||
}
|
||||
|
||||
private Set<Integer> getMergedSalaryPaymentBillBelongs(Integer billBelong) {
|
||||
if (Objects.isNull(billBelong)) {
|
||||
return Set.of();
|
||||
}
|
||||
Set<Integer> billBelongs = new HashSet<>();
|
||||
billBelongs.add(billBelong);
|
||||
Integer month = TeamBillCycleUtils.extractMonth(billBelong);
|
||||
if (Objects.equals(month, LEGACY_HALF_MONTH_COMPAT_BILL_BELONG)) {
|
||||
billBelongs.add(month);
|
||||
billBelongs.add(month * 100 + 1);
|
||||
billBelongs.add(month * 100 + 16);
|
||||
}
|
||||
return billBelongs;
|
||||
}
|
||||
|
||||
private List<TeamSalaryPayment> listCyclePayments(
|
||||
Map<String, TeamSalaryPayment> salaryPaymentMap, Long userId, Integer billBelong) {
|
||||
if (Objects.isNull(userId) || CollectionUtils.isEmpty(salaryPaymentMap)) {
|
||||
return List.of();
|
||||
}
|
||||
return getMergedSalaryPaymentBillBelongs(billBelong).stream()
|
||||
.map(item -> salaryPaymentMap.get(paymentId(userId, item)))
|
||||
.filter(Objects::nonNull)
|
||||
.collect(Collectors.toList());
|
||||
}
|
||||
|
||||
private ManualSalaryRow buildRow(TeamMemberTarget target, Map<Long, TeamMember> memberMap,
|
||||
Map<Long, TeamProfile> teamProfileMap, Map<String, TeamPolicyManager> policyCache,
|
||||
Integer billBelong, String requestedCountryCode) {
|
||||
Integer billBelong, String requestedCountryCode,
|
||||
Map<String, TeamSalaryPayment> salaryPaymentMap) {
|
||||
TeamMember member = memberMap.get(target.getUserId());
|
||||
TeamProfile teamProfile = teamProfileMap.get(target.getTeamId());
|
||||
if (Objects.isNull(member) || Objects.isNull(teamProfile)
|
||||
@ -264,14 +346,16 @@ public class TeamManualSalaryPaymentClientServiceImpl implements
|
||||
policyCache);
|
||||
TeamBillMemberTarget billTarget = calculateBillTarget(target, policyManager);
|
||||
|
||||
TeamSalaryPayment payment = teamSalaryPaymentService.getOneById(paymentId(target.getUserId(),
|
||||
billBelong));
|
||||
List<PolicyPayment> policyPayments = listUnpaidPolicyPayments(policyManager, billTarget,
|
||||
payment, target.getUserId(), region);
|
||||
BigDecimal payableSalary = policyPayments.stream()
|
||||
.map(PolicyPayment::getSalary)
|
||||
.reduce(BigDecimal.ZERO, BigDecimal::add)
|
||||
List<TeamSalaryPayment> cyclePayments = listCyclePayments(salaryPaymentMap,
|
||||
target.getUserId(), billBelong);
|
||||
PaymentSummary paymentSummary = summarizePayments(cyclePayments);
|
||||
BigDecimal expectedSalary = expectedMemberSalary(billTarget);
|
||||
BigDecimal payableSalary = expectedSalary.subtract(paymentSummary.getTotalIssuedSalary())
|
||||
.setScale(2, RoundingMode.DOWN);
|
||||
boolean currentLevelSettled = isCurrentLevelSettled(cyclePayments, target.getUserId(), region,
|
||||
billTarget.getLevel(), payableSalary);
|
||||
List<PolicyPayment> policyPayments = buildSettlementPayments(policyManager, billTarget,
|
||||
payableSalary, currentLevelSettled);
|
||||
|
||||
TeamManualSalaryPaymentDTO dto = new TeamManualSalaryPaymentDTO()
|
||||
.setId(target.getId())
|
||||
@ -282,15 +366,16 @@ public class TeamManualSalaryPaymentClientServiceImpl implements
|
||||
.setTeamOwnId(teamProfile.getOwnUserId())
|
||||
.setUserId(target.getUserId())
|
||||
.setBillBelong(billBelong)
|
||||
.setLastSettlementTarget(getLastSettlementTarget(payment))
|
||||
.setLastSettlementTarget(getLastSettlementTarget(cyclePayments))
|
||||
.setCurrentTarget(target.sumAcceptGiftValue())
|
||||
.setPolicyLevel(billTarget.getLevel())
|
||||
.setSatisfyLevel(billTarget.getSatisfyLevel())
|
||||
.setExpectedSalary(expectedSalary)
|
||||
.setPayableSalary(payableSalary)
|
||||
.setTotalIssuedSalary(getTotalIssuedSalary(payment))
|
||||
.setTotalIssuedSalary(paymentSummary.getTotalIssuedSalary())
|
||||
.setOverIssuedSalary(paymentSummary.getOverIssuedSalary())
|
||||
.setCurrentSalaryBalance(getAccurateBalance(target.getUserId()))
|
||||
.setPaid(Objects.nonNull(billTarget.getLevel())
|
||||
&& BigDecimal.ZERO.compareTo(payableSalary) == 0);
|
||||
.setPaid(currentLevelSettled);
|
||||
|
||||
return new ManualSalaryRow(dto, target, teamProfile, policyManager, billTarget, policyPayments);
|
||||
}
|
||||
@ -345,51 +430,55 @@ public class TeamManualSalaryPaymentClientServiceImpl implements
|
||||
.setSatisfyLevel(Boolean.FALSE);
|
||||
}
|
||||
|
||||
private List<PolicyPayment> listUnpaidPolicyPayments(TeamPolicyManager policyManager,
|
||||
TeamBillMemberTarget billTarget, TeamSalaryPayment payment, Long userId, String region) {
|
||||
if (Objects.isNull(policyManager) || CollectionUtils.isEmpty(policyManager.getPolicy())
|
||||
private BigDecimal expectedMemberSalary(TeamBillMemberTarget billTarget) {
|
||||
return Optional.ofNullable(billTarget)
|
||||
.map(TeamBillMemberTarget::getMemberSalary)
|
||||
.orElse(BigDecimal.ZERO)
|
||||
.setScale(2, RoundingMode.DOWN);
|
||||
}
|
||||
|
||||
private List<PolicyPayment> buildSettlementPayments(TeamPolicyManager policyManager,
|
||||
TeamBillMemberTarget billTarget, BigDecimal payableSalary, boolean currentLevelSettled) {
|
||||
if (currentLevelSettled || Objects.isNull(billTarget)
|
||||
|| Objects.isNull(billTarget.getLevel())) {
|
||||
return List.of();
|
||||
}
|
||||
|
||||
List<TeamPolicy> completePolicies = policyManager.getPolicy().stream()
|
||||
.filter(policy -> Objects.nonNull(policy.getLevel()))
|
||||
.filter(policy -> policy.getLevel() <= billTarget.getLevel())
|
||||
.sorted(Comparator.comparing(TeamPolicy::getLevel))
|
||||
.collect(Collectors.toList());
|
||||
if (CollectionUtils.isEmpty(completePolicies)) {
|
||||
return List.of();
|
||||
}
|
||||
|
||||
List<PolicyPayment> payments = new ArrayList<>();
|
||||
for (int i = 0; i < completePolicies.size(); i++) {
|
||||
TeamPolicy policy = completePolicies.get(i);
|
||||
if (Objects.nonNull(payment) && Boolean.TRUE.equals(
|
||||
teamSalaryPaymentService.checkRepeatPayment(payment.getId(), userId, region,
|
||||
policy.getLevel(), Boolean.TRUE))) {
|
||||
continue;
|
||||
}
|
||||
|
||||
BigDecimal salary = Optional.ofNullable(policy.getMemberSalary()).orElse(BigDecimal.ZERO);
|
||||
if (i > 0) {
|
||||
salary = salary.subtract(Optional.ofNullable(completePolicies.get(i - 1).getMemberSalary())
|
||||
.orElse(BigDecimal.ZERO));
|
||||
}
|
||||
salary = salary.setScale(2, RoundingMode.DOWN);
|
||||
if (salary.compareTo(BigDecimal.ZERO) <= 0) {
|
||||
continue;
|
||||
}
|
||||
|
||||
payments.add(new PolicyPayment(policy, policy.getLevel(), salary));
|
||||
}
|
||||
return payments;
|
||||
BigDecimal issueSalary = payableSalary.compareTo(BigDecimal.ZERO) > 0
|
||||
? payableSalary.setScale(2, RoundingMode.DOWN)
|
||||
: BigDecimal.ZERO.setScale(2, RoundingMode.DOWN);
|
||||
return List.of(new PolicyPayment(findPolicy(policyManager, billTarget.getLevel()),
|
||||
billTarget.getLevel(), issueSalary));
|
||||
}
|
||||
|
||||
private Long getLastSettlementTarget(TeamSalaryPayment payment) {
|
||||
return Optional.ofNullable(payment)
|
||||
.map(TeamSalaryPayment::getSalarySendDetails)
|
||||
.stream()
|
||||
.flatMap(List::stream)
|
||||
private TeamPolicy findPolicy(TeamPolicyManager policyManager, Integer level) {
|
||||
if (Objects.isNull(policyManager) || CollectionUtils.isEmpty(policyManager.getPolicy())
|
||||
|| Objects.isNull(level)) {
|
||||
return null;
|
||||
}
|
||||
return policyManager.getPolicy().stream()
|
||||
.filter(policy -> Objects.equals(policy.getLevel(), level))
|
||||
.findFirst()
|
||||
.orElse(null);
|
||||
}
|
||||
|
||||
private boolean isCurrentLevelSettled(List<TeamSalaryPayment> cyclePayments, Long userId,
|
||||
String region, Integer policyLevel, BigDecimal payableSalary) {
|
||||
return Objects.nonNull(policyLevel)
|
||||
&& payableSalary.compareTo(BigDecimal.ZERO) <= 0
|
||||
&& hasPaidPolicy(cyclePayments, userId, region, policyLevel);
|
||||
}
|
||||
|
||||
private boolean hasPaidPolicy(List<TeamSalaryPayment> cyclePayments, Long userId, String region,
|
||||
Integer policyLevel) {
|
||||
return listValidAnchorDetails(cyclePayments).stream()
|
||||
.anyMatch(details -> Objects.equals(details.getTeamMemberId(), userId)
|
||||
&& Objects.equals(details.getTeamRegionId(), region)
|
||||
&& Objects.equals(details.getPolicyLevel(), policyLevel));
|
||||
}
|
||||
|
||||
private Long getLastSettlementTarget(List<TeamSalaryPayment> cyclePayments) {
|
||||
return listValidAnchorDetails(cyclePayments).stream()
|
||||
.filter(this::validAnchorDetails)
|
||||
.max(Comparator.comparing(details -> Optional.ofNullable(details.getCreateTime())
|
||||
.orElse(new Timestamp(0))))
|
||||
@ -397,15 +486,54 @@ public class TeamManualSalaryPaymentClientServiceImpl implements
|
||||
.orElse(0L);
|
||||
}
|
||||
|
||||
private BigDecimal getTotalIssuedSalary(TeamSalaryPayment payment) {
|
||||
return Optional.ofNullable(payment)
|
||||
.map(TeamSalaryPayment::getSalarySendDetails)
|
||||
.stream()
|
||||
.flatMap(List::stream)
|
||||
.filter(this::validAnchorDetails)
|
||||
.map(details -> Optional.ofNullable(details.getSalary()).orElse(BigDecimal.ZERO))
|
||||
private PaymentSummary summarizePayments(List<TeamSalaryPayment> cyclePayments) {
|
||||
List<TeamSalaryPaymentDetails> details = listValidAnchorDetails(cyclePayments);
|
||||
BigDecimal totalIssuedSalary = details.stream()
|
||||
.map(detail -> Optional.ofNullable(detail.getSalary()).orElse(BigDecimal.ZERO))
|
||||
.reduce(BigDecimal.ZERO, BigDecimal::add)
|
||||
.setScale(2, RoundingMode.DOWN);
|
||||
return new PaymentSummary(totalIssuedSalary, getOverIssuedSalary(details));
|
||||
}
|
||||
|
||||
private BigDecimal getOverIssuedSalary(List<TeamSalaryPaymentDetails> details) {
|
||||
if (CollectionUtils.isEmpty(details)) {
|
||||
return BigDecimal.ZERO.setScale(2, RoundingMode.DOWN);
|
||||
}
|
||||
Set<String> issuedKeys = new HashSet<>();
|
||||
return details.stream()
|
||||
.sorted(Comparator.comparing(detail -> Optional.ofNullable(detail.getCreateTime())
|
||||
.orElse(new Timestamp(0))))
|
||||
.filter(detail -> !issuedKeys.add(paymentDetailsPolicyKey(detail)))
|
||||
.map(detail -> Optional.ofNullable(detail.getSalary()).orElse(BigDecimal.ZERO))
|
||||
.reduce(BigDecimal.ZERO, BigDecimal::add)
|
||||
.setScale(2, RoundingMode.DOWN);
|
||||
}
|
||||
|
||||
private String paymentDetailsPolicyKey(TeamSalaryPaymentDetails details) {
|
||||
if (Objects.isNull(details)
|
||||
|| Objects.isNull(details.getTeamMemberId())
|
||||
|| StringUtils.isBlank(details.getTeamRegionId())
|
||||
|| Objects.isNull(details.getPolicyLevel())
|
||||
|| Objects.isNull(details.getAnchor())) {
|
||||
return Optional.ofNullable(details).map(TeamSalaryPaymentDetails::getId)
|
||||
.orElse(String.valueOf(System.identityHashCode(details)));
|
||||
}
|
||||
return details.getTeamMemberId() + ":" + details.getTeamRegionId() + ":"
|
||||
+ details.getPolicyLevel() + ":" + details.getAnchor();
|
||||
}
|
||||
|
||||
private List<TeamSalaryPaymentDetails> listValidAnchorDetails(
|
||||
List<TeamSalaryPayment> cyclePayments) {
|
||||
if (CollectionUtils.isEmpty(cyclePayments)) {
|
||||
return List.of();
|
||||
}
|
||||
return cyclePayments.stream()
|
||||
.filter(Objects::nonNull)
|
||||
.flatMap(payment -> Optional.ofNullable(payment.getSalarySendDetails())
|
||||
.stream()
|
||||
.flatMap(List::stream))
|
||||
.filter(this::validAnchorDetails)
|
||||
.collect(Collectors.toList());
|
||||
}
|
||||
|
||||
private boolean validAnchorDetails(TeamSalaryPaymentDetails details) {
|
||||
@ -471,6 +599,25 @@ public class TeamManualSalaryPaymentClientServiceImpl implements
|
||||
return userId + "_" + billBelong;
|
||||
}
|
||||
|
||||
private static class PaymentSummary {
|
||||
|
||||
private final BigDecimal totalIssuedSalary;
|
||||
private final BigDecimal overIssuedSalary;
|
||||
|
||||
private PaymentSummary(BigDecimal totalIssuedSalary, BigDecimal overIssuedSalary) {
|
||||
this.totalIssuedSalary = totalIssuedSalary;
|
||||
this.overIssuedSalary = overIssuedSalary;
|
||||
}
|
||||
|
||||
private BigDecimal getTotalIssuedSalary() {
|
||||
return totalIssuedSalary;
|
||||
}
|
||||
|
||||
private BigDecimal getOverIssuedSalary() {
|
||||
return overIssuedSalary;
|
||||
}
|
||||
}
|
||||
|
||||
private static class ManualSalaryRow {
|
||||
|
||||
private final TeamManualSalaryPaymentDTO dto;
|
||||
@ -527,6 +674,18 @@ public class TeamManualSalaryPaymentClientServiceImpl implements
|
||||
return dto.getCurrentTarget();
|
||||
}
|
||||
|
||||
private BigDecimal getPayableSalary() {
|
||||
return dto.getPayableSalary();
|
||||
}
|
||||
|
||||
private BigDecimal getTotalIssuedSalary() {
|
||||
return dto.getTotalIssuedSalary();
|
||||
}
|
||||
|
||||
private BigDecimal getCurrentSalaryBalance() {
|
||||
return dto.getCurrentSalaryBalance();
|
||||
}
|
||||
|
||||
private TeamPolicyManager getPolicyManager() {
|
||||
return policyManager;
|
||||
}
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user