Commit 7cdf5e50 by zhangxingmin

push

parent e3b27bbd
......@@ -131,6 +131,16 @@ public class ApiSalaryController implements ApiSalaryFeignClient {
}
/**
* 薪资单信息-汇款明细-查询汇率
* @param request
* @return
*/
@Override
public Result<BigDecimal> getExchangeRate(ApiSalaryExchangeRateRequest request) {
return apiSalaryService.getExchangeRate(request);
}
/**
* 计算-实发金额
* @param request
* @return
......
......@@ -30,6 +30,8 @@ public interface ApiSalaryService {
Result delSalaryRemittance(String salaryRemittanceBizId);
Result<BigDecimal> getExchangeRate(ApiSalaryExchangeRateRequest request);
Result<BigDecimal> calculatePaidAmount(ApiSalaryCalculatePaidAmountRequest request);
Result<BigDecimal> calculateTotalAmount(ApiSalaryCalculateTotalAmountRequest request);
......
package com.yd.csf.api.service.impl;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.metadata.IPage;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.yd.base.feign.client.exchangerate.ApiExchangeRateFeignClient;
import com.yd.common.enums.CommonEnum;
import com.yd.common.exception.BusinessException;
import com.yd.common.result.Result;
......@@ -28,11 +30,10 @@ import org.apache.commons.lang3.ObjectUtils;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import javax.annotation.Resource;
import java.math.BigDecimal;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.*;
import java.util.stream.Collectors;
@Slf4j
......@@ -48,6 +49,9 @@ public class ApiSalaryServiceImpl implements ApiSalaryService {
@Autowired
private ISalaryRemittanceService iSalaryRemittanceService;
@Autowired
private ApiExchangeRateFeignClient apiExchangeRateFeignClient;
/**
* 分页查询-制作薪资单列表信息
* @param request
......@@ -68,8 +72,8 @@ public class ApiSalaryServiceImpl implements ApiSalaryService {
@Override
public Result<IPage<ApiSalaryPushPageResponse>> pushPage(ApiSalaryPushPageRequest request) {
Page<ApiSalaryPushPageResponse> page = new Page<>(request.getPageNo(), request.getPageSize());
// IPage<ApiSalaryPushPageResponse> iPage = iSalaryService.pushPage(page, request);
return Result.success();
IPage<ApiSalaryPushPageResponse> iPage = iSalaryService.pushPage(page, request);
return Result.success(iPage);
}
/**
......@@ -225,8 +229,11 @@ public class ApiSalaryServiceImpl implements ApiSalaryService {
if (CollectionUtils.isEmpty(apiSalaryBatchAddDTOList)) {
throw new BusinessException("批量新增的数据列表不能为空");
}
//批量校验同一转介人同一年月只能有一条薪资单记录 TODO
//批量校验薪资单信息金额字段信息 TODO
//批量校验同一转介人同一年月只能有一条薪资单记录
batchCheckUniqueByBrokerMonth(apiSalaryBatchAddDTOList);
//批量校验薪资单信息金额字段信息
batchAddCheckAmount(apiSalaryBatchAddDTOList);
Map<Salary,List<SalaryRemittance>> map = new HashMap<>();
apiSalaryBatchAddDTOList.forEach(dto -> {
Salary salary = new Salary();
......@@ -286,6 +293,16 @@ public class ApiSalaryServiceImpl implements ApiSalaryService {
}
/**
* 薪资单信息-汇款明细-查询汇率
* @param request
* @return
*/
@Override
public Result<BigDecimal> getExchangeRate(ApiSalaryExchangeRateRequest request) {
return apiExchangeRateFeignClient.getExchangeRate(request.getFromCurrency(),request.getToCurrency(),"");
}
/**
* 计算-实发金额
* @param request
* @return
......@@ -329,10 +346,150 @@ public class ApiSalaryServiceImpl implements ApiSalaryService {
/**
* 批量校验同一转介人同一年月只能有一条薪资单记录
* @param apiSalaryBatchAddDTOList
* @param apiSalaryBatchAddDTOList 批量新增DTO列表
*/
public void batchCheckUniqueByBrokerMonth(List<ApiSalaryBatchAddDTO> apiSalaryBatchAddDTOList) {
if (CollectionUtils.isEmpty(apiSalaryBatchAddDTOList)) {
return;
}
// 构建 key -> brokerName 映射(用于错误提示)
Map<String, String> keyToBrokerName = new HashMap<>();
for (ApiSalaryBatchAddDTO dto : apiSalaryBatchAddDTOList) {
String key = dto.getBrokerBizId() + "|" + dto.getMonth();
if (!keyToBrokerName.containsKey(key)) {
keyToBrokerName.put(key, dto.getBrokerName());
}
}
// 1. 校验列表内部是否有重复
Set<String> keySet = new HashSet<>();
List<String> duplicateKeys = new ArrayList<>();
for (ApiSalaryBatchAddDTO dto : apiSalaryBatchAddDTOList) {
String key = dto.getBrokerBizId() + "|" + dto.getMonth();
if (!keySet.add(key)) {
duplicateKeys.add(key);
}
}
if (!duplicateKeys.isEmpty()) {
List<String> duplicateDescriptions = duplicateKeys.stream()
.distinct()
.map(key -> {
String name = keyToBrokerName.getOrDefault(key, "未知");
String month = key.split("\\|")[1];
return name + "-" + month;
})
.collect(Collectors.toList());
throw new BusinessException("批量数据中存在重复的转介人与薪资月份组合: " + String.join(", ", duplicateDescriptions));
}
// 2. 查询数据库中已存在的相同组合
List<String> brokerBizIdList = apiSalaryBatchAddDTOList.stream()
.map(ApiSalaryBatchAddDTO::getBrokerBizId)
.distinct()
.collect(Collectors.toList());
List<String> monthList = apiSalaryBatchAddDTOList.stream()
.map(ApiSalaryBatchAddDTO::getMonth)
.distinct()
.collect(Collectors.toList());
LambdaQueryWrapper<Salary> wrapper = new LambdaQueryWrapper<>();
wrapper.eq(Salary::getIsDeleted, 0)
.in(Salary::getBrokerBizId, brokerBizIdList)
.in(Salary::getMonth, monthList);
List<Salary> existingSalaries = iSalaryService.list(wrapper);
Set<String> existingKeys = existingSalaries.stream()
.map(s -> s.getBrokerBizId() + "|" + s.getMonth())
.collect(Collectors.toSet());
// 3. 找出冲突的组合
List<String> conflictKeys = apiSalaryBatchAddDTOList.stream()
.map(dto -> dto.getBrokerBizId() + "|" + dto.getMonth())
.filter(existingKeys::contains)
.distinct()
.collect(Collectors.toList());
if (!conflictKeys.isEmpty()) {
List<String> conflictDescriptions = conflictKeys.stream()
.map(key -> {
String name = keyToBrokerName.getOrDefault(key, "未知");
String month = key.split("\\|")[1];
return name + "-" + month;
})
.collect(Collectors.toList());
throw new BusinessException("以下转介人与薪资月份组合已存在薪资单记录: " + String.join(", ", conflictDescriptions));
}
}
/**
* 批量新增薪资单-校验金额
* @param apiSalaryBatchAddDTOList
*/
public void batchAddCheckAmount(List<ApiSalaryBatchAddDTO> apiSalaryBatchAddDTOList) {
if (CollectionUtils.isEmpty(apiSalaryBatchAddDTOList)) {
return;
}
// 构建 key -> brokerName 映射(用于错误提示)
Map<String, String> keyToBrokerName = new HashMap<>();
for (ApiSalaryBatchAddDTO dto : apiSalaryBatchAddDTOList) {
String key = dto.getBrokerBizId() + "|" + dto.getMonth();
if (!keyToBrokerName.containsKey(key)) {
keyToBrokerName.put(key, dto.getBrokerName());
}
}
//创建需要校验的key值
List<String> checkKeys = new ArrayList<>();
for (ApiSalaryBatchAddDTO addDTO : apiSalaryBatchAddDTOList) {
//获取2条汇款明细的发放金额总和
BigDecimal totalAmount = statisticsAmountByBatchAdd(addDTO);
//校验totalAmount和实发金额是否相等
BigDecimal paidAmount = ObjectUtils.defaultIfNull(addDTO.getPaidAmount(), BigDecimal.ZERO);
if (paidAmount.compareTo(totalAmount) != 0){
//汇款明细合计总金额和实发总金额必须相等,记录key值
String key = addDTO.getBrokerBizId() + "|" + addDTO.getMonth();
checkKeys.add(key);
}
}
if (!checkKeys.isEmpty()) {
List<String> duplicateDescriptions = checkKeys.stream()
.distinct()
.map(key -> {
String name = keyToBrokerName.getOrDefault(key, "未知");
String month = key.split("\\|")[1];
return name + "-" + month;
})
.collect(Collectors.toList());
throw new BusinessException("批量数据中,汇款明细金额合计值和实发金额不相等的转介人与薪资月份组合: " + String.join(", ", duplicateDescriptions));
}
}
/**
* 统计批量新增的汇款明细对象发放金额合计值
* @return
*/
public BigDecimal statisticsAmountByBatchAdd(ApiSalaryBatchAddDTO addDTO) {
//获取2条汇款明细的发放金额总和
//汇款金额1
BigDecimal amount1 = ObjectUtils.defaultIfNull(addDTO.getAmount1(), BigDecimal.ZERO);
//汇率1
BigDecimal exchangeRate1 = ObjectUtils.defaultIfNull(addDTO.getExchangeRate1(), BigDecimal.ZERO);
//目标发放金额1 = 汇款金额1 * 汇率1
BigDecimal targetAmount1 = amount1.multiply(exchangeRate1);
//汇款金额2
BigDecimal amount2 = ObjectUtils.defaultIfNull(addDTO.getAmount2(), BigDecimal.ZERO);
//汇率2
BigDecimal exchangeRate2 = ObjectUtils.defaultIfNull(addDTO.getExchangeRate2(), BigDecimal.ZERO);
//目标发放金额2 = 汇款金额2 * 汇率2
BigDecimal targetAmount2 = amount2.multiply(exchangeRate2);
//合计发放金额 = targetAmount1 + targetAmount2
BigDecimal totalAmount = targetAmount1.add(targetAmount2);
return totalAmount;
}
/**
......
......@@ -98,6 +98,14 @@ public interface ApiSalaryFeignClient {
Result delSalaryRemittance(@NotBlank(message = "薪资汇款明细表唯一业务ID不能为空") @RequestParam(value = "salaryRemittanceBizId") String salaryRemittanceBizId);
/**
* 薪资单信息-汇款明细-查询汇率
* @param request
* @return
*/
@PostMapping("/get/exchangeRate")
Result<BigDecimal> getExchangeRate(@Validated @RequestBody ApiSalaryExchangeRateRequest request);
/**
* 计算-实发金额
* @param request
* @return
......
package com.yd.csf.feign.request.salary;
import lombok.Data;
import javax.validation.constraints.NotBlank;
@Data
public class ApiSalaryExchangeRateRequest {
/**
* 原币种
*/
@NotBlank(message = "原币种不能为空")
private String fromCurrency;
/**
* 目标币种
*/
@NotBlank(message = "目标币种不能为空")
private String toCurrency;
}
......@@ -17,7 +17,7 @@ public class ApiSalaryPushPageRequest extends PageDto {
private String month;
/**
* 薪资单状态:1-待审核提交 2-待审核 3-审核退回 4-待核对提交 5-待核对 6-核对退回 7-已核对 8-已推送 9-已取消
* 薪资单状态:1-待提交 2-待核对 3-已核对 4-退回 5-已推送 6-已取消
*/
private String status;
}
......@@ -29,7 +29,7 @@ public class ApiSalaryPushPageResponse {
private BigDecimal grossAmount;
/**
* 扣款合计(单位:HKD)
* 扣款合计(单位:HKD)( 扣款合计 = 应发 - 实发)
*/
private BigDecimal totalDeductions;
......@@ -39,6 +39,11 @@ public class ApiSalaryPushPageResponse {
private String otherRemark;
/**
* 薪资单状态:1-待提交 2-待核对 3-已核对 4-退回 5-已推送 6-已取消
*/
private String status;
/**
* 制作人(创建人名称)
*/
private String creatorName;
......
......@@ -3,7 +3,9 @@ package com.yd.csf.service.dao;
import com.baomidou.mybatisplus.core.metadata.IPage;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.yd.csf.feign.request.salary.ApiSalaryPageRequest;
import com.yd.csf.feign.request.salary.ApiSalaryPushPageRequest;
import com.yd.csf.feign.response.salary.ApiSalaryPageResponse;
import com.yd.csf.feign.response.salary.ApiSalaryPushPageResponse;
import com.yd.csf.service.model.Salary;
import com.baomidou.mybatisplus.core.mapper.BaseMapper;
import org.apache.ibatis.annotations.Param;
......@@ -20,4 +22,7 @@ public interface SalaryMapper extends BaseMapper<Salary> {
IPage<ApiSalaryPageResponse> page(@Param("page") Page<ApiSalaryPageResponse> page,
@Param("request") ApiSalaryPageRequest request);
IPage<ApiSalaryPushPageResponse> pushPage(@Param("page") Page<ApiSalaryPushPageResponse> page,
@Param("request") ApiSalaryPushPageRequest request);
}
......@@ -110,7 +110,7 @@ public class Salary implements Serializable {
private String otherRemark;
/**
* 薪资单状态:1-待提交 2-待核对 3-已核对 4-退回 5-已推送
* 薪资单状态:1-待提交 2-待核对 3-已核对 4-退回 5-已推送 6-已取消
*/
@TableField("status")
private String status;
......
......@@ -3,6 +3,7 @@ package com.yd.csf.service.service;
import com.baomidou.mybatisplus.core.metadata.IPage;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.yd.csf.feign.request.salary.ApiSalaryPageRequest;
import com.yd.csf.feign.request.salary.ApiSalaryPushPageRequest;
import com.yd.csf.feign.response.salary.ApiSalaryPageResponse;
import com.yd.csf.feign.response.salary.ApiSalaryPushPageResponse;
import com.yd.csf.service.model.Salary;
......@@ -21,6 +22,9 @@ public interface ISalaryService extends IService<Salary> {
IPage<ApiSalaryPageResponse> page(Page<ApiSalaryPageResponse> page,
ApiSalaryPageRequest request);
IPage<ApiSalaryPushPageResponse> pushPage(Page<ApiSalaryPushPageResponse> page,
ApiSalaryPushPageRequest request);
Salary queryOne(String brokerBizId,String month,
String salaryBizId,Boolean isExcludeMy);
......
......@@ -4,7 +4,9 @@ import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.metadata.IPage;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.yd.csf.feign.request.salary.ApiSalaryPageRequest;
import com.yd.csf.feign.request.salary.ApiSalaryPushPageRequest;
import com.yd.csf.feign.response.salary.ApiSalaryPageResponse;
import com.yd.csf.feign.response.salary.ApiSalaryPushPageResponse;
import com.yd.csf.service.model.Salary;
import com.yd.csf.service.dao.SalaryMapper;
import com.yd.csf.service.service.ISalaryService;
......@@ -29,6 +31,12 @@ public class SalaryServiceImpl extends ServiceImpl<SalaryMapper, Salary> impleme
}
@Override
public IPage<ApiSalaryPushPageResponse> pushPage(Page<ApiSalaryPushPageResponse> page,
ApiSalaryPushPageRequest request) {
return this.baseMapper.pushPage(page,request);
}
@Override
public Salary queryOne(String brokerBizId, String month,
String salaryBizId,Boolean isExcludeMy) {
return this.baseMapper.selectOne(new LambdaQueryWrapper<Salary>()
......
......@@ -28,4 +28,30 @@
GROUP BY s.salary_biz_id
ORDER BY s.create_time DESC
</select>
<select id="pushPage" resultType="com.yd.csf.feign.response.salary.ApiSalaryPushPageResponse">
select
s.broker_name,
s.month,
s.paid_amount,
s.gross_amount,
(s.gross_amount - s.paid_amount) as totalDeductions,
s.other_remark,
s.status,
s.creator_name,
s.create_time
from salary s
<where>
<if test="request.brokerName != null and request.brokerName != ''">
AND s.broker_name LIKE CONCAT('%', #{request.brokerName}, '%')
</if>
<if test="request.month != null and request.month != ''">
AND s.month = #{request.month}
</if>
<if test="request.status != null and request.status != ''">
AND s.status = #{request.status}
</if>
AND s.is_deleted = 0
</where>
</select>
</mapper>
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