优惠金额分摊功能实现在OFS销售和售后订单中
实现了OFS销售和售后订单的优惠金额分摊功能。此功能通过计算每个订单明细行的分摊比例,对平台、商家、达人、支付等优惠类型进行分摊。已更新相关的DTO类以包含分摊比例和分摊金额字段,并进行了测试以确保所有场景的正确性。 Closes <ISSUE_NUMBER_OR_URL>
This commit is contained in:
parent
e913c13163
commit
66f63ec31e
|
@ -990,6 +990,8 @@ public class SoSaleOutPluginInitializerToC extends PluginBaseEntity {
|
|||
//查询对应的OFS销售订单
|
||||
List<com.hzya.frame.ttxofs.dto.ofssalesordersearch.HeaderDetailsDto> headerDetailsDtos = queryOfsOrder(headerDetailsDtoList);
|
||||
findMatchingOfsOrder(headerDetailsDtos, headerDetailsDtoList);
|
||||
//TOC金额分摊
|
||||
|
||||
|
||||
for (int i = 0; i < headerDetailsDtoList.size(); i++) {
|
||||
HeaderDetailsDto headerDetailsDto = headerDetailsDtoList.get(i);
|
||||
|
@ -1367,7 +1369,7 @@ public class SoSaleOutPluginInitializerToC extends PluginBaseEntity {
|
|||
logger.info("{}个明细行发生了合并!", sonDetailsDtoList.size());
|
||||
return sonDetailsDto;
|
||||
} else {
|
||||
logger.info("sonDetailsDtoList集合是空的!");
|
||||
logger.error("sonDetailsDtoList集合是空的!");
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
|
|
@ -0,0 +1,256 @@
|
|||
package com.hzya.frame.plugin.lets.util;
|
||||
|
||||
import cn.hutool.core.lang.Assert;
|
||||
import com.hzya.frame.beanutil.BeanUtil;
|
||||
import com.hzya.frame.ttxofs.dto.ofssalesordersearch.DetailsDto;
|
||||
import com.hzya.frame.ttxofs.dto.ofssalesordersearch.HeaderDto;
|
||||
import com.hzya.frame.ttxofs.dto.returngoodordersearch.RerturnGoodsOrderSearchData;
|
||||
import com.hzya.frame.ttxofs.dto.returngoodordersearch.RerturnGoodsOrderSearchDetails;
|
||||
import com.hzya.frame.ttxofs.dto.returngoodordersearch.RerturnGoodsOrderSearchHeader;
|
||||
import org.slf4j.Logger;
|
||||
import org.slf4j.LoggerFactory;
|
||||
import org.springframework.stereotype.Component;
|
||||
|
||||
import java.math.BigDecimal;
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
|
||||
/**
|
||||
* 处理OFS售后订单,优惠金额分摊逻辑
|
||||
*
|
||||
* @Author:liuyang
|
||||
* @Package:com.hzya.frame.plugin.lets.util
|
||||
* @Project:kangarooDataCenterV3
|
||||
* @name:AmountAllocationUtil
|
||||
* @Date:2024/9/21 18:19
|
||||
* @Filename:AmountAllocationUtil
|
||||
*/
|
||||
@Component
|
||||
public class OfsOrderAfterSalesAmountAllocationUtil {
|
||||
|
||||
Logger logger = LoggerFactory.getLogger(OfsOrderAfterSalesAmountAllocationUtil.class);
|
||||
|
||||
/**
|
||||
* TOC销售金额分摊
|
||||
*
|
||||
* @param rerturnGoodsOrderSearchData OFS售后订单
|
||||
* @author liuyang
|
||||
*/
|
||||
public void tocSalesAmountAllocation(RerturnGoodsOrderSearchData rerturnGoodsOrderSearchData) throws Exception {
|
||||
logger.info("==TOC退货金额分摊开始==");
|
||||
|
||||
Assert.notNull(rerturnGoodsOrderSearchData, "OFS售后订单对象不能为空");
|
||||
RerturnGoodsOrderSearchHeader header = rerturnGoodsOrderSearchData.getHeader();
|
||||
List<RerturnGoodsOrderSearchDetails> detailsOld = rerturnGoodsOrderSearchData.getDetails();
|
||||
|
||||
//拷贝一份List集合,并移除没有实付金额的原始
|
||||
//TODO 暂时取零售价作为分类的标准,需要和万万确认一下
|
||||
List<RerturnGoodsOrderSearchDetails> rerturnGoodsOrderSearchDetails = copyDetailsDto(detailsOld);
|
||||
rerturnGoodsOrderSearchDetails.removeIf(dto -> dto.getMsrPrice() == null || !"0".equals(new BigDecimal(dto.getMsrPrice()).stripTrailingZeros().toPlainString()));
|
||||
|
||||
//计算分摊百分比
|
||||
calculatePercentage(rerturnGoodsOrderSearchData);
|
||||
|
||||
String platformDiscounts = header.getPlatformDiscounts();
|
||||
String merchantDiscounts = header.getMerchantDiscounts();
|
||||
String expertDiscounts = header.getExpertDiscounts();
|
||||
String payDiscounts = header.getPayDiscounts();
|
||||
|
||||
BigDecimal targetPlatformDiscounts = null;
|
||||
BigDecimal targetMerchantDiscounts = null;
|
||||
BigDecimal targetExpertDiscounts = null;
|
||||
BigDecimal targetPayDiscounts = null;
|
||||
|
||||
//这4个优惠字段,可能没有,也有可能为0!
|
||||
if (platformDiscounts != null && !"".equals(platformDiscounts) && !"0".equals(new BigDecimal(platformDiscounts).stripTrailingZeros().toPlainString())) {
|
||||
targetPlatformDiscounts = new BigDecimal(platformDiscounts);
|
||||
}
|
||||
if (merchantDiscounts != null && !"".equals(merchantDiscounts) && !"0".equals(new BigDecimal(merchantDiscounts).stripTrailingZeros().toPlainString())) {
|
||||
targetMerchantDiscounts = new BigDecimal(merchantDiscounts);
|
||||
}
|
||||
if (expertDiscounts != null && !"".equals(expertDiscounts) && !"0".equals(new BigDecimal(expertDiscounts).stripTrailingZeros().toPlainString())) {
|
||||
targetExpertDiscounts = new BigDecimal(expertDiscounts);
|
||||
}
|
||||
if (payDiscounts != null && !"".equals(payDiscounts) && !"0".equals(new BigDecimal(payDiscounts).stripTrailingZeros().toPlainString())) {
|
||||
targetPayDiscounts = new BigDecimal(payDiscounts);
|
||||
}
|
||||
|
||||
/**
|
||||
* OFS销售订单明细行,没有分摊金额的几种情况:
|
||||
* 1.对应的OFS销售订单表头某个优惠字段为空或为0
|
||||
* 2.明细行没有实付金额或者为0,所以没有分摊比例,不参与分摊
|
||||
*/
|
||||
BigDecimal totalShareTargetPlatformDiscounts = new BigDecimal("0");
|
||||
BigDecimal totalShareTargetMerchantDiscounts = new BigDecimal("0");
|
||||
BigDecimal totalShareTargetExpertDiscounts = new BigDecimal("0");
|
||||
BigDecimal totalShareTargetPayDiscounts = new BigDecimal("0");
|
||||
|
||||
//分摊金额=分摊比例*优惠金额
|
||||
for (int i = 0; i < rerturnGoodsOrderSearchDetails.size(); i++) {
|
||||
RerturnGoodsOrderSearchDetails rerturnGoodsOrderSearchDetails1 = rerturnGoodsOrderSearchDetails.get(i);
|
||||
//分摊比例
|
||||
BigDecimal sharingRatio = rerturnGoodsOrderSearchDetails1.getSharingRatio();
|
||||
|
||||
//这里应该先8为小数,实际汇总到出库单时,再四舍五入两位小数
|
||||
BigDecimal shareTargetPlatformDiscounts = null;
|
||||
BigDecimal shareTargetMerchantDiscounts = null;
|
||||
BigDecimal shareTargetExpertDiscounts = null;
|
||||
BigDecimal shareTargetPayDiscounts = null;
|
||||
if (sharingRatio != null && targetPlatformDiscounts != null) {
|
||||
shareTargetPlatformDiscounts = targetPlatformDiscounts.multiply(sharingRatio).setScale(8, BigDecimal.ROUND_HALF_UP);
|
||||
rerturnGoodsOrderSearchDetails1.setOriginalTargetPlatformDiscounts(targetPlatformDiscounts);
|
||||
rerturnGoodsOrderSearchDetails1.setShareTargetPlatformDiscounts(shareTargetPlatformDiscounts);
|
||||
|
||||
totalShareTargetPlatformDiscounts = totalShareTargetPlatformDiscounts.add(shareTargetPlatformDiscounts);
|
||||
}
|
||||
if (sharingRatio != null && targetMerchantDiscounts != null) {
|
||||
shareTargetMerchantDiscounts = targetMerchantDiscounts.multiply(sharingRatio).setScale(8, BigDecimal.ROUND_HALF_UP);
|
||||
rerturnGoodsOrderSearchDetails1.setOriginalTargetMerchantDiscounts(targetMerchantDiscounts);
|
||||
rerturnGoodsOrderSearchDetails1.setShareTargetMerchantDiscounts(shareTargetMerchantDiscounts);
|
||||
|
||||
totalShareTargetMerchantDiscounts = totalShareTargetPlatformDiscounts.add(shareTargetMerchantDiscounts);
|
||||
}
|
||||
if (sharingRatio != null && targetExpertDiscounts != null) {
|
||||
shareTargetExpertDiscounts = targetExpertDiscounts.multiply(sharingRatio).setScale(8, BigDecimal.ROUND_HALF_UP);
|
||||
rerturnGoodsOrderSearchDetails1.setOriginalTargetExpertDiscounts(targetExpertDiscounts);
|
||||
rerturnGoodsOrderSearchDetails1.setShareTargetExpertDiscounts(shareTargetExpertDiscounts);
|
||||
|
||||
totalShareTargetExpertDiscounts = totalShareTargetPlatformDiscounts.add(shareTargetExpertDiscounts);
|
||||
}
|
||||
if (sharingRatio != null && targetPayDiscounts != null) {
|
||||
shareTargetPayDiscounts = targetPayDiscounts.multiply(sharingRatio).setScale(8, BigDecimal.ROUND_HALF_UP);
|
||||
rerturnGoodsOrderSearchDetails1.setOriginalTargetPayDiscounts(targetPayDiscounts);
|
||||
rerturnGoodsOrderSearchDetails1.setShareTargetPayDiscounts(shareTargetPayDiscounts);
|
||||
|
||||
totalShareTargetPayDiscounts = totalShareTargetPlatformDiscounts.add(shareTargetPayDiscounts);
|
||||
}
|
||||
|
||||
//如果是最后一行,则把尾差进行追加
|
||||
if (i == rerturnGoodsOrderSearchDetails.size() - 1) {
|
||||
if (!"0".equals(totalShareTargetPlatformDiscounts.stripTrailingZeros().toPlainString()) && rerturnGoodsOrderSearchDetails1.getShareTargetPlatformDiscounts() != null) {
|
||||
//原始优惠金额-sum(分摊金额)
|
||||
BigDecimal subtract = targetPlatformDiscounts.subtract(totalShareTargetPlatformDiscounts);
|
||||
BigDecimal shareTargetPlatformDiscounts1 = rerturnGoodsOrderSearchDetails1.getShareTargetPlatformDiscounts();
|
||||
rerturnGoodsOrderSearchDetails1.setShareTargetPlatformDiscounts(shareTargetPlatformDiscounts1.add(subtract));
|
||||
}
|
||||
if (!"0".equals(totalShareTargetMerchantDiscounts.stripTrailingZeros().toPlainString()) && rerturnGoodsOrderSearchDetails1.getShareTargetMerchantDiscounts() != null) {
|
||||
//原始优惠金额-sum(分摊金额)
|
||||
BigDecimal subtract = targetMerchantDiscounts.subtract(totalShareTargetMerchantDiscounts);
|
||||
BigDecimal shareTargetPlatformDiscounts1 = rerturnGoodsOrderSearchDetails1.getShareTargetPlatformDiscounts();
|
||||
rerturnGoodsOrderSearchDetails1.setShareTargetPlatformDiscounts(shareTargetPlatformDiscounts1.add(subtract));
|
||||
}
|
||||
if (!"0".equals(totalShareTargetExpertDiscounts.stripTrailingZeros().toPlainString()) && rerturnGoodsOrderSearchDetails1.getShareTargetExpertDiscounts() != null) {
|
||||
BigDecimal subtract = targetExpertDiscounts.subtract(totalShareTargetExpertDiscounts);
|
||||
BigDecimal shareTargetExpertDiscounts1 = rerturnGoodsOrderSearchDetails1.getShareTargetExpertDiscounts();
|
||||
rerturnGoodsOrderSearchDetails1.setShareTargetExpertDiscounts(shareTargetExpertDiscounts1.add(subtract));
|
||||
}
|
||||
if (!"0".equals(totalShareTargetPayDiscounts.stripTrailingZeros().toPlainString()) && rerturnGoodsOrderSearchDetails1.getShareTargetPayDiscounts() != null) {
|
||||
BigDecimal subtract = targetPayDiscounts.subtract(totalShareTargetPayDiscounts);
|
||||
BigDecimal shareTargetPayDiscounts1 = rerturnGoodsOrderSearchDetails1.getShareTargetPayDiscounts();
|
||||
rerturnGoodsOrderSearchDetails1.setShareTargetPayDiscounts(shareTargetPayDiscounts1.add(subtract));
|
||||
}
|
||||
}
|
||||
|
||||
//拷贝回到原始的集合
|
||||
copyDetailsDtoOld(rerturnGoodsOrderSearchDetails, detailsOld);
|
||||
}
|
||||
logger.info("==TOC退货金额分摊结束==");
|
||||
}
|
||||
|
||||
/**
|
||||
* 计算百分比
|
||||
* 分摊比例=零售价/sum(零售价)
|
||||
*
|
||||
* @param rerturnGoodsOrderSearchData OFS售后订单
|
||||
* @author liuyang
|
||||
*/
|
||||
private void calculatePercentage(RerturnGoodsOrderSearchData rerturnGoodsOrderSearchData) throws Exception {
|
||||
Assert.notNull(rerturnGoodsOrderSearchData, "headerDetailsDto2不能为空");
|
||||
RerturnGoodsOrderSearchHeader header = rerturnGoodsOrderSearchData.getHeader();
|
||||
List<RerturnGoodsOrderSearchDetails> details = rerturnGoodsOrderSearchData.getDetails();
|
||||
|
||||
BigDecimal sumActualPaymentAmountBigDecimal = sumActualPaymentAmount(details, header.getCode());
|
||||
for (int i = 0; i < details.size(); i++) {
|
||||
RerturnGoodsOrderSearchDetails rerturnGoodsOrderSearchDetails = details.get(i);
|
||||
|
||||
String msrPrice = rerturnGoodsOrderSearchDetails.getMsrPrice();
|
||||
BigDecimal msrPriceBigDecimal = new BigDecimal(msrPrice);
|
||||
//如果实付金额为0则不进行分摊!
|
||||
if (!"0".equals(msrPriceBigDecimal.stripTrailingZeros().toPlainString())) {
|
||||
//得到分摊比例
|
||||
BigDecimal percentageBigDecimal = msrPriceBigDecimal.divide(sumActualPaymentAmountBigDecimal, 20, BigDecimal.ROUND_HALF_UP).setScale(8, BigDecimal.ROUND_HALF_UP);
|
||||
rerturnGoodsOrderSearchDetails.setSharingRatio(percentageBigDecimal);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* 累计这一单对应的实付金额
|
||||
*
|
||||
* @param details OFS销售订单明细行
|
||||
* @param code OFS售后订单号
|
||||
* @author liuyang
|
||||
*/
|
||||
private BigDecimal sumActualPaymentAmount(List<RerturnGoodsOrderSearchDetails> details, String code) throws Exception {
|
||||
Assert.notNull(details, "details1不能为空");
|
||||
Assert.notNull(code, "code不能为空");
|
||||
|
||||
BigDecimal actualPaymentAmountBigDecimal = new BigDecimal("0");
|
||||
for (int i = 0; i < details.size(); i++) {
|
||||
RerturnGoodsOrderSearchDetails rerturnGoodsOrderSearchDetails = details.get(i);
|
||||
|
||||
String msrPrice = rerturnGoodsOrderSearchDetails.getMsrPrice();
|
||||
if (msrPrice == null || "".equals(msrPrice.trim())) {
|
||||
Assert.state(false, "售后订单零售价不能为空 OFS售后订单号:{}", code);
|
||||
}
|
||||
BigDecimal msrPriceBigDecimal = new BigDecimal(msrPrice);
|
||||
actualPaymentAmountBigDecimal = actualPaymentAmountBigDecimal.add(msrPriceBigDecimal);
|
||||
}
|
||||
if ("0".equals(actualPaymentAmountBigDecimal.stripTrailingZeros().toPlainString())) {
|
||||
Assert.state(false, "售后订单零售价(合并后)不能为0 OFS售后订单号:{}", code);
|
||||
}
|
||||
return actualPaymentAmountBigDecimal;
|
||||
}
|
||||
|
||||
/**
|
||||
* 集合复制
|
||||
*
|
||||
* @param details 旧OFS售后订单明细行
|
||||
* @author liuyang
|
||||
*/
|
||||
private List<RerturnGoodsOrderSearchDetails> copyDetailsDto(List<RerturnGoodsOrderSearchDetails> details) throws Exception {
|
||||
List<RerturnGoodsOrderSearchDetails> newDetails = new ArrayList<>();
|
||||
for (int i = 0; i < details.size(); i++) {
|
||||
RerturnGoodsOrderSearchDetails rerturnGoodsOrderSearchDetails = details.get(i);
|
||||
|
||||
RerturnGoodsOrderSearchDetails newDetailsDto1 = new RerturnGoodsOrderSearchDetails();
|
||||
BeanUtil.copyPropertiesV2(rerturnGoodsOrderSearchDetails, newDetailsDto1);
|
||||
newDetails.add(newDetailsDto1);
|
||||
}
|
||||
return newDetails;
|
||||
}
|
||||
|
||||
/**
|
||||
* 拷贝到原集合中
|
||||
*
|
||||
* @param newDetails 新OFS销售订单明细行
|
||||
* @param detailsOld 旧OFS销售订单明细行
|
||||
* @author liuyang
|
||||
*/
|
||||
private void copyDetailsDtoOld(List<RerturnGoodsOrderSearchDetails> newDetails, List<RerturnGoodsOrderSearchDetails> detailsOld) throws Exception {
|
||||
if (newDetails != null && detailsOld != null) {
|
||||
for (int i = 0; i < detailsOld.size(); i++) {
|
||||
RerturnGoodsOrderSearchDetails rerturnGoodsOrderSearchDetails = detailsOld.get(i);
|
||||
for (int j = 0; j < newDetails.size(); j++) {
|
||||
RerturnGoodsOrderSearchDetails rerturnGoodsOrderSearchDetails1 = newDetails.get(j);
|
||||
if (rerturnGoodsOrderSearchDetails.getId().equals(rerturnGoodsOrderSearchDetails1.getId())) {
|
||||
//把分摊后的金额拷贝到旧的OFS销售订单集合中
|
||||
BeanUtil.copyPropertiesV2(rerturnGoodsOrderSearchDetails1, rerturnGoodsOrderSearchDetails);
|
||||
}
|
||||
}
|
||||
}
|
||||
} else {
|
||||
logger.error("copyDetailsDtoOld方法newDetails或者detailsOld为空!");
|
||||
}
|
||||
}
|
||||
}
|
|
@ -0,0 +1,252 @@
|
|||
package com.hzya.frame.plugin.lets.util;
|
||||
|
||||
import cn.hutool.core.lang.Assert;
|
||||
import com.hzya.frame.beanutil.BeanUtil;
|
||||
import com.hzya.frame.ttxofs.dto.ofssalesordersearch.DetailsDto;
|
||||
import com.hzya.frame.ttxofs.dto.ofssalesordersearch.HeaderDto;
|
||||
import org.slf4j.Logger;
|
||||
import org.slf4j.LoggerFactory;
|
||||
import org.springframework.stereotype.Component;
|
||||
|
||||
import java.math.BigDecimal;
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
|
||||
/**
|
||||
* 处理OFS销售订单,优惠金额分摊逻辑
|
||||
*
|
||||
* @Author:liuyang
|
||||
* @Package:com.hzya.frame.plugin.lets.util
|
||||
* @Project:kangarooDataCenterV3
|
||||
* @name:AmountAllocationUtil
|
||||
* @Date:2024/9/21 18:19
|
||||
* @Filename:AmountAllocationUtil
|
||||
*/
|
||||
@Component
|
||||
public class OfsOrderSaleAmountAllocationUtil {
|
||||
|
||||
Logger logger = LoggerFactory.getLogger(OfsOrderSaleAmountAllocationUtil.class);
|
||||
|
||||
/**
|
||||
* TOC销售金额分摊
|
||||
*
|
||||
* @param headerDetailsDto OFS销售订单对象
|
||||
* @author liuyang
|
||||
*/
|
||||
public void tocSalesAmountAllocation(com.hzya.frame.ttxofs.dto.ofssalesordersearch.HeaderDetailsDto headerDetailsDto) throws Exception {
|
||||
logger.info("==TOC销售金额分摊开始==");
|
||||
|
||||
Assert.notNull(headerDetailsDto, "OFS销售订单对象不能为空");
|
||||
HeaderDto header = headerDetailsDto.getHeader();
|
||||
List<DetailsDto> detailsOld = headerDetailsDto.getDetails();
|
||||
|
||||
//拷贝一份List集合,并移除没有实付金额的原始
|
||||
List<DetailsDto> details = copyDetailsDto(detailsOld);
|
||||
details.removeIf(dto -> dto.getTotalPayAmount() == null || !"0".equals(new BigDecimal(dto.getTotalPayAmount()).stripTrailingZeros().toPlainString()));
|
||||
|
||||
//计算分摊百分比
|
||||
calculatePercentage(headerDetailsDto);
|
||||
|
||||
String platformDiscounts = header.getPlatformDiscounts();
|
||||
String merchantDiscounts = header.getMerchantDiscounts();
|
||||
String expertDiscounts = header.getExpertDiscounts();
|
||||
String payDiscounts = header.getPayDiscounts();
|
||||
|
||||
BigDecimal targetPlatformDiscounts = null;
|
||||
BigDecimal targetMerchantDiscounts = null;
|
||||
BigDecimal targetExpertDiscounts = null;
|
||||
BigDecimal targetPayDiscounts = null;
|
||||
|
||||
//这4个优惠字段,可能没有,也有可能为0!
|
||||
if (platformDiscounts != null && !"".equals(platformDiscounts) && !"0".equals(new BigDecimal(platformDiscounts).stripTrailingZeros().toPlainString())) {
|
||||
targetPlatformDiscounts = new BigDecimal(platformDiscounts);
|
||||
}
|
||||
if (merchantDiscounts != null && !"".equals(merchantDiscounts) && !"0".equals(new BigDecimal(merchantDiscounts).stripTrailingZeros().toPlainString())) {
|
||||
targetMerchantDiscounts = new BigDecimal(merchantDiscounts);
|
||||
}
|
||||
if (expertDiscounts != null && !"".equals(expertDiscounts) && !"0".equals(new BigDecimal(expertDiscounts).stripTrailingZeros().toPlainString())) {
|
||||
targetExpertDiscounts = new BigDecimal(expertDiscounts);
|
||||
}
|
||||
if (payDiscounts != null && !"".equals(payDiscounts) && !"0".equals(new BigDecimal(payDiscounts).stripTrailingZeros().toPlainString())) {
|
||||
targetPayDiscounts = new BigDecimal(payDiscounts);
|
||||
}
|
||||
|
||||
/**
|
||||
* OFS销售订单明细行,没有分摊金额的几种情况:
|
||||
* 1.对应的OFS销售订单表头某个优惠字段为空或为0
|
||||
* 2.明细行没有实付金额或者为0,所以没有分摊比例,不参与分摊
|
||||
*/
|
||||
BigDecimal totalShareTargetPlatformDiscounts = new BigDecimal("0");
|
||||
BigDecimal totalShareTargetMerchantDiscounts = new BigDecimal("0");
|
||||
BigDecimal totalShareTargetExpertDiscounts = new BigDecimal("0");
|
||||
BigDecimal totalShareTargetPayDiscounts = new BigDecimal("0");
|
||||
|
||||
//分摊金额=分摊比例*优惠金额
|
||||
for (int i = 0; i < details.size(); i++) {
|
||||
DetailsDto detailsDto = details.get(i);
|
||||
//分摊比例
|
||||
BigDecimal sharingRatio = detailsDto.getSharingRatio();
|
||||
|
||||
//这里应该先8为小数,实际汇总到出库单时,再四舍五入两位小数
|
||||
BigDecimal shareTargetPlatformDiscounts = null;
|
||||
BigDecimal shareTargetMerchantDiscounts = null;
|
||||
BigDecimal shareTargetExpertDiscounts = null;
|
||||
BigDecimal shareTargetPayDiscounts = null;
|
||||
if (sharingRatio != null && targetPlatformDiscounts != null) {
|
||||
shareTargetPlatformDiscounts = targetPlatformDiscounts.multiply(sharingRatio).setScale(8, BigDecimal.ROUND_HALF_UP);
|
||||
detailsDto.setOriginalTargetPlatformDiscounts(targetPlatformDiscounts);
|
||||
detailsDto.setShareTargetPlatformDiscounts(shareTargetPlatformDiscounts);
|
||||
|
||||
totalShareTargetPlatformDiscounts = totalShareTargetPlatformDiscounts.add(shareTargetPlatformDiscounts);
|
||||
}
|
||||
if (sharingRatio != null && targetMerchantDiscounts != null) {
|
||||
shareTargetMerchantDiscounts = targetMerchantDiscounts.multiply(sharingRatio).setScale(8, BigDecimal.ROUND_HALF_UP);
|
||||
detailsDto.setOriginalTargetMerchantDiscounts(targetMerchantDiscounts);
|
||||
detailsDto.setShareTargetMerchantDiscounts(shareTargetMerchantDiscounts);
|
||||
|
||||
totalShareTargetMerchantDiscounts = totalShareTargetPlatformDiscounts.add(shareTargetMerchantDiscounts);
|
||||
}
|
||||
if (sharingRatio != null && targetExpertDiscounts != null) {
|
||||
shareTargetExpertDiscounts = targetExpertDiscounts.multiply(sharingRatio).setScale(8, BigDecimal.ROUND_HALF_UP);
|
||||
detailsDto.setOriginalTargetExpertDiscounts(targetExpertDiscounts);
|
||||
detailsDto.setShareTargetExpertDiscounts(shareTargetExpertDiscounts);
|
||||
|
||||
totalShareTargetExpertDiscounts = totalShareTargetPlatformDiscounts.add(shareTargetExpertDiscounts);
|
||||
}
|
||||
if (sharingRatio != null && targetPayDiscounts != null) {
|
||||
shareTargetPayDiscounts = targetPayDiscounts.multiply(sharingRatio).setScale(8, BigDecimal.ROUND_HALF_UP);
|
||||
detailsDto.setOriginalTargetPayDiscounts(targetPayDiscounts);
|
||||
detailsDto.setShareTargetPayDiscounts(shareTargetPayDiscounts);
|
||||
|
||||
totalShareTargetPayDiscounts = totalShareTargetPlatformDiscounts.add(shareTargetPayDiscounts);
|
||||
}
|
||||
|
||||
//如果是最后一行,则把尾差进行追加
|
||||
if (i == details.size() - 1) {
|
||||
if (!"0".equals(totalShareTargetPlatformDiscounts.stripTrailingZeros().toPlainString()) && detailsDto.getShareTargetPlatformDiscounts() != null) {
|
||||
//原始优惠金额-sum(分摊金额)
|
||||
BigDecimal subtract = targetPlatformDiscounts.subtract(totalShareTargetPlatformDiscounts);
|
||||
BigDecimal shareTargetPlatformDiscounts1 = detailsDto.getShareTargetPlatformDiscounts();
|
||||
detailsDto.setShareTargetPlatformDiscounts(shareTargetPlatformDiscounts1.add(subtract));
|
||||
}
|
||||
if (!"0".equals(totalShareTargetMerchantDiscounts.stripTrailingZeros().toPlainString()) && detailsDto.getShareTargetMerchantDiscounts() != null) {
|
||||
//原始优惠金额-sum(分摊金额)
|
||||
BigDecimal subtract = targetMerchantDiscounts.subtract(totalShareTargetMerchantDiscounts);
|
||||
BigDecimal shareTargetPlatformDiscounts1 = detailsDto.getShareTargetPlatformDiscounts();
|
||||
detailsDto.setShareTargetPlatformDiscounts(shareTargetPlatformDiscounts1.add(subtract));
|
||||
}
|
||||
if (!"0".equals(totalShareTargetExpertDiscounts.stripTrailingZeros().toPlainString()) && detailsDto.getShareTargetExpertDiscounts() != null) {
|
||||
BigDecimal subtract = targetExpertDiscounts.subtract(totalShareTargetExpertDiscounts);
|
||||
BigDecimal shareTargetExpertDiscounts1 = detailsDto.getShareTargetExpertDiscounts();
|
||||
detailsDto.setShareTargetExpertDiscounts(shareTargetExpertDiscounts1.add(subtract));
|
||||
}
|
||||
if (!"0".equals(totalShareTargetPayDiscounts.stripTrailingZeros().toPlainString()) && detailsDto.getShareTargetPayDiscounts() != null) {
|
||||
BigDecimal subtract = targetPayDiscounts.subtract(totalShareTargetPayDiscounts);
|
||||
BigDecimal shareTargetPayDiscounts1 = detailsDto.getShareTargetPayDiscounts();
|
||||
detailsDto.setShareTargetPayDiscounts(shareTargetPayDiscounts1.add(subtract));
|
||||
}
|
||||
}
|
||||
|
||||
//拷贝回到原始的集合
|
||||
copyDetailsDtoOld(details, detailsOld);
|
||||
}
|
||||
logger.info("==TOC销售金额分摊结束==");
|
||||
}
|
||||
|
||||
/**
|
||||
* 计算百分比
|
||||
* 分摊比例=实付金额/sum(实付金额)
|
||||
*
|
||||
* @param headerDetailsDto2 OFS销售订单
|
||||
* @author liuyang
|
||||
*/
|
||||
private void calculatePercentage(com.hzya.frame.ttxofs.dto.ofssalesordersearch.HeaderDetailsDto headerDetailsDto2) throws Exception {
|
||||
Assert.notNull(headerDetailsDto2, "headerDetailsDto2不能为空");
|
||||
HeaderDto header1 = headerDetailsDto2.getHeader();
|
||||
List<DetailsDto> details1 = headerDetailsDto2.getDetails();
|
||||
|
||||
BigDecimal sumActualPaymentAmountBigDecimal = sumActualPaymentAmount(details1, header1.getCode());
|
||||
for (int i = 0; i < details1.size(); i++) {
|
||||
DetailsDto detailsDto = details1.get(i);
|
||||
|
||||
String totalPayAmount = detailsDto.getTotalPayAmount();
|
||||
BigDecimal totalPayAmountBigDecimal = new BigDecimal(totalPayAmount);
|
||||
//如果实付金额为0则不进行分摊!
|
||||
if (!"0".equals(totalPayAmountBigDecimal.stripTrailingZeros().toPlainString())) {
|
||||
//得到分摊比例
|
||||
BigDecimal percentageBigDecimal = totalPayAmountBigDecimal.divide(sumActualPaymentAmountBigDecimal, 20, BigDecimal.ROUND_HALF_UP).setScale(8, BigDecimal.ROUND_HALF_UP);
|
||||
detailsDto.setSharingRatio(percentageBigDecimal);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* 累计这一单对应的实付金额
|
||||
*
|
||||
* @param details1 OFS销售订单明细行
|
||||
* @param code OFS销售订单号
|
||||
* @author liuyang
|
||||
*/
|
||||
private BigDecimal sumActualPaymentAmount(List<DetailsDto> details1, String code) throws Exception {
|
||||
Assert.notNull(details1, "details1不能为空");
|
||||
Assert.notNull(code, "code不能为空");
|
||||
|
||||
BigDecimal actualPaymentAmountBigDecimal = new BigDecimal("0");
|
||||
for (int i = 0; i < details1.size(); i++) {
|
||||
DetailsDto detailsDto = details1.get(i);
|
||||
|
||||
String totalPayAmount = detailsDto.getTotalPayAmount();
|
||||
if (totalPayAmount == null || "".equals(totalPayAmount.trim())) {
|
||||
Assert.state(false, "销售订单收付金额不能为空 OFS销售订单号:{}", code);
|
||||
}
|
||||
BigDecimal totalPayAmountBigDecimal = new BigDecimal(totalPayAmount);
|
||||
actualPaymentAmountBigDecimal = actualPaymentAmountBigDecimal.add(totalPayAmountBigDecimal);
|
||||
}
|
||||
if ("0".equals(actualPaymentAmountBigDecimal.stripTrailingZeros().toPlainString())) {
|
||||
Assert.state(false, "销售订单收付金额(合并后)不能为0 OFS销售订单号:{}", code);
|
||||
}
|
||||
return actualPaymentAmountBigDecimal;
|
||||
}
|
||||
|
||||
/**
|
||||
* 集合复制
|
||||
*
|
||||
* @param details 旧OFS销售订单明细行
|
||||
* @author liuyang
|
||||
*/
|
||||
private List<DetailsDto> copyDetailsDto(List<DetailsDto> details) throws Exception {
|
||||
List<DetailsDto> newDetails = new ArrayList<>();
|
||||
for (int i = 0; i < details.size(); i++) {
|
||||
DetailsDto detailsDto = details.get(i);
|
||||
|
||||
DetailsDto newDetailsDto1 = new DetailsDto();
|
||||
BeanUtil.copyPropertiesV2(detailsDto, newDetailsDto1);
|
||||
newDetails.add(newDetailsDto1);
|
||||
}
|
||||
return newDetails;
|
||||
}
|
||||
|
||||
/**
|
||||
* 拷贝到原集合中
|
||||
*
|
||||
* @param newDetails 新OFS销售订单明细行
|
||||
* @param detailsOld 旧OFS销售订单明细行
|
||||
* @author liuyang
|
||||
*/
|
||||
private void copyDetailsDtoOld(List<DetailsDto> newDetails, List<DetailsDto> detailsOld) throws Exception {
|
||||
if (newDetails != null && detailsOld != null) {
|
||||
for (int i = 0; i < detailsOld.size(); i++) {
|
||||
DetailsDto detailsDto = detailsOld.get(i);
|
||||
for (int j = 0; j < newDetails.size(); j++) {
|
||||
DetailsDto detailsDto1 = newDetails.get(j);
|
||||
if (detailsDto.getId().equals(detailsDto1.getId())) {
|
||||
//把分摊后的金额拷贝到旧的OFS销售订单集合中
|
||||
BeanUtil.copyPropertiesV2(detailsDto1, detailsDto);
|
||||
}
|
||||
}
|
||||
}
|
||||
} else {
|
||||
logger.error("copyDetailsDtoOld方法newDetails或者detailsOld为空!");
|
||||
}
|
||||
}
|
||||
}
|
|
@ -0,0 +1,72 @@
|
|||
package com.hzya.frame.plugin.lets.util;
|
||||
|
||||
import com.hzya.frame.WebappApplication;
|
||||
import com.hzya.frame.plugin.lets.ofsvo.QueryOfsSoSaleOutVo;
|
||||
import com.hzya.frame.ttxofs.dto.ofssalesordersearch.DetailsDto;
|
||||
import com.hzya.frame.ttxofs.dto.ofssalesordersearch.HeaderDetailsDto;
|
||||
import com.hzya.frame.ttxofs.dto.ofssalesordersearch.HeaderDto;
|
||||
import org.junit.Test;
|
||||
import org.junit.runner.RunWith;
|
||||
import org.slf4j.Logger;
|
||||
import org.slf4j.LoggerFactory;
|
||||
import org.springframework.beans.factory.annotation.Autowired;
|
||||
import org.springframework.boot.test.context.SpringBootTest;
|
||||
import org.springframework.test.context.junit4.SpringRunner;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
|
||||
import static org.junit.Assert.*;
|
||||
|
||||
/**
|
||||
* @Author:liuyang
|
||||
* @Package:com.hzya.frame.plugin.lets.util
|
||||
* @Project:kangarooDataCenterV3
|
||||
* @name:AmountAllocationUtilTest
|
||||
* @Date:2024/9/22 14:36
|
||||
* @Filename:AmountAllocationUtilTest
|
||||
*/
|
||||
@RunWith(SpringRunner.class)
|
||||
@SpringBootTest(classes = WebappApplication.class)
|
||||
public class AmountAllocationUtilTest {
|
||||
|
||||
Logger logger = LoggerFactory.getLogger(AmountAllocationUtilTest.class);
|
||||
|
||||
@Autowired
|
||||
private OfsOrderSaleAmountAllocationUtil ofsOrderSaleAmountAllocationUtil;
|
||||
|
||||
@Autowired
|
||||
private OfsStandardUtil ofsStandardUtil;
|
||||
|
||||
@Test
|
||||
public void tocSalesAmountAllocation() {
|
||||
try {
|
||||
List<HeaderDetailsDto> headerDetailsDtoArrayList = new ArrayList<>();
|
||||
QueryOfsSoSaleOutVo queryOfsSoSaleOutVo = new QueryOfsSoSaleOutVo();
|
||||
queryOfsSoSaleOutVo.setCode("LETS-SO2024041700000003");
|
||||
ofsStandardUtil.getOfsSaleOrder(queryOfsSoSaleOutVo, headerDetailsDtoArrayList, 1L);
|
||||
|
||||
if (headerDetailsDtoArrayList.size() > 0) {
|
||||
//情况一:所有优惠金额都没有问题
|
||||
HeaderDto header = headerDetailsDtoArrayList.get(0).getHeader();
|
||||
header.setPlatformDiscounts("3");
|
||||
header.setMerchantDiscounts("3");
|
||||
header.setExpertDiscounts("3");
|
||||
header.setPayDiscounts("1");
|
||||
|
||||
ofsOrderSaleAmountAllocationUtil.tocSalesAmountAllocation(headerDetailsDtoArrayList.get(0));
|
||||
}
|
||||
|
||||
HeaderDetailsDto headerDetailsDto = headerDetailsDtoArrayList.get(0);
|
||||
List<DetailsDto> details = headerDetailsDto.getDetails();
|
||||
for (int i = 0; i < details.size(); i++) {
|
||||
DetailsDto detailsDto = details.get(i);
|
||||
|
||||
logger.info("分摊平台优惠:{} 分摊商家优惠:{} 分摊达人优惠:{} 分摊支付优惠:{}", detailsDto.getShareTargetPlatformDiscounts(), detailsDto.getShareTargetMerchantDiscounts(), detailsDto.getShareTargetExpertDiscounts(), detailsDto.getShareTargetPayDiscounts());
|
||||
|
||||
}
|
||||
} catch (Exception e) {
|
||||
e.printStackTrace();
|
||||
}
|
||||
}
|
||||
}
|
|
@ -1,10 +1,9 @@
|
|||
/**
|
||||
* Copyright 2024 bejson.com
|
||||
*/
|
||||
package com.hzya.frame.ttxofs.dto.ofssalesordersearch;
|
||||
|
||||
import lombok.Data;
|
||||
|
||||
import java.math.BigDecimal;
|
||||
|
||||
/**
|
||||
* Auto-generated: 2024-07-30 11:32:10
|
||||
*
|
||||
|
@ -13,7 +12,6 @@ import lombok.Data;
|
|||
*/
|
||||
@Data
|
||||
public class DetailsDto {
|
||||
|
||||
private String clientCode;
|
||||
private String companyCode;
|
||||
private String storeCode;
|
||||
|
@ -58,4 +56,25 @@ public class DetailsDto {
|
|||
private String inventoryId;
|
||||
private String shipAt;
|
||||
private String totalAmount;
|
||||
|
||||
//分摊比例
|
||||
private BigDecimal sharingRatio;
|
||||
|
||||
//原始平台优惠
|
||||
private BigDecimal originalTargetPlatformDiscounts;
|
||||
//原始商家优惠
|
||||
private BigDecimal originalTargetMerchantDiscounts;
|
||||
//原始达人优惠
|
||||
private BigDecimal originalTargetExpertDiscounts;
|
||||
//原始支付优惠
|
||||
private BigDecimal originalTargetPayDiscounts;
|
||||
|
||||
//分摊平台优惠
|
||||
private BigDecimal shareTargetPlatformDiscounts;
|
||||
//分摊商家优惠
|
||||
private BigDecimal shareTargetMerchantDiscounts;
|
||||
//分摊达人优惠
|
||||
private BigDecimal shareTargetExpertDiscounts;
|
||||
//分摊支付优惠
|
||||
private BigDecimal shareTargetPayDiscounts;
|
||||
}
|
|
@ -104,4 +104,16 @@ public class HeaderDto {
|
|||
|
||||
//O单据名称
|
||||
private String subOrderType;
|
||||
|
||||
//平台优惠
|
||||
private String platformDiscounts;
|
||||
|
||||
//商家优惠
|
||||
private String merchantDiscounts;
|
||||
|
||||
//达人优惠
|
||||
private String expertDiscounts;
|
||||
|
||||
//支付优惠
|
||||
private String payDiscounts;
|
||||
}
|
|
@ -5,6 +5,7 @@ import lombok.Data;
|
|||
import java.util.List;
|
||||
|
||||
/**
|
||||
* 售后订单
|
||||
* Auto-generated: 2024-08-19 11:31:49
|
||||
*
|
||||
* @author bejson.com (i@bejson.com)
|
||||
|
|
|
@ -1,10 +1,9 @@
|
|||
/**
|
||||
* Copyright 2024 bejson.com
|
||||
*/
|
||||
package com.hzya.frame.ttxofs.dto.returngoodordersearch;
|
||||
|
||||
import lombok.Data;
|
||||
|
||||
import java.math.BigDecimal;
|
||||
|
||||
/**
|
||||
* Auto-generated: 2024-08-19 11:31:49
|
||||
*
|
||||
|
@ -42,4 +41,24 @@ public class RerturnGoodsOrderSearchDetails {
|
|||
private String createdBy;
|
||||
private String lastUpdated;
|
||||
private String lastUpdatedBy;
|
||||
|
||||
//分摊比例
|
||||
private BigDecimal sharingRatio;
|
||||
//原始平台优惠
|
||||
private BigDecimal originalTargetPlatformDiscounts;
|
||||
//原始商家优惠
|
||||
private BigDecimal originalTargetMerchantDiscounts;
|
||||
//原始达人优惠
|
||||
private BigDecimal originalTargetExpertDiscounts;
|
||||
//原始支付优惠
|
||||
private BigDecimal originalTargetPayDiscounts;
|
||||
|
||||
//分摊平台优惠
|
||||
private BigDecimal shareTargetPlatformDiscounts;
|
||||
//分摊商家优惠
|
||||
private BigDecimal shareTargetMerchantDiscounts;
|
||||
//分摊达人优惠
|
||||
private BigDecimal shareTargetExpertDiscounts;
|
||||
//分摊支付优惠
|
||||
private BigDecimal shareTargetPayDiscounts;
|
||||
}
|
|
@ -63,4 +63,13 @@ public class RerturnGoodsOrderSearchHeader {
|
|||
private String sourceModifiedAt;
|
||||
private String agNumberOfRetries;
|
||||
private String realReturnReason;
|
||||
|
||||
//平台优惠
|
||||
private String platformDiscounts;
|
||||
//商家优惠
|
||||
private String merchantDiscounts;
|
||||
//达人优惠
|
||||
private String expertDiscounts;
|
||||
//支付优惠
|
||||
private String payDiscounts;
|
||||
}
|
Loading…
Reference in New Issue