Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
62 changes: 39 additions & 23 deletions src/main/java/com/example/spring/app/company/CompanyController.java
Original file line number Diff line number Diff line change
Expand Up @@ -4,11 +4,12 @@
import com.example.spring.app.company.dto.CompanyDetails;
import com.example.spring.app.company.dto.CompanyDtoWithStatusDTO;
import com.example.spring.app.company.dto.CompanyFilterRequest;
import com.example.spring.app.company.enums.Status;
import com.example.spring.app.userCompanyStatus.UserCompanyStatusModel;
import com.example.spring.app.userCompanyStatus.UserCompanyStatusService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.domain.*;
import org.springframework.http.HttpStatus;
import org.springframework.http.ResponseEntity;
import org.springframework.web.bind.annotation.*;
import org.springframework.web.server.ResponseStatusException;

Expand All @@ -20,17 +21,28 @@

@CrossOrigin
@RestController
@RequestMapping("/v1/company")
@RequestMapping("/v1/companies")
public class CompanyController {

@Autowired
private CompanyService companyService;
private final CompanyService companyService;
private final UserCompanyStatusService userCompanyStatusService;

@Autowired
private UserCompanyStatusService userCompanyStatusService;
public CompanyController(CompanyService companyService,
UserCompanyStatusService userCompanyStatusService) {
this.companyService = companyService;
this.userCompanyStatusService = userCompanyStatusService;
}

// Example: http://localhost:8080/api/v1/company/search-by-name?companyName=ExampleCompany&page=0
@GetMapping("/")
public Page<CompanyDetails> searchCompaniesByName(@RequestParam("companyName") String companyName,
@RequestParam(defaultValue = "0") int page,
@RequestParam(defaultValue = "10") int size) {
Pageable pageable = PageRequest.of(page, size, Sort.by("id").ascending());
return companyService.searchCompanies(companyName, pageable);
}

// Example: http://localhost:8080/api/v1/company/get-by-id/123
@GetMapping("/get-by-id/{id}")
@GetMapping("/{id}")
public CompanyDtoWithStatusDTO getCompanyById(@PathVariable("id") Integer id) {
String userId = extractUserIdFromHeader();
CompanyDTO companyDto = companyService.getCompanyById(id).toCompanyDTO();
Expand All @@ -41,7 +53,7 @@ public CompanyDtoWithStatusDTO getCompanyById(@PathVariable("id") Integer id) {
}

// Example: http://localhost:8080/api/v1/company/get-seen-by-user?page=0
@GetMapping("/get-seen-by-user")
@GetMapping("/seen")
public Page<CompanyDtoWithStatusDTO> getCompaniesSeenByUser(@RequestParam(defaultValue = "0") int page,
@RequestParam(defaultValue = "10") int size) {
Pageable pageable = PageRequest.of(page, size);
Expand All @@ -57,17 +69,8 @@ public Page<CompanyDtoWithStatusDTO> getCompaniesSeenByUser(@RequestParam(defaul
return CompanyUtil.fillPaginationCompanyDtoWithStatusDto(companies, userCompanyStatuses);
}

// Example: http://localhost:8080/api/v1/company/search-by-name?companyName=ExampleCompany&page=0
@GetMapping("/search-by-name")
public Page<CompanyDetails> searchCompaniesByName(@RequestParam("companyName") String companyName,
@RequestParam(defaultValue = "0") int page,
@RequestParam(defaultValue = "10") int size) {
Pageable pageable = PageRequest.of(page, size, Sort.by("id").ascending());
return companyService.searchCompanies(companyName, pageable);
}

// Example: http://localhost:8080/api/v1/company/filter-by-parameters?regions=region1,region2&cities=city1,city2&industrySectors=sector1,sector2&legalForms=form1,form2&page=0
@PostMapping("/filter-by-parameters")
@PostMapping("/filter")
public Page<CompanyDtoWithStatusDTO> getCompaniesByFilters(
@RequestBody(required = false) CompanyFilterRequest filterRequest) {
String userId = extractUserIdFromHeader();
Expand Down Expand Up @@ -96,7 +99,7 @@ public Page<CompanyDtoWithStatusDTO> getCompaniesByFilters(
}

// Example: http://localhost:8080/api/v1/company/random-unseen?page=0
@GetMapping("/random-unseen")
@GetMapping("/random")
public Page<CompanyDtoWithStatusDTO> getRandomUnseenCompanies(@RequestParam(defaultValue = "0") int page,
@RequestParam(defaultValue = "10") int size) {
Pageable pageable = PageRequest.of(page, size);
Expand All @@ -113,8 +116,8 @@ public Page<CompanyDtoWithStatusDTO> getRandomUnseenCompanies(@RequestParam(defa

// Make a request to the scrap API
// Example: http://localhost:8080/api/v1/company/scrap?companyId=1
@GetMapping("/scrap")
public CompanyDTO scrapCompany(@RequestParam Integer companyId) {
@GetMapping("/{id}/scrap")
public CompanyDTO scrapCompany(@PathVariable("id") Integer companyId) {
CompanyModel company = companyService.getCompanyById(companyId);
if (company == null) {
throw new ResponseStatusException(HttpStatus.NOT_FOUND, "Company not found");
Expand All @@ -136,7 +139,7 @@ public CompanyDTO scrapCompany(@RequestParam Integer companyId) {


// Example: http://localhost:8080/api/v1/company/filter-by-parameters?regions=region1,region2&cities=city1,city2&industrySectors=sector1,sector2&legalForms=form1,form2&page=0
@GetMapping("/landing-filter")
@GetMapping("/landing")
public Page<CompanyDTO> getCompaniesOnLandingByFilters(
//@RequestParam(required = false) List<String> regions,
@RequestParam(required = false) List<String> cityNames,
Expand Down Expand Up @@ -167,4 +170,17 @@ public Page<CompanyDTO> getCompaniesOnLandingByFilters(
companiesPage.getTotalElements()
);
}

@PostMapping("/{id}/status")
public ResponseEntity<UserCompanyStatusModel> updateStatus(@PathVariable("id") Integer companyId,
@RequestParam Status status) {
String userId = extractUserIdFromHeader();
UserCompanyStatusModel updated = userCompanyStatusService.updateCompanyStatus(userId, companyId, status);

if (updated == null) {
return ResponseEntity.noContent().build(); // deleted or no-op
}

return ResponseEntity.ok(updated);
}
}
33 changes: 7 additions & 26 deletions src/main/java/com/example/spring/app/company/CompanyService.java
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,6 @@
import com.fasterxml.jackson.databind.JsonNode;
import com.fasterxml.jackson.databind.ObjectMapper;
import io.github.resilience4j.ratelimiter.annotation.RateLimiter;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.cache.annotation.CacheEvict;
import org.springframework.cache.annotation.Cacheable;
import org.springframework.data.domain.Page;
Expand All @@ -25,15 +24,17 @@
import java.nio.charset.StandardCharsets;
import java.time.LocalDate;
import java.util.List;
import java.util.Map;

import static com.example.spring.app.company.CompanyUtil.setIfNotEmpty;

@Service
public class CompanyService {

@Autowired
private CompanyRepository companyRepository;
private final CompanyRepository companyRepository;

public CompanyService(CompanyRepository companyRepository) {
this.companyRepository = companyRepository;
}

public CompanyModel getCompanyById(Integer id) {
return companyRepository.findCompanyById(id);
Expand Down Expand Up @@ -64,22 +65,6 @@ public Page<CompanyModel> findCompaniesByFilters(List<String> regionNames, List<
return companyRepository.findAll(specification, pageable);
}

@Cacheable(value = "companyCounts", key = "#root.methodName + #regionNames + #cityNames + #industrySectorNames + #legalFormNames + #numberOfEmployeeFilter + #socials + #contacts")
public long countCompaniesByFilters(List<String> regionNames, List<String> cityNames, List<String> industrySectorNames, List<String> legalFormNames,
NumberOfEmployeeFilterDTO numberOfEmployeeFilter, SocialMediaDTO socials, ContactDTO contacts) {

Specification<CompanyModel> specification = Specification.where(CompanySpecification.regionsIn(regionNames))
.and(CompanySpecification.citiesIn(cityNames))
.and(CompanySpecification.industrySectorsIn(industrySectorNames))
.and(CompanySpecification.legalFormsIn(legalFormNames))
.and(CompanySpecification.employeeComparator(numberOfEmployeeFilter))
.and(CompanySpecification.socialMediaNotNull(socials))
.and(CompanySpecification.contactInfoNotNull(contacts));

// Run a custom count query that only calculates the total number of companies matching the filters
return companyRepository.count(specification);
}

public Page<CompanyModel> findRandomUnseenCompanies(String userId, Pageable pageable) {
return companyRepository.findRandomUnseenCompanies(userId, pageable);
}
Expand Down Expand Up @@ -120,7 +105,8 @@ public CompanyModel scrapCompany(CompanyModel company) {
setIfNotEmpty(jsonNode, "youtube", companyScrapped::setYoutube);
setIfNotEmpty(jsonNode, "email", companyScrapped::setEmail);
setIfNotEmpty(jsonNode, "scrapingDate", (value) -> companyScrapped.setScrapingDate(LocalDate.parse(value)));
setIfNotEmpty(jsonNode, "reviews", (value) -> companyScrapped.setReviews(new ObjectMapper().convertValue(jsonNode.get("reviews"), new TypeReference<Map<String, Object>>() {})));
setIfNotEmpty(jsonNode, "reviews", (value) -> companyScrapped.setReviews(new ObjectMapper().convertValue(jsonNode.get("reviews"), new TypeReference<>() {
})));
setIfNotEmpty(jsonNode, "schedule", companyScrapped::setSchedule);

return companyScrapped;
Expand All @@ -135,9 +121,4 @@ public CompanyModel scrapCompany(CompanyModel company) {
public void saveCompany(CompanyModel company) {
companyRepository.save(company);
}

@CacheEvict(value = "companyCounts", allEntries = true)
public void deleteCompany(Integer id) {
companyRepository.deleteById(id);
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -3,9 +3,11 @@
import com.example.spring.config.EnvConfig;
import org.springframework.cache.annotation.Cacheable;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;

@RestController
@RequestMapping("/v1/configuration")
public class ConfigurationController {

private final EnvConfig envConfig;
Expand All @@ -16,7 +18,7 @@ public ConfigurationController(EnvConfig envConfig) {

// Make sure to flush the cache when updating the env variables
@Cacheable(value = "configCache", unless = "#result == null")
@GetMapping("/configuration")
@GetMapping("/")
public ConfigurationDTO getEnv() {
return ConfigurationDTO.builder()
.oauthBaseUrl(envConfig.getOAUTH_BASE_URL())
Expand Down
Original file line number Diff line number Diff line change
@@ -1,33 +1,29 @@
package com.example.spring.app.filters.autocomplete.city;

import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.RequestBody;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestParam;
import org.springframework.web.bind.annotation.RestController;

import java.util.List;

@RestController
@RequestMapping("/v1/autocomplete")
@RequestMapping("/v1/autocomplete/cities")
public class CityController {

@Autowired
private CityService cityService;
private final CityService cityService;

// Example: http://localhost:8080/api/v1/autocomplete/city?query=New
@GetMapping("/city")
public List<City> autocompleteCitiesByName(@RequestParam String query) {
return cityService.searchCitiesByName(query);
public CityController(CityService cityService) {
this.cityService = cityService;
}

@GetMapping("/city/ids")
public List<City> autocompleteCitiesByIds(@RequestParam List<Integer> query) {
@PostMapping("/ids")
public List<CityModel> autocompleteCitiesByIds(@RequestBody List<Integer> query) {
return cityService.searchCitiesByIds(query);
}

@GetMapping("/cities")
public List<City> autocompleteCitiesByNames(@RequestParam List<String> query) {
return cityService.searchCitiesByNames(query);
@PostMapping("/names")
public List<CityModel> autocompleteCitiesByNames(@RequestBody List<String> query) {
return cityService.searchCitiesByNameContainingIgnoreCaseAny(query);
}
}
Original file line number Diff line number Diff line change
@@ -1,17 +1,15 @@
package com.example.spring.app.filters.autocomplete.city;


import jakarta.persistence.Entity;
import jakarta.persistence.GeneratedValue;
import jakarta.persistence.GenerationType;
import jakarta.persistence.Id;
import jakarta.persistence.*;
import lombok.Getter;
import lombok.Setter;

@Setter
@Getter
@Entity
public class City {
@Table(name = "city")
public class CityModel {

@Id
@GeneratedValue(strategy = GenerationType.IDENTITY)
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -5,16 +5,16 @@

import java.util.List;

public interface CityRepository extends JpaRepository<City, Integer> {
public interface CityRepository extends JpaRepository<CityModel, Integer> {

@Query("SELECT c FROM City c " +
@Query("SELECT c FROM CityModel c " +
"WHERE LOWER(c.name) " +
"LIKE LOWER(CONCAT('%', :query, '%')) " +
"ORDER BY c.name " +
"ASC LIMIT 25")
List<City> findByNameContainingIgnoreCase(String query);
List<CityModel> findByNameContainingIgnoreCase(String query);

List<City> findByNameIn(List<String> names);
List<CityModel> findByNameIn(List<String> names);

List<City> findByIdIn(List<Integer> ids);
List<CityModel> findByIdIn(List<Integer> ids);
}
Original file line number Diff line number Diff line change
@@ -1,25 +1,27 @@
package com.example.spring.app.filters.autocomplete.city;

import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

import java.util.List;

@Service
public class CityService {

@Autowired
private CityRepository cityRepository;
private final CityRepository cityRepository;

public List<City> searchCitiesByName(String query) {
return cityRepository.findByNameContainingIgnoreCase(query);
public CityService(CityRepository cityRepository) {
this.cityRepository = cityRepository;
}

public List<City> searchCitiesByNames(List<String> query) {
return cityRepository.findByNameIn(query);
public List<CityModel> searchCitiesByNameContainingIgnoreCaseAny(List<String> query) {
if (query.size() > 1) {
return cityRepository.findByNameIn(query);
}

return cityRepository.findByNameContainingIgnoreCase(query.getFirst());
}

public List<City> searchCitiesByIds(List<Integer> query) {
public List<CityModel> searchCitiesByIds(List<Integer> query) {
return cityRepository.findByIdIn(query);
}
}
Original file line number Diff line number Diff line change
@@ -1,33 +1,29 @@
package com.example.spring.app.filters.autocomplete.industrySector;

import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.RequestBody;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestParam;
import org.springframework.web.bind.annotation.RestController;

import java.util.List;

@RestController
@RequestMapping("/v1/autocomplete")
@RequestMapping("/v1/autocomplete/industry-sectors")
public class IndustrySectorController {

@Autowired
private IndustrySectorService industrySectorService;
private final IndustrySectorService industrySectorService;

// Example: http://localhost:8080/api/v1/autocomplete/industrySector?query=New
@GetMapping("/industrySector")
public List<IndustrySector> autocompleteIndustrySectorsByName(@RequestParam String query) {
return industrySectorService.searchIndustrySectorsByName(query);
public IndustrySectorController(IndustrySectorService industrySectorService) {
this.industrySectorService = industrySectorService;
}

@GetMapping("/industrySector/ids")
public List<IndustrySector> autocompleteIndustrySectorsByIds(@RequestParam List<Integer> query) {
@PostMapping("/ids")
public List<IndustrySectorModel> autocompleteIndustrySectorsByIds(@RequestBody List<Integer> query) {
return industrySectorService.searchIndustrySectorsByIds(query);
}

@GetMapping("/industrySectors")
public List<IndustrySector> autocompleteIndustrySectorsByNames(@RequestParam List<String> query) {
return industrySectorService.searchIndustrySectorsByNames(query);
@PostMapping("/names")
public List<IndustrySectorModel> autocompleteIndustrySectorsByNames(@RequestBody List<String> query) {
return industrySectorService.searchIndustrySectorsByNameContainingIgnoreCase(query);
}
}
Loading