优化安全库存,调整为每个仓库的安全库存
This commit is contained in:
@@ -6,6 +6,8 @@ import com.jsh.erp.constants.BusinessConstants;
|
||||
import com.jsh.erp.constants.ExceptionConstants;
|
||||
import com.jsh.erp.datasource.entities.Depot;
|
||||
import com.jsh.erp.datasource.entities.DepotEx;
|
||||
import com.jsh.erp.datasource.entities.MaterialCurrentStock;
|
||||
import com.jsh.erp.datasource.entities.MaterialInitialStock;
|
||||
import com.jsh.erp.exception.BusinessRunTimeException;
|
||||
import com.jsh.erp.service.depot.DepotService;
|
||||
import com.jsh.erp.service.material.MaterialService;
|
||||
@@ -153,6 +155,9 @@ public class DepotController {
|
||||
BigDecimal currentStock = materialService.getCurrentStock(mId, depot.getId());
|
||||
de.setInitStock(initStock);
|
||||
de.setCurrentStock(currentStock);
|
||||
MaterialInitialStock materialInitialStock = materialService.getSafeStock(mId, depot.getId());
|
||||
de.setLowSafeStock(materialInitialStock.getLowSafeStock());
|
||||
de.setHighSafeStock(materialInitialStock.getHighSafeStock());
|
||||
} else {
|
||||
de.setInitStock(BigDecimal.ZERO);
|
||||
de.setCurrentStock(BigDecimal.ZERO);
|
||||
|
||||
@@ -327,23 +327,22 @@ public class MaterialController {
|
||||
try {
|
||||
List<MaterialVo4Unit> dataList = materialService.findByAll(StringUtil.toNull(barCode), StringUtil.toNull(name),
|
||||
StringUtil.toNull(standard), StringUtil.toNull(model), StringUtil.toNull(categoryId));
|
||||
String[] names = {"名称", "类型", "型号", "安全存量", "单位", "零售价", "最低售价", "采购价", "销售价", "备注", "状态"};
|
||||
String[] names = {"名称", "类型", "型号", "单位", "零售价", "最低售价", "采购价", "销售价", "备注", "状态"};
|
||||
String title = "商品信息";
|
||||
List<String[]> objects = new ArrayList<String[]>();
|
||||
if (null != dataList) {
|
||||
for (MaterialVo4Unit m : dataList) {
|
||||
String[] objs = new String[11];
|
||||
String[] objs = new String[10];
|
||||
objs[0] = m.getName();
|
||||
objs[1] = m.getCategoryName();
|
||||
objs[2] = m.getModel();
|
||||
objs[3] = m.getSafetyStock() == null? "" : m.getSafetyStock().toString();
|
||||
objs[4] = m.getCommodityUnit();
|
||||
objs[5] = m.getCommodityDecimal() == null? "" : m.getCommodityDecimal().toString();
|
||||
objs[6] = m.getLowDecimal() == null? "" : m.getLowDecimal().toString();
|
||||
objs[7] = m.getPurchaseDecimal() == null? "" : m.getPurchaseDecimal().toString();
|
||||
objs[8] = m.getWholesaleDecimal() == null? "" : m.getWholesaleDecimal().toString();
|
||||
objs[9] = m.getRemark();
|
||||
objs[10] = m.getEnabled() ? "启用" : "禁用";
|
||||
objs[3] = m.getCommodityUnit();
|
||||
objs[4] = m.getCommodityDecimal() == null? "" : m.getCommodityDecimal().toString();
|
||||
objs[5] = m.getLowDecimal() == null? "" : m.getLowDecimal().toString();
|
||||
objs[6] = m.getPurchaseDecimal() == null? "" : m.getPurchaseDecimal().toString();
|
||||
objs[7] = m.getWholesaleDecimal() == null? "" : m.getWholesaleDecimal().toString();
|
||||
objs[8] = m.getRemark();
|
||||
objs[9] = m.getEnabled() ? "启用" : "禁用";
|
||||
objects.add(objs);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -19,4 +19,8 @@ public class DepotEx extends Depot{
|
||||
|
||||
private BigDecimal currentStock;
|
||||
|
||||
private BigDecimal lowSafeStock;
|
||||
|
||||
private BigDecimal highSafeStock;
|
||||
|
||||
}
|
||||
|
||||
@@ -11,8 +11,6 @@ public class Material {
|
||||
|
||||
private String mfrs;
|
||||
|
||||
private BigDecimal safetyStock;
|
||||
|
||||
private String model;
|
||||
|
||||
private String standard;
|
||||
@@ -29,6 +27,8 @@ public class Material {
|
||||
|
||||
private Integer expiryNum;
|
||||
|
||||
private BigDecimal weight;
|
||||
|
||||
private Boolean enabled;
|
||||
|
||||
private String otherField1;
|
||||
@@ -77,14 +77,6 @@ public class Material {
|
||||
this.mfrs = mfrs == null ? null : mfrs.trim();
|
||||
}
|
||||
|
||||
public BigDecimal getSafetyStock() {
|
||||
return safetyStock;
|
||||
}
|
||||
|
||||
public void setSafetyStock(BigDecimal safetyStock) {
|
||||
this.safetyStock = safetyStock;
|
||||
}
|
||||
|
||||
public String getModel() {
|
||||
return model;
|
||||
}
|
||||
@@ -149,6 +141,14 @@ public class Material {
|
||||
this.expiryNum = expiryNum;
|
||||
}
|
||||
|
||||
public BigDecimal getWeight() {
|
||||
return weight;
|
||||
}
|
||||
|
||||
public void setWeight(BigDecimal weight) {
|
||||
this.weight = weight;
|
||||
}
|
||||
|
||||
public Boolean getEnabled() {
|
||||
return enabled;
|
||||
}
|
||||
|
||||
@@ -365,66 +365,6 @@ public class MaterialExample {
|
||||
return (Criteria) this;
|
||||
}
|
||||
|
||||
public Criteria andSafetyStockIsNull() {
|
||||
addCriterion("safety_stock is null");
|
||||
return (Criteria) this;
|
||||
}
|
||||
|
||||
public Criteria andSafetyStockIsNotNull() {
|
||||
addCriterion("safety_stock is not null");
|
||||
return (Criteria) this;
|
||||
}
|
||||
|
||||
public Criteria andSafetyStockEqualTo(BigDecimal value) {
|
||||
addCriterion("safety_stock =", value, "safetyStock");
|
||||
return (Criteria) this;
|
||||
}
|
||||
|
||||
public Criteria andSafetyStockNotEqualTo(BigDecimal value) {
|
||||
addCriterion("safety_stock <>", value, "safetyStock");
|
||||
return (Criteria) this;
|
||||
}
|
||||
|
||||
public Criteria andSafetyStockGreaterThan(BigDecimal value) {
|
||||
addCriterion("safety_stock >", value, "safetyStock");
|
||||
return (Criteria) this;
|
||||
}
|
||||
|
||||
public Criteria andSafetyStockGreaterThanOrEqualTo(BigDecimal value) {
|
||||
addCriterion("safety_stock >=", value, "safetyStock");
|
||||
return (Criteria) this;
|
||||
}
|
||||
|
||||
public Criteria andSafetyStockLessThan(BigDecimal value) {
|
||||
addCriterion("safety_stock <", value, "safetyStock");
|
||||
return (Criteria) this;
|
||||
}
|
||||
|
||||
public Criteria andSafetyStockLessThanOrEqualTo(BigDecimal value) {
|
||||
addCriterion("safety_stock <=", value, "safetyStock");
|
||||
return (Criteria) this;
|
||||
}
|
||||
|
||||
public Criteria andSafetyStockIn(List<BigDecimal> values) {
|
||||
addCriterion("safety_stock in", values, "safetyStock");
|
||||
return (Criteria) this;
|
||||
}
|
||||
|
||||
public Criteria andSafetyStockNotIn(List<BigDecimal> values) {
|
||||
addCriterion("safety_stock not in", values, "safetyStock");
|
||||
return (Criteria) this;
|
||||
}
|
||||
|
||||
public Criteria andSafetyStockBetween(BigDecimal value1, BigDecimal value2) {
|
||||
addCriterion("safety_stock between", value1, value2, "safetyStock");
|
||||
return (Criteria) this;
|
||||
}
|
||||
|
||||
public Criteria andSafetyStockNotBetween(BigDecimal value1, BigDecimal value2) {
|
||||
addCriterion("safety_stock not between", value1, value2, "safetyStock");
|
||||
return (Criteria) this;
|
||||
}
|
||||
|
||||
public Criteria andModelIsNull() {
|
||||
addCriterion("model is null");
|
||||
return (Criteria) this;
|
||||
@@ -965,6 +905,66 @@ public class MaterialExample {
|
||||
return (Criteria) this;
|
||||
}
|
||||
|
||||
public Criteria andWeightIsNull() {
|
||||
addCriterion("weight is null");
|
||||
return (Criteria) this;
|
||||
}
|
||||
|
||||
public Criteria andWeightIsNotNull() {
|
||||
addCriterion("weight is not null");
|
||||
return (Criteria) this;
|
||||
}
|
||||
|
||||
public Criteria andWeightEqualTo(BigDecimal value) {
|
||||
addCriterion("weight =", value, "weight");
|
||||
return (Criteria) this;
|
||||
}
|
||||
|
||||
public Criteria andWeightNotEqualTo(BigDecimal value) {
|
||||
addCriterion("weight <>", value, "weight");
|
||||
return (Criteria) this;
|
||||
}
|
||||
|
||||
public Criteria andWeightGreaterThan(BigDecimal value) {
|
||||
addCriterion("weight >", value, "weight");
|
||||
return (Criteria) this;
|
||||
}
|
||||
|
||||
public Criteria andWeightGreaterThanOrEqualTo(BigDecimal value) {
|
||||
addCriterion("weight >=", value, "weight");
|
||||
return (Criteria) this;
|
||||
}
|
||||
|
||||
public Criteria andWeightLessThan(BigDecimal value) {
|
||||
addCriterion("weight <", value, "weight");
|
||||
return (Criteria) this;
|
||||
}
|
||||
|
||||
public Criteria andWeightLessThanOrEqualTo(BigDecimal value) {
|
||||
addCriterion("weight <=", value, "weight");
|
||||
return (Criteria) this;
|
||||
}
|
||||
|
||||
public Criteria andWeightIn(List<BigDecimal> values) {
|
||||
addCriterion("weight in", values, "weight");
|
||||
return (Criteria) this;
|
||||
}
|
||||
|
||||
public Criteria andWeightNotIn(List<BigDecimal> values) {
|
||||
addCriterion("weight not in", values, "weight");
|
||||
return (Criteria) this;
|
||||
}
|
||||
|
||||
public Criteria andWeightBetween(BigDecimal value1, BigDecimal value2) {
|
||||
addCriterion("weight between", value1, value2, "weight");
|
||||
return (Criteria) this;
|
||||
}
|
||||
|
||||
public Criteria andWeightNotBetween(BigDecimal value1, BigDecimal value2) {
|
||||
addCriterion("weight not between", value1, value2, "weight");
|
||||
return (Criteria) this;
|
||||
}
|
||||
|
||||
public Criteria andEnabledIsNull() {
|
||||
addCriterion("enabled is null");
|
||||
return (Criteria) this;
|
||||
|
||||
@@ -11,6 +11,10 @@ public class MaterialInitialStock {
|
||||
|
||||
private BigDecimal number;
|
||||
|
||||
private BigDecimal lowSafeStock;
|
||||
|
||||
private BigDecimal highSafeStock;
|
||||
|
||||
private Long tenantId;
|
||||
|
||||
private String deleteFlag;
|
||||
@@ -47,6 +51,22 @@ public class MaterialInitialStock {
|
||||
this.number = number;
|
||||
}
|
||||
|
||||
public BigDecimal getLowSafeStock() {
|
||||
return lowSafeStock;
|
||||
}
|
||||
|
||||
public void setLowSafeStock(BigDecimal lowSafeStock) {
|
||||
this.lowSafeStock = lowSafeStock;
|
||||
}
|
||||
|
||||
public BigDecimal getHighSafeStock() {
|
||||
return highSafeStock;
|
||||
}
|
||||
|
||||
public void setHighSafeStock(BigDecimal highSafeStock) {
|
||||
this.highSafeStock = highSafeStock;
|
||||
}
|
||||
|
||||
public Long getTenantId() {
|
||||
return tenantId;
|
||||
}
|
||||
|
||||
@@ -345,6 +345,126 @@ public class MaterialInitialStockExample {
|
||||
return (Criteria) this;
|
||||
}
|
||||
|
||||
public Criteria andLowSafeStockIsNull() {
|
||||
addCriterion("low_safe_stock is null");
|
||||
return (Criteria) this;
|
||||
}
|
||||
|
||||
public Criteria andLowSafeStockIsNotNull() {
|
||||
addCriterion("low_safe_stock is not null");
|
||||
return (Criteria) this;
|
||||
}
|
||||
|
||||
public Criteria andLowSafeStockEqualTo(BigDecimal value) {
|
||||
addCriterion("low_safe_stock =", value, "lowSafeStock");
|
||||
return (Criteria) this;
|
||||
}
|
||||
|
||||
public Criteria andLowSafeStockNotEqualTo(BigDecimal value) {
|
||||
addCriterion("low_safe_stock <>", value, "lowSafeStock");
|
||||
return (Criteria) this;
|
||||
}
|
||||
|
||||
public Criteria andLowSafeStockGreaterThan(BigDecimal value) {
|
||||
addCriterion("low_safe_stock >", value, "lowSafeStock");
|
||||
return (Criteria) this;
|
||||
}
|
||||
|
||||
public Criteria andLowSafeStockGreaterThanOrEqualTo(BigDecimal value) {
|
||||
addCriterion("low_safe_stock >=", value, "lowSafeStock");
|
||||
return (Criteria) this;
|
||||
}
|
||||
|
||||
public Criteria andLowSafeStockLessThan(BigDecimal value) {
|
||||
addCriterion("low_safe_stock <", value, "lowSafeStock");
|
||||
return (Criteria) this;
|
||||
}
|
||||
|
||||
public Criteria andLowSafeStockLessThanOrEqualTo(BigDecimal value) {
|
||||
addCriterion("low_safe_stock <=", value, "lowSafeStock");
|
||||
return (Criteria) this;
|
||||
}
|
||||
|
||||
public Criteria andLowSafeStockIn(List<BigDecimal> values) {
|
||||
addCriterion("low_safe_stock in", values, "lowSafeStock");
|
||||
return (Criteria) this;
|
||||
}
|
||||
|
||||
public Criteria andLowSafeStockNotIn(List<BigDecimal> values) {
|
||||
addCriterion("low_safe_stock not in", values, "lowSafeStock");
|
||||
return (Criteria) this;
|
||||
}
|
||||
|
||||
public Criteria andLowSafeStockBetween(BigDecimal value1, BigDecimal value2) {
|
||||
addCriterion("low_safe_stock between", value1, value2, "lowSafeStock");
|
||||
return (Criteria) this;
|
||||
}
|
||||
|
||||
public Criteria andLowSafeStockNotBetween(BigDecimal value1, BigDecimal value2) {
|
||||
addCriterion("low_safe_stock not between", value1, value2, "lowSafeStock");
|
||||
return (Criteria) this;
|
||||
}
|
||||
|
||||
public Criteria andHighSafeStockIsNull() {
|
||||
addCriterion("high_safe_stock is null");
|
||||
return (Criteria) this;
|
||||
}
|
||||
|
||||
public Criteria andHighSafeStockIsNotNull() {
|
||||
addCriterion("high_safe_stock is not null");
|
||||
return (Criteria) this;
|
||||
}
|
||||
|
||||
public Criteria andHighSafeStockEqualTo(BigDecimal value) {
|
||||
addCriterion("high_safe_stock =", value, "highSafeStock");
|
||||
return (Criteria) this;
|
||||
}
|
||||
|
||||
public Criteria andHighSafeStockNotEqualTo(BigDecimal value) {
|
||||
addCriterion("high_safe_stock <>", value, "highSafeStock");
|
||||
return (Criteria) this;
|
||||
}
|
||||
|
||||
public Criteria andHighSafeStockGreaterThan(BigDecimal value) {
|
||||
addCriterion("high_safe_stock >", value, "highSafeStock");
|
||||
return (Criteria) this;
|
||||
}
|
||||
|
||||
public Criteria andHighSafeStockGreaterThanOrEqualTo(BigDecimal value) {
|
||||
addCriterion("high_safe_stock >=", value, "highSafeStock");
|
||||
return (Criteria) this;
|
||||
}
|
||||
|
||||
public Criteria andHighSafeStockLessThan(BigDecimal value) {
|
||||
addCriterion("high_safe_stock <", value, "highSafeStock");
|
||||
return (Criteria) this;
|
||||
}
|
||||
|
||||
public Criteria andHighSafeStockLessThanOrEqualTo(BigDecimal value) {
|
||||
addCriterion("high_safe_stock <=", value, "highSafeStock");
|
||||
return (Criteria) this;
|
||||
}
|
||||
|
||||
public Criteria andHighSafeStockIn(List<BigDecimal> values) {
|
||||
addCriterion("high_safe_stock in", values, "highSafeStock");
|
||||
return (Criteria) this;
|
||||
}
|
||||
|
||||
public Criteria andHighSafeStockNotIn(List<BigDecimal> values) {
|
||||
addCriterion("high_safe_stock not in", values, "highSafeStock");
|
||||
return (Criteria) this;
|
||||
}
|
||||
|
||||
public Criteria andHighSafeStockBetween(BigDecimal value1, BigDecimal value2) {
|
||||
addCriterion("high_safe_stock between", value1, value2, "highSafeStock");
|
||||
return (Criteria) this;
|
||||
}
|
||||
|
||||
public Criteria andHighSafeStockNotBetween(BigDecimal value1, BigDecimal value2) {
|
||||
addCriterion("high_safe_stock not between", value1, value2, "highSafeStock");
|
||||
return (Criteria) this;
|
||||
}
|
||||
|
||||
public Criteria andTenantIdIsNull() {
|
||||
addCriterion("tenant_id is null");
|
||||
return (Criteria) this;
|
||||
|
||||
@@ -182,9 +182,17 @@ public class MaterialService {
|
||||
JSONObject jsonObj = stockArr.getJSONObject(i);
|
||||
if(jsonObj.get("id")!=null && jsonObj.get("initStock")!=null) {
|
||||
String number = jsonObj.getString("initStock");
|
||||
BigDecimal lowSafeStock = null;
|
||||
BigDecimal highSafeStock = null;
|
||||
if(jsonObj.get("lowSafeStock")!=null) {
|
||||
lowSafeStock = jsonObj.getBigDecimal("lowSafeStock");
|
||||
}
|
||||
if(jsonObj.get("highSafeStock")!=null) {
|
||||
highSafeStock = jsonObj.getBigDecimal("highSafeStock");
|
||||
}
|
||||
Long depotId = jsonObj.getLong("id");
|
||||
if(StringUtil.isNotEmpty(number) && Double.valueOf(number)>0) {
|
||||
insertInitialStockByMaterialAndDepot(depotId, mId, parseBigDecimalEx(number));
|
||||
if(StringUtil.isNotEmpty(number) && Double.valueOf(number)>0 || lowSafeStock!=null || highSafeStock!=null) {
|
||||
insertInitialStockByMaterialAndDepot(depotId, mId, parseBigDecimalEx(number), lowSafeStock, highSafeStock);
|
||||
insertCurrentStockByMaterialAndDepot(depotId, mId, parseBigDecimalEx(number));
|
||||
}
|
||||
}
|
||||
@@ -221,13 +229,21 @@ public class MaterialService {
|
||||
JSONObject jsonObj = stockArr.getJSONObject(i);
|
||||
if (jsonObj.get("id") != null && jsonObj.get("initStock") != null) {
|
||||
String number = jsonObj.getString("initStock");
|
||||
BigDecimal lowSafeStock = null;
|
||||
BigDecimal highSafeStock = null;
|
||||
if(jsonObj.get("lowSafeStock")!=null) {
|
||||
lowSafeStock = jsonObj.getBigDecimal("lowSafeStock");
|
||||
}
|
||||
if(jsonObj.get("highSafeStock")!=null) {
|
||||
highSafeStock = jsonObj.getBigDecimal("highSafeStock");
|
||||
}
|
||||
Long depotId = jsonObj.getLong("id");
|
||||
//初始库存-先清除再插入
|
||||
MaterialInitialStockExample example = new MaterialInitialStockExample();
|
||||
example.createCriteria().andMaterialIdEqualTo(material.getId()).andDepotIdEqualTo(depotId);
|
||||
materialInitialStockMapper.deleteByExample(example);
|
||||
if (StringUtil.isNotEmpty(number) && Double.valueOf(number) > 0) {
|
||||
insertInitialStockByMaterialAndDepot(depotId, material.getId(), parseBigDecimalEx(number));
|
||||
if (StringUtil.isNotEmpty(number) && Double.valueOf(number) > 0 || lowSafeStock!=null || highSafeStock!=null) {
|
||||
insertInitialStockByMaterialAndDepot(depotId, material.getId(), parseBigDecimalEx(number), lowSafeStock, highSafeStock);
|
||||
}
|
||||
//更新当前库存
|
||||
depotItemService.updateCurrentStockFun(material.getId(), depotId);
|
||||
@@ -468,7 +484,6 @@ public class MaterialService {
|
||||
if(null!=categoryId){
|
||||
m.setCategoryId(categoryId);
|
||||
}
|
||||
m.setSafetyStock(parseBigDecimalEx(safetyStock));
|
||||
String manyUnit = ExcelUtils.getContent(src, i, 7); //副单位
|
||||
String barCode = ExcelUtils.getContent(src, i, 8); //基础条码
|
||||
String manyBarCode = ExcelUtils.getContent(src, i, 9); //副条码
|
||||
@@ -598,7 +613,7 @@ public class MaterialService {
|
||||
materialInitialStockMapper.deleteByExample(example);
|
||||
if(stock!=null && stock.compareTo(BigDecimal.ZERO)!=0) {
|
||||
depotId = depot.getId();
|
||||
insertInitialStockByMaterialAndDepot(depotId, mId, stock);
|
||||
insertInitialStockByMaterialAndDepot(depotId, mId, stock, null, null);
|
||||
//更新当前库存
|
||||
depotItemService.updateCurrentStockFun(mId, depotId);
|
||||
}
|
||||
@@ -663,11 +678,18 @@ public class MaterialService {
|
||||
* @param stock
|
||||
*/
|
||||
@Transactional(value = "transactionManager", rollbackFor = Exception.class)
|
||||
public void insertInitialStockByMaterialAndDepot(Long depotId, Long mId, BigDecimal stock){
|
||||
public void insertInitialStockByMaterialAndDepot(Long depotId, Long mId, BigDecimal stock, BigDecimal lowSafeStock, BigDecimal highSafeStock){
|
||||
MaterialInitialStock materialInitialStock = new MaterialInitialStock();
|
||||
materialInitialStock.setDepotId(depotId);
|
||||
materialInitialStock.setMaterialId(mId);
|
||||
stock = stock == null? BigDecimal.ZERO: stock;
|
||||
materialInitialStock.setNumber(stock);
|
||||
if(lowSafeStock!=null) {
|
||||
materialInitialStock.setLowSafeStock(lowSafeStock);
|
||||
}
|
||||
if(highSafeStock!=null) {
|
||||
materialInitialStock.setHighSafeStock(highSafeStock);
|
||||
}
|
||||
materialInitialStockMapper.insertSelective(materialInitialStock); //存入初始库存
|
||||
}
|
||||
|
||||
@@ -788,6 +810,24 @@ public class MaterialService {
|
||||
return stock;
|
||||
}
|
||||
|
||||
/**
|
||||
* 根据商品和仓库获取安全库存信息
|
||||
* @param materialId
|
||||
* @param depotId
|
||||
* @return
|
||||
*/
|
||||
public MaterialInitialStock getSafeStock(Long materialId, Long depotId) {
|
||||
MaterialInitialStock materialInitialStock = new MaterialInitialStock();
|
||||
MaterialInitialStockExample example = new MaterialInitialStockExample();
|
||||
example.createCriteria().andMaterialIdEqualTo(materialId).andDepotIdEqualTo(depotId)
|
||||
.andDeleteFlagNotEqualTo(BusinessConstants.DELETE_FLAG_DELETED);
|
||||
List<MaterialInitialStock> list = materialInitialStockMapper.selectByExample(example);
|
||||
if(list!=null && list.size()>0) {
|
||||
materialInitialStock = list.get(0);
|
||||
}
|
||||
return materialInitialStock;
|
||||
}
|
||||
|
||||
public List<MaterialVo4Unit> getMaterialByMeId(Long meId) {
|
||||
List<MaterialVo4Unit> result = new ArrayList<MaterialVo4Unit>();
|
||||
try{
|
||||
|
||||
Reference in New Issue
Block a user