Compare commits
1 Commits
master
...
feature/ho
| Author | SHA1 | Date | |
|---|---|---|---|
| 96d357f1a5 |
@@ -0,0 +1,32 @@
|
||||
package com.celestialarchives.celestialarchives.api;
|
||||
|
||||
import org.apache.logging.log4j.LogManager;
|
||||
import org.apache.logging.log4j.Logger;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
|
||||
public class ApiResponse {
|
||||
final static Logger LOG = LogManager.getLogger(ApiResponse.class);
|
||||
private List<String> errors = new ArrayList<>();
|
||||
|
||||
public static ApiResponse fromErrors (String... errors){
|
||||
ApiResponse apiResponse = new ApiResponse();
|
||||
|
||||
for (String err : errors){
|
||||
apiResponse.addError(err);
|
||||
}
|
||||
return apiResponse;
|
||||
}
|
||||
|
||||
public void addError(String err) {
|
||||
LOG.error("API Response ERROR: " + err);
|
||||
errors.add(err);
|
||||
}
|
||||
|
||||
public List<String> getErrors() {
|
||||
return errors;
|
||||
}
|
||||
|
||||
public boolean isSuccessful () {return errors.isEmpty();}
|
||||
}
|
||||
@@ -0,0 +1,141 @@
|
||||
package com.celestialarchives.celestialarchives.controller;
|
||||
|
||||
import com.celestialarchives.celestialarchives.api.ApiResponse;
|
||||
import com.celestialarchives.celestialarchives.entity.hoardable.Hoardable;
|
||||
import com.celestialarchives.celestialarchives.entity.hoardable.HoardableCategory;
|
||||
import com.celestialarchives.celestialarchives.entity.hoardable.HoardableField;
|
||||
import com.celestialarchives.celestialarchives.repository.HoardableCategoryRepository;
|
||||
import com.celestialarchives.celestialarchives.repository.HoardableFieldTypeRepository;
|
||||
import com.celestialarchives.celestialarchives.repository.HoardableRepository;
|
||||
import com.celestialarchives.celestialarchives.utils.HoardableUtil;
|
||||
import org.springframework.beans.factory.annotation.Autowired;
|
||||
import org.springframework.data.domain.PageRequest;
|
||||
import org.springframework.data.domain.Pageable;
|
||||
import org.springframework.http.HttpStatus;
|
||||
import org.springframework.http.ResponseEntity;
|
||||
import org.springframework.transaction.annotation.Propagation;
|
||||
import org.springframework.transaction.annotation.Transactional;
|
||||
import org.springframework.web.bind.annotation.*;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
@RestController
|
||||
@RequestMapping("/api/hoardable")
|
||||
public class HoardableController {
|
||||
|
||||
@Autowired
|
||||
private HoardableRepository hoardableRepository;
|
||||
@Autowired
|
||||
private HoardableCategoryRepository hoardableCategoryRepository;
|
||||
@Autowired
|
||||
private HoardableFieldTypeRepository hoardableFieldTypeRepository;
|
||||
|
||||
@CrossOrigin
|
||||
@PostMapping(value = "/category")
|
||||
@Transactional(propagation = Propagation.REQUIRED)
|
||||
public ResponseEntity<ApiResponse> createHoardableCategory(@RequestBody HoardableCategory category) {
|
||||
ApiResponse apiResponse = new ApiResponse();
|
||||
|
||||
if (category.getDisplayName().isEmpty()) {
|
||||
apiResponse = ApiResponse.fromErrors("Name must not be blank!");
|
||||
} else {
|
||||
for (HoardableField field : category.getFields()) {
|
||||
field.setHoardableCategory(category);
|
||||
field.setSystemName(HoardableUtil.generateSystemName(field.getDisplayName()));
|
||||
field.setFieldType(hoardableFieldTypeRepository.getTypeByCode(field.getFieldType().getCode()).get(0));
|
||||
}
|
||||
category.setSystemName(HoardableUtil.generateSystemName(category.getDisplayName()));
|
||||
hoardableCategoryRepository.save(category);
|
||||
}
|
||||
|
||||
return apiResponse.isSuccessful()
|
||||
? new ResponseEntity(apiResponse, HttpStatus.CREATED)
|
||||
: new ResponseEntity(apiResponse, HttpStatus.BAD_REQUEST);
|
||||
}
|
||||
|
||||
@CrossOrigin
|
||||
@GetMapping(value = "categories")
|
||||
public List<HoardableCategory> getAllCategories() {
|
||||
return hoardableCategoryRepository.findAll();
|
||||
}
|
||||
|
||||
// TODO: countHoardableCategories(), searchHoardablesByNameAndCategory(), searchHoardablesByName(), countSearchResults()
|
||||
|
||||
@CrossOrigin
|
||||
@GetMapping("items")
|
||||
public List<HoardableCategory> getCategoryById(@RequestParam("categoryId") Integer categoryId) {
|
||||
return hoardableCategoryRepository.getCategoryById(categoryId);
|
||||
}
|
||||
|
||||
@CrossOrigin
|
||||
@GetMapping("itemsByCategory")
|
||||
public List<Hoardable> getItemsByCategoryId(@RequestParam("categoryId") Integer categoryId, @RequestParam("page") int page, @RequestParam("size") int size) {
|
||||
Pageable pageable = PageRequest.of(page, size);
|
||||
return hoardableRepository.getHoardablesByCategoryId(categoryId, pageable);
|
||||
}
|
||||
|
||||
@CrossOrigin
|
||||
@PostMapping(value = "new")
|
||||
@Transactional(propagation = Propagation.REQUIRED)
|
||||
public ResponseEntity<ApiResponse> createTrackedItem(@RequestBody Hoardable hoardable) {
|
||||
ApiResponse apiResponse = new ApiResponse();
|
||||
|
||||
HoardableCategory category = hoardableCategoryRepository.getReferenceById(hoardable.getCategory().getId());
|
||||
|
||||
for (HoardableField field : hoardable.getFields()) {
|
||||
field.setHoardable(hoardable);
|
||||
field.setSystemName(HoardableUtil.generateSystemName(field.getDisplayName()));
|
||||
field.setFieldType(hoardableFieldTypeRepository.getTypeByCode(field.getFieldType().getCode()).get(0));
|
||||
}
|
||||
|
||||
hoardable.setCategory(category);
|
||||
List<Hoardable> existingHoardables = category.getHoardables();
|
||||
existingHoardables.add(hoardable);
|
||||
|
||||
category.setHoardables(existingHoardables);
|
||||
hoardableCategoryRepository.save(category);
|
||||
|
||||
return apiResponse.isSuccessful()
|
||||
? new ResponseEntity(apiResponse, HttpStatus.CREATED)
|
||||
: new ResponseEntity(apiResponse, HttpStatus.BAD_REQUEST);
|
||||
}
|
||||
|
||||
@CrossOrigin
|
||||
@GetMapping(value = "/item/detail")
|
||||
public List<Hoardable> getItemDetailsById(@RequestParam("id") Integer id) {
|
||||
return hoardableRepository.getHoardableById(id);
|
||||
}
|
||||
|
||||
@CrossOrigin
|
||||
@PostMapping(value = "/item/update")
|
||||
@Transactional(propagation = Propagation.REQUIRED)
|
||||
public ResponseEntity<ApiResponse> updateHoardable(@RequestParam("id") Integer id, @RequestParam("categoryId") Integer categoryId, @RequestBody Hoardable hoardable) {
|
||||
ApiResponse apiResponse = new ApiResponse();
|
||||
|
||||
Hoardable hoardableFromDao = hoardableRepository.getReferenceById(id);
|
||||
hoardableFromDao.setCategory(hoardableCategoryRepository.getReferenceById(categoryId));
|
||||
|
||||
for (HoardableField daoField : hoardableFromDao.getFields()) {
|
||||
for (HoardableField field : hoardable.getFields()) {
|
||||
field.setHoardable(hoardable);
|
||||
if (daoField.getId() == field.getId()) {
|
||||
daoField.setValue(field.getValue());
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
hoardableRepository.save(hoardableFromDao);
|
||||
|
||||
return apiResponse.isSuccessful()
|
||||
? new ResponseEntity(apiResponse, HttpStatus.CREATED)
|
||||
: new ResponseEntity(apiResponse, HttpStatus.BAD_REQUEST);
|
||||
}
|
||||
|
||||
// Counts
|
||||
|
||||
@CrossOrigin
|
||||
@GetMapping(value = "itemCount")
|
||||
public long countHoardablesByCategoryId(@RequestParam("categoryId") Integer categoryId) {
|
||||
return hoardableRepository.countAllByCategoryId(categoryId);
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,22 @@
|
||||
package com.celestialarchives.celestialarchives.entity;
|
||||
|
||||
import jakarta.persistence.*;
|
||||
import lombok.Data;
|
||||
import lombok.Getter;
|
||||
import lombok.Setter;
|
||||
|
||||
@MappedSuperclass
|
||||
@Data
|
||||
@Getter
|
||||
@Setter
|
||||
public class ReferenceData {
|
||||
@Id
|
||||
@Column(name = "ref_id")
|
||||
@GeneratedValue(strategy = GenerationType.IDENTITY)
|
||||
private int id;
|
||||
@Column(name = "ref_cd")
|
||||
private String code;
|
||||
@Column(name = "ref_desc")
|
||||
private String desc;
|
||||
}
|
||||
|
||||
@@ -0,0 +1,28 @@
|
||||
package com.celestialarchives.celestialarchives.entity.hoardable;
|
||||
|
||||
import com.fasterxml.jackson.annotation.JsonProperty;
|
||||
import jakarta.persistence.*;
|
||||
import lombok.Data;
|
||||
import lombok.Getter;
|
||||
import lombok.Setter;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
@Data
|
||||
@Getter
|
||||
@Setter
|
||||
@Entity
|
||||
@Table(name = "hoardable_item")
|
||||
public class Hoardable {
|
||||
@Id
|
||||
@GeneratedValue(strategy = GenerationType.IDENTITY)
|
||||
@Column(name = "hoardable_item_id")
|
||||
private int id;
|
||||
@JoinColumn(name = "hoardable_category_id", referencedColumnName = "hoardable_category_id")
|
||||
@ManyToOne(targetEntity = HoardableCategory.class)
|
||||
@JsonProperty(access = JsonProperty.Access.WRITE_ONLY)
|
||||
private HoardableCategory category;
|
||||
@OneToMany(mappedBy = "hoardable", cascade = CascadeType.ALL, fetch = FetchType.EAGER)
|
||||
@OrderBy("sortIndex asc")
|
||||
private List<HoardableField> fields;
|
||||
}
|
||||
@@ -0,0 +1,56 @@
|
||||
package com.celestialarchives.celestialarchives.entity.hoardable;
|
||||
|
||||
import com.celestialarchives.celestialarchives.utils.HoardableUtil;
|
||||
import jakarta.persistence.*;
|
||||
import lombok.Data;
|
||||
import lombok.Getter;
|
||||
import lombok.NoArgsConstructor;
|
||||
import lombok.Setter;
|
||||
import org.hibernate.annotations.CreationTimestamp;
|
||||
import org.hibernate.annotations.UpdateTimestamp;
|
||||
|
||||
import java.time.Instant;
|
||||
import java.util.List;
|
||||
|
||||
@Data
|
||||
@NoArgsConstructor
|
||||
@Getter
|
||||
@Setter
|
||||
@Entity
|
||||
@Table(name = "hoardable_category")
|
||||
public class HoardableCategory {
|
||||
@Id
|
||||
@GeneratedValue(strategy = GenerationType.IDENTITY)
|
||||
@Column(name = "hoardable_category_id")
|
||||
private int id;
|
||||
@Column(name = "hoardable_category_display_name")
|
||||
private String displayName;
|
||||
@Column(name = "hoardable_category_system_name")
|
||||
private String systemName;
|
||||
@OneToMany(mappedBy = "hoardableCategory", cascade = CascadeType.ALL, fetch = FetchType.EAGER)
|
||||
@OrderBy("sortIndex asc")
|
||||
private List<HoardableField> fields;
|
||||
@Column(name = "hoardable_category_nav_index")
|
||||
private int navIndex;
|
||||
@OneToMany(mappedBy = "category", cascade = CascadeType.ALL, fetch = FetchType.EAGER)
|
||||
private List<Hoardable> hoardables;
|
||||
@CreationTimestamp
|
||||
@Column(name = "created")
|
||||
private Instant createdOn;
|
||||
@UpdateTimestamp
|
||||
@Column(name = "updated")
|
||||
private Instant updatedOn;
|
||||
|
||||
public HoardableCategory(String displayName, List<HoardableField> fields, int navIndex) {
|
||||
this.displayName = displayName;
|
||||
this.systemName = HoardableUtil.generateSystemName(displayName);
|
||||
this.fields = fields;
|
||||
this.navIndex = navIndex;
|
||||
}
|
||||
|
||||
public HoardableCategory(String displayName, int navIndex) {
|
||||
this.displayName = displayName;
|
||||
this.systemName = HoardableUtil.generateSystemName(displayName);
|
||||
this.navIndex = navIndex;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,69 @@
|
||||
package com.celestialarchives.celestialarchives.entity.hoardable;
|
||||
|
||||
import com.fasterxml.jackson.annotation.JsonIgnore;
|
||||
import jakarta.persistence.*;
|
||||
import lombok.*;
|
||||
import org.hibernate.annotations.CreationTimestamp;
|
||||
import org.hibernate.annotations.UpdateTimestamp;
|
||||
|
||||
import java.time.Instant;
|
||||
|
||||
@Data
|
||||
@NoArgsConstructor
|
||||
@Getter
|
||||
@Setter
|
||||
@Entity
|
||||
@Table(name = "hoardable_field")
|
||||
public class HoardableField {
|
||||
@Id
|
||||
@GeneratedValue(strategy = GenerationType.IDENTITY)
|
||||
@Column(name = "hoardable_field_id")
|
||||
private int id;
|
||||
@Column(name = "hoardable_field_display_name")
|
||||
private String displayName;
|
||||
@Column(name = "hoardable_field_system_name")
|
||||
private String systemName;
|
||||
@Column(name = "hoardable_field_value")
|
||||
// If FieldType is select/dropdown, value is set as comma-separated and then split by ','
|
||||
private String value;
|
||||
@Column(name = "hoardable_field_header_indicator")
|
||||
private boolean isListHeader;
|
||||
@Column(name = "hoardable_field_sort_index")
|
||||
private int sortIndex;
|
||||
@JoinColumn(name = "hoardable_field_field_type_id")
|
||||
@ManyToOne(fetch = FetchType.EAGER)
|
||||
private HoardableFieldType fieldType;
|
||||
@JoinColumn(name = "hoardable_category_id", referencedColumnName = "hoardable_category_id")
|
||||
@ManyToOne(targetEntity = HoardableCategory.class)
|
||||
@JsonIgnore
|
||||
private HoardableCategory hoardableCategory;
|
||||
@JoinColumn(name = "hoardable_item_id")
|
||||
@ManyToOne(targetEntity = Hoardable.class)
|
||||
@JsonIgnore
|
||||
private Hoardable hoardable;
|
||||
@CreationTimestamp
|
||||
@Column(name = "created")
|
||||
private Instant createdOn;
|
||||
@UpdateTimestamp
|
||||
@Column(name = "updated")
|
||||
private Instant updatedOn;
|
||||
|
||||
public HoardableField(String displayName, String systemName, String value, boolean isListHeader, int sortIndex, HoardableFieldType fieldType) {
|
||||
this.displayName = displayName;
|
||||
this.systemName = systemName;
|
||||
this.value = value;
|
||||
this.isListHeader = isListHeader;
|
||||
this.sortIndex = sortIndex;
|
||||
this.fieldType = fieldType;
|
||||
}
|
||||
|
||||
public HoardableField(String displayName, String systemName, String value, boolean isListHeader, int sortIndex, HoardableFieldType fieldType, HoardableCategory hoardableCategory) {
|
||||
this.displayName = displayName;
|
||||
this.systemName = systemName;
|
||||
this.value = value;
|
||||
this.isListHeader = isListHeader;
|
||||
this.sortIndex = sortIndex;
|
||||
this.fieldType = fieldType;
|
||||
this.hoardableCategory = hoardableCategory;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,17 @@
|
||||
package com.celestialarchives.celestialarchives.entity.hoardable;
|
||||
|
||||
import com.celestialarchives.celestialarchives.entity.ReferenceData;
|
||||
import jakarta.persistence.Entity;
|
||||
import jakarta.persistence.Table;
|
||||
import lombok.Data;
|
||||
import lombok.Getter;
|
||||
import lombok.Setter;
|
||||
|
||||
@Data
|
||||
@Getter
|
||||
@Setter
|
||||
@Entity
|
||||
@Table(name = "hoardable_field_type", catalog = "celestial_ref")
|
||||
public class HoardableFieldType extends ReferenceData {
|
||||
private String systemName;
|
||||
}
|
||||
@@ -0,0 +1,16 @@
|
||||
package com.celestialarchives.celestialarchives.repository;
|
||||
|
||||
import com.celestialarchives.celestialarchives.entity.hoardable.HoardableCategory;
|
||||
import org.springframework.data.jpa.repository.JpaRepository;
|
||||
import org.springframework.data.jpa.repository.Query;
|
||||
import org.springframework.stereotype.Repository;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
@Repository
|
||||
public interface HoardableCategoryRepository extends JpaRepository<HoardableCategory,Integer> {
|
||||
List<HoardableCategory> getHoardableCategoriesBySystemName(String systemName);
|
||||
|
||||
@Query("from HoardableCategory h where h.id = ?1")
|
||||
List<HoardableCategory> getCategoryById(int id);
|
||||
}
|
||||
@@ -0,0 +1,17 @@
|
||||
package com.celestialarchives.celestialarchives.repository;
|
||||
|
||||
import com.celestialarchives.celestialarchives.entity.hoardable.HoardableField;
|
||||
import org.springframework.data.jpa.repository.JpaRepository;
|
||||
import org.springframework.data.jpa.repository.Query;
|
||||
import org.springframework.stereotype.Repository;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
@Repository
|
||||
public interface HoardableFieldRepository extends JpaRepository<HoardableField, Integer> {
|
||||
@Query("from HoardableField h where h.hoardableCategory.id = ?1 order by h.sortIndex asc")
|
||||
List<HoardableField> getFieldsByCategoryId(int categoryId);
|
||||
|
||||
@Query("from HoardableField h where h.hoardable.id = ?1 order by h.sortIndex asc")
|
||||
List<HoardableField> getFieldsByHoardableId(int hoardableId);
|
||||
}
|
||||
@@ -0,0 +1,17 @@
|
||||
package com.celestialarchives.celestialarchives.repository;
|
||||
|
||||
import com.celestialarchives.celestialarchives.entity.hoardable.HoardableFieldType;
|
||||
import org.springframework.data.jpa.repository.JpaRepository;
|
||||
import org.springframework.data.jpa.repository.Query;
|
||||
import org.springframework.stereotype.Repository;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
@Repository
|
||||
public interface HoardableFieldTypeRepository extends JpaRepository<HoardableFieldType, Integer> {
|
||||
@Query("from HoardableFieldType r where r.code = ?1")
|
||||
List<HoardableFieldType> getTypeByCode(String code);
|
||||
|
||||
@Query("from HoardableFieldType r order by r.id asc")
|
||||
List<HoardableFieldType> getAllTypes();
|
||||
}
|
||||
@@ -0,0 +1,21 @@
|
||||
package com.celestialarchives.celestialarchives.repository;
|
||||
|
||||
import com.celestialarchives.celestialarchives.entity.hoardable.Hoardable;
|
||||
import org.springframework.data.domain.Pageable;
|
||||
import org.springframework.data.jpa.repository.JpaRepository;
|
||||
import org.springframework.data.jpa.repository.Query;
|
||||
import org.springframework.stereotype.Repository;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
@Repository
|
||||
public interface HoardableRepository extends JpaRepository<Hoardable, Integer> {
|
||||
@Query("from Hoardable h where h.category.id = ?1")
|
||||
List<Hoardable> getHoardablesByCategoryId(int categoryId, Pageable pageable);
|
||||
|
||||
@Query("select count(h) from Hoardable h where h.category.id = ?1")
|
||||
Long countAllByCategoryId(int categoryId);
|
||||
|
||||
@Query("from Hoardable h where h.id = ?1")
|
||||
List<Hoardable> getHoardableById(int id);
|
||||
}
|
||||
@@ -0,0 +1,8 @@
|
||||
package com.celestialarchives.celestialarchives.utils;
|
||||
|
||||
public class HoardableUtil {
|
||||
public static String generateSystemName(String displayName) {
|
||||
String out = displayName.replaceAll("\s", "");
|
||||
return out.toLowerCase();
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user