加入change变化金额问题
This commit is contained in:
@@ -48,6 +48,17 @@ public class EqpAuxiliaryMaterial extends BaseEntity {
|
||||
* 当前库存数量
|
||||
*/
|
||||
private Long quantity;
|
||||
|
||||
/**
|
||||
* 当前移动加权平均单价
|
||||
*/
|
||||
private java.math.BigDecimal unitPrice;
|
||||
|
||||
/**
|
||||
* 当前库存总金额(可冗余,= quantity * unit_price)
|
||||
*/
|
||||
private java.math.BigDecimal totalAmount;
|
||||
|
||||
/**
|
||||
* 删除标志(0=存在 2=删除)
|
||||
*/
|
||||
|
||||
@@ -6,7 +6,6 @@ import lombok.Data;
|
||||
import lombok.EqualsAndHashCode;
|
||||
|
||||
import java.util.Date;
|
||||
import com.fasterxml.jackson.annotation.JsonFormat;
|
||||
|
||||
/**
|
||||
* 辅料变动记录对象 eqp_auxiliary_material_change
|
||||
@@ -38,6 +37,22 @@ public class EqpAuxiliaryMaterialChange extends BaseEntity {
|
||||
* 变动数量
|
||||
*/
|
||||
private Long changeQuantity;
|
||||
|
||||
/**
|
||||
* 入库单价(仅增加时有意义)
|
||||
*/
|
||||
private java.math.BigDecimal inUnitPrice;
|
||||
|
||||
/**
|
||||
* 单价快照(减少时必填)
|
||||
*/
|
||||
private java.math.BigDecimal unitPriceSnapshot;
|
||||
|
||||
/**
|
||||
* 本次变动金额(有符号;减少为负)
|
||||
*/
|
||||
private java.math.BigDecimal amount;
|
||||
|
||||
/**
|
||||
* 变动原因
|
||||
*/
|
||||
|
||||
@@ -48,6 +48,17 @@ public class EqpSparePart extends BaseEntity {
|
||||
* 当前库存数量
|
||||
*/
|
||||
private Long quantity;
|
||||
|
||||
/**
|
||||
* 当前移动加权平均单价
|
||||
*/
|
||||
private java.math.BigDecimal unitPrice;
|
||||
|
||||
/**
|
||||
* 当前库存总金额(可冗余,= quantity * unit_price)
|
||||
*/
|
||||
private java.math.BigDecimal totalAmount;
|
||||
|
||||
/**
|
||||
* 删除标志(0=存在 2=删除)
|
||||
*/
|
||||
|
||||
@@ -6,7 +6,6 @@ import lombok.Data;
|
||||
import lombok.EqualsAndHashCode;
|
||||
|
||||
import java.util.Date;
|
||||
import com.fasterxml.jackson.annotation.JsonFormat;
|
||||
|
||||
/**
|
||||
* 备品备件变动记录对象 eqp_spare_parts_change
|
||||
@@ -38,6 +37,22 @@ public class EqpSparePartsChange extends BaseEntity {
|
||||
* 变动数量
|
||||
*/
|
||||
private Long changeQuantity;
|
||||
|
||||
/**
|
||||
* 入库单价(仅增加时有意义)
|
||||
*/
|
||||
private java.math.BigDecimal inUnitPrice;
|
||||
|
||||
/**
|
||||
* 单价快照(减少时必填)
|
||||
*/
|
||||
private java.math.BigDecimal unitPriceSnapshot;
|
||||
|
||||
/**
|
||||
* 本次变动金额(有符号;减少为负)
|
||||
*/
|
||||
private java.math.BigDecimal amount;
|
||||
|
||||
/**
|
||||
* 变动原因
|
||||
*/
|
||||
|
||||
@@ -39,6 +39,11 @@ public class EqpAuxiliaryMaterialChangeBo extends BaseEntity {
|
||||
*/
|
||||
private Long changeQuantity;
|
||||
|
||||
/**
|
||||
* 入库单价(前端传入,仅 changeType=增加 时必填)
|
||||
*/
|
||||
private java.math.BigDecimal inUnitPrice;
|
||||
|
||||
/**
|
||||
* 变动原因
|
||||
*/
|
||||
|
||||
@@ -39,6 +39,11 @@ public class EqpSparePartsChangeBo extends BaseEntity {
|
||||
*/
|
||||
private Long changeQuantity;
|
||||
|
||||
/**
|
||||
* 入库单价(前端传入,仅 changeType=增加 时必填)
|
||||
*/
|
||||
private java.math.BigDecimal inUnitPrice;
|
||||
|
||||
/**
|
||||
* 变动原因
|
||||
*/
|
||||
|
||||
@@ -22,7 +22,6 @@ import org.springframework.transaction.annotation.Transactional;
|
||||
|
||||
import java.util.Date;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
import java.util.Collection;
|
||||
|
||||
/**
|
||||
@@ -67,7 +66,6 @@ public class EqpAuxiliaryMaterialChangeServiceImpl implements IEqpAuxiliaryMater
|
||||
}
|
||||
|
||||
private LambdaQueryWrapper<EqpAuxiliaryMaterialChange> buildQueryWrapper(EqpAuxiliaryMaterialChangeBo bo) {
|
||||
Map<String, Object> params = bo.getParams();
|
||||
LambdaQueryWrapper<EqpAuxiliaryMaterialChange> lqw = Wrappers.lambdaQuery();
|
||||
lqw.eq(bo.getAuxiliaryId() != null, EqpAuxiliaryMaterialChange::getAuxiliaryId, bo.getAuxiliaryId());
|
||||
lqw.eq(StringUtils.isNotBlank(bo.getChangeType()), EqpAuxiliaryMaterialChange::getChangeType, bo.getChangeType());
|
||||
@@ -146,23 +144,80 @@ public class EqpAuxiliaryMaterialChangeServiceImpl implements IEqpAuxiliaryMater
|
||||
return R.fail("辅料已删除,无法操作");
|
||||
}
|
||||
|
||||
// 3. 库存变动逻辑
|
||||
Long newQuantity; // 替换为Integer(原表quantity是int)
|
||||
if ("减少".equals(bo.getChangeType())) {
|
||||
// 减少库存时校验库存充足性
|
||||
if (auxiliaryMaterial.getQuantity() < bo.getChangeQuantity()) {
|
||||
return R.fail("库存不足,当前库存:" + auxiliaryMaterial.getQuantity() + ",需减少:" + bo.getChangeQuantity());
|
||||
// 3. 库存与金额变动逻辑(移动加权平均 + 消耗单价快照)
|
||||
java.math.BigDecimal oldUnitPrice = auxiliaryMaterial.getUnitPrice() == null ? java.math.BigDecimal.ZERO : auxiliaryMaterial.getUnitPrice();
|
||||
java.math.BigDecimal oldTotalAmount = auxiliaryMaterial.getTotalAmount() == null ? java.math.BigDecimal.ZERO : auxiliaryMaterial.getTotalAmount();
|
||||
|
||||
Long oldQty = auxiliaryMaterial.getQuantity() == null ? 0L : auxiliaryMaterial.getQuantity();
|
||||
Long changeQty = bo.getChangeQuantity();
|
||||
|
||||
Long newQuantity;
|
||||
java.math.BigDecimal newUnitPrice = oldUnitPrice;
|
||||
java.math.BigDecimal newTotalAmount = oldTotalAmount;
|
||||
|
||||
// 从上下文获取操作人
|
||||
String operator = String.valueOf(LoginHelper.getUsername());
|
||||
|
||||
// 4. 插入变动记录(先组装,后续补齐单价快照与金额)
|
||||
EqpAuxiliaryMaterialChange changeLog = new EqpAuxiliaryMaterialChange();
|
||||
changeLog.setAuxiliaryId(bo.getAuxiliaryId());
|
||||
changeLog.setChangeType(bo.getChangeType());
|
||||
changeLog.setChangeQuantity(changeQty);
|
||||
changeLog.setReason(bo.getReason());
|
||||
changeLog.setRemark(bo.getRemark());
|
||||
changeLog.setChangeTime(new Date());
|
||||
changeLog.setCreateBy(operator);
|
||||
changeLog.setUpdateBy(operator);
|
||||
changeLog.setDelFlag("0");
|
||||
|
||||
if ("增加".equals(bo.getChangeType())) {
|
||||
// 入库单价前端必填
|
||||
if (bo.getInUnitPrice() == null) {
|
||||
return R.fail("入库单价不能为空。建议按当前台账单价补齐后再提交。");
|
||||
}
|
||||
newQuantity = auxiliaryMaterial.getQuantity() - bo.getChangeQuantity();
|
||||
java.math.BigDecimal inUnitPrice = bo.getInUnitPrice();
|
||||
|
||||
newQuantity = oldQty + changeQty;
|
||||
|
||||
// 移动加权平均价: (old_price*old_qty + in_price*in_qty) / (old_qty + in_qty)
|
||||
java.math.BigDecimal numerator = oldUnitPrice.multiply(java.math.BigDecimal.valueOf(oldQty))
|
||||
.add(inUnitPrice.multiply(java.math.BigDecimal.valueOf(changeQty)));
|
||||
java.math.BigDecimal denominator = java.math.BigDecimal.valueOf(newQuantity);
|
||||
newUnitPrice = denominator.compareTo(java.math.BigDecimal.ZERO) > 0
|
||||
? numerator.divide(denominator, 6, java.math.RoundingMode.HALF_UP)
|
||||
: java.math.BigDecimal.ZERO;
|
||||
|
||||
newTotalAmount = newUnitPrice.multiply(java.math.BigDecimal.valueOf(newQuantity)).setScale(2, java.math.RoundingMode.HALF_UP);
|
||||
|
||||
changeLog.setInUnitPrice(inUnitPrice);
|
||||
// 增加时也记录快照(记录“入库后单价”更利于追溯)
|
||||
changeLog.setUnitPriceSnapshot(newUnitPrice);
|
||||
// amount 采用有符号:增加为正
|
||||
changeLog.setAmount(inUnitPrice.multiply(java.math.BigDecimal.valueOf(changeQty)).setScale(2, java.math.RoundingMode.HALF_UP));
|
||||
} else {
|
||||
// 增加库存直接累加
|
||||
newQuantity = auxiliaryMaterial.getQuantity() + bo.getChangeQuantity();
|
||||
// 减少库存时校验库存充足性
|
||||
if (oldQty < changeQty) {
|
||||
return R.fail("库存不足,当前库存:" + oldQty + ",需减少:" + changeQty);
|
||||
}
|
||||
|
||||
newQuantity = oldQty - changeQty;
|
||||
|
||||
// 减少时捕捉当前台账单价快照,amount 为负
|
||||
java.math.BigDecimal unitPriceSnapshot = oldUnitPrice;
|
||||
java.math.BigDecimal costAbs = unitPriceSnapshot.multiply(java.math.BigDecimal.valueOf(changeQty)).setScale(2, java.math.RoundingMode.HALF_UP);
|
||||
|
||||
changeLog.setUnitPriceSnapshot(unitPriceSnapshot);
|
||||
changeLog.setAmount(costAbs.negate());
|
||||
|
||||
// 更新库存总金额(按剩余库存重新计算)
|
||||
newUnitPrice = oldUnitPrice;
|
||||
newTotalAmount = newUnitPrice.multiply(java.math.BigDecimal.valueOf(newQuantity)).setScale(2, java.math.RoundingMode.HALF_UP);
|
||||
}
|
||||
|
||||
// 4. 更新辅料库存(填充审计字段)
|
||||
// 5. 更新辅料库存(数量 + 单价 + 总金额)
|
||||
auxiliaryMaterial.setQuantity(newQuantity);
|
||||
// 从上下文获取操作人(替换为你的登录助手类)
|
||||
String operator = String.valueOf(LoginHelper.getUsername());
|
||||
auxiliaryMaterial.setUnitPrice(newUnitPrice);
|
||||
auxiliaryMaterial.setTotalAmount(newTotalAmount);
|
||||
auxiliaryMaterial.setUpdateBy(operator);
|
||||
auxiliaryMaterial.setUpdateTime(new Date());
|
||||
boolean updateSuccess = eqpAuxiliaryMaterialMapper.updateById(auxiliaryMaterial) > 0;
|
||||
@@ -170,21 +225,7 @@ public class EqpAuxiliaryMaterialChangeServiceImpl implements IEqpAuxiliaryMater
|
||||
return R.fail("库存更新失败");
|
||||
}
|
||||
|
||||
// 5. 插入变动记录(基于EqpAuxiliaryMaterialChangeBo转换)
|
||||
EqpAuxiliaryMaterialChange changeLog = new EqpAuxiliaryMaterialChange();
|
||||
// 从Bo复制核心字段
|
||||
changeLog.setAuxiliaryId(bo.getAuxiliaryId());
|
||||
changeLog.setChangeType(bo.getChangeType());
|
||||
changeLog.setChangeQuantity(bo.getChangeQuantity());
|
||||
changeLog.setReason(bo.getReason()); // 变动原因
|
||||
changeLog.setRemark(bo.getRemark()); // 备注
|
||||
// 补充审计字段
|
||||
changeLog.setChangeTime(new Date());
|
||||
changeLog.setCreateBy(operator);
|
||||
changeLog.setUpdateBy(operator);
|
||||
changeLog.setDelFlag("0"); // 未删除
|
||||
|
||||
// 插入变动记录
|
||||
// 6. 插入变动记录
|
||||
int insertCount = baseMapper.insert(changeLog);
|
||||
if (insertCount <= 0) {
|
||||
return R.fail("变动记录插入失败");
|
||||
|
||||
@@ -3,7 +3,6 @@ package com.klp.mes.eqp.service.impl;
|
||||
import cn.hutool.core.bean.BeanUtil;
|
||||
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
|
||||
import com.klp.common.core.domain.R;
|
||||
import com.klp.common.core.domain.model.LoginUser;
|
||||
import com.klp.common.core.page.TableDataInfo;
|
||||
import com.klp.common.core.domain.PageQuery;
|
||||
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
|
||||
@@ -12,7 +11,6 @@ import com.baomidou.mybatisplus.core.toolkit.Wrappers;
|
||||
import com.klp.common.helper.LoginHelper;
|
||||
import com.klp.common.utils.StringUtils;
|
||||
import com.klp.mes.eqp.domain.EqpSparePart;
|
||||
import com.klp.mes.eqp.domain.bo.EqpSparePartBo;
|
||||
import com.klp.mes.eqp.mapper.EqpSparePartMapper;
|
||||
import lombok.RequiredArgsConstructor;
|
||||
import org.springframework.beans.factory.annotation.Autowired;
|
||||
@@ -26,7 +24,6 @@ import org.springframework.transaction.annotation.Transactional;
|
||||
|
||||
import java.util.Date;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
import java.util.Collection;
|
||||
|
||||
/**
|
||||
@@ -85,7 +82,6 @@ public class EqpSparePartsChangeServiceImpl implements IEqpSparePartsChangeServi
|
||||
}
|
||||
|
||||
private LambdaQueryWrapper<EqpSparePartsChange> buildQueryWrapper(EqpSparePartsChangeBo bo) {
|
||||
Map<String, Object> params = bo.getParams();
|
||||
LambdaQueryWrapper<EqpSparePartsChange> lqw = Wrappers.lambdaQuery();
|
||||
lqw.eq(bo.getPartId() != null, EqpSparePartsChange::getPartId, bo.getPartId());
|
||||
lqw.eq(StringUtils.isNotBlank(bo.getChangeType()), EqpSparePartsChange::getChangeType, bo.getChangeType());
|
||||
@@ -164,23 +160,71 @@ public class EqpSparePartsChangeServiceImpl implements IEqpSparePartsChangeServi
|
||||
return R.fail("备品备件已删除,无法操作");
|
||||
}
|
||||
|
||||
// 3. 库存变动逻辑
|
||||
// 3. 库存与金额变动逻辑(移动加权平均 + 消耗单价快照)
|
||||
java.math.BigDecimal oldUnitPrice = sparePart.getUnitPrice() == null ? java.math.BigDecimal.ZERO : sparePart.getUnitPrice();
|
||||
java.math.BigDecimal oldTotalAmount = sparePart.getTotalAmount() == null ? java.math.BigDecimal.ZERO : sparePart.getTotalAmount();
|
||||
|
||||
Long oldQty = sparePart.getQuantity() == null ? 0L : sparePart.getQuantity();
|
||||
Long changeQty = bo.getChangeQuantity();
|
||||
|
||||
Long newQuantity;
|
||||
if ("减少".equals(bo.getChangeType())) {
|
||||
// 减少库存时校验库存充足性
|
||||
if (sparePart.getQuantity() < bo.getChangeQuantity()) {
|
||||
return R.fail("库存不足,当前库存:" + sparePart.getQuantity() + ",需减少:" + bo.getChangeQuantity());
|
||||
java.math.BigDecimal newUnitPrice = oldUnitPrice;
|
||||
java.math.BigDecimal newTotalAmount = oldTotalAmount;
|
||||
|
||||
String operator = String.valueOf(LoginHelper.getUsername());
|
||||
|
||||
EqpSparePartsChange changeLog = new EqpSparePartsChange();
|
||||
changeLog.setPartId(bo.getPartId());
|
||||
changeLog.setChangeType(bo.getChangeType());
|
||||
changeLog.setChangeQuantity(changeQty);
|
||||
changeLog.setReason(bo.getReason());
|
||||
changeLog.setRemark(bo.getRemark());
|
||||
changeLog.setChangeTime(new Date());
|
||||
changeLog.setCreateBy(operator);
|
||||
changeLog.setUpdateBy(operator);
|
||||
changeLog.setDelFlag("0");
|
||||
|
||||
if ("增加".equals(bo.getChangeType())) {
|
||||
if (bo.getInUnitPrice() == null) {
|
||||
return R.fail("入库单价不能为空。建议按当前台账单价补齐后再提交。");
|
||||
}
|
||||
newQuantity = sparePart.getQuantity() - bo.getChangeQuantity();
|
||||
java.math.BigDecimal inUnitPrice = bo.getInUnitPrice();
|
||||
|
||||
newQuantity = oldQty + changeQty;
|
||||
|
||||
java.math.BigDecimal numerator = oldUnitPrice.multiply(java.math.BigDecimal.valueOf(oldQty))
|
||||
.add(inUnitPrice.multiply(java.math.BigDecimal.valueOf(changeQty)));
|
||||
java.math.BigDecimal denominator = java.math.BigDecimal.valueOf(newQuantity);
|
||||
newUnitPrice = denominator.compareTo(java.math.BigDecimal.ZERO) > 0
|
||||
? numerator.divide(denominator, 6, java.math.RoundingMode.HALF_UP)
|
||||
: java.math.BigDecimal.ZERO;
|
||||
|
||||
newTotalAmount = newUnitPrice.multiply(java.math.BigDecimal.valueOf(newQuantity)).setScale(2, java.math.RoundingMode.HALF_UP);
|
||||
|
||||
changeLog.setInUnitPrice(inUnitPrice);
|
||||
changeLog.setUnitPriceSnapshot(newUnitPrice);
|
||||
changeLog.setAmount(inUnitPrice.multiply(java.math.BigDecimal.valueOf(changeQty)).setScale(2, java.math.RoundingMode.HALF_UP));
|
||||
} else {
|
||||
// 增加库存直接累加
|
||||
newQuantity = sparePart.getQuantity() + bo.getChangeQuantity();
|
||||
if (oldQty < changeQty) {
|
||||
return R.fail("库存不足,当前库存:" + oldQty + ",需减少:" + changeQty);
|
||||
}
|
||||
|
||||
newQuantity = oldQty - changeQty;
|
||||
|
||||
java.math.BigDecimal unitPriceSnapshot = oldUnitPrice;
|
||||
java.math.BigDecimal costAbs = unitPriceSnapshot.multiply(java.math.BigDecimal.valueOf(changeQty)).setScale(2, java.math.RoundingMode.HALF_UP);
|
||||
|
||||
changeLog.setUnitPriceSnapshot(unitPriceSnapshot);
|
||||
changeLog.setAmount(costAbs.negate());
|
||||
|
||||
newUnitPrice = oldUnitPrice;
|
||||
newTotalAmount = newUnitPrice.multiply(java.math.BigDecimal.valueOf(newQuantity)).setScale(2, java.math.RoundingMode.HALF_UP);
|
||||
}
|
||||
|
||||
// 4. 更新备件库存(填充审计字段)
|
||||
// 4. 更新备件库存(数量 + 单价 + 总金额)
|
||||
sparePart.setQuantity(newQuantity);
|
||||
// 从Bo获取操作人(优先)或默认值
|
||||
String operator = String.valueOf(LoginHelper.getUsername());
|
||||
sparePart.setUnitPrice(newUnitPrice);
|
||||
sparePart.setTotalAmount(newTotalAmount);
|
||||
sparePart.setUpdateBy(operator);
|
||||
sparePart.setUpdateTime(new Date());
|
||||
boolean updateSuccess = eqpSparePartMapper.updateById(sparePart) > 0;
|
||||
@@ -188,21 +232,7 @@ public class EqpSparePartsChangeServiceImpl implements IEqpSparePartsChangeServi
|
||||
return R.fail("库存更新失败");
|
||||
}
|
||||
|
||||
// 5. 插入变动记录(基于EqpSparePartsChangeBo转换)
|
||||
EqpSparePartsChange changeLog = new EqpSparePartsChange();
|
||||
// 从Bo复制核心字段
|
||||
changeLog.setPartId(bo.getPartId());
|
||||
changeLog.setChangeType(bo.getChangeType());
|
||||
changeLog.setChangeQuantity(bo.getChangeQuantity());
|
||||
changeLog.setReason(bo.getReason()); // 变动原因(Bo中应包含该字段)
|
||||
changeLog.setRemark(bo.getRemark()); // 备注(Bo中应包含该字段)
|
||||
// 补充审计字段
|
||||
changeLog.setChangeTime(new Date());
|
||||
changeLog.setCreateBy(operator);
|
||||
changeLog.setUpdateBy(operator);
|
||||
changeLog.setDelFlag("0"); // 未删除
|
||||
|
||||
// 插入变动记录(需注入对应Mapper)
|
||||
// 5. 插入变动记录
|
||||
int insertCount = baseMapper.insert(changeLog);
|
||||
if (insertCount <= 0) {
|
||||
return R.fail("变动记录插入失败");
|
||||
|
||||
Reference in New Issue
Block a user