yys
1.客户档案导入-维护人,维护时间默认当前
2.销售报价审核非必填,产品选择方式也要改
3.销售产品增加物料号字段
4.产品维护增加录入时间,修改时间
6.发货审核不需要了
7.BI的生产核算分析不要了,增加生产订单当前工序
3.库存导入模板规格改成图纸编号,产品名称可以为空,加个库位
4.库存管理外购改为标准件
5.bom产品唯一
6.产品根据bom计算子项数量(只统计二级)
| | |
| | | package com.ruoyi.basic.dto; |
| | | |
| | | import com.baomidou.mybatisplus.annotation.FieldFill; |
| | | import com.baomidou.mybatisplus.annotation.TableField; |
| | | import com.fasterxml.jackson.annotation.JsonFormat; |
| | | import com.ruoyi.framework.aspectj.lang.annotation.Excel; |
| | | import com.ruoyi.sales.pojo.CommonFile; |
| | | import io.swagger.annotations.ApiModelProperty; |
| | | import lombok.Data; |
| | | |
| | | import java.time.LocalDateTime; |
| | | import java.util.List; |
| | | |
| | | /** |
| | |
| | | |
| | | private String routeName; |
| | | |
| | | @ApiModelProperty(value = "子项数量") |
| | | @Excel(name = "子项数量") |
| | | private Long subItemCount; |
| | | |
| | | /** |
| | | * 规格id |
| | | * 图纸编号id |
| | | */ |
| | | private Long id; |
| | | |
| | |
| | | @ApiModelProperty(value = "1=自制,2=外购,3=委外") |
| | | private Integer productType; |
| | | |
| | | |
| | | @ApiModelProperty(value = "创建时间") |
| | | @JsonFormat(pattern = "yyyy-MM-dd", timezone = "GMT+8",shape = JsonFormat.Shape.STRING) |
| | | private LocalDateTime createTime; |
| | | |
| | | @ApiModelProperty(value = "修改时间") |
| | | @JsonFormat(pattern = "yyyy-MM-dd", timezone = "GMT+8",shape = JsonFormat.Shape.STRING) |
| | | private LocalDateTime updateTime; |
| | | |
| | | } |
| | |
| | | /** |
| | | * 维护人 |
| | | */ |
| | | @Excel(name = "维护人") |
| | | // @Excel(name = "维护人") |
| | | private String maintainer; |
| | | |
| | | /** |
| | | * 维护时间 |
| | | */ |
| | | @JsonFormat(pattern = "yyyy-MM-dd") |
| | | @Excel(name = "维护时间" , width = 30, dateFormat = "yyyy-MM-dd") |
| | | // @Excel(name = "维护时间" , width = 30, dateFormat = "yyyy-MM-dd") |
| | | private Date maintenanceTime; |
| | | |
| | | @TableField(fill = FieldFill.INSERT) |
| | |
| | | @Excel(name = "规格型号") |
| | | private String drawingNumber; |
| | | |
| | | @TableField(exist = false) |
| | | private LocalDateTime createTime; |
| | | |
| | | @ApiModelProperty(value = "产品类型(1-物料,2-产品)") |
| | | private Integer productType; |
| | | |
| | | @ApiModelProperty(value = "创建时间") |
| | | @TableField(fill = FieldFill.INSERT) |
| | | private LocalDateTime createTime; |
| | | |
| | | @ApiModelProperty(value = "修改时间") |
| | | @TableField(fill = FieldFill.INSERT_UPDATE) |
| | | private LocalDateTime updateTime; |
| | | |
| | | } |
| | |
| | | import com.ruoyi.basic.mapper.CustomerMapper; |
| | | import com.ruoyi.basic.pojo.Customer; |
| | | import com.ruoyi.basic.service.ICustomerService; |
| | | import com.ruoyi.common.utils.DateUtils; |
| | | import com.ruoyi.common.utils.SecurityUtils; |
| | | import com.ruoyi.common.utils.StringUtils; |
| | | import com.ruoyi.common.utils.poi.ExcelUtil; |
| | |
| | | |
| | | @Override |
| | | public AjaxResult importData(MultipartFile file) { |
| | | String nickName = SecurityUtils.getLoginUser().getNickName(); |
| | | try { |
| | | ExcelUtil<Customer> util = new ExcelUtil<Customer>(Customer.class); |
| | | List<Customer> userList = util.importExcel(file.getInputStream()); |
| | | if(CollectionUtils.isEmpty(userList)){ |
| | | return AjaxResult.warn("模板错误或导入数据为空"); |
| | | } |
| | | for (Customer customer : userList) { |
| | | customer.setMaintenanceTime(DateUtils.getNowDate()); |
| | | customer.setMaintainer(nickName); |
| | | } |
| | | this.saveOrUpdateBatch(userList); |
| | | return AjaxResult.success(true); |
| | | }catch (Exception e){ |
| | |
| | | import com.ruoyi.common.utils.bean.BeanUtils; |
| | | import com.ruoyi.common.utils.poi.ExcelUtil; |
| | | import com.ruoyi.framework.web.domain.AjaxResult; |
| | | import com.ruoyi.production.service.impl.ProductBomServiceImpl; |
| | | import com.ruoyi.sales.service.impl.CommonFileServiceImpl; |
| | | import lombok.AllArgsConstructor; |
| | | import org.apache.commons.collections4.CollectionUtils; |
| | | import org.springframework.beans.factory.annotation.Autowired; |
| | | import org.springframework.stereotype.Service; |
| | | import org.springframework.web.multipart.MultipartFile; |
| | | |
| | |
| | | import java.util.stream.Collectors; |
| | | |
| | | @Service |
| | | @AllArgsConstructor |
| | | public class ProductServiceImpl extends ServiceImpl<ProductMapper, Product> implements IProductService { |
| | | |
| | | @Autowired |
| | | private ProductMapper productMapper; |
| | | |
| | | @Autowired |
| | | private ProductModelMapper productModelMapper; |
| | | |
| | | private final CommonFileServiceImpl commonFileService; |
| | | @Autowired |
| | | private CommonFileServiceImpl commonFileService; |
| | | |
| | | @Autowired |
| | | private ProductBomServiceImpl productBomService; |
| | | |
| | | @Override |
| | | public List<ProductTreeDto> selectProductList(ProductDto productDto) { |
| | |
| | | public AjaxResult listPage(Page page, ProductAndModelDto productDto) { |
| | | IPage<ProductAndModelDto> productAndModelDtoIPage = productModelMapper.listPage(page, productDto); |
| | | productAndModelDtoIPage.getRecords().forEach(item -> { |
| | | item.setSubItemCount(productBomService.countChild(item.getId())); |
| | | item.setSalesLedgerFiles(commonFileService.getFileListByBusinessId(item.getId(), FileNameType.PRODUCT_MODEL.getValue())); |
| | | }); |
| | | return AjaxResult.success(productAndModelDtoIPage); |
| | |
| | | import com.ruoyi.production.mapper.SalesLedgerProductionAccountingMapper; |
| | | import com.ruoyi.production.pojo.ProductProcess; |
| | | import com.ruoyi.production.pojo.ProductWorkOrder; |
| | | import com.ruoyi.production.service.impl.ProductOrderServiceImpl; |
| | | import com.ruoyi.project.system.domain.SysDept; |
| | | import com.ruoyi.project.system.mapper.SysDeptMapper; |
| | | import com.ruoyi.purchase.mapper.PaymentRegistrationMapper; |
| | |
| | | |
| | | @Autowired |
| | | private ProductOrderMapper productOrderMapper; |
| | | |
| | | @Autowired |
| | | private ProductOrderServiceImpl productOrderService; |
| | | |
| | | @Autowired |
| | | private ProductWorkOrderMapper productWorkOrderMapper; |
| | |
| | | ProductOrderDto orderDto = new ProductOrderDto(); |
| | | orderDto.setStartTime(LocalDateTime.now().minusMonths(1)); |
| | | orderDto.setEndTime(LocalDateTime.now()); |
| | | List<ProductOrderDto> productOrderDtos = productOrderMapper.pageProductOrder(new Page<>(1, -1), orderDto) |
| | | List<ProductOrderDto> productOrderDtos = productOrderService.pageProductOrder(new Page<>(1, -1), orderDto) |
| | | .getRecords(); |
| | | productionProgressDto.setCompletedOrderDetails(productOrderDtos); |
| | | long totalCount = productOrderDtos.size(); |
| | |
| | | @JsonFormat(pattern = "yyyy-MM-dd HH:mm:ss", timezone = "GMT+8") |
| | | private LocalDateTime updateTime; |
| | | |
| | | @ApiModelProperty("产品型号id") |
| | | private Long productModelId; |
| | | |
| | | @ApiModelProperty("是否返修 1-是 2-否") |
| | | private Integer isReturn; |
| | | |
| | | |
| | | } |
| | |
| | | @Log(title = "修改", businessType = BusinessType.UPDATE) |
| | | @PutMapping("/update") |
| | | public AjaxResult update(@RequestBody ProductBom productBom) { |
| | | return AjaxResult.success(productBomService.updateById(productBom)); |
| | | return AjaxResult.success(productBomService.updateBom(productBom)); |
| | | } |
| | | |
| | | @ApiOperation("删除BOM") |
| | |
| | | void uploadBom(MultipartFile file,HttpServletResponse response); |
| | | |
| | | void exportBom(HttpServletResponse response, Integer bomId); |
| | | |
| | | String updateBom(ProductBom productBom); |
| | | } |
| | |
| | | List<ProductStructureDto> listBybomId(Integer bomId); |
| | | |
| | | List<ProductStructureDto> listBybomIdIsParent(Integer bomId); |
| | | |
| | | Long countBybomId(Integer bomId); |
| | | } |
| | |
| | | @Autowired |
| | | private ProductProcessService productProcessService; |
| | | |
| | | |
| | | @Override |
| | | public IPage<ProductBomDto> listPage(Page page, ProductBomDto productBomDto) { |
| | | return productBomMapper.listPage(page, productBomDto); |
| | | } |
| | | |
| | | /** |
| | | * 产品根据bom计算子项数量(只统计二级) |
| | | */ |
| | | public Long countChild(Long productModelId) { |
| | | ProductBom productBom = productBomMapper.selectOne(new LambdaQueryWrapper<ProductBom>() |
| | | .eq(ProductBom::getProductModelId, productModelId)); |
| | | if(productBom != null){ |
| | | return productStructureService.countBybomId(productBom.getId()); |
| | | } |
| | | return 0L; |
| | | } |
| | | |
| | | /** |
| | | * 判断产品是否存在bom false不存在 true存在 |
| | | * @param productBom |
| | | * @return |
| | | */ |
| | | public boolean checkBom(ProductBom productBom) { |
| | | ProductBom productBom1 = productBomMapper.selectOne(new LambdaQueryWrapper<ProductBom>() |
| | | .eq(ProductBom::getProductModelId, productBom.getProductModelId())); |
| | | return productBom1 == null ? false : true; |
| | | } |
| | | |
| | | @Override |
| | | @Transactional(rollbackFor = Exception.class) |
| | | public AjaxResult add(ProductBom productBom) { |
| | | boolean b = checkBom(productBom); |
| | | if (b) { |
| | | return AjaxResult.error("产品模型已存在BOM"); |
| | | } |
| | | boolean save = productBomMapper.insert(productBom) > 0; |
| | | if (save) { |
| | | String no = "BM." + String.format("%05d", productBom.getId()); |
| | |
| | | errorList.add(error); |
| | | continue; |
| | | } |
| | | |
| | | ProductBom bom = new ProductBom(); |
| | | bom.setProductModelId(rootModel.getId()); |
| | | bom.setVersion("1.0"); |
| | | boolean b = checkBom(bom); |
| | | if(b){ |
| | | BomImportErrorDto error = new BomImportErrorDto(); |
| | | BeanUtils.copyProperties(first, error); |
| | | error.setErrorMsg("产品【"+ first.getParentSpec() + "】BOM已存在"); |
| | | errorList.add(error); |
| | | continue; |
| | | } |
| | | productBomMapper.insert(bom); |
| | | bom.setBomNo("BM." + String.format("%05d", bom.getId())); |
| | | productBomMapper.updateById(bom); |
| | |
| | | util.exportExcel(response, exportList, "BOM结构导出"); |
| | | } |
| | | |
| | | @Override |
| | | public String updateBom(ProductBom productBom) { |
| | | ProductBom productBom1 = productBomMapper.selectById(productBom.getId()); |
| | | if(productBom.getProductModelId().equals(productBom1.getProductModelId())){ |
| | | productBomMapper.updateById(productBom); |
| | | }else{ |
| | | boolean b = checkBom(productBom); |
| | | if(b){ |
| | | throw new ServiceException("产品BOM已存在"); |
| | | }else{ |
| | | productBomMapper.updateById(productBom); |
| | | } |
| | | } |
| | | return "修改成功"; |
| | | } |
| | | |
| | | private void populateMap(List<ProductStructureDto> nodes, Map<Long, ProductStructureDto> map) { |
| | | if (nodes == null || nodes.isEmpty()) { |
| | | return; |
| | |
| | | return productStructureMapper.listBybomId(bomId,true); |
| | | } |
| | | |
| | | @Override |
| | | public Long countBybomId(Integer bomId) { |
| | | ProductStructure productStructure = productStructureMapper.selectOne(new LambdaQueryWrapper<ProductStructure>() |
| | | .eq(ProductStructure::getBomId, bomId) |
| | | .isNull(ProductStructure::getParentId)); |
| | | if(productStructure != null){ |
| | | return productStructureMapper.selectCount(new LambdaQueryWrapper<ProductStructure>() |
| | | .eq(ProductStructure::getParentId, productStructure.getId())); |
| | | } |
| | | return 0L; |
| | | } |
| | | |
| | | } |
| | |
| | | @Transactional(rollbackFor = Exception.class) |
| | | @Log(title = "发货信息管理", businessType = BusinessType.INSERT) |
| | | public AjaxResult add(@RequestBody ShippingInfoDto req) throws Exception { |
| | | LoginUser loginUser = SecurityUtils.getLoginUser(); |
| | | // LoginUser loginUser = SecurityUtils.getLoginUser(); |
| | | String sh = OrderUtils.countTodayByCreateTime(shippingInfoMapper, "SH"); |
| | | // 发货审批 |
| | | ApproveProcessVO approveProcessVO = new ApproveProcessVO(); |
| | | approveProcessVO.setApproveType(7); |
| | | approveProcessVO.setApproveDeptId(loginUser.getCurrentDeptId()); |
| | | approveProcessVO.setApproveReason(req.getType() + ":" +sh); |
| | | approveProcessVO.setApproveUserIds(req.getApproveUserIds()); |
| | | approveProcessVO.setApproveUser(loginUser.getUserId()); |
| | | approveProcessVO.setApproveTime(LocalDate.now().toString()); |
| | | approveProcessService.addApprove(approveProcessVO); |
| | | // ApproveProcessVO approveProcessVO = new ApproveProcessVO(); |
| | | // approveProcessVO.setApproveType(7); |
| | | // approveProcessVO.setApproveDeptId(loginUser.getCurrentDeptId()); |
| | | // approveProcessVO.setApproveReason(req.getType() + ":" +sh); |
| | | // approveProcessVO.setApproveUserIds(req.getApproveUserIds()); |
| | | // approveProcessVO.setApproveUser(loginUser.getUserId()); |
| | | // approveProcessVO.setApproveTime(LocalDate.now().toString()); |
| | | // approveProcessService.addApprove(approveProcessVO); |
| | | // 添加发货消息 |
| | | req.setShippingNo(sh); |
| | | req.setStatus("待审核"); |
| | | req.setStatus("待发货"); |
| | | boolean save = shippingInfoService.save(req); |
| | | return save ? AjaxResult.success() : AjaxResult.error(); |
| | | } |
| | |
| | | private String productCategory; |
| | | |
| | | /** |
| | | * 规格型号 |
| | | * 图纸编号 |
| | | */ |
| | | @Excel(name = "规格型号") |
| | | @Excel(name = "图纸编号") |
| | | private String specificationModel; |
| | | |
| | | /** |
| | |
| | | @ApiModelProperty(value = "退货数量") |
| | | @TableField(exist = false) |
| | | private BigDecimal returnNum; |
| | | |
| | | @ApiModelProperty(value = "物料号") |
| | | private String material; |
| | | } |
| | |
| | | private String paymentMethod; |
| | | @ApiModelProperty(value = "交货周期天数") |
| | | private String deliveryPeriod; |
| | | @ApiModelProperty(value = "状态") |
| | | @ApiModelProperty(value = "状态 待审批 审核中 拒绝 通过") |
| | | private String status; |
| | | @ApiModelProperty(value = "报价总金额") |
| | | @Excel(name = "报价金额") |
| | |
| | | private ShippingInfoServiceImpl shippingInfoService; |
| | | private ReturnSaleProductMapper returnSaleProductMapper; |
| | | private ReturnManagementMapper returnManagementMapper; |
| | | |
| | | |
| | | private StockUtils stockUtils; |
| | | |
| | | |
| | | |
| | | @Autowired |
| | | private ProductStructureMapper productStructureMapper; |
| | |
| | | List<SalesLedgerProduct> salesLedgerProducts = salesLedgerProductMapper.selectSalesLedgerProductList(salesLedgerProduct); |
| | | if(!CollectionUtils.isEmpty(salesLedgerProducts)){ |
| | | salesLedgerProducts.forEach(item -> { |
| | | |
| | | // 发货信息 |
| | | ShippingInfo shippingInfo = shippingInfoMapper.selectOne(new LambdaQueryWrapper<ShippingInfo>() |
| | | .eq(ShippingInfo::getSalesLedgerProductId, item.getId()) |
| | |
| | | int count = 0; |
| | | StringBuilder stringBuffer = new StringBuilder(); |
| | | for (ProductStructureDto productStructureDto : productStructureDtos) { |
| | | StockInventory stockInventory = stockInventoryMapper.selectOne(new QueryWrapper<StockInventory>().lambda().eq(StockInventory::getProductModelId, productStructureDto.getProductModelId())); |
| | | StockInventory stockInventory = stockInventoryMapper.selectOne(new QueryWrapper<StockInventory>() |
| | | .lambda() |
| | | .eq(StockInventory::getProductModelId, productStructureDto.getProductModelId())); |
| | | |
| | | //所需数量 |
| | | BigDecimal multiply = salesLedgerProduct.getQuantity().multiply(productStructureDto.getUnitQuantity()); |
| | |
| | | import com.ruoyi.approve.vo.ApproveProcessVO; |
| | | import com.ruoyi.common.utils.OrderUtils; |
| | | import com.ruoyi.common.utils.SecurityUtils; |
| | | import com.ruoyi.common.utils.StringUtils; |
| | | import com.ruoyi.common.utils.bean.BeanUtils; |
| | | import com.ruoyi.common.utils.uuid.UUID; |
| | | import com.ruoyi.framework.security.LoginUser; |
| | |
| | | |
| | | @Override |
| | | public boolean add(SalesQuotationDto salesQuotationDto) { |
| | | boolean isApprove = StringUtils.isNotEmpty(salesQuotationDto.getApproveUserIds()) ? true : false; |
| | | LoginUser loginUser = SecurityUtils.getLoginUser(); |
| | | SalesQuotation salesQuotation = new SalesQuotation(); |
| | | BeanUtils.copyProperties(salesQuotationDto, salesQuotation); |
| | | String quotationNo = OrderUtils.countTodayByCreateTime(salesQuotationMapper, "QT"); |
| | | salesQuotation.setQuotationNo(quotationNo); |
| | | salesQuotation.setStatus("待审批"); |
| | | salesQuotation.setStatus(isApprove ? "待审批" : "通过"); |
| | | salesQuotationMapper.insert(salesQuotation); |
| | | if(CollectionUtils.isEmpty(salesQuotationDto.getProducts())){ |
| | | return true; |
| | |
| | | return salesQuotationProduct; |
| | | }).collect(Collectors.toList()); |
| | | salesQuotationProductService.saveBatch(products); |
| | | // 报价审批 |
| | | ApproveProcessVO approveProcessVO = new ApproveProcessVO(); |
| | | approveProcessVO.setApproveType(6); |
| | | approveProcessVO.setApproveDeptId(loginUser.getCurrentDeptId()); |
| | | approveProcessVO.setApproveReason(quotationNo); |
| | | approveProcessVO.setApproveUserIds(salesQuotationDto.getApproveUserIds()); |
| | | approveProcessVO.setApproveUser(loginUser.getUserId()); |
| | | approveProcessVO.setApproveTime(LocalDate.now().toString()); |
| | | approveProcessVO.setPrice(salesQuotationDto.getTotalAmount()); |
| | | try { |
| | | approveProcessService.addApprove(approveProcessVO); |
| | | }catch (Exception e){ |
| | | log.error("SalesQuotationServiceImpl error:{}", e); |
| | | throw new RuntimeException("审批失败"); |
| | | // 审核人不为空 |
| | | if(isApprove){ |
| | | // 报价审批 |
| | | ApproveProcessVO approveProcessVO = new ApproveProcessVO(); |
| | | approveProcessVO.setApproveType(6); |
| | | approveProcessVO.setApproveDeptId(loginUser.getCurrentDeptId()); |
| | | approveProcessVO.setApproveReason(quotationNo); |
| | | approveProcessVO.setApproveUserIds(salesQuotationDto.getApproveUserIds()); |
| | | approveProcessVO.setApproveUser(loginUser.getUserId()); |
| | | approveProcessVO.setApproveTime(LocalDate.now().toString()); |
| | | approveProcessVO.setPrice(salesQuotationDto.getTotalAmount()); |
| | | try { |
| | | approveProcessService.addApprove(approveProcessVO); |
| | | }catch (Exception e){ |
| | | log.error("SalesQuotationServiceImpl error:{}", e); |
| | | throw new RuntimeException("审批失败"); |
| | | } |
| | | } |
| | | return true; |
| | | } |
| | |
| | | @Excel(name = "产品名称") |
| | | private String productName; |
| | | |
| | | @Excel(name = "规格") |
| | | @Excel(name = "图纸编号") |
| | | private String model; |
| | | |
| | | @Excel(name = "单位") |
| | |
| | | list.forEach(dto -> { |
| | | boolean matched = false; |
| | | for (SalesLedgerProduct item : salesLedgerProducts) { |
| | | if (item.getProductCategory().equals(dto.getProductName()) && |
| | | item.getSpecificationModel().equals(dto.getModel())) { |
| | | if (item.getSpecificationModel().equals(dto.getModel())) { |
| | | StockInventoryDto stockInventoryDto = new StockInventoryDto(); |
| | | stockInventoryDto.setRecordId(0L); |
| | | stockInventoryDto.setRecordType(StockInQualifiedRecordTypeEnum.CUSTOMIZATION_STOCK_IN.getCode()); |
| | |
| | | pm.drawing_number as drawingNumber, |
| | | pm.product_type as productType, |
| | | pr.id as routeId, |
| | | pr.process_route_name as routeName |
| | | pr.process_route_name as routeName, |
| | | pm.create_time as createTime, |
| | | pm.update_time as updateTime |
| | | from product_model pm |
| | | left join product p on p.id = pm.product_id |
| | | left join process_route pr on pr.id = pm.route_id |
| | |
| | | SELECT |
| | | T1.*, |
| | | CASE |
| | | WHEN t2.qualitity > T1.quantity THEN 1 |
| | | WHEN sum(t2.qualitity) > T1.quantity THEN 1 |
| | | ELSE 0 |
| | | END as has_sufficient_stock |
| | | FROM |
| | |
| | | AND T1.type = #{salesLedgerProduct.type} |
| | | </if> |
| | | </where> |
| | | group by T1.id |
| | | ORDER BY T1.register_date DESC |
| | | </select> |
| | | <select id="selectSalesLedgerProductByMainId" resultType="com.ruoyi.sales.pojo.SalesLedgerProduct"> |