优化销售出库和退货流程,增加结存价和采购价判断逻辑

- 在销售出库和退货流程中,增加对特定店铺的判断,如果为指定店铺,则取结存价
- 如果没有结存价,则查询采购价作为备用
- 优化了价格计算逻辑,确保在各种情况下都能正确计算含税单价
- 新增BalanceUnitPriceUtil工具类,用于查询结存价和采购价- 在IaPeriodaccountEntity中添加了nabmny字段,用于存储结存金额
- 在PoOrderBEntity中添加了nordernum字段,用于计算采购总价
This commit is contained in:
liuy 2024-10-18 11:31:35 +08:00
parent 498a0da6ce
commit 4f9932f15c
6 changed files with 183 additions and 8 deletions

View File

@ -62,6 +62,7 @@ public class IaPeriodaccountEntity extends BaseEntity {
private String vproducebatch;
//查询结存价依赖的参数
private String pk_invmandoc;
private String pk_corp;

View File

@ -3,7 +3,7 @@
<mapper namespace="com.hzya.frame.plugin.lets.dao.impl.IaPeriodaccountDaoImpl">
<resultMap id="get-IaPeriodaccountEntity-result" type="com.hzya.frame.plugin.lets.entity.IaPeriodaccountEntity" >
<result property="caccountmonth" column="CACCOUNTMONTH" jdbcType="VARCHAR"/>
<result property="caccountmonth" column="CACCOUNTMONTH" jdbcType="VARCHAR"/>
<result property="caccountyear" column="CACCOUNTYEAR" jdbcType="VARCHAR"/>
<result property="cagentid" column="CAGENTID" jdbcType="VARCHAR"/>
<result property="castunitid" column="CASTUNITID" jdbcType="VARCHAR"/>

View File

@ -1824,6 +1824,7 @@
SELECT
t.cmangid,
t.norgtaxprice,
t.nordernum,
t.ts,
b.pk_invmandoc,
b.pk_corp,

View File

@ -65,6 +65,9 @@ public class SoSaleOutPluginInitializerToB extends PluginBaseEntity {
@Autowired
private ISoSaleorderBDao iSoSaleorderBDao;
@Autowired
private BalanceUnitPriceUtil balanceUnitPriceUtil;
@Autowired
private SaveOrUpdateBusinessLogUtil saveOrUpdateBusinessLogUtil;
@ -744,6 +747,9 @@ public class SoSaleOutPluginInitializerToB extends PluginBaseEntity {
List<SaleorderRequestChildrenDto> saleorderRequestChildrenDtoList = new ArrayList<>();
saleorderRequestDto.setChildrenvo(saleorderRequestChildrenDtoList);
//验证是否为指定的店铺如果为true则取结存价
Boolean isCheckShopChoose = balanceUnitPriceUtil.checkOfsShop(header.getStoreCode());
//把汇总好的出库单明细行合并成一行
for (int j = 0; j < details.size(); j++) {
DetailsDto detailsDto = details.get(j);
@ -768,7 +774,9 @@ public class SoSaleOutPluginInitializerToB extends PluginBaseEntity {
BigDecimal noriginalcursummny = null;//价税合计
BigDecimal noriginalcurtaxmny = null;//税额
try {
noriginalcurtaxprice = new BigDecimal(detailsDto.getTotalPayAmount()).divide(new BigDecimal(detailsDto.getShipQty()), 20, BigDecimal.ROUND_HALF_UP).setScale(4, BigDecimal.ROUND_HALF_UP);
//综合判断对应的目标金额
String totalPayAmount = getFloorPrice(isCheckShopChoose, bdInvbasdocEntity, header, detailsDto);
noriginalcurtaxprice = new BigDecimal(totalPayAmount).divide(new BigDecimal(detailsDto.getShipQty()), 20, BigDecimal.ROUND_HALF_UP).setScale(4, BigDecimal.ROUND_HALF_UP);
noriginalcurprice = noriginalcurtaxprice.divide(new BigDecimal(1).add(new BigDecimal(tax)), 20, BigDecimal.ROUND_HALF_UP).setScale(4, BigDecimal.ROUND_HALF_UP);
noriginalcurmny = noriginalcurprice.multiply(new BigDecimal(detailsDto.getShipQty())).setScale(2, BigDecimal.ROUND_HALF_UP);
noriginalcursummny = noriginalcurtaxprice.multiply(new BigDecimal(detailsDto.getShipQty())).setScale(2, BigDecimal.ROUND_HALF_UP);
@ -1840,6 +1848,9 @@ public class SoSaleOutPluginInitializerToB extends PluginBaseEntity {
salesInvoiceHeadDto.setPk_defdoc16(OverallConstant.getOverAllValue("u8c自定义项档案-单据红字标识-N主键"));
salesInvoiceHeadDto.setVdef16(OverallConstant.getOverAllValue("u8c自定义项档案-单据红字标识-N名称"));
//验证是否为指定的店铺如果为true则取结存价
Boolean isCheckShopChoose = balanceUnitPriceUtil.checkOfsShop(header.getStoreCode());
List<SalesInvoiceBodyDto> salesInvoiceBodyDtoList = new ArrayList<>();
for (int j = 0; j < details.size(); j++) {
DetailsDto detailsDto = details.get(j);
@ -1857,9 +1868,12 @@ public class SoSaleOutPluginInitializerToB extends PluginBaseEntity {
// BdInvclEntity bdInvclEntity = queryU8CEntityUtil.queryBdInvbasdocByBdInvcl(bdInvbasdocEntity);
// BdCostsubjEntity bdCostsubjEntity = queryU8CEntityUtil.queryBdCostsubj(bdInvclEntity);
BigDecimal noriginalcurtaxprice = null;//含税单价
//含税单价
BigDecimal noriginalcurtaxprice = null;
try {
noriginalcurtaxprice = new BigDecimal(detailsDto.getTotalPayAmount()).divide(new BigDecimal(detailsDto.getShipQty()), 20, BigDecimal.ROUND_HALF_UP).setScale(4, BigDecimal.ROUND_HALF_UP);
//综合判断对应的目标金额
String totalPayAmount = getFloorPrice(isCheckShopChoose, bdInvbasdocEntity, header, detailsDto);
noriginalcurtaxprice = new BigDecimal(totalPayAmount).divide(new BigDecimal(detailsDto.getShipQty()), 20, BigDecimal.ROUND_HALF_UP).setScale(4, BigDecimal.ROUND_HALF_UP);
} catch (Exception e) {
logger.error("含税单价金额计算失败!", e);
Assert.state(false, "含税单价金额计算失败 原因:{}", e.getMessage());
@ -2592,4 +2606,67 @@ public class SoSaleOutPluginInitializerToB extends PluginBaseEntity {
// }
// }
// }
/**
* 获取结存金额或者采购金额
*
* @param isCheckShopChoose true取OFS实付金额false取结存金额或者采购价
* @param bdInvbasdocEntity 存货基本档案
* @param header 对应的销售出库单表头
* @param detailsDto 对应的销售出库单明细行对象
* @author liuyang
*/
private String getFloorPrice(Boolean isCheckShopChoose, BdInvbasdocEntity bdInvbasdocEntity, HeaderDto header, DetailsDto detailsDto) throws Exception {
Assert.notNull(isCheckShopChoose, "isCheckShopChoose不能为空");
Assert.notNull(bdInvbasdocEntity, "bdInvbasdocEntity不能为空");
Assert.notNull(header, "header不能为空");
Assert.notNull(detailsDto, "detailsDto不能为空");
String totalPayAmount = null;
if (isCheckShopChoose) {
//取结存价
List<BdInvbasdocEntity> bdInvbasdocEntityList = new ArrayList<>();
bdInvbasdocEntityList.add(bdInvbasdocEntity);
List<IaPeriodaccountEntity> iaPeriodaccountEntityList = balanceUnitPriceUtil.queryBalanceUnitPrice(bdInvbasdocEntityList);
if (iaPeriodaccountEntityList != null && iaPeriodaccountEntityList.size() > 0) {
//结存金额
logger.info("店铺:{} 取O结存价", header.getStoreCode());
IaPeriodaccountEntity iaPeriodaccountEntity = iaPeriodaccountEntityList.get(0);
String nabmny = iaPeriodaccountEntity.getNabmny();
if (nabmny == null || "".equals(nabmny)) {
nabmny = "0";
}
BigDecimal nabmnyBigDecimal = new BigDecimal(nabmny);
if (!"0".equals(nabmnyBigDecimal.stripTrailingZeros().toPlainString())) {
totalPayAmount = nabmnyBigDecimal.stripTrailingZeros().toPlainString();
} else {
//如果结存金额为0则设置为0
totalPayAmount = "0";
}
} else {
//取采购价
List<PoOrderBEntity> poOrderBEntityList = balanceUnitPriceUtil.queryPurchaseUnitPriceByInvcodes(bdInvbasdocEntityList);
if (poOrderBEntityList != null && poOrderBEntityList.size() > 0) {
logger.info("店铺:{} 取O采购价", header.getStoreCode());
String norgtaxprice = poOrderBEntityList.get(0).getNorgtaxprice();
String nordernum = poOrderBEntityList.get(0).getNordernum();
if ("0".equals(new BigDecimal(norgtaxprice).stripTrailingZeros().toPlainString()) || "0".equals(new BigDecimal(nordernum).stripTrailingZeros().toPlainString())) {
//如果采购单价都为0那么金额也为0
totalPayAmount = "0";
} else {
BigDecimal norgtaxpriceBigDecimal = new BigDecimal(norgtaxprice);
BigDecimal nordernumBigDecimal = new BigDecimal(nordernum);
BigDecimal multiply = norgtaxpriceBigDecimal.multiply(nordernumBigDecimal).setScale(2, BigDecimal.ROUND_HALF_UP);
totalPayAmount = multiply.stripTrailingZeros().toPlainString();
}
} else {
Assert.state(false, "店铺:{} 存货:{} 既没有结存价、也没有采购价!", header.getStoreCode(), bdInvbasdocEntity.getInvcode());
}
}
} else {
logger.info("店铺:{} 取O实付金额", header.getStoreCode());
totalPayAmount = detailsDto.getTotalPayAmount();
}
return totalPayAmount;
}
}

View File

@ -231,6 +231,9 @@ public class SoSaleReturnPluginInitializerToB extends PluginBaseEntity {
private static final String VNOTETYPE = "RETURN";
@Autowired
private BalanceUnitPriceUtil balanceUnitPriceUtil;
/**
* 库存同步按指定时间拉取
*
@ -735,6 +738,9 @@ public class SoSaleReturnPluginInitializerToB extends PluginBaseEntity {
List<SaleorderRequestChildrenDto> saleorderRequestChildrenDtoList = new ArrayList<>();
saleorderRequestDto.setChildrenvo(saleorderRequestChildrenDtoList);
//验证是否为指定的店铺如果为true则取结存价
Boolean isCheckShopChoose = balanceUnitPriceUtil.checkOfsShop(header.getStoreCode());
//把汇总好的出库单明细行合并成一行
for (int j = 0; j < details.size(); j++) {
StockinOrderSearchResponse.StockinOrder.StockinB stockinB = details.get(j);
@ -765,10 +771,13 @@ public class SoSaleReturnPluginInitializerToB extends PluginBaseEntity {
BigDecimal noriginalcursummny = null;//价税合计
BigDecimal noriginalcurtaxmny = null;//税额
try {
Assert.notNull(stockinB.getTotalAmount(), "退货入库单总金额不能为空 明细行对象:{}", JSON.toJSONString(stockinB));
// Assert.notNull(stockinB.getTotalAmount(), "退货入库单总金额不能为空 明细行对象:{}", JSON.toJSONString(stockinB));
Assert.notNull(stockinB.getReceivedQty(), "实收数量不能为空 明细行对象:{}", JSON.toJSONString(stockinB));
noriginalcurtaxprice = new BigDecimal(afterSalesOrder.getTotalAmount()).divide(new BigDecimal(stockinB.getReceivedQty()), 20, BigDecimal.ROUND_HALF_UP).setScale(4, BigDecimal.ROUND_HALF_UP);
//确定好实退金额可能为O的实退金额也可能是结存价和采购价
String totalAmount = getFloorPrice(isCheckShopChoose, bdInvbasdocEntity, header, afterSalesOrder);
noriginalcurtaxprice = new BigDecimal(totalAmount).divide(new BigDecimal(stockinB.getReceivedQty()), 20, BigDecimal.ROUND_HALF_UP).setScale(4, BigDecimal.ROUND_HALF_UP);
noriginalcurprice = noriginalcurtaxprice.divide(new BigDecimal(1).add(new BigDecimal(tax)), 20, BigDecimal.ROUND_HALF_UP).setScale(4, BigDecimal.ROUND_HALF_UP);
noriginalcurmny = noriginalcurprice.multiply(new BigDecimal(stockinB.getReceivedQty())).setScale(2, BigDecimal.ROUND_HALF_UP);
noriginalcursummny = noriginalcurtaxprice.multiply(new BigDecimal(stockinB.getReceivedQty())).setScale(2, BigDecimal.ROUND_HALF_UP);
@ -2464,5 +2473,68 @@ public class SoSaleReturnPluginInitializerToB extends PluginBaseEntity {
}
}
/**
* 获取结存金额或者采购金额
* Boolean isCheckShopChoose
*
* @param isCheckShopChoose true取OFS实付金额false取结存金额或者采购价
* @param bdInvbasdocEntity 存货基础档案
* @param header OFS收入入库单表头
* @param afterSalesOrder OFS售后订单明细行
* @author liuyang
*/
private String getFloorPrice(Boolean isCheckShopChoose, BdInvbasdocEntity bdInvbasdocEntity, StockinOrderSearchResponse.StockinOrder.StockinH header, RerturnGoodsOrderSearchDetails afterSalesOrder) throws Exception {
Assert.notNull(isCheckShopChoose, "isCheckShopChoose不能为空");
Assert.notNull(bdInvbasdocEntity, "bdInvbasdocEntity不能为空");
Assert.notNull(header, "header不能为空");
Assert.notNull(afterSalesOrder, "afterSalesOrder不能为空");
String totalPayAmount = null;
if (isCheckShopChoose) {
//取结存
List<BdInvbasdocEntity> bdInvbasdocEntityList = new ArrayList<>();
bdInvbasdocEntityList.add(bdInvbasdocEntity);
List<IaPeriodaccountEntity> iaPeriodaccountEntityList = balanceUnitPriceUtil.queryBalanceUnitPrice(bdInvbasdocEntityList);
if (iaPeriodaccountEntityList != null && iaPeriodaccountEntityList.size() > 0) {
//结存金额
logger.info("店铺:{} 取O结存价", header.getStoreCode());
IaPeriodaccountEntity iaPeriodaccountEntity = iaPeriodaccountEntityList.get(0);
String nabmny = iaPeriodaccountEntity.getNabmny();
if (nabmny == null || "".equals(nabmny)) {
nabmny = "0";
}
BigDecimal nabmnyBigDecimal = new BigDecimal(nabmny);
if (!"0".equals(nabmnyBigDecimal.stripTrailingZeros().toPlainString())) {
totalPayAmount = nabmnyBigDecimal.stripTrailingZeros().toPlainString();
} else {
//如果结存金额为0则设置为0
totalPayAmount = "0";
}
} else {
//取采购价
List<PoOrderBEntity> poOrderBEntityList = balanceUnitPriceUtil.queryPurchaseUnitPriceByInvcodes(bdInvbasdocEntityList);
if (poOrderBEntityList != null && poOrderBEntityList.size() > 0) {
logger.info("店铺:{} 取O采购价", header.getStoreCode());
String norgtaxprice = poOrderBEntityList.get(0).getNorgtaxprice();
String nordernum = poOrderBEntityList.get(0).getNordernum();
if ("0".equals(new BigDecimal(norgtaxprice).stripTrailingZeros().toPlainString()) || "0".equals(new BigDecimal(nordernum).stripTrailingZeros().toPlainString())) {
//如果采购单价都为0那么金额也为0
totalPayAmount = "0";
} else {
BigDecimal norgtaxpriceBigDecimal = new BigDecimal(norgtaxprice);
BigDecimal nordernumBigDecimal = new BigDecimal(nordernum);
BigDecimal multiply = norgtaxpriceBigDecimal.multiply(nordernumBigDecimal).setScale(2, BigDecimal.ROUND_HALF_UP);
totalPayAmount = multiply.stripTrailingZeros().toPlainString();
}
} else {
Assert.state(false, "店铺:{} 存货:{} 既没有结存价、也没有采购价!", header.getStoreCode(), bdInvbasdocEntity.getInvcode());
}
}
} else {
//O用户实退
logger.info("店铺:{} 取O实付金额", header.getStoreCode());
totalPayAmount = afterSalesOrder.getTotalAmount();
}
return totalPayAmount;
}
}

View File

@ -1,5 +1,6 @@
package com.hzya.frame.plugin.lets.util;
import cn.hutool.core.lang.Assert;
import com.hzya.frame.plugin.lets.dao.IIaPeriodaccountDao;
import com.hzya.frame.plugin.lets.dao.IPoOrderBDao;
import com.hzya.frame.plugin.lets.entity.BdInvbasdocEntity;
@ -10,7 +11,9 @@ import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.stream.Collectors;
/**
@ -32,8 +35,29 @@ public class BalanceUnitPriceUtil {
@Autowired
private IPoOrderBDao iPoOrderBDao;
public Boolean checkOfsShop() {
return false;
private static final Map<String, String> cacheShopMap = new HashMap<>();
static {
cacheShopMap.put("FANG-Q-L", "FANG-Q-L");
cacheShopMap.put("dy-FQL", "dy-FQL");
cacheShopMap.put("hzz", "hzz");
cacheShopMap.put("pdd-gunanxi", "pdd-gunanxi");
cacheShopMap.put("pdd-yanxi", "pdd-yanxi");
}
/**
* 判断是否取结存价的店铺
*
* @param ofsShop OFS店铺编码
* @author liuyang
*/
public Boolean checkOfsShop(String ofsShop) {
Assert.notNull(ofsShop, "OFS店铺编码不能为空");
String cacheValue = cacheShopMap.get(ofsShop);
if (cacheValue == null) {
return false;
}
return true;
}
/**