商品库存数据统计
商品库存查询变动记录 耗材库存数据统计 商品列表排序 耗材列表排序 商品报损 耗材报损
This commit is contained in:
@@ -1,18 +1,21 @@
|
||||
package cn.ysk.cashier.cons.rest;
|
||||
|
||||
import cn.ysk.cashier.annotation.Log;
|
||||
import cn.ysk.cashier.cons.domain.TbConsInfoFlow;
|
||||
import cn.ysk.cashier.cons.service.TbConsInfoFlowService;
|
||||
import cn.ysk.cashier.cons.service.dto.TbConsInfoFlowDto;
|
||||
import cn.ysk.cashier.cons.service.dto.TbConsInfoFlowQueryCriteria;
|
||||
import org.springframework.data.domain.Pageable;
|
||||
import cn.ysk.cashier.dto.product.TbProductStockCountQueryCriteria;
|
||||
import io.swagger.annotations.Api;
|
||||
import io.swagger.annotations.ApiOperation;
|
||||
import lombok.RequiredArgsConstructor;
|
||||
import org.springframework.http.HttpStatus;
|
||||
import org.springframework.http.ResponseEntity;
|
||||
import org.springframework.validation.annotation.Validated;
|
||||
import org.springframework.web.bind.annotation.*;
|
||||
import io.swagger.annotations.*;
|
||||
import java.io.IOException;
|
||||
import javax.servlet.http.HttpServletResponse;
|
||||
import org.springframework.web.bind.annotation.PostMapping;
|
||||
import org.springframework.web.bind.annotation.RequestBody;
|
||||
import org.springframework.web.bind.annotation.RequestMapping;
|
||||
import org.springframework.web.bind.annotation.RestController;
|
||||
|
||||
import java.text.ParseException;
|
||||
|
||||
/**
|
||||
* @author admin
|
||||
@@ -26,39 +29,65 @@ public class TbConsInfoFlowController {
|
||||
|
||||
private final TbConsInfoFlowService tbConsInfoFlowService;
|
||||
|
||||
@Log("导出数据")
|
||||
@ApiOperation("导出数据")
|
||||
@GetMapping(value = "/download")
|
||||
public void exportTbConsInfoFlow(HttpServletResponse response, TbConsInfoFlowQueryCriteria criteria) throws IOException {
|
||||
tbConsInfoFlowService.download(tbConsInfoFlowService.queryAll(criteria), response);
|
||||
// @Log("导出数据")
|
||||
// @ApiOperation("导出数据")
|
||||
// @GetMapping(value = "/download")
|
||||
// public void exportTbConsInfoFlow(HttpServletResponse response, TbConsInfoFlowQueryCriteria criteria) throws IOException {
|
||||
// tbConsInfoFlowService.download(tbConsInfoFlowService.queryAll(criteria), response);
|
||||
// }
|
||||
|
||||
@PostMapping("/count")
|
||||
@ApiOperation("耗材库存统计")
|
||||
public ResponseEntity<Object> stockCount(@RequestBody TbProductStockCountQueryCriteria criteria) throws ParseException {
|
||||
return new ResponseEntity<>(tbConsInfoFlowService.stockCount(criteria),HttpStatus.OK);
|
||||
}
|
||||
//
|
||||
// @PostMapping("/list")
|
||||
// @ApiOperation("耗材库存统计列表")
|
||||
// public ResponseEntity<Object> stockList(@RequestBody TbProductStockCountQueryCriteria criteria) throws ParseException {
|
||||
// return new ResponseEntity<>(tbConsInfoFlowService.stockList(criteria),HttpStatus.OK);
|
||||
// }
|
||||
|
||||
@PostMapping("/stock")
|
||||
@ApiOperation("耗材库存记录列表")
|
||||
public ResponseEntity<Object> queryPage(@RequestBody TbConsInfoFlowQueryCriteria criteria){
|
||||
return new ResponseEntity<>(tbConsInfoFlowService.queryPage(criteria),HttpStatus.OK);
|
||||
}
|
||||
|
||||
@GetMapping
|
||||
@ApiOperation("查询耗材流水")
|
||||
public ResponseEntity<Object> queryTbConsInfoFlow(TbConsInfoFlowQueryCriteria criteria, Pageable pageable){
|
||||
return new ResponseEntity<>(tbConsInfoFlowService.queryAll(criteria,pageable),HttpStatus.OK);
|
||||
@Log("耗材报损")
|
||||
@PostMapping("frmLoss")
|
||||
@ApiOperation("耗材报损")
|
||||
public ResponseEntity<Object> frmLoss(@RequestBody TbConsInfoFlowDto resources){
|
||||
tbConsInfoFlowService.frmLoss(resources);
|
||||
return new ResponseEntity<>(HttpStatus.CREATED);
|
||||
}
|
||||
|
||||
@PostMapping
|
||||
@Log("新增耗材流水")
|
||||
@ApiOperation("新增耗材流水")
|
||||
public ResponseEntity<Object> createTbConsInfoFlow(@Validated @RequestBody TbConsInfoFlow resources){
|
||||
return new ResponseEntity<>(tbConsInfoFlowService.create(resources),HttpStatus.CREATED);
|
||||
}
|
||||
|
||||
@PutMapping
|
||||
@Log("修改耗材流水")
|
||||
@ApiOperation("修改耗材流水")
|
||||
public ResponseEntity<Object> updateTbConsInfoFlow(@Validated @RequestBody TbConsInfoFlow resources){
|
||||
tbConsInfoFlowService.update(resources);
|
||||
return new ResponseEntity<>(HttpStatus.NO_CONTENT);
|
||||
}
|
||||
|
||||
@DeleteMapping
|
||||
@Log("删除耗材流水")
|
||||
@ApiOperation("删除耗材流水")
|
||||
public ResponseEntity<Object> deleteTbConsInfoFlow(@RequestBody Integer[] ids) {
|
||||
tbConsInfoFlowService.deleteAll(ids);
|
||||
return new ResponseEntity<>(HttpStatus.OK);
|
||||
}
|
||||
// @GetMapping
|
||||
// @ApiOperation("查询耗材流水")
|
||||
// public ResponseEntity<Object> queryTbConsInfoFlow(TbConsInfoFlowQueryCriteria criteria, Pageable pageable){
|
||||
// return new ResponseEntity<>(tbConsInfoFlowService.queryAll(criteria,pageable),HttpStatus.OK);
|
||||
// }
|
||||
//
|
||||
// @PostMapping
|
||||
// @Log("新增耗材流水")
|
||||
// @ApiOperation("新增耗材流水")
|
||||
// public ResponseEntity<Object> createTbConsInfoFlow(@Validated @RequestBody TbConsInfoFlow resources){
|
||||
// return new ResponseEntity<>(tbConsInfoFlowService.create(resources),HttpStatus.CREATED);
|
||||
// }
|
||||
//
|
||||
// @PutMapping
|
||||
// @Log("修改耗材流水")
|
||||
// @ApiOperation("修改耗材流水")
|
||||
// public ResponseEntity<Object> updateTbConsInfoFlow(@Validated @RequestBody TbConsInfoFlow resources){
|
||||
// tbConsInfoFlowService.update(resources);
|
||||
// return new ResponseEntity<>(HttpStatus.NO_CONTENT);
|
||||
// }
|
||||
//
|
||||
// @DeleteMapping
|
||||
// @Log("删除耗材流水")
|
||||
// @ApiOperation("删除耗材流水")
|
||||
// public ResponseEntity<Object> deleteTbConsInfoFlow(@RequestBody Integer[] ids) {
|
||||
// tbConsInfoFlowService.deleteAll(ids);
|
||||
// return new ResponseEntity<>(HttpStatus.OK);
|
||||
// }
|
||||
}
|
||||
@@ -33,9 +33,9 @@ public class ViewConInfoFlowController {
|
||||
viewConInfoFlowService.download(viewConInfoFlowService.queryAll(criteria), response);
|
||||
}
|
||||
|
||||
@GetMapping
|
||||
@PostMapping("get")
|
||||
@ApiOperation("查询获取耗材流水信息")
|
||||
public ResponseEntity<Object> queryViewConInfoFlow(ViewConInfoFlowQueryCriteria criteria, Pageable pageable){
|
||||
public ResponseEntity<Object> queryViewConInfoFlow(@RequestBody ViewConInfoFlowQueryCriteria criteria, Pageable pageable){
|
||||
return new ResponseEntity<>(viewConInfoFlowService.queryAll(criteria,pageable),HttpStatus.OK);
|
||||
}
|
||||
|
||||
|
||||
@@ -3,11 +3,15 @@ package cn.ysk.cashier.cons.service;
|
||||
import cn.ysk.cashier.cons.domain.TbConsInfoFlow;
|
||||
import cn.ysk.cashier.cons.service.dto.TbConsInfoFlowDto;
|
||||
import cn.ysk.cashier.cons.service.dto.TbConsInfoFlowQueryCriteria;
|
||||
import cn.ysk.cashier.dto.product.TbProductStockCountQueryCriteria;
|
||||
import cn.ysk.cashier.vo.TbProductStockCountVo;
|
||||
import org.springframework.data.domain.Pageable;
|
||||
import java.util.Map;
|
||||
import java.util.List;
|
||||
import java.io.IOException;
|
||||
|
||||
import javax.servlet.http.HttpServletResponse;
|
||||
import java.io.IOException;
|
||||
import java.text.ParseException;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
|
||||
/**
|
||||
* @author admin
|
||||
@@ -30,6 +34,11 @@ public interface TbConsInfoFlowService {
|
||||
*/
|
||||
List<TbConsInfoFlowDto> queryAll(TbConsInfoFlowQueryCriteria criteria);
|
||||
|
||||
Map<String,Object> queryPage(TbConsInfoFlowQueryCriteria criteria);
|
||||
TbProductStockCountVo stockCount(TbProductStockCountQueryCriteria criteria) throws ParseException;
|
||||
Map<String,Object> stockList(TbProductStockCountQueryCriteria criteria) throws ParseException;
|
||||
|
||||
void frmLoss(TbConsInfoFlowDto resources);
|
||||
/**
|
||||
* 根据ID查询
|
||||
* @param id ID
|
||||
|
||||
@@ -1,27 +1,10 @@
|
||||
/*
|
||||
* Copyright 2019-2020 Zheng Jie
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
package cn.ysk.cashier.cons.service.dto;
|
||||
|
||||
import io.swagger.annotations.ApiModelProperty;
|
||||
import lombok.Data;
|
||||
|
||||
import javax.persistence.Column;
|
||||
import java.sql.Timestamp;
|
||||
import java.math.BigDecimal;
|
||||
import java.io.Serializable;
|
||||
import java.math.BigDecimal;
|
||||
import java.sql.Timestamp;
|
||||
|
||||
/**
|
||||
* @author admin
|
||||
|
||||
@@ -13,23 +13,27 @@ import cn.ysk.cashier.annotation.Query;
|
||||
@Data
|
||||
public class TbConsInfoFlowQueryCriteria{
|
||||
|
||||
/** 精确 */
|
||||
|
||||
@Query
|
||||
private Integer shopId;
|
||||
@Query
|
||||
private Integer consId;
|
||||
|
||||
/** 模糊 */
|
||||
@Query(type = Query.Type.INNER_LIKE)
|
||||
private String conName;
|
||||
|
||||
/** 精确 */
|
||||
@Query
|
||||
private Integer shopId;
|
||||
|
||||
|
||||
private String column;
|
||||
@Query(type = Query.Type.IN)
|
||||
private List<String> bizCode;
|
||||
@Query
|
||||
private String orderNo;
|
||||
|
||||
|
||||
@Query(type = Query.Type.NOT_EQUAL)
|
||||
private BigDecimal amount;
|
||||
|
||||
private Integer page;
|
||||
|
||||
private Integer size;
|
||||
|
||||
|
||||
}
|
||||
@@ -1,24 +1,35 @@
|
||||
package cn.ysk.cashier.cons.service.dto;
|
||||
|
||||
import lombok.Data;
|
||||
|
||||
import java.util.Date;
|
||||
import java.util.List;
|
||||
|
||||
import cn.ysk.cashier.annotation.Query;
|
||||
|
||||
/**
|
||||
* @author admin
|
||||
* @date 2024-07-17
|
||||
**/
|
||||
* @author admin
|
||||
* @date 2024-07-17
|
||||
**/
|
||||
@Data
|
||||
public class ViewConInfoFlowQueryCriteria{
|
||||
public class ViewConInfoFlowQueryCriteria {
|
||||
|
||||
/** 模糊 */
|
||||
/**
|
||||
* 模糊
|
||||
*/
|
||||
@Query(type = Query.Type.INNER_LIKE)
|
||||
private String conName;
|
||||
|
||||
@Query(type = Query.Type.INNER_LIKE)
|
||||
private String productName;
|
||||
|
||||
|
||||
@Query
|
||||
private String shopId;
|
||||
|
||||
@Query
|
||||
private String conTypeCode;
|
||||
private Integer conTypeId;
|
||||
|
||||
@Query(type = Query.Type.BETWEEN)
|
||||
private List<Date> createTime;
|
||||
}
|
||||
@@ -1,16 +1,27 @@
|
||||
package cn.ysk.cashier.cons.service.impl;
|
||||
|
||||
import cn.hutool.core.bean.copier.CopyOptions;
|
||||
import cn.hutool.core.util.StrUtil;
|
||||
import cn.ysk.cashier.cons.domain.TbConsInfo;
|
||||
import cn.ysk.cashier.cons.domain.TbConsInfoFlow;
|
||||
import cn.ysk.cashier.utils.FileUtil;
|
||||
import cn.ysk.cashier.utils.PageUtil;
|
||||
import cn.ysk.cashier.utils.QueryHelp;
|
||||
import cn.ysk.cashier.utils.ValidationUtil;
|
||||
import cn.ysk.cashier.cons.repository.TbConsInfoRepository;
|
||||
import cn.ysk.cashier.dto.product.TbProductStockCountQueryCriteria;
|
||||
import cn.ysk.cashier.dto.product.TbProductStockDetailQueryCriteria;
|
||||
import cn.ysk.cashier.dto.product.TbProductStockListDto;
|
||||
import cn.ysk.cashier.exception.BadRequestException;
|
||||
import cn.ysk.cashier.pojo.product.TbProduct;
|
||||
import cn.ysk.cashier.pojo.product.TbProductStockDetail;
|
||||
import cn.ysk.cashier.pojo.shop.TbShopUnit;
|
||||
import cn.ysk.cashier.repository.product.ProductStockCountRepository;
|
||||
import cn.ysk.cashier.utils.*;
|
||||
import cn.ysk.cashier.vo.TbProductStockCountVo;
|
||||
import lombok.RequiredArgsConstructor;
|
||||
import cn.ysk.cashier.cons.repository.TbConsInfoFlowRepository;
|
||||
import cn.ysk.cashier.cons.service.TbConsInfoFlowService;
|
||||
import cn.ysk.cashier.cons.service.dto.TbConsInfoFlowDto;
|
||||
import cn.ysk.cashier.cons.service.dto.TbConsInfoFlowQueryCriteria;
|
||||
import cn.ysk.cashier.cons.service.mapstruct.TbConsInfoFlowMapper;
|
||||
import org.apache.commons.lang3.StringUtils;
|
||||
import org.springframework.data.domain.PageRequest;
|
||||
import org.springframework.data.domain.Sort;
|
||||
import org.springframework.stereotype.Service;
|
||||
@@ -19,6 +30,9 @@ import org.springframework.data.domain.Page;
|
||||
import org.springframework.data.domain.Pageable;
|
||||
|
||||
import java.math.BigDecimal;
|
||||
import java.sql.Timestamp;
|
||||
import java.text.ParseException;
|
||||
import java.text.SimpleDateFormat;
|
||||
import java.util.*;
|
||||
import java.io.IOException;
|
||||
import javax.servlet.http.HttpServletResponse;
|
||||
@@ -34,7 +48,9 @@ import javax.servlet.http.HttpServletResponse;
|
||||
public class TbConsInfoFlowServiceImpl implements TbConsInfoFlowService {
|
||||
|
||||
private final TbConsInfoFlowRepository tbConsInfoFlowRepository;
|
||||
private final TbConsInfoRepository consInfoRepository;
|
||||
private final TbConsInfoFlowMapper tbConsInfoFlowMapper;
|
||||
private final ProductStockCountRepository stockRepository;
|
||||
|
||||
@Override
|
||||
public Map<String,Object> queryAll(TbConsInfoFlowQueryCriteria criteria, Pageable pageable){
|
||||
@@ -59,6 +75,111 @@ public class TbConsInfoFlowServiceImpl implements TbConsInfoFlowService {
|
||||
return tbConsInfoFlowMapper.toDto(tbConsInfoFlowRepository.findAll((root, criteriaQuery, criteriaBuilder) -> QueryHelp.getPredicate(root,criteria,criteriaBuilder)));
|
||||
}
|
||||
|
||||
|
||||
//增加数量addCountNumber; stockIn cancelCart init stockIn checkStockIn
|
||||
//手动增加addNumber; checkStockIn stockOtherIn
|
||||
//退货refundNumber; cancelCart
|
||||
//减少数量subCountNumber; createCart stockout checkStockOut
|
||||
//手动减少subNumber; checkStockOut
|
||||
//销售量/消耗saleNumber; createCart
|
||||
//报损lossNumber; frmLoss
|
||||
//入库stockInNumber; stockIn
|
||||
//出库stockOutNumber; stockout
|
||||
public Map<String,Object> queryPage(TbConsInfoFlowQueryCriteria criteria){
|
||||
if(StringUtils.isBlank(criteria.getColumn())){
|
||||
throw new BadRequestException("必填参数未填写");
|
||||
}
|
||||
switch (criteria.getColumn()){
|
||||
case "addCountNumber":
|
||||
criteria.setBizCode(Arrays.asList("stockIn","cancelCart","init","stockIn","checkStockIn"));
|
||||
break;
|
||||
case "addNumber":
|
||||
criteria.setBizCode(Arrays.asList("checkStockIn", "stockOtherIn"));
|
||||
break;
|
||||
case "refundNumber":
|
||||
criteria.setBizCode(Arrays.asList("cancelCart"));
|
||||
break;
|
||||
case "subCountNumber":
|
||||
criteria.setBizCode(Arrays.asList("createCart","stockout","checkStockOut"));
|
||||
break;
|
||||
case "subNumber":
|
||||
criteria.setBizCode(Arrays.asList("checkStockOut"));
|
||||
break;
|
||||
case "saleNumber":
|
||||
criteria.setBizCode(Arrays.asList("createCart"));
|
||||
break;
|
||||
case "lossNumber":
|
||||
criteria.setBizCode(Arrays.asList("frmLoss"));
|
||||
break;
|
||||
case "stockInNumber":
|
||||
criteria.setBizCode(Arrays.asList("stockIn"));
|
||||
break;
|
||||
case "stockOutNumber":
|
||||
criteria.setBizCode(Arrays.asList("stockout"));
|
||||
break;
|
||||
}
|
||||
|
||||
Sort sort = Sort.by(Sort.Direction.DESC, "id");
|
||||
Pageable pageable = PageRequest.of(criteria.getPage(), criteria.getSize(), sort);
|
||||
|
||||
Page<TbConsInfoFlow> page = tbConsInfoFlowRepository.findAll((root, criteriaQuery, criteriaBuilder)
|
||||
-> QueryHelp.getPredicate(root,criteria,criteriaBuilder),pageable);
|
||||
return PageUtil.toPage(page);
|
||||
}
|
||||
|
||||
@Override
|
||||
public TbProductStockCountVo stockCount(TbProductStockCountQueryCriteria criteria) throws ParseException {
|
||||
if (criteria.getStartTime() == null || criteria.getEndTime() == null) {
|
||||
criteria.setEndTime(new Date());//
|
||||
SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd");
|
||||
criteria.setStartTime(sdf.parse("2024-01-01"));//创建2024年1月1日的Date对象
|
||||
}
|
||||
return stockRepository.consStockCount(criteria.getShopId().toString(), criteria.getProductName(),
|
||||
criteria.getCategoryId(), DateUtil.getStrTime(criteria.getStartTime()), DateUtil.getStrTime(criteria.getEndTime()));
|
||||
}
|
||||
|
||||
@Override
|
||||
public Map<String, Object> stockList(TbProductStockCountQueryCriteria criteria) throws ParseException {
|
||||
Sort sort = Sort.by(Sort.Direction.DESC, "id");
|
||||
Pageable pageable = PageRequest.of(criteria.getPage(), criteria.getSize(), sort);
|
||||
if (criteria.getStartTime() == null || criteria.getEndTime() == null) {
|
||||
criteria.setEndTime(new Date());//
|
||||
SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd");
|
||||
criteria.setStartTime(sdf.parse("2024-01-01"));//创建2024年1月1日的Date对象
|
||||
}
|
||||
Page<TbProductStockListDto> stockCountDtos = stockRepository.consStock(
|
||||
criteria.getShopId().toString(),
|
||||
criteria.getProductName(),
|
||||
criteria.getCategoryId(),
|
||||
DateUtil.getStrTime(criteria.getStartTime()), DateUtil.getStrTime(criteria.getEndTime()), pageable);
|
||||
if (!stockCountDtos.isEmpty()) {
|
||||
stockCountDtos.getContent().parallelStream().forEach(s->{
|
||||
s.setCountNumber(s.getStockNumber().add(s.getSubCountNumber()));
|
||||
});
|
||||
}
|
||||
return PageUtil.toPage(stockCountDtos);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void frmLoss(TbConsInfoFlowDto resources) {
|
||||
TbConsInfo tbConsInfo = consInfoRepository.findById(resources.getConsId()).orElse(null);
|
||||
if(Objects.isNull(tbConsInfo)){
|
||||
throw new BadRequestException("该耗材不存在");
|
||||
}
|
||||
BigDecimal balance = tbConsInfo.getStockNumber().subtract(resources.getAmount());
|
||||
TbConsInfoFlow tbConsInfoFlow = new TbConsInfoFlow();
|
||||
cn.hutool.core.bean.BeanUtil.copyProperties(resources,tbConsInfoFlow, CopyOptions.create().setIgnoreNullValue(true));
|
||||
tbConsInfoFlow.setConName(tbConsInfo.getConName());
|
||||
tbConsInfoFlow.setBalance(balance);
|
||||
tbConsInfoFlow.setBizCode("frmLoss");
|
||||
tbConsInfoFlow.setBizName("报损");
|
||||
tbConsInfoFlow.setBizType("-");
|
||||
tbConsInfoFlow.setCreateTime(new Timestamp(System.currentTimeMillis()));
|
||||
tbConsInfoFlowRepository.save(tbConsInfoFlow);
|
||||
tbConsInfo.setStockNumber(balance);
|
||||
consInfoRepository.save(tbConsInfo);
|
||||
}
|
||||
|
||||
@Override
|
||||
@Transactional
|
||||
public TbConsInfoFlowDto findById(Integer id) {
|
||||
|
||||
@@ -280,7 +280,8 @@ public class TbConsInfoServiceImpl implements TbConsInfoService {
|
||||
purveyorTransact.setType("cons_in");
|
||||
|
||||
object.put("number", conInfos.getStockNumber());
|
||||
} else if ("out".equals(resources.getType())) {
|
||||
}
|
||||
else if ("out".equals(resources.getType())) {
|
||||
stockOperate.setSubType(-1);
|
||||
|
||||
if (conInfos.getStockNumber().compareTo(info.getStockNumber()) > 0) {
|
||||
@@ -303,7 +304,8 @@ public class TbConsInfoServiceImpl implements TbConsInfoService {
|
||||
purveyorTransact.setWaitAmount((resources.getAccountsPayable().subtract(resources.getActualPayment())).negate());
|
||||
purveyorTransact.setType("cons_out");
|
||||
object.put("number", conInfos.getStockNumber());
|
||||
} else {
|
||||
}
|
||||
else {
|
||||
throw new BadRequestException("错误操作类型");
|
||||
}
|
||||
|
||||
|
||||
Reference in New Issue
Block a user