Skip to content

Commit 4ece967

Browse files
ryankazokasdevclericuzziclericuzzi
authored
Adds mapping fix for order fulfillments (#106)
* migration to fulfillmet order api (2023-04) * javaDocs problem solved * feedback implemented * fulfillment order move response root added * feedback implemented * throwing exception if we cannot create a fulfillment * throwing exception for non supported actions * feedback implemented * removing unecessary try/catch * feedback implemented * fixing tracking url mapping * missing tests * pom version update * Updates release version --------- Co-authored-by: Pedro Clericuzzi <dev.clericuzzi@gmail.com> Co-authored-by: Pedro Clericuzzi <pedroclericuzzi@gmail.com>
1 parent dd7cd5c commit 4ece967

File tree

4 files changed

+340
-50
lines changed

4 files changed

+340
-50
lines changed

pom.xml

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -4,7 +4,7 @@
44
<modelVersion>4.0.0</modelVersion>
55
<groupId>com.channelape</groupId>
66
<artifactId>shopify-sdk</artifactId>
7-
<version>2.6.0</version>
7+
<version>2.8.0</version>
88

99
<name>Shopify SDK</name>
1010
<description>Java SDK for Shopify REST API.</description>

src/main/java/com/shopify/mappers/LegacyToFulfillmentOrderMapping.java

Lines changed: 66 additions & 49 deletions
Original file line numberDiff line numberDiff line change
@@ -27,6 +27,29 @@ public class LegacyToFulfillmentOrderMapping {
2727

2828
private static final Logger LOGGER = LoggerFactory.getLogger(LegacyToFulfillmentOrderMapping.class);
2929

30+
/**
31+
* creates the fulfillment order's tracking info based on a fulfillment
32+
* shopify fulfillment order based creation does not support a list of
33+
* tracking urls, so we're getting the first one of CA's list if available.
34+
* Otherwise we just grab the single tracking url string
35+
*
36+
* @param fulfillment
37+
* the fulfillment to be created by the fulfillment order api
38+
* @return the payload's tracking info
39+
*/
40+
private static ShopifyTrackingInfo getFulfillmentTrackingInfo(final ShopifyFulfillment fulfillment) {
41+
final ShopifyTrackingInfo trackingInfo = new ShopifyTrackingInfo();
42+
if (fulfillment.getTrackingUrls().size() > 0) {
43+
trackingInfo.setUrl(fulfillment.getTrackingUrls().get(0));
44+
} else {
45+
trackingInfo.setUrl(fulfillment.getTrackingUrl());
46+
}
47+
trackingInfo.setNumber(fulfillment.getTrackingNumber());
48+
trackingInfo.setCompany(fulfillment.getTrackingCompany());
49+
50+
return trackingInfo;
51+
}
52+
3053
/**
3154
* the idea here is to create a payload similar to what <a href=
3255
* "https://shopify.dev/docs/api/admin-rest/2023-04/resources/fulfillmentorder#post-fulfillment-orders-fulfillment-order-id-move">we
@@ -70,6 +93,14 @@ public static ShopifyFulfillmentOrderMoveRequestRoot toShopifyMoveFulfillmentOrd
7093
* have here</a>, the resulting payload will be sent to shopify via the
7194
* active ShopifySdk instance
7295
*
96+
* we need to iterate through all fulfillmentOrder line items to determine
97+
* which fulfillment order line items are going to be referenced inside the
98+
* payload's line_items_by_fulfillment_order section
99+
*
100+
* if a shopify fulfillment is cancelled a new fulfillment order is added
101+
* the old one gets it's supported actions emptied, so we need to make sure
102+
* the current fulfillmentOrder supportes fulfillment creation under it
103+
*
73104
* @see ShopifySdk
74105
* @see ShopifyFulfillmentPayloadRoot
75106
*
@@ -83,57 +114,47 @@ public static ShopifyFulfillmentOrderMoveRequestRoot toShopifyMoveFulfillmentOrd
83114
*/
84115
public static ShopifyFulfillmentPayloadRoot toShopifyFulfillmentPayloadRoot(final ShopifyFulfillment fulfillment,
85116
final List<ShopifyFulfillmentOrder> fulfillmentOrders) throws ShopifyEmptyLineItemsException {
86-
try {
87-
final ShopifyTrackingInfo trackingInfo = new ShopifyTrackingInfo();
88-
final ShopifyFulfillmentPayload payload = new ShopifyFulfillmentPayload();
89-
final List<ShopifyLineItemsByFulfillmentOrder> lineItemsByFulfillmentOrder = new LinkedList<>();
90-
91-
trackingInfo.setUrl(fulfillment.getTrackingUrl());
92-
trackingInfo.setNumber(fulfillment.getTrackingNumber());
93-
trackingInfo.setCompany(fulfillment.getTrackingCompany());
94-
95-
// here we need to iterate through all fulfillmentOrder line items
96-
// to determine which fulfillment order line items are going to be
97-
// referenced inside the payload's line_items_by_fulfillment_order
98-
// section
99-
for (final ShopifyFulfillmentOrder fulfillmentOrder : fulfillmentOrders) {
100-
// if a shopify fulfillment is cancelled a new fulfillment order
101-
// is added the old one gets it's supported actions emptied, so
102-
// we need to make sure the current fulfillmentOrder supportes
103-
// fulfillment creation under it
104-
if (fulfillmentOrder.hasSupportedAction(SupportedActions.CREATE_FULFILLMENT)) {
105-
ShopifyLineItemsByFulfillmentOrder lineItemsByFulfillment = new ShopifyLineItemsByFulfillmentOrder();
106-
lineItemsByFulfillment.setFulfillmentOrderId(fulfillmentOrder.getId());
107-
for (final ShopifyFulfillmentOrderLineItem fulfillmentOrderLineItem : fulfillmentOrder
108-
.getLineItems()) {
109-
for (final ShopifyLineItem fulfillmentLineItem : fulfillment.getLineItems()) {
110-
if (fulfillmentOrderLineItem.getLineItemId().equals(fulfillmentLineItem.getId())) {
111-
ShopifyFulfillmentOrderPayloadLineItem payloadLineItem = new ShopifyFulfillmentOrderPayloadLineItem(
112-
fulfillmentOrderLineItem.getId(), fulfillmentLineItem.getQuantity());
113-
lineItemsByFulfillment.getFulfillmentOrderLineItems().add(payloadLineItem);
114-
}
117+
final ShopifyTrackingInfo trackingInfo = getFulfillmentTrackingInfo(fulfillment);
118+
final ShopifyFulfillmentPayload payload = new ShopifyFulfillmentPayload();
119+
final List<ShopifyLineItemsByFulfillmentOrder> lineItemsByFulfillmentOrder = new LinkedList<>();
120+
121+
// here we need to iterate through all fulfillmentOrder line items
122+
// to determine which fulfillment order line items are going to be
123+
// referenced inside the payload's line_items_by_fulfillment_order
124+
// section
125+
for (final ShopifyFulfillmentOrder fulfillmentOrder : fulfillmentOrders) {
126+
// if a shopify fulfillment is cancelled a new fulfillment order
127+
// is added the old one gets it's supported actions emptied, so
128+
// we need to make sure the current fulfillmentOrder supportes
129+
// fulfillment creation under it
130+
if (fulfillmentOrder.hasSupportedAction(SupportedActions.CREATE_FULFILLMENT)) {
131+
ShopifyLineItemsByFulfillmentOrder lineItemsByFulfillment = new ShopifyLineItemsByFulfillmentOrder();
132+
lineItemsByFulfillment.setFulfillmentOrderId(fulfillmentOrder.getId());
133+
for (final ShopifyFulfillmentOrderLineItem fulfillmentOrderLineItem : fulfillmentOrder.getLineItems()) {
134+
for (final ShopifyLineItem fulfillmentLineItem : fulfillment.getLineItems()) {
135+
if (fulfillmentOrderLineItem.getLineItemId().equals(fulfillmentLineItem.getId())) {
136+
ShopifyFulfillmentOrderPayloadLineItem payloadLineItem = new ShopifyFulfillmentOrderPayloadLineItem(
137+
fulfillmentOrderLineItem.getId(), fulfillmentLineItem.getQuantity());
138+
lineItemsByFulfillment.getFulfillmentOrderLineItems().add(payloadLineItem);
115139
}
116140
}
141+
}
117142

118-
if (lineItemsByFulfillment.getFulfillmentOrderLineItems().size() > 0) {
119-
lineItemsByFulfillmentOrder.add(lineItemsByFulfillment);
120-
}
143+
if (lineItemsByFulfillment.getFulfillmentOrderLineItems().size() > 0) {
144+
lineItemsByFulfillmentOrder.add(lineItemsByFulfillment);
121145
}
122146
}
123-
if (lineItemsByFulfillmentOrder.size() < 1)
124-
throw new ShopifyEmptyLineItemsException();
147+
}
148+
if (lineItemsByFulfillmentOrder.size() < 1)
149+
throw new ShopifyEmptyLineItemsException();
125150

126-
payload.setTrackingInfo(trackingInfo);
127-
payload.setNotifyCustomer(fulfillment.isNotifyCustomer());
128-
payload.setLineItemsByFulfillmentOrder(lineItemsByFulfillmentOrder);
151+
payload.setTrackingInfo(trackingInfo);
152+
payload.setNotifyCustomer(fulfillment.isNotifyCustomer());
153+
payload.setLineItemsByFulfillmentOrder(lineItemsByFulfillmentOrder);
129154

130-
ShopifyFulfillmentPayloadRoot root = new ShopifyFulfillmentPayloadRoot();
131-
root.setFulfillment(payload);
132-
return root;
133-
} catch (final Exception e) {
134-
LOGGER.error("There was an error parsing fulfillmentOrder into a ShopifyFulfillment create payload", e);
135-
throw e;
136-
}
155+
ShopifyFulfillmentPayloadRoot root = new ShopifyFulfillmentPayloadRoot();
156+
root.setFulfillment(payload);
157+
return root;
137158
}
138159

139160
/**
@@ -153,13 +174,9 @@ public static ShopifyFulfillmentPayloadRoot toShopifyFulfillmentPayloadRoot(fina
153174
public static ShopifyUpdateFulfillmentPayloadRoot toUpdateShopifyFulfillmentPayloadRoot(
154175
final ShopifyFulfillment fulfillment) {
155176
try {
156-
final ShopifyTrackingInfo trackingInfo = new ShopifyTrackingInfo();
177+
final ShopifyTrackingInfo trackingInfo = getFulfillmentTrackingInfo(fulfillment);
157178
final ShopifyUpdateFulfillmentPayload payload = new ShopifyUpdateFulfillmentPayload();
158179

159-
trackingInfo.setUrl(fulfillment.getTrackingUrl());
160-
trackingInfo.setNumber(fulfillment.getTrackingNumber());
161-
trackingInfo.setCompany(fulfillment.getTrackingCompany());
162-
163180
payload.setTrackingInfo(trackingInfo);
164181
payload.setNotifyCustomer(fulfillment.isNotifyCustomer());
165182

src/test/java/com/shopify/ShopifySdkTest.java

Lines changed: 73 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -44,6 +44,7 @@
4444
import com.shopify.exceptions.ShopifyClientException;
4545
import com.shopify.exceptions.ShopifyEmptyLineItemsException;
4646
import com.shopify.exceptions.ShopifyErrorResponseException;
47+
import com.shopify.mappers.LegacyToFulfillmentOrderMapping;
4748
import com.shopify.mappers.ShopifySdkObjectMapper;
4849
import com.shopify.model.Count;
4950
import com.shopify.model.Image;
@@ -69,6 +70,7 @@
6970
import com.shopify.model.ShopifyFulfillmentCreationRequest;
7071
import com.shopify.model.ShopifyFulfillmentOrder;
7172
import com.shopify.model.ShopifyFulfillmentOrderLineItem;
73+
import com.shopify.model.ShopifyFulfillmentPayloadRoot;
7274
import com.shopify.model.ShopifyFulfillmentRoot;
7375
import com.shopify.model.ShopifyFulfillmentUpdateRequest;
7476
import com.shopify.model.ShopifyGetCustomersRequest;
@@ -447,6 +449,77 @@ public void givenSomeShopifyFulfillmentCreationRequestWhenCreatingShopifyFulfill
447449

448450
final ShopifyFulfillment actualShopifyFulfillment = shopifySdk.createFulfillment(request, fulfillmentOrders);
449451

452+
// making sure the tracking url mapping is correct
453+
final ShopifyFulfillmentPayloadRoot payload = LegacyToFulfillmentOrderMapping
454+
.toShopifyFulfillmentPayloadRoot(request.getRequest(), fulfillmentOrders);
455+
456+
assertEquals(payload.getFulfillment().getTrackingInfo().getUrl(), "tracking_url1");
457+
assertValidFulfillment(currentFulfillment, actualShopifyFulfillment);
458+
}
459+
460+
@Test
461+
public void givenSomeShopifyFulfillmentCreationRequestWhenCreatingShopifyFulfillmentThenCreateAndReturnFulfillmentWithFulfillmentOrderApiWithoutTrackingUrlsArray()
462+
throws JsonProcessingException, ConnectException, ShopifyEmptyLineItemsException {
463+
final String lineItemId = "987";
464+
final String fulfillmentOrderId = "1234";
465+
466+
final ShopifyLineItem lineItem = new ShopifyLineItem();
467+
lineItem.setId(lineItemId);
468+
lineItem.setSku("some_sku");
469+
lineItem.setQuantity(5L);
470+
471+
List<ShopifyFulfillmentOrderLineItem> fulfillmentOrderLineItems = new LinkedList<>();
472+
ShopifyFulfillmentOrderLineItem fulfillmentOrderLineItem = new ShopifyFulfillmentOrderLineItem();
473+
fulfillmentOrderLineItem.setQuantity(1);
474+
fulfillmentOrderLineItem.setLineItemId(lineItemId);
475+
fulfillmentOrderLineItem.setFulfillableQuantity(1);
476+
fulfillmentOrderLineItem.setFulfillmentOrderId(fulfillmentOrderId);
477+
fulfillmentOrderLineItems.add(fulfillmentOrderLineItem);
478+
479+
final List<String> supportedActions = new LinkedList<>();
480+
supportedActions.add("move");
481+
supportedActions.add("create_fulfillment");
482+
483+
final ShopifyFulfillmentOrder fulfillmentOrder = new ShopifyFulfillmentOrder();
484+
fulfillmentOrder.setId(fulfillmentOrderId);
485+
fulfillmentOrder.setLineItems(fulfillmentOrderLineItems);
486+
fulfillmentOrder.setSupportedActions(supportedActions);
487+
fulfillmentOrder.setAssignedLocationId("5678");
488+
final List<ShopifyFulfillmentOrder> fulfillmentOrders = new LinkedList<>();
489+
fulfillmentOrders.add(fulfillmentOrder);
490+
491+
final String expectedPath = new StringBuilder().append(FORWARD_SLASH).append(ShopifySdk.API_VERSION_PREFIX)
492+
.append(FORWARD_SLASH).append(SOME_API_VERSION).append(FORWARD_SLASH).append(ShopifySdk.FULFILLMENTS)
493+
.toString();
494+
final ShopifyFulfillment currentFulfillment = buildShopifyFulfillment(lineItem);
495+
final ShopifyFulfillmentRoot shopifyFulfillmentRoot = new ShopifyFulfillmentRoot();
496+
shopifyFulfillmentRoot.setFulfillment(currentFulfillment);
497+
498+
final String expectedResponseBodyString = getJsonString(ShopifyFulfillmentRoot.class, shopifyFulfillmentRoot);
499+
500+
final Status expectedStatus = Status.CREATED;
501+
final int expectedStatusCode = expectedStatus.getStatusCode();
502+
final JsonBodyCapture actualRequestBody = new JsonBodyCapture();
503+
driver.addExpectation(
504+
onRequestTo(expectedPath).withHeader(ShopifySdk.ACCESS_TOKEN_HEADER, accessToken)
505+
.withMethod(Method.POST).capturingBodyIn(actualRequestBody),
506+
giveResponse(expectedResponseBodyString, MediaType.APPLICATION_JSON).withStatus(expectedStatusCode)
507+
.withHeader(ShopifySdk.DEPRECATED_REASON_HEADER, "Call to be removed from API.")
508+
.withHeader("Location", new StringBuilder().append("https://test.myshopify.com/admin")
509+
.append(expectedPath).toString()));
510+
511+
final ShopifyFulfillmentCreationRequest request = ShopifyFulfillmentCreationRequest.newBuilder()
512+
.withOrderId("1234").withTrackingCompany("USPS").withTrackingNumber("12341234").withNotifyCustomer(true)
513+
.withLineItems(Arrays.asList(lineItem)).withLocationId("1").withTrackingUrls(Arrays.asList()).build();
514+
515+
request.getRequest().setTrackingUrl("tracking_url");
516+
final ShopifyFulfillment actualShopifyFulfillment = shopifySdk.createFulfillment(request, fulfillmentOrders);
517+
518+
// making sure the tracking url mapping is correct
519+
final ShopifyFulfillmentPayloadRoot payload = LegacyToFulfillmentOrderMapping
520+
.toShopifyFulfillmentPayloadRoot(request.getRequest(), fulfillmentOrders);
521+
522+
assertEquals(payload.getFulfillment().getTrackingInfo().getUrl(), "tracking_url");
450523
assertValidFulfillment(currentFulfillment, actualShopifyFulfillment);
451524
}
452525

0 commit comments

Comments
 (0)