优惠金额分摊功能实现在OFS销售和售后订单中

实现了OFS销售和售后订单的优惠金额分摊功能。此功能通过计算每个订单明细行的分摊比例,对平台、商家、达人、支付等优惠类型进行分摊。已更新相关的DTO类以包含分摊比例和分摊金额字段,并进行了测试以确保所有场景的正确性。

Closes <ISSUE_NUMBER_OR_URL>
This commit is contained in:
liuy 2024-09-22 15:46:14 +08:00
parent e913c13163
commit 66f63ec31e
9 changed files with 650 additions and 8 deletions

View File

@ -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;
}

View File

@ -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售后订单优惠金额分摊逻辑
*
* @Authorliuyang
* @Packagecom.hzya.frame.plugin.lets.util
* @ProjectkangarooDataCenterV3
* @nameAmountAllocationUtil
* @Date2024/9/21 18:19
* @FilenameAmountAllocationUtil
*/
@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为空");
}
}
}

View File

@ -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销售订单优惠金额分摊逻辑
*
* @Authorliuyang
* @Packagecom.hzya.frame.plugin.lets.util
* @ProjectkangarooDataCenterV3
* @nameAmountAllocationUtil
* @Date2024/9/21 18:19
* @FilenameAmountAllocationUtil
*/
@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为空");
}
}
}

View File

@ -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.*;
/**
* @Authorliuyang
* @Packagecom.hzya.frame.plugin.lets.util
* @ProjectkangarooDataCenterV3
* @nameAmountAllocationUtilTest
* @Date2024/9/22 14:36
* @FilenameAmountAllocationUtilTest
*/
@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();
}
}
}

View File

@ -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;
}

View File

@ -104,4 +104,16 @@ public class HeaderDto {
//O单据名称
private String subOrderType;
//平台优惠
private String platformDiscounts;
//商家优惠
private String merchantDiscounts;
//达人优惠
private String expertDiscounts;
//支付优惠
private String payDiscounts;
}

View File

@ -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)

View File

@ -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;
}

View File

@ -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;
}