diff --git a/CHANGELOG.md b/CHANGELOG.md index 362e92fd2..dfc4ace57 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -2,6 +2,7 @@ ## Next Release +- Adds new `shipment.recommendShipDate`, `smartrate.recommendShipDate`, and `smartrate.estimateDeliveryDate` functions - Routes `UpsAccount`, `UpsMailInnovationsAccount`, and `UpsSurepostAccount` create/update requests to the new `/ups_oauth_registrations` endpoint - Starting `2024-08-05`, UPS accounts will require a new payload to register or update. See [UPS OAuth 2.0 Update](https://support.easypost.com/hc/en-us/articles/26635027512717-UPS-OAuth-2-0-Update?utm_medium=email&_hsenc=p2ANqtz-96MmFtWICOzy9sKRbbcZSiMovZSrY3MSX1_bgY9N3f9yLVfWQdLhjAGq-SmNcOnDIS6GYhZ0OApjDBrGkKyLLMx1z6_TFOVp6-wllhEFQINrkuRuc&_hsmi=313130292&utm_content=313130292&utm_source=hs_email) for more details diff --git a/src/main/java/com/easypost/model/DeliveryDateForZipPairEstimate.java b/src/main/java/com/easypost/model/DeliveryDateForZipPairEstimate.java new file mode 100644 index 000000000..4a72f5a18 --- /dev/null +++ b/src/main/java/com/easypost/model/DeliveryDateForZipPairEstimate.java @@ -0,0 +1,10 @@ +package com.easypost.model; + +import lombok.Getter; + +@Getter +public class DeliveryDateForZipPairEstimate { + private String carrier; + private String service; + private TimeInTransitDetailsForDeliveryDate easypostTimeInTransitData; +} diff --git a/src/main/java/com/easypost/model/EstimateDeliveryDateForZipPairResult.java b/src/main/java/com/easypost/model/EstimateDeliveryDateForZipPairResult.java new file mode 100644 index 000000000..aa38c20a1 --- /dev/null +++ b/src/main/java/com/easypost/model/EstimateDeliveryDateForZipPairResult.java @@ -0,0 +1,14 @@ +package com.easypost.model; + +import java.util.List; +import lombok.Getter; + +@Getter +public class EstimateDeliveryDateForZipPairResult { + private Boolean saturdayDelivery; + private List results; + private List carriersWithoutTintEstimates; + private String desiredDeliveryDate; + private String fromZip; + private String toZip; +} diff --git a/src/main/java/com/easypost/model/RecommendShipDateForZipPairResult.java b/src/main/java/com/easypost/model/RecommendShipDateForZipPairResult.java new file mode 100644 index 000000000..cfb87e5a2 --- /dev/null +++ b/src/main/java/com/easypost/model/RecommendShipDateForZipPairResult.java @@ -0,0 +1,15 @@ +package com.easypost.model; + +import java.util.List; + +import lombok.Getter; + +@Getter +public class RecommendShipDateForZipPairResult { + private Boolean saturdayDelivery; + private List results; + private List carriersWithoutTintEstimates; + private String desiredDeliveryDate; + private String fromZip; + private String toZip; +} diff --git a/src/main/java/com/easypost/model/ShipDateForZipPairRecommendation.java b/src/main/java/com/easypost/model/ShipDateForZipPairRecommendation.java new file mode 100644 index 000000000..7d8716f80 --- /dev/null +++ b/src/main/java/com/easypost/model/ShipDateForZipPairRecommendation.java @@ -0,0 +1,10 @@ +package com.easypost.model; + +import lombok.Getter; + +@Getter +public class ShipDateForZipPairRecommendation { + private String carrier; + private String service; + private TimeInTransitDetailsForDeliveryDate easypostTimeInTransitData; +} diff --git a/src/main/java/com/easypost/model/TimeInTransitDetailsForDeliveryDate.java b/src/main/java/com/easypost/model/TimeInTransitDetailsForDeliveryDate.java new file mode 100644 index 000000000..4846780b5 --- /dev/null +++ b/src/main/java/com/easypost/model/TimeInTransitDetailsForDeliveryDate.java @@ -0,0 +1,12 @@ +package com.easypost.model; + +import java.util.Date; +import lombok.Getter; + +@Getter +public class TimeInTransitDetailsForDeliveryDate { + private Date shipOnDate; + private Float deliveryDateConfidence; + private int estimatedTransitDays; + private TimeInTransit daysInTransit; +} diff --git a/src/main/java/com/easypost/service/EasyPostClient.java b/src/main/java/com/easypost/service/EasyPostClient.java index cd5b5d1d9..e4c523a96 100644 --- a/src/main/java/com/easypost/service/EasyPostClient.java +++ b/src/main/java/com/easypost/service/EasyPostClient.java @@ -41,6 +41,7 @@ public class EasyPostClient { public final ReportService report; public final ScanformService scanForm; public final ShipmentService shipment; + public final SmartRateService smartRate; public final TrackerService tracker; public final UserService user; public final WebhookService webhook; @@ -150,6 +151,7 @@ public EasyPostClient(String apiKey, int connectTimeoutMilliseconds, int readTim this.report = new ReportService(this); this.scanForm = new ScanformService(this); this.shipment = new ShipmentService(this); + this.smartRate = new SmartRateService(this); this.tracker = new TrackerService(this); this.user = new UserService(this); this.webhook = new WebhookService(this); diff --git a/src/main/java/com/easypost/service/ShipmentService.java b/src/main/java/com/easypost/service/ShipmentService.java index de6160d69..5c2fe4509 100644 --- a/src/main/java/com/easypost/service/ShipmentService.java +++ b/src/main/java/com/easypost/service/ShipmentService.java @@ -461,4 +461,24 @@ public List retrieveEstimatedDeliveryDate(final String id EstimatedDeliveryDateResponse.class, client); return response.getRates(); } + + /** + * Retrieve a recommended ship date for an existing Shipment via the Precision Shipping API, + * based on a specific desired delivery date. + * + * @param id The id of the shipment. + * @param desiredDeliveryDate The desired delivery date. + * @return EstimatedDeliveryDate object. + * @throws EasyPostException When the request fails. + */ + public List recommendShipDate(final String id, final String desiredDeliveryDate) + throws EasyPostException { + HashMap params = new HashMap<>(); + params.put("desired_delivery_date", desiredDeliveryDate); + String endpoint = "shipments/" + id + "/smartrate/precision_shipping"; + + EstimatedDeliveryDateResponse response = Requestor.request(RequestMethod.GET, endpoint, params, + EstimatedDeliveryDateResponse.class, client); + return response.getRates(); + } } diff --git a/src/main/java/com/easypost/service/SmartRateService.java b/src/main/java/com/easypost/service/SmartRateService.java new file mode 100644 index 000000000..fdd92a169 --- /dev/null +++ b/src/main/java/com/easypost/service/SmartRateService.java @@ -0,0 +1,53 @@ +package com.easypost.service; + +import java.util.Map; + +import com.easypost.exception.EasyPostException; +import com.easypost.http.Requestor; +import com.easypost.http.Requestor.RequestMethod; +import com.easypost.model.EstimateDeliveryDateForZipPairResult; +import com.easypost.model.RecommendShipDateForZipPairResult; + +public class SmartRateService { + private final EasyPostClient client; + + /** + * TrackerService constructor. + * + * @param client The client object. + */ + SmartRateService(EasyPostClient client) { + this.client = client; + } + + /** + * Retrieve a recommended ship date for an existing Shipment via the Precision Shipping API, + * based on a specific desired delivery date. + * + * @param params Parameters to include on the API call. + * @return EstimatedDeliveryDate object. + * @throws EasyPostException When the request fails. + */ + public RecommendShipDateForZipPairResult recommendShipDate(final Map params) + throws EasyPostException { + String endpoint = "smartrate/deliver_on"; + + return Requestor.request(RequestMethod.POST, endpoint, params, RecommendShipDateForZipPairResult.class, client); + } + + /** + * Retrieve the estimated delivery date of each carrier-service level combination via the + * Smart Deliver By API, based on a specific ship date and origin-destination postal code pair. + * + * @param params Parameters to include on the API call. + * @return EstimatedDeliveryDate object. + * @throws EasyPostException When the request fails. + */ + public EstimateDeliveryDateForZipPairResult estimateDeliveryDate(final Map params) + throws EasyPostException { + String endpoint = "smartrate/deliver_by"; + + return Requestor.request(RequestMethod.POST, endpoint, params, + EstimateDeliveryDateForZipPairResult.class, client); + } +} diff --git a/src/test/cassettes/shipment/retrieve_recommend_date.json b/src/test/cassettes/shipment/retrieve_recommend_date.json new file mode 100644 index 000000000..da49a7e17 --- /dev/null +++ b/src/test/cassettes/shipment/retrieve_recommend_date.json @@ -0,0 +1,180 @@ +[ + { + "recordedAt": 1720736919, + "request": { + "body": "{\n \"shipment\": {\n \"parcel\": {\n \"length\": 10.0,\n \"width\": 8.0,\n \"weight\": 15.4,\n \"height\": 4.0\n },\n \"to_address\": {\n \"zip\": \"90277\",\n \"country\": \"US\",\n \"city\": \"Redondo Beach\",\n \"phone\": \"REDACTED\",\n \"name\": \"Elizabeth Swan\",\n \"street1\": \"179 N Harbor Dr\",\n \"state\": \"CA\",\n \"email\": \"test@example.com\"\n },\n \"from_address\": {\n \"zip\": \"94107\",\n \"country\": \"US\",\n \"city\": \"San Francisco\",\n \"phone\": \"REDACTED\",\n \"name\": \"Jack Sparrow\",\n \"street1\": \"388 Townsend St\",\n \"street2\": \"Apt 20\",\n \"state\": \"CA\",\n \"email\": \"test@example.com\"\n }\n }\n}", + "method": "POST", + "headers": { + "Accept-Charset": [ + "UTF-8" + ], + "User-Agent": [ + "REDACTED" + ], + "Content-Type": [ + "application/json" + ] + }, + "uri": "https://api.easypost.com/v2/shipments" + }, + "response": { + "body": "{\n \"insurance\": null,\n \"fees\": [],\n \"batch_id\": null,\n \"batch_message\": null,\n \"batch_status\": null,\n \"created_at\": \"2024-07-11T22:28:38Z\",\n \"mode\": \"test\",\n \"reference\": null,\n \"usps_zone\": 4.0,\n \"is_return\": false,\n \"updated_at\": \"2024-07-11T22:28:39Z\",\n \"selected_rate\": null,\n \"options\": {\n \"date_advance\": 0.0,\n \"currency\": \"USD\",\n \"payment\": {\n \"type\": \"SENDER\"\n }\n },\n \"tracker\": null,\n \"return_address\": {\n \"zip\": \"94107\",\n \"country\": \"US\",\n \"city\": \"San Francisco\",\n \"created_at\": \"2024-07-11T22:28:38+00:00\",\n \"verifications\": {},\n \"mode\": \"test\",\n \"federal_tax_id\": null,\n \"state_tax_id\": null,\n \"carrier_facility\": null,\n \"residential\": null,\n \"updated_at\": \"2024-07-11T22:28:38+00:00\",\n \"phone\": \"REDACTED\",\n \"name\": \"Jack Sparrow\",\n \"company\": null,\n \"street1\": \"388 Townsend St\",\n \"id\": \"adr_eb2721e53fd411ef86ffac1f6bc53342\",\n \"street2\": \"Apt 20\",\n \"state\": \"CA\",\n \"email\": \"test@example.com\",\n \"object\": \"Address\"\n },\n \"id\": \"shp_d0343b63312947078c3a6fcadfc56ebd\",\n \"from_address\": {\n \"zip\": \"94107\",\n \"country\": \"US\",\n \"city\": \"San Francisco\",\n \"created_at\": \"2024-07-11T22:28:38+00:00\",\n \"verifications\": {},\n \"mode\": \"test\",\n \"federal_tax_id\": null,\n \"state_tax_id\": null,\n \"carrier_facility\": null,\n \"residential\": null,\n \"updated_at\": \"2024-07-11T22:28:38+00:00\",\n \"phone\": \"REDACTED\",\n \"name\": \"Jack Sparrow\",\n \"company\": null,\n \"street1\": \"388 Townsend St\",\n \"id\": \"adr_eb2721e53fd411ef86ffac1f6bc53342\",\n \"street2\": \"Apt 20\",\n \"state\": \"CA\",\n \"email\": \"test@example.com\",\n \"object\": \"Address\"\n },\n \"customs_info\": null,\n \"postage_label\": null,\n \"parcel\": {\n \"mode\": \"test\",\n \"updated_at\": \"2024-07-11T22:28:38Z\",\n \"predefined_package\": null,\n \"length\": 10.0,\n \"width\": 8.0,\n \"created_at\": \"2024-07-11T22:28:38Z\",\n \"weight\": 15.4,\n \"id\": \"prcl_7cf14ee69e984568b1b4e14e3700a95e\",\n \"object\": \"Parcel\",\n \"height\": 4.0\n },\n \"refund_status\": null,\n \"buyer_address\": {\n \"zip\": \"90277\",\n \"country\": \"US\",\n \"city\": \"Redondo Beach\",\n \"created_at\": \"2024-07-11T22:28:38+00:00\",\n \"verifications\": {},\n \"mode\": \"test\",\n \"federal_tax_id\": null,\n \"state_tax_id\": null,\n \"carrier_facility\": null,\n \"residential\": null,\n \"updated_at\": \"2024-07-11T22:28:38+00:00\",\n \"phone\": \"REDACTED\",\n \"name\": \"Elizabeth Swan\",\n \"company\": null,\n \"street1\": \"179 N Harbor Dr\",\n \"id\": \"adr_eb1d2c433fd411efb4f83cecef1b359e\",\n \"street2\": null,\n \"state\": \"CA\",\n \"email\": \"test@example.com\",\n \"object\": \"Address\"\n },\n \"rates\": [\n {\n \"carrier_account_id\": \"ca_f09befdb2e9c410e95c7622ea912c18c\",\n \"list_rate\": \"8.25\",\n \"created_at\": \"2024-07-11T22:28:38Z\",\n \"delivery_days\": 2.0,\n \"list_currency\": \"USD\",\n \"shipment_id\": \"shp_d0343b63312947078c3a6fcadfc56ebd\",\n \"mode\": \"test\",\n \"carrier\": \"USPS\",\n \"delivery_date\": null,\n \"delivery_date_guaranteed\": false,\n \"retail_rate\": \"9.80\",\n \"retail_currency\": \"USD\",\n \"updated_at\": \"2024-07-11T22:28:38Z\",\n \"rate\": \"6.90\",\n \"service\": \"Priority\",\n \"billing_type\": \"easypost\",\n \"est_delivery_days\": 2.0,\n \"currency\": \"USD\",\n \"id\": \"rate_46e59a95a0964ea6bbca3b2e344bad7e\",\n \"object\": \"Rate\"\n },\n {\n \"carrier_account_id\": \"ca_f09befdb2e9c410e95c7622ea912c18c\",\n \"list_rate\": \"6.40\",\n \"created_at\": \"2024-07-11T22:28:38Z\",\n \"delivery_days\": 3.0,\n \"list_currency\": \"USD\",\n \"shipment_id\": \"shp_d0343b63312947078c3a6fcadfc56ebd\",\n \"mode\": \"test\",\n \"carrier\": \"USPS\",\n \"delivery_date\": null,\n \"delivery_date_guaranteed\": false,\n \"retail_rate\": \"8.45\",\n \"retail_currency\": \"USD\",\n \"updated_at\": \"2024-07-11T22:28:38Z\",\n \"rate\": \"5.93\",\n \"service\": \"GroundAdvantage\",\n \"billing_type\": \"easypost\",\n \"est_delivery_days\": 3.0,\n \"currency\": \"USD\",\n \"id\": \"rate_43da52d9104643308d8fb98adf36d015\",\n \"object\": \"Rate\"\n },\n {\n \"carrier_account_id\": \"ca_f09befdb2e9c410e95c7622ea912c18c\",\n \"list_rate\": \"6.40\",\n \"created_at\": \"2024-07-11T22:28:39Z\",\n \"delivery_days\": 3.0,\n \"list_currency\": \"USD\",\n \"shipment_id\": \"shp_d0343b63312947078c3a6fcadfc56ebd\",\n \"mode\": \"test\",\n \"carrier\": \"USPS\",\n \"delivery_date\": null,\n \"delivery_date_guaranteed\": false,\n \"retail_rate\": \"8.45\",\n \"retail_currency\": \"USD\",\n \"updated_at\": \"2024-07-11T22:28:39Z\",\n \"rate\": \"5.93\",\n \"service\": \"First\",\n \"billing_type\": \"easypost\",\n \"est_delivery_days\": 3.0,\n \"currency\": \"USD\",\n \"id\": \"rate_0e86d03a50864820b9e2c3a52c78fd1f\",\n \"object\": \"Rate\"\n },\n {\n \"carrier_account_id\": \"ca_f09befdb2e9c410e95c7622ea912c18c\",\n \"list_rate\": \"6.40\",\n \"created_at\": \"2024-07-11T22:28:39Z\",\n \"delivery_days\": 3.0,\n \"list_currency\": \"USD\",\n \"shipment_id\": \"shp_d0343b63312947078c3a6fcadfc56ebd\",\n \"mode\": \"test\",\n \"carrier\": \"USPS\",\n \"delivery_date\": null,\n \"delivery_date_guaranteed\": false,\n \"retail_rate\": \"8.45\",\n \"retail_currency\": \"USD\",\n \"updated_at\": \"2024-07-11T22:28:39Z\",\n \"rate\": \"5.93\",\n \"service\": \"ParcelSelect\",\n \"billing_type\": \"easypost\",\n \"est_delivery_days\": 3.0,\n \"currency\": \"USD\",\n \"id\": \"rate_d46dfb6154f14867b140ee3d819c7b22\",\n \"object\": \"Rate\"\n },\n {\n \"carrier_account_id\": \"ca_f09befdb2e9c410e95c7622ea912c18c\",\n \"list_rate\": \"33.10\",\n \"created_at\": \"2024-07-11T22:28:39Z\",\n \"delivery_days\": 2.0,\n \"list_currency\": \"USD\",\n \"shipment_id\": \"shp_d0343b63312947078c3a6fcadfc56ebd\",\n \"mode\": \"test\",\n \"carrier\": \"USPS\",\n \"delivery_date\": null,\n \"delivery_date_guaranteed\": false,\n \"retail_rate\": \"37.90\",\n \"retail_currency\": \"USD\",\n \"updated_at\": \"2024-07-11T22:28:39Z\",\n \"rate\": \"33.10\",\n \"service\": \"Express\",\n \"billing_type\": \"easypost\",\n \"est_delivery_days\": 2.0,\n \"currency\": \"USD\",\n \"id\": \"rate_5e80a9f81ee648c283ca834e41ba4def\",\n \"object\": \"Rate\"\n }\n ],\n \"scan_form\": null,\n \"to_address\": {\n \"zip\": \"90277\",\n \"country\": \"US\",\n \"city\": \"Redondo Beach\",\n \"created_at\": \"2024-07-11T22:28:38+00:00\",\n \"verifications\": {},\n \"mode\": \"test\",\n \"federal_tax_id\": null,\n \"state_tax_id\": null,\n \"carrier_facility\": null,\n \"residential\": null,\n \"updated_at\": \"2024-07-11T22:28:38+00:00\",\n \"phone\": \"REDACTED\",\n \"name\": \"Elizabeth Swan\",\n \"company\": null,\n \"street1\": \"179 N Harbor Dr\",\n \"id\": \"adr_eb1d2c433fd411efb4f83cecef1b359e\",\n \"street2\": null,\n \"state\": \"CA\",\n \"email\": \"test@example.com\",\n \"object\": \"Address\"\n },\n \"tracking_code\": null,\n \"messages\": [\n {\n \"carrier\": \"UPS\",\n \"carrier_account_id\": \"ca_2cdc6fb96d99484e8631d7c9620dec24\",\n \"type\": \"rate_error\",\n \"message\": \"Invalid Access License number\"\n },\n {\n \"carrier\": \"UPS\",\n \"carrier_account_id\": \"ca_1c4eecb124f841d7a51e7e53cdda6cd8\",\n \"type\": \"rate_error\",\n \"message\": \"Invalid Access License number\"\n },\n {\n \"carrier\": \"UPS\",\n \"carrier_account_id\": \"ca_6924408886ad49ac9a8468804f2b52b7\",\n \"type\": \"rate_error\",\n \"message\": \"Invalid Access License number\"\n },\n {\n \"carrier\": \"UPS\",\n \"carrier_account_id\": \"ca_8031f3014d2b49dba089e5c14da57413\",\n \"type\": \"rate_error\",\n \"message\": \"Invalid Access License number\"\n },\n {\n \"carrier\": \"UPS\",\n \"carrier_account_id\": \"ca_687017c7f80044ab942b697a9607c439\",\n \"type\": \"rate_error\",\n \"message\": \"Invalid Access License number\"\n },\n {\n \"carrier\": \"UPS\",\n \"carrier_account_id\": \"ca_e6db2c19d54c4025b852d0ad81ee7f4e\",\n \"type\": \"rate_error\",\n \"message\": \"Invalid Access License number\"\n },\n {\n \"carrier\": \"UPS\",\n \"carrier_account_id\": \"ca_f363eb4e1b194798b015a07598be6ed4\",\n \"type\": \"rate_error\",\n \"message\": \"Invalid Access License number\"\n },\n {\n \"carrier\": \"UPS\",\n \"carrier_account_id\": \"ca_3e92a82adac444a58f032ebcd8eb9028\",\n \"type\": \"rate_error\",\n \"message\": \"Invalid Access License number\"\n }\n ],\n \"order_id\": null,\n \"forms\": [],\n \"status\": \"unknown\",\n \"object\": \"Shipment\"\n}", + "httpVersion": null, + "headers": { + "null": [ + "HTTP/1.1 201 Created" + ], + "content-length": [ + "6509" + ], + "expires": [ + "0" + ], + "x-node": [ + "bigweb33nuq" + ], + "x-frame-options": [ + "SAMEORIGIN" + ], + "x-backend": [ + "easypost" + ], + "x-permitted-cross-domain-policies": [ + "none" + ], + "x-download-options": [ + "noopen" + ], + "strict-transport-security": [ + "max-age\u003d31536000; includeSubDomains; preload" + ], + "pragma": [ + "no-cache" + ], + "x-content-type-options": [ + "nosniff" + ], + "x-xss-protection": [ + "1; mode\u003dblock" + ], + "x-ep-request-uuid": [ + "b8e53c1f66905c96e78861e30048c9d4" + ], + "x-proxied": [ + "extlb2nuq fa152d4755", + "intlb4nuq fa152d4755" + ], + "referrer-policy": [ + "strict-origin-when-cross-origin" + ], + "x-runtime": [ + "0.890869" + ], + "content-type": [ + "application/json; charset\u003dutf-8" + ], + "location": [ + "/api/v2/shipments/shp_d0343b63312947078c3a6fcadfc56ebd" + ], + "x-version-label": [ + "easypost-202407112200-905bf72bcb-master" + ], + "cache-control": [ + "private, no-cache, no-store" + ] + }, + "status": { + "code": 201, + "message": "Created" + }, + "uri": "https://api.easypost.com/v2/shipments" + }, + "duration": 1311 + }, + { + "recordedAt": 1720736919, + "request": { + "body": "", + "method": "GET", + "headers": { + "Accept-Charset": [ + "UTF-8" + ], + "User-Agent": [ + "REDACTED" + ] + }, + "uri": "https://api.easypost.com/v2/shipments/shp_d0343b63312947078c3a6fcadfc56ebd/smartrate/precision_shipping?%64%65%73%69%72%65%64%5F%64%65%6C%69%76%65%72%79%5F%64%61%74%65\u003d%32%30%32%34%2D%30%37%2D%31%36" + }, + "response": { + "body": "{\n \"rates\": [\n {\n \"rate\": {\n \"carrier_account_id\": \"ca_f09befdb2e9c410e95c7622ea912c18c\",\n \"list_rate\": 8.25,\n \"created_at\": \"2024-07-11T22:28:38Z\",\n \"delivery_days\": 2.0,\n \"list_currency\": \"USD\",\n \"shipment_id\": \"shp_d0343b63312947078c3a6fcadfc56ebd\",\n \"mode\": \"test\",\n \"carrier\": \"USPS\",\n \"delivery_date\": null,\n \"delivery_date_guaranteed\": false,\n \"retail_currency\": \"USD\",\n \"retail_rate\": 9.8,\n \"updated_at\": \"2024-07-11T22:28:38Z\",\n \"rate\": 6.9,\n \"service\": \"Priority\",\n \"est_delivery_days\": 2.0,\n \"currency\": \"USD\",\n \"id\": \"rate_46e59a95a0964ea6bbca3b2e344bad7e\",\n \"object\": \"Rate\"\n },\n \"easypost_time_in_transit_data\": {\n \"days_in_transit\": {\n \"percentile_90\": 4.0,\n \"percentile_50\": 2.0,\n \"percentile_85\": 4.0,\n \"percentile_95\": 5.0,\n \"percentile_75\": 3.0,\n \"percentile_97\": 5.0,\n \"percentile_99\": 7.0\n },\n \"delivery_date_confidence\": 0.19,\n \"ship_on_date\": \"2024-07-13\",\n \"desired_delivery_date\": \"2024-07-16\",\n \"estimated_transit_days\": 3.0\n }\n },\n {\n \"rate\": {\n \"carrier_account_id\": \"ca_f09befdb2e9c410e95c7622ea912c18c\",\n \"list_rate\": 6.4,\n \"created_at\": \"2024-07-11T22:28:38Z\",\n \"delivery_days\": 3.0,\n \"list_currency\": \"USD\",\n \"shipment_id\": \"shp_d0343b63312947078c3a6fcadfc56ebd\",\n \"mode\": \"test\",\n \"carrier\": \"USPS\",\n \"delivery_date\": null,\n \"delivery_date_guaranteed\": false,\n \"retail_currency\": \"USD\",\n \"retail_rate\": 8.45,\n \"updated_at\": \"2024-07-11T22:28:38Z\",\n \"rate\": 5.93,\n \"service\": \"GroundAdvantage\",\n \"est_delivery_days\": 3.0,\n \"currency\": \"USD\",\n \"id\": \"rate_43da52d9104643308d8fb98adf36d015\",\n \"object\": \"Rate\"\n },\n \"easypost_time_in_transit_data\": {\n \"days_in_transit\": {\n \"percentile_90\": 4.0,\n \"percentile_50\": 2.0,\n \"percentile_85\": 4.0,\n \"percentile_95\": 5.0,\n \"percentile_75\": 3.0,\n \"percentile_97\": 5.0,\n \"percentile_99\": 9.0\n },\n \"delivery_date_confidence\": 0.21,\n \"ship_on_date\": \"2024-07-13\",\n \"desired_delivery_date\": \"2024-07-16\",\n \"estimated_transit_days\": 3.0\n }\n },\n {\n \"rate\": {\n \"carrier_account_id\": \"ca_f09befdb2e9c410e95c7622ea912c18c\",\n \"list_rate\": 6.4,\n \"created_at\": \"2024-07-11T22:28:39Z\",\n \"delivery_days\": 3.0,\n \"list_currency\": \"USD\",\n \"shipment_id\": \"shp_d0343b63312947078c3a6fcadfc56ebd\",\n \"mode\": \"test\",\n \"carrier\": \"USPS\",\n \"delivery_date\": null,\n \"delivery_date_guaranteed\": false,\n \"retail_currency\": \"USD\",\n \"retail_rate\": 8.45,\n \"updated_at\": \"2024-07-11T22:28:39Z\",\n \"rate\": 5.93,\n \"service\": \"First\",\n \"est_delivery_days\": 3.0,\n \"currency\": \"USD\",\n \"id\": \"rate_0e86d03a50864820b9e2c3a52c78fd1f\",\n \"object\": \"Rate\"\n },\n \"easypost_time_in_transit_data\": {\n \"days_in_transit\": {\n \"percentile_90\": 4.0,\n \"percentile_50\": 2.0,\n \"percentile_85\": 4.0,\n \"percentile_95\": 5.0,\n \"percentile_75\": 3.0,\n \"percentile_97\": 5.0,\n \"percentile_99\": 9.0\n },\n \"delivery_date_confidence\": 0.21,\n \"ship_on_date\": \"2024-07-13\",\n \"desired_delivery_date\": \"2024-07-16\",\n \"estimated_transit_days\": 3.0\n }\n },\n {\n \"rate\": {\n \"carrier_account_id\": \"ca_f09befdb2e9c410e95c7622ea912c18c\",\n \"list_rate\": 6.4,\n \"created_at\": \"2024-07-11T22:28:39Z\",\n \"delivery_days\": 3.0,\n \"list_currency\": \"USD\",\n \"shipment_id\": \"shp_d0343b63312947078c3a6fcadfc56ebd\",\n \"mode\": \"test\",\n \"carrier\": \"USPS\",\n \"delivery_date\": null,\n \"delivery_date_guaranteed\": false,\n \"retail_currency\": \"USD\",\n \"retail_rate\": 8.45,\n \"updated_at\": \"2024-07-11T22:28:39Z\",\n \"rate\": 5.93,\n \"service\": \"ParcelSelect\",\n \"est_delivery_days\": 3.0,\n \"currency\": \"USD\",\n \"id\": \"rate_d46dfb6154f14867b140ee3d819c7b22\",\n \"object\": \"Rate\"\n },\n \"easypost_time_in_transit_data\": {\n \"days_in_transit\": {\n \"percentile_90\": 4.0,\n \"percentile_50\": 2.0,\n \"percentile_85\": 4.0,\n \"percentile_95\": 5.0,\n \"percentile_75\": 3.0,\n \"percentile_97\": 5.0,\n \"percentile_99\": 9.0\n },\n \"delivery_date_confidence\": 0.21,\n \"ship_on_date\": \"2024-07-13\",\n \"desired_delivery_date\": \"2024-07-16\",\n \"estimated_transit_days\": 3.0\n }\n },\n {\n \"rate\": {\n \"carrier_account_id\": \"ca_f09befdb2e9c410e95c7622ea912c18c\",\n \"list_rate\": 33.1,\n \"created_at\": \"2024-07-11T22:28:39Z\",\n \"delivery_days\": 2.0,\n \"list_currency\": \"USD\",\n \"shipment_id\": \"shp_d0343b63312947078c3a6fcadfc56ebd\",\n \"mode\": \"test\",\n \"carrier\": \"USPS\",\n \"delivery_date\": null,\n \"delivery_date_guaranteed\": false,\n \"retail_currency\": \"USD\",\n \"retail_rate\": 37.9,\n \"updated_at\": \"2024-07-11T22:28:39Z\",\n \"rate\": 33.1,\n \"service\": \"Express\",\n \"est_delivery_days\": 2.0,\n \"currency\": \"USD\",\n \"id\": \"rate_5e80a9f81ee648c283ca834e41ba4def\",\n \"object\": \"Rate\"\n },\n \"easypost_time_in_transit_data\": {\n \"days_in_transit\": {\n \"percentile_90\": 3.0,\n \"percentile_50\": 2.0,\n \"percentile_85\": 2.0,\n \"percentile_95\": 3.0,\n \"percentile_75\": 2.0,\n \"percentile_97\": 4.0,\n \"percentile_99\": 7.0\n },\n \"delivery_date_confidence\": 0.47,\n \"ship_on_date\": \"2024-07-15\",\n \"desired_delivery_date\": \"2024-07-16\",\n \"estimated_transit_days\": 1.0\n }\n }\n ]\n}", + "httpVersion": null, + "headers": { + "null": [ + "HTTP/1.1 200 OK" + ], + "content-length": [ + "4098" + ], + "expires": [ + "0" + ], + "x-node": [ + "bigweb39nuq" + ], + "x-frame-options": [ + "SAMEORIGIN" + ], + "x-backend": [ + "easypost" + ], + "x-permitted-cross-domain-policies": [ + "none" + ], + "x-download-options": [ + "noopen" + ], + "strict-transport-security": [ + "max-age\u003d31536000; includeSubDomains; preload" + ], + "pragma": [ + "no-cache" + ], + "x-content-type-options": [ + "nosniff" + ], + "x-xss-protection": [ + "1; mode\u003dblock" + ], + "x-ep-request-uuid": [ + "b8e53c2066905c97e78861e40048cb66" + ], + "x-proxied": [ + "extlb2nuq fa152d4755", + "intlb3nuq fa152d4755" + ], + "referrer-policy": [ + "strict-origin-when-cross-origin" + ], + "x-runtime": [ + "0.148588" + ], + "content-type": [ + "application/json; charset\u003dutf-8" + ], + "x-version-label": [ + "easypost-202407112200-905bf72bcb-master" + ], + "cache-control": [ + "private, no-cache, no-store" + ] + }, + "status": { + "code": 200, + "message": "OK" + }, + "uri": "https://api.easypost.com/v2/shipments/shp_d0343b63312947078c3a6fcadfc56ebd/smartrate/precision_shipping?%64%65%73%69%72%65%64%5F%64%65%6C%69%76%65%72%79%5F%64%61%74%65\u003d%32%30%32%34%2D%30%37%2D%31%36" + }, + "duration": 575 + } +] \ No newline at end of file diff --git a/src/test/cassettes/smart_rate/retrieve_estimated_delivery_date.json b/src/test/cassettes/smart_rate/retrieve_estimated_delivery_date.json new file mode 100644 index 000000000..61c50f6bb --- /dev/null +++ b/src/test/cassettes/smart_rate/retrieve_estimated_delivery_date.json @@ -0,0 +1,94 @@ +[ + { + "recordedAt": 1720804348, + "request": { + "body": "{\n \"planned_ship_date\": \"2024-07-16\",\n \"to_zip\": \"90277\",\n \"from_zip\": \"94107\",\n \"carriers\": [\n \"USPS\"\n ]\n}", + "method": "POST", + "headers": { + "Accept-Charset": [ + "UTF-8" + ], + "User-Agent": [ + "REDACTED" + ], + "Content-Type": [ + "application/json" + ] + }, + "uri": "https://api.easypost.com/v2/smartrate/deliver_by" + }, + "response": { + "body": "{\n \"planned_ship_date\": \"2024-07-16\",\n \"to_zip\": \"90277\",\n \"carriers_without_tint_estimates\": null,\n \"from_zip\": \"94107\",\n \"saturday_delivery\": null,\n \"results\": [\n {\n \"carrier\": \"USPS\",\n \"service\": \"express\",\n \"easypost_time_in_transit_data\": {\n \"days_in_transit\": {\n \"percentile_90\": 3.0,\n \"percentile_50\": 1.0,\n \"percentile_85\": 2.0,\n \"percentile_95\": 3.0,\n \"percentile_75\": 2.0,\n \"percentile_97\": 4.0,\n \"percentile_99\": 6.0\n },\n \"easypost_estimated_delivery_date\": \"2024-07-17\"\n }\n },\n {\n \"carrier\": \"USPS\",\n \"service\": \"groundadvantage\",\n \"easypost_time_in_transit_data\": {\n \"days_in_transit\": {\n \"percentile_90\": 4.0,\n \"percentile_50\": 2.0,\n \"percentile_85\": 3.0,\n \"percentile_95\": 6.0,\n \"percentile_75\": 3.0,\n \"percentile_97\": 6.0,\n \"percentile_99\": 9.0\n },\n \"easypost_estimated_delivery_date\": \"2024-07-18\"\n }\n },\n {\n \"carrier\": \"USPS\",\n \"service\": \"librarymail\",\n \"easypost_time_in_transit_data\": {\n \"days_in_transit\": {\n \"percentile_90\": 6.0,\n \"percentile_50\": 3.0,\n \"percentile_85\": 3.0,\n \"percentile_95\": 6.0,\n \"percentile_75\": 3.0,\n \"percentile_97\": 6.0,\n \"percentile_99\": 9.0\n },\n \"easypost_estimated_delivery_date\": \"2024-07-18\"\n }\n },\n {\n \"carrier\": \"USPS\",\n \"service\": \"mediamail\",\n \"easypost_time_in_transit_data\": {\n \"days_in_transit\": {\n \"percentile_90\": 4.0,\n \"percentile_50\": 3.0,\n \"percentile_85\": 3.0,\n \"percentile_95\": 6.0,\n \"percentile_75\": 3.0,\n \"percentile_97\": 6.0,\n \"percentile_99\": 9.0\n },\n \"easypost_estimated_delivery_date\": \"2024-07-18\"\n }\n },\n {\n \"carrier\": \"USPS\",\n \"service\": \"priority\",\n \"easypost_time_in_transit_data\": {\n \"days_in_transit\": {\n \"percentile_90\": 3.0,\n \"percentile_50\": 2.0,\n \"percentile_85\": 3.0,\n \"percentile_95\": 4.0,\n \"percentile_75\": 3.0,\n \"percentile_97\": 6.0,\n \"percentile_99\": 7.0\n },\n \"easypost_estimated_delivery_date\": \"2024-07-18\"\n }\n }\n ]\n}", + "httpVersion": null, + "headers": { + "null": [ + "HTTP/1.1 200 OK" + ], + "content-length": [ + "1496" + ], + "expires": [ + "0" + ], + "x-node": [ + "bigweb32nuq" + ], + "x-frame-options": [ + "SAMEORIGIN" + ], + "x-backend": [ + "easypost" + ], + "x-permitted-cross-domain-policies": [ + "none" + ], + "x-download-options": [ + "noopen" + ], + "strict-transport-security": [ + "max-age\u003d31536000; includeSubDomains; preload" + ], + "pragma": [ + "no-cache" + ], + "x-canary": [ + "direct" + ], + "x-content-type-options": [ + "nosniff" + ], + "x-xss-protection": [ + "1; mode\u003dblock" + ], + "x-ep-request-uuid": [ + "096cfd34669163fce78748fe00465b93" + ], + "x-proxied": [ + "extlb1nuq fa152d4755", + "intlb3nuq fa152d4755" + ], + "referrer-policy": [ + "strict-origin-when-cross-origin" + ], + "x-runtime": [ + "0.071641" + ], + "content-type": [ + "application/json; charset\u003dutf-8" + ], + "x-version-label": [ + "easypost-202407121702-a82cfb9ac3-master" + ], + "cache-control": [ + "private, no-cache, no-store" + ] + }, + "status": { + "code": 200, + "message": "OK" + }, + "uri": "https://api.easypost.com/v2/smartrate/deliver_by" + }, + "duration": 461 + } +] \ No newline at end of file diff --git a/src/test/cassettes/smart_rate/retrieve_recommend_ship_date.json b/src/test/cassettes/smart_rate/retrieve_recommend_ship_date.json new file mode 100644 index 000000000..1f5500e56 --- /dev/null +++ b/src/test/cassettes/smart_rate/retrieve_recommend_ship_date.json @@ -0,0 +1,91 @@ +[ + { + "recordedAt": 1720803740, + "request": { + "body": "{\n \"to_zip\": \"90277\",\n \"from_zip\": \"94107\",\n \"carriers\": [\n \"USPS\"\n ],\n \"desired_delivery_date\": \"2024-07-16\"\n}", + "method": "POST", + "headers": { + "Accept-Charset": [ + "UTF-8" + ], + "User-Agent": [ + "REDACTED" + ], + "Content-Type": [ + "application/json" + ] + }, + "uri": "https://api.easypost.com/v2/smartrate/deliver_on" + }, + "response": { + "body": "{\n \"to_zip\": \"90277\",\n \"carriers_without_tint_estimates\": null,\n \"from_zip\": \"94107\",\n \"saturday_delivery\": null,\n \"desired_delivery_date\": \"2024-07-16\",\n \"results\": [\n {\n \"carrier\": \"USPS\",\n \"service\": \"express\",\n \"easypost_time_in_transit_data\": {\n \"days_in_transit\": {\n \"percentile_90\": 3.0,\n \"percentile_50\": 2.0,\n \"percentile_85\": 2.0,\n \"percentile_95\": 3.0,\n \"percentile_75\": 2.0,\n \"percentile_97\": 4.0,\n \"percentile_99\": 7.0\n },\n \"delivery_date_confidence\": 0.47,\n \"ship_on_date\": \"2024-07-15\",\n \"estimated_transit_days\": 1.0\n }\n },\n {\n \"carrier\": \"USPS\",\n \"service\": \"groundadvantage\",\n \"easypost_time_in_transit_data\": {\n \"days_in_transit\": {\n \"percentile_90\": 4.0,\n \"percentile_50\": 2.0,\n \"percentile_85\": 4.0,\n \"percentile_95\": 5.0,\n \"percentile_75\": 3.0,\n \"percentile_97\": 5.0,\n \"percentile_99\": 9.0\n },\n \"delivery_date_confidence\": 0.21,\n \"ship_on_date\": \"2024-07-13\",\n \"estimated_transit_days\": 3.0\n }\n },\n {\n \"carrier\": \"USPS\",\n \"service\": \"librarymail\",\n \"easypost_time_in_transit_data\": {\n \"days_in_transit\": {\n \"percentile_90\": 4.0,\n \"percentile_50\": 2.0,\n \"percentile_85\": 4.0,\n \"percentile_95\": 5.0,\n \"percentile_75\": 3.0,\n \"percentile_97\": 6.0,\n \"percentile_99\": 9.0\n },\n \"delivery_date_confidence\": 0.25,\n \"ship_on_date\": \"2024-07-13\",\n \"estimated_transit_days\": 3.0\n }\n },\n {\n \"carrier\": \"USPS\",\n \"service\": \"mediamail\",\n \"easypost_time_in_transit_data\": {\n \"days_in_transit\": {\n \"percentile_90\": 4.0,\n \"percentile_50\": 2.0,\n \"percentile_85\": 3.0,\n \"percentile_95\": 5.0,\n \"percentile_75\": 3.0,\n \"percentile_97\": 5.0,\n \"percentile_99\": 7.0\n },\n \"delivery_date_confidence\": 0.24,\n \"ship_on_date\": \"2024-07-13\",\n \"estimated_transit_days\": 3.0\n }\n },\n {\n \"carrier\": \"USPS\",\n \"service\": \"priority\",\n \"easypost_time_in_transit_data\": {\n \"days_in_transit\": {\n \"percentile_90\": 4.0,\n \"percentile_50\": 2.0,\n \"percentile_85\": 4.0,\n \"percentile_95\": 5.0,\n \"percentile_75\": 3.0,\n \"percentile_97\": 5.0,\n \"percentile_99\": 7.0\n },\n \"delivery_date_confidence\": 0.19,\n \"ship_on_date\": \"2024-07-13\",\n \"estimated_transit_days\": 3.0\n }\n }\n ]\n}", + "httpVersion": null, + "headers": { + "null": [ + "HTTP/1.1 200 OK" + ], + "content-length": [ + "1695" + ], + "expires": [ + "0" + ], + "x-node": [ + "bigweb40nuq" + ], + "x-frame-options": [ + "SAMEORIGIN" + ], + "x-backend": [ + "easypost" + ], + "x-permitted-cross-domain-policies": [ + "none" + ], + "x-download-options": [ + "noopen" + ], + "strict-transport-security": [ + "max-age\u003d31536000; includeSubDomains; preload" + ], + "pragma": [ + "no-cache" + ], + "x-content-type-options": [ + "nosniff" + ], + "x-xss-protection": [ + "1; mode\u003dblock" + ], + "x-ep-request-uuid": [ + "efcdd3866691619ce7873c8300434549" + ], + "x-proxied": [ + "extlb2nuq fa152d4755", + "intlb4nuq fa152d4755" + ], + "referrer-policy": [ + "strict-origin-when-cross-origin" + ], + "x-runtime": [ + "0.081346" + ], + "content-type": [ + "application/json; charset\u003dutf-8" + ], + "x-version-label": [ + "easypost-202407112200-905bf72bcb-master" + ], + "cache-control": [ + "private, no-cache, no-store" + ] + }, + "status": { + "code": 200, + "message": "OK" + }, + "uri": "https://api.easypost.com/v2/smartrate/deliver_on" + }, + "duration": 499 + } +] \ No newline at end of file diff --git a/src/test/java/com/easypost/CarrierAccountTest.java b/src/test/java/com/easypost/CarrierAccountTest.java index 700524459..963fc7d7f 100644 --- a/src/test/java/com/easypost/CarrierAccountTest.java +++ b/src/test/java/com/easypost/CarrierAccountTest.java @@ -116,7 +116,7 @@ public void testCreateWithCustomWorkflow() throws EasyPostException { /** - * Test creating a carrier account with a custom workflow. + * Test creating a UPS carrier account. * * @throws EasyPostException when the request fails. */ diff --git a/src/test/java/com/easypost/Fixtures.java b/src/test/java/com/easypost/Fixtures.java index afb5cd9a9..0cd2399d8 100644 --- a/src/test/java/com/easypost/Fixtures.java +++ b/src/test/java/com/easypost/Fixtures.java @@ -328,6 +328,15 @@ public static HashMap referralUser() { * @return The default planned ship date */ public static String plannedShipDate() { - return "2023-12-28"; + return "2024-07-16"; + } + + /** + * Get the default desired delivery date. + * + * @return The default desired delivery date + */ + public static String desiredDeliveryDate() { + return "2024-07-16"; } } diff --git a/src/test/java/com/easypost/ShipmentTest.java b/src/test/java/com/easypost/ShipmentTest.java index e5b3b6a8c..a998c5592 100644 --- a/src/test/java/com/easypost/ShipmentTest.java +++ b/src/test/java/com/easypost/ShipmentTest.java @@ -718,4 +718,22 @@ public void testRetrieveEstimatedDeliveryDate() throws EasyPostException { assertNotNull(estimatedDeliveryDate.getEasypostTimeInTransitData().getDaysInTransit().getPercentile99()); } } + + /** + * Test that we retrieve SmartRates when providing a shipment and desired delivery date. + * + * @throws EasyPostException when the request fails. + */ + @Test + public void testRetrieveRecommendDate() throws EasyPostException { + vcr.setUpTest("retrieve_recommend_date"); + + Shipment shipment = vcr.client.shipment.create(Fixtures.basicShipment()); + + List estimatedDeliveryDates = vcr.client.shipment + .recommendShipDate(shipment.getId(), Fixtures.desiredDeliveryDate()); + for (EstimatedDeliveryDate estimatedDeliveryDate : estimatedDeliveryDates) { + assertNotNull(estimatedDeliveryDate.getEasypostTimeInTransitData()); + } + } } diff --git a/src/test/java/com/easypost/SmartRateTest.java b/src/test/java/com/easypost/SmartRateTest.java new file mode 100644 index 000000000..a51c913a5 --- /dev/null +++ b/src/test/java/com/easypost/SmartRateTest.java @@ -0,0 +1,70 @@ +package com.easypost; + +import static org.junit.jupiter.api.Assertions.assertNotNull; + +import java.util.Collections; +import java.util.HashMap; +import java.util.Map; + +import org.junit.jupiter.api.BeforeAll; +import org.junit.jupiter.api.Test; + +import com.easypost.exception.EasyPostException; +import com.easypost.model.DeliveryDateForZipPairEstimate; +import com.easypost.model.EstimateDeliveryDateForZipPairResult; +import com.easypost.model.RecommendShipDateForZipPairResult; +import com.easypost.model.ShipDateForZipPairRecommendation; + +public class SmartRateTest { + private static TestUtils.VCR vcr; + + /** + * Set up the testing environment for this file. + * + * @throws EasyPostException when the request fails. + */ + @BeforeAll + public static void setup() throws EasyPostException { + vcr = new TestUtils.VCR("smart_rate", TestUtils.ApiKey.TEST); + } + + /** + * Test that we retrieve SmartRates when provided a from/to zip and desired delivery date. + * + * @throws EasyPostException when the request fails. + */ + @Test + public void testRetrieveRecommendShipDate() throws EasyPostException { + vcr.setUpTest("retrieve_recommend_ship_date"); + Map params = new HashMap(); + params.put("from_zip", Fixtures.caAddress1().get("zip")); + params.put("to_zip", Fixtures.caAddress2().get("zip")); + params.put("desired_delivery_date", Fixtures.desiredDeliveryDate()); + params.put("carriers", Collections.singletonList(Fixtures.usps())); + + RecommendShipDateForZipPairResult results = vcr.client.smartRate.recommendShipDate(params); + for (ShipDateForZipPairRecommendation entry : results.getResults()) { + assertNotNull(entry.getEasypostTimeInTransitData()); + } + } + + /** + * Test that we retrieve SmartRates when provided a from/to zip and planned ship date. + * + * @throws EasyPostException when the request fails. + */ + @Test + public void testRetrieveEstimatedDeliveryDate() throws EasyPostException { + vcr.setUpTest("retrieve_estimated_delivery_date"); + Map params = new HashMap(); + params.put("from_zip", Fixtures.caAddress1().get("zip")); + params.put("to_zip", Fixtures.caAddress2().get("zip")); + params.put("planned_ship_date", Fixtures.plannedShipDate()); + params.put("carriers", Collections.singletonList(Fixtures.usps())); + + EstimateDeliveryDateForZipPairResult results = vcr.client.smartRate.estimateDeliveryDate(params); + for (DeliveryDateForZipPairEstimate entry : results.getResults()) { + assertNotNull(entry.getEasypostTimeInTransitData()); + } + } +}