Skip to content

Commit

Permalink
PBL-9157 Shopify Orders Partial Refund (#45)
Browse files Browse the repository at this point in the history
PBL-9157 shopify orders partial refund on orders sync implemented, unit tests added
  • Loading branch information
maxim-saltanov-skuvault authored Oct 7, 2024
1 parent 01c7161 commit c35a4a4
Show file tree
Hide file tree
Showing 5 changed files with 92 additions and 53 deletions.
2 changes: 1 addition & 1 deletion .build.ps1
Original file line number Diff line number Diff line change
Expand Up @@ -76,7 +76,7 @@ task NuGet Package, Version, {
<package>
<metadata>
<id>$project_name</id>
<version>$Version</version>
<version>$Version-alpha</version>
<authors>SkuVault</authors>
<owners>SkuVault</owners>
<projectUrl>https://github.com/agileharbor/$project_name</projectUrl>
Expand Down
2 changes: 1 addition & 1 deletion src/Global/GlobalAssemblyInfo.cs
Original file line number Diff line number Diff line change
Expand Up @@ -22,4 +22,4 @@
// by using the '*' as shown below:
// [assembly: AssemblyVersion("1.0.*")]

[ assembly : AssemblyVersion( "1.12.0.0" ) ]
[ assembly : AssemblyVersion( "1.13.0.0" ) ]
70 changes: 19 additions & 51 deletions src/ShopifyAccess/ShopifyService.cs
Original file line number Diff line number Diff line change
Expand Up @@ -152,7 +152,7 @@ private async Task< ShopifyOrders > CollectOrdersFromAllPagesAsync( string mainU
break;

foreach( var order in updatedOrdersWithinPage.Response.Orders )
this.RemoveCancelledOrderItems( order );
ProcessRefundOrderLineItems( order );

orders.Orders.AddRange( updatedOrdersWithinPage.Response.Orders );

Expand All @@ -162,60 +162,44 @@ private async Task< ShopifyOrders > CollectOrdersFromAllPagesAsync( string mainU
return orders;
}

private void RemoveCancelledOrderItems( ShopifyOrder order )
internal static void ProcessRefundOrderLineItems( ShopifyOrder order )
{
if ( order.Refunds == null || !order.Refunds.Any() )
return;

var actualOrderItems = new List< ShopifyOrderItem >();
foreach( var orderItem in order.OrderItems )
{
bool isCancelled = false;
int cancelledQuantity = 0;
var isCancelled = false;
var cancelledQuantity = 0;

foreach( var refund in order.Refunds )
{
var refundLineItem = refund.RefundLineItems.FirstOrDefault( rl => rl.LineItemId.ToString().Equals( orderItem.Id ) );
if( refundLineItem == null )
continue;

if ( refundLineItem != null && refundLineItem.RestockType.Equals( "cancel" ) )
// remove order item
if ( orderItem.Quantity == refundLineItem.Quantity && refundLineItem.RestockType.Equals( "cancel" ) )
{
// remove order item
if ( orderItem.Quantity == refundLineItem.Quantity )
{
isCancelled = true;
break;
}

// adjust quantity
cancelledQuantity += refundLineItem.Quantity;
isCancelled = true;
break;
}

// adjust quantity
cancelledQuantity += refundLineItem.Quantity;
}

if ( !isCancelled )
{
orderItem.Quantity -= cancelledQuantity;
actualOrderItems.Add( orderItem );
}
if( isCancelled )
continue;

orderItem.Quantity -= cancelledQuantity;
actualOrderItems.Add( orderItem );
}

order.OrderItems = actualOrderItems;
}

private int GetOrdersCount( string updatedOrdersEndpoint, Mark mark, CancellationToken token )
{
var count = ActionPolicies.GetPolicy( mark, this._shopName, token ).Get(
() => this._throttler.Execute(
() => this._webRequestServices.GetResponse< OrdersCount >( _shopifyCommandFactory.CreateGetOrdersCountCommand(), updatedOrdersEndpoint, token, mark, this._timeouts[ ShopifyOperationEnum.GetOrdersCount ] ).Count ) );
return count;
}

private Task< int > GetOrdersCountAsync( string updatedOrdersEndpoint, Mark mark, CancellationToken token )
{
var count = ActionPolicies.GetPolicyAsync( mark, this._shopName, token ).Get(
() => this._throttlerAsync.ExecuteAsync(
async () => ( await this._webRequestServices.GetResponseAsync< OrdersCount >( _shopifyCommandFactory.CreateGetOrdersCountCommand(), updatedOrdersEndpoint, token, mark, this._timeouts[ ShopifyOperationEnum.GetOrdersCount ] ) ).Count ) );
return count;
}
#endregion

#region Products
Expand Down Expand Up @@ -463,23 +447,7 @@ private static bool FilterProductVariants( ProductVariant variant )
{
return variant.InventoryItem.Tracked && !string.IsNullOrEmpty( variant.Sku );
}

private int GetProductsCount( Mark mark, CancellationToken token )
{
var count = ActionPolicies.GetPolicy( mark, this._shopName, token ).Get(
() => this._throttler.Execute(
() => this._webRequestServices.GetResponse< ProductsCount >( _shopifyCommandFactory.CreateGetProductsCountCommand(), EndpointsBuilder.EmptyEndpoint, token, mark, this._timeouts[ ShopifyOperationEnum.GetProductsCount ] ).Count ) );
return count;
}

private Task< int > GetProductsCountAsync( Mark mark, CancellationToken token )
{
var count = ActionPolicies.GetPolicyAsync( mark, this._shopName, token ).Get(
() => this._throttlerAsync.ExecuteAsync(
async () => ( await this._webRequestServices.GetResponseAsync< ProductsCount >( _shopifyCommandFactory.CreateGetProductsCountCommand(), EndpointsBuilder.EmptyEndpoint, token, mark, this._timeouts[ ShopifyOperationEnum.GetProductsCount ] ) ).Count ) );
return count;
}


private ShopifyProducts CollectProductsFromAllPages( CancellationToken token, Mark mark, int timeout )
{
var products = new ShopifyProducts();
Expand Down
70 changes: 70 additions & 0 deletions src/ShopifyAccessTests/ShopifyAccessTests/Orders/OrdersTests.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,70 @@
using NUnit.Framework;
using NUnit.Framework.Internal;
using ServiceStack.Text;
using ShopifyAccess;
using ShopifyAccess.Models.Order;

namespace ShopifyAccessTests.Orders
{
[ TestFixture ]
public class OrderTests
{
private static readonly Randomizer _randomizer = new Randomizer();

[ Test ]
public void ProcessRefundOrderLineItems_ReturnLineItemQuantityRefundDeducted_WhenIsRefundQuantityLessThanLineItemQuantity()
{
// Arrange
var quantity = _randomizer.Next( 2, int.MaxValue );
var refundQuantity = _randomizer.Next( 1, quantity - 1 );
var shopifyOrderJson = GenerateShopifyOrderJsonWithRefund( quantity, refundQuantity );
var shopifyOrder = JsonSerializer.DeserializeFromString< ShopifyOrder >( shopifyOrderJson );

// Act
ShopifyService.ProcessRefundOrderLineItems( shopifyOrder );

// Assert
Assert.That( shopifyOrder.OrderItems[ 0 ].Quantity, Is.EqualTo( quantity - refundQuantity ) );
}

[ Test ]
public void ProcessRefundOrderLineItems_LineItemRemovedFromOrder_WhenIsRefundQuantityEqualsToLineItemQuantity_andRestockTypeIsCancel()
{
// Arrange
var quantity = _randomizer.Next( 2, int.MaxValue );
var shopifyOrderJson = GenerateShopifyOrderJsonWithRefund( quantity, quantity, restockType: "cancel" );
var shopifyOrder = JsonSerializer.DeserializeFromString< ShopifyOrder >( shopifyOrderJson );

// Act
ShopifyService.ProcessRefundOrderLineItems( shopifyOrder );

// Assert
Assert.That( shopifyOrder.OrderItems.Count, Is.EqualTo( 0 ) );
}

private static string GenerateShopifyOrderJsonWithRefund( int orderQuantity, int refundQuantity, string restockType = "" )
{
var lineItemId = _randomizer.Next();
return @"
{
""line_items"": [
{
""id"": " + lineItemId + @",
""quantity"": " + orderQuantity + @"
}
],
""refunds"": [
{
""refund_line_items"": [
{
""line_item_id"": " + lineItemId + @",
""quantity"": " + refundQuantity + @",
""restock_type"": " + restockType + @"
}
]
}
]
}";
}
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -110,6 +110,7 @@
<Compile Include="Orders\Models\ShopifyOrderTests.cs" />
<Compile Include="Orders\OrderMapperTests.cs" />
<Compile Include="Orders\OrdersListTests.cs" />
<Compile Include="Orders\OrdersTests.cs" />
<Compile Include="Products\Models\ShopifyProductVariantTests.cs" />
<Compile Include="Products\ProductVariantTests.cs" />
<Compile Include="Properties\AssemblyInfo.cs" />
Expand Down

0 comments on commit c35a4a4

Please sign in to comment.