Commit 7cdf5e50 by zhangxingmin

push

parent e3b27bbd
...@@ -131,6 +131,16 @@ public class ApiSalaryController implements ApiSalaryFeignClient { ...@@ -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 * @param request
* @return * @return
......
...@@ -30,6 +30,8 @@ public interface ApiSalaryService { ...@@ -30,6 +30,8 @@ public interface ApiSalaryService {
Result delSalaryRemittance(String salaryRemittanceBizId); Result delSalaryRemittance(String salaryRemittanceBizId);
Result<BigDecimal> getExchangeRate(ApiSalaryExchangeRateRequest request);
Result<BigDecimal> calculatePaidAmount(ApiSalaryCalculatePaidAmountRequest request); Result<BigDecimal> calculatePaidAmount(ApiSalaryCalculatePaidAmountRequest request);
Result<BigDecimal> calculateTotalAmount(ApiSalaryCalculateTotalAmountRequest request); Result<BigDecimal> calculateTotalAmount(ApiSalaryCalculateTotalAmountRequest request);
......
package com.yd.csf.api.service.impl; 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.core.metadata.IPage;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page; 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.enums.CommonEnum;
import com.yd.common.exception.BusinessException; import com.yd.common.exception.BusinessException;
import com.yd.common.result.Result; import com.yd.common.result.Result;
...@@ -28,11 +30,10 @@ import org.apache.commons.lang3.ObjectUtils; ...@@ -28,11 +30,10 @@ import org.apache.commons.lang3.ObjectUtils;
import org.springframework.beans.BeanUtils; import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired; import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service; import org.springframework.stereotype.Service;
import javax.annotation.Resource;
import java.math.BigDecimal; import java.math.BigDecimal;
import java.util.ArrayList; import java.util.*;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.stream.Collectors; import java.util.stream.Collectors;
@Slf4j @Slf4j
...@@ -48,6 +49,9 @@ public class ApiSalaryServiceImpl implements ApiSalaryService { ...@@ -48,6 +49,9 @@ public class ApiSalaryServiceImpl implements ApiSalaryService {
@Autowired @Autowired
private ISalaryRemittanceService iSalaryRemittanceService; private ISalaryRemittanceService iSalaryRemittanceService;
@Autowired
private ApiExchangeRateFeignClient apiExchangeRateFeignClient;
/** /**
* 分页查询-制作薪资单列表信息 * 分页查询-制作薪资单列表信息
* @param request * @param request
...@@ -68,8 +72,8 @@ public class ApiSalaryServiceImpl implements ApiSalaryService { ...@@ -68,8 +72,8 @@ public class ApiSalaryServiceImpl implements ApiSalaryService {
@Override @Override
public Result<IPage<ApiSalaryPushPageResponse>> pushPage(ApiSalaryPushPageRequest request) { public Result<IPage<ApiSalaryPushPageResponse>> pushPage(ApiSalaryPushPageRequest request) {
Page<ApiSalaryPushPageResponse> page = new Page<>(request.getPageNo(), request.getPageSize()); Page<ApiSalaryPushPageResponse> page = new Page<>(request.getPageNo(), request.getPageSize());
// IPage<ApiSalaryPushPageResponse> iPage = iSalaryService.pushPage(page, request); IPage<ApiSalaryPushPageResponse> iPage = iSalaryService.pushPage(page, request);
return Result.success(); return Result.success(iPage);
} }
/** /**
...@@ -225,8 +229,11 @@ public class ApiSalaryServiceImpl implements ApiSalaryService { ...@@ -225,8 +229,11 @@ public class ApiSalaryServiceImpl implements ApiSalaryService {
if (CollectionUtils.isEmpty(apiSalaryBatchAddDTOList)) { if (CollectionUtils.isEmpty(apiSalaryBatchAddDTOList)) {
throw new BusinessException("批量新增的数据列表不能为空"); throw new BusinessException("批量新增的数据列表不能为空");
} }
//批量校验同一转介人同一年月只能有一条薪资单记录 TODO //批量校验同一转介人同一年月只能有一条薪资单记录
//批量校验薪资单信息金额字段信息 TODO batchCheckUniqueByBrokerMonth(apiSalaryBatchAddDTOList);
//批量校验薪资单信息金额字段信息
batchAddCheckAmount(apiSalaryBatchAddDTOList);
Map<Salary,List<SalaryRemittance>> map = new HashMap<>(); Map<Salary,List<SalaryRemittance>> map = new HashMap<>();
apiSalaryBatchAddDTOList.forEach(dto -> { apiSalaryBatchAddDTOList.forEach(dto -> {
Salary salary = new Salary(); Salary salary = new Salary();
...@@ -286,6 +293,16 @@ public class ApiSalaryServiceImpl implements ApiSalaryService { ...@@ -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 * @param request
* @return * @return
...@@ -329,10 +346,150 @@ public class ApiSalaryServiceImpl implements ApiSalaryService { ...@@ -329,10 +346,150 @@ public class ApiSalaryServiceImpl implements ApiSalaryService {
/** /**
* 批量校验同一转介人同一年月只能有一条薪资单记录 * 批量校验同一转介人同一年月只能有一条薪资单记录
* @param apiSalaryBatchAddDTOList * @param apiSalaryBatchAddDTOList 批量新增DTO列表
*/ */
public void batchCheckUniqueByBrokerMonth(List<ApiSalaryBatchAddDTO> apiSalaryBatchAddDTOList) { 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 { ...@@ -98,6 +98,14 @@ public interface ApiSalaryFeignClient {
Result delSalaryRemittance(@NotBlank(message = "薪资汇款明细表唯一业务ID不能为空") @RequestParam(value = "salaryRemittanceBizId") String salaryRemittanceBizId); 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 * @param request
* @return * @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 { ...@@ -17,7 +17,7 @@ public class ApiSalaryPushPageRequest extends PageDto {
private String month; private String month;
/** /**
* 薪资单状态:1-待审核提交 2-待审核 3-审核退回 4-待核对提交 5-待核对 6-核对退回 7-已核对 8-已推送 9-已取消 * 薪资单状态:1-待提交 2-待核对 3-已核对 4-退回 5-已推送 6-已取消
*/ */
private String status; private String status;
} }
...@@ -29,7 +29,7 @@ public class ApiSalaryPushPageResponse { ...@@ -29,7 +29,7 @@ public class ApiSalaryPushPageResponse {
private BigDecimal grossAmount; private BigDecimal grossAmount;
/** /**
* 扣款合计(单位:HKD) * 扣款合计(单位:HKD)( 扣款合计 = 应发 - 实发)
*/ */
private BigDecimal totalDeductions; private BigDecimal totalDeductions;
...@@ -39,6 +39,11 @@ public class ApiSalaryPushPageResponse { ...@@ -39,6 +39,11 @@ public class ApiSalaryPushPageResponse {
private String otherRemark; private String otherRemark;
/** /**
* 薪资单状态:1-待提交 2-待核对 3-已核对 4-退回 5-已推送 6-已取消
*/
private String status;
/**
* 制作人(创建人名称) * 制作人(创建人名称)
*/ */
private String creatorName; private String creatorName;
......
...@@ -3,7 +3,9 @@ package com.yd.csf.service.dao; ...@@ -3,7 +3,9 @@ package com.yd.csf.service.dao;
import com.baomidou.mybatisplus.core.metadata.IPage; import com.baomidou.mybatisplus.core.metadata.IPage;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page; import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.yd.csf.feign.request.salary.ApiSalaryPageRequest; 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.ApiSalaryPageResponse;
import com.yd.csf.feign.response.salary.ApiSalaryPushPageResponse;
import com.yd.csf.service.model.Salary; import com.yd.csf.service.model.Salary;
import com.baomidou.mybatisplus.core.mapper.BaseMapper; import com.baomidou.mybatisplus.core.mapper.BaseMapper;
import org.apache.ibatis.annotations.Param; import org.apache.ibatis.annotations.Param;
...@@ -20,4 +22,7 @@ public interface SalaryMapper extends BaseMapper<Salary> { ...@@ -20,4 +22,7 @@ public interface SalaryMapper extends BaseMapper<Salary> {
IPage<ApiSalaryPageResponse> page(@Param("page") Page<ApiSalaryPageResponse> page, IPage<ApiSalaryPageResponse> page(@Param("page") Page<ApiSalaryPageResponse> page,
@Param("request") ApiSalaryPageRequest request); @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 { ...@@ -110,7 +110,7 @@ public class Salary implements Serializable {
private String otherRemark; private String otherRemark;
/** /**
* 薪资单状态:1-待提交 2-待核对 3-已核对 4-退回 5-已推送 * 薪资单状态:1-待提交 2-待核对 3-已核对 4-退回 5-已推送 6-已取消
*/ */
@TableField("status") @TableField("status")
private String status; private String status;
......
...@@ -3,6 +3,7 @@ package com.yd.csf.service.service; ...@@ -3,6 +3,7 @@ package com.yd.csf.service.service;
import com.baomidou.mybatisplus.core.metadata.IPage; import com.baomidou.mybatisplus.core.metadata.IPage;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page; import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.yd.csf.feign.request.salary.ApiSalaryPageRequest; 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.ApiSalaryPageResponse;
import com.yd.csf.feign.response.salary.ApiSalaryPushPageResponse; import com.yd.csf.feign.response.salary.ApiSalaryPushPageResponse;
import com.yd.csf.service.model.Salary; import com.yd.csf.service.model.Salary;
...@@ -21,6 +22,9 @@ public interface ISalaryService extends IService<Salary> { ...@@ -21,6 +22,9 @@ public interface ISalaryService extends IService<Salary> {
IPage<ApiSalaryPageResponse> page(Page<ApiSalaryPageResponse> page, IPage<ApiSalaryPageResponse> page(Page<ApiSalaryPageResponse> page,
ApiSalaryPageRequest request); ApiSalaryPageRequest request);
IPage<ApiSalaryPushPageResponse> pushPage(Page<ApiSalaryPushPageResponse> page,
ApiSalaryPushPageRequest request);
Salary queryOne(String brokerBizId,String month, Salary queryOne(String brokerBizId,String month,
String salaryBizId,Boolean isExcludeMy); String salaryBizId,Boolean isExcludeMy);
......
...@@ -4,7 +4,9 @@ import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper; ...@@ -4,7 +4,9 @@ import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.metadata.IPage; import com.baomidou.mybatisplus.core.metadata.IPage;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page; import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.yd.csf.feign.request.salary.ApiSalaryPageRequest; 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.ApiSalaryPageResponse;
import com.yd.csf.feign.response.salary.ApiSalaryPushPageResponse;
import com.yd.csf.service.model.Salary; import com.yd.csf.service.model.Salary;
import com.yd.csf.service.dao.SalaryMapper; import com.yd.csf.service.dao.SalaryMapper;
import com.yd.csf.service.service.ISalaryService; import com.yd.csf.service.service.ISalaryService;
...@@ -29,6 +31,12 @@ public class SalaryServiceImpl extends ServiceImpl<SalaryMapper, Salary> impleme ...@@ -29,6 +31,12 @@ public class SalaryServiceImpl extends ServiceImpl<SalaryMapper, Salary> impleme
} }
@Override @Override
public IPage<ApiSalaryPushPageResponse> pushPage(Page<ApiSalaryPushPageResponse> page,
ApiSalaryPushPageRequest request) {
return this.baseMapper.pushPage(page,request);
}
@Override
public Salary queryOne(String brokerBizId, String month, public Salary queryOne(String brokerBizId, String month,
String salaryBizId,Boolean isExcludeMy) { String salaryBizId,Boolean isExcludeMy) {
return this.baseMapper.selectOne(new LambdaQueryWrapper<Salary>() return this.baseMapper.selectOne(new LambdaQueryWrapper<Salary>()
......
...@@ -28,4 +28,30 @@ ...@@ -28,4 +28,30 @@
GROUP BY s.salary_biz_id GROUP BY s.salary_biz_id
ORDER BY s.create_time DESC ORDER BY s.create_time DESC
</select> </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> </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