🆕 提交申请

This commit is contained in:
my_ong 2024-12-07 11:24:55 +08:00
parent e3be8f2510
commit 43f14ce542
10 changed files with 275 additions and 64 deletions

View File

@ -7,23 +7,22 @@ import io.swagger.v3.oas.annotations.Operation;
import io.swagger.v3.oas.annotations.Parameter;
import io.swagger.v3.oas.annotations.tags.Tag;
import lombok.RequiredArgsConstructor;
import org.nutz.lang.Strings;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.validation.annotation.Validated;
import org.springframework.web.bind.annotation.*;
import tech.riemann.ims.dto.request.ApplyInfo;
import tech.riemann.ims.dto.response.ApplyDTO;
import tech.riemann.ims.entity.material.ApplyDetail;
import tech.riemann.ims.entity.material.ApplyForm;
import tech.riemann.ims.entity.material.Material;
import tech.riemann.ims.entity.material.MaterialStockDetail;
import tech.riemann.ims.enums.ApplyTypeEnum;
import tech.riemann.ims.enums.AssignRuleEnum;
import tech.riemann.ims.enums.StockStatusEnum;
import tech.riemann.ims.enums.*;
import tech.riemann.ims.service.material.IApplyDetailService;
import tech.riemann.ims.service.material.IApplyFormService;
import tech.riemann.ims.service.material.IMaterialService;
import tech.riemann.ims.service.material.IMaterialStockDetailService;
import java.time.LocalDateTime;
import java.util.List;
import java.util.Map;
import java.util.stream.Collectors;
@ -42,18 +41,34 @@ public class ApplyFormController {
private final IMaterialStockDetailService materialStockDetailService;
private final IMaterialService materialService;
@GetMapping("apply")
@Operation(summary = "分页查询申请单列表")
public IPage<ApplyForm> applies(
@Parameter(description = "页码") @RequestParam(required = false, defaultValue = "1") int page,
@Parameter(description = "页面大小") @RequestParam(required = false, defaultValue = "10") int size,
@Parameter(description = "类型") @RequestParam(name = "type") Integer type, // 1入库 2出库
@Parameter(description = "搜索关键词") @RequestParam(required = false, defaultValue = "") String key) {
boolean hasLike = Strings.isNotBlank(key);
key = String.format("%%%s%%", key);
@GetMapping("applies")
@Operation(summary = "分页查询申请列表")
public IPage<ApplyDTO> searchPage(
@Parameter(description = "页码") @RequestParam(name = "page", required = false, defaultValue = "1") int page,
@Parameter(description = "页面大小") @RequestParam(name = "size", required = false, defaultValue = "10") int size,
@Parameter(description = "申请类型(1入库 3出库 4盘点)") @RequestParam(name = "applyType") Integer applyType,
@Parameter(description = "物料类型") @RequestParam(name = "type", required = false) String type,
@Parameter(description = "物料编码") @RequestParam(name = "code", required = false) String code,
@Parameter(description = "物料名称") @RequestParam(name = "name", required = false) String name) {
return applyFormService.search(page, size, applyType, type, code, name);
}
@GetMapping("audit-applies")
@Operation(summary = "分页查询盘点列表")
public IPage<ApplyForm> searchAuditPage(
@Parameter(description = "页码") @RequestParam(name = "page", required = false, defaultValue = "1") int page,
@Parameter(description = "页面大小") @RequestParam(name = "size", required = false, defaultValue = "10") int size,
@Parameter(description = "盘点类型") @RequestParam(name = "auditType", required = false) AuditTypeEnum auditType,
@Parameter(description = "盘点人") @RequestParam(name = "taker", required = false) String taker,
@Parameter(description = "创建日期") @RequestParam(name = "createDate", required = false) LocalDateTime createDate,
@Parameter(description = "审核状态") @RequestParam(name = "reviewResult", required = false) ReviewResultEnum reviewResult) {
return applyFormService.page(Page.of(page, size), Wrappers.<ApplyForm>lambdaQuery()
.eq(ApplyForm::getType, type)
.orderByDesc(ApplyForm::getUpdatedTime));
.eq(auditType != null, ApplyForm::getAuditType, auditType)
.eq(taker != null, ApplyForm::getTaker, taker)
.eq(createDate != null, ApplyForm::getCreatedTime, createDate)
.eq(reviewResult != null, ApplyForm::getReviewResult, reviewResult)
.orderByDesc(ApplyForm::getCreatedTime)
);
}
@GetMapping("apply/{applyId}")
@ -61,13 +76,13 @@ public class ApplyFormController {
public ApplyInfo detail(@Parameter(description = "类型") @PathVariable(name = "applyId") Integer applyId) {
List<ApplyDetail> list = applyDetailService.list(Wrappers.<ApplyDetail>lambdaQuery().eq(ApplyDetail::getApplyId, applyId));
return ApplyInfo.builder()
.applyForm(applyFormService.getById(applyId))
.applyDetails(list)
.build();
.applyForm(applyFormService.getById(applyId))
.applyDetails(list)
.build();
}
@PutMapping("apply")
@Operation(summary = "提交申请单")
@Operation(summary = "提交出入库申请单")
@Transactional(rollbackFor = Exception.class)
public void saveApply(@Validated @Parameter(description = "申请单") @RequestBody ApplyInfo applyInfo) {
// 如果是采购入库 就新增数据否则只改状态
@ -75,14 +90,14 @@ public class ApplyFormController {
// 校验物料数量
Map<Long, Integer> confirmMap = applyInfo.getApplyDetails().stream()
.filter(item -> item.getAssignRule() == AssignRuleEnum.LOW_VALUE)
.filter(item -> item.getAssignRule() != AssignRuleEnum.LOW_VALUE)
.collect(Collectors.toMap(ApplyDetail::getMaterialId, ApplyDetail::getConfirmQuantity));
Map<Long, Long> dataMap = applyInfo.getDetailList().stream()
.collect(Collectors.groupingBy(MaterialStockDetail::getMaterialId, Collectors.counting()));
confirmMap.forEach((k, v) -> {
Long l = dataMap.get(k);
if(l == null || l.intValue() != v){
throw new IllegalArgumentException("["+k+"]物料数量不匹配");
if (l == null || l.intValue() != v) {
throw new IllegalArgumentException("[" + k + "]物料数量不匹配");
}
});
// 新增申请单
@ -94,29 +109,52 @@ public class ApplyFormController {
if (applyType == ApplyTypeEnum.PURCHASE_RECEIPT) {
// 新增物料
applyInfo.getDetailList().forEach(detail -> {
detail.setApplyId(applyInfo.getApplyForm().getId());
detail.setStatus(StockStatusEnum.IN);
});
materialStockDetailService.saveBatch(applyInfo.getDetailList());
if(!applyInfo.getDetailList().isEmpty()){
applyInfo.getDetailList().forEach(detail -> {
detail.setApplyId(applyInfo.getApplyForm().getId());
detail.setStatus(StockStatusEnum.IN);
});
materialStockDetailService.saveBatch(applyInfo.getDetailList());
}
//记录物料库存数据
applyInfo.getApplyDetails().forEach(detail ->
materialService.update(Wrappers.<Material>lambdaUpdate()
.eq(Material::getId, detail.getMaterialId())
.setSql("m_stock = m_stock + " + detail.getConfirmQuantity())
.setSql(detail.getAssignRule() == AssignRuleEnum.HIGH_VALUE,
"m_stock = m_stock + " + detail.getConfirmQuantity())
.setSql(detail.getAssignRule() == AssignRuleEnum.LOW_VALUE,
"m_stock = m_stock + " + detail.getQuantity())
));
}
else if(applyType == ApplyTypeEnum.LOAN_OUT || applyType == ApplyTypeEnum.RETURN_RECEIPT) {
} else if (applyType == ApplyTypeEnum.LOAN_OUT) {
//修改物料状态
applyInfo.getDetailList().forEach(detail -> materialStockDetailService.update(Wrappers.<MaterialStockDetail>lambdaUpdate()
.set(MaterialStockDetail::getMaterialId, applyType ==ApplyTypeEnum.RETURN_RECEIPT
? StockStatusEnum.IN : StockStatusEnum.OUT)
.eq(MaterialStockDetail::getBarcode, detail.getBarcode())));
if(!applyInfo.getDetailList().isEmpty()){
applyInfo.getDetailList().forEach(detail -> materialStockDetailService.update(Wrappers.<MaterialStockDetail>lambdaUpdate()
.set(MaterialStockDetail::getStatus, StockStatusEnum.OUT)
.eq(MaterialStockDetail::getBarcode, detail.getBarcode())));
}
//修改物料库存数据
confirmMap.forEach((key, value) -> materialService.update(Wrappers.<Material>lambdaUpdate()
.setSql(applyType == ApplyTypeEnum.LOAN_OUT,"m_stock = m_stock - " + value)
.setSql(applyType == ApplyTypeEnum.RETURN_RECEIPT,"m_stock = m_stock + " + value)
.eq(Material::getId, key)));
applyInfo.getApplyDetails().forEach(detail -> materialService.update(Wrappers.<Material>lambdaUpdate()
.eq(Material::getId, detail.getMaterialId())
.setSql(detail.getAssignRule() == AssignRuleEnum.HIGH_VALUE,
"m_stock = m_stock - " + detail.getConfirmQuantity())
.setSql(detail.getAssignRule() == AssignRuleEnum.LOW_VALUE,
"m_stock = m_stock - " + detail.getQuantity())
));
} else if (applyType == ApplyTypeEnum.RETURN_RECEIPT) {
//修改物料状态
if(!applyInfo.getDetailList().isEmpty()){
applyInfo.getDetailList().forEach(detail -> materialStockDetailService.update(Wrappers.<MaterialStockDetail>lambdaUpdate()
.set(MaterialStockDetail::getStatus, StockStatusEnum.IN)
.eq(MaterialStockDetail::getBarcode, detail.getBarcode())));
}
//修改物料库存数据
applyInfo.getApplyDetails().forEach(detail -> materialService.update(Wrappers.<Material>lambdaUpdate()
.eq(Material::getId, detail.getMaterialId())
.setSql(detail.getAssignRule() == AssignRuleEnum.HIGH_VALUE,
"m_stock = m_stock + " + detail.getConfirmQuantity())
.setSql(detail.getAssignRule() == AssignRuleEnum.LOW_VALUE,
"m_stock = m_stock + " + detail.getQuantity())
));
}
}

View File

@ -0,0 +1,50 @@
package tech.riemann.ims.dto.response;
import io.swagger.v3.oas.annotations.media.Schema;
import lombok.AllArgsConstructor;
import lombok.Builder;
import lombok.Data;
import lombok.NoArgsConstructor;
import tech.riemann.ims.enums.ApplyTypeEnum;
/**
* @author mayong
* @since 2024/12/6 21:21
*/
@Data
@Builder
@AllArgsConstructor
@NoArgsConstructor
public class ApplyDTO {
@Schema(description = "申请类型")
private ApplyTypeEnum applyType;
@Schema(description = "物料名称")
private String name;
@Schema(description = "物料编码")
private String code;
@Schema(description = "物料类型")
private String type;
@Schema(description = "物料规格")
private String spec;
@Schema(description = "申请人")
private String applicant;
@Schema(description = "申请日期")
private String applyDate;
@Schema(description = "申请数量")
private String applyNum;
@Schema(description = "确认数量")
private String confirmNum;
@Schema(description = "备注")
private String remark;
}

View File

@ -15,6 +15,7 @@ import tech.riemann.ims.entity.IdBaseEntity;
import tech.riemann.ims.enums.ApplyTypeEnum;
import tech.riemann.ims.enums.AuditTypeEnum;
import tech.riemann.ims.enums.HandleEnum;
import tech.riemann.ims.enums.ReviewResultEnum;
import java.io.Serial;
import java.time.LocalDateTime;
@ -61,11 +62,25 @@ public class ApplyForm extends IdBaseEntity {
@ColDefine(notNull = false, width = 128, precision = 0)
private String applicant;
@Schema(description = "盘点审核人", requiredMode = Schema.RequiredMode.NOT_REQUIRED)
@TableField("af_reviewer")
@Column("af_reviewer")
@Comment("盘点审核人")
@ColDefine(notNull = false, width = 128, precision = 0)
private String reviewer;
@Schema(description = "盘点人", requiredMode = Schema.RequiredMode.NOT_REQUIRED)
@TableField("af_taker")
@Column("af_taker")
@Comment("盘点人")
@ColDefine(notNull = false, width = 128, precision = 0)
private String taker;
@Schema(description = "申请日期", requiredMode = Schema.RequiredMode.NOT_REQUIRED)
@TableField("af_apply_date")
@Column("af_apply_date")
@Comment("申请日期")
@ColDefine(type = ColType.DATE, notNull = false, width = 128, precision = 0)
@ColDefine(type = ColType.DATETIME, notNull = false, width = 128, precision = 0)
private LocalDateTime applyDate;
@Schema(description = "是否确认0: 未确认 1: 已确认)", requiredMode = Schema.RequiredMode.NOT_REQUIRED)
@ -89,11 +104,18 @@ public class ApplyForm extends IdBaseEntity {
@ColDefine(type = ColType.VARCHAR, notNull = false, width = 512, precision = 0)
private String exception;
@Schema(description = "处理方式(0-无需处理 1-忽略并修改库存 2-补充库存 3-其他)", requiredMode = Schema.RequiredMode.NOT_REQUIRED)
@TableField("s_exception_handle")
@Column("s_exception_handle")
@Comment("处理方式(0-无需处理 1-忽略并修改库存 2-补充库存 3-其他)")
@Schema(description = "处理方式(1-无需处理 2-忽略并修改库存 3-补充库存 4-其他)", requiredMode = Schema.RequiredMode.NOT_REQUIRED)
@TableField("af_exception_handle")
@Column("af_exception_handle")
@Comment("处理方式(处理方式(1-无需处理 2-忽略并修改库存 3-补充库存 4-其他))")
@ColDefine(type = ColType.VARCHAR, notNull = false, width = 128, precision = 0)
private HandleEnum handle;
@Schema(description = "审核结果(1-通过 2-不通过 3-待审核 4-退回重新盘点)", requiredMode = Schema.RequiredMode.NOT_REQUIRED)
@TableField("af_review_result")
@Column("af_review_result")
@Comment("审核结果(1-通过 2-不通过 3-待审核 4-退回重新盘点)")
@ColDefine(notNull = false, width = 128, precision = 0)
private ReviewResultEnum reviewResult;
}

View File

@ -1,20 +1,11 @@
package tech.riemann.ims.entity.material;
import com.baomidou.mybatisplus.annotation.TableField;
import com.baomidou.mybatisplus.annotation.TableName;
import io.swagger.v3.oas.annotations.media.Schema;
import io.swagger.v3.oas.annotations.media.Schema.RequiredMode;
import lombok.AllArgsConstructor;
import lombok.Data;
import lombok.EqualsAndHashCode;
import lombok.NoArgsConstructor;
import lombok.experimental.Accessors;
import lombok.experimental.FieldNameConstants;
import lombok.experimental.SuperBuilder;
import org.nutz.dao.entity.annotation.ColDefine;
import org.nutz.dao.entity.annotation.Column;
import org.nutz.dao.entity.annotation.Comment;
import org.nutz.dao.entity.annotation.Table;
import tech.riemann.ims.entity.IdBaseEntity;
import java.io.Serial;
@ -26,17 +17,17 @@ import java.io.Serial;
*
* @since 2024-12-06 10:32:29
*/
@Data
@SuperBuilder
@NoArgsConstructor
@AllArgsConstructor
@FieldNameConstants
@EqualsAndHashCode(callSuper = true)
@Accessors(chain = true)
@TableName("t_stocktaking_audit")
@Table("t_stocktaking_audit")
@Comment("盘点审核表")
@Schema(name = "StocktakingAudit", description = "盘点审核表")
//@Data
//@SuperBuilder
//@NoArgsConstructor
//@AllArgsConstructor
//@FieldNameConstants
//@EqualsAndHashCode(callSuper = true)
//@Accessors(chain = true)
//@TableName("t_stocktaking_audit")
//@Table("t_stocktaking_audit")
//@Comment("盘点审核表")
//@Schema(name = "StocktakingAudit", description = "盘点审核表")
public class StocktakingAudit extends IdBaseEntity{
@Serial

View File

@ -13,7 +13,7 @@ import lombok.Getter;
@AllArgsConstructor
public enum HandleEnum implements ICodeBook {
NO_ACTION("0", "无需处理"),
NO_ACTION("1", "无需处理"),
IGNORE_AND_SAVE("2", "忽略并保存"),
REPLENISH("3", "补货"),
OTHER("4", "其他")

View File

@ -0,0 +1,26 @@
package tech.riemann.ims.enums;
import club.zhcs.lina.utils.enums.ICodeBook;
import com.baomidou.mybatisplus.annotation.EnumValue;
import lombok.AllArgsConstructor;
import lombok.Getter;
/**
* @author mayong
* @since 2024/12/7 10:10
*/
@Getter
@AllArgsConstructor
public enum ReviewResultEnum implements ICodeBook {
PASS("1", "全部盘点"),
UN_PASS("2", "部分盘点"),
WAIT("3", "等待审核"),
REJECT("4", "退回"),
;
@EnumValue
final String code;
final String description;
}

View File

@ -1,6 +1,8 @@
package tech.riemann.ims.mapper.material;
import com.baomidou.mybatisplus.core.mapper.BaseMapper;
import com.baomidou.mybatisplus.core.metadata.IPage;
import tech.riemann.ims.dto.response.ApplyDTO;
import tech.riemann.ims.entity.material.ApplyForm;
/**
@ -8,4 +10,6 @@ import tech.riemann.ims.entity.material.ApplyForm;
* @since 2024/11/28 15:38
*/
public interface ApplyFormMapper extends BaseMapper<ApplyForm> {
IPage<ApplyDTO> searchPage(IPage<ApplyDTO> page, Integer applyType, String type, String code, String name);
}

View File

@ -1,7 +1,9 @@
package tech.riemann.ims.service.material;
import com.baomidou.mybatisplus.core.metadata.IPage;
import com.baomidou.mybatisplus.extension.service.IService;
import org.nutz.spring.boot.service.interfaces.IdNameEntityService;
import tech.riemann.ims.dto.response.ApplyDTO;
import tech.riemann.ims.entity.material.ApplyForm;
/**
@ -9,4 +11,16 @@ import tech.riemann.ims.entity.material.ApplyForm;
* @since 2024/11/28 15:35
*/
public interface IApplyFormService extends IService<ApplyForm>, IdNameEntityService<ApplyForm> {
/**
*
* @param page 页码
* @param size 每页数量
* @param applyType 申请类型
* @param type 申请材料类型
* @param code 申请材料编码
* @param name 申请材料名称
* @return IPage<ApplyDTO>
*/
IPage<ApplyDTO> search(int page, int size, Integer applyType, String type, String code, String name);
}

View File

@ -1,9 +1,12 @@
package tech.riemann.ims.service.material.impl;
import com.baomidou.mybatisplus.core.metadata.IPage;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import lombok.RequiredArgsConstructor;
import org.nutz.dao.Dao;
import org.springframework.stereotype.Service;
import tech.riemann.ims.dto.response.ApplyDTO;
import tech.riemann.ims.entity.material.ApplyForm;
import tech.riemann.ims.mapper.material.ApplyFormMapper;
import tech.riemann.ims.service.material.IApplyFormService;
@ -16,10 +19,16 @@ import tech.riemann.ims.service.material.IApplyFormService;
@RequiredArgsConstructor
public class ApplyFormServiceImpl extends ServiceImpl<ApplyFormMapper, ApplyForm> implements IApplyFormService {
private final ApplyFormMapper applyFormMapper;
private final Dao dao;
@Override
public Dao dao() {
return dao;
}
@Override
public IPage<ApplyDTO> search(int page, int size, Integer applyType, String type, String code, String name) {
return applyFormMapper.searchPage(Page.of(page, size), applyType, type, code, name);
}
}

View File

@ -0,0 +1,57 @@
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE mapper PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN" "https://mybatis.org/dtd/mybatis-3-mapper.dtd">
<mapper namespace="tech.riemann.ims.mapper.material.ApplyFormMapper">
<resultMap id="resultMap" type="tech.riemann.ims.dto.response.ApplyDTO">
<result property="applyNum" column="ad_quantity" />
<result property="applyDate" column="af_apply_date" />
<result property="applicant" column="af_applicant" />
<result property="confirmNum" column="ad_confirm_quantity" />
<result property="type" column="m_type" />
<result property="code" column="m_code" />
<result property="name" column="m_name" />
<result property="spec" column="m_spec" />
<result property="applyType" column="af_type" />
<result property="remark" column="ad_exception_remark" />
</resultMap>
<select id="searchPage" resultMap="resultMap">
SELECT
d.ad_quantity,
f.af_apply_date,
d.ad_exception_remark,
d.ad_confirm_quantity,
f.af_applicant,
m.m_type,
m.m_code,
m.m_name,
m.m_spec,
f.af_type
FROM
t_apply_form f
LEFT JOIN t_apply_detail d ON f.id = d.ad_apply_id
LEFT JOIN t_material m ON d.ad_material_id = m.id
WHERE 1 = 1
<if test="applyType!= null and applyType!= ''">
<choose>
<when test="applyType == '1'">
and f.af_type in ('1', '2')
</when>
<otherwise>
and f.af_type = #{applyType}
</otherwise>
</choose>
</if>
<if test="type!= null and type!= ''">
AND m.m_type = #{type}
</if>
<if test="code!= null and code!= ''">
AND m.m_code LIKE CONCAT('%', #{code}, '%')
</if>
<if test="name!= null and name!= ''">
AND m.m_name LIKE CONCAT('%', #{name}, '%')
</if>
ORDER BY f.af_apply_date DESC
</select>
</mapper>