Логика по работнику
This commit is contained in:
1
.gitignore
vendored
1
.gitignore
vendored
@@ -19,6 +19,7 @@
|
|||||||
*.zip
|
*.zip
|
||||||
*.tar.gz
|
*.tar.gz
|
||||||
*.rar
|
*.rar
|
||||||
|
../target
|
||||||
|
|
||||||
# virtual machine crash logs, see http://www.java.com/en/download/help/error_hotspot.xml
|
# virtual machine crash logs, see http://www.java.com/en/download/help/error_hotspot.xml
|
||||||
hs_err_pid*
|
hs_err_pid*
|
||||||
|
|||||||
92
ServiceCenter/pom.xml
Normal file
92
ServiceCenter/pom.xml
Normal file
@@ -0,0 +1,92 @@
|
|||||||
|
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
|
||||||
|
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
|
||||||
|
<modelVersion>4.0.0</modelVersion>
|
||||||
|
|
||||||
|
<groupId>org.example</groupId>
|
||||||
|
<artifactId>ServiceCenter</artifactId>
|
||||||
|
<version>1.0-SNAPSHOT</version>
|
||||||
|
<packaging>jar</packaging>
|
||||||
|
|
||||||
|
<name>ServiceCenter</name>
|
||||||
|
<url>http://maven.apache.org</url>
|
||||||
|
|
||||||
|
<properties>
|
||||||
|
<project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
|
||||||
|
<org.postgesql.version>42.7.3</org.postgesql.version>
|
||||||
|
<org.flywaydb.version>10.18.0</org.flywaydb.version>
|
||||||
|
<org.lombok.version>1.18.34</org.lombok.version>
|
||||||
|
<org.mapstruct.version>1.6.3</org.mapstruct.version>
|
||||||
|
<lombok-mapstruct-binding.version>0.2.0</lombok-mapstruct-binding.version>
|
||||||
|
</properties>
|
||||||
|
<parent>
|
||||||
|
<groupId>org.springframework.boot</groupId>
|
||||||
|
<artifactId>spring-boot-starter-parent</artifactId>
|
||||||
|
<version>3.3.2</version>
|
||||||
|
</parent>
|
||||||
|
|
||||||
|
<dependencies>
|
||||||
|
<dependency>
|
||||||
|
<groupId>org.flywaydb</groupId>
|
||||||
|
<artifactId>flyway-database-postgresql</artifactId>
|
||||||
|
<version>${org.flywaydb.version}</version>
|
||||||
|
</dependency>
|
||||||
|
|
||||||
|
<dependency>
|
||||||
|
<groupId>org.flywaydb</groupId>
|
||||||
|
<artifactId>flyway-core</artifactId>
|
||||||
|
<version>${org.flywaydb.version}</version>
|
||||||
|
</dependency>
|
||||||
|
|
||||||
|
<dependency>
|
||||||
|
<groupId>org.postgresql</groupId>
|
||||||
|
<artifactId>postgresql</artifactId>
|
||||||
|
<version>${org.postgesql.version}</version>
|
||||||
|
</dependency>
|
||||||
|
|
||||||
|
<dependency>
|
||||||
|
<groupId>org.mapstruct</groupId>
|
||||||
|
<artifactId>mapstruct</artifactId>
|
||||||
|
<version>${org.mapstruct.version}</version>
|
||||||
|
</dependency>
|
||||||
|
|
||||||
|
<dependency>
|
||||||
|
<groupId>org.projectlombok</groupId>
|
||||||
|
<artifactId>lombok</artifactId>
|
||||||
|
<version>${org.lombok.version}</version>
|
||||||
|
<scope>provided</scope>
|
||||||
|
</dependency>
|
||||||
|
|
||||||
|
<dependency>
|
||||||
|
<groupId>org.springframework.boot</groupId>
|
||||||
|
<artifactId>spring-boot-starter-data-jpa</artifactId>
|
||||||
|
</dependency>
|
||||||
|
</dependencies>
|
||||||
|
<build>
|
||||||
|
<plugins>
|
||||||
|
<plugin>
|
||||||
|
<groupId>org.apache.maven.plugins</groupId>
|
||||||
|
<artifactId>maven-compiler-plugin</artifactId>
|
||||||
|
<version>3.13.0</version>
|
||||||
|
<configuration>
|
||||||
|
<annotationProcessorPaths>
|
||||||
|
<path>
|
||||||
|
<groupId>org.mapstruct</groupId>
|
||||||
|
<artifactId>mapstruct-processor</artifactId>
|
||||||
|
<version>${org.mapstruct.version}</version>
|
||||||
|
</path>
|
||||||
|
<path>
|
||||||
|
<groupId>org.projectlombok</groupId>
|
||||||
|
<artifactId>lombok</artifactId>
|
||||||
|
<version>${org.lombok.version}</version>
|
||||||
|
</path>
|
||||||
|
<path>
|
||||||
|
<groupId>org.projectlombok</groupId>
|
||||||
|
<artifactId>lombok-mapstruct-binding</artifactId>
|
||||||
|
<version>${lombok-mapstruct-binding.version}</version>
|
||||||
|
</path>
|
||||||
|
</annotationProcessorPaths>
|
||||||
|
</configuration>
|
||||||
|
</plugin>
|
||||||
|
</plugins>
|
||||||
|
</build>
|
||||||
|
</project>
|
||||||
13
ServiceCenter/src/main/java/org/example/App.java
Normal file
13
ServiceCenter/src/main/java/org/example/App.java
Normal file
@@ -0,0 +1,13 @@
|
|||||||
|
package org.example;
|
||||||
|
|
||||||
|
import org.springframework.boot.SpringApplication;
|
||||||
|
import org.springframework.boot.autoconfigure.SpringBootApplication;
|
||||||
|
|
||||||
|
@SpringBootApplication
|
||||||
|
public class App
|
||||||
|
{
|
||||||
|
public static void main( String[] args )
|
||||||
|
{
|
||||||
|
SpringApplication.run(App.class, args);
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -0,0 +1,29 @@
|
|||||||
|
package org.example.domain.entity;
|
||||||
|
|
||||||
|
import jakarta.persistence.*;
|
||||||
|
import lombok.Data;
|
||||||
|
|
||||||
|
import java.util.List;
|
||||||
|
import java.util.UUID;
|
||||||
|
|
||||||
|
@Data
|
||||||
|
@Entity
|
||||||
|
public class Car {
|
||||||
|
@Id
|
||||||
|
private Long id;
|
||||||
|
|
||||||
|
@Column(nullable = false)
|
||||||
|
private String brand;
|
||||||
|
|
||||||
|
@Column(nullable = false)
|
||||||
|
private String model;
|
||||||
|
|
||||||
|
@Column(nullable = false)
|
||||||
|
private Integer year;
|
||||||
|
|
||||||
|
@ManyToMany(fetch = FetchType.EAGER)
|
||||||
|
private List<Configuration> configurations;
|
||||||
|
|
||||||
|
@OneToMany(mappedBy = "car")
|
||||||
|
private List<Feature> features;
|
||||||
|
}
|
||||||
@@ -0,0 +1,26 @@
|
|||||||
|
package org.example.domain.entity;
|
||||||
|
|
||||||
|
import jakarta.persistence.*;
|
||||||
|
import lombok.Data;
|
||||||
|
|
||||||
|
import java.util.List;
|
||||||
|
import java.util.UUID;
|
||||||
|
|
||||||
|
@Data
|
||||||
|
@Entity
|
||||||
|
public class Configuration {
|
||||||
|
@Id
|
||||||
|
private Long id;
|
||||||
|
|
||||||
|
@Column(nullable = false)
|
||||||
|
private String name;
|
||||||
|
|
||||||
|
@Column(nullable = false)
|
||||||
|
private String description;
|
||||||
|
|
||||||
|
@OneToOne(fetch = FetchType.EAGER)
|
||||||
|
private User user;
|
||||||
|
|
||||||
|
@ManyToMany(fetch = FetchType.LAZY, mappedBy = "configurations")
|
||||||
|
private List<Car> cars;
|
||||||
|
}
|
||||||
@@ -0,0 +1,22 @@
|
|||||||
|
package org.example.domain.entity;
|
||||||
|
|
||||||
|
import jakarta.persistence.Column;
|
||||||
|
import jakarta.persistence.Entity;
|
||||||
|
import jakarta.persistence.Id;
|
||||||
|
import jakarta.persistence.OneToOne;
|
||||||
|
import lombok.Data;
|
||||||
|
|
||||||
|
import java.util.UUID;
|
||||||
|
|
||||||
|
@Entity
|
||||||
|
@Data
|
||||||
|
public class Feature {
|
||||||
|
@Id
|
||||||
|
private Long id;
|
||||||
|
|
||||||
|
@Column(nullable = false)
|
||||||
|
private String description;
|
||||||
|
|
||||||
|
@OneToOne
|
||||||
|
private Car car;
|
||||||
|
}
|
||||||
@@ -0,0 +1,32 @@
|
|||||||
|
package org.example.domain.entity;
|
||||||
|
|
||||||
|
import jakarta.persistence.*;
|
||||||
|
import lombok.Data;
|
||||||
|
|
||||||
|
import java.util.List;
|
||||||
|
import java.util.UUID;
|
||||||
|
|
||||||
|
@Entity
|
||||||
|
@Data
|
||||||
|
public class PreparationWork {
|
||||||
|
@Id
|
||||||
|
private Long id;
|
||||||
|
|
||||||
|
@Column(nullable = false)
|
||||||
|
private String name;
|
||||||
|
|
||||||
|
@Column(nullable = false)
|
||||||
|
private String description;
|
||||||
|
|
||||||
|
@OneToOne(fetch = FetchType.EAGER)
|
||||||
|
private User user;
|
||||||
|
|
||||||
|
@OneToMany(fetch = FetchType.LAZY, mappedBy = "preparationWorks")
|
||||||
|
private List<Request> requests;
|
||||||
|
|
||||||
|
@OneToMany(fetch = FetchType.EAGER, mappedBy = "preparationWork")
|
||||||
|
private List<Wish> wishes;
|
||||||
|
|
||||||
|
@ManyToMany(fetch = FetchType.LAZY)
|
||||||
|
private List<Configuration> configurations;
|
||||||
|
}
|
||||||
@@ -0,0 +1,30 @@
|
|||||||
|
package org.example.domain.entity;
|
||||||
|
|
||||||
|
import jakarta.persistence.*;
|
||||||
|
import jdk.jfr.Timestamp;
|
||||||
|
import lombok.Data;
|
||||||
|
import org.hibernate.annotations.Fetch;
|
||||||
|
|
||||||
|
import java.time.LocalDateTime;
|
||||||
|
import java.util.List;
|
||||||
|
import java.util.UUID;
|
||||||
|
|
||||||
|
@Entity
|
||||||
|
@Data
|
||||||
|
public class Request {
|
||||||
|
@Id
|
||||||
|
private Long id;
|
||||||
|
|
||||||
|
@Timestamp
|
||||||
|
@Column(nullable = false)
|
||||||
|
private LocalDateTime createdAt;
|
||||||
|
|
||||||
|
@OneToOne(fetch = FetchType.EAGER)
|
||||||
|
private User user;
|
||||||
|
|
||||||
|
@ManyToMany
|
||||||
|
private List<Car> cars;
|
||||||
|
|
||||||
|
@ManyToMany(fetch = FetchType.EAGER)
|
||||||
|
private List<PreparationWork> preparationWorks;
|
||||||
|
}
|
||||||
@@ -0,0 +1,29 @@
|
|||||||
|
package org.example.domain.entity;
|
||||||
|
|
||||||
|
|
||||||
|
import jakarta.persistence.*;
|
||||||
|
import lombok.Data;
|
||||||
|
import org.example.domain.enums.Role;
|
||||||
|
|
||||||
|
import java.util.UUID;
|
||||||
|
|
||||||
|
@Entity
|
||||||
|
@Data
|
||||||
|
@Table(name = "users")
|
||||||
|
public class User {
|
||||||
|
@Id
|
||||||
|
private Long id;
|
||||||
|
|
||||||
|
@Column(nullable = false)
|
||||||
|
private String name;
|
||||||
|
|
||||||
|
@Column(nullable = false)
|
||||||
|
private String email;
|
||||||
|
|
||||||
|
@Column(nullable = false)
|
||||||
|
private String password;
|
||||||
|
|
||||||
|
@Column(nullable = false)
|
||||||
|
@Enumerated(EnumType.STRING)
|
||||||
|
private Role role;
|
||||||
|
}
|
||||||
@@ -0,0 +1,24 @@
|
|||||||
|
package org.example.domain.entity;
|
||||||
|
|
||||||
|
import jakarta.persistence.*;
|
||||||
|
import jdk.jfr.Timestamp;
|
||||||
|
import lombok.Data;
|
||||||
|
|
||||||
|
import java.time.LocalDateTime;
|
||||||
|
import java.util.UUID;
|
||||||
|
|
||||||
|
@Entity
|
||||||
|
@Data
|
||||||
|
public class Wish {
|
||||||
|
@Id
|
||||||
|
private Long id;
|
||||||
|
|
||||||
|
@Column(nullable = false)
|
||||||
|
private String name;
|
||||||
|
|
||||||
|
@Timestamp
|
||||||
|
private LocalDateTime createdAt;
|
||||||
|
|
||||||
|
@OneToOne
|
||||||
|
private PreparationWork preparationWork;
|
||||||
|
}
|
||||||
@@ -0,0 +1,8 @@
|
|||||||
|
package org.example.domain.enums;
|
||||||
|
|
||||||
|
public enum Role {
|
||||||
|
CLADDING("CLADDING"),
|
||||||
|
WORKER("WORKER");
|
||||||
|
Role(String value){
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -0,0 +1,7 @@
|
|||||||
|
package org.example.domain.repositories;
|
||||||
|
|
||||||
|
import org.example.domain.entity.PreparationWork;
|
||||||
|
import org.springframework.data.jpa.repository.JpaRepository;
|
||||||
|
|
||||||
|
public interface PreparationWorkRepository extends JpaRepository<PreparationWork, Long> {
|
||||||
|
}
|
||||||
@@ -0,0 +1,13 @@
|
|||||||
|
package org.example.domain.repositories;
|
||||||
|
|
||||||
|
import org.example.domain.entity.Request;
|
||||||
|
import org.example.domain.entity.Wish;
|
||||||
|
import org.springframework.data.jpa.repository.JpaRepository;
|
||||||
|
|
||||||
|
import java.time.LocalDate;
|
||||||
|
import java.util.List;
|
||||||
|
import java.util.UUID;
|
||||||
|
|
||||||
|
public interface RequestRepository extends JpaRepository<Request, Long> {
|
||||||
|
List<Request> findByCreatedAtBetween(LocalDate dateFrom, LocalDate dateTo);
|
||||||
|
}
|
||||||
@@ -0,0 +1,9 @@
|
|||||||
|
package org.example.domain.repositories;
|
||||||
|
|
||||||
|
import org.example.domain.entity.User;
|
||||||
|
import org.springframework.data.jpa.repository.JpaRepository;
|
||||||
|
|
||||||
|
import java.util.UUID;
|
||||||
|
|
||||||
|
public interface UserRepository extends JpaRepository<User, Long> {
|
||||||
|
}
|
||||||
@@ -0,0 +1,14 @@
|
|||||||
|
package org.example.domain.repositories;
|
||||||
|
|
||||||
|
import org.example.domain.entity.Wish;
|
||||||
|
import org.springframework.data.jpa.repository.JpaRepository;
|
||||||
|
import org.springframework.data.jpa.repository.JpaSpecificationExecutor;
|
||||||
|
|
||||||
|
import java.time.LocalDate;
|
||||||
|
import java.util.List;
|
||||||
|
import java.util.UUID;
|
||||||
|
|
||||||
|
public interface WishRepository extends JpaRepository<Wish, Long>{
|
||||||
|
|
||||||
|
List<Wish> findByCreatedAtBetween(LocalDate dateFrom, LocalDate dateTo);
|
||||||
|
}
|
||||||
@@ -0,0 +1,8 @@
|
|||||||
|
package org.example.exceptions;
|
||||||
|
|
||||||
|
public class ObjectExistsException extends RuntimeException {
|
||||||
|
public ObjectExistsException(Class<?> type,String value)
|
||||||
|
{
|
||||||
|
super("Object " + type.getName() + " exists by: " + value);
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -0,0 +1,7 @@
|
|||||||
|
package org.example.exceptions;
|
||||||
|
|
||||||
|
public class ObjectNotExistsException extends RuntimeException {
|
||||||
|
public ObjectNotExistsException(Class<?> type,String value) {
|
||||||
|
super("Object " + type.getName() + " not found by: " + value );
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -0,0 +1,35 @@
|
|||||||
|
package org.example.managers;
|
||||||
|
|
||||||
|
|
||||||
|
import lombok.RequiredArgsConstructor;
|
||||||
|
import org.example.domain.entity.PreparationWork;
|
||||||
|
import org.example.domain.entity.Request;
|
||||||
|
import org.example.domain.repositories.PreparationWorkRepository;
|
||||||
|
import org.example.exceptions.ObjectNotExistsException;
|
||||||
|
import org.springframework.stereotype.Component;
|
||||||
|
|
||||||
|
import java.util.List;
|
||||||
|
|
||||||
|
@Component
|
||||||
|
@RequiredArgsConstructor
|
||||||
|
public class PreparationWorkManager {
|
||||||
|
private final PreparationWorkRepository preparationWorkRepository;
|
||||||
|
|
||||||
|
public void save(PreparationWork preparationWork){
|
||||||
|
preparationWorkRepository.save(preparationWork);
|
||||||
|
}
|
||||||
|
|
||||||
|
public void existsById(Long id){
|
||||||
|
preparationWorkRepository.existsById(id);
|
||||||
|
}
|
||||||
|
|
||||||
|
public PreparationWork getById(Long id){
|
||||||
|
return preparationWorkRepository.findById(id)
|
||||||
|
.orElseThrow(() -> new ObjectNotExistsException(PreparationWork.class, id.toString()));
|
||||||
|
}
|
||||||
|
|
||||||
|
public List<PreparationWork> getAll(){
|
||||||
|
return preparationWorkRepository.findAll();
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
@@ -0,0 +1,38 @@
|
|||||||
|
package org.example.managers;
|
||||||
|
|
||||||
|
import lombok.RequiredArgsConstructor;
|
||||||
|
import org.example.domain.entity.Request;
|
||||||
|
import org.example.domain.repositories.RequestRepository;
|
||||||
|
import org.example.exceptions.ObjectExistsException;
|
||||||
|
import org.example.exceptions.ObjectNotExistsException;
|
||||||
|
import org.springframework.stereotype.Component;
|
||||||
|
|
||||||
|
import java.time.LocalDate;
|
||||||
|
import java.util.List;
|
||||||
|
|
||||||
|
@Component
|
||||||
|
@RequiredArgsConstructor
|
||||||
|
public class RequestManager {
|
||||||
|
private RequestRepository requestRepository;
|
||||||
|
|
||||||
|
public void save(Request request){
|
||||||
|
requestRepository.save(request);
|
||||||
|
}
|
||||||
|
|
||||||
|
public void existsById(Long id){
|
||||||
|
requestRepository.existsById(id);
|
||||||
|
}
|
||||||
|
|
||||||
|
public Request getById(Long id){
|
||||||
|
return requestRepository.findById(id)
|
||||||
|
.orElseThrow(() -> new ObjectNotExistsException(Request.class, id.toString()));
|
||||||
|
}
|
||||||
|
|
||||||
|
public List<Request> getAll(){
|
||||||
|
return requestRepository.findAll();
|
||||||
|
}
|
||||||
|
|
||||||
|
public List<Request> getAll(LocalDate dateFrom, LocalDate dateTo){
|
||||||
|
return requestRepository.findByCreatedAtBetween(dateFrom, dateTo);
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -0,0 +1,43 @@
|
|||||||
|
package org.example.managers;
|
||||||
|
|
||||||
|
import lombok.RequiredArgsConstructor;
|
||||||
|
import org.example.domain.entity.User;
|
||||||
|
import org.example.domain.entity.Wish;
|
||||||
|
import org.example.domain.enums.Role;
|
||||||
|
import org.example.domain.repositories.UserRepository;
|
||||||
|
import org.example.exceptions.ObjectExistsException;
|
||||||
|
import org.example.exceptions.ObjectNotExistsException;
|
||||||
|
import org.springframework.data.domain.Example;
|
||||||
|
import org.springframework.stereotype.Component;
|
||||||
|
|
||||||
|
import java.util.List;
|
||||||
|
|
||||||
|
@Component
|
||||||
|
@RequiredArgsConstructor
|
||||||
|
public class UserManager {
|
||||||
|
private final UserRepository userRepository;
|
||||||
|
|
||||||
|
public void save(User user){
|
||||||
|
userRepository.save(user);
|
||||||
|
}
|
||||||
|
|
||||||
|
public boolean existsById(Long id){
|
||||||
|
return userRepository.existsById(id);
|
||||||
|
}
|
||||||
|
|
||||||
|
public User getById(Long id){
|
||||||
|
return userRepository.findById(id)
|
||||||
|
.orElseThrow(() -> new ObjectNotExistsException(User.class, id.toString()));
|
||||||
|
}
|
||||||
|
|
||||||
|
public List<User> getAll(){
|
||||||
|
return userRepository.findAll();
|
||||||
|
}
|
||||||
|
|
||||||
|
public List<User> getAll(Role role){
|
||||||
|
var user = new User();
|
||||||
|
user.setRole(role);
|
||||||
|
var example = Example.of(user);
|
||||||
|
return userRepository.findAll(example);
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -0,0 +1,40 @@
|
|||||||
|
package org.example.managers;
|
||||||
|
|
||||||
|
import lombok.RequiredArgsConstructor;
|
||||||
|
import org.example.domain.entity.User;
|
||||||
|
import org.example.domain.entity.Wish;
|
||||||
|
import org.example.domain.repositories.WishRepository;
|
||||||
|
import org.example.exceptions.ObjectExistsException;
|
||||||
|
import org.example.exceptions.ObjectNotExistsException;
|
||||||
|
import org.springframework.stereotype.Component;
|
||||||
|
|
||||||
|
import java.time.LocalDate;
|
||||||
|
import java.time.LocalDateTime;
|
||||||
|
import java.util.List;
|
||||||
|
|
||||||
|
@Component
|
||||||
|
@RequiredArgsConstructor
|
||||||
|
public class WishManager {
|
||||||
|
private final WishRepository wishRepository;
|
||||||
|
|
||||||
|
public void save(Wish wish){
|
||||||
|
wishRepository.save(wish);
|
||||||
|
}
|
||||||
|
|
||||||
|
public boolean existsById(Long id){
|
||||||
|
return wishRepository.existsById(id);
|
||||||
|
}
|
||||||
|
|
||||||
|
public Wish getById(Long id){
|
||||||
|
return wishRepository.findById(id)
|
||||||
|
.orElseThrow(() -> new ObjectNotExistsException(Wish.class, id.toString()));
|
||||||
|
}
|
||||||
|
|
||||||
|
public List<Wish> getAll(){
|
||||||
|
return wishRepository.findAll();
|
||||||
|
}
|
||||||
|
|
||||||
|
public List<Wish> getAll(LocalDate dateFrom, LocalDate dateTo){
|
||||||
|
return wishRepository.findByCreatedAtBetween(dateFrom, dateTo);
|
||||||
|
}
|
||||||
|
}
|
||||||
12
ServiceCenter/src/main/resources/application.yml
Normal file
12
ServiceCenter/src/main/resources/application.yml
Normal file
@@ -0,0 +1,12 @@
|
|||||||
|
spring:
|
||||||
|
datasource:
|
||||||
|
url: jdbc:postgresql://localhost:5432/
|
||||||
|
username: postgres
|
||||||
|
password: postgres
|
||||||
|
jpa:
|
||||||
|
show-sql: true
|
||||||
|
hibernate:
|
||||||
|
ddl-auto: create
|
||||||
|
properties:
|
||||||
|
hibernate:
|
||||||
|
format_sql: true
|
||||||
Reference in New Issue
Block a user