diff --git a/Apps/W1/Shopify/app/src/Base/Enums/ShpfyReturnLocationPriority.Enum.al b/Apps/W1/Shopify/app/src/Base/Enums/ShpfyReturnLocationPriority.Enum.al new file mode 100644 index 0000000000..06e112299d --- /dev/null +++ b/Apps/W1/Shopify/app/src/Base/Enums/ShpfyReturnLocationPriority.Enum.al @@ -0,0 +1,16 @@ +namespace Microsoft.Integration.Shopify; + +enum 30162 "Shpfy Return Location Priority" +{ + Access = Public; + Extensible = false; + + value(0; "Default Return Location") + { + Caption = 'Default Return Location'; + } + value(1; "Original -> Default Location") + { + Caption = 'Original -> Default Location'; + } +} \ No newline at end of file diff --git a/Apps/W1/Shopify/app/src/Base/Pages/ShpfyShopCard.Page.al b/Apps/W1/Shopify/app/src/Base/Pages/ShpfyShopCard.Page.al index 18fa93e076..3c71c716ed 100644 --- a/Apps/W1/Shopify/app/src/Base/Pages/ShpfyShopCard.Page.al +++ b/Apps/W1/Shopify/app/src/Base/Pages/ShpfyShopCard.Page.al @@ -540,6 +540,12 @@ page 30101 "Shpfy Shop Card" ShowCaption = false; Visible = IsReturnRefundsVisible; + field("Return Location Priority"; Rec."Return Location Priority") + { + ApplicationArea = All; + Caption = 'Return Location Priority'; + ToolTip = 'Specifies the priority of the return location.'; + } field("Location Code of Returns"; Rec."Return Location") { ApplicationArea = All; diff --git a/Apps/W1/Shopify/app/src/Base/Tables/ShpfyShop.Table.al b/Apps/W1/Shopify/app/src/Base/Tables/ShpfyShop.Table.al index d521572415..05bf12e5ad 100644 --- a/Apps/W1/Shopify/app/src/Base/Tables/ShpfyShop.Table.al +++ b/Apps/W1/Shopify/app/src/Base/Tables/ShpfyShop.Table.al @@ -233,8 +233,8 @@ table 30102 "Shpfy Shop" ObsoleteState = Pending; ObsoleteTag = '24.0'; #else - ObsoleteState = Removed; - ObsoleteTag = '27.0'; + ObsoleteState = Removed; + ObsoleteTag = '27.0'; #endif } field(30; "Shopify Can Update Customer"; Boolean) @@ -511,7 +511,7 @@ table 30102 "Shpfy Shop" } field(73; "Return Location"; Code[10]) { - Caption = 'Return Location'; + Caption = 'Default Return Location'; DataClassification = CustomerContent; TableRelation = Location where("Use As In-Transit" = const(false)); } @@ -778,6 +778,11 @@ table 30102 "Shpfy Shop" end; #endif } + field(128; "Return Location Priority"; Enum "Shpfy Return Location Priority") + { + Caption = 'Return Location Priority'; + DataClassification = CustomerContent; + } field(200; "Shop Id"; Integer) { DataClassification = SystemMetadata; diff --git a/Apps/W1/Shopify/app/src/GraphQL/Codeunits/ShpfyGQLNextRefundLines.Codeunit.al b/Apps/W1/Shopify/app/src/GraphQL/Codeunits/ShpfyGQLNextRefundLines.Codeunit.al index 69a0ca1fd1..426d81629f 100644 --- a/Apps/W1/Shopify/app/src/GraphQL/Codeunits/ShpfyGQLNextRefundLines.Codeunit.al +++ b/Apps/W1/Shopify/app/src/GraphQL/Codeunits/ShpfyGQLNextRefundLines.Codeunit.al @@ -5,7 +5,7 @@ codeunit 30232 "Shpfy GQL NextRefundLines" implements "Shpfy IGraphQL" internal procedure GetGraphQL(): Text begin - exit('{"query":"{ refund(id: \"gid://shopify/Refund/{{RefundId}}\") { refundLineItems(first: 10, after:\"{{After}}\") { pageInfo { endCursor hasNextPage } nodes { lineItem { id } quantity restockType restocked priceSet { presentmentMoney { amount } shopMoney { amount }} subtotalSet { presentmentMoney { amount } shopMoney { amount }} totalTaxSet { presentmentMoney { amount } shopMoney { amount }}}}}}"}'); + exit('{"query":"{ refund(id: \"gid://shopify/Refund/{{RefundId}}\") { refundLineItems(first: 10, after:\"{{After}}\") { pageInfo { endCursor hasNextPage } nodes { lineItem { id } quantity restockType location { legacyResourceId } restocked priceSet { presentmentMoney { amount } shopMoney { amount }} subtotalSet { presentmentMoney { amount } shopMoney { amount }} totalTaxSet { presentmentMoney { amount } shopMoney { amount }}}}}}"}'); end; internal procedure GetExpectedCost(): Integer diff --git a/Apps/W1/Shopify/app/src/GraphQL/Codeunits/ShpfyGQLNextRevFulfillOrdLns.Codeunit.al b/Apps/W1/Shopify/app/src/GraphQL/Codeunits/ShpfyGQLNextRevFulfillOrdLns.Codeunit.al new file mode 100644 index 0000000000..a5e508b6a2 --- /dev/null +++ b/Apps/W1/Shopify/app/src/GraphQL/Codeunits/ShpfyGQLNextRevFulfillOrdLns.Codeunit.al @@ -0,0 +1,27 @@ +namespace Microsoft.Integration.Shopify; + +/// +/// Codeunit Shpfy GQL NextRevFulfillOrdLns (ID 30349) implements Interface Shpfy IGraphQL. +/// +codeunit 30349 "Shpfy GQL NextRevFulfillOrdLns" implements "Shpfy IGraphQL" +{ + Access = Internal; + + /// + /// GetGraphQL. + /// + /// Return value of type Text. + internal procedure GetGraphQL(): Text + begin + exit('{"query":"{ reverseFulfillmentOrder(id: \"{{FulfillOrderId}}\") { lineItems(first: 10, after:\"{{After}}\") { pageInfo { endCursor hasNextPage } nodes { id fulfillmentLineItem { id lineItem { id name } } dispositions { id quantity type location { id legacyResourceId } } } } } }"}'); + end; + + /// + /// GetExpectedCost. + /// + /// Return value of type Integer. + internal procedure GetExpectedCost(): Integer + begin + exit(15); + end; +} diff --git a/Apps/W1/Shopify/app/src/GraphQL/Codeunits/ShpfyGQLNextRevFulfillOrders.Codeunit.al b/Apps/W1/Shopify/app/src/GraphQL/Codeunits/ShpfyGQLNextRevFulfillOrders.Codeunit.al new file mode 100644 index 0000000000..126f0ffab7 --- /dev/null +++ b/Apps/W1/Shopify/app/src/GraphQL/Codeunits/ShpfyGQLNextRevFulfillOrders.Codeunit.al @@ -0,0 +1,28 @@ +namespace Microsoft.Integration.Shopify; + +/// +/// Codeunit Shpfy GQL NextRevFulfillOrders (ID 30347) implements Interface Shpfy IGraphQL. +/// +codeunit 30347 "Shpfy GQL NextRevFulfillOrders" implements "Shpfy IGraphQL" +{ + Access = Internal; + + /// + /// GetGraphQL. + /// + /// Return value of type Text. + internal procedure GetGraphQL(): Text + begin + exit('{"query":"{ return(id: \"gid://shopify/Return/{{ReturnId}}\") { reverseFulfillmentOrders(first: 10, after:\"{{After}}\") { pageInfo { endCursor hasNextPage } nodes { id } } } }"}'); + + end; + + /// + /// GetExpectedCost. + /// + /// Return value of type Integer. + internal procedure GetExpectedCost(): Integer + begin + exit(7); + end; +} diff --git a/Apps/W1/Shopify/app/src/GraphQL/Codeunits/ShpfyGQLRefundLines.Codeunit.al b/Apps/W1/Shopify/app/src/GraphQL/Codeunits/ShpfyGQLRefundLines.Codeunit.al index bb11635ff8..29649cb17f 100644 --- a/Apps/W1/Shopify/app/src/GraphQL/Codeunits/ShpfyGQLRefundLines.Codeunit.al +++ b/Apps/W1/Shopify/app/src/GraphQL/Codeunits/ShpfyGQLRefundLines.Codeunit.al @@ -5,7 +5,7 @@ codeunit 30230 "Shpfy GQL RefundLines" implements "Shpfy IGraphQL" internal procedure GetGraphQL(): Text begin - exit('{"query":"{ refund(id: \"gid://shopify/Refund/{{RefundId}}\") { refundLineItems(first: 10) { pageInfo { endCursor hasNextPage } nodes { lineItem { id } quantity restockType restocked priceSet { presentmentMoney { amount } shopMoney { amount }} subtotalSet { presentmentMoney { amount } shopMoney { amount }} totalTaxSet { presentmentMoney { amount } shopMoney { amount }}}}}}"}'); + exit('{"query":"{ refund(id: \"gid://shopify/Refund/{{RefundId}}\") { refundLineItems(first: 10) { pageInfo { endCursor hasNextPage } nodes { lineItem { id } quantity restockType location { legacyResourceId } restocked priceSet { presentmentMoney { amount } shopMoney { amount }} subtotalSet { presentmentMoney { amount } shopMoney { amount }} totalTaxSet { presentmentMoney { amount } shopMoney { amount }}}}}}"}'); end; internal procedure GetExpectedCost(): Integer diff --git a/Apps/W1/Shopify/app/src/GraphQL/Codeunits/ShpfyGQLRevFulfillOrderLines.Codeunit.al b/Apps/W1/Shopify/app/src/GraphQL/Codeunits/ShpfyGQLRevFulfillOrderLines.Codeunit.al new file mode 100644 index 0000000000..f4e6ac63e5 --- /dev/null +++ b/Apps/W1/Shopify/app/src/GraphQL/Codeunits/ShpfyGQLRevFulfillOrderLines.Codeunit.al @@ -0,0 +1,27 @@ +namespace Microsoft.Integration.Shopify; + +/// +/// Codeunit Shpfy GQL RevFulfillOrderLines (ID 30348) implements Interface Shpfy IGraphQL. +/// +codeunit 30348 "Shpfy GQL RevFulfillOrderLines" implements "Shpfy IGraphQL" +{ + Access = Internal; + + /// + /// GetGraphQL. + /// + /// Return value of type Text. + internal procedure GetGraphQL(): Text + begin + exit('{"query":"{ reverseFulfillmentOrder(id: \"{{FulfillOrderId}}\") { id lineItems(first: 10) { nodes { id fulfillmentLineItem { id lineItem { id name } } dispositions { id quantity type location { id legacyResourceId } } } } } }"}'); + end; + + /// + /// GetExpectedCost. + /// + /// Return value of type Integer. + internal procedure GetExpectedCost(): Integer + begin + exit(15); + end; +} diff --git a/Apps/W1/Shopify/app/src/GraphQL/Codeunits/ShpfyGQLRevFulfillOrders.Codeunit.al b/Apps/W1/Shopify/app/src/GraphQL/Codeunits/ShpfyGQLRevFulfillOrders.Codeunit.al new file mode 100644 index 0000000000..29dd45361e --- /dev/null +++ b/Apps/W1/Shopify/app/src/GraphQL/Codeunits/ShpfyGQLRevFulfillOrders.Codeunit.al @@ -0,0 +1,28 @@ +namespace Microsoft.Integration.Shopify; + +/// +/// Codeunit Shpfy GQL RevFulfillOrders (ID 30346) implements Interface Shpfy IGraphQL. +/// +codeunit 30346 "Shpfy GQL RevFulfillOrders" implements "Shpfy IGraphQL" +{ + Access = Internal; + + /// + /// GetGraphQL. + /// + /// Return value of type Text. + internal procedure GetGraphQL(): Text + begin + exit('{"query":"{ return(id: \"gid://shopify/Return/{{ReturnId}}\") { reverseFulfillmentOrders(first: 10) { pageInfo { endCursor hasNextPage } nodes { id } } } }"}'); + + end; + + /// + /// GetExpectedCost. + /// + /// Return value of type Integer. + internal procedure GetExpectedCost(): Integer + begin + exit(7); + end; +} diff --git a/Apps/W1/Shopify/app/src/GraphQL/Enums/ShpfyGraphQLType.Enum.al b/Apps/W1/Shopify/app/src/GraphQL/Enums/ShpfyGraphQLType.Enum.al index 5991ef71dd..c3ee92e22b 100644 --- a/Apps/W1/Shopify/app/src/GraphQL/Enums/ShpfyGraphQLType.Enum.al +++ b/Apps/W1/Shopify/app/src/GraphQL/Enums/ShpfyGraphQLType.Enum.al @@ -415,4 +415,24 @@ enum 30111 "Shpfy GraphQL Type" implements "Shpfy IGraphQL" Caption = 'Get Product Options'; Implementation = "Shpfy IGraphQL" = "Shpfy GQL GetProductOptions"; } + value(87; GetReverseFulfillmentOrders) + { + Caption = 'Get Reverse Fulfillment Orders'; + Implementation = "Shpfy IGraphQL" = "Shpfy GQL RevFulfillOrders"; + } + value(88; GetNextReverseFulfillmentOrders) + { + Caption = 'Get Next Reverse Fulfillment Orders'; + Implementation = "Shpfy IGraphQL" = "Shpfy GQL NextRevFulfillOrders"; + } + value(89; GetReverseFulfillmentOrderLines) + { + Caption = 'Get Reverse Fulfillment Order Lines'; + Implementation = "Shpfy IGraphQL" = "Shpfy GQL RevFulfillOrderLines"; + } + value(90; GetNextReverseFulfillmentOrderLines) + { + Caption = 'Get Next Reverse Fulfillment Order Lines'; + Implementation = "Shpfy IGraphQL" = "Shpfy GQL NextRevFulfillOrdLns"; + } } diff --git a/Apps/W1/Shopify/app/src/Order Refunds/Codeunits/ShpfyRefundsAPI.Codeunit.al b/Apps/W1/Shopify/app/src/Order Refunds/Codeunits/ShpfyRefundsAPI.Codeunit.al index a6c5ab8c21..6b5b9e943c 100644 --- a/Apps/W1/Shopify/app/src/Order Refunds/Codeunits/ShpfyRefundsAPI.Codeunit.al +++ b/Apps/W1/Shopify/app/src/Order Refunds/Codeunits/ShpfyRefundsAPI.Codeunit.al @@ -31,11 +31,14 @@ codeunit 30228 "Shpfy Refunds API" RefundHeader: Record "Shpfy Refund Header"; GraphQLType: Enum "Shpfy GraphQL Type"; Parameters: Dictionary of [text, Text]; + ReturnLocations: Dictionary of [BigInteger, BigInteger]; JResponse: JsonToken; JLines: JsonArray; JLine: JsonToken; begin GetRefundHeader(RefundId, UpdatedAt, RefundHeader); + ReturnLocations := CollectReturnLocations(RefundHeader."Return Id"); + Parameters.Add('RefundId', Format(RefundId)); GraphQLType := "Shpfy GraphQL Type"::GetRefundLines; repeat @@ -46,8 +49,9 @@ codeunit 30228 "Shpfy Refunds API" Parameters.Set('After', JsonHelper.GetValueAsText(JResponse, 'data.refund.refundLineItems.pageInfo.endCursor')) else Parameters.Add('After', JsonHelper.GetValueAsText(JResponse, 'data.refund.refundLineItems.pageInfo.endCursor')); + foreach JLine in JLines do - FillInRefundLine(RefundId, JLine.AsObject(), IsNonZeroOrReturnRefund(RefundHeader)); + FillInRefundLine(RefundId, JLine.AsObject(), IsNonZeroOrReturnRefund(RefundHeader), ReturnLocations); until not JsonHelper.GetValueAsBoolean(JResponse, 'data.refund.refundLineItems.pageInfo.hasNextPage'); end; @@ -88,21 +92,34 @@ codeunit 30228 "Shpfy Refunds API" DataCapture.Add(Database::"Shpfy Refund Header", RefundHeader.SystemId, JResponse); end; - local procedure FillInRefundLine(RefundId: BigInteger; JLine: JsonObject; NonZeroOrReturnRefund: Boolean) + + local procedure CollectReturnLocations(ReturnId: BigInteger): Dictionary of [BigInteger, BigInteger] + var + ReturnsAPI: Codeunit "Shpfy Returns API"; + begin + if ReturnId <> 0 then + exit(ReturnsAPI.GetReturnLocations(ReturnId)); + end; + + local procedure FillInRefundLine(RefundId: BigInteger; JLine: JsonObject; NonZeroOrReturnRefund: Boolean; ReturnLocations: Dictionary of [BigInteger, BigInteger]) var DataCapture: Record "Shpfy Data Capture"; RefundLine: Record "Shpfy Refund Line"; RefundLineRecordRef: RecordRef; Id: BigInteger; + ReturnLocation: BigInteger; begin Id := CommunicationMgt.GetIdOfGId(JsonHelper.GetValueAsText(JLine, 'lineItem.id')); + if not RefundLine.Get(RefundId, Id) then begin RefundLine."Refund Line Id" := Id; RefundLine."Refund Id" := RefundId; RefundLine."Order Line Id" := Id; RefundLine.Insert(); end; + RefundLine."Restock Type" := RefundEnumConvertor.ConvertToReStockType(JsonHelper.GetValueAsText(JLine, 'restockType')); + RefundLineRecordRef.GetTable(RefundLine); JsonHelper.GetValueIntoField(JLine, 'quantity', RefundLineRecordRef, RefundLine.FieldNo(Quantity)); JsonHelper.GetValueIntoField(JLine, 'restocked', RefundLineRecordRef, RefundLine.FieldNo(Restocked)); @@ -113,8 +130,17 @@ codeunit 30228 "Shpfy Refunds API" JsonHelper.GetValueIntoField(JLine, 'totalTaxSet.shopMoney.amount', RefundLineRecordRef, RefundLine.FieldNo("Total Tax Amount")); JsonHelper.GetValueIntoField(JLine, 'totalTaxSet.presentmentMoney.amount', RefundLineRecordRef, RefundLine.FieldNo("Presentment Total Tax Amount")); RefundLineRecordRef.SetTable(RefundLine); + RefundLine."Can Create Credit Memo" := NonZeroOrReturnRefund; + RefundLine."Location Id" := JsonHelper.GetValueAsBigInteger(JLine, 'location.legacyResourceId'); + + // If refund was created from a return, the location needs to come from the return + // If Item was restocked to multiple locations, the return location is not known + if (RefundLine."Location Id" = 0) and (ReturnLocations.Get(RefundLine."Order Line Id", ReturnLocation)) then + RefundLine."Location Id" := ReturnLocation; + RefundLine.Modify(); + RefundLineRecordRef.Close(); DataCapture.Add(Database::"Shpfy Refund Line", RefundLine.SystemId, JLine); end; diff --git a/Apps/W1/Shopify/app/src/Order Refunds/Tables/ShpfyRefundLine.Table.al b/Apps/W1/Shopify/app/src/Order Refunds/Tables/ShpfyRefundLine.Table.al index 65d2030dfc..59248c70da 100644 --- a/Apps/W1/Shopify/app/src/Order Refunds/Tables/ShpfyRefundLine.Table.al +++ b/Apps/W1/Shopify/app/src/Order Refunds/Tables/ShpfyRefundLine.Table.al @@ -115,6 +115,12 @@ table 30145 "Shpfy Refund Line" CalcFormula = lookup("Shpfy Order Line"."Gift Card" where("Line Id" = field("Order Line Id"))); Editable = false; } + field(105; "Location Id"; BigInteger) + { + Caption = 'Location Id'; + DataClassification = SystemMetadata; + Editable = false; + } } keys { diff --git a/Apps/W1/Shopify/app/src/Order Return Refund Processing/Codeunits/ShpfyCreateSalesDocRefund.Codeunit.al b/Apps/W1/Shopify/app/src/Order Return Refund Processing/Codeunits/ShpfyCreateSalesDocRefund.Codeunit.al index 4c05820e44..8d2a888d1c 100644 --- a/Apps/W1/Shopify/app/src/Order Return Refund Processing/Codeunits/ShpfyCreateSalesDocRefund.Codeunit.al +++ b/Apps/W1/Shopify/app/src/Order Return Refund Processing/Codeunits/ShpfyCreateSalesDocRefund.Codeunit.al @@ -111,7 +111,6 @@ codeunit 30246 "Shpfy Create Sales Doc. Refund" SalesHeader.Validate("Document Date", DT2Date(RefundHeader."Created At")); if OrderMgt.FindTaxArea(OrderHeader, ShopifyTaxArea) and (ShopifyTaxArea."Tax Area Code" <> '') then SalesHeader.Validate("Tax Area Code", ShopifyTaxArea."Tax Area Code"); - SalesHeader.Validate("Location Code", Shop."Return Location"); end; SalesHeader."Shpfy Refund Id" := RefundHeader."Refund Id"; SalesHeader.Modify(true); @@ -143,6 +142,7 @@ codeunit 30246 "Shpfy Create Sales Doc. Refund" RefundLine: Record "Shpfy Refund Line"; ReturnLine: Record "Shpfy Return Line"; GiftCard: Record "Shpfy Gift Card"; + ShopLocation: Record "Shpfy Shop Location"; LineNo: Integer; OpenAmount: Decimal; IsHandled: Boolean; @@ -181,7 +181,13 @@ codeunit 30246 "Shpfy Create Sales Doc. Refund" SalesLine.Validate("No.", RefundLine."Item No."); if RefundLine."Variant Code" <> '' then SalesLine.Validate("Variant Code", RefundLine."Variant Code"); - SalesLine.Validate("Location Code", Shop."Return Location"); + + if ShopLocation.Get(Shop.Code, RefundLine."Location Id") then + SalesLine.Validate("Location Code", ShopLocation."Default Location Code"); + + If (Shop."Return Location Priority" = "Shpfy Return Location Priority"::"Default Return Location") or (SalesLine."Location Code" = '') then + SalesLine.Validate("Location Code", Shop."Return Location"); + end; SalesLine.Validate(Quantity, RefundLine.Quantity); SalesLine.Validate("Unit Price", RefundLine.Amount); @@ -233,7 +239,13 @@ codeunit 30246 "Shpfy Create Sales Doc. Refund" SalesLine.Validate("No.", ReturnLine."Item No."); if ReturnLine."Variant Code" <> '' then SalesLine.Validate("Variant Code", ReturnLine."Variant Code"); - SalesLine.Validate("Location Code", Shop."Return Location"); + + if ShopLocation.Get(Shop.Code, ReturnLine."Location Id") then + SalesLine.Validate("Location Code", ShopLocation."Default Location Code"); + + If (Shop."Return Location Priority" = "Shpfy Return Location Priority"::"Default Return Location") or (SalesLine."Location Code" = '') then + SalesLine.Validate("Location Code", Shop."Return Location"); + SalesLine.Validate(Quantity, ReturnLine.Quantity); SalesLine.Validate("Unit Price", ReturnLine."Discounted Total Amount" / ReturnLine.Quantity); end; diff --git a/Apps/W1/Shopify/app/src/Order Returns/Codeunits/ShpfyReturnsAPI.Codeunit.al b/Apps/W1/Shopify/app/src/Order Returns/Codeunits/ShpfyReturnsAPI.Codeunit.al index 0855c28be4..5de1dc01bb 100644 --- a/Apps/W1/Shopify/app/src/Order Returns/Codeunits/ShpfyReturnsAPI.Codeunit.al +++ b/Apps/W1/Shopify/app/src/Order Returns/Codeunits/ShpfyReturnsAPI.Codeunit.al @@ -32,11 +32,14 @@ codeunit 30250 "Shpfy Returns API" var GraphQLType: Enum "Shpfy GraphQL Type"; LineParameters: Dictionary of [text, Text]; + ReturnLocations: Dictionary of [BigInteger, BigInteger]; JResponse: JsonToken; JLines: JsonArray; JLine: JsonToken; begin GetReturnHeader(ReturnId); + ReturnLocations := GetReturnLocations(ReturnId); + LineParameters.Add('ReturnId', Format(ReturnId)); GraphQLType := "Shpfy GraphQL Type"::GetReturnLines; repeat @@ -48,7 +51,7 @@ codeunit 30250 "Shpfy Returns API" else LineParameters.Add('After', JsonHelper.GetValueAsText(JResponse, 'data.return.returnLineItems.pageInfo.endCursor')); foreach JLine in JLines do - FillInReturnLine(ReturnId, JLine.AsObject()); + FillInReturnLine(ReturnId, JLine.AsObject(), ReturnLocations); until not JsonHelper.GetValueAsBoolean(JResponse, 'data.return.returnLineItems.pageInfo.hasNextPage'); end; @@ -81,12 +84,96 @@ codeunit 30250 "Shpfy Returns API" DataCapture.Add(Database::"Shpfy Return Header", ReturnHeader.SystemId, JResponse); end; - local procedure FillInReturnLine(ReturnId: BigInteger; JLine: JsonObject) + /// + /// Get the return locations for return lines. + /// + /// Id of the return. + /// + /// If item was restocked to multiple locations, we cannot determine the return location for the return line, + /// and the order line id will not be included in the return locations. + /// + /// Dictionary of Order Line Id and Location Id. + internal procedure GetReturnLocations(ReturnId: BigInteger) ReturnLocations: Dictionary of [BigInteger, BigInteger] + var + GraphQLType: Enum "Shpfy GraphQL Type"; + LineParameters: Dictionary of [text, Text]; + JResponse: JsonToken; + JOrders: JsonArray; + JOrder: JsonToken; + begin + LineParameters.Add('ReturnId', Format(ReturnId)); + GraphQLType := "Shpfy GraphQL Type"::GetReverseFulfillmentOrders; + repeat + JResponse := CommunicationMgt.ExecuteGraphQL(GraphQLType, LineParameters); + + GraphQLType := "Shpfy GraphQL Type"::GetNextReverseFulfillmentOrders; + JOrders := JsonHelper.GetJsonArray(JResponse, 'data.return.reverseFulfillmentOrders.nodes'); + if Parameters.ContainsKey('After') then + Parameters.Set('After', JsonHelper.GetValueAsText(JResponse, 'data.return.reverseFulfillmentOrders.pageInfo.endCursor')) + else + Parameters.Add('After', JsonHelper.GetValueAsText(JResponse, 'data.return.reverseFulfillmentOrders.pageInfo.endCursor')); + + foreach JOrder in JOrders do + GetReturnLocationsFromReturnFulfillOrder(JsonHelper.GetValueAsText(JOrder, 'id'), ReturnLocations); + until not JsonHelper.GetValueAsBoolean(JResponse, 'data.return.reverseFulfillmentOrders.pageInfo.hasNextPage'); + end; + + local procedure GetReturnLocationsFromReturnFulfillOrder(FulfillOrderId: Text; var ReturnLocations: Dictionary of [BigInteger, BigInteger]) + var + GraphQLType: Enum "Shpfy GraphQL Type"; + LineParameters: Dictionary of [text, Text]; + JResponse: JsonToken; + JLines: JsonArray; + JLine: JsonToken; + begin + LineParameters.Add('FulfillOrderId', FulfillOrderId); + GraphQLType := "Shpfy GraphQL Type"::GetReverseFulfillmentOrderLines; + repeat + JResponse := CommunicationMgt.ExecuteGraphQL(GraphQLType, LineParameters); + + GraphQLType := "Shpfy GraphQL Type"::GetNextReverseFulfillmentOrders; + JLines := JsonHelper.GetJsonArray(JResponse, 'data.reverseFulfillmentOrder.lineItems.nodes'); + if Parameters.ContainsKey('After') then + Parameters.Set('After', JsonHelper.GetValueAsText(JResponse, 'data.reverseFulfillmentOrder.lineItems.pageInfo.endCursor')) + else + Parameters.Add('After', JsonHelper.GetValueAsText(JResponse, 'data.reverseFulfillmentOrder.lineItems.pageInfo.endCursor')); + + foreach JLine in JLines do + CollectLocationsFromLineDispositions(JLine, ReturnLocations); + until not JsonHelper.GetValueAsBoolean(JResponse, 'data.reverseFulfillmentOrder.lineItems.pageInfo.hasNextPage'); + end; + + local procedure CollectLocationsFromLineDispositions(JLine: JsonToken; ReturnLocations: Dictionary of [BigInteger, BigInteger]) + var + OrderLineId: BigInteger; + LocationId: BigInteger; + Dispositions: JsonArray; + Disposition: JsonToken; + begin + OrderLineId := CommunicationMgt.GetIdOfGId(JsonHelper.GetValueAsText(JLine, 'fulfillmentLineItem.lineItem.id')); + + Dispositions := JsonHelper.GetJsonArray(JLine, 'dispositions'); + if Dispositions.Count = 0 then + exit; + + // If dispositions have different locations (Item was restocked to multiple locations), + // we cannot determine the return location for the line + Dispositions.Get(0, Disposition); + LocationId := JsonHelper.GetValueAsBigInteger(Disposition, 'location.legacyResourceId'); + foreach Disposition in Dispositions do + if LocationId <> JsonHelper.GetValueAsBigInteger(Disposition, 'location.legacyResourceId') then + exit; + + ReturnLocations.Add(OrderLineId, LocationId); + end; + + local procedure FillInReturnLine(ReturnId: BigInteger; JLine: JsonObject; ReturnLocations: Dictionary of [BigInteger, BigInteger]) var DataCapture: Record "Shpfy Data Capture"; ReturnLine: Record "Shpfy Return Line"; ReturnLineRecordRef: RecordRef; Id: BigInteger; + ReturnLocation: BigInteger; begin Id := CommunicationMgt.GetIdOfGId(JsonHelper.GetValueAsText(JLine, 'id')); if not ReturnLine.Get(Id) then begin @@ -97,8 +184,13 @@ codeunit 30250 "Shpfy Returns API" ReturnLine.Insert(); end; ReturnLine."Return Reason" := ReturnEnumConvertor.ConvertToReturnReason(JsonHelper.GetValueAsText(JLine, 'returnReason')); + // If item was restocked to multiple locations, we cannot determine the return location for the line + if ReturnLocations.Get(ReturnLine."Order Line Id", ReturnLocation) then + ReturnLine."Location Id" := ReturnLocation; + ReturnLine.SetReturnReasonNote(JsonHelper.GetValueAsText(JLine, 'returnReasonNote')); ReturnLine.SetCustomerNote(JsonHelper.GetValueAsText(JLine, 'customerNote')); + ReturnLineRecordRef.GetTable(ReturnLine); JsonHelper.GetValueIntoField(JLine, 'quantity', ReturnLineRecordRef, ReturnLine.FieldNo(Quantity)); JsonHelper.GetValueIntoField(JLine, 'refundableQuantity', ReturnLineRecordRef, ReturnLine.FieldNo("Refundable Quantity")); diff --git a/Apps/W1/Shopify/app/src/Order Returns/Tables/ShpfyReturnLine.Table.al b/Apps/W1/Shopify/app/src/Order Returns/Tables/ShpfyReturnLine.Table.al index 9150f4d570..3598ff4855 100644 --- a/Apps/W1/Shopify/app/src/Order Returns/Tables/ShpfyReturnLine.Table.al +++ b/Apps/W1/Shopify/app/src/Order Returns/Tables/ShpfyReturnLine.Table.al @@ -112,6 +112,12 @@ table 30141 "Shpfy Return Line" FieldClass = FlowField; CalcFormula = lookup("Shpfy Order Line"."Variant Code" where("Line Id" = field("Order Line Id"))); } + field(104; "Location Id"; BigInteger) + { + Caption = 'Location Id'; + DataClassification = SystemMetadata; + Editable = false; + } } keys { diff --git a/Apps/W1/Shopify/app/src/Order handling/Codeunits/ShpfyOrderEvents.Codeunit.al b/Apps/W1/Shopify/app/src/Order handling/Codeunits/ShpfyOrderEvents.Codeunit.al index 7ec64dae1c..ada8e63e93 100644 --- a/Apps/W1/Shopify/app/src/Order handling/Codeunits/ShpfyOrderEvents.Codeunit.al +++ b/Apps/W1/Shopify/app/src/Order handling/Codeunits/ShpfyOrderEvents.Codeunit.al @@ -78,6 +78,25 @@ codeunit 30162 "Shpfy Order Events" begin end; + [IntegrationEvent(false, false)] + /// + /// Description for OnBeforeMapShipmentAgent. + /// + /// Parameter of type Record "Shopify Order Header". + /// Parameter of type Boolean. + internal procedure OnBeforeMapShipmentAgent(var ShopifyOrderHeader: Record "Shpfy Order Header"; var Handled: Boolean) + begin + end; + + [IntegrationEvent(false, false)] + /// + /// Description for OnAfterMapShipmentAgent. + /// + /// Parameter of type Record "Shopify Order Header". + internal procedure OnAfterMapShipmentAgent(var ShopifyOrderHeader: Record "Shpfy Order Header") + begin + end; + [IntegrationEvent(false, false)] /// /// Description for OnBeforeMapPaymentMethod. diff --git a/Apps/W1/Shopify/app/src/Order handling/Codeunits/ShpfyOrderMapping.Codeunit.al b/Apps/W1/Shopify/app/src/Order handling/Codeunits/ShpfyOrderMapping.Codeunit.al index ca765c3291..0193e9c612 100644 --- a/Apps/W1/Shopify/app/src/Order handling/Codeunits/ShpfyOrderMapping.Codeunit.al +++ b/Apps/W1/Shopify/app/src/Order handling/Codeunits/ShpfyOrderMapping.Codeunit.al @@ -127,6 +127,7 @@ codeunit 30163 "Shpfy Order Mapping" end; MapShippingMethodCode(OrderHeader); + MapShippingAgent(OrderHeader); MapPaymentMethodCode(OrderHeader); OrderHeader.Modify(); exit((OrderHeader."Bill-to Customer No." <> '') and (OrderHeader."Sell-to Customer No." <> '')); @@ -163,6 +164,7 @@ codeunit 30163 "Shpfy Order Mapping" end; MapShippingMethodCode(OrderHeader); + MapShippingAgent(OrderHeader); MapPaymentMethodCode(OrderHeader); OrderHeader.Modify(); exit((OrderHeader."Bill-to Customer No." <> '') and (OrderHeader."Sell-to Customer No." <> '')); @@ -247,6 +249,26 @@ codeunit 30163 "Shpfy Order Mapping" end; end; + local procedure MapShippingAgent(var OrderHeader: Record "Shpfy Order Header") + var + OrderShippingCharges: Record "Shpfy Order Shipping Charges"; + ShipmentMethodMapping: Record "Shpfy Shipment Method Mapping"; + IsHandled: Boolean; + begin + if OrderHeader."Shipping Agent Code" = '' then begin + OrderEvents.OnBeforeMapShipmentAgent(OrderHeader, IsHandled); + if not IsHandled then begin + OrderShippingCharges.SetRange("Shopify Order Id", OrderHeader."Shopify Order Id"); + if OrderShippingCharges.FindFirst() then + if ShipmentMethodMapping.Get(OrderHeader."Shop Code", OrderShippingCharges.Title) then begin + OrderHeader."Shipping Agent Code" := ShipmentMethodMapping."Shipping Agent Code"; + OrderHeader."Shipping Agent Service Code" := ShipmentMethodMapping."Shipping Agent Service Code"; + end; + OrderEvents.OnAfterMapShipmentAgent(OrderHeader); + end; + end; + end; + local procedure MapPaymentMethodCode(var OrderHeader: Record "Shpfy Order Header") var OrderTransaction: Record "Shpfy Order Transaction"; diff --git a/Apps/W1/Shopify/app/src/Order handling/Codeunits/ShpfyProcessOrder.Codeunit.al b/Apps/W1/Shopify/app/src/Order handling/Codeunits/ShpfyProcessOrder.Codeunit.al index a9ea62de6b..c2dadeb483 100644 --- a/Apps/W1/Shopify/app/src/Order handling/Codeunits/ShpfyProcessOrder.Codeunit.al +++ b/Apps/W1/Shopify/app/src/Order handling/Codeunits/ShpfyProcessOrder.Codeunit.al @@ -1,6 +1,7 @@ namespace Microsoft.Integration.Shopify; using Microsoft.Inventory.Item; +using Microsoft.Finance.Currency; using Microsoft.Sales.Document; using Microsoft.Foundation.Address; using Microsoft.Sales.History; @@ -118,6 +119,10 @@ codeunit 30166 "Shpfy Process Order" SalesHeader.Validate("Tax Area Code", ShopifyTaxArea."Tax Area Code"); if ShopifyOrderHeader."Shipping Method Code" <> '' then SalesHeader.Validate("Shipment Method Code", ShopifyOrderHeader."Shipping Method Code"); + if ShopifyOrderHeader."Shipping Agent Code" <> '' then begin + SalesHeader.Validate("Shipping Agent Code", ShopifyOrderHeader."Shipping Agent Code"); + SalesHeader.Validate("Shipping Agent Service Code", ShopifyOrderHeader."Shipping Agent Service Code"); + end; if ShopifyOrderHeader."Payment Method Code" <> '' then SalesHeader.Validate("Payment Method Code", ShopifyOrderHeader."Payment Method Code"); @@ -173,8 +178,10 @@ codeunit 30166 "Shpfy Process Order" ShopifyOrderLine: Record "Shpfy Order Line"; OrderShippingCharges: Record "Shpfy Order Shipping Charges"; ShopLocation: Record "Shpfy Shop Location"; + ShipmentMethodMapping: Record "Shpfy Shipment Method Mapping"; SuppressAsmWarning: Codeunit "Shpfy Suppress Asm Warning"; IsHandled: Boolean; + ShipmentChargeType: Boolean; ShopfyOrderNoLbl: Label 'Shopify Order No.: %1', Comment = '%1 = Order No.'; begin BindSubscription(SuppressAsmWarning); @@ -230,12 +237,21 @@ codeunit 30166 "Shpfy Process Order" OrderShippingCharges.Reset(); OrderShippingCharges.SetRange("Shopify Order Id", ShopifyOrderHeader."Shopify Order Id"); OrderShippingCharges.SetFilter(Amount, '>0'); - if OrderShippingCharges.FindSet() then begin - ShopifyShop.TestField("Shipping Charges Account"); + if OrderShippingCharges.FindSet() then repeat IsHandled := false; OrderEvents.OnBeforeCreateShippingCostSalesLine(ShopifyOrderHeader, OrderShippingCharges, SalesHeader, SalesLine, IsHandled); if not IsHandled then begin + + if ShipmentMethodMapping.Get(ShopifyShop.Code, OrderShippingCharges.Title) then + if ShipmentMethodMapping."Shipping Charges Type" <> ShipmentMethodMapping."Shipping Charges Type"::" " then begin + ShipmentMethodMapping.TestField("Shipping Charges No."); + ShipmentChargeType := true; + end; + + if not ShipmentChargeType then + ShopifyShop.TestField("Shipping Charges Account"); + SalesLine.Init(); SalesLine.SetHideValidationDialog(true); SalesLine.Validate("Document Type", SalesHeader."Document Type"); @@ -243,18 +259,111 @@ codeunit 30166 "Shpfy Process Order" SalesLine.Validate("Line No.", GetNextLineNo(SalesHeader)); SalesLine.Insert(true); - SalesLine.Validate(Type, SalesLine.Type::"G/L Account"); - SalesLine.Validate("No.", ShopifyShop."Shipping Charges Account"); + if ShipmentChargeType then begin + SalesLine.Validate(Type, ShipmentMethodMapping."Shipping Charges Type"); + SalesLine.Validate("No.", ShipmentMethodMapping."Shipping Charges No."); + end else begin + SalesLine.Validate(Type, SalesLine.Type::"G/L Account"); + SalesLine.Validate("No.", ShopifyShop."Shipping Charges Account"); + end; + + SalesLine.Validate("Shipping Agent Code", ShipmentMethodMapping."Shipping Agent Code"); + SalesLine.Validate("Shipping Agent Service Code", ShipmentMethodMapping."Shipping Agent Service Code"); SalesLine.Validate(Quantity, 1); SalesLine.Validate(Description, OrderShippingCharges.Title); SalesLine.Validate("Unit Price", OrderShippingCharges.Amount); SalesLine.Validate("Line Discount Amount", OrderShippingCharges."Discount Amount"); SalesLine."Shpfy Order No." := ShopifyOrderHeader."Shopify Order No."; SalesLine.Modify(true); + + if SalesLine.Type = SalesLine.Type::"Charge (Item)" then + AssignItemCharges(SalesHeader, SalesLine); end; OrderEvents.OnAfterCreateShippingCostSalesLine(ShopifyOrderHeader, OrderShippingCharges, SalesHeader, SalesLine); until OrderShippingCharges.Next() = 0; + end; + + local procedure AssignItemCharges(SalesHeader: Record "Sales Header"; SalesLine: Record "Sales Line") + var + AssignItemChargeSales: Codeunit "Item Charge Assgnt. (Sales)"; + ItemChargeAssgntLineAmt: Decimal; + AssignableQty: Decimal; + begin + SalesLine.TestField("No."); + SalesLine.TestField(Quantity); + + PrepareAssignItemChargesLines(SalesHeader, SalesLine, AssignableQty, ItemChargeAssgntLineAmt); + AssignItemChargeSales.AssignItemCharges(SalesLine, AssignableQty, ItemChargeAssgntLineAmt, AssignableQty, ItemChargeAssgntLineAmt, AssignItemChargeSales.AssignEquallyMenuText()); + end; + + local procedure PrepareAssignItemChargesLines( + SalesHeader: Record "Sales Header"; + SalesLine: Record "Sales Line"; + var AssignableQty: Decimal; + var ItemChargeAssgntLineAmt: Decimal + ) + var + ItemChargeAssgntSales: Record "Item Charge Assignment (Sales)"; + begin + GetItemChargeAssgntLineAmt(SalesHeader, SalesLine, ItemChargeAssgntSales, ItemChargeAssgntLineAmt); + GetAssignableQty(SalesLine, ItemChargeAssgntSales, AssignableQty); + end; + + local procedure GetItemChargeAssgntLineAmt( + SalesHeader: Record "Sales Header"; + SalesLine: Record "Sales Line"; + var ItemChargeAssgntSales: Record "Item Charge Assignment (Sales)"; + var ItemChargeAssgntLineAmt: Decimal + ) + var + Currency: Record Currency; + begin + SalesHeader := SalesLine.GetSalesHeader(); + Currency.Initialize(SalesHeader."Currency Code"); + if (SalesLine."Inv. Discount Amount" = 0) and (SalesLine."Line Discount Amount" = 0) and + (not SalesHeader."Prices Including VAT") + then + ItemChargeAssgntLineAmt := SalesLine."Line Amount" + else + if SalesHeader."Prices Including VAT" then + ItemChargeAssgntLineAmt := + Round(SalesLine.CalcLineAmount() / (1 + SalesLine."VAT %" / 100), Currency."Amount Rounding Precision") + else + ItemChargeAssgntLineAmt := SalesLine.CalcLineAmount(); + + ItemChargeAssgntSales.Reset(); + ItemChargeAssgntSales.SetRange("Document Type", SalesLine."Document Type"); + ItemChargeAssgntSales.SetRange("Document No.", SalesLine."Document No."); + ItemChargeAssgntSales.SetRange("Document Line No.", SalesLine."Line No."); + ItemChargeAssgntSales.SetRange("Item Charge No.", SalesLine."No."); + if not ItemChargeAssgntSales.FindLast() then begin + ItemChargeAssgntSales."Document Type" := SalesLine."Document Type"; + ItemChargeAssgntSales."Document No." := SalesLine."Document No."; + ItemChargeAssgntSales."Document Line No." := SalesLine."Line No."; + ItemChargeAssgntSales."Item Charge No." := SalesLine."No."; + ItemChargeAssgntSales."Unit Cost" := + Round(ItemChargeAssgntLineAmt / SalesLine.Quantity, Currency."Unit-Amount Rounding Precision"); end; + + ItemChargeAssgntLineAmt := + Round(ItemChargeAssgntLineAmt * (SalesLine."Qty. to Invoice" / SalesLine.Quantity), Currency."Amount Rounding Precision"); + end; + + local procedure GetAssignableQty( + SalesLine: Record "Sales Line"; + ItemChargeAssgntSales: Record "Item Charge Assignment (Sales)"; + var AssignableQty: Decimal + ) + var + AssignItemChargeSales: Codeunit "Item Charge Assgnt. (Sales)"; + begin + if SalesLine.IsCreditDocType() then + AssignItemChargeSales.CreateDocChargeAssgn(ItemChargeAssgntSales, SalesLine."Return Receipt No.") + else + AssignItemChargeSales.CreateDocChargeAssgn(ItemChargeAssgntSales, SalesLine."Shipment No."); + + SalesLine.CalcFields("Qty. to Assign", "Item Charge Qty. to Handle", "Qty. Assigned"); + AssignableQty := SalesLine."Qty. to Invoice" + SalesLine."Quantity Invoiced" - SalesLine."Qty. Assigned"; end; /// diff --git a/Apps/W1/Shopify/app/src/Order handling/Pages/ShpfyOrder.Page.al b/Apps/W1/Shopify/app/src/Order handling/Pages/ShpfyOrder.Page.al index 53c7b012c8..17e7fa6610 100644 --- a/Apps/W1/Shopify/app/src/Order handling/Pages/ShpfyOrder.Page.al +++ b/Apps/W1/Shopify/app/src/Order handling/Pages/ShpfyOrder.Page.al @@ -62,6 +62,16 @@ page 30113 "Shpfy Order" ApplicationArea = All; ToolTip = 'Specifies how items on the Shopify Order are shipped to the customer.'; } + field(ShippingAgentCode; Rec."Shipping Agent Code") + { + ApplicationArea = All; + ToolTip = 'Specifies which shipping agent is used to transport the items on the Shopify Order to the customer.'; + } + field(ShippingAgentServiceCode; Rec."Shipping Agent Service Code") + { + ApplicationArea = All; + ToolTip = 'Specifies the code that represents the default shipping agent service you are using for this Shopify Order.'; + } field("Payment Method"; Rec."Payment Method Code") { ApplicationArea = All; diff --git a/Apps/W1/Shopify/app/src/Order handling/Tables/ShpfyOrderHeader.Table.al b/Apps/W1/Shopify/app/src/Order handling/Tables/ShpfyOrderHeader.Table.al index b71f4c1934..e31860f410 100644 --- a/Apps/W1/Shopify/app/src/Order handling/Tables/ShpfyOrderHeader.Table.al +++ b/Apps/W1/Shopify/app/src/Order handling/Tables/ShpfyOrderHeader.Table.al @@ -735,6 +735,22 @@ table 30118 "Shpfy Order Header" Caption = 'Has Order State Error'; DataClassification = SystemMetadata; } + field(1021; "Shipping Agent Code"; Code[10]) + { + Caption = 'Shipping Agent Code'; + TableRelation = "Shipping Agent"; + + trigger OnValidate() + begin + if "Shipping Agent Code" <> xRec."Shipping Agent Code" then + Clear("Shipping Agent Service Code"); + end; + } + field(1022; "Shipping Agent Service Code"; Code[10]) + { + Caption = 'Shipping Agent Service Code'; + TableRelation = "Shipping Agent Services".Code where("Shipping Agent Code" = field("Shipping Agent Code")); + } } keys { diff --git a/Apps/W1/Shopify/app/src/Shipping/Pages/ShpfyShipmentMethodsMapping.Page.al b/Apps/W1/Shopify/app/src/Shipping/Pages/ShpfyShipmentMethodsMapping.Page.al index 70b28df117..cf26927279 100644 --- a/Apps/W1/Shopify/app/src/Shipping/Pages/ShpfyShipmentMethodsMapping.Page.al +++ b/Apps/W1/Shopify/app/src/Shipping/Pages/ShpfyShipmentMethodsMapping.Page.al @@ -26,6 +26,27 @@ page 30129 "Shpfy Shipment Methods Mapping" ApplicationArea = All; ToolTip = 'Specifies the shipping method in D365BC.'; } + field("Shipping Charges Type"; Rec."Shipping Charges Type") + { + ApplicationArea = All; + ToolTip = 'Specifies the value of the Shipping Charges Type field.'; + } + field("Shipping Charges No."; Rec."Shipping Charges No.") + { + ApplicationArea = All; + ShowMandatory = Rec."Shipping Charges Type" <> Rec."Shipping Charges Type"::" "; + ToolTip = 'Specifies the value of the Shipping Charges No. field.'; + } + field("Shipping Agent Code"; Rec."Shipping Agent Code") + { + ApplicationArea = All; + ToolTip = 'Specifies the code for the shipping agent who is transporting the items.'; + } + field("Shipping Agent Service Code"; Rec."Shipping Agent Service Code") + { + ApplicationArea = All; + ToolTip = 'Specifies the code for the service, such as a one-day delivery, that is offered by the shipping agent.'; + } } } } diff --git a/Apps/W1/Shopify/app/src/Shipping/Tables/ShpfyShipmentMethodMapping.Table.al b/Apps/W1/Shopify/app/src/Shipping/Tables/ShpfyShipmentMethodMapping.Table.al index ea91386f18..89819deeeb 100644 --- a/Apps/W1/Shopify/app/src/Shipping/Tables/ShpfyShipmentMethodMapping.Table.al +++ b/Apps/W1/Shopify/app/src/Shipping/Tables/ShpfyShipmentMethodMapping.Table.al @@ -1,6 +1,9 @@ namespace Microsoft.Integration.Shopify; using Microsoft.Foundation.Shipping; +using Microsoft.Sales.Document; +using Microsoft.Finance.GeneralLedger.Account; +using Microsoft.Inventory.Item; /// /// Table Shpfy Shipment Method Mapping (ID 30131). @@ -31,6 +34,55 @@ table 30131 "Shpfy Shipment Method Mapping" DataClassification = CustomerContent; TableRelation = "Shipment Method"; } + field(4; "Shipping Charges Type"; Enum "Sales Line Type") + { + Caption = 'Shipping Charges Type'; + DataClassification = CustomerContent; + ValuesAllowed = " ", "G/L Account", Item, "Charge (Item)"; + + trigger OnValidate() + begin + if "Shipping Charges Type" <> xRec."Shipping Charges Type" then + Clear("Shipping Charges No."); + end; + } + field(5; "Shipping Charges No."; Code[20]) + { + Caption = 'Shipping Charges No.'; + TableRelation = if ("Shipping Charges Type" = const("G/L Account")) "G/L Account" + else + if ("Shipping Charges Type" = const(Item)) Item + else + if ("Shipping Charges Type" = const("Charge (Item)")) "Item Charge"; + + trigger OnValidate() + var + GLAccount: Record "G/L Account"; + ShpfyShop: Record "Shpfy Shop"; + begin + if "Shipping Charges Type" = "Shipping Charges Type"::"G/L Account" then + if GLAccount.Get("Shipping Charges No.") then + ShpfyShop.CheckGLAccount(GLAccount); + end; + } + field(6; "Shipping Agent Code"; Code[10]) + { + AccessByPermission = TableData "Shipping Agent Services" = R; + Caption = 'Shipping Agent Code'; + TableRelation = "Shipping Agent"; + + trigger OnValidate() + begin + if "Shipping Agent Code" <> xRec."Shipping Agent Code" then + Clear("Shipping Agent Service Code"); + end; + } + field(7; "Shipping Agent Service Code"; Code[10]) + { + AccessByPermission = TableData "Shipping Agent Services" = R; + Caption = 'Shipping Agent Service Code'; + TableRelation = "Shipping Agent Services".Code where("Shipping Agent Code" = field("Shipping Agent Code")); + } } keys