diff --git a/pom.xml b/pom.xml index 6142921d..1572627b 100644 --- a/pom.xml +++ b/pom.xml @@ -1,6 +1,5 @@ - + xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 https://maven.apache.org/xsd/maven-4.0.0.xsd"> 4.0.0 org.springframework.boot @@ -13,28 +12,69 @@ 0.0.1-SNAPSHOT tendermanagement Tender Management project - - - - - - - - - - - - - 17 + 1.5.5.Final + org.springframework.boot spring-boot-starter-web + + + org.projectlombok + lombok + 1.18.24 + + + + + com.h2database + h2 + 1.4.200 + + + + + org.postgresql + postgresql + + + + + org.springframework.boot + spring-boot-starter-data-jpa + + + + + org.springdoc + springdoc-openapi-starter-webmvc-ui + 2.2.0 + + + + + org.mapstruct + mapstruct + ${mapstruct.version} + + + org.mapstruct + mapstruct-processor + ${mapstruct.version} + provided + + + + org.liquibase + liquibase-core + + + org.springframework.boot spring-boot-starter-test @@ -42,13 +82,21 @@ + org.springframework.boot spring-boot-maven-plugin + + org.liquibase + liquibase-maven-plugin + 4.20.0 + + src/main/resources/application.properties + + - diff --git a/src/main/java/net/gepafin/tendermanagement/TendermanagementApplication.java b/src/main/java/net/gepafin/tendermanagement/TendermanagementApplication.java index f63a972f..07a51505 100644 --- a/src/main/java/net/gepafin/tendermanagement/TendermanagementApplication.java +++ b/src/main/java/net/gepafin/tendermanagement/TendermanagementApplication.java @@ -2,12 +2,21 @@ package net.gepafin.tendermanagement; import org.springframework.boot.SpringApplication; import org.springframework.boot.autoconfigure.SpringBootApplication; +import org.springframework.boot.autoconfigure.domain.EntityScan; +import org.springframework.context.annotation.ComponentScan; +import org.springframework.data.jpa.repository.config.EnableJpaRepositories; +import org.springframework.scheduling.annotation.EnableScheduling; +@EnableScheduling +@ComponentScan(basePackages = {"net.gepafin.tendermanagement"}) +@EnableJpaRepositories(basePackages = {"net.gepafin.tendermanagement"}) +@EntityScan(basePackages = {"net.gepafin.tendermanagement"}) @SpringBootApplication public class TendermanagementApplication { public static void main(String[] args) { SpringApplication.run(TendermanagementApplication.class, args); + System.out.println("Spring Boot started"); } } diff --git a/src/main/java/net/gepafin/tendermanagement/config/MessageSourceConfig.java b/src/main/java/net/gepafin/tendermanagement/config/MessageSourceConfig.java new file mode 100644 index 00000000..6f9767c6 --- /dev/null +++ b/src/main/java/net/gepafin/tendermanagement/config/MessageSourceConfig.java @@ -0,0 +1,17 @@ +package net.gepafin.tendermanagement.config; + +import org.springframework.context.annotation.Bean; +import org.springframework.context.annotation.Configuration; +import org.springframework.context.support.ResourceBundleMessageSource; + +@Configuration +public class MessageSourceConfig { + @Bean(name = "defaultMessageSource") + public ResourceBundleMessageSource messageSource() { + ResourceBundleMessageSource messageSource = new ResourceBundleMessageSource(); + messageSource.setBasenames("message"); + messageSource.setDefaultEncoding("UTF-8"); + messageSource.setUseCodeAsDefaultMessage(true); + return messageSource; + } +} diff --git a/src/main/java/net/gepafin/tendermanagement/config/SchemaInit.java b/src/main/java/net/gepafin/tendermanagement/config/SchemaInit.java new file mode 100644 index 00000000..6d57f81f --- /dev/null +++ b/src/main/java/net/gepafin/tendermanagement/config/SchemaInit.java @@ -0,0 +1,70 @@ +package net.gepafin.tendermanagement.config; + +import java.sql.Connection; +import java.sql.SQLException; +import java.sql.Statement; + +import javax.sql.DataSource; + +import org.springframework.beans.factory.InitializingBean; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.boot.autoconfigure.AbstractDependsOnBeanFactoryPostProcessor; +import org.springframework.boot.autoconfigure.AutoConfigureAfter; +import org.springframework.boot.autoconfigure.condition.ConditionalOnBean; +import org.springframework.boot.autoconfigure.condition.ConditionalOnClass; +import org.springframework.boot.autoconfigure.condition.ConditionalOnProperty; +import org.springframework.boot.autoconfigure.jdbc.DataSourceAutoConfiguration; +import org.springframework.boot.autoconfigure.orm.jpa.HibernateJpaAutoConfiguration; +import org.springframework.context.annotation.Configuration; +import org.springframework.context.annotation.Import; +import org.springframework.stereotype.Component; + +import liquibase.change.DatabaseChange; +import liquibase.integration.spring.SpringLiquibase; +import org.springframework.beans.factory.annotation.Value; +import lombok.extern.slf4j.Slf4j; + +@Slf4j +@Configuration +@ConditionalOnClass({ SpringLiquibase.class, DatabaseChange.class }) +@ConditionalOnProperty(prefix = "spring.liquibase", name = "enabled", matchIfMissing = true) +@AutoConfigureAfter({ DataSourceAutoConfiguration.class, HibernateJpaAutoConfiguration.class }) +@Import({SchemaInit.SpringLiquibaseDependsOnPostProcessor.class}) +public class SchemaInit { + + @Component + @ConditionalOnProperty(prefix = "spring.liquibase", name = "enabled", matchIfMissing = true) + public static class SchemaInitBean implements InitializingBean { + + private final DataSource dataSource; + private final String schemaName; + + @Autowired + public SchemaInitBean(DataSource dataSource, @Value("${spring.liquibase.default-schema}") String schemaName) { + this.dataSource = dataSource; + this.schemaName = schemaName; + } + + @Override + public void afterPropertiesSet() { + try (Connection conn = dataSource.getConnection(); + Statement statement = conn.createStatement()) { + log.info("Going to create DB schema '{}' if not exists.", schemaName); + String query = "create schema if not exists " + schemaName; + statement.execute(query); + } catch (SQLException e) { + throw new RuntimeException("Failed to create schema '" + schemaName + "'", e); + } + } + } + + + @ConditionalOnBean(SchemaInitBean.class) + static class SpringLiquibaseDependsOnPostProcessor extends AbstractDependsOnBeanFactoryPostProcessor { + + SpringLiquibaseDependsOnPostProcessor() { + // Configure the 3rd party SpringLiquibase bean to depend on our SchemaInitBean + super(SpringLiquibase.class, SchemaInitBean.class); + } + } +} \ No newline at end of file diff --git a/src/main/java/net/gepafin/tendermanagement/config/Translator.java b/src/main/java/net/gepafin/tendermanagement/config/Translator.java new file mode 100644 index 00000000..b3c02401 --- /dev/null +++ b/src/main/java/net/gepafin/tendermanagement/config/Translator.java @@ -0,0 +1,25 @@ +package net.gepafin.tendermanagement.config; + +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.context.i18n.LocaleContextHolder; +import org.springframework.context.support.ResourceBundleMessageSource; +import org.springframework.stereotype.Component; + +import java.util.Locale; + +@Component +public class Translator { + + private static ResourceBundleMessageSource messageSource; + + @Autowired + Translator(ResourceBundleMessageSource messageSource) { + Translator.messageSource = messageSource; + } + + public static String toLocale(String msgCode) { +// LocaleContextHolder.setDefaultLocale(Locale.ITALIAN); + Locale locale = LocaleContextHolder.getLocale(); + return messageSource.getMessage(msgCode, null, locale); + } +} \ No newline at end of file diff --git a/src/main/java/net/gepafin/tendermanagement/constants/GepafinConstant.java b/src/main/java/net/gepafin/tendermanagement/constants/GepafinConstant.java new file mode 100644 index 00000000..7d00913f --- /dev/null +++ b/src/main/java/net/gepafin/tendermanagement/constants/GepafinConstant.java @@ -0,0 +1,27 @@ +package net.gepafin.tendermanagement.constants; + +public class GepafinConstant { + + public static final String USER_CREATED_SUCCESS_MSG = "user.created.success"; + public static final String USER_UPDATED_SUCCESS_MSG = "user.updated.success"; + public static final String USER_DELETED_SUCCESS_MSG = "user.deleted.success"; + public static final String USER_NOT_FOUND_MSG = "user.not.found"; + public static final String CREATE_USER_ERROR_MSG = "create_user_error_msg"; + public static final String UPDATE_USER_ERROR_MSG = "update_user_error_msg"; + public static final String DELETE_USER_ERROR_MSG = "delete_user_error_msg"; + public static final String GET_USER_SUCCESS_MSG = "get_user_success_msg"; + + public static final String ROLE_CREATED_SUCCESS_MSG = "role.created.success"; + public static final String ROLE_UPDATED_SUCCESS_MSG = "role.updated.success"; + public static final String ROLE_DELETED_SUCCESS_MSG = "role.deleted.success"; + public static final String ROLE_FETCH_SUCCESS_MSG = "role.fetch.success"; + public static final String ROLE_NOT_FOUND = "role.not.found"; + + + public static final String REGION_CREATED_SUCCESS_MSG = "region.created.success"; + public static final String REGION_UPDATED_SUCCESS_MSG = "region.updated.success"; + public static final String GET_REGION_SUCCESS_MSG = "get.region.success"; + public static final String DELETE_REGION_SUCCESS_MSG = "delete.region.success"; + public static final String REGION_NOT_FOUND_MSG = "user.region.not.found"; + public static final String PASSWORD_DOESNT_MATCH ="password.doesnt.match"; +} diff --git a/src/main/java/net/gepafin/tendermanagement/dao/RegionDao.java b/src/main/java/net/gepafin/tendermanagement/dao/RegionDao.java new file mode 100644 index 00000000..27f7f250 --- /dev/null +++ b/src/main/java/net/gepafin/tendermanagement/dao/RegionDao.java @@ -0,0 +1,109 @@ +package net.gepafin.tendermanagement.dao; + +import net.gepafin.tendermanagement.config.Translator; +import net.gepafin.tendermanagement.constants.GepafinConstant; +import net.gepafin.tendermanagement.entities.RegionEntity; +import net.gepafin.tendermanagement.entities.RoleEntity; +import net.gepafin.tendermanagement.model.request.RegionReq; +import net.gepafin.tendermanagement.model.request.RoleReq; +import net.gepafin.tendermanagement.model.response.RegionResponseBean; +import net.gepafin.tendermanagement.model.request.UpdateRegionReq; +import net.gepafin.tendermanagement.model.response.RoleResponseBean; +import net.gepafin.tendermanagement.repositories.RegionRepository; +import net.gepafin.tendermanagement.util.Utils; +import net.gepafin.tendermanagement.web.rest.api.errors.ResourceNotFoundException; +import net.gepafin.tendermanagement.web.rest.api.errors.Status; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.stereotype.Repository; + +import java.math.BigDecimal; +import java.time.LocalDateTime; +import java.util.List; +import java.util.stream.Collectors; + +import static net.gepafin.tendermanagement.util.ObjectUtils.setIfUpdated; + +@Repository +public class RegionDao { + @Autowired + private RegionRepository regionRepository; + + public RegionResponseBean createRegion(RegionReq regionReq) { + RegionEntity regionEntity = convertRegionRequestToRegionEntity(regionReq); + regionRepository.save(regionEntity); + return convertRegionEntityToRegionResponse(regionEntity); + } + private RegionEntity convertRegionRequestToRegionEntity(RegionReq regionReq) { + RegionEntity regionEntity = new RegionEntity(); + regionEntity.setCountry(regionReq.getCountry()); + regionEntity.setDescription(regionReq.getDescription()); + regionEntity.setGdp(regionReq.getGdp()); + regionEntity.setRegionName(regionReq.getRegionName()); + regionEntity.setAreaSize(regionReq.getAreaSize()); + regionEntity.setPopulation(regionReq.getPopulation()); + regionEntity.setEnvironmentalScore(regionReq.getEnvironmentalScore()); + regionEntity.setStatus(regionReq.getStatus()); + regionEntity.setHealthcareAccess(regionReq.getHealthcareAccess()); + regionEntity.setInfrastructureScore(regionReq.getInfrastructureScore()); + regionEntity.setPriorityArea(regionReq.getPriorityArea()); + regionEntity.setUnemploymentRate(regionReq.getUnemploymentRate()); + regionEntity.setEducationLevel(regionReq.getEducationLevel()); + return regionEntity; + } + private RegionResponseBean convertRegionEntityToRegionResponse(RegionEntity regionEntity) { + RegionResponseBean regionResponseBean = new RegionResponseBean(); + regionResponseBean.setId(regionEntity.getId()); + regionResponseBean.setCreatedDate(regionEntity.getCreatedDate()); + regionResponseBean.setUpdatedDate(regionEntity.getUpdatedDate()); + regionResponseBean.setCountry(regionEntity.getCountry()); + regionResponseBean.setDescription(regionEntity.getDescription()); + regionResponseBean.setGdp(regionEntity.getGdp()); + regionResponseBean.setRegionName(regionEntity.getRegionName()); + regionResponseBean.setAreaSize(regionEntity.getAreaSize()); + regionResponseBean.setPopulation(regionEntity.getPopulation()); + regionResponseBean.setEnvironmentalScore(regionEntity.getEnvironmentalScore()); + regionResponseBean.setStatus(regionEntity.getStatus()); + regionResponseBean.setHealthcareAccess(regionEntity.getHealthcareAccess()); + regionResponseBean.setInfrastructureScore(regionEntity.getInfrastructureScore()); + regionResponseBean.setPriorityArea(regionEntity.getPriorityArea()); + regionResponseBean.setUnemploymentRate(regionEntity.getUnemploymentRate()); + regionResponseBean.setEducationLevel(regionEntity.getEducationLevel()); + return regionResponseBean; + } + + public RegionResponseBean updateRegion(Long id, RegionReq regionReq) { + RegionEntity existingRegion = getRegionById(id); + setIfUpdated(existingRegion::getRegionName, existingRegion::setRegionName, regionReq.getRegionName()); + setIfUpdated(existingRegion::getDescription, existingRegion::setDescription, regionReq.getDescription()); + setIfUpdated(existingRegion::getCountry, existingRegion::setCountry, regionReq.getCountry()); + setIfUpdated(existingRegion::getStatus, existingRegion::setStatus, regionReq.getStatus()); + setIfUpdated(existingRegion::getPriorityArea, existingRegion::setPriorityArea, regionReq.getPriorityArea()); + setIfUpdated(existingRegion::getPopulation, existingRegion::setPopulation, regionReq.getPopulation()); + setIfUpdated(existingRegion::getAreaSize, existingRegion::setAreaSize, regionReq.getAreaSize()); + setIfUpdated(existingRegion::getGdp, existingRegion::setGdp, regionReq.getGdp()); + setIfUpdated(existingRegion::getUnemploymentRate, existingRegion::setUnemploymentRate, regionReq.getUnemploymentRate()); + setIfUpdated(existingRegion::getInfrastructureScore, existingRegion::setInfrastructureScore, regionReq.getInfrastructureScore() ); + setIfUpdated(existingRegion::getEducationLevel, existingRegion::setEducationLevel, regionReq.getEducationLevel()); + setIfUpdated(existingRegion::getHealthcareAccess, existingRegion::setHealthcareAccess, regionReq.getHealthcareAccess()); + setIfUpdated(existingRegion::getEnvironmentalScore, existingRegion::setEnvironmentalScore, regionReq.getEnvironmentalScore()); + regionRepository.save(existingRegion); + return Utils.convertObject(existingRegion, RegionResponseBean.class); + } + public RegionEntity getRegionById(Long id) { + return regionRepository.findById(id) + .orElseThrow(() -> new ResourceNotFoundException(Status.NOT_FOUND, Translator.toLocale(GepafinConstant.REGION_NOT_FOUND_MSG))); + } + public void deleteById(Long id) { + + regionRepository.findById(id) + .orElseThrow(() -> new ResourceNotFoundException(Status.NOT_FOUND, Translator.toLocale(GepafinConstant.REGION_NOT_FOUND_MSG))); + regionRepository.deleteById(id); + } + public List getAllRegions() + { + return regionRepository.findAll() + .stream() + .map(regionEntity -> Utils.convertObject(regionEntity, RegionResponseBean.class)) + .collect(Collectors.toList()); + } +} diff --git a/src/main/java/net/gepafin/tendermanagement/dao/RoleDao.java b/src/main/java/net/gepafin/tendermanagement/dao/RoleDao.java new file mode 100644 index 00000000..08c1a40f --- /dev/null +++ b/src/main/java/net/gepafin/tendermanagement/dao/RoleDao.java @@ -0,0 +1,80 @@ +package net.gepafin.tendermanagement.dao; + +import net.gepafin.tendermanagement.config.Translator; +import net.gepafin.tendermanagement.constants.GepafinConstant; +import net.gepafin.tendermanagement.entities.RoleEntity; +import net.gepafin.tendermanagement.model.request.RoleReq; +import net.gepafin.tendermanagement.model.response.RoleResponseBean; +import net.gepafin.tendermanagement.repositories.RoleRepository; +import net.gepafin.tendermanagement.service.RegionService; +import net.gepafin.tendermanagement.util.Utils; +import net.gepafin.tendermanagement.web.rest.api.errors.ResourceNotFoundException; +import net.gepafin.tendermanagement.web.rest.api.errors.Status; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.stereotype.Component; + +import java.util.List; +import java.util.stream.Collectors; + +import static net.gepafin.tendermanagement.util.ObjectUtils.setIfUpdated; + +@Component +public class RoleDao { + + @Autowired + private RoleRepository roleRepository; + @Autowired + private RegionService regionService; + + public RoleResponseBean createRole(RoleReq roleReq) { + RoleEntity roleEntity = convertRoleRequestToRoleEntity(roleReq); + roleEntity = roleRepository.save(roleEntity); + return convertRoleEntityToRoleResponse(roleEntity); + } + private RoleEntity convertRoleRequestToRoleEntity(RoleReq roleReq) { + RoleEntity roleEntity = new RoleEntity(); + roleEntity.setRoleName(roleReq.getRoleName()); + roleEntity.setPermissions(roleReq.getPermissions()); + roleEntity.setDescription(roleEntity.getDescription()); + roleEntity.setRegion(regionService.getRegionById(roleReq.getRegionId())); + return roleEntity; + } + private RoleResponseBean convertRoleEntityToRoleResponse(RoleEntity roleEntity) { + RoleResponseBean roleResponseBean=new RoleResponseBean(); + roleResponseBean.setId(roleEntity.getId()); + roleResponseBean.setCreatedDate(roleEntity.getCreatedDate()); + roleResponseBean.setUpdatedDate(roleEntity.getUpdatedDate()); + roleResponseBean.setRoleName(roleEntity.getRoleName()); + roleResponseBean.setDescription(roleEntity.getDescription()); + roleResponseBean.setPermissions(roleEntity.getPermissions()); + roleResponseBean.setRegion(roleEntity.getRegion()); + return roleResponseBean; + } + public RoleResponseBean updateRole(Long id, RoleReq roleReq) { + + RoleEntity existingUserRole = getRoleById(id); + setIfUpdated(existingUserRole::getRoleName, existingUserRole::setRoleName, roleReq.getRoleName()); + setIfUpdated(existingUserRole::getDescription, existingUserRole::setDescription, roleReq.getDescription()); + setIfUpdated(existingUserRole::getPermissions, existingUserRole::setPermissions, roleReq.getPermissions()); + roleRepository.save(existingUserRole); + return Utils.convertObject(existingUserRole, RoleResponseBean.class); + } + + public RoleEntity getRoleById(Long id) { + return roleRepository.findById(id) + .orElseThrow(() -> new ResourceNotFoundException(Status.NOT_FOUND, Translator.toLocale(GepafinConstant.ROLE_NOT_FOUND))); + } + + public void deleteById(Long id) { + roleRepository.findById(id) + .orElseThrow(() -> new ResourceNotFoundException(Status.NOT_FOUND,Translator.toLocale(GepafinConstant.ROLE_NOT_FOUND))); + roleRepository.deleteById(id); + } + + public List getAllRoles() { + return roleRepository.findAll() + .stream() + .map(roleEntity -> Utils.convertObject(roleEntity, RoleResponseBean.class)) + .collect(Collectors.toList()); + } +} diff --git a/src/main/java/net/gepafin/tendermanagement/dao/UserDao.java b/src/main/java/net/gepafin/tendermanagement/dao/UserDao.java new file mode 100644 index 00000000..63a7c353 --- /dev/null +++ b/src/main/java/net/gepafin/tendermanagement/dao/UserDao.java @@ -0,0 +1,99 @@ +package net.gepafin.tendermanagement.dao; + +import net.gepafin.tendermanagement.config.Translator; +import net.gepafin.tendermanagement.constants.GepafinConstant; +import net.gepafin.tendermanagement.entities.RoleEntity; +import net.gepafin.tendermanagement.entities.UserEntity; +import net.gepafin.tendermanagement.model.request.UpdateUserReq; +import net.gepafin.tendermanagement.model.request.UserReq; +import net.gepafin.tendermanagement.model.response.UserResponseBean; +import net.gepafin.tendermanagement.repositories.UserRepository; +import net.gepafin.tendermanagement.service.RoleService; +import net.gepafin.tendermanagement.web.rest.api.errors.CustomValidationException; +import net.gepafin.tendermanagement.web.rest.api.errors.ResourceNotFoundException; +import net.gepafin.tendermanagement.web.rest.api.errors.Status; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.stereotype.Repository; + +import static net.gepafin.tendermanagement.util.ObjectUtils.setIfUpdated; + +@Repository +public class UserDao { + @Autowired + private UserRepository userRepository; + + @Autowired + private RoleService roleService; + + public UserResponseBean createUser(UserReq userReq) { + if (!userReq.getPassword().equals(userReq.getConfPassword())) { + throw new CustomValidationException(Status.VALIDATION_ERROR,Translator.toLocale(GepafinConstant.PASSWORD_DOESNT_MATCH)); + } + UserEntity userEntity = convertUserRequestToUserEntity(userReq); + userEntity = userRepository.save(userEntity); + return convertUserEntityToUserResponse(userEntity); + } + + public UserResponseBean updateUser(Long userId, UpdateUserReq userReq) { + UserEntity userEntity = userRepository.findById(userId) + .orElseThrow(() -> new ResourceNotFoundException(Status.NOT_FOUND, Translator.toLocale(GepafinConstant.REGION_NOT_FOUND_MSG))); + setIfUpdated(userEntity::getStatus, userEntity::setStatus, userReq.getStatus()); + setIfUpdated(userEntity::getFirstName, userEntity::setFirstName, userReq.getFirstName()); + setIfUpdated(userEntity::getLastName, userEntity::setLastName, userReq.getLastName()); + setIfUpdated(userEntity::getOrganization, userEntity::setOrganization, userReq.getOrganization()); + setIfUpdated(userEntity::getAddress, userEntity::setAddress, userReq.getAddress()); + setIfUpdated(userEntity::getPhoneNumber, userEntity::setPhoneNumber, userReq.getPhoneNumber()); + if (userReq.getRoleId() != null) { + RoleEntity roleEntity = roleService.getRoleById(userReq.getRoleId()); + setIfUpdated(userEntity::getRoleEntity, userEntity::setRoleEntity, roleEntity); + } + userEntity = userRepository.save(userEntity); + return convertUserEntityToUserResponse(userEntity); + } + + private UserEntity convertUserRequestToUserEntity(UserReq userReq) { + UserEntity userEntity = new UserEntity(); + userEntity.setPassword(userReq.getPassword()); + userEntity.setEmail(userReq.getEmail()); + userEntity.setFirstName(userReq.getFirstName()); + userEntity.setStatus(userReq.getStatus()); + userEntity.setLastName(userReq.getLastName()); + userEntity.setOrganization(userReq.getOrganization()); + userEntity.setAddress(userReq.getAddress()); + userEntity.setPhoneNumber(userReq.getPhoneNumber()); + userEntity.setRoleEntity(roleService.getRoleById(userReq.getRoleId())); + return userEntity; + } + + private UserResponseBean convertUserEntityToUserResponse(UserEntity userEntity) { + UserResponseBean userResponseBean = new UserResponseBean(); + userResponseBean.setId(userEntity.getId()); + userResponseBean.setCreatedDate(userEntity.getCreatedDate()); + userResponseBean.setUpdatedDate(userEntity.getUpdatedDate()); + userResponseBean.setId(userEntity.getId()); + userResponseBean.setEmail(userEntity.getEmail()); + userResponseBean.setFirstName(userEntity.getFirstName()); + userResponseBean.setLastName(userEntity.getLastName()); + userResponseBean.setPhoneNumber(userEntity.getPhoneNumber()); + userResponseBean.setOrganization(userEntity.getOrganization()); + userResponseBean.setAddress(userEntity.getAddress()); + userResponseBean.setCity(userEntity.getCity()); + userResponseBean.setCountry(userEntity.getCountry()); + userResponseBean.setStatus(userEntity.getStatus()); + userResponseBean.setRole(userEntity.getRoleEntity()); + userResponseBean.setLastLogin(userEntity.getLastLogin()); + return userResponseBean; + } + + public UserResponseBean getUserById(Long id) { + UserEntity userEntity = userRepository.findById(id) + .orElseThrow(() -> new ResourceNotFoundException(Status.NOT_FOUND,Translator.toLocale(GepafinConstant.USER_NOT_FOUND_MSG))); + return convertUserEntityToUserResponse(userEntity); + } + + public void deleteUser(Long id) { + userRepository.findById(id) + .orElseThrow(() -> new ResourceNotFoundException(Status.NOT_FOUND,Translator.toLocale(GepafinConstant.USER_NOT_FOUND_MSG))); + userRepository.deleteById(id); + } +} diff --git a/src/main/java/net/gepafin/tendermanagement/entities/BaseEntity.java b/src/main/java/net/gepafin/tendermanagement/entities/BaseEntity.java new file mode 100644 index 00000000..f8427719 --- /dev/null +++ b/src/main/java/net/gepafin/tendermanagement/entities/BaseEntity.java @@ -0,0 +1,35 @@ +package net.gepafin.tendermanagement.entities; + +import jakarta.persistence.*; +import lombok.Data; +import net.gepafin.tendermanagement.util.DateTimeUtil; + + +import java.time.LocalDateTime; + +@MappedSuperclass +@Data +public class BaseEntity { + @Id + @GeneratedValue(strategy = GenerationType.IDENTITY) + @Column(name = "ID", unique = true) + private Long id; + + + @Column(name = "CREATED_DATE", updatable = false) + LocalDateTime createdDate; + + @Column(name = "UPDATED_DATE") + LocalDateTime updatedDate; + + @PrePersist + public void setCreatedDate() { + this.createdDate = DateTimeUtil.DateServerToUTC(LocalDateTime.now()); + this.updatedDate = DateTimeUtil.DateServerToUTC(LocalDateTime.now()); + } + @PreUpdate + public void setUpdatedDate() { + this.updatedDate = DateTimeUtil.DateServerToUTC(LocalDateTime.now()); + } + +} diff --git a/src/main/java/net/gepafin/tendermanagement/entities/RegionEntity.java b/src/main/java/net/gepafin/tendermanagement/entities/RegionEntity.java new file mode 100644 index 00000000..d9687dd1 --- /dev/null +++ b/src/main/java/net/gepafin/tendermanagement/entities/RegionEntity.java @@ -0,0 +1,60 @@ +package net.gepafin.tendermanagement.entities; + +import jakarta.persistence.Column; +import jakarta.persistence.Entity; +import jakarta.persistence.GeneratedValue; +import jakarta.persistence.GenerationType; +import jakarta.persistence.Id; +import jakarta.persistence.Table; + +import lombok.Getter; +import lombok.Setter; +import net.gepafin.tendermanagement.entities.BaseEntity; + +import java.math.BigDecimal; + +@Entity +@Table(name = "\"REGION\"") +@Getter +@Setter +public class RegionEntity extends BaseEntity { + + @Column(name = "REGION_NAME", length = 255, nullable = true) + private String regionName; + + @Column(name = "DESCRIPTION", length = 255, nullable = true) + private String description; + + @Column(name = "COUNTRY", length = 50, nullable = true) + private String country; + + @Column(name = "STATUS", length = 30, nullable = true) + private String status; + + @Column(name = "PRIORITY_AREA", length = 255, nullable = true) + private String priorityArea; + + @Column(name = "POPULATION", nullable = true) + private Long population; + + @Column(name = "AREA_SIZE", nullable = true) + private BigDecimal areaSize; + + @Column(name = "GDP", nullable = true) + private BigDecimal gdp; + + @Column(name = "UNEMPLOYMENT_RATE", nullable = true) + private BigDecimal unemploymentRate; + + @Column(name = "INFRASTRUCTURE_SCORE", nullable = true) + private BigDecimal infrastructureScore; + + @Column(name = "EDUCATION_LEVEL", nullable = true) + private BigDecimal educationLevel; + + @Column(name = "HEALTHCARE_ACCESS", nullable = true) + private BigDecimal healthcareAccess; + + @Column(name = "ENVIRONMENTAL_SCORE", nullable = true) + private BigDecimal environmentalScore; +} diff --git a/src/main/java/net/gepafin/tendermanagement/entities/RoleEntity.java b/src/main/java/net/gepafin/tendermanagement/entities/RoleEntity.java new file mode 100644 index 00000000..25693802 --- /dev/null +++ b/src/main/java/net/gepafin/tendermanagement/entities/RoleEntity.java @@ -0,0 +1,26 @@ +package net.gepafin.tendermanagement.entities; + +import jakarta.persistence.*; + +import lombok.Getter; +import lombok.Setter; + +@Entity +@Table(name = "\"ROLE\"") +@Getter +@Setter +public class RoleEntity extends BaseEntity { + + @Column(name = "ROLE_NAME", length = 50, nullable = true) + private String roleName; + + @Column(name = "DESCRIPTION", length = 255, nullable = true) + private String description; + + @Column(name = "PERMISSIONS", length = 255, nullable = true) + private String permissions; + @ManyToOne + @JoinColumn(name = "REGION_ID", nullable = true) + private RegionEntity region; + +} diff --git a/src/main/java/net/gepafin/tendermanagement/entities/UserEntity.java b/src/main/java/net/gepafin/tendermanagement/entities/UserEntity.java new file mode 100644 index 00000000..890fdc32 --- /dev/null +++ b/src/main/java/net/gepafin/tendermanagement/entities/UserEntity.java @@ -0,0 +1,77 @@ +package net.gepafin.tendermanagement.entities; + +import com.fasterxml.jackson.annotation.JsonValue; +import jakarta.persistence.*; +import jakarta.validation.constraints.Email; + +import com.fasterxml.jackson.annotation.JsonIgnore; + +import lombok.Getter; +import lombok.Setter; +import net.gepafin.tendermanagement.entities.BaseEntity; + +import java.time.LocalDateTime; + +@Entity +@Table(name = "\"USER\"") +@Getter +@Setter +public class UserEntity extends BaseEntity { + + @Column(name = "PASSWORD", columnDefinition = "TEXT",nullable = false) + @JsonIgnore + private String password; + + @Email + @Column(name = "EMAIL", length = 255, unique = true, nullable = false) + private String email; + + @ManyToOne + @JoinColumn(name = "ROLE_ID") + @JsonIgnore + private RoleEntity roleEntity; + + + @Column(name = "LAST_LOGIN") + private LocalDateTime lastLogin; + + @Column(name = "STATUS", length = 30, nullable = true) + private String status; + + @Column(name = "FIRST_NAME", length = 50, nullable = true) + private String firstName; + + @Column(name = "LAST_NAME", length = 50, nullable = true) + private String lastName; + + @Column(name = "PHONE_NUMBER", length = 15, nullable = true) + private String phoneNumber; + + @Column(name = "ORGANIZATION", length = 255, nullable = true) + private String organization; + + @Column(name = "ADDRESS", length = 255, nullable = true) + private String address; + + @Column(name = "CITY", length = 50, nullable = true) + private String city; + + @Column(name = "COUNTRY", length = 50, nullable = true) + private String country; + + public enum UserStatusEnum { + ACTIVE("ACTIVE"), + INACTIVE("INACTIVE"); + + private String value; + + UserStatusEnum(String value) { + this.value = value; + } + + @JsonValue + public String getValue() { + return value; + } + } +} diff --git a/src/main/java/net/gepafin/tendermanagement/model/User.java b/src/main/java/net/gepafin/tendermanagement/model/User.java deleted file mode 100644 index 8b3fe662..00000000 --- a/src/main/java/net/gepafin/tendermanagement/model/User.java +++ /dev/null @@ -1,38 +0,0 @@ -package net.gepafin.tendermanagement.model; - -public class User { - private Long id; - private String name; - private String email; - - public User() {} - - public User(Long id, String name, String email) { - this.id = id; - this.name = name; - this.email = email; - } - public Long getId() { - return id; - } - - public void setId(Long id) { - this.id = id; - } - - public String getName() { - return name; - } - - public void setName(String name) { - this.name = name; - } - - public String getEmail() { - return email; - } - - public void setEmail(String email) { - this.email = email; - } -} diff --git a/src/main/java/net/gepafin/tendermanagement/model/request/RegionReq.java b/src/main/java/net/gepafin/tendermanagement/model/request/RegionReq.java new file mode 100644 index 00000000..fae42f3c --- /dev/null +++ b/src/main/java/net/gepafin/tendermanagement/model/request/RegionReq.java @@ -0,0 +1,39 @@ +package net.gepafin.tendermanagement.model.request; + +import jakarta.validation.constraints.NotEmpty; +import jakarta.validation.constraints.NotNull; +import lombok.Getter; +import lombok.Setter; + +import java.math.BigDecimal; + +@Getter +@Setter +public class RegionReq { + + private String regionName; + + private String description; + + private String country; + + private String status; + + private String priorityArea; + + private Long population; + + private BigDecimal areaSize; + + private BigDecimal gdp; + + private BigDecimal unemploymentRate; + + private BigDecimal infrastructureScore; + + private BigDecimal educationLevel; + + private BigDecimal healthcareAccess; + + private BigDecimal environmentalScore; +} diff --git a/src/main/java/net/gepafin/tendermanagement/model/request/RoleReq.java b/src/main/java/net/gepafin/tendermanagement/model/request/RoleReq.java new file mode 100644 index 00000000..1e4ec6f4 --- /dev/null +++ b/src/main/java/net/gepafin/tendermanagement/model/request/RoleReq.java @@ -0,0 +1,27 @@ +package net.gepafin.tendermanagement.model.request; + +import com.fasterxml.jackson.annotation.JsonProperty; +import jakarta.validation.constraints.NotEmpty; +import jakarta.validation.constraints.NotNull; + +import lombok.Getter; +import lombok.Setter; + +@Getter +@Setter +public class RoleReq { + + @JsonProperty(access = JsonProperty.Access.READ_ONLY) + private Long id; + + private String roleName; + + private String description; + + private String permissions; + + private String status; + + private Long regionId; + +} diff --git a/src/main/java/net/gepafin/tendermanagement/model/request/UpdateRegionReq.java b/src/main/java/net/gepafin/tendermanagement/model/request/UpdateRegionReq.java new file mode 100644 index 00000000..8d32dc83 --- /dev/null +++ b/src/main/java/net/gepafin/tendermanagement/model/request/UpdateRegionReq.java @@ -0,0 +1,35 @@ +package net.gepafin.tendermanagement.model.request; + +import lombok.Getter; +import lombok.Setter; + +@Getter +@Setter +public class UpdateRegionReq { + private String regionName; + + private String description; + + private String country; + + private String status; + + private String priorityArea; + + private Long population; + + private Double areaSize; + + private Double gdp; + + private Double unemploymentRate; + + private Double infrastructureScore; + + private Double educationLevel; + + private Double healthcareAccess; + + private Double environmentalScore; + +} diff --git a/src/main/java/net/gepafin/tendermanagement/model/request/UpdateUserReq.java b/src/main/java/net/gepafin/tendermanagement/model/request/UpdateUserReq.java new file mode 100644 index 00000000..63eb2b89 --- /dev/null +++ b/src/main/java/net/gepafin/tendermanagement/model/request/UpdateUserReq.java @@ -0,0 +1,21 @@ +package net.gepafin.tendermanagement.model.request; + +import jakarta.validation.constraints.NotEmpty; +import jakarta.validation.constraints.NotNull; +import lombok.Getter; +import lombok.Setter; + +@Getter +@Setter +public class UpdateUserReq { + + private String firstName; + private String lastName; + private String phoneNumber; + private Long roleId; + private String organization; + private String address; + private String city; + private String status; + private String country; +} diff --git a/src/main/java/net/gepafin/tendermanagement/model/request/UserReq.java b/src/main/java/net/gepafin/tendermanagement/model/request/UserReq.java new file mode 100644 index 00000000..f866ac99 --- /dev/null +++ b/src/main/java/net/gepafin/tendermanagement/model/request/UserReq.java @@ -0,0 +1,44 @@ +package net.gepafin.tendermanagement.model.request; + +import com.fasterxml.jackson.annotation.JsonProperty; +import com.fasterxml.jackson.annotation.JsonValue; +import jakarta.validation.constraints.Email; +import jakarta.validation.constraints.NotEmpty; +import jakarta.validation.constraints.NotNull; +import lombok.Getter; +import lombok.Setter; + +import java.time.LocalDateTime; + +@Getter +@Setter +public class UserReq { + + + private String password; + + private String confPassword; + + private String email; + + private String firstName; + + private String lastName; + + private String phoneNumber; + + private Long roleId; + + private String organization; + + private String address; + + private String city; + + private String country; + + private String status; + + private LocalDateTime lastLogin; + +} diff --git a/src/main/java/net/gepafin/tendermanagement/model/response/RegionResponseBean.java b/src/main/java/net/gepafin/tendermanagement/model/response/RegionResponseBean.java new file mode 100644 index 00000000..c16d4c94 --- /dev/null +++ b/src/main/java/net/gepafin/tendermanagement/model/response/RegionResponseBean.java @@ -0,0 +1,28 @@ +package net.gepafin.tendermanagement.model.response; + +import lombok.Getter; +import lombok.Setter; + +import java.math.BigDecimal; +import java.time.LocalDateTime; + +@Getter +@Setter +public class RegionResponseBean { + private Long id; + private String regionName; + private String description; + private String country; + private String status; + private String priorityArea; + private Long population; + private BigDecimal areaSize; + private BigDecimal gdp; + private BigDecimal unemploymentRate; + private BigDecimal infrastructureScore; + private BigDecimal educationLevel; + private BigDecimal healthcareAccess; + private BigDecimal environmentalScore; + private LocalDateTime createdDate; + private LocalDateTime updatedDate; +} diff --git a/src/main/java/net/gepafin/tendermanagement/model/response/RoleResponseBean.java b/src/main/java/net/gepafin/tendermanagement/model/response/RoleResponseBean.java new file mode 100644 index 00000000..1e708b58 --- /dev/null +++ b/src/main/java/net/gepafin/tendermanagement/model/response/RoleResponseBean.java @@ -0,0 +1,19 @@ +package net.gepafin.tendermanagement.model.response; + +import lombok.Data; +import lombok.Getter; +import lombok.Setter; +import net.gepafin.tendermanagement.entities.RegionEntity; + +import java.time.LocalDateTime; + +@Data +public class RoleResponseBean { + private Long id; + private String roleName; + private String description; + private LocalDateTime createdDate; + private LocalDateTime updatedDate; + private String permissions; + private RegionEntity region; +} diff --git a/src/main/java/net/gepafin/tendermanagement/model/response/UserResponseBean.java b/src/main/java/net/gepafin/tendermanagement/model/response/UserResponseBean.java new file mode 100644 index 00000000..2c036804 --- /dev/null +++ b/src/main/java/net/gepafin/tendermanagement/model/response/UserResponseBean.java @@ -0,0 +1,41 @@ +package net.gepafin.tendermanagement.model.response; + +import jakarta.validation.constraints.Email; +import jakarta.validation.constraints.NotEmpty; +import jakarta.validation.constraints.NotNull; +import lombok.Getter; +import lombok.Setter; +import net.gepafin.tendermanagement.entities.RoleEntity; + +import java.time.LocalDateTime; + +@Getter +@Setter +public class UserResponseBean { + private Long id; + private String email; + + private String firstName; + + private String lastName; + + private String phoneNumber; + + private RoleEntity role; + + private String organization; + + private String address; + + private String city; + + private String country; + + private String status; + + private LocalDateTime lastLogin; + + private LocalDateTime createdDate; + + private LocalDateTime updatedDate; +} diff --git a/src/main/java/net/gepafin/tendermanagement/model/util/Response.java b/src/main/java/net/gepafin/tendermanagement/model/util/Response.java new file mode 100644 index 00000000..7d0c768d --- /dev/null +++ b/src/main/java/net/gepafin/tendermanagement/model/util/Response.java @@ -0,0 +1,29 @@ +package net.gepafin.tendermanagement.model.util; + +import com.fasterxml.jackson.annotation.JsonIgnoreProperties; +import lombok.AllArgsConstructor; +import lombok.Getter; +import lombok.NoArgsConstructor; +import lombok.Setter; +import net.gepafin.tendermanagement.web.rest.api.errors.Status; + +import java.io.Serializable; + +/** + * A generic response class used for API responses. + * + * @param the type of the response data + */ +@JsonIgnoreProperties(ignoreUnknown = true) +@Getter +@Setter +@AllArgsConstructor +@NoArgsConstructor +public class Response implements Serializable { + + private static final long serialVersionUID = 1L; + + private T data; // The response data + private Status status; // The status of the response + private String message; // Additional message or error description +} diff --git a/src/main/java/net/gepafin/tendermanagement/repositories/RegionRepository.java b/src/main/java/net/gepafin/tendermanagement/repositories/RegionRepository.java new file mode 100644 index 00000000..87dfdfa0 --- /dev/null +++ b/src/main/java/net/gepafin/tendermanagement/repositories/RegionRepository.java @@ -0,0 +1,9 @@ +package net.gepafin.tendermanagement.repositories; + +import net.gepafin.tendermanagement.entities.RegionEntity; +import org.springframework.data.jpa.repository.JpaRepository; +import org.springframework.stereotype.Repository; + +@Repository +public interface RegionRepository extends JpaRepository { +} diff --git a/src/main/java/net/gepafin/tendermanagement/repositories/RoleRepository.java b/src/main/java/net/gepafin/tendermanagement/repositories/RoleRepository.java new file mode 100644 index 00000000..e009e6a3 --- /dev/null +++ b/src/main/java/net/gepafin/tendermanagement/repositories/RoleRepository.java @@ -0,0 +1,9 @@ +package net.gepafin.tendermanagement.repositories; + +import net.gepafin.tendermanagement.entities.RoleEntity; +import org.springframework.data.jpa.repository.JpaRepository; +import org.springframework.stereotype.Repository; + +@Repository +public interface RoleRepository extends JpaRepository { +} diff --git a/src/main/java/net/gepafin/tendermanagement/repositories/UserRepository.java b/src/main/java/net/gepafin/tendermanagement/repositories/UserRepository.java new file mode 100644 index 00000000..2fdee718 --- /dev/null +++ b/src/main/java/net/gepafin/tendermanagement/repositories/UserRepository.java @@ -0,0 +1,9 @@ +package net.gepafin.tendermanagement.repositories; + +import net.gepafin.tendermanagement.entities.UserEntity; +import org.springframework.data.jpa.repository.JpaRepository; + +import java.util.Optional; + +public interface UserRepository extends JpaRepository { +} diff --git a/src/main/java/net/gepafin/tendermanagement/service/RegionService.java b/src/main/java/net/gepafin/tendermanagement/service/RegionService.java new file mode 100644 index 00000000..2288fa17 --- /dev/null +++ b/src/main/java/net/gepafin/tendermanagement/service/RegionService.java @@ -0,0 +1,22 @@ +package net.gepafin.tendermanagement.service; + +import net.gepafin.tendermanagement.entities.RegionEntity; +import net.gepafin.tendermanagement.model.request.RegionReq; +import net.gepafin.tendermanagement.model.response.RegionResponseBean; +import net.gepafin.tendermanagement.model.request.UpdateRegionReq; + +import java.util.List; + + +public interface RegionService { + + RegionResponseBean createRegion(RegionReq regionReq); + + RegionResponseBean updateRegion(Long regionId, RegionReq regionReq); + + RegionEntity getRegionById(Long regionId); + + void deleteRegion(Long regionId); + + List getAllRegions(); +} diff --git a/src/main/java/net/gepafin/tendermanagement/service/RoleService.java b/src/main/java/net/gepafin/tendermanagement/service/RoleService.java new file mode 100644 index 00000000..448197b4 --- /dev/null +++ b/src/main/java/net/gepafin/tendermanagement/service/RoleService.java @@ -0,0 +1,19 @@ +package net.gepafin.tendermanagement.service; + +import net.gepafin.tendermanagement.entities.RoleEntity; +import net.gepafin.tendermanagement.model.request.RoleReq; +import net.gepafin.tendermanagement.model.response.RoleResponseBean; + +import java.util.List; + +public interface RoleService { + RoleResponseBean createRole(RoleReq roleReq); + + RoleResponseBean updateRole(Long roleId, RoleReq roleReq); + + RoleEntity getRoleById(Long roleId); + + void deleteRole(Long roleId); + + List getAllRoles(); +} diff --git a/src/main/java/net/gepafin/tendermanagement/service/UserService.java b/src/main/java/net/gepafin/tendermanagement/service/UserService.java new file mode 100644 index 00000000..71faf129 --- /dev/null +++ b/src/main/java/net/gepafin/tendermanagement/service/UserService.java @@ -0,0 +1,12 @@ +package net.gepafin.tendermanagement.service; + +import net.gepafin.tendermanagement.model.request.UpdateUserReq; +import net.gepafin.tendermanagement.model.request.UserReq; +import net.gepafin.tendermanagement.model.response.UserResponseBean; + +public interface UserService { + UserResponseBean createUser(UserReq userReq); + UserResponseBean updateUser(Long userId, UpdateUserReq userReq); + UserResponseBean getUserById(Long userId); + void deleteUser(Long userId); +} diff --git a/src/main/java/net/gepafin/tendermanagement/service/impl/RegionServiceImpl.java b/src/main/java/net/gepafin/tendermanagement/service/impl/RegionServiceImpl.java new file mode 100644 index 00000000..63921ef1 --- /dev/null +++ b/src/main/java/net/gepafin/tendermanagement/service/impl/RegionServiceImpl.java @@ -0,0 +1,43 @@ +package net.gepafin.tendermanagement.service.impl; + +import java.util.List; + +import net.gepafin.tendermanagement.dao.RegionDao; +import net.gepafin.tendermanagement.entities.RegionEntity; +import net.gepafin.tendermanagement.model.request.RegionReq; +import net.gepafin.tendermanagement.model.response.RegionResponseBean; +import net.gepafin.tendermanagement.model.request.UpdateRegionReq; +import net.gepafin.tendermanagement.service.RegionService; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.stereotype.Service; +@Service +public class RegionServiceImpl implements RegionService { + + @Autowired + private RegionDao regionDao; + + @Override + public RegionResponseBean createRegion(RegionReq regionReq) { + return regionDao.createRegion(regionReq); + } + + @Override + public RegionResponseBean updateRegion(Long regionId, RegionReq regionReq) { + return regionDao.updateRegion(regionId,regionReq); + } + + @Override + public RegionEntity getRegionById(Long regionId) { + return regionDao.getRegionById(regionId); + } + + @Override + public void deleteRegion(Long regionId) { + regionDao.deleteById(regionId); + } + + @Override + public List getAllRegions() { + return regionDao.getAllRegions(); + } +} diff --git a/src/main/java/net/gepafin/tendermanagement/service/impl/RoleServiceImpl.java b/src/main/java/net/gepafin/tendermanagement/service/impl/RoleServiceImpl.java new file mode 100644 index 00000000..41f3f6ba --- /dev/null +++ b/src/main/java/net/gepafin/tendermanagement/service/impl/RoleServiceImpl.java @@ -0,0 +1,44 @@ +package net.gepafin.tendermanagement.service.impl; + +import java.util.List; + +import net.gepafin.tendermanagement.dao.RoleDao; +import net.gepafin.tendermanagement.entities.RoleEntity; +import net.gepafin.tendermanagement.model.request.RoleReq; +import net.gepafin.tendermanagement.model.response.RoleResponseBean; +import net.gepafin.tendermanagement.service.RoleService; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.stereotype.Service; + + +@Service +public class RoleServiceImpl implements RoleService { + + @Autowired + private RoleDao roleDao; + + @Override + public RoleResponseBean createRole(RoleReq roleReq) { + return roleDao.createRole(roleReq); + } + @Override + public RoleResponseBean updateRole(Long roleId, RoleReq roleReq) { + return roleDao.updateRole(roleId,roleReq); + } + + @Override + public RoleEntity getRoleById(Long roleId) { + return roleDao.getRoleById(roleId); + } + + @Override + public void deleteRole(Long roleId) { + roleDao.deleteById(roleId); + } + + @Override + public List getAllRoles() { + return roleDao.getAllRoles(); + + } +} diff --git a/src/main/java/net/gepafin/tendermanagement/service/impl/UserServiceImpl.java b/src/main/java/net/gepafin/tendermanagement/service/impl/UserServiceImpl.java new file mode 100644 index 00000000..4d39ffc5 --- /dev/null +++ b/src/main/java/net/gepafin/tendermanagement/service/impl/UserServiceImpl.java @@ -0,0 +1,38 @@ +package net.gepafin.tendermanagement.service.impl; + +import net.gepafin.tendermanagement.dao.UserDao; +import net.gepafin.tendermanagement.model.request.UpdateUserReq; +import net.gepafin.tendermanagement.model.request.UserReq; +import net.gepafin.tendermanagement.model.response.UserResponseBean; +import net.gepafin.tendermanagement.service.UserService; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.stereotype.Service; + +import java.time.format.DateTimeFormatter; + +@Service +public class UserServiceImpl implements UserService { + + @Autowired + private UserDao userDao; + public UserResponseBean createUser(UserReq userReq) { + return userDao.createUser(userReq); + } + + + @Override + public UserResponseBean updateUser(Long userId, UpdateUserReq userReq) { + return userDao.updateUser(userId, userReq); + } + + @Override + public UserResponseBean getUserById(Long userId) { + return userDao.getUserById(userId); + } + + @Override + public void deleteUser(Long userId) { + userDao.deleteUser(userId); + } + +} diff --git a/src/main/java/net/gepafin/tendermanagement/util/DateTimeUtil.java b/src/main/java/net/gepafin/tendermanagement/util/DateTimeUtil.java new file mode 100644 index 00000000..ab67ccdd --- /dev/null +++ b/src/main/java/net/gepafin/tendermanagement/util/DateTimeUtil.java @@ -0,0 +1,53 @@ +package net.gepafin.tendermanagement.util; + +import org.springframework.stereotype.Component; + +import java.time.LocalDateTime; +import java.time.ZoneId; +import java.time.ZonedDateTime; +import java.util.Calendar; +import java.util.Date; + +@Component +public class DateTimeUtil { + + + public static LocalDateTime DateServerToUTC(LocalDateTime systemDate) { + + ZonedDateTime ldtZoned = systemDate.atZone(ZoneId.systemDefault()); + LocalDateTime localDatetime = ldtZoned.withZoneSameInstant(ZoneId.of("UTC")).toLocalDateTime(); + return localDatetime; + } + + public static LocalDateTime getPreviousMonthDate(int month) { + Calendar c = Calendar.getInstance(); + c.add(Calendar.MONTH, -month); + LocalDateTime conv = LocalDateTime.ofInstant(c.getTime().toInstant(), ZoneId.systemDefault()); + return conv; + } + + public static Date getDateWithoutTime(LocalDateTime systemDate) { + ZonedDateTime zdt = systemDate.atZone(ZoneId.systemDefault()); + Date date = Date.from(zdt.toInstant()); + Calendar calendar = Calendar.getInstance(); + calendar.setTime(date); + calendar.set(Calendar.HOUR_OF_DAY, 0); + calendar.set(Calendar.MINUTE, 0); + calendar.set(Calendar.SECOND, 0); + calendar.set(Calendar.MILLISECOND, 0); + return calendar.getTime(); + } + + public static LocalDateTime convertDateToLocalDateTime(Date date) { + LocalDateTime ldt = LocalDateTime.ofInstant(date.toInstant(), + ZoneId.systemDefault()); + return ldt; + } + + + public static Date convertLocalDateTimeToDateUsingInstant(LocalDateTime localDateTime) { + return Date + .from(localDateTime.atZone(ZoneId.systemDefault()) + .toInstant()); + } +} diff --git a/src/main/java/net/gepafin/tendermanagement/util/ObjectUtils.java b/src/main/java/net/gepafin/tendermanagement/util/ObjectUtils.java new file mode 100644 index 00000000..1f7d1215 --- /dev/null +++ b/src/main/java/net/gepafin/tendermanagement/util/ObjectUtils.java @@ -0,0 +1,20 @@ +package net.gepafin.tendermanagement.util; + +import java.util.function.Consumer; +import java.util.function.Supplier; + +public class ObjectUtils { + + public static void setIfNotNull(Consumer setter, T value) { + if (value != null) { + setter.accept(value); + } + } + public static void setIfUpdated(Supplier getter, Consumer setter, T newValue) { + T currentValue = getter.get(); + if (newValue != null && !newValue.equals(currentValue)) { + setter.accept(newValue); + } + } + +} diff --git a/src/main/java/net/gepafin/tendermanagement/util/Utils.java b/src/main/java/net/gepafin/tendermanagement/util/Utils.java new file mode 100644 index 00000000..aa1fe35b --- /dev/null +++ b/src/main/java/net/gepafin/tendermanagement/util/Utils.java @@ -0,0 +1,49 @@ +package net.gepafin.tendermanagement.util; + +import com.fasterxml.jackson.databind.ObjectMapper; +import com.fasterxml.jackson.databind.DeserializationFeature; +import com.fasterxml.jackson.datatype.jsr310.JavaTimeModule; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; + +import java.util.List; +import java.util.stream.Collectors; + +public class Utils { + + public static final Logger log = LoggerFactory.getLogger(Utils.class); + + private static final ObjectMapper mapper = new ObjectMapper() + .registerModule(new JavaTimeModule()) + .configure(DeserializationFeature.FAIL_ON_UNKNOWN_PROPERTIES, false); + + public static U convertObject(T source, Class destinationClass) { + try { + return mapper.convertValue(source, destinationClass); + } catch (Exception e) { + log.error("Error converting object: " + e.getMessage(), e); + } + return null; + } + + public static List convertSourceListToDestinationList(List sourceList, Class destinationClass) { + try { + return sourceList.stream() + .map(source -> mapper.convertValue(source, destinationClass)) + .collect(Collectors.toList()); + } catch (Exception e) { + log.error("Error converting list: " + e.getMessage(), e); + } + return null; + } + + public static List convertSourceToList(T source, Class destinationClass) { + try { + // Convert single source object to a single-element list of destination type + return List.of(mapper.convertValue(source, destinationClass)); + } catch (Exception e) { + log.error("Error converting single object to list: " + e.getMessage(), e); + } + return null; + } +} diff --git a/src/main/java/net/gepafin/tendermanagement/web/rest/api/RegionApi.java b/src/main/java/net/gepafin/tendermanagement/web/rest/api/RegionApi.java new file mode 100644 index 00000000..3c9237a6 --- /dev/null +++ b/src/main/java/net/gepafin/tendermanagement/web/rest/api/RegionApi.java @@ -0,0 +1,91 @@ +package net.gepafin.tendermanagement.web.rest.api; + +import net.gepafin.tendermanagement.entities.RegionEntity; +import net.gepafin.tendermanagement.model.request.RegionReq; +import net.gepafin.tendermanagement.model.response.RegionResponseBean; +import net.gepafin.tendermanagement.model.request.UpdateRegionReq; +import net.gepafin.tendermanagement.model.response.RoleResponseBean; +import net.gepafin.tendermanagement.model.util.Response; +import io.swagger.v3.oas.annotations.Operation; +import io.swagger.v3.oas.annotations.media.Content; +import io.swagger.v3.oas.annotations.media.ExampleObject; +import io.swagger.v3.oas.annotations.responses.ApiResponse; +import io.swagger.v3.oas.annotations.Parameter; +import jakarta.validation.Valid; +import net.gepafin.tendermanagement.web.rest.api.errors.ErrorConstants; +import org.springframework.http.MediaType; +import org.springframework.http.ResponseEntity; +import org.springframework.validation.annotation.Validated; +import org.springframework.web.bind.annotation.*; + +import java.util.List; + +@Validated +@RequestMapping("/region") +public interface RegionApi { + + @Operation(summary = "Api to create region", + responses = { + @ApiResponse(responseCode = "200", description = "OK"), + @ApiResponse(responseCode = "404", description = "Not Found", content = @Content(mediaType = MediaType.APPLICATION_JSON_VALUE, examples = { + @ExampleObject(value = ErrorConstants.NOTFOUND_ERROR_EXAMPLE) })), + @ApiResponse(responseCode = "401", description = "Unauthorized", content = @Content(mediaType = MediaType.APPLICATION_JSON_VALUE, examples = { + @ExampleObject(value = ErrorConstants.UNAUTHORIZED_ERROR_EXAMPLE) })), + @ApiResponse(responseCode = "400", description = "Bad Request", content = @Content(mediaType = MediaType.APPLICATION_JSON_VALUE, examples = { + @ExampleObject(value = ErrorConstants.BADREQUEST_ERROR_EXAMPLE) })) }) + @PostMapping(value = "",produces = "application/json") + ResponseEntity> createRegion( + @Parameter(description = "Region request object", required = true) @Valid @RequestBody RegionReq regionReq); + + @Operation(summary = "Api to update region", + responses = { + @ApiResponse(responseCode = "200", description = "OK"), + @ApiResponse(responseCode = "404", description = "Not Found", content = @Content(mediaType = MediaType.APPLICATION_JSON_VALUE, examples = { + @ExampleObject(value = ErrorConstants.NOTFOUND_ERROR_EXAMPLE) })), + @ApiResponse(responseCode = "401", description = "Unauthorized", content = @Content(mediaType = MediaType.APPLICATION_JSON_VALUE, examples = { + @ExampleObject(value = ErrorConstants.UNAUTHORIZED_ERROR_EXAMPLE) })), + @ApiResponse(responseCode = "400", description = "Bad Request", content = @Content(mediaType = MediaType.APPLICATION_JSON_VALUE, examples = { + @ExampleObject(value = ErrorConstants.BADREQUEST_ERROR_EXAMPLE) })) }) + @PutMapping(value = "/{regionId}", produces = "application/json") + ResponseEntity> updateRegion( + @Parameter(description = "The region id", required = true) @PathVariable("regionId") Long regionId, + @Parameter(description = "Region request object", required = true) @Valid @RequestBody RegionReq regionReq); + + @Operation(summary = "Api to get a region by id", + responses = { + @ApiResponse(responseCode = "200", description = "OK"), + @ApiResponse(responseCode = "404", description = "Not Found", content = @Content(mediaType = MediaType.APPLICATION_JSON_VALUE, examples = { + @ExampleObject(value = ErrorConstants.NOTFOUND_ERROR_EXAMPLE) })), + @ApiResponse(responseCode = "401", description = "Unauthorized", content = @Content(mediaType = MediaType.APPLICATION_JSON_VALUE, examples = { + @ExampleObject(value = ErrorConstants.UNAUTHORIZED_ERROR_EXAMPLE) })), + @ApiResponse(responseCode = "400", description = "Bad Request", content = @Content(mediaType = MediaType.APPLICATION_JSON_VALUE, examples = { + @ExampleObject(value = ErrorConstants.BADREQUEST_ERROR_EXAMPLE) })) }) + @GetMapping(value = "/{regionId}", produces = "application/json") + ResponseEntity> getRegionById( + @Parameter(description = "The region id", required = true) @PathVariable("regionId") Long regionId); + + @Operation(summary = "Api to get all regions", + responses = { + @ApiResponse(responseCode = "200", description = "OK"), + @ApiResponse(responseCode = "404", description = "Not Found", content = @Content(mediaType = MediaType.APPLICATION_JSON_VALUE, examples = { + @ExampleObject(value = ErrorConstants.NOTFOUND_ERROR_EXAMPLE) })), + @ApiResponse(responseCode = "401", description = "Unauthorized", content = @Content(mediaType = MediaType.APPLICATION_JSON_VALUE, examples = { + @ExampleObject(value = ErrorConstants.UNAUTHORIZED_ERROR_EXAMPLE) })), + @ApiResponse(responseCode = "400", description = "Bad Request", content = @Content(mediaType = MediaType.APPLICATION_JSON_VALUE, examples = { + @ExampleObject(value = ErrorConstants.BADREQUEST_ERROR_EXAMPLE) })) }) + @GetMapping(value = "", + produces = { "application/json" }) + ResponseEntity>> getAllRegions(); + @Operation(summary = "Api to delete region", + responses = { + @ApiResponse(responseCode = "200", description = "OK"), + @ApiResponse(responseCode = "404", description = "Not Found", content = @Content(mediaType = MediaType.APPLICATION_JSON_VALUE, examples = { + @ExampleObject(value = ErrorConstants.NOTFOUND_ERROR_EXAMPLE) })), + @ApiResponse(responseCode = "401", description = "Unauthorized", content = @Content(mediaType = MediaType.APPLICATION_JSON_VALUE, examples = { + @ExampleObject(value = ErrorConstants.UNAUTHORIZED_ERROR_EXAMPLE) })), + @ApiResponse(responseCode = "400", description = "Bad Request", content = @Content(mediaType = MediaType.APPLICATION_JSON_VALUE, examples = { + @ExampleObject(value = ErrorConstants.BADREQUEST_ERROR_EXAMPLE) })) }) + @DeleteMapping(value = "/{regionId}") + ResponseEntity> deleteRegion( + @Parameter(description = "The region id", required = true) @PathVariable("regionId") Long regionId); +} diff --git a/src/main/java/net/gepafin/tendermanagement/web/rest/api/RoleApi.java b/src/main/java/net/gepafin/tendermanagement/web/rest/api/RoleApi.java new file mode 100644 index 00000000..2f94be9e --- /dev/null +++ b/src/main/java/net/gepafin/tendermanagement/web/rest/api/RoleApi.java @@ -0,0 +1,93 @@ +package net.gepafin.tendermanagement.web.rest.api; + +import net.gepafin.tendermanagement.entities.RoleEntity; +import net.gepafin.tendermanagement.model.request.RoleReq; +import net.gepafin.tendermanagement.model.response.RoleResponseBean; +import net.gepafin.tendermanagement.model.util.Response; +import io.swagger.v3.oas.annotations.Operation; +import io.swagger.v3.oas.annotations.media.Content; +import io.swagger.v3.oas.annotations.media.ExampleObject; +import io.swagger.v3.oas.annotations.responses.ApiResponse; +import io.swagger.v3.oas.annotations.Parameter; +import jakarta.validation.Valid; +import net.gepafin.tendermanagement.web.rest.api.errors.ErrorConstants; +import org.springframework.http.MediaType; +import org.springframework.http.ResponseEntity; +import org.springframework.validation.annotation.Validated; +import org.springframework.web.bind.annotation.*; + +import java.util.List; + +@Validated +public interface RoleApi { + + @Operation(summary = "API to create role", + responses = { + @ApiResponse(responseCode = "200", description = "OK"), + @ApiResponse(responseCode = "404", description = "Not Found", content = @Content(mediaType = MediaType.APPLICATION_JSON_VALUE, examples = { + @ExampleObject(value = ErrorConstants.NOTFOUND_ERROR_EXAMPLE) })), + @ApiResponse(responseCode = "401", description = "Unauthorized", content = @Content(mediaType = MediaType.APPLICATION_JSON_VALUE, examples = { + @ExampleObject(value = ErrorConstants.UNAUTHORIZED_ERROR_EXAMPLE) })), + @ApiResponse(responseCode = "400", description = "Bad Request", content = @Content(mediaType = MediaType.APPLICATION_JSON_VALUE, examples = { + @ExampleObject(value = ErrorConstants.BADREQUEST_ERROR_EXAMPLE) })) }) + @PostMapping(value = "", + produces = { "application/json" }) + ResponseEntity> createRole( + @Parameter(description = " Role request object", required = true) @Valid @RequestBody RoleReq roleReq); + + + @Operation(summary = "API to update role", + responses = { + @ApiResponse(responseCode = "200", description = "OK"), + @ApiResponse(responseCode = "404", description = "Not Found", content = @Content(mediaType = MediaType.APPLICATION_JSON_VALUE, examples = { + @ExampleObject(value = ErrorConstants.NOTFOUND_ERROR_EXAMPLE) })), + @ApiResponse(responseCode = "401", description = "Unauthorized", content = @Content(mediaType = MediaType.APPLICATION_JSON_VALUE, examples = { + @ExampleObject(value = ErrorConstants.UNAUTHORIZED_ERROR_EXAMPLE) })), + @ApiResponse(responseCode = "400", description = "Bad Request", content = @Content(mediaType = MediaType.APPLICATION_JSON_VALUE, examples = { + @ExampleObject(value = ErrorConstants.BADREQUEST_ERROR_EXAMPLE) })) }) + @PutMapping(value = "/{roleId}", + produces = { "application/json" }) + ResponseEntity> updateRole( + @Parameter(description = "The role ID", required = true) @PathVariable("roleId") Long roleId, + @Parameter(description = "Role request object", required = true) @Valid @RequestBody RoleReq roleReq); + + @Operation(summary = "API to get role by id", + responses = { + @ApiResponse(responseCode = "200", description = "OK"), + @ApiResponse(responseCode = "404", description = "Not Found", content = @Content(mediaType = MediaType.APPLICATION_JSON_VALUE, examples = { + @ExampleObject(value = ErrorConstants.NOTFOUND_ERROR_EXAMPLE) })), + @ApiResponse(responseCode = "401", description = "Unauthorized", content = @Content(mediaType = MediaType.APPLICATION_JSON_VALUE, examples = { + @ExampleObject(value = ErrorConstants.UNAUTHORIZED_ERROR_EXAMPLE) })), + @ApiResponse(responseCode = "400", description = "Bad Request", content = @Content(mediaType = MediaType.APPLICATION_JSON_VALUE, examples = { + @ExampleObject(value = ErrorConstants.BADREQUEST_ERROR_EXAMPLE) })) }) + @GetMapping(value = "/{roleId}", + produces = { "application/json" }) + ResponseEntity> getRoleById( + @Parameter(description = "The role ID", required = true) @PathVariable("roleId") Long roleId); + + @Operation(summary = "API to get all roles", + responses = { + @ApiResponse(responseCode = "200", description = "OK"), + @ApiResponse(responseCode = "404", description = "Not Found", content = @Content(mediaType = MediaType.APPLICATION_JSON_VALUE, examples = { + @ExampleObject(value = ErrorConstants.NOTFOUND_ERROR_EXAMPLE) })), + @ApiResponse(responseCode = "401", description = "Unauthorized", content = @Content(mediaType = MediaType.APPLICATION_JSON_VALUE, examples = { + @ExampleObject(value = ErrorConstants.UNAUTHORIZED_ERROR_EXAMPLE) })), + @ApiResponse(responseCode = "400", description = "Bad Request", content = @Content(mediaType = MediaType.APPLICATION_JSON_VALUE, examples = { + @ExampleObject(value = ErrorConstants.BADREQUEST_ERROR_EXAMPLE) })) }) + @GetMapping(value = "", + produces = { "application/json" }) + ResponseEntity>> getAllRoles(); + + @Operation(summary = "API to delete role", + responses = { + @ApiResponse(responseCode = "200", description = "OK"), + @ApiResponse(responseCode = "404", description = "Not Found", content = @Content(mediaType = MediaType.APPLICATION_JSON_VALUE, examples = { + @ExampleObject(value = ErrorConstants.NOTFOUND_ERROR_EXAMPLE) })), + @ApiResponse(responseCode = "401", description = "Unauthorized", content = @Content(mediaType = MediaType.APPLICATION_JSON_VALUE, examples = { + @ExampleObject(value = ErrorConstants.UNAUTHORIZED_ERROR_EXAMPLE) })), + @ApiResponse(responseCode = "400", description = "Bad Request", content = @Content(mediaType = MediaType.APPLICATION_JSON_VALUE, examples = { + @ExampleObject(value = ErrorConstants.BADREQUEST_ERROR_EXAMPLE) })) }) + @DeleteMapping(value = "/{roleId}") + ResponseEntity> deleteRole( + @Parameter(description = "The role ID", required = true) @PathVariable("roleId") Long roleId); +} diff --git a/src/main/java/net/gepafin/tendermanagement/web/rest/api/UserApi.java b/src/main/java/net/gepafin/tendermanagement/web/rest/api/UserApi.java index e1e0f29a..3c9eadc6 100644 --- a/src/main/java/net/gepafin/tendermanagement/web/rest/api/UserApi.java +++ b/src/main/java/net/gepafin/tendermanagement/web/rest/api/UserApi.java @@ -1,8 +1,94 @@ package net.gepafin.tendermanagement.web.rest.api; -import net.gepafin.tendermanagement.model.User; -import org.springframework.web.bind.annotation.GetMapping; +import io.swagger.v3.oas.annotations.Parameter; +import io.swagger.v3.oas.annotations.Operation; +import io.swagger.v3.oas.annotations.media.Content; +import io.swagger.v3.oas.annotations.media.ExampleObject; +import io.swagger.v3.oas.annotations.responses.ApiResponse; +import jakarta.validation.Valid; +import net.gepafin.tendermanagement.model.request.UpdateUserReq; +import net.gepafin.tendermanagement.model.request.UserReq; +import net.gepafin.tendermanagement.model.response.UserResponseBean; +import net.gepafin.tendermanagement.model.util.Response; +import net.gepafin.tendermanagement.web.rest.api.errors.ErrorConstants; +import org.springframework.http.HttpStatus; +import org.springframework.http.MediaType; +import org.springframework.http.ResponseEntity; +import org.springframework.validation.annotation.Validated; +import org.springframework.web.bind.annotation.PathVariable; +import org.springframework.web.bind.annotation.RequestBody; +import org.springframework.web.bind.annotation.RequestMapping; +import org.springframework.web.bind.annotation.RequestMethod; + +@Validated +//@RequestMapping("/user") public interface UserApi { - @GetMapping("") - User getUser(); + + @Operation(summary = "Api to create user", + responses = { + @ApiResponse(responseCode = "200", description = "OK"), + @ApiResponse(responseCode = "404", description = "Not Found", content = @Content(mediaType = MediaType.APPLICATION_JSON_VALUE, examples = { + @ExampleObject(value = ErrorConstants.NOTFOUND_ERROR_EXAMPLE) })), + @ApiResponse(responseCode = "401", description = "Unauthorized", content = @Content(mediaType = MediaType.APPLICATION_JSON_VALUE, examples = { + @ExampleObject(value = ErrorConstants.UNAUTHORIZED_ERROR_EXAMPLE) })), + @ApiResponse(responseCode = "400", description = "Bad Request", content = @Content(mediaType = MediaType.APPLICATION_JSON_VALUE, examples = { + @ExampleObject(value = ErrorConstants.BADREQUEST_ERROR_EXAMPLE) })) }) + @RequestMapping(value = "", + produces = { "application/json" }, + method = RequestMethod.POST) + default ResponseEntity> createUser( + @Parameter(description = "User request object", required = true) @Valid @RequestBody UserReq userReq) { + return new ResponseEntity>(HttpStatus.NOT_IMPLEMENTED); + } + + @Operation(summary = "Api to update user", + responses = { + @ApiResponse(responseCode = "200", description = "OK"), + @ApiResponse(responseCode = "404", description = "Not Found", content = @Content(mediaType = MediaType.APPLICATION_JSON_VALUE, examples = { + @ExampleObject(value = ErrorConstants.NOTFOUND_ERROR_EXAMPLE) })), + @ApiResponse(responseCode = "401", description = "Unauthorized", content = @Content(mediaType = MediaType.APPLICATION_JSON_VALUE, examples = { + @ExampleObject(value = ErrorConstants.UNAUTHORIZED_ERROR_EXAMPLE) })), + @ApiResponse(responseCode = "400", description = "Bad Request", content = @Content(mediaType = MediaType.APPLICATION_JSON_VALUE, examples = { + @ExampleObject(value = ErrorConstants.BADREQUEST_ERROR_EXAMPLE) })) }) + @RequestMapping(value = "/{userId}", + produces = { "application/json" }, + method = RequestMethod.PUT) + default ResponseEntity> updateUser( + @Parameter(description = "The user id", required = true) @PathVariable("userId") Long userId, + @Parameter(description = "User request object", required = true) @Valid @RequestBody UpdateUserReq userReq) { + return new ResponseEntity<>(HttpStatus.NOT_IMPLEMENTED); + } + + @Operation(summary = "Api to get user by id", + responses = { + @ApiResponse(responseCode = "200", description = "OK"), + @ApiResponse(responseCode = "404", description = "Not Found", content = @Content(mediaType = MediaType.APPLICATION_JSON_VALUE, examples = { + @ExampleObject(value = ErrorConstants.NOTFOUND_ERROR_EXAMPLE) })), + @ApiResponse(responseCode = "401", description = "Unauthorized", content = @Content(mediaType = MediaType.APPLICATION_JSON_VALUE, examples = { + @ExampleObject(value = ErrorConstants.UNAUTHORIZED_ERROR_EXAMPLE) })), + @ApiResponse(responseCode = "400", description = "Bad Request", content = @Content(mediaType = MediaType.APPLICATION_JSON_VALUE, examples = { + @ExampleObject(value = ErrorConstants.BADREQUEST_ERROR_EXAMPLE) })) }) + @RequestMapping(value = "/{userId}", + produces = { "application/json" }, + method = RequestMethod.GET) + default ResponseEntity> getUserById( + @Parameter(description = "The user id", required = true) @PathVariable("userId") Long userId) { + return new ResponseEntity<>(HttpStatus.NOT_IMPLEMENTED); + } + + @Operation(summary = "Api to delete user", + responses = { + @ApiResponse(responseCode = "200", description = "OK"), + @ApiResponse(responseCode = "404", description = "Not Found", content = @Content(mediaType = MediaType.APPLICATION_JSON_VALUE, examples = { + @ExampleObject(value = ErrorConstants.NOTFOUND_ERROR_EXAMPLE) })), + @ApiResponse(responseCode = "401", description = "Unauthorized", content = @Content(mediaType = MediaType.APPLICATION_JSON_VALUE, examples = { + @ExampleObject(value = ErrorConstants.UNAUTHORIZED_ERROR_EXAMPLE) })), + @ApiResponse(responseCode = "400", description = "Bad Request", content = @Content(mediaType = MediaType.APPLICATION_JSON_VALUE, examples = { + @ExampleObject(value = ErrorConstants.BADREQUEST_ERROR_EXAMPLE) })) }) + @RequestMapping(value = "/{userId}", + method = RequestMethod.DELETE) + default ResponseEntity> deleteUser( + @Parameter(description = "The user id", required = true) @PathVariable("userId") Long userId) { + return new ResponseEntity<>(HttpStatus.NOT_IMPLEMENTED); + } } diff --git a/src/main/java/net/gepafin/tendermanagement/web/rest/api/errors/CustomValidationException.java b/src/main/java/net/gepafin/tendermanagement/web/rest/api/errors/CustomValidationException.java new file mode 100644 index 00000000..197a4e2b --- /dev/null +++ b/src/main/java/net/gepafin/tendermanagement/web/rest/api/errors/CustomValidationException.java @@ -0,0 +1,16 @@ +package net.gepafin.tendermanagement.web.rest.api.errors; + +public class CustomValidationException extends RuntimeException { + + private final Status status; + private static final long serialVersionUID = 1L; + + public Status getStatus() { + return status; + } + + public CustomValidationException(Status status, String message) { + super(message); + this.status = status; + } +} diff --git a/src/main/java/net/gepafin/tendermanagement/web/rest/api/errors/ErrorConstants.java b/src/main/java/net/gepafin/tendermanagement/web/rest/api/errors/ErrorConstants.java new file mode 100644 index 00000000..d48defba --- /dev/null +++ b/src/main/java/net/gepafin/tendermanagement/web/rest/api/errors/ErrorConstants.java @@ -0,0 +1,28 @@ +package net.gepafin.tendermanagement.web.rest.api.errors; + +import java.net.URI; + +public final class ErrorConstants { + + public static final String ERR_CONCURRENCY_FAILURE = "error.concurrencyFailure"; + public static final String ERR_VALIDATION = "error.validation"; + public static final String PROBLEM_BASE_URL = "https://www.jhipster.tech/problem"; + public static final URI DEFAULT_TYPE = URI.create(PROBLEM_BASE_URL + "/problem-with-message"); + public static final URI CONSTRAINT_VIOLATION_TYPE = URI.create(PROBLEM_BASE_URL + "/constraint-violation"); + public static final URI INVALID_PASSWORD_TYPE = URI.create(PROBLEM_BASE_URL + "/invalid-password"); + public static final URI EMAIL_ALREADY_USED_TYPE = URI.create(PROBLEM_BASE_URL + "/email-already-used"); + public static final URI LOGIN_ALREADY_USED_TYPE = URI.create(PROBLEM_BASE_URL + "/login-already-used"); + + public static final String BADREQUEST_ERROR_EXAMPLE="{\"data\": null," + +"\"status\": \"VALIDATION_ERROR\",\"message\": \"string\"" + + "}"; + public static final String NOTFOUND_ERROR_EXAMPLE="{\"data\": null," + +"\"status\": \"NOT_FOUND\",\"message\": \"string\"" + + "}"; + public static final String UNAUTHORIZED_ERROR_EXAMPLE="{\"data\": null," + +"\"status\": \"UNAUTHORIZED\",\"message\": \"string\"" + + "}"; + + private ErrorConstants() { + } +} diff --git a/src/main/java/net/gepafin/tendermanagement/web/rest/api/errors/ResourceNotFoundException.java b/src/main/java/net/gepafin/tendermanagement/web/rest/api/errors/ResourceNotFoundException.java new file mode 100644 index 00000000..bdc1bcc0 --- /dev/null +++ b/src/main/java/net/gepafin/tendermanagement/web/rest/api/errors/ResourceNotFoundException.java @@ -0,0 +1,23 @@ +package net.gepafin.tendermanagement.web.rest.api.errors; + +import org.springframework.http.HttpStatus; +import org.springframework.web.bind.annotation.ResponseStatus; + +@ResponseStatus(value = HttpStatus.NOT_FOUND) +public class ResourceNotFoundException extends RuntimeException { + + /** + * + */ + private static final long serialVersionUID = 1L; +private final Status status; + + public ResourceNotFoundException(Status status, String message) { + super(message); + this.status = status; + } + + public Status getStatus() { + return status; + } +} \ No newline at end of file diff --git a/src/main/java/net/gepafin/tendermanagement/web/rest/api/errors/Status.java b/src/main/java/net/gepafin/tendermanagement/web/rest/api/errors/Status.java new file mode 100644 index 00000000..dc713f3e --- /dev/null +++ b/src/main/java/net/gepafin/tendermanagement/web/rest/api/errors/Status.java @@ -0,0 +1,16 @@ +package net.gepafin.tendermanagement.web.rest.api.errors; + +public enum Status { + SUCCESS("1"), VALIDATION_ERROR("2"), EXCEPTION_ERROR("3") , NOT_FOUND("4") , BAD_REQUEST("5") , UNAUTHORIZED("6") , + FORBIDDEN("7"), VALIDATION_COMPLETED("8"); + + private String action; + + public String getAction() { + return this.action; + } + + private Status(String action) { + this.action = action; + } +} diff --git a/src/main/java/net/gepafin/tendermanagement/web/rest/api/impl/RegionApiController.java b/src/main/java/net/gepafin/tendermanagement/web/rest/api/impl/RegionApiController.java new file mode 100644 index 00000000..e7387562 --- /dev/null +++ b/src/main/java/net/gepafin/tendermanagement/web/rest/api/impl/RegionApiController.java @@ -0,0 +1,79 @@ +package net.gepafin.tendermanagement.web.rest.api.impl; + +import jakarta.validation.Valid; +import net.gepafin.tendermanagement.config.Translator; +import net.gepafin.tendermanagement.constants.GepafinConstant; +import net.gepafin.tendermanagement.entities.RegionEntity; +import net.gepafin.tendermanagement.model.request.RegionReq; +import net.gepafin.tendermanagement.model.response.RegionResponseBean; +import net.gepafin.tendermanagement.model.request.UpdateRegionReq; +import net.gepafin.tendermanagement.model.util.Response; +import net.gepafin.tendermanagement.service.RegionService; +import net.gepafin.tendermanagement.web.rest.api.RegionApi; +import net.gepafin.tendermanagement.web.rest.api.errors.Status; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.http.HttpStatus; +import org.springframework.http.ResponseEntity; +import org.springframework.web.bind.annotation.PathVariable; +import org.springframework.web.bind.annotation.RequestBody; +import org.springframework.web.bind.annotation.RequestMapping; +import org.springframework.web.bind.annotation.RestController; + +import java.util.List; + +@RestController +@RequestMapping("${openapi.gepafin.base-path:/v1/region}") +public class RegionApiController implements RegionApi { + + private final Logger log = LoggerFactory.getLogger(RegionApiController.class); + + @Autowired + private RegionService regionService; + + @Override + public ResponseEntity> createRegion( + @Valid @RequestBody RegionReq regionReq) { + log.info("Create Region - Request Body: {}", regionReq); + RegionResponseBean createdRegion = regionService.createRegion(regionReq); + return ResponseEntity.status(HttpStatus.CREATED) + .body(new Response<>(createdRegion, Status.SUCCESS, Translator.toLocale(GepafinConstant.REGION_CREATED_SUCCESS_MSG))); + } + + @Override + public ResponseEntity> updateRegion( + @PathVariable("regionId") Long regionId, + @Valid @RequestBody RegionReq regionReq) { + log.info("Update Region - Region ID: {}, Request Body: {}", regionId, regionReq); + RegionResponseBean updatedRegion = regionService.updateRegion(regionId, regionReq); + return ResponseEntity.status(HttpStatus.OK) + .body(new Response<>(updatedRegion, Status.SUCCESS, Translator.toLocale(GepafinConstant.REGION_UPDATED_SUCCESS_MSG))); + } + + @Override + public ResponseEntity> getRegionById( + @PathVariable("regionId") Long regionId) { + log.info("Get Region by ID - Region ID: {}", regionId); + RegionEntity region = regionService.getRegionById(regionId); + return ResponseEntity.status(HttpStatus.OK) + .body(new Response<>(region, Status.SUCCESS, Translator.toLocale(GepafinConstant.GET_REGION_SUCCESS_MSG))); + } + + @Override + public ResponseEntity> deleteRegion( + @PathVariable("regionId") Long regionId) { + log.info("Delete Region - Region ID: {}", regionId); + regionService.deleteRegion(regionId); + return ResponseEntity.status(HttpStatus.OK) + .body(new Response<>(null, Status.SUCCESS, Translator.toLocale(GepafinConstant.DELETE_REGION_SUCCESS_MSG))); + } + @Override + public ResponseEntity>> getAllRegions() { + List regions = regionService.getAllRegions(); + log.info("Get All Region"); + regionService.getAllRegions(); + return ResponseEntity.status(HttpStatus.OK) + .body(new Response<>(regions, Status.SUCCESS, Translator.toLocale(GepafinConstant.GET_REGION_SUCCESS_MSG))); + } +} diff --git a/src/main/java/net/gepafin/tendermanagement/web/rest/api/impl/RoleApiController.java b/src/main/java/net/gepafin/tendermanagement/web/rest/api/impl/RoleApiController.java new file mode 100644 index 00000000..a720bf3c --- /dev/null +++ b/src/main/java/net/gepafin/tendermanagement/web/rest/api/impl/RoleApiController.java @@ -0,0 +1,75 @@ +package net.gepafin.tendermanagement.web.rest.api.impl; + +import java.util.List; + +import net.gepafin.tendermanagement.config.Translator; +import net.gepafin.tendermanagement.constants.GepafinConstant; +import net.gepafin.tendermanagement.entities.RoleEntity; +import net.gepafin.tendermanagement.model.request.RoleReq; +import net.gepafin.tendermanagement.model.response.RoleResponseBean; +import net.gepafin.tendermanagement.model.util.Response; +import net.gepafin.tendermanagement.service.RoleService; +import net.gepafin.tendermanagement.web.rest.api.RoleApi; +import net.gepafin.tendermanagement.web.rest.api.errors.Status; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.http.HttpStatus; +import org.springframework.http.ResponseEntity; +import org.springframework.web.bind.annotation.RequestMapping; +import org.springframework.web.bind.annotation.RestController; + +@RestController +@RequestMapping("${openapi.gepafin.base-path:/v1/role}") +public class RoleApiController implements RoleApi { + + private static final Logger log = LoggerFactory.getLogger(RoleApiController.class); + + @Autowired + private RoleService roleService; + @Override + public ResponseEntity> createRole(RoleReq body) { + log.info("Create Role - Request Body: {}", body); + RoleResponseBean roleReq = roleService.createRole(body); + + return ResponseEntity.status(HttpStatus.CREATED) + .body(new Response<>(roleReq, Status.SUCCESS, Translator.toLocale(GepafinConstant.ROLE_CREATED_SUCCESS_MSG))); + + } + + @Override + public ResponseEntity> updateRole(Long roleId, RoleReq body) { + log.info("Update Role - Role ID: {}, Request Body: {}", roleId, body); + RoleResponseBean updatedUserRole = roleService.updateRole(roleId, body); + + return ResponseEntity.status(HttpStatus.OK) + .body(new Response<>(updatedUserRole, Status.SUCCESS, Translator.toLocale(GepafinConstant.ROLE_UPDATED_SUCCESS_MSG))); + } + + @Override + public ResponseEntity>> getAllRoles() { + log.info("Get All Roles"); + List roles = roleService.getAllRoles(); + + return ResponseEntity.status(HttpStatus.OK) + .body(new Response<>(roles, Status.SUCCESS, Translator.toLocale(GepafinConstant.ROLE_FETCH_SUCCESS_MSG))); + + } + + @Override + public ResponseEntity> getRoleById(Long roleId) { + log.info("Get Role by ID - Role ID: {}", roleId); + RoleEntity roleEntity = roleService.getRoleById(roleId); + return ResponseEntity.status(HttpStatus.OK) + .body(new Response<>(roleEntity, Status.SUCCESS, Translator.toLocale(GepafinConstant.ROLE_FETCH_SUCCESS_MSG))); + } + + @Override + public ResponseEntity> deleteRole(Long roleId) { + log.info("Delete Role - Role ID: {}", roleId); + roleService.deleteRole(roleId); + + return ResponseEntity.status(HttpStatus.NO_CONTENT) + .body(new Response<>(null, Status.SUCCESS, Translator.toLocale(GepafinConstant.ROLE_DELETED_SUCCESS_MSG))); + } +} diff --git a/src/main/java/net/gepafin/tendermanagement/web/rest/api/impl/UserApiController.java b/src/main/java/net/gepafin/tendermanagement/web/rest/api/impl/UserApiController.java index 4dbd4107..ad169e42 100644 --- a/src/main/java/net/gepafin/tendermanagement/web/rest/api/impl/UserApiController.java +++ b/src/main/java/net/gepafin/tendermanagement/web/rest/api/impl/UserApiController.java @@ -1,18 +1,72 @@ package net.gepafin.tendermanagement.web.rest.api.impl; -import net.gepafin.tendermanagement.model.User; +import jakarta.validation.Valid; +import net.gepafin.tendermanagement.config.Translator; +import net.gepafin.tendermanagement.constants.GepafinConstant; +import net.gepafin.tendermanagement.model.request.UpdateUserReq; +import net.gepafin.tendermanagement.model.request.UserReq; +import net.gepafin.tendermanagement.model.response.UserResponseBean; +import net.gepafin.tendermanagement.model.util.Response; +import net.gepafin.tendermanagement.service.UserService; import net.gepafin.tendermanagement.web.rest.api.UserApi; -import org.springframework.web.bind.annotation.RequestMapping; -import org.springframework.web.bind.annotation.RestController; +import net.gepafin.tendermanagement.web.rest.api.errors.Status; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.http.HttpStatus; +import org.springframework.http.ResponseEntity; +import org.springframework.validation.annotation.Validated; +import org.springframework.web.bind.annotation.*; @RestController -@RequestMapping("/v1/user") -public class UserApiController implements UserApi -{ +@RequestMapping("${openapi.gepafin.base-path:/v1/user}") +public class UserApiController implements UserApi { + + private final Logger log = LoggerFactory.getLogger(UserApiController.class); + + @Autowired + private UserService userService; @Override - public User getUser() { - return new User(1L, "John Doe", "john.doe@test.test"); + public ResponseEntity> createUser( + @Valid @RequestBody UserReq userReq) { + log.info("Create User with - Request Body: {}", userReq); + UserResponseBean createdUser = userService.createUser(userReq); + return ResponseEntity.status(HttpStatus.CREATED) + .body(new Response<>(createdUser, Status.SUCCESS, Translator.toLocale(GepafinConstant.USER_CREATED_SUCCESS_MSG))); + } + + @Override + public ResponseEntity> updateUser( + @PathVariable("userId") Long userId, + @Valid @RequestBody UpdateUserReq userReq) { + log.info("Update User - User ID: {}, Request Body: {}", userId, userReq); + UserResponseBean updatedUser = userService.updateUser(userId, userReq); + + return ResponseEntity.status(HttpStatus.OK) + .body(new Response<>(updatedUser, Status.SUCCESS, Translator.toLocale(GepafinConstant.USER_UPDATED_SUCCESS_MSG))); + + } + + @Override + public ResponseEntity> getUserById( + @PathVariable("userId") Long userId) { + log.info("Get User by ID - User ID: {}", userId); + UserResponseBean user = userService.getUserById(userId); + return ResponseEntity.status(HttpStatus.OK) + .body(new Response<>(user, Status.SUCCESS, Translator.toLocale(GepafinConstant.GET_USER_SUCCESS_MSG))); + + } + + @Override + public ResponseEntity> deleteUser( + @PathVariable("userId") Long userId) { + log.info("Delete User By- User ID: {}", userId); + userService.deleteUser(userId); + + return ResponseEntity.status(HttpStatus.OK) + .body(new Response<>(null, Status.SUCCESS, Translator.toLocale(GepafinConstant.USER_DELETED_SUCCESS_MSG))); + } } diff --git a/src/main/resources/application.properties b/src/main/resources/application.properties index 9aa841e8..9126bd0a 100644 --- a/src/main/resources/application.properties +++ b/src/main/resources/application.properties @@ -1,3 +1,26 @@ spring.application.name=tendermanagement -server.port=8080 +springdoc.api-docs.path=/v1/api-docs +springdoc.swagger-ui.configUrl=/v1/api-docs +springfox.documentation.swagger-ui.path=/v1/api-docs +springdoc.swagger-ui.disable-swagger-default-url=true +springdoc.swagger-ui.path=/swagger-ui.html +# DataSource Configuration +spring.datasource.url=jdbc:postgresql://localhost:5432/gepafin_local +spring.datasource.username=postgres +spring.datasource.password=root +spring.datasource.driver-class-name=org.postgresql.Driver + +# JPA Configuration +spring.jpa.properties.hibernate.default_schema=gepafin_schema +spring.jpa.hibernate.ddl-auto=none + + +# Liquibase Configuration +spring.liquibase.change-log=classpath:db/changelog/db.changelog-master.xml +spring.liquibase.default-schema=gepafin_schema +spring.liquibase.enabled=true + +# Debugging and SQL Output +logging.level.org.springframework.boot.autoconfigure.liquibase=ERROR +logging.level.liquibase=ERROR \ No newline at end of file diff --git a/src/main/resources/db/changelog/db.changelog-1.0.0.xml b/src/main/resources/db/changelog/db.changelog-1.0.0.xml new file mode 100644 index 00000000..20506096 --- /dev/null +++ b/src/main/resources/db/changelog/db.changelog-1.0.0.xml @@ -0,0 +1,137 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/src/main/resources/db/changelog/db.changelog-master.xml b/src/main/resources/db/changelog/db.changelog-master.xml new file mode 100644 index 00000000..f44695c7 --- /dev/null +++ b/src/main/resources/db/changelog/db.changelog-master.xml @@ -0,0 +1,8 @@ + + + + + diff --git a/src/main/resources/message_en.properties b/src/main/resources/message_en.properties new file mode 100644 index 00000000..bdbcf92b --- /dev/null +++ b/src/main/resources/message_en.properties @@ -0,0 +1,29 @@ +user.created.success=User created successfully. +user.updated.success=User updated successfully. +user.deleted.success=User deleted successfully. +user.not.found=User not found. +create_user_error_msg=An error occurred while creating the user. +update_user_error_msg=An error occurred while updating the user. +delete_user_error_msg=An error occurred while deleting the user. +get_user_success_msg=User retrieved successfully. +get_user_error_msg=An error occurred while retrieving the user. +# Role-related messages +role.created.success=Role created successfully. +role.updated.success=Role updated successfully. +role.deleted.success=Role deleted successfully. +role.not.found=Role not found. +create.role.error=Error occurred while creating the role. +update.role.error=Error occurred while updating the role. +role.fetch.success=Role fetched successfully. +delete.role.error=Error occurred while deleting the role. + +# Region-related messages +region.created.success=Region created successfully. +region.updated.success=Region updated successfully. +get.region.success=Region fetched successfully. +delete.region.success=Region deleted successfully. +user.region.not.found=Region not found. +create.regiom.error=Error occurred while creating the region. +update.region.error=Error occurred while updating the region. +password.doesnt.match=Password and confirm password do not match. + diff --git a/src/main/resources/message_it.properties b/src/main/resources/message_it.properties new file mode 100644 index 00000000..bfd0d8f3 --- /dev/null +++ b/src/main/resources/message_it.properties @@ -0,0 +1,28 @@ +user.created.success=Utente creato con successo. +user.updated.success=Utente aggiornato con successo. +user.deleted.success=Utente eliminato con successo. +user.not.found=Utente non trovato. +create_user_error_msg=Si è verificato un errore durante la creazione dell'utente. +update_user_error_msg=Si è verificato un errore durante l'aggiornamento dell'utente. +delete_user_error_msg=Si è verificato un errore durante l'eliminazione dell'utente. +get_user_success_msg=Utente recuperato con successo. +get_user_error_msg=Si è verificato un errore durante il recupero dell'utente. +# Role-related messages +role.created.success=Ruolo creato con successo. +role.updated.success=Ruolo aggiornato con successo. +role.deleted.success=Ruolo eliminato con successo. +role.not.found=Ruolo non trovato. +create.role.error=Errore durante la creazione del ruolo. +update.role.error=Errore durante l'aggiornamento del ruolo. +role.fetch.success=Ruolo recuperato con successo. +delete.role.error=Errore durante l'eliminazione del ruolo. + +# Region-related messages +region.created.success=Regione creata con successo. +region.updated.success=Regione aggiornata con successo. +get.region.success=Regione recuperata con successo. +delete.region.success=Regione eliminata con successo. +user.region.not.found=Regione non trovata. +create.regiom.error=Errore durante la creazione della regione. +update.region.error=Errore durante l'aggiornamento della regione. +password.doesnt.match=La password e la conferma della password non corrispondono. diff --git a/target/classes/application.properties b/target/classes/application.properties deleted file mode 100644 index 9aa841e8..00000000 --- a/target/classes/application.properties +++ /dev/null @@ -1,3 +0,0 @@ -spring.application.name=tendermanagement -server.port=8080 -