ERP:采购入库 50%

This commit is contained in:
YunaiV 2024-02-12 10:42:23 +08:00
parent 5d092361ed
commit 0599f5392c
13 changed files with 1177 additions and 0 deletions

View File

@ -26,6 +26,14 @@ public interface ErrorCodeConstants {
ErrorCode PURCHASE_ORDER_ITEM_RETURN_FAIL_IN_EXCEED = new ErrorCode(1_030_101_009, "采购订单项({})超过最大允许退货数量({})"); ErrorCode PURCHASE_ORDER_ITEM_RETURN_FAIL_IN_EXCEED = new ErrorCode(1_030_101_009, "采购订单项({})超过最大允许退货数量({})");
ErrorCode PURCHASE_ORDER_PROCESS_FAIL_EXISTS_RETURN = new ErrorCode(1_030_101_010, "反审核失败,已存在对应的采购退货单"); ErrorCode PURCHASE_ORDER_PROCESS_FAIL_EXISTS_RETURN = new ErrorCode(1_030_101_010, "反审核失败,已存在对应的采购退货单");
// ========== ERP 采购入库1-030-102-000 ==========
ErrorCode PURCHASE_IN_NOT_EXISTS = new ErrorCode(1_030_102_000, "采购入库单不存在");
ErrorCode PURCHASE_IN_DELETE_FAIL_APPROVE = new ErrorCode(1_030_102_001, "采购入库单({})已审核,无法删除");
ErrorCode PURCHASE_IN_PROCESS_FAIL = new ErrorCode(1_030_102_002, "反审核失败,只有已审核的入库单才能反审核");
ErrorCode PURCHASE_IN_APPROVE_FAIL = new ErrorCode(1_030_102_003, "审核失败,只有未审核的入库单才能审核");
ErrorCode PURCHASE_IN_NO_EXISTS = new ErrorCode(1_030_102_004, "生成入库单失败,请重新提交");
ErrorCode PURCHASE_IN_UPDATE_FAIL_APPROVE = new ErrorCode(1_030_102_005, "采购入库单({})已审核,无法修改");
// ========== ERP 客户1-030-200-000========== // ========== ERP 客户1-030-200-000==========
ErrorCode CUSTOMER_NOT_EXISTS = new ErrorCode(1_020_200_000, "客户不存在"); ErrorCode CUSTOMER_NOT_EXISTS = new ErrorCode(1_020_200_000, "客户不存在");
ErrorCode CUSTOMER_NOT_ENABLE = new ErrorCode(1_020_200_001, "客户({})未启用"); ErrorCode CUSTOMER_NOT_ENABLE = new ErrorCode(1_020_200_001, "客户({})未启用");

View File

@ -36,6 +36,9 @@ public enum ErpStockRecordBizTypeEnum implements IntArrayValuable {
SALE_RETURN(60, "销售退货入库"), SALE_RETURN(60, "销售退货入库"),
SALE_RETURN_CANCEL(61, "销售退货入库(作废)"), SALE_RETURN_CANCEL(61, "销售退货入库(作废)"),
PURCHASE_IN(70, "采购入库"),
PURCHASE_IN_CANCEL(71, "采购入库(作废)"),
; ;
public static final int[] ARRAYS = Arrays.stream(values()).mapToInt(ErpStockRecordBizTypeEnum::getType).toArray(); public static final int[] ARRAYS = Arrays.stream(values()).mapToInt(ErpStockRecordBizTypeEnum::getType).toArray();

View File

@ -0,0 +1,165 @@
package cn.iocoder.yudao.module.erp.controller.admin.purchase;
import cn.hutool.core.collection.CollUtil;
import cn.iocoder.yudao.framework.common.pojo.CommonResult;
import cn.iocoder.yudao.framework.common.pojo.PageParam;
import cn.iocoder.yudao.framework.common.pojo.PageResult;
import cn.iocoder.yudao.framework.common.util.collection.MapUtils;
import cn.iocoder.yudao.framework.common.util.object.BeanUtils;
import cn.iocoder.yudao.framework.excel.core.util.ExcelUtils;
import cn.iocoder.yudao.framework.operatelog.core.annotations.OperateLog;
import cn.iocoder.yudao.module.erp.controller.admin.product.vo.product.ErpProductRespVO;
import cn.iocoder.yudao.module.erp.controller.admin.purchase.vo.in.ErpPurchaseInPageReqVO;
import cn.iocoder.yudao.module.erp.controller.admin.purchase.vo.in.ErpPurchaseInRespVO;
import cn.iocoder.yudao.module.erp.controller.admin.purchase.vo.in.ErpPurchaseInSaveReqVO;
import cn.iocoder.yudao.module.erp.dal.dataobject.purchase.ErpPurchaseInDO;
import cn.iocoder.yudao.module.erp.dal.dataobject.purchase.ErpPurchaseInItemDO;
import cn.iocoder.yudao.module.erp.dal.dataobject.purchase.ErpSupplierDO;
import cn.iocoder.yudao.module.erp.dal.dataobject.stock.ErpStockDO;
import cn.iocoder.yudao.module.erp.service.product.ErpProductService;
import cn.iocoder.yudao.module.erp.service.purchase.ErpPurchaseInService;
import cn.iocoder.yudao.module.erp.service.purchase.ErpSupplierService;
import cn.iocoder.yudao.module.erp.service.stock.ErpStockService;
import cn.iocoder.yudao.module.system.api.user.AdminUserApi;
import cn.iocoder.yudao.module.system.api.user.dto.AdminUserRespDTO;
import io.swagger.v3.oas.annotations.Operation;
import io.swagger.v3.oas.annotations.Parameter;
import io.swagger.v3.oas.annotations.tags.Tag;
import jakarta.annotation.Resource;
import jakarta.servlet.http.HttpServletResponse;
import jakarta.validation.Valid;
import org.springframework.security.access.prepost.PreAuthorize;
import org.springframework.validation.annotation.Validated;
import org.springframework.web.bind.annotation.*;
import java.io.IOException;
import java.math.BigDecimal;
import java.util.List;
import java.util.Map;
import static cn.iocoder.yudao.framework.common.pojo.CommonResult.success;
import static cn.iocoder.yudao.framework.common.util.collection.CollectionUtils.convertMultiMap;
import static cn.iocoder.yudao.framework.common.util.collection.CollectionUtils.convertSet;
import static cn.iocoder.yudao.framework.operatelog.core.enums.OperateTypeEnum.EXPORT;
@Tag(name = "管理后台 - ERP 采购入库")
@RestController
@RequestMapping("/erp/purchase-in")
@Validated
public class ErpPurchaseInController {
@Resource
private ErpPurchaseInService purchaseInService;
@Resource
private ErpStockService stockService;
@Resource
private ErpProductService productService;
@Resource
private ErpSupplierService supplierService;
@Resource
private AdminUserApi adminUserApi;
@PostMapping("/create")
@Operation(summary = "创建采购入库")
@PreAuthorize("@ss.hasPermission('erp:purchase-in:create')")
public CommonResult<Long> createPurchaseIn(@Valid @RequestBody ErpPurchaseInSaveReqVO createReqVO) {
return success(purchaseInService.createPurchaseIn(createReqVO));
}
@PutMapping("/update")
@Operation(summary = "更新采购入库")
@PreAuthorize("@ss.hasPermission('erp:purchase-in:update')")
public CommonResult<Boolean> updatePurchaseIn(@Valid @RequestBody ErpPurchaseInSaveReqVO updateReqVO) {
purchaseInService.updatePurchaseIn(updateReqVO);
return success(true);
}
@PutMapping("/update-status")
@Operation(summary = "更新采购入库的状态")
@PreAuthorize("@ss.hasPermission('erp:purchase-in:update-status')")
public CommonResult<Boolean> updatePurchaseInStatus(@RequestParam("id") Long id,
@RequestParam("status") Integer status) {
purchaseInService.updatePurchaseInStatus(id, status);
return success(true);
}
@DeleteMapping("/delete")
@Operation(summary = "删除采购入库")
@Parameter(name = "ids", description = "编号数组", required = true)
@PreAuthorize("@ss.hasPermission('erp:purchase-in:delete')")
public CommonResult<Boolean> deletePurchaseIn(@RequestParam("ids") List<Long> ids) {
purchaseInService.deletePurchaseIn(ids);
return success(true);
}
@GetMapping("/get")
@Operation(summary = "获得采购入库")
@Parameter(name = "id", description = "编号", required = true, example = "1024")
@PreAuthorize("@ss.hasPermission('erp:purchase-in:query')")
public CommonResult<ErpPurchaseInRespVO> getPurchaseIn(@RequestParam("id") Long id) {
ErpPurchaseInDO purchaseIn = purchaseInService.getPurchaseIn(id);
if (purchaseIn == null) {
return success(null);
}
List<ErpPurchaseInItemDO> purchaseInItemList = purchaseInService.getPurchaseInItemListByInId(id);
Map<Long, ErpProductRespVO> productMap = productService.getProductVOMap(
convertSet(purchaseInItemList, ErpPurchaseInItemDO::getProductId));
return success(BeanUtils.toBean(purchaseIn, ErpPurchaseInRespVO.class, purchaseInVO ->
purchaseInVO.setItems(BeanUtils.toBean(purchaseInItemList, ErpPurchaseInRespVO.Item.class, item -> {
ErpStockDO stock = stockService.getStock(item.getProductId(), item.getWarehouseId());
item.setStockCount(stock != null ? stock.getCount() : BigDecimal.ZERO);
MapUtils.findAndThen(productMap, item.getProductId(), product -> item.setProductName(product.getName())
.setProductBarCode(product.getBarCode()).setProductUnitName(product.getUnitName()));
}))));
}
@GetMapping("/page")
@Operation(summary = "获得采购入库分页")
@PreAuthorize("@ss.hasPermission('erp:purchase-in:query')")
public CommonResult<PageResult<ErpPurchaseInRespVO>> getPurchaseInPage(@Valid ErpPurchaseInPageReqVO pageReqVO) {
PageResult<ErpPurchaseInDO> pageResult = purchaseInService.getPurchaseInPage(pageReqVO);
return success(buildPurchaseInVOPageResult(pageResult));
}
@GetMapping("/export-excel")
@Operation(summary = "导出采购入库 Excel")
@PreAuthorize("@ss.hasPermission('erp:purchase-in:export')")
@OperateLog(type = EXPORT)
public void exportPurchaseInExcel(@Valid ErpPurchaseInPageReqVO pageReqVO,
HttpServletResponse response) throws IOException {
pageReqVO.setPageSize(PageParam.PAGE_SIZE_NONE);
List<ErpPurchaseInRespVO> list = buildPurchaseInVOPageResult(purchaseInService.getPurchaseInPage(pageReqVO)).getList();
// 导出 Excel
ExcelUtils.write(response, "采购入库.xls", "数据", ErpPurchaseInRespVO.class, list);
}
private PageResult<ErpPurchaseInRespVO> buildPurchaseInVOPageResult(PageResult<ErpPurchaseInDO> pageResult) {
if (CollUtil.isEmpty(pageResult.getList())) {
return PageResult.empty(pageResult.getTotal());
}
// 1.1 出库项
List<ErpPurchaseInItemDO> purchaseInItemList = purchaseInService.getPurchaseInItemListByInIds(
convertSet(pageResult.getList(), ErpPurchaseInDO::getId));
Map<Long, List<ErpPurchaseInItemDO>> purchaseInItemMap = convertMultiMap(purchaseInItemList, ErpPurchaseInItemDO::getInId);
// 1.2 产品信息
Map<Long, ErpProductRespVO> productMap = productService.getProductVOMap(
convertSet(purchaseInItemList, ErpPurchaseInItemDO::getProductId));
// 1.3 供应商信息
Map<Long, ErpSupplierDO> supplierMap = supplierService.getSupplierMap(
convertSet(pageResult.getList(), ErpPurchaseInDO::getSupplierId));
// 1.4 管理员信息
Map<Long, AdminUserRespDTO> userMap = adminUserApi.getUserMap(
convertSet(pageResult.getList(), erpStockRecordDO -> Long.parseLong(erpStockRecordDO.getCreator())));
// 2. 开始拼接
return BeanUtils.toBean(pageResult, ErpPurchaseInRespVO.class, purchaseIn -> {
purchaseIn.setItems(BeanUtils.toBean(purchaseInItemMap.get(purchaseIn.getId()), ErpPurchaseInRespVO.Item.class,
item -> MapUtils.findAndThen(productMap, item.getProductId(), product -> item.setProductName(product.getName())
.setProductBarCode(product.getBarCode()).setProductUnitName(product.getUnitName()))));
purchaseIn.setProductNames(CollUtil.join(purchaseIn.getItems(), "", ErpPurchaseInRespVO.Item::getProductName));
MapUtils.findAndThen(supplierMap, purchaseIn.getSupplierId(), supplier -> purchaseIn.setSupplierName(supplier.getName()));
MapUtils.findAndThen(userMap, Long.parseLong(purchaseIn.getCreator()), user -> purchaseIn.setCreatorName(user.getNickname()));
});
}
}

View File

@ -0,0 +1,54 @@
package cn.iocoder.yudao.module.erp.controller.admin.purchase.vo.in;
import cn.iocoder.yudao.framework.common.pojo.PageParam;
import io.swagger.v3.oas.annotations.media.Schema;
import lombok.Data;
import lombok.EqualsAndHashCode;
import lombok.ToString;
import org.springframework.format.annotation.DateTimeFormat;
import java.time.LocalDateTime;
import static cn.iocoder.yudao.framework.common.util.date.DateUtils.FORMAT_YEAR_MONTH_DAY_HOUR_MINUTE_SECOND;
@Schema(description = "管理后台 - ERP 采购入库分页 Request VO")
@Data
@EqualsAndHashCode(callSuper = true)
@ToString(callSuper = true)
public class ErpPurchaseInPageReqVO extends PageParam {
@Schema(description = "采购单编号", example = "XS001")
private String no;
@Schema(description = "供应商编号", example = "1724")
private Long supplierId;
@Schema(description = "入库时间")
@DateTimeFormat(pattern = FORMAT_YEAR_MONTH_DAY_HOUR_MINUTE_SECOND)
private LocalDateTime[] inTime;
@Schema(description = "备注", example = "你猜")
private String remark;
@Schema(description = "入库状态", example = "2")
private Integer status;
@Schema(description = "创建者")
private String creator;
@Schema(description = "产品编号", example = "1")
private Long productId;
@Schema(description = "仓库编号", example = "1")
private Long warehouseId;
@Schema(description = "结算账号编号", example = "1")
private Long accountId;
@Schema(description = "是否欠款", example = "true")
private Boolean debtStatus;
@Schema(description = "采购单号", example = "1")
private String orderNo;
}

View File

@ -0,0 +1,148 @@
package cn.iocoder.yudao.module.erp.controller.admin.purchase.vo.in;
import com.alibaba.excel.annotation.ExcelIgnoreUnannotated;
import com.alibaba.excel.annotation.ExcelProperty;
import io.swagger.v3.oas.annotations.media.Schema;
import jakarta.validation.constraints.NotNull;
import lombok.Data;
import java.math.BigDecimal;
import java.time.LocalDateTime;
import java.util.List;
@Schema(description = "管理后台 - ERP 采购入库 Response VO")
@Data
@ExcelIgnoreUnannotated
public class ErpPurchaseInRespVO {
@Schema(description = "编号", requiredMode = Schema.RequiredMode.REQUIRED, example = "17386")
@ExcelProperty("编号")
private Long id;
@Schema(description = "入库单编号", requiredMode = Schema.RequiredMode.REQUIRED, example = "XS001")
@ExcelProperty("入库单编号")
private String no;
@Schema(description = "入库状态", requiredMode = Schema.RequiredMode.REQUIRED, example = "2")
@ExcelProperty("入库状态")
private Integer status;
@Schema(description = "供应商编号", requiredMode = Schema.RequiredMode.REQUIRED, example = "1724")
private Long supplierId;
@Schema(description = "供应商名称", example = "芋道")
@ExcelProperty("供应商名称")
private String supplierName;
@Schema(description = "结算账户编号", requiredMode = Schema.RequiredMode.REQUIRED, example = "311.89")
@ExcelProperty("结算账户编号")
private Long accountId;
@Schema(description = "入库时间", requiredMode = Schema.RequiredMode.REQUIRED)
@ExcelProperty("入库时间")
private LocalDateTime inTime;
@Schema(description = "采购订单编号", requiredMode = Schema.RequiredMode.REQUIRED, example = "17386")
private Long orderId;
@Schema(description = "采购订单号", requiredMode = Schema.RequiredMode.REQUIRED, example = "XS001")
private String orderNo;
@Schema(description = "合计数量", requiredMode = Schema.RequiredMode.REQUIRED, example = "15663")
@ExcelProperty("合计数量")
private BigDecimal totalCount;
@Schema(description = "最终合计价格", requiredMode = Schema.RequiredMode.REQUIRED, example = "24906")
@ExcelProperty("最终合计价格")
private BigDecimal totalPrice;
@Schema(description = "合计产品价格,单位:元", requiredMode = Schema.RequiredMode.REQUIRED, example = "7127")
private BigDecimal totalProductPrice;
@Schema(description = "合计税额,单位:元", requiredMode = Schema.RequiredMode.REQUIRED, example = "7127")
private BigDecimal totalTaxPrice;
@Schema(description = "优惠率,百分比", requiredMode = Schema.RequiredMode.REQUIRED, example = "99.88")
private BigDecimal discountPercent;
@Schema(description = "优惠金额,单位:元", requiredMode = Schema.RequiredMode.REQUIRED, example = "7127")
private BigDecimal discountPrice;
@Schema(description = "定金金额,单位:元", requiredMode = Schema.RequiredMode.REQUIRED, example = "7127")
private BigDecimal otherPrice;
@Schema(description = "本次收款,单位:元", requiredMode = Schema.RequiredMode.REQUIRED, example = "7127")
private BigDecimal payPrice;
@Schema(description = "本次欠款,单位:元", requiredMode = Schema.RequiredMode.REQUIRED, example = "666")
private BigDecimal debtPrice;
@Schema(description = "附件地址", example = "https://www.iocoder.cn")
@ExcelProperty("附件地址")
private String fileUrl;
@Schema(description = "备注", example = "你猜")
@ExcelProperty("备注")
private String remark;
@Schema(description = "创建人", example = "芋道")
private String creator;
@Schema(description = "创建人名称", example = "芋道")
private String creatorName;
@Schema(description = "创建时间", requiredMode = Schema.RequiredMode.REQUIRED)
@ExcelProperty("创建时间")
private LocalDateTime createTime;
@Schema(description = "入库项列表", requiredMode = Schema.RequiredMode.REQUIRED)
private List<Item> items;
@Schema(description = "产品信息", requiredMode = Schema.RequiredMode.REQUIRED)
@ExcelProperty("产品信息")
private String productNames;
@Data
public static class Item {
@Schema(description = "入库项编号", example = "11756")
private Long id;
@Schema(description = "采购订单项编号", requiredMode = Schema.RequiredMode.REQUIRED, example = "11756")
private Long orderItemId;
@Schema(description = "仓库编号", requiredMode = Schema.RequiredMode.REQUIRED, example = "3113")
private Long warehouseId;
@Schema(description = "产品编号", requiredMode = Schema.RequiredMode.REQUIRED, example = "3113")
private Long productId;
@Schema(description = "产品单位单位", requiredMode = Schema.RequiredMode.REQUIRED, example = "3113")
private Long productUnitId;
@Schema(description = "产品单价", example = "100.00")
private BigDecimal productPrice;
@Schema(description = "产品数量", requiredMode = Schema.RequiredMode.REQUIRED, example = "100.00")
@NotNull(message = "产品数量不能为空")
private BigDecimal count;
@Schema(description = "税率,百分比", example = "99.88")
private BigDecimal taxPercent;
@Schema(description = "税额,单位:元", example = "100.00")
private BigDecimal taxPrice;
@Schema(description = "备注", example = "随便")
private String remark;
// ========== 关联字段 ==========
@Schema(description = "产品名称", requiredMode = Schema.RequiredMode.REQUIRED, example = "巧克力")
private String productName;
@Schema(description = "产品条码", requiredMode = Schema.RequiredMode.REQUIRED, example = "A9985")
private String productBarCode;
@Schema(description = "产品单位名称", requiredMode = Schema.RequiredMode.REQUIRED, example = "")
private String productUnitName;
@Schema(description = "库存数量", requiredMode = Schema.RequiredMode.REQUIRED, example = "100.00")
private BigDecimal stockCount; // 该字段仅仅在详情编辑时使用
}
}

View File

@ -0,0 +1,85 @@
package cn.iocoder.yudao.module.erp.controller.admin.purchase.vo.in;
import io.swagger.v3.oas.annotations.media.Schema;
import jakarta.validation.constraints.NotNull;
import lombok.Data;
import java.math.BigDecimal;
import java.time.LocalDateTime;
import java.util.List;
@Schema(description = "管理后台 - ERP 采购入库新增/修改 Request VO")
@Data
public class ErpPurchaseInSaveReqVO {
@Schema(description = "编号", requiredMode = Schema.RequiredMode.REQUIRED, example = "17386")
private Long id;
@Schema(description = "结算账户编号", example = "31189")
private Long accountId;
@Schema(description = "入库时间", requiredMode = Schema.RequiredMode.REQUIRED)
@NotNull(message = "入库时间不能为空")
private LocalDateTime inTime;
@Schema(description = "采购订单编号", requiredMode = Schema.RequiredMode.REQUIRED, example = "17386")
@NotNull(message = "采购订单编号不能为空")
private Long orderId;
@Schema(description = "优惠率,百分比", requiredMode = Schema.RequiredMode.REQUIRED, example = "99.88")
private BigDecimal discountPercent;
@Schema(description = "其它金额,单位:元", example = "7127")
private BigDecimal otherPrice;
@Schema(description = "本次收款,单位:元", requiredMode = Schema.RequiredMode.REQUIRED, example = "7127")
@NotNull(message = "本次收款不能为空")
private BigDecimal payPrice;
@Schema(description = "附件地址", example = "https://www.iocoder.cn")
private String fileUrl;
@Schema(description = "备注", example = "你猜")
private String remark;
@Schema(description = "入库清单列表")
private List<Item> items;
@Data
public static class Item {
@Schema(description = "入库项编号", example = "11756")
private Long id;
@Schema(description = "采购订单项编号", requiredMode = Schema.RequiredMode.REQUIRED, example = "11756")
@NotNull(message = "采购订单项编号不能为空")
private Long orderItemId;
@Schema(description = "仓库编号", requiredMode = Schema.RequiredMode.REQUIRED, example = "3113")
@NotNull(message = "仓库编号不能为空")
private Long warehouseId;
@Schema(description = "产品编号", requiredMode = Schema.RequiredMode.REQUIRED, example = "3113")
@NotNull(message = "产品编号不能为空")
private Long productId;
@Schema(description = "产品单位单位", requiredMode = Schema.RequiredMode.REQUIRED, example = "3113")
@NotNull(message = "产品单位单位不能为空")
private Long productUnitId;
@Schema(description = "产品单价", example = "100.00")
private BigDecimal productPrice;
@Schema(description = "产品数量", requiredMode = Schema.RequiredMode.REQUIRED, example = "100.00")
@NotNull(message = "产品数量不能为空")
private BigDecimal count;
@Schema(description = "税率,百分比", example = "99.88")
private BigDecimal taxPercent;
@Schema(description = "备注", example = "随便")
private String remark;
}
}

View File

@ -0,0 +1,127 @@
package cn.iocoder.yudao.module.erp.dal.dataobject.purchase;
import cn.iocoder.yudao.framework.mybatis.core.dataobject.BaseDO;
import cn.iocoder.yudao.module.erp.dal.dataobject.finance.ErpAccountDO;
import com.baomidou.mybatisplus.annotation.KeySequence;
import com.baomidou.mybatisplus.annotation.TableId;
import com.baomidou.mybatisplus.annotation.TableName;
import lombok.*;
import java.math.BigDecimal;
import java.time.LocalDateTime;
/**
* ERP 采购入库 DO
*
* @author 芋道源码
*/
@TableName(value = "erp_purchase_in")
@KeySequence("erp_purchase_in_seq") // 用于 OraclePostgreSQLKingbaseDB2H2 数据库的主键自增如果是 MySQL 等数据库可不写
@Data
@EqualsAndHashCode(callSuper = true)
@ToString(callSuper = true)
@Builder
@NoArgsConstructor
@AllArgsConstructor
public class ErpPurchaseInDO extends BaseDO {
/**
* 编号
*/
@TableId
private Long id;
/**
* 销售入库单号
*/
private String no;
/**
* 入库状态
*
* 枚举 {@link cn.iocoder.yudao.module.erp.enums.ErpAuditStatus}
*/
private Integer status;
/**
* 供应商编号
*
* 关联 {@link ErpSupplierDO#getId()}
*/
private Long supplierId;
/**
* 结算账户编号
*
* 关联 {@link ErpAccountDO#getId()}
*/
private Long accountId;
/**
* 入库时间
*/
private LocalDateTime inTime;
/**
* 采购订单编号
*
* 关联 {@link ErpPurchaseOrderDO#getId()}
*/
private Long orderId;
/**
* 采购订单号
*
* 冗余 {@link ErpPurchaseOrderDO#getNo()}
*/
private String orderNo;
/**
* 合计数量
*/
private BigDecimal totalCount;
/**
* 最终合计价格单位
*
* totalPrice = totalProductPrice + totalTaxPrice - discountPrice
*/
private BigDecimal totalPrice;
/**
* 合计产品价格单位
*/
private BigDecimal totalProductPrice;
/**
* 合计税额单位
*/
private BigDecimal totalTaxPrice;
/**
* 优惠率百分比
*/
private BigDecimal discountPercent;
/**
* 优惠金额单位
*
* discountPrice = (totalProductPrice + totalTaxPrice) * discountPercent
*/
private BigDecimal discountPrice;
/**
* 其它金额单位
*/
private BigDecimal otherPrice;
/**
* 本次收款单位
*
* payPrice = totalPrice + otherPrice - debtPrice
*/
private BigDecimal payPrice;
/**
* 本次欠款单位
*/
private BigDecimal debtPrice;
/**
* 附件地址
*/
private String fileUrl;
/**
* 备注
*/
private String remark;
}

View File

@ -0,0 +1,95 @@
package cn.iocoder.yudao.module.erp.dal.dataobject.purchase;
import cn.iocoder.yudao.framework.mybatis.core.dataobject.BaseDO;
import cn.iocoder.yudao.module.erp.dal.dataobject.product.ErpProductDO;
import cn.iocoder.yudao.module.erp.dal.dataobject.stock.ErpWarehouseDO;
import com.baomidou.mybatisplus.annotation.KeySequence;
import com.baomidou.mybatisplus.annotation.TableId;
import com.baomidou.mybatisplus.annotation.TableName;
import lombok.*;
import java.math.BigDecimal;
/**
* ERP 采购入库项 DO
*
* @author 芋道源码
*/
@TableName("erp_purchase_in_items")
@KeySequence("erp_purchase_in_items_seq") // 用于 OraclePostgreSQLKingbaseDB2H2 数据库的主键自增如果是 MySQL 等数据库可不写
@Data
@EqualsAndHashCode(callSuper = true)
@ToString(callSuper = true)
@Builder
@NoArgsConstructor
@AllArgsConstructor
public class ErpPurchaseInItemDO extends BaseDO {
/**
* 编号
*/
@TableId
private Long id;
/**
* 采购入库编号
*
* 关联 {@link ErpPurchaseInDO##getId()}
*/
private Long inId;
/**
* 采购订单项编号
*
* 关联 {@link ErpPurchaseOrderItemDO#getId()}
* 目的方便更新关联的采购订单项的入库数量
*/
private Long orderItemId;
/**
* 仓库编号
*
* 关联 {@link ErpWarehouseDO#getId()}
*/
private Long warehouseId;
/**
* 产品编号
*
* 关联 {@link ErpProductDO#getId()}
*/
private Long productId;
/**
* 产品单位单位
*
* 冗余 {@link ErpProductDO#getUnitId()}
*/
private Long productUnitId;
/**
* 产品单位单价单位
*/
private BigDecimal productPrice;
/**
* 数量
*/
private BigDecimal count;
/**
* 总价单位
*
* totalPrice = productPrice * count
*/
private BigDecimal totalPrice;
/**
* 税率百分比
*/
private BigDecimal taxPercent;
/**
* 税额单位
*
* taxPrice = totalPrice * taxPercent
*/
private BigDecimal taxPrice;
/**
* 备注
*/
private String remark;
}

View File

@ -0,0 +1,56 @@
package cn.iocoder.yudao.module.erp.dal.mysql.purchase;
import cn.hutool.core.collection.CollUtil;
import cn.iocoder.yudao.framework.mybatis.core.mapper.BaseMapperX;
import cn.iocoder.yudao.module.erp.dal.dataobject.purchase.ErpPurchaseInItemDO;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import org.apache.ibatis.annotations.Mapper;
import java.math.BigDecimal;
import java.util.Collection;
import java.util.Collections;
import java.util.List;
import java.util.Map;
import static cn.iocoder.yudao.framework.common.util.collection.CollectionUtils.convertMap;
/**
* ERP 采购入库项 Mapper
*
* @author 芋道源码
*/
@Mapper
public interface ErpPurchaseInItemMapper extends BaseMapperX<ErpPurchaseInItemDO> {
default List<ErpPurchaseInItemDO> selectListByInId(Long inId) {
return selectList(ErpPurchaseInItemDO::getInId, inId);
}
default List<ErpPurchaseInItemDO> selectListByInIds(Collection<Long> inIds) {
return selectList(ErpPurchaseInItemDO::getInId, inIds);
}
default int deleteByInId(Long inId) {
return delete(ErpPurchaseInItemDO::getInId, inId);
}
/**
* 基于销售订单编号查询每个销售订单项的入库数量之和
*
* @param inIds 入库订单项编号数组
* @return key销售订单项编号value入库数量之和
*/
default Map<Long, BigDecimal> selectOrderItemCountSumMapByInIds(Collection<Long> inIds) {
if (CollUtil.isEmpty(inIds)) {
return Collections.emptyMap();
}
// SQL sum 查询
List<Map<String, Object>> result = selectMaps(new QueryWrapper<ErpPurchaseInItemDO>()
.select("order_item_id, SUM(count) AS sumCount")
.groupBy("order_item_id")
.in("in_id", inIds));
// 获得数量
return convertMap(result, obj -> (Long) obj.get("order_item_id"), obj -> (BigDecimal) obj.get("sumCount"));
}
}

View File

@ -0,0 +1,62 @@
package cn.iocoder.yudao.module.erp.dal.mysql.purchase;
import cn.iocoder.yudao.framework.common.pojo.PageResult;
import cn.iocoder.yudao.framework.mybatis.core.mapper.BaseMapperX;
import cn.iocoder.yudao.framework.mybatis.core.query.MPJLambdaWrapperX;
import cn.iocoder.yudao.module.erp.controller.admin.purchase.vo.in.ErpPurchaseInPageReqVO;
import cn.iocoder.yudao.module.erp.dal.dataobject.purchase.ErpPurchaseInDO;
import cn.iocoder.yudao.module.erp.dal.dataobject.purchase.ErpPurchaseInItemDO;
import com.baomidou.mybatisplus.core.conditions.update.LambdaUpdateWrapper;
import org.apache.ibatis.annotations.Mapper;
import java.math.BigDecimal;
import java.util.List;
/**
* ERP 采购入库 Mapper
*
* @author 芋道源码
*/
@Mapper
public interface ErpPurchaseInMapper extends BaseMapperX<ErpPurchaseInDO> {
default PageResult<ErpPurchaseInDO> selectPage(ErpPurchaseInPageReqVO reqVO) {
MPJLambdaWrapperX<ErpPurchaseInDO> query = new MPJLambdaWrapperX<ErpPurchaseInDO>()
.likeIfPresent(ErpPurchaseInDO::getNo, reqVO.getNo())
.eqIfPresent(ErpPurchaseInDO::getSupplierId, reqVO.getSupplierId())
.betweenIfPresent(ErpPurchaseInDO::getInTime, reqVO.getInTime())
.eqIfPresent(ErpPurchaseInDO::getStatus, reqVO.getStatus())
.likeIfPresent(ErpPurchaseInDO::getRemark, reqVO.getRemark())
.eqIfPresent(ErpPurchaseInDO::getCreator, reqVO.getCreator())
.eqIfPresent(ErpPurchaseInDO::getAccountId, reqVO.getAccountId())
.likeIfPresent(ErpPurchaseInDO::getOrderNo, reqVO.getOrderNo())
.orderByDesc(ErpPurchaseInDO::getId);
if (Boolean.TRUE.equals(reqVO.getDebtStatus())) {
query.gt(ErpPurchaseInDO::getDebtPrice, BigDecimal.ZERO);
} else if (Boolean.FALSE.equals(reqVO.getDebtStatus())) {
query.eq(ErpPurchaseInDO::getDebtPrice, BigDecimal.ZERO);
}
if (reqVO.getWarehouseId() != null || reqVO.getProductId() != null) {
query.leftJoin(ErpPurchaseInItemDO.class, ErpPurchaseInItemDO::getInId, ErpPurchaseInDO::getId)
.eq(reqVO.getWarehouseId() != null, ErpPurchaseInItemDO::getWarehouseId, reqVO.getWarehouseId())
.eq(reqVO.getProductId() != null, ErpPurchaseInItemDO::getProductId, reqVO.getProductId())
.groupBy(ErpPurchaseInDO::getId); // 避免 1 对多查询产生相同的 1
}
return selectJoinPage(reqVO, ErpPurchaseInDO.class, query);
}
default int updateByIdAndStatus(Long id, Integer status, ErpPurchaseInDO updateObj) {
return update(updateObj, new LambdaUpdateWrapper<ErpPurchaseInDO>()
.eq(ErpPurchaseInDO::getId, id).eq(ErpPurchaseInDO::getStatus, status));
}
default ErpPurchaseInDO selectByNo(String no) {
return selectOne(ErpPurchaseInDO::getNo, no);
}
default List<ErpPurchaseInDO> selectListByOrderId(Long orderId) {
return selectList(ErpPurchaseInDO::getOrderId, orderId);
}
}

View File

@ -55,6 +55,10 @@ public class ErpNoRedisDAO {
* 采购订单 {@link cn.iocoder.yudao.module.erp.dal.dataobject.purchase.ErpPurchaseOrderDO} * 采购订单 {@link cn.iocoder.yudao.module.erp.dal.dataobject.purchase.ErpPurchaseOrderDO}
*/ */
public static final String PURCHASE_ORDER_NO_PREFIX = "CGDD"; public static final String PURCHASE_ORDER_NO_PREFIX = "CGDD";
/**
* 采购入库 {@link cn.iocoder.yudao.module.erp.dal.dataobject.purchase.ErpPurchaseInDO}
*/
public static final String PURCHASE_IN_NO_PREFIX = "CGRK";
@Resource @Resource
private StringRedisTemplate stringRedisTemplate; private StringRedisTemplate stringRedisTemplate;

View File

@ -0,0 +1,84 @@
package cn.iocoder.yudao.module.erp.service.purchase;
import cn.iocoder.yudao.framework.common.pojo.PageResult;
import cn.iocoder.yudao.module.erp.controller.admin.purchase.vo.in.ErpPurchaseInPageReqVO;
import cn.iocoder.yudao.module.erp.controller.admin.purchase.vo.in.ErpPurchaseInSaveReqVO;
import cn.iocoder.yudao.module.erp.dal.dataobject.purchase.ErpPurchaseInDO;
import cn.iocoder.yudao.module.erp.dal.dataobject.purchase.ErpPurchaseInItemDO;
import jakarta.validation.Valid;
import java.util.Collection;
import java.util.List;
/**
* ERP 采购入库 Service 接口
*
* @author 芋道源码
*/
public interface ErpPurchaseInService {
/**
* 创建采购入库
*
* @param createReqVO 创建信息
* @return 编号
*/
Long createPurchaseIn(@Valid ErpPurchaseInSaveReqVO createReqVO);
/**
* 更新采购入库
*
* @param updateReqVO 更新信息
*/
void updatePurchaseIn(@Valid ErpPurchaseInSaveReqVO updateReqVO);
/**
* 更新采购入库的状态
*
* @param id 编号
* @param status 状态
*/
void updatePurchaseInStatus(Long id, Integer status);
/**
* 删除采购入库
*
* @param ids 编号数组
*/
void deletePurchaseIn(List<Long> ids);
/**
* 获得采购入库
*
* @param id 编号
* @return 采购入库
*/
ErpPurchaseInDO getPurchaseIn(Long id);
/**
* 获得采购入库分页
*
* @param pageReqVO 分页查询
* @return 采购入库分页
*/
PageResult<ErpPurchaseInDO> getPurchaseInPage(ErpPurchaseInPageReqVO pageReqVO);
// ==================== 采购入库项 ====================
/**
* 获得采购入库项列表
*
* @param inId 采购入库编号
* @return 采购入库项列表
*/
List<ErpPurchaseInItemDO> getPurchaseInItemListByInId(Long inId);
/**
* 获得采购入库项 List
*
* @param inIds 采购入库编号数组
* @return 采购入库项 List
*/
List<ErpPurchaseInItemDO> getPurchaseInItemListByInIds(Collection<Long> inIds);
}

View File

@ -0,0 +1,286 @@
package cn.iocoder.yudao.module.erp.service.purchase;
import cn.hutool.core.collection.CollUtil;
import cn.hutool.core.util.ObjectUtil;
import cn.iocoder.yudao.framework.common.pojo.PageResult;
import cn.iocoder.yudao.framework.common.util.number.MoneyUtils;
import cn.iocoder.yudao.framework.common.util.object.BeanUtils;
import cn.iocoder.yudao.module.erp.controller.admin.purchase.vo.in.ErpPurchaseInPageReqVO;
import cn.iocoder.yudao.module.erp.controller.admin.purchase.vo.in.ErpPurchaseInSaveReqVO;
import cn.iocoder.yudao.module.erp.dal.dataobject.product.ErpProductDO;
import cn.iocoder.yudao.module.erp.dal.dataobject.purchase.ErpPurchaseInDO;
import cn.iocoder.yudao.module.erp.dal.dataobject.purchase.ErpPurchaseInItemDO;
import cn.iocoder.yudao.module.erp.dal.dataobject.purchase.ErpPurchaseOrderDO;
import cn.iocoder.yudao.module.erp.dal.mysql.purchase.ErpPurchaseInItemMapper;
import cn.iocoder.yudao.module.erp.dal.mysql.purchase.ErpPurchaseInMapper;
import cn.iocoder.yudao.module.erp.dal.redis.no.ErpNoRedisDAO;
import cn.iocoder.yudao.module.erp.enums.ErpAuditStatus;
import cn.iocoder.yudao.module.erp.enums.stock.ErpStockRecordBizTypeEnum;
import cn.iocoder.yudao.module.erp.service.finance.ErpAccountService;
import cn.iocoder.yudao.module.erp.service.product.ErpProductService;
import cn.iocoder.yudao.module.erp.service.stock.ErpStockRecordService;
import cn.iocoder.yudao.module.erp.service.stock.bo.ErpStockRecordCreateReqBO;
import cn.iocoder.yudao.module.system.api.user.AdminUserApi;
import jakarta.annotation.Resource;
import org.springframework.context.annotation.Lazy;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.validation.annotation.Validated;
import java.math.BigDecimal;
import java.util.Collection;
import java.util.Collections;
import java.util.List;
import java.util.Map;
import static cn.iocoder.yudao.framework.common.exception.util.ServiceExceptionUtil.exception;
import static cn.iocoder.yudao.framework.common.util.collection.CollectionUtils.*;
import static cn.iocoder.yudao.module.erp.enums.ErrorCodeConstants.*;
// TODO 芋艿记录操作日志
/**
* ERP 采购入库 Service 实现类
*
* @author 芋道源码
*/
@Service
@Validated
public class ErpPurchaseInServiceImpl implements ErpPurchaseInService {
@Resource
private ErpPurchaseInMapper purchaseInMapper;
@Resource
private ErpPurchaseInItemMapper purchaseInItemMapper;
@Resource
private ErpNoRedisDAO noRedisDAO;
@Resource
private ErpProductService productService;
@Resource
@Lazy // 延迟加载避免循环依赖
private ErpPurchaseOrderService purchaseOrderService;
@Resource
private ErpAccountService accountService;
@Resource
private ErpStockRecordService stockRecordService;
@Resource
private AdminUserApi adminUserApi;
@Override
@Transactional(rollbackFor = Exception.class)
public Long createPurchaseIn(ErpPurchaseInSaveReqVO createReqVO) {
// 1.1 校验采购订单已审核
ErpPurchaseOrderDO purchaseOrder = purchaseOrderService.validatePurchaseOrder(createReqVO.getOrderId());
// 1.2 校验入库项的有效性
List<ErpPurchaseInItemDO> purchaseInItems = validatePurchaseInItems(createReqVO.getItems());
// 1.3 校验结算账户
accountService.validateAccount(createReqVO.getAccountId());
// 1.4 生成调拨单号并校验唯一性
String no = noRedisDAO.generate(ErpNoRedisDAO.PURCHASE_IN_NO_PREFIX);
if (purchaseInMapper.selectByNo(no) != null) {
throw exception(PURCHASE_IN_NO_EXISTS);
}
// 2.1 插入入库
ErpPurchaseInDO purchaseIn = BeanUtils.toBean(createReqVO, ErpPurchaseInDO.class, in -> in
.setNo(no).setStatus(ErpAuditStatus.PROCESS.getStatus()))
.setOrderNo(purchaseOrder.getNo()).setSupplierId(purchaseOrder.getSupplierId());
calculateTotalPrice(purchaseIn, purchaseInItems);
purchaseInMapper.insert(purchaseIn);
// 2.2 插入入库项
purchaseInItems.forEach(o -> o.setInId(purchaseIn.getId()));
purchaseInItemMapper.insertBatch(purchaseInItems);
// 3. 更新采购订单的入库数量
updatePurchaseOrderInCount(createReqVO.getOrderId());
return purchaseIn.getId();
}
@Override
@Transactional(rollbackFor = Exception.class)
public void updatePurchaseIn(ErpPurchaseInSaveReqVO updateReqVO) {
// 1.1 校验存在
ErpPurchaseInDO purchaseIn = validatePurchaseInExists(updateReqVO.getId());
if (ErpAuditStatus.APPROVE.getStatus().equals(purchaseIn.getStatus())) {
throw exception(PURCHASE_IN_UPDATE_FAIL_APPROVE, purchaseIn.getNo());
}
// 1.2 校验采购订单已审核
ErpPurchaseOrderDO purchaseOrder = purchaseOrderService.validatePurchaseOrder(updateReqVO.getOrderId());
// 1.3 校验结算账户
accountService.validateAccount(updateReqVO.getAccountId());
// 1.4 校验订单项的有效性
List<ErpPurchaseInItemDO> purchaseInItems = validatePurchaseInItems(updateReqVO.getItems());
// 2.1 更新入库
ErpPurchaseInDO updateObj = BeanUtils.toBean(updateReqVO, ErpPurchaseInDO.class)
.setOrderNo(purchaseOrder.getNo()).setSupplierId(purchaseOrder.getSupplierId());
calculateTotalPrice(updateObj, purchaseInItems);
purchaseInMapper.updateById(updateObj);
// 2.2 更新入库项
updatePurchaseInItemList(updateReqVO.getId(), purchaseInItems);
// 3.1 更新采购订单的入库数量
updatePurchaseOrderInCount(updateObj.getOrderId());
// 3.2 注意如果采购订单编号变更了需要更新采购订单的入库数量
if (ObjectUtil.notEqual(purchaseIn.getOrderId(), updateObj.getOrderId())) {
updatePurchaseOrderInCount(purchaseIn.getOrderId());
}
}
private void calculateTotalPrice(ErpPurchaseInDO purchaseIn, List<ErpPurchaseInItemDO> purchaseInItems) {
purchaseIn.setTotalCount(getSumValue(purchaseInItems, ErpPurchaseInItemDO::getCount, BigDecimal::add));
purchaseIn.setTotalProductPrice(getSumValue(purchaseInItems, ErpPurchaseInItemDO::getTotalPrice, BigDecimal::add, BigDecimal.ZERO));
purchaseIn.setTotalTaxPrice(getSumValue(purchaseInItems, ErpPurchaseInItemDO::getTaxPrice, BigDecimal::add, BigDecimal.ZERO));
purchaseIn.setTotalPrice(purchaseIn.getTotalProductPrice().add(purchaseIn.getTotalTaxPrice()));
// 计算优惠价格
if (purchaseIn.getDiscountPercent() == null) {
purchaseIn.setDiscountPercent(BigDecimal.ZERO);
}
purchaseIn.setDiscountPrice(MoneyUtils.priceMultiplyPercent(purchaseIn.getTotalPrice(), purchaseIn.getDiscountPercent()));
purchaseIn.setTotalPrice(purchaseIn.getTotalPrice().subtract(purchaseIn.getDiscountPrice()));
// 计算应收金额
BigDecimal allPrice = purchaseIn.getTotalPrice().add(purchaseIn.getOtherPrice());
purchaseIn.setDebtPrice(allPrice.subtract(purchaseIn.getPayPrice()));
}
private void updatePurchaseOrderInCount(Long orderId) {
// 1.1 查询采购订单对应的采购入库单列表
List<ErpPurchaseInDO> purchaseIns = purchaseInMapper.selectListByOrderId(orderId);
// 1.2 查询对应的采购订单项的入库数量
Map<Long, BigDecimal> returnCountMap = purchaseInItemMapper.selectOrderItemCountSumMapByInIds(
convertList(purchaseIns, ErpPurchaseInDO::getId));
// 2. 更新采购订单的入库数量
purchaseOrderService.updatePurchaseOrderInCount(orderId, returnCountMap);
}
@Override
@Transactional(rollbackFor = Exception.class)
public void updatePurchaseInStatus(Long id, Integer status) {
boolean approve = ErpAuditStatus.APPROVE.getStatus().equals(status);
// 1.1 校验存在
ErpPurchaseInDO purchaseIn = validatePurchaseInExists(id);
// 1.2 校验状态
if (purchaseIn.getStatus().equals(status)) {
throw exception(approve ? PURCHASE_IN_APPROVE_FAIL : PURCHASE_IN_PROCESS_FAIL);
}
// 2. 更新状态
int updateCount = purchaseInMapper.updateByIdAndStatus(id, purchaseIn.getStatus(),
new ErpPurchaseInDO().setStatus(status));
if (updateCount == 0) {
throw exception(approve ? PURCHASE_IN_APPROVE_FAIL : PURCHASE_IN_PROCESS_FAIL);
}
// 3. 变更库存
List<ErpPurchaseInItemDO> purchaseInItems = purchaseInItemMapper.selectListByInId(id);
Integer bizType = approve ? ErpStockRecordBizTypeEnum.PURCHASE_IN.getType()
: ErpStockRecordBizTypeEnum.PURCHASE_IN_CANCEL.getType();
purchaseInItems.forEach(purchaseInItem -> {
BigDecimal count = approve ? purchaseInItem.getCount() : purchaseInItem.getCount().negate();
stockRecordService.createStockRecord(new ErpStockRecordCreateReqBO(
purchaseInItem.getProductId(), purchaseInItem.getWarehouseId(), count,
bizType, purchaseInItem.getInId(), purchaseInItem.getId(), purchaseIn.getNo()));
});
}
private List<ErpPurchaseInItemDO> validatePurchaseInItems(List<ErpPurchaseInSaveReqVO.Item> list) {
// 1. 校验产品存在
List<ErpProductDO> productList = productService.validProductList(
convertSet(list, ErpPurchaseInSaveReqVO.Item::getProductId));
Map<Long, ErpProductDO> productMap = convertMap(productList, ErpProductDO::getId);
// 2. 转化为 ErpPurchaseInItemDO 列表
return convertList(list, o -> BeanUtils.toBean(o, ErpPurchaseInItemDO.class, item -> {
item.setProductUnitId(productMap.get(item.getProductId()).getUnitId());
item.setTotalPrice(MoneyUtils.priceMultiply(item.getProductPrice(), item.getCount()));
if (item.getTotalPrice() == null) {
return;
}
if (item.getTaxPercent() != null) {
item.setTaxPrice(MoneyUtils.priceMultiplyPercent(item.getTotalPrice(), item.getTaxPercent()));
}
}));
}
private void updatePurchaseInItemList(Long id, List<ErpPurchaseInItemDO> newList) {
// 第一步对比新老数据获得添加修改删除的列表
List<ErpPurchaseInItemDO> oldList = purchaseInItemMapper.selectListByInId(id);
List<List<ErpPurchaseInItemDO>> diffList = diffList(oldList, newList, // id 不同就认为是不同的记录
(oldVal, newVal) -> oldVal.getId().equals(newVal.getId()));
// 第二步批量添加修改删除
if (CollUtil.isNotEmpty(diffList.get(0))) {
diffList.get(0).forEach(o -> o.setInId(id));
purchaseInItemMapper.insertBatch(diffList.get(0));
}
if (CollUtil.isNotEmpty(diffList.get(1))) {
purchaseInItemMapper.updateBatch(diffList.get(1));
}
if (CollUtil.isNotEmpty(diffList.get(2))) {
purchaseInItemMapper.deleteBatchIds(convertList(diffList.get(2), ErpPurchaseInItemDO::getId));
}
}
@Override
@Transactional(rollbackFor = Exception.class)
public void deletePurchaseIn(List<Long> ids) {
// 1. 校验不处于已审批
List<ErpPurchaseInDO> purchaseIns = purchaseInMapper.selectBatchIds(ids);
if (CollUtil.isEmpty(purchaseIns)) {
return;
}
purchaseIns.forEach(purchaseIn -> {
if (ErpAuditStatus.APPROVE.getStatus().equals(purchaseIn.getStatus())) {
throw exception(PURCHASE_IN_DELETE_FAIL_APPROVE, purchaseIn.getNo());
}
});
// 2. 遍历删除并记录操作日志
purchaseIns.forEach(purchaseIn -> {
// 2.1 删除订单
purchaseInMapper.deleteById(purchaseIn.getId());
// 2.2 删除订单项
purchaseInItemMapper.deleteByInId(purchaseIn.getId());
// 2.3 更新采购订单的入库数量
updatePurchaseOrderInCount(purchaseIn.getOrderId());
});
}
private ErpPurchaseInDO validatePurchaseInExists(Long id) {
ErpPurchaseInDO purchaseIn = purchaseInMapper.selectById(id);
if (purchaseIn == null) {
throw exception(PURCHASE_IN_NOT_EXISTS);
}
return purchaseIn;
}
@Override
public ErpPurchaseInDO getPurchaseIn(Long id) {
return purchaseInMapper.selectById(id);
}
@Override
public PageResult<ErpPurchaseInDO> getPurchaseInPage(ErpPurchaseInPageReqVO pageReqVO) {
return purchaseInMapper.selectPage(pageReqVO);
}
// ==================== 采购入库项 ====================
@Override
public List<ErpPurchaseInItemDO> getPurchaseInItemListByInId(Long inId) {
return purchaseInItemMapper.selectListByInId(inId);
}
@Override
public List<ErpPurchaseInItemDO> getPurchaseInItemListByInIds(Collection<Long> inIds) {
if (CollUtil.isEmpty(inIds)) {
return Collections.emptyList();
}
return purchaseInItemMapper.selectListByInIds(inIds);
}
}