CP关系申请 问题修复
This commit is contained in:
parent
e5eeebf84a
commit
0260498bd3
@ -108,6 +108,9 @@ public class SendCpApplyCmdExe {
|
||||
ResponseAssert.isFalse(UserRelationErrorCode.UNAVAILABLE_OPS_YOURSELF,
|
||||
Objects.equals(sendUserId, acceptUserId));
|
||||
|
||||
cpApplyService.expireOverdueWaitApplies(sendUserId);
|
||||
cpApplyService.expireOverdueWaitApplies(acceptUserId);
|
||||
|
||||
boolean eqRegion = userRegionGateway.checkEqRegion(sendUserId, acceptUserId);
|
||||
ResponseAssert.isTrue(UserRelationErrorCode.UNAVAILABLE_NOT_REGION, eqRegion);
|
||||
|
||||
|
||||
@ -3,7 +3,8 @@ package com.red.circle.other.app.command.user.query;
|
||||
import com.red.circle.other.app.dto.cmd.user.relation.cp.CpApplyIdQueryCmd;
|
||||
import com.red.circle.other.infra.database.rds.service.user.user.CpApplyService;
|
||||
import com.red.circle.other.infra.enums.user.user.CpRelationshipType;
|
||||
import java.util.Optional;
|
||||
import java.util.Objects;
|
||||
import java.util.Optional;
|
||||
import lombok.RequiredArgsConstructor;
|
||||
import org.springframework.stereotype.Component;
|
||||
|
||||
@ -16,13 +17,27 @@ import org.springframework.stereotype.Component;
|
||||
@RequiredArgsConstructor
|
||||
public class CpApplyIdQryExe {
|
||||
|
||||
private final CpApplyService cpApplyService;
|
||||
|
||||
private final CpApplyService cpApplyService;
|
||||
|
||||
public String execute(CpApplyIdQueryCmd cmd) {
|
||||
return Optional.ofNullable(cpApplyService.getId(cmd.requiredReqUserId(), cmd.getUserId(),
|
||||
CpRelationshipType.normalize(cmd.getRelationType())))
|
||||
Long currentUserId = cmd.requiredReqUserId();
|
||||
Long targetUserId = cmd.getUserId();
|
||||
String relationType = CpRelationshipType.normalize(cmd.getRelationType());
|
||||
cpApplyService.expireOverdueWaitApplies(currentUserId);
|
||||
cpApplyService.expireOverdueWaitApplies(targetUserId);
|
||||
|
||||
Long applyId = cpApplyService.getId(targetUserId, currentUserId, relationType);
|
||||
if (isEmptyApplyId(applyId)) {
|
||||
applyId = cpApplyService.getId(currentUserId, targetUserId, relationType);
|
||||
}
|
||||
return Optional.ofNullable(applyId)
|
||||
.filter(id -> id > 0)
|
||||
.map(String::valueOf)
|
||||
.orElse(null);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
private boolean isEmptyApplyId(Long applyId) {
|
||||
return Objects.isNull(applyId) || applyId <= 0;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@ -3,6 +3,8 @@ package com.red.circle.other.app.command.user.query;
|
||||
import com.red.circle.other.app.dto.cmd.user.relation.cp.CpApplyStatusQueryCmd;
|
||||
import com.red.circle.other.infra.database.rds.entity.user.user.CpApply;
|
||||
import com.red.circle.other.infra.database.rds.service.user.user.CpApplyService;
|
||||
import com.red.circle.other.infra.enums.user.user.CpApplyStatus;
|
||||
import java.time.LocalDateTime;
|
||||
import java.util.Objects;
|
||||
import lombok.RequiredArgsConstructor;
|
||||
import org.springframework.stereotype.Component;
|
||||
@ -14,10 +16,26 @@ import org.springframework.stereotype.Component;
|
||||
@RequiredArgsConstructor
|
||||
public class CpApplyStatusQryExe {
|
||||
|
||||
private static final long APPLY_WAIT_EXPIRE_HOURS = 24L;
|
||||
|
||||
private final CpApplyService cpApplyService;
|
||||
|
||||
public String execute(CpApplyStatusQueryCmd cmd) {
|
||||
CpApply cpApply = cpApplyService.getById(cmd.getApplyId());
|
||||
return Objects.nonNull(cpApply) ? cpApply.getStatus() : null;
|
||||
if (Objects.isNull(cpApply)) {
|
||||
return null;
|
||||
}
|
||||
if (isOverdueWait(cpApply)) {
|
||||
cpApplyService.expireWaitById(cpApply.getId());
|
||||
return CpApplyStatus.EXPIRE.name();
|
||||
}
|
||||
return cpApply.getStatus();
|
||||
}
|
||||
|
||||
private boolean isOverdueWait(CpApply cpApply) {
|
||||
return Objects.equals(cpApply.getStatus(), CpApplyStatus.WAIT.name())
|
||||
&& Objects.nonNull(cpApply.getCreateTime())
|
||||
&& cpApply.getCreateTime().toLocalDateTime()
|
||||
.isBefore(LocalDateTime.now().minusHours(APPLY_WAIT_EXPIRE_HOURS));
|
||||
}
|
||||
}
|
||||
|
||||
@ -9,6 +9,7 @@ import com.red.circle.tool.core.json.JacksonUtils;
|
||||
import java.util.LinkedHashMap;
|
||||
import java.util.Map;
|
||||
import java.util.Objects;
|
||||
import java.util.concurrent.TimeUnit;
|
||||
import org.apache.commons.lang3.StringUtils;
|
||||
|
||||
public final class CpRelationC2cNoticeUtils {
|
||||
@ -36,9 +37,17 @@ public final class CpRelationC2cNoticeUtils {
|
||||
content.put("applyType", isReconcile ? "RECONCILE" : "APPLY");
|
||||
content.put("relationType", relationType.name());
|
||||
putAcceptProfile(content, acceptProfile);
|
||||
long createTimeSeconds = System.currentTimeMillis() / 1000;
|
||||
long expireTimeSeconds = createTimeSeconds + TimeUnit.DAYS.toSeconds(1);
|
||||
content.put("createTime", createTimeSeconds);
|
||||
content.put("sendTime", createTimeSeconds);
|
||||
content.put("dismissEndTime", expireTimeSeconds);
|
||||
|
||||
Map<String, Object> payload = basePayload(applyId, relationType.name(), title,
|
||||
ACTION_INVITE_PENDING, "PENDING", content);
|
||||
payload.put("createTime", createTimeSeconds);
|
||||
payload.put("sendTime", createTimeSeconds);
|
||||
payload.put("dismissEndTime", expireTimeSeconds);
|
||||
putSenderProfile(payload, senderProfile);
|
||||
putAcceptProfile(payload, acceptProfile);
|
||||
return buildMessage(fromUserId, toUserId, payload);
|
||||
|
||||
@ -56,12 +56,15 @@ public class CpApplyListener implements MessageListener {
|
||||
// 等待超时
|
||||
if (Objects.equals(cpApply.getStatus(), CpApplyStatus.WAIT.name())) {
|
||||
expire(cpApply);
|
||||
} else {
|
||||
log.info("[CP] skip expire cp apply, applyId={}, status={}", cpApply.getId(),
|
||||
cpApply.getStatus());
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
private void expire(CpApply cpApply) {
|
||||
boolean changed = cpApplyService.changeStatusById(cpApply.getId(), CpApplyStatus.EXPIRE);
|
||||
boolean changed = cpApplyService.expireWaitById(cpApply.getId());
|
||||
if (changed) {
|
||||
sendExpiredNotice(cpApply);
|
||||
}
|
||||
|
||||
@ -0,0 +1,43 @@
|
||||
package com.red.circle.other.app.command.user.query;
|
||||
|
||||
import static org.junit.jupiter.api.Assertions.assertEquals;
|
||||
import static org.mockito.Mockito.mock;
|
||||
import static org.mockito.Mockito.verify;
|
||||
import static org.mockito.Mockito.when;
|
||||
|
||||
import com.red.circle.other.app.dto.cmd.user.relation.cp.CpApplyIdQueryCmd;
|
||||
import com.red.circle.other.infra.database.rds.service.user.user.CpApplyService;
|
||||
import org.junit.jupiter.api.Test;
|
||||
|
||||
class CpApplyIdQryExeTest {
|
||||
|
||||
@Test
|
||||
void shouldReturnApplyIdSentByCurrentUser() {
|
||||
CpApplyService cpApplyService = mock(CpApplyService.class);
|
||||
when(cpApplyService.getId(2001L, 1001L, "BROTHER")).thenReturn(3001L);
|
||||
|
||||
CpApplyIdQryExe exe = new CpApplyIdQryExe(cpApplyService);
|
||||
|
||||
assertEquals("3001", exe.execute(cmd(1001L, 2001L, "BROTHER")));
|
||||
verify(cpApplyService).expireOverdueWaitApplies(1001L);
|
||||
verify(cpApplyService).expireOverdueWaitApplies(2001L);
|
||||
}
|
||||
|
||||
@Test
|
||||
void shouldFallbackToApplyIdReceivedByCurrentUser() {
|
||||
CpApplyService cpApplyService = mock(CpApplyService.class);
|
||||
when(cpApplyService.getId(1001L, 2001L, "CP")).thenReturn(3002L);
|
||||
|
||||
CpApplyIdQryExe exe = new CpApplyIdQryExe(cpApplyService);
|
||||
|
||||
assertEquals("3002", exe.execute(cmd(1001L, 2001L, "CP")));
|
||||
}
|
||||
|
||||
private static CpApplyIdQueryCmd cmd(Long reqUserId, Long targetUserId, String relationType) {
|
||||
CpApplyIdQueryCmd cmd = new CpApplyIdQueryCmd();
|
||||
cmd.setReqUserId(reqUserId);
|
||||
cmd.setUserId(targetUserId);
|
||||
cmd.setRelationType(relationType);
|
||||
return cmd;
|
||||
}
|
||||
}
|
||||
@ -3,11 +3,14 @@ package com.red.circle.other.app.command.user.query;
|
||||
import static org.junit.jupiter.api.Assertions.assertEquals;
|
||||
import static org.junit.jupiter.api.Assertions.assertNull;
|
||||
import static org.mockito.Mockito.mock;
|
||||
import static org.mockito.Mockito.verify;
|
||||
import static org.mockito.Mockito.when;
|
||||
|
||||
import com.red.circle.other.app.dto.cmd.user.relation.cp.CpApplyStatusQueryCmd;
|
||||
import com.red.circle.other.infra.database.rds.entity.user.user.CpApply;
|
||||
import com.red.circle.other.infra.database.rds.service.user.user.CpApplyService;
|
||||
import java.sql.Timestamp;
|
||||
import java.time.LocalDateTime;
|
||||
import org.junit.jupiter.api.Test;
|
||||
|
||||
class CpApplyStatusQryExeTest {
|
||||
@ -30,6 +33,21 @@ class CpApplyStatusQryExeTest {
|
||||
assertNull(exe.execute(cmd(3001L)));
|
||||
}
|
||||
|
||||
@Test
|
||||
void shouldExpireOverdueWaitApplyWhenQueryingStatus() {
|
||||
CpApplyService cpApplyService = mock(CpApplyService.class);
|
||||
CpApply cpApply = new CpApply()
|
||||
.setId(3001L)
|
||||
.setStatus("WAIT");
|
||||
cpApply.setCreateTime(Timestamp.valueOf(LocalDateTime.now().minusHours(25)));
|
||||
when(cpApplyService.getById(3001L)).thenReturn(cpApply);
|
||||
|
||||
CpApplyStatusQryExe exe = new CpApplyStatusQryExe(cpApplyService);
|
||||
|
||||
assertEquals("EXPIRE", exe.execute(cmd(3001L)));
|
||||
verify(cpApplyService).expireWaitById(3001L);
|
||||
}
|
||||
|
||||
private static CpApplyStatusQueryCmd cmd(Long applyId) {
|
||||
CpApplyStatusQueryCmd cmd = new CpApplyStatusQueryCmd();
|
||||
cmd.setApplyId(applyId);
|
||||
|
||||
@ -6,6 +6,8 @@ import static org.mockito.ArgumentMatchers.any;
|
||||
import static org.mockito.ArgumentMatchers.eq;
|
||||
import static org.mockito.Mockito.inOrder;
|
||||
import static org.mockito.Mockito.mock;
|
||||
import static org.mockito.Mockito.never;
|
||||
import static org.mockito.Mockito.verify;
|
||||
import static org.mockito.Mockito.when;
|
||||
|
||||
import com.red.circle.common.business.core.enums.SysOriginPlatformEnum;
|
||||
@ -45,7 +47,7 @@ class CpApplyListenerTest {
|
||||
.setStatus(CpApplyStatus.WAIT.name());
|
||||
|
||||
when(cpApplyService.getById(3001L)).thenReturn(apply);
|
||||
when(cpApplyService.changeStatusById(3001L, CpApplyStatus.EXPIRE)).thenReturn(true);
|
||||
when(cpApplyService.expireWaitById(3001L)).thenReturn(true);
|
||||
when(userProfileGateway.getByUserId(1001L)).thenReturn(profile(1001L));
|
||||
when(userProfileGateway.getByUserId(2001L)).thenReturn(profile(2001L));
|
||||
when(imMessageClient.sendCustomMessage(any(CustomC2cMsgBodyCmd.class)))
|
||||
@ -68,12 +70,41 @@ class CpApplyListenerTest {
|
||||
ArgumentCaptor<CustomC2cMsgBodyCmd> captor = ArgumentCaptor.forClass(
|
||||
CustomC2cMsgBodyCmd.class);
|
||||
InOrder inOrder = inOrder(cpApplyService, imMessageClient);
|
||||
inOrder.verify(cpApplyService).changeStatusById(3001L, CpApplyStatus.EXPIRE);
|
||||
inOrder.verify(cpApplyService).expireWaitById(3001L);
|
||||
inOrder.verify(imMessageClient).sendCustomMessage(captor.capture());
|
||||
List<CustomC2cMsgBodyCmd> messages = captor.getAllValues();
|
||||
assertExpiredMessage(messages.get(0), "1001", "2001");
|
||||
}
|
||||
|
||||
@Test
|
||||
void nonWaitApplyShouldNotExpireAgain() {
|
||||
CpApplyService cpApplyService = mock(CpApplyService.class);
|
||||
ImMessageClient imMessageClient = mock(ImMessageClient.class);
|
||||
UserProfileGateway userProfileGateway = mock(UserProfileGateway.class);
|
||||
MessageEventProcess messageEventProcess = mock(MessageEventProcess.class);
|
||||
CpApply apply = new CpApply()
|
||||
.setId(3001L)
|
||||
.setStatus(CpApplyStatus.EXPIRE.name());
|
||||
|
||||
when(cpApplyService.getById(3001L)).thenReturn(apply);
|
||||
when(messageEventProcess.consume(any(MessageEventProcessDescribe.class),
|
||||
eq(CpApplyEvent.class), any())).thenAnswer(invocation -> {
|
||||
@SuppressWarnings("unchecked")
|
||||
Consumer<CpApplyEvent> consumer = invocation.getArgument(2, Consumer.class);
|
||||
consumer.accept(new CpApplyEvent()
|
||||
.setId(3001L)
|
||||
.setSysOrigin(SysOriginPlatformEnum.LIKEI));
|
||||
return Action.SUCCESS;
|
||||
});
|
||||
|
||||
CpApplyListener listener = new CpApplyListener(cpApplyService, imMessageClient,
|
||||
userProfileGateway, messageEventProcess);
|
||||
|
||||
assertEquals(Action.SUCCESS, listener.consume(new ConsumerMessage()));
|
||||
verify(cpApplyService, never()).expireWaitById(3001L);
|
||||
verify(imMessageClient, never()).sendCustomMessage(any(CustomC2cMsgBodyCmd.class));
|
||||
}
|
||||
|
||||
@SuppressWarnings("unchecked")
|
||||
private static void assertExpiredMessage(CustomC2cMsgBodyCmd message, String fromAccount,
|
||||
String toAccount) {
|
||||
|
||||
@ -76,7 +76,17 @@ public interface CpApplyService extends BaseService<CpApply> {
|
||||
* @param status 状态
|
||||
* @return true 成功,false 失败
|
||||
*/
|
||||
boolean changeStatusById(Long id, CpApplyStatus status);
|
||||
boolean changeStatusById(Long id, CpApplyStatus status);
|
||||
|
||||
/**
|
||||
* 只把等待中的申请置为超时.
|
||||
*/
|
||||
boolean expireWaitById(Long id);
|
||||
|
||||
/**
|
||||
* 清理用户相关超过 24 小时仍处于等待状态的申请.
|
||||
*/
|
||||
void expireOverdueWaitApplies(Long userId);
|
||||
|
||||
/**
|
||||
* 拒绝所有等待状态在用户.
|
||||
|
||||
@ -10,9 +10,10 @@ import com.red.circle.other.infra.database.rds.entity.user.user.CpApply;
|
||||
import com.red.circle.other.infra.database.rds.service.user.user.CpApplyService;
|
||||
import com.red.circle.other.infra.enums.user.user.CpApplyStatus;
|
||||
import com.red.circle.other.infra.enums.user.user.CpRelationshipType;
|
||||
import com.red.circle.other.inner.model.cmd.user.CpApplyQryCmd;
|
||||
import java.time.LocalDateTime;
|
||||
import java.util.List;
|
||||
import com.red.circle.other.inner.model.cmd.user.CpApplyQryCmd;
|
||||
import java.sql.Timestamp;
|
||||
import java.time.LocalDateTime;
|
||||
import java.util.List;
|
||||
import java.util.Objects;
|
||||
import java.util.Optional;
|
||||
import org.springframework.stereotype.Service;
|
||||
@ -26,9 +27,11 @@ import org.springframework.stereotype.Service;
|
||||
* @since 2021-07-13
|
||||
*/
|
||||
@Service
|
||||
public class CpApplyServiceImpl extends BaseServiceImpl<CpApplyDAO, CpApply> implements
|
||||
CpApplyService {
|
||||
|
||||
public class CpApplyServiceImpl extends BaseServiceImpl<CpApplyDAO, CpApply> implements
|
||||
CpApplyService {
|
||||
|
||||
private static final long APPLY_WAIT_EXPIRE_HOURS = 24L;
|
||||
|
||||
@Override
|
||||
public void dismiss(Long requestUserId) {
|
||||
dismiss(requestUserId, CpRelationshipType.CP.name());
|
||||
@ -62,10 +65,12 @@ public class CpApplyServiceImpl extends BaseServiceImpl<CpApplyDAO, CpApply> imp
|
||||
.eq(CpApply::getRelationType, CpRelationshipType.normalize(relationType))
|
||||
.eq(CpApply::getAcceptApplyUserId, acceptApplyUserId)
|
||||
.eq(CpApply::getSendApplyUserId, sendApplyUserId)
|
||||
.last(PageConstant.LIMIT_ONE)
|
||||
.getOne()
|
||||
).map(CpApply::getId).orElse(null);
|
||||
}
|
||||
.gt(CpApply::getCreateTime, waitExpireBefore())
|
||||
.orderByDesc(CpApply::getCreateTime)
|
||||
.last(PageConstant.LIMIT_ONE)
|
||||
.getOne()
|
||||
).map(CpApply::getId).orElse(null);
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean exists(Long acceptApplyUserId, Long sendApplyUserId) {
|
||||
@ -89,6 +94,7 @@ public class CpApplyServiceImpl extends BaseServiceImpl<CpApplyDAO, CpApply> imp
|
||||
.eq(CpApply::getSendApplyUserId, sendApplyUserId)
|
||||
.eq(CpApply::getRelationType, CpRelationshipType.normalize(relationType))
|
||||
.eq(CpApply::getStatus, CpApplyStatus.WAIT.name())
|
||||
.gt(CpApply::getCreateTime, waitExpireBefore())
|
||||
.getOne())
|
||||
.map(cpApply -> Objects.nonNull(cpApply.getId()))
|
||||
.orElse(Boolean.FALSE);
|
||||
@ -98,9 +104,39 @@ public class CpApplyServiceImpl extends BaseServiceImpl<CpApplyDAO, CpApply> imp
|
||||
public boolean changeStatusById(Long id, CpApplyStatus status) {
|
||||
return update()
|
||||
.set(CpApply::getStatus, status.name())
|
||||
.set(CpApply::getUpdateTime, LocalDateTime.now())
|
||||
.eq(CpApply::getId, id)
|
||||
.execute();
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean expireWaitById(Long id) {
|
||||
return update()
|
||||
.set(CpApply::getStatus, CpApplyStatus.EXPIRE.name())
|
||||
.set(CpApply::getUpdateTime, LocalDateTime.now())
|
||||
.eq(CpApply::getId, id)
|
||||
.eq(CpApply::getStatus, CpApplyStatus.WAIT.name())
|
||||
.execute();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void expireOverdueWaitApplies(Long userId) {
|
||||
if (Objects.isNull(userId)) {
|
||||
return;
|
||||
}
|
||||
update()
|
||||
.set(CpApply::getStatus, CpApplyStatus.EXPIRE.name())
|
||||
.set(CpApply::getUpdateTime, LocalDateTime.now())
|
||||
.eq(CpApply::getStatus, CpApplyStatus.WAIT.name())
|
||||
.lt(CpApply::getCreateTime, waitExpireBefore())
|
||||
.and(where -> where.eq(CpApply::getSendApplyUserId, userId)
|
||||
.or().eq(CpApply::getAcceptApplyUserId, userId))
|
||||
.execute();
|
||||
}
|
||||
|
||||
private Timestamp waitExpireBefore() {
|
||||
return Timestamp.valueOf(LocalDateTime.now().minusHours(APPLY_WAIT_EXPIRE_HOURS));
|
||||
}
|
||||
|
||||
@Override
|
||||
public void refuseStatusWait(Long acceptApplyUserId) {
|
||||
|
||||
@ -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<PolicyPayment> 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) {
|
||||
|
||||
@ -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));
|
||||
}
|
||||
}
|
||||
Loading…
x
Reference in New Issue
Block a user