From 808af354d318cf437e75c14d89adca8e1d198b29 Mon Sep 17 00:00:00 2001 From: Onat Buyukakkus <55088871+onbuyuka@users.noreply.github.com> Date: Mon, 20 Oct 2025 16:57:52 +0200 Subject: [PATCH 1/4] Accept request on the fulfillment service before syncing shipments --- .../ShpfyGQLAcceptFFRequest.Codeunit.al | 29 +++++ .../ShpfyGQLAssignedFFOrders.Codeunit.al | 29 +++++ .../ShpfyGQLFFOrdersFromOrder.Codeunit.al | 2 +- .../ShpfyGQLNextAssignedFFOrders.Codeunit.al | 29 +++++ .../ShpfyGQLNextFFOrdersFromOrd.Codeunit.al | 2 +- .../GraphQL/Enums/ShpfyGraphQLType.Enum.al | 15 +++ .../ShpfyFulfillmentOrdersAPI.Codeunit.al | 80 ++++++++++++ .../Enums/ShpfyFFRequestStatus.Enum.al | 52 ++++++++ .../ShpfyFulFillmentOrderHeader.Table.al | 6 + .../ShpfyExportShipments.Codeunit.al | 30 ++++- .../Reports/ShpfySyncShipmToShopify.Report.al | 8 +- .../FulfillmentOrderAcceptResponse.txt | 1 + .../ShpfySkippedRecordLogTest.Codeunit.al | 6 +- .../Shipping/ShpfyShippingHelper.Codeunit.al | 4 +- .../Shipping/ShpfyShippingTest.Codeunit.al | 121 ++++++++++++++++-- 15 files changed, 392 insertions(+), 22 deletions(-) create mode 100644 src/Apps/W1/Shopify/App/src/GraphQL/Codeunits/ShpfyGQLAcceptFFRequest.Codeunit.al create mode 100644 src/Apps/W1/Shopify/App/src/GraphQL/Codeunits/ShpfyGQLAssignedFFOrders.Codeunit.al create mode 100644 src/Apps/W1/Shopify/App/src/GraphQL/Codeunits/ShpfyGQLNextAssignedFFOrders.Codeunit.al create mode 100644 src/Apps/W1/Shopify/App/src/Order Fulfillments/Enums/ShpfyFFRequestStatus.Enum.al create mode 100644 src/Apps/W1/Shopify/Test/.resources/Shipping/FulfillmentOrderAcceptResponse.txt diff --git a/src/Apps/W1/Shopify/App/src/GraphQL/Codeunits/ShpfyGQLAcceptFFRequest.Codeunit.al b/src/Apps/W1/Shopify/App/src/GraphQL/Codeunits/ShpfyGQLAcceptFFRequest.Codeunit.al new file mode 100644 index 0000000000..557fd3df75 --- /dev/null +++ b/src/Apps/W1/Shopify/App/src/GraphQL/Codeunits/ShpfyGQLAcceptFFRequest.Codeunit.al @@ -0,0 +1,29 @@ +// ------------------------------------------------------------------------------------------------ +// Copyright (c) Microsoft Corporation. All rights reserved. +// Licensed under the MIT License. See License.txt in the project root for license information. +// ------------------------------------------------------------------------------------------------ + +namespace Microsoft.Integration.Shopify; + +codeunit 30412 "Shpfy GQL AcceptFFRequest" implements "Shpfy IGraphQL" +{ + Access = Internal; + + /// + /// GetGraphQL. + /// + /// Return value of type Text. + internal procedure GetGraphQL(): Text + begin + exit('{"query":"mutation { fulfillmentOrderAcceptFulfillmentRequest(id: \"gid://shopify/FulfillmentOrder/{{FulfillmentOrderId}}\") { fulfillmentOrder { id requestStatus } userErrors { field message }}}"}'); + end; + + /// + /// GetExpectedCost. + /// + /// Return value of type Integer. + internal procedure GetExpectedCost(): Integer + begin + exit(10); + end; +} diff --git a/src/Apps/W1/Shopify/App/src/GraphQL/Codeunits/ShpfyGQLAssignedFFOrders.Codeunit.al b/src/Apps/W1/Shopify/App/src/GraphQL/Codeunits/ShpfyGQLAssignedFFOrders.Codeunit.al new file mode 100644 index 0000000000..0496461c27 --- /dev/null +++ b/src/Apps/W1/Shopify/App/src/GraphQL/Codeunits/ShpfyGQLAssignedFFOrders.Codeunit.al @@ -0,0 +1,29 @@ +// ------------------------------------------------------------------------------------------------ +// Copyright (c) Microsoft Corporation. All rights reserved. +// Licensed under the MIT License. See License.txt in the project root for license information. +// ------------------------------------------------------------------------------------------------ + +namespace Microsoft.Integration.Shopify; + +codeunit 30410 "Shpfy GQL AssignedFFOrders" implements "Shpfy IGraphQL" +{ + Access = Internal; + + /// + /// GetGraphQL. + /// + /// Return value of type Text. + internal procedure GetGraphQL(): Text + begin + exit('{"query":"{ assignedFulfillmentOrders(assignmentStatus: FULFILLMENT_REQUESTED, first: 25) { pageInfo { hasNextPage } edges { cursor node { id status requestStatus }}}}"}'); + end; + + /// + /// GetExpectedCost. + /// + /// Return value of type Integer. + internal procedure GetExpectedCost(): Integer + begin + exit(12); + end; +} diff --git a/src/Apps/W1/Shopify/App/src/GraphQL/Codeunits/ShpfyGQLFFOrdersFromOrder.Codeunit.al b/src/Apps/W1/Shopify/App/src/GraphQL/Codeunits/ShpfyGQLFFOrdersFromOrder.Codeunit.al index 910b2fec6d..7e7e927062 100644 --- a/src/Apps/W1/Shopify/App/src/GraphQL/Codeunits/ShpfyGQLFFOrdersFromOrder.Codeunit.al +++ b/src/Apps/W1/Shopify/App/src/GraphQL/Codeunits/ShpfyGQLFFOrdersFromOrder.Codeunit.al @@ -15,7 +15,7 @@ codeunit 30267 "Shpfy GQL FFOrdersFromOrder" implements "Shpfy IGraphQL" /// Return value of type Text. internal procedure GetGraphQL(): Text begin - exit('{"query":"{order(id: \"gid:\/\/shopify\/Order\/{{OrderId}}\") { legacyResourceId fulfillmentOrders(first: 25) { pageInfo { hasNextPage } edges { cursor node { id updatedAt status assignedLocation {location {legacyResourceId}} order {legacyResourceId} deliveryMethod {methodType}}}}}}"}'); + exit('{"query":"{order(id: \"gid:\/\/shopify\/Order\/{{OrderId}}\") { legacyResourceId fulfillmentOrders(first: 25) { pageInfo { hasNextPage } edges { cursor node { id updatedAt status requestStatus assignedLocation {location {legacyResourceId}} order {legacyResourceId} deliveryMethod {methodType}}}}}}"}'); end; /// diff --git a/src/Apps/W1/Shopify/App/src/GraphQL/Codeunits/ShpfyGQLNextAssignedFFOrders.Codeunit.al b/src/Apps/W1/Shopify/App/src/GraphQL/Codeunits/ShpfyGQLNextAssignedFFOrders.Codeunit.al new file mode 100644 index 0000000000..e08da47a0d --- /dev/null +++ b/src/Apps/W1/Shopify/App/src/GraphQL/Codeunits/ShpfyGQLNextAssignedFFOrders.Codeunit.al @@ -0,0 +1,29 @@ +// ------------------------------------------------------------------------------------------------ +// Copyright (c) Microsoft Corporation. All rights reserved. +// Licensed under the MIT License. See License.txt in the project root for license information. +// ------------------------------------------------------------------------------------------------ + +namespace Microsoft.Integration.Shopify; + +codeunit 30411 "Shpfy GQL NextAssignedFFOrders" implements "Shpfy IGraphQL" +{ + Access = Internal; + + /// + /// GetGraphQL. + /// + /// Return value of type Text. + internal procedure GetGraphQL(): Text + begin + exit('{"query":"{ assignedFulfillmentOrders(assignmentStatus: FULFILLMENT_REQUESTED, first: 25, after: \"{{After}}\") { pageInfo { hasNextPage } edges { cursor node { id status requestStatus }}}}"}'); + end; + + /// + /// GetExpectedCost. + /// + /// Return value of type Integer. + internal procedure GetExpectedCost(): Integer + begin + exit(12); + end; +} diff --git a/src/Apps/W1/Shopify/App/src/GraphQL/Codeunits/ShpfyGQLNextFFOrdersFromOrd.Codeunit.al b/src/Apps/W1/Shopify/App/src/GraphQL/Codeunits/ShpfyGQLNextFFOrdersFromOrd.Codeunit.al index 7ac6b02287..92701e8d34 100644 --- a/src/Apps/W1/Shopify/App/src/GraphQL/Codeunits/ShpfyGQLNextFFOrdersFromOrd.Codeunit.al +++ b/src/Apps/W1/Shopify/App/src/GraphQL/Codeunits/ShpfyGQLNextFFOrdersFromOrd.Codeunit.al @@ -15,7 +15,7 @@ codeunit 30268 "Shpfy GQL NextFFOrdersFromOrd" implements "Shpfy IGraphQL" /// Return value of type Text. internal procedure GetGraphQL(): Text begin - exit('{"query":"{order(id: \"gid:\/\/shopify\/Order\/{{OrderId}}\") { legacyResourceId fulfillmentOrders(first: 25, after:\"{{After}}\") { pageInfo { hasNextPage } edges { cursor node { id updatedAt status assignedLocation {location {legacyResourceId}} order {legacyResourceId} deliveryMethod {methodType}}}}}}"}'); + exit('{"query":"{order(id: \"gid:\/\/shopify\/Order\/{{OrderId}}\") { legacyResourceId fulfillmentOrders(first: 25, after:\"{{After}}\") { pageInfo { hasNextPage } edges { cursor node { id updatedAt status requestStatus assignedLocation {location {legacyResourceId}} order {legacyResourceId} deliveryMethod {methodType}}}}}}"}'); end; /// diff --git a/src/Apps/W1/Shopify/App/src/GraphQL/Enums/ShpfyGraphQLType.Enum.al b/src/Apps/W1/Shopify/App/src/GraphQL/Enums/ShpfyGraphQLType.Enum.al index f14e14c3c6..575b9c62f3 100644 --- a/src/Apps/W1/Shopify/App/src/GraphQL/Enums/ShpfyGraphQLType.Enum.al +++ b/src/Apps/W1/Shopify/App/src/GraphQL/Enums/ShpfyGraphQLType.Enum.al @@ -660,4 +660,19 @@ enum 30111 "Shpfy GraphQL Type" implements "Shpfy IGraphQL" Caption = 'Get Company Location'; Implementation = "Shpfy IGraphQL" = "Shpfy GQL CompLocation"; } + value(134; GetAssignedFulfillmentOrders) + { + Caption = 'Get Assigned Fulfillment Orders'; + Implementation = "Shpfy IGraphQL" = "Shpfy GQL AssignedFFOrders"; + } + value(135; GetNextAssignedFulfillmentOrders) + { + Caption = 'Get Next Assigned Fulfillment Orders'; + Implementation = "Shpfy IGraphQL" = "Shpfy GQL NextAssignedFFOrders"; + } + value(136; AcceptFulfillmentRequest) + { + Caption = 'Accept Fulfillment Request'; + Implementation = "Shpfy IGraphQL" = "Shpfy GQL AcceptFFRequest"; + } } diff --git a/src/Apps/W1/Shopify/App/src/Order Fulfillments/Codeunits/ShpfyFulfillmentOrdersAPI.Codeunit.al b/src/Apps/W1/Shopify/App/src/Order Fulfillments/Codeunits/ShpfyFulfillmentOrdersAPI.Codeunit.al index 6569053a9c..251c7d45d9 100644 --- a/src/Apps/W1/Shopify/App/src/Order Fulfillments/Codeunits/ShpfyFulfillmentOrdersAPI.Codeunit.al +++ b/src/Apps/W1/Shopify/App/src/Order Fulfillments/Codeunits/ShpfyFulfillmentOrdersAPI.Codeunit.al @@ -91,6 +91,7 @@ codeunit 30238 "Shpfy Fulfillment Orders API" FulfillmentOrderHeader."Shopify Location Id" := JsonHelper.GetValueAsBigInteger(JNode, 'assignedLocation.location.legacyResourceId'); FulfillmentOrderHeader."Updated At" := JsonHelper.GetValueAsDateTime(JNode, 'updatedAt'); FulfillmentOrderHeader.Status := CopyStr(JsonHelper.GetValueAsText(JNode, 'status'), 1, MaxStrLen(FulfillmentOrderHeader.Status)); + FulfillmentOrderHeader."Request Status" := ConvertToRequestStatus(JsonHelper.GetValueAsText(JNode, 'requestStatus')); FulfillmentOrderHeader."Delivery Method Type" := ConvertToDeliveryMethodType(JsonHelper.GetValueAsText(JNode, 'deliveryMethod.methodType')); if not FulfillmentOrderHeader.Insert() then FulfillmentOrderHeader.Modify(); @@ -199,6 +200,76 @@ codeunit 30238 "Shpfy Fulfillment Orders API" until not JsonHelper.GetValueAsBoolean(JResponse, 'data.order.fulfillmentOrders.pageInfo.hasNextPage'); end; + internal procedure GetAssignedFulfillmentOrders(Shop: Record "Shpfy Shop"; var FulfillmentOrderIds: Dictionary of [BigInteger, Code[20]]) + var + Cursor: Text; + Parameters: Dictionary of [Text, Text]; + JResponse: JsonToken; + begin + if not Shop."Fulfillment Service Activated" then + exit; + + CommunicationMgt.SetShop(Shop); + GraphQLType := "Shpfy GraphQL Type"::GetAssignedFulfillmentOrders; + + repeat + JResponse := CommunicationMgt.ExecuteGraphQL(GraphQLType, Parameters); + if JResponse.IsObject() then + if ExtractAssignedFulfillmentOrderIds(Shop.Code, JResponse.AsObject(), FulfillmentOrderIds, Cursor) then begin + if Parameters.ContainsKey('After') then + Parameters.Set('After', Cursor) + else + Parameters.Add('After', Cursor); + GraphQLType := "Shpfy GraphQL Type"::GetNextAssignedFulfillmentOrders; + end else + break; + until not JsonHelper.GetValueAsBoolean(JResponse, 'data.assignedFulfillmentOrders.pageInfo.hasNextPage'); + end; + + local procedure ExtractAssignedFulfillmentOrderIds(ShopCode: Code[20]; JResponse: JsonObject; var FulfillmentOrderIds: Dictionary of [BigInteger, Code[20]]; var Cursor: Text): Boolean + var + JEdges: JsonArray; + JNode: JsonObject; + JItem: JsonToken; + Id: BigInteger; + begin + if JsonHelper.GetJsonArray(JResponse, JEdges, 'data.assignedFulfillmentOrders.edges') then begin + foreach JItem in JEdges do begin + Cursor := JsonHelper.GetValueAsText(JItem.AsObject(), 'cursor'); + if JsonHelper.GetJsonObject(JItem.AsObject(), JNode, 'node') then begin + Id := CommunicationMgt.GetIdOfGId(JsonHelper.GetValueAsText(JNode, 'id')); + if not FulfillmentOrderIds.ContainsKey(Id) then + FulfillmentOrderIds.Add(Id, ShopCode); + end; + end; + exit(JEdges.Count() > 0); + end; + exit(false); + end; + + internal procedure AcceptFulfillmentRequest(Shop: Record "Shpfy Shop"; var FulfillmentOrderHeader: Record "Shpfy FulFillment Order Header"): Boolean + var + Parameters: Dictionary of [Text, Text]; + JResponse: JsonToken; + NewRequestStatus: Enum "Shpfy FF Request Status"; + begin + CommunicationMgt.SetShop(Shop); + Parameters.Add('FulfillmentOrderId', Format(FulfillmentOrderHeader."Shopify Fulfillment Order Id")); + + GraphQLType := "Shpfy GraphQL Type"::AcceptFulfillmentRequest; + JResponse := CommunicationMgt.ExecuteGraphQL(GraphQLType, Parameters); + + if JResponse.IsObject() then begin + NewRequestStatus := ConvertToRequestStatus(JsonHelper.GetValueAsText(JResponse, 'data.fulfillmentOrderAcceptFulfillmentRequest.fulfillmentOrder.requestStatus')); + if NewRequestStatus = Enum::"Shpfy FF Request Status"::ACCEPTED then begin + FulfillmentOrderHeader."Request Status" := NewRequestStatus; + FulfillmentOrderHeader.Modify(); + exit(true); + end; + end; + exit(false); + end; + local procedure ConvertToDeliveryMethodType(Value: Text): Enum "Shpfy Delivery Method Type" begin Value := CommunicationMgt.ConvertToCleanOptionValue(Value); @@ -207,4 +278,13 @@ codeunit 30238 "Shpfy Fulfillment Orders API" else exit(Enum::"Shpfy Delivery Method Type"::" "); end; + + local procedure ConvertToRequestStatus(Value: Text): Enum "Shpfy FF Request Status" + begin + Value := CommunicationMgt.ConvertToCleanOptionValue(Value); + if Enum::"Shpfy FF Request Status".Names().Contains(Value) then + exit(Enum::"Shpfy FF Request Status".FromInteger(Enum::"Shpfy FF Request Status".Ordinals().Get(Enum::"Shpfy FF Request Status".Names().IndexOf(Value)))) + else + exit(Enum::"Shpfy FF Request Status"::" "); + end; } \ No newline at end of file diff --git a/src/Apps/W1/Shopify/App/src/Order Fulfillments/Enums/ShpfyFFRequestStatus.Enum.al b/src/Apps/W1/Shopify/App/src/Order Fulfillments/Enums/ShpfyFFRequestStatus.Enum.al new file mode 100644 index 0000000000..b5b0d180c8 --- /dev/null +++ b/src/Apps/W1/Shopify/App/src/Order Fulfillments/Enums/ShpfyFFRequestStatus.Enum.al @@ -0,0 +1,52 @@ +// ------------------------------------------------------------------------------------------------ +// Copyright (c) Microsoft Corporation. All rights reserved. +// Licensed under the MIT License. See License.txt in the project root for license information. +// ------------------------------------------------------------------------------------------------ + +namespace Microsoft.Integration.Shopify; + +/// +/// Enum Shpfy FF Request Status (ID 30178). +/// +enum 30178 "Shpfy FF Request Status" +{ + Access = Public; + Caption = 'Shopify Fulfillment Request Status'; + + value(0; " ") + { + Caption = ' '; + } + value(1; Accepted) + { + Caption = 'Accepted'; + } + value(2; "Cancellation Accepted") + { + Caption = 'Cancellation Accepted'; + } + value(3; "Cancellation Rejected") + { + Caption = 'Cancellation Rejected'; + } + value(4; "Cancellation Requested") + { + Caption = 'Cancellation Requested'; + } + value(5; Closed) + { + Caption = 'Closed'; + } + value(6; Rejected) + { + Caption = 'Rejected'; + } + value(7; Submitted) + { + Caption = 'Submitted'; + } + value(8; Unsubmitted) + { + Caption = 'Unsubmitted'; + } +} diff --git a/src/Apps/W1/Shopify/App/src/Order Fulfillments/Tables/ShpfyFulFillmentOrderHeader.Table.al b/src/Apps/W1/Shopify/App/src/Order Fulfillments/Tables/ShpfyFulFillmentOrderHeader.Table.al index 8fb9d54282..ceae6b2033 100644 --- a/src/Apps/W1/Shopify/App/src/Order Fulfillments/Tables/ShpfyFulFillmentOrderHeader.Table.al +++ b/src/Apps/W1/Shopify/App/src/Order Fulfillments/Tables/ShpfyFulFillmentOrderHeader.Table.al @@ -60,6 +60,12 @@ table 30143 "Shpfy FulFillment Order Header" DataClassification = SystemMetadata; Editable = false; } + field(10; "Request Status"; Enum "Shpfy FF Request Status") + { + Caption = 'Request Status'; + DataClassification = SystemMetadata; + Editable = false; + } } keys { diff --git a/src/Apps/W1/Shopify/App/src/Shipping/Codeunits/ShpfyExportShipments.Codeunit.al b/src/Apps/W1/Shopify/App/src/Shipping/Codeunits/ShpfyExportShipments.Codeunit.al index 57fc70a903..1f790f98d1 100644 --- a/src/Apps/W1/Shopify/App/src/Shipping/Codeunits/ShpfyExportShipments.Codeunit.al +++ b/src/Apps/W1/Shopify/App/src/Shipping/Codeunits/ShpfyExportShipments.Codeunit.al @@ -29,7 +29,8 @@ codeunit 30190 "Shpfy Export Shipments" /// Create Shopify Fulfillment. /// /// Parameter of type Record "Sales Shipment Header". - internal procedure CreateShopifyFulfillment(var SalesShipmentHeader: Record "Sales Shipment Header"); + /// Parameter of type Dictionary of [BigInteger, Code[20]]. + internal procedure CreateShopifyFulfillment(var SalesShipmentHeader: Record "Sales Shipment Header"; var AssignedFulfillmentOrderIds: Dictionary of [BigInteger, Code[20]]); var ShipmentLocation: Query "Shpfy Shipment Location"; begin @@ -37,11 +38,11 @@ codeunit 30190 "Shpfy Export Shipments" ShipmentLocation.SetRange(No, SalesShipmentHeader."No."); if ShipmentLocation.Open() then while ShipmentLocation.Read() do - CreateShopifyFulfillment(SalesShipmentHeader, ShipmentLocation.LocationId, ShipmentLocation.DeliveryMethodType); + CreateShopifyFulfillment(SalesShipmentHeader, ShipmentLocation.LocationId, ShipmentLocation.DeliveryMethodType, AssignedFulfillmentOrderIds); end; end; - local procedure CreateShopifyFulfillment(var SalesShipmentHeader: Record "Sales Shipment Header"; LocationId: BigInteger; DeliveryMethodType: Enum "Shpfy Delivery Method Type"); + local procedure CreateShopifyFulfillment(var SalesShipmentHeader: Record "Sales Shipment Header"; LocationId: BigInteger; DeliveryMethodType: Enum "Shpfy Delivery Method Type"; var AssignedFulfillmentOrderIds: Dictionary of [BigInteger, Code[20]]); var Shop: Record "Shpfy Shop"; ShopifyOrderHeader: Record "Shpfy Order Header"; @@ -57,7 +58,7 @@ codeunit 30190 "Shpfy Export Shipments" if ShopifyOrderHeader.Get(SalesShipmentHeader."Shpfy Order Id") then begin ShopifyCommunicationMgt.SetShop(ShopifyOrderHeader."Shop Code"); Shop.Get(ShopifyOrderHeader."Shop Code"); - FulfillmentOrderRequests := CreateFulfillmentOrderRequest(SalesShipmentHeader, Shop, LocationId, DeliveryMethodType); + FulfillmentOrderRequests := CreateFulfillmentOrderRequest(SalesShipmentHeader, Shop, LocationId, DeliveryMethodType, AssignedFulfillmentOrderIds); if FulfillmentOrderRequests.Count <> 0 then foreach FulfillmentOrderRequest in FulfillmentOrderRequests do begin JResponse := ShopifyCommunicationMgt.ExecuteGraphQL(FulfillmentOrderRequest); @@ -79,7 +80,7 @@ codeunit 30190 "Shpfy Export Shipments" end; end; - internal procedure CreateFulfillmentOrderRequest(SalesShipmentHeader: Record "Sales Shipment Header"; Shop: Record "Shpfy Shop"; LocationId: BigInteger; DeliveryMethodType: Enum "Shpfy Delivery Method Type") Requests: List of [Text]; + internal procedure CreateFulfillmentOrderRequest(SalesShipmentHeader: Record "Sales Shipment Header"; Shop: Record "Shpfy Shop"; LocationId: BigInteger; DeliveryMethodType: Enum "Shpfy Delivery Method Type"; var AssignedFulfillmentOrderIds: Dictionary of [BigInteger, Code[20]]) Requests: List of [Text]; var SalesShipmentLine: Record "Sales Shipment Line"; ShippingAgent: Record "Shipping Agent"; @@ -119,6 +120,8 @@ codeunit 30190 "Shpfy Export Shipments" TempFulfillmentOrderLine."Quantity to Fulfill" := Round(SalesShipmentLine.Quantity, 1, '='); TempFulfillmentOrderLine.Insert(); end; + // Accept pending fulfillment request before creating fulfillment + AcceptPendingFulfillmentRequests(Shop, FulfillmentOrderLine."Shopify Fulfillment Order Id", AssignedFulfillmentOrderIds); end; until SalesShipmentLine.Next() = 0; @@ -163,6 +166,10 @@ codeunit 30190 "Shpfy Export Shipments" GraphQuery.Append('lineItemsByFulfillmentOrder: ['); GraphQueryStart := GraphQuery.ToText(); repeat + // Skip fulfillment orders that are assigned and not accepted + if AssignedFulfillmentOrderIds.ContainsKey(TempFulfillmentOrderLine."Shopify Fulfillment Order Id") then + continue; + if PrevFulfillmentOrderId <> TempFulfillmentOrderLine."Shopify Fulfillment Order Id" then begin if PrevFulfillmentOrderId <> 0 then GraphQuery.Append(']},'); @@ -229,4 +236,17 @@ codeunit 30190 "Shpfy Export Shipments" else exit(Shop."Send Shipping Confirmation"); end; + + local procedure AcceptPendingFulfillmentRequests(Shop: Record "Shpfy Shop"; FulfillmentOrderId: BigInteger; var AssignedFulfillmentOrderIds: Dictionary of [BigInteger, Code[20]]) + var + FulfillmentOrderHeader: Record "Shpfy FulFillment Order Header"; + FulfillmentOrdersAPI: Codeunit "Shpfy Fulfillment Orders API"; + begin + // Check if this fulfillment order needs to be accepted and remove from dictionary + if AssignedFulfillmentOrderIds.ContainsKey(FulfillmentOrderId) then + if FulfillmentOrderHeader.Get(FulfillmentOrderId) then + if (FulfillmentOrderHeader.Status = 'OPEN') and (FulfillmentOrderHeader."Request Status" = FulfillmentOrderHeader."Request Status"::SUBMITTED) then + if FulfillmentOrdersAPI.AcceptFulfillmentRequest(Shop, FulfillmentOrderHeader) then + AssignedFulfillmentOrderIds.Remove(FulfillmentOrderId); + end; } \ No newline at end of file diff --git a/src/Apps/W1/Shopify/App/src/Shipping/Reports/ShpfySyncShipmToShopify.Report.al b/src/Apps/W1/Shopify/App/src/Shipping/Reports/ShpfySyncShipmToShopify.Report.al index dbdba2018d..e457e1dce8 100644 --- a/src/Apps/W1/Shopify/App/src/Shipping/Reports/ShpfySyncShipmToShopify.Report.al +++ b/src/Apps/W1/Shopify/App/src/Shipping/Reports/ShpfySyncShipmToShopify.Report.al @@ -48,8 +48,13 @@ report 30109 "Shpfy Sync Shipm. to Shopify" end else if ShopifyOrderHeader.Get("Sales Shipment Header"."Shpfy Order Id") then begin Shop.Get(ShopifyOrderHeader."Shop Code"); + + // Get assigned fulfillment orders if not already retrieved for this shop + if not AssignedFulfillmentOrderIds.Values.Contains(Shop.Code) then + FulfillmentOrdersAPI.GetAssignedFulfillmentOrders(Shop, AssignedFulfillmentOrderIds); + FulfillmentOrdersAPI.GetShopifyFulfillmentOrdersFromShopifyOrder(Shop, "Sales Shipment Header"."Shpfy Order Id"); - ExportShipments.CreateShopifyFulfillment("Sales Shipment Header"); + ExportShipments.CreateShopifyFulfillment("Sales Shipment Header", AssignedFulfillmentOrderIds); end else SkippedRecord.LogSkippedRecord("Sales Shipment Header"."Shpfy Order Id", "Sales Shipment Header".RecordId, StrSubstNo(ShopifyOrderNotExistsLbl, "Sales Shipment Header"."Shpfy Order Id"), Shop); end; @@ -59,6 +64,7 @@ report 30109 "Shpfy Sync Shipm. to Shopify" var ExportShipments: Codeunit "Shpfy Export Shipments"; FulfillmentOrdersAPI: Codeunit "Shpfy Fulfillment Orders API"; + AssignedFulfillmentOrderIds: Dictionary of [BigInteger, Code[20]]; NoLinesApplicableLbl: Label 'No lines applicable for fulfillment.'; ShopifyOrderNotExistsLbl: Label 'Shopify order %1 does not exist.', Comment = '%1 = Shopify Order Id'; } \ No newline at end of file diff --git a/src/Apps/W1/Shopify/Test/.resources/Shipping/FulfillmentOrderAcceptResponse.txt b/src/Apps/W1/Shopify/Test/.resources/Shipping/FulfillmentOrderAcceptResponse.txt new file mode 100644 index 0000000000..9f6e33c690 --- /dev/null +++ b/src/Apps/W1/Shopify/Test/.resources/Shipping/FulfillmentOrderAcceptResponse.txt @@ -0,0 +1 @@ +{"data":{"fulfillmentOrderAcceptFulfillmentRequest":{"fulfillmentOrder":{"id":"gid://shopify/FulfillmentOrder/8683141071148","requestStatus":"ACCEPTED"},"userErrors":[]}}} \ No newline at end of file diff --git a/src/Apps/W1/Shopify/Test/Logs/ShpfySkippedRecordLogTest.Codeunit.al b/src/Apps/W1/Shopify/Test/Logs/ShpfySkippedRecordLogTest.Codeunit.al index cbc1a6b59e..ee0b18a844 100644 --- a/src/Apps/W1/Shopify/Test/Logs/ShpfySkippedRecordLogTest.Codeunit.al +++ b/src/Apps/W1/Shopify/Test/Logs/ShpfySkippedRecordLogTest.Codeunit.al @@ -696,6 +696,7 @@ codeunit 139581 "Shpfy Skipped Record Log Test" SkippedRecord: Record "Shpfy Skipped Record"; ExportShipments: Codeunit "Shpfy Export Shipments"; ShippingHelper: Codeunit "Shpfy Shipping Helper"; + AssignedFulfillmentOrderIds: Dictionary of [BigInteger, Code[20]]; ShopifyOrderId: BigInteger; begin // [SCENARIO] Log skipped record when sales shipment is export is skip because theres no fulfillment lines shopify. @@ -707,7 +708,7 @@ codeunit 139581 "Shpfy Skipped Record Log Test" ShippingHelper.CreateRandomSalesShipment(SalesShipmentHeader, ShopifyOrderId); // [WHEN] Invoke Shopify Sync Shipment to Shopify - ExportShipments.CreateShopifyFulfillment(SalesShipmentHeader); + ExportShipments.CreateShopifyFulfillment(SalesShipmentHeader, AssignedFulfillmentOrderIds); // [THEN] Related record is created in shopify skipped record table. SkippedRecord.SetRange("Record ID", SalesShipmentHeader.RecordId); @@ -723,6 +724,7 @@ codeunit 139581 "Shpfy Skipped Record Log Test" ExportShipments: Codeunit "Shpfy Export Shipments"; ShippingHelper: Codeunit "Shpfy Shipping Helper"; SkippedRecordLogSub: Codeunit "Shpfy Skipped Record Log Sub."; + AssignedFulfillmentOrderIds: Dictionary of [BigInteger, Code[20]]; ShopifyOrderId: BigInteger; DeliveryMethodType: Enum "Shpfy Delivery Method Type"; begin @@ -741,7 +743,7 @@ codeunit 139581 "Shpfy Skipped Record Log Test" // [WHEN] Invoke Shopify Sync Shipment to Shopify BindSubscription(SkippedRecordLogSub); - ExportShipments.CreateShopifyFulfillment(SalesShipmentHeader); + ExportShipments.CreateShopifyFulfillment(SalesShipmentHeader, AssignedFulfillmentOrderIds); UnbindSubscription(SkippedRecordLogSub); // [THEN] Related record is created in shopify skipped record table. diff --git a/src/Apps/W1/Shopify/Test/Shipping/ShpfyShippingHelper.Codeunit.al b/src/Apps/W1/Shopify/Test/Shipping/ShpfyShippingHelper.Codeunit.al index 8dbef6a0e1..aa323f00d2 100644 --- a/src/Apps/W1/Shopify/Test/Shipping/ShpfyShippingHelper.Codeunit.al +++ b/src/Apps/W1/Shopify/Test/Shipping/ShpfyShippingHelper.Codeunit.al @@ -55,7 +55,7 @@ codeunit 139559 "Shpfy Shipping Helper" end; end; - internal procedure CreateShopifyFulfillmentOrder(ShopifyOrderId: BigInteger; DeliveryMethodType: Enum "Shpfy Delivery Method Type"): BigInteger + internal procedure CreateShopifyFulfillmentOrder(ShopifyOrderId: BigInteger; DeliveryMethodType: Enum "Shpfy Delivery Method Type"): Record "Shpfy FulFillment Order Header" var OrderLine: Record "Shpfy Order Line"; FulfillmentOrderHeader: Record "Shpfy FulFillment Order Header"; @@ -87,7 +87,7 @@ codeunit 139559 "Shpfy Shipping Helper" FulfillmentOrderLine.Insert(); until OrderLine.Next() = 0; - exit(FulfillmentOrderHeader."Shopify Fulfillment Order Id"); + exit(FulfillmentOrderHeader); end; internal procedure CreateRandomSalesShipment(var SalesShipmentHeader: Record "Sales Shipment Header"; ShopifyOrderId: BigInteger) diff --git a/src/Apps/W1/Shopify/Test/Shipping/ShpfyShippingTest.Codeunit.al b/src/Apps/W1/Shopify/Test/Shipping/ShpfyShippingTest.Codeunit.al index 3706ce2d65..2bf462fc3b 100644 --- a/src/Apps/W1/Shopify/Test/Shipping/ShpfyShippingTest.Codeunit.al +++ b/src/Apps/W1/Shopify/Test/Shipping/ShpfyShippingTest.Codeunit.al @@ -13,10 +13,14 @@ codeunit 139606 "Shpfy Shipping Test" { Subtype = Test; TestPermissions = Disabled; + TestHttpRequestPolicy = BlockOutboundRequests; var + Shop: Record "Shpfy Shop"; Any: Codeunit Any; LibraryAssert: Codeunit "Library Assert"; + InitializeTest: Codeunit "Shpfy Initialize Test"; + IsInitialized: Boolean; [Test] procedure UnitTestExportShipment() @@ -24,32 +28,33 @@ codeunit 139606 "Shpfy Shipping Test" SalesShipmentHeader: Record "Sales Shipment Header"; SalesShipmentLine: Record "Sales Shipment Line"; OrderLine: Record "Shpfy Order Line"; - Shop: Record "Shpfy Shop"; + FulfillmentOrderHeader: Record "Shpfy FulFillment Order Header"; ExportShipments: Codeunit "Shpfy Export Shipments"; ShippingHelper: Codeunit "Shpfy Shipping Helper"; DeliveryMethodType: Enum "Shpfy Delivery Method Type"; FulfillmentRequest: Text; FulfillmentRequests: List of [Text]; + AssignedFulfillmentOrderIds: Dictionary of [BigInteger, Code[20]]; ShopifyOrderId: BigInteger; - ShopifyFulfillmentOrderId: BigInteger; LocationId: BigInteger; QuantityLbl: Label 'quantity: %1', Comment = '%1 - quantity', Locked = true; begin // [SCENARIO] Export a Sales Shipment record into a Json token that contains the shipping info // [GIVEN] A random Sales Shipment, a random LocationId, a random Shop + Initialize(); LocationId := Any.IntegerInRange(10000, 99999); DeliveryMethodType := DeliveryMethodType::Shipping; ShopifyOrderId := ShippingHelper.CreateRandomShopifyOrder(LocationId, DeliveryMethodType); - ShopifyFulfillmentOrderId := ShippingHelper.CreateShopifyFulfillmentOrder(ShopifyOrderId, DeliveryMethodType); + FulfillmentOrderHeader := ShippingHelper.CreateShopifyFulfillmentOrder(ShopifyOrderId, DeliveryMethodType); ShippingHelper.CreateRandomSalesShipment(SalesShipmentHeader, ShopifyOrderId); // [WHEN] Invoke the function CreateFulfillmentRequest() - FulfillmentRequests := ExportShipments.CreateFulfillmentOrderRequest(SalesShipmentHeader, Shop, LocationId, DeliveryMethodType); + FulfillmentRequests := ExportShipments.CreateFulfillmentOrderRequest(SalesShipmentHeader, Shop, LocationId, DeliveryMethodType, AssignedFulfillmentOrderIds); // [THEN] We must find the correct fulfilment data in the json token LibraryAssert.AreEqual(1, FulfillmentRequests.Count, 'FulfillmentRequest count check'); FulfillmentRequests.Get(1, FulfillmentRequest); - LibraryAssert.IsTrue(FulfillmentRequest.Contains(Format(ShopifyFulfillmentOrderId)), 'Fulfillmentorder Id Check'); + LibraryAssert.IsTrue(FulfillmentRequest.Contains(Format(FulfillmentOrderHeader."Shopify Fulfillment Order Id")), 'Fulfillmentorder Id Check'); LibraryAssert.IsTrue(FulfillmentRequest.Contains(SalesShipmentHeader."Package Tracking No."), 'tracking number check'); // [THEN] We must find the fulfilment lines in the json token @@ -66,33 +71,129 @@ codeunit 139606 "Shpfy Shipping Test" procedure UnitTestExportShipment250Lines() var SalesShipmentHeader: Record "Sales Shipment Header"; - Shop: Record "Shpfy Shop"; + FulfillmentOrderHeader: Record "Shpfy FulFillment Order Header"; ExportShipments: Codeunit "Shpfy Export Shipments"; ShippingHelper: Codeunit "Shpfy Shipping Helper"; DeliveryMethodType: Enum "Shpfy Delivery Method Type"; FulfillmentRequest: Text; FulfillmentRequests: List of [Text]; + AssignedFulfillmentOrderIds: Dictionary of [BigInteger, Code[20]]; ShopifyOrderId: BigInteger; - ShopifyFulfillmentOrderId: BigInteger; LocationId: BigInteger; begin // [SCENARIO] Export a Sales Shipment with more than 250 lines creates two fulfillment requests // [GIVEN] A random Sales Shipment, a random LocationId, a random Shop + Initialize(); LocationId := Any.IntegerInRange(10000, 99999); DeliveryMethodType := DeliveryMethodType::Shipping; ShopifyOrderId := ShippingHelper.CreateRandomShopifyOrder(LocationId, DeliveryMethodType); ShippingHelper.CreateOrderLines(ShopifyOrderId, LocationId, DeliveryMethodType, 300); - ShopifyFulfillmentOrderId := ShippingHelper.CreateShopifyFulfillmentOrder(ShopifyOrderId, DeliveryMethodType); + FulfillmentOrderHeader := ShippingHelper.CreateShopifyFulfillmentOrder(ShopifyOrderId, DeliveryMethodType); ShippingHelper.CreateRandomSalesShipment(SalesShipmentHeader, ShopifyOrderId); // [WHEN] Invoke the function CreateFulfillmentRequest() - FulfillmentRequests := ExportShipments.CreateFulfillmentOrderRequest(SalesShipmentHeader, Shop, LocationId, DeliveryMethodType); + FulfillmentRequests := ExportShipments.CreateFulfillmentOrderRequest(SalesShipmentHeader, Shop, LocationId, DeliveryMethodType, AssignedFulfillmentOrderIds); // [THEN] We must find the correct fulfilment data in the json token LibraryAssert.AreEqual(2, FulfillmentRequests.Count(), 'FulfillmentRequest count check'); foreach FulfillmentRequest in FulfillmentRequests do begin - LibraryAssert.IsTrue(FulfillmentRequest.Contains(Format(ShopifyFulfillmentOrderId)), 'Fulfillmentorder Id Check'); + LibraryAssert.IsTrue(FulfillmentRequest.Contains(Format(FulfillmentOrderHeader."Shopify Fulfillment Order Id")), 'Fulfillmentorder Id Check'); LibraryAssert.IsTrue(FulfillmentRequest.Contains(SalesShipmentHeader."Package Tracking No."), 'tracking number check'); end; end; + + [Test] + [HandlerFunctions('HttpSubmitHandler')] + procedure UnitTestExportFulfillmentServiceShipment() + var + SalesShipmentHeader: Record "Sales Shipment Header"; + SalesShipmentLine: Record "Sales Shipment Line"; + OrderLine: Record "Shpfy Order Line"; + FulfillmentOrderHeader: Record "Shpfy FulFillment Order Header"; + ExportShipments: Codeunit "Shpfy Export Shipments"; + ShippingHelper: Codeunit "Shpfy Shipping Helper"; + DeliveryMethodType: Enum "Shpfy Delivery Method Type"; + FulfillmentRequest: Text; + FulfillmentRequests: List of [Text]; + AssignedFulfillmentOrderIds: Dictionary of [BigInteger, Code[20]]; + ShopifyOrderId: BigInteger; + LocationId: BigInteger; + QuantityLbl: Label 'quantity: %1', Comment = '%1 - quantity', Locked = true; + begin + // [SCENARIO] Export a Sales Shipment record into a Json token that contains the shipping info + // [GIVEN] A random Sales Shipment, a random LocationId, a random Shop + Initialize(); + LocationId := Any.IntegerInRange(10000, 99999); + DeliveryMethodType := DeliveryMethodType::Shipping; + ShopifyOrderId := ShippingHelper.CreateRandomShopifyOrder(LocationId, DeliveryMethodType); + FulfillmentOrderHeader := ShippingHelper.CreateShopifyFulfillmentOrder(ShopifyOrderId, DeliveryMethodType); + ShippingHelper.CreateRandomSalesShipment(SalesShipmentHeader, ShopifyOrderId); + AssignedFulfillmentOrderIds.Add(FulfillmentOrderHeader."Shopify Fulfillment Order Id", Shop.Code); + FulfillmentOrderHeader.Status := 'OPEN'; + FulfillmentOrderHeader."Request Status" := FulfillmentOrderHeader."Request Status"::Submitted; + FulfillmentOrderHeader.Modify(); + + // [WHEN] Invoke the function CreateFulfillmentRequest() + FulfillmentRequests := ExportShipments.CreateFulfillmentOrderRequest(SalesShipmentHeader, Shop, LocationId, DeliveryMethodType, AssignedFulfillmentOrderIds); + + // [THEN] We must find the correct fulfilment data in the json token + LibraryAssert.AreEqual(1, FulfillmentRequests.Count, 'FulfillmentRequest count check'); + FulfillmentRequests.Get(1, FulfillmentRequest); + LibraryAssert.IsTrue(FulfillmentRequest.Contains(Format(FulfillmentOrderHeader."Shopify Fulfillment Order Id")), 'Fulfillmentorder Id Check'); + LibraryAssert.IsTrue(FulfillmentRequest.Contains(SalesShipmentHeader."Package Tracking No."), 'tracking number check'); + LibraryAssert.IsTrue(AssignedFulfillmentOrderIds.Count() = 0, 'Assigned Fulfillment Order Ids count check'); + + // [THEN] We must find the fulfilment lines in the json token + OrderLine.SetRange("Shopify Order Id", ShopifyOrderId); + OrderLine.FindFirst(); +#pragma warning disable AA0210 + SalesShipmentLine.SetRange("Shpfy Order Line Id", OrderLine."Line Id"); +#pragma warning restore AA0210 + SalesShipmentLine.FindFirst(); + LibraryAssert.IsTrue(FulfillmentRequest.Contains(StrSubstNo(QuantityLbl, SalesShipmentLine.Quantity)), 'quantity check'); + end; + + local procedure Initialize() + var + CommunicationMgt: Codeunit "Shpfy Communication Mgt."; + LibraryTestInitialize: Codeunit "Library - Test Initialize"; + LibraryRandom: Codeunit "Library - Random"; + AccessToken: SecretText; + begin + LibraryTestInitialize.OnTestInitialize(Codeunit::"Shpfy Shipping Test"); + ClearLastError(); + + if IsInitialized then + exit; + + LibraryTestInitialize.OnBeforeTestSuiteInitialize(Codeunit::"Shpfy Shipping Test"); + + LibraryRandom.Init(); + + Any.SetDefaultSeed(); + + IsInitialized := true; + Commit(); + + // Creating Shopify Shop + Shop := InitializeTest.CreateShop(); + + CommunicationMgt.SetTestInProgress(false); + + //Register Shopify Access Token + AccessToken := LibraryRandom.RandText(20); + InitializeTest.RegisterAccessTokenForShop(Shop.GetStoreName(), AccessToken); + + LibraryTestInitialize.OnAfterTestSuiteInitialize(Codeunit::"Shpfy Shipping Test"); + end; + + [HttpClientHandler] + internal procedure HttpSubmitHandler(Request: TestHttpRequestMessage; var Response: TestHttpResponseMessage): Boolean + begin + if not InitializeTest.VerifyRequestUrl(Request.Path, Shop."Shopify URL") then + exit(true); + + Response.Content.WriteFrom(NavApp.GetResourceAsText('Shipping/FulfillmentOrderAcceptResponse.txt', TextEncoding::UTF8)); + exit(false); // Prevents actual HTTP call + end; } \ No newline at end of file From decbb9f3dd7d4ece5391bc1a4e5f2ace98f94959 Mon Sep 17 00:00:00 2001 From: Onat Buyukakkus <55088871+onbuyuka@users.noreply.github.com> Date: Mon, 20 Oct 2025 17:01:12 +0200 Subject: [PATCH 2/4] Permissions --- .../App/src/PermissionSets/ShpfyObjects.PermissionSet.al | 3 +++ 1 file changed, 3 insertions(+) diff --git a/src/Apps/W1/Shopify/App/src/PermissionSets/ShpfyObjects.PermissionSet.al b/src/Apps/W1/Shopify/App/src/PermissionSets/ShpfyObjects.PermissionSet.al index f145465716..39baa906a1 100644 --- a/src/Apps/W1/Shopify/App/src/PermissionSets/ShpfyObjects.PermissionSet.al +++ b/src/Apps/W1/Shopify/App/src/PermissionSets/ShpfyObjects.PermissionSet.al @@ -149,9 +149,11 @@ permissionset 30104 "Shpfy - Objects" codeunit "Shpfy Fulfillment API" = X, codeunit "Shpfy Fulfillment Orders API" = X, codeunit "Shpfy Gift Cards" = X, + codeunit "Shpfy GQL AcceptFFRequest" = X, codeunit "Shpfy GQL AddProductImage" = X, codeunit "Shpfy GQL AllCustomerIds" = X, codeunit "Shpfy GQL ApiKey" = X, + codeunit "Shpfy GQL AssignedFFOrders" = X, codeunit "Shpfy GQL BulkOperation" = X, codeunit "Shpfy GQL BulkOperations" = X, codeunit "Shpfy GQL BulkOpMutation" = X, @@ -208,6 +210,7 @@ permissionset 30104 "Shpfy - Objects" codeunit "Shpfy GQL Modify Inventory" = X, codeunit "Shpfy GQL Next Locations" = X, codeunit "Shpfy GQL NextAllCustomerIds" = X, + codeunit "Shpfy GQL NextAssignedFFOrders" = X, codeunit "Shpfy GQL NextCatalogMarkets" = X, codeunit "Shpfy GQL NextCatalogPrices" = X, codeunit "Shpfy GQL NextCatalogProducts" = X, From 8c7dea9bd4fb3d8593fcbd5222e40a26f608a42d Mon Sep 17 00:00:00 2001 From: Onat Buyukakkus <55088871+onbuyuka@users.noreply.github.com> Date: Tue, 21 Oct 2025 12:27:47 +0200 Subject: [PATCH 3/4] Update --- .../src/GraphQL/Codeunits/ShpfyGQLAcceptFFRequest.Codeunit.al | 4 ++++ .../GraphQL/Codeunits/ShpfyGQLAssignedFFOrders.Codeunit.al | 4 ++++ .../Codeunits/ShpfyGQLNextAssignedFFOrders.Codeunit.al | 4 ++++ 3 files changed, 12 insertions(+) diff --git a/src/Apps/W1/Shopify/App/src/GraphQL/Codeunits/ShpfyGQLAcceptFFRequest.Codeunit.al b/src/Apps/W1/Shopify/App/src/GraphQL/Codeunits/ShpfyGQLAcceptFFRequest.Codeunit.al index 557fd3df75..ea5e1cd602 100644 --- a/src/Apps/W1/Shopify/App/src/GraphQL/Codeunits/ShpfyGQLAcceptFFRequest.Codeunit.al +++ b/src/Apps/W1/Shopify/App/src/GraphQL/Codeunits/ShpfyGQLAcceptFFRequest.Codeunit.al @@ -5,6 +5,10 @@ namespace Microsoft.Integration.Shopify; +/// +/// Codeunit Shpfy GQL AcceptFFRequest (ID 30412). +/// Implements the IGraphQL interface for accepting Shopify fulfillment requests using GraphQL. +/// codeunit 30412 "Shpfy GQL AcceptFFRequest" implements "Shpfy IGraphQL" { Access = Internal; diff --git a/src/Apps/W1/Shopify/App/src/GraphQL/Codeunits/ShpfyGQLAssignedFFOrders.Codeunit.al b/src/Apps/W1/Shopify/App/src/GraphQL/Codeunits/ShpfyGQLAssignedFFOrders.Codeunit.al index 0496461c27..959e990b42 100644 --- a/src/Apps/W1/Shopify/App/src/GraphQL/Codeunits/ShpfyGQLAssignedFFOrders.Codeunit.al +++ b/src/Apps/W1/Shopify/App/src/GraphQL/Codeunits/ShpfyGQLAssignedFFOrders.Codeunit.al @@ -5,6 +5,10 @@ namespace Microsoft.Integration.Shopify; +/// +/// Codeunit Shpfy GQL AssignedFFOrders (ID 30410). +/// Implements the IGraphQL interface for retrieving assigned fulfillment orders using GraphQL. +/// codeunit 30410 "Shpfy GQL AssignedFFOrders" implements "Shpfy IGraphQL" { Access = Internal; diff --git a/src/Apps/W1/Shopify/App/src/GraphQL/Codeunits/ShpfyGQLNextAssignedFFOrders.Codeunit.al b/src/Apps/W1/Shopify/App/src/GraphQL/Codeunits/ShpfyGQLNextAssignedFFOrders.Codeunit.al index e08da47a0d..7f42a0285f 100644 --- a/src/Apps/W1/Shopify/App/src/GraphQL/Codeunits/ShpfyGQLNextAssignedFFOrders.Codeunit.al +++ b/src/Apps/W1/Shopify/App/src/GraphQL/Codeunits/ShpfyGQLNextAssignedFFOrders.Codeunit.al @@ -5,6 +5,10 @@ namespace Microsoft.Integration.Shopify; +/// +/// Codeunit Shpfy GQL NextAssignedFFOrders (ID 30411). +/// Implements the IGraphQL interface for retrieving the next page of assigned fulfillment orders using GraphQL. +/// codeunit 30411 "Shpfy GQL NextAssignedFFOrders" implements "Shpfy IGraphQL" { Access = Internal; From acc4dde00a33655e9d7881999215684f1ecaadec Mon Sep 17 00:00:00 2001 From: Onat Buyukakkus <55088871+onbuyuka@users.noreply.github.com> Date: Wed, 22 Oct 2025 17:12:07 +0200 Subject: [PATCH 4/4] Merge --- .../src/GraphQL/Codeunits/ShpfyGQLAcceptFFRequest.Codeunit.al | 2 +- .../src/GraphQL/Codeunits/ShpfyGQLAssignedFFOrders.Codeunit.al | 2 +- .../GraphQL/Codeunits/ShpfyGQLNextAssignedFFOrders.Codeunit.al | 2 +- 3 files changed, 3 insertions(+), 3 deletions(-) diff --git a/src/Apps/W1/Shopify/App/src/GraphQL/Codeunits/ShpfyGQLAcceptFFRequest.Codeunit.al b/src/Apps/W1/Shopify/App/src/GraphQL/Codeunits/ShpfyGQLAcceptFFRequest.Codeunit.al index ea5e1cd602..47c22e85bb 100644 --- a/src/Apps/W1/Shopify/App/src/GraphQL/Codeunits/ShpfyGQLAcceptFFRequest.Codeunit.al +++ b/src/Apps/W1/Shopify/App/src/GraphQL/Codeunits/ShpfyGQLAcceptFFRequest.Codeunit.al @@ -9,7 +9,7 @@ namespace Microsoft.Integration.Shopify; /// Codeunit Shpfy GQL AcceptFFRequest (ID 30412). /// Implements the IGraphQL interface for accepting Shopify fulfillment requests using GraphQL. /// -codeunit 30412 "Shpfy GQL AcceptFFRequest" implements "Shpfy IGraphQL" +codeunit 30414 "Shpfy GQL AcceptFFRequest" implements "Shpfy IGraphQL" { Access = Internal; diff --git a/src/Apps/W1/Shopify/App/src/GraphQL/Codeunits/ShpfyGQLAssignedFFOrders.Codeunit.al b/src/Apps/W1/Shopify/App/src/GraphQL/Codeunits/ShpfyGQLAssignedFFOrders.Codeunit.al index 959e990b42..1115a17fac 100644 --- a/src/Apps/W1/Shopify/App/src/GraphQL/Codeunits/ShpfyGQLAssignedFFOrders.Codeunit.al +++ b/src/Apps/W1/Shopify/App/src/GraphQL/Codeunits/ShpfyGQLAssignedFFOrders.Codeunit.al @@ -9,7 +9,7 @@ namespace Microsoft.Integration.Shopify; /// Codeunit Shpfy GQL AssignedFFOrders (ID 30410). /// Implements the IGraphQL interface for retrieving assigned fulfillment orders using GraphQL. /// -codeunit 30410 "Shpfy GQL AssignedFFOrders" implements "Shpfy IGraphQL" +codeunit 30412 "Shpfy GQL AssignedFFOrders" implements "Shpfy IGraphQL" { Access = Internal; diff --git a/src/Apps/W1/Shopify/App/src/GraphQL/Codeunits/ShpfyGQLNextAssignedFFOrders.Codeunit.al b/src/Apps/W1/Shopify/App/src/GraphQL/Codeunits/ShpfyGQLNextAssignedFFOrders.Codeunit.al index 7f42a0285f..8d83f592c1 100644 --- a/src/Apps/W1/Shopify/App/src/GraphQL/Codeunits/ShpfyGQLNextAssignedFFOrders.Codeunit.al +++ b/src/Apps/W1/Shopify/App/src/GraphQL/Codeunits/ShpfyGQLNextAssignedFFOrders.Codeunit.al @@ -9,7 +9,7 @@ namespace Microsoft.Integration.Shopify; /// Codeunit Shpfy GQL NextAssignedFFOrders (ID 30411). /// Implements the IGraphQL interface for retrieving the next page of assigned fulfillment orders using GraphQL. /// -codeunit 30411 "Shpfy GQL NextAssignedFFOrders" implements "Shpfy IGraphQL" +codeunit 30413 "Shpfy GQL NextAssignedFFOrders" implements "Shpfy IGraphQL" { Access = Internal;