Skip to content

Commit 65a2ea5

Browse files
authored
❇️ Create classes and interfaces for the Product submodule (#46)
* ➕ update .gitignore * 💻 Create all the classes and interfaces needed for the product subsection * 🔧 Effect requested changes * 💄 refactor and clean up
1 parent 1d213ac commit 65a2ea5

File tree

10 files changed

+241
-4
lines changed

10 files changed

+241
-4
lines changed

.gitignore

Lines changed: 1 addition & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -4,10 +4,7 @@ target/
44
!**/src/test/**/target/
55

66
### IntelliJ IDEA ###
7-
.idea/modules.xml
8-
.idea/jarRepositories.xml
9-
.idea/compiler.xml
10-
.idea/libraries/
7+
.idea/
118
*.iws
129
*.iml
1310
*.ipr

paystack-clients-spring-boot-starter/src/main/java/com/chrisworks/paystackclients/definitions/Constants.java

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -7,4 +7,5 @@ private Constants() {}
77
static final String PLAN_CLIENT = "plan-client";
88
static final String APPLE_PAY_CLIENT = "apple-pay-client";
99
static final String TRANSACTION_CLIENT = "transaction-client";
10+
static final String PRODUCT_CLIENT = "product-client";
1011
}
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,37 @@
1+
package com.chrisworks.paystackclients.definitions;
2+
3+
import com.chrisworks.paystackclient.domain.product.CreateOrUpdateProductRequest;
4+
import com.chrisworks.paystackclient.domain.product.ProductResponse;
5+
import com.chrisworks.paystackclient.domain.request.QueryParamConstants;
6+
import com.maciejwalkowiak.spring.http.annotation.HttpClient;
7+
import org.springframework.lang.NonNull;
8+
import org.springframework.web.bind.annotation.PathVariable;
9+
import org.springframework.web.bind.annotation.RequestBody;
10+
import org.springframework.web.bind.annotation.RequestParam;
11+
import org.springframework.web.service.annotation.GetExchange;
12+
import org.springframework.web.service.annotation.PostExchange;
13+
import org.springframework.web.service.annotation.PutExchange;
14+
15+
import java.math.BigInteger;
16+
import java.time.ZonedDateTime;
17+
18+
@HttpClient(Constants.PRODUCT_CLIENT)
19+
public interface ProductClient {
20+
21+
@PostExchange
22+
ProductResponse.Single createProduct(@RequestBody CreateOrUpdateProductRequest body);
23+
24+
@GetExchange
25+
ProductResponse.Multiple listProducts(
26+
@RequestParam(name = QueryParamConstants.PAGE) @NonNull BigInteger page,
27+
@RequestParam(name = QueryParamConstants.PER_PAGE) @NonNull BigInteger perPage,
28+
@RequestParam(name = QueryParamConstants.FROM, required = false)ZonedDateTime from,
29+
@RequestParam(name = QueryParamConstants.TO, required = false)ZonedDateTime to
30+
);
31+
32+
@GetExchange("/{id}")
33+
ProductResponse.Single fetchProduct(@PathVariable String id);
34+
35+
@PutExchange("/{id}")
36+
ProductResponse.Multiple updateProduct(@PathVariable String id);
37+
}

paystack-clients-spring-boot-starter/src/main/resources/application-paystack-clients-config.yml

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -18,6 +18,12 @@ http:
1818

1919
transaction-client:
2020
url: "${base-url}/transaction"
21+
headers:
22+
Content-Type: "application/json"
23+
Authorization: "Bearer ${paystack-client.secret-key}"
24+
25+
product-client:
26+
url: "${base-url}/product"
2127
headers:
2228
Content-Type: "application/json"
2329
Authorization: "Bearer ${paystack-client.secret-key}"

paystack-clients/src/main/java/com/chrisworks/paystackclient/PaystackClient.java

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,7 @@
22

33
import com.chrisworks.paystackclient.definitions.ApplePayClient;
44
import com.chrisworks.paystackclient.definitions.PlanClient;
5+
import com.chrisworks.paystackclient.definitions.ProductClient;
56
import com.chrisworks.paystackclient.definitions.TransactionClient;
67
import okhttp3.OkHttpClient;
78

@@ -10,6 +11,7 @@ public interface PaystackClient {
1011
ApplePayClient applePay();
1112
PlanClient plan();
1213
TransactionClient transaction();
14+
ProductClient product();
1315

1416
final class Impl extends WithConfiguredHttpClient implements PaystackClient {
1517
Impl(OkHttpClient httpClient) {
@@ -30,5 +32,10 @@ public PlanClient plan() {
3032
public TransactionClient transaction() {
3133
return new TransactionClient.Impl(httpClient);
3234
}
35+
36+
@Override
37+
public ProductClient product() {
38+
return new ProductClient.Impl(httpClient);
39+
}
3340
}
3441
}
Lines changed: 70 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,70 @@
1+
package com.chrisworks.paystackclient.definitions;
2+
3+
import com.chrisworks.paystackclient.ExecutionSpec;
4+
import com.chrisworks.paystackclient.WithConfiguredHttpClient;
5+
import com.chrisworks.paystackclient.domain.Routes;
6+
import com.chrisworks.paystackclient.domain.product.CreateOrUpdateProductRequest;
7+
import com.chrisworks.paystackclient.domain.product.ProductListQueryParam;
8+
import com.chrisworks.paystackclient.domain.product.ProductResponse;
9+
import okhttp3.OkHttpClient;
10+
import okhttp3.Request;
11+
import okhttp3.RequestBody;
12+
import org.jetbrains.annotations.NotNull;
13+
14+
public interface ProductClient {
15+
16+
ExecutionSpec<ProductResponse.Single> createProduct(CreateOrUpdateProductRequest body);
17+
18+
ExecutionSpec<ProductResponse.Multiple> listProducts(ProductListQueryParam queryParam);
19+
20+
ExecutionSpec<ProductResponse.Single> fetchProduct(@NotNull String id);
21+
22+
ExecutionSpec<ProductResponse.Single> updateProduct(@NotNull String id, CreateOrUpdateProductRequest body);
23+
24+
final class Impl extends WithConfiguredHttpClient implements ProductClient {
25+
26+
public Impl(OkHttpClient httpClient) {
27+
super(httpClient);
28+
}
29+
30+
@Override
31+
public ExecutionSpec<ProductResponse.Single> createProduct(CreateOrUpdateProductRequest body) {
32+
final Request request = new Request.Builder()
33+
.url(Routes.Product.BASE_URL)
34+
.post(RequestBody.create(body.json(), applicationJson))
35+
.build();
36+
37+
return execSpec(request, ProductResponse.Single.class);
38+
}
39+
40+
@Override
41+
public ExecutionSpec<ProductResponse.Multiple> listProducts(ProductListQueryParam queryParam) {
42+
final Request request = new Request.Builder()
43+
.url(Routes.Product.BASE_URL + safeExtractQueryParams(queryParam))
44+
.get()
45+
.build();
46+
47+
return execSpec(request, ProductResponse.Multiple.class);
48+
}
49+
50+
@Override
51+
public ExecutionSpec<ProductResponse.Single> fetchProduct(@NotNull String id) {
52+
final Request request = new Request.Builder()
53+
.url(Routes.Product.BY_ID.apply(id))
54+
.get()
55+
.build();
56+
57+
return execSpec(request, ProductResponse.Single.class);
58+
}
59+
60+
@Override
61+
public ExecutionSpec<ProductResponse.Single> updateProduct(@NotNull String id, CreateOrUpdateProductRequest body) {
62+
final Request request = new Request.Builder()
63+
.url(Routes.Product.BY_ID.apply(id))
64+
.put(RequestBody.create(body.json(), applicationJson))
65+
.build();
66+
67+
return execSpec(request, ProductResponse.Single.class);
68+
}
69+
}
70+
}

paystack-domain/src/main/java/com/chrisworks/paystackclient/domain/Routes.java

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -32,4 +32,10 @@ private Transaction() {}
3232
public static final UnaryOperator<String> VIEW_TIMELINE_URL = (BASE_URL + "/timeline/%s")::formatted;
3333
public static final UnaryOperator<String> VERIFY_TRANSACTION_URL = (BASE_URL + "/verify/%s")::formatted;
3434
}
35+
36+
public static final class Product {
37+
private Product(){}
38+
public static final String BASE_URL = Routes.BASE_URL + "/product";
39+
public static final UnaryOperator<String> BY_ID = (BASE_URL + "/%s")::formatted;
40+
}
3541
}
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,54 @@
1+
package com.chrisworks.paystackclient.domain.product;
2+
3+
import com.chrisworks.paystackclient.domain.Amount;
4+
import com.chrisworks.paystackclient.domain.request.RequestBody;
5+
6+
public class CreateOrUpdateProductRequest implements RequestBody<CreateOrUpdateProductRequest> {
7+
private final String name;
8+
private final String description;
9+
private final String price;
10+
private final String currency;
11+
private boolean unlimited;
12+
private Integer quantity;
13+
14+
public CreateOrUpdateProductRequest(String name, String description, Amount price){
15+
this.name = name;
16+
this.description = description;
17+
this.price = price.getUnitValue();
18+
this.currency = price.getCurrency().name();
19+
}
20+
21+
public String getName() {
22+
return name;
23+
}
24+
25+
public String getDescription() {
26+
return description;
27+
}
28+
29+
public String getPrice() {
30+
return price;
31+
}
32+
33+
public String getCurrency() {
34+
return currency;
35+
}
36+
37+
public boolean isUnlimited() {
38+
return unlimited;
39+
}
40+
41+
public Integer getQuantity() {
42+
return quantity;
43+
}
44+
45+
public CreateOrUpdateProductRequest unlimited(boolean unlimited) {
46+
this.unlimited = unlimited;
47+
return this;
48+
}
49+
50+
public CreateOrUpdateProductRequest quantity(Integer quantity) {
51+
this.quantity = quantity;
52+
return this;
53+
}
54+
}
Lines changed: 28 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,28 @@
1+
package com.chrisworks.paystackclient.domain.product;
2+
3+
import com.chrisworks.paystackclient.domain.request.PaystackListPagedQueryParam;
4+
import com.chrisworks.paystackclient.domain.request.QueryParamConstants;
5+
6+
import java.math.BigInteger;
7+
import java.time.ZonedDateTime;
8+
9+
public final class ProductListQueryParam extends PaystackListPagedQueryParam {
10+
11+
public ProductListQueryParam(BigInteger perPage, BigInteger page) {
12+
super(perPage, page);
13+
}
14+
15+
public ProductListQueryParam(){
16+
super();
17+
}
18+
19+
public ProductListQueryParam from(ZonedDateTime from){
20+
params.put(QueryParamConstants.FROM, from.toString());
21+
return this;
22+
}
23+
24+
public ProductListQueryParam to(ZonedDateTime to){
25+
params.put(QueryParamConstants.TO, to.toString());
26+
return this;
27+
}
28+
}
Lines changed: 31 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,31 @@
1+
package com.chrisworks.paystackclient.domain.product;
2+
3+
import com.chrisworks.paystackclient.domain.Amount;
4+
import com.chrisworks.paystackclient.domain.Currency;
5+
import com.chrisworks.paystackclient.domain.response.PaystackMultiResponse;
6+
import com.chrisworks.paystackclient.domain.response.PaystackSingleResponse;
7+
8+
import java.math.BigInteger;
9+
import java.time.ZonedDateTime;
10+
import java.util.List;
11+
12+
public record ProductResponse(String name, String description, Currency currency, Amount.MoneyValue price,
13+
Integer quantity, boolean is_shippable, boolean unlimited, BigInteger integration,
14+
String domain, Object metadata, String slug, String product_code, Integer quantity_sold,
15+
String type, Object shipping_fields, boolean active, boolean in_stock,
16+
Integer minimum_orderable, Integer maximum_orderable, boolean low_stock_alert,
17+
BigInteger id, ZonedDateTime createdAt, ZonedDateTime updatedAt) {
18+
19+
public Amount getPrice() {
20+
return this.price.ofCurrency(this.currency);
21+
}
22+
23+
public record Single(boolean status, String message, ProductResponse data)
24+
implements PaystackSingleResponse<ProductResponse> {
25+
}
26+
27+
public record Multiple(boolean status, String message, List<ProductResponse> data, PageMetaInfo.Impl meta)
28+
implements PaystackMultiResponse<ProductResponse> {
29+
}
30+
31+
}

0 commit comments

Comments
 (0)