Commit 879700fb by 杨浩

新增expected_quantity字段、pickUp接口改造、销售订单灶点信息、下单数量截断

- 4张表新增expected_quantity字段,DO/VO/DTO同步新增
- pickUp接口改造:支持传入数量,级联更新销售/客户/采购/入库订单及库存
- 销售订单RespVO新增灶点id和灶点名称,赋值逻辑参考采购订单
- 客户下单orderItemQuantity截断为小数点后两位(RoundingMode.DOWN)

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
parent f3918b9d
......@@ -63,6 +63,23 @@ public class MoneyUtils {
}
/**
* 计算百分比金额(BigDecimal 数量)
*
* @param price 金额(单位分)
* @param count 数量(BigDecimal)
* @param percent 折扣(单位分),列如 60.2%,则传入 6020
* @return 商品总价
*/
public static Integer calculator(Integer price, BigDecimal count, Integer percent) {
int totalPrice = BigDecimal.valueOf(price).multiply(count)
.setScale(0, RoundingMode.DOWN).intValue();
if (percent == null) {
return totalPrice;
}
return MoneyUtils.calculateRatePriceFloor(totalPrice, (double) (percent / 100));
}
/**
* 计算百分比金额
*
* @param price 金额
......@@ -144,24 +161,35 @@ public class MoneyUtils {
}
/**
* BigDecimal与int相乘,四舍五入后转为int
* BigDecimal与int相乘,向下截断后转为int
* @param decimal 待相乘的BigDecimal(如金额、费率)
* @param integer 待相乘的int(如数量、倍数)
* @return 四舍五入后的int结果
* @return 向下截断后的int结果
* @throws ArithmeticException 结果超出int范围时抛出
*/
public static Integer multiplyAndRoundToInt(BigDecimal decimal, Integer integer) {
// 1. 空值校验(根据业务调整,也可默认decimal为0)
if (decimal == null) {
throw new IllegalArgumentException("BigDecimal参数不能为空");
}
// 2. 相乘运算 + 四舍五入(RoundingMode.HALF_UP = 标准四舍五入)
BigDecimal resultBigDecimal = decimal.multiply(BigDecimal.valueOf(integer))
.setScale(0, RoundingMode.HALF_UP);
// 3. 转换为int(超出int范围会抛ArithmeticException,需捕获或处理)
.setScale(0, RoundingMode.DOWN);
return resultBigDecimal.intValueExact();
}
/**
* 价格(int)与数量(BigDecimal)相乘,向下截断后转为int
* <p>用于单位为分的价格计算,结果出现小数时只保留整数部分,不四舍五入</p>
*
* @param price 单价(单位:分)
* @param count 数量(BigDecimal)
* @return 向下截断后的int总价
*/
public static Integer priceMultiplyCount(Integer price, BigDecimal count) {
if (price == null || count == null) {
return null;
}
return BigDecimal.valueOf(price).multiply(count)
.setScale(0, RoundingMode.DOWN).intValue();
}
}
......@@ -117,7 +117,10 @@ public class ErpPurchaseInRespVO {
@Schema(description = "产品数量", requiredMode = Schema.RequiredMode.REQUIRED, example = "100.00")
@NotNull(message = "产品数量不能为空")
private Integer count;
private BigDecimal count;
@Schema(description = "预期下单数量")
private BigDecimal expectedQuantity;
@Schema(description = "税率,百分比", example = "99.88")
private BigDecimal taxPercent;
......
......@@ -68,7 +68,10 @@ public class ErpPurchaseInSaveReqVO {
@Schema(description = "产品数量", requiredMode = Schema.RequiredMode.REQUIRED, example = "100.00")
@NotNull(message = "产品数量不能为空")
private Integer count;
private BigDecimal count;
@Schema(description = "预期下单数量")
private BigDecimal expectedQuantity;
@Schema(description = "税率,百分比", example = "99.88")
private BigDecimal taxPercent;
......
......@@ -182,7 +182,10 @@ public class ErpPurchaseOrderRespVO {
@Schema(description = "产品数量", requiredMode = Schema.RequiredMode.REQUIRED, example = "100.00")
@NotNull(message = "产品数量不能为空")
private Integer count;
private BigDecimal count;
@Schema(description = "预期下单数量")
private BigDecimal expectedQuantity;
@Schema(description = "总价,单位:分")
private Integer totalPrice;
......
......@@ -82,7 +82,10 @@ public class ErpPurchaseOrderSaveReqVO {
@Schema(description = "产品数量", requiredMode = Schema.RequiredMode.REQUIRED, example = "100.00")
@NotNull(message = "产品数量不能为空")
private Integer count;
private BigDecimal count;
@Schema(description = "预期下单数量")
private BigDecimal expectedQuantity;
@Schema(description = "税率,百分比", example = "99.88")
private BigDecimal taxPercent;
......
......@@ -11,6 +11,7 @@ import cn.iocoder.foodnexus.framework.common.util.object.BeanUtils;
import cn.iocoder.foodnexus.framework.excel.core.util.ExcelUtils;
import cn.iocoder.foodnexus.module.erp.api.service.ErpSupplierApi;
import cn.iocoder.foodnexus.module.erp.controller.admin.sale.vo.order.ErpSaleOrderPageReqVO;
import cn.iocoder.foodnexus.module.erp.controller.admin.sale.vo.order.ErpSaleOrderPickUpReqVO;
import cn.iocoder.foodnexus.module.erp.controller.admin.sale.vo.order.ErpSaleOrderRespVO;
import cn.iocoder.foodnexus.module.erp.dal.dataobject.purchase.ErpPurchaseOrderDO;
import cn.iocoder.foodnexus.module.erp.dal.dataobject.sale.ErpCustomerDO;
......@@ -29,6 +30,7 @@ import cn.iocoder.foodnexus.module.order.dto.DeliveryStaffSimpleInfo;
import cn.iocoder.foodnexus.module.product.api.dto.ProductInfo;
import cn.iocoder.foodnexus.module.product.service.spu.ProductSpuService;
import cn.iocoder.foodnexus.module.system.api.user.AdminUserApi;
import cn.iocoder.foodnexus.module.system.service.dept.DeptService;
import cn.iocoder.foodnexus.module.system.api.user.dto.AdminUserRespDTO;
import io.swagger.v3.oas.annotations.Operation;
import io.swagger.v3.oas.annotations.Parameter;
......@@ -44,6 +46,8 @@ import org.springframework.web.bind.annotation.*;
import java.io.IOException;
import java.math.BigDecimal;
import java.util.ArrayList;
import java.util.Collections;
import java.util.List;
import java.util.Map;
import java.util.Optional;
......@@ -83,6 +87,9 @@ public class ErpSaleOrderController {
@Autowired
private ErpSupplierApi supplierApi;
@Autowired
private DeptService deptService;
/*@PostMapping("/create")
@Operation(summary = "创建销售订单")
@PreAuthorize("@ss.hasPermission('erp:sale-out:create')")
......@@ -117,11 +124,8 @@ public class ErpSaleOrderController {
@PostMapping("/pick-up")
@Operation(summary = "检获")
@Parameter(name = "id", description = "销售订单id", required = true)
@Parameter(name = "itemId", description = "销售订单子id", required = true)
public CommonResult<Boolean> pickUp(@RequestParam("id") Long id,
@RequestParam("itemId") Long itemId) {
saleOrderService.updatePickUp(id, itemId);
public CommonResult<Boolean> pickUp(@Valid @RequestBody ErpSaleOrderPickUpReqVO reqVO) {
saleOrderService.updatePickUp(reqVO.getId(), reqVO.getItemId(), reqVO.getCount());
return success(Boolean.TRUE);
}
......@@ -149,8 +153,13 @@ public class ErpSaleOrderController {
Map<Long, ErpPurchaseOrderDO> purchaseOrderMap = purchaseOrderService.getMap(CommonUtil.listConvert(saleOrderItemList, ErpSaleOrderItemDO::getPurchaseOrderId));
Map<Long, String> supplierMap = supplierApi.queryNameMapByIds(CommonUtil.listConvertSet(saleOrderItemList, ErpSaleOrderItemDO::getSupplierId));
return success(BeanUtils.toBean(saleOrder, ErpSaleOrderRespVO.class, saleOrderVO -> {
CustomerOrderDTO customerOrder = customerOrderApi.queryById(saleOrderVO.getCustomerOrderId());
saleOrderVO.setCustomerOrderCode(
Optional.ofNullable(customerOrderApi.queryById(saleOrderVO.getCustomerOrderId())).map(CustomerOrderDTO::getCode).orElse(""));
Optional.ofNullable(customerOrder).map(CustomerOrderDTO::getCode).orElse(""));
if (customerOrder != null && CommonUtil.isNotEmpty(customerOrder.getCustomerDeptId())) {
Map<Long, String> deptMap = deptService.queryNameMapByIds(Collections.singleton(customerOrder.getCustomerDeptId()), Boolean.TRUE);
MapUtils.findAndThen(deptMap, customerOrder.getCustomerDeptId(), saleOrderVO::setCustomerDeptName);
}
if (CommonUtil.isNotEmpty(saleOrderVO.getDeliveryStaffId())) {
saleOrderVO.setDeliveryStaffInfo(deliveryStaffApi.querybyStaffId(saleOrderVO.getDeliveryStaffId()));
}
......@@ -207,6 +216,7 @@ public class ErpSaleOrderController {
// 客户订单编号
Map<Long, CustomerOrderDTO> orderMap = customerOrderApi.getOrderMap(CommonUtil.listConvert(pageResult.getList(), ErpSaleOrderDO::getCustomerOrderId));
Map<Long, String> deptNameMap = deptService.queryNameMapByIds(CommonUtil.listConvertSet(new ArrayList<>(orderMap.values()), CustomerOrderDTO::getCustomerDeptId), Boolean.TRUE);
List<CustomerOrderItemDTO> customerOrderItems = customerOrderApi.queryItemsByIds(CommonUtil.listConvert(saleOrderItemList, ErpSaleOrderItemDO::getCustomerOrderItemId));
Map<Long, CustomerOrderItemDTO> customerOrderItemMap = CommonUtil.listConvertMap(customerOrderItems, CustomerOrderItemDTO::getId);
......@@ -230,6 +240,7 @@ public class ErpSaleOrderController {
MapUtils.findAndThen(userMap, Long.parseLong(saleOrder.getCreator()), user -> saleOrder.setCreatorName(user.getNickname()));
MapUtils.findAndThen(staffMap, saleOrder.getDeliveryStaffId(), saleOrder::setDeliveryStaffInfo);
MapUtils.findAndThen(orderMap, saleOrder.getCustomerOrderId(), order -> saleOrder.setCustomerOrderCode(order.getCode()));
MapUtils.findAndThen(deptNameMap, saleOrder.getCustomerDeptId(), saleOrder::setCustomerDeptName);
saleOrder.setPickUpStatusDetails(String.format(pickUpStatusDetails,
Optional.ofNullable(saleOrder.getItems()).orElse(Lists.newArrayList()).stream().filter(item -> SaleOrderPickUpStatus.ARRIVAL.equals(item.getPickUpStatus())).count(),
Optional.ofNullable(saleOrder.getItems()).orElse(Lists.newArrayList()).stream().filter(item -> !SaleOrderPickUpStatus.TO_BE.equals(item.getPickUpStatus())).count(),
......
package cn.iocoder.foodnexus.module.erp.controller.admin.sale.vo.order;
import io.swagger.v3.oas.annotations.media.Schema;
import jakarta.validation.constraints.DecimalMin;
import jakarta.validation.constraints.NotNull;
import lombok.Data;
import java.math.BigDecimal;
@Schema(description = "管理后台 - ERP 销售订单检获 Request VO")
@Data
public class ErpSaleOrderPickUpReqVO {
@Schema(description = "销售订单id", requiredMode = Schema.RequiredMode.REQUIRED)
@NotNull(message = "销售订单id不能为空")
private Long id;
@Schema(description = "销售订单子项id", requiredMode = Schema.RequiredMode.REQUIRED)
@NotNull(message = "销售订单子项id不能为空")
private Long itemId;
@Schema(description = "数量", requiredMode = Schema.RequiredMode.REQUIRED)
@NotNull(message = "数量不能为空")
@DecimalMin(value = "0", inclusive = false, message = "数量必须大于0")
private BigDecimal count;
}
......@@ -54,7 +54,7 @@ public class ErpSaleOrderRespVO {
@Schema(description = "合计数量", requiredMode = Schema.RequiredMode.REQUIRED, example = "15663")
@ExcelProperty("合计数量")
private Integer totalCount;
private BigDecimal totalCount;
@Schema(description = "最终合计价格", requiredMode = Schema.RequiredMode.REQUIRED, example = "24906")
@ExcelProperty("最终合计价格")
private Integer totalPrice;
......@@ -148,6 +148,11 @@ public class ErpSaleOrderRespVO {
@Schema(description = "拣货状态")
private SaleOrderPickUpStatus pickUpStatus;
@Schema(description = "灶点id")
private Long customerDeptId;
@Schema(description = "灶点名称")
private String customerDeptName;
@Schema(description = "收获仓库id", requiredMode = Schema.RequiredMode.REQUIRED, example = "27065")
private Long warehouseId;
......@@ -193,7 +198,10 @@ public class ErpSaleOrderRespVO {
@Schema(description = "产品数量", requiredMode = Schema.RequiredMode.REQUIRED, example = "100.00")
@NotNull(message = "产品数量不能为空")
private Integer count;
private BigDecimal count;
@Schema(description = "预期下单数量")
private BigDecimal expectedQuantity;
@Schema(description = "总价")
private Integer totalPrice;
......
......@@ -114,7 +114,10 @@ public class ErpSaleOrderSaveReqVO {
@Schema(description = "产品数量", requiredMode = Schema.RequiredMode.REQUIRED, example = "100.00")
@NotNull(message = "产品数量不能为空")
private Integer count;
private BigDecimal count;
@Schema(description = "预期下单数量")
private BigDecimal expectedQuantity;
@Schema(description = "税率,百分比", example = "99.88")
private BigDecimal taxPercent;
......
......@@ -74,7 +74,7 @@ public class ErpPurchaseInDO extends BaseDO {
/**
* 合计数量
*/
private Integer totalCount;
private BigDecimal totalCount;
/**
* 最终合计价格,单位:分
*
......
......@@ -69,7 +69,11 @@ public class ErpPurchaseInItemDO extends BaseDO {
/**
* 数量
*/
private Integer count;
private BigDecimal count;
/**
* 预期下单数量
*/
private BigDecimal expectedQuantity;
/**
* 总价,单位:分
*
......
......@@ -63,7 +63,7 @@ public class ErpPurchaseOrderDO extends BaseDO {
/**
* 合计数量
*/
private Integer totalCount;
private BigDecimal totalCount;
/**
* 最终合计价格,单位:分
*
......
......@@ -55,7 +55,11 @@ public class ErpPurchaseOrderItemDO extends BaseDO {
/**
* 数量
*/
private Integer count;
private BigDecimal count;
/**
* 预期下单数量
*/
private BigDecimal expectedQuantity;
/**
* 总价,单位:分
*
......
......@@ -77,7 +77,7 @@ public class ErpSaleOrderDO extends BaseDO {
/**
* 合计数量
*/
private Integer totalCount;
private BigDecimal totalCount;
/**
* 最终合计价格,单位:分
*
......
......@@ -63,7 +63,11 @@ public class ErpSaleOrderItemDO extends BaseDO {
/**
* 数量
*/
private Integer count;
private BigDecimal count;
/**
* 预期下单数量
*/
private BigDecimal expectedQuantity;
/**
* 总价,单位:分
*
......
......@@ -53,4 +53,8 @@ public interface ErpPurchaseInItemMapper extends BaseMapperX<ErpPurchaseInItemDO
return convertMap(result, obj -> (Long) obj.get("order_item_id"), obj -> (BigDecimal) obj.get("sumCount"));
}
default ErpPurchaseInItemDO selectByOrderItemId(Long orderItemId) {
return selectOne(ErpPurchaseInItemDO::getOrderItemId, orderItemId);
}
}
\ No newline at end of file
......@@ -27,4 +27,8 @@ public interface ErpPurchaseOrderItemMapper extends BaseMapperX<ErpPurchaseOrder
return delete(ErpPurchaseOrderItemDO::getOrderId, orderId);
}
default ErpPurchaseOrderItemDO selectByCustomerOrderItemId(Long customerOrderItemId) {
return selectOne(ErpPurchaseOrderItemDO::getCustomerOrderItemId, customerOrderItemId);
}
}
\ No newline at end of file
......@@ -132,7 +132,7 @@ public class ErpPurchaseInServiceImpl implements ErpPurchaseInService {
}
private void calculateTotalPrice(ErpPurchaseInDO purchaseIn, List<ErpPurchaseInItemDO> purchaseInItems) {
purchaseIn.setTotalCount(purchaseInItems.stream().mapToInt(ErpPurchaseInItemDO::getCount).sum());
purchaseIn.setTotalCount(getSumValue(purchaseInItems, ErpPurchaseInItemDO::getCount, BigDecimal::add, BigDecimal.ZERO));
purchaseIn.setTotalProductPrice(getSumValue(purchaseInItems, ErpPurchaseInItemDO::getTotalPrice, Integer::sum , 0));
purchaseIn.setTotalTaxPrice(getSumValue(purchaseInItems, ErpPurchaseInItemDO::getTaxPrice, BigDecimal::add, BigDecimal.ZERO));
purchaseIn.setTotalPrice(purchaseIn.getTotalProductPrice());
......@@ -181,9 +181,9 @@ public class ErpPurchaseInServiceImpl implements ErpPurchaseInService {
Integer bizType = approve ? ErpStockRecordBizTypeEnum.PURCHASE_IN.getType()
: ErpStockRecordBizTypeEnum.PURCHASE_IN_CANCEL.getType();
purchaseInItems.forEach(purchaseInItem -> {
Integer count = approve ? purchaseInItem.getCount() : - purchaseInItem.getCount();
BigDecimal count = approve ? purchaseInItem.getCount() : purchaseInItem.getCount().negate();
stockRecordService.createStockRecord(new ErpStockRecordCreateReqBO(
purchaseInItem.getProductId(), purchaseInItem.getWarehouseId(), BigDecimal.valueOf(count),
purchaseInItem.getProductId(), purchaseInItem.getWarehouseId(), count,
bizType, purchaseInItem.getInId(), purchaseInItem.getId(), purchaseIn.getNo()));
});
}
......@@ -219,7 +219,7 @@ public class ErpPurchaseInServiceImpl implements ErpPurchaseInService {
// 2. 转化为 ErpPurchaseInItemDO 列表
return convertList(list, o -> BeanUtils.toBean(o, ErpPurchaseInItemDO.class, item -> {
// item.setProductUnitId(productMap.get(item.getProductId()).getUnitId());
item.setTotalPrice(item.getProductPrice() * item.getCount());
item.setTotalPrice(MoneyUtils.priceMultiplyCount(item.getProductPrice(), item.getCount()));
if (item.getTotalPrice() == null) {
return;
}
......
......@@ -5,6 +5,7 @@ import cn.hutool.core.util.ObjectUtil;
import cn.iocoder.foodnexus.framework.common.enums.CheckTaskStatus;
import cn.iocoder.foodnexus.framework.common.pojo.PageResult;
import cn.iocoder.foodnexus.framework.common.util.CommonUtil;
import cn.iocoder.foodnexus.framework.common.util.number.MoneyUtils;
import cn.iocoder.foodnexus.framework.common.util.object.BeanUtils;
import cn.iocoder.foodnexus.framework.common.util.spring.SpringUtils;
import cn.iocoder.foodnexus.framework.security.core.util.SecurityFrameworkUtils;
......@@ -144,7 +145,7 @@ public class ErpPurchaseOrderServiceImpl implements ErpPurchaseOrderService {
}
private void calculateTotalPrice(ErpPurchaseOrderDO purchaseOrder, List<ErpPurchaseOrderItemDO> purchaseOrderItems) {
purchaseOrder.setTotalCount(getSumValue(purchaseOrderItems, ErpPurchaseOrderItemDO::getCount, Integer::sum));
purchaseOrder.setTotalCount(getSumValue(purchaseOrderItems, ErpPurchaseOrderItemDO::getCount, BigDecimal::add, BigDecimal.ZERO));
purchaseOrder.setTotalProductPrice(getSumValue(purchaseOrderItems, ErpPurchaseOrderItemDO::getTotalPrice, Integer::sum, 0));
purchaseOrder.setTotalTaxPrice(getSumValue(purchaseOrderItems, ErpPurchaseOrderItemDO::getTaxPrice, Integer::sum, 0));
purchaseOrder.setTotalPrice(purchaseOrder.getTotalProductPrice() + (purchaseOrder.getTotalTaxPrice()));
......@@ -190,7 +191,7 @@ public class ErpPurchaseOrderServiceImpl implements ErpPurchaseOrderService {
Map<Long, ErpProductDO> productMap = convertMap(productList, ErpProductDO::getId);*/
// 2. 转化为 ErpPurchaseOrderItemDO 列表
return convertList(list, o -> BeanUtils.toBean(o, ErpPurchaseOrderItemDO.class, item -> {
item.setTotalPrice((item.getProductPrice() * item.getCount()));
item.setTotalPrice(MoneyUtils.priceMultiplyCount(item.getProductPrice(), item.getCount()));
if (item.getTotalPrice() == null) {
return;
}
......@@ -523,6 +524,7 @@ public class ErpPurchaseOrderServiceImpl implements ErpPurchaseOrderService {
purhcaseOrderItem.setProductUnit(customerOrderItem.getProductInfo().getUnitName());
purhcaseOrderItem.setProductPrice(customerOrderItem.getOrderItemPrice());
purhcaseOrderItem.setCount(customerOrderItem.getOrderItemQuantity());
purhcaseOrderItem.setExpectedQuantity(customerOrderItem.getOrderItemQuantity());
purhcaseOrderItem.setCustomerOrderItemId(customerOrderItem.getId());
purhcaseOrderItem.setRemark(customerOrderItem.getCustomerRemark());
purchaseOrder.put(purhcaseOrderItem);
......
......@@ -121,8 +121,9 @@ public interface ErpSaleOrderService {
* 更新拣货
* @param id
* @param itemId
* @param count
*/
void updatePickUp(Long id, Long itemId);
void updatePickUp(Long id, Long itemId, BigDecimal count);
/**
* 取货,生成销售出库单
......
......@@ -10,11 +10,17 @@ import cn.iocoder.foodnexus.module.erp.api.vo.warehouse.WarehouseInfo;
import cn.iocoder.foodnexus.module.erp.controller.admin.sale.vo.order.*;
import cn.iocoder.foodnexus.module.erp.controller.admin.sale.vo.out.ErpSaleOutSaveReqVO;
import cn.iocoder.foodnexus.module.erp.dal.dataobject.purchase.ErpPurchaseOrderDO;
import cn.iocoder.foodnexus.module.erp.dal.dataobject.purchase.ErpPurchaseOrderItemDO;
import cn.iocoder.foodnexus.module.erp.dal.dataobject.purchase.ErpPurchaseInDO;
import cn.iocoder.foodnexus.module.erp.dal.dataobject.purchase.ErpPurchaseInItemDO;
import cn.iocoder.foodnexus.module.erp.dal.dataobject.sale.ErpSaleOrderDO;
import cn.iocoder.foodnexus.module.erp.dal.dataobject.sale.ErpSaleOrderItemDO;
import cn.iocoder.foodnexus.module.erp.dal.dataobject.sale.ErpSaleOutDO;
import cn.iocoder.foodnexus.module.erp.dal.dataobject.sale.ErpSaleOutItemDO;
import cn.iocoder.foodnexus.module.erp.dal.mysql.purchase.ErpPurchaseOrderMapper;
import cn.iocoder.foodnexus.module.erp.dal.mysql.purchase.ErpPurchaseOrderItemMapper;
import cn.iocoder.foodnexus.module.erp.dal.mysql.purchase.ErpPurchaseInItemMapper;
import cn.iocoder.foodnexus.module.erp.dal.mysql.purchase.ErpPurchaseInMapper;
import cn.iocoder.foodnexus.module.erp.dal.mysql.sale.ErpSaleOrderItemMapper;
import cn.iocoder.foodnexus.module.erp.dal.mysql.sale.ErpSaleOrderMapper;
import cn.iocoder.foodnexus.module.erp.dal.mysql.sale.ErpSaleOutItemMapper;
......@@ -24,6 +30,9 @@ import cn.iocoder.foodnexus.module.erp.api.enums.ErpAuditStatus;
import cn.iocoder.foodnexus.module.erp.enums.SaleOrderPickUpStatus;
import cn.iocoder.foodnexus.module.erp.service.finance.ErpAccountService;
import cn.iocoder.foodnexus.module.erp.service.purchase.ErpPurchaseOrderService;
import cn.iocoder.foodnexus.module.erp.service.stock.ErpStockRecordService;
import cn.iocoder.foodnexus.module.erp.service.stock.bo.ErpStockRecordCreateReqBO;
import cn.iocoder.foodnexus.module.erp.enums.stock.ErpStockRecordBizTypeEnum;
import cn.iocoder.foodnexus.module.order.api.CustomerOrderApi;
import cn.iocoder.foodnexus.module.order.api.CustomerOrderRecordApi;
import cn.iocoder.foodnexus.module.order.api.DeliveryStaffApi;
......@@ -33,6 +42,7 @@ import cn.iocoder.foodnexus.module.product.service.spu.ProductSpuService;
import cn.iocoder.foodnexus.module.system.api.user.AdminUserApi;
import com.baomidou.mybatisplus.core.toolkit.Wrappers;
import jakarta.annotation.Resource;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.annotation.Lazy;
import org.springframework.scheduling.annotation.Async;
......@@ -57,6 +67,7 @@ import static cn.iocoder.foodnexus.module.erp.enums.ErrorCodeConstants.*;
*/
@Service
@Validated
@Slf4j
public class ErpSaleOrderServiceImpl implements ErpSaleOrderService {
@Resource
......@@ -99,6 +110,18 @@ public class ErpSaleOrderServiceImpl implements ErpSaleOrderService {
private ErpPurchaseOrderMapper purchaseOrderMapper;
@Autowired
private ErpPurchaseOrderItemMapper purchaseOrderItemMapper;
@Autowired
private ErpPurchaseInItemMapper purchaseInItemMapper;
@Autowired
private ErpPurchaseInMapper purchaseInMapper;
@Autowired
private ErpStockRecordService stockRecordService;
@Autowired
@Lazy
private ErpSaleReturnService saleReturnService;
......@@ -164,7 +187,7 @@ public class ErpSaleOrderServiceImpl implements ErpSaleOrderService {
}
private void calculateTotalPrice(ErpSaleOrderDO saleOrder, List<ErpSaleOrderItemDO> saleOrderItems) {
saleOrder.setTotalCount(getSumValue(saleOrderItems, ErpSaleOrderItemDO::getCount, Integer::sum));
saleOrder.setTotalCount(getSumValue(saleOrderItems, ErpSaleOrderItemDO::getCount, BigDecimal::add, BigDecimal.ZERO));
saleOrder.setTotalProductPrice(getSumValue(saleOrderItems, ErpSaleOrderItemDO::getTotalPrice, Integer::sum, 0));
saleOrder.setTotalTaxPrice(getSumValue(saleOrderItems, ErpSaleOrderItemDO::getTaxPrice, BigDecimal::add, BigDecimal.ZERO));
saleOrder.setTotalPrice(saleOrder.getTotalProductPrice());
......@@ -208,7 +231,7 @@ public class ErpSaleOrderServiceImpl implements ErpSaleOrderService {
// 2. 转化为 ErpSaleOrderItemDO 列表
return convertList(list, o -> BeanUtils.toBean(o, ErpSaleOrderItemDO.class, item -> {
// item.setProductUnit(productMap.get(item.getProductId()).getUni());
item.setTotalPrice(item.getProductPrice() * item.getCount());
item.setTotalPrice(MoneyUtils.priceMultiplyCount(item.getProductPrice(), item.getCount()));
if (item.getTotalPrice() == null) {
return;
}
......@@ -246,7 +269,7 @@ public class ErpSaleOrderServiceImpl implements ErpSaleOrderService {
if (item.getOutCount().equals(outCount)) {
return;
}
if (outCount.compareTo(BigDecimal.valueOf(item.getCount())) > 0) {
if (outCount.compareTo(item.getCount()) > 0) {
throw exception(SALE_ORDER_ITEM_OUT_FAIL_PRODUCT_EXCEED,
productService.getSpu(item.getProductId()).getName(), item.getCount());
}
......@@ -357,7 +380,8 @@ public class ErpSaleOrderServiceImpl implements ErpSaleOrderService {
@Override
@Transactional(rollbackFor = Exception.class)
public void updatePickUp(Long id, Long itemId) {
public void updatePickUp(Long id, Long itemId, BigDecimal count) {
// 1. 校验销售订单和子项存在
ErpSaleOrderDO saleOrder = getSaleOrder(id);
if (CommonUtil.isEmpty(saleOrder)) {
throw exception(SALE_ORDER_NOT_EXISTS);
......@@ -366,26 +390,147 @@ public class ErpSaleOrderServiceImpl implements ErpSaleOrderService {
if (CommonUtil.isEmpty(saleItemOrder)) {
throw exception(SALE_ORDER_NOT_EXISTS);
}
// 2. 加分布式锁
String lock = String.format(SALE_ORDER_LOCK, id);
RedisUtils.tryLockRds(lock);
try {
CustomerOrderDTO customerOrder = customerOrderApi.queryById(saleOrder.getCustomerOrderId());
// 3. 记录旧的 count
BigDecimal oldSaleItemCount = saleItemOrder.getCount();
// 4. 更新 ErpSaleOrderItemDO
Integer newTotalPrice = MoneyUtils.priceMultiplyCount(saleItemOrder.getProductPrice(), count);
saleOrderItemMapper.update(Wrappers.<ErpSaleOrderItemDO>lambdaUpdate()
.set(ErpSaleOrderItemDO::getCount, count)
.set(ErpSaleOrderItemDO::getTotalPrice, newTotalPrice)
.set(ErpSaleOrderItemDO::getPickUpTime, LocalDateTime.now())
.set(ErpSaleOrderItemDO::getPickUpStatus, SaleOrderPickUpStatus.PICK_UP.getType())
.eq(ErpSaleOrderItemDO::getId, itemId));
log.info("[updatePickUp] 销售订单项更新: saleOrderId={}, itemId={}, oldCount={}, newCount={}, newTotalPrice={}",
id, itemId, oldSaleItemCount, count, newTotalPrice);
// 5. 重新计算 ErpSaleOrderDO 的 totalCount 和 totalProductPrice/totalPrice
List<ErpSaleOrderItemDO> allSaleItems = saleOrderItemMapper.selectListByOrderId(saleOrder.getId());
ErpSaleOrderDO updateSaleOrder = new ErpSaleOrderDO();
updateSaleOrder.setId(saleOrder.getId());
calculateTotalPrice(updateSaleOrder, allSaleItems);
saleOrderMapper.updateById(updateSaleOrder);
// 6. 更新 CustomerOrderItemDO
CustomerOrderItemDTO updateCustomerOrderItem = new CustomerOrderItemDTO();
updateCustomerOrderItem.setId(saleItemOrder.getCustomerOrderItemId());
updateCustomerOrderItem.setOrderItemQuantity(count);
updateCustomerOrderItem.setOrderItemTotal(MoneyUtils.priceMultiplyCount(
customerOrderApi.queryItemsByIds(CommonUtil.asList(saleItemOrder.getCustomerOrderItemId()))
.stream().findFirst().map(CustomerOrderItemDTO::getOrderItemPrice).orElse(0),
count));
customerOrderApi.updateItems(CommonUtil.asList(updateCustomerOrderItem));
log.info("[updatePickUp] 客户订单项更新: customerOrderItemId={}, newQuantity={}, newTotal={}",
updateCustomerOrderItem.getId(), count, updateCustomerOrderItem.getOrderItemTotal());
// 7. 重新计算 CustomerOrderDO.orderAmount(所有子项 orderItemTotal 之和)
List<CustomerOrderItemDTO> allCustomerOrderItems = customerOrderApi.queryItemsByOrderId(saleOrder.getCustomerOrderId());
int newOrderAmount = allCustomerOrderItems.stream()
.mapToInt(item -> item.getOrderItemTotal() != null ? item.getOrderItemTotal() : 0)
.sum();
// 通过差值方式更新 orderAmount:先查出旧值,计算差值
CustomerOrderDTO customerOrder = customerOrderApi.queryById(saleOrder.getCustomerOrderId());
int oldOrderAmount = customerOrder.getOrderAmount() != null ? customerOrder.getOrderAmount() : 0;
int diffAmount = newOrderAmount - oldOrderAmount;
if (diffAmount != 0) {
customerOrderApi.updateActualAmount(saleOrder.getCustomerOrderId(), diffAmount);
}
// 8. 更新 ErpPurchaseOrderItemDO
ErpPurchaseOrderItemDO purchaseOrderItem = purchaseOrderItemMapper.selectByCustomerOrderItemId(saleItemOrder.getCustomerOrderItemId());
if (purchaseOrderItem != null) {
BigDecimal oldPurchaseOrderItemCount = purchaseOrderItem.getCount();
Integer purchaseItemTotalPrice = MoneyUtils.priceMultiplyCount(purchaseOrderItem.getProductPrice(), count);
purchaseOrderItem.setCount(count);
purchaseOrderItem.setTotalPrice(purchaseItemTotalPrice);
purchaseOrderItemMapper.updateById(purchaseOrderItem);
log.info("[updatePickUp] 采购订单项更新: purchaseOrderItemId={}, oldCount={}, newCount={}, newTotalPrice={}",
purchaseOrderItem.getId(), oldPurchaseOrderItemCount, count, purchaseItemTotalPrice);
// 9. 重新计算 ErpPurchaseOrderDO 的 totalCount 和 totalProductPrice/totalPrice
List<ErpPurchaseOrderItemDO> allPurchaseOrderItems = purchaseOrderItemMapper.selectListByOrderId(purchaseOrderItem.getOrderId());
ErpPurchaseOrderDO updatePurchaseOrder = new ErpPurchaseOrderDO();
updatePurchaseOrder.setId(purchaseOrderItem.getOrderId());
updatePurchaseOrder.setTotalCount(getSumValue(allPurchaseOrderItems, ErpPurchaseOrderItemDO::getCount, BigDecimal::add, BigDecimal.ZERO));
updatePurchaseOrder.setTotalProductPrice(getSumValue(allPurchaseOrderItems, ErpPurchaseOrderItemDO::getTotalPrice, Integer::sum, 0));
updatePurchaseOrder.setTotalPrice(updatePurchaseOrder.getTotalProductPrice());
// 10. 更新 ErpPurchaseOrderDO.depositPrice
// 重新查询该采购订单对应的客户订单总金额
ErpPurchaseOrderDO purchaseOrder = purchaseOrderMapper.selectById(purchaseOrderItem.getOrderId());
if (purchaseOrder != null && purchaseOrder.getCustomerOrderId() != null) {
List<CustomerOrderItemDTO> customerItems = customerOrderApi.queryItemsByOrderId(purchaseOrder.getCustomerOrderId());
// 筛选属于该供应商的子项金额之和作为 depositPrice
List<ErpPurchaseOrderItemDO> thisPurchaseItems = purchaseOrderItemMapper.selectListByOrderId(purchaseOrder.getId());
Set<Long> customerOrderItemIds = new HashSet<>();
for (ErpPurchaseOrderItemDO item : thisPurchaseItems) {
if (item.getCustomerOrderItemId() != null) {
customerOrderItemIds.add(item.getCustomerOrderItemId());
}
}
int depositPrice = customerItems.stream()
.filter(item -> customerOrderItemIds.contains(item.getId()))
.mapToInt(item -> item.getOrderItemTotal() != null ? item.getOrderItemTotal() : 0)
.sum();
updatePurchaseOrder.setDepositPrice(depositPrice);
}
purchaseOrderMapper.updateById(updatePurchaseOrder);
// 11. 更新 ErpPurchaseInItemDO
ErpPurchaseInItemDO purchaseInItem = purchaseInItemMapper.selectByOrderItemId(purchaseOrderItem.getId());
if (purchaseInItem != null) {
BigDecimal oldPurchaseInItemCount = purchaseInItem.getCount();
Integer purchaseInItemTotalPrice = MoneyUtils.priceMultiplyCount(purchaseInItem.getProductPrice(), count);
purchaseInItem.setCount(count);
purchaseInItem.setTotalPrice(purchaseInItemTotalPrice);
purchaseInItemMapper.updateById(purchaseInItem);
log.info("[updatePickUp] 采购入库项更新: purchaseInItemId={}, oldCount={}, newCount={}, newTotalPrice={}",
purchaseInItem.getId(), oldPurchaseInItemCount, count, purchaseInItemTotalPrice);
// 12. 重新计算 ErpPurchaseInDO 的 totalCount 和 totalProductPrice/totalPrice
ErpPurchaseInDO purchaseIn = purchaseInMapper.selectById(purchaseInItem.getInId());
if (purchaseIn != null) {
List<ErpPurchaseInItemDO> allPurchaseInItems = purchaseInItemMapper.selectListByInId(purchaseIn.getId());
purchaseIn.setTotalCount(getSumValue(allPurchaseInItems, ErpPurchaseInItemDO::getCount, BigDecimal::add, BigDecimal.ZERO));
purchaseIn.setTotalProductPrice(getSumValue(allPurchaseInItems, ErpPurchaseInItemDO::getTotalPrice, Integer::sum, 0));
purchaseIn.setTotalPrice(purchaseIn.getTotalProductPrice());
purchaseInMapper.updateById(purchaseIn);
}
// 13. 库存差值补录
BigDecimal diff = count.subtract(oldPurchaseInItemCount);
if (diff.compareTo(BigDecimal.ZERO) != 0) {
stockRecordService.createStockRecord(new ErpStockRecordCreateReqBO(
purchaseInItem.getProductId(), purchaseInItem.getWarehouseId(), diff,
ErpStockRecordBizTypeEnum.PURCHASE_IN.getType(),
purchaseInItem.getInId(), purchaseInItem.getId(),
purchaseIn != null ? purchaseIn.getNo() : ""));
log.info("[updatePickUp] 库存差值补录: productId={}, warehouseId={}, diff={}",
purchaseInItem.getProductId(), purchaseInItem.getWarehouseId(), diff);
}
}
}
// 14. 日志
log.info("[updatePickUp] 完成: saleOrderId={}, itemId={}, oldCount={}, newCount={}", id, itemId, oldSaleItemCount, count);
Long allCount = saleOrderItemMapper.selectCount(ErpSaleOrderItemDO::getOrderId, saleOrder.getId());
// 15. 全部检获完成后触发 SORTING 事件
Long allItemCount = saleOrderItemMapper.selectCount(ErpSaleOrderItemDO::getOrderId, saleOrder.getId());
Long pickUpCount = saleOrderItemMapper.selectCount(Wrappers.<ErpSaleOrderItemDO>lambdaQuery()
.eq(ErpSaleOrderItemDO::getOrderId, saleOrder.getId())
.eq(ErpSaleOrderItemDO::getPickUpStatus, SaleOrderPickUpStatus.PICK_UP.getType()));
if (allCount > 0 && Objects.equals(pickUpCount, allCount)) {
if (allItemCount > 0 && Objects.equals(pickUpCount, allItemCount)) {
saleOrderMapper.update(Wrappers.<ErpSaleOrderDO>lambdaUpdate()
.set(ErpSaleOrderDO::getPickUpStatus, SaleOrderPickUpStatus.PICK_UP.getType())
.eq(ErpSaleOrderDO::getId, saleOrder.getId()));
String warehouseName = Optional.ofNullable(customerOrder.getWarehouseInfo()).map(WarehouseInfo::getName).orElse("");
CustomerOrderDTO customerOrderForEvent = customerOrderApi.queryById(saleOrder.getCustomerOrderId());
String warehouseName = Optional.ofNullable(customerOrderForEvent.getWarehouseInfo()).map(WarehouseInfo::getName).orElse("");
CustomerOrderRecordEvent event = new CustomerOrderRecordEvent();
event.setOrderStatus(CustomerOrderStatus.SORTING);
event.setCustomerOrderId(saleOrder.getCustomerOrderId());
......@@ -459,7 +604,7 @@ public class ErpSaleOrderServiceImpl implements ErpSaleOrderService {
item.setProductId(saleOrderItem.getProductId());
item.setProductUnit(saleOrderItem.getProductUnit());
item.setProductPrice(saleOrderItem.getProductPrice());
item.setCount(BigDecimal.valueOf(saleOrderItem.getCount()));
item.setCount(saleOrderItem.getCount());
item.setTaxPercent(saleOrderItem.getTaxPercent());
item.setRemark(saleOrderItem.getRemark());
item.setCustomerOrderItemId(saleOrderItem.getCustomerOrderItemId());
......@@ -627,6 +772,7 @@ public class ErpSaleOrderServiceImpl implements ErpSaleOrderService {
item.setProductUnit(orderItem.getProductInfo().getUnitName());
item.setProductPrice(orderItem.getOrderItemPrice());
item.setCount(orderItem.getOrderItemQuantity());
item.setExpectedQuantity(orderItem.getOrderItemQuantity());
item.setSupplierId(orderItem.getSupplierId());
item.setPickUpStatus(SaleOrderPickUpStatus.TO_BE);
item.setPurchaseOrderId(Optional.ofNullable(purchaseOrderMapper.selectOne(Wrappers.<ErpPurchaseOrderDO>lambdaQuery()
......
......@@ -56,7 +56,11 @@ public class CustomerOrderItemDTO {
/**
* 订单商品数量
*/
private Integer orderItemQuantity;
private BigDecimal orderItemQuantity;
/**
* 预期下单数量
*/
private BigDecimal expectedQuantity;
/**
* 市场价,单位使用:分
*/
......
package cn.iocoder.foodnexus.module.order.controller.admin.checktask.vo;
import lombok.*;
import java.math.BigDecimal;
import java.util.*;
import io.swagger.v3.oas.annotations.media.Schema;
import cn.iocoder.foodnexus.framework.common.pojo.PageParam;
......@@ -32,7 +33,7 @@ public class CheckTaskItemsPageReqVO extends PageParam {
private String picUrl;
@Schema(description = "检查数量", example = "24148")
private Integer checkCount;
private BigDecimal checkCount;
@Schema(description = "商品单位", example = "李四")
private String unitName;
......
......@@ -2,6 +2,7 @@ package cn.iocoder.foodnexus.module.order.controller.admin.checktask.vo;
import io.swagger.v3.oas.annotations.media.Schema;
import lombok.*;
import java.math.BigDecimal;
import java.util.*;
import org.springframework.format.annotation.DateTimeFormat;
import java.time.LocalDateTime;
......@@ -50,7 +51,7 @@ public class CheckTaskItemsRespVO {
@Schema(description = "检查数量", requiredMode = Schema.RequiredMode.REQUIRED, example = "24148")
@ExcelProperty("检查数量")
private Integer checkCount;
private BigDecimal checkCount;
@Schema(description = "商品单位", example = "李四")
@ExcelProperty("商品单位")
......
......@@ -2,6 +2,7 @@ package cn.iocoder.foodnexus.module.order.controller.admin.checktask.vo;
import io.swagger.v3.oas.annotations.media.Schema;
import lombok.*;
import java.math.BigDecimal;
import java.util.*;
import jakarta.validation.constraints.*;
......@@ -41,7 +42,7 @@ public class CheckTaskItemsSaveReqVO {
@Schema(description = "检查数量", requiredMode = Schema.RequiredMode.REQUIRED, example = "24148")
@NotNull(message = "检查数量不能为空")
private Integer checkCount;
private BigDecimal checkCount;
@Schema(description = "商品单位", example = "李四")
private String unitName;
......
......@@ -72,7 +72,10 @@ public class CustomerOrderItemExcelVO {
@Schema(description = "订单商品数量", requiredMode = Schema.RequiredMode.REQUIRED)
@ExcelProperty("下单数量")
private Integer orderItemQuantity;
private BigDecimal orderItemQuantity;
@Schema(description = "预期下单数量")
private BigDecimal expectedQuantity;
@Schema(description = "订单商品单价,单位:分", requiredMode = Schema.RequiredMode.REQUIRED, example = "29922")
// @ExcelProperty("订单商品单价,单位:分")
......
......@@ -48,7 +48,10 @@ public class CustomerOrderItemPageReqVO extends PageParam {
private Integer orderItemTotal;
@Schema(description = "订单商品数量")
private Integer orderItemQuantity;
private BigDecimal orderItemQuantity;
@Schema(description = "预期下单数量")
private BigDecimal expectedQuantity;
@Schema(description = "签收数量")
private BigDecimal signedQuantity;
......
......@@ -66,7 +66,10 @@ public class CustomerOrderItemRespVO {
@Schema(description = "订单商品数量", requiredMode = Schema.RequiredMode.REQUIRED)
@ExcelProperty("订单商品数量")
private Integer orderItemQuantity;
private BigDecimal orderItemQuantity;
@Schema(description = "预期下单数量")
private BigDecimal expectedQuantity;
@Schema(description = "签收数量", requiredMode = Schema.RequiredMode.REQUIRED)
@ExcelProperty("签收数量")
......
......@@ -50,7 +50,10 @@ public class CustomerOrderItemSaveReqVO {
@Schema(description = "订单商品数量", requiredMode = Schema.RequiredMode.REQUIRED)
@NotNull(message = "订单商品数量不能为空")
private Integer orderItemQuantity;
private BigDecimal orderItemQuantity;
@Schema(description = "预期下单数量")
private BigDecimal expectedQuantity;
@Schema(description = "签收数量", requiredMode = Schema.RequiredMode.REQUIRED)
@NotNull(message = "签收数量不能为空")
......
......@@ -32,6 +32,7 @@ import org.springframework.validation.annotation.Validated;
import org.springframework.web.bind.annotation.*;
import javax.sql.rowset.serial.SerialException;
import java.math.RoundingMode;
import java.util.List;
import java.util.Map;
import java.util.Set;
......@@ -66,6 +67,14 @@ public class AppCustomerOrderController {
@PostMapping("/create")
@Operation(summary = "创建客户总订单")
public CommonResult<Long> createCustomerOrder(@Valid @RequestBody AppCustomerOrderSaveReqVO createReqVO) {
// orderItemQuantity 只保留小数点后两位,不四舍五入
if (CommonUtil.isNotEmpty(createReqVO.getOrderItems())) {
createReqVO.getOrderItems().forEach(item -> {
if (item.getOrderItemQuantity() != null) {
item.setOrderItemQuantity(item.getOrderItemQuantity().setScale(2, RoundingMode.DOWN));
}
});
}
return success(customerOrderService.appCreateCustomerOrder(createReqVO));
}
......
......@@ -31,8 +31,7 @@ public class AppCustomerOrderItemSaveReqVO {
@Schema(description = "订单商品数量", requiredMode = Schema.RequiredMode.REQUIRED)
@NotNull(message = "订单商品数量不能为空")
@Min(value = 1, message = "订单商品数量不能小于1")
private Integer orderItemQuantity;
private BigDecimal orderItemQuantity;
@Schema(description = "商品对应供应商id", hidden = true)
private Long supplierId;
......
package cn.iocoder.foodnexus.module.order.dal.dataobject.checktaskitems;
import lombok.*;
import java.math.BigDecimal;
import java.util.*;
import java.time.LocalDateTime;
import java.time.LocalDateTime;
......@@ -62,7 +63,7 @@ public class CheckTaskItemsDO extends BaseDO {
/**
* 检查数量
*/
private Integer checkCount;
private BigDecimal checkCount;
/**
* 商品单位
*/
......
......@@ -77,7 +77,11 @@ public class CustomerOrderItemDO extends BaseDO {
/**
* 订单商品数量
*/
private Integer orderItemQuantity;
private BigDecimal orderItemQuantity;
/**
* 预期下单数量
*/
private BigDecimal expectedQuantity;
/**
* 签收数量
*/
......
......@@ -249,7 +249,7 @@ public class CustomerOrderServiceImpl implements CustomerOrderService, CustomerO
if (customerProductMap.containsKey(item.getProductId())) {
CustomerVisibleProductRespDTO.CustomerProduct customerProduct = customerProductMap.get(item.getProductId());
item.setOrderItemPrice(customerProduct.getSupplierQuote());
item.setOrderItemTotal(customerProduct.getSupplierQuote() * item.getOrderItemQuantity());
item.setOrderItemTotal(MoneyUtils.priceMultiplyCount(customerProduct.getSupplierQuote(), item.getOrderItemQuantity()));
item.setMarketPrice(customerProduct.getMarketPrice());
item.setDiscount(customerProduct.getFloatingRate());
InquireSupplierPushDO inquireSupplierPush = inquireSupplierPushService.getInquireSupplierPush(customerProduct.getInquireSupplierId());
......@@ -286,6 +286,7 @@ public class CustomerOrderServiceImpl implements CustomerOrderService, CustomerO
item.setProductName(item.getProductInfo().getName());
item.setSignedQuantity(BigDecimal.ZERO);
item.setSignedTotal(0);
item.setExpectedQuantity(orderItem.getOrderItemQuantity());
if (shoppingMap.containsKey(orderItem.getProductId())) {
item.setCustomerRemark(shoppingMap.get(orderItem.getProductId()).getRemark());
}
......@@ -430,7 +431,7 @@ public class CustomerOrderServiceImpl implements CustomerOrderService, CustomerO
remark.setRemark(saleOutItem.getRemark());
updateItem.setOrderRemark(remark);
} else {
updateItem.setSignedQuantity(BigDecimal.valueOf(customerOrderItem.getOrderItemQuantity()));
updateItem.setSignedQuantity(customerOrderItem.getOrderItemQuantity());
}
updateItem.setSignedTotal(MoneyUtils.multiplyAndRoundToInt(updateItem.getSignedQuantity(), customerOrderItem.getOrderItemPrice()));
actualAmount.updateAndGet(v -> v + updateItem.getSignedTotal());
......@@ -488,8 +489,8 @@ public class CustomerOrderServiceImpl implements CustomerOrderService, CustomerO
result.setRemark(saleOutItem.getRemark());
result.setRemarkFiles(saleOutItem.getRemarkFiles());
} else {
result.setSignedQuantity(BigDecimal.valueOf(customerOrderItem.getOrderItemQuantity()));
result.setSignedTotal(customerOrderItem.getOrderItemQuantity() * customerOrderItem.getOrderItemPrice());
result.setSignedQuantity(customerOrderItem.getOrderItemQuantity());
result.setSignedTotal(MoneyUtils.priceMultiplyCount(customerOrderItem.getOrderItemPrice(), customerOrderItem.getOrderItemQuantity()));
}
return result;
});
......
......@@ -63,6 +63,9 @@ public class ProductSpuRespVO {
@Schema(description = "商品单位")
private String unitName;
@Schema(description = "计量方式")
private String measureType;
// ========== 统计相关字段 =========
@Schema(description = "商品销量", requiredMode = Schema.RequiredMode.REQUIRED, example = "2000")
......
......@@ -43,6 +43,9 @@ public class ProductSpuSaveReqVO {
@Schema(description = "商品单位")
private String unitName;
@Schema(description = "计量方式", example = "按重量")
private String measureType;
// ========== 统计相关字段 =========
@Schema(description = "虚拟销量", example = "66")
......
......@@ -41,6 +41,9 @@ public class AppProductSpuDetailRespVO {
@Schema(description = "商品单位")
private String unitName;
@Schema(description = "计量方式")
private String measureType;
@Schema(description = "市场价")
private Integer marketPrice;
......
......@@ -36,6 +36,9 @@ public class AppProductSpuRespVO {
@Schema(description = "商品单位")
private String unitName;
@Schema(description = "计量方式")
private String measureType;
@Schema(description = "市场价")
private Integer marketPrice;
......
......@@ -86,6 +86,11 @@ public class ProductSpuDO extends BaseDO {
*/
private String unitName;
/**
* 计量方式
*/
private String measureType;
// ========== 统计相关字段 =========
/**
......
......@@ -82,7 +82,7 @@ spring:
host: 127.0.0.1 # 地址
port: 6379 # 端口
database: 2 # 数据库索引
password: 123456 # 密码,建议生产环境开启
password: '@#d43ed845$%'# 123456 # 密码,建议生产环境开启
--- #################### 定时任务相关配置 ####################
......
......@@ -3,7 +3,7 @@ spring:
name: foodnexus-server
profiles:
active: pro
active: local
main:
allow-circular-references: true # 允许循环依赖,因为项目是三层架构,无法避免这个情况。
......
-- 订单商品数量 int -> decimal
-- 订单商品数量 int -> decimal
ALTER TABLE order_customer_order_item MODIFY COLUMN order_item_quantity decimal(11,2) NOT NULL DEFAULT '0.00' COMMENT '订单商品数量';
-- 销售订单项数量
ALTER TABLE erp_sale_order_items MODIFY COLUMN count decimal(11,2) NOT NULL DEFAULT '0.00' COMMENT '数量';
-- 采购订单项数量
ALTER TABLE erp_purchase_order_items MODIFY COLUMN count decimal(11,2) NOT NULL DEFAULT '0.00' COMMENT '数量';
-- 采购入库项数量
ALTER TABLE erp_purchase_in_items MODIFY COLUMN count decimal(11,2) NOT NULL DEFAULT '0.00' COMMENT '数量';
-- 来料质检清单检查数量
ALTER TABLE order_check_task_items MODIFY COLUMN check_count decimal(11,2) NOT NULL DEFAULT '0.00' COMMENT '检查数量';
-- 父表 total_count 联动修改
ALTER TABLE erp_sale_order MODIFY COLUMN total_count decimal(11,2) NOT NULL DEFAULT '0.00' COMMENT '合计数量';
ALTER TABLE erp_purchase_order MODIFY COLUMN total_count decimal(11,2) NOT NULL DEFAULT '0.00' COMMENT '合计数量';
ALTER TABLE erp_purchase_in MODIFY COLUMN total_count decimal(11,2) NOT NULL DEFAULT '0.00' COMMENT '合计数量';
ALTER TABLE order_customer_order_item ADD COLUMN expected_quantity decimal(11,2) NOT NULL DEFAULT '0.00' COMMENT '预期下单数量';
ALTER TABLE order_customer_order_item ADD COLUMN expected_quantity decimal(11,2) NOT NULL DEFAULT '0.00' COMMENT '预期下单数量';
ALTER TABLE erp_sale_order_items ADD COLUMN expected_quantity decimal(11,2) NOT NULL DEFAULT '0.00' COMMENT '预期下单数量';
ALTER TABLE erp_purchase_order_items ADD COLUMN expected_quantity decimal(11,2) NOT NULL DEFAULT '0.00' COMMENT '预期下单数量';
ALTER TABLE erp_purchase_in_items ADD COLUMN expected_quantity decimal(11,2) NOT NULL DEFAULT '0.00' COMMENT '预期下单数量';
ALTER TABLE product_spu ADD COLUMN measure_type VARCHAR(64) DEFAULT NULL COMMENT '计量方式' AFTER unit_name;
ALTER TABLE product_spu ADD COLUMN measure_type VARCHAR(64) DEFAULT NULL COMMENT '计量方式' AFTER unit_name;
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