diff --git a/src/main/kotlin/com/ecwid/apiclient/v3/ApiClient.kt b/src/main/kotlin/com/ecwid/apiclient/v3/ApiClient.kt index f8a67ccca..7d99d8c7c 100644 --- a/src/main/kotlin/com/ecwid/apiclient/v3/ApiClient.kt +++ b/src/main/kotlin/com/ecwid/apiclient/v3/ApiClient.kt @@ -25,6 +25,8 @@ import com.ecwid.apiclient.v3.dto.instantsite.redirects.request.* import com.ecwid.apiclient.v3.dto.instantsite.redirects.result.* import com.ecwid.apiclient.v3.dto.order.request.* import com.ecwid.apiclient.v3.dto.order.result.* +import com.ecwid.apiclient.v3.dto.productreview.request.* +import com.ecwid.apiclient.v3.dto.productreview.result.* import com.ecwid.apiclient.v3.dto.producttype.request.* import com.ecwid.apiclient.v3.dto.producttype.result.* import com.ecwid.apiclient.v3.dto.report.request.ReportRequest @@ -64,6 +66,7 @@ open class ApiClient private constructor( subscriptionsApiClient: SubscriptionsApiClientImpl, instantSiteRedirectsApiClient: InstantSiteRedirectsApiClientImpl, slugInfoApiClient: SlugInfoApiClientImpl, + productReviewsApiClient: ProductReviewsApiClientImpl, ) : StoreProfileApiClient by storeProfileApiClient, ProductsApiClient by productsApiClient, @@ -82,7 +85,8 @@ open class ApiClient private constructor( ReportsApiClient by reportsApiClient, SubscriptionsApiClient by subscriptionsApiClient, InstantSiteRedirectsApiClient by instantSiteRedirectsApiClient, - SlugInfoApiClient by slugInfoApiClient { + SlugInfoApiClient by slugInfoApiClient, + ProductReviewsApiClient by productReviewsApiClient { constructor(apiClientHelper: ApiClientHelper) : this( apiClientHelper = apiClientHelper, @@ -104,6 +108,7 @@ open class ApiClient private constructor( subscriptionsApiClient = SubscriptionsApiClientImpl(apiClientHelper), instantSiteRedirectsApiClient = InstantSiteRedirectsApiClientImpl(apiClientHelper), slugInfoApiClient = SlugInfoApiClientImpl(apiClientHelper), + productReviewsApiClient = ProductReviewsApiClientImpl(apiClientHelper), ) companion object { @@ -291,3 +296,12 @@ interface InstantSiteRedirectsApiClient { interface SlugInfoApiClient { fun getSlugInfo(request: SlugInfoRequest): FetchedSlugInfo } + +// Product reviews +interface ProductReviewsApiClient { + fun searchProductReviews(request: ProductReviewsSearchRequest): ProductReviewSearchResult + fun searchProductReviewsAsSequence(request: ProductReviewsSearchRequest): Sequence + fun getProductReviewDetails(request: ProductReviewDetailsRequest): FetchedProductReview + fun updateProductReviewStatus(request: ProductReviewUpdateStatusRequest): ProductReviewUpdateStatusResult + fun deleteProductReview(request: ProductReviewDeleteRequest): ProductReviewDeleteResult +} diff --git a/src/main/kotlin/com/ecwid/apiclient/v3/dto/productreview/enums/ProductReviewSortOrder.kt b/src/main/kotlin/com/ecwid/apiclient/v3/dto/productreview/enums/ProductReviewSortOrder.kt new file mode 100644 index 000000000..c29fbc5e9 --- /dev/null +++ b/src/main/kotlin/com/ecwid/apiclient/v3/dto/productreview/enums/ProductReviewSortOrder.kt @@ -0,0 +1,9 @@ +package com.ecwid.apiclient.v3.dto.productreview.enums + +@Suppress("unused") +enum class ProductReviewSortOrder { + DATE_CREATED_ASC, + DATE_CREATED_DESC, + RATING_ASC, + RATING_DESC, +} diff --git a/src/main/kotlin/com/ecwid/apiclient/v3/dto/productreview/enums/ProductReviewStatus.kt b/src/main/kotlin/com/ecwid/apiclient/v3/dto/productreview/enums/ProductReviewStatus.kt new file mode 100644 index 000000000..18953e5bd --- /dev/null +++ b/src/main/kotlin/com/ecwid/apiclient/v3/dto/productreview/enums/ProductReviewStatus.kt @@ -0,0 +1,7 @@ +package com.ecwid.apiclient.v3.dto.productreview.enums + +@Suppress("unused") +enum class ProductReviewStatus { + MODERATED, + PUBLISHED, +} diff --git a/src/main/kotlin/com/ecwid/apiclient/v3/dto/productreview/request/ProductReviewDeleteRequest.kt b/src/main/kotlin/com/ecwid/apiclient/v3/dto/productreview/request/ProductReviewDeleteRequest.kt new file mode 100644 index 000000000..afd775544 --- /dev/null +++ b/src/main/kotlin/com/ecwid/apiclient/v3/dto/productreview/request/ProductReviewDeleteRequest.kt @@ -0,0 +1,15 @@ +package com.ecwid.apiclient.v3.dto.productreview.request + +import com.ecwid.apiclient.v3.dto.ApiRequest +import com.ecwid.apiclient.v3.impl.RequestInfo + +data class ProductReviewDeleteRequest( + val reviewId: Int = 0 +) : ApiRequest { + override fun toRequestInfo() = RequestInfo.createDeleteRequest( + pathSegments = listOf( + "reviews", + "$reviewId" + ) + ) +} diff --git a/src/main/kotlin/com/ecwid/apiclient/v3/dto/productreview/request/ProductReviewDetailsRequest.kt b/src/main/kotlin/com/ecwid/apiclient/v3/dto/productreview/request/ProductReviewDetailsRequest.kt new file mode 100644 index 000000000..db1d317cf --- /dev/null +++ b/src/main/kotlin/com/ecwid/apiclient/v3/dto/productreview/request/ProductReviewDetailsRequest.kt @@ -0,0 +1,18 @@ +package com.ecwid.apiclient.v3.dto.productreview.request + +import com.ecwid.apiclient.v3.dto.ApiRequest +import com.ecwid.apiclient.v3.impl.RequestInfo +import com.ecwid.apiclient.v3.responsefields.ResponseFields + +data class ProductReviewDetailsRequest( + val reviewId: Int = 0, + val responseFields: ResponseFields = ResponseFields.All, +) : ApiRequest { + override fun toRequestInfo() = RequestInfo.createGetRequest( + pathSegments = listOf( + "reviews", + "$reviewId" + ), + responseFields = responseFields, + ) +} diff --git a/src/main/kotlin/com/ecwid/apiclient/v3/dto/productreview/request/ProductReviewUpdateStatusRequest.kt b/src/main/kotlin/com/ecwid/apiclient/v3/dto/productreview/request/ProductReviewUpdateStatusRequest.kt new file mode 100644 index 000000000..e785a3ce7 --- /dev/null +++ b/src/main/kotlin/com/ecwid/apiclient/v3/dto/productreview/request/ProductReviewUpdateStatusRequest.kt @@ -0,0 +1,21 @@ +package com.ecwid.apiclient.v3.dto.productreview.request + +import com.ecwid.apiclient.v3.dto.ApiRequest +import com.ecwid.apiclient.v3.httptransport.HttpBody +import com.ecwid.apiclient.v3.impl.RequestInfo + +data class ProductReviewUpdateStatusRequest( + val reviewId: Int = 0, + val status: UpdatedProductReviewStatus = UpdatedProductReviewStatus(), +) : ApiRequest { + override fun toRequestInfo() = RequestInfo.createPutRequest( + pathSegments = listOf( + "reviews", + "$reviewId", + ), + params = mapOf(), + httpBody = HttpBody.JsonBody( + obj = status + ) + ) +} diff --git a/src/main/kotlin/com/ecwid/apiclient/v3/dto/productreview/request/ProductReviewsSearchRequest.kt b/src/main/kotlin/com/ecwid/apiclient/v3/dto/productreview/request/ProductReviewsSearchRequest.kt new file mode 100644 index 000000000..305cc6ea3 --- /dev/null +++ b/src/main/kotlin/com/ecwid/apiclient/v3/dto/productreview/request/ProductReviewsSearchRequest.kt @@ -0,0 +1,54 @@ +package com.ecwid.apiclient.v3.dto.productreview.request + +import com.ecwid.apiclient.v3.dto.ApiRequest +import com.ecwid.apiclient.v3.dto.common.PagingRequest +import com.ecwid.apiclient.v3.dto.productreview.enums.ProductReviewSortOrder +import com.ecwid.apiclient.v3.dto.productreview.enums.ProductReviewStatus +import com.ecwid.apiclient.v3.impl.RequestInfo +import com.ecwid.apiclient.v3.responsefields.ResponseFields +import java.time.Instant + +data class ProductReviewsSearchRequest( + val reviewId: String? = null, + val productId: String? = null, + val orderId: String? = null, + val status: ProductReviewStatus? = null, + val rating: Int? = null, + val createdFrom: Instant? = null, + val createdTo: Instant? = null, + val updatedFrom: Instant? = null, + val updatedTo: Instant? = null, + val sortBy: ProductReviewSortOrder? = null, + val limit: Int = 100, + override val offset: Int = 0, + val responseFields: ResponseFields = ResponseFields.All, +) : ApiRequest, PagingRequest { + override fun toRequestInfo() = RequestInfo.createGetRequest( + pathSegments = listOf( + "reviews" + ), + params = toParams(), + responseFields = responseFields, + ) + + private fun toParams(): Map { + val request = this + return mutableMapOf().apply { + request.reviewId?.let { put("reviewId", it) } + request.productId?.let { put("productId", it) } + request.orderId?.let { put("orderId", it) } + request.status?.let { put("status", it.toString()) } + request.rating?.let { put("rating", it.toString()) } + request.createdFrom?.let { put("createdFrom", it.toString()) } + request.createdTo?.let { put("createdTo", it.toString()) } + request.updatedFrom?.let { put("updatedFrom", it.toString()) } + request.updatedTo?.let { put("updatedTo", it.toString()) } + request.sortBy?.let { put("sortBy", it.name) } + put("offset", request.offset.toString()) + put("limit", request.limit.toString()) + }.toMap() + } + + override fun copyWithOffset(offset: Int) = copy(offset = offset) + +} diff --git a/src/main/kotlin/com/ecwid/apiclient/v3/dto/productreview/request/UpdatedProductReviewStatus.kt b/src/main/kotlin/com/ecwid/apiclient/v3/dto/productreview/request/UpdatedProductReviewStatus.kt new file mode 100644 index 000000000..552515e40 --- /dev/null +++ b/src/main/kotlin/com/ecwid/apiclient/v3/dto/productreview/request/UpdatedProductReviewStatus.kt @@ -0,0 +1,8 @@ +package com.ecwid.apiclient.v3.dto.productreview.request + +import com.ecwid.apiclient.v3.dto.common.ApiRequestDTO +import com.ecwid.apiclient.v3.dto.productreview.enums.ProductReviewStatus + +data class UpdatedProductReviewStatus( + val status: ProductReviewStatus? = null +) : ApiRequestDTO diff --git a/src/main/kotlin/com/ecwid/apiclient/v3/dto/productreview/result/FetchedProductReview.kt b/src/main/kotlin/com/ecwid/apiclient/v3/dto/productreview/result/FetchedProductReview.kt new file mode 100644 index 000000000..1bbec6a63 --- /dev/null +++ b/src/main/kotlin/com/ecwid/apiclient/v3/dto/productreview/result/FetchedProductReview.kt @@ -0,0 +1,38 @@ +package com.ecwid.apiclient.v3.dto.productreview.result + +import com.ecwid.apiclient.v3.dto.common.ApiFetchedDTO +import com.ecwid.apiclient.v3.dto.common.ApiResultDTO +import com.ecwid.apiclient.v3.dto.productreview.enums.ProductReviewStatus +import java.util.* + +data class FetchedProductReview( + val id: Long? = null, + val productId: Long? = null, + val productName: String? = null, + val customerId: Long? = null, + val orderId: Long? = null, + val orderNumber: String? = null, + val orderItemId: Long? = null, + val status: ProductReviewStatus? = null, + val rating: Int? = null, + val review: String? = null, + val reviewerInfo: FetchedProductReviewerInfo? = null, + val createDate: Date? = null, + val updateDate: Date? = null, + val createTimestamp: Long? = null, + val updateTimestamp: Long? = null, +) : ApiFetchedDTO, ApiResultDTO { + + override fun getModifyKind() = + ApiFetchedDTO.ModifyKind.ReadOnly + + data class FetchedProductReviewerInfo( + val name: String? = null, + val email: String? = null, + val city: String? = null, + val country: String? = null, + val ordersCount: Int? = null, + ) + +} + diff --git a/src/main/kotlin/com/ecwid/apiclient/v3/dto/productreview/result/ProductReviewDeleteResult.kt b/src/main/kotlin/com/ecwid/apiclient/v3/dto/productreview/result/ProductReviewDeleteResult.kt new file mode 100644 index 000000000..dd4e62c20 --- /dev/null +++ b/src/main/kotlin/com/ecwid/apiclient/v3/dto/productreview/result/ProductReviewDeleteResult.kt @@ -0,0 +1,7 @@ +package com.ecwid.apiclient.v3.dto.productreview.result + +import com.ecwid.apiclient.v3.dto.common.ApiResultDTO + +data class ProductReviewDeleteResult( + val deleteCount: Int = 0 +) : ApiResultDTO diff --git a/src/main/kotlin/com/ecwid/apiclient/v3/dto/productreview/result/ProductReviewSearchResult.kt b/src/main/kotlin/com/ecwid/apiclient/v3/dto/productreview/result/ProductReviewSearchResult.kt new file mode 100644 index 000000000..00e243a9f --- /dev/null +++ b/src/main/kotlin/com/ecwid/apiclient/v3/dto/productreview/result/ProductReviewSearchResult.kt @@ -0,0 +1,11 @@ +package com.ecwid.apiclient.v3.dto.productreview.result + +import com.ecwid.apiclient.v3.dto.common.ApiResultDTO + +data class ProductReviewSearchResult( + val items: List = listOf(), + val count: Int = 0, + val total: Int = 0, + val limit: Int = 0, + val offset: Int = 0, +) : ApiResultDTO diff --git a/src/main/kotlin/com/ecwid/apiclient/v3/dto/productreview/result/ProductReviewUpdateStatusResult.kt b/src/main/kotlin/com/ecwid/apiclient/v3/dto/productreview/result/ProductReviewUpdateStatusResult.kt new file mode 100644 index 000000000..fcdde8c0c --- /dev/null +++ b/src/main/kotlin/com/ecwid/apiclient/v3/dto/productreview/result/ProductReviewUpdateStatusResult.kt @@ -0,0 +1,7 @@ +package com.ecwid.apiclient.v3.dto.productreview.result + +import com.ecwid.apiclient.v3.dto.common.ApiResultDTO + +data class ProductReviewUpdateStatusResult( + val updateCount: Int = 0 +) : ApiResultDTO diff --git a/src/main/kotlin/com/ecwid/apiclient/v3/impl/ProductReviewsApiClientImpl.kt b/src/main/kotlin/com/ecwid/apiclient/v3/impl/ProductReviewsApiClientImpl.kt new file mode 100644 index 000000000..6adfe41e4 --- /dev/null +++ b/src/main/kotlin/com/ecwid/apiclient/v3/impl/ProductReviewsApiClientImpl.kt @@ -0,0 +1,25 @@ +package com.ecwid.apiclient.v3.impl + +import com.ecwid.apiclient.v3.ApiClientHelper +import com.ecwid.apiclient.v3.ProductReviewsApiClient +import com.ecwid.apiclient.v3.dto.productreview.request.* +import com.ecwid.apiclient.v3.dto.productreview.result.* + +class ProductReviewsApiClientImpl( + private val apiClientHelper: ApiClientHelper, +) : ProductReviewsApiClient { + override fun searchProductReviews(request: ProductReviewsSearchRequest) = + apiClientHelper.makeObjectResultRequest(request) + + override fun searchProductReviewsAsSequence(request: ProductReviewsSearchRequest) = + apiClientHelper.makeObjectResultRequest>(request) + + override fun getProductReviewDetails(request: ProductReviewDetailsRequest) = + apiClientHelper.makeObjectResultRequest(request) + + override fun updateProductReviewStatus(request: ProductReviewUpdateStatusRequest) = + apiClientHelper.makeObjectResultRequest(request) + + override fun deleteProductReview(request: ProductReviewDeleteRequest) = + apiClientHelper.makeObjectResultRequest(request) +} diff --git a/src/test/kotlin/com/ecwid/apiclient/v3/rule/NullablePropertyRules.kt b/src/test/kotlin/com/ecwid/apiclient/v3/rule/NullablePropertyRules.kt index a0681e4de..560cffe6a 100644 --- a/src/test/kotlin/com/ecwid/apiclient/v3/rule/NullablePropertyRules.kt +++ b/src/test/kotlin/com/ecwid/apiclient/v3/rule/NullablePropertyRules.kt @@ -14,6 +14,7 @@ import com.ecwid.apiclient.v3.dto.product.request.ProductInventoryUpdateRequest import com.ecwid.apiclient.v3.dto.product.request.ProductUpdateRequest import com.ecwid.apiclient.v3.dto.product.result.GetProductFiltersResult import com.ecwid.apiclient.v3.dto.product.result.ProductInventoryUpdateResult +import com.ecwid.apiclient.v3.dto.productreview.request.UpdatedProductReviewStatus import com.ecwid.apiclient.v3.dto.profile.request.StoreProfileRequest import com.ecwid.apiclient.v3.dto.profile.result.FetchedLatestStats import com.ecwid.apiclient.v3.dto.report.request.ReportRequest @@ -101,6 +102,8 @@ val otherNullablePropertyRules: List> = listOf( AllowNullable(InstantSiteRedirectsSearchRequest::offset), AllowNullable(InstantSiteRedirectsGetForExactPathRequest::exactPath), + + AllowNullable(UpdatedProductReviewStatus::status), ) val nullablePropertyRules: List> = listOf( @@ -138,7 +141,9 @@ val nullablePropertyRules: List> = listOf( otherNullablePropertyRules, fetchedSlugInfoNullablePropertyRules, fetchedSlugInfoClassesNullablePropertyRules, - slugInfoRequestNullablePropertyRules + slugInfoRequestNullablePropertyRules, + fetchedProductReviewNullablePropertyRules, + productReviewsSearchRequestNullablePropertyRules, ).flatten() sealed class NullablePropertyRule( diff --git a/src/test/kotlin/com/ecwid/apiclient/v3/rule/nullablepropertyrules/FetchedProductReviewRules.kt b/src/test/kotlin/com/ecwid/apiclient/v3/rule/nullablepropertyrules/FetchedProductReviewRules.kt new file mode 100644 index 000000000..1000cd585 --- /dev/null +++ b/src/test/kotlin/com/ecwid/apiclient/v3/rule/nullablepropertyrules/FetchedProductReviewRules.kt @@ -0,0 +1,28 @@ +package com.ecwid.apiclient.v3.rule.nullablepropertyrules + +import com.ecwid.apiclient.v3.dto.productreview.result.FetchedProductReview +import com.ecwid.apiclient.v3.rule.NullablePropertyRule +import com.ecwid.apiclient.v3.rule.NullablePropertyRule.AllowNullable + +val fetchedProductReviewNullablePropertyRules: List> = listOf( + AllowNullable(FetchedProductReview::createDate), + AllowNullable(FetchedProductReview::createTimestamp), + AllowNullable(FetchedProductReview::customerId), + AllowNullable(FetchedProductReview::id), + AllowNullable(FetchedProductReview::orderId), + AllowNullable(FetchedProductReview::orderItemId), + AllowNullable(FetchedProductReview::orderNumber), + AllowNullable(FetchedProductReview::productId), + AllowNullable(FetchedProductReview::productName), + AllowNullable(FetchedProductReview::rating), + AllowNullable(FetchedProductReview::review), + AllowNullable(FetchedProductReview::reviewerInfo), + AllowNullable(FetchedProductReview::status), + AllowNullable(FetchedProductReview::updateDate), + AllowNullable(FetchedProductReview::updateTimestamp), + AllowNullable(FetchedProductReview.FetchedProductReviewerInfo::city), + AllowNullable(FetchedProductReview.FetchedProductReviewerInfo::country), + AllowNullable(FetchedProductReview.FetchedProductReviewerInfo::email), + AllowNullable(FetchedProductReview.FetchedProductReviewerInfo::name), + AllowNullable(FetchedProductReview.FetchedProductReviewerInfo::ordersCount), +) diff --git a/src/test/kotlin/com/ecwid/apiclient/v3/rule/nullablepropertyrules/ProductReviewsSearchRequestRules.kt b/src/test/kotlin/com/ecwid/apiclient/v3/rule/nullablepropertyrules/ProductReviewsSearchRequestRules.kt new file mode 100644 index 000000000..1fd1c77eb --- /dev/null +++ b/src/test/kotlin/com/ecwid/apiclient/v3/rule/nullablepropertyrules/ProductReviewsSearchRequestRules.kt @@ -0,0 +1,18 @@ +package com.ecwid.apiclient.v3.rule.nullablepropertyrules + +import com.ecwid.apiclient.v3.dto.productreview.request.ProductReviewsSearchRequest +import com.ecwid.apiclient.v3.rule.NullablePropertyRule +import com.ecwid.apiclient.v3.rule.NullablePropertyRule.AllowNullable + +val productReviewsSearchRequestNullablePropertyRules: List> = listOf( + AllowNullable(ProductReviewsSearchRequest::createdFrom), + AllowNullable(ProductReviewsSearchRequest::createdTo), + AllowNullable(ProductReviewsSearchRequest::orderId), + AllowNullable(ProductReviewsSearchRequest::productId), + AllowNullable(ProductReviewsSearchRequest::rating), + AllowNullable(ProductReviewsSearchRequest::reviewId), + AllowNullable(ProductReviewsSearchRequest::sortBy), + AllowNullable(ProductReviewsSearchRequest::status), + AllowNullable(ProductReviewsSearchRequest::updatedFrom), + AllowNullable(ProductReviewsSearchRequest::updatedTo), +)