From fe1bff26ed78a06444f1a1fd47bc156d3f76b7b5 Mon Sep 17 00:00:00 2001 From: Gediminas Gaubys Date: Thu, 31 Oct 2024 10:23:06 +0200 Subject: [PATCH 1/2] [Shopify] - Export Posted Sales Invoices to Shopify as Orders Tests --- .../ShpfyInvoicesAPISubscriber.Codeunit.al | 120 ++++ .../Invoices/ShpfyInvoicesTest.Codeunit.al | 520 +++++++++++++++++- 2 files changed, 610 insertions(+), 30 deletions(-) create mode 100644 Apps/W1/Shopify/test/Invoices/ShpfyInvoicesAPISubscriber.Codeunit.al diff --git a/Apps/W1/Shopify/test/Invoices/ShpfyInvoicesAPISubscriber.Codeunit.al b/Apps/W1/Shopify/test/Invoices/ShpfyInvoicesAPISubscriber.Codeunit.al new file mode 100644 index 0000000000..93c08a35c1 --- /dev/null +++ b/Apps/W1/Shopify/test/Invoices/ShpfyInvoicesAPISubscriber.Codeunit.al @@ -0,0 +1,120 @@ +codeunit 139576 "Shpfy Invoices API Subscriber" +{ + SingleInstance = true; + EventSubscriberInstance = Manual; + + var + FullDraftOrder: Boolean; + ShopifyOrderId: BigInteger; + ShopifyOrderNo: Code[50]; + + [EventSubscriber(ObjectType::Codeunit, Codeunit::"Shpfy Communication Events", 'OnClientSend', '', true, false)] + local procedure OnClientSend(HttpRequestMessage: HttpRequestMessage; var HttpResponseMessage: HttpResponseMessage) + begin + MakeResponse(HttpRequestMessage, HttpResponseMessage); + end; + + [EventSubscriber(ObjectType::Codeunit, Codeunit::"Shpfy Communication Events", 'OnGetContent', '', true, false)] + local procedure OnGetContent(HttpResponseMessage: HttpResponseMessage; var Response: Text) + begin + HttpResponseMessage.Content.ReadAs(Response); + end; + + local procedure MakeResponse(HttpRequestMessage: HttpRequestMessage; var HttpResponseMessage: HttpResponseMessage) + var + Uri: Text; + GraphQlQuery: Text; + DraftOrderCreateGraphQLTok: Label '{"query":"mutation {draftOrderCreate(input: {', Locked = true; + DraftOrderCompleteGraphQLTok: Label '{ draftOrder { order { legacyResourceId, name }} userErrors { field, message }}}"}', Locked = true; + FulfillmentOrderGraphQLTok: Label '{ fulfillmentOrders ( first:', Locked = true; + FulfillmentCreateGraphQLTok: Label '{"query": "mutation { fulfillmentCreateV2 ( fulfillment: { lineItemsByFulfillmentOrder:', Locked = true; + GraphQLQuerryTok: Label '/graphql.json', Locked = true; + begin + case HttpRequestMessage.Method of + 'POST': + begin + Uri := HttpRequestMessage.GetRequestUri(); + if Uri.EndsWith(GraphQLQuerryTok) then + if HttpRequestMessage.Content.ReadAs(GraphQlQuery) then + case true of + GraphQlQuery.Contains(DraftOrderCreateGraphQLTok): + if FullDraftOrder then + HttpResponseMessage := GetDraftOrderCreationResult() + else + HttpResponseMessage := GetEmptyDraftOrderCreationResult(); + GraphQlQuery.Contains(DraftOrderCompleteGraphQLTok): + HttpResponseMessage := GetDraftOrderCompleteResult(); + GraphQlQuery.Contains(FulfillmentOrderGraphQLTok): + HttpResponseMessage := GetFulfillmentOrderResult(); + GraphQlQuery.Contains(FulfillmentCreateGraphQLTok): + HttpResponseMessage := GetFulfillmentCreateResult(); + end; + end; + end; + end; + + local procedure GetDraftOrderCreationResult(): HttpResponseMessage; + var + HttpResponseMessage: HttpResponseMessage; + Body: Text; + begin + Body := '{"data":{"draftOrderCreate":{"draftOrder":{"id":"gid://shopify/DraftOrder/981388394558","legacyResourceId":"981388394558"},"userErrors":[]}},"extensions":{"cost":{"requestedQueryCost":10,"actualQueryCost":10,"throttleStatus":{"maximumAvailable":2000.0,"currentlyAvailable":1990,"restoreRate":100.0}}}}'; + HttpResponseMessage.Content.WriteFrom(Body); + exit(HttpResponseMessage); + end; + + local procedure GetEmptyDraftOrderCreationResult(): HttpResponseMessage; + var + HttpResponseMessage: HttpResponseMessage; + Body: Text; + begin + Body := '{"data":{"draftOrderCreate":{"draftOrder":{"id":"gid://shopify/DraftOrder/981388394558","legacyResourceId":"0"},"userErrors":[]}},"extensions":{"cost":{"requestedQueryCost":10,"actualQueryCost":10,"throttleStatus":{"maximumAvailable":2000.0,"currentlyAvailable":1990,"restoreRate":100.0}}}}'; + HttpResponseMessage.Content.WriteFrom(Body); + exit(HttpResponseMessage); + end; + + local procedure GetDraftOrderCompleteResult(): HttpResponseMessage; + var + HttpResponseMessage: HttpResponseMessage; + Body: Text; + begin + Body := StrSubstNo('{"data":{"draftOrderComplete":{"draftOrder":{"order":{"legacyResourceId":"%1","name":"%2"}},"userErrors":[]}},"extensions":{"cost":{"requestedQueryCost":11,"actualQueryCost":11,"throttleStatus":{"maximumAvailable":2000.0,"currentlyAvailable":1989,"restoreRate":100.0}}}}', ShopifyOrderId, ShopifyOrderNo); + HttpResponseMessage.Content.WriteFrom(Body); + exit(HttpResponseMessage); + end; + + local procedure GetFulfillmentOrderResult(): HttpResponseMessage; + var + HttpResponseMessage: HttpResponseMessage; + Body: Text; + begin + Body := '{"data":{"order":{"fulfillmentOrders":{"nodes":[{"id":"gid://shopify/FulfillmentOrder/7478691168318"}]}}},"extensions":{"cost":{"requestedQueryCost":7,"actualQueryCost":4,"throttleStatus":{"maximumAvailable":2000.0,"currentlyAvailable":1996,"restoreRate":100.0}}}}'; + HttpResponseMessage.Content.WriteFrom(Body); + exit(HttpResponseMessage); + end; + + local procedure GetFulfillmentCreateResult(): HttpResponseMessage; + var + HttpResponseMessage: HttpResponseMessage; + Body: Text; + begin + Body := '{"data":{"fulfillmentCreateV2":{"fulfillment":{"id":"gid://shopify/Fulfillment/5936298623038","status":"SUCCESS"},"userErrors":[]}},"extensions":{"cost":{"requestedQueryCost":10,"actualQueryCost":10,"throttleStatus":{"maximumAvailable":2000.0,"currentlyAvailable":1990,"restoreRate":100.0}}}}'; + HttpResponseMessage.Content.WriteFrom(Body); + exit(HttpResponseMessage); + end; + + internal procedure SetFullDraftOrder(IsFull: Boolean) + begin + this.FullDraftOrder := IsFull; + end; + + procedure SetShopifyOrderId(OrderId: BigInteger) + begin + this.ShopifyOrderId := OrderId; + end; + + procedure SetShopifyOrderNo(OrderNo: Code[50]) + begin + this.ShopifyOrderNo := OrderNo; + end; +} diff --git a/Apps/W1/Shopify/test/Invoices/ShpfyInvoicesTest.Codeunit.al b/Apps/W1/Shopify/test/Invoices/ShpfyInvoicesTest.Codeunit.al index a53d82c5a5..6cd4bc10a8 100644 --- a/Apps/W1/Shopify/test/Invoices/ShpfyInvoicesTest.Codeunit.al +++ b/Apps/W1/Shopify/test/Invoices/ShpfyInvoicesTest.Codeunit.al @@ -4,28 +4,28 @@ codeunit 139695 "Shpfy Invoices Test" TestPermissions = Disabled; var - LibraryAssert: Codeunit "Library Assert"; - Any: Codeunit Any; + Customer: Record Customer; + Item: Record Item; + Shop: Record "Shpfy Shop"; + LibraryRandom: Codeunit "Library - Random"; LibrarySales: Codeunit "Library - Sales"; - LibraryInventory: Codeunit "Library - Inventory"; - LibraryERMCountryData: Codeunit "Library - ERM Country Data"; + LibraryAssert: Codeunit "Library Assert"; + CommunicationMgt: Codeunit "Shpfy Communication Mgt."; IsInitialized: Boolean; + #region Test Methods [Test] procedure UnitTestCopyInvoice() var - Item: Record Item; - Customer: Record Customer; SalesHeader: Record "Sales Header"; - InvoiceNo: Code[20]; OrderId: BigInteger; + InvoiceNo: Code[20]; begin // [SCENARIO] Shopify related fields are not copied to the new invoice - // [GIVEN] Posted sales invoice with Shopify related fields and empty invoice Initialize(); - OrderId := Any.IntegerInRange(10000, 99999); - LibraryInventory.CreateItem(Item); - LibrarySales.CreateCustomer(Customer); + + // [GIVEN] Posted sales invoice with Shopify related fields and empty invoice + OrderId := LibraryRandom.RandIntInRange(10000, 99999); InvoiceNo := CreateAndPostSalesInvoice(Item, Customer, 1, false, OrderId); LibrarySales.CreateSalesHeader(SalesHeader, SalesHeader."Document Type"::Invoice, Customer."No."); @@ -36,27 +36,23 @@ codeunit 139695 "Shpfy Invoices Test" LibraryAssert.IsTrue(SalesHeader."Shpfy Order Id" = 0, 'Shpfy Order Id is not copied'); end; - [Test] procedure UnitTestMapPostedSalesInvoice() var - Item: Record Item; - Customer: Record Customer; SalesInvoiceHeader: Record "Sales Invoice Header"; SalesInvoiceLine: Record "Sales Invoice Line"; TempOrderHeader: Record "Shpfy Order Header" temporary; TempOrderLine: Record "Shpfy Order Line" temporary; PostedInvoiceExport: Codeunit "Shpfy Posted Invoice Export"; - InvoiceNo: Code[20]; OrderId: BigInteger; + InvoiceNo: Code[20]; OrderTaxLines: Dictionary of [Text, Decimal]; begin // [SCENARIO] Header and lines are mapped correctly - // [GIVEN] Posted sales invoice Initialize(); - OrderId := Any.IntegerInRange(10000, 99999); - LibraryInventory.CreateItem(Item); - LibrarySales.CreateCustomer(Customer); + + // [GIVEN] Posted sales invoice + OrderId := LibraryRandom.RandIntInRange(10000, 99999); InvoiceNo := CreateAndPostSalesInvoice(Item, Customer, 1, false, OrderId); SalesInvoiceHeader.Get(InvoiceNo); SalesInvoiceLine.SetRange("Document No.", InvoiceNo); @@ -90,22 +86,19 @@ codeunit 139695 "Shpfy Invoices Test" [Test] procedure UnitTestMapZeroQuantityLine() var - Item: Record Item; - Customer: Record Customer; SalesInvoiceHeader: Record "Sales Invoice Header"; TempOrderHeader: Record "Shpfy Order Header" temporary; TempOrderLine: Record "Shpfy Order Line" temporary; PostedInvoiceExport: Codeunit "Shpfy Posted Invoice Export"; - InvoiceNo: Code[20]; OrderId: BigInteger; + InvoiceNo: Code[20]; OrderTaxLines: Dictionary of [Text, Decimal]; begin // [SCENARIO] Lines with zero quantity are not mapped - // [GIVEN] Posted sales invoice with two lines, one with zero quantity Initialize(); - OrderId := Any.IntegerInRange(10000, 99999); - LibraryInventory.CreateItem(Item); - LibrarySales.CreateCustomer(Customer); + + // [GIVEN] Posted sales invoice with two lines, one with zero quantity + OrderId := LibraryRandom.RandIntInRange(10000, 99999); InvoiceNo := CreateAndPostSalesInvoice(Item, Customer, 1, true, OrderId); SalesInvoiceHeader.Get(InvoiceNo); @@ -116,24 +109,433 @@ codeunit 139695 "Shpfy Invoices Test" LibraryAssert.RecordCount(TempOrderLine, 1); end; + [Test] + procedure UnitTestExportWithoutSettingEnabled() + var + SalesInvoiceHeader: Record "Sales Invoice Header"; + SyncInvoicestoShpfy: Report "Shpfy Sync Invoices to Shpfy"; + InvoiceNo: Code[20]; + PostedInvoiceSyncNotSetErr: Label 'Posted Invoice Sync is not enabled for this shop.'; + ErrorMessage: Text; + begin + // [SCENARIO] Sales invoice export without the setup enabled is not exported + Initialize(); + + // [GIVEN] Shopify Shop + Shop := CommunicationMgt.GetShopRecord(); + Shop."Posted Invoice Sync" := false; + Shop.Modify(false); + + // [GIVEN] Posted sales invoice + InvoiceNo := CreateAndPostSalesInvoice(Item, Customer, 1, false, 0); + SalesInvoiceHeader.Get(InvoiceNo); + + // [WHEN] Execute the posted sales invoice export report + SyncInvoicestoShpfy.SetShop(Shop.Code); + SyncInvoicestoShpfy.UseRequestPage(false); + asserterror SyncInvoicestoShpfy.Run(); + ErrorMessage := GetLastErrorText(); + + // [THEN] Posted sales invoice is not exported + LibraryAssert.IsTrue(ErrorMessage.Contains(PostedInvoiceSyncNotSetErr), 'Posted Invoice Sync should not be executed.'); + end; + + [Test] + procedure UnitTestExportWithoutShopifyCustomerOrCompanySet() + var + SalesInvoiceHeader: Record "Sales Invoice Header"; + ShpfyCustomer: Record "Shpfy Customer"; + PostedInvoiceExport: Codeunit "Shpfy Posted Invoice Export"; + InvoiceNo: Code[20]; + begin + // [SCENARIO] Sales invoice export without the Shopify customer or company set. + Initialize(); + + // [GIVEN] Shopify Shop + Shop := CommunicationMgt.GetShopRecord(); + Shop."Posted Invoice Sync" := true; + Shop.Modify(false); + + // [GIVEN] There is no Shopify customer or company set + ShpfyCustomer.DeleteAll(false); + + // [GIVEN] Posted sales invoice + InvoiceNo := CreateAndPostSalesInvoice(Item, Customer, 1, false, 0); + SalesInvoiceHeader.Get(InvoiceNo); + + // [WHEN] Execute the posted sales invoice export + PostedInvoiceExport.Run(SalesInvoiceHeader); + SalesInvoiceHeader.Get(InvoiceNo); + + // [THEN] Posted sales invoice is not exported + LibraryAssert.AreEqual(Format(-2), Format(SalesInvoiceHeader."Shpfy Order Id"), 'Shpfy Order Id is not set correctly.'); + end; + + [Test] + procedure UnitTestExportWithoutShopifyPaymentTerms() + var + SalesInvoiceHeader: Record "Sales Invoice Header"; + PaymentTerms: Record "Shpfy Payment Terms"; + PostedInvoiceExport: Codeunit "Shpfy Posted Invoice Export"; + InvoiceNo: Code[20]; + begin + // [SCENARIO] Sales invoice export without the Shopify payment terms set up. + Initialize(); + + // [GIVEN] Shopify Shop + Shop := CommunicationMgt.GetShopRecord(); + Shop."Posted Invoice Sync" := true; + Shop.Modify(false); + + // [GIVEN] Posted sales invoice + InvoiceNo := CreateAndPostSalesInvoice(Item, Customer, 1, false, 0); + SalesInvoiceHeader.Get(InvoiceNo); + + // [GIVEN] Created Shopify company + CreateShopifyCustomer(SalesInvoiceHeader."Bill-to Customer No."); + + // [GIVEN] There is no Shopify payment terms set + PaymentTerms.DeleteAll(false); + + // [WHEN] Execute the posted sales invoice export + PostedInvoiceExport.Run(SalesInvoiceHeader); + SalesInvoiceHeader.Get(InvoiceNo); + + // [THEN] Posted sales invoice is not exported + LibraryAssert.AreEqual(Format(-2), Format(SalesInvoiceHeader."Shpfy Order Id"), 'Shpfy Order Id is not set correctly.'); + end; + + [Test] + procedure UnitTestExportWithDefaultCustomerFromSetup() + var + SalesInvoiceHeader: Record "Sales Invoice Header"; + PostedInvoiceExport: Codeunit "Shpfy Posted Invoice Export"; + InvoiceNo: Code[20]; + begin + // [SCENARIO] Sales invoice export with the default customer same as the bill-to customer. + Initialize(); + + // [GIVEN] Shopify Shop + Shop := CommunicationMgt.GetShopRecord(); + + // [GIVEN] Posted sales invoice + InvoiceNo := CreateAndPostSalesInvoice(Item, Customer, 1, false, 0); + SalesInvoiceHeader.Get(InvoiceNo); + + // [GIVEN] Created Shopify company + CreateShopifyCustomer(SalesInvoiceHeader."Bill-to Customer No."); + + // [GIVEN] Created payment terms + CreatePrimaryPaymentTerms(); + + // [GIVEN] Default customer is set to the bill-to customer + Shop."Default Customer No." := SalesInvoiceHeader."Bill-to Customer No."; + Shop.Modify(false); + + // [WHEN] Execute the posted sales invoice export + PostedInvoiceExport.SetShop(Shop.Code); + PostedInvoiceExport.Run(SalesInvoiceHeader); + SalesInvoiceHeader.Get(InvoiceNo); + + // [THEN] Posted sales invoice is not exported + LibraryAssert.AreEqual(Format(-2), Format(SalesInvoiceHeader."Shpfy Order Id"), 'Shpfy Order Id is not set correctly.'); + IsInitialized := false; + end; + + [Test] + procedure UnitTestExportWithFractionQuantity() + var + SalesInvoiceHeader: Record "Sales Invoice Header"; + PostedInvoiceExport: Codeunit "Shpfy Posted Invoice Export"; + InvoiceNo: Code[20]; + begin + // [SCENARIO] Sales invoice export with fraction quantity. + Initialize(); + + // [GIVEN] Shopify Shop + Shop := CommunicationMgt.GetShopRecord(); + + // [GIVEN] Posted sales invoice with fraction quantity + InvoiceNo := CreateAndPostSalesInvoice(Item, Customer, LibraryRandom.RandDec(5, 2), false, 0); + SalesInvoiceHeader.Get(InvoiceNo); + + // [GIVEN] Created Shopify company + CreateShopifyCustomer(SalesInvoiceHeader."Bill-to Customer No."); + + // [GIVEN] Created payment terms + CreatePrimaryPaymentTerms(); + + // [WHEN] Execute the posted sales invoice export + PostedInvoiceExport.SetShop(Shop.Code); + PostedInvoiceExport.Run(SalesInvoiceHeader); + SalesInvoiceHeader.Get(InvoiceNo); + + // [THEN] Posted sales invoice is not exported + LibraryAssert.AreEqual(Format(-2), Format(SalesInvoiceHeader."Shpfy Order Id"), 'Shpfy Order Id is not set correctly.'); + end; + + [Test] + procedure UnitTestExportWithCustomerTemplateSet() + var + SalesInvoiceHeader: Record "Sales Invoice Header"; + PostedInvoiceExport: Codeunit "Shpfy Posted Invoice Export"; + InvoiceNo: Code[20]; + begin + // [SCENARIO] Sales invoice export with Shopify customer template set up. + Initialize(); + + // [GIVEN] Shopify Shop + Shop := CommunicationMgt.GetShopRecord(); + + // [GIVEN] Posted sales invoice with fraction quantity + InvoiceNo := CreateAndPostSalesInvoice(Item, Customer, 1, false, 0); + SalesInvoiceHeader.Get(InvoiceNo); + + // [GIVEN] Created Shopify company + CreateShopifyCustomer(SalesInvoiceHeader."Bill-to Customer No."); + + // [GIVEN] Created payment terms + CreatePrimaryPaymentTerms(); + + // [GIVEN] Created Shopify customer template + CreateCustomerTemplate(SalesInvoiceHeader."Bill-to Customer No."); + + // [WHEN] Execute the posted sales invoice export + PostedInvoiceExport.SetShop(Shop.Code); + PostedInvoiceExport.Run(SalesInvoiceHeader); + SalesInvoiceHeader.Get(InvoiceNo); + + // [THEN] Posted sales invoice is not exported + LibraryAssert.AreEqual(Format(-2), Format(SalesInvoiceHeader."Shpfy Order Id"), 'Shpfy Order Id is not set correctly.'); + IsInitialized := false; + end; + + [Test] + procedure UnitTestExportWithoutCreatedDraftOrder() + var + SalesInvoiceHeader: Record "Sales Invoice Header"; + InvoicesAPISubscriber: Codeunit "Shpfy Invoices API Subscriber"; + PostedInvoiceExport: Codeunit "Shpfy Posted Invoice Export"; + InvoiceNo: Code[20]; + begin + // [SCENARIO] Sales invoice export without successfuly created draft order. + Initialize(); + + // [GIVEN] Shopify Shop + Shop := CommunicationMgt.GetShopRecord(); + + // [GIVEN] Posted sales invoice with fraction quantity + InvoiceNo := CreateAndPostSalesInvoice(Item, Customer, 1, false, 0); + SalesInvoiceHeader.Get(InvoiceNo); + + // [GIVEN] Created Shopify company + CreateShopifyCustomer(SalesInvoiceHeader."Bill-to Customer No."); + + // [GIVEN] Created payment terms + CreatePrimaryPaymentTerms(); + + // [WHEN] Execute the posted sales invoice export + InvoicesAPISubscriber.SetFullDraftOrder(false); + BindSubscription(InvoicesAPISubscriber); + PostedInvoiceExport.SetShop(Shop.Code); + PostedInvoiceExport.Run(SalesInvoiceHeader); + SalesInvoiceHeader.Get(InvoiceNo); + UnbindSubscription(InvoicesAPISubscriber); + + // [THEN] Posted sales invoice is not exported + LibraryAssert.AreEqual(Format(-1), Format(SalesInvoiceHeader."Shpfy Order Id"), 'Shpfy Order Id is not set correctly.'); + end; + + [Test] + procedure UnitTestSuccessfulSalesInvoiceExportUpdatesOrderInformation() + var + SalesInvoiceHeader: Record "Sales Invoice Header"; + InvoicesAPISubscriber: Codeunit "Shpfy Invoices API Subscriber"; + PostedInvoiceExport: Codeunit "Shpfy Posted Invoice Export"; + OrderId: BigInteger; + InvoiceNo: Code[20]; + OrderNo: Code[50]; + begin + // [SCENARIO] Sales invoice exported successfully updates posted sales invoice with Shopify order information. + Initialize(); + + // [GIVEN] Shopify Shop + Shop := CommunicationMgt.GetShopRecord(); + + // [GIVEN] Shopify order id and no + OrderId := LibraryRandom.RandIntInRange(10000, 99999); + OrderNo := LibraryRandom.RandText(10); + + // [GIVEN] Posted sales invoice with fraction quantity + InvoiceNo := CreateAndPostSalesInvoice(Item, Customer, 1, false, 0); + SalesInvoiceHeader.Get(InvoiceNo); + + // [GIVEN] Created Shopify company + CreateShopifyCustomer(SalesInvoiceHeader."Bill-to Customer No."); + + // [GIVEN] Created payment terms + CreatePrimaryPaymentTerms(); + + // [WHEN] Execute the posted sales invoice export + InvoicesAPISubscriber.SetFullDraftOrder(true); + InvoicesAPISubscriber.SetShopifyOrderId(OrderId); + InvoicesAPISubscriber.SetShopifyOrderNo(OrderNo); + BindSubscription(InvoicesAPISubscriber); + PostedInvoiceExport.SetShop(Shop.Code); + PostedInvoiceExport.Run(SalesInvoiceHeader); + SalesInvoiceHeader.Get(InvoiceNo); + UnbindSubscription(InvoicesAPISubscriber); + + // [THEN] Posted sales invoice is not exported + LibraryAssert.AreEqual(OrderId, SalesInvoiceHeader."Shpfy Order Id", 'Shpfy Order Id is not set correctly.'); + LibraryAssert.AreEqual(OrderNo, SalesInvoiceHeader."Shpfy Order No.", 'Shpfy Order No. is not set correctly.'); + IsInitialized := false; + end; + + [Test] + procedure UnitTestSuccessfulSalesInvoiceExportCreatesProcessedRecord() + var + SalesInvoiceHeader: Record "Sales Invoice Header"; + InvoiceHeader: Record "Shpfy Invoice Header"; + InvoicesAPISubscriber: Codeunit "Shpfy Invoices API Subscriber"; + PostedInvoiceExport: Codeunit "Shpfy Posted Invoice Export"; + OrderId: BigInteger; + InvoiceNo: Code[20]; + OrderNo: Code[50]; + begin + // [SCENARIO] Sales invoice exported successfully creates shopify invoice header record. + Initialize(); + + // [GIVEN] Shopify Shop + Shop := CommunicationMgt.GetShopRecord(); + + // [GIVEN] Shopify order id and no + OrderId := LibraryRandom.RandIntInRange(10000, 99999); + OrderNo := LibraryRandom.RandText(10); + + // [GIVEN] Posted sales invoice with fraction quantity + InvoiceNo := CreateAndPostSalesInvoice(Item, Customer, 1, false, 0); + SalesInvoiceHeader.Get(InvoiceNo); + + // [GIVEN] Created Shopify company + CreateShopifyCustomer(SalesInvoiceHeader."Bill-to Customer No."); + + // [GIVEN] Created payment terms + CreatePrimaryPaymentTerms(); + + // [WHEN] Execute the posted sales invoice export + InvoicesAPISubscriber.SetFullDraftOrder(true); + InvoicesAPISubscriber.SetShopifyOrderId(OrderId); + InvoicesAPISubscriber.SetShopifyOrderNo(OrderNo); + BindSubscription(InvoicesAPISubscriber); + PostedInvoiceExport.SetShop(Shop.Code); + PostedInvoiceExport.Run(SalesInvoiceHeader); + SalesInvoiceHeader.Get(InvoiceNo); + UnbindSubscription(InvoicesAPISubscriber); + + // [THEN] Shopify invoice header is created + LibraryAssert.IsTrue(InvoiceHeader.Get(SalesInvoiceHeader."Shpfy Order Id"), 'Shpfy Invoice Header is not created.'); + IsInitialized := false; + end; + + [Test] + procedure UnitTestSuccessfulSalesInvoiceExportCreatesDocumentLink() + var + SalesInvoiceHeader: Record "Sales Invoice Header"; + DocLinkToBCDoc: Record "Shpfy Doc. Link To Doc."; + InvoiceHeader: Record "Shpfy Invoice Header"; + BCDocumentTypeConvert: Codeunit "Shpfy BC Document Type Convert"; + InvoicesAPISubscriber: Codeunit "Shpfy Invoices API Subscriber"; + PostedInvoiceExport: Codeunit "Shpfy Posted Invoice Export"; + OrderId: BigInteger; + InvoiceNo: Code[20]; + OrderNo: Code[50]; + begin + // [SCENARIO] Sales invoice exported successfully creates document link. + Initialize(); + + // [GIVEN] Shopify Shop + Shop := CommunicationMgt.GetShopRecord(); + + // [GIVEN] Shopify order id and no + OrderId := LibraryRandom.RandIntInRange(10000, 99999); + OrderNo := LibraryRandom.RandText(10); + + // [GIVEN] Posted sales invoice with fraction quantity + InvoiceNo := CreateAndPostSalesInvoice(Item, Customer, 1, false, 0); + SalesInvoiceHeader.Get(InvoiceNo); + + // [GIVEN] Created Shopify company + CreateShopifyCustomer(SalesInvoiceHeader."Bill-to Customer No."); + + // [GIVEN] Created payment terms + CreatePrimaryPaymentTerms(); + + // [WHEN] Execute the posted sales invoice export + InvoicesAPISubscriber.SetFullDraftOrder(true); + InvoicesAPISubscriber.SetShopifyOrderId(OrderId); + InvoicesAPISubscriber.SetShopifyOrderNo(OrderNo); + BindSubscription(InvoicesAPISubscriber); + PostedInvoiceExport.SetShop(Shop.Code); + PostedInvoiceExport.Run(SalesInvoiceHeader); + SalesInvoiceHeader.Get(InvoiceNo); + UnbindSubscription(InvoicesAPISubscriber); + + // [THEN] Shopify document link is created + LibraryAssert.IsTrue( + DocLinkToBCDoc.Get( + "Shpfy Shop Document Type"::"Shopify Shop Order", + SalesInvoiceHeader."Shpfy Order Id", + BCDocumentTypeConvert.Convert(SalesInvoiceHeader), + SalesInvoiceHeader."No."), + 'Shpfy document link is not created.' + ); + IsInitialized := false; + end; + #endregion + + #region Local Procedures local procedure Initialize() + var + ShpfyCustomer: Record "Shpfy Customer"; + ShopifyCustomerTemplate: Record "Shpfy Customer Template"; + DocLinkToBCDoc: Record "Shpfy Doc. Link To Doc."; + InvoiceHeader: Record "Shpfy Invoice Header"; + LibraryERMCountryData: Codeunit "Library - ERM Country Data"; + LibraryInventory: Codeunit "Library - Inventory"; begin if IsInitialized then exit; - IsInitialized := true; + + Codeunit.Run(Codeunit::"Shpfy Initialize Test"); + LibraryERMCountryData.CreateVATData(); LibraryERMCountryData.UpdateGeneralPostingSetup(); + LibraryInventory.CreateItem(Item); + LibrarySales.CreateCustomer(Customer); + ShopifyCustomerTemplate.DeleteAll(false); + InvoiceHeader.DeleteAll(false); + DocLinkToBCDoc.DeleteAll(false); + ShpfyCustomer.DeleteAll(false); + + IsInitialized := true; end; - local procedure CreateAndPostSalesInvoice(Item: Record Item; Customer: Record Customer; NumberOfLines: Integer; AddComment: Boolean; OrderId: BigInteger): Code[20] + local procedure CreateAndPostSalesInvoice( + Item: Record Item; + Customer: Record Customer; + Quantity: Decimal; + AddComment: Boolean; + OrderId: BigInteger + ): Code[20] var SalesHeader: Record "Sales Header"; SalesLine: Record "Sales Line"; begin LibrarySales.CreateSalesHeader(SalesHeader, SalesHeader."Document Type"::Invoice, Customer."No."); SalesHeader."Shpfy Order Id" := OrderId; - SalesHeader.Modify(); - LibrarySales.CreateSalesLine(SalesLine, SalesHeader, SalesLine.Type::Item, Item."No.", NumberOfLines); + SalesHeader.Modify(false); + LibrarySales.CreateSalesLine(SalesLine, SalesHeader, SalesLine.Type::Item, Item."No.", Quantity); if AddComment then begin LibrarySales.CreateSalesLineSimple(SalesLine, SalesHeader); SalesLine."Type" := SalesLine.Type::" "; @@ -149,4 +551,62 @@ codeunit 139695 "Shpfy Invoices Test" CopyDocumentMgt.SetProperties(true, false, false, false, false, false, false); CopyDocumentMgt.CopySalesDoc("Sales Document Type From"::"Posted Invoice", DocNo, ToSalesHeader); end; + + local procedure CreateShopifyCustomer(CustomerNo: Code[20]) + var + Customer: Record Customer; + ShpfyCustomer: Record "Shpfy Customer"; + begin + Customer.Get(CustomerNo); + + if ShopifyCustomerEmpty(Customer.SystemId) then begin + ShpfyCustomer.Init(); + ShpfyCustomer.Id := LibraryRandom.RandInt(99999); + ShpfyCustomer."Customer SystemId" := Customer.SystemId; + ShpfyCustomer.Insert(false); + end; + end; + + local procedure CreatePrimaryPaymentTerms() + var + PaymentTerms: Record "Shpfy Payment Terms"; + begin + if PrimaryPaymentTermsEmpty() then begin + PaymentTerms.Init(); + PaymentTerms."Shop Code" := Shop.Code; + PaymentTerms.Id := LibraryRandom.RandInt(99999); + PaymentTerms."Is Primary" := true; + PaymentTerms.Insert(false); + end; + end; + + local procedure PrimaryPaymentTermsEmpty(): Boolean + var + PaymentTerms: Record "Shpfy Payment Terms"; + begin + PaymentTerms.SetRange("Shop Code", Shop.Code); + PaymentTerms.SetRange("Is Primary", true); + exit(PaymentTerms.IsEmpty()); + end; + + local procedure ShopifyCustomerEmpty(CustomerId: Guid): Boolean + var + ShpfyCustomer: Record "Shpfy Customer"; + begin + ShpfyCustomer.SetRange("Customer SystemId", CustomerId); + exit(ShpfyCustomer.IsEmpty()); + end; + + local procedure CreateCustomerTemplate(CustomerNo: Code[20]) + var + ShopifyCustomerTemplate: Record "Shpfy Customer Template"; + LibraryERM: Codeunit "Library - ERM"; + begin + ShopifyCustomerTemplate.Init(); + ShopifyCustomerTemplate."Default Customer No." := CustomerNo; + ShopifyCustomerTemplate."Shop Code" := Shop.Code; + ShopifyCustomerTemplate."Country/Region Code" := LibraryERM.CreateCountryRegion(); + ShopifyCustomerTemplate.Insert(false); + end; + #endregion } From 66972f9dd1cd5f483c81e4326fb03aa3e1525f12 Mon Sep 17 00:00:00 2001 From: Gediminas Gaubys Date: Wed, 6 Nov 2024 10:54:36 +0200 Subject: [PATCH 2/2] Fixed PR comments --- .../test/Invoices/ShpfyInvoicesAPISubscriber.Codeunit.al | 2 +- Apps/W1/Shopify/test/Invoices/ShpfyInvoicesTest.Codeunit.al | 1 - Apps/W1/Shopify/test/app.json | 2 +- 3 files changed, 2 insertions(+), 3 deletions(-) diff --git a/Apps/W1/Shopify/test/Invoices/ShpfyInvoicesAPISubscriber.Codeunit.al b/Apps/W1/Shopify/test/Invoices/ShpfyInvoicesAPISubscriber.Codeunit.al index 93c08a35c1..4641104e27 100644 --- a/Apps/W1/Shopify/test/Invoices/ShpfyInvoicesAPISubscriber.Codeunit.al +++ b/Apps/W1/Shopify/test/Invoices/ShpfyInvoicesAPISubscriber.Codeunit.al @@ -1,4 +1,4 @@ -codeunit 139576 "Shpfy Invoices API Subscriber" +codeunit 139558 "Shpfy Invoices API Subscriber" { SingleInstance = true; EventSubscriberInstance = Manual; diff --git a/Apps/W1/Shopify/test/Invoices/ShpfyInvoicesTest.Codeunit.al b/Apps/W1/Shopify/test/Invoices/ShpfyInvoicesTest.Codeunit.al index 6cd4bc10a8..da2862129d 100644 --- a/Apps/W1/Shopify/test/Invoices/ShpfyInvoicesTest.Codeunit.al +++ b/Apps/W1/Shopify/test/Invoices/ShpfyInvoicesTest.Codeunit.al @@ -443,7 +443,6 @@ codeunit 139695 "Shpfy Invoices Test" var SalesInvoiceHeader: Record "Sales Invoice Header"; DocLinkToBCDoc: Record "Shpfy Doc. Link To Doc."; - InvoiceHeader: Record "Shpfy Invoice Header"; BCDocumentTypeConvert: Codeunit "Shpfy BC Document Type Convert"; InvoicesAPISubscriber: Codeunit "Shpfy Invoices API Subscriber"; PostedInvoiceExport: Codeunit "Shpfy Posted Invoice Export"; diff --git a/Apps/W1/Shopify/test/app.json b/Apps/W1/Shopify/test/app.json index ba1deea22a..46c6526fec 100644 --- a/Apps/W1/Shopify/test/app.json +++ b/Apps/W1/Shopify/test/app.json @@ -53,7 +53,7 @@ "platform": "26.0.0.0", "idRanges": [ { - "from": 139560, + "from": 139558, "to": 139574 }, {