diff --git a/rc-service/rc-service-other/other-inner-endpoint/src/main/java/com/red/circle/other/app/inner/service/team/impl/TeamManualSalaryPaymentClientServiceImpl.java b/rc-service/rc-service-other/other-inner-endpoint/src/main/java/com/red/circle/other/app/inner/service/team/impl/TeamManualSalaryPaymentClientServiceImpl.java index d9cdcace..f756861d 100644 --- a/rc-service/rc-service-other/other-inner-endpoint/src/main/java/com/red/circle/other/app/inner/service/team/impl/TeamManualSalaryPaymentClientServiceImpl.java +++ b/rc-service/rc-service-other/other-inner-endpoint/src/main/java/com/red/circle/other/app/inner/service/team/impl/TeamManualSalaryPaymentClientServiceImpl.java @@ -134,7 +134,8 @@ public class TeamManualSalaryPaymentClientServiceImpl implements billBelong, row.getSysOrigin()); for (PolicyPayment policyPayment : row.getPayments()) { - if (Boolean.TRUE.equals(teamSalaryPaymentService.checkRepeatPayment(payment.getId(), + if (policyPayment.getSalary().compareTo(BigDecimal.ZERO) <= 0 + && Boolean.TRUE.equals(teamSalaryPaymentService.checkRepeatPayment(payment.getId(), row.getUserId(), row.getRegion(), policyPayment.getLevel(), policyPayment.getAnchor()))) { continue; @@ -501,32 +502,32 @@ public class TeamManualSalaryPaymentClientServiceImpl implements .setScale(2, RoundingMode.DOWN); BigDecimal agentMissing = agentExpected.subtract(paymentSummary.getAgentIssuedSalary()) .setScale(2, RoundingMode.DOWN); - boolean memberSettled = isRoleSettled(cyclePayments, userId, region, billTarget.getLevel(), - Boolean.TRUE, memberExpected); - boolean agentSettled = isRoleSettled(cyclePayments, userId, region, billTarget.getLevel(), - Boolean.FALSE, agentExpected); + boolean memberHasSettlementRecord = hasPaidPolicy(cyclePayments, userId, region, + billTarget.getLevel(), Boolean.TRUE); + boolean agentHasSettlementRecord = hasPaidPolicy(cyclePayments, userId, region, + billTarget.getLevel(), Boolean.FALSE); List payments = new ArrayList<>(); if (remainingPayable.compareTo(BigDecimal.ZERO) <= 0) { - if (!memberSettled && memberExpected.compareTo(BigDecimal.ZERO) > 0) { + if (!memberHasSettlementRecord && memberExpected.compareTo(BigDecimal.ZERO) > 0) { payments.add(new PolicyPayment(policy, billTarget.getLevel(), BigDecimal.ZERO.setScale(2, RoundingMode.DOWN), Boolean.TRUE)); } - if (!agentSettled && agentExpected.compareTo(BigDecimal.ZERO) > 0) { + if (!agentHasSettlementRecord && agentExpected.compareTo(BigDecimal.ZERO) > 0) { payments.add(new PolicyPayment(policy, billTarget.getLevel(), BigDecimal.ZERO.setScale(2, RoundingMode.DOWN), Boolean.FALSE)); } return payments; } - if (!memberSettled && memberMissing.compareTo(BigDecimal.ZERO) > 0) { + if (memberMissing.compareTo(BigDecimal.ZERO) > 0) { BigDecimal issueSalary = memberMissing.min(remainingPayable).setScale(2, RoundingMode.DOWN); if (issueSalary.compareTo(BigDecimal.ZERO) > 0) { payments.add(new PolicyPayment(policy, billTarget.getLevel(), issueSalary, Boolean.TRUE)); remainingPayable = remainingPayable.subtract(issueSalary).setScale(2, RoundingMode.DOWN); } } - if (!agentSettled && agentMissing.compareTo(BigDecimal.ZERO) > 0 + if (agentMissing.compareTo(BigDecimal.ZERO) > 0 && remainingPayable.compareTo(BigDecimal.ZERO) > 0) { BigDecimal issueSalary = agentMissing.min(remainingPayable).setScale(2, RoundingMode.DOWN); if (issueSalary.compareTo(BigDecimal.ZERO) > 0) { diff --git a/rc-service/rc-service-other/other-inner-endpoint/src/test/java/com/red/circle/other/app/inner/service/team/impl/TeamManualSalaryPaymentClientServiceImplTest.java b/rc-service/rc-service-other/other-inner-endpoint/src/test/java/com/red/circle/other/app/inner/service/team/impl/TeamManualSalaryPaymentClientServiceImplTest.java new file mode 100644 index 00000000..9656bf8b --- /dev/null +++ b/rc-service/rc-service-other/other-inner-endpoint/src/test/java/com/red/circle/other/app/inner/service/team/impl/TeamManualSalaryPaymentClientServiceImplTest.java @@ -0,0 +1,103 @@ +package com.red.circle.other.app.inner.service.team.impl; + +import static org.junit.jupiter.api.Assertions.assertEquals; + +import com.red.circle.other.infra.database.mongo.dto.team.TeamBillMemberTarget; +import com.red.circle.other.infra.database.mongo.dto.team.TeamSalaryPaymentDetails; +import com.red.circle.other.infra.database.mongo.entity.team.team.TeamSalaryPayment; +import java.lang.reflect.Constructor; +import java.math.BigDecimal; +import java.util.List; +import org.junit.jupiter.api.Test; +import org.springframework.test.util.ReflectionTestUtils; + +class TeamManualSalaryPaymentClientServiceImplTest { + + @Test + void buildSettlementPaymentsShouldTopUpWhenCurrentLevelRecordExistsButSalaryIsInsufficient() + throws Exception { + TeamManualSalaryPaymentClientServiceImpl service = + new TeamManualSalaryPaymentClientServiceImpl( + null, null, null, null, null, null, null, null); + Long userId = 2054591808909930498L; + String region = "2046067717605224449"; + + TeamBillMemberTarget billTarget = new TeamBillMemberTarget() + .setLevel(6) + .setMemberSalary(new BigDecimal("35.00")) + .setOwnSalary(new BigDecimal("8.75")); + TeamSalaryPayment currentPayment = new TeamSalaryPayment() + .setSalarySendDetails(List.of(new TeamSalaryPaymentDetails() + .setTeamMemberId(userId) + .setTeamRegionId(region) + .setPolicyLevel(6) + .setAnchor(Boolean.TRUE) + .setSalary(new BigDecimal("3.00")) + .setRecycled(Boolean.FALSE))); + + Object paymentSummary = paymentSummary( + new BigDecimal("31.50"), + new BigDecimal("22.00"), + new BigDecimal("9.50")); + + List payments = ReflectionTestUtils.invokeMethod(service, "buildSettlementPayments", + null, billTarget, List.of(currentPayment), userId, region, paymentSummary, + new BigDecimal("12.25"), false); + + assertEquals(1, payments.size()); + Object payment = payments.get(0); + assertEquals(6, ReflectionTestUtils.getField(payment, "level")); + assertEquals(Boolean.TRUE, ReflectionTestUtils.getField(payment, "anchor")); + assertEquals(new BigDecimal("12.25"), ReflectionTestUtils.getField(payment, "salary")); + } + + @Test + void buildSettlementPaymentsShouldSettleZeroWhenPayableSalaryIsNegative() throws Exception { + TeamManualSalaryPaymentClientServiceImpl service = + new TeamManualSalaryPaymentClientServiceImpl( + null, null, null, null, null, null, null, null); + Long userId = 1008071L; + String region = "2046067717605224449"; + + TeamBillMemberTarget billTarget = new TeamBillMemberTarget() + .setLevel(6) + .setMemberSalary(new BigDecimal("35.00")) + .setOwnSalary(new BigDecimal("8.75")); + Object paymentSummary = paymentSummary( + new BigDecimal("45.00"), + new BigDecimal("36.00"), + new BigDecimal("9.00")); + + List payments = ReflectionTestUtils.invokeMethod(service, "buildSettlementPayments", + null, billTarget, List.of(), userId, region, paymentSummary, + new BigDecimal("-1.25"), false); + + assertEquals(2, payments.size()); + assertEquals(BigDecimal.ZERO.setScale(2), ReflectionTestUtils.getField(payments.get(0), + "salary")); + assertEquals(BigDecimal.ZERO.setScale(2), ReflectionTestUtils.getField(payments.get(1), + "salary")); + } + + private Object paymentSummary(BigDecimal totalIssuedSalary, BigDecimal memberIssuedSalary, + BigDecimal agentIssuedSalary) throws Exception { + Class summaryClass = Class.forName( + "com.red.circle.other.app.inner.service.team.impl." + + "TeamManualSalaryPaymentClientServiceImpl$PaymentSummary"); + Constructor constructor = summaryClass.getDeclaredConstructor( + BigDecimal.class, + BigDecimal.class, + BigDecimal.class, + BigDecimal.class, + BigDecimal.class, + BigDecimal.class); + constructor.setAccessible(true); + return constructor.newInstance( + totalIssuedSalary, + memberIssuedSalary, + agentIssuedSalary, + BigDecimal.ZERO.setScale(2), + BigDecimal.ZERO.setScale(2), + BigDecimal.ZERO.setScale(2)); + } +}