diff --git a/src/Global/GlobalAssemblyInfo.cs b/src/Global/GlobalAssemblyInfo.cs index 8afa1b3..f2ca3bc 100644 --- a/src/Global/GlobalAssemblyInfo.cs +++ b/src/Global/GlobalAssemblyInfo.cs @@ -23,4 +23,4 @@ // [assembly: AssemblyVersion("1.0.*")] // Keep in track with CA API version -[ assembly : AssemblyVersion( "1.3.84.0" ) ] \ No newline at end of file +[ assembly : AssemblyVersion( "1.4.1.0" ) ] \ No newline at end of file diff --git a/src/ShipStationAccess/ShipStationAccess.csproj b/src/ShipStationAccess/ShipStationAccess.csproj index 4d381e0..209fa36 100644 --- a/src/ShipStationAccess/ShipStationAccess.csproj +++ b/src/ShipStationAccess/ShipStationAccess.csproj @@ -95,9 +95,11 @@ + + diff --git a/src/ShipStationAccess/V2/IShipStationService.cs b/src/ShipStationAccess/V2/IShipStationService.cs index 07ecc12..38dd5c2 100644 --- a/src/ShipStationAccess/V2/IShipStationService.cs +++ b/src/ShipStationAccess/V2/IShipStationService.cs @@ -18,6 +18,8 @@ public interface IShipStationService ShipStationOrder GetOrderById( string orderId ); Task< ShipStationOrder > GetOrderByIdAsync( string orderId ); + Task< IEnumerable< ShipStationOrderShipment > > GetOrderShipmentsByIdAsync( string orderId ); + Task< IEnumerable< ShipStationOrderFulfillment > > GetOrderFulfillmentsByIdAsync( string orderId ); void UpdateOrder( ShipStationOrder order ); Task UpdateOrderAsync( ShipStationOrder order ); diff --git a/src/ShipStationAccess/V2/Models/Command/ShipStationCommand.cs b/src/ShipStationAccess/V2/Models/Command/ShipStationCommand.cs index e3174d8..302501e 100644 --- a/src/ShipStationAccess/V2/Models/Command/ShipStationCommand.cs +++ b/src/ShipStationAccess/V2/Models/Command/ShipStationCommand.cs @@ -11,6 +11,9 @@ internal sealed class ShipStationCommand public static readonly ShipStationCommand GetStores = new ShipStationCommand( "/Stores" ); public static readonly ShipStationCommand GetShippingLabel = new ShipStationCommand( "/Orders/CreateLabelForOrder" ); public static readonly ShipStationCommand Register = new ShipStationCommand( "/Integratedapp/Register" ); + public static readonly ShipStationCommand GetOrderShipments = new ShipStationCommand( "/Shipments" ); + public static readonly ShipStationCommand GetOrderFulfillments = new ShipStationCommand( "/Fulfillments" ); + private ShipStationCommand( string command ) { this.Command = command; diff --git a/src/ShipStationAccess/V2/Models/Command/ShipStationParam.cs b/src/ShipStationAccess/V2/Models/Command/ShipStationParam.cs index 7b493dc..47c5371 100644 --- a/src/ShipStationAccess/V2/Models/Command/ShipStationParam.cs +++ b/src/ShipStationAccess/V2/Models/Command/ShipStationParam.cs @@ -16,7 +16,8 @@ internal sealed class ShipStationParam public static readonly ShipStationParam ServiceCode = new ShipStationParam( "serviceCode" ); public static readonly ShipStationParam Confirmation = new ShipStationParam( "confirmation" ); public static readonly ShipStationParam ShipDate = new ShipStationParam( "shipDate" ); - + public static readonly ShipStationParam OrderId = new ShipStationParam( "orderId" ); + public static readonly ShipStationParam IncludeShipmentItems = new ShipStationParam( "includeShipmentItems" ); private ShipStationParam( string name ) { diff --git a/src/ShipStationAccess/V2/Models/Order/ShipStationOrder.cs b/src/ShipStationAccess/V2/Models/Order/ShipStationOrder.cs index 90a3789..3d4a55e 100644 --- a/src/ShipStationAccess/V2/Models/Order/ShipStationOrder.cs +++ b/src/ShipStationAccess/V2/Models/Order/ShipStationOrder.cs @@ -107,6 +107,10 @@ [ DataMember( Name = "advancedOptions" ) ] [ DataMember( Name = "tagIds" ) ] public IList< long > TagsIds { get; set; } + public IEnumerable< ShipStationOrderShipment > Shipments { get; set; } + + public IEnumerable< ShipStationOrderFulfillment > Fulfillments { get; set; } + public int MarketplaceId{ get; set; } public string MarketplaceName{ get; set; } diff --git a/src/ShipStationAccess/V2/Models/Order/ShipStationOrderAdvancedOptions.cs b/src/ShipStationAccess/V2/Models/Order/ShipStationOrderAdvancedOptions.cs index b960c7d..4b86a40 100644 --- a/src/ShipStationAccess/V2/Models/Order/ShipStationOrderAdvancedOptions.cs +++ b/src/ShipStationAccess/V2/Models/Order/ShipStationOrderAdvancedOptions.cs @@ -39,6 +39,9 @@ [ DataMember( Name = "mergedOrSplit" ) ] [ DataMember( Name = "mergedIds" ) ] public IList< long > MergedIds{ get; set; } + [ DataMember( Name = "parentId" ) ] + public long? ParentId { get; set; } + [ DataMember( Name = "billToParty" ) ] public string BillToParty{ get; set; } diff --git a/src/ShipStationAccess/V2/Models/Order/ShipStationOrderFulfillment.cs b/src/ShipStationAccess/V2/Models/Order/ShipStationOrderFulfillment.cs new file mode 100644 index 0000000..6a3493f --- /dev/null +++ b/src/ShipStationAccess/V2/Models/Order/ShipStationOrderFulfillment.cs @@ -0,0 +1,50 @@ +using System; +using System.Collections.Generic; +using System.Runtime.Serialization; + +namespace ShipStationAccess.V2.Models.Order +{ + [ DataContract ] + public sealed class ShipStationOrderFulfillments + { + [ DataMember( Name = "fulfillments" ) ] + public IEnumerable< ShipStationOrderFulfillment > Fulfillments { get; set; } + + [ DataMember( Name = "total" ) ] + public int Total { get; set; } + + [ DataMember( Name = "page" ) ] + public int Page { get; set; } + + [ DataMember( Name = "pages" ) ] + public int Pages { get; set; } + } + + [ DataContract ] + public sealed class ShipStationOrderFulfillment + { + [ DataMember( Name = "fulfillmentId" ) ] + public long Id { get; set; } + + [ DataMember( Name = "orderId" ) ] + public long OrderId { get; set; } + + [ DataMember( Name = "trackingNumber" ) ] + public string TrackingNumber { get; set; } + + [ DataMember( Name = "createDate" ) ] + public DateTime CreateDate { get; set; } + + [ DataMember( Name = "shipDate" ) ] + public DateTime ShipDate { get; set; } + + [ DataMember( Name = "deliveryDate" ) ] + public DateTime? DeliveryDate { get; set; } + + [ DataMember( Name = "carrierCode" ) ] + public string CarrierCode { get; set; } + + [ DataMember( Name = "voided" ) ] + public bool Voided { get; set; } + } +} \ No newline at end of file diff --git a/src/ShipStationAccess/V2/Models/Order/ShipStationOrderShipment.cs b/src/ShipStationAccess/V2/Models/Order/ShipStationOrderShipment.cs new file mode 100644 index 0000000..b5d9c6f --- /dev/null +++ b/src/ShipStationAccess/V2/Models/Order/ShipStationOrderShipment.cs @@ -0,0 +1,104 @@ +using System; +using System.Collections.Generic; +using System.Runtime.Serialization; + +namespace ShipStationAccess.V2.Models.Order +{ + [ DataContract ] + public sealed class ShipStationOrderShipments + { + [ DataMember( Name = "shipments" ) ] + public IEnumerable< ShipStationOrderShipment > Shipments { get; set; } + + [ DataMember( Name = "total" ) ] + public int Total { get; set; } + + [ DataMember( Name = "page" ) ] + public int Page { get; set; } + + [ DataMember( Name = "pages" ) ] + public int Pages { get; set; } + } + + [ DataContract ] + public sealed class ShipStationOrderShipment + { + [ DataMember( Name = "shipmentId" ) ] + public long Id { get; set; } + + [ DataMember( Name = "orderId" ) ] + public long OrderId { get; set; } + + [ DataMember( Name = "createDate" ) ] + public DateTime CreateDate { get; set; } + + [ DataMember( Name = "shipDate" ) ] + public DateTime? ShipDate { get; set; } + + [ DataMember( Name = "shipmentCost" ) ] + public decimal Cost { get; set; } + + [ DataMember( Name = "insuranceCost" ) ] + public decimal InsuranceCost { get; set; } + + [ DataMember( Name = "trackingNumber" ) ] + public string TrackingNumber { get; set; } + + [ DataMember( Name = "carrierCode" ) ] + public string CarrierCode { get; set; } + + [ DataMember( Name = "serviceCode" ) ] + public string ServiceCode { get; set; } + + [ DataMember( Name = "confirmation" ) ] + public string Confirmation { get; set; } + + [ DataMember( Name = "voided" ) ] + public bool Voided { get; set; } + + [ DataMember( Name = "weight" ) ] + public ShipmentWeight Weight { get; set; } + + [ DataMember( Name = "dimensions" ) ] + public ShipmentDimensions Dimensions { get; set; } + + [ DataMember( Name = "shipmentItems" ) ] + public IEnumerable< ShipmentItem > Items { get; set; } + } + + [ DataContract ] + public sealed class ShipmentWeight + { + [ DataMember( Name = "value" ) ] + public decimal Value { get; set; } + + [ DataMember( Name = "units" ) ] + public string Units { get; set; } + } + + [ DataContract ] + public sealed class ShipmentDimensions + { + [ DataMember( Name = "units" ) ] + public string Units { get; set; } + + [ DataMember( Name = "length" ) ] + public decimal Length { get; set; } + + [ DataMember( Name = "width" ) ] + public decimal Width { get; set; } + + [ DataMember( Name = "height" ) ] + public decimal Height { get; set; } + } + + [ DataContract ] + public sealed class ShipmentItem + { + [ DataMember( Name = "sku" ) ] + public string Sku { get; set; } + + [ DataMember( Name = "quantity" ) ] + public int Quantity { get; set; } + } +} \ No newline at end of file diff --git a/src/ShipStationAccess/V2/Services/ParamsBuilder.cs b/src/ShipStationAccess/V2/Services/ParamsBuilder.cs index cda3dd5..2dc494b 100644 --- a/src/ShipStationAccess/V2/Services/ParamsBuilder.cs +++ b/src/ShipStationAccess/V2/Services/ParamsBuilder.cs @@ -32,6 +32,19 @@ public static string CreateStoreIdOrderNumberParams( string storeId, string orde return endpoint; } + public static string CreateOrderShipmentsParams( string orderId, bool includeShipmentItems = true ) + { + var endpoint = string.Format( "?{0}={1}&{2}={3}", + ShipStationParam.OrderId.Name, orderId, + ShipStationParam.IncludeShipmentItems.Name, includeShipmentItems ); + return endpoint; + } + + public static string CreateOrderFulfillmentsParams( string orderId ) + { + return string.Format( "?{0}={1}", ShipStationParam.OrderId.Name, orderId ); + } + public static string CreateGetNextPageParams( ShipStationCommandConfig config ) { var endpoint = string.Format( "?{0}={1}&{2}={3}", diff --git a/src/ShipStationAccess/V2/ShipStationService.cs b/src/ShipStationAccess/V2/ShipStationService.cs index 4a2f202..79f8308 100644 --- a/src/ShipStationAccess/V2/ShipStationService.cs +++ b/src/ShipStationAccess/V2/ShipStationService.cs @@ -162,6 +162,9 @@ public async Task< IEnumerable< ShipStationOrder > > GetOrdersAsync( DateTime da foreach( var order in processedOrders ) { + order.Shipments = await GetOrderShipmentsByIdAsync( order.OrderId.ToString() ).ConfigureAwait( false ); + order.Fulfillments = await GetOrderFulfillmentsByIdAsync( order.OrderId.ToString() ).ConfigureAwait( false ); + orders.Add( order ); processedOrderIds.Add( order.OrderId ); } @@ -300,6 +303,70 @@ await ActionPolicies.GetAsync.Do( async () => return order; } + + public async Task< IEnumerable< ShipStationOrderShipment > > GetOrderShipmentsByIdAsync( string orderId ) + { + var orderShipments = new List< ShipStationOrderShipment >(); + + var currentPage = 1; + var pagesCount = int.MaxValue; + + do + { + var getOrderShipmentsEndpoint = ParamsBuilder.CreateOrderShipmentsParams( orderId ); + var nextPageParams = ParamsBuilder.CreateGetNextPageParams( new ShipStationCommandConfig( currentPage, RequestMaxLimit ) ); + var orderShipmentsByPageEndPoint = getOrderShipmentsEndpoint.ConcatParams( nextPageParams ); + + await ActionPolicies.GetAsync.Do( async () => + { + var orderShipmentsPage = await this._webRequestServices.GetResponseAsync< ShipStationOrderShipments >( ShipStationCommand.GetOrderShipments, orderShipmentsByPageEndPoint ); + + ++currentPage; + if ( pagesCount == int.MaxValue ) + { + pagesCount = orderShipmentsPage.Pages + 1; + } + + orderShipments.AddRange( orderShipmentsPage.Shipments ); + + } ); + } + while( currentPage <= pagesCount ); + + return orderShipments; + } + + public async Task< IEnumerable< ShipStationOrderFulfillment > > GetOrderFulfillmentsByIdAsync( string orderId ) + { + var orderFulfillments = new List< ShipStationOrderFulfillment >(); + + var currentPage = 1; + var pagesCount = int.MaxValue; + + do + { + var getOrderFulfillmentsEndpoint = ParamsBuilder.CreateOrderFulfillmentsParams( orderId ); + var nextPageParams = ParamsBuilder.CreateGetNextPageParams( new ShipStationCommandConfig( currentPage, RequestMaxLimit ) ); + var orderFulfillmentsByPageEndPoint = getOrderFulfillmentsEndpoint.ConcatParams( nextPageParams ); + + await ActionPolicies.GetAsync.Do( async () => + { + var orderFulfillmentsPage = await this._webRequestServices.GetResponseAsync< ShipStationOrderFulfillments >( ShipStationCommand.GetOrderFulfillments, orderFulfillmentsByPageEndPoint ); + + ++currentPage; + if ( pagesCount == int.MaxValue ) + { + pagesCount = orderFulfillmentsPage.Pages + 1; + } + + orderFulfillments.AddRange( orderFulfillmentsPage.Fulfillments ); + + } ); + } + while( currentPage <= pagesCount ); + + return orderFulfillments; + } #endregion #region Update Orders diff --git a/src/ShipStationAccessTests/Orders/OrderTests.cs b/src/ShipStationAccessTests/Orders/OrderTests.cs index 3d7b171..5631299 100644 --- a/src/ShipStationAccessTests/Orders/OrderTests.cs +++ b/src/ShipStationAccessTests/Orders/OrderTests.cs @@ -20,6 +20,8 @@ public class OrderTests { private readonly IShipStationFactory ShipStationFactory = new ShipStationFactory(); private ShipStationCredentials _credentials; + private string _testOrderWithShipments = "564221696"; + private string _testOrderWithFulfillments = "576752152"; [ SetUp ] public void Init() @@ -56,6 +58,24 @@ public async Task GetOrdersAsync() orders.Count().Should().BeGreaterThan( 0 ); } + [ Test ] + public async Task GetOrderShipmentsAsync() + { + var service = this.ShipStationFactory.CreateServiceV2( this._credentials ); + var orderShipments = await service.GetOrderShipmentsByIdAsync( this._testOrderWithShipments ); + + orderShipments.Count().Should().BeGreaterThan( 0 ); + } + + [ Test ] + public async Task GetOrderFulfillmentsAsync() + { + var service = this.ShipStationFactory.CreateServiceV2( this._credentials ); + var orderFulfillments = await service.GetOrderFulfillmentsByIdAsync( this._testOrderWithFulfillments ); + + orderFulfillments.Count().Should().BeGreaterThan( 0 ); + } + [ Test ] public void GetTags() {