diff --git a/jasamedika-business/src/main/java/com/jasamedika/medifirst2000/dao/LogbookKinerjaDetailLogDao.java b/jasamedika-business/src/main/java/com/jasamedika/medifirst2000/dao/LogbookKinerjaDetailLogDao.java index 881f78b6..6922e6f4 100644 --- a/jasamedika-business/src/main/java/com/jasamedika/medifirst2000/dao/LogbookKinerjaDetailLogDao.java +++ b/jasamedika-business/src/main/java/com/jasamedika/medifirst2000/dao/LogbookKinerjaDetailLogDao.java @@ -2,11 +2,12 @@ package com.jasamedika.medifirst2000.dao; import com.jasamedika.medifirst2000.entities.LogbookKinerjaDetailLog; import org.springframework.data.jpa.repository.JpaRepository; +import org.springframework.data.jpa.repository.JpaSpecificationExecutor; /** * @author salmanoe * @version 1.0.0 * @since 31/10/2024 */ -public interface LogbookKinerjaDetailLogDao extends JpaRepository { +public interface LogbookKinerjaDetailLogDao extends JpaRepository, JpaSpecificationExecutor { } diff --git a/jasamedika-core/pom.xml b/jasamedika-core/pom.xml index e60cfec5..050e7ac3 100644 --- a/jasamedika-core/pom.xml +++ b/jasamedika-core/pom.xml @@ -76,6 +76,13 @@ itextpdf 5.5.9 + + + org.projectlombok + lombok + ${project.lombok.version} + provided + Jasa Medika diff --git a/jasamedika-core/src/main/java/com/jasamedika/medifirst2000/search/SearchCriteria.java b/jasamedika-core/src/main/java/com/jasamedika/medifirst2000/search/SearchCriteria.java new file mode 100644 index 00000000..c09ea6ec --- /dev/null +++ b/jasamedika-core/src/main/java/com/jasamedika/medifirst2000/search/SearchCriteria.java @@ -0,0 +1,30 @@ +package com.jasamedika.medifirst2000.search; + +import lombok.AllArgsConstructor; +import lombok.Data; +import lombok.NoArgsConstructor; + +/** + * @author salmanoe + * @version 1.0.0 + * @since 06/11/2024 + */ +@Data +@AllArgsConstructor +@NoArgsConstructor +public class SearchCriteria { + private String filterKey; + + private Object value; + + private String operation; + + private String dataOption; + + public SearchCriteria(String filterKey, String operation, Object value) { + super(); + this.filterKey = filterKey; + this.operation = operation; + this.value = value; + } +} diff --git a/jasamedika-core/src/main/java/com/jasamedika/medifirst2000/search/SearchDto.java b/jasamedika-core/src/main/java/com/jasamedika/medifirst2000/search/SearchDto.java new file mode 100644 index 00000000..1e0bb473 --- /dev/null +++ b/jasamedika-core/src/main/java/com/jasamedika/medifirst2000/search/SearchDto.java @@ -0,0 +1,21 @@ +package com.jasamedika.medifirst2000.search; + +import lombok.AllArgsConstructor; +import lombok.Data; +import lombok.NoArgsConstructor; + +import java.util.List; + +/** + * @author salmanoe + * @version 1.0.0 + * @since 06/11/2024 + */ +@Data +@AllArgsConstructor +@NoArgsConstructor +public class SearchDto { + private List searchCriteria; + + private String dataOption; +} diff --git a/jasamedika-core/src/main/java/com/jasamedika/medifirst2000/search/SearchOperation.java b/jasamedika-core/src/main/java/com/jasamedika/medifirst2000/search/SearchOperation.java new file mode 100644 index 00000000..3d5f2a8f --- /dev/null +++ b/jasamedika-core/src/main/java/com/jasamedika/medifirst2000/search/SearchOperation.java @@ -0,0 +1,57 @@ +package com.jasamedika.medifirst2000.search; + +/** + * @author salmanoe + * @version 1.0.0 + * @since 06/11/2024 + */ +public enum SearchOperation { + CONTAINS, DOES_NOT_CONTAIN, EQUAL, NOT_EQUAL, BEGINS_WITH, DOES_NOT_BEGIN_WITH, ENDS_WITH, DOES_NOT_END_WITH, + NULL, NOT_NULL, GREATER_THAN, GREATER_THAN_EQUAL, LESS_THAN, LESS_THAN_EQUAL, ANY, ALL; + + public static SearchOperation getDataOption(final String dataOption) { + switch (dataOption) { + case "all": + return ALL; + case "any": + return ANY; + default: + return null; + } + } + + public static SearchOperation getSimpleOperation(final String input) { + switch (input) { + case "cn": + return CONTAINS; + case "nc": + return DOES_NOT_CONTAIN; + case "eq": + return EQUAL; + case "ne": + return NOT_EQUAL; + case "bw": + return BEGINS_WITH; + case "bn": + return DOES_NOT_BEGIN_WITH; + case "ew": + return ENDS_WITH; + case "en": + return DOES_NOT_END_WITH; + case "nu": + return NULL; + case "nn": + return NOT_NULL; + case "gt": + return GREATER_THAN; + case "ge": + return GREATER_THAN_EQUAL; + case "lt": + return LESS_THAN; + case "le": + return LESS_THAN_EQUAL; + default: + return null; + } + } +} diff --git a/jasamedika-domain/src/main/java/com/jasamedika/medifirst2000/entities/spec/LogbookKinerjaDetailLogSpec.java b/jasamedika-domain/src/main/java/com/jasamedika/medifirst2000/entities/spec/LogbookKinerjaDetailLogSpec.java new file mode 100644 index 00000000..940df4df --- /dev/null +++ b/jasamedika-domain/src/main/java/com/jasamedika/medifirst2000/entities/spec/LogbookKinerjaDetailLogSpec.java @@ -0,0 +1,90 @@ +package com.jasamedika.medifirst2000.entities.spec; + +import com.jasamedika.medifirst2000.entities.LogbookKinerjaDetailLog; +import com.jasamedika.medifirst2000.search.SearchCriteria; +import com.jasamedika.medifirst2000.search.SearchOperation; +import lombok.RequiredArgsConstructor; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.data.jpa.domain.Specification; + +import javax.persistence.criteria.CriteriaBuilder; +import javax.persistence.criteria.CriteriaQuery; +import javax.persistence.criteria.Predicate; +import javax.persistence.criteria.Root; +import java.util.Objects; + +/** + * @author salmanoe + * @version 1.0.0 + * @since 06/11/2024 + */ +@RequiredArgsConstructor +public class LogbookKinerjaDetailLogSpec implements Specification { + + @Autowired + private SearchCriteria searchCriteria; + + @Override + public Predicate toPredicate(Root root, CriteriaQuery query, CriteriaBuilder cb) { + String strToSearch = searchCriteria.getValue().toString().toLowerCase(); + switch (Objects.requireNonNull(SearchOperation.getSimpleOperation(searchCriteria.getOperation()))) { + case CONTAINS: + if (searchCriteria.getFilterKey().equals("unitCode")) + return cb.like(cb.lower(root.get(searchCriteria.getFilterKey())), "%" + strToSearch + "%"); + if (searchCriteria.getFilterKey().equals("unitName")) + return cb.like(cb.lower(root.get(searchCriteria.getFilterKey())), "%" + strToSearch + "%"); + case DOES_NOT_CONTAIN: + if (searchCriteria.getFilterKey().equals("unitCode")) + return cb.notLike(cb.lower(root.get(searchCriteria.getFilterKey())), "%" + strToSearch + "%"); + if (searchCriteria.getFilterKey().equals("unitName")) + return cb.notLike(cb.lower(root.get(searchCriteria.getFilterKey())), "%" + strToSearch + "%"); + case BEGINS_WITH: + if (searchCriteria.getFilterKey().equals("unitCode")) + return cb.like(cb.lower(root.get(searchCriteria.getFilterKey())), strToSearch + "%"); + if (searchCriteria.getFilterKey().equals("unitName")) + return cb.like(cb.lower(root.get(searchCriteria.getFilterKey())), strToSearch + "%"); + case DOES_NOT_BEGIN_WITH: + if (searchCriteria.getFilterKey().equals("unitCode")) + return cb.notLike(cb.lower(root.get(searchCriteria.getFilterKey())), strToSearch + "%"); + if (searchCriteria.getFilterKey().equals("unitName")) + return cb.notLike(cb.lower(root.get(searchCriteria.getFilterKey())), strToSearch + "%"); + case ENDS_WITH: + if (searchCriteria.getFilterKey().equals("unitCode")) + return cb.like(cb.lower(root.get(searchCriteria.getFilterKey())), "%" + strToSearch); + if (searchCriteria.getFilterKey().equals("unitName")) + return cb.like(cb.lower(root.get(searchCriteria.getFilterKey())), "%" + strToSearch); + case DOES_NOT_END_WITH: + if (searchCriteria.getFilterKey().equals("unitCode")) + return cb.notLike(cb.lower(root.get(searchCriteria.getFilterKey())), "%" + strToSearch); + if (searchCriteria.getFilterKey().equals("unitName")) + return cb.notLike(cb.lower(root.get(searchCriteria.getFilterKey())), "%" + strToSearch); + case EQUAL: + if (searchCriteria.getFilterKey().equals("unitCode")) + return cb.equal(cb.lower(root.get(searchCriteria.getFilterKey())), searchCriteria.getValue()); + if (searchCriteria.getFilterKey().equals("unitName")) + return cb.equal(cb.lower(root.get(searchCriteria.getFilterKey())), searchCriteria.getValue()); + case NOT_EQUAL: + if (searchCriteria.getFilterKey().equals("unitCode")) + return cb.notEqual(cb.lower(root.get(searchCriteria.getFilterKey())), searchCriteria.getValue()); + if (searchCriteria.getFilterKey().equals("unitName")) + return cb.notEqual(cb.lower(root.get(searchCriteria.getFilterKey())), searchCriteria.getValue()); + case NULL: + return cb.isNull(root.get(searchCriteria.getFilterKey())); + case NOT_NULL: + return cb.isNotNull(root.get(searchCriteria.getFilterKey())); + case GREATER_THAN: + return cb.greaterThan(root + .get(searchCriteria.getFilterKey()), searchCriteria.getValue().toString()); + case GREATER_THAN_EQUAL: + return cb.greaterThanOrEqualTo(root + .get(searchCriteria.getFilterKey()), searchCriteria.getValue().toString()); + case LESS_THAN: + return cb.lessThan(root + .get(searchCriteria.getFilterKey()), searchCriteria.getValue().toString()); + case LESS_THAN_EQUAL: + return cb.lessThanOrEqualTo(root + .get(searchCriteria.getFilterKey()), searchCriteria.getValue().toString()); + } + return null; + } +} diff --git a/jasamedika-domain/src/main/java/com/jasamedika/medifirst2000/entities/spec/LogbookKinerjaDetailLogSpecBuilder.java b/jasamedika-domain/src/main/java/com/jasamedika/medifirst2000/entities/spec/LogbookKinerjaDetailLogSpecBuilder.java new file mode 100644 index 00000000..d58772aa --- /dev/null +++ b/jasamedika-domain/src/main/java/com/jasamedika/medifirst2000/entities/spec/LogbookKinerjaDetailLogSpecBuilder.java @@ -0,0 +1,46 @@ +package com.jasamedika.medifirst2000.entities.spec; + +import com.jasamedika.medifirst2000.entities.LogbookKinerjaDetailLog; +import com.jasamedika.medifirst2000.search.SearchCriteria; +import com.jasamedika.medifirst2000.search.SearchOperation; +import org.springframework.data.jpa.domain.Specification; +import org.springframework.data.jpa.domain.Specifications; + +import java.util.ArrayList; +import java.util.List; + +/** + * @author salmanoe + * @version 1.0.0 + * @since 06/11/2024 + */ +public class LogbookKinerjaDetailLogSpecBuilder { + private final List params; + + public LogbookKinerjaDetailLogSpecBuilder() { + this.params = new ArrayList<>(); + } + + public final LogbookKinerjaDetailLogSpecBuilder with(String key, String operation, Object value) { + params.add(new SearchCriteria(key, operation, value)); + return this; + } + + public final LogbookKinerjaDetailLogSpecBuilder with(SearchCriteria searchCriteria) { + params.add(searchCriteria); + return this; + } + + public Specifications build() { + if (params.isEmpty()) + return null; + Specification result = new LogbookKinerjaDetailLogSpec(params.get(0)); + for (int idx = 1; idx < params.size(); idx++) { + SearchCriteria criteria = params.get(idx); + result = SearchOperation.getDataOption(criteria.getDataOption()) == SearchOperation.ALL + ? Specification.where(result).and(new LogbookKinerjaDetailLogSpec(criteria)) + : Specification.where(result).or(new LogbookKinerjaDetailLogSpec(criteria)); + } + return result; + } +}