diff --git a/app-api/src/main/java/com/parkingcomestrue/parking/application/parking/ParkingService.java b/app-api/src/main/java/com/parkingcomestrue/parking/application/parking/ParkingService.java index a3d30a03..078e376c 100644 --- a/app-api/src/main/java/com/parkingcomestrue/parking/application/parking/ParkingService.java +++ b/app-api/src/main/java/com/parkingcomestrue/parking/application/parking/ParkingService.java @@ -1,17 +1,5 @@ package com.parkingcomestrue.parking.application.parking; -import com.parkingcomestrue.parking.application.SearchConditionMapper; -import com.parkingcomestrue.parking.application.parking.dto.ParkingDetailInfoResponse; -import com.parkingcomestrue.parking.application.parking.dto.ParkingDetailInfoResponse.FeeInfo; -import com.parkingcomestrue.parking.application.parking.dto.ParkingDetailInfoResponse.HolidayOperatingTime; -import com.parkingcomestrue.parking.application.parking.dto.ParkingDetailInfoResponse.SaturdayOperatingTime; -import com.parkingcomestrue.parking.application.parking.dto.ParkingDetailInfoResponse.WeekdayOperatingTime; -import com.parkingcomestrue.parking.application.parking.dto.ParkingLotsResponse; -import com.parkingcomestrue.parking.application.parking.dto.ParkingLotsResponse.ParkingResponse; -import com.parkingcomestrue.parking.application.parking.dto.ParkingQueryRequest; -import com.parkingcomestrue.parking.application.parking.dto.ParkingSearchConditionRequest; -import com.parkingcomestrue.parking.application.review.ReviewService; -import com.parkingcomestrue.parking.application.review.dto.ReviewInfoResponse; import com.parkingcomestrue.common.domain.favorite.Favorite; import com.parkingcomestrue.common.domain.favorite.repository.FavoriteRepository; import com.parkingcomestrue.common.domain.parking.Fee; @@ -26,6 +14,18 @@ import com.parkingcomestrue.common.domain.parking.service.ParkingFilteringService; import com.parkingcomestrue.common.domain.searchcondition.FeeType; import com.parkingcomestrue.common.support.Association; +import com.parkingcomestrue.parking.application.SearchConditionMapper; +import com.parkingcomestrue.parking.application.parking.dto.ParkingDetailInfoResponse; +import com.parkingcomestrue.parking.application.parking.dto.ParkingDetailInfoResponse.FeeInfo; +import com.parkingcomestrue.parking.application.parking.dto.ParkingDetailInfoResponse.HolidayOperatingTime; +import com.parkingcomestrue.parking.application.parking.dto.ParkingDetailInfoResponse.SaturdayOperatingTime; +import com.parkingcomestrue.parking.application.parking.dto.ParkingDetailInfoResponse.WeekdayOperatingTime; +import com.parkingcomestrue.parking.application.parking.dto.ParkingLotsResponse; +import com.parkingcomestrue.parking.application.parking.dto.ParkingLotsResponse.ParkingResponse; +import com.parkingcomestrue.parking.application.parking.dto.ParkingQueryRequest; +import com.parkingcomestrue.parking.application.parking.dto.ParkingSearchConditionRequest; +import com.parkingcomestrue.parking.application.review.ReviewService; +import com.parkingcomestrue.parking.application.review.dto.ReviewInfoResponse; import java.time.LocalDateTime; import java.util.Collections; import java.util.List; @@ -82,10 +82,10 @@ private List findMemberFavorites(Long memberId) { private List findParkingLotsByOrderCondition(String priority, ParkingQueryRequest parkingQueryRequest, Location middleLocation) { if (priority.equals(DISTANCE_ORDER_CONDITION)) { - return parkingRepository.findAroundParkingLotsOrderByDistance(middleLocation.getPoint(), + return parkingRepository.findAroundParkingLotsOrderByDistance(middleLocation.toPoint(), parkingQueryRequest.getRadius()); } - return parkingRepository.findAroundParkingLots(middleLocation.getPoint(), parkingQueryRequest.getRadius()); + return parkingRepository.findAroundParkingLots(middleLocation.toPoint(), parkingQueryRequest.getRadius()); } private SearchingCondition toSearchingCondition(ParkingSearchConditionRequest request) { @@ -166,7 +166,7 @@ private ParkingDetailInfoResponse toParkingResponse(ReviewInfoResponse reviews, parking.getSpace().getCapacity(), diffMinute, parking.getBaseInformation().getTel(), - parking.getBaseInformation().getPayTypes().getDescription(), + parking.getBaseInformation().getPayTypesDescription(), new WeekdayOperatingTime( parking.getOperatingTime().getWeekdayBeginTime(), parking.getOperatingTime().getWeekdayEndTime()), diff --git a/app-api/src/main/java/com/parkingcomestrue/parking/config/argumentresolver/parking/ParkingSearchConditionArgumentResolver.java b/app-api/src/main/java/com/parkingcomestrue/parking/config/argumentresolver/parking/ParkingSearchConditionArgumentResolver.java index a4698554..73a3a61f 100644 --- a/app-api/src/main/java/com/parkingcomestrue/parking/config/argumentresolver/parking/ParkingSearchConditionArgumentResolver.java +++ b/app-api/src/main/java/com/parkingcomestrue/parking/config/argumentresolver/parking/ParkingSearchConditionArgumentResolver.java @@ -65,7 +65,7 @@ private ParkingSearchConditionRequest defaultRequest() { searchConditionMapper.getValues(OperationType.class), searchConditionMapper.getValues(ParkingType.class), NOT_FREE, - searchConditionMapper.getValues(PayType.class), + List.of(PayType.NO_INFO.getDescription()), BASE_HOURS, RECOMMEND_ORDER_CONDITION ); diff --git a/app-api/src/test/java/com/parkingcomestrue/parking/application/parking/ParkingServiceTest.java b/app-api/src/test/java/com/parkingcomestrue/parking/application/parking/ParkingServiceTest.java index b5e56930..884f4d36 100644 --- a/app-api/src/test/java/com/parkingcomestrue/parking/application/parking/ParkingServiceTest.java +++ b/app-api/src/test/java/com/parkingcomestrue/parking/application/parking/ParkingServiceTest.java @@ -2,9 +2,6 @@ import static org.junit.jupiter.api.Assertions.assertAll; -import com.parkingcomestrue.parking.application.ContainerTest; -import com.parkingcomestrue.parking.application.parking.dto.ParkingDetailInfoResponse; -import com.parkingcomestrue.parking.application.review.dto.ReviewCreateRequest; import com.parkingcomestrue.common.domain.member.Member; import com.parkingcomestrue.common.domain.member.Password; import com.parkingcomestrue.common.domain.parking.BaseInformation; @@ -16,13 +13,16 @@ import com.parkingcomestrue.common.domain.parking.OperationType; import com.parkingcomestrue.common.domain.parking.Parking; import com.parkingcomestrue.common.domain.parking.ParkingType; -import com.parkingcomestrue.common.domain.parking.PayTypes; +import com.parkingcomestrue.common.domain.parking.PayType; import com.parkingcomestrue.common.domain.parking.Space; import com.parkingcomestrue.common.domain.parking.TimeInfo; import com.parkingcomestrue.common.domain.parking.TimeUnit; import com.parkingcomestrue.common.domain.review.Content; import com.parkingcomestrue.common.support.exception.DomainException; import com.parkingcomestrue.common.support.exception.DomainExceptionInformation; +import com.parkingcomestrue.parking.application.ContainerTest; +import com.parkingcomestrue.parking.application.parking.dto.ParkingDetailInfoResponse; +import com.parkingcomestrue.parking.application.review.dto.ReviewCreateRequest; import java.time.LocalTime; import java.util.List; import org.assertj.core.api.Assertions; @@ -46,7 +46,7 @@ class ParkingServiceTest extends ContainerTest { List parkings = List.of(parking); parkingService.saveAll(parkings); - Member member = new Member( "email", "하디", new Password("qwer1234")); + Member member = new Member("email", "하디", new Password("qwer1234")); memberRepository.save(member); ReviewCreateRequest reviewCreateRequest = new ReviewCreateRequest( @@ -64,7 +64,7 @@ class ParkingServiceTest extends ContainerTest { private Parking makeParking(String parkingName) { return new Parking ( - new BaseInformation(parkingName, "010", "부산", PayTypes.DEFAULT, ParkingType.MECHANICAL, + new BaseInformation(parkingName, "010", "부산", List.of(PayType.NO_INFO), ParkingType.MECHANICAL, OperationType.PRIVATE), Location.of(30d, 30d), Space.of(100, 30), @@ -86,5 +86,4 @@ private Parking makeParking(String parkingName) { Fee.from(50000)) ); } - } diff --git a/app-scheduler/src/main/java/com/parkingcomestrue/external/parkingapi/pusan/PusanPublicParkingAdapter.java b/app-scheduler/src/main/java/com/parkingcomestrue/external/parkingapi/pusan/PusanPublicParkingAdapter.java index 387c8b32..54354cb0 100644 --- a/app-scheduler/src/main/java/com/parkingcomestrue/external/parkingapi/pusan/PusanPublicParkingAdapter.java +++ b/app-scheduler/src/main/java/com/parkingcomestrue/external/parkingapi/pusan/PusanPublicParkingAdapter.java @@ -9,7 +9,7 @@ import com.parkingcomestrue.common.domain.parking.OperationType; import com.parkingcomestrue.common.domain.parking.Parking; import com.parkingcomestrue.common.domain.parking.ParkingType; -import com.parkingcomestrue.common.domain.parking.PayTypes; +import com.parkingcomestrue.common.domain.parking.PayType; import com.parkingcomestrue.common.domain.parking.Space; import com.parkingcomestrue.common.domain.parking.TimeInfo; import com.parkingcomestrue.common.domain.parking.TimeUnit; @@ -48,7 +48,7 @@ private BaseInformation getBaseInformation(final PusanPublicParkingResponse.Park response.getParkingName(), response.getTelephoneNumber(), filterAddress(response), - PayTypes.DEFAULT, + List.of(PayType.NO_INFO), ParkingType.find(response.getParkingTypeNM()), OperationType.PUBLIC ); diff --git a/app-scheduler/src/main/java/com/parkingcomestrue/external/parkingapi/seoul/SeoulPublicParkingAdapter.java b/app-scheduler/src/main/java/com/parkingcomestrue/external/parkingapi/seoul/SeoulPublicParkingAdapter.java index a0918d7b..c4eaf4c9 100644 --- a/app-scheduler/src/main/java/com/parkingcomestrue/external/parkingapi/seoul/SeoulPublicParkingAdapter.java +++ b/app-scheduler/src/main/java/com/parkingcomestrue/external/parkingapi/seoul/SeoulPublicParkingAdapter.java @@ -9,7 +9,7 @@ import com.parkingcomestrue.common.domain.parking.OperationType; import com.parkingcomestrue.common.domain.parking.Parking; import com.parkingcomestrue.common.domain.parking.ParkingType; -import com.parkingcomestrue.common.domain.parking.PayTypes; +import com.parkingcomestrue.common.domain.parking.PayType; import com.parkingcomestrue.common.domain.parking.Space; import com.parkingcomestrue.common.domain.parking.TimeInfo; import com.parkingcomestrue.common.domain.parking.TimeUnit; @@ -33,20 +33,23 @@ public class SeoulPublicParkingAdapter { public List convert(SeoulPublicParkingResponse response) { List rows = response.getParkingInfo().getRows(); - List seoulCityParkingLots = calculateCapacity(filterByOperation(rows)); + List seoulCityParkingLots = calculateCapacity( + filterByOperation(rows)); return seoulCityParkingLots.stream() .map(this::toParking) .toList(); } - private List filterByOperation(final List rows) { + private List filterByOperation( + final List rows) { return rows.stream() .filter(result -> TIMED_PARKING_RULES.contains(result.getOperationRule())) .toList(); } - private List calculateCapacity(final List results) { + private List calculateCapacity( + final List results) { final Map> collect = results.stream() .collect(Collectors.groupingBy(a -> a.getParkingCode())); @@ -76,7 +79,7 @@ private BaseInformation getBaseInformation(final SeoulPublicParkingResponse.Park response.getParkingName(), response.getTel(), response.getAddr(), - PayTypes.DEFAULT, + List.of(PayType.NO_INFO), ParkingType.find(response.getParkingTypeNM()), OperationType.PUBLIC ); diff --git a/app-scheduler/src/test/java/com/parkingcomestrue/fake/NotOfferCurrentParkingApiService.java b/app-scheduler/src/test/java/com/parkingcomestrue/fake/NotOfferCurrentParkingApiService.java index 96aaa5e7..41079e07 100644 --- a/app-scheduler/src/test/java/com/parkingcomestrue/fake/NotOfferCurrentParkingApiService.java +++ b/app-scheduler/src/test/java/com/parkingcomestrue/fake/NotOfferCurrentParkingApiService.java @@ -1,6 +1,5 @@ package com.parkingcomestrue.fake; -import com.parkingcomestrue.external.parkingapi.ParkingApiService; import com.parkingcomestrue.common.domain.parking.BaseInformation; import com.parkingcomestrue.common.domain.parking.Fee; import com.parkingcomestrue.common.domain.parking.FeePolicy; @@ -10,9 +9,10 @@ import com.parkingcomestrue.common.domain.parking.OperationType; import com.parkingcomestrue.common.domain.parking.Parking; import com.parkingcomestrue.common.domain.parking.ParkingType; -import com.parkingcomestrue.common.domain.parking.PayTypes; +import com.parkingcomestrue.common.domain.parking.PayType; import com.parkingcomestrue.common.domain.parking.Space; import com.parkingcomestrue.common.domain.parking.TimeUnit; +import com.parkingcomestrue.external.parkingapi.ParkingApiService; import java.util.LinkedList; import java.util.List; @@ -34,7 +34,8 @@ public List read() { LinkedList result = new LinkedList<>(); for (int i = 0; i < readSize; i++) { Parking parking = new Parking( - new BaseInformation("not offer parking" + i, "051-000" + i, "부산시 어딘가 " + i, PayTypes.DEFAULT, + new BaseInformation("not offer parking" + i, "051-000" + i, "부산시 어딘가 " + i, + List.of(PayType.NO_INFO), ParkingType.NO_INFO, OperationType.PUBLIC), Location.of("33.333" + i, "44.444" + i), diff --git a/app-scheduler/src/test/java/com/parkingcomestrue/fake/OfferCurrentParkingApiService.java b/app-scheduler/src/test/java/com/parkingcomestrue/fake/OfferCurrentParkingApiService.java index 2df132e5..0138d62b 100644 --- a/app-scheduler/src/test/java/com/parkingcomestrue/fake/OfferCurrentParkingApiService.java +++ b/app-scheduler/src/test/java/com/parkingcomestrue/fake/OfferCurrentParkingApiService.java @@ -1,6 +1,5 @@ package com.parkingcomestrue.fake; -import com.parkingcomestrue.external.parkingapi.ParkingApiService; import com.parkingcomestrue.common.domain.parking.BaseInformation; import com.parkingcomestrue.common.domain.parking.Fee; import com.parkingcomestrue.common.domain.parking.FeePolicy; @@ -10,9 +9,10 @@ import com.parkingcomestrue.common.domain.parking.OperationType; import com.parkingcomestrue.common.domain.parking.Parking; import com.parkingcomestrue.common.domain.parking.ParkingType; -import com.parkingcomestrue.common.domain.parking.PayTypes; +import com.parkingcomestrue.common.domain.parking.PayType; import com.parkingcomestrue.common.domain.parking.Space; import com.parkingcomestrue.common.domain.parking.TimeUnit; +import com.parkingcomestrue.external.parkingapi.ParkingApiService; import java.util.LinkedList; import java.util.List; @@ -34,7 +34,7 @@ public List read() { LinkedList result = new LinkedList<>(); for (int i = 0; i < readSize; i++) { Parking parking = new Parking( - new BaseInformation("offer parking" + i, "02-000" + i, "서울시 어딘가 " + i, PayTypes.DEFAULT, + new BaseInformation("offer parking" + i, "02-000" + i, "서울시 어딘가 " + i, List.of(PayType.NO_INFO), ParkingType.NO_INFO, OperationType.PUBLIC), Location.of("11.111" + i, "22.222" + i), diff --git a/domain/src/main/java/com/parkingcomestrue/common/domain/favorite/Favorite.java b/domain/src/main/java/com/parkingcomestrue/common/domain/favorite/Favorite.java index 2c760ee1..7b7afab4 100644 --- a/domain/src/main/java/com/parkingcomestrue/common/domain/favorite/Favorite.java +++ b/domain/src/main/java/com/parkingcomestrue/common/domain/favorite/Favorite.java @@ -3,10 +3,9 @@ import com.parkingcomestrue.common.domain.AuditingEntity; import com.parkingcomestrue.common.domain.member.Member; import com.parkingcomestrue.common.domain.parking.Parking; +import com.parkingcomestrue.common.infra.converter.AssociationConverter; import com.parkingcomestrue.common.support.Association; -import jakarta.persistence.AttributeOverride; -import jakarta.persistence.Column; -import jakarta.persistence.Embedded; +import jakarta.persistence.Convert; import jakarta.persistence.Entity; import jakarta.persistence.GeneratedValue; import jakarta.persistence.GenerationType; @@ -33,12 +32,10 @@ public class Favorite extends AuditingEntity { @GeneratedValue(strategy = GenerationType.IDENTITY) private Long id; - @Embedded - @AttributeOverride(name = "id", column = @Column(name = "member_id")) + @Convert(converter = AssociationConverter.class) private Association memberId; - @Embedded - @AttributeOverride(name = "id", column = @Column(name = "parking_id")) + @Convert(converter = AssociationConverter.class) private Association parkingId; public Favorite(Association memberId, Association parkingId) { diff --git a/domain/src/main/java/com/parkingcomestrue/common/domain/parking/BaseInformation.java b/domain/src/main/java/com/parkingcomestrue/common/domain/parking/BaseInformation.java index 73f24df6..a70e3e05 100644 --- a/domain/src/main/java/com/parkingcomestrue/common/domain/parking/BaseInformation.java +++ b/domain/src/main/java/com/parkingcomestrue/common/domain/parking/BaseInformation.java @@ -2,10 +2,12 @@ import static jakarta.persistence.EnumType.STRING; +import com.parkingcomestrue.common.infra.converter.PayTypeConverter; +import jakarta.persistence.Convert; import jakarta.persistence.Embeddable; -import jakarta.persistence.Embedded; import jakarta.persistence.Enumerated; import java.util.List; +import java.util.stream.Collectors; import lombok.AccessLevel; import lombok.Getter; import lombok.NoArgsConstructor; @@ -15,12 +17,14 @@ @Embeddable public class BaseInformation { + private static final String DELIMITER = ", "; + private String name; private String tel; private String address; - @Embedded - private PayTypes payTypes; + @Convert(converter = PayTypeConverter.class) + private List payTypes; @Enumerated(STRING) private ParkingType parkingType; @@ -28,7 +32,7 @@ public class BaseInformation { @Enumerated(STRING) private OperationType operationType; - public BaseInformation(String name, String tel, String address, PayTypes payTypes, ParkingType parkingType, + public BaseInformation(String name, String tel, String address, List payTypes, ParkingType parkingType, OperationType operationType) { this.name = name; this.tel = tel; @@ -49,6 +53,24 @@ public boolean containsParkingType(List parkingTypes) { } public boolean containsPayType(List memberPayTypes) { - return this.payTypes.contains(memberPayTypes); + if (memberPayTypes.contains(PayType.NO_INFO)) { + return true; + } + return memberPayTypes.stream() + .anyMatch(payType -> this.payTypes.contains(payType)); + } + + public String getPayTypesDescription() { + return payTypes.stream() + .map(PayType::getDescription) + .sorted() + .collect(Collectors.joining(DELIMITER)); + } + + public String getPayTypesName() { + return payTypes.stream() + .map(PayType::name) + .sorted() + .collect(Collectors.joining(DELIMITER)); } } diff --git a/domain/src/main/java/com/parkingcomestrue/common/domain/parking/FeePolicy.java b/domain/src/main/java/com/parkingcomestrue/common/domain/parking/FeePolicy.java index 8cb08d36..7956c1f5 100644 --- a/domain/src/main/java/com/parkingcomestrue/common/domain/parking/FeePolicy.java +++ b/domain/src/main/java/com/parkingcomestrue/common/domain/parking/FeePolicy.java @@ -1,9 +1,9 @@ package com.parkingcomestrue.common.domain.parking; -import jakarta.persistence.AttributeOverride; -import jakarta.persistence.Column; +import com.parkingcomestrue.common.infra.converter.FeeConverter; +import com.parkingcomestrue.common.infra.converter.TimeUnitConverter; +import jakarta.persistence.Convert; import jakarta.persistence.Embeddable; -import jakarta.persistence.Embedded; import lombok.AccessLevel; import lombok.Getter; import lombok.NoArgsConstructor; @@ -13,31 +13,26 @@ @Embeddable public class FeePolicy { - @AttributeOverride(name = "fee", column = @Column(name = "base_fee")) - @Embedded + @Convert(converter = FeeConverter.class) private Fee baseFee; - @AttributeOverride(name = "fee", column = @Column(name = "extra_fee")) - @Embedded + @Convert(converter = FeeConverter.class) private Fee extraFee; - @AttributeOverride(name = "timeUnit", column = @Column(name = "base_time_unit")) - @Embedded + @Convert(converter = TimeUnitConverter.class) private TimeUnit baseTimeUnit; - @AttributeOverride(name = "timeUnit", column = @Column(name = "extra_time_unit")) - @Embedded - private TimeUnit extraTimUnit; + @Convert(converter = TimeUnitConverter.class) + private TimeUnit extraTimeUnit; - @AttributeOverride(name = "fee", column = @Column(name = "day_maximum_fee")) - @Embedded + @Convert(converter = FeeConverter.class) private Fee dayMaximumFee; - public FeePolicy(Fee baseFee, Fee extraFee, TimeUnit baseTimeUnit, TimeUnit extraTimUnit, Fee dayMaximumFee) { + public FeePolicy(Fee baseFee, Fee extraFee, TimeUnit baseTimeUnit, TimeUnit extraTimeUnit, Fee dayMaximumFee) { this.baseFee = baseFee; this.extraFee = extraFee; this.baseTimeUnit = baseTimeUnit; - this.extraTimUnit = extraTimUnit; + this.extraTimeUnit = extraTimeUnit; this.dayMaximumFee = dayMaximumFee; } @@ -53,7 +48,7 @@ public boolean supportBase() { } public boolean supportExtra() { - return extraFee.isValidFee() && extraTimUnit.isValidTimeUnit(); + return extraFee.isValidFee() && extraTimeUnit.isValidTimeUnit(); } private Fee calculateFeeWithBase(int minutes) { @@ -64,7 +59,7 @@ private Fee calculateFeeWithBase(int minutes) { return baseFee; } minutes = minutes - baseTimeUnit.getTimeUnit(); - int time = extraTimUnit.calculateQuotient(minutes); + int time = extraTimeUnit.calculateQuotient(minutes); return Fee.min(extraFee.multiply(time).plus(baseFee), dayMaximumFee); } @@ -73,7 +68,7 @@ private Fee calculateFeeWithoutBase(int minutes) { return Fee.ZERO; } if (supportExtra()) { - int time = extraTimUnit.calculateQuotient(minutes); + int time = extraTimeUnit.calculateQuotient(minutes); return Fee.min(extraFee.multiply(time), dayMaximumFee); } return Fee.NO_INFO; diff --git a/domain/src/main/java/com/parkingcomestrue/common/domain/parking/Location.java b/domain/src/main/java/com/parkingcomestrue/common/domain/parking/Location.java index 0f512a6b..f3ba4642 100644 --- a/domain/src/main/java/com/parkingcomestrue/common/domain/parking/Location.java +++ b/domain/src/main/java/com/parkingcomestrue/common/domain/parking/Location.java @@ -19,7 +19,7 @@ public class Location { private static final GeometryFactory geometryFactory = new GeometryFactory(new PrecisionModel(), 4326); - private static final Location NO_PROVIDE = new Location(geometryFactory.createPoint(new Coordinate(-1.0, -1.0))); + private static final Location NO_PROVIDE = new Location(-1.0, -1.0); private static final Double MAX_LONGITUDE = 180.0; private static final Double MIN_LONGITUDE = -180.0; @@ -27,17 +27,18 @@ public class Location { private static final Double MAX_LATITUDE = 90.0; private static final Double MIN_LATITUDE = -90.0; - private Point point; + private Double longitude; + private Double latitude; - private Location(Point point) { - this.point = point; + private Location(Double longitude, Double latitude) { + this.longitude = longitude; + this.latitude = latitude; } public static Location of(Double longitude, Double latitude) { try { verifyLocation(longitude, latitude); - Point point = geometryFactory.createPoint(new Coordinate(longitude, latitude)); - return new Location(point); + return new Location(longitude, latitude); } catch (NullPointerException e) { return NO_PROVIDE; } @@ -58,11 +59,7 @@ public static Location of(String longitude, String latitude) { } } - public double getLongitude() { - return point.getX(); - } - - public double getLatitude() { - return point.getY(); + public Point toPoint() { + return geometryFactory.createPoint(new Coordinate(longitude, latitude)); } } diff --git a/domain/src/main/java/com/parkingcomestrue/common/domain/parking/Parking.java b/domain/src/main/java/com/parkingcomestrue/common/domain/parking/Parking.java index 0f135a38..15134c03 100644 --- a/domain/src/main/java/com/parkingcomestrue/common/domain/parking/Parking.java +++ b/domain/src/main/java/com/parkingcomestrue/common/domain/parking/Parking.java @@ -1,6 +1,8 @@ package com.parkingcomestrue.common.domain.parking; import com.parkingcomestrue.common.domain.AuditingEntity; +import com.parkingcomestrue.common.infra.converter.LocationConverter; +import jakarta.persistence.Convert; import jakarta.persistence.Embedded; import jakarta.persistence.Entity; import jakarta.persistence.GeneratedValue; @@ -31,7 +33,7 @@ public class Parking extends AuditingEntity { @Embedded private BaseInformation baseInformation; - @Embedded + @Convert(converter = LocationConverter.class) private Location location; @Embedded diff --git a/domain/src/main/java/com/parkingcomestrue/common/domain/parking/PayTypes.java b/domain/src/main/java/com/parkingcomestrue/common/domain/parking/PayTypes.java deleted file mode 100644 index 9089cdb7..00000000 --- a/domain/src/main/java/com/parkingcomestrue/common/domain/parking/PayTypes.java +++ /dev/null @@ -1,46 +0,0 @@ -package com.parkingcomestrue.common.domain.parking; - -import jakarta.persistence.Embeddable; -import java.util.Collection; -import java.util.List; -import java.util.stream.Collectors; -import lombok.AccessLevel; -import lombok.EqualsAndHashCode; -import lombok.Getter; -import lombok.NoArgsConstructor; - -@Getter -@NoArgsConstructor(access = AccessLevel.PROTECTED) -@EqualsAndHashCode -@Embeddable -public class PayTypes { - - public static final PayTypes DEFAULT = new PayTypes(PayType.NO_INFO.getDescription()); - private static final String DELIMITER = ", "; - - private String description; - - private PayTypes(String description) { - this.description = description; - } - - public static PayTypes from(Collection payTypes) { - if (payTypes.contains(PayType.NO_INFO)) { - return DEFAULT; - } - - return new PayTypes(payTypes.stream() - .map(PayType::getDescription) - .sorted() - .collect(Collectors.joining(DELIMITER)) - ); - } - - public boolean contains(List memberPayTypes) { - if (this.description.equals(DEFAULT.description)) { - return true; - } - return memberPayTypes.stream() - .anyMatch(payType -> this.description.contains(payType.getDescription())); - } -} diff --git a/domain/src/main/java/com/parkingcomestrue/common/domain/parking/dto/ParkingQueryCondition.java b/domain/src/main/java/com/parkingcomestrue/common/domain/parking/dto/ParkingQueryCondition.java deleted file mode 100644 index fd8ae260..00000000 --- a/domain/src/main/java/com/parkingcomestrue/common/domain/parking/dto/ParkingQueryCondition.java +++ /dev/null @@ -1,23 +0,0 @@ -package com.parkingcomestrue.common.domain.parking.dto; - -import com.parkingcomestrue.common.domain.parking.OperationType; -import com.parkingcomestrue.common.domain.parking.ParkingType; -import com.parkingcomestrue.common.domain.parking.PayTypes; -import lombok.Getter; - -@Getter -public class ParkingQueryCondition { - - private final OperationType operationType; - private final ParkingType parkingType; - private final Boolean cardEnabled; - private final PayTypes payTypes; - - public ParkingQueryCondition(OperationType operationType, ParkingType parkingType, Boolean cardEnabled, - PayTypes payTypes) { - this.operationType = operationType; - this.parkingType = parkingType; - this.cardEnabled = cardEnabled; - this.payTypes = payTypes; - } -} diff --git a/domain/src/main/java/com/parkingcomestrue/common/domain/parking/repository/ParkingRepository.java b/domain/src/main/java/com/parkingcomestrue/common/domain/parking/repository/ParkingRepository.java index 47372665..8616c896 100644 --- a/domain/src/main/java/com/parkingcomestrue/common/domain/parking/repository/ParkingRepository.java +++ b/domain/src/main/java/com/parkingcomestrue/common/domain/parking/repository/ParkingRepository.java @@ -22,7 +22,7 @@ default Parking getById(Long id) { @Query(""" SELECT p FROM Parking p - WHERE ST_Contains(ST_Buffer(:point, :radius), p.location.point) + WHERE ST_Contains(ST_Buffer(:point, :radius), p.location) """ ) List findAroundParkingLots(@Param("point") Point point, @Param("radius") int radius); @@ -30,8 +30,8 @@ WHERE ST_Contains(ST_Buffer(:point, :radius), p.location.point) @Query(""" SELECT p FROM Parking p - WHERE ST_Contains(ST_Buffer(:point, :radius), p.location.point) - ORDER BY ST_DISTANCE_SPHERE(:point, p.location.point) + WHERE ST_Contains(ST_Buffer(:point, :radius), p.location) + ORDER BY ST_DISTANCE_SPHERE(:point, p.location) """ ) List findAroundParkingLotsOrderByDistance( diff --git a/domain/src/main/java/com/parkingcomestrue/common/domain/review/Review.java b/domain/src/main/java/com/parkingcomestrue/common/domain/review/Review.java index 7f959b74..6e9d6396 100644 --- a/domain/src/main/java/com/parkingcomestrue/common/domain/review/Review.java +++ b/domain/src/main/java/com/parkingcomestrue/common/domain/review/Review.java @@ -1,15 +1,14 @@ package com.parkingcomestrue.common.domain.review; +import com.parkingcomestrue.common.domain.member.Member; import com.parkingcomestrue.common.domain.parking.Parking; +import com.parkingcomestrue.common.infra.converter.AssociationConverter; import com.parkingcomestrue.common.infra.converter.ContentConverter; -import com.parkingcomestrue.common.domain.member.Member; import com.parkingcomestrue.common.support.Association; import com.parkingcomestrue.common.support.exception.DomainException; import com.parkingcomestrue.common.support.exception.DomainExceptionInformation; -import jakarta.persistence.AttributeOverride; import jakarta.persistence.Column; import jakarta.persistence.Convert; -import jakarta.persistence.Embedded; import jakarta.persistence.Entity; import jakarta.persistence.GeneratedValue; import jakarta.persistence.GenerationType; @@ -31,12 +30,10 @@ public class Review { @GeneratedValue(strategy = GenerationType.IDENTITY) private Long id; - @Embedded - @AttributeOverride(name = "id", column = @Column(name = "parking_id")) + @Convert(converter = AssociationConverter.class) private Association parkingId; - @Embedded - @AttributeOverride(name = "id", column = @Column(name = "reviewer_id")) + @Convert(converter = AssociationConverter.class) private Association reviewerId; @Convert(converter = ContentConverter.class) diff --git a/domain/src/main/java/com/parkingcomestrue/common/domain/searchcondition/SearchCondition.java b/domain/src/main/java/com/parkingcomestrue/common/domain/searchcondition/SearchCondition.java index 043f1781..29f441ed 100644 --- a/domain/src/main/java/com/parkingcomestrue/common/domain/searchcondition/SearchCondition.java +++ b/domain/src/main/java/com/parkingcomestrue/common/domain/searchcondition/SearchCondition.java @@ -4,13 +4,12 @@ import com.parkingcomestrue.common.domain.parking.OperationType; import com.parkingcomestrue.common.domain.parking.ParkingType; import com.parkingcomestrue.common.domain.parking.PayType; +import com.parkingcomestrue.common.infra.converter.AssociationConverter; import com.parkingcomestrue.common.infra.converter.FeeTypeConverter; import com.parkingcomestrue.common.infra.converter.OperationTypeConverter; import com.parkingcomestrue.common.infra.converter.ParkingTypeConverter; import com.parkingcomestrue.common.infra.converter.PayTypeConverter; import com.parkingcomestrue.common.support.Association; -import jakarta.persistence.AttributeOverride; -import jakarta.persistence.Column; import jakarta.persistence.Convert; import jakarta.persistence.Embedded; import jakarta.persistence.Entity; @@ -33,8 +32,7 @@ public class SearchCondition { @GeneratedValue(strategy = GenerationType.IDENTITY) private Long id; - @Embedded - @AttributeOverride(name = "id", column = @Column(name = "member_id")) + @Convert(converter = AssociationConverter.class) private Association memberId; @Convert(converter = OperationTypeConverter.class) diff --git a/domain/src/main/java/com/parkingcomestrue/common/infra/converter/AssociationConverter.java b/domain/src/main/java/com/parkingcomestrue/common/infra/converter/AssociationConverter.java new file mode 100644 index 00000000..13f07f8f --- /dev/null +++ b/domain/src/main/java/com/parkingcomestrue/common/infra/converter/AssociationConverter.java @@ -0,0 +1,19 @@ +package com.parkingcomestrue.common.infra.converter; + +import com.parkingcomestrue.common.support.Association; +import jakarta.persistence.AttributeConverter; +import jakarta.persistence.Converter; + +@Converter +public class AssociationConverter implements AttributeConverter { + + @Override + public Long convertToDatabaseColumn(Association attribute) { + return attribute.getId(); + } + + @Override + public Association convertToEntityAttribute(Long dbData) { + return Association.from(dbData); + } +} diff --git a/domain/src/main/java/com/parkingcomestrue/common/infra/converter/FeeConverter.java b/domain/src/main/java/com/parkingcomestrue/common/infra/converter/FeeConverter.java new file mode 100644 index 00000000..a14f4d55 --- /dev/null +++ b/domain/src/main/java/com/parkingcomestrue/common/infra/converter/FeeConverter.java @@ -0,0 +1,19 @@ +package com.parkingcomestrue.common.infra.converter; + +import com.parkingcomestrue.common.domain.parking.Fee; +import jakarta.persistence.AttributeConverter; +import jakarta.persistence.Converter; + +@Converter +public class FeeConverter implements AttributeConverter { + + @Override + public Integer convertToDatabaseColumn(Fee attribute) { + return attribute.getFee(); + } + + @Override + public Fee convertToEntityAttribute(Integer dbData) { + return Fee.from(dbData); + } +} diff --git a/domain/src/main/java/com/parkingcomestrue/common/infra/converter/LocationConverter.java b/domain/src/main/java/com/parkingcomestrue/common/infra/converter/LocationConverter.java new file mode 100644 index 00000000..c657ccd1 --- /dev/null +++ b/domain/src/main/java/com/parkingcomestrue/common/infra/converter/LocationConverter.java @@ -0,0 +1,20 @@ +package com.parkingcomestrue.common.infra.converter; + +import com.parkingcomestrue.common.domain.parking.Location; +import jakarta.persistence.AttributeConverter; +import jakarta.persistence.Converter; +import org.locationtech.jts.geom.Point; + +@Converter +public class LocationConverter implements AttributeConverter { + + @Override + public Point convertToDatabaseColumn(Location attribute) { + return attribute.toPoint(); + } + + @Override + public Location convertToEntityAttribute(Point dbData) { + return Location.of(dbData.getX(), dbData.getY()); + } +} diff --git a/domain/src/main/java/com/parkingcomestrue/common/infra/converter/TimeUnitConverter.java b/domain/src/main/java/com/parkingcomestrue/common/infra/converter/TimeUnitConverter.java new file mode 100644 index 00000000..890caaac --- /dev/null +++ b/domain/src/main/java/com/parkingcomestrue/common/infra/converter/TimeUnitConverter.java @@ -0,0 +1,19 @@ +package com.parkingcomestrue.common.infra.converter; + +import com.parkingcomestrue.common.domain.parking.TimeUnit; +import jakarta.persistence.AttributeConverter; +import jakarta.persistence.Converter; + +@Converter +public class TimeUnitConverter implements AttributeConverter { + + @Override + public Integer convertToDatabaseColumn(TimeUnit attribute) { + return attribute.getTimeUnit(); + } + + @Override + public TimeUnit convertToEntityAttribute(Integer dbData) { + return TimeUnit.from(dbData); + } +} diff --git a/domain/src/main/resources/db/migration/mysql/V4.0.1__change_column_name.sql b/domain/src/main/resources/db/migration/mysql/V4.0.1__change_column_name.sql new file mode 100644 index 00000000..6c3cad66 --- /dev/null +++ b/domain/src/main/resources/db/migration/mysql/V4.0.1__change_column_name.sql @@ -0,0 +1,3 @@ +ALTER TABLE parking + CHANGE COLUMN point location GEOMETRY, + CHANGE COLUMN description pay_types VARCHAR(255); diff --git a/domain/src/test/java/com/parkingcomestrue/common/domain/parking/BaseInformationTest.java b/domain/src/test/java/com/parkingcomestrue/common/domain/parking/BaseInformationTest.java deleted file mode 100644 index ac00ab36..00000000 --- a/domain/src/test/java/com/parkingcomestrue/common/domain/parking/BaseInformationTest.java +++ /dev/null @@ -1,17 +0,0 @@ -package com.parkingcomestrue.common.domain.parking; - -import com.parkingcomestrue.common.domain.parking.PayType; -import com.parkingcomestrue.common.domain.parking.PayTypes; -import java.util.List; -import org.assertj.core.api.Assertions; -import org.junit.jupiter.api.Test; - -class BaseInformationTest { - - @Test - void 결제_방식_포함_여부를_확인한다() { - PayTypes defaultPayTypes = PayTypes.from(List.of(PayType.NO_INFO)); - - Assertions.assertThat(defaultPayTypes.contains(List.of(PayType.CARD))).isTrue(); - } -} diff --git a/domain/src/test/java/com/parkingcomestrue/common/domain/parking/PayTypesTest.java b/domain/src/test/java/com/parkingcomestrue/common/domain/parking/PayTypesTest.java deleted file mode 100644 index a7522149..00000000 --- a/domain/src/test/java/com/parkingcomestrue/common/domain/parking/PayTypesTest.java +++ /dev/null @@ -1,67 +0,0 @@ -package com.parkingcomestrue.common.domain.parking; - -import static com.parkingcomestrue.common.domain.parking.PayType.BANK_TRANSFER; -import static com.parkingcomestrue.common.domain.parking.PayType.CARD; -import static com.parkingcomestrue.common.domain.parking.PayType.CASH; -import static com.parkingcomestrue.common.domain.parking.PayType.NO_INFO; -import static org.assertj.core.api.Assertions.assertThat; -import static org.junit.jupiter.params.provider.Arguments.arguments; - -import com.parkingcomestrue.common.domain.parking.PayType; -import com.parkingcomestrue.common.domain.parking.PayTypes; -import java.util.Collection; -import java.util.List; -import java.util.Set; -import java.util.stream.Stream; -import org.junit.jupiter.api.DisplayNameGeneration; -import org.junit.jupiter.api.DisplayNameGenerator; -import org.junit.jupiter.api.Test; -import org.junit.jupiter.params.ParameterizedTest; -import org.junit.jupiter.params.provider.Arguments; -import org.junit.jupiter.params.provider.MethodSource; - -@DisplayNameGeneration(DisplayNameGenerator.ReplaceUnderscores.class) -class PayTypesTest { - - @ParameterizedTest - @MethodSource("parametersProvider") - void 열거형으로_결제방식을_생성한다(Collection payTypes, String expected) { - //given, when - PayTypes actual = PayTypes.from(payTypes); - - //then - assertThat(actual.getDescription()).isEqualTo(expected); - } - - @Test - void 결제방식_포함_시_true() { - //given, when - PayTypes actual = PayTypes.from(List.of(CARD, CASH)); - - //then - assertThat(actual.contains(List.of(CARD))).isTrue(); - } - - @Test - void 결제방식_미포함_시_false() { - //given, when - PayTypes actual = PayTypes.from(List.of(CARD, CASH)); - - //then - assertThat(actual.contains(List.of(BANK_TRANSFER))).isFalse(); - } - - static Stream parametersProvider() { - final String DELIMITER = ", "; - return Stream.of( - arguments(Set.of(CARD), CARD.getDescription()), - arguments(Set.of(CARD, CASH), CARD.getDescription() + DELIMITER + CASH.getDescription()), - arguments(Set.of(CARD, CASH, BANK_TRANSFER), - BANK_TRANSFER.getDescription() + DELIMITER + CARD.getDescription() + DELIMITER - + CASH.getDescription()), - arguments(Set.of(CARD, CASH, BANK_TRANSFER, NO_INFO), NO_INFO.getDescription()) - ); - } -} - - diff --git a/domain/src/test/java/com/parkingcomestrue/common/domain/parking/service/ParkingFilteringServiceTest.java b/domain/src/test/java/com/parkingcomestrue/common/domain/parking/service/ParkingFilteringServiceTest.java index 91857ef5..52addc89 100644 --- a/domain/src/test/java/com/parkingcomestrue/common/domain/parking/service/ParkingFilteringServiceTest.java +++ b/domain/src/test/java/com/parkingcomestrue/common/domain/parking/service/ParkingFilteringServiceTest.java @@ -11,10 +11,8 @@ import com.parkingcomestrue.common.domain.parking.ParkingFeeCalculator; import com.parkingcomestrue.common.domain.parking.ParkingType; import com.parkingcomestrue.common.domain.parking.PayType; -import com.parkingcomestrue.common.domain.parking.PayTypes; import com.parkingcomestrue.common.domain.parking.SearchingCondition; import com.parkingcomestrue.common.domain.parking.TimeUnit; -import com.parkingcomestrue.common.domain.parking.service.ParkingFilteringService; import com.parkingcomestrue.common.domain.searchcondition.FeeType; import java.time.LocalDateTime; import java.util.List; @@ -31,25 +29,24 @@ class ParkingFilteringServiceTest { // given ParkingType parkingTypeCondition = ParkingType.MECHANICAL; OperationType operationTypeCondition = OperationType.PUBLIC; - PayType wantPayType = PayType.CASH; Parking wantParking = Parking.builder() .baseInformation(new BaseInformation("name", "tell", "address", - PayTypes.from(List.of(wantPayType)), + List.of(PayType.CASH), parkingTypeCondition, operationTypeCondition)) .build(); Parking notWantParking1 = Parking.builder() .baseInformation(new BaseInformation("name", "tell", "address", - PayTypes.DEFAULT, + List.of(PayType.NO_INFO), parkingTypeCondition, OperationType.NO_INFO)) .build(); Parking notWantParking2 = Parking.builder() .baseInformation(new BaseInformation("name", "tell", "address", - PayTypes.DEFAULT, + List.of(PayType.NO_INFO), ParkingType.OFF_STREET, operationTypeCondition)) .build(); @@ -58,7 +55,7 @@ class ParkingFilteringServiceTest { SearchingCondition searchingCondition = new SearchingCondition( List.of(operationTypeCondition), List.of(parkingTypeCondition), - List.of(wantPayType), + List.of(PayType.CASH), FeeType.PAID, 3); List filterList = parkingFilteringService.filterByCondition( @@ -76,25 +73,24 @@ class ParkingFilteringServiceTest { // given ParkingType wantParkingTypeCondition = ParkingType.ON_STREET; OperationType wantOperationTypeCondition = OperationType.PUBLIC; - PayType wantPayType = PayType.CARD; Parking wantParking = Parking.builder() .baseInformation(new BaseInformation("name", "tel", "address", - PayTypes.from(List.of(wantPayType)), + List.of(PayType.CARD), wantParkingTypeCondition, wantOperationTypeCondition)) .build(); Parking notWantParking1 = Parking.builder() .baseInformation(new BaseInformation("name", "tel", "address", - PayTypes.DEFAULT, + List.of(PayType.NO_INFO), ParkingType.MECHANICAL, wantOperationTypeCondition)) .build(); Parking notWantParking2 = Parking.builder() .baseInformation(new BaseInformation("name", "tel", "address", - PayTypes.DEFAULT, + List.of(PayType.NO_INFO), ParkingType.NO_INFO, wantOperationTypeCondition)) .build(); @@ -103,7 +99,7 @@ class ParkingFilteringServiceTest { SearchingCondition searchingCondition = new SearchingCondition( List.of(wantOperationTypeCondition), List.of(wantParkingTypeCondition), - List.of(wantPayType), + List.of(PayType.CARD), FeeType.PAID, 3); List result = parkingFilteringService.filterByCondition( @@ -124,7 +120,7 @@ class ParkingFilteringServiceTest { OperationType operationType = OperationType.PUBLIC; ParkingType parkingType = ParkingType.MECHANICAL; BaseInformation baseInformation = new BaseInformation("name", "tel", "address", - PayTypes.from(List.of(PayType.CARD)), + List.of(PayType.CARD), parkingType, operationType ); @@ -160,4 +156,68 @@ class ParkingFilteringServiceTest { // then Assertions.assertThat(filteredParkings).hasSize(2); } + + @Test + void 결제방식을_기본값으로_조회시_모든_결제방식의_주차장이_조회된다() { + // given + OperationType operationType = OperationType.PUBLIC; + ParkingType parkingType = ParkingType.MECHANICAL; + BaseInformation onlyCard = new BaseInformation("name", "tel", "address", + List.of(PayType.CARD), + parkingType, + operationType + ); + + BaseInformation cardAndCash = new BaseInformation("name", "tel", "address", + List.of(PayType.CARD, PayType.CASH), + parkingType, + operationType + ); + + BaseInformation bankTransfer = new BaseInformation("name", "tel", "address", + List.of(PayType.BANK_TRANSFER), + parkingType, + operationType + ); + + BaseInformation noInfo = new BaseInformation("name", "tel", "address", + List.of(PayType.NO_INFO), + parkingType, + operationType + ); + + Parking parking1 = Parking.builder() + .baseInformation(onlyCard) + .build(); + + Parking parking2 = Parking.builder() + .baseInformation(cardAndCash) + .build(); + + Parking parking3 = Parking.builder() + .baseInformation(cardAndCash) + .build(); + + Parking parking4 = Parking.builder() + .baseInformation(bankTransfer) + .build(); + + Parking parking5 = Parking.builder() + .baseInformation(noInfo) + .build(); + + + + // when - 결제 방식을 기본 값(NO_INFO)으로 주차장 필터링 + SearchingCondition searchingCondition = new SearchingCondition(List.of(operationType), List.of(parkingType), + List.of(PayType.NO_INFO), FeeType.PAID, 3); + List filteredParkings = parkingFilteringService.filterByCondition( + List.of(parking1, parking2, parking3, parking4, parking5), + searchingCondition, + LocalDateTime.now() + ); + + // then + Assertions.assertThat(filteredParkings).hasSize(5); + } } diff --git a/domain/src/testFixtures/java/repository/BasicParkingRepository.java b/domain/src/testFixtures/java/repository/BasicParkingRepository.java index f4b0dd52..e49f9e22 100644 --- a/domain/src/testFixtures/java/repository/BasicParkingRepository.java +++ b/domain/src/testFixtures/java/repository/BasicParkingRepository.java @@ -9,7 +9,7 @@ import com.parkingcomestrue.common.domain.parking.OperationType; import com.parkingcomestrue.common.domain.parking.Parking; import com.parkingcomestrue.common.domain.parking.ParkingType; -import com.parkingcomestrue.common.domain.parking.PayTypes; +import com.parkingcomestrue.common.domain.parking.PayType; import com.parkingcomestrue.common.domain.parking.Space; import com.parkingcomestrue.common.domain.parking.TimeUnit; import com.parkingcomestrue.common.domain.parking.repository.ParkingRepository; @@ -67,10 +67,11 @@ public List saveAndGet(int size) { LinkedList result = new LinkedList<>(); for (int i = 0; i < size; i++) { Parking parking = new Parking( - new BaseInformation("not offer parking" + i, "051-000" + i, "부산시 어딘가 " + i, PayTypes.DEFAULT, + new BaseInformation("not offer parking" + i, "051-000" + i, "부산시 어딘가 " + i, + List.of(PayType.NO_INFO), ParkingType.NO_INFO, OperationType.PUBLIC), - Location.of("33.333" + i, "44.444" + i), + Location.of("133.333" + i, "44.444" + i), Space.of(-1, -1), FreeOperatingTime.ALWAYS_FREE, OperatingTime.ALWAYS_OPEN,