浏览代码

库存盘点

24282 2 年之前
父节点
当前提交
911f4934e9

+ 4 - 1
hx-victoriatourist/src/main/java/com/fjhx/victoriatourist/controller/after/AfterSaleHandleController.java

@@ -1,5 +1,6 @@
 package com.fjhx.victoriatourist.controller.after;
 
+import org.springframework.validation.annotation.Validated;
 import org.springframework.web.bind.annotation.*;
 import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
 import com.fjhx.victoriatourist.entity.after.vo.AfterSaleHandleVo;
@@ -8,6 +9,8 @@ import com.fjhx.victoriatourist.entity.after.dto.AfterSaleHandleDto;
 import com.fjhx.victoriatourist.service.after.AfterSaleHandleService;
 import org.springframework.beans.factory.annotation.Autowired;
 
+import javax.validation.Valid;
+
 
 /**
  * <p>
@@ -36,7 +39,7 @@ public class AfterSaleHandleController {
      * 售后管理-跟进记录新增
      */
     @PostMapping("/add")
-    public void add(@RequestBody AfterSaleHandleDto afterSaleHandleDto) {
+    public void add(@Validated @RequestBody AfterSaleHandleDto afterSaleHandleDto) {
         afterSaleHandleService.add(afterSaleHandleDto);
     }
 

+ 43 - 0
hx-victoriatourist/src/main/java/com/fjhx/victoriatourist/controller/sales/SalesRecordController.java

@@ -0,0 +1,43 @@
+package com.fjhx.victoriatourist.controller.sales;
+
+import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
+import com.fjhx.victoriatourist.entity.sales.dto.SalesRecordSelectDto;
+import com.fjhx.victoriatourist.entity.sales.vo.SalesRecordVo;
+import com.fjhx.victoriatourist.service.sales.SalesRecordService;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.web.bind.annotation.*;
+import org.springframework.web.multipart.MultipartFile;
+
+
+/**
+ * <p>
+ * 销售数据 前端控制器
+ * </p>
+ *
+ * @author
+ * @since 2023-04-19
+ */
+@RestController
+@RequestMapping("/salesRecord")
+public class SalesRecordController {
+
+    @Autowired
+    private SalesRecordService salesRecordService;
+
+    /**
+     * 销售数据分页
+     */
+    @PostMapping("/page")
+    public Page<SalesRecordVo> page(@RequestBody SalesRecordSelectDto dto) {
+        return salesRecordService.getPage(dto);
+    }
+
+    /**
+     * 导入excel数据
+     */
+    @PostMapping("/excelImport")
+    public void excelImport(@RequestParam("file") MultipartFile file, @RequestParam("warehouseId") Long warehouseId) {
+        salesRecordService.excelImport(file, warehouseId);
+    }
+
+}

+ 7 - 0
hx-victoriatourist/src/main/java/com/fjhx/victoriatourist/entity/after/po/AfterSaleHandle.java

@@ -5,6 +5,8 @@ import com.ruoyi.common.core.domain.BasePo;
 import lombok.Getter;
 import lombok.Setter;
 
+import javax.validation.constraints.NotBlank;
+import javax.validation.constraints.NotNull;
 import java.util.Date;
 
 /**
@@ -23,21 +25,25 @@ public class AfterSaleHandle extends BasePo {
     /**
      * 售后管理id
      */
+    @NotNull(message = "售后管理id不能为空")
     private Long afterSaleRecordId;
 
     /**
      * 售后状态
      */
+    @NotNull(message = "售后状态不能为空")
     private Integer status;
 
     /**
      * 跟进人id
      */
+    @NotNull(message = "跟进人id不能为空")
     private Long handleUserId;
 
     /**
      * 跟进时间
      */
+    @NotNull(message = "跟进时间不能为空")
     private Date handleTime;
 
     /**
@@ -48,6 +54,7 @@ public class AfterSaleHandle extends BasePo {
     /**
      * 跟进记录
      */
+    @NotBlank(message = "跟进记录不能为空")
     private String remark;
 
 }

+ 26 - 0
hx-victoriatourist/src/main/java/com/fjhx/victoriatourist/entity/sales/bo/ExcelImportBo.java

@@ -0,0 +1,26 @@
+package com.fjhx.victoriatourist.entity.sales.bo;
+
+
+import com.alibaba.excel.annotation.ExcelProperty;
+import com.fasterxml.jackson.annotation.JsonFormat;
+import lombok.Getter;
+import lombok.Setter;
+
+import java.math.BigDecimal;
+import java.util.Date;
+
+@Getter
+@Setter
+public class ExcelImportBo {
+
+    @ExcelProperty("SKU")
+    private String productCode;
+
+    @JsonFormat(pattern = "yyyy-MM-dd")
+    @ExcelProperty("时间")
+    private Date dateSale;
+
+    @ExcelProperty("全国昨日出库商品件数")
+    private BigDecimal quantity;
+
+}

+ 17 - 0
hx-victoriatourist/src/main/java/com/fjhx/victoriatourist/entity/sales/dto/SalesRecordSelectDto.java

@@ -0,0 +1,17 @@
+package com.fjhx.victoriatourist.entity.sales.dto;
+
+import com.ruoyi.common.core.domain.BaseSelectDto;
+import lombok.Getter;
+import lombok.Setter;
+
+/**
+ * 销售数据列表查询入参实体
+ *
+ * @author 
+ * @since 2023-04-19
+ */
+@Getter
+@Setter
+public class SalesRecordSelectDto extends BaseSelectDto {
+
+}

+ 45 - 0
hx-victoriatourist/src/main/java/com/fjhx/victoriatourist/entity/sales/po/SalesRecord.java

@@ -0,0 +1,45 @@
+package com.fjhx.victoriatourist.entity.sales.po;
+
+import com.alibaba.excel.annotation.ExcelIgnoreUnannotated;
+import com.baomidou.mybatisplus.annotation.TableName;
+import com.ruoyi.common.core.domain.BasePo;
+import lombok.Getter;
+import lombok.Setter;
+
+import java.math.BigDecimal;
+import java.util.Date;
+
+/**
+ * <p>
+ * 销售数据
+ * </p>
+ *
+ * @author
+ * @since 2023-04-19
+ */
+@Getter
+@Setter
+@TableName("sales_record")
+public class SalesRecord extends BasePo {
+
+    /**
+     * 产品id
+     */
+    private Long productId;
+
+    /**
+     * 销售日期
+     */
+    private Date dateSale;
+
+    /**
+     * 销售数量
+     */
+    private BigDecimal quantity;
+
+    /**
+     * 仓库id
+     */
+    private Long warehouseId;
+
+}

+ 47 - 0
hx-victoriatourist/src/main/java/com/fjhx/victoriatourist/entity/sales/vo/SalesRecordVo.java

@@ -0,0 +1,47 @@
+package com.fjhx.victoriatourist.entity.sales.vo;
+
+import com.fjhx.victoriatourist.entity.sales.po.SalesRecord;
+import lombok.Getter;
+import lombok.Setter;
+
+/**
+ * 销售数据列表查询返回值实体
+ *
+ * @author
+ * @since 2023-04-19
+ */
+@Getter
+@Setter
+public class SalesRecordVo extends SalesRecord {
+
+    /**
+     * 分类id
+     */
+    private Long classifyId;
+
+    /**
+     * 分类名称
+     */
+    private String classifyName;
+
+    /**
+     * 产品编码
+     */
+    private String productCode;
+
+    /**
+     * 产品名称
+     */
+    private String productName;
+
+    /**
+     * 产品规格型号
+     */
+    private String productSpec;
+
+    /**
+     * 产品单位
+     */
+    private String productUnit;
+
+}

+ 26 - 0
hx-victoriatourist/src/main/java/com/fjhx/victoriatourist/mapper/sales/SalesRecordMapper.java

@@ -0,0 +1,26 @@
+package com.fjhx.victoriatourist.mapper.sales;
+
+import com.fjhx.victoriatourist.entity.sales.po.SalesRecord;
+import com.baomidou.mybatisplus.core.mapper.BaseMapper;
+import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
+import com.fjhx.victoriatourist.entity.sales.vo.SalesRecordVo;
+import com.ruoyi.common.utils.wrapper.IWrapper;
+import org.apache.ibatis.annotations.Param;
+
+
+/**
+ * <p>
+ * 销售数据 Mapper 接口
+ * </p>
+ *
+ * @author 
+ * @since 2023-04-19
+ */
+public interface SalesRecordMapper extends BaseMapper<SalesRecord> {
+
+    /**
+     * 销售数据分页
+     */
+    Page<SalesRecordVo> getPage(@Param("page") Page<Object> page, @Param("ew") IWrapper<SalesRecord> wrapper);
+
+}

+ 29 - 0
hx-victoriatourist/src/main/java/com/fjhx/victoriatourist/service/sales/SalesRecordService.java

@@ -0,0 +1,29 @@
+package com.fjhx.victoriatourist.service.sales;
+
+import com.fjhx.victoriatourist.entity.sales.po.SalesRecord;
+import com.ruoyi.common.core.service.BaseService;
+import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
+import com.fjhx.victoriatourist.entity.sales.vo.SalesRecordVo;
+import com.fjhx.victoriatourist.entity.sales.dto.SalesRecordSelectDto;
+import org.springframework.web.multipart.MultipartFile;
+
+
+/**
+ * <p>
+ * 销售数据 服务类
+ * </p>
+ *
+ * @author 
+ * @since 2023-04-19
+ */
+public interface SalesRecordService extends BaseService<SalesRecord> {
+
+    /**
+     * 销售数据分页
+     */
+    Page<SalesRecordVo> getPage(SalesRecordSelectDto dto);
+
+
+    void excelImport(MultipartFile file, Long warehouseId);
+
+}

+ 128 - 0
hx-victoriatourist/src/main/java/com/fjhx/victoriatourist/service/sales/impl/SalesRecordServiceImpl.java

@@ -0,0 +1,128 @@
+package com.fjhx.victoriatourist.service.sales.impl;
+
+import com.baomidou.dynamic.datasource.annotation.DSTransactional;
+import com.baomidou.mybatisplus.core.toolkit.IdWorker;
+import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
+import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
+import com.fjhx.item.entity.product.po.ProductInfo;
+import com.fjhx.item.service.product.ProductClassifyService;
+import com.fjhx.item.service.product.ProductInfoService;
+import com.fjhx.item.util.excel.util.ExcelUtil;
+import com.fjhx.victoriatourist.entity.sales.bo.ExcelImportBo;
+import com.fjhx.victoriatourist.entity.sales.dto.SalesRecordSelectDto;
+import com.fjhx.victoriatourist.entity.sales.po.SalesRecord;
+import com.fjhx.victoriatourist.entity.sales.vo.SalesRecordVo;
+import com.fjhx.victoriatourist.mapper.sales.SalesRecordMapper;
+import com.fjhx.victoriatourist.service.sales.SalesRecordService;
+import com.fjhx.wms.entity.stock.bo.InOutBo;
+import com.fjhx.wms.entity.stock.emums.JournalType;
+import com.fjhx.wms.service.stock.StockService;
+import com.ruoyi.common.core.domain.BaseIdPo;
+import com.ruoyi.common.exception.ServiceException;
+import com.ruoyi.common.utils.wrapper.IWrapper;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.stereotype.Service;
+import org.springframework.web.multipart.MultipartFile;
+
+import java.util.*;
+import java.util.stream.Collectors;
+
+
+/**
+ * <p>
+ * 销售数据 服务实现类
+ * </p>
+ *
+ * @author
+ * @since 2023-04-19
+ */
+@Service
+public class SalesRecordServiceImpl extends ServiceImpl<SalesRecordMapper, SalesRecord> implements SalesRecordService {
+
+    @Autowired
+    private ProductInfoService productInfoService;
+
+    @Autowired
+    private ProductClassifyService productClassifyService;
+
+    @Autowired
+    private StockService stockService;
+
+    @Override
+    public Page<SalesRecordVo> getPage(SalesRecordSelectDto dto) {
+        IWrapper<SalesRecord> wrapper = getWrapper();
+        wrapper.orderByDesc("sr", SalesRecord::getId);
+        Page<SalesRecordVo> page = this.baseMapper.getPage(dto.getPage(), wrapper);
+        List<SalesRecordVo> records = page.getRecords();
+        if (records.size() == 0) {
+            return page;
+        }
+
+        productInfoService.attributeAssign(records, SalesRecord::getProductId, (item, product) -> {
+            item.setClassifyId(product.getProductClassifyId());
+            item.setProductCode(product.getCode());
+            item.setProductName(product.getName());
+            item.setProductUnit(product.getUnit());
+            item.setProductSpec(product.getSpec());
+        });
+
+        productClassifyService.attributeAssign(records, SalesRecordVo::getClassifyId, (item, classify) -> {
+            item.setClassifyName(classify.getName());
+        });
+
+        return page;
+    }
+
+    @DSTransactional
+    @Override
+    public void excelImport(MultipartFile file, Long warehouseId) {
+
+        // 读取excel数据
+        List<ExcelImportBo> excelImportBoList = ExcelUtil.read(file, ExcelImportBo.class);
+
+        // 产品code列表
+        List<String> productCodeList = excelImportBoList.stream()
+                .map(ExcelImportBo::getProductCode)
+                .filter(Objects::nonNull).distinct()
+                .collect(Collectors.toList());
+
+        // 产品信息
+        List<ProductInfo> productInfoList = productInfoService.list(q -> q.in(ProductInfo::getCode, productCodeList));
+
+        // 判断产品编码
+        if (productCodeList.size() != productInfoList.size()) {
+
+            Set<String> productCodeSet = productInfoList.stream().map(ProductInfo::getCode).collect(Collectors.toSet());
+
+            String nonexistenceCodeStr = productCodeList.stream()
+                    .filter(item -> !productCodeSet.contains(item))
+                    .collect(Collectors.joining(","));
+
+            throw new ServiceException("未知产品编码:" + nonexistenceCodeStr);
+        }
+
+        // 产品code id map
+        Map<String, Long> codeIdMap = productInfoList.stream()
+                .collect(Collectors.toMap(ProductInfo::getCode, BaseIdPo::getId));
+
+        List<SalesRecord> salesRecordList = excelImportBoList.stream().map(item -> {
+            SalesRecord salesRecord = new SalesRecord();
+            salesRecord.setId(IdWorker.getId());
+            salesRecord.setDateSale(item.getDateSale());
+            salesRecord.setQuantity(item.getQuantity());
+            salesRecord.setWarehouseId(warehouseId);
+            salesRecord.setProductId(codeIdMap.get(item.getProductCode()));
+
+            // 出入库明细
+            InOutBo inOutBo = new InOutBo();
+            inOutBo.setProductId(salesRecord.getProductId());
+            inOutBo.setQuantity(salesRecord.getQuantity());
+            stockService.inOut(Collections.singletonList(inOutBo), warehouseId, JournalType.JD_SALES_OUT, salesRecord.getId());
+
+            return salesRecord;
+        }).collect(Collectors.toList());
+
+        saveBatch(salesRecordList);
+    }
+
+}

+ 18 - 0
hx-victoriatourist/src/main/resources/mapper/sales/SalesRecordMapper.xml

@@ -0,0 +1,18 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!DOCTYPE mapper PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN" "http://mybatis.org/dtd/mybatis-3-mapper.dtd">
+<mapper namespace="com.fjhx.victoriatourist.mapper.sales.SalesRecordMapper">
+    <select id="getPage" resultType="com.fjhx.victoriatourist.entity.sales.vo.SalesRecordVo">
+        select
+            sr.id,
+            sr.product_id,
+            sr.date_sale,
+            sr.quantity,
+            sr.create_user,
+            sr.create_time,
+            sr.update_user,
+            sr.update_time
+        from sales_record sr
+            ${ew.customSqlSegment}
+    </select>
+
+</mapper>

+ 10 - 6
hx-wms/src/main/java/com/fjhx/wms/entity/stock/emums/JournalType.java

@@ -6,17 +6,21 @@ import lombok.Getter;
 @AllArgsConstructor
 @Getter
 public enum JournalType {
-//    操作类型 1手动入库 2手动出库 3调仓 4待入库入库 5待出库出库
+    //    操作类型 1手动入库 2手动出库 3调仓 4待入库入库 5待出库出库
 
-    COMBINATION_IN(InOutType.IN, 6, "组合入库", "group_record_details"),
-    COMBINATION_OUT(InOutType.OUT, 7, "组合出库", "group_record_details"),
-    SPLIT_IN(InOutType.IN, 8, "组合拆分入库", "group_record_details"),
-    SPLIT_OUT(InOutType.OUT, 9, "组合拆分出库", "group_record_details"),
     MANUAL_IN(InOutType.IN, 1, "手动入库", ""),
     MANUAL_OUT(InOutType.OUT, 2, "手动出库", ""),
     ADJUSTING(InOutType.ADJUSTING, 3, "调仓", ""),
     STOCK_WAIT_IN(InOutType.IN, 4, "待入库入库", "stock_wait"),
-    STOCK_WAIT_OUT(InOutType.OUT, 5, "待出库入库", "stock_wait");
+    STOCK_WAIT_OUT(InOutType.OUT, 5, "待出库入库", "stock_wait"),
+    COMBINATION_IN(InOutType.IN, 6, "组合入库", "group_record_details"),
+    COMBINATION_OUT(InOutType.OUT, 7, "组合出库", "group_record_details"),
+    SPLIT_IN(InOutType.IN, 8, "组合拆分入库", "group_record_details"),
+    SPLIT_OUT(InOutType.OUT, 9, "组合拆分出库", "group_record_details"),
+    JD_SALES_OUT(InOutType.OUT, 10, "京东销售出库", "sales_record"),
+
+    ;
+
 
     /**
      * 出入库类型